diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9678c65c363e..5944baf90b9d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,7 +7,7 @@ - [ ] Only relevant files were touched - [ ] Only one feature/fix was added per PR and the code change compiles without warnings - [ ] The code change is tested and works with Tasmota core ESP8266 V.2.7.4.9 - - [ ] The code change is tested and works with Tasmota core ESP32 V.2.0.9 + - [ ] The code change is tested and works with Tasmota core ESP32 V.2.0.13 - [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla). _NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_ diff --git a/.github/workflows/Tasmota_build_devel.yml b/.github/workflows/Tasmota_build_devel.yml index 023165fdaa01..6b087e613aad 100644 --- a/.github/workflows/Tasmota_build_devel.yml +++ b/.github/workflows/Tasmota_build_devel.yml @@ -2,7 +2,7 @@ name: Build_development on: - workflow_dispatch: # Manually start a workflow + workflow_dispatch: # Start a workflow push: branches: development paths-ignore: @@ -16,8 +16,8 @@ concurrency: jobs: be_solidify: - runs-on: ubuntu-20.04 - if: github.repository == 'arendst/Tasmota' + runs-on: ubuntu-latest + if: github.repository == 'arendst/Tasmota' && github.ref_name == 'development' continue-on-error: true steps: - uses: actions/checkout@v3 @@ -25,6 +25,9 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.x' + - name: Install clang compiler + run: | + sudo apt-get install -f clang - name: Make Berry and Tasmota Berry code run: | cd lib/libesp32/berry @@ -41,13 +44,13 @@ jobs: ../../libesp32/berry/berry -s -g solidify_all.be - uses: jason2866/upload-artifact@v2.0.2 with: - name: '["berry_matter", "berry_tasmota", "lvgl_tasmota"]' - path: '["./lib/libesp32/berry_matter/src/solidify", "./lib/libesp32/berry_tasmota/src/solidify", "./lib/libesp32_lvgl/lv_binding_berry/src/solidify"]' + name: '["berry_tasmota", "berry_matter", "berry_lvgl", "berry_header"]' + path: '["./lib/libesp32/berry_tasmota/src/solidify", "./lib/libesp32/berry_matter/src/solidify", "./lib/libesp32_lvgl/lv_binding_berry/src/solidify", "./lib/libesp32/berry/generate"]' push_solidified: needs: be_solidify runs-on: ubuntu-latest - if: github.repository == 'arendst/Tasmota' + if: github.repository == 'arendst/Tasmota' && github.ref_name == 'development' continue-on-error: true steps: - uses: actions/checkout@v3 @@ -58,13 +61,15 @@ jobs: - uses: jason2866/download-artifact@v3 with: name: | - berry_matter berry_tasmota - lvgl_tasmota + berry_matter + berry_lvgl + berry_header path: | - ./lib/libesp32/berry_matter/src/solidify - ./lib/libesp32/berry_tasmota/src/solidify - ./lib/libesp32_lvgl/lv_binding_berry/src/solidify + ./lib/libesp32/berry_tasmota/src/solidify + ./lib/libesp32/berry_matter/src/solidify + ./lib/libesp32_lvgl/lv_binding_berry/src/solidify + ./lib/libesp32/berry/generate - uses: stefanzweifel/git-auto-commit-action@v4 with: commit_message: Solidified Code updated @@ -85,6 +90,9 @@ jobs: - tasmota32s2cdc-safeboot - tasmota32s3-safeboot - tasmota32s3cdc-safeboot + - tasmota32c2-safeboot + - tasmota32c6-safeboot + - tasmota32c6cdc-safeboot steps: - uses: actions/checkout@v3 with: @@ -97,6 +105,7 @@ jobs: run: | pip install wheel pip install -U platformio + cp ./platformio_tasmota_core3_env_sample.ini ./platformio_tasmota_core3_env.ini - name: Run PlatformIO run: platformio run -e ${{ matrix.variant }} - name: Upload safeboot firmware artifacts @@ -231,87 +240,13 @@ jobs: name: firmware path: ./build_output - Upload: - needs: [base-images, base32-images, language-images] - runs-on: ubuntu-latest - continue-on-error: true - steps: - - name: Download firmware - uses: actions/download-artifact@v3 - with: - name: firmware - path: ./mv_firmware - - name: Downlaod safeboot firmware - uses: actions/download-artifact@v3 - with: - name: firmware_safeboot - path: ./mv_firmware - - name: Display structure of downloaded files - run: ls -R - working-directory: ./mv_firmware - - name: Move firmware files in sub-folders - run: | - mkdir -p ./firmware/tasmota/languages - mkdir -p ./firmware/tasmota32/languages - mkdir -p ./firmware/map - [ ! -f ./mv_firmware/map/* ] || mv ./mv_firmware/map/* ./firmware/map/ - [ ! -f ./mv_firmware/firmware/tasmota.* ] || mv ./mv_firmware/firmware/tasmota.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-4M.* ] || mv ./mv_firmware/firmware/tasmota-4M.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-sensors.* ] || mv ./mv_firmware/firmware/tasmota-sensors.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-minimal.bin.gz ] || mv ./mv_firmware/firmware/tasmota-minimal.bin.gz ./firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-lite.* ] || mv ./mv_firmware/firmware/tasmota-lite.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-ir*.* ] || mv ./mv_firmware/firmware/tasmota-ir*.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-display.* ] || mv ./mv_firmware/firmware/tasmota-display.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-knx.* ] || mv ./mv_firmware/firmware/tasmota-knx.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-zbbridge.* ] || mv ./mv_firmware/firmware/tasmota-zbbridge.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-zigbee.* ] || mv ./mv_firmware/firmware/tasmota-zigbee.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota32.* ] || mv ./mv_firmware/firmware/tasmota32.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32solo1*.* ] || mv ./mv_firmware/firmware/tasmota32solo1*.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-ir*.* ] || mv ./mv_firmware/firmware/tasmota32-ir*.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-display.* ] || mv ./mv_firmware/firmware/tasmota32-display.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-lvgl.* ] || mv ./mv_firmware/firmware/tasmota32-lvgl.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-web*.* ] || mv ./mv_firmware/firmware/tasmota32-web*.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-odroidgo.* ] || mv ./mv_firmware/firmware/tasmota32-odroidgo.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-zbbrdgpro.* ] || mv ./mv_firmware/firmware/tasmota32-zbbrdgpro.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-nspanel.* ] || mv ./mv_firmware/firmware/tasmota32-nspanel.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-core2.* ] || mv ./mv_firmware/firmware/tasmota32-core2.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-bluetooth.* ] || mv ./mv_firmware/firmware/tasmota32-bluetooth.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32c3*.* ] || mv ./mv_firmware/firmware/tasmota32c3*.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32s2*.* ] || mv ./mv_firmware/firmware/tasmota32s2*.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32s3*.* ] || mv ./mv_firmware/firmware/tasmota32s3*.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-safeboot* ] || mv ./mv_firmware/firmware/tasmota32-safeboot* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-* ] || mv ./mv_firmware/firmware/tasmota32-* ./firmware/tasmota32/languages/ - [ ! -f ./mv_firmware/firmware/tasmota32* ] || mv ./mv_firmware/firmware/tasmota32* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota-minimal.bin ] || rm -rf ./mv_firmware/firmware/tasmota-minimal.bin - [ ! -f ./mv_firmware/firmware/* ] || mv ./mv_firmware/firmware/* ./firmware/tasmota/languages/ - - name: Display files to transfer - run: ls -R ./* - - name: Push Firmware files to tmp_copy repo - uses: Jason2866/copy_file_to_another_repo_action@main - env: - API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }} - with: - source_file: 'firmware' - destination_repo: 'arendst/tmp_copy' - destination_branch: 'firmware' - user_email: 'github-actions@github.com' - user_name: 'github-actions' Start_final_copy: - needs: Upload + needs: [base-images, base32-images, language-images] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Creat trigger.txt + - name: Dispatch workflow in arendst/Tasmota-firmware run: | - echo ${GITHUB_SHA} &> trigger.txt - echo "$( map_all.zip + run: 7z a -mx=9 -tzip -xr'!.*' map_all.zip mv_firmware/map - name: Release uses: jason2866/action-gh-release@v1.2 #if: startsWith(github.ref, 'refs/tags/') with: tag_name: ${{ github.run_number }} - files: ./mv_firmware/firmware/* + files: | + ./mv_firmware/firmware/* + map_all.zip env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Move firmware files in sub-folders - run: | - mkdir -p ./release-firmware/tasmota/languages - mkdir -p ./release-firmware/tasmota32/languages - mkdir -p ./release-firmware/map - [ ! -f ./mv_firmware/map/* ] || mv ./mv_firmware/map/* ./release-firmware/map/ - [ ! -f ./mv_firmware/firmware/tasmota.* ] || mv ./mv_firmware/firmware/tasmota.* ./release-firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-4M.* ] || mv ./mv_firmware/firmware/tasmota-4M.* ./release-firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-sensors.* ] || mv ./mv_firmware/firmware/tasmota-sensors.* ./release-firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-minimal.bin.gz ] || mv ./mv_firmware/firmware/tasmota-minimal.bin.gz ./release-firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-lite.* ] || mv ./mv_firmware/firmware/tasmota-lite.* ./release-firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-ir*.* ] || mv ./mv_firmware/firmware/tasmota-ir*.* ./release-firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-display.* ] || mv ./mv_firmware/firmware/tasmota-display.* ./release-firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-knx.* ] || mv ./mv_firmware/firmware/tasmota-knx.* ./release-firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-zbbridge.* ] || mv ./mv_firmware/firmware/tasmota-zbbridge.* ./release-firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota-zigbee.* ] || mv ./mv_firmware/firmware/tasmota-zigbee.* ./release-firmware/tasmota/ - [ ! -f ./mv_firmware/firmware/tasmota32.* ] || mv ./mv_firmware/firmware/tasmota32.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32solo1*.* ] || mv ./mv_firmware/firmware/tasmota32solo1*.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-ir*.* ] || mv ./mv_firmware/firmware/tasmota32-ir*.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-display.* ] || mv ./mv_firmware/firmware/tasmota32-display.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-lvgl.* ] || mv ./mv_firmware/firmware/tasmota32-lvgl.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-web*.* ] || mv ./mv_firmware/firmware/tasmota32-web*.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-zbbrdgpro.* ] || mv ./mv_firmware/firmware/tasmota32-zbbrdgpro.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-nspanel.* ] || mv ./mv_firmware/firmware/tasmota32-nspanel.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-odroidgo.* ] || mv ./mv_firmware/firmware/tasmota32-odroidgo.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-core2.* ] || mv ./mv_firmware/firmware/tasmota32-core2.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-bluetooth.* ] || mv ./mv_firmware/firmware/tasmota32-bluetooth.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32c3*.* ] || mv ./mv_firmware/firmware/tasmota32c3*.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32s2*.* ] || mv ./mv_firmware/firmware/tasmota32s2*.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32s3*.* ] || mv ./mv_firmware/firmware/tasmota32s3*.* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-safeboot* ] || mv ./mv_firmware/firmware/tasmota32-safeboot* ./release-firmware/tasmota32/ - [ ! -f ./mv_firmware/firmware/tasmota32-* ] || mv ./mv_firmware/firmware/tasmota32-* ./release-firmware/tasmota32/languages/ - [ ! -f ./mv_firmware/firmware/tasmota32* ] || mv ./mv_firmware/firmware/tasmota32* ./release-firmware/tasmota32/languages/ - [ ! -f ./mv_firmware/firmware/tasmota-minimal.bin ] || rm -rf ./mv_firmware/firmware/tasmota-minimal.bin - [ ! -f ./mv_firmware/firmware/* ] || mv ./mv_firmware/firmware/* ./release-firmware/tasmota/languages/ - - name: Display files to transfer - run: ls -R ./* - - name: Push Firmware files to tmp_copy repo - uses: Jason2866/copy_file_to_another_repo_action@main - env: - API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }} - with: - source_file: 'release-firmware' - destination_repo: 'arendst/tmp_copy' - destination_branch: 'firmware' - user_email: 'github-actions@github.com' - user_name: 'github-actions' - Start_final_copy: - needs: Upload + needs: Release runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Creat trigger.txt + - name: Dispatch workflow in arendst/Tasmota-firmware run: | - echo ${GITHUB_SHA} &> trigger.txt - echo "$(%`` and ``%switch<1..28>%`` to rules (#19331) +- Experimental support for ESP32-C2 and ESP32-C6 using Arduino core v3.0 + +### Changed +- Display invert setting after tasmota start in uDisplay driver (#19337) + +### Fixed +- Shutter invert (#19341, #19374) +- Teleinfo power (#19381) +- Exception 3 in IRHVAC (#19389) + +## [Released] - Development + +## [13.1.0] 20230815 +- Release Quentin + +## [13.0.0.4] 20230815 +### Added +- ESP32 prepare for Arduino Core v3 and esp-idf v5 (#19264) + +### Changed +- Console height from default 318 pixels to viewport (#19241) +- Shutter button hold behaviour with grouptopic (#19263) +- Thermostat improvements (#19279) +- PID controller improvements (#19285) +- HDC1080 detect device offline (#19298) +- ADE7953 lowered no load threshold (#19302) + +## [13.0.0.3] 20230805 +### Added +- Support for MAX17043 fuel-gauge systems Lipo batteries (#18788) +- Support for multiple PCA9685 with extended functionality (#18805) +- Zigbee decode Aqara 0000/FF01 attribute 03 as Temperature (#19210) +- Berry bytes `get` and `set` work for 3 bytes values (#19225) +- Matter support for fabric_filtered request (for Google compatibility) (#19249) + +### Changed +- Initial ``DisplayMode`` from 1 to 0 and ``DisplayDimmmer`` from 10% to 50% (#19138) +- ESP32 Framework (Arduino Core) from v2.0.10 to v2.0.11 +- Berry `mqtt.publish` now distinguishes between `string` and `bytes` (#19196) +- IRremoteESP8266 library from v2.8.5 to v2.8.6 +- ESP32 autodetect flashsize and adjust filesystem (#19215) +- Reduced log level for TeleInfo (#19216) +- Matter increased polling frequency for local switches/occupancy (#19242) + +### Fixed +- Initial battery level percentage (#19160) +- Berry SK6812_GRBW crash (#19166) +- ESP8266 SPI initialization for scripter, filesystem and MFRC522 (#19209) +- Zero cross dimmer minimum interrupt time (#19211) +- Fade would fail when the difference between start and target would be too small (#19248) +- Inverted shutter (#19243) +- Matter support for large atribute responses (#19252) +- Matter auto-configuration Relay indices (#19255) + +## [13.0.0.2] 20230721 +### Added +- Partition Wizard is now able to convert to safeboot from Shelly partition layout (#19034) +- Matter mini-profiler (#19075) +- Berry `_class` can be used in `static var` initialization code (#19088) +- Berry `energy.update_total()` to call `EnergyUpdateTotal()` from energy driver (#19117) +- Support for DeepSleep battery level percentage (#19134) +- Berry metrics for memory allocation/deallocation/reallocation (#19150) +- Berry `tasmota.loglevel()` and `tasmota.rtc_utc()` for faster performance (#19152) +- Berry AES CCM decrypting in a single call to avoid any object allocation (#19153) + +### Changed +- ESP32 shutter driver support up to 16 shutters (#18295) +- Configuration backup and restore now backup and restore ``.xdrvsetXXX`` files too (#18295) +- Berry extend `range(lower, upper, incr)` to arbitrary increment (#19120) +- Berry updated syntax highlighting plugin for VSCode (#19123) +- Matter latency improvement for single attribute reads and single commands (#19158) + +## [13.0.0.1] 20230708 +### Added +- Command ``Delay -1`` to wait until next second (#18984) +- Matter add option to disable bridge mode (#18992) +- Support for SGP41 TVOC/NOx Sensor (#18880) +- Command ``BrRestart`` to restart the Berry VM (experimental) (#19003) +- Command ``Restart 9`` to save all changes and go into deepsleep waiting for a reset (#19024) +- Berry added `getgbl` performance counter to `debug.counters()` (#19070) + +### Breaking Changed +- Berry `bool( [] )` and `bool( {} )` now evaluate as `false` (#18986) +- Berry `import strict` now detects useless expr without side effects (#18997) + +### Changed +- Matter support for temperature in Fahrenheit (`SetOption8 1`) (#18987) +- Matter improve responsiveness (#19002) +- ESP32 LVGL library from v8.3.7 to v8.3.8 (no functional change) +- Matter improve latency for remote commands (#19072) + +### Fixed +- Berry various fixes for Walrus Operator (#18982) +- MiElHVAC power commands regression from v12.4.0.1 (#18923) +- `BrRestart` now supports web handlers to work after Berry restart + +### Removed +- Support for ESP32-C3 with chip rev below 3 (old development boards) + +## [13.0.0] 20230626 +- Release Qasim + +## [12.5.0.4] 20230626 +### Added +- Matter ability to add or remove endpoint in bridge mode (code only) +- Matter add controller's Vendor Name to logs and UI +- Matter redesigned UI +- Matter add support for Contact Sensor +- Berry `string.format()` now automatically converts type according to format +- Matter add friendly-name (NodeLabel) to each endpoint +- Berry add global function `format` as a simpler syntax to `string.format` +- Berry added f-strings as an alternative to string formatting +- Matter display the remote Device Name instead of IP address +- Berry Walrus operator ':=' +- Zigbee firmware for Sonoff-ZB-Pro v20230507 + +### Changed +- Berry `webclient.url_encode()` is now a static class method, no change required to existing code (#18775) +- Matter Bridge mode always on +- ESP32 Framework (Core) from v2.0.9 to v2.0.10 +- Berry code size optimizations + +### Fixed +- Interaction of ``SetOption92``, ``VirtualCT``, and ``RGBWWTable`` (#18768) +- Fixed HASPmota event when value is non-integer (fixes #18229) +- Matter fix local Occupancy sensor +- Zigbee fixed regression with SetOption101 +- Berry fixed parser error with upvals in closures +- NeoPool fix NPFiltration switch result (#18871) + +## [12.5.0.3] 20230602 +### Added +- Command ``WifiPower 0`` to enable dynamic wifi power based on RSSI by @TD-er (#15443) +- Command ``WifiPower 1`` to restore default wifi power +- HASPmota `meta` attribute and improved `berry_run` (#18685) +- Matter bridge for ESP8266 remote endpoints (experimental) (#18734) +- Display descriptor for ST7735 128x160 display (#18741) +- Matter support for Occupancy via Switch (experimental) (#18742) +- Berry RS256 crypto algorithm (RSASSA-MCKS1_v1-5 with SHA256) used for JWT (#18763) +- Berry add `set_lsb_justified(bool)` to `AudioOutputI2S` (#18774) + +### Breaking Changed +- Matter relay number starts at 1 instead of 0 to match Tasmota numbering + +### Changed +- InfluxDb resolves DNS name before request (#18015) +- Shutter sliders in WEBGUI automatically appear and disappear during configuration and update during movement (#18701) +- AdafruitFingerprint library from v2.0.4 to v2.1.0 + +### Fixed +- ESP32 InfluxDb initial connection delays using HTTPClient (#18015) +- Shutter bootloop using more than 4 shutters (#18673) +- AIThinker webcam issues (#18652) +- Berry `tasmota.wifi()` would wrongly report wifi as up +- Inverted shutter now reflect status also in WEBGUI and several minor fixes to make "inverted" consistant (#18701) +- Matter fix fabric provisioning from CASE session for iOS 16.5 (#18709) +- ESP32 SPI initialization for MFRC522 (#18711) +- Freeze BMP readings before deepsleep (#18720) +- ESP32 Neopixel busy time adjustment (#18723) +- Zigbee attributes handling in Berry mapping (#18747) + +## [12.5.0.2] 20230516 ### Added - Matter support for Shutters with Tilt - Matter POC for remote Relay -- Support for Zero-Cross Dimmer on ESP32, changed calculation on EPS8266, high resolution control e.g. Solar: `ZCDimmerSet` +- Support for Zero-Cross Dimmer on ESP32, changed calculation on ESP8266, high resolution control e.g. Solar: `ZCDimmerSet` - ESP32 Enhanced Shutterbuttons functionality to control tilt position, additionally incr/decr possible to position and tilt. -- ESP32 `Shuttersetup` for "Shelly 2.5 pro" automatic calibration and setup (experimental) +- ESP32 command ``Shuttersetup`` for "Shelly 2.5 pro" automatic calibration and setup (experimental) - Berry `tcpclientasync` class for non-blocking TCP client - Support for GM861 1D and 2D bar code reader (#18399) - Berry `re` (regex) add `match2` and optional offset +- Support for PCA9557 8-bit I/O expander (#18632) +- Matter support for async HTTP for bridged devices (#18656) +- Zigbee support for air sensors (#18665) +- Command ``I2cScan0`` to scan both busses on ESP32 with one command ### Breaking Changed - Change command ``FileUpload`` index binary data detection from >199 to >299 @@ -20,12 +224,13 @@ All notable changes to this project will be documented in this file. ### Changed - ESP32 Framework (Core) from v2.0.8 to v2.0.9 - autoconf extract `display.ini` to file system +- IRremoteESP8266 library from v2.8.4 to v2.8.5 +- Energy power delta report delayed by two seconds allowing hardware to stabilize (#17751) ### Fixed - Partition_Manager.tapp fixed - Berry fixed a rare condition when a GC causes a memory corruption - -### Removed +- LED PWM ac_dimmer curve was wrongly applied instead of Gamma regression from v12.2.0.5 (#18666) ## [12.5.0.1] 20230505 ### Added @@ -47,8 +252,6 @@ All notable changes to this project will be documented in this file. - Berry fix rules for string comparisons (#18464) - Shutter: GarageMode does not stop on console commands, `ShutterSetOpen` and `ShutterSetClose` does not reset direction (#18539) -## [Released] - ## [12.5.0] 20230417 - Release Peyton @@ -451,15 +654,6 @@ All notable changes to this project will be documented in this file. ### Fixed - Removed whitespace from JSON values with no decimals (#16365) -## [12.1.0.1] 20220825 -### Added -- Zigbee device plugin mechanism with commands ``ZbLoad``, ``ZbUnload`` and ``ZbLoadDump`` (#16252) -- ESP32-S3 support for internal temperature sensor -- Command ``StatusRetain`` (#11109) - -### Changed -- ESP32 NimBLE library from v1.3.6 to v1.4.0 - ## [12.1.1] 20220825 - Release Patricia @@ -469,6 +663,15 @@ All notable changes to this project will be documented in this file. - Button response delay regression from v12.0.2.4 (#16319) - Lost module name in GUI regression from v12.0.2.4 - 20220803 (#16324) +## [12.1.0.1] 20220825 +### Added +- Zigbee device plugin mechanism with commands ``ZbLoad``, ``ZbUnload`` and ``ZbLoadDump`` (#16252) +- ESP32-S3 support for internal temperature sensor +- Command ``StatusRetain`` (#11109) + +### Changed +- ESP32 NimBLE library from v1.3.6 to v1.4.0 + ## [12.1.0] 20220818 - Release Patricia @@ -505,7 +708,7 @@ All notable changes to this project will be documented in this file. - Driver DHT v6 consolidation for both ESP8266 and ESP32 to support SI7021, THS01 and MS01 on ESP32 (#15856) - Tasmota ESP32 Arduino core from v2.0.3 to v2.0.4 (#15940) -## [12.0.2.2] +## [12.0.2.2] 20220701 ### Added - Command ``GlobalTemp2 1..250`` to select Global Temperature source indexed from teleperiod occurance data (#15834) - Command ``GlobalHum2 1..250`` to select Global Humidity source indexed from teleperiod occurance data (#15834) diff --git a/CODE_OWNERS.md b/CODE_OWNERS.md index 49d7f6f53668..b0d05100f576 100644 --- a/CODE_OWNERS.md +++ b/CODE_OWNERS.md @@ -80,7 +80,16 @@ In addition to @arendst the following code is mainly owned by: | xdrv_66_tm1638 | @arendst | xdrv_67_mcp23xxx | @arendst | xdrv_68_zerocrossDimmer.ino | @stefanbode -| | +| xdrv_69_pca9557 | @cctweaker +| xdrv_70 | +| xdrv_71 | +| xdrv_72 | +| xdrv_73 | +| xdrv_74 | +| xdrv_75 | +| xdrv_76 | +| xdrv_77 | +| xdrv_78 | | xdrv_79_esp32_ble | @staars, @btsimonh | xdrv_81_esp32_webcam | @gemu, @philrich | xdrv_82_esp32_ethernet | @arendst @@ -208,6 +217,8 @@ In addition to @arendst the following code is mainly owned by: | xsns_106_gdk101 | @Szewcson | xsns_107_gm861 | @arendst | xsns_108_tc74 | Michael Loftis +| xsns_109_sgp4x | Andrew Klaus +| xsns_110_max17043 | Vincent de Groot | | | Libraries | | | diff --git a/FIRMWARE.md b/FIRMWARE.md index e7d042c39c2a..ab962399c40c 100644 --- a/FIRMWARE.md +++ b/FIRMWARE.md @@ -18,7 +18,7 @@ See [CHANGELOG.md](https://github.com/arendst/Tasmota/blob/development/tasmota/C ## Development -[![Dev Version](https://img.shields.io/badge/development%20version-v12.5.x.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Dev Version](https://img.shields.io/badge/development%20version-v13.1.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://ota.tasmota.com/tasmota/) [![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22) [![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22) diff --git a/I2CDEVICES.md b/I2CDEVICES.md index 9faaea61c299..9bba8962e720 100644 --- a/I2CDEVICES.md +++ b/I2CDEVICES.md @@ -9,6 +9,7 @@ The following table lists the supported I2C devices Index | Define | Driver | Device | Address(es) | Description ------|---------------------|----------|----------|-------------|----------------------------------------------- 1 | USE_PCA9685 | xdrv_15 | PCA9685 | 0x40 - 0x47 | 16-channel 12-bit pwm driver + 1 | USE_PCA9685_V2 | xdrv_15 | PCA9685 | 0x40 - 0x47 | 16-channel 12-bit pwm driver 2 | USE_PCF8574 | xdrv_28 | PCF8574 | 0x20 - 0x26 | 8-bit I/O expander (address range overridable) 2 | USE_PCF8574 | xdrv_28 | PCF8574A | 0x39 - 0x3F | 8-bit I/O expander (address range overridable) 3 | USE_DISPLAY_LCD | xdsp_01 | | 0x27, 0x3F | LCD display @@ -115,4 +116,7 @@ Index | Define | Driver | Device | Address(es) | Description 77 | USE_MCP23XXX_DRV | xdrv_67 | MCP23x17 | 0x20 - 0x26 | 16-bit I/O expander as virtual button/switch/relay 78 | USE_PMSA003I | xsns_104 | PMSA003I | 0x12 | PM2.5 Air Quality Sensor with I2C Interface 79 | USE_GDK101 | xsns_106 | GDK101 | 0x18 - 0x1B | Gamma Radiation Sensor - 80 | USE_TC74 | xsns_108 | TC74 | 0x48 - 0x4F | Temperature sensor \ No newline at end of file + 80 | USE_TC74 | xsns_108 | TC74 | 0x48 - 0x4F | Temperature sensor + 81 | USE_PCA9557 | xdrv_69 | PCA95xx | 0x18 - 0x1F | 8-bit I/O expander as virtual button/switch/relay + 82 | USE_SGP4X | xsns_109 | SGP4X | 0x59 | Gas (TVOC/NOx index) + 83 | USE_MAX17043 | xsns_110 | MAX17043 | 0x36 | Fuel-gauge for 3.7 Volt Lipo battery diff --git a/README.md b/README.md index f3039bda5823..14911249a137 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Firmware binaries can be downloaded from http://ota.tasmota.com/tasmota/release/ ## Development -[![Dev Version](https://img.shields.io/badge/development%20version-v12.5.x.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Dev Version](https://img.shields.io/badge/development%20version-v13.1.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://ota.tasmota.com/tasmota/) [![Tasmota CI](https://github.com/arendst/Tasmota/actions/workflows/build_all_the_things.yml/badge.svg)](https://github.com/arendst/Tasmota/actions/workflows/build_all_the_things.yml) [![Build_development](https://github.com/arendst/Tasmota/actions/workflows/Tasmota_build_devel.yml/badge.svg)](https://github.com/arendst/Tasmota/actions/workflows/Tasmota_build_devel.yml) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 2490b7a5645c..7b8a74f7c3c8 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -36,9 +36,9 @@ While fallback or downgrading is common practice it was never supported due to S This release will be supported from ESP8266/Arduino library Core version **2.7.4.9** due to reported security and stability issues on previous Core version. This will also support gzipped binaries. -This release will be supported from ESP32/Arduino library Core version **2.0.9**. +This release will be supported from ESP32/Arduino library Core version **2.0.12**. -Support of ESP8266 Core versions before 2.7.4.9 and ESP32 Core versions before 2.0.9 have been removed. +Support of ESP8266 Core versions before 2.7.4.9 and ESP32 Core versions before 2.0.12 have been removed. ## Support of TLS @@ -75,12 +75,12 @@ Latest released binaries can be downloaded from - http://ota.tasmota.com/tasmota/release Historical binaries can be downloaded from -- http://ota.tasmota.com/tasmota/release-12.5.0 +- http://ota.tasmota.com/tasmota/release-13.1.0 The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz`` ### ESP32, ESP32-C3, ESP32-S2 and ESP32-S3 based -The following binary downloads have been compiled with ESP32/Arduino library core version **2.0.9**. +The following binary downloads have been compiled with ESP32/Arduino library core version **2.0.12**. - **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY** - **tasmota32xy.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3/S2/S3 and 4M+ flash. @@ -100,7 +100,7 @@ Latest released binaries can be downloaded from - https://ota.tasmota.com/tasmota32/release Historical binaries can be downloaded from -- https://ota.tasmota.com/tasmota32/release-12.5.0 +- https://ota.tasmota.com/tasmota32/release-13.1.0 The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasmota.com/tasmota32/release/tasmota32.bin`` @@ -110,27 +110,32 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v12.5.0.2 +## Changelog v13.1.0.3 ### Added -- Command ``SetOption152 0/1`` to select two (0 = default) pin bistable or one (1) pin latching relay control [#18386](https://github.com/arendst/Tasmota/issues/18386) -- Support for TC74 temperature sensor by Michael Loftis [#18042](https://github.com/arendst/Tasmota/issues/18042) -- Support for GM861 1D and 2D bar code reader [#18399](https://github.com/arendst/Tasmota/issues/18399) -- Matter sensors Humidity, Pressure, Illuminance [#18441](https://github.com/arendst/Tasmota/issues/18441) -- Matter allow `Matter#Initialized` rule once the device is configured [#18451](https://github.com/arendst/Tasmota/issues/18451) -- Matter UI to change endpoints configuration [#18498](https://github.com/arendst/Tasmota/issues/18498) -- Matter support for Shutters with Tilt [#18509](https://github.com/arendst/Tasmota/issues/18509) -- ESP32 Enhanced Shutterbuttons functionality to control tilt position, additionally incr/decr possible to position and tilt. -- ESP32 `Shuttersetup` for "Shelly 2.5 pro" automatic calibration and setup (experimental) -- Berry `tcpclientasync` class for non-blocking TCP client +- Experimental support for ESP32-C2 and ESP32-C6 using Arduino core v3.0 +- Commands to allow setting of timeprop parameters [#19310](https://github.com/arendst/Tasmota/issues/19310) +- Variables ``%power<1..28>%`` and ``%switch<1..28>%`` to rules [#19331](https://github.com/arendst/Tasmota/issues/19331) +- Support for HDMI CEC protocol [#19434](https://github.com/arendst/Tasmota/issues/19434) +- Support different baudrates on BL0942 +- Support for Shelly PlusPMMini, Plus1Mini and Plus1PMMini ### Breaking Changed -- Change command ``FileUpload`` index binary data detection from >199 to >299 ### Changed -- ESP32 Framework (Core) from v2.0.7 to v2.0.9 -- Refactored Zero Cross Dimmer [#18481](https://github.com/arendst/Tasmota/issues/18481) +- ESP32 Framework (Arduino Core) from v2.0.11 to v2.0.13 +- ESP32 LVGL library from v8.3.8 to v8.3.9 (no functional change) +- Display invert setting after tasmota start in uDisplay driver [#19337](https://github.com/arendst/Tasmota/issues/19337) ### Fixed -- ESP8266 Energy Export Active no update regression from v12.3.1.3 -- NovaSDS GUI values [#18444](https://github.com/arendst/Tasmota/issues/18444) -- Berry fix rules for string comparisons [#18464](https://github.com/arendst/Tasmota/issues/18464) \ No newline at end of file +- Shutter invert [#19341](https://github.com/arendst/Tasmota/issues/19341) and [#19374](https://github.com/arendst/Tasmota/issues/19374) +- Teleinfo power [#19381](https://github.com/arendst/Tasmota/issues/19381) +- Exception 3 in IRHVAC [#19389](https://github.com/arendst/Tasmota/issues/19389) +- PCF8574 mode 1 with base relays exception 3/28 regression from v12.4.0.4 [#19408](https://github.com/arendst/Tasmota/issues/19408) +- ESP32 DS18x20 driver support extended over GPIO33 +- ESP32 Support for IPv6 link-local zones for esp-idf 5.1 (necessary for Matter) +- ESP32 Shutter migration [#19454](https://github.com/arendst/Tasmota/issues/19454) +- ESP32 Shutter multi press button events [#19465](https://github.com/arendst/Tasmota/issues/19465) +- ESP32C3 relay click on restart +- Matter support for Virtual Devices controllable via Rules or Berry [#19520](https://github.com/arendst/Tasmota/issues/19520) + +### Removed diff --git a/TEMPLATES.md b/TEMPLATES.md index 739cd6a0e2d4..4cb82b7866a4 100644 --- a/TEMPLATES.md +++ b/TEMPLATES.md @@ -5,11 +5,12 @@ # Templates -Find below the available templates as of April 2023. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) +Find below the available templates as of August 2023. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) ## Adapter Board ``` 3DStar ESP-OpenTherm v1.1 {"NAME":"3DS_OpenTherm","GPIO":[0,0,0,0,0,0,0,0,4960,0,4928,0,0,0],"FLAG":0,"BASE":18} +KinCony Ethernet IO Expansion Board {"NAME":"KC868-AM","GPIO":[1,1,1,1,640,1,1,1,1,1,1,224,608,1,5600,1,0,1,1,5568,0,1,1,1,0,0,0,0,3200,1,1,3232,1,0,0,1],"FLAG":0,"BASE":1} WifInfo - Teleinfo Server {"NAME":"WifInfo","GPIO":[1376,1,1,5152,640,608,1,1,1,1,1,1,1,1],"FLAG":0,"BASE":18} ZiGate-Ethernet {"NAME":"ZIGATE-ETH","GPIO":[1,1,1,1,1,1,0,0,1,0,1,1,3840,576,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0],"FLAG":0,"BASE":18,"CMND":"EthClockMode 3 | EthAddress 1"} ``` @@ -18,6 +19,7 @@ ZiGate-Ethernet {"NAME":"ZIGATE-ETH","GPIO":[1,1,1,1,1,1,0,0,1,0,1, ``` Alfawise {"NAME":"alfawise P2","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} BlitzHome AP1 {"NAME":"BH-AP1","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +BlitzHome AP2501 {"NAME":"BH-AP2501","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Kogan 5-Stage 3S {"NAME":"Kogan Air Purifier 3S","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} ``` @@ -152,6 +154,7 @@ V-Tac PAR16 4.5W 300lm 110 {"NAME":"V-TAC VT-5174","GPIO":[0,0,0,0,0,0,0,0,417 Vestaiot BR30 800lm {"NAME":"Vesta BR30 CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18} Wipro Garnet NS9100 810lm {"NAME":"Wipro 9W CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":48} Wyze A19 800lm {"NAME":"Wyze Bulb","GPIO":[5728,0,0,0,0,0,0,0,0,416,417,0,0,0],"FLAG":0,"BASE":48} +Wyze A19 800lm {"NAME":"WLPA19v2","GPIO":[0,0,0,0,0,0,0,0,0,0,0,0,0,417,416,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1} ``` ## Camera @@ -160,6 +163,7 @@ Ai-Thinker {"NAME":"AITHINKER CAM","GPIO":[4992,1,672,1,416,50 Freenove ESP32-WROVER.DEV {"NAME":"Freenove-WROVER-Cam","GPIO":[1,1,1,1,5088,5089,0,0,1,1,1,1,1,1,5090,5091,1,4992,5184,5152,1,5120,5024,5056,0,0,0,0,1,1,5094,5095,5092,1,1,5093],"FLAG":0,"BASE":1} M5Stack ESP32CAM Camera Module OV2640 {"NAME":"M5Cam","GPIO":[0,1,672,1,416,5091,1,1,1,6720,320,4960,1,1,5093,5095,0,5184,5024,5056,0,5120,5152,4992,0,0,0,0,5088,1,5090,5089,5094,0,0,5092],"FLAG":0,"BASE":2} M5Stack PSRAM Timer Camera (OV3660) {"NAME":"M5STACK CAM","GPIO":[0,0,0,0,0,5091,1,0,0,0,0,4960,1,0,5093,5095,0,5184,5120,5056,0,5024,5152,4992,0,0,0,0,5088,0,5090,5089,5094,0,0,5092],"FLAG":0,"BASE":2} +OV5640 ESP32 {"NAME":"ESP32-OV5640-Cam","GPIO":[32,1,5088,1,8832,4960,1,1,5091,8864,5089,4992,1,1,5120,8800,0,8960,5024,5056,0,288,5184,5092,0,0,0,0,1,5093,5094,5090,5152,0,0,5095],"FLAG":0,"BASE":1} Wireles Tag Camera {"NAME":"WT-ESP32-CAM","GPIO":[4992,1,1,1,1,5088,0,0,1,1,1,1,1,0,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,0,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":2} ``` @@ -222,12 +226,14 @@ MS-108 In-Wall {"NAME":"MS-108","GPIO":[0,0,0,0,161,160,0,0,224,0, MS-108WR RF Curtain Module {"NAME":"MS-108WR","GPIO":[1,1,1,544,32,33,1,1,225,32,224,1,1,1],"FLAG":0,"BASE":18} Nous {"NAME":" Smart WiFi Curtain Module L12T","GPIO":[1,160,1,161,225,224,1,1,544,1,32,1,1,1],"FLAG":0,"BASE":18} QS-WIFI-C01-RF {"NAME":"Shutter-QS-WIFI-C01","GPIO":[0,0,1,0,288,0,0,0,32,33,224,225,0,0],"FLAG":0,"BASE":18} +wesmartify Smart Home Aktor Shut It TASMOTA {"NAME":"ITzy","GPIO":[0,0,0,0,225,224,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} ``` ## Curtain Switch ``` Anccy {"NAME":"Anccy Shutter","GPIO":[544,0,289,34,226,33,0,0,32,224,290,225,288,0],"FLAG":0,"BASE":18} Anccy Relax {"NAME":"Tuya Shutter","GPIO":[544,0,290,161,225,34,0,0,32,224,289,226,288,0],"FLAG":0,"BASE":18} +Avatto Curtain + Light {"NAME":"Avatto Curtain + Light","GPIO":[576,0,0,34,226,35,0,0,32,224,225,227,33,0],"FLAG":0,"BASE":18} Avatto SYS-CS01 {"NAME":"Avatto","GPIO":[320,576,0,33,225,0,0,0,0,224,321,0,32,0],"FLAG":0,"BASE":18} Currydouble {"NAME":"Currydouble","GPIO":[260,258,576,0,0,224,0,0,0,1,5760,225,259,0],"FLAG":0,"BASE":18} Etersky WF-CS01 {"NAME":"Etersky","GPIO":[544,0,289,34,226,33,0,0,32,224,290,225,288,0],"FLAG":0,"BASE":18} @@ -252,10 +258,11 @@ Zemismart Backlit {"NAME":"WF-CS01","GPIO":[544,227,289,34,226,161,0, ## DIN Relay ``` -CurrySmarter Power Monitoring 30A {"NAME":"30A Breaker","GPIO":[0,0,0,0,7584,224,0,0,2720,32,2656,2624,320,0],"FLAG":0,"BASE":18} +CurrySmarter Power Monitoring 30A {"NAME":"30A Breaker on Led","GPIO":[0,0,0,0,7584,224,0,0,2720,32,2656,2624,320,0],"FLAG":0,"BASE":18} EARU DIN Circuit Breaker 1P 32A/50A {"NAME":"RDCBC-1P","GPIO":[320,0,0,0,0,0,0,0,32,224,0,0,0,0],"FLAG":0,"BASE":18} Hoch Circuit Breaker 1P {"NAME":"HOCH ZJSB9","GPIO":[32,0,0,0,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":18} Ketotek Single Phase Energy Monitor {"NAME":"Ketotek KTEM06","GPIO":[0,2272,0,2304,0,0,0,0,0,0,320,0,32,0],"FLAG":0,"BASE":54} +Martin Jerry 30A Circuit Breaker {"NAME":"30A Breaker","GPIO":[0,0,0,0,7584,224,0,0,2720,32,2656,2624,320,0],"FLAG":0,"BASE":18} OpenEnergyMonitor WiFi MQTT Thermostat {"NAME":"MQTT-RELAY","GPIO":[32,0,1,0,0,224,0,0,0,0,0,0,320,0],"FLAG":0,"BASE":18} RocketController ASTRA Controller {"NAME":"ASTRA R4A4","GPIO":[1,1,1,1,576,1,1,1,480,1,1,1,3232,3200,1,1,0,640,608,1,0,224,225,1152,0,0,0,0,227,226,160,161,162,0,0,163],"FLAG":0,"BASE":1} Shelly Pro 1 {"NAME":"Shelly Pro 1","GPIO":[0,1,0,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"} @@ -290,9 +297,11 @@ Adafruit QT Py ESP32 Pico {"NAME":"QTPy ESP32 Pico","GPIO":[32,3200,0,3232,1, AZ-Envy Environmental Sensor {"NAME":"AZ Envy","GPIO":[32,0,320,0,640,608,0,0,0,0,0,0,0,4704],"FLAG":0,"BASE":18} Coiaca Tasmota {"NAME":"AWR01t","GPIO":[576,1,1,128,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Coiaca Tasmota Development Board AWR12 {"NAME":"AWR12t","GPIO":[320,1,1,1,1,1,0,0,1,1,1,1,1,1],"FLAG":0,"BASE":18} -Dasduino CONNECT {"NAME":"Dasduino CONNECTPLUS","GPIO":[32,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,640,608,1,0,1,1,1,0,0,0,0,1376,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} Dasduino CONNECTPLUS {"NAME":"Dasduino CONNECT","GPIO":[1,1,1376,1,640,608,1,1,1,1,1,1,1,1],"FLAG":0,"BASE":18} +Dasduino CONNECTPLUS {"NAME":"Dasduino CONNECTPLUS","GPIO":[32,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,640,608,1,0,1,1,1,0,0,0,0,1376,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} Espoir Rev 1.0.0 PoE+ {"NAME":"Espoir","GPIO":[0,0,1,0,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,5568,5600,1,7968,1,1,1,1],"FLAG":0,"BASE":1} +KinCony 128 Channel Controller {"NAME":"KC868-A128","GPIO":[0,1,0,1,609,640,1,1,1,3232,3200,641,608,1,5600,0,0,1,0,5568,0,1,0,0,0,0,0,0,0,0,4705,4707,4706,0,0,4704],"FLAG":0,"BASE":1} +KinCony 64 Channel Controller {"NAME":"KC868-A64","GPIO":[0,1,0,1,609,640,1,1,1,3232,3200,641,608,1,5600,0,0,1,0,5568,0,1,0,0,0,0,0,0,0,0,4705,4707,4706,0,0,4704],"FLAG":0,"BASE":1} LC Technology MicroPython Maker {"NAME":"LC-ESP-Python","GPIO":[1,1,544,1,1,1,1,1,1,1,1,1,1,1],"FLAG":0,"BASE":18} LilyGO RGB LED Ring Encoder {"NAME":"T-Encoder","GPIO":[0,0,1,0,1,0,0,0,1,1,1,1,0,0,0,480,6212,0,0,0,0,449,450,448,0,0,0,0,0,0,0,0,3296,3264,32,0],"FLAG":0,"BASE":1,"CMND":"BuzzerPwm 1"} LilyGO T7 Mini32 V1.5 {"NAME":"LilyGO T7 V1.5","GPIO":[1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,544,0,0,0,1,0,1,1,1,0,0,0,0,0,1,1,4704,1,0,0,1],"FLAG":0,"BASE":1} @@ -386,7 +395,7 @@ Shelly Vintage 7W 750lm 2700k {"NAME":"Shelly Vintage","GPIO":[0,0,0,0,416,0,0, Shelly Vintage 7W 750lm 2700k {"NAME":"Shelly Vintage","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} SmartDGM 9W 806lm {"NAME":"L-WB9W1","GPIO":[0,0,0,0,0,416,0,0,160,0,0,0,0,0],"FLAG":0,"BASE":18} Smitch 10W 6500K {"NAME":"Smitch Ambience SB-0110","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Smitch 10W 6500K {"NAME":"Smitch Ambience SB-0110","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Smitch 10W 6500K {"NAME":"Smitch 10W 6500K Dimmable Bulb (SB0110 - E27)","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":1} TCP Smart 806lm Warm White {"NAME":"TCP Smart Clas","GPIO":[0,0,0,0,0,0,0,0,0,416,0,0,0,0],"FLAG":0,"BASE":1} TCP Smart 810lm Filament {"NAME":"TCP Filament","GPIO":[0,0,0,0,0,0,0,0,0,0,448,0,0,0],"FLAG":0,"BASE":18} TCP Smart 810lm Filament {"NAME":"TCP Filament","GPIO":[0,0,0,0,0,0,0,0,0,0,448,0,0,0],"FLAG":0,"BASE":18} @@ -402,6 +411,7 @@ Athom EU {"NAME":"Athom Dimmer Switch","GPIO":[576,2272,0,23 CE Smart Home {"NAME":"CE-WF500D","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54} CE Smart Home CFW500D-3W 3 Way {"NAME":"CE-WF500D-3W","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54} CNSKOU Touch {"NAME":"CNSKOU Dimmer Switch","GPIO":[0,0,0,0,0,0,0,0,0,0,290,0,0,0],"FLAG":0,"BASE":54} +Deta Single Gang Touch Dimmer {"NAME":"Deta 6910HA","GPIO":[0,3200,1,3232,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Eva Logik {"NAME":"WF31 Dimmer","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} Eva Logik 3 Way {"NAME":"EL WF31T","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} Feit Electric Smart {"NAME":"Feit DIM/WIFI","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} @@ -528,10 +538,11 @@ Sonoff SC {"NAME":"Sonoff SC","GPIO":[32,3200,1,3232,0,0,0,0, ``` Anko HEGSM40 {"NAME":"Anko HEGSM40","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54} Arlec 117cm Aurora Digital Tower {"NAME":"ATF4601HA","GPIO":[1,2272,1,2304,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} +Arlec 130cm White 4 Blade DC Ceiling Light and {"NAME":"Arlec DCF4002WHA","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54} Arlec 45cm DC Pedestal {"NAME":"Arlec 45cm Fan","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 61,2 | TuyaMCU 64,3 | TuyaMCU 99,6 | TuyaMCU 12,101"} Arlec Smart 45cm Smart DC Wall {"NAME":"Arlec 45cm Fan","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 61,2 | TuyaMCU 64,3 | TuyaMCU 99,6 | TuyaMCU 12,101"} Duux Whisper Flex Battery Pack {"NAME":"Duux DXCF12","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 61,2 | TuyaMCU 62,3 | TuyaMCU 12,4 | TuyaMCU 13,5 | TuyaMCU 64,6"} -Duux Whisper Flex Smart {"NAME":"Duux Fan","GPIO":[0,0,0,0,0,0,0,0,0,0,2304,0,2272,0],"FLAG":0,"BASE":54} +Duux Whisper Flex Smart {"NAME":"Duux Fan","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54} Geek Aire 3D Oscillating Desktop {"NAME":"Geek Aire Fan","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 12,4 | TuyaMCU 13,5"} Goldair SleepSmart GCPF315 {"NAME":"Goldair Fan","GPIO":[0,0,0,0,0,0,0,0,0,2304,0,2272,0,0],"FLAG":0,"BASE":54} Holmes 36" Oscillating Tower {"NAME":"Generic","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,1,1],"FLAG":0,"BASE":54,"CMND":"TuyaMcu 11,1 | TuyaMcu 12,5 | WebButton1 Power | WebButton2 Oscillation "} @@ -597,6 +608,7 @@ AI Universal Remote {"NAME":"YTF IR Controller","GPIO":[1,1,1,1,320,108 AI Universal Remote Control {"NAME":"LQ-08","GPIO":[0,0,0,0,0,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} Alfawise KS1 {"NAME":"KS1","GPIO":[1,1792,32,1824,32,1088,0,0,320,0,1056,0,0,4704],"FLAG":0,"BASE":62} Antsig Universal Remote Controller {"NAME":"Antsig Smart Wi-Fi IR","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} +Athom {"NAME":"Athom_IR_Remote","GPIO":[32,0,0,0,1056,1088,0,0,0,576,0,0,0,0],"FLAG":0,"BASE":18} Automate Things IR Bridge {"NAME":"AT-IRBR-1.0","GPIO":[0,0,0,0,1056,1088,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"Module 0"} Automate Things IR Bridge {"NAME":"AT-IRBR-1.4","GPIO":[1088,0,0,0,1056,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"Module 0"} auvisio S06 {"NAME":"NX-4519-675","GPIO":[0,0,0,0,288,1088,0,0,0,0,1056,0,0,0],"FLAG":0,"BASE":18} @@ -610,7 +622,7 @@ Geeklink GK01 {"NAME":"GL IR Blaster","GPIO":[1,1,1,1,320,1088,0, HIPER IoT IR2 {"NAME":"hiper_HI-IR2","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} Jinvoo AC/TV Box {"NAME":"Jinvoo IR Controller","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} JS-IR1 Universal Remote {"NAME":"JS-IR1","GPIO":[1,1,1,1,288,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":18} -Kincony ESP32 433MHz RF and {"NAME":"KC868-AG","GPIO":[0,0,1056,0,480,0,0,0,0,0,1,0,1,1,1,1,0,1,1120,1152,0,7968,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1,"CMND":"BuzzerPwm 1"} +KinCony ESP32 433MHz RF and {"NAME":"KC868-AG","GPIO":[0,0,1056,0,480,0,0,0,0,0,1,0,1,1,1,1,0,1,1120,1152,0,7968,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1,"CMND":"BuzzerPwm 1"} Lenovo SE-741C {"NAME":"Lenovo IR","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} Mirabella Genio I002577 {"NAME":"Genio IR TxRx","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} Moes Tuya Remote Control {"NAME":"Moes IR Controller","GPIO":[1,1,1,1,1,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} @@ -702,6 +714,7 @@ ZJ-WF-ESP-A v1.1 {"NAME":"RGB2","GPIO":[0,0,0,0,0,0,0,0,417,416,418, ## LED Strip ``` Aldi Casalux RGB {"NAME":"DW-RGB-WI01","GPIO":[1088,0,0,0,416,0,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18} +ARLEC 5m Colour Changing "Not available" Arlec Smart 1m CCT LED Strip Light {"NAME":"ALD155HA","GPIO":[0,0,1088,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18} Arlec Smart 2m LED Colour Changing Strip Light {"NAME":"Arlec_Light_Strip","GPIO":[1,1,1088,1,416,419,1,1,417,420,418,0,1,1],"FLAG":0,"BASE":18} Arlec Smart 5m White & Colour Changing {"NAME":"ALD556HA","GPIO":[0,0,1088,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} @@ -786,6 +799,7 @@ Deta 18W 1900lm T8 Tube {"NAME":"DETA Smart LED","GPIO":[0,0,0,0,0,0,0,0,0, electriQ MOODL Ambiance Lamp {"NAME":"ElectriQ MOODL","GPIO":[0,4640,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Gosund Table Lamp {"NAME":"Gosund LB3","GPIO":[0,0,0,0,0,418,0,0,417,419,0,416,0,0],"FLAG":0,"BASE":18} Hama Wall Light Square, 10 cm, IP 44 {"NAME":"Hama Wifi Wall Light","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,1],"FLAG":0,"BASE":18} +HiFree Table Lamp {"NAME":"TuyaMCU","GPIO":[2304,1184,2272,1184,1184,1184,1184,1184,1184,1184,1184,1184,1184,0],"FLAG":0,"BASE":18} Hugoai Table Lamp {"NAME":"HG02","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,20 | TuyaMCU 26,21 | TuyaMCU 21,22 | TuyaMCU 23,23 | TuyaMCU 24,24 | DimmerRange 34,1000"} Iwoole Table Lamp {"NAME":"GLOBELAMP","GPIO":[0,0,0,0,419,0,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} Lepro Bedroom Lamp {"NAME":"Lepro 902101-US","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,20 | TuyaMCU 26,21 | TuyaMCU 21,22 | TuyaMCU 23,23 | TuyaMCU 24,24 | DimmerRange 34,1000"} @@ -800,6 +814,7 @@ Mirabella Genio 4 Black LED Garden Path {"NAME":"GenioGardenStr","GPIO":[0,0,0, Mirabella Genio CCT 6 LED 30mm Stainless Steel Deck {"NAME":"Mirabella Deck CCT","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18} MiraBella Genio Colour 6 LED 30mm Stainless Steel Deck {"NAME":"Genio RGB Deck Lights","GPIO":[0,0,0,0,416,0,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18} Mirabella Genio Rechargable LED Portable Lamp {"NAME":"MirabellaPortableLamp","GPIO":[32,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18} +Moes RGBCW (8+8+15+15W) {"NAME":"JL-TD3-4-4-2516-V1.0","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Nous CCT Desk Lamp {"NAME":"NOUS Smart Desk Lamp S1","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,1 | TuyaMCU 21,3 | TuyaMCU 23,4 | DimmerRange 25,255"} Novostella Bloom 20W RGBCW Flood {"NAME":"Novostella NTF36 Floodlight","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Novostella UT88835 20W Flood {"NAME":"Novo 20W Flood","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} @@ -856,6 +871,7 @@ Xystec USB3.0 4 Port Hub {"NAME":"Xystec USB Hub","GPIO":[0,0,0,0,224,0,0,0, DT-Light ESP8285 Lighting {"NAME":"DMP-L1","GPIO":[1,1,0,1,1,1,0,0,1,1,1,1,1,1],"FLAG":0,"BASE":18} ESP-01D {"NAME":"ESP-01D","GPIO":[1,1,0,1,1,0,0,0,1,0,1,0,0,0],"FLAG":0,"BASE":18} ESP-01S {"NAME":"ESP-01","GPIO":[1,1,1,1,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +ESP-02S TYWE2S Replacement {"NAME":"ESP-02S","GPIO":[1,1,1,1,1,1,0,0,1,1,1,0,0,1],"FLAG":0,"BASE":18} ESP-12 {"NAME":"ESP-12","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,1],"FLAG":0,"BASE":18} ESP-15F {"NAME":"ESP-15F","GPIO":[1,1,0,1,1,1,0,0,0,544,0,0,0,0],"FLAG":0,"BASE":18} ESP-M2 {"NAME":"ESP-M2","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,0,1],"FLAG":0,"BASE":18} @@ -867,7 +883,6 @@ M5Stack M5Stamp Pico {"NAME":"M5Stamp Pico","GPIO":[1,1,0,1,0,0,0,0,0,0, MTools 16 Channel ESP32 Relay Driver 5V DC {"NAME":"16ch Board","GPIO":[1,1,237,1,232,1,1,1,228,231,1,1,233,230,234,235,0,238,239,236,0,224,227,226,0,0,0,0,229,225,1,1,1,0,0,1],"FLAG":0,"BASE":1} Shelly Universal Input/Output {"NAME":"Shelly Uni","GPIO":[320,0,0,0,225,1216,0,0,192,193,194,224,0,4864],"FLAG":0,"BASE":18} Sinilink MODBUS Interface {"NAME":"XY-WFPOW","GPIO":[0,8768,544,8800,32,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -TYWE2S Replacement {"NAME":"ESP-02S","GPIO":[1,1,1,1,1,1,0,0,1,1,1,0,0,1],"FLAG":0,"BASE":18} ``` ## Motion Sensor @@ -902,6 +917,7 @@ Atomi {"NAME":"AtomiSmartPlug","GPIO":[0,0,0,0,320,576,0, Blitzwolf 16A IP44 Dual {"NAME":"Blitzwolf BW-SHP14","GPIO":[0,320,0,32,0,321,0,0,224,0,225,0,0,0],"FLAG":0,"BASE":18} BN-Link {"NAME":"BNC-60/U130T","GPIO":[1,0,1,0,1,320,1,1,224,32,1,0,0,1],"FLAG":0,"BASE":18} Brennenstuhl WA 3000 {"NAME":"WA 3000 XS02","GPIO":[0,0,0,0,224,32,0,0,576,288,0,0,0,0],"FLAG":0,"BASE":61} +BSEED {"NAME":"PA-GEBA-01SWP","GPIO":[0,0,0,0,288,321,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} C119 {"NAME":"Subosi C119","GPIO":[0,0,0,0,225,320,0,0,224,544,32,0,321,0],"FLAG":0,"BASE":18} C137 IP55 {"NAME":"C137 Outdoor","GPIO":[0,32,0,320,2720,2656,0,0,224,2624,225,0,0,1],"FLAG":0,"BASE":18} C168 IP64 {"NAME":"C188","GPIO":[320,0,321,0,33,0,0,0,224,32,544,225,0,0],"FLAG":0,"BASE":18} @@ -935,6 +951,7 @@ Ledvance Smart+ 16A {"NAME":"LEDVANCE Smart Wifi Outdoor Plug","GPIO":[ Ledvance Smart+ Compact {"NAME":"LEDVANCE SMART+ Compact Outdoor Plug ","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} LSC Dual Socket {"NAME":"LSC NFL-022","GPIO":[0,0,0,0,320,32,0,0,0,224,225,0,0,0],"FLAG":0,"BASE":18} LSC Dual Socket {"NAME":"LSC Outdoor Dual Socket","GPIO":[320,0,0,32,8673,8672,0,0,0,0,8674,0,8675,0],"FLAG":0,"BASE":18} +Luminea 16A {"NAME":"NX-4655-675","GPIO":[0,0,0,0,320,576,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Luminea 2 Outlet {"NAME":"Luminea","GPIO":[0,0,0,0,225,320,0,0,224,321,32,0,0,1],"FLAG":0,"BASE":18} Luminea NX-4458 {"NAME":"Luminea NX4458","GPIO":[32,0,0,0,2688,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":65} Master {"NAME":"Master_IOT-EXTPLUG","GPIO":[32,1,0,1,1,0,0,0,224,288,0,0,0,0],"FLAG":0,"BASE":1} @@ -957,6 +974,7 @@ Signstek EOP03-EU {"NAME":"Signstek EOP03","GPIO":[0,0,0,0,320,321,0, SK03 {"NAME":"SK03 Outdoor","GPIO":[32,0,0,0,2688,2656,0,0,2624,321,320,224,0,0],"FLAG":0,"BASE":57} STITCH {"NAME":"STITCH 35556","GPIO":[1,1,1,1,225,321,0,0,224,320,32,1,1,0],"FLAG":0,"BASE":18} Suraielec 40A Heavy Duty {"NAME":"Suraielec UBTW01B","GPIO":[0,0,0,0,544,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} +Tate Guard ZUM-26EU-X Dual {"NAME":"Tate Guard","GPIO":[0,0,0,0,224,288,0,0,225,288,32,0,0,0],"FLAG":0,"BASE":18} Teckin SS31 {"NAME":"Teckin SS31","GPIO":[1,1,1,1,320,321,1,1,224,32,225,1,1,1],"FLAG":0,"BASE":18} Teckin SS33 {"NAME":"Teckin SS31","GPIO":[0,0,0,226,320,321,0,0,224,32,225,0,0,1],"FLAG":0,"BASE":18} Teckin SS42 {"NAME":"Teckin SS42","GPIO":[0,0,0,0,320,321,0,0,224,32,225,0,0,0],"FLAG":0,"BASE":18} @@ -1015,6 +1033,7 @@ Aquiv S1 {"NAME":"Aquiv S1","GPIO":[0,0,544,0,320,0,0,0,224, Arlec 10m Smart Extension Lead {"NAME":"Arlec Ext Cord","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} Arlec Heavy Duty 20m Extension Lead {"NAME":"Arlec Ext Cord","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} Arlec Plug In Socket {"NAME":"PC191HA","GPIO":[0,32,0,0,2720,2656,0,0,2624,224,288,0,0,0],"FLAG":0,"BASE":18} +Arlec Plug In Socket {"NAME":"PC191HAS2","GPIO":[0,0,0,32,2656,2624,0,0,224,2720,320,0,0,0],"FLAG":0,"BASE":18} Arlec Smart {"NAME":"Arlec-PC190HA","GPIO":[0,0,0,0,320,0,0,0,224,576,32,0,0,0],"FLAG":0,"BASE":18} Arlec Smart {"NAME":"PC399HA","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":52} Arlec Smart 2.1A USB Charger {"NAME":"Arlec Single","GPIO":[0,0,0,0,321,0,0,0,224,0,64,0,0,0],"FLAG":0,"BASE":18} @@ -1044,6 +1063,7 @@ Aukey SH-PA1 {"NAME":"AUKEY SH-PA1","GPIO":[320,0,321,0,0,0,0,0, Aukey SH-PA3 {"NAME":"Aukey SH-PA3","GPIO":[0,0,576,0,321,32,0,0,225,0,0,224,0,0],"FLAG":0,"BASE":18} Aunics Presa Smart {"NAME":"AUNICS","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} Aunics Smart IT {"NAME":"AUNICS","GPIO":[0,0,0,32,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":18} +Avatar {"NAME":"Generic","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18} Avatar {"NAME":"Avatar UK 10A","GPIO":[0,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":45} Avatar AWP01L {"NAME":"AWP01L","GPIO":[0,0,0,0,0,320,0,0,0,32,224,0,0,0],"FLAG":0,"BASE":18} Avatar AWP02L-N {"NAME":"AWP02L-N","GPIO":[576,0,0,0,320,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18} @@ -1056,6 +1076,7 @@ Avatto 10A {"NAME":"Avatto NAS-WR01W 10A 2021-12","GPIO":[0,0, Avatto JH-G01E {"NAME":"AVATTO JH-G01E","GPIO":[0,3072,0,3104,0,0,0,0,32,320,224,0,0,0],"FLAG":0,"BASE":41} Avatto OT06 16A {"NAME":"Avatto OT06","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49} Avatto OT08 {"NAME":"Avatto OT08","GPIO":[416,0,418,0,417,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} +Avidsen Home {"NAME":"Avidsen HomePlug","GPIO":[0,0,0,0,224,35,0,0,289,288,0,0,0,0],"FLAG":0,"BASE":18} Awow X5P {"NAME":"Awow","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18} AWP02L-N {"NAME":"AWP02L-N","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18} AzpenHome Smart {"NAME":"Socket2Me","GPIO":[288,1,1,1,225,1,0,0,224,1,32,1,1,0],"FLAG":0,"BASE":18} @@ -1108,6 +1129,7 @@ Bytech {"NAME":"BYTECH B POWERED","GPIO":[0,321,0,0,320,0, Calex 429198 {"NAME":"Calex Pwr Plug","GPIO":[0,0,0,0,320,0,0,0,224,0,32,0,0,0],"FLAG":0,"BASE":1} Calex Powerplug UK {"NAME":"Calex UK Plug","GPIO":[0,0,0,0,320,321,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":1} Calex UK {"NAME":"Calex 429202","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224,0,1],"FLAG":0,"BASE":18} +casa NOVA {"NAME":"casa-NOVA","GPIO":[0,0,0,0,320,576,0,0,224,0,32,0,0,0],"FLAG":0,"BASE":1} CE Smart Home {"NAME":"LITESUN LA-WF7","GPIO":[0,320,0,32,2720,2656,0,0,2624,321,224,0,0,0],"FLAG":0,"BASE":18} CE Smart Home LA-WF3 {"NAME":"CE LA-WF3","GPIO":[0,0,0,0,544,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} CloudFree EU {"NAME":"CloudFree P1EU","GPIO":[0,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} @@ -1123,6 +1145,8 @@ Coosa SP1 {"NAME":"COOSA SP1","GPIO":[321,1,320,1,0,2720,0,0, CooWoo {"NAME":"CooWoo AW01","GPIO":[0,0,0,0,288,160,0,0,256,0,0,0,0,0],"FLAG":0,"BASE":18} CozyLife HomeKit 16A {"NAME":"CozyLife 16A","GPIO":[0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,2720,0,0,2656,576,0,224,2624,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1} CrazyLynX WiFi {"NAME":"CrazyLynX","GPIO":[0,0,0,0,321,320,0,0,224,32,0,0,0,4704],"FLAG":0,"BASE":18} +Crest Single Power Adaptor {"NAME":"SHSPM1","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":52} +Crest Smart Home Single Power Adaptor with 2 USB {"NAME":"Medion","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":52} CurrySmarter 16A {"NAME":"CurrySmarter 16A","GPIO":[0,0,0,32,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} CurrySmarter 16A Power Monitoring {"NAME":"Currysmarter XH-TW2P","GPIO":[0,0,0,2624,32,320,0,0,224,2720,2656,0,0,0],"FLAG":0,"BASE":18} CYYLTF BIFANS J23 {"NAME":"CYYLTD BIFANS J23","GPIO":[0,0,0,0,288,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} @@ -1174,8 +1198,6 @@ Etekcity 15A {"NAME":"ESW15-US","GPIO":[0,0,0,0,0,224,0,0,2656,2 Etekcity 8A {"NAME":"ESW01-USA","GPIO":[0,0,0,0,224,544,0,0,2656,2688,32,2592,288,0],"FLAG":0,"BASE":55} EU3S {"NAME":"AWOW BSD33","GPIO":[0,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} Eva Logik {"NAME":"EVA LOGIK Plug","GPIO":[1,32,1,1,1,1,0,0,1,288,224,1,1,0],"FLAG":0,"BASE":18} -EZPlug V1 OpenSource {"NAME":"EZPlug V1","GPIO":[0,0,0,32,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":1} -EZPlug+ V1 {"NAME":"EZPlug+ V1","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":1} Febite {"NAME":"Febite","GPIO":[320,0,0,0,0,2720,0,0,224,32,2656,0,0,0],"FLAG":0,"BASE":1} Feit Electric PLUG/WIFI {"NAME":"Feit Wifi Plug","GPIO":[0,0,0,320,0,0,0,0,224,0,32,0,0,0],"FLAG":0,"BASE":18} FK-PW901U {"NAME":"FK-PW901U","GPIO":[320,1,1,1,1,226,0,0,224,32,227,225,1,0],"FLAG":0,"BASE":18} @@ -1296,6 +1318,7 @@ JuoYou 16A {"NAME":"Juoyou ZY-OYD","GPIO":[0,0,0,32,2720,2656, JVMAC-EU01 {"NAME":"JVMAC","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} Kaforto KW-US-801 {"NAME":"Kaforto US-801","GPIO":[32,576,0,227,2720,2656,0,0,2624,225,224,226,0,0],"FLAG":0,"BASE":18} Kauf esphome {"NAME":"KAUF Plug","GPIO":[576,0,320,0,224,2720,0,0,2624,32,2656,0,0,0],"FLAG":0,"BASE":18} +Kauf esphome {"NAME":"Kauf Plug","GPIO":[0,320,0,32,2720,2656,0,0,321,224,2624,0,0,0],"FLAG":0,"BASE":18} Kimire S12 {"NAME":"Kimire S12","GPIO":[1,1,1,32,1,1,0,0,1,320,224,1,1,0],"FLAG":0,"BASE":18} King-Link KL-US-WF002 {"NAME":"Kinglink-plug","GPIO":[0,0,0,0,0,224,0,0,288,32,0,0,0,0],"FLAG":0,"BASE":18} Kisslink SP200 {"NAME":"Kisslink SP200","GPIO":[0,0,0,0,320,321,0,0,224,32,0,0,0,4704],"FLAG":0,"BASE":18} @@ -1393,8 +1416,8 @@ NGS Loop Track 16A {"NAME":"LOOP","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224 Nightlight and AC Outlet {"NAME":"SWN03","GPIO":[32,0,0,0,0,0,1,1,416,0,0,224,0,0],"FLAG":0,"BASE":18} Nishica SM-PW701I {"NAME":"SM-PW701I","GPIO":[1,1,1,1,1,1,1,1,224,288,32,1,1,1],"FLAG":0,"BASE":18} Nivian {"NAME":"Nivian Smart Socket","GPIO":[0,0,320,0,0,2688,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} -Nous 16A {"NAME":"NOUS A1T","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49} Nous A1 {"NAME":"NOUS A1","GPIO":[320,0,576,0,2656,2720,0,0,2624,32,0,224,0,0],"FLAG":0,"BASE":45} +Nous A1T 16A {"NAME":"NOUS A1T","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49} NX-SM112 {"NAME":"NX-SM112v3","GPIO":[0,0,0,0,2720,2656,0,0,576,32,2592,224,0,0],"FLAG":0,"BASE":45} NX-SM200 {"NAME":"NX-SM200","GPIO":[320,0,0,0,0,2720,0,0,224,32,2656,321,2624,0],"FLAG":0,"BASE":18} NX-SM210 {"NAME":"NX-SM210","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} @@ -1402,7 +1425,7 @@ NX-SM223 {"NAME":"Smart Thurmm","GPIO":[0,32,0,0,0,0,0,0,0,3 Oakter Oak Plug Plus 16A {"NAME":"Oakter OakPlug Plus","GPIO":[0,0,0,0,224,0,0,0,544,320,0,0,0,0],"FLAG":0,"BASE":18} Oakter OakPlug Mini 10A {"NAME":"Oakter OakPlug Mini","GPIO":[0,0,0,0,224,0,0,0,544,320,0,0,0,0],"FLAG":0,"BASE":18} Oakter OakPlug Plus (old) {"NAME":"Oakter OakPlug Plus (old)","GPIO":[0,0,0,0,224,0,0,0,0,320,0,0,544,0],"FLAG":0,"BASE":18} -Obi Stecker {"NAME":"OBI Socket","GPIO":[1,1,0,1,288,224,0,0,290,1,32,0,1,4704],"FLAG":0,"BASE":51} +Obi Stecker {"NAME":"Euromate","GPIO":[1,1,1,1,288,224,1,1,289,1,32,1,1,1],"FLAG":0,"BASE":18} Obi Stecker 2 {"NAME":"OBI Socket 2","GPIO":[0,0,0,0,224,32,0,0,320,289,0,0,0,0],"FLAG":0,"BASE":61} OFFONG 16A {"NAME":"OFFONG P1","GPIO":[0,32,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18} Oittm Smart {"NAME":"Oittm","GPIO":[0,0,0,0,224,320,0,0,32,0,0,0,0,0],"FLAG":0,"BASE":1} @@ -1422,6 +1445,7 @@ OxaOxe NX-SP202 v2 {"NAME":"oxaoxe-dold","GPIO":[320,0,0,2624,32,2720, OZWI Smart {"NAME":"OZWI Smart Plug","GPIO":[0,0,0,0,288,0,0,0,224,32,544,0,0,0],"FLAG":0,"BASE":18} Panamalar Nightlight {"NAME":"Panamalar EWN0","GPIO":[32,0,0,0,0,0,1,1,416,0,0,224,0,0],"FLAG":0,"BASE":18} Panamalar NX-SM200 {"NAME":"NX-SM200","GPIO":[0,0,0,0,320,2720,0,0,2624,32,2656,224,0,4704],"FLAG":0,"BASE":18} +Polycam Hohm Lanre 16A {"NAME":"SLV1910001","GPIO":[0,0,0,32,2720,2656,0,0,2624,576,224,0,0,0],"FLAG":0,"BASE":18} Positivo PPW1000 {"NAME":"PPW1000","GPIO":[0,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":45} Positivo Max {"NAME":"PPW1600","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":55} PowerAdd BIE0091 {"NAME":"BIE0091","GPIO":[32,0,0,0,0,0,0,0,416,0,0,224,0,0],"FLAG":0,"BASE":18} @@ -1440,6 +1464,7 @@ QNCX {"NAME":"QNCX","GPIO":[0,0,0,32,2720,2656,0,0,2624, Qnect 16A {"NAME":"Qnect QN-WP01","GPIO":[0,0,0,0,0,224,0,0,288,0,32,0,0,0],"FLAG":0,"BASE":18} qnect 16A {"NAME":"QNECT QN-WP01E","GPIO":[0,0,0,32,2688,2656,0,0,2624,288,224,0,0,0],"FLAG":0,"BASE":18} Qualitel Mini {"NAME":"Qualitel HG01WT","GPIO":[320,0,321,0,0,2688,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} +Refoss P11 {"NAME":"Refoss-P11","GPIO":[0,0,0,3104,576,32,0,0,320,224,0,0,0,4736],"FLAG":0,"BASE":1} RenPho RF-SM004 {"NAME":"RenPho RFSM004","GPIO":[0,0,0,0,544,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Robaxo {"NAME":"Robaxo RSP-025","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18} RSH-WS005 {"NAME":"RSH-WS005 Energy Monitor","GPIO":[320,0,576,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} @@ -1498,6 +1523,7 @@ STITCH {"NAME":"Stitch 27937","GPIO":[32,0,320,0,2688,2656 STITCH {"NAME":"Stitch 35511","GPIO":[320,0,321,0,0,2688,0,0,0,32,2656,224,2624,0],"FLAG":0,"BASE":18} STITCH 15A In-Line {"NAME":"Stitch 39047","GPIO":[0,288,0,32,2688,2656,0,0,2624,0,224,0,0,0],"FLAG":0,"BASE":18} STITCH Mini 10A {"NAME":"STITCH 41730","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18} +Strong Helo EU {"NAME":"Strong-Helo-PLUG","GPIO":[0,0,0,32,2688,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":65} Strong Helo Plight {"NAME":"Strong HELO-PLIGHT-EU","GPIO":[416,0,418,0,417,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} Strong Helo PLUSB 2x USB {"NAME":"Helo-PLUSB-EU","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,225,8096,0],"FLAG":0,"BASE":18} SuperNight Dual {"NAME":"SUPERNIGHT","GPIO":[0,32,0,224,2656,2688,0,0,225,2624,576,0,0,4833],"FLAG":0,"BASE":18} @@ -1526,6 +1552,8 @@ Teckin SP27 {"NAME":"Teckin SP27","GPIO":[320,1,1,1,1,1,0,0,1,3 Tellur 16A 2 Ports {"NAME":"Tellur WiFi Smart Socket","GPIO":[0,0,0,2624,96,2688,0,0,224,33,2656,225,0,0],"FLAG":0,"BASE":18} Tellur 1USB 10A {"NAME":"Tellur TTL331021","GPIO":[0,0,544,0,288,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Tflag NX-SM100 {"NAME":"NX-SM100","GPIO":[320,0,0,0,0,2720,0,0,224,32,2656,321,2624,0],"FLAG":0,"BASE":18} +TH3D EZPlug V1 {"NAME":"EZPlug V1","GPIO":[0,0,0,32,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":1} +TH3D EZPlug+ V1 {"NAME":"EZPlug+ V1","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":1} TikLok TL650 {"NAME":"TikLok Mini","GPIO":[0,0,0,0,321,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Timethinker C338 {"NAME":"C338","GPIO":[32,0,1,0,0,0,0,0,224,288,1,0,0,0],"FLAG":0,"BASE":1} Timethinker TK04 {"NAME":"TimethinkerEU","GPIO":[1,1,1,1,32,1,0,0,1,288,224,1,0,0],"FLAG":0,"BASE":18} @@ -1545,6 +1573,7 @@ Treatlife Dimmable {"NAME":"DP20","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0, Treatlife Smart {"NAME":"Treatlife SK50","GPIO":[1,1,1,1,320,576,1,1,224,1,32,1,1,1],"FLAG":0,"BASE":18} Tuya 16A Nightlight {"NAME":"Nightlight","GPIO":[225,0,320,0,226,227,0,0,34,64,0,224,0,0],"FLAG":0,"BASE":18} U10 Series {"NAME":"WIFI-Socket","GPIO":[1,32,1,1,1,1,1,1,1,320,224,1,1,4704],"FLAG":0,"BASE":18} +Ucomen Night Light {"NAME":"UCOMEN Plug","GPIO":[0,0,0,0,544,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} UltraBrite {"NAME":"UltraBrite Smart Plug","GPIO":[1,1,1,1,288,289,1,1,224,32,1,1,1,1],"FLAG":0,"BASE":18} Ultralink UL-P01W {"NAME":"UL-P01W","GPIO":[0,288,0,32,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":18} Unlocked Automation 15A {"NAME":"UA 100","GPIO":[0,0,0,0,320,321,0,0,224,32,0,0,0,1],"FLAG":0,"BASE":18} @@ -1596,7 +1625,7 @@ XS-A18 {"NAME":"XS-A18","GPIO":[416,0,417,0,0,418,0,0,0,32 XS-A23 {"NAME":"XS-A23","GPIO":[320,1,0,2624,32,2720,0,0,0,33,2656,224,225,0],"FLAG":0,"BASE":45} XS-SSA01 {"NAME":"XS-SSA01","GPIO":[1,0,0,1,0,0,0,0,320,32,1,224,1,0],"FLAG":0,"BASE":18} XS-SSA01 v2 {"NAME":"XS-SSA01","GPIO":[1,32,1,1,1,1,0,0,320,1,1,224,1,0],"FLAG":0,"BASE":18} -XS-SSA05 {"NAME":"XS-SSA05","GPIO":[257,1,1,2624,1,2688,0,0,224,32,2656,258,1,4704],"FLAG":0,"BASE":18} +XS-SSA05 {"NAME":"XS-SSA05","GPIO":[320,0,0,2624,544,2688,0,0,224,32,2656,0,0,4704],"FLAG":0,"BASE":18} XS-SSA06 {"NAME":"XS-SSA06","GPIO":[416,0,417,0,0,418,0,0,0,64,0,224,0,0],"FLAG":0,"BASE":18} Yagala SWA9 {"NAME":"SWA9","GPIO":[0,0,0,0,288,224,0,0,0,32,0,0,0,0],"FLAG":0,"BASE":18} Yelomin JH-G01E {"NAME":"Yelomin","GPIO":[0,3072,0,3104,0,0,0,0,32,320,224,0,0,0],"FLAG":0,"BASE":18} @@ -1657,6 +1686,7 @@ Digma DiPlug Strip 40 {"NAME":"DiPlug Strip 40","GPIO":[1,320,1,32,225,22 Digoo DG-PS01 {"NAME":"Digoo DG-PS01","GPIO":[0,320,0,32,226,225,0,0,0,227,224,0,0,4704],"FLAG":0,"BASE":18} Ener-J Extension Box with USB {"NAME":"ENER-J SHA5207","GPIO":[544,0,0,321,225,322,1,1,320,224,227,226,32,1],"FLAG":0,"BASE":18} Forrinx 3AC 4USB {"NAME":"SH-20","GPIO":[0,320,0,321,225,224,0,0,32,226,227,0,0,0],"FLAG":0,"BASE":18} +Geekbes 3AC 3USB {"NAME":"GC801U","GPIO":[291,0,0,320,256,35,0,0,258,257,0,0,227,0],"FLAG":0,"BASE":18} Geekbes 4AC+4USB {"NAME":"Geekbes 4xStri","GPIO":[0,320,0,32,225,224,0,0,226,227,228,0,0,4704],"FLAG":0,"BASE":18} Geeni Surge + Charge 2 USB {"NAME":"Geeni GN-SW023","GPIO":[288,0,0,0,225,224,0,0,226,227,228,0,32,0],"FLAG":0,"BASE":18} Geeni SURGE 6-Outlet Surge Protector {"NAME":"Geeni 6 Strip","GPIO":[320,0,0,0,225,224,0,0,227,228,226,229,32,0],"FLAG":0,"BASE":18} @@ -1688,17 +1718,18 @@ Konesky Type 1 {"NAME":"Konesky","GPIO":[0,0,0,0,228,225,0,0,227,3 Koogeek KLOE4 {"NAME":"Koogeek KLOE4","GPIO":[0,320,0,32,225,224,0,0,226,227,228,0,0,4704],"FLAG":0,"BASE":18} Larkkey 4AC 4USB {"NAME":"LARKKEY Strip","GPIO":[0,544,0,32,225,224,0,0,226,227,228,0,0,0],"FLAG":0,"BASE":18} LeFun SK2 {"NAME":"LeFun SK2","GPIO":[0,0,0,32,225,224,0,0,226,227,228,0,0,0],"FLAG":0,"BASE":18} +Lidl Silvercrest Zigbee {"NAME":"Lidl Silvercrest HG06338","GPIO":[0,288,0,0,225,226,0,0,32,224,576,0,0,0],"FLAG":0,"BASE":18} LITEdge Smart Power Strip {"NAME":"LITEEdge Power Strip","GPIO":[227,0,0,0,288,289,0,0,224,32,225,226,228,0],"FLAG":0,"BASE":18} Luminea 3AC+4USB 16A {"NAME":"Luminea-NX4473","GPIO":[0,320,0,32,225,224,0,0,0,226,227,0,0,0],"FLAG":0,"BASE":18} Maxcio ZLD-34EU-W {"NAME":"MAXCIO","GPIO":[0,320,0,32,225,224,0,0,0,226,227,0,0,4704],"FLAG":0,"BASE":18} Merkury Innovations Smart Surge {"NAME":"Merkury Power Strip MIC-SW002-199L","GPIO":[288,0,289,0,228,32,0,0,225,224,226,0,259,0],"FLAG":0,"BASE":18} Merkury Innovations SmartSurge {"NAME":"Merkury MI-SW001","GPIO":[288,0,289,0,228,32,0,0,225,224,226,0,227,0],"FLAG":0,"BASE":18} -Meross 4AC 4USB {"NAME":"HamaStrip","GPIO":[0,544,0,32,225,224,0,0,226,227,228,0,0,0],"FLAG":0,"BASE":18} +Meross 4AC 4USB {"NAME":"MSS425F","GPIO":[0,544,0,32,225,224,0,0,226,227,260,0,0,0],"FLAG":0,"BASE":18} Meross MSS425 {"NAME":"Meross MSS425","GPIO":[260,0,0,0,320,0,0,0,224,32,225,226,259,0],"FLAG":0,"BASE":18} Mirabella Genio 4 Outlet Power Board with 2 USB {"NAME":"Genio i002340","GPIO":[320,0,0,0,224,225,0,0,226,32,227,228,0,0],"FLAG":0,"BASE":18} Mirabella Genio Powerboard {"NAME":"Genio Powerboa","GPIO":[224,288,0,0,226,225,0,0,228,32,229,227,0,0],"FLAG":0,"BASE":18} Nedis P310 {"NAME":"Nedis WIFIP310","GPIO":[0,320,0,32,225,224,0,0,0,226,227,0,0,4704],"FLAG":0,"BASE":18} -Nous 15A 3AC 3USB {"NAME":"NOUS A5T","GPIO":[0,3072,544,3104,0,259,0,0,225,226,224,0,32,4704],"FLAG":0,"BASE":18} +Nous 15A 3AC 3USB {"NAME":"NOUS A5T","GPIO":[0,3072,544,3104,0,259,0,0,225,226,224,0,35,4704],"FLAG":1,"BASE":18} Nozdom 3AC+2USB {"NAME":"NOZDOM SWB3","GPIO":[544,0,289,0,0,226,0,0,224,32,225,227,0,0],"FLAG":0,"BASE":18} Pearl CHA1555 3AC 4USB {"NAME":"Pearl CHA1555","GPIO":[32,0,0,225,2720,2656,0,0,2624,227,226,224,320,0],"FLAG":0,"BASE":18} Powertech 4AC 2USB {"NAME":"Ptech MS6107","GPIO":[0,288,0,32,224,225,0,0,227,228,226,0,0,0],"FLAG":0,"BASE":18} @@ -1724,6 +1755,7 @@ Tellur 3AC 4USB {"NAME":"Tellur","GPIO":[0,320,0,32,225,224,0,0,0,2 Tessan {"NAME":"TESSAN A4L-BK","GPIO":[0,0,0,227,226,0,0,0,224,0,225,0,0,0],"FLAG":0,"BASE":18} Tonbux SM-SO301-U {"NAME":"Tonbux SM-SO30","GPIO":[320,0,0,0,256,0,0,0,258,257,259,0,228,0],"FLAG":0,"BASE":18} Useelink {"NAME":"Useelink","GPIO":[288,0,0,321,256,32,0,0,258,257,259,0,228,0],"FLAG":0,"BASE":18} +Useelink 4AC 2USB {"NAME":"306 Power Strip","GPIO":[576,0,576,291,259,32,0,0,257,258,256,0,228,0],"FLAG":0,"BASE":18} Vivitar HA-1007 {"NAME":"Vivitar HA-1007 Power Strip","GPIO":[544,0,0,0,227,228,0,0,225,224,226,0,35,1],"FLAG":0,"BASE":18} Vivitar HA-1007-AU {"NAME":"HA-1007-AU","GPIO":[320,32,0,322,256,321,0,0,258,257,259,0,228,0],"FLAG":0,"BASE":18} wesmartify essentials 3-socket 2 USB {"NAME":"Essentials Smart Home 3-socket USB Power Strip","GPIO":[0,0,0,0,544,226,0,0,224,32,225,0,0,0],"FLAG":0,"BASE":18} @@ -1733,6 +1765,7 @@ Wolf Armor 4AC 4USB {"NAME":"Wolf Armor SP26","GPIO":[0,320,0,32,227,22 WOOX Powerstrip EU {"NAME":"WOOX R5104","GPIO":[0,0,0,32,0,352,0,0,225,355,226,227,224,4896],"FLAG":0,"BASE":18} WOOX R4028 {"NAME":"WOOX R4028","GPIO":[0,320,0,32,226,225,0,0,0,227,224,0,0,4704],"FLAG":0,"BASE":18} WP40 {"NAME":"WP40","GPIO":[260,0,0,0,320,0,0,0,224,32,225,226,259,0],"FLAG":0,"BASE":18} +Xenon {"NAME":"SM-SO306I1","GPIO":[0,0,0,0,256,32,0,0,258,257,259,0,228,0],"FLAG":0,"BASE":18} Xenon SM-S0301 {"NAME":"SM-SO301","GPIO":[288,1,1,321,256,32,0,0,258,257,259,1,228,0],"FLAG":0,"BASE":18} Xenon SM-S0301-U {"NAME":"SM-SO301-U","GPIO":[288,1,1,321,256,32,0,0,258,257,259,1,228,0],"FLAG":0,"BASE":18} Xenon SM-SO301 v2 {"NAME":"SM-SO301","GPIO":[320,0,0,0,257,32,0,0,259,258,260,0,224,0],"FLAG":0,"BASE":18} @@ -1743,6 +1776,7 @@ XS-A34 {"NAME":"XS-A24","GPIO":[288,0,289,0,228,225,0,0,22 Yagala {"NAME":"Yagala","GPIO":[288,1,1,321,256,32,0,0,258,257,259,1,228,0],"FLAG":0,"BASE":18} Yagala SWB3 {"NAME":"YAGALA SWB3","GPIO":[544,0,289,0,0,226,0,0,224,32,225,227,0,0],"FLAG":0,"BASE":18} Yagala Z1 {"NAME":"YAGALA Z1","GPIO":[0,544,0,32,225,227,0,0,226,228,224,0,0,0],"FLAG":0,"BASE":18} +YPS11 {"NAME":"SM-SO301","GPIO":[320,0,0,0,257,32,0,0,259,258,260,0,224,0],"FLAG":0,"BASE":18} Yuanguo 4AC+2USB {"NAME":"YUANGUO","GPIO":[164,35,0,227,34,33,0,0,32,225,224,226,544,0],"FLAG":0,"BASE":1} Zeoota 4AC 2USB {"NAME":"Zeoota WP30","GPIO":[0,32,0,227,0,0,0,0,0,225,224,226,0,4896],"FLAG":0,"BASE":18} Zeoota PS022 {"NAME":"ZEOOTA 3x plus","GPIO":[0,321,0,320,225,224,0,0,32,226,227,0,0,4704],"FLAG":0,"BASE":18} @@ -1863,9 +1897,12 @@ iQtech 9W 800lm {"NAME":"iQ-Tech RGBCCT 9W 800LM","GPIO":[0,0,0,0,4 Jeeo TF-QPZ13 800lm {"NAME":"Jeeo","GPIO":[0,0,0,0,2912,416,0,0,417,2976,2944,0,0,0],"FLAG":0,"BASE":18} Julun JL-021 5W Candle {"NAME":"E14 RGBCCT","GPIO":[0,0,0,0,419,420,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} Kauf esphome 10W {"NAME":"Kauf Bulb","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} +Kauf esphome A15 5W {"NAME":"Kauf Bulb","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} +Kauf esphome A19 7W {"NAME":"Kauf Bulb","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} KHSUIN BR30 13W 1300lm {"NAME":"KHSUIN 13W BR30","GPIO":[0,0,0,0,416,420,0,0,417,419,418,0,0,0],"FLAG":0,"BASE":18} Kogan 10W 1050lm {"NAME":"Kogan RGB+CCT","GPIO":[1,1,1,0,416,419,1,1,417,452,418,1,1,1],"FLAG":0,"BASE":18} Kohree 600lm {"NAME":"Kohree VHP560","GPIO":[0,0,0,0,416,420,0,0,417,419,418,0,0,0],"FLAG":0,"BASE":18} +LangPlus+ A60 7W {"NAME":"LangPlus+ A60 7W","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Lasco 9W 700lm {"NAME":"Lasco 7W","GPIO":[0,0,0,0,2912,416,0,0,0,0,2944,0,0,0],"FLAG":0,"BASE":1} Laser 10W 1000lm {"NAME":"LSH-E27RGB10W","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Laser 5W 460lm {"NAME":"LSH-E14RGB5W","GPIO":[0,0,0,0,419,420,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} @@ -1953,6 +1990,7 @@ Teckin SB50 v3 A19 800lm {"NAME":"Teckin SB50v3","GPIO":[0,0,0,0,416,419,0,0 Teckin SB53 1300lm {"NAME":"Teckin SB53","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Treatlife A19 8W 650lm {"NAME":"Treatlife RGBW","GPIO":[0,0,0,0,417,416,0,0,420,418,419,0,0,0],"FLAG":0,"BASE":18} V-TAC 10W 806lm {"NAME":"V-TAC VT-5119","GPIO":[0,0,0,0,4032,0,0,0,0,0,4064,0,0,0],"FLAG":0,"BASE":18} +V-Tac A60 10W 806lm {"NAME":"V-Tac A60","GPIO":[0,0,0,0,416,417,0,0,418,419,420,0,0,0],"FLAG":0,"BASE":18,"CMND":"SetOption37 13"} V-Tac PAR16 4.5W 400lm 100 {"NAME":"V-TAC VT5164","GPIO":[0,0,0,0,0,0,0,0,4064,0,4032,0,0,0],"FLAG":0,"BASE":18} Vizia 5W GU10 {"NAME":"Vizia RGBWW","GPIO":[0,0,0,0,419,420,0,0,417,418,416,0,0,1],"FLAG":0,"BASE":18} WdtPro 8W 800lm {"NAME":"WdtPro","GPIO":[0,0,0,0,419,420,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} @@ -2111,6 +2149,7 @@ Nedis 6W 470lm {"NAME":"nedis Bulb","GPIO":[0,0,0,0,416,419,0,0,41 Nedis A60 800lm {"NAME":"Nedis RGBW","GPIO":[0,0,0,0,2912,416,0,0,0,2976,2944,0,0,4704],"FLAG":0,"BASE":18} Nedis C10 350lm {"NAME":"Nedis WIFILC10","GPIO":[0,0,0,0,418,416,0,0,419,417,420,0,0,4704],"FLAG":0,"BASE":18} Nedis PAR16 330lm {"NAME":"Nedis GU10","GPIO":[0,0,0,0,418,416,0,0,419,417,420,0,0,0],"FLAG":0,"BASE":18} +NGteco {"NAME":"NGTECO L100","GPIO":[0,0,0,0,0,418,0,0,417,0,416,419,0,0],"FLAG":0,"BASE":18} Novostella UT55506 10W 1050lm {"NAME":"Novostella 10W","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Onforu 7W 700lm {"NAME":"Onforu RGBW","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Orbecco 5W 400lm {"NAME":"Orbecco Bulb","GPIO":[0,0,0,0,0,0,0,0,3008,0,3040,0,0,0],"FLAG":0,"BASE":27} @@ -2142,6 +2181,7 @@ Teckin 7.5W 800lm {"NAME":"Teckin SB60","GPIO":[0,0,0,0,416,419,0,0,4 Teckin SB50 800lm {"NAME":"Teckin SB50","GPIO":[0,0,0,0,419,0,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} Teckin SB50 v2 800lm {"NAME":"Teckin SB50","GPIO":[0,0,0,0,416,0,0,0,417,419,418,0,0,0],"FLAG":0,"BASE":18} Teckin SB51 800lm {"NAME":"Teckin SB51","GPIO":[0,0,0,0,419,0,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} +TH3D EZBulb V1 {"NAME":"EZBulb V1","GPIO":[0,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18} TikLOk TL530 A19 7.5W 800lm {"NAME":"TikLOk WW-CW-L","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18} TVLive 7.5W 800lm {"NAME":"TVLIVE RGBCW","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Utorch LE7 600lm {"NAME":"Utorch LE7","GPIO":[0,0,0,0,0,417,0,0,418,0,419,416,0,0],"FLAG":0,"BASE":18} @@ -2202,9 +2242,18 @@ Ewelink RF No Neutral 3 Channel {"NAME":"Ewelink 3 Gang Module","GPIO":[32,0,0, Geekcreit 5V DIY 4 Channel Jog Inching Self-Locking {"NAME":"Geekcreit-4ch","GPIO":[160,0,0,0,226,225,161,162,224,288,163,227,0,0],"FLAG":0,"BASE":18} Geekcreit Module 220V 10A {"NAME":"DIY ESP8266 Re","GPIO":[0,0,544,0,224,32,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} HW-622 ESP8266 {"NAME":"HW-622","GPIO":[0,0,544,0,224,32,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Kincony 16 Channel {"NAME":"KC868-A16 rev 1.4","GPIO":[32,1,1,1,640,608,1,1,1,1,1,1,1,1,5600,1,0,1,1,5568,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} -Kincony 8 Channel {"NAME":"KC868-A8","GPIO":[32,0,1120,0,640,608,0,0,0,1,1,1152,0,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,1],"FLAG":0,"BASE":1,"CMND":"EthClockMode 3 | EthAddress 0 | EthType 0 | I2CDriver2 1"} -Kincony IR+RF 4 Channel {"NAME":"KC868-A4","GPIO":[32,0,227,0,224,225,0,0,0,1312,1,226,0,0,480,1152,0,1120,1056,1088,0,1,1,1,0,0,0,0,4706,4707,4704,4705,1,0,0,1],"FLAG":0,"BASE":1} +KinCony 16 Channel {"NAME":"KC868-A16 rev 1.4","GPIO":[32,1,1,1,640,608,1,1,1,1,1,1,1,1,5600,1,0,1,1,5568,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} +KinCony 32 Channel MOSFET {"NAME":"KC868-A32M","GPIO":[0,1,0,1,640,608,1,1,1,3200,1152,3232,1088,1,5600,0,0,1,0,5568,0,1,0,0,0,0,0,0,0,0,4704,4705,4707,0,0,4706],"FLAG":0,"BASE":1} +KinCony 6 Channel {"NAME":"KC868-A6","GPIO":[0,1,0,1,640,768,1,1,1,1,3232,608,0,1,736,672,0,1,0,704,0,1,0,3200,0,0,0,0,1312,1184,4706,4707,4704,0,0,4705],"FLAG":0,"BASE":1} +KinCony 8 Channel {"NAME":"KC868-A8","GPIO":[32,0,1120,0,640,608,0,0,0,1,1,1152,0,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,1],"FLAG":0,"BASE":1,"CMND":"EthClockMode 3 | EthAddress 0 | EthType 0 | I2CDriver2 1"} +KinCony ESP32 4G 2 Channel {"NAME":"KC868-A2","GPIO":[0,1,225,1,640,0,1,1,1,1,1184,224,608,1,5600,0,0,1,0,5568,0,1,0,0,0,0,0,0,3200,1312,1,3232,160,0,0,161],"FLAG":0,"BASE":1} +KinCony ESP32 Ethernet RS485 4G GSM {"NAME":"KC868-A8S","GPIO":[1,1,480,1,640,608,1,1,1376,1,1312,1,1152,1,5600,1,0,1,1,5568,0,1,1,1,0,0,0,0,3232,3200,1,1,1,0,0,1],"FLAG":0,"BASE":1} +KinCony ESP32 SD Card DS3231 RTC Sensor {"NAME":"KC868-ASR","GPIO":[32,1,1,1,0,225,1,1,1,1,1,0,0,1,480,224,0,1,289,288,0,1,640,608,0,0,0,0,1312,1184,1,0,1,0,0,1],"FLAG":0,"BASE":1} +KinCony Ethernet 16 Channel {"NAME":"KC868-A16S","GPIO":[0,1,0,1,640,608,1,1,1,0,0,0,1152,1,5600,0,0,1,0,5568,0,1,0,0,0,0,0,0,3232,3200,4705,4706,4704,0,0,4707],"FLAG":0,"BASE":1} +KinCony Ethernet 32 Channel {"NAME":"KC868-A32","GPIO":[0,1,0,1,641,609,1,1,1,608,3200,640,3232,1,5600,0,0,1,0,5568,0,1,0,0,0,0,0,0,0,0,4705,4707,4706,0,0,4704],"FLAG":0,"BASE":1} +KinCony Ethernet CAN Bus 8 Channel {"NAME":"KC868-A8M","GPIO":[0,1,0,1,640,608,1,1,1,3200,1312,3232,1152,1,5600,0,0,1,0,5568,0,1,0,0,0,0,0,0,0,0,4704,4705,4706,0,0,4707],"FLAG":0,"BASE":1} +KinCony GSM 4 Channel {"NAME":"KC868-A4S","GPIO":[0,1,0,1,640,1312,1,1,1,1,1184,0,608,1,5600,0,0,1,0,5568,0,1,0,0,0,0,0,0,3200,3232,1,0,4704,4705,4706,4707],"FLAG":0,"BASE":1} +KinCony IR+RF 4 Channel {"NAME":"KC868-A4","GPIO":[32,0,227,0,224,225,0,0,0,1312,1,226,0,0,480,1152,0,1120,1056,1088,0,1,1,1,0,0,0,0,4706,4707,4704,4705,1,0,0,1],"FLAG":0,"BASE":1} KRIDA 4 Channel 10A Electromagnetic {"NAME":"4CH Relay","GPIO":[0,0,0,0,0,0,0,0,226,225,227,224,0,0],"FLAG":0,"BASE":18} KRIDA 8 Channel 10A Electromagnetic {"NAME":"8CH Relay","GPIO":[230,1,231,229,1,1,1,1,226,225,227,224,228,1],"FLAG":0,"BASE":18} LC Technology 12V 4 Channel {"NAME":"LC Technology 4CH Relay","GPIO":[224,0,225,0,226,227,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} @@ -2324,6 +2373,7 @@ CloudFree Light {"NAME":"CloudFree SW1","GPIO":[32,1,0,1,0,0,0,0,22 CloudFree Motion Light {"NAME":"CloudFree SWM1","GPIO":[32,0,0,0,0,160,0,0,224,576,161,0,0,0],"FLAG":0,"BASE":18} Connect SmartHome 2 Gang Wall {"NAME":"CSH-SWTCH2","GPIO":[0,0,288,0,0,33,0,0,225,224,0,0,32,0],"FLAG":0,"BASE":18} Connect SmartHome 3 Gang Wall Switch () {"NAME":"CSH-SWTCH3","GPIO":[0,0,288,0,34,33,0,0,225,224,226,0,32,0],"FLAG":0,"BASE":18} +Csmart US-B2 {"NAME":"Csmart US-B2","GPIO":[0,544,0,33,32,0,0,0,0,225,224,0,0,0],"FLAG":0,"BASE":18} Delock WLAN EASY-USB {"NAME":"Delock 11828","GPIO":[0,0,0,32,0,0,0,0,0,576,224,0,0,0],"FLAG":0,"BASE":53} Deta 1 Gang {"NAME":"Deta 1G Switch","GPIO":[0,0,0,0,544,0,0,0,0,224,0,0,64,0],"FLAG":0,"BASE":18} Deta 2 Gang {"NAME":"DETA 2G Switch","GPIO":[0,0,0,0,544,0,0,0,65,224,225,0,64,0],"FLAG":0,"BASE":18} @@ -2374,6 +2424,7 @@ Gosund Single Pole {"NAME":"Gosund SW5","GPIO":[32,0,320,0,0,0,0,0,0,0 Gosund SW6 3-Way {"NAME":"Gosund SW6","GPIO":[161,0,320,0,160,0,0,0,0,226,225,224,576,0],"FLAG":0,"BASE":18} Hama Flush-mounted 2 Gang {"NAME":"Hama WiFiTouch","GPIO":[544,0,0,0,0,33,0,0,32,225,0,224,0,0],"FLAG":0,"BASE":45} HBN Wall-Mounted Timer {"NAME":"HBN Timer Switch","GPIO":[0,0,0,0,290,321,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} +Hidin US Light {"NAME":"Hidin MFA03","GPIO":[32,0,0,0,288,0,0,0,224,544,0,0,0,0],"FLAG":0,"BASE":18} Innens 1 Gang 1 Way {"NAME":"Innens 1 Gang 1 Way","GPIO":[0,0,0,32,224,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18} Innens RF433 2 Gang 1 Way {"NAME":"Innens Light Switch 2G","GPIO":[0,0,289,0,0,33,0,0,32,225,0,224,0,0],"FLAG":0,"BASE":18} Jinvoo SM-SW101-1 {"NAME":"SM-SW101-1","GPIO":[288,0,0,33,0,0,0,0,32,224,0,0,0,4704],"FLAG":0,"BASE":18} @@ -2479,6 +2530,7 @@ Q-touch 1 Gang {"NAME":"Qtouch","GPIO":[289,0,0,32,0,0,0,0,224,0,0 Q-touch 433MHz 1 Gang {"NAME":"Qtouch 1G","GPIO":[32,0,0,0,0,0,0,0,224,288,0,0,0,0],"FLAG":0,"BASE":18} Q-touch 433MHz 1 Gang No Neutral {"NAME":"QWP_W1_WIFI-TOUCH","GPIO":[32,1,1,1,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":28} Q-touch 433MHz 2 Gang No Neutral {"NAME":"QWP_W2_WIFI-TOUCH","GPIO":[32,1,1,1,0,225,33,0,224,320,0,0,0,0],"FLAG":0,"BASE":29} +QNCX Smart Breaker {"NAME":"QNCX Smart breaker","GPIO":[0,0,0,0,160,224,0,0,0,320,0,0,0,0],"FLAG":0,"BASE":18} Qualitel 1 Gang {"NAME":"Qualitel 1 Gang","GPIO":[544,0,0,160,224,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18} Qualitel 2-Gang {"NAME":"Qualitel 2 Gang","GPIO":[544,0,289,0,0,161,0,0,160,224,0,225,288,0],"FLAG":0,"BASE":18} Qualitel 3 Gang {"NAME":"Qualitel 3 Gang","GPIO":[544,0,290,161,225,162,0,0,160,224,289,226,288,0],"FLAG":0,"BASE":18} @@ -2499,6 +2551,7 @@ Shawader 3Ch Touch Light {"NAME":"ShawaderTuya3C","GPIO":[0,3872,0,66,64,65, SK-A801-01-US 1 Gang {"NAME":"jsankou US Switch 1 Gang","GPIO":[544,0,0,0,0,0,0,0,32,256,0,0,0,0],"FLAG":0,"BASE":18} SK-W803-01-US 3 Gang {"NAME":"jsankou US Switch 3 Gang","GPIO":[544,0,0,33,257,34,0,0,32,256,0,258,0,0],"FLAG":0,"BASE":18} Smart 3 Gang Touch {"NAME":"ETERSKY KS601 3 Gang","GPIO":[0,0,544,0,34,33,0,0,225,224,226,0,32,0],"FLAG":0,"BASE":18} +Smart 3 in 1 Wall {"NAME":"SW02-03","GPIO":[320,1,1,34,226,33,0,0,32,224,321,225,322,544],"FLAG":0,"BASE":18} SmartGrade {"NAME":"SmartGrade AC 5005","GPIO":[0,0,0,32,2688,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":18} Smartlife Opard CD302 {"NAME":"CD302","GPIO":[0,0,0,0,288,321,0,0,256,32,0,0,0,0],"FLAG":0,"BASE":18} SmartPlex 3 Gang {"NAME":"Tuya 3 Channel","GPIO":[1,1,1,1,224,33,0,0,34,226,32,225,1,0],"FLAG":0,"BASE":18} @@ -2538,6 +2591,9 @@ Sonoff TX T3 EU 2 Gang {"NAME":"Sonoff T3 TX 2CH","GPIO":[32,1,1,1,0,225,3 Sonoff TX T3 EU 3 Gang {"NAME":"TX T3EU3C","GPIO":[32,1,0,1,226,225,33,34,224,576,0,0,0,0],"FLAG":0,"BASE":30} Sonoff TX T3 US 3 Gang {"NAME":"TX T3US3C","GPIO":[32,1,0,1,226,225,33,34,224,576,0,0,0,0],"FLAG":0,"BASE":30} Sonoff TX T4 EU No Neutral 1 Gang {"NAME":"Sonoff T4 1CH","GPIO":[32,1,1,1,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":28} +Sonoff TX Ultimate 1 Gang {"NAME":"TX Ultimate 1","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,0,224,3232,0,480,3200,0,0,0,3840,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Backlog Pixels 28"} +Sonoff TX Ultimate 2 Gang {"NAME":"TX Ultimate 2","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,225,224,3232,0,480,3200,0,0,0,3840,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Backlog Pixels 28"} +Sonoff TX Ultimate 3 Gang {"NAME":"TX Ultimate 3","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,225,224,3232,0,480,3200,0,0,0,3840,226,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Backlog Pixels 28"} SPC Hera {"NAME":"SPC HERA","GPIO":[544,0,0,32,224,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18} SRL 2 Gang {"NAME":"SRL 4WW Switch","GPIO":[0,0,0,0,0,33,0,0,32,224,0,225,0,0],"FLAG":0,"BASE":18} SRL 4 Gang {"NAME":"SRL 4WW Switch","GPIO":[0,0,0,34,226,33,0,0,32,224,227,225,35,0],"FLAG":0,"BASE":18} @@ -2642,13 +2698,16 @@ LoraTap RR500W {"NAME":"LoraTap RR500W","GPIO":[544,0,0,0,160,0,0, LoveAnna AC85-250V 10A {"NAME":"2xSwitch No RF LoveAnna","GPIO":[32,0,0,0,0,225,33,0,224,320,0,0,0,0],"FLAG":0,"BASE":18} Luani HVIO {"NAME":"Luani HVIO","GPIO":[0,1,1,1,224,225,0,0,160,161,1,288,0,4704],"FLAG":0,"BASE":35} Luminea {"NAME":"Luminea NX-4651","GPIO":[0,0,0,0,288,0,0,0,160,224,0,0,0,0],"FLAG":0,"BASE":18} +MHCOZY DC 7-32V {"NAME":"MHCOZY RF 1CH","GPIO":[32,0,0,0,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":18} Milfra Smart {"NAME":"Milfra Smart Module TB41","GPIO":[576,0,0,225,2688,2656,0,0,2592,193,480,224,192,0],"FLAG":0,"BASE":18} Mini Smart Switch {"NAME":"SmartSwitch-MK601","GPIO":[0,0,0,160,32,224,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18} Moes {"NAME":"Moes MS-104B","GPIO":[0,0,32,0,480,0,0,0,161,160,224,225,0,0],"FLAG":0,"BASE":18} Moes 10A {"NAME":"Moes MS-101","GPIO":[0,0,0,0,0,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Moes Mini 3 Gang 1/2 Way {"NAME":"Moes MS-104C","GPIO":[0,0,0,34,32,33,0,0,224,225,226,0,0,0],"FLAG":0,"BASE":18} Nedis 10A {"NAME":"Nedis WIFIPS10WT","GPIO":[0,0,0,0,224,0,0,0,32,321,0,288,0,0],"FLAG":0,"BASE":18} +Nous 1 Channel Touch {"NAME":"NOUS L1T","GPIO":[544,0,1,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1} Nous 1/2 Channel {"NAME":"NOUS L13T Smart Switch Module","GPIO":[1,161,1,160,225,224,1,1,544,1,32,1,1,1],"FLAG":0,"BASE":18} +Nous 2 Channel Touch {"NAME":"NOUS L2T","GPIO":[544,289,1,32,225,33,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1} Nova Digital Basic 1 MS101 {"NAME":"NovaDigBasic1","GPIO":[0,1,0,1,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} PPA Contatto Wi-Fi {"NAME":"PPA Contatto","GPIO":[0,0,32,0,224,162,0,0,288,225,0,0,0,0],"FLAG":0,"BASE":18} PS-1604 16A {"NAME":"PS-1604 16A","GPIO":[32,1,1,1,1,0,0,0,224,320,1,0,0,0],"FLAG":0,"BASE":1} @@ -2747,6 +2806,7 @@ Tuya Gas/Water {"NAME":"Valve FM101","GPIO":[320,0,0,0,224,0,0,0,0 Aigostar P40 {"NAME":"Aigostar 8433325212278","GPIO":[0,0,0,0,544,288,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Aseer THWFS01 {"NAME":"ASEER-THWFS01","GPIO":[320,33,544,323,2720,2656,0,0,2624,225,321,224,32,0],"FLAG":0,"BASE":18} Athom {"NAME":"Athom SK01","GPIO":[0,0,0,3104,0,32,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":18} +Athom 16A UK {"NAME":"Athom SK03-TAS","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18} Bestten LO-2-W {"NAME":"BESTTEN LO-2-W","GPIO":[0,0,0,0,576,32,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":18} BingoElec 16A {"NAME":"BingoElecPower","GPIO":[0,0,0,0,288,289,1,1,224,32,0,0,1,1],"FLAG":0,"BASE":18} BlitzWolf SHP8 {"NAME":"SHP8","GPIO":[0,320,0,32,2720,2656,0,0,2624,289,224,0,0,0],"FLAG":0,"BASE":64} @@ -2777,11 +2837,13 @@ Milfra UK Double USB Chager Twin {"NAME":"Milfra TBU02","GPIO":[0,0,0,0,288,33, Moes 16A {"NAME":"WK-EU(FR/UK)16M","GPIO":[0,288,0,32,2720,2656,0,0,2624,224,0,0,0,0],"FLAG":0,"BASE":18} Moes WWK Glass Panel {"NAME":"Smart Socket","GPIO":[0,0,0,0,288,289,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Oittm 120 {"NAME":"Oittm WS01","GPIO":[32,0,0,0,0,2592,0,0,224,2656,2688,288,0,0],"FLAG":0,"BASE":18} +PFS Presa Smart {"NAME":"PFS_PresaSmart","GPIO":[1,1,1,1,288,289,1,1,224,32,0,1,1,1],"FLAG":0,"BASE":18} PS-1607 {"NAME":"PS-1607","GPIO":[32,0,0,0,0,225,33,0,224,0,0,0,0,0],"FLAG":0,"BASE":18} Smanergy KA10 {"NAME":"KA10","GPIO":[0,320,0,32,2720,2656,0,0,2624,289,224,0,0,0],"FLAG":0,"BASE":64} Sonoff IW100 {"NAME":"Sonoff IW100","GPIO":[32,3072,0,3104,0,0,0,0,224,544,0,0,0,0],"FLAG":0,"BASE":41} Sonoff S55 {"NAME":"Sonoff S55","GPIO":[32,1,0,1,1,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":1} Steren Dual Plug and USB Charger {"NAME":"Steren_SHOME-118","GPIO":[0,576,0,32,33,288,0,0,224,225,289,0,0,0],"FLAG":0,"BASE":18} +Steren Dual Plug and USB Charger Wall Outlet (SHOME-118) {"NAME":"Steren_SHOME-118","GPIO":[576,0,0,32,320,33,0,0,225,224,321,226,0,0],"FLAG":0,"BASE":18} T16E Dual USB 10A {"NAME":"T16E 10A","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18} TCP Smart Dual {"NAME":"TCP TAUWIS2GUK","GPIO":[33,0,0,0,0,224,32,0,225,544,0,0,0,0],"FLAG":0,"BASE":18} Teckin SR40 {"NAME":"RF-SR40-US","GPIO":[576,0,0,32,320,33,0,0,225,224,321,226,0,0],"FLAG":0,"BASE":18} diff --git a/boards/esp32c2.json b/boards/esp32c2.json new file mode 100644 index 000000000000..563a3357c15f --- /dev/null +++ b/boards/esp32c2.json @@ -0,0 +1,44 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32c2_out.ld" + }, + "core": "esp32", + "extra_flags": "-DESP32_4M -DESP32C2", + "f_cpu": "120000000L", + "f_flash": "60000000L", + "flash_mode": "dio", + "mcu": "esp32c2", + "variant": "esp32c2", + "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "openocd_target": "esp32c2.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif Generic ESP32-C2 = 4M Flash", + "upload": { + "arduino": { + "flash_extra_images": [ + [ + "0x10000", + "variants/tasmota/tasmota32c2-safeboot.bin" + ] + ] + }, + "flash_size": "4MB", + "maximum_ram_size": 278528, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32c6/esp32-c6-devkitc-1/index.html", + "vendor": "Espressif" + } diff --git a/boards/esp32c2_2M.json b/boards/esp32c2_2M.json new file mode 100644 index 000000000000..36f16ffe3432 --- /dev/null +++ b/boards/esp32c2_2M.json @@ -0,0 +1,44 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32c2_out.ld" + }, + "core": "esp32", + "extra_flags": "-DESP32_2M -DESP32C2", + "f_cpu": "120000000L", + "f_flash": "60000000L", + "flash_mode": "dio", + "mcu": "esp32c2", + "variant": "esp32c2", + "partitions": "partitions/esp32_partition_app1245k_fs64k.csv" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "openocd_target": "esp32c2.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif Generic ESP32-C2 = 2M Flash, Tasmota 1245kB Code/OTA, 64k FS", + "upload": { + "arduino": { + "flash_extra_images": [ + [ + "0x10000", + "variants/tasmota/tasmota32c2-safeboot.bin" + ] + ] + }, + "flash_size": "2MB", + "maximum_ram_size": 278528, + "maximum_size": 2097152, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32c6/esp32-c6-devkitc-1/index.html", + "vendor": "Espressif" + } diff --git a/boards/esp32c6.json b/boards/esp32c6.json new file mode 100644 index 000000000000..57dd9b8f4d91 --- /dev/null +++ b/boards/esp32c6.json @@ -0,0 +1,44 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32c6_out.ld" + }, + "core": "esp32", + "extra_flags": "-DESP32_4M -DESP32C6", + "f_cpu": "160000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "mcu": "esp32c6", + "variant": "esp32c6", + "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "openocd_target": "esp32c6.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif Generic ESP32-C6 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS", + "upload": { + "arduino": { + "flash_extra_images": [ + [ + "0x10000", + "variants/tasmota/tasmota32c6-safeboot.bin" + ] + ] + }, + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32c6/esp32-c6-devkitc-1/index.html", + "vendor": "Espressif" + } diff --git a/boards/esp32c6cdc.json b/boards/esp32c6cdc.json new file mode 100644 index 000000000000..17932b7a83bf --- /dev/null +++ b/boards/esp32c6cdc.json @@ -0,0 +1,45 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32c6_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_USB_MODE=1 -DESP32_4M -DESP32C6 -DUSE_USB_CDC_CONSOLE", + "f_cpu": "160000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "mcu": "esp32c6", + "variant": "esp32c6", + "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "openocd_target": "esp32c6.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif Generic ESP32-C6 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS", + "upload": { + "arduino": { + "flash_extra_images": [ + [ + "0x10000", + "variants/tasmota/tasmota32c6cdc-safeboot.bin" + ] + ] + }, + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "before_reset": "usb_reset", + "speed": 460800 + }, + "url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32c6/esp32-c6-devkitc-1/index.html", + "vendor": "Espressif" + } diff --git a/include/esp32x_fixes.h b/include/esp32x_fixes.h index a9f963d428ed..13860477a034 100644 --- a/include/esp32x_fixes.h +++ b/include/esp32x_fixes.h @@ -68,10 +68,28 @@ #define SPI_HOST SPI1_HOST #define HSPI_HOST SPI2_HOST #define VSPI_HOST SPI2_HOST /* No SPI3_host on C3 */ +#if ESP_IDF_VERSION_MAJOR < 5 // fix a bug in esp-idf 4.4 for esp32c3 #ifndef REG_SPI_BASE #define REG_SPI_BASE(i) (DR_REG_SPI1_BASE + (((i)>1) ? (((i)* 0x1000) + 0x20000) : (((~(i)) & 1)* 0x1000 ))) // SPI_MOSI_DLEN_REG is not defined anymore in esp32c3, instead use SPI_MS_DLEN_REG #define SPI_MOSI_DLEN_REG(x) SPI_MS_DLEN_REG(x) #endif // REG_SPI_BASE +#endif //ESP_IDF_VERSION_MAJOR < 5 + +#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 +#define SPI_HOST SPI1_HOST +#define HSPI_HOST SPI1_HOST /* No SPI2_host on C2/C6 */ +#define VSPI_HOST SPI1_HOST /* No SPI3_host on C2/C6 */ +#define VSPI SPI +// #if ESP_IDF_VERSION_MAJOR < 5 +// // fix a bug in esp-idf 4.4 for esp32c3 +// #ifndef REG_SPI_BASE +// #define REG_SPI_BASE(i) (DR_REG_SPI1_BASE + (((i)>1) ? (((i)* 0x1000) + 0x20000) : (((~(i)) & 1)* 0x1000 ))) +// // SPI_MOSI_DLEN_REG is not defined anymore in esp32c3, instead use SPI_MS_DLEN_REG +#define SPI_MOSI_DLEN_REG(x) SPI_MS_DLEN_REG(x) +// #endif // REG_SPI_BASE +// #endif //ESP_IDF_VERSION_MAJOR < 5 + + #endif // TARGET diff --git a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp index 18cfee1e08f2..9bdfb9733e71 100644 --- a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp @@ -39,6 +39,8 @@ TasmotaSerial *tms_obj_list[16]; #ifdef ESP32 #include "driver/uart.h" +#include "driver/gpio.h" +#include "esp_rom_gpio.h" static uint32_t tasmota_serial_uart_bitmap = 0; // Assigned UARTs @@ -466,6 +468,7 @@ size_t TasmotaSerial::write(uint8_t b) { return size; } +#ifdef ESP8266 void IRAM_ATTR TasmotaSerial::rxRead(void) { if (!m_nwmode) { uint32_t start = ESP.getCycleCount(); @@ -586,3 +589,4 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { } } } +#endif // ESP8266 diff --git a/lib/lib_audio/ESP8266Audio/src/AudioOutputI2S.cpp b/lib/lib_audio/ESP8266Audio/src/AudioOutputI2S.cpp index b18f9ae39ba5..36c14da665b8 100755 --- a/lib/lib_audio/ESP8266Audio/src/AudioOutputI2S.cpp +++ b/lib/lib_audio/ESP8266Audio/src/AudioOutputI2S.cpp @@ -19,6 +19,7 @@ */ #include +#if ESP_IDF_VERSION_MAJOR < 5 // TODO Arduino 3.0 Port I2S #ifdef ESP32 #include "driver/i2s.h" #elif defined(ARDUINO_ARCH_RP2040) || ARDUINO_ESP8266_MAJOR >= 3 @@ -374,3 +375,4 @@ bool AudioOutputI2S::stop() i2sOn = false; return true; } +#endif // TODO Arduino 3.0 Port I2S \ No newline at end of file diff --git a/lib/lib_audio/ESP8266Audio/src/AudioOutputI2SNoDAC.cpp b/lib/lib_audio/ESP8266Audio/src/AudioOutputI2SNoDAC.cpp index 976d73c77f1f..571e7e636faa 100644 --- a/lib/lib_audio/ESP8266Audio/src/AudioOutputI2SNoDAC.cpp +++ b/lib/lib_audio/ESP8266Audio/src/AudioOutputI2SNoDAC.cpp @@ -19,6 +19,7 @@ */ #include +#if ESP_IDF_VERSION_MAJOR < 5 // TODO Arduino 3.0 Port I2S #ifdef ESP32 #include "driver/i2s.h" #elif defined(ARDUINO_ARCH_RP2040) || ARDUINO_ESP8266_MAJOR >= 3 @@ -119,3 +120,4 @@ bool AudioOutputI2SNoDAC::ConsumeSample(int16_t sample[2]) #endif return true; } +#endif // ESP_IDF_VERSION_MAJOR < 5 // TODO Arduino 3.0 Port I2S \ No newline at end of file diff --git a/lib/lib_audio/ESP8266Audio/src/AudioOutputSPDIF.cpp b/lib/lib_audio/ESP8266Audio/src/AudioOutputSPDIF.cpp index 6e1cf1978b13..19074d1c57ad 100644 --- a/lib/lib_audio/ESP8266Audio/src/AudioOutputSPDIF.cpp +++ b/lib/lib_audio/ESP8266Audio/src/AudioOutputSPDIF.cpp @@ -37,9 +37,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ + #if defined(ESP32) || defined(ESP8266) #include +#if ESP_IDF_VERSION_MAJOR < 5 // TODO Arduino 3.0 Port I2S #if defined(ESP32) #include "driver/i2s.h" #include "soc/rtc.h" @@ -293,3 +295,4 @@ bool AudioOutputSPDIF::stop() } #endif +#endif // ESP_IDF_VERSION_MAJOR < 5 // TODO Arduino 3.0 Port I2S \ No newline at end of file diff --git a/lib/lib_audio/ESP8266Audio/src/AudioOutputULP.cpp b/lib/lib_audio/ESP8266Audio/src/AudioOutputULP.cpp index a6f8773d2a7d..60ac31bf3dc1 100644 --- a/lib/lib_audio/ESP8266Audio/src/AudioOutputULP.cpp +++ b/lib/lib_audio/ESP8266Audio/src/AudioOutputULP.cpp @@ -18,6 +18,9 @@ along with this program. If not, see . */ +#include +#if ESP_IDF_VERSION_MAJOR < 5 // TODO Arduino 3.0 Port I2S + #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 #include "AudioOutputULP.h" @@ -260,3 +263,4 @@ bool AudioOutputULP::stop() } #endif +#endif // ESP_IDF_VERSION_MAJOR < 5 // TODO Arduino 3.0 Port I2S \ No newline at end of file diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README.md b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README.md index 47178861a86d..5eac39e4b86b 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README.md +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README.md @@ -10,8 +10,8 @@ This library enables you to **send _and_ receive** infra-red signals on an [ESP8266](https://github.com/esp8266/Arduino) or an [ESP32](https://github.com/espressif/arduino-esp32) using the [Arduino framework](https://www.arduino.cc/) using common 940nm IR LEDs and common IR receiver modules. e.g. TSOP{17,22,24,36,38,44,48}* demodulators etc. -## v2.8.5 Now Available -Version 2.8.5 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes. +## v2.8.6 Now Available +Version 2.8.6 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes. #### Upgrading from pre-v2.0 Usage of the library has been slightly changed in v2.0. You will need to change your usage to work with v2.0 and beyond. You can read more about the changes required on our [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page. diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README_de.md b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README_de.md index f558605284f8..9e584bb84b6f 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README_de.md +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README_de.md @@ -11,8 +11,8 @@ Diese Programmbibliothek ermöglicht das **Senden _und_ Empfangen** von Infrarotsignalen mit [ESP8266](https://github.com/esp8266/Arduino)- und [ESP32](https://github.com/espressif/arduino-esp32)-Mikrocontrollern mithilfe des [Arduino-Frameworks](https://www.arduino.cc/) und handelsüblichen 940nm Infrarot-LEDs undIR-Empfängermodulen, wie zum Beispiel TSOP{17,22,24,36,38,44,48}*-Demodulatoren. -## v2.8.5 jetzt verfügbar -Version 2.8.5 der Bibliothek ist nun [verfügbar](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Die [Versionshinweise](ReleaseNotes.md) enthalten alle wichtigen Neuerungen. +## v2.8.6 jetzt verfügbar +Version 2.8.6 der Bibliothek ist nun [verfügbar](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Die [Versionshinweise](ReleaseNotes.md) enthalten alle wichtigen Neuerungen. #### Hinweis für Nutzer von Versionen vor v2.0 Die Benutzung der Bibliothek hat sich mit Version 2.0 leicht geändert. Einige Anpassungen im aufrufenden Code werden nötig sein, um mit Version ab 2.0 korrekt zu funktionieren. Mehr zu den Anpassungen finden sich auf unserer [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0)-Seite. diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README_fr.md b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README_fr.md index 430d32de3813..f7bd69eaf838 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README_fr.md +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README_fr.md @@ -10,8 +10,8 @@ Cette librairie vous permetra de **recevoir et d'envoyer des signaux** infrarouge sur le protocole [ESP8266](https://github.com/esp8266/Arduino) ou sur le protocole [ESP32](https://github.com/espressif/arduino-esp32) en utilisant le [Arduino framework](https://www.arduino.cc/) qui utilise la norme 940nm IR LEDs et le module basique de reception d'onde IR. Exemple : TSOP{17,22,24,36,38,44,48}* modules etc. -## v2.8.5 disponible -Version 2.8.5 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants. +## v2.8.6 disponible +Version 2.8.6 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants. #### mise à jour depuis pre-v2.0 L'utilisation de la librairie à un peu changer depuis la version in v2.0. Si vous voulez l'utiliser vous devrez changer votre utilisation aussi. Vous pouvez vous renseigner sur les précondition d'utilisation ici : [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page. diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README_nl.md b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README_nl.md index fdea85caed18..8c4cb8e08c7e 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README_nl.md +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/README_nl.md @@ -10,8 +10,8 @@ Deze library maakt het mogelijk om Infraroodsignalen **te versturen en ontvangen** via het [Arduino framework](https://www.arduino.cc/) met veelgebruikte 940nm IR LEDs en IR ontvang modules. b.v. TSOP{17,22,24,36,38,44,48}* demodulatoren enz. -## v2.8.5 nu beschikbaar -Versie 2.8.5 van de bibliotheek is nu [beschikbaar](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Bekijk de [Release Notes](ReleaseNotes.md) voor alle belangrijke veranderingen. +## v2.8.6 nu beschikbaar +Versie 2.8.6 van de bibliotheek is nu [beschikbaar](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Bekijk de [Release Notes](ReleaseNotes.md) voor alle belangrijke veranderingen. #### Upgraden vanaf pre-v2.0 Het gebruik van de bibliotheek is enigszins gewijzigd in v2.0. Je zult het gebruik moeten aanpassen om te kunnen werken met v2.0 en hoger. Je kunt meer lezen over de vereiste aanpassingen op onze [Upgraden naar v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) pagina. diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/ReleaseNotes.md b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/ReleaseNotes.md index d9e86c7e3503..27b5b3fac250 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/ReleaseNotes.md +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/ReleaseNotes.md @@ -1,5 +1,23 @@ # Release Notes +## _v2.8.6 (20230727)_ + +**[Bug Fixes]** +- Ensure `IRCoolixAC::toCommon()` returns `kNoTempValue` when no sensor temp is detected. (#2015 #2012) +- Fix compilation dependency of LG on Samsung send protocol (#2011 #2010) +- Fix missing parameter in call to `IRac::gree()` (#2008 #2007) + +**[Features]** +- IRac: Ensure the `sleep` parameter is used for the `FUJITSU_AC` protocol. (#1992 #1991) + +**[Misc]** +- Allow the BlynkIRRemote.ino code to compile again. (#2016) +- do not list WHIRLPOOL_AC unconditionally as supported protocol (#2003) +- IRUtils:typeToString() — simplify (#2002) +- Fix brand Green -> Gree (#1994) +- Fix undefined `std::round` compilation error (#1989) + + ## _v2.8.5 (20230508)_ **[Bug Fixes]** diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/SupportedProtocols.md b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/SupportedProtocols.md index 46b65ca5ef9a..3c6d38a03498 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/SupportedProtocols.md +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/SupportedProtocols.md @@ -1,6 +1,6 @@ + Last generated: Thu 27 Jul 2023 05:37:11 +0000 ---> # IR Protocols supported by this library | Protocol | Brand | Model | A/C Model | Detailed A/C Support | @@ -65,8 +65,7 @@ | [JVC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_JVC.cpp) | **JVC** | PTU94023B remote | | - | | [Kelon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelon.cpp) | **[Hisense](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelon.h)** | AST-09UW4RVETG00A A/C (KELON168) | | Yes | | [Kelon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelon.cpp) | **[Kelon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelon.h)** | AST-09UW4RVETG00A A/C (KELON168)
DG11R2-01 remote (KELON168)
ON/OFF 9000-12000 (KELON) | | Yes | -| [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | YAP0F8 remote | | Yes | -| [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Green](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | YAPOF3 remote | | Yes | +| [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | YAP0F8 remote
YAPOF3 remote | | Yes | | [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | KSV26CRC A/C
KSV26HRC A/C
KSV35CRC A/C
KSV35HRC A/C
KSV53HRC A/C
KSV62HRC A/C
KSV70CRC A/C
KSV70HRC A/C
KSV80HRC A/C
YALIF Remote | | Yes | | [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | A5VEY A/C
YB1FA remote | | Yes | | [LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.cpp) | **[General Electric](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h)** | 6711AR2853M Remote (LG - GE6711AR2853M)
AG1BH09AW101 A/C (LG - GE6711AR2853M) | | Yes | diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/BlynkIrRemote/BlynkIrRemote.ino b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/BlynkIrRemote/BlynkIrRemote.ino index 6e659bd6433f..1948f3c4ccee 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/BlynkIrRemote/BlynkIrRemote.ino +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/BlynkIrRemote/BlynkIrRemote.ino @@ -104,6 +104,8 @@ /* Comment this out to disable prints and save space */ #define BLYNK_PRINT Serial +#define BLYNK_TEMPLATE_ID "TMPL••••••••" // Made up values. Please Change. +#define BLYNK_TEMPLATE_NAME "My First Device" // Please Change. #if defined(ESP8266) #include diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/IRrecvDumpV2/platformio.ini b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/IRrecvDumpV2/platformio.ini index b56304f66b4a..eca7c917e99e 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/IRrecvDumpV2/platformio.ini +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/IRrecvDumpV2/platformio.ini @@ -64,4 +64,9 @@ build_flags = -D_IR_LOCALE_=zh-CN ; Chinese (Simplified) ; Build the library with all protocols disabled to flush out #if/#ifdef issues & ; any compiler warnings, by turning them into errors. [env:shakedown_no_protocols] -build_flags = -D_IR_ENABLE_DEFAULT_=false -Werror -Wno-error=switch +build_flags = + ${env.build_flags} + -Werror + -Wno-error=switch + -Wno-error=switch-unreachable + -D_IR_ENABLE_DEFAULT_=false diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/SmartIRRepeater/platformio.ini b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/SmartIRRepeater/platformio.ini index 0db3d6dc868c..88a7e8a17de5 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/SmartIRRepeater/platformio.ini +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/SmartIRRepeater/platformio.ini @@ -34,4 +34,5 @@ build_flags = ${env.build_flags} -Werror -Wno-error=switch + -Wno-error=switch-unreachable -D_IR_ENABLE_DEFAULT_=false diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.json b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.json index 302372566d0e..60c4811529d5 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.json +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.json @@ -1,6 +1,6 @@ { "name": "IRremoteESP8266", - "version": "2.8.5", + "version": "2.8.6", "keywords": "infrared, ir, remote, esp8266, esp32", "description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)", "repository": diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.properties b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.properties index 769cbc1fa355..faed00b7545e 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.properties +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.properties @@ -1,5 +1,5 @@ name=IRremoteESP8266 -version=2.8.5 +version=2.8.6 author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff maintainer=David Conran, Mark Szabo, Sebastien Warin, Roi Dayan, Massimiliano Pinto, Christian Nilsson sentence=Send and receive infrared signals with multiple protocols (ESP8266/ESP32) diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRac.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRac.cpp index 8826bc1ae913..67c218c1ed52 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRac.cpp +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRac.cpp @@ -13,6 +13,11 @@ #include #endif #include +#if __cplusplus >= 201103L && defined(_GLIBCXX_USE_C99_MATH_TR1) + using std::roundf; +#else + using ::roundf; +#endif #include "IRsend.h" #include "IRremoteESP8266.h" #include "IRtext.h" @@ -366,7 +371,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) { #if SEND_YORK case decode_type_t::YORK: #endif +#if SEND_WHIRLPOOL_AC case decode_type_t::WHIRLPOOL_AC: +#endif return true; default: return false; @@ -489,9 +496,9 @@ void IRac::argo(IRArgoAC *ac, ac->begin(); ac->setPower(on); ac->setMode(ac->convertMode(mode)); - ac->setTemp(static_cast(std::round(degrees))); + ac->setTemp(static_cast(roundf(degrees))); if (sensorTemp != kNoTempValue) { - ac->setSensorTemp(static_cast(std::round(sensorTemp))); + ac->setSensorTemp(static_cast(roundf(sensorTemp))); } ac->setiFeel(iFeel); ac->setFan(ac->convertFan(fan)); @@ -537,7 +544,7 @@ void IRac::argoWrem3_ACCommand(IRArgoAC_WREM3 *ac, const bool on, ac->setMode(ac->convertMode(mode)); ac->setTemp(degrees); if (sensorTemp != kNoTempValue) { - ac->setSensorTemp(static_cast(std::round(sensorTemp))); + ac->setSensorTemp(static_cast(roundf(sensorTemp))); } ac->setiFeel(iFeel); ac->setFan(ac->convertFan(fan)); @@ -563,7 +570,7 @@ void IRac::argoWrem3_ACCommand(IRArgoAC_WREM3 *ac, const bool on, void IRac::argoWrem3_iFeelReport(IRArgoAC_WREM3 *ac, const float sensorTemp) { ac->begin(); ac->setMessageType(argoIrMessageType_t::IFEEL_TEMP_REPORT); - ac->setSensorTemp(static_cast(std::round(sensorTemp))); + ac->setSensorTemp(static_cast(roundf(sensorTemp))); ac->send(); } @@ -738,7 +745,7 @@ void IRac::coolix(IRCoolixAC *ac, // No Econo setting available. // No Quiet setting available. if (sensorTemp != kNoTempValue) { - ac->setSensorTemp(static_cast(std::round(sensorTemp))); + ac->setSensorTemp(static_cast(roundf(sensorTemp))); } else { ac->clearSensorTemp(); } @@ -1128,7 +1135,7 @@ void IRac::ecoclim(IREcoclimAc *ac, ac->setTemp(degrees); ac->setFan(ac->convertFan(fan)); if (sensorTemp != kNoTempValue) { - ac->setSensorTemp(static_cast(std::round(sensorTemp))); + ac->setSensorTemp(static_cast(roundf(sensorTemp))); } else { ac->setSensorTemp(degrees); //< Set to the desired temp // until we can disable. @@ -1174,7 +1181,7 @@ void IRac::electra(IRElectraAc *ac, ac->setMode(ac->convertMode(mode)); ac->setTemp(degrees); if (sensorTemp != kNoTempValue) { - ac->setSensorTemp(static_cast(std::round(sensorTemp))); + ac->setSensorTemp(static_cast(roundf(sensorTemp))); } ac->setFan(ac->convertFan(fan)); ac->setSwingV(swingv != stdAc::swingv_t::kOff); @@ -2288,7 +2295,7 @@ void IRac::sanyo(IRSanyoAc *ac, ac->setMode(ac->convertMode(mode)); ac->setTemp(degrees); if (sensorTemp != kNoTempValue) { - ac->setSensorTemp(static_cast(std::round(sensorTemp))); + ac->setSensorTemp(static_cast(roundf(sensorTemp))); } else { ac->setSensorTemp(degrees); // Set the sensor temp to the desired // (normal) temp. @@ -3229,7 +3236,7 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { fujitsu(&ac, (fujitsu_ac_remote_model_t)send.model, send.power, send.mode, send.celsius, send.degrees, send.fanspeed, send.swingv, send.swingh, send.quiet, - send.turbo, send.econo, send.filter, send.clean); + send.turbo, send.econo, send.filter, send.clean, send.sleep); break; } #endif // SEND_FUJITSU_AC @@ -3249,7 +3256,8 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { _modulation); gree(&ac, (gree_ac_remote_model_t)send.model, send.power, send.mode, send.celsius, send.degrees, send.fanspeed, send.swingv, send.swingh, - send.turbo, send.econo, send.light, send.clean, send.sleep); + send.iFeel, send.turbo, send.econo, send.light, send.clean, + send.sleep); break; } #endif // SEND_GREE diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRrecv.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRrecv.cpp index ecb8a382bf15..764870706f08 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRrecv.cpp +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRrecv.cpp @@ -13,6 +13,11 @@ extern "C" { } #endif // ESP8266 #include +#if defined(ESP32) +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) +#include +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 +#endif #endif // UNIT_TEST #include #ifdef UNIT_TEST @@ -242,8 +247,13 @@ static void USE_IRAM_ATTR gpio_intr() { // @see https://github.com/espressif/arduino-esp32/blob/6b0114366baf986c155e8173ab7c22bc0c5fcedc/cores/esp32/esp32-hal-timer.c#L176-L178 timer->dev->config.alarm_en = 1; #else // _ESP32_IRRECV_TIMER_HACK +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + timerAlarm(timer, MS_TO_USEC(params.timeout), ONCE, 0); + timerAttachInterrupt(timer, &read_timeout); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerWrite(timer, 0); timerAlarmEnable(timer); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #endif // _ESP32_IRRECV_TIMER_HACK #endif // ESP32 } @@ -359,7 +369,11 @@ void IRrecv::enableIRIn(const bool pullup) { #if defined(ESP32) // Initialise the ESP32 timer. // 80MHz / 80 = 1 uSec granularity. +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + timer = timerBegin(80); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timer = timerBegin(_timer_num, 80, true); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #ifdef DEBUG if (timer == NULL) { DPRINT("FATAL: Unable enable system timer: "); @@ -367,12 +381,17 @@ void IRrecv::enableIRIn(const bool pullup) { } #endif // DEBUG assert(timer != NULL); // Check we actually got the timer. +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + timerAlarm(timer, MS_TO_USEC(params.timeout), ONCE, 0); + timerAttachInterrupt(timer, &read_timeout); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 // Set the timer so it only fires once, and set it's trigger in uSeconds. timerAlarmWrite(timer, MS_TO_USEC(params.timeout), ONCE); // Note: Interrupt needs to be attached before it can be enabled or disabled. // Note: EDGE (true) is not supported, use LEVEL (false). Ref: #1713 // See: https://github.com/espressif/arduino-esp32/blob/caef4006af491130136b219c1205bdcf8f08bf2b/cores/esp32/esp32-hal-timer.c#L224-L227 timerAttachInterrupt(timer, &read_timeout, false); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #endif // ESP32 // Initialise state machine variables @@ -398,9 +417,13 @@ void IRrecv::disableIRIn(void) { os_timer_disarm(&timer); #endif // ESP8266 #if defined(ESP32) +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + timerEnd(timer); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerAlarmDisable(timer); timerDetachInterrupt(timer); timerEnd(timer); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #endif // ESP32 detachInterrupt(params.recvpin); #endif // UNIT_TEST @@ -412,10 +435,6 @@ void IRrecv::pause(void) { params.rcvstate = kStopState; params.rawlen = 0; params.overflow = false; -#if defined(ESP8266) - os_timer_disarm(&timer); - detachInterrupt(params.recvpin); -#endif #if defined(ESP32) gpio_intr_disable((gpio_num_t)params.recvpin); #endif // ESP32 @@ -429,12 +448,12 @@ void IRrecv::resume(void) { params.rcvstate = kIdleState; params.rawlen = 0; params.overflow = false; -#if defined(ESP8266) - os_timer_setfn(&timer, reinterpret_cast(read_timeout),NULL); - attachInterrupt(params.recvpin, gpio_intr, CHANGE); -#endif #if defined(ESP32) +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + timerEnd(timer); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerAlarmDisable(timer); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 gpio_intr_enable((gpio_num_t)params.recvpin); #endif // ESP32 } diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRremoteESP8266.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRremoteESP8266.h index 133d507b8e92..949de1ecf408 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRremoteESP8266.h +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRremoteESP8266.h @@ -58,7 +58,7 @@ // Minor version number (x.X.x) #define _IRREMOTEESP8266_VERSION_MINOR 8 // Patch version number (x.x.X) -#define _IRREMOTEESP8266_VERSION_PATCH 5 +#define _IRREMOTEESP8266_VERSION_PATCH 6 // Macro to convert version info into an integer #define _IRREMOTEESP8266_VERSION_VAL(major, minor, patch) \ (((major) << 16) | ((minor) << 8) | (patch)) diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRsend.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRsend.h index f8a447197e79..38491372aa5d 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRsend.h +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRsend.h @@ -310,11 +310,12 @@ class IRsend { void sendSherwood(uint64_t data, uint16_t nbits = kSherwoodBits, uint16_t repeat = kSherwoodMinRepeat); #endif -#if SEND_SAMSUNG + // `sendSAMSUNG()` is required by `sendLG()` +#if (SEND_SAMSUNG || SEND_LG) void sendSAMSUNG(const uint64_t data, const uint16_t nbits = kSamsungBits, const uint16_t repeat = kNoRepeat); uint32_t encodeSAMSUNG(const uint8_t customer, const uint8_t command); -#endif +#endif // (SEND_SAMSUNG || SEND_LG) #if SEND_SAMSUNG36 void sendSamsung36(const uint64_t data, const uint16_t nbits = kSamsung36Bits, const uint16_t repeat = kNoRepeat); diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRutils.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRutils.cpp index 4c713c87b4af..e9af0b28fe00 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRutils.cpp +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRutils.cpp @@ -145,16 +145,12 @@ String typeToString(const decode_type_t protocol, const bool isRepeat) { result = kUnknownStr; } else { auto *ptr = reinterpret_cast(kAllProtocolNamesStr); - if (protocol > kLastDecodeType || protocol == decode_type_t::UNKNOWN) { - result = kUnknownStr; - } else { - for (uint16_t i = 0; i <= protocol && STRLEN(ptr); i++) { - if (i == protocol) { - result = FPSTR(ptr); - break; - } - ptr += STRLEN(ptr) + 1; + for (uint16_t i = 0; i <= protocol && STRLEN(ptr); i++) { + if (i == protocol) { + result = FPSTR(ptr); + break; } + ptr += STRLEN(ptr) + 1; } } if (isRepeat) { diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Coolix.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Coolix.cpp index 3fb4e8d0a520..6769ebb79d0e 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Coolix.cpp +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Coolix.cpp @@ -549,6 +549,9 @@ stdAc::state_t IRCoolixAC::toCommon(const stdAc::state_t *prev) const { result.mode = toCommonMode(getMode()); result.degrees = getTemp(); result.sensorTemperature = getSensorTemp(); + if (result.sensorTemperature == kCoolixSensorTempIgnoreCode) { + result.sensorTemperature = kNoTempValue; + } result.iFeel = getZoneFollow(); result.fanspeed = toCommonFanSpeed(getFan()); return result; diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Kelvinator.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Kelvinator.h index 32cb3e1fa0ea..342c60592d9e 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Kelvinator.h +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Kelvinator.h @@ -13,7 +13,7 @@ // Brand: Kelvinator, Model: KSV70CRC A/C // Brand: Kelvinator, Model: KSV70HRC A/C // Brand: Kelvinator, Model: KSV80HRC A/C -// Brand: Green, Model: YAPOF3 remote +// Brand: Gree, Model: YAPOF3 remote // Brand: Gree, Model: YAP0F8 remote // Brand: Sharp, Model: YB1FA remote // Brand: Sharp, Model: A5VEY A/C diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Samsung.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Samsung.cpp index b3fe2a860106..958f2665bdd7 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Samsung.cpp +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Samsung.cpp @@ -82,7 +82,8 @@ using irutils::addTempToString; using irutils::addToggleToString; using irutils::minsToString; -#if SEND_SAMSUNG +// This sending protocol is used by some other protocols. e.g. LG. +#if (SEND_SAMSUNG || SEND_LG) /// Send a 32-bit Samsung formatted message. /// Status: STABLE / Should be working. /// @param[in] data The message to be sent. @@ -112,7 +113,7 @@ uint32_t IRsend::encodeSAMSUNG(const uint8_t customer, const uint8_t command) { return ((revcommand ^ 0xFF) | (revcommand << 8) | (revcustomer << 16) | (revcustomer << 24)); } -#endif +#endif // (SEND_SAMSUNG || SEND_LG) #if DECODE_SAMSUNG /// Decode the supplied Samsung 32-bit message. diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/IRac_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/IRac_test.cpp index 32a745a31199..8d6274c65da2 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/IRac_test.cpp +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/IRac_test.cpp @@ -669,7 +669,8 @@ TEST(TestIRac, Fujitsu) { false, // Turbo (Powerful) false, // Econo true, // Filter - true); // Clean + true, // Clean + -1); // Sleep ASSERT_EQ(ardb1_expected, ac.toString()); ac._irsend.makeDecodeResult(); EXPECT_TRUE(capture.decode(&ac._irsend.capture)); @@ -719,7 +720,8 @@ TEST(TestIRac, Fujitsu) { false, // Turbo (Powerful) false, // Econo true, // Filter - true); // Clean + true, // Clean + -1); // Sleep ASSERT_EQ(arry4_expected, ac.toString()); ac._irsend.makeDecodeResult(); EXPECT_TRUE(capture.decode(&ac._irsend.capture)); @@ -742,8 +744,9 @@ TEST(TestIRac, Fujitsu) { false, // Quiet false, // Turbo (Powerful) false, // Econo - false, // Filter - false); // Clean + false, // Filter + false, // Clean + -1); // Sleep ASSERT_EQ(arrew4e_expected, ac.toString()); ac._irsend.makeDecodeResult(); EXPECT_TRUE(capture.decode(&ac._irsend.capture)); diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Coolix_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Coolix_test.cpp index ba3610bc7f02..101fab654670 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Coolix_test.cpp +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Coolix_test.cpp @@ -492,6 +492,9 @@ TEST(TestCoolixACClass, SetGetClearSensorTempAndZoneFollow) { EXPECT_EQ( "Power: On, Mode: 3 (Heat), Fan: 6 (Zone Follow), Temp: 24C, " "Zone Follow: On, Sensor Temp: 19C", ac.toString()); + // For #Issue2012 + EXPECT_EQ(19, ac.getSensorTemp()); + EXPECT_EQ(19, ac.toCommon().sensorTemperature); } TEST(TestCoolixACClass, SpecialModesAndReset) { @@ -1068,3 +1071,36 @@ TEST(TestDecodeCoolix48, SyntheticSelfDecode) { "m552s5244", irsend.outputStr()); } + +// Test for issue https://github.com/crankyoldgit/IRremoteESP8266/issues/2012#issuecomment-1650098971 +TEST(TestCoolixACClass, Issue2012) { + IRrecv irrecv(kGpioUnused); + IRCoolixAC ac(kGpioUnused); + + ac.stateReset(); + ac.setRaw(0xB21FD8); + EXPECT_EQ( + "Power: On, Mode: 2 (Auto), Fan: 0 (Auto0), Temp: 26C, " + "Zone Follow: Off, Sensor Temp: Off", + ac.toString()); + EXPECT_EQ(kNoTempValue, ac.toCommon().sensorTemperature); + + ac.setRaw(0xB21F98); + EXPECT_EQ( + "Power: On, Mode: 2 (Auto), Fan: 0 (Auto0), Temp: 27C, " + "Zone Follow: Off, Sensor Temp: Off", + ac.toString()); + EXPECT_EQ(kNoTempValue, ac.toCommon().sensorTemperature); + + ac.setRaw(0xB21F88); + EXPECT_EQ( + "Power: On, Mode: 2 (Auto), Fan: 0 (Auto0), Temp: 28C, " + "Zone Follow: Off, Sensor Temp: Off", + ac.toString()); + EXPECT_EQ(kNoTempValue, ac.toCommon().sensorTemperature); + ac.setRaw(0xB27BE0); + EXPECT_EQ( + "Power: Off", + ac.toString()); + EXPECT_EQ(kNoTempValue, ac.toCommon().sensorTemperature); +} diff --git a/lib/lib_basic/IRremoteESP8266/library.json b/lib/lib_basic/IRremoteESP8266/library.json index 476000469410..87c32e6870b2 100644 --- a/lib/lib_basic/IRremoteESP8266/library.json +++ b/lib/lib_basic/IRremoteESP8266/library.json @@ -1,6 +1,6 @@ { "name": "IRremoteESP8266", - "version": "2.8.5", + "version": "2.8.6", "keywords": "infrared, ir, remote, esp8266, esp32", "description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)", "repository": diff --git a/lib/lib_basic/NeoPixelBus/src/NeoPixelBus.h b/lib/lib_basic/NeoPixelBus/src/NeoPixelBus.h index 1f06ef52ce7c..d810e2a94b6e 100644 --- a/lib/lib_basic/NeoPixelBus/src/NeoPixelBus.h +++ b/lib/lib_basic/NeoPixelBus/src/NeoPixelBus.h @@ -101,9 +101,16 @@ License along with NeoPixel. If not, see #include "internal/NeoEspBitBangMethod.h" #elif defined(ARDUINO_ARCH_ESP32) - +#if ESP_IDF_VERSION_MAJOR < 5 #include "internal/NeoEsp32I2sMethod.h" #include "internal/NeoEsp32RmtMethod.h" +#else +#if !defined(CONFIG_IDF_TARGET_ESP32C2) +#include "internal/NeoEsp32RmtMethod_idf5.h" // every other SOC +#else //CONFIG_IDF_TARGET_ESP32C2 +#include "internal/NeoEsp32SpiMethod_idf5.h" // ESP32C2 +#endif //CONFIG_IDF_TARGET_ESP32C2 +#endif // ESP_IDF_VERSION_MAJOR #include "internal/NeoEspBitBangMethod.h" #include "internal/DotStarEsp32DmaSpiMethod.h" diff --git a/lib/lib_basic/NeoPixelBus/src/internal/DotStarEsp32DmaSpiMethod.h b/lib/lib_basic/NeoPixelBus/src/internal/DotStarEsp32DmaSpiMethod.h index a9d149b71b27..953a216e7481 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/DotStarEsp32DmaSpiMethod.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/DotStarEsp32DmaSpiMethod.h @@ -29,12 +29,12 @@ License along with NeoPixel. If not, see #include "driver/spi_master.h" -#if defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(HSPI_HOST) +#if (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6)) && !defined(HSPI_HOST) // HSPI_HOST depreciated in C3 #define HSPI_HOST SPI2_HOST #endif -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) class Esp32VspiBus { public: @@ -52,7 +52,7 @@ class Esp32HspiBus const static int ParallelBits = 1; }; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) class Esp32Vspi2BitBus { public: @@ -70,7 +70,7 @@ class Esp32Hspi2BitBus const static int ParallelBits = 2; }; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) class Esp32Vspi4BitBus { public: @@ -174,7 +174,7 @@ template class DotStarEsp32DmaSpiMethod // If pins aren't specified, initialize bus with just the default SCK and MOSI pins for the SPI peripheral (no SS, no >1-bit pins) void Initialize() { -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) if (T_SPIBUS::SpiHostDevice == VSPI_HOST) { Initialize(SCK, -1, MOSI, -1, -1, -1); @@ -277,7 +277,7 @@ template class DotStarEsp32DmaSpiMethod int8_t _ssPin; }; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) // Clock Speed and Default Definitions for DotStarEsp32DmaVspi typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi40MhzMethod; typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi20MhzMethod; @@ -303,7 +303,7 @@ typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaHspiHz typedef DotStarEsp32DmaHspi10MhzMethod DotStarEsp32DmaHspiMethod; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) // Clock Speed and Default Definitions for DotStarEsp32DmaVspi2Bit typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi2Bit40MhzMethod; typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi2Bit20MhzMethod; @@ -329,7 +329,7 @@ typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaHsp typedef DotStarEsp32DmaHspi2Bit10MhzMethod DotStarEsp32DmaHspi2BitMethod; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) // Clock Speed and Default Definitions for DotStarEsp32DmaVspi4Bit typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi4Bit40MhzMethod; typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi4Bit20MhzMethod; diff --git a/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.c b/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.c index 0f100cb41d6f..5823b1875f73 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.c +++ b/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.c @@ -20,7 +20,8 @@ #include "sdkconfig.h" // this sets useful config symbols, like CONFIG_IDF_TARGET_ESP32C3 // ESP32C3/S3 I2S is not supported yet due to significant changes to interface -#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) +#ifndef CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP // turn this off with something new from idf5.1 +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(CONFIG_IDF_TARGET_ESP32C2) #include #include @@ -495,5 +496,6 @@ size_t i2sWrite(uint8_t bus_num, uint8_t* data, size_t len, bool copy, bool free } #endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif //ESP_IDF_VERSION_MAJOR < 5 #endif // defined(ARDUINO_ARCH_ESP32) diff --git a/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.h b/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.h index 1249d2e11dd4..bfc024a8ce7e 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.h @@ -1,7 +1,10 @@ #pragma once +#include "sdkconfig.h" // this sets useful config symbols, like CONFIG_IDF_TARGET_ESP32C3 + +#ifndef CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP // turn this off with something new from idf5.1 // ESP32C3 I2S is not supported yet due to significant changes to interface -#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) #ifdef __cplusplus extern "C" { @@ -38,5 +41,5 @@ bool i2sWriteDone(uint8_t bus_num); #ifdef __cplusplus } #endif - #endif +#endif // ESP_IDF_VERSION_MAJOR < 5 diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoBusChannel.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoBusChannel.h index 6f4b3c66f125..5fdb131bf377 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoBusChannel.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoBusChannel.h @@ -12,7 +12,7 @@ enum NeoBusChannel NeoBusChannel_0, NeoBusChannel_1, -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) NeoBusChannel_2, @@ -35,7 +35,7 @@ enum NeoBusChannel NeoBusChannel_7, #endif // !defined(CONFIG_IDF_TARGET_ESP32S2) -#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #endif // ARDUINO_ARCH_ESP32 diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32I2sMethod.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32I2sMethod.h index 9dbaa7fe76d9..2afe6d5aa868 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32I2sMethod.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32I2sMethod.h @@ -26,12 +26,16 @@ License along with NeoPixel. If not, see #pragma once +#if ESP_IDF_VERSION_MAJOR <= 4 // ESP32C3 I2S is not supported yet due to significant changes to interface #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) extern "C" { #include +#if ESP_IDF_VERSION_MAJOR >= 5 +#include +#endif #include "Esp32_i2s.h" } @@ -376,5 +380,5 @@ typedef NeoEsp32I2s1Ws2812xInvertedMethod Neo800KbpsInvertedMethod; typedef NeoEsp32I2s1400KbpsInvertedMethod Neo400KbpsInvertedMethod; #endif // !defined(NEOPIXEL_ESP32_RMT_DEFAULT) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) - #endif +#endif // ESP_IDF_VERSION_MAJOR < 5 diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.cpp b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.cpp index f25d20d8fc5a..c8525e09dc07 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.cpp +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.cpp @@ -32,7 +32,7 @@ License along with NeoPixel. If not, see #include "NeoBusChannel.h" #include "NeoEsp32RmtMethod.h" -#ifdef ARDUINO_ARCH_ESP32 +#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32C2) // translate NeoPixelBuffer into RMT buffer diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.h index 2ed7e4a0ecbf..e804cc2a7e3a 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.h @@ -29,7 +29,7 @@ License along with NeoPixel. If not, see #pragma once -#ifdef ARDUINO_ARCH_ESP32 +#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32C2) /* General Reference documentation for the APIs used in this implementation LOW LEVEL: (what is actually used) @@ -47,6 +47,9 @@ Esp32-hal-rmt.c extern "C" { +#if ESP_IDF_VERSION_MAJOR >= 5 +#include +#endif #include } @@ -451,7 +454,7 @@ class NeoEsp32RmtChannel3 const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_3; }; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) class NeoEsp32RmtChannel4 { diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod_idf5.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod_idf5.h new file mode 100644 index 000000000000..9057102541a8 --- /dev/null +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod_idf5.h @@ -0,0 +1,892 @@ +/*------------------------------------------------------------------------- +NeoPixel library helper functions for Esp32. + +A BIG thanks to Andreas Merkle for the investigation and implementation of +a workaround to the GCC bug that drops method attributes from template methods + +Written by Michael C. Miller. + +I invest time and resources providing this open source code, +please support me by dontating (see https://github.com/Makuna/NeoPixelBus) + +------------------------------------------------------------------------- +This file is part of the Makuna/NeoPixelBus library. + +NeoPixelBus is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as +published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +NeoPixelBus is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with NeoPixel. If not, see +. +-------------------------------------------------------------------------*/ + +#pragma once + +#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C2) + +/* General Reference documentation for the APIs used in this implementation +LOW LEVEL: (what is actually used) +DOCS: https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/rmt.html +EXAMPLE: https://github.com/espressif/esp-idf/blob/826ff7186ae07dc81e960a8ea09ebfc5304bfb3b/examples/peripherals/rmt_tx/main/rmt_tx_main.c + +HIGHER LEVEL: +NO TRANSLATE SUPPORT so this was not used +NOTE: https://github.com/espressif/arduino-esp32/commit/50d142950d229b8fabca9b749dc4a5f2533bc426 +Esp32-hal-rmt.h +Esp32-hal-rmt.c +*/ + +#include + +extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); + +extern "C" +{ +#include +#include "driver/rmt_tx.h" +#include "driver/rmt_encoder.h" +#include "esp_check.h" +} + +#define RMT_LED_STRIP_RESOLUTION_HZ 40000000 // 40MHz resolution - setting of the "old" driver + +typedef struct { + uint32_t resolution; /*!< Encoder resolution, in Hz */ +} led_strip_encoder_config_t; + +typedef struct { + rmt_encoder_t base; + rmt_encoder_t *bytes_encoder; + rmt_encoder_t *copy_encoder; + int state; + rmt_symbol_word_t reset_code; +} rmt_led_strip_encoder_t; + +static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder; + rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder; + rmt_encode_state_t session_state = RMT_ENCODING_RESET; + rmt_encode_state_t state = RMT_ENCODING_RESET; + size_t encoded_symbols = 0; + switch (led_encoder->state) { + case 0: // send RGB data + encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, primary_data, data_size, &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 1; // switch to next state when current encoding session finished + } + if (session_state & RMT_ENCODING_MEM_FULL) { + // static_cast(static_cast(a) | static_cast(b)); + state = static_cast(static_cast(state) | static_cast(RMT_ENCODING_MEM_FULL)); + goto out; // yield if there's no free space for encoding artifacts + } + // fall-through + case 1: // send reset code + encoded_symbols += copy_encoder->encode(copy_encoder, channel, &led_encoder->reset_code, + sizeof(led_encoder->reset_code), &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = RMT_ENCODING_RESET; // back to the initial encoding session + state = static_cast(static_cast(state) | static_cast(RMT_ENCODING_COMPLETE)); + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state = static_cast(static_cast(state) | static_cast(RMT_ENCODING_MEM_FULL)); + goto out; // yield if there's no free space for encoding artifacts + } + } +out: + *ret_state = state; + return encoded_symbols; +} + +static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_del_encoder(led_encoder->bytes_encoder); + rmt_del_encoder(led_encoder->copy_encoder); + delete led_encoder; + return ESP_OK; +} + +static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_reset(led_encoder->bytes_encoder); + rmt_encoder_reset(led_encoder->copy_encoder); + led_encoder->state = RMT_ENCODING_RESET; + return ESP_OK; +} + +esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder, uint32_t bit0, uint32_t bit1) +{ + const char* TAG = "TEST_RMT"; //TODO: Remove later + esp_err_t ret = ESP_OK; + rmt_led_strip_encoder_t *led_encoder = NULL; + uint32_t reset_ticks = config->resolution / 1000000 * 50 / 2; // reset code duration defaults to 50us + rmt_bytes_encoder_config_t bytes_encoder_config; + rmt_copy_encoder_config_t copy_encoder_config = {}; + rmt_symbol_word_t reset_code_config; + + + ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + led_encoder = new rmt_led_strip_encoder_t(); + ESP_GOTO_ON_FALSE(led_encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for led strip encoder"); + led_encoder->base.encode = rmt_encode_led_strip; + led_encoder->base.del = rmt_del_led_strip_encoder; + led_encoder->base.reset = rmt_led_strip_encoder_reset; + + bytes_encoder_config.bit0.val = bit0; + bytes_encoder_config.bit1.val = bit1; + + bytes_encoder_config.flags.msb_first = 1; // WS2812 transfer bit order: G7...G0R7...R0B7...B0 - TODO: more checks + + ESP_GOTO_ON_ERROR(rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder), err, TAG, "create bytes encoder failed"); + ESP_GOTO_ON_ERROR(rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder), err, TAG, "create copy encoder failed"); + + reset_code_config.level0 = 0; + reset_code_config.duration0 = reset_ticks; + reset_code_config.level1 = 0; + reset_code_config.duration1 = reset_ticks; + led_encoder->reset_code = reset_code_config; + *ret_encoder = &led_encoder->base; + return ret; +err: + // AddLog(2,"RMT:could not init led decoder"); + if (led_encoder) { + if (led_encoder->bytes_encoder) { + rmt_del_encoder(led_encoder->bytes_encoder); + } + if (led_encoder->copy_encoder) { + rmt_del_encoder(led_encoder->copy_encoder); + } + delete led_encoder; + } + return ret; +} + +#define NEOPIXELBUS_RMT_INT_FLAGS (ESP_INTR_FLAG_LOWMED) + +class NeoEsp32RmtSpeed +{ +public: +// next section is probably not needed anymore for IDF 5.1 + // ClkDiv of 2 provides for good resolution and plenty of reset resolution; but + // a ClkDiv of 1 will provide enough space for the longest reset and does show + // little better pulse accuracy + const static uint8_t RmtClockDivider = 2; + + inline constexpr static uint32_t FromNs(uint32_t ns) + { + return ns / NsPerRmtTick; + } + +protected: + const static uint32_t RmtCpu = 80000000L; // 80 mhz RMT clock + const static uint32_t NsPerSecond = 1000000000L; + const static uint32_t RmtTicksPerSecond = (RmtCpu / RmtClockDivider); + const static uint32_t NsPerRmtTick = (NsPerSecond / RmtTicksPerSecond); // about 25 +// end of deprecated section + +}; + +class NeoEsp32RmtSpeedBase : public NeoEsp32RmtSpeed +{ +public: + // this is used rather than the rmt_symbol_word_t as you can't correctly initialize + // it as a static constexpr within the template + inline constexpr static uint32_t Item32Val(uint16_t nsHigh, uint16_t nsLow) + { + return (FromNs(nsLow) << 16) | (1 << 15) | (FromNs(nsHigh)); + } +}; + +class NeoEsp32RmtInvertedSpeedBase : public NeoEsp32RmtSpeed +{ +public: + // this is used rather than the rmt_symbol_word_t as you can't correctly initialize + // it as a static constexpr within the template + inline constexpr static uint32_t Item32Val(uint16_t nsHigh, uint16_t nsLow) + { + return (FromNs(nsLow) << 16) | (1 << 31) | (FromNs(nsHigh)); + } +}; + +class NeoEsp32RmtSpeedWs2811 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(300, 950); // TODO: DRAM_ATTR debatable everywhere + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(900, 350); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(300000); // 300us +}; + +class NeoEsp32RmtSpeedWs2812x : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(400, 850); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 450); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(300000); // 300us +}; + +class NeoEsp32RmtSpeedSk6812 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(400, 850); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 450); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(80000); // 80us +}; + +// normal is inverted signal +class NeoEsp32RmtSpeedTm1814 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(360, 890); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(720, 530); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us +}; + +// normal is inverted signal +class NeoEsp32RmtSpeedTm1829 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(300, 900); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 400); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us +}; + +// normal is inverted signal +class NeoEsp32RmtSpeedTm1914 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(360, 890); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(720, 530); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us +}; + +class NeoEsp32RmtSpeed800Kbps : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(400, 850); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 450); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us +}; + +class NeoEsp32RmtSpeed400Kbps : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(800, 1700); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1600, 900); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us +}; + +class NeoEsp32RmtSpeedApa106 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(350, 1350); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1350, 350); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us +}; + +class NeoEsp32RmtSpeedTx1812 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(300, 600); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(600, 300); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(80000); // 80us +}; + +class NeoEsp32RmtInvertedSpeedWs2811 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(300, 950); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(900, 350); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(300000); // 300us +}; + +class NeoEsp32RmtInvertedSpeedWs2812x : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(400, 850); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 450); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(300000); // 300us +}; + +class NeoEsp32RmtInvertedSpeedSk6812 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(400, 850); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 450); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(80000); // 80us +}; + +// normal is inverted signal +class NeoEsp32RmtInvertedSpeedTm1814 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(360, 890); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(720, 530); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us +}; + +// normal is inverted signal +class NeoEsp32RmtInvertedSpeedTm1829 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(300, 900); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 400); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us +}; + +// normal is inverted signal +class NeoEsp32RmtInvertedSpeedTm1914 : public NeoEsp32RmtSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(360, 890); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(720, 530); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us +}; + +class NeoEsp32RmtInvertedSpeed800Kbps : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(400, 850); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(800, 450); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us +}; + +class NeoEsp32RmtInvertedSpeed400Kbps : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(800, 1700); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1600, 900); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us +}; + +class NeoEsp32RmtInvertedSpeedApa106 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(350, 1350); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(1350, 350); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us +}; + +class NeoEsp32RmtInvertedSpeedTx1812 : public NeoEsp32RmtInvertedSpeedBase +{ +public: + const static DRAM_ATTR uint32_t RmtBit0 = Item32Val(300, 600); + const static DRAM_ATTR uint32_t RmtBit1 = Item32Val(600, 300); + const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(80000); // 80us +}; + +class NeoEsp32RmtChannel0 +{ +public: + NeoEsp32RmtChannel0() {}; + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +class NeoEsp32RmtChannel1 +{ +public: + NeoEsp32RmtChannel1() {}; + + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +#if !defined(CONFIG_IDF_TARGET_ESP32C6) // C6 only 2 RMT channels ?? +class NeoEsp32RmtChannel2 +{ +public: + NeoEsp32RmtChannel2() {}; + + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +class NeoEsp32RmtChannel3 +{ +public: + NeoEsp32RmtChannel3() {}; + +protected: + rmt_channel_handle_t RmtChannelNumber = NULL; +}; +#endif // !defined(CONFIG_IDF_TARGET_ESP32C6) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) + +class NeoEsp32RmtChannel4 +{ +public: + NeoEsp32RmtChannel4() {}; + + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +class NeoEsp32RmtChannel5 +{ +public: + NeoEsp32RmtChannel5() {}; + + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +class NeoEsp32RmtChannel6 +{ +public: + NeoEsp32RmtChannel6() {}; + + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +class NeoEsp32RmtChannel7 +{ +public: + NeoEsp32RmtChannel7() {}; + + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +#endif + +// dynamic channel support +class NeoEsp32RmtChannelN +{ +public: + NeoEsp32RmtChannelN(NeoBusChannel channel) : + RmtChannelNumber(RmtChannelNumber) + { + RmtChannelNumber = NULL; + }; + NeoEsp32RmtChannelN() = delete; // no default constructor + rmt_channel_handle_t RmtChannelNumber = NULL; +}; + +template class NeoEsp32RmtMethodBase +{ +public: + typedef NeoNoSettings SettingsObject; + + NeoEsp32RmtMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize) : + _sizeData(pixelCount * elementSize + settingsSize), + _pin(pin) + { + construct(); + } + + NeoEsp32RmtMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize, NeoBusChannel channel) : + _sizeData(pixelCount* elementSize + settingsSize), + _pin(pin), + _channel(channel) + { + construct(); + } + + ~NeoEsp32RmtMethodBase() + { + // wait until the last send finishes before destructing everything + // arbitrary time out of 10 seconds + + ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_tx_wait_all_done(_channel.RmtChannelNumber, 10000 / portTICK_PERIOD_MS)); + ESP_ERROR_CHECK( rmt_del_channel(_channel.RmtChannelNumber)); + + gpio_matrix_out(_pin, 0x100, false, false); + pinMode(_pin, INPUT); + + free(_dataEditing); + free(_dataSending); + } + + + bool IsReadyToUpdate() const + { + return (ESP_OK == rmt_tx_wait_all_done(_channel.RmtChannelNumber, 0)); + } + + void Initialize() + { + esp_err_t ret = ESP_OK; + rmt_tx_channel_config_t config = {}; + config.clk_src = RMT_CLK_SRC_DEFAULT; + config.gpio_num = static_cast(_pin); + config.mem_block_symbols = 64; // memory block size, 64 * 4 = 256 Bytes + config.resolution_hz = RMT_LED_STRIP_RESOLUTION_HZ; // 1 MHz tick resolution, i.e., 1 tick = 1 µs + config.trans_queue_depth = 4; // set the number of transactions that can pend in the background + config.flags.invert_out = false; // do not invert output signal + config.flags.with_dma = false; // do not need DMA backend + + ret += rmt_new_tx_channel(&config,&_channel.RmtChannelNumber); + led_strip_encoder_config_t encoder_config = {}; + encoder_config.resolution = RMT_LED_STRIP_RESOLUTION_HZ; + + _tx_config.loop_count = 0; //no loop + + ret += rmt_new_led_strip_encoder(&encoder_config, &_led_encoder, T_SPEED::RmtBit0, T_SPEED::RmtBit1); + + // ESP_LOGI(TAG, "Enable RMT TX channel"); + ret += rmt_enable(_channel.RmtChannelNumber); + AddLog(2,"RMT:initialized with error code: %u on pin: %u",ret, _pin); + } + + void Update(bool maintainBufferConsistency) + { + // AddLog(2,".."); + // wait for not actively sending data + // this will time out at 10 seconds, an arbitrarily long period of time + // and do nothing if this happens + + if (ESP_OK == ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_tx_wait_all_done(_channel.RmtChannelNumber, 10000 / portTICK_PERIOD_MS))) + { + // AddLog(2,"__ %u", _sizeData); + // now start the RMT transmit with the editing buffer before we swap + esp_err_t ret = rmt_transmit(_channel.RmtChannelNumber, _led_encoder, _dataEditing, _sizeData, &_tx_config); // 3 for _sizeData + // AddLog(2,"rmt_transmit: %u", ret); + if (maintainBufferConsistency) + { + // copy editing to sending, + // this maintains the contract that "colors present before will + // be the same after", otherwise GetPixelColor will be inconsistent + memcpy(_dataSending, _dataEditing, _sizeData); + } + + // swap so the user can modify without affecting the async operation + std::swap(_dataSending, _dataEditing); + } + } + + uint8_t* getData() const + { + return _dataEditing; + }; + + size_t getDataSize() const + { + return _sizeData; + } + + void applySettings(const SettingsObject& settings) + { + } + +private: + const size_t _sizeData; // Size of '_data*' buffers + const uint8_t _pin; // output pin number + + rmt_transmit_config_t _tx_config = {}; + rmt_encoder_handle_t _led_encoder = nullptr; + + T_CHANNEL _channel; // holds instance for multi channel support + + + // Holds data stream which include LED color values and other settings as needed + uint8_t* _dataEditing; // exposed for get and set + uint8_t* _dataSending; // used for async send using RMT + + + void construct() + { + // AddLog(2,"RMT:construct"); + _dataEditing = static_cast(malloc(_sizeData)); + // data cleared later in Begin() + + _dataSending = static_cast(malloc(_sizeData)); + // no need to initialize it, it gets overwritten on every send + } +}; + +// normal +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNWs2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNWs2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNSk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNApa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtN800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtN400KbpsMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0400KbpsMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1400KbpsMethod; + +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2400KbpsMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3400KbpsMethod; + +#if !defined(CONFIG_IDF_TARGET_ESP32S2) + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4400KbpsMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5400KbpsMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6400KbpsMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Ws2811Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Ws2812xMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Sk6812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tm1814Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tm1829Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tm1914Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Apa106Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tx1812Method; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7800KbpsMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7400KbpsMethod; + +#endif // !defined(CONFIG_IDF_TARGET_ESP32S2) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C3) + +// inverted +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNWs2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNWs2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNSk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNApa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtNTx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtN800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32RmtN400KbpsInvertedMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt0400KbpsInvertedMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1400KbpsInvertedMethod; + +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2400KbpsInvertedMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt3400KbpsInvertedMethod; + +#if !defined(CONFIG_IDF_TARGET_ESP32S2) + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt4400KbpsInvertedMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt5400KbpsInvertedMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt6400KbpsInvertedMethod; + +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Ws2811InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Ws2812xInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Sk6812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tm1814InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tm1829InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tm1914InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Apa106InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7Tx1812InvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7800KbpsInvertedMethod; +typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7400KbpsInvertedMethod; + +#endif // !defined(CONFIG_IDF_TARGET_ESP32S2) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) + + +#if defined(NEOPIXEL_ESP32_RMT_DEFAULT) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) + +// Normally I2s method is the default, defining NEOPIXEL_ESP32_RMT_DEFAULT +// will switch to use RMT as the default method +// The ESP32S2 & ESP32C3 will always defualt to RMT + +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) + +// RMT channel 1 method is the default method for Esp32S2 & Esp32C3 +typedef NeoEsp32Rmt1Ws2812xMethod NeoWs2813Method; +typedef NeoEsp32Rmt1Ws2812xMethod NeoWs2812xMethod; +typedef NeoEsp32Rmt1800KbpsMethod NeoWs2812Method; +typedef NeoEsp32Rmt1Ws2812xMethod NeoWs2811Method; +typedef NeoEsp32Rmt1Sk6812Method NeoSk6812Method; +typedef NeoEsp32Rmt1Tm1814Method NeoTm1814Method; +typedef NeoEsp32Rmt1Tm1829Method NeoTm1829Method; +typedef NeoEsp32Rmt1Tm1914Method NeoTm1914Method; +typedef NeoEsp32Rmt1Sk6812Method NeoLc8812Method; +typedef NeoEsp32Rmt1Apa106Method NeoApa106Method; +typedef NeoEsp32Rmt1Tx1812Method NeoTx1812Method; + +typedef NeoEsp32Rmt1Ws2812xMethod Neo800KbpsMethod; +typedef NeoEsp32Rmt1400KbpsMethod Neo400KbpsMethod; + +typedef NeoEsp32Rmt1Ws2812xInvertedMethod NeoWs2813InvertedMethod; +typedef NeoEsp32Rmt1Ws2812xInvertedMethod NeoWs2812xInvertedMethod; +typedef NeoEsp32Rmt1Ws2812xInvertedMethod NeoWs2811InvertedMethod; +typedef NeoEsp32Rmt1800KbpsInvertedMethod NeoWs2812InvertedMethod; +typedef NeoEsp32Rmt1Sk6812InvertedMethod NeoSk6812InvertedMethod; +typedef NeoEsp32Rmt1Tm1814InvertedMethod NeoTm1814InvertedMethod; +typedef NeoEsp32Rmt1Tm1829InvertedMethod NeoTm1829InvertedMethod; +typedef NeoEsp32Rmt1Tm1914InvertedMethod NeoTm1914InvertedMethod; +typedef NeoEsp32Rmt1Sk6812InvertedMethod NeoLc8812InvertedMethod; +typedef NeoEsp32Rmt1Apa106InvertedMethod NeoApa106InvertedMethod; +typedef NeoEsp32Rmt1Tx1812InvertedMethod NeoTx1812InvertedMethod; + +typedef NeoEsp32Rmt1Ws2812xInvertedMethod Neo800KbpsInvertedMethod; +typedef NeoEsp32Rmt1400KbpsInvertedMethod Neo400KbpsInvertedMethod; + +#else // defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) + +// RMT channel 6 method is the default method for Esp32 +typedef NeoEsp32Rmt6Ws2812xMethod NeoWs2813Method; +typedef NeoEsp32Rmt6Ws2812xMethod NeoWs2812xMethod; +typedef NeoEsp32Rmt6800KbpsMethod NeoWs2812Method; +typedef NeoEsp32Rmt6Ws2812xMethod NeoWs2811Method; +typedef NeoEsp32Rmt6Sk6812Method NeoSk6812Method; +typedef NeoEsp32Rmt6Tm1814Method NeoTm1814Method; +typedef NeoEsp32Rmt6Tm1829Method NeoTm1829Method; +typedef NeoEsp32Rmt6Tm1914Method NeoTm1914Method; +typedef NeoEsp32Rmt6Sk6812Method NeoLc8812Method; +typedef NeoEsp32Rmt6Apa106Method NeoApa106Method; +typedef NeoEsp32Rmt6Tx1812Method NeoTx1812Method; + +typedef NeoEsp32Rmt6Ws2812xMethod Neo800KbpsMethod; +typedef NeoEsp32Rmt6400KbpsMethod Neo400KbpsMethod; + +typedef NeoEsp32Rmt6Ws2812xInvertedMethod NeoWs2813InvertedMethod; +typedef NeoEsp32Rmt6Ws2812xInvertedMethod NeoWs2812xInvertedMethod; +typedef NeoEsp32Rmt6Ws2812xInvertedMethod NeoWs2811InvertedMethod; +typedef NeoEsp32Rmt6800KbpsInvertedMethod NeoWs2812InvertedMethod; +typedef NeoEsp32Rmt6Sk6812InvertedMethod NeoSk6812InvertedMethod; +typedef NeoEsp32Rmt6Tm1814InvertedMethod NeoTm1814InvertedMethod; +typedef NeoEsp32Rmt6Tm1829InvertedMethod NeoTm1829InvertedMethod; +typedef NeoEsp32Rmt6Tm1914InvertedMethod NeoTm1914InvertedMethod; +typedef NeoEsp32Rmt6Sk6812InvertedMethod NeoLc8812InvertedMethod; +typedef NeoEsp32Rmt6Apa106InvertedMethod NeoApa106InvertedMethod; +typedef NeoEsp32Rmt6Tx1812InvertedMethod NeoTx1812InvertedMethod; + +typedef NeoEsp32Rmt6Ws2812xInvertedMethod Neo800KbpsInvertedMethod; +typedef NeoEsp32Rmt6400KbpsInvertedMethod Neo400KbpsInvertedMethod; + +#endif // defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) + +#endif // defined(NEOPIXEL_ESP32_RMT_DEFAULT) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) + +#endif diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32SpiMethod_idf5.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32SpiMethod_idf5.h new file mode 100644 index 000000000000..826d6ef99c47 --- /dev/null +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32SpiMethod_idf5.h @@ -0,0 +1,504 @@ +/*------------------------------------------------------------------------- +NeoPixel library helper functions for Esp32. + +Adaption of Espressif's component library code by Christian Baars + +Written by Michael C. Miller. + +I invest time and resources providing this open source code, +please support me by dontating (see https://github.com/Makuna/NeoPixelBus) + +------------------------------------------------------------------------- +This file is not yet part of the Makuna/NeoPixelBus library. + +NeoPixelBus is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as +published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +NeoPixelBus is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with NeoPixel. If not, see +. +-------------------------------------------------------------------------*/ + +#pragma once + +#if defined(ARDUINO_ARCH_ESP32) + +#if (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6)) && !defined(HSPI_HOST) +// HSPI_HOST depreciated in C3 +#define HSPI_HOST SPI2_HOST +#endif + +#include + +extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); // TODO: Remove all Addlogs + +extern "C" +{ +#include +#include "esp_rom_gpio.h" +#include "driver/spi_master.h" +#include "esp_check.h" +} + +#define LED_STRIP_SPI_DEFAULT_RESOLUTION (25 * 100 * 1000) // 2.5MHz resolution +#define LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE 4 + +#define SPI_BYTES_PER_COLOR_BYTE 3 +#define SPI_BITS_PER_COLOR_BYTE (SPI_BYTES_PER_COLOR_BYTE * 8) + +static const char *TAG = "led_strip_spi"; // TODO: Remove all TAG log stuff + +typedef enum { + LED_MODEL_WS2812, /*!< LED strip model: WS2812 */ + LED_MODEL_SK6812, /*!< LED strip model: SK6812 */ + LED_MODEL_INVALID /*!< Invalid LED strip model */ +} led_model_t; + +typedef enum { + LED_PIXEL_FORMAT_GRB, /*!< Pixel format: GRB */ + LED_PIXEL_FORMAT_GRBW, /*!< Pixel format: GRBW */ + LED_PIXEL_FORMAT_INVALID /*!< Invalid pixel format */ +} led_pixel_format_t; + +typedef struct { + spi_host_device_t spi_host; + spi_device_handle_t spi_device; + uint32_t strip_len; + uint8_t bytes_per_pixel; + uint8_t pixel_buf[]; +} led_strip_spi_obj; + +/** + * @brief LED Strip Configuration + */ +typedef struct { + int strip_gpio_num; /*!< GPIO number that used by LED strip */ + uint32_t max_leds; /*!< Maximum LEDs in a single strip */ + led_pixel_format_t led_pixel_format; /*!< LED pixel format */ + led_model_t led_model; /*!< LED model */ + + struct { + uint32_t invert_out: 1; /*!< Invert output signal */ + } flags; +} led_strip_config_t; + +typedef struct { + spi_clock_source_t clk_src; /*!< SPI clock source */ + spi_host_device_t spi_bus; /*!< SPI bus ID. Which buses are available depends on the specific chip */ + struct { + uint32_t with_dma: 1; /*!< Use DMA to transmit data */ + } flags; +} led_strip_spi_config_t; + + +class NeoEsp32SpiSpeed +{ +public: + + +protected: + +// end of deprecated section + +}; + +class NeoEsp32SpiSpeedBase : public NeoEsp32SpiSpeed +{ +public: + +}; + +class NeoEsp32SpiInvertedSpeedBase : public NeoEsp32SpiSpeed +{ +public: + +}; + +class NeoEsp32SpiSpeedWs2811 : public NeoEsp32SpiSpeedBase +{ +public: + +}; + +class NeoEsp32SpiSpeedWs2812x : public NeoEsp32SpiSpeedBase +{ +public: + static const uint8_t bytes_per_pixel = 3; + +}; + +class NeoEsp32SpiSpeedSk6812 : public NeoEsp32SpiSpeedBase +{ +public: + static const uint8_t bytes_per_pixel = 4; + +}; + +class NeoEsp32SpiSpeed400Kbps : public NeoEsp32SpiSpeedBase +{ +public: + +}; + +class NeoEsp32SpiSpeedApa106 : public NeoEsp32SpiSpeedBase +{ +public: + +}; + +class NeoEsp32SpiSpeedTx1812 : public NeoEsp32SpiSpeedBase +{ +public: + +}; + +class NeoEsp32SpiInvertedSpeedWs2811 : public NeoEsp32SpiInvertedSpeedBase +{ +public: + +}; + +class NeoEsp32SpiInvertedSpeedWs2812x : public NeoEsp32SpiInvertedSpeedBase +{ +public: + +}; + +class NeoEsp32SpiInvertedSpeedSk6812 : public NeoEsp32SpiInvertedSpeedBase +{ +public: + +}; + +class NeoEsp32SpiInvertedSpeed800Kbps : public NeoEsp32SpiInvertedSpeedBase +{ +public: + +}; + +class NeoEsp32SpiInvertedSpeed400Kbps : public NeoEsp32SpiInvertedSpeedBase +{ +public: + +}; + +class NeoEsp32SpiInvertedSpeedApa106 : public NeoEsp32SpiInvertedSpeedBase +{ +public: + +}; + +class NeoEsp32SpiInvertedSpeedTx1812 : public NeoEsp32SpiInvertedSpeedBase +{ +public: + +}; + +class NeoEsp32SpiChannel +{ +public: + +}; + + +template class NeoEsp32SpiMethodBase +{ +public: + typedef NeoNoSettings SettingsObject; + + NeoEsp32SpiMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize) : + _sizeData(pixelCount * elementSize + settingsSize), + // _pixelCount(pixelCount), + _pin(pin) + { + _pixelCount = pixelCount; + construct(); + } + + NeoEsp32SpiMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize, NeoBusChannel channel) : + _sizeData(pixelCount* elementSize + settingsSize), + // _pixelCount(pixelCount), + _pin(pin) + // _channel(channel) // TODO: Refactor this somehow + { + _pixelCount = pixelCount; + construct(); + } + + ~NeoEsp32SpiMethodBase() + { + // wait until the last send finishes before destructing everything + // arbitrary time out of 10 seconds + + gpio_matrix_out(_pin, 0x100, false, false); + pinMode(_pin, INPUT); + + spi_bus_remove_device(_spi_strip->spi_device); + spi_bus_free(_spi_strip->spi_host); + free(_spi_strip); + + free(_dataEditing); + free(_dataSending); + } + + + bool IsReadyToUpdate() const + { + return true; // TODO + } + + void Initialize() + { + esp_err_t ret = ESP_OK; + uint8_t bytes_per_pixel = T_SPEED::bytes_per_pixel; + uint32_t mem_caps = MALLOC_CAP_DEFAULT; + spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT; + spi_bus_config_t spi_bus_cfg; + spi_device_interface_config_t spi_dev_cfg; + bool with_dma = true; /// TODO: pass value or compute based on pixelcount + int clock_resolution_khz = 0; + + // ESP_GOTO_ON_FALSE(led_config && spi_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + // ESP_GOTO_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, err, TAG, "invalid led_pixel_format"); + + // if ( LED_PIXEL_FORMAT_GRB == LED_PIXEL_FORMAT_GRBW) { // TODO + // bytes_per_pixel = 4; + // } else if (LED_PIXEL_FORMAT_GRB == LED_PIXEL_FORMAT_GRB) { + // bytes_per_pixel = 3; + // } else { + // assert(false); + // } + + if (with_dma) { // TODO + // DMA buffer must be placed in internal SRAM + mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA; + } + _spi_strip = (led_strip_spi_obj *)heap_caps_calloc(1, sizeof(led_strip_spi_obj) + _pixelCount * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, mem_caps); + + ESP_GOTO_ON_FALSE(_spi_strip, ESP_ERR_NO_MEM, err, TAG, "no mem for spi strip"); + + _spi_strip->spi_host = SPI2_HOST; + + // for backward compatibility, if the user does not set the clk_src, use the default value + // if (clk_src) { + // clk_src = spi_config->clk_src; + // } + + spi_bus_cfg = { + .mosi_io_num = _pin, + //Only use MOSI to generate the signal, set -1 when other pins are not used. + .miso_io_num = -1, + .sclk_io_num = -1, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = _pixelCount * bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE, + }; + ESP_GOTO_ON_ERROR(spi_bus_initialize(_spi_strip->spi_host, &spi_bus_cfg, with_dma ? SPI_DMA_CH_AUTO : SPI_DMA_DISABLED), err, TAG, "create SPI bus failed"); + + // if (led_config->flags.invert_out == true) { + // esp_rom_gpio_connect_out_signal(_pin, spi_periph_signal[_spi_strip->spi_host].spid_out, true, false); + // } + + spi_dev_cfg = { + .command_bits = 0, + .address_bits = 0, + .dummy_bits = 0, + .mode = 0, + //set -1 when CS is not used + .clock_source = clk_src, + .clock_speed_hz = LED_STRIP_SPI_DEFAULT_RESOLUTION, + .spics_io_num = -1, + .queue_size = LED_STRIP_SPI_DEFAULT_TRANS_QUEUE_SIZE, + }; + + ESP_GOTO_ON_ERROR(spi_bus_add_device(_spi_strip->spi_host, &spi_dev_cfg, &_spi_strip->spi_device), err, TAG, "Failed to add spi device"); + + spi_device_get_actual_freq(_spi_strip->spi_device, &clock_resolution_khz); + // TODO: ideally we should decide the SPI_BYTES_PER_COLOR_BYTE by the real clock resolution + // But now, let's fixed the resolution, the downside is, we don't support a clock source whose frequency is not multiple of LED_STRIP_SPI_DEFAULT_RESOLUTION + ESP_GOTO_ON_FALSE(clock_resolution_khz == LED_STRIP_SPI_DEFAULT_RESOLUTION / 1000, ESP_ERR_NOT_SUPPORTED, err, + TAG, "unsupported clock resolution:%dKHz", clock_resolution_khz); + + _spi_strip->bytes_per_pixel = bytes_per_pixel; + _spi_strip->strip_len = _pixelCount; + + AddLog(2,"SPI:initialized with error code: %u on pin: %u",ret, _pin); + return; + err: + if (_spi_strip) { + if (_spi_strip->spi_device) { + spi_bus_remove_device(_spi_strip->spi_device); + } + if (_spi_strip->spi_host) { + spi_bus_free(_spi_strip->spi_host); + } + free(_spi_strip); + } + AddLog(2,"SPI-Error:initialized with error code: %u on pin: %u",ret, _pin); + return; + } + + void Update(bool maintainBufferConsistency) + { + // AddLog(2,".."); + // wait for not actively sending data + // this will time out at 10 seconds, an arbitrarily long period of time + // and do nothing if this happens + + // if READY + { + // AddLog(2,"__ %u", _sizeData); + // now start the SPI transmit with the editing buffer before we swap + led_strip_transmit_RGB_buffer(_dataEditing, _sizeData, T_SPEED::bytes_per_pixel); + + if (maintainBufferConsistency) + { + // copy editing to sending, + // this maintains the contract that "colors present before will + // be the same after", otherwise GetPixelColor will be inconsistent + memcpy(_dataSending, _dataEditing, _sizeData); + } + + // swap so the user can modify without affecting the async operation + std::swap(_dataSending, _dataEditing); + } + } + + uint8_t* getData() const + { + return _dataEditing; + }; + + size_t getDataSize() const + { + return _sizeData; + } + + void applySettings(const SettingsObject& settings) + { + } + +private: + const size_t _sizeData; // Size of '_data*' buffers + int16_t _pixelCount; + const uint8_t _pin; // output pin number + T_CHANNEL _channel; // not really used here + + led_strip_spi_obj *_spi_strip; + + + // Holds data stream which include LED color values and other settings as needed + uint8_t* _dataEditing; // exposed for get and set + uint8_t* _dataSending; // used for async send using RMT - TODO: Check if this useful for SPI + + + void construct() + { + _dataEditing = static_cast(malloc(_sizeData)); + // data cleared later in Begin() + + _dataSending = static_cast(malloc(_sizeData)); + // no need to initialize it, it gets overwritten on every send + } + + // please make sure to zero-initialize the buf before calling this function + + void __led_strip_spi_bit(uint8_t data, uint8_t *buf) + { + // Each color of 1 bit is represented by 3 bits of SPI, low_level:100 ,high_level:110 + // So a color byte occupies 3 bytes of SPI. + *(buf + 2) |= data & BIT(0) ? BIT(2) | BIT(1) : BIT(2); + *(buf + 2) |= data & BIT(1) ? BIT(5) | BIT(4) : BIT(5); + *(buf + 2) |= data & BIT(2) ? BIT(7) : 0x00; + *(buf + 1) |= BIT(0); + *(buf + 1) |= data & BIT(3) ? BIT(3) | BIT(2) : BIT(3); + *(buf + 1) |= data & BIT(4) ? BIT(6) | BIT(5) : BIT(6); + *(buf + 0) |= data & BIT(5) ? BIT(1) | BIT(0) : BIT(1); + *(buf + 0) |= data & BIT(6) ? BIT(4) | BIT(3) : BIT(4); + *(buf + 0) |= data & BIT(7) ? BIT(7) | BIT(6) : BIT(7); + } + + esp_err_t led_strip_spi_set_pixel(uint32_t index, uint32_t red, uint32_t green, uint32_t blue) + { + if(index >= _spi_strip->strip_len) return ESP_FAIL; + // LED_PIXEL_FORMAT_GRB takes 72bits(9bytes) + uint32_t start = index * _spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; + memset(_spi_strip->pixel_buf + start, 0, _spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + __led_strip_spi_bit(green, &_spi_strip->pixel_buf[start]); + __led_strip_spi_bit(red, &_spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); + __led_strip_spi_bit(blue, &_spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); + if (_spi_strip->bytes_per_pixel > 3) { + __led_strip_spi_bit(0, &_spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); + } + return ESP_OK; + } + + esp_err_t led_strip_spi_set_pixel_rgbw(uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) + { + // LED_PIXEL_FORMAT_GRBW takes 96bits(12bytes) + uint32_t start = index * _spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE; + // SK6812 component order is GRBW + memset(_spi_strip->pixel_buf + start, 0, _spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + __led_strip_spi_bit(green, &_spi_strip->pixel_buf[start]); + __led_strip_spi_bit(red, &_spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE]); + __led_strip_spi_bit(blue, &_spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 2]); + __led_strip_spi_bit(white, &_spi_strip->pixel_buf[start + SPI_BYTES_PER_COLOR_BYTE * 3]); + + return ESP_OK; + } + + esp_err_t led_strip_spi_clear() + { + //Write zero to turn off all leds + memset(_spi_strip->pixel_buf, 0, _spi_strip->strip_len * _spi_strip->bytes_per_pixel * SPI_BYTES_PER_COLOR_BYTE); + uint8_t *buf = _spi_strip->pixel_buf; + for (int index = 0; index < _spi_strip->strip_len * _spi_strip->bytes_per_pixel; index++) { + __led_strip_spi_bit(0, buf); + buf += SPI_BYTES_PER_COLOR_BYTE; + } + return led_strip_spi_refresh(); + } + + esp_err_t led_strip_spi_refresh() + { + spi_transaction_t tx_conf; + memset(&tx_conf, 0, sizeof(tx_conf)); + + tx_conf.length = _spi_strip->strip_len * _spi_strip->bytes_per_pixel * SPI_BITS_PER_COLOR_BYTE; + tx_conf.tx_buffer = _spi_strip->pixel_buf; + tx_conf.rx_buffer = NULL; + spi_device_transmit(_spi_strip->spi_device, &tx_conf); // TODO -check + return ESP_OK; + } + + void led_strip_transmit_RGB_buffer(uint8_t * buffer, size_t size, uint8_t bytes_per_pixel) + { + for (int i = 0; i < size; i+=bytes_per_pixel) { + led_strip_spi_set_pixel(i/bytes_per_pixel, buffer[i+1], buffer[i], buffer[i+2]); //GRB -> RGB + } + /* Refresh the strip to send data */ + led_strip_spi_refresh(); + } +}; + +// normal +typedef NeoEsp32SpiMethodBase NeoEsp32SpiN800KbpsMethod; +typedef NeoEsp32SpiMethodBase NeoEsp32SpiNSk6812Method; + + +// SPI channel method is the default method for Esp32C2 +#ifdef CONFIG_IDF_TARGET_ESP32C2 +typedef NeoEsp32SpiSpeedWs2812x NeoWs2813Method; +typedef NeoEsp32SpiSpeedWs2812x NeoWs2812xMethod; +typedef NeoEsp32SpiSpeedSk6812 NeoSk6812Method; + +#endif //CONFIG_IDF_TARGET_ESP32C2 + +#endif diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.cpp b/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.cpp index 32c069f3d2e1..01499fe13e15 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.cpp +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.cpp @@ -28,8 +28,11 @@ License along with NeoPixel. If not, see #include -// ESP32C3 I2S is not supported yet -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +// ESP32C3 I2S is not supported yet +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) +#if !defined(ARDUINO_ARCH_ESP8266) +#include "soc/gpio_periph.h" +#endif static inline uint32_t getCycleCount(void) { @@ -154,5 +157,5 @@ void IRAM_ATTR NeoEspBitBangBase_send_pixels_inv(uint8_t* pixels, uint8_t* end, } } -#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #endif // defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.h index bfbd13545d7f..44f8654889ff 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.h @@ -29,7 +29,7 @@ License along with NeoPixel. If not, see #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) // ESP32C3 I2S is not supported yet -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #if defined(ARDUINO_ARCH_ESP8266) #include @@ -377,5 +377,5 @@ typedef NeoEsp8266BitBangSk6812InvertedMethod NeoEsp8266BitBangLc8812InvertedMet // ESP bitbang doesn't have defaults and should avoided except for testing -#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #endif // defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) diff --git a/lib/lib_basic/OneWire-Stickbreaker/OneWire.h b/lib/lib_basic/OneWire-Stickbreaker/OneWire.h index c92dda8d0afa..77910ecb9673 100644 --- a/lib/lib_basic/OneWire-Stickbreaker/OneWire.h +++ b/lib/lib_basic/OneWire-Stickbreaker/OneWire.h @@ -147,6 +147,9 @@ #elif defined(ARDUINO_ARCH_ESP32) #include +#if ESP_IDF_VERSION_MAJOR >= 5 +#include "soc/gpio_periph.h" +#endif // ESP_IDF_VERSION_MAJOR >= 5 #define PIN_TO_BASEREG(pin) (0) #define PIN_TO_BITMASK(pin) (pin) #define IO_REG_TYPE uint32_t @@ -156,27 +159,35 @@ static inline __attribute__((always_inline)) IO_REG_TYPE directRead(IO_REG_TYPE pin) { -#if CONFIG_IDF_TARGET_ESP32C3 +// return digitalRead(pin); // Works most of the time +// return gpio_ll_get_level(&GPIO, pin); // The hal is not public api, don't use in application code + +//#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 +#if SOC_GPIO_PIN_COUNT <= 32 return (GPIO.in.val >> pin) & 0x1; -#else // plain ESP32 +#else // ESP32 with over 32 gpios if ( pin < 32 ) return (GPIO.in >> pin) & 0x1; - else if ( pin < 46 ) + else return (GPIO.in1.val >> (pin - 32)) & 0x1; #endif - return 0; + } static inline __attribute__((always_inline)) void directWriteLow(IO_REG_TYPE pin) { -#if CONFIG_IDF_TARGET_ESP32C3 +// digitalWrite(pin, 0); // Works most of the time +// gpio_ll_set_level(&GPIO, pin, 0); // The hal is not public api, don't use in application code + +//#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 +#if SOC_GPIO_PIN_COUNT <= 32 GPIO.out_w1tc.val = ((uint32_t)1 << pin); -#else // plain ESP32 +#else // ESP32 with over 32 gpios if ( pin < 32 ) GPIO.out_w1tc = ((uint32_t)1 << pin); - else if ( pin < 46 ) + else GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32)); #endif } @@ -184,66 +195,63 @@ void directWriteLow(IO_REG_TYPE pin) static inline __attribute__((always_inline)) void directWriteHigh(IO_REG_TYPE pin) { -#if CONFIG_IDF_TARGET_ESP32C3 +// digitalWrite(pin, 1); // Works most of the time +// gpio_ll_set_level(&GPIO, pin, 1); // The hal is not public api, don't use in application code + +//#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 +#if SOC_GPIO_PIN_COUNT <= 32 GPIO.out_w1ts.val = ((uint32_t)1 << pin); -#else // plain ESP32 +#else // ESP32 with over 32 gpios if ( pin < 32 ) GPIO.out_w1ts = ((uint32_t)1 << pin); - else if ( pin < 46 ) + else GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32)); #endif + } static inline __attribute__((always_inline)) void directModeInput(IO_REG_TYPE pin) { -#if CONFIG_IDF_TARGET_ESP32C3 - GPIO.enable_w1tc.val = ((uint32_t)1 << (pin)); -#else +// pinMode(pin, INPUT); // Too slow - doesn't work +// gpio_ll_output_disable(&GPIO, pin); // The hal is not public api, don't use in application code + if ( digitalPinIsValid(pin) ) { -#if ESP_IDF_VERSION_MAJOR < 4 // IDF 3.x ESP32/PICO-D4 - uint32_t rtc_reg(rtc_gpio_desc[pin].reg); - - if ( rtc_reg ) // RTC pins PULL settings - { - ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux); - ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown); - } -#endif // Input +//#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 +#if SOC_GPIO_PIN_COUNT <= 32 + GPIO.enable_w1tc.val = ((uint32_t)1 << (pin)); +#else // ESP32 with over 32 gpios if ( pin < 32 ) GPIO.enable_w1tc = ((uint32_t)1 << pin); else GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32)); - } #endif + } + } static inline __attribute__((always_inline)) void directModeOutput(IO_REG_TYPE pin) { -#if CONFIG_IDF_TARGET_ESP32C3 - GPIO.enable_w1ts.val = ((uint32_t)1 << (pin)); -#else - if ( digitalPinIsValid(pin) && pin <= 33 ) // pins above 33 can be only inputs +// pinMode(pin, OUTPUT); // Too slow - doesn't work +// gpio_ll_output_enable(&GPIO, pin); // The hal is not public api, don't use in application code + + if ( digitalPinCanOutput(pin) ) { -#if ESP_IDF_VERSION_MAJOR < 4 // IDF 3.x ESP32/PICO-D4 - uint32_t rtc_reg(rtc_gpio_desc[pin].reg); - - if ( rtc_reg ) // RTC pins PULL settings - { - ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux); - ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown); - } -#endif // Output +//#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 +#if SOC_GPIO_PIN_COUNT <= 32 + GPIO.enable_w1ts.val = ((uint32_t)1 << (pin)); +#else // ESP32 with over 32 gpios if ( pin < 32 ) GPIO.enable_w1ts = ((uint32_t)1 << pin); - else // already validated to pins <= 33 + else GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32)); - } #endif + } + } #define DIRECT_READ(base, pin) directRead(pin) @@ -251,7 +259,6 @@ void directModeOutput(IO_REG_TYPE pin) #define DIRECT_WRITE_HIGH(base, pin) directWriteHigh(pin) #define DIRECT_MODE_INPUT(base, pin) directModeInput(pin) #define DIRECT_MODE_OUTPUT(base, pin) directModeOutput(pin) -//#warning "ESP32 OneWire testing" #elif defined(__SAMD21G18A__) #define PIN_TO_BASEREG(pin) portModeRegister(digitalPinToPort(pin)) diff --git a/lib/lib_basic/TasmotaModbus-3.6.0/src/TasmotaModbus.cpp b/lib/lib_basic/TasmotaModbus-3.6.0/src/TasmotaModbus.cpp index 2e2fef4f83e3..69971cc0c718 100644 --- a/lib/lib_basic/TasmotaModbus-3.6.0/src/TasmotaModbus.cpp +++ b/lib/lib_basic/TasmotaModbus-3.6.0/src/TasmotaModbus.cpp @@ -79,6 +79,11 @@ uint8_t TasmotaModbus::Send(uint8_t device_address, uint8_t function_code, uint1 uint8_t *frame; uint8_t framepointer = 0; +#ifdef TASMOTAMODBUSDEBUG + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: Serial Send: @%02X f:%02X r:%04X c:%u &:%08X"), device_address, function_code, start_address, count, (uint32)write_data); + if (write_data) AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: Serial Send: Write data 0x%04X"), write_data[0]); +#endif + uint16_t byte_count = count * 2; // In register mode count is nr of registers (2 bytes) if ((function_code == 1) || (function_code == 2) || (function_code == 15)) byte_count = ((count-1) / 8) + 1; // In bitmode count is nr of bits @@ -107,11 +112,17 @@ uint8_t TasmotaModbus::Send(uint8_t device_address, uint8_t function_code, uint1 if (write_data == NULL) { free(frame); +#ifdef TASMOTAMODBUSDEBUG + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: Serial Send: no data (13.1)")); +#endif return 13; // Register data not specified } if (count != 1) { free(frame); +#ifdef TASMOTAMODBUSDEBUG + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: Serial Send: wrong count (12.1)")); +#endif return 12; // Wrong register count } frame[framepointer++] = (uint8_t)(write_data[0] >> 8); // MSB @@ -127,11 +138,17 @@ uint8_t TasmotaModbus::Send(uint8_t device_address, uint8_t function_code, uint1 if (write_data == NULL) { free(frame); +#ifdef TASMOTAMODBUSDEBUG + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: Serial Send: no data (13.2)")); +#endif return 13; // Register data not specified } if (count == 0) { free(frame); +#ifdef TASMOTAMODBUSDEBUG + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: Serial Send: wrong count (12.2)")); +#endif return 12; // Wrong register count } for (uint16_t bytepointer = 0; bytepointer < byte_count; bytepointer++) @@ -142,6 +159,9 @@ uint8_t TasmotaModbus::Send(uint8_t device_address, uint8_t function_code, uint1 else { free(frame); +#ifdef TASMOTAMODBUSDEBUG + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: Serial Send: wrong fct (1)")); +#endif return 1; // Wrong function code } diff --git a/lib/lib_display/UDisplay/uDisplay.cpp b/lib/lib_display/UDisplay/uDisplay.cpp index 66ab35bac67d..2f48351cc274 100755 --- a/lib/lib_display/UDisplay/uDisplay.cpp +++ b/lib/lib_display/UDisplay/uDisplay.cpp @@ -945,7 +945,11 @@ Renderer *uDisplay::Init(void) { _panel_config->disp_gpio_num = GPIO_NUM_NC; _panel_config->flags.disp_active_low = 0; +#if ESP_IDF_VERSION_MAJOR >= 5 + _panel_config->flags.refresh_on_demand = 0; +#else _panel_config->flags.relax_on_idle = 0; +#endif // ESP_IDF_VERSION_MAJOR >= 5 _panel_config->flags.fb_in_psram = 1; // allocate frame buffer in PSRAM ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(_panel_config, &_panel_handle)); @@ -955,9 +959,16 @@ Renderer *uDisplay::Init(void) { uint16_t color = random(0xffff); ESP_ERROR_CHECK(_panel_handle->draw_bitmap(_panel_handle, 0, 0, 1, 1, &color)); +#if ESP_IDF_VERSION_MAJOR < 5 _rgb_panel = __containerof(_panel_handle, esp_rgb_panel_t, base); - rgb_fb = (uint16_t *)_rgb_panel->fb; +#else + void * buf = NULL; + esp_lcd_rgb_panel_get_frame_buffer(_panel_handle, 1, &buf); + rgb_fb = (uint16_t *)buf; +#endif + + #endif // USE_ESP32_S3 } @@ -1032,12 +1043,14 @@ Renderer *uDisplay::Init(void) { esp_lcd_new_i80_bus(&bus_config, &_i80_bus); +#if ESP_IDF_VERSION_MAJOR < 5 _dma_chan = _i80_bus->dma_chan; +#endif uint32_t div_a, div_b, div_n, clkcnt; calcClockDiv(&div_a, &div_b, &div_n, &clkcnt, 240*1000*1000, spi_speed*1000000); lcd_cam_lcd_clock_reg_t lcd_clock; - lcd_clock.lcd_clkcnt_n = std::max(1u, clkcnt - 1); + lcd_clock.lcd_clkcnt_n = std::max((uint32_t)1u, clkcnt - 1); // ESP_IDF_VERSION_MAJOR >= 5 lcd_clock.lcd_clk_equ_sysclk = (clkcnt == 1); lcd_clock.lcd_ck_idle_edge = true; lcd_clock.lcd_ck_out_edge = false; diff --git a/lib/lib_display/UDisplay/uDisplay.h b/lib/lib_display/UDisplay/uDisplay.h index 2f11044f1a40..88bcdce6f5dd 100755 --- a/lib/lib_display/UDisplay/uDisplay.h +++ b/lib/lib_display/UDisplay/uDisplay.h @@ -6,15 +6,15 @@ #include #include - #ifdef ESP32 #ifdef CONFIG_IDF_TARGET_ESP32S3 #define USE_ESP32_S3 #endif -#endif - -#ifdef ESP32 #include "driver/spi_master.h" +#if ESP_IDF_VERSION_MAJOR >= 5 +#include "soc/gpio_periph.h" +#include +#endif // ESP_IDF_VERSION_MAJOR >= 5 #endif #ifdef USE_ESP32_S3 @@ -37,6 +37,9 @@ static inline void gpio_lo(int_fast8_t pin) { if (pin >= 0) *get_gpio_lo_reg(pin #include "esp_lcd_panel_ops.h" #include #include +#if ESP_IDF_VERSION_MAJOR >= 5 +#include "esp_rom_lldesc.h" +#endif // ESP_IDF_VERSION_MAJOR >= 5 #endif // USE_ESP32_S3 #define _UDSP_I2C 1 @@ -89,13 +92,16 @@ enum uColorType { uCOLOR_BW, uCOLOR_COLOR }; #undef GPIO_CLR #undef GPIO_SET_SLOW #undef GPIO_CLR_SLOW -#if CONFIG_IDF_TARGET_ESP32C3 + +#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 #define GPIO_CLR(A) GPIO.out_w1tc.val = (1 << A) #define GPIO_SET(A) GPIO.out_w1ts.val = (1 << A) #else // plain ESP32 #define GPIO_CLR(A) GPIO.out_w1tc = (1 << A) #define GPIO_SET(A) GPIO.out_w1ts = (1 << A) #endif + + #define GPIO_CLR_SLOW(A) digitalWrite(A, LOW) #define GPIO_SET_SLOW(A) digitalWrite(A, HIGH) @@ -110,7 +116,7 @@ enum uColorType { uCOLOR_BW, uCOLOR_COLOR }; #define SPI_DC_HIGH if (spi_dc >= 0) GPIO_SET_SLOW(spi_dc); -#ifdef USE_ESP32_S3 +#if defined(USE_ESP32_S3) && ESP_IDF_VERSION_MAJOR < 5 struct esp_lcd_i80_bus_t { int bus_id; // Bus ID, index from 0 portMUX_TYPE spinlock; // spinlock used to protect i80 bus members(hal, device_list, cur_trans) @@ -143,7 +149,9 @@ struct esp_rgb_panel_t size_t resolution_hz; // Peripheral clock resolution esp_lcd_rgb_timing_t timings; // RGB timing parameters (e.g. pclk, sync pulse, porch width) gdma_channel_handle_t dma_chan; // DMA channel handle +#if ESP_IDF_VERSION_MAJOR < 5 esp_lcd_rgb_panel_frame_trans_done_cb_t on_frame_trans_done; // Callback, invoked after frame trans done +#endif // ESP_IDF_VERSION_MAJOR < 5 void *user_ctx; // Reserved user's data of callback functions int x_gap; // Extra gap in x coordinate, it's used when calculate the flush window int y_gap; // Extra gap in y coordinate, it's used when calculate the flush window @@ -155,8 +163,7 @@ struct esp_rgb_panel_t } flags; dma_descriptor_t dma_nodes[]; // DMA descriptor pool of size `num_dma_nodes` }; - -#endif +#endif //USE_ESP32_S3 && ESP_IDF_VERSION_MAJOR < 5 class uDisplay : public Renderer { @@ -352,7 +359,9 @@ class uDisplay : public Renderer { uint16_t pclk_active_neg; esp_lcd_panel_handle_t _panel_handle = NULL; +#if ESP_IDF_VERSION_MAJOR < 5 esp_rgb_panel_t *_rgb_panel; +#endif //ESP_IDF_VERSION_MAJOR < 5 uint16_t *rgb_fb; diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/documentation/ZFM-20_Fingerprint_Module.pdf b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/documentation/ZFM-20_Fingerprint_Module.pdf deleted file mode 100644 index d732b8280576..000000000000 Binary files a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/documentation/ZFM-20_Fingerprint_Module.pdf and /dev/null differ diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/.github/ISSUE_TEMPLATE.md b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/.github/ISSUE_TEMPLATE.md similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/.github/ISSUE_TEMPLATE.md rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/.github/ISSUE_TEMPLATE.md diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/.github/PULL_REQUEST_TEMPLATE.md b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/.github/PULL_REQUEST_TEMPLATE.md rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/.github/PULL_REQUEST_TEMPLATE.md diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/.github/workflows/githubci.yml b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/.github/workflows/githubci.yml similarity index 75% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/.github/workflows/githubci.yml rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/.github/workflows/githubci.yml index e4395824eadd..04285ca58442 100644 --- a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/.github/workflows/githubci.yml +++ b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/.github/workflows/githubci.yml @@ -5,7 +5,11 @@ on: [pull_request, push, repository_dispatch] jobs: build: runs-on: ubuntu-latest - + strategy: + fail-fast: false + matrix: + arduino-platform: ["uno", "leonardo", "mega2560", "zero", "esp8266", "esp32", "metro_m4", "trinket_m0"] + steps: - uses: actions/setup-python@v1 with: @@ -20,7 +24,7 @@ jobs: run: bash ci/actions_install.sh - name: test platforms - run: python3 ci/build_platform.py main_platforms + run: python3 ci/build_platform.py ${{ matrix.arduino-platform }} - name: clang run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/.gitignore b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/.gitignore similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/.gitignore rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/.gitignore diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/Adafruit_Fingerprint.cpp b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/Adafruit_Fingerprint.cpp similarity index 89% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/Adafruit_Fingerprint.cpp rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/Adafruit_Fingerprint.cpp index fadc5a164624..d48545df56df 100644 --- a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/Adafruit_Fingerprint.cpp +++ b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/Adafruit_Fingerprint.cpp @@ -64,6 +64,7 @@ /**************************************************************************/ //Adafruit_Fingerprint::Adafruit_Fingerprint(SoftwareSerial *ss, Adafruit_Fingerprint::Adafruit_Fingerprint(TasmotaSerial *ss, + uint32_t password) { thePassword = password; theAddress = 0xFFFFFFFF; @@ -413,10 +414,64 @@ uint8_t Adafruit_Fingerprint::getTemplateCount(void) { */ /**************************************************************************/ uint8_t Adafruit_Fingerprint::setPassword(uint32_t password) { - SEND_CMD_PACKET(FINGERPRINT_SETPASSWORD, (uint8_t)(password >> 24), (uint8_t)(password >> 16), - (uint8_t)(password >> 8), (uint8_t)password); + SEND_CMD_PACKET(FINGERPRINT_SETPASSWORD, (uint8_t)(password >> 24), + (uint8_t)(password >> 16), (uint8_t)(password >> 8), + (uint8_t)(password & 0xFF)); +} + +/**************************************************************************/ +/*! + @brief Writing module registers + @param regAdd 8-bit address of register + @param value 8-bit value will write to register + @returns FINGERPRINT_OK on success + @returns FINGERPRINT_PACKETRECIEVEERR on communication error + @returns FINGERPRINT_ADDRESS_ERROR on register address error +*/ +/**************************************************************************/ +uint8_t Adafruit_Fingerprint::writeRegister(uint8_t regAdd, uint8_t value) { + + SEND_CMD_PACKET(FINGERPRINT_WRITE_REG, regAdd, value); +} + +/**************************************************************************/ +/*! + @brief Change UART baudrate + @param baudrate 8-bit Uart baudrate + @returns FINGERPRINT_OK on success + @returns FINGERPRINT_PACKETRECIEVEERR on communication error +*/ +/**************************************************************************/ +uint8_t Adafruit_Fingerprint::setBaudRate(uint8_t baudrate) { + + return (writeRegister(FINGERPRINT_BAUD_REG_ADDR, baud_rate)); } +/**************************************************************************/ +/*! + @brief Change security level + @param level 8-bit security level + @returns FINGERPRINT_OK on success + @returns FINGERPRINT_PACKETRECIEVEERR on communication error +*/ +/**************************************************************************/ +uint8_t Adafruit_Fingerprint::setSecurityLevel(uint8_t level) { + + return (writeRegister(FINGERPRINT_SECURITY_REG_ADDR, level)); +} + +/**************************************************************************/ +/*! + @brief Change packet size + @param size 8-bit packet size + @returns FINGERPRINT_OK on success + @returns FINGERPRINT_PACKETRECIEVEERR on communication error +*/ +/**************************************************************************/ +uint8_t Adafruit_Fingerprint::setPacketSize(uint8_t size) { + + return (writeRegister(FINGERPRINT_PACKET_REG_ADDR, size)); +} /**************************************************************************/ /*! @brief Helper function to process a packet and send it over UART to the @@ -559,6 +614,9 @@ Adafruit_Fingerprint::getStructuredPacket(Adafruit_Fingerprint_Packet *packet, break; } idx++; + if ((idx + 9) >= sizeof(packet->data)) { + return FINGERPRINT_BADPACKET; + } } // Shouldn't get here so... return FINGERPRINT_BADPACKET; diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/Adafruit_Fingerprint.h b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/Adafruit_Fingerprint.h similarity index 80% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/Adafruit_Fingerprint.h rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/Adafruit_Fingerprint.h index 604386f6322a..b64c3207c9c6 100644 --- a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/Adafruit_Fingerprint.h +++ b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/Adafruit_Fingerprint.h @@ -87,7 +87,40 @@ #define FINGERPRINT_LED_GRADUAL_OFF 0x06 //!< Gradually off #define FINGERPRINT_LED_RED 0x01 //!< Red LED #define FINGERPRINT_LED_BLUE 0x02 //!< Blue LED -#define FINGERPRINT_LED_PURPLE 0x03 //!< Purple LED +#define FINGERPRINT_LED_PURPLE 0x03 //!< Purple LEDpassword + +#define FINGERPRINT_REG_ADDR_ERROR 0x1A //!< shows register address error +#define FINGERPRINT_WRITE_REG 0x0E //!< Write system register instruction + +#define FINGERPRINT_BAUD_REG_ADDR 0x4 //!< BAUDRATE register address +#define FINGERPRINT_BAUDRATE_9600 0x1 //!< UART baud 9600 +#define FINGERPRINT_BAUDRATE_19200 0x2 //!< UART baud 19200 +#define FINGERPRINT_BAUDRATE_28800 0x3 //!< UART baud 28800 +#define FINGERPRINT_BAUDRATE_38400 0x4 //!< UART baud 38400 +#define FINGERPRINT_BAUDRATE_48000 0x5 //!< UART baud 48000 +#define FINGERPRINT_BAUDRATE_57600 0x6 //!< UART baud 57600 +#define FINGERPRINT_BAUDRATE_67200 0x7 //!< UART baud 67200 +#define FINGERPRINT_BAUDRATE_76800 0x8 //!< UART baud 76800 +#define FINGERPRINT_BAUDRATE_86400 0x9 //!< UART baud 86400 +#define FINGERPRINT_BAUDRATE_96000 0xA //!< UART baud 96000 +#define FINGERPRINT_BAUDRATE_105600 0xB //!< UART baud 105600 +#define FINGERPRINT_BAUDRATE_115200 0xC //!< UART baud 115200 + +#define FINGERPRINT_SECURITY_REG_ADDR 0x5 //!< Security level register address +// The safety level is 1 The highest rate of false recognition , The rejection +// rate is the lowest . The safety level is 5 The lowest tate of false +// recognition, The rejection rate is the highest . +#define FINGERPRINT_SECURITY_LEVEL_1 0X1 //!< Security level 1 +#define FINGERPRINT_SECURITY_LEVEL_2 0X2 //!< Security level 2 +#define FINGERPRINT_SECURITY_LEVEL_3 0X3 //!< Security level 3 +#define FINGERPRINT_SECURITY_LEVEL_4 0X4 //!< Security level 4 +#define FINGERPRINT_SECURITY_LEVEL_5 0X5 //!< Security level 5 + +#define FINGERPRINT_PACKET_REG_ADDR 0x6 //!< Packet size register address +#define FINGERPRINT_PACKET_SIZE_32 0X0 //!< Packet size is 32 Byte +#define FINGERPRINT_PACKET_SIZE_64 0X1 //!< Packet size is 64 Byte +#define FINGERPRINT_PACKET_SIZE_128 0X2 //!< Packet size is 128 Byte +#define FINGERPRINT_PACKET_SIZE_256 0X3 //!< Packet size is 256 Byte //#define FINGERPRINT_DEBUG @@ -158,6 +191,10 @@ class Adafruit_Fingerprint { uint8_t LEDcontrol(uint8_t control, uint8_t speed, uint8_t coloridx, uint8_t count = 0); + uint8_t setBaudRate(uint8_t baudrate); + uint8_t setSecurityLevel(uint8_t level); + uint8_t setPacketSize(uint8_t size); + void writeStructuredPacket(const Adafruit_Fingerprint_Packet &p); uint8_t getStructuredPacket(Adafruit_Fingerprint_Packet *p, uint16_t timeout = DEFAULTTIMEOUT); @@ -181,6 +218,7 @@ class Adafruit_Fingerprint { private: uint8_t checkPassword(void); + uint8_t writeRegister(uint8_t regAdd, uint8_t value); uint32_t thePassword; uint32_t theAddress; uint8_t recvPacket[20]; diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/README.md b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/README.md similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/README.md rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/README.md diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/documentation/ZFM-20_Fingerprint_Module.pdf b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/documentation/ZFM-20_Fingerprint_Module.pdf new file mode 100644 index 000000000000..0fa776828935 Binary files /dev/null and b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/documentation/ZFM-20_Fingerprint_Module.pdf differ diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/documentation/fingerprint_en.pdf b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/documentation/fingerprint_en.pdf similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/documentation/fingerprint_en.pdf rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/documentation/fingerprint_en.pdf diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/documentation/readme.txt b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/documentation/readme.txt similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/documentation/readme.txt rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/documentation/readme.txt diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/Leo_passthru/.uno.test.skip b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/Leo_passthru/.uno.test.skip similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/Leo_passthru/.uno.test.skip rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/Leo_passthru/.uno.test.skip diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/Leo_passthru/Leo_passthru.ino b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/Leo_passthru/Leo_passthru.ino similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/Leo_passthru/Leo_passthru.ino rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/Leo_passthru/Leo_passthru.ino diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/blank/blank.ino b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/blank/blank.ino similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/blank/blank.ino rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/blank/blank.ino diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/changepassword/changepassword.ino b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/changepassword/changepassword.ino similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/changepassword/changepassword.ino rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/changepassword/changepassword.ino diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/delete/delete.ino b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/delete/delete.ino similarity index 97% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/delete/delete.ino rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/delete/delete.ino index 563b4b719cf3..107906d4e687 100644 --- a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/delete/delete.ino +++ b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/delete/delete.ino @@ -86,15 +86,13 @@ uint8_t deleteFingerprint(uint8_t id) { Serial.println("Deleted!"); } else if (p == FINGERPRINT_PACKETRECIEVEERR) { Serial.println("Communication error"); - return p; } else if (p == FINGERPRINT_BADLOCATION) { Serial.println("Could not delete in that location"); - return p; } else if (p == FINGERPRINT_FLASHERR) { Serial.println("Error writing to flash"); - return p; } else { Serial.print("Unknown error: 0x"); Serial.println(p, HEX); - return p; } + + return p; } diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/emptyDatabase/emptyDatabase.ino b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/emptyDatabase/emptyDatabase.ino similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/emptyDatabase/emptyDatabase.ino rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/emptyDatabase/emptyDatabase.ino diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/enroll/enroll.ino b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/enroll/enroll.ino similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/enroll/enroll.ino rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/enroll/enroll.ino diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/fingerprint/fingerprint.ino b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/fingerprint/fingerprint.ino similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/fingerprint/fingerprint.ino rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/fingerprint/fingerprint.ino diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/ledcontrol/ledcontrol.ino b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/ledcontrol/ledcontrol.ino similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/ledcontrol/ledcontrol.ino rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/ledcontrol/ledcontrol.ino diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/show_fingerprint_templates/show_fingerprint_templates.ino b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/show_fingerprint_templates/show_fingerprint_templates.ino similarity index 75% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/show_fingerprint_templates/show_fingerprint_templates.ino rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/show_fingerprint_templates/show_fingerprint_templates.ino index f180220238e4..d4f2a2d610a7 100644 --- a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/examples/show_fingerprint_templates/show_fingerprint_templates.ino +++ b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/examples/show_fingerprint_templates/show_fingerprint_templates.ino @@ -33,7 +33,7 @@ int getFingerprintIDez(); void setup() { - while(!Serial); + while (!Serial); Serial.begin(9600); Serial.println("Fingerprint template extractor"); @@ -78,7 +78,7 @@ uint8_t downloadFingerprintTemplate(uint16_t id) case FINGERPRINT_OK: Serial.print("Template "); Serial.print(id); Serial.println(" transferring:"); break; - default: + default: Serial.print("Unknown error "); Serial.println(p); return p; } @@ -90,9 +90,9 @@ uint8_t downloadFingerprintTemplate(uint16_t id) uint32_t starttime = millis(); int i = 0; while (i < 534 && (millis() - starttime) < 20000) { - if (mySerial.available()) { - bytesReceived[i++] = mySerial.read(); - } + if (mySerial.available()) { + bytesReceived[i++] = mySerial.read(); + } } Serial.print(i); Serial.println(" bytes read."); Serial.println("Decoding packet..."); @@ -102,42 +102,41 @@ uint8_t downloadFingerprintTemplate(uint16_t id) // filtering only the data packets int uindx = 9, index = 0; - while (index < 534) { - while (index < uindx) ++index; - uindx += 256; - while (index < uindx) { - fingerTemplate[index++] = bytesReceived[index]; - } - uindx += 2; - while (index < uindx) ++index; - uindx = index + 9; - } + memcpy(fingerTemplate + index, bytesReceived + uindx, 256); // first 256 bytes + uindx += 256; // skip data + uindx += 2; // skip checksum + uindx += 9; // skip next header + index += 256; // advance pointer + memcpy(fingerTemplate + index, bytesReceived + uindx, 256); // second 256 bytes + for (int i = 0; i < 512; ++i) { - //Serial.print("0x"); - printHex(fingerTemplate[i], 2); - //Serial.print(", "); + //Serial.print("0x"); + printHex(fingerTemplate[i], 2); + //Serial.print(", "); } Serial.println("\ndone."); + return p; + /* - uint8_t templateBuffer[256]; - memset(templateBuffer, 0xff, 256); //zero out template buffer - int index=0; - uint32_t starttime = millis(); - while ((index < 256) && ((millis() - starttime) < 1000)) - { + uint8_t templateBuffer[256]; + memset(templateBuffer, 0xff, 256); //zero out template buffer + int index=0; + uint32_t starttime = millis(); + while ((index < 256) && ((millis() - starttime) < 1000)) + { if (mySerial.available()) { templateBuffer[index] = mySerial.read(); index++; } - } + } - Serial.print(index); Serial.println(" bytes read"); + Serial.print(index); Serial.println(" bytes read"); - //dump entire templateBuffer. This prints out 16 lines of 16 bytes - for (int count= 0; count < 16; count++) - { + //dump entire templateBuffer. This prints out 16 lines of 16 bytes + for (int count= 0; count < 16; count++) + { for (int i = 0; i < 16; i++) { Serial.print("0x"); @@ -145,22 +144,21 @@ uint8_t downloadFingerprintTemplate(uint16_t id) Serial.print(", "); } Serial.println(); - }*/ + }*/ } void printHex(int num, int precision) { - char tmp[16]; - char format[128]; + char tmp[16]; + char format[128]; - sprintf(format, "%%.%dX", precision); + sprintf(format, "%%.%dX", precision); - sprintf(tmp, format, num); - Serial.print(tmp); + sprintf(tmp, format, num); + Serial.print(tmp); } void loop() {} - diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/library.properties b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/library.properties similarity index 96% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/library.properties rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/library.properties index d5c86812e316..b435fecb999d 100644 --- a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/library.properties +++ b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/library.properties @@ -1,5 +1,5 @@ name=Adafruit Fingerprint Sensor Library -version=2.0.4 +version=2.1.0 author=Adafruit maintainer=Adafruit sentence=Arduino library for interfacing to the fingerprint sensor in the Adafruit shop diff --git a/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/license.txt b/lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/license.txt similarity index 100% rename from lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.0.4-Tasmota/license.txt rename to lib/lib_div/Adafruit-Fingerprint-Sensor-Library-2.1.0-Tasmota/license.txt diff --git a/lib/lib_div/rfid-1.4.7/src/MFRC522Extended.cpp b/lib/lib_div/rfid-1.4.7/src/MFRC522Extended.cpp index da603ab7789e..fcf030f9bba4 100644 --- a/lib/lib_div/rfid-1.4.7/src/MFRC522Extended.cpp +++ b/lib/lib_div/rfid-1.4.7/src/MFRC522Extended.cpp @@ -821,7 +821,7 @@ MFRC522::StatusCode MFRC522Extended::TCL_Transceive(TagInfo *tag, byte *sendData // Swap block number on success tag->blockNumber = !tag->blockNumber; - if (backData && (backLen > 0)) { + if (backData && (backLen != 0)) { if (*backLen < in.inf.size) return STATUS_NO_ROOM; @@ -844,7 +844,7 @@ MFRC522::StatusCode MFRC522Extended::TCL_Transceive(TagInfo *tag, byte *sendData if (result != STATUS_OK) return result; - if (backData && (backLen > 0)) { + if (backData && (backLen != 0)) { if ((*backLen + ackDataSize) > totalBackLen) return STATUS_NO_ROOM; diff --git a/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp b/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp index 1cd9a9de3d89..57a0a67a92d1 100644 --- a/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp +++ b/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp @@ -214,7 +214,7 @@ void Adafruit_TSL2591::setGain(tsl2591Gain_t gain) enable(); _gain = gain; - write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain); + write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, static_cast(_integration) | static_cast(_gain)); disable(); } @@ -245,7 +245,7 @@ void Adafruit_TSL2591::setTiming(tsl2591IntegrationTime_t integration) enable(); _integration = integration; - write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain); + write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, static_cast(_integration) | static_cast(_gain)); disable(); } diff --git a/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.cpp b/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.cpp index f0e324eb8ede..a44a9cd324d4 100644 --- a/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.cpp +++ b/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.cpp @@ -47,7 +47,7 @@ bool Tsl2561::begin() { bool Tsl2561::readByte( register_t reg, uint8_t &val ) { _wire.beginTransmission(_addr); - _wire.write(reg | CONTROL_CMD); + _wire.write(reg | static_cast(CONTROL_CMD)); if( (_status = static_cast(_wire.endTransmission(false))) == ERR_OK ) { if( _wire.requestFrom(_addr, 1) == 1 ) { val = static_cast(_wire.read()); @@ -61,7 +61,7 @@ bool Tsl2561::readByte( register_t reg, uint8_t &val ) { bool Tsl2561::readWord( register_t reg, uint16_t &val ) { _wire.beginTransmission(_addr); - _wire.write(reg | CONTROL_CMD); + _wire.write(reg | static_cast(CONTROL_CMD)); if( (_status = static_cast(_wire.endTransmission(false))) == ERR_OK ) { if( _wire.requestFrom(_addr, 2) == 2 ) { val = static_cast(_wire.read()) & 0xff; @@ -76,7 +76,7 @@ bool Tsl2561::readWord( register_t reg, uint16_t &val ) { bool Tsl2561::writeByte( register_t reg, uint8_t val ) { _wire.beginTransmission(_addr); - _wire.write(reg | CONTROL_CMD); + _wire.write(reg | static_cast(CONTROL_CMD)); _wire.write(val); return (_status = static_cast(_wire.endTransmission())) == ERR_OK; } @@ -118,7 +118,7 @@ bool Tsl2561::off() { } bool Tsl2561::setSensitivity( bool gain, exposure_t exposure ) { - return writeByte(REG_TIMING, (gain ? GAIN_ON : GAIN_OFF) | exposure); + return writeByte(REG_TIMING, (gain ? GAIN_ON : GAIN_OFF) | static_cast(exposure)); } bool Tsl2561::getSensitivity( bool &gain, exposure_t &exposure ) diff --git a/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.h b/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.h index 147db2a7769d..84f86ee2729c 100644 --- a/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.h +++ b/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.h @@ -42,7 +42,7 @@ class Tsl2561 { ADDR_VDD = 0b1001001 } address_t; - typedef enum { + typedef enum : uint8_t { REG_CONTROL, // Control of basic functions REG_TIMING, // Integration time/gain control REG_THRESHLOWLOW, // Low byte of low interrupt threshold @@ -61,7 +61,7 @@ class Tsl2561 { REG_DATA1HIGH // High byte of ADC channel 1 } register_t; - enum { + enum : uint8_t{ CONTROL_CMD = 0b10000000, CONTROL_CLEAR = 0b01000000, CONTROL_WORD = 0b00100000, // SPI only? diff --git a/lib/lib_i2c/Sensirion_Core/src/SensirionI2CCommunication.cpp b/lib/lib_i2c/Sensirion_Core/src/SensirionI2CCommunication.cpp index 2d8b7acabe69..b95502c4764e 100644 --- a/lib/lib_i2c/Sensirion_Core/src/SensirionI2CCommunication.cpp +++ b/lib/lib_i2c/Sensirion_Core/src/SensirionI2CCommunication.cpp @@ -52,7 +52,7 @@ uint16_t SensirionI2CCommunication::sendFrame(uint8_t address, size_t writtenBytes = i2cBus.write(frame._buffer, frame._index); uint8_t i2c_error = i2cBus.endTransmission(); if (writtenBytes != frame._index) { - return WriteError | I2cOtherError; + return static_cast(WriteError) | static_cast(I2cOtherError); } // translate Arduino errors, see // https://www.arduino.cc/en/Reference/WireEndTransmission @@ -60,13 +60,13 @@ uint16_t SensirionI2CCommunication::sendFrame(uint8_t address, case 0: return NoError; case 1: - return WriteError | InternalBufferSizeError; + return static_cast(WriteError) | static_cast(InternalBufferSizeError); case 2: - return WriteError | I2cAddressNack; + return static_cast(WriteError) | static_cast(I2cAddressNack); case 3: - return WriteError | I2cDataNack; + return static_cast(WriteError) | static_cast(I2cDataNack); default: - return WriteError | I2cOtherError; + return static_cast(WriteError) | static_cast(I2cOtherError); } } @@ -89,19 +89,19 @@ uint16_t SensirionI2CCommunication::receiveFrame(uint8_t address, #endif if (numBytes % 3) { - return ReadError | WrongNumberBytesError; + return static_cast(ReadError) | static_cast(WrongNumberBytesError); } if ((numBytes / 3) * 2 > frame._bufferSize) { - return ReadError | BufferSizeError; + return static_cast(ReadError) | static_cast(BufferSizeError); } if (numBytes > sizeBuffer) { - return ReadError | InternalBufferSizeError; + return static_cast(ReadError) | static_cast(InternalBufferSizeError); } readAmount = i2cBus.requestFrom(address, static_cast(numBytes), static_cast(true)); if (numBytes != readAmount) { - return ReadError | NotEnoughDataError; + return static_cast(ReadError) | static_cast(NotEnoughDataError); } do { frame._buffer[i++] = i2cBus.read(); @@ -110,7 +110,7 @@ uint16_t SensirionI2CCommunication::receiveFrame(uint8_t address, uint8_t expectedCRC = generateCRC(&frame._buffer[i - 2], 2, poly); if (actualCRC != expectedCRC) { clearRxBuffer(i2cBus); - return ReadError | CRCError; + return static_cast(ReadError) | static_cast(CRCError); } readAmount -= 3; } while (readAmount > 0); diff --git a/lib/lib_i2c/Sensirion_Core/src/SensirionI2CTxFrame.cpp b/lib/lib_i2c/Sensirion_Core/src/SensirionI2CTxFrame.cpp index 67999f86c2b5..301fafaf56fa 100644 --- a/lib/lib_i2c/Sensirion_Core/src/SensirionI2CTxFrame.cpp +++ b/lib/lib_i2c/Sensirion_Core/src/SensirionI2CTxFrame.cpp @@ -68,7 +68,7 @@ SensirionI2CTxFrame SensirionI2CTxFrame::createWithUInt16Command( uint16_t SensirionI2CTxFrame::addCommand(uint16_t command) { if (_bufferSize < 2) { - return TxFrameError | BufferSizeError; + return static_cast(TxFrameError) | static_cast(BufferSizeError); } _buffer[0] = static_cast((command & 0xFF00) >> 8); _buffer[1] = static_cast((command & 0x00FF) >> 0); @@ -130,12 +130,12 @@ uint16_t SensirionI2CTxFrame::addBytes(const uint8_t data[], uint16_t SensirionI2CTxFrame::_addByte(uint8_t data) { if (_bufferSize <= _index) { - return TxFrameError | BufferSizeError; + return static_cast(TxFrameError) | static_cast(BufferSizeError); } _buffer[_index++] = data; if ((_index - _numCommandBytes) % 3 == 2) { if (_bufferSize <= _index) { - return TxFrameError | BufferSizeError; + return static_cast(TxFrameError) | static_cast(BufferSizeError); } uint8_t crc = generateCRC(&_buffer[_index - 2], 2, _polynomial_type); _buffer[_index++] = crc; diff --git a/lib/lib_i2c/Sensirion_Core/src/SensirionRxFrame.cpp b/lib/lib_i2c/Sensirion_Core/src/SensirionRxFrame.cpp index c653c250dd73..e89a0b86b485 100644 --- a/lib/lib_i2c/Sensirion_Core/src/SensirionRxFrame.cpp +++ b/lib/lib_i2c/Sensirion_Core/src/SensirionRxFrame.cpp @@ -42,7 +42,7 @@ SensirionRxFrame::SensirionRxFrame(uint8_t buffer[], size_t bufferSize) uint16_t SensirionRxFrame::getUInt32(uint32_t& data) { if (_numBytes < 4) { - return RxFrameError | NoDataError; + return static_cast(RxFrameError) | static_cast(NoDataError); } data = static_cast(_buffer[_index++]) << 24; data |= static_cast(_buffer[_index++]) << 16; @@ -61,7 +61,7 @@ uint16_t SensirionRxFrame::getInt32(int32_t& data) { uint16_t SensirionRxFrame::getUInt16(uint16_t& data) { if (_numBytes < 2) { - return RxFrameError | NoDataError; + return static_cast(RxFrameError) | static_cast(NoDataError); } data = static_cast(_buffer[_index++]) << 8; data |= static_cast(_buffer[_index++]); @@ -78,7 +78,7 @@ uint16_t SensirionRxFrame::getInt16(int16_t& data) { uint16_t SensirionRxFrame::getUInt8(uint8_t& data) { if (_numBytes < 1) { - return RxFrameError | NoDataError; + return static_cast(RxFrameError) | static_cast(NoDataError); } data = _buffer[_index++]; _numBytes -= 1; @@ -87,7 +87,7 @@ uint16_t SensirionRxFrame::getUInt8(uint8_t& data) { uint16_t SensirionRxFrame::getInt8(int8_t& data) { if (_numBytes < 1) { - return RxFrameError | NoDataError; + return static_cast(RxFrameError) | static_cast(NoDataError); } data = static_cast(_buffer[_index++]); _numBytes -= 1; @@ -96,7 +96,7 @@ uint16_t SensirionRxFrame::getInt8(int8_t& data) { uint16_t SensirionRxFrame::getBool(bool& data) { if (_numBytes < 1) { - return RxFrameError | NoDataError; + return static_cast(RxFrameError) | static_cast(NoDataError); } data = static_cast(_buffer[_index++]); _numBytes -= 1; @@ -115,7 +115,7 @@ uint16_t SensirionRxFrame::getFloat(float& data) { uint16_t SensirionRxFrame::getBytes(uint8_t data[], size_t maxBytes) { if (_numBytes < 1) { - return RxFrameError | NoDataError; + return static_cast(RxFrameError) | static_cast(NoDataError); } size_t readAmount = maxBytes; if (_numBytes < maxBytes) { diff --git a/lib/lib_i2c/Sensirion_Core/src/SensirionShdlcCommunication.cpp b/lib/lib_i2c/Sensirion_Core/src/SensirionShdlcCommunication.cpp index 300546ee8326..ce9155e509c5 100644 --- a/lib/lib_i2c/Sensirion_Core/src/SensirionShdlcCommunication.cpp +++ b/lib/lib_i2c/Sensirion_Core/src/SensirionShdlcCommunication.cpp @@ -42,7 +42,7 @@ static uint16_t readByte(uint8_t& data, Stream& serial, unsigned long startTime, unsigned long timeoutMicros) { do { if (micros() - startTime > timeoutMicros) { - return ReadError | TimeoutError; + return static_cast(ReadError) | static_cast(TimeoutError); } } while (!serial.available()); data = serial.read(); @@ -70,7 +70,7 @@ uint16_t SensirionShdlcCommunication::sendFrame(SensirionShdlcTxFrame& frame, Stream& serial) { size_t writtenBytes = serial.write(&frame._buffer[0], frame._index); if (writtenBytes != frame._index) { - return WriteError | SerialWriteError; + return static_cast(WriteError) | static_cast(SerialWriteError); } return NoError; } @@ -83,7 +83,7 @@ uint16_t SensirionShdlcCommunication::receiveFrame( uint8_t current = 0; if (frame._numBytes) { - return ReadError | NonemptyFrameError; + return static_cast(ReadError) | static_cast(NonemptyFrameError); } // Wait for start byte and ignore all other bytes in case a partial frame @@ -121,7 +121,7 @@ uint16_t SensirionShdlcCommunication::receiveFrame( frame._address + frame._command + frame._state + dataLength; if (dataLength > frame._bufferSize) { - return RxFrameError | BufferSizeError; + return static_cast(RxFrameError) | static_cast(BufferSizeError); } size_t i = 0; @@ -142,7 +142,7 @@ uint16_t SensirionShdlcCommunication::receiveFrame( return error; } if (expectedChecksum != actualChecksum) { - return ReadError | ChecksumError; + return static_cast(ReadError) | static_cast(ChecksumError); } uint8_t stop; @@ -151,10 +151,10 @@ uint16_t SensirionShdlcCommunication::receiveFrame( return error; } if (stop != 0x7e) { - return ReadError | StopByteError; + return static_cast(ReadError) | static_cast(StopByteError); } if (frame._state & 0x7F) { - return ExecutionError | frame._state; + return static_cast(ExecutionError) | frame._state; } frame._dataLength = dataLength; frame._numBytes = dataLength; @@ -175,10 +175,10 @@ uint16_t SensirionShdlcCommunication::sendAndReceiveFrame( return error; } if (rxFrame.getCommand() != txFrame.getCommand()) { - return RxFrameError | RxCommandError; + return static_cast(RxFrameError) | static_cast(RxCommandError); } if (rxFrame.getAddress() != txFrame.getAddress()) { - return RxFrameError | RxAddressError; + return static_cast(RxFrameError) | static_cast(RxAddressError); } return NoError; } diff --git a/lib/lib_i2c/Sensirion_Core/src/SensirionShdlcTxFrame.cpp b/lib/lib_i2c/Sensirion_Core/src/SensirionShdlcTxFrame.cpp index fc8c4c9944fd..9efc5d824361 100644 --- a/lib/lib_i2c/Sensirion_Core/src/SensirionShdlcTxFrame.cpp +++ b/lib/lib_i2c/Sensirion_Core/src/SensirionShdlcTxFrame.cpp @@ -53,7 +53,7 @@ uint16_t SensirionShdlcTxFrame::finish(void) { return error; } if (_index + 1 > _bufferSize) { - return TxFrameError | BufferSizeError; + return static_cast(TxFrameError) | BufferSizeError; } _buffer[_index++] = 0x7e; _isFinished = true; @@ -84,7 +84,7 @@ uint16_t SensirionShdlcTxFrame::addInt16(int16_t data) { uint16_t SensirionShdlcTxFrame::addUInt8(uint8_t data) { if (_index + 2 > _bufferSize) { - return TxFrameError | BufferSizeError; + return static_cast(TxFrameError) | BufferSizeError; } switch (data) { case 0x11: diff --git a/lib/lib_i2c/arduino-i2c-sgp41/CHANGELOG.md b/lib/lib_i2c/arduino-i2c-sgp41/CHANGELOG.md new file mode 100644 index 000000000000..b119c080dd42 --- /dev/null +++ b/lib/lib_i2c/arduino-i2c-sgp41/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +## [0.1.0] - 2021-11-17 + +Initial release + +[0.1.0]: https://github.com/Sensirion/arduino-i2c-sgp41/releases/tag/0.1.0 + diff --git a/lib/lib_i2c/arduino-i2c-sgp41/LICENSE b/lib/lib_i2c/arduino-i2c-sgp41/LICENSE new file mode 100644 index 000000000000..ff20c41dfa2a --- /dev/null +++ b/lib/lib_i2c/arduino-i2c-sgp41/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2021, Sensirion AG +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/lib_i2c/arduino-i2c-sgp41/README.md b/lib/lib_i2c/arduino-i2c-sgp41/README.md new file mode 100644 index 000000000000..0a374464735d --- /dev/null +++ b/lib/lib_i2c/arduino-i2c-sgp41/README.md @@ -0,0 +1,78 @@ +# Sensirion I2C SGP41 Arduino Library + +This is the Sensirion SGP41 library for Arduino using the +modules I2C interface. + +[
](https://www.sensirion.com/en/environmental-sensors/gas-sensors/sgp41) + +Click [here](https://www.sensirion.com/en/environmental-sensors/gas-sensors/sgp41) to learn more about the SGP41 sensor. + + +# Installation + +To install, download the latest release as .zip file and add it to your +[Arduino IDE](http://www.arduino.cc/en/main/software) via + + Sketch => Include Library => Add .ZIP Library... + +Don't forget to **install the dependencies** listed below the same way via `Add +.ZIP Library` + +Note: Installation via the Arduino Library Manager is coming soon. + +# Dependencies + +* [Sensirion Core](https://github.com/Sensirion/arduino-core) + + +# Quick Start + +1. Connect the SGP41 Sensor to your Arduino board's standard + I2C bus. Check the pinout of your Arduino board to find the correct pins. + The pinout of the SGP41 Sensor board can be found in the + data sheet. + + * **VDD** of the SEK-SGP41 to the **3.3V** of your Arduino board + * **GND** of the SEK-SGP41 to the **GND** of your Arduino board + * **SCL** of the SEK-SGP41 to the **SCL** of your Arduino board + * **SDA** of the SEK-SGP41 to the **SDA** of your Arduino board + +2. Open the `exampleUsage` sample project within the Arduino IDE + + File => Examples => Sensirion I2C SGP41 => exampleUsage + +3. Click the `Upload` button in the Arduino IDE or + + Sketch => Upload + +4. When the upload process has finished, open the `Serial Monitor` or `Serial + Plotter` via the `Tools` menu to observe the measurement values. Note that + the `Baud Rate` in the corresponding window has to be set to `115200 baud`. + +# Contributing + +**Contributions are welcome!** + +We develop and test this driver using our company internal tools (version +control, continuous integration, code review etc.) and automatically +synchronize the master branch with GitHub. But this doesn't mean that we don't +respond to issues or don't accept pull requests on GitHub. In fact, you're very +welcome to open issues or create pull requests :) + +This Sensirion library uses +[`clang-format`](https://releases.llvm.org/download.html) to standardize the +formatting of all our `.cpp` and `.h` files. Make sure your contributions are +formatted accordingly: + +The `-i` flag will apply the format changes to the files listed. + +```bash +clang-format -i src/*.cpp src/*.h +``` + +Note that differences from this formatting will result in a failed build until +they are fixed. + +# License + +See [LICENSE](LICENSE). diff --git a/lib/lib_i2c/arduino-i2c-sgp41/examples/exampleUsage/exampleUsage.ino b/lib/lib_i2c/arduino-i2c-sgp41/examples/exampleUsage/exampleUsage.ino new file mode 100644 index 000000000000..3490dddb2077 --- /dev/null +++ b/lib/lib_i2c/arduino-i2c-sgp41/examples/exampleUsage/exampleUsage.ino @@ -0,0 +1,124 @@ +/* + * I2C-Generator: 0.3.0 + * Yaml Version: 0.1.0 + * Template Version: 0.7.0-62-g3d691f9 + */ +/* + * Copyright (c) 2021, Sensirion AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Sensirion AG nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +SensirionI2CSgp41 sgp41; + +// time in seconds needed for NOx conditioning +uint16_t conditioning_s = 10; + +void setup() { + + Serial.begin(115200); + while (!Serial) { + delay(100); + } + + Wire.begin(); + + uint16_t error; + char errorMessage[256]; + + sgp41.begin(Wire); + + uint16_t serialNumber[3]; + uint8_t serialNumberSize = 3; + + error = sgp41.getSerialNumber(serialNumber, serialNumberSize); + + if (error) { + Serial.print("Error trying to execute getSerialNumber(): "); + errorToString(error, errorMessage, 256); + Serial.println(errorMessage); + } else { + Serial.print("SerialNumber:"); + Serial.print("0x"); + for (size_t i = 0; i < serialNumberSize; i++) { + uint16_t value = serialNumber[i]; + Serial.print(value < 4096 ? "0" : ""); + Serial.print(value < 256 ? "0" : ""); + Serial.print(value < 16 ? "0" : ""); + Serial.print(value, HEX); + } + Serial.println(); + } + + uint16_t testResult; + error = sgp41.executeSelfTest(testResult); + if (error) { + Serial.print("Error trying to execute executeSelfTest(): "); + errorToString(error, errorMessage, 256); + Serial.println(errorMessage); + } else if (testResult != 0xD400) { + Serial.print("executeSelfTest failed with error: "); + Serial.println(testResult); + } +} + +void loop() { + uint16_t error; + char errorMessage[256]; + uint16_t defaultRh = 0x8000; + uint16_t defaultT = 0x6666; + uint16_t srawVoc = 0; + uint16_t srawNox = 0; + + delay(1000); + + if (conditioning_s > 0) { + // During NOx conditioning (10s) SRAW NOx will remain 0 + error = sgp41.executeConditioning(defaultRh, defaultT, srawVoc); + conditioning_s--; + } else { + // Read Measurement + error = sgp41.measureRawSignals(defaultRh, defaultT, srawVoc, srawNox); + } + + if (error) { + Serial.print("Error trying to execute measureRawSignals(): "); + errorToString(error, errorMessage, 256); + Serial.println(errorMessage); + } else { + Serial.print("SRAW_VOC:"); + Serial.print(srawVoc); + Serial.print("\t"); + Serial.print("SRAW_NOx:"); + Serial.println(srawNox); + } +} diff --git a/lib/lib_i2c/arduino-i2c-sgp41/images/SGP41.png b/lib/lib_i2c/arduino-i2c-sgp41/images/SGP41.png new file mode 100644 index 000000000000..a36e2d82e552 Binary files /dev/null and b/lib/lib_i2c/arduino-i2c-sgp41/images/SGP41.png differ diff --git a/lib/lib_i2c/arduino-i2c-sgp41/keywords.txt b/lib/lib_i2c/arduino-i2c-sgp41/keywords.txt new file mode 100644 index 000000000000..13e6ba269768 --- /dev/null +++ b/lib/lib_i2c/arduino-i2c-sgp41/keywords.txt @@ -0,0 +1,27 @@ +####################################### +# Syntax Coloring Map +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +SensirionI2CSgp41 KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +executeConditioning KEYWORD2 +measureRawSignals KEYWORD2 +executeSelfTest KEYWORD2 +turnHeaterOff KEYWORD2 +getSerialNumber KEYWORD2 +####################################### +# Instances (KEYWORD2) +####################################### + +sgp41 KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/lib/lib_i2c/arduino-i2c-sgp41/library.properties b/lib/lib_i2c/arduino-i2c-sgp41/library.properties new file mode 100644 index 000000000000..5412354f9cf3 --- /dev/null +++ b/lib/lib_i2c/arduino-i2c-sgp41/library.properties @@ -0,0 +1,10 @@ +name=Sensirion I2C SGP41 +version=0.1.0 +author=Sensirion +maintainer=Sensirion +sentence=Library for the SGP41 sensor family by Sensirion +paragraph=Enables you to use the SGP41 via I2C. +url=https://github.com/Sensirion/arduino-i2c-sgp41 +category=Sensors +depends=Sensirion Core +includes=SensirionI2CSgp41.h diff --git a/lib/lib_i2c/arduino-i2c-sgp41/src/SensirionI2CSgp4x.cpp b/lib/lib_i2c/arduino-i2c-sgp41/src/SensirionI2CSgp4x.cpp new file mode 100644 index 000000000000..7395d4a51055 --- /dev/null +++ b/lib/lib_i2c/arduino-i2c-sgp41/src/SensirionI2CSgp4x.cpp @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2021, Sensirion AG + * Copyright (c) 2023, Andrew Klaus (Removing delay functions) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Sensirion AG nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "SensirionI2CSgp4x.h" +#include "Arduino.h" +#include "SensirionCore.h" +#include + +#define SGP4X_I2C_ADDRESS 0x59 + +SensirionI2CSgp4x::SensirionI2CSgp4x() { +} + +void SensirionI2CSgp4x::begin(TwoWire& i2cBus) { + _i2cBus = &i2cBus; +} + +uint16_t SensirionI2CSgp4x::sendConditioningCmd(uint16_t defaultRh, + uint16_t defaultT) { + uint16_t error; + uint8_t buffer[8]; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2612, buffer, 8); + + error = txFrame.addUInt16(defaultRh); + error |= txFrame.addUInt16(defaultT); + if (error) { + return error; + } + + error = SensirionI2CCommunication::sendFrame(SGP4X_I2C_ADDRESS, txFrame, + *_i2cBus); + return error; +} + +uint16_t SensirionI2CSgp4x::readConditioningValue(uint16_t& srawVoc){ + // This must run at least 50ms after initiateConditioning + uint16_t error; + uint8_t buffer[8]; + + SensirionI2CRxFrame rxFrame(buffer, 8); + error = SensirionI2CCommunication::receiveFrame(SGP4X_I2C_ADDRESS, 3, + rxFrame, *_i2cBus); + if (error) { + return error; + } + + error |= rxFrame.getUInt16(srawVoc); + return error; +} + +uint16_t SensirionI2CSgp4x::sendRawSignalsCmd(uint16_t relativeHumidity, + uint16_t temperature) { + uint16_t error; + uint8_t buffer[8]; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2619, buffer, 8); + + error = txFrame.addUInt16(relativeHumidity); + error |= txFrame.addUInt16(temperature); + if (error) { + return error; + } + + error = SensirionI2CCommunication::sendFrame(SGP4X_I2C_ADDRESS, txFrame, + *_i2cBus); + return error; +} + +uint16_t SensirionI2CSgp4x::readRawSignalsValue(uint16_t& srawVoc, + uint16_t& srawNox) { + // This must run 50ms after initiateRawSignals + + uint16_t error; + uint8_t buffer[6]; + SensirionI2CRxFrame rxFrame(buffer, 6); + error = SensirionI2CCommunication::receiveFrame(SGP4X_I2C_ADDRESS, 6, + rxFrame, *_i2cBus); + if (error) { + return error; + } + + error |= rxFrame.getUInt16(srawVoc); + error |= rxFrame.getUInt16(srawNox); + return error; +} + +uint16_t SensirionI2CSgp4x::sendRawSignalCmd(uint16_t relativeHumidity, + uint16_t temperature) { + uint16_t error; + uint8_t buffer[8]; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x260F, buffer, 8); + + error = txFrame.addUInt16(relativeHumidity); + error |= txFrame.addUInt16(temperature); + + if (error) { + return error; + } + + error = SensirionI2CCommunication::sendFrame(SGP4X_I2C_ADDRESS, txFrame, + *_i2cBus); + return error; + +} + + +uint16_t SensirionI2CSgp4x::readRawSignalValue(uint16_t& srawVoc) { + uint16_t error; + uint8_t buffer[8]; + + SensirionI2CRxFrame rxFrame(buffer, 8); + error = SensirionI2CCommunication::receiveFrame(SGP4X_I2C_ADDRESS, 3, + rxFrame, *_i2cBus); + if (error) { + return error; + } + + error |= rxFrame.getUInt16(srawVoc); + return error; + +} + +uint16_t SensirionI2CSgp4x::sendSelfTestCmd() { + uint16_t error; + uint8_t buffer[3]; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x280E, buffer, 3); + + error = SensirionI2CCommunication::sendFrame(SGP4X_I2C_ADDRESS, txFrame, + *_i2cBus); + return error; +} + +uint16_t SensirionI2CSgp4x::readSelfTestValue(uint16_t& testResult) { + // Must run 320ms after initiateSelfTest + uint16_t error; + uint8_t buffer[3]; + + SensirionI2CRxFrame rxFrame(buffer, 3); + error = SensirionI2CCommunication::receiveFrame(SGP4X_I2C_ADDRESS, 3, + rxFrame, *_i2cBus); + if (error) { + return error; + } + + error |= rxFrame.getUInt16(testResult); + return error; +} + +uint16_t SensirionI2CSgp4x::turnHeaterOff() { + uint16_t error; + uint8_t buffer[2]; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x3615, buffer, 2); + + error = SensirionI2CCommunication::sendFrame(SGP4X_I2C_ADDRESS, txFrame, + *_i2cBus); + delay(1); + return error; +} + +uint16_t SensirionI2CSgp4x::getSerialNumber(uint16_t serialNumber[], + uint8_t serialNumberSize) { + uint16_t error; + uint8_t buffer[9]; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x3682, buffer, 9); + + error = SensirionI2CCommunication::sendFrame(SGP4X_I2C_ADDRESS, txFrame, + *_i2cBus); + if (error) { + return error; + } + + delay(1); + + SensirionI2CRxFrame rxFrame(buffer, 9); + error = SensirionI2CCommunication::receiveFrame(SGP4X_I2C_ADDRESS, 9, + rxFrame, *_i2cBus); + if (error) { + return error; + } + + error |= rxFrame.getUInt16(serialNumber[0]); + error |= rxFrame.getUInt16(serialNumber[1]); + error |= rxFrame.getUInt16(serialNumber[2]); + return error; +} diff --git a/lib/lib_i2c/arduino-i2c-sgp41/src/SensirionI2CSgp4x.h b/lib/lib_i2c/arduino-i2c-sgp41/src/SensirionI2CSgp4x.h new file mode 100644 index 000000000000..b03bed3f4f1f --- /dev/null +++ b/lib/lib_i2c/arduino-i2c-sgp41/src/SensirionI2CSgp4x.h @@ -0,0 +1,145 @@ +/* + * THIS FILE IS AUTOMATICALLY GENERATED + * + * I2C-Generator: 0.3.0 + * Yaml Version: 0.1.0 + * Template Version: 0.7.0-62-g3d691f9 + */ +/* + * Copyright (c) 2021, Sensirion AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Sensirion AG nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SENSIRIONI2CSGP4X_H +#define SENSIRIONI2CSGP4X_H + +#include + +#include + +class SensirionI2CSgp4x { + + public: + SensirionI2CSgp4x(); + /** + * begin() - Initializes the SensirionI2CSgp4x class. + * + * @param serial Arduino stream object to be communicated with. + * + */ + void begin(TwoWire& i2cBus); + + /** + * executeConditioning() - This command starts the conditioning, i.e., the + * VOC pixel will be operated at the same temperature as it is by calling + * the sgp41_measure_raw command while the NOx pixel will be operated at a + * different temperature for conditioning. This command returns only the + * measured raw signal of the VOC pixel SRAW_VOC as 2 bytes (+ 1 CRC byte). + * + * @param defaultRh Default conditions for relative humidty. + * + * @param defaultT Default conditions for temperature. + * + * @param srawVoc u16 unsigned integer directly provides the raw signal + * SRAW_VOC in ticks which is proportional to the logarithm of the + * resistance of the sensing element. + * + * @return 0 on success, an error code otherwise + */ + uint16_t sendConditioningCmd(uint16_t defaultRh, uint16_t defaultT); + + uint16_t readConditioningValue(uint16_t& srawVoc); + + /** + * measureRawSignals() - This command starts/continues the VOC+NOx + * measurement mode + * + * @param relativeHumidity Leaves humidity compensation disabled by sending + * the default value 0x8000 (50%RH) or enables humidity compensation when + * sending the relative humidity in ticks (ticks = %RH * 65535 / 100) + * + * @param temperature Leaves humidity compensation disabled by sending the + * default value 0x6666 (25 degC) or enables humidity compensation when + * sending the temperature in ticks (ticks = (degC + 45) * 65535 / 175) + * + * @param srawVoc u16 unsigned integer directly provides the raw signal + * SRAW_VOC in ticks which is proportional to the logarithm of the + * resistance of the sensing element. + * + * @param srawNox u16 unsigned integer directly provides the raw signal + * SRAW_NOX in ticks which is proportional to the logarithm of the + * resistance of the sensing element. + * + * @return 0 on success, an error code otherwise + */ + uint16_t sendRawSignalsCmd(uint16_t relativeHumidity, uint16_t temperature); + uint16_t readRawSignalsValue(uint16_t& srawVoc, uint16_t& srawNox); + + uint16_t sendRawSignalCmd(uint16_t relativeHumidity, uint16_t temperature); + uint16_t readRawSignalValue(uint16_t& srawVoc); + + /** + * executeSelfTest() - This command triggers the built-in self-test checking + * for integrity of both hotplate and MOX material and returns the result of + * this test as 2 bytes + * + * @param testResult 0xXX 0xYY: ignore most significant byte 0xXX. The four + * least significant bits of the least significant byte 0xYY provide + * information if the self-test has or has not passed for each individual + * pixel. All zero mean all tests passed successfully. Check the datasheet + * for more detailed information. + * + * @return 0 on success, an error code otherwise + */ + uint16_t sendSelfTestCmd(void); + uint16_t readSelfTestValue(uint16_t& testResult); + + /** + * turnHeaterOff() - This command turns the hotplate off and stops the + * measurement. Subsequently, the sensor enters the idle mode. + * + * @return 0 on success, an error code otherwise + */ + uint16_t turnHeaterOff(void); + + /** + * getSerialNumber() - This command provides the decimal serial number of + * the SGP41 chip by returning 3x2 bytes. + * + * @param serialNumber 48-bit unique serial number + * + * @return 0 on success, an error code otherwise + */ + uint16_t getSerialNumber(uint16_t serialNumber[], uint8_t serialNumberSize); + + private: + TwoWire* _i2cBus = nullptr; +}; + +#endif /* SENSIRIONI2CSGP4X_H */ diff --git a/lib/lib_i2c/arduino-i2c-sgp41/src/sensirion_gas_index_algorithm.c b/lib/lib_i2c/arduino-i2c-sgp41/src/sensirion_gas_index_algorithm.c new file mode 100644 index 000000000000..5ec3edeea2c3 --- /dev/null +++ b/lib/lib_i2c/arduino-i2c-sgp41/src/sensirion_gas_index_algorithm.c @@ -0,0 +1,582 @@ +/* + * Copyright (c) 2022, Sensirion AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Sensirion AG nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "sensirion_gas_index_algorithm.h" +#include + +static void GasIndexAlgorithm__init_instances(GasIndexAlgorithmParams* params); +static void GasIndexAlgorithm__mean_variance_estimator__set_parameters( + GasIndexAlgorithmParams* params); +static void GasIndexAlgorithm__mean_variance_estimator__set_states( + GasIndexAlgorithmParams* params, float mean, float std, float uptime_gamma); +static float GasIndexAlgorithm__mean_variance_estimator__get_std( + const GasIndexAlgorithmParams* params); +static float GasIndexAlgorithm__mean_variance_estimator__get_mean( + const GasIndexAlgorithmParams* params); +static bool GasIndexAlgorithm__mean_variance_estimator__is_initialized( + GasIndexAlgorithmParams* params); +static void GasIndexAlgorithm__mean_variance_estimator___calculate_gamma( + GasIndexAlgorithmParams* params); +static void GasIndexAlgorithm__mean_variance_estimator__process( + GasIndexAlgorithmParams* params, float sraw); +static void +GasIndexAlgorithm__mean_variance_estimator___sigmoid__set_parameters( + GasIndexAlgorithmParams* params, float X0, float K); +static float GasIndexAlgorithm__mean_variance_estimator___sigmoid__process( + GasIndexAlgorithmParams* params, float sample); +static void +GasIndexAlgorithm__mox_model__set_parameters(GasIndexAlgorithmParams* params, + float SRAW_STD, float SRAW_MEAN); +static float +GasIndexAlgorithm__mox_model__process(GasIndexAlgorithmParams* params, + float sraw); +static void GasIndexAlgorithm__sigmoid_scaled__set_parameters( + GasIndexAlgorithmParams* params, float X0, float K, float offset_default); +static float +GasIndexAlgorithm__sigmoid_scaled__process(GasIndexAlgorithmParams* params, + float sample); +static void GasIndexAlgorithm__adaptive_lowpass__set_parameters( + GasIndexAlgorithmParams* params); +static float +GasIndexAlgorithm__adaptive_lowpass__process(GasIndexAlgorithmParams* params, + float sample); + +void GasIndexAlgorithm_init_with_sampling_interval( + GasIndexAlgorithmParams* params, int32_t algorithm_type, + float sampling_interval) { + params->mAlgorithm_Type = algorithm_type; + params->mSamplingInterval = sampling_interval; + if ((algorithm_type == GasIndexAlgorithm_ALGORITHM_TYPE_NOX)) { + params->mIndex_Offset = GasIndexAlgorithm_NOX_INDEX_OFFSET_DEFAULT; + params->mSraw_Minimum = GasIndexAlgorithm_NOX_SRAW_MINIMUM; + params->mGating_Max_Duration_Minutes = + GasIndexAlgorithm_GATING_NOX_MAX_DURATION_MINUTES; + params->mInit_Duration_Mean = GasIndexAlgorithm_INIT_DURATION_MEAN_NOX; + params->mInit_Duration_Variance = + GasIndexAlgorithm_INIT_DURATION_VARIANCE_NOX; + params->mGating_Threshold = GasIndexAlgorithm_GATING_THRESHOLD_NOX; + } else { + params->mIndex_Offset = GasIndexAlgorithm_VOC_INDEX_OFFSET_DEFAULT; + params->mSraw_Minimum = GasIndexAlgorithm_VOC_SRAW_MINIMUM; + params->mGating_Max_Duration_Minutes = + GasIndexAlgorithm_GATING_VOC_MAX_DURATION_MINUTES; + params->mInit_Duration_Mean = GasIndexAlgorithm_INIT_DURATION_MEAN_VOC; + params->mInit_Duration_Variance = + GasIndexAlgorithm_INIT_DURATION_VARIANCE_VOC; + params->mGating_Threshold = GasIndexAlgorithm_GATING_THRESHOLD_VOC; + } + params->mIndex_Gain = GasIndexAlgorithm_INDEX_GAIN; + params->mTau_Mean_Hours = GasIndexAlgorithm_TAU_MEAN_HOURS; + params->mTau_Variance_Hours = GasIndexAlgorithm_TAU_VARIANCE_HOURS; + params->mSraw_Std_Initial = GasIndexAlgorithm_SRAW_STD_INITIAL; + GasIndexAlgorithm_reset(params); +} + +void GasIndexAlgorithm_init(GasIndexAlgorithmParams* params, + int32_t algorithm_type) { + GasIndexAlgorithm_init_with_sampling_interval( + params, algorithm_type, GasIndexAlgorithm_DEFAULT_SAMPLING_INTERVAL); +} + +void GasIndexAlgorithm_reset(GasIndexAlgorithmParams* params) { + params->mUptime = 0.f; + params->mSraw = 0.f; + params->mGas_Index = 0; + GasIndexAlgorithm__init_instances(params); +} + +static void GasIndexAlgorithm__init_instances(GasIndexAlgorithmParams* params) { + + GasIndexAlgorithm__mean_variance_estimator__set_parameters(params); + GasIndexAlgorithm__mox_model__set_parameters( + params, GasIndexAlgorithm__mean_variance_estimator__get_std(params), + GasIndexAlgorithm__mean_variance_estimator__get_mean(params)); + if ((params->mAlgorithm_Type == GasIndexAlgorithm_ALGORITHM_TYPE_NOX)) { + GasIndexAlgorithm__sigmoid_scaled__set_parameters( + params, GasIndexAlgorithm_SIGMOID_X0_NOX, + GasIndexAlgorithm_SIGMOID_K_NOX, + GasIndexAlgorithm_NOX_INDEX_OFFSET_DEFAULT); + } else { + GasIndexAlgorithm__sigmoid_scaled__set_parameters( + params, GasIndexAlgorithm_SIGMOID_X0_VOC, + GasIndexAlgorithm_SIGMOID_K_VOC, + GasIndexAlgorithm_VOC_INDEX_OFFSET_DEFAULT); + } + GasIndexAlgorithm__adaptive_lowpass__set_parameters(params); +} + +void GasIndexAlgorithm_get_sampling_interval( + const GasIndexAlgorithmParams* params, float* sampling_interval) { + *sampling_interval = params->mSamplingInterval; +} + +void GasIndexAlgorithm_get_states(const GasIndexAlgorithmParams* params, + float* state0, float* state1) { + + *state0 = GasIndexAlgorithm__mean_variance_estimator__get_mean(params); + *state1 = GasIndexAlgorithm__mean_variance_estimator__get_std(params); + return; +} + +void GasIndexAlgorithm_set_states(GasIndexAlgorithmParams* params, float state0, + float state1) { + + GasIndexAlgorithm__mean_variance_estimator__set_states( + params, state0, state1, GasIndexAlgorithm_PERSISTENCE_UPTIME_GAMMA); + GasIndexAlgorithm__mox_model__set_parameters( + params, GasIndexAlgorithm__mean_variance_estimator__get_std(params), + GasIndexAlgorithm__mean_variance_estimator__get_mean(params)); + params->mSraw = state0; +} + +void GasIndexAlgorithm_set_tuning_parameters( + GasIndexAlgorithmParams* params, int32_t index_offset, + int32_t learning_time_offset_hours, int32_t learning_time_gain_hours, + int32_t gating_max_duration_minutes, int32_t std_initial, + int32_t gain_factor) { + + params->mIndex_Offset = ((float)(index_offset)); + params->mTau_Mean_Hours = ((float)(learning_time_offset_hours)); + params->mTau_Variance_Hours = ((float)(learning_time_gain_hours)); + params->mGating_Max_Duration_Minutes = + ((float)(gating_max_duration_minutes)); + params->mSraw_Std_Initial = ((float)(std_initial)); + params->mIndex_Gain = ((float)(gain_factor)); + GasIndexAlgorithm__init_instances(params); +} + +void GasIndexAlgorithm_get_tuning_parameters( + const GasIndexAlgorithmParams* params, int32_t* index_offset, + int32_t* learning_time_offset_hours, int32_t* learning_time_gain_hours, + int32_t* gating_max_duration_minutes, int32_t* std_initial, + int32_t* gain_factor) { + + *index_offset = ((int32_t)(params->mIndex_Offset)); + *learning_time_offset_hours = ((int32_t)(params->mTau_Mean_Hours)); + *learning_time_gain_hours = ((int32_t)(params->mTau_Variance_Hours)); + *gating_max_duration_minutes = + ((int32_t)(params->mGating_Max_Duration_Minutes)); + *std_initial = ((int32_t)(params->mSraw_Std_Initial)); + *gain_factor = ((int32_t)(params->mIndex_Gain)); + return; +} + +void GasIndexAlgorithm_process(GasIndexAlgorithmParams* params, int32_t sraw, + int32_t* gas_index) { + + if ((params->mUptime <= GasIndexAlgorithm_INITIAL_BLACKOUT)) { + params->mUptime = (params->mUptime + params->mSamplingInterval); + } else { + if (((sraw > 0) && (sraw < 65000))) { + if ((sraw < (params->mSraw_Minimum + 1))) { + sraw = (params->mSraw_Minimum + 1); + } else if ((sraw > (params->mSraw_Minimum + 32767))) { + sraw = (params->mSraw_Minimum + 32767); + } + params->mSraw = ((float)((sraw - params->mSraw_Minimum))); + } + if (((params->mAlgorithm_Type == + GasIndexAlgorithm_ALGORITHM_TYPE_VOC) || + GasIndexAlgorithm__mean_variance_estimator__is_initialized( + params))) { + params->mGas_Index = + GasIndexAlgorithm__mox_model__process(params, params->mSraw); + params->mGas_Index = GasIndexAlgorithm__sigmoid_scaled__process( + params, params->mGas_Index); + } else { + params->mGas_Index = params->mIndex_Offset; + } + params->mGas_Index = GasIndexAlgorithm__adaptive_lowpass__process( + params, params->mGas_Index); + if ((params->mGas_Index < 0.5f)) { + params->mGas_Index = 0.5f; + } + if ((params->mSraw > 0.f)) { + GasIndexAlgorithm__mean_variance_estimator__process(params, + params->mSraw); + GasIndexAlgorithm__mox_model__set_parameters( + params, + GasIndexAlgorithm__mean_variance_estimator__get_std(params), + GasIndexAlgorithm__mean_variance_estimator__get_mean(params)); + } + } + *gas_index = ((int32_t)((params->mGas_Index + 0.5f))); + return; +} + +static void GasIndexAlgorithm__mean_variance_estimator__set_parameters( + GasIndexAlgorithmParams* params) { + + params->m_Mean_Variance_Estimator___Initialized = false; + params->m_Mean_Variance_Estimator___Mean = 0.f; + params->m_Mean_Variance_Estimator___Sraw_Offset = 0.f; + params->m_Mean_Variance_Estimator___Std = params->mSraw_Std_Initial; + params->m_Mean_Variance_Estimator___Gamma_Mean = + (((GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__ADDITIONAL_GAMMA_MEAN_SCALING * + GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING) * + (params->mSamplingInterval / 3600.f)) / + (params->mTau_Mean_Hours + (params->mSamplingInterval / 3600.f))); + params->m_Mean_Variance_Estimator___Gamma_Variance = + ((GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING * + (params->mSamplingInterval / 3600.f)) / + (params->mTau_Variance_Hours + (params->mSamplingInterval / 3600.f))); + if ((params->mAlgorithm_Type == GasIndexAlgorithm_ALGORITHM_TYPE_NOX)) { + params->m_Mean_Variance_Estimator___Gamma_Initial_Mean = + (((GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__ADDITIONAL_GAMMA_MEAN_SCALING * + GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING) * + params->mSamplingInterval) / + (GasIndexAlgorithm_TAU_INITIAL_MEAN_NOX + + params->mSamplingInterval)); + } else { + params->m_Mean_Variance_Estimator___Gamma_Initial_Mean = + (((GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__ADDITIONAL_GAMMA_MEAN_SCALING * + GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING) * + params->mSamplingInterval) / + (GasIndexAlgorithm_TAU_INITIAL_MEAN_VOC + + params->mSamplingInterval)); + } + params->m_Mean_Variance_Estimator___Gamma_Initial_Variance = + ((GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING * + params->mSamplingInterval) / + (GasIndexAlgorithm_TAU_INITIAL_VARIANCE + params->mSamplingInterval)); + params->m_Mean_Variance_Estimator__Gamma_Mean = 0.f; + params->m_Mean_Variance_Estimator__Gamma_Variance = 0.f; + params->m_Mean_Variance_Estimator___Uptime_Gamma = 0.f; + params->m_Mean_Variance_Estimator___Uptime_Gating = 0.f; + params->m_Mean_Variance_Estimator___Gating_Duration_Minutes = 0.f; +} + +static void GasIndexAlgorithm__mean_variance_estimator__set_states( + GasIndexAlgorithmParams* params, float mean, float std, + float uptime_gamma) { + + params->m_Mean_Variance_Estimator___Mean = mean; + params->m_Mean_Variance_Estimator___Std = std; + params->m_Mean_Variance_Estimator___Uptime_Gamma = uptime_gamma; + params->m_Mean_Variance_Estimator___Initialized = true; +} + +static float GasIndexAlgorithm__mean_variance_estimator__get_std( + const GasIndexAlgorithmParams* params) { + + return params->m_Mean_Variance_Estimator___Std; +} + +static float GasIndexAlgorithm__mean_variance_estimator__get_mean( + const GasIndexAlgorithmParams* params) { + + return (params->m_Mean_Variance_Estimator___Mean + + params->m_Mean_Variance_Estimator___Sraw_Offset); +} + +static bool GasIndexAlgorithm__mean_variance_estimator__is_initialized( + GasIndexAlgorithmParams* params) { + + return params->m_Mean_Variance_Estimator___Initialized; +} + +static void GasIndexAlgorithm__mean_variance_estimator___calculate_gamma( + GasIndexAlgorithmParams* params) { + + float uptime_limit; + float sigmoid_gamma_mean; + float gamma_mean; + float gating_threshold_mean; + float sigmoid_gating_mean; + float sigmoid_gamma_variance; + float gamma_variance; + float gating_threshold_variance; + float sigmoid_gating_variance; + + uptime_limit = (GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__FIX16_MAX - + params->mSamplingInterval); + if ((params->m_Mean_Variance_Estimator___Uptime_Gamma < uptime_limit)) { + params->m_Mean_Variance_Estimator___Uptime_Gamma = + (params->m_Mean_Variance_Estimator___Uptime_Gamma + + params->mSamplingInterval); + } + if ((params->m_Mean_Variance_Estimator___Uptime_Gating < uptime_limit)) { + params->m_Mean_Variance_Estimator___Uptime_Gating = + (params->m_Mean_Variance_Estimator___Uptime_Gating + + params->mSamplingInterval); + } + GasIndexAlgorithm__mean_variance_estimator___sigmoid__set_parameters( + params, params->mInit_Duration_Mean, + GasIndexAlgorithm_INIT_TRANSITION_MEAN); + sigmoid_gamma_mean = + GasIndexAlgorithm__mean_variance_estimator___sigmoid__process( + params, params->m_Mean_Variance_Estimator___Uptime_Gamma); + gamma_mean = (params->m_Mean_Variance_Estimator___Gamma_Mean + + ((params->m_Mean_Variance_Estimator___Gamma_Initial_Mean - + params->m_Mean_Variance_Estimator___Gamma_Mean) * + sigmoid_gamma_mean)); + gating_threshold_mean = + (params->mGating_Threshold + + ((GasIndexAlgorithm_GATING_THRESHOLD_INITIAL - + params->mGating_Threshold) * + GasIndexAlgorithm__mean_variance_estimator___sigmoid__process( + params, params->m_Mean_Variance_Estimator___Uptime_Gating))); + GasIndexAlgorithm__mean_variance_estimator___sigmoid__set_parameters( + params, gating_threshold_mean, + GasIndexAlgorithm_GATING_THRESHOLD_TRANSITION); + sigmoid_gating_mean = + GasIndexAlgorithm__mean_variance_estimator___sigmoid__process( + params, params->mGas_Index); + params->m_Mean_Variance_Estimator__Gamma_Mean = + (sigmoid_gating_mean * gamma_mean); + GasIndexAlgorithm__mean_variance_estimator___sigmoid__set_parameters( + params, params->mInit_Duration_Variance, + GasIndexAlgorithm_INIT_TRANSITION_VARIANCE); + sigmoid_gamma_variance = + GasIndexAlgorithm__mean_variance_estimator___sigmoid__process( + params, params->m_Mean_Variance_Estimator___Uptime_Gamma); + gamma_variance = + (params->m_Mean_Variance_Estimator___Gamma_Variance + + ((params->m_Mean_Variance_Estimator___Gamma_Initial_Variance - + params->m_Mean_Variance_Estimator___Gamma_Variance) * + (sigmoid_gamma_variance - sigmoid_gamma_mean))); + gating_threshold_variance = + (params->mGating_Threshold + + ((GasIndexAlgorithm_GATING_THRESHOLD_INITIAL - + params->mGating_Threshold) * + GasIndexAlgorithm__mean_variance_estimator___sigmoid__process( + params, params->m_Mean_Variance_Estimator___Uptime_Gating))); + GasIndexAlgorithm__mean_variance_estimator___sigmoid__set_parameters( + params, gating_threshold_variance, + GasIndexAlgorithm_GATING_THRESHOLD_TRANSITION); + sigmoid_gating_variance = + GasIndexAlgorithm__mean_variance_estimator___sigmoid__process( + params, params->mGas_Index); + params->m_Mean_Variance_Estimator__Gamma_Variance = + (sigmoid_gating_variance * gamma_variance); + params->m_Mean_Variance_Estimator___Gating_Duration_Minutes = + (params->m_Mean_Variance_Estimator___Gating_Duration_Minutes + + ((params->mSamplingInterval / 60.f) * + (((1.f - sigmoid_gating_mean) * + (1.f + GasIndexAlgorithm_GATING_MAX_RATIO)) - + GasIndexAlgorithm_GATING_MAX_RATIO))); + if ((params->m_Mean_Variance_Estimator___Gating_Duration_Minutes < 0.f)) { + params->m_Mean_Variance_Estimator___Gating_Duration_Minutes = 0.f; + } + if ((params->m_Mean_Variance_Estimator___Gating_Duration_Minutes > + params->mGating_Max_Duration_Minutes)) { + params->m_Mean_Variance_Estimator___Uptime_Gating = 0.f; + } +} + +static void GasIndexAlgorithm__mean_variance_estimator__process( + GasIndexAlgorithmParams* params, float sraw) { + + float delta_sgp; + float c; + float additional_scaling; + + if ((params->m_Mean_Variance_Estimator___Initialized == false)) { + params->m_Mean_Variance_Estimator___Initialized = true; + params->m_Mean_Variance_Estimator___Sraw_Offset = sraw; + params->m_Mean_Variance_Estimator___Mean = 0.f; + } else { + if (((params->m_Mean_Variance_Estimator___Mean >= 100.f) || + (params->m_Mean_Variance_Estimator___Mean <= -100.f))) { + params->m_Mean_Variance_Estimator___Sraw_Offset = + (params->m_Mean_Variance_Estimator___Sraw_Offset + + params->m_Mean_Variance_Estimator___Mean); + params->m_Mean_Variance_Estimator___Mean = 0.f; + } + sraw = (sraw - params->m_Mean_Variance_Estimator___Sraw_Offset); + GasIndexAlgorithm__mean_variance_estimator___calculate_gamma(params); + delta_sgp = ((sraw - params->m_Mean_Variance_Estimator___Mean) / + GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING); + if ((delta_sgp < 0.f)) { + c = (params->m_Mean_Variance_Estimator___Std - delta_sgp); + } else { + c = (params->m_Mean_Variance_Estimator___Std + delta_sgp); + } + additional_scaling = 1.f; + if ((c > 1440.f)) { + additional_scaling = ((c / 1440.f) * (c / 1440.f)); + } + params->m_Mean_Variance_Estimator___Std = + (sqrtf((additional_scaling * + (GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING - + params->m_Mean_Variance_Estimator__Gamma_Variance))) * + sqrtf( + ((params->m_Mean_Variance_Estimator___Std * + (params->m_Mean_Variance_Estimator___Std / + (GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING * + additional_scaling))) + + (((params->m_Mean_Variance_Estimator__Gamma_Variance * + delta_sgp) / + additional_scaling) * + delta_sgp)))); + params->m_Mean_Variance_Estimator___Mean = + (params->m_Mean_Variance_Estimator___Mean + + ((params->m_Mean_Variance_Estimator__Gamma_Mean * delta_sgp) / + GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__ADDITIONAL_GAMMA_MEAN_SCALING)); + } +} + +static void +GasIndexAlgorithm__mean_variance_estimator___sigmoid__set_parameters( + GasIndexAlgorithmParams* params, float X0, float K) { + + params->m_Mean_Variance_Estimator___Sigmoid__K = K; + params->m_Mean_Variance_Estimator___Sigmoid__X0 = X0; +} + +static float GasIndexAlgorithm__mean_variance_estimator___sigmoid__process( + GasIndexAlgorithmParams* params, float sample) { + + float x; + + x = (params->m_Mean_Variance_Estimator___Sigmoid__K * + (sample - params->m_Mean_Variance_Estimator___Sigmoid__X0)); + if ((x < -50.f)) { + return 1.f; + } else if ((x > 50.f)) { + return 0.f; + } else { + return (1.f / (1.f + expf(x))); + } +} + +static void +GasIndexAlgorithm__mox_model__set_parameters(GasIndexAlgorithmParams* params, + float SRAW_STD, float SRAW_MEAN) { + + params->m_Mox_Model__Sraw_Std = SRAW_STD; + params->m_Mox_Model__Sraw_Mean = SRAW_MEAN; +} + +static float +GasIndexAlgorithm__mox_model__process(GasIndexAlgorithmParams* params, + float sraw) { + + if ((params->mAlgorithm_Type == GasIndexAlgorithm_ALGORITHM_TYPE_NOX)) { + return (((sraw - params->m_Mox_Model__Sraw_Mean) / + GasIndexAlgorithm_SRAW_STD_NOX) * + params->mIndex_Gain); + } else { + return (((sraw - params->m_Mox_Model__Sraw_Mean) / + (-1.f * (params->m_Mox_Model__Sraw_Std + + GasIndexAlgorithm_SRAW_STD_BONUS_VOC))) * + params->mIndex_Gain); + } +} + +static void GasIndexAlgorithm__sigmoid_scaled__set_parameters( + GasIndexAlgorithmParams* params, float X0, float K, float offset_default) { + + params->m_Sigmoid_Scaled__K = K; + params->m_Sigmoid_Scaled__X0 = X0; + params->m_Sigmoid_Scaled__Offset_Default = offset_default; +} + +static float +GasIndexAlgorithm__sigmoid_scaled__process(GasIndexAlgorithmParams* params, + float sample) { + + float x; + float shift; + + x = (params->m_Sigmoid_Scaled__K * (sample - params->m_Sigmoid_Scaled__X0)); + if ((x < -50.f)) { + return GasIndexAlgorithm_SIGMOID_L; + } else if ((x > 50.f)) { + return 0.f; + } else { + if ((sample >= 0.f)) { + if ((params->m_Sigmoid_Scaled__Offset_Default == 1.f)) { + shift = ((500.f / 499.f) * (1.f - params->mIndex_Offset)); + } else { + shift = ((GasIndexAlgorithm_SIGMOID_L - + (5.f * params->mIndex_Offset)) / + 4.f); + } + return (((GasIndexAlgorithm_SIGMOID_L + shift) / (1.f + expf(x))) - + shift); + } else { + return ((params->mIndex_Offset / + params->m_Sigmoid_Scaled__Offset_Default) * + (GasIndexAlgorithm_SIGMOID_L / (1.f + expf(x)))); + } + } +} + +static void GasIndexAlgorithm__adaptive_lowpass__set_parameters( + GasIndexAlgorithmParams* params) { + + params->m_Adaptive_Lowpass__A1 = + (params->mSamplingInterval / + (GasIndexAlgorithm_LP_TAU_FAST + params->mSamplingInterval)); + params->m_Adaptive_Lowpass__A2 = + (params->mSamplingInterval / + (GasIndexAlgorithm_LP_TAU_SLOW + params->mSamplingInterval)); + params->m_Adaptive_Lowpass___Initialized = false; +} + +static float +GasIndexAlgorithm__adaptive_lowpass__process(GasIndexAlgorithmParams* params, + float sample) { + + float abs_delta; + float F1; + float tau_a; + float a3; + + if ((params->m_Adaptive_Lowpass___Initialized == false)) { + params->m_Adaptive_Lowpass___X1 = sample; + params->m_Adaptive_Lowpass___X2 = sample; + params->m_Adaptive_Lowpass___X3 = sample; + params->m_Adaptive_Lowpass___Initialized = true; + } + params->m_Adaptive_Lowpass___X1 = + (((1.f - params->m_Adaptive_Lowpass__A1) * + params->m_Adaptive_Lowpass___X1) + + (params->m_Adaptive_Lowpass__A1 * sample)); + params->m_Adaptive_Lowpass___X2 = + (((1.f - params->m_Adaptive_Lowpass__A2) * + params->m_Adaptive_Lowpass___X2) + + (params->m_Adaptive_Lowpass__A2 * sample)); + abs_delta = + (params->m_Adaptive_Lowpass___X1 - params->m_Adaptive_Lowpass___X2); + if ((abs_delta < 0.f)) { + abs_delta = (-1.f * abs_delta); + } + F1 = expf((GasIndexAlgorithm_LP_ALPHA * abs_delta)); + tau_a = (((GasIndexAlgorithm_LP_TAU_SLOW - GasIndexAlgorithm_LP_TAU_FAST) * + F1) + + GasIndexAlgorithm_LP_TAU_FAST); + a3 = (params->mSamplingInterval / (params->mSamplingInterval + tau_a)); + params->m_Adaptive_Lowpass___X3 = + (((1.f - a3) * params->m_Adaptive_Lowpass___X3) + (a3 * sample)); + return params->m_Adaptive_Lowpass___X3; +} \ No newline at end of file diff --git a/lib/lib_i2c/arduino-i2c-sgp41/src/sensirion_gas_index_algorithm.h b/lib/lib_i2c/arduino-i2c-sgp41/src/sensirion_gas_index_algorithm.h new file mode 100644 index 000000000000..0bd584bb9376 --- /dev/null +++ b/lib/lib_i2c/arduino-i2c-sgp41/src/sensirion_gas_index_algorithm.h @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2022, Sensirion AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Sensirion AG nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GASINDEXALGORITHM_H_ +#define GASINDEXALGORITHM_H_ + +#include + +#ifndef __cplusplus + +#if __STDC_VERSION__ >= 199901L +#include +#else + +#ifndef bool +#define bool int +#define true 1 +#define false 0 +#endif // bool + +#endif // __STDC_VERSION__ + +#endif // __cplusplus + +// Should be set by the building toolchain +#ifndef LIBRARY_VERSION_NAME +#define LIBRARY_VERSION_NAME "3.2.0" +#endif + +#define GasIndexAlgorithm_ALGORITHM_TYPE_VOC (0) +#define GasIndexAlgorithm_ALGORITHM_TYPE_NOX (1) +#define GasIndexAlgorithm_DEFAULT_SAMPLING_INTERVAL (1.f) +#define GasIndexAlgorithm_INITIAL_BLACKOUT (45.f) +#define GasIndexAlgorithm_INDEX_GAIN (230.f) +#define GasIndexAlgorithm_SRAW_STD_INITIAL (50.f) +#define GasIndexAlgorithm_SRAW_STD_BONUS_VOC (220.f) +#define GasIndexAlgorithm_SRAW_STD_NOX (2000.f) +#define GasIndexAlgorithm_TAU_MEAN_HOURS (12.f) +#define GasIndexAlgorithm_TAU_VARIANCE_HOURS (12.f) +#define GasIndexAlgorithm_TAU_INITIAL_MEAN_VOC (20.f) +#define GasIndexAlgorithm_TAU_INITIAL_MEAN_NOX (1200.f) +#define GasIndexAlgorithm_INIT_DURATION_MEAN_VOC ((3600.f * 0.75f)) +#define GasIndexAlgorithm_INIT_DURATION_MEAN_NOX ((3600.f * 4.75f)) +#define GasIndexAlgorithm_INIT_TRANSITION_MEAN (0.01f) +#define GasIndexAlgorithm_TAU_INITIAL_VARIANCE (2500.f) +#define GasIndexAlgorithm_INIT_DURATION_VARIANCE_VOC ((3600.f * 1.45f)) +#define GasIndexAlgorithm_INIT_DURATION_VARIANCE_NOX ((3600.f * 5.70f)) +#define GasIndexAlgorithm_INIT_TRANSITION_VARIANCE (0.01f) +#define GasIndexAlgorithm_GATING_THRESHOLD_VOC (340.f) +#define GasIndexAlgorithm_GATING_THRESHOLD_NOX (30.f) +#define GasIndexAlgorithm_GATING_THRESHOLD_INITIAL (510.f) +#define GasIndexAlgorithm_GATING_THRESHOLD_TRANSITION (0.09f) +#define GasIndexAlgorithm_GATING_VOC_MAX_DURATION_MINUTES ((60.f * 3.f)) +#define GasIndexAlgorithm_GATING_NOX_MAX_DURATION_MINUTES ((60.f * 12.f)) +#define GasIndexAlgorithm_GATING_MAX_RATIO (0.3f) +#define GasIndexAlgorithm_SIGMOID_L (500.f) +#define GasIndexAlgorithm_SIGMOID_K_VOC (-0.0065f) +#define GasIndexAlgorithm_SIGMOID_X0_VOC (213.f) +#define GasIndexAlgorithm_SIGMOID_K_NOX (-0.0101f) +#define GasIndexAlgorithm_SIGMOID_X0_NOX (614.f) +#define GasIndexAlgorithm_VOC_INDEX_OFFSET_DEFAULT (100.f) +#define GasIndexAlgorithm_NOX_INDEX_OFFSET_DEFAULT (1.f) +#define GasIndexAlgorithm_LP_TAU_FAST (20.0f) +#define GasIndexAlgorithm_LP_TAU_SLOW (500.0f) +#define GasIndexAlgorithm_LP_ALPHA (-0.2f) +#define GasIndexAlgorithm_VOC_SRAW_MINIMUM (20000) +#define GasIndexAlgorithm_NOX_SRAW_MINIMUM (10000) +#define GasIndexAlgorithm_PERSISTENCE_UPTIME_GAMMA ((3.f * 3600.f)) +#define GasIndexAlgorithm_TUNING_INDEX_OFFSET_MIN (1) +#define GasIndexAlgorithm_TUNING_INDEX_OFFSET_MAX (250) +#define GasIndexAlgorithm_TUNING_LEARNING_TIME_OFFSET_HOURS_MIN (1) +#define GasIndexAlgorithm_TUNING_LEARNING_TIME_OFFSET_HOURS_MAX (1000) +#define GasIndexAlgorithm_TUNING_LEARNING_TIME_GAIN_HOURS_MIN (1) +#define GasIndexAlgorithm_TUNING_LEARNING_TIME_GAIN_HOURS_MAX (1000) +#define GasIndexAlgorithm_TUNING_GATING_MAX_DURATION_MINUTES_MIN (0) +#define GasIndexAlgorithm_TUNING_GATING_MAX_DURATION_MINUTES_MAX (3000) +#define GasIndexAlgorithm_TUNING_STD_INITIAL_MIN (10) +#define GasIndexAlgorithm_TUNING_STD_INITIAL_MAX (5000) +#define GasIndexAlgorithm_TUNING_GAIN_FACTOR_MIN (1) +#define GasIndexAlgorithm_TUNING_GAIN_FACTOR_MAX (1000) +#define GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING (64.f) +#define GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__ADDITIONAL_GAMMA_MEAN_SCALING \ + (8.f) +#define GasIndexAlgorithm_MEAN_VARIANCE_ESTIMATOR__FIX16_MAX (32767.f) + +/** + * Struct to hold all parameters and states of the gas algorithm. + */ +typedef struct { + int mAlgorithm_Type; + float mSamplingInterval; + float mIndex_Offset; + int32_t mSraw_Minimum; + float mGating_Max_Duration_Minutes; + float mInit_Duration_Mean; + float mInit_Duration_Variance; + float mGating_Threshold; + float mIndex_Gain; + float mTau_Mean_Hours; + float mTau_Variance_Hours; + float mSraw_Std_Initial; + float mUptime; + float mSraw; + float mGas_Index; + bool m_Mean_Variance_Estimator___Initialized; + float m_Mean_Variance_Estimator___Mean; + float m_Mean_Variance_Estimator___Sraw_Offset; + float m_Mean_Variance_Estimator___Std; + float m_Mean_Variance_Estimator___Gamma_Mean; + float m_Mean_Variance_Estimator___Gamma_Variance; + float m_Mean_Variance_Estimator___Gamma_Initial_Mean; + float m_Mean_Variance_Estimator___Gamma_Initial_Variance; + float m_Mean_Variance_Estimator__Gamma_Mean; + float m_Mean_Variance_Estimator__Gamma_Variance; + float m_Mean_Variance_Estimator___Uptime_Gamma; + float m_Mean_Variance_Estimator___Uptime_Gating; + float m_Mean_Variance_Estimator___Gating_Duration_Minutes; + float m_Mean_Variance_Estimator___Sigmoid__K; + float m_Mean_Variance_Estimator___Sigmoid__X0; + float m_Mox_Model__Sraw_Std; + float m_Mox_Model__Sraw_Mean; + float m_Sigmoid_Scaled__K; + float m_Sigmoid_Scaled__X0; + float m_Sigmoid_Scaled__Offset_Default; + float m_Adaptive_Lowpass__A1; + float m_Adaptive_Lowpass__A2; + bool m_Adaptive_Lowpass___Initialized; + float m_Adaptive_Lowpass___X1; + float m_Adaptive_Lowpass___X2; + float m_Adaptive_Lowpass___X3; +} GasIndexAlgorithmParams; + +/** + * Initialize the gas index algorithm parameters for the specified algorithm + * type and reset its internal states. Call this once at the beginning. + * @param params Pointer to the GasIndexAlgorithmParams struct + * @param algorithm_type 0 (GasIndexAlgorithm_ALGORITHM_TYPE_VOC) for VOC or + * 1 (GasIndexAlgorithm_ALGORITHM_TYPE_NOX) for NOx + */ +void GasIndexAlgorithm_init(GasIndexAlgorithmParams* params, + int32_t algorithm_type); + +/** + * Initialize the gas index algorithm parameters for the specified algorithm + * type and reset its internal states. Call this once at the beginning. + * @param params Pointer to the GasIndexAlgorithmParams struct + * @param algorithm_type 0 (GasIndexAlgorithm_ALGORITHM_TYPE_VOC) for VOC or + * 1 (GasIndexAlgorithm_ALGORITHM_TYPE_NOX) for NOx + * @param sampling_interval The sampling interval in seconds the algorithm is + * called. Tested for 1s and 10s. + */ +void GasIndexAlgorithm_init_with_sampling_interval( + GasIndexAlgorithmParams* params, int32_t algorithm_type, + float sampling_interval); + +/** + * Reset the internal states of the gas index algorithm. Previously set tuning + * parameters are preserved. Call this when resuming operation after a + * measurement interruption. + * @param params Pointer to the GasIndexAlgorithmParams struct + */ +void GasIndexAlgorithm_reset(GasIndexAlgorithmParams* params); + +/** + * Get current algorithm states. Retrieved values can be used in + * GasIndexAlgorithm_set_states() to resume operation after a short + * interruption, skipping initial learning phase. + * NOTE: This feature can only be used for VOC algorithm type and after at least + * 3 hours of continuous operation. + * @param params Pointer to the GasIndexAlgorithmParams struct + * @param state0 State0 to be stored + * @param state1 State1 to be stored + */ +void GasIndexAlgorithm_get_states(const GasIndexAlgorithmParams* params, + float* state0, float* state1); + +/** + * Set previously retrieved algorithm states to resume operation after a short + * interruption, skipping initial learning phase. This feature should not be + * used after interruptions of more than 10 minutes. Call this once after + * GasIndexAlgorithm_init() or GasIndexAlgorithm_reset() and the optional + * GasIndexAlgorithm_set_tuning_parameters(), if desired. Otherwise, the + * algorithm will start with initial learning phase. + * NOTE: This feature can only be used for VOC algorithm type. + * @param params Pointer to the GasIndexAlgorithmParams struct + * @param state0 State0 to be restored + * @param state1 State1 to be restored + */ +void GasIndexAlgorithm_set_states(GasIndexAlgorithmParams* params, float state0, + float state1); + +/** + * Set parameters to customize the gas index algorithm. Call this once after + * GasIndexAlgorithm_init() and before optional GasIndexAlgorithm_set_states(), + * if desired. Otherwise, the default values will be used. + * + * @param params Pointer to the GasIndexAlgorithmParams + * struct + * @param index_offset Gas index representing typical (average) + * conditions. Range 1..250, + * default 100 for VOC and 1 for NOx + * @param learning_time_offset_hours Time constant of long-term estimator for + * offset. Past events will be forgotten + * after about twice the learning time. + * Range 1..1000 [hours], default 12 [hours] + * @param learning_time_gain_hours Time constant of long-term estimator for + * gain. Past events will be forgotten + * after about twice the learning time. + * Range 1..1000 [hours], default 12 [hours] + * NOTE: This value is not relevant for NOx + * algorithm type + * @param gating_max_duration_minutes Maximum duration of gating (freeze of + * estimator during high gas index signal). + * 0 (no gating) or range 1..3000 [minutes], + * default 180 [minutes] for VOC and + * 720 [minutes] for NOx + * @param std_initial Initial estimate for standard deviation. + * Lower value boosts events during initial + * learning period, but may result in larger + * device-to-device variations. + * Range 10..5000, default 50 + * NOTE: This value is not relevant for NOx + * algorithm type + * @param gain_factor Factor used to scale applied gain value + * when calculating gas index. Range 1..1000, + * default 230 + */ +void GasIndexAlgorithm_set_tuning_parameters( + GasIndexAlgorithmParams* params, int32_t index_offset, + int32_t learning_time_offset_hours, int32_t learning_time_gain_hours, + int32_t gating_max_duration_minutes, int32_t std_initial, + int32_t gain_factor); + +/** + * Get current parameters to customize the gas index algorithm. + * Refer to GasIndexAlgorithm_set_tuning_parameters() for description of the + * parameters. + */ +void GasIndexAlgorithm_get_tuning_parameters( + const GasIndexAlgorithmParams* params, int32_t* index_offset, + int32_t* learning_time_offset_hours, int32_t* learning_time_gain_hours, + int32_t* gating_max_duration_minutes, int32_t* std_initial, + int32_t* gain_factor); + +/** + * Get the sampling interval parameter used by the algorithm. + */ +void GasIndexAlgorithm_get_sampling_interval( + const GasIndexAlgorithmParams* params, float* sampling_interval); + +/** + * Calculate the gas index value from the raw sensor value. + * + * @param params Pointer to the GasIndexAlgorithmParams struct + * @param sraw Raw value from the SGP4x sensor + * @param gas_index Calculated gas index value from the raw sensor value. Zero + * during initial blackout period and 1..500 afterwards + */ +void GasIndexAlgorithm_process(GasIndexAlgorithmParams* params, int32_t sraw, + int32_t* gas_index); + +#endif /* GASINDEXALGORITHM_H_ */ \ No newline at end of file diff --git a/lib/lib_ssl/bearssl-esp8266/library.properties b/lib/lib_ssl/bearssl-esp8266/library.properties index 032d4d247aed..7728af80cb66 100644 --- a/lib/lib_ssl/bearssl-esp8266/library.properties +++ b/lib/lib_ssl/bearssl-esp8266/library.properties @@ -2,7 +2,7 @@ name=BearSSL version=0.6 author=Thomas Pornin maintainer=Earle F. Philhower, III -sentence=BearSSL implementation of the SSL/TLS protocol optimized for ESP8266 by Earle F. Philhower, optimized for Tamota by Stephan Hadinger +sentence=BearSSL implementation of the SSL/TLS protocol optimized for ESP8266 by Earle F. Philhower, optimized for Tasmota by Stephan Hadinger paragraph= category=Other url=https://github.com/earlephilhower/bearssl-esp8266.git diff --git a/lib/lib_ssl/bearssl-esp8266/src/t_inner.h b/lib/lib_ssl/bearssl-esp8266/src/t_inner.h index 924486db7d72..d5fecd71ba88 100644 --- a/lib/lib_ssl/bearssl-esp8266/src/t_inner.h +++ b/lib/lib_ssl/bearssl-esp8266/src/t_inner.h @@ -2597,7 +2597,11 @@ br_cpuid(uint32_t mask_eax, uint32_t mask_ebx, #endif #define _debugBearSSL (0) - extern void optimistic_yield(uint32_t); + #ifdef ESP8266 + extern void optimistic_yield(uint32_t); + #else + #define optimistic_yield(ignored) + #endif #ifdef __cplusplus } #endif diff --git a/lib/libesp32/lib_mail/LICENSE b/lib/libesp32/ESP-Mail-Client/LICENSE similarity index 95% rename from lib/libesp32/lib_mail/LICENSE rename to lib/libesp32/ESP-Mail-Client/LICENSE index 4ba9966fdb95..c22fc2301a88 100644 --- a/lib/libesp32/lib_mail/LICENSE +++ b/lib/libesp32/ESP-Mail-Client/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2021 mobizt - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +MIT License + +Copyright (c) 2023 mobizt + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/lib/libesp32/ESP-Mail-Client/README.md b/lib/libesp32/ESP-Mail-Client/README.md new file mode 100644 index 000000000000..79d584f99407 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/README.md @@ -0,0 +1,1127 @@ +![ESP Mail](https://raw.githubusercontent.com/mobizt/ESP-Mail-Client/master/media/images/esp-mail-client.svg) + + +![Compile](https://github.com/mobizt/ESP-Mail-Client/actions/workflows/compile_library.yml/badge.svg) ![Examples](https://github.com/mobizt/ESP-Mail-Client/actions/workflows/compile_examples.yml/badge.svg) [![Github Stars](https://img.shields.io/github/stars/mobizt/ESP-Mail-Client?logo=github)](https://github.com/mobizt/ESP-Mail-Client/stargazers) ![Github Issues](https://img.shields.io/github/issues/mobizt/ESP-Mail-Client?logo=github) + +![arduino-library-badge](https://www.ardu-badge.com/badge/ESP%20Mail%20Client.svg) ![PlatformIO](https://badges.registry.platformio.org/packages/mobizt/library/ESP%20Mail%20Client.svg) + + +The comprehensive Arduino Email Client Library to send and read Email for Arduino devices. + +This library was tested and works well with ESP32s, ESP8266s, SAMD21s and RP2040 Pico based modules. + +The library supported external networking devices hat work with Arduino Clients e.g. WiFiClient, EthernetClient, and GSMClient. + +Minimum 200k flash space device is recommended for library installation and user code. + +The minimum ram requirement is based on the applications (SMTP and IMAP). IMAP application may required up to 20k memory while SMTP application required much less memory. + + +## Contents + + +[1. Features](#features) + +[2. Supported Devices](#supported-devices) + +[3. Prerequisites](#prerequisites) +- [Gmail SMTP and IMAP required App Passwords to sign in](#gmail-smtp-and-imap-required-app-passwords-to-sign-in) + +- [PlatformIO IDE Compile Options](#platformio-ide-compile-options) + +- [Third party SD library must be removed](#third-party-sd-library-must-be-removed) + +- [SdFat conflicts in ESP8266 and must be removed](#sdfat-conflicts-in-esp8266-and-must-be-removed) + +- [ESP32 and ESP8266 SDKs](#esp32-and-esp8266-sdks) + +- [RP2040 Arduino SDK](#rp2040-arduino-sdk) + +[4. Library Instalation](#library-instalation) + +- [Using Library Manager](#using-library-manager) + +- [Manual installation](#manual-installation) + +[5. Memory Options](#memory-options) + +- [Memory Options for ESP8266](#memory-options-for-esp8266) + + - [Arduino IDE](#arduino-ide) + + - [PlatformIO IDE](#platformio-ide) + + - [ESP8266 and SRAM/PSRAM Chip connection](#esp8266-and-srampsram-chip-connection) + +- [Memory Options for ESP32](#memory-options-for-esp32) + + - [Arduino IDE](#arduino-ide-1) + + - [PlatformIO IDE](#platformio-ide-1) + + +[6. Library Build Options](#library-build-options) + + - [Predefined Options](#predefined-options) + + - [Optional Options](#optional-options) + + +[7. Usage](#usage) + +- [Send Email message](#send-email-message) + +- [Read Email message](#read-email-message) + +- [Get Incoming Message Notification and Reading](#get-incoming-message-notification-and-reading) + +- [Sending Custom IMAP commands](#sending-custom-imap-commands) + +- [Using TCP session KeepAlive in ESP8266 and ESP32](#using-tcp-session-keepalive-in-esp8266-and-esp32) + +- [Use external Arduino Clients interfaces](#use-external-arduino-clients-interfaces) + + - [TTGO T-A7670 LTE with TinyGSM](#ttgo-t-a7670-lte-with-tinygsm) + + - [ESP32 and W5500](#esp32-and-w5500) + +[8. License](#license) + + + +## Features + +* Supports sending Email with attachments. +* Supports reading the message and listening the mailbox changes. +* Supports custom SMTP and IMAP commands. +* Supports PLAIN, LOGIN and XOAUTH2 authentication mechanisms. +* Supports standard ports and user defined ports. +* Supports STARTTLS for both SMTP and IMAP. +* Supports TCP session reusage. +* Supports the content encodings e.g. quoted-printable and base64. +* Supports the content decodings e.g. base64, UTF-8, UTF-7, quoted-printable, ISO-8859-1 (latin1) and ISO-8859-11 (Thai). +* Supports embedded contents e.g. inline images, attachments, parallel media attachments and RFC822 message. +* Supports IMAP MIME data stream callback for external reader. +* supports IMAP custom character decoding callback based on the character set. +* Support full debuging. +* Support on-board or native networking (WiFi and Ethernet) and external networking (WiFi, Ethernet and GSM) via external basic WiFiClient, EthernetClient and GSMClient. +* Supports TinyGSM library integration. + + + + +## Supported Devices + +This following devices are supported. + + * ESP8266 MCUs based boards + * ESP32 MCUs based boards + * Arduino MKR WiFi 1010 + * Arduino MKR 1000 WIFI + * Arduino Nano 33 IoT + * Arduino MKR Vidor 4000 + * Raspberry Pi Pico (RP2040) + * Arduino UNO R4 WiFi (Renesas). + * LAN8720 Ethernet PHY + * TLK110 Ethernet PHY + * IP101 Ethernet PHY + * ENC28J60 SPI Ethernet module + * W5100 SPI Ethernet module + * W5500 SPI Ethernet module + * SIMCom Modules with TinyGSMClient + + + +## Prerequisites + + +### Gmail SMTP and IMAP required App Passwords to sign in + +From May 30, 2022, Google no longer supports the use of third-party apps or devices which ask you to sign in to your GoogleAccount using only your username and password. + +This means the Gmail account credentials i.e. account Email and account password can't be used to sign in with Google SMTP and IMAP servers. This prevents the third party apps hack to Gmail user account. + +To use Gmail with this library, you need to use App Passwords instead. + +For setting up the App Passwords, please read [here](https://support.google.com/accounts/answer/185833). + +After you created App Password, you can use Gmail Email address and App Password created to sign in as the following. + +```cpp +config.login.email = ""; +config.login.password = ""; +``` + + +### PlatformIO IDE Compile Options + +For Arduino Nano RP2040 Connect board, using PlatformIO IDE, to prevent the compile error due to wrong headers compilation, please set the lib_ldf_mode in platformio.ini as this. + +```ini +lib_ldf_mode = chain+ +``` + +### Third party SD library must be removed + +In Arduino IDE, all third party SD libraries installed in libraries folder must be reboved. + +The Core SD library was used instead of third party SD libraries. + +### SdFat conflicts in ESP8266 and must be removed + +The [SdFat](https://github.com/greiman/SdFat) is already implemented as wrapper class in ESP8266 core library. + +For Arduino IDE, the SdFat library should be removed from libraries folder when you compile this library for ESP8266 because of conclicts with core library SDFS.h. + + +### ESP32 and ESP8266 SDKs + +For Espressif's ESP32 and ESP8266 based boards, this library requires Arduino's ESP32 or ESP8266 Core SDK to be installed. + +The latest Core SDK is recommended. For ESP8266, the Core SDK version 3.x.x or later is recommended. + +The ESP8266 Core SDK version 2.5.x and earlier are not supported. + +For ESP32, the Core SDK version 2.0.4 or later is recommended. + +The ESP32 Core SDK version 1.0.4 and earlier are not supported. + + +### RP2040 Arduino SDK + +For Arduino IDE, the Arduino-Pico SDK can be installed from Boards Manager by searching pico and choose Raspberry Pi Pico/RP2040 to install. + +For PlatformIO, the Arduino-Pico SDK can be installed via platformio.ini + +```ini +[env:rpipicow] +platform = https://github.com/maxgerhardt/platform-raspberrypi.git +board = rpipicow +framework = arduino +board_build.core = earlephilhower +monitor_speed = 115200 +board_build.filesystem_size = 1m +``` + +See this Arduino-Pico SDK [documentation](https://arduino-pico.readthedocs.io/en/latest/) for more information. + + +## Library Instalation + + +### Using Library Manager + +At Arduino IDE, go to menu **Sketch** -> **Include Library** -> **Manage Libraries...** + +In Library Manager Window, search **"ESP Mail Client"** in the search form then select **"ESP Mail Client"**. + +Click **"Install"** button. + + + +For PlatformIO IDE. + +Go to **PIO Home** -> **Libraries** -> **Registry** then search **ESP Mail Client**. + + +If you ever installed this library in Global storage in PlatformIO version prior to v2.0.0 and you have updated the PlatformIO to v2.0.0 and later, the global library installation was not available, the sources files of old library version still be able to search by the library dependency finder (LDF), you needed to remove the library from folder **C:\Users\\\\.platformio\lib** to prevent unexpected behavior when compile and run. + + + +### Manual installation + + +Click on **Code** dropdown at the top of repository, select **Download ZIP** and save file on your computer. + +From Arduino IDE, goto menu **Sketch** -> **Include Library** -> **Add .ZIP Library...** and choose **ESP-Mail-Client-master.zip** that previously downloaded. + +Rename **ESP-Mail-Client-master** folder to **ESP_Mail_Client**. + +Go to menu **Files** -> **Examples** -> **ESP Mail Client** and choose one from examples + + + +## Memory Options + + +### Memory Options for ESP8266 + +This section is optional for memory settings in IDE. + +When you update the ESP8266 Arduino Core SDK to v3.0.0, the memory can be configurable from IDE. + +You can choose the Heap memory between internal and external memory chip from IDE e.g. Arduino IDE and PlatformIO on VSCode or Atom IDE. + +#### Arduino IDE + + +For ESP8266 devices that don't have external SRAM/PSRAM chip installed, choose the MMU **option 3**, 16KB cache + 48KB IRAM and 2nd Heap (shared). + +![Arduino IDE config](/media/images/ArduinoIDE.png) + +For ESP8266 devices that have external 23LC1024 SRAM chip installed, choose the MMU **option 5**, 128K External 23LC1024. + +![MMU VM 128K](/media/images/ESP8266_VM.png) + +For ESP8266 devices that have external ESP-PSRAM64 chip installed, choose the MMU **option 6**, 1M External 64 MBit PSRAM. + + +#### PlatformIO IDE + +The MMU options can be selected from build_flags in your project's platformio.ini file + +For ESP8266 devices that don't not have external SRAM/PSRAM chip installed, add build flag as below. + +```ini +[env:d1_mini] +platform = espressif8266 +build_flags = -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED +board = d1_mini +framework = arduino +monitor_speed = 115200 +``` + + +For ESP8266 devices that have external 23LC1024 SRAM chip installed, add build flag as below. + +```ini +[env:d1_mini] +platform = espressif8266 +;128K External 23LC1024 +build_flags = -D PIO_FRAMEWORK_ARDUINO_MMU_EXTERNAL_128K +board = d1_mini +framework = arduino +monitor_speed = 115200 +``` + + +For ESP8266 devices that have external ESP-PSRAM64 chip installed, add build flag as below. + +```ini +[env:d1_mini] +platform = espressif8266 +;1M External 64 MBit PSRAM +build_flags = -D PIO_FRAMEWORK_ARDUINO_MMU_EXTERNAL_1024K +board = d1_mini +framework = arduino +monitor_speed = 115200 +``` + + +#### ESP8266 and SRAM/PSRAM Chip connection + +Most ESP8266 modules don't have the built-in SRAM/PSRAM on board. External memory chip connection can be done via SPI port as below. + +``` +23LC1024/ESP-PSRAM64 ESP8266 + +CS (Pin 1) GPIO15 +SCK (Pin 6) GPIO14 +MOSI (Pin 5) GPIO13 +MISO (Pin 2) GPIO12 +/HOLD (Pin 7 on 23LC1024 only) 3V3 +Vcc (Pin 8) 3V3 +Vcc (Pin 4) GND +``` + +Once the external Heap memory was selected in IDE, to allow the library to use the external memory, you can set it in [**ESP_Mail_FS.h**](src/ESP_Mail_FS.h) by define this macro. + + +```cpp +#define ESP_MAIL_USE_PSRAM +``` + +This macro was defined by default when you installed or update the library. + + + +### Memory Options for ESP32 + +This section is optional for memory settings in IDE. + +In ESP32 module that has PSRAM installed, you can enable it and set the library to use this external memory instead. + +#### Arduino IDE + +To enable PSRAM in ESP32 module. + +![Enable PSRAM in ESP32](/media/images/ESP32-PSRAM.png) + + +#### PlatformIO IDE + + +In PlatformIO on VSCode or Atom IDE, add the following build_flags in your project's platformio.ini file. + +```ini +build_flags = -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue +``` + +As in ESP8266, once the external Heap memory was enabled in IDE, to allow the library to use the external memory, you can set it in [**ESP_Mail_FS.h**](src/ESP_Mail_FS.h) by define this macro. + +```cpp +#define ESP_MAIL_USE_PSRAM +``` + + + +## Library Build Options + +The library build options are defined as preprocessor macros (`#define name`). + +Some options can be disabled to reduce program space. + +### Predefined Options + +The predefined options that are already set in [**ESP_Mail_FS.h**](src/ESP_Mail_FS.h) are following. + +```cpp +ENABLE_IMAP // For IMAP class compilation +ENABLE_SMTP // For SMTP class compilation +ENABLE_NTP_TIME // For enabling the device or library time setup from NTP server +ENABLE_ERROR_STRING // For enabling the error string from error reason +ESP_MAIL_USE_PSRAM // For enabling PSRAM support +ESP_MAIL_DEFAULT_FLASH_FS // For enabling flash filesystem support +ESP_MAIL_DEFAULT_SD_FS // For enabling SD filesystem support +``` + +### Optional Options + +The following options are not yet defined in [**ESP_Mail_FS.h**](src/ESP_Mail_FS.h) and can be assigned by user. + +```cpp +SILENT_MODE // For silent operation (no debug printing and callback) +ENABLE_ESP8266_ENC28J60_ETH // For ENC28J60 Ethernet module support in ESP8266 +ENABLE_ESP8266_W5500_ETH // For W5500 Ethernet module support in ESP8266 +ENABLE_ESP8266_W5100_ETH // For W5100 Ethernet module support in ESP8266 +ESP_MAIL_DISABLE_ONBOARD_WIFI // For disabling on-board WiFI functionality in case external Client usage +ESP_MAIL_DISABLE_NATIVE_ETHERNET // For disabling native (sdk) Ethernet functionality in case external Client usage +ESP_MAIL_DISABLE_SSL // // For disabling SSL connection (also disabling TLS using STARTTLS) in MAP and SMTP application +ESP_MAIL_DEBUG_PORT // For debug port assignment if SILENT_MODE option was not set +``` + + +You can assign the optional build options using one of the following methods. + +- By creating user config file `Custom_ESP_Mail_FS.h` in library installed folder and define these optional options. + +- By adding compiler build flags with `-D name`. + +In PlatformIO IDE, using `build_flags` in PlatformIO IDE's platformio.ini is more convenient + +```ini +build_flags = -D ESP_MAIL_DEBUG_PORT=Serial + -D DISABLE_IMAP + -D ESP_MAIL_DISABLE_ONBOARD_WIFI +``` + +For disabling predefined options instead of editing the [**ESP_Mail_FS.h**](src/ESP_Mail_FS.h) or using `#undef` in `Custom_ESP_Mail_FS.h`, you can define these build flags with these names or macros in `Custom_ESP_Mail_FS.h`. + +```cpp +DISABLE_IMAP // For excluding the IMAP class compilation +DISABLE_SMTP // For excluding the SMTP class compilation +DISABLE_NTP_TIME // For disabling the NTP time setting +DISABLE_ERROR_STRING // For disabling the error string from error reason +DISABLE_PSRAM // For disabling PSRAM support +DISABLE_FLASH // For disabling flash filesystem support +DISABLE_SD // For disabling SD filesystem support + +DISABLE_ALL_OPTIONS // For disabling all predefined build options above +``` + +Note that, `Custom_ESP_Mail_FS.h` for user config should be placed in the library install folder inside src folder. + +This `Custom_ESP_Mail_FS.h` will not change or overwrite when update the library. + + + +## Usage + + +See [examples folder](/examples) for all usage examples. + +See [src/README.md](/src/README.md) for the functions descriptions. + +The usefull blogs that described how to send and read E-mail in detail can be found here. + +[ESP32 Send Emails using an SMTP Server: HTML, Text, and Attachments (Arduino IDE) by Rui and Sara from randomnerdtutorials.com](https://randomnerdtutorials.com/esp32-send-email-smtp-server-arduino-ide/) + +[Receiving Emails with ESP32 using IMAP Server by Alina Mybeth from theengineeringprojects.com](https://www.theengineeringprojects.com/2022/01/receiving-emails-with-esp32-using-imap-server.html) + + +The following code snippet showed the minimum usage of the library. + + +### Send Email message + +The following code will send email with image attachment. + +```C++ +// Include WiFi library +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +// Include ESP Mail Client library (this library) +#include + + +// Declare the global used SMTPSession object for SMTP transport +SMTPSession smtp; + +// Declare the global used Session_Config for user defined session credentials +Session_Config config; + +// Callback function to get the Email sending status +void smtpCallback(SMTP_Status status); + +void setup() +{ + + Serial.begin(115200); + + WiFi.begin("", ""); + Serial.print("Connecting to Wi-Fi"); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + // Set the session config + config.server.host_name = "smtp.office365.com"; // for outlook.com + config.server.port = 587; // for TLS with STARTTLS or 25 (Plain/TLS with STARTTLS) or 465 (SSL) + config.login.email = "your Email address"; // set to empty for no SMTP Authentication + config.login.password = "your Email password"; // set to empty for no SMTP Authentication + + // For client identity, assign invalid string can cause server rejection + config.login.user_domain = "client domain or public ip"; + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = "pool.ntp.org,time.nist.gov"; + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + // Declare the SMTP_Message class variable to handle to message being transport + SMTP_Message message; + + // Set the message headers + message.sender.name = "My Mail"; + message.sender.email = "sender or your Email address"; + message.subject = "Test sending Email"; + message.addRecipient("name1", "email1"); + message.addRecipient("name2", "email2"); + + message.addCc("email3"); + message.addBcc("email4"); + + // Set the message content + message.text.content = "This is simple plain text message"; + + //Base64 data of image + const char *greenImg = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAoUlEQVR42u" + "3RAQ0AMAgAoJviyWxtAtNYwzmoQGT/eqwRQoQgRAhChCBECEKECBGCECEI" + "EYIQIQgRghCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCB" + "GCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQ" + "ghAhCBGCECEIEYIQIUKEIEQIQoQg5LoBBaDPbQYiMoMAAAAASUVORK5CYII="; + + // Declare the attachment data + SMTP_Attachment att; + + // Set the attatchment info + att.descr.filename = "green.png"; + att.descr.mime = "image/png"; + att.blob.data = (uint8_t *)greenImg; + att.blob.size = strlen(greenImg); + // Set the transfer encoding to base64 + att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + // We set the content encoding to match the above greenImage data + att.descr.content_encoding = Content_Transfer_Encoding::enc_base64; + + // Add attachment to the message + message.addAttachment(att); + + // Set debug option + smtp.debug(1); + + // Set the callback function to get the sending results + smtp.callback(smtpCallback); + + // Connect to the server + smtp.connect(&config); + + // Start sending Email and close the session + if (!MailClient.sendMail(&smtp, &message)) + Serial.println("Error sending Email, " + smtp.errorReason()); + +} + +void smtpCallback(SMTP_Status status) +{ + + Serial.println(status.info()); + + if (status.success()) + { + // See example for how to get the sending result + } +} + + +``` + + +### Read Email message + +The following code will read the latest email message in the "INBOX" mailbox. + +```C++ +// Include WiFi library +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +// Include ESP Mail Client library (this library) +#include + +// Declare the global used IMAPSession object for IMAP transport +IMAPSession imap; + +// Declare the global used Session_Config for user defined session credentials +Session_Config config; + +// Callback function to get the Email reading status +void imapCallback(IMAP_Status status) + +void setup() +{ + + Serial.begin(115200); + + WiFi.begin("", ""); + Serial.print("Connecting to Wi-Fi"); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + // Set the session config + config.server.host_name = "outlook.office365.com"; //for outlook.com + config.server.port = 993; // for SSL or 143 for Plain or TLS with STARTTLS + config.login.email = "your Email address"; + config.login.password = "your Email password"; + + // Declare the IMAP_Data object used for user defined IMAP operating options + // and contains the IMAP operating result + IMAP_Data imap_data; + + + // Set to enable the message content which will be stored in the IMAP_Data data + imap_data.enable.html = true; + imap_data.enable.text = true; + + + // Set the debug option + imap.debug(1); + + // Set the callback function to get message information + imap.callback(imapCallback); + + + // Connect to the server + imap.connect(&config, &imap_data); + + // Open or select the mailbox folder to read the message + imap.selectFolder("INBOX"); + + + // Define the message UID (number) which required to fetch or read the message + // In this case we will get the UID from the max message number (lastest message) + // then imap.getUID and imap.selectedFolder().msgCount() should be called after + // calling select or open the folder (mailbox). + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + // Empty search criteria to disable the messsage search + imap_data.search.criteria.clear(); + + + // Read the Email and close the session + MailClient.readMail(&imap); + + +} + + +void imapCallback(IMAP_Status status) +{ + + Serial.println(status.info()); + + if (status.success()) + { + // See example for how to get the message info + } +} + +``` + + +### Get Mailbox Changes Notification + +See [Mailbox_Changes_Notification.ino](/examples/IMAP/Mailbox_Changes_Notification/Mailbox_Changes_Notification.ino) for the example. + + +### Sending Custom IMAP commands + +Can't find what you want from exising IMAP functions, sending custom command was supported. + +Please read the RFC 3501 and RFC 9051 documents for the details of IMAP protocol commands. + +See [Custom_Command examples](/examples/IMAP/Custom_Command) for how to use. + + +### Using TCP session KeepAlive in ESP8266 and ESP32 + +The server connection will be probed at some intervals to maintain connection. + +The TCP session KeepAlive can be enabled from executing `.keepAlive` or `.keepAlive` with providing TCP options as arguments, i.e., + +`tcpKeepIdleSeconds`, `tcpKeepIntervalSeconds` and `tcpKeepCount`. + +Ex. + +```cpp +smtp.keepAlive(5 /* tcp KeepAlive idle 5 seconds */, 5 /* tcp KeeAalive interval 5 seconds */, 1 /* tcp KeepAlive count 1 */); + +imap.keepAlive(5 /* tcp KeepAlive idle 5 seconds */, 5 /* tcp KeeAalive interval 5 seconds */, 1 /* tcp KeepAlive count 1 */); + +// If one of three arguments is zero, the KeepAlive will be disabled. +``` + +To check the KeepAlive status, use `.isKeepAlive` or `.isKeepAlive`. + + +For the TCP (KeepAlive) options, see [here](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options). + +You can check the server connecting status, by executing `.connected()` or `.connected()` which will return true when connection to the server is still alive. + + +The TCP KeepAlive was currently available in ESP32 unless in ESP8266, [this ESP8266 PR #8940](https://github.com/esp8266/Arduino/pull/8940) should be merged in the [ESP8266 Arduino Core SDK](https://github.com/esp8266/Arduino/releases), i.e., it will be supported in the ESP8266 core version newer than v3.1.2. + + +In ESP8266 core v3.1.2 and older, the error can be occurred when executing `.keepAlive` or `.isKeepAlive` because of object slicing. + + +The Arduino Pico is currently not support TCP KeepAlive until it's implemented in WiFiClientSecure library as in ESP8266. + + +For External Client, this TCP KeepAlive option is not appliable and should be managed by external Client library. + + + + +### Use External Arduino Clients for External Networking Devices + +This library supports external netwoking devices e.g. WiFi modules, Ethernet modules and GSM modules that connected to the Arduino device via communication ports e.g. SPI and Serial, through the Arduino Clients (driver) for those networking devices e.g. WiFiClient, EthernetClient and GSMClient. + +Since v3.4.0, the Arduino Clients can be used with this library without additional external SSL Client required. + +No additional setup needed, only pass the Arduino Client to the function `setClient` or pass the TinyGSMClient and TinyGSM modem to the function `setGSMClient`. + +Two callback functions required (except for using `setGSMClient`) for network connection (with disconnection) and sending connecting status back to the Mail Client. + +If device has on-board WiFi and supports native (SDK) Ethernet, these two native networks will be auto detectd and used. + +If you don't want to let `ESP Mail Client` library to use the native networking and use external networking devices using Arduino Clients instead, the following build flags or macros should be defined in `Custom_ESP_Mail_FS.h`. + +```cpp +ESP_MAIL_DISABLE_ONBOARD_WIFI + +ESP_MAIL_DISABLE_NATIVE_ETHERNET +``` + +See [External Client Examples](/examples/SMTP/External_Client) for more external Client usage. + + +#### TTGO T-A7670 LTE with TinyGSM + +The following example showed how to use TTGO T-A7670 with `GSMClient` to connect to SMTP server. + +To allow TinyGSM library integration, the following build flag or macro should be defined in `Custom_ESP_Mail_FS.h`. + +```cpp +TINY_GSM_MODEM_SIM7600 +``` + +See the TinyGSM documentation and example for other SIMCom modules definition. + + +```cpp + +// For TTGO T-A7670 +#define TINY_GSM_MODEM_SIM7600 // SIMA7670 Compatible with SIM7600 AT instructions + +// Set serial for debug console (to the Serial Monitor, default speed 115200) +#define SerialMon Serial + +// Set serial for AT commands (to the module) +// Use Hardware Serial on Mega, Leonardo, Micro +#define SerialAT Serial1 + +// See all AT commands, if wanted +// #define DUMP_AT_COMMANDS + +// Define the serial console for debug prints, if needed +#define TINY_GSM_DEBUG SerialMon + +#define TINY_GSM_USE_GPRS true +#define TINY_GSM_USE_WIFI false + +// set GSM PIN, if any +#define GSM_PIN "" + +// Your GPRS credentials, if any +const char apn[] = "YourAPN"; +const char gprsUser[] = ""; +const char gprsPass[] = ""; + + +#define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds +#define TIME_TO_SLEEP 600 // Time ESP32 will go to sleep (in seconds) + +#define UART_BAUD 115200 +#define PIN_DTR 25 +#define PIN_TX 26 +#define PIN_RX 27 +#define PWR_PIN 4 +#define BAT_ADC 35 +#define BAT_EN 12 +#define PIN_RI 33 +#define PIN_DTR 25 +#define RESET 5 + +#define SD_MISO 2 +#define SD_MOSI 15 +#define SD_SCLK 14 +#define SD_CS 13 + + +#include +#include + + +TinyGsm modem(SerialAT); + +TinyGsmClient gsm_client(modem); // basic non-secure client + +SMTPSession smtp; + +// Callback function to get the Email sending status +void smtpCallback(SMTP_Status status); + +void setup() +{ + + SerialMon.begin(115200); + + // Set debug option + smtp.debug(1); + + // Set the callback function to get the sending results + smtp.callback(smtpCallback); + + delay(10); + pinMode(BAT_EN, OUTPUT); + digitalWrite(BAT_EN, HIGH); + + // A7670 Reset + pinMode(RESET, OUTPUT); + digitalWrite(RESET, LOW); + delay(100); + digitalWrite(RESET, HIGH); + delay(3000); + digitalWrite(RESET, LOW); + + pinMode(PWR_PIN, OUTPUT); + digitalWrite(PWR_PIN, LOW); + delay(100); + digitalWrite(PWR_PIN, HIGH); + delay(1000); + digitalWrite(PWR_PIN, LOW); + + DBG("Wait..."); + + delay(3000); + + SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX); + + // Restart takes quite some time + // To skip it, call init() instead of restart() + DBG("Initializing modem..."); + if (!modem.init()) + { + DBG("Failed to restart modem, delaying 10s and retrying"); + return; + } + + /* + 2 Automatic + 13 GSM Only + 14 WCDMA Only + 38 LTE Only + */ + modem.setNetworkMode(38); + if (modem.waitResponse(10000L) != 1) + { + DBG(" setNetworkMode faill"); + } + + String name = modem.getModemName(); + DBG("Modem Name:", name); + + String modemInfo = modem.getModemInfo(); + DBG("Modem Info:", modemInfo); + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + config.login.user_domain = F("127.0.0.1"); + + // Declare the SMTP_Message class variable to handle to message being transport + SMTP_Message message; + + // Set the message headers + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email using GSM module"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + // Set the message content + message.text.content = "This is simple plain text message"; + + // Set debug option + smtp.debug(1); + + // Set the callback function to get the sending results + smtp.callback(smtpCallback); + + smtp.setGSMClient(&gsm_client, &modem, GSM_PIN, apn, gprsUser, gprsPass); + + // Connect to the server with the defined session and options + smtp.connect(&config); + + // Start sending Email and close the session + if (!MailClient.sendMail(&smtp, &message)) + Serial.println("Error sending Email, " + smtp.errorReason()); +} + +void loop() +{ +} + +void smtpCallback(SMTP_Status status) +{ + + Serial.println(status.info()); + + if (status.success()) + { + // See example for how to get the sending result + } +} + +``` + +#### ESP32 and W5500 + +The below example will use ESP32 and W5500 and Ethernet client library to connect to SMTP server + + +```cpp + +#include + +#include + +#define WIZNET_RESET_PIN 26 // Connect W5500 Reset pin to GPIO 26 of ESP32 +#define WIZNET_CS_PIN 5 // Connect W5500 CS pin to GPIO 5 of ESP32 +#define WIZNET_MISO_PIN 19 // Connect W5500 MISO pin to GPIO 19 of ESP32 +#define WIZNET_MOSI_PIN 23 // Connect W5500 MOSI pin to GPIO 23 of ESP32 +#define WIZNET_SCLK_PIN 18 // Connect W5500 SCLK pin to GPIO 18 of ESP32 + + +EthernetClient eth_client; + +uint8_t Eth_MAC[] = {0x02, 0xF0, 0x0D, 0xBE, 0xEF, 0x01}; + +SMTPSession smtp; + +Session_Config config; + +// Callback function to get the Email sending status +void smtpCallback(SMTP_Status status); + +void ResetEthernet() +{ + Serial.println("Resetting WIZnet W5500 Ethernet Board... "); + pinMode(WIZNET_RESET_PIN, OUTPUT); + digitalWrite(WIZNET_RESET_PIN, HIGH); + delay(200); + digitalWrite(WIZNET_RESET_PIN, LOW); + delay(50); + digitalWrite(WIZNET_RESET_PIN, HIGH); + delay(200); +} + +void networkConnection() +{ + + Ethernet.init(WIZNET_CS_PIN); + + ResetEthernet(); + + Serial.println("Starting Ethernet connection..."); + Ethernet.begin(Eth_MAC); + + unsigned long to = millis(); + + while (Ethernet.linkStatus() == LinkOFF || millis() - to < 2000) + { + delay(100); + } + + if (Ethernet.linkStatus() == LinkON) + { + Serial.print("Connected with IP "); + Serial.println(Ethernet.localIP()); + } + else + { + Serial.println("Can't connect"); + } +} + +void networkStatusRequestCallback() +{ + smtp.setNetworkStatus(Ethernet.linkStatus() == LinkON); +} + +void setup() +{ + Serial.begin(115200); + + networkConnection(); + + config.server.host_name = "smtp.gmail.com"; //for gmail.com + config.server.port = 587; // requires connection upgrade via STARTTLS + config.login.email = "your Email address"; //set to empty for no SMTP Authentication + config.login.password = "your Email password"; //set to empty for no SMTP Authentication + config.login.user_domain = "client domain or ip e.g. mydomain.com"; + + // Declare the SMTP_Message class variable to handle to message being transport + SMTP_Message message; + + // Set the message headers + message.sender.name = "My Mail"; + message.sender.email = "sender or your Email address"; + message.subject = "Test sending Email"; + message.addRecipient("name1", "email1"); + message.addRecipient("name2", "email2"); + + message.addCc("email3"); + message.addBcc("email4"); + + // Set the message content + message.text.content = "This is simple plain text message"; + + // Set the callback function for connection upgrade + smtp.networkStatusRequestCallback(networkStatusRequestCallback); + + smtp.networkConnectionRequestCallback(networkConnection); + + smtp.setClient(ð_client); + + // Set debug option + smtp.debug(1); + + // Set the callback function to get the sending results + smtp.callback(smtpCallback); + + // Connect to the server with the defined session and options + smtp.connect(&config); + + // Start sending Email and close the session + if (!MailClient.sendMail(&smtp, &message)) + Serial.println("Error sending Email, " + smtp.errorReason()); + +} + +void smtpCallback(SMTP_Status status) +{ + + Serial.println(status.info()); + + if (status.success()) + { + // See example for how to get the sending result + } +} + +``` + + +## License + +The MIT License (MIT) + +Copyright (c) 2023 K. Suwatchai (Mobizt) + + +Permission is hereby granted, free of charge, to any person returning a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/lib/libesp32/lib_mail/_config.yml b/lib/libesp32/ESP-Mail-Client/_config.yml similarity index 100% rename from lib/libesp32/lib_mail/_config.yml rename to lib/libesp32/ESP-Mail-Client/_config.yml diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/ACL/ACL.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/ACL/ACL.ino new file mode 100644 index 000000000000..145e9815c8e0 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/ACL/ACL.ino @@ -0,0 +1,258 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example shows how to get, set the access control list. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + IMAP_Rights_List acl_list; + + Serial.println("\nGet ACLs..."); + + if (!imap.getACL("INBOX", &acl_list)) + { + Serial.println("Get ACLs failed"); + } + else + { + Serial.println("ACL..."); + + for (size_t i = 0; i < acl_list.size(); i++) + { + MailClient.printf("Identifier: %s, Rights: ", acl_list[i].identifier.c_str()); + String r; + for (int j = esp_mail_imap_rights_administer; j < esp_mail_imap_rights_maxType; j++) + { + if (acl_list[i].rights[j]) + r += (char)('a' + j); + } + + Serial.println(r); + } + } + + IMAP_Rights_Info acl; + acl.identifier = "Steve"; + acl.rights[esp_mail_imap_rights_administer] = true; + acl.rights[esp_mail_imap_rights_create] = true; + acl.rights[esp_mail_imap_rights_create_c] = true; + acl.rights[esp_mail_imap_rights_delete_message] = true; + acl.rights[esp_mail_imap_rights_delete_d] = true; + acl.rights[esp_mail_imap_rights_delete_mailbox] = true; + acl.rights[esp_mail_imap_rights_expunge] = true; + acl.rights[esp_mail_imap_rights_lookup] = true; + acl.rights[esp_mail_imap_rights_insert] = true; + acl.rights[esp_mail_imap_rights_post] = true; + acl.rights[esp_mail_imap_rights_read] = true; + acl.rights[esp_mail_imap_rights_write] = true; + acl.rights[esp_mail_imap_rights_seen] = true; + + Serial.println("\nSet ACLs..."); + + if (!imap.setACL("INBOX", &acl)) + { + Serial.println("Set ACLs failed"); + } + else + { + Serial.println("Set ACLs success"); + } + + Serial.println("\nGet my rights..."); + + if (!imap.myRights("INBOX", &acl)) + { + Serial.println("Set my rights failed"); + } + else + { + Serial.print("Rights: "); + + String r; + for (int i = esp_mail_imap_rights_administer; i < esp_mail_imap_rights_maxType; i++) + { + if (acl.rights[i]) + r += (char)('a' + i); + } + + Serial.println(r); + } + + Serial.println("\nDelete ACLs..."); + + if (!imap.deleteACL("INBOX", "Steve")) + { + Serial.println("Set ACLs failed"); + } + else + { + Serial.println("Delete ACLs success"); + } + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/Append_Message.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/Append_Message.ino new file mode 100644 index 000000000000..d7bbea2c21c8 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/Append_Message.ino @@ -0,0 +1,239 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to append message to mailbox. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#include + +// required IMAP and SMTP +#if defined(ENABLE_IMAP) && defined(ENABLE_SMTP) + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); +} + +#endif + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +// required IMAP and SMTP +#if defined(ENABLE_IMAP) && defined(ENABLE_SMTP) + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + ESP_Mail_Message message[2]; // The same usage as SMTP_Message + + message[0].sender.name = "Fred Foobar"; + message[0].sender.email = "foobar@Blurdybloop.example.COM"; + message[0].subject = "afternoon meeting"; + message[0].addRecipient("Joe Mooch", "mooch@owatagu.example.net"); + message[0].text.content = "Hello Joe, do you think we can meet at 3:30 tomorrow?"; + message[0].text.charSet = "us-ascii"; + message[0].text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + ESP_Mail_Attachment att[2]; // The same usage as SMTP_Attachment + + att[0].descr.filename = "shaun.png"; + att[0].descr.mime = "image/png"; + att[0].blob.data = shaun_png; + att[0].blob.size = sizeof(shaun_png); + att[0].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + message[0].addAttachment(att[0]); + + message[1].sender.name = "Joe Mooch"; + message[1].sender.email = "mooch@OWaTaGu.example.net"; + message[1].subject = "Re: afternoon meeting"; + message[1].addRecipient("Fred Foobar", "foobar@blurdybloop.example.com"); + message[1].text.content = "3:30 is fine with me."; + message[1].text.charSet = "us-ascii"; + message[1].text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + att[1].descr.filename = "mu_law.wav"; + att[1].descr.mime = "audio/basic"; + att[1].blob.data = mu_law_wave; + att[1].blob.size = sizeof(mu_law_wave); + att[1].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + message[1].addAttachment(att[1]); + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + if (!imap.selectFolder(F("INBOX"))) + return; + + // If MULTIAPPEND extension is supported, the multiple messages will send by a single APPEND command. + // If not, one message can append for a APPEND command. + // Outlook.com does not accept flag and date/time arguments in APPEND command + if (!MailClient.appendMessage(&imap, &message[0], false /* if not last message to append */, "\\Flagged" /* flags or empty string for Outlook.com */, "Thu, 16 Jun 2022 12:30:25 -0800 (PST)" /* date/time or empty string for Outlook.com */)) + MailClient.printf("Message appending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + + if (!MailClient.appendMessage(&imap, &message[1], true /* last message to append */)) + MailClient.printf("Message appending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); + +#endif +} + +void loop() +{ +} diff --git a/lib/libesp32/lib_mail/examples/Send_Parallel_Attachment/data.h b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/data.h similarity index 98% rename from lib/libesp32/lib_mail/examples/Send_Parallel_Attachment/data.h rename to lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/data.h index 0b73e9752b42..c7a88aeab659 100644 --- a/lib/libesp32/lib_mail/examples/Send_Parallel_Attachment/data.h +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/data.h @@ -1,1957 +1,1957 @@ -#include - -static const uint8_t mu_law_wave[] PROGMEM = { -0x52, 0x49, 0x46, 0x46, 0x84, 0x5D, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20, -0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, -0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x66, 0x61, 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0x00, 0x5D, -0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x5D, 0x00, 0x00, 0xFB, 0xFD, 0xFF, 0xFE, 0xFF, 0x7F, -0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7C, 0x7D, -0x7C, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7E, 0xFF, 0x7F, -0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7C, 0x7C, 0x7B, -0x7B, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, -0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x79, 0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7C, 0x7E, 0xFF, 0xFE, 0xFE, -0xFF, 0x7E, 0x7C, 0x7D, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x79, 0x78, 0x79, -0x7A, 0x79, 0x78, 0x78, 0x78, 0x77, 0x78, 0x78, 0x79, 0x79, 0x78, 0x77, 0x77, 0x78, 0x78, 0x79, -0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, -0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF8, -0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFB, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, -0xFF, 0xFF, 0xFE, 0x7E, 0x7D, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7C, -0x7B, 0x7A, 0x79, 0x79, 0x79, 0x77, 0x77, 0x78, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, -0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x79, -0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, -0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7A, 0x79, -0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, 0xFB, 0xFC, -0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, -0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, -0x7C, 0x7B, 0x79, 0x7A, 0x7A, 0x7A, 0x7A, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7C, 0x79, 0x79, 0x7A, -0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7C, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFE, -0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, -0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, -0x78, 0x78, 0x77, 0x77, 0x77, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, 0x72, 0x73, 0x73, -0x74, 0x74, 0x74, 0x75, 0x77, 0x78, 0x78, 0x77, 0x76, 0x77, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, -0x78, 0x79, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, -0x7E, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFD, 0xFE, 0x7F, 0xFF, -0x7F, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7D, 0x7F, -0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7D, -0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFC, 0xFC, 0xFD, -0xFC, 0xFB, 0xFB, 0xFC, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFD, 0xFE, -0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x79, -0x78, 0x78, 0x78, 0x76, 0x74, 0x74, 0x73, 0x72, 0x75, 0x77, 0x77, 0x76, 0x75, 0x75, 0x76, 0x77, -0x77, 0x76, 0x74, 0x74, 0x74, 0x74, 0x76, 0x76, 0x76, 0x77, 0x75, 0x76, 0x78, 0x79, 0x77, 0x77, -0x79, 0x7B, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFE, -0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7F, 0x7F, 0x7D, 0x7E, 0xFF, 0x7F, -0x7F, 0xFF, 0x7F, 0x7E, 0x7D, 0x7E, 0xFF, 0x7E, 0x7F, 0x7F, 0x7C, 0x7D, 0x7F, 0x7D, 0x7E, 0x7E, -0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x7D, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, -0x7D, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFB, 0xFB, -0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, -0x78, 0x79, 0x78, 0x75, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x73, 0x74, 0x73, 0x72, 0x73, -0x75, 0x75, 0x74, 0x76, 0x74, 0x72, 0x73, 0x74, 0x75, 0x75, 0x76, 0x77, 0x77, 0x78, 0x77, 0x77, -0x77, 0x78, 0x78, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, -0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7C, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, -0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, -0xFE, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0xFF, 0x7E, 0x7E, 0x7E, 0x7D, -0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, -0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7B, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7D, 0x7C, 0x7C, -0x7D, 0x7C, 0x7C, 0x7E, 0x7E, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, -0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, -0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, -0x7E, 0x7E, 0x7E, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7F, -0x7D, 0x7B, 0x7C, 0x7C, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7E, -0x7F, 0x7E, 0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x74, 0x73, -0x72, 0x73, 0x74, 0x75, 0x77, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, -0x7C, 0x7D, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, -0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x79, 0x79, -0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, -0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7D, 0x7D, -0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, -0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, -0x7A, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, -0x7D, 0x7E, 0xFF, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, -0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7C, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x78, -0x78, 0x77, 0x77, 0x76, 0x75, 0x74, 0x74, 0x74, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x76, 0x75, -0x74, 0x75, 0x77, 0x78, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, -0xFC, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, -0xF8, 0xFA, 0xF8, 0xF6, 0xF7, 0xF7, 0xF8, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFB, -0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, -0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFD, 0xFE, 0xFF, -0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, -0x7D, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x78, 0x79, 0x78, 0x77, 0x76, -0x76, 0x75, 0x73, 0x74, 0x73, 0x71, 0x70, 0x70, 0x71, 0x72, 0x71, 0x71, 0x70, 0x6F, 0x6F, 0x6F, -0x70, 0x71, 0x71, 0x72, 0x73, 0x74, 0x74, 0x74, 0x76, 0x77, 0x76, 0x78, 0x79, 0x79, 0x79, 0x78, -0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, -0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7D, -0x7D, 0x7D, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7C, 0x7A, 0x78, 0x79, 0x78, 0x77, -0x76, 0x78, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, -0x7E, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, 0xFA, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, -0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF7, 0xF9, 0xF9, 0xF8, 0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFD, 0xFD, -0xFC, 0xFD, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0x7F, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, -0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x75, 0x76, 0x76, 0x75, 0x76, 0x77, -0x78, 0x79, 0x7B, 0x7B, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7A, 0x7B, 0x7B, 0x7A, -0x7B, 0x7D, 0x7E, 0x7B, 0x7C, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFE, 0xFF, -0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7D, 0x7F, 0x7F, 0x7C, 0x7B, -0x7A, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7C, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7C, 0x7C, -0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, -0x7D, 0xFE, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF9, 0xF8, 0xF5, 0xF4, 0xF7, 0xF8, -0xF8, 0xF8, 0xF9, 0xFB, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, -0x7A, 0x7B, 0x7B, 0x7A, 0x78, 0x78, 0x77, 0x76, 0x76, 0x75, 0x76, 0x76, 0x76, 0x77, 0x75, 0x75, -0x76, 0x75, 0x76, 0x76, 0x78, 0x78, 0x77, 0x78, 0x76, 0x74, 0x75, 0x77, 0x79, 0x7A, 0x7A, 0x7B, -0x7C, 0x7D, 0x7D, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, -0xFE, 0x7F, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0xFF, 0xFD, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, -0xFC, 0xFD, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, -0x7B, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7E, 0x7E, 0xFF, -0xFF, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, -0x7C, 0x7D, 0xFF, 0x7E, 0x7C, 0x7D, 0xFF, 0xFF, 0xFF, 0xFD, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, 0x7E, -0x7F, 0x7E, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x79, -0x77, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7C, 0x7D, 0x7D, 0x7E, 0xFD, 0xFD, 0xFE, 0xFC, 0xFC, 0xFB, -0xFB, 0xFC, 0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, -0xFF, 0xFF, 0xFD, 0xFC, 0xFD, 0xFD, 0xFC, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7C, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, -0x7B, 0x7C, 0x7D, 0x7B, 0x7B, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x75, 0x73, 0x72, -0x72, 0x72, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x74, -0x75, 0x76, 0x76, 0x76, 0x77, 0x78, 0x77, 0x78, 0x79, 0x77, 0x78, 0x78, 0x79, 0x7A, 0x7A, 0x7A, -0x7A, 0x79, 0x77, 0x76, 0x76, 0x78, 0x78, 0x77, 0x77, 0x77, 0x75, 0x74, 0x74, 0x75, 0x75, 0x76, -0x79, 0x79, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7D, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFE, 0xFC, -0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF4, 0xF6, 0xF8, 0xF7, 0xF7, 0xF9, 0xF9, -0xF9, 0xF8, 0xF8, 0xFB, 0xFA, 0xF9, 0xFA, 0xFB, 0xFC, 0xFE, 0xFC, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, -0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, -0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7F, 0xFE, 0xFE, 0xFD, 0xFD, -0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFB, 0xFC, -0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, -0x7C, 0x7B, 0x7B, 0x7C, 0x79, 0x79, 0x79, 0x78, 0x76, 0x75, 0x76, 0x78, 0x77, 0x76, 0x76, 0x77, -0x76, 0x74, 0x74, 0x75, 0x75, 0x75, 0x74, 0x74, 0x76, 0x77, 0x78, 0x7A, 0x7C, 0x7B, 0x7A, 0x7D, -0x7E, 0x7E, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, -0xFF, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFE, 0xFD, 0xFC, 0xFE, -0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7F, 0xFE, 0xFC, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0x7F, 0x7E, 0xFF, -0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7E, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, -0x7E, 0x7D, 0x7E, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7B, 0x7B, -0x7D, 0x7E, 0x7E, 0x7D, 0xFF, 0xFF, 0x7F, 0x7F, 0x7E, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x77, 0x77, -0x77, 0x78, 0x78, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x74, 0x74, 0x75, 0x74, 0x72, 0x74, -0x76, 0x74, 0x74, 0x76, 0x76, 0x74, 0x73, 0x73, 0x72, 0x73, 0x74, 0x76, 0x77, 0x75, 0x73, 0x75, -0x77, 0x78, 0x75, 0x75, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7B, -0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7C, 0x7F, -0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x79, 0x77, 0x77, -0x78, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7B, 0x7C, 0x7B, 0x7C, 0x7D, 0xFF, -0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, -0xFA, 0xF9, 0xF9, 0xF7, 0xF7, 0xF7, 0xF4, 0xF4, 0xF4, 0xF2, 0xEF, 0xEE, 0xEF, 0xF2, 0xF2, 0xF1, -0xF2, 0xF5, 0xF5, 0xF3, 0xF1, 0xF2, 0xF5, 0xF7, 0xF8, 0xFA, 0xFB, 0xFC, 0xFC, 0xFB, 0xFC, 0xFC, -0xFD, 0xFF, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, 0x78, 0x77, 0x76, 0x75, 0x75, 0x74, 0x71, 0x70, 0x71, -0x71, 0x71, 0x70, 0x6F, 0x71, 0x71, 0x71, 0x73, 0x75, 0x77, 0x77, 0x76, 0x79, 0x7A, 0x79, 0x79, -0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0x7E, 0x7D, 0x7E, 0x7E, 0x7D, 0x7D, -0x7E, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x78, -0x7A, 0x7C, 0x7C, 0x7A, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7D, 0x7C, -0x7C, 0x7E, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7E, -0x7D, 0x7D, 0xFF, 0xFF, 0x7F, 0xFF, 0xFC, 0xFC, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, -0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7F, 0x7F, 0x7E, 0x7D, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, -0x7B, 0x7C, 0x7C, 0x7A, 0x78, 0x78, 0x7B, 0x7A, 0x77, 0x75, 0x76, 0x75, 0x76, 0x76, 0x76, 0x76, -0x78, 0x79, 0x78, 0x75, 0x75, 0x76, 0x77, 0x7A, 0x7D, 0xFF, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFA, -0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0x7E, 0x78, 0x76, 0x72, 0x70, 0x71, 0x75, 0x77, 0x77, 0x79, 0x7A, -0x7A, 0x7A, 0x7B, 0xFF, 0xFB, 0xFA, 0xF9, 0xFB, 0xFD, 0xFE, 0x7E, 0x7F, 0xFF, 0xFC, 0xF6, 0xF3, -0xF7, 0xFC, 0xFF, 0x7A, 0x73, 0x6E, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6E, 0x6F, 0x74, 0x73, 0x72, -0x75, 0x7A, 0x7D, 0x7D, 0xFF, 0xFF, 0x7C, 0x7C, 0x7D, 0x7B, 0x7A, 0x79, 0x7B, 0xFF, 0xFF, 0x7D, -0x7C, 0xFF, 0xFE, 0x7D, 0xFC, 0xF3, 0xF6, 0xFC, 0xFE, 0xFE, 0xFF, 0x78, 0x75, 0x79, 0x7A, 0x7E, -0xF8, 0xF6, 0xF6, 0xF2, 0xEF, 0xEE, 0xF0, 0xF7, 0xFD, 0xFE, 0xFD, 0x7B, 0x77, 0x7C, 0xFF, 0xFB, -0xFD, 0x7D, 0xFF, 0x7C, 0x78, 0x7A, 0x7A, 0xFF, 0xF9, 0xF5, 0xF1, 0xF4, 0xFA, 0xFC, 0xFC, 0xFA, -0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFF, 0x7D, 0x7B, 0x7D, 0x7E, 0x7A, 0x76, 0x76, 0x75, -0x72, 0x75, 0x7B, 0x7D, 0x7A, 0x7A, 0x7D, 0xFF, 0x7C, 0x7C, 0xFF, 0x7D, 0x7A, 0x7B, 0x7C, 0x7E, -0xFC, 0xFC, 0x7F, 0xFE, 0xFD, 0xFE, 0xFC, 0xF8, 0xF9, 0xFA, 0xFB, 0xFE, 0x7E, 0x79, 0x72, 0x72, -0x74, 0x76, 0x78, 0x76, 0x78, 0x7A, 0x75, 0x76, 0x77, 0x75, 0x73, 0x73, 0x73, 0x73, 0x74, 0x73, -0x73, 0x77, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x73, 0x73, 0x7B, 0x7C, 0x7C, 0xFC, 0xFC, 0xFE, 0x7F, -0x76, 0x73, 0x76, 0x73, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0x7D, 0x7B, 0x7B, -0x7C, 0x7A, 0x78, 0x7B, 0x7B, 0x7D, 0x7F, 0x7A, 0x77, 0x73, 0x6F, 0x70, 0x72, 0x73, 0x72, 0x72, -0x73, 0x74, 0x74, 0x76, 0x7D, 0xFE, 0x7D, 0x7C, 0x7C, 0x78, 0x76, 0x77, 0x79, 0x7B, 0xFF, 0xFD, -0xFE, 0x7E, 0x7B, 0x7A, 0x78, 0x78, 0x7B, 0x7C, 0x7C, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x79, 0x7B, -0xFF, 0xFA, 0xF9, 0xFD, 0x7E, 0x7D, 0x7C, 0x7B, 0x7E, 0xFE, 0xFC, 0xFF, 0x7E, 0xFE, 0xFD, 0xFE, -0xFD, 0xFC, 0xFB, 0xFC, 0xFC, 0xFD, 0xF9, 0xF3, 0xF2, 0xF3, 0xF4, 0xF6, 0xF6, 0xF8, 0xFA, 0xFC, -0xFB, 0xF7, 0xF9, 0xFC, 0xFC, 0xFD, 0xFD, 0x7E, 0x7C, 0x7F, 0xFF, 0x7D, 0x7A, 0x7A, 0x7B, 0x78, -0x78, 0x78, 0x75, 0x75, 0x76, 0x79, 0x7A, 0x79, 0x7C, 0x7F, 0xFD, 0xFF, 0x7E, 0xFF, 0x7D, 0x79, -0x77, 0x78, 0x79, 0x78, 0x79, 0x7C, 0x7D, 0x7F, 0x7E, 0x7E, 0xFE, 0xFC, 0xF8, 0xF7, 0xFA, 0xFB, -0xFC, 0xFD, 0xFF, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, 0x7B, 0x7D, 0xFE, 0xF9, 0xF5, 0xF6, 0xF6, 0xF4, -0xF6, 0xFA, 0xFE, 0x7D, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFF, 0xFF, 0xFA, 0xFA, 0xFE, -0x7C, 0x75, 0x71, 0x72, 0x74, 0x75, 0x74, 0x75, 0x75, 0x77, 0x79, 0x79, 0x77, 0x74, 0x74, 0x74, -0x72, 0x71, 0x70, 0x71, 0x70, 0x6F, 0x72, 0x73, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7A, 0x78, -0x77, 0x77, 0x76, 0x74, 0x73, 0x72, 0x70, 0x71, 0x75, 0x78, 0x7B, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, -0x7E, 0xFF, 0xFD, 0x7F, 0x7C, 0x7B, 0x7F, 0xFD, 0xFF, 0xFE, 0xFC, 0xFE, 0xFD, 0xFC, 0xFA, 0xF7, -0xF7, 0xFB, 0xFD, 0xFE, 0x7E, 0x7C, 0x7B, 0x7A, 0x7B, 0x79, 0x75, 0x75, 0x76, 0x78, 0x7D, 0xFF, -0x7E, 0x7D, 0x7E, 0x7C, 0x77, 0x75, 0x76, 0x76, 0x78, 0x7E, 0xFD, 0xFB, 0xFC, 0xFD, 0xFE, 0x7C, -0x78, 0x78, 0x7A, 0x7B, 0x7E, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x78, 0x79, 0x7B, 0x7A, 0x7D, 0xFC, -0xFD, 0x7E, 0xFF, 0xFB, 0xF7, 0xF6, 0xF7, 0xF7, 0xF6, 0xFA, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0xFF, -0xFC, 0xFB, 0xF9, 0xFD, 0xFE, 0xFD, 0x7E, 0x79, 0x76, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x72, 0x76, -0x7A, 0x7E, 0xFF, 0xFF, 0x7C, 0x7B, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7E, 0xFF, 0xFF, 0x7E, 0x7D, -0x7D, 0x7E, 0x7C, 0x78, 0x79, 0x7A, 0x7B, 0xFF, 0xFF, 0x7F, 0x7E, 0x7B, 0x79, 0x79, 0x76, 0x72, -0x73, 0x7B, 0xFF, 0xFE, 0xFB, 0xFA, 0xFA, 0xFC, 0x7D, 0x78, 0x77, 0x78, 0x79, 0x79, 0x78, 0x79, -0x77, 0x73, 0x74, 0x76, 0x77, 0x79, 0x7A, 0x7B, 0x7F, 0xFD, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0x7C, -0x78, 0x78, 0x7B, 0x7B, 0x7A, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0x7E, 0xFF, 0xFD, 0xFC, 0xF9, 0xF5, -0xF2, 0xF0, 0xF2, 0xF3, 0xF0, 0xF1, 0xF2, 0xF1, 0xF4, 0xF7, 0xF8, 0xFC, 0xFC, 0xF6, 0xF3, 0xF4, -0xF5, 0xF5, 0xF6, 0xFB, 0xFF, 0xFF, 0xFF, 0x7D, 0x7D, 0x7E, 0x7D, 0x79, 0x75, 0x74, 0x75, 0x72, -0x72, 0x75, 0x75, 0x74, 0x77, 0x7A, 0x7A, 0x7A, 0x7A, 0x77, 0x74, 0x73, 0x72, 0x74, 0x75, 0x76, -0x77, 0x74, 0x74, 0x77, 0x79, 0x79, 0x79, 0x78, 0x77, 0x74, 0x70, 0x6F, 0x70, 0x6F, 0x6E, 0x6E, -0x6E, 0x6F, 0x6F, 0x72, 0x75, 0x72, 0x74, 0x79, 0x7B, 0x7B, 0x7B, 0x7D, 0xFF, 0x7E, 0x7F, 0xFE, -0xFE, 0x7F, 0x7D, 0x7D, 0xFF, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7E, 0x7C, 0x79, 0x77, 0x75, 0x76, -0x77, 0x78, 0x78, 0x74, 0x75, 0x7A, 0x7F, 0xFB, 0xF9, 0xF9, 0xF8, 0xFD, 0x7E, 0x7B, 0x76, 0x78, -0x7B, 0x7C, 0x7E, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7C, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x7D, 0x7B, -0x7B, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0x7F, 0x7F, 0xFF, 0xFD, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0x7D, -0x7C, 0x7F, 0xFB, 0xF7, 0xF6, 0xFC, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0x7C, -0x76, 0x74, 0x74, 0x79, 0x79, 0x76, 0x77, 0x79, 0x7C, 0x7D, 0x7B, 0x7B, 0x7B, 0x7E, 0xFD, 0xFB, -0xF9, 0xF9, 0xFE, 0x7C, 0x79, 0x79, 0x77, 0x76, 0x79, 0x7B, 0x7D, 0x7C, 0x7C, 0x7D, 0x7C, 0x78, -0x75, 0x74, 0x72, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0x7F, 0x7F, 0x7D, -0x7A, 0x78, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x7B, 0xFF, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, -0xF8, 0xF9, 0xFE, 0x7E, 0xFF, 0xFE, 0xFE, 0x7D, 0x7A, 0x78, 0x75, 0x75, 0x77, 0x7A, 0x7A, 0x79, -0x7B, 0x7D, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF7, -0xF8, 0xFA, 0xF8, 0xF9, 0xFC, 0xFD, 0xFD, 0xFC, 0xF9, 0xF7, 0xF8, 0xFC, 0x7E, 0x7B, 0x7A, 0x7A, -0x79, 0x79, 0x7A, 0x7A, 0x7A, 0x77, 0x72, 0x72, 0x74, 0x76, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, -0x7D, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, -0x7A, 0x7A, 0x77, 0x75, 0x75, 0x74, 0x73, 0x70, 0x6E, 0x6E, 0x6E, 0x6F, 0x72, 0x75, 0x77, 0x7A, -0x7D, 0x7D, 0x7D, 0x7E, 0xFF, 0x7D, 0x7A, 0x7A, 0x7A, 0x7B, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, -0x7D, 0x7B, 0x78, 0x75, 0x73, 0x74, 0x75, 0x75, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7D, 0xFE, 0xFC, -0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, 0xF6, 0xF8, 0xFB, 0xFC, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x7C, -0x7C, 0x7B, 0x7C, 0x7B, 0x79, 0x79, 0x7A, 0x79, 0x76, 0x74, 0x72, 0x72, 0x73, 0x74, 0x75, 0x77, -0x78, 0x78, 0x78, 0x77, 0x76, 0x75, 0x75, 0x78, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, -0xFE, 0xFC, 0xFC, 0xFC, 0xFA, 0xF8, 0xF7, 0xF7, 0xF8, 0xF7, 0xF5, 0xF5, 0xF5, 0xF4, 0xF5, 0xF6, -0xF7, 0xF8, 0xF9, 0xFB, 0xFE, 0x7F, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7D, 0x7A, 0x7A, 0x7A, -0x7A, 0x79, 0x79, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7A, 0x7A, 0x79, 0x77, 0x76, -0x77, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7B, -0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0xFE, -0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, -0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x76, 0x77, 0x78, 0x77, 0x79, -0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7D, 0x7B, 0x7B, 0x7D, 0x7C, 0x7D, 0xFF, 0x7E, -0xFF, 0xFD, 0xFB, 0xF9, 0xF8, 0xF9, 0xF9, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF3, 0xF5, 0xF6, 0xF6, -0xF7, 0xF9, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFC, 0xFB, 0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xF8, -0xF8, 0xF9, 0xFB, 0xFD, 0x7E, 0x7B, 0x78, 0x78, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x75, 0x75, -0x73, 0x71, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x6E, 0x6E, 0x6E, 0x6D, -0x6D, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x70, 0x72, 0x73, 0x74, 0x75, 0x79, 0x7C, 0x7D, 0x7E, 0xFF, -0xFF, 0xFF, 0xFD, 0xFC, 0xFA, 0xF9, 0xFB, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0x7E, 0x7B, 0x7A, -0x79, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7C, 0x7C, 0x7B, 0x79, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x7C, -0x7E, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0xFD, -0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFB, 0xFB, -0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFD, 0xFC, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF7, -0xF6, 0xF7, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7D, 0x7C, 0x7C, -0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, -0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x78, 0x77, 0x76, 0x75, 0x75, 0x75, 0x76, 0x76, 0x75, 0x76, -0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFE, -0xFD, 0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFF, 0x7F, 0x7E, 0x7C, 0x7C, 0x7B, -0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7B, -0x7A, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7B, 0x7F, 0xFD, 0x7D, 0x79, 0xFE, -0xFA, 0xFE, 0xFC, 0xF8, 0xFC, 0xFF, 0xFF, 0xFE, 0xFB, 0xFC, 0x7F, 0xFF, 0x7F, 0x7C, 0x7D, 0x7D, -0x7E, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, -0x7D, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, -0x7D, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x74, 0x73, -0x74, 0x75, 0x74, 0x74, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x77, 0x77, 0x79, 0x7B, 0x7C, 0x7D, -0x7D, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFB, 0xFC, 0xFD, -0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, -0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, -0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, -0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, -0x7D, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x77, 0x78, 0x76, 0x76, 0x78, 0x7A, 0x78, 0x78, 0x78, 0x77, -0x77, 0x76, 0x75, 0x76, 0x75, 0x75, 0x77, 0x77, 0x76, 0x74, 0x74, 0x75, 0x76, 0x75, 0x76, 0x76, -0x75, 0x76, 0x76, 0x75, 0x74, 0x73, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x78, 0x7A, 0x7A, 0x7B, -0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFD, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xFE, -0xFE, 0xFE, 0x7F, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFD, 0xFD, 0xFD, -0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0xFE, 0xFC, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF9, 0xFA, -0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0xFE, 0xFF, 0x7F, 0xFF, 0x7E, 0x7D, 0x7B, 0x79, 0x79, 0x7B, 0x7C, -0x7C, 0x7D, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x78, 0x75, 0x75, 0x76, 0x76, -0x78, 0x75, 0x76, 0x77, 0x73, 0x75, 0x73, 0x77, 0x76, 0x73, 0x78, 0x73, 0x78, 0x77, 0x75, 0x7B, -0x70, 0x7E, 0x68, 0x5B, 0xE4, 0xD9, 0x77, 0x66, 0x5F, 0x6B, 0xEB, 0x78, 0x6B, 0xEC, 0xE9, 0x67, -0x5A, 0x62, 0xF8, 0xE2, 0xF1, 0x6B, 0x6F, 0x72, 0x6E, 0x6D, 0x72, 0xEF, 0xE7, 0xF7, 0x6D, 0x6A, -0x70, 0x7B, 0xFC, 0xF5, 0xED, 0xEF, 0x7D, 0x71, 0x70, 0xFF, 0xEE, 0xEF, 0xF8, 0xFC, 0x7B, 0x73, -0x6F, 0x71, 0x7E, 0xF2, 0xF2, 0x76, 0x67, 0x68, 0x78, 0xF7, 0xF5, 0xFC, 0x7E, 0x7B, 0x73, 0x70, -0x79, 0xF4, 0xEB, 0xEC, 0xF8, 0x7C, 0x7B, 0xFF, 0xF6, 0xEF, 0xEF, 0xF4, 0xF8, 0xFE, 0x7D, 0xFE, -0xF8, 0xF4, 0xF4, 0xF9, 0xFE, 0x7E, 0x7C, 0x7C, 0xFD, 0xF8, 0xF8, 0xFD, 0x7D, 0x7A, 0x79, 0x7C, -0xFF, 0xFD, 0xFB, 0xFC, 0x7D, 0x7B, 0x7D, 0x7F, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7A, 0x79, 0x7C, -0x7E, 0x7D, 0x7D, 0x7B, 0x78, 0x79, 0x7B, 0x7A, 0x78, 0x79, 0x77, 0x76, 0x78, 0x71, 0x70, 0x78, -0x7E, 0xF6, 0xFE, 0x67, 0x68, 0xF4, 0xEF, 0x74, 0x69, 0x6A, 0xFF, 0x7E, 0x6E, 0xF2, 0xFB, 0x69, -0x66, 0x69, 0xDD, 0xD9, 0x71, 0x7B, 0x74, 0x5F, 0x69, 0x61, 0x6A, 0xE6, 0xEC, 0x66, 0x55, 0x50, -0x5C, 0xFB, 0xED, 0xF5, 0xFA, 0x6F, 0x6E, 0x7B, 0xE8, 0xCF, 0xC7, 0xC6, 0xCA, 0xCB, 0xDB, 0x3A, -0x2E, 0x49, 0xBD, 0xB7, 0xC6, 0x4D, 0x41, 0x4B, 0x49, 0x4D, 0xD9, 0xBF, 0xC2, 0xFD, 0x3F, 0x3D, -0x51, 0xDF, 0xCD, 0xCC, 0xD5, 0xF4, 0x50, 0x46, 0x4D, 0xF0, 0xCB, 0xCA, 0xDA, 0x61, 0x51, 0x52, -0x5B, 0xE6, 0xD0, 0xCE, 0xDC, 0x5D, 0x53, 0x51, 0x6A, 0xF9, 0x48, 0x67, 0xC2, 0xE0, 0x5F, 0x5B, -0x4C, 0x71, 0xFA, 0x6E, 0xCE, 0xCF, 0x7A, 0x64, 0x79, 0xD8, 0xCE, 0xD1, 0xCD, 0xC3, 0xC5, 0xCD, -0xC7, 0xDC, 0x42, 0x3E, 0x53, 0xD2, 0xC0, 0xDE, 0x44, 0x48, 0x58, 0x53, 0x59, 0xFA, 0xD9, 0xD6, -0x5E, 0x43, 0x47, 0x61, 0xE1, 0xD8, 0xEA, 0x64, 0x46, 0x3C, 0x51, 0x7F, 0x77, 0xD0, 0xF6, 0x4B, -0x4B, 0x4A, 0x6F, 0xCA, 0xC6, 0xC9, 0xC7, 0xC2, 0xC8, 0xBD, 0xB0, 0xAB, 0xBB, 0x1F, 0x19, 0x5F, -0xA3, 0xA5, 0xBA, 0x30, 0x30, 0x47, 0x31, 0x37, 0xBC, 0xAB, 0xB8, 0x3D, 0x2B, 0x30, 0x4E, 0xBD, -0xB4, 0xC4, 0x5D, 0x3F, 0x38, 0x41, 0x6E, 0xC8, 0xC1, 0xDC, 0x4B, 0x3B, 0x3F, 0xE5, 0xBF, 0xBC, -0xC8, 0xE5, 0xDE, 0xC0, 0xAE, 0xAD, 0xAF, 0xC1, 0x20, 0x1A, 0x63, 0xA8, 0xA7, 0xB5, 0x36, 0x2E, -0x3D, 0x32, 0x3F, 0xBD, 0xB1, 0xC1, 0x39, 0x2E, 0x42, 0xE8, 0xCA, 0xC3, 0xDB, 0x5F, 0x47, 0x39, -0x47, 0xD5, 0xCB, 0xD1, 0x70, 0x4B, 0x4D, 0xF0, 0xC1, 0xB3, 0xAE, 0xB4, 0xBE, 0xB8, 0xB8, 0x34, -0x1C, 0x27, 0xB6, 0xA3, 0xAC, 0x4F, 0x2C, 0x32, 0x3B, 0x3E, 0xEB, 0xB9, 0xBB, 0x45, 0x2E, 0x39, -0x60, 0xC3, 0xBB, 0xD8, 0x4D, 0x45, 0x41, 0x57, 0xD6, 0xDE, 0x79, 0x5D, 0x50, 0x5B, 0xDB, 0xBE, -0xB4, 0xB3, 0xBC, 0xC4, 0xB6, 0xAC, 0xC2, 0x26, 0x1A, 0x30, 0xAB, 0xA9, 0xBB, 0x61, 0x33, 0x30, -0x36, 0x39, 0xCF, 0xB9, 0x64, 0x41, 0x42, 0x3E, 0x5E, 0xD3, 0xCF, 0xC4, 0xEC, 0x47, 0x56, 0x5C, -0x50, 0x57, 0x62, 0xDF, 0xD2, 0xD3, 0xC4, 0xB6, 0xB3, 0xBA, 0xB8, 0xAD, 0xAF, 0x3C, 0x1C, 0x1E, -0xCB, 0xA1, 0xA9, 0xFE, 0x2D, 0x2C, 0x39, 0x3D, 0x64, 0xBE, 0xD5, 0x4B, 0x42, 0x3A, 0x40, 0xEC, -0xC4, 0xBE, 0xD1, 0x4A, 0x3E, 0x47, 0x62, 0xE4, 0xD7, 0xD6, 0xDC, 0xDE, 0xCD, 0xB6, 0xAD, 0xAE, -0xAC, 0xAD, 0xE6, 0x22, 0x19, 0x2E, 0xA6, 0x9E, 0xB2, 0x39, 0x28, 0x2D, 0x39, 0x4E, 0xC2, 0xBE, -0x5B, 0x3E, 0x3B, 0x3C, 0x58, 0xC6, 0xBD, 0xC7, 0x60, 0x3F, 0x3F, 0x51, 0xED, 0xCF, 0xC8, 0xD1, -0xE0, 0xD9, 0xBC, 0xAC, 0xAB, 0xAB, 0xA9, 0xC2, 0x25, 0x17, 0x22, 0xAE, 0x9D, 0xA9, 0x47, 0x26, -0x29, 0x34, 0x47, 0xC5, 0xBB, 0x77, 0x3F, 0x3A, 0x38, 0x4E, 0xC6, 0xBC, 0xBE, 0xE6, 0x3D, 0x39, -0x43, 0x67, 0xCE, 0xC7, 0xD6, 0xED, 0xD9, 0xBD, 0xAB, 0xAB, 0xAE, 0xA9, 0xB4, 0x30, 0x1A, 0x1B, -0xD5, 0x9D, 0xA3, 0xDA, 0x2A, 0x26, 0x31, 0x3C, 0x6C, 0xBF, 0xCE, 0x5E, 0x42, 0x32, 0x3C, 0xD6, -0xBC, 0xB8, 0xCC, 0x3F, 0x37, 0x3B, 0x51, 0xCC, 0xC1, 0xCC, 0xE2, 0xDE, 0xBD, 0xAC, 0xAA, 0xA9, -0xA7, 0xC5, 0x26, 0x18, 0x1F, 0xB7, 0x9D, 0xA6, 0xDF, 0x2B, 0x26, 0x2D, 0x37, 0xEB, 0xBA, 0xCB, -0x5E, 0x3C, 0x30, 0x44, 0xC9, 0xBB, 0xB8, 0xCF, 0x3D, 0x34, 0x3B, 0x5F, 0xC1, 0xBE, 0xCE, 0xD6, -0xCE, 0xB8, 0xAB, 0xAA, 0xA4, 0xA8, 0x42, 0x1C, 0x18, 0x31, 0xA4, 0x9F, 0xAF, 0x48, 0x29, 0x28, -0x2C, 0x37, 0xCC, 0xBA, 0xC7, 0x57, 0x30, 0x31, 0x5A, 0xC6, 0xB6, 0xB7, 0x5F, 0x38, 0x34, 0x3D, -0xE2, 0xBD, 0xBD, 0xC7, 0xD2, 0xCA, 0xB2, 0xAB, 0xA7, 0xA2, 0xB3, 0x29, 0x18, 0x1C, 0xD2, 0x9F, -0xA5, 0xBC, 0x3A, 0x2A, 0x29, 0x2A, 0x3E, 0xC3, 0xBB, 0xC1, 0x43, 0x2D, 0x3A, 0xF5, 0xC1, 0xB5, -0xBE, 0x4F, 0x36, 0x32, 0x3F, 0xD2, 0xBB, 0xBA, 0xBE, 0xC5, 0xBF, 0xB1, 0xAB, 0xA4, 0xA7, 0x75, -0x1F, 0x18, 0x27, 0xAE, 0xA2, 0xAD, 0xD6, 0x36, 0x2B, 0x28, 0x2C, 0x4E, 0xC2, 0xB8, 0xC9, 0x35, -0x2F, 0x42, 0x71, 0xBA, 0xB4, 0xD2, 0x44, 0x34, 0x34, 0x4C, 0xCD, 0xBE, 0xBB, 0xB9, 0xBC, 0xB3, -0xAE, 0xAB, 0xA3, 0xB0, 0x2C, 0x1A, 0x1C, 0x5F, 0xA4, 0xA9, 0xBA, 0x6F, 0x34, 0x28, 0x26, 0x32, -0x77, 0xB9, 0xB3, 0x5E, 0x32, 0x38, 0x40, 0xD8, 0xB6, 0xBE, 0xF4, 0x40, 0x34, 0x3A, 0x5B, 0xC7, -0xB7, 0xB4, 0xB7, 0xB4, 0xB2, 0xAE, 0xA5, 0xAB, 0x3B, 0x1D, 0x1B, 0x34, 0xAE, 0xAA, 0xB4, 0xC7, -0x42, 0x2C, 0x25, 0x2B, 0x43, 0xCF, 0xB5, 0xBE, 0x3F, 0x38, 0x3D, 0x4D, 0xC4, 0xBD, 0xCF, 0x5D, -0x3E, 0x38, 0x43, 0xE4, 0xBF, 0xB4, 0xAF, 0xB0, 0xAF, 0xAE, 0xA8, 0xA7, 0xF6, 0x21, 0x1A, 0x27, -0xBA, 0xAC, 0xB5, 0xB9, 0xE2, 0x36, 0x26, 0x25, 0x33, 0x4E, 0xBA, 0xB2, 0x64, 0x41, 0x3F, 0x3D, -0xE6, 0xC6, 0xCD, 0xD4, 0x50, 0x3D, 0x3C, 0x48, 0xD4, 0xB9, 0xAF, 0xAD, 0xAE, 0xAE, 0xAA, 0xA7, -0xC0, 0x2A, 0x1B, 0x1F, 0x65, 0xAF, 0xB5, 0xB5, 0xBF, 0x4C, 0x2C, 0x23, 0x2A, 0x37, 0xE6, 0xAF, -0xBC, 0x5B, 0x4B, 0x3B, 0x49, 0xCF, 0xCE, 0xD0, 0xDE, 0x4F, 0x40, 0x3F, 0x57, 0xC7, 0xB3, 0xAA, -0xA9, 0xAC, 0xAE, 0xA9, 0xAE, 0x3B, 0x1E, 0x1E, 0x37, 0xBA, 0xB7, 0xB7, 0xB5, 0xC9, 0x3A, 0x26, -0x27, 0x2E, 0x37, 0xC1, 0xB1, 0xCA, 0xE8, 0x49, 0x3E, 0x62, 0x78, 0xEF, 0xD7, 0x69, 0x4F, 0x44, -0x48, 0xFB, 0xC5, 0xAF, 0xA9, 0xA8, 0xAA, 0xAB, 0xAA, 0xCF, 0x26, 0x1C, 0x22, 0x4A, 0xBD, 0xBB, -0xAF, 0xB1, 0xD7, 0x31, 0x25, 0x27, 0x28, 0x38, 0xB9, 0xB6, 0xC3, 0xCB, 0x4B, 0x45, 0x4E, 0x47, -0x62, 0xE0, 0xF9, 0x5C, 0x4C, 0x5C, 0xE4, 0xBF, 0xAD, 0xA8, 0xA5, 0xA7, 0xA9, 0xB2, 0x36, 0x20, -0x1E, 0x29, 0x56, 0xCC, 0xB8, 0xAC, 0xB5, 0xFA, 0x2F, 0x28, 0x25, 0x25, 0x45, 0xBE, 0xBF, 0xB8, -0xC5, 0x5F, 0x54, 0x41, 0x43, 0x4F, 0x56, 0x75, 0x70, 0xFE, 0xE2, 0xD3, 0xB9, 0xAD, 0xA8, 0xA6, -0xA6, 0xA8, 0xCA, 0x2D, 0x22, 0x21, 0x2E, 0x47, 0x77, 0xB4, 0xAD, 0xB7, 0xDC, 0x39, 0x2D, 0x24, -0x28, 0x40, 0x5A, 0xC7, 0xB5, 0xBD, 0xC0, 0xDB, 0x4E, 0x4C, 0x40, 0x44, 0x4E, 0x56, 0xDA, 0xCC, -0xC0, 0xB1, 0xAC, 0xA7, 0xA5, 0xA6, 0xAD, 0x4F, 0x2A, 0x23, 0x25, 0x2F, 0x39, 0x6C, 0xB6, 0xB1, -0xB7, 0xD6, 0x43, 0x2F, 0x26, 0x2C, 0x35, 0x3A, 0xDF, 0xC7, 0xBE, 0xBA, 0xCB, 0xD4, 0x6E, 0x48, -0x44, 0x3E, 0x4A, 0x6C, 0xD6, 0xB9, 0xB0, 0xA8, 0xA4, 0xA5, 0xA4, 0xB5, 0x42, 0x2C, 0x23, 0x27, -0x2B, 0x2E, 0x55, 0xC2, 0xB9, 0xB6, 0xC5, 0xF4, 0x3C, 0x32, 0x34, 0x2F, 0x37, 0x4A, 0x5B, 0xCF, -0xC9, 0xC6, 0xC0, 0xCA, 0xCF, 0xF4, 0x52, 0x51, 0x4E, 0xF8, 0xC4, 0xB7, 0xAD, 0xA9, 0xA6, 0xA7, -0xB8, 0x5D, 0x38, 0x2F, 0x2E, 0x2B, 0x2C, 0x35, 0x42, 0x5D, 0x7D, 0xE3, 0xDF, 0x6F, 0x73, 0x5A, -0x4D, 0x55, 0x4F, 0x4F, 0x58, 0x5C, 0x6E, 0xFA, 0xE2, 0xD4, 0xD4, 0xD6, 0xD9, 0xD6, 0xCC, 0xC6, -0xBF, 0xBB, 0xB8, 0xB6, 0xBC, 0xC9, 0xDC, 0x60, 0x59, 0x53, 0x4A, 0x49, 0x46, 0x45, 0x46, 0x43, -0x45, 0x45, 0x49, 0x56, 0x5A, 0x5D, 0x6E, 0x72, 0x7C, 0x74, 0x6D, 0x7A, 0x7A, 0xFC, 0xED, 0xE8, -0xEB, 0xFF, 0xFD, 0xEC, 0xDE, 0xD2, 0xCC, 0xC7, 0xC5, 0xCA, 0xD2, 0xD9, 0xDB, 0xD4, 0xCF, 0xD1, -0xD9, 0xE7, 0xFC, 0x6E, 0x60, 0x57, 0x50, 0x4C, 0x49, 0x47, 0x46, 0x45, 0x47, 0x4A, 0x4D, 0x4F, -0x4F, 0x53, 0x5A, 0x5F, 0x62, 0x60, 0x62, 0x6B, 0x77, 0xEC, 0xD8, 0xCC, 0xC7, 0xC7, 0xCB, 0xCF, -0xD3, 0xD3, 0xCE, 0xCB, 0xCA, 0xCC, 0xCF, 0xD4, 0xD9, 0xDF, 0xEB, 0xFE, 0x6A, 0x58, 0x4D, 0x46, -0x43, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x52, 0x54, 0x55, 0x54, 0x57, 0x5C, 0x61, 0x72, 0xE5, -0xD4, 0xCC, 0xCB, 0xCD, 0xD0, 0xD4, 0xD3, 0xD1, 0xD0, 0xCF, 0xD1, 0xD2, 0xD4, 0xD6, 0xD9, 0xDB, -0xDB, 0xDD, 0xEC, 0x6B, 0x59, 0x53, 0x54, 0x57, 0x59, 0x58, 0x57, 0x5A, 0x5C, 0x5A, 0x55, 0x52, -0x52, 0x51, 0x51, 0x57, 0x61, 0xFC, 0xE3, 0xDF, 0xE0, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDD, 0xDE, -0xDD, 0xDF, 0xE0, 0xDF, 0xDC, 0xD9, 0xDC, 0xE7, 0x7E, 0x6B, 0x6D, 0x7C, 0xEE, 0xE6, 0xE7, 0xEA, -0xEC, 0xF5, 0x7A, 0x6A, 0x61, 0x5A, 0x51, 0x4F, 0x50, 0x55, 0x5D, 0x62, 0x63, 0x60, 0x5F, 0x61, -0x65, 0x68, 0x6D, 0x75, 0xFA, 0xF1, 0xF1, 0xEE, 0xE6, 0xDD, 0xDB, 0xDE, 0xEB, 0x79, 0x6B, 0x6F, -0xF7, 0xE2, 0xDC, 0xDB, 0xDA, 0xDA, 0xDC, 0xDD, 0xDE, 0xE0, 0xF1, 0x6B, 0x5F, 0x5F, 0x66, 0x6B, -0x6A, 0x65, 0x5E, 0x5B, 0x5A, 0x59, 0x5A, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x68, 0xFC, 0xE8, 0xE5, -0xEB, 0xFB, 0x71, 0x6D, 0x78, 0xEE, 0xE2, 0xDE, 0xDD, 0xDC, 0xDE, 0xDF, 0xDC, 0xD9, 0xD9, 0xE0, -0xED, 0xF0, 0xEC, 0xE4, 0xE2, 0xE6, 0xEE, 0x7C, 0x6D, 0x65, 0x5E, 0x5E, 0x62, 0x64, 0x61, 0x5C, -0x5B, 0x5F, 0x70, 0xF7, 0xF8, 0x78, 0x6B, 0x65, 0x61, 0x69, 0xFA, 0xE9, 0xE5, 0xE2, 0xE5, 0xEA, -0xED, 0xEB, 0xE5, 0xE5, 0xED, 0xF9, 0xFC, 0xEF, 0xE3, 0xDE, 0xDE, 0xE1, 0xE9, 0xF4, 0x74, 0x6A, -0x6B, 0x6F, 0x6F, 0x67, 0x5E, 0x5C, 0x5F, 0x6A, 0x6F, 0x6C, 0x66, 0x5F, 0x5D, 0x5E, 0x64, 0x6F, -0xFE, 0xEF, 0xEC, 0xF2, 0xFD, 0x7E, 0xFB, 0xF6, 0xFF, 0x6F, 0x6A, 0x6A, 0x74, 0xF4, 0xE9, 0xE4, -0xE7, 0xEE, 0x7D, 0x6A, 0x69, 0x6F, 0xFE, 0xF7, 0x7B, 0x6B, 0x68, 0x6E, 0x79, 0x78, 0x6F, 0x69, -0x62, 0x5F, 0x60, 0x66, 0x72, 0xF6, 0xEB, 0xEC, 0xF3, 0xFC, 0xFA, 0xF2, 0xF2, 0xFE, 0x70, 0x69, -0x69, 0x71, 0xF7, 0xE8, 0xE3, 0xE4, 0xED, 0x76, 0x69, 0x6A, 0x6F, 0x7E, 0xFB, 0x7D, 0x75, 0x73, -0x7C, 0xFB, 0xFC, 0x7D, 0x73, 0x6D, 0x6A, 0x69, 0x6F, 0xFD, 0xEC, 0xE8, 0xED, 0xF6, 0xF7, 0xF1, -0xED, 0xEF, 0xF6, 0x7E, 0x76, 0x78, 0xFB, 0xEC, 0xE2, 0xDE, 0xE0, 0xEB, 0xFE, 0x73, 0x73, 0x7E, -0xFA, 0xFC, 0xFF, 0x7B, 0x7D, 0xFC, 0xFE, 0x7B, 0x74, 0x6F, 0x6D, 0x6C, 0x6E, 0x77, 0xFA, 0xEE, -0xED, 0xF6, 0x7A, 0x73, 0x77, 0x7B, 0x7C, 0x78, 0x6E, 0x6B, 0x6F, 0x7C, 0xEF, 0xE7, 0xE2, 0xE6, -0xF2, 0x7A, 0x71, 0x75, 0x7D, 0xFE, 0xFD, 0xFD, 0xFB, 0xF5, 0xF7, 0xFE, 0x77, 0x6E, 0x6A, 0x67, -0x67, 0x6C, 0x76, 0xF7, 0xEE, 0xEF, 0xFA, 0x7B, 0x78, 0x7B, 0xFF, 0x7F, 0x78, 0x6F, 0x6C, 0x6C, -0x72, 0xFE, 0xEF, 0xEC, 0xEF, 0xFD, 0x76, 0x70, 0x71, 0x75, 0x7A, 0x7E, 0x7E, 0xFF, 0xFC, 0xFD, -0x7C, 0x73, 0x6D, 0x69, 0x65, 0x63, 0x65, 0x6B, 0x79, 0xFB, 0xFD, 0x78, 0x70, 0x70, 0x74, 0x79, -0x7C, 0x7B, 0x79, 0x77, 0x78, 0x7F, 0xF4, 0xED, 0xED, 0xF2, 0xFB, 0x7A, 0x74, 0x74, 0x76, 0x7A, -0x7F, 0xFB, 0xF5, 0xF4, 0xF6, 0xFA, 0x7D, 0x75, 0x6E, 0x6B, 0x6B, 0x6F, 0x7D, 0xF3, 0xEF, 0xF4, -0x7E, 0x78, 0x7A, 0xFF, 0xFA, 0xF7, 0xF5, 0xF4, 0xF4, 0xF1, 0xED, 0xE9, 0xE6, 0xE8, 0xEE, 0xF8, -0x7F, 0x7C, 0x7A, 0x7A, 0x7B, 0x7D, 0xFD, 0xF8, 0xF8, 0xF9, 0xFC, 0x7D, 0x74, 0x6C, 0x69, 0x69, -0x6C, 0x76, 0xFA, 0xF6, 0xFD, 0x78, 0x71, 0x6F, 0x6F, 0x6F, 0x71, 0x74, 0x77, 0x7C, 0xFD, 0xF5, -0xEC, 0xE9, 0xEA, 0xEF, 0xFB, 0x7A, 0x74, 0x73, 0x73, 0x73, 0x73, 0x78, 0x7E, 0xFE, 0xFD, 0xFE, -0x7B, 0x74, 0x6D, 0x68, 0x66, 0x69, 0x6F, 0x7B, 0x7F, 0x7C, 0x77, 0x73, 0x72, 0x6F, 0x6D, 0x6D, -0x6D, 0x6D, 0x6E, 0x72, 0x7A, 0xFA, 0xF1, 0xEE, 0xEF, 0xF6, 0xFD, 0x7D, 0x7B, 0x7A, 0x78, 0x78, -0x79, 0x79, 0x7A, 0x7C, 0x7D, 0x7E, 0x7D, 0x77, 0x70, 0x6E, 0x71, 0x79, 0x7E, 0x7E, 0x7E, 0x7D, -0x7E, 0x7D, 0x7C, 0x7A, 0x78, 0x76, 0x74, 0x73, 0x75, 0x7A, 0xFC, 0xF6, 0xF4, 0xF4, 0xF6, 0xF6, -0xF6, 0xF9, 0xF9, 0xF7, 0xF5, 0xF3, 0xF1, 0xF1, 0xF3, 0xF5, 0xF7, 0xFA, 0x7B, 0x6F, 0x6D, 0x6D, -0x6F, 0x6F, 0x6E, 0x6E, 0x70, 0x70, 0x71, 0x74, 0x78, 0x7C, 0x7D, 0x7E, 0x7D, 0xFF, 0xFB, 0xF7, -0xF4, 0xF4, 0xF6, 0xF8, 0xFB, 0xFD, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x7F, 0xFF, 0xFC, 0xF8, -0xF9, 0xFD, 0x7D, 0x7C, 0x7F, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x79, 0x76, -0x71, 0x6F, 0x6F, 0x71, 0x76, 0x78, 0x78, 0x78, 0x7B, 0x7D, 0x7A, 0x77, 0x76, 0x76, 0x78, 0x79, -0x78, 0x79, 0x7C, 0xFD, 0xF4, 0xF1, 0xF2, 0xF5, 0xF9, 0xFB, 0x7F, 0x79, 0x76, 0x76, 0x78, 0x77, -0x77, 0x7B, 0xFF, 0xFA, 0xF6, 0xF6, 0xF7, 0xF6, 0xF6, 0xF7, 0xF9, 0xFA, 0xF9, 0xF6, 0xF6, 0xF9, -0xFB, 0xFE, 0x7F, 0x7E, 0x7C, 0x79, 0x7A, 0xFE, 0xF5, 0xEF, 0xEE, 0xEF, 0xF1, 0xF3, 0xF4, 0xFB, -0x79, 0x73, 0x72, 0x6E, 0x6B, 0x68, 0x68, 0x6C, 0x73, 0x7A, 0x7C, 0x7B, 0x7B, 0x7D, 0x7D, 0xFD, -0xF6, 0xF0, 0xEE, 0xEF, 0xF6, 0xFB, 0xFF, 0x7D, 0x7F, 0x7D, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, 0x7B, -0x7A, 0xFF, 0xFD, 0xFF, 0x7E, 0x7A, 0x75, 0x74, 0x71, 0x6F, 0x6F, 0x70, 0x77, 0x7A, 0x78, 0x75, -0x72, 0x75, 0x73, 0x6F, 0x6F, 0x70, 0x75, 0x77, 0x76, 0x78, 0x75, 0x78, 0x7B, 0x7B, 0x7F, 0x7B, -0x7E, 0x7F, 0x7E, 0x7E, 0x77, 0x79, 0x73, 0x71, 0x71, 0x6B, 0x6F, 0x60, 0x5B, 0x6F, 0x72, 0x69, -0x71, 0x72, 0x7E, 0xFC, 0xF7, 0xEE, 0xF4, 0xFB, 0x7E, 0x7E, 0xFC, 0xF9, 0xFD, 0x7F, 0xFC, 0x72, -0x78, 0x64, 0x53, 0x71, 0xDF, 0xF0, 0xEB, 0xE9, 0xF0, 0x7C, 0x7B, 0xEA, 0xF6, 0x7E, 0x79, 0x6C, -0x79, 0x5F, 0x5B, 0xEC, 0xE2, 0xEF, 0xED, 0xF1, 0xF7, 0xFE, 0x7C, 0xFE, 0x75, 0x6E, 0x75, 0x79, -0x7A, 0x72, 0x6E, 0x75, 0x7A, 0x7B, 0x77, 0x77, 0xFE, 0xF8, 0xF6, 0xF5, 0xEB, 0xE9, 0xEC, 0xE8, -0xEE, 0xEC, 0xED, 0x77, 0xFD, 0x61, 0x51, 0x66, 0xE7, 0xDC, 0xD8, 0xD3, 0xD3, 0x6C, 0x52, 0x63, -0x6F, 0x73, 0x7F, 0xFB, 0xF4, 0x79, 0x7B, 0xF1, 0xED, 0xEC, 0xFA, 0x76, 0x7A, 0x74, 0x6B, 0x6B, -0x75, 0x7C, 0x7C, 0x79, 0xFE, 0xF6, 0xFE, 0x7A, 0x71, 0x75, 0xFF, 0x70, 0x6D, 0x6E, 0x69, 0x66, -0x5E, 0x62, 0xFA, 0xEA, 0xE5, 0xE0, 0xE1, 0xE5, 0xEE, 0xF1, 0xE5, 0xE4, 0xEA, 0xE8, 0xE7, 0xE7, -0xE3, 0xE7, 0xE8, 0xE8, 0xEF, 0xF7, 0x78, 0x6E, 0x6D, 0x60, 0x5A, 0x57, 0x54, 0x53, 0x51, 0x50, -0x52, 0x54, 0x57, 0x59, 0x5D, 0x67, 0x70, 0x7B, 0xF5, 0xE5, 0xDA, 0xD5, 0xD2, 0xCD, 0xC4, 0xBE, -0xBB, 0xB7, 0xB5, 0xBB, 0xCB, 0xDE, 0xE9, 0x56, 0x3F, 0x3A, 0x39, 0x3B, 0x3B, 0x3A, 0x3F, 0x4E, -0x5D, 0x69, 0xF2, 0xDD, 0xD9, 0xE2, 0xF3, 0xF4, 0x72, 0x5C, 0x53, 0x4E, 0x4D, 0x4E, 0x4E, 0x4F, -0x58, 0x7E, 0xDA, 0xCB, 0xBF, 0xBA, 0xB7, 0xB4, 0xB0, 0xAE, 0xB2, 0xBE, 0xD7, 0x70, 0x4E, 0x3B, -0x32, 0x30, 0x33, 0x35, 0x35, 0x3A, 0x49, 0x5F, 0x7E, 0xEF, 0xE1, 0xD2, 0xD1, 0xE6, 0xEF, 0xF7, -0x5F, 0x4F, 0x48, 0x48, 0x4B, 0x48, 0x4B, 0x55, 0x72, 0xE1, 0xD2, 0xC2, 0xBA, 0xB6, 0xB3, 0xB0, -0xAD, 0xAE, 0xBA, 0xD0, 0x64, 0x4C, 0x3C, 0x30, 0x2E, 0x2F, 0x33, 0x35, 0x3A, 0x47, 0x6C, 0xE6, -0xEB, 0xD0, 0xC6, 0xCC, 0xD6, 0xE3, 0xEF, 0x69, 0x4E, 0x4B, 0x4B, 0x47, 0x46, 0x48, 0x4F, 0x61, -0xFE, 0xD1, 0xBE, 0xB8, 0xB5, 0xB2, 0xAF, 0xAD, 0xAE, 0xBA, 0xCD, 0x5F, 0x47, 0x3B, 0x2F, 0x2D, -0x2E, 0x30, 0x35, 0x3B, 0x47, 0x6C, 0xF4, 0xE2, 0xCB, 0xC7, 0xCD, 0xD7, 0xDD, 0xE3, 0x6E, 0x4E, -0x4A, 0x4B, 0x48, 0x47, 0x4A, 0x5B, 0xE4, 0xD3, 0xC0, 0xB7, 0xB3, 0xB0, 0xAF, 0xAC, 0xAC, 0xB3, -0xC4, 0x7D, 0x4C, 0x3E, 0x30, 0x2C, 0x2E, 0x31, 0x35, 0x3A, 0x45, 0x62, 0xFA, 0xEB, 0xCE, 0xCA, -0xD2, 0xDA, 0xE7, 0xE9, 0x6D, 0x4C, 0x49, 0x49, 0x47, 0x48, 0x4C, 0x68, 0xD7, 0xCA, 0xBC, 0xB5, -0xB2, 0xB0, 0xAE, 0xAC, 0xAE, 0xB9, 0xCE, 0x5D, 0x45, 0x39, 0x2F, 0x2D, 0x2E, 0x31, 0x36, 0x3B, -0x47, 0x5C, 0x6E, 0xE4, 0xD3, 0xD3, 0xD4, 0xDA, 0xDE, 0xEB, 0x5B, 0x4D, 0x4A, 0x47, 0x48, 0x49, -0x54, 0xEB, 0xCE, 0xBE, 0xB8, 0xB7, 0xB3, 0xB3, 0xB5, 0xB3, 0xBB, 0xC9, 0xC8, 0xED, 0x47, 0x42, -0x3A, 0x36, 0x37, 0x34, 0x39, 0x3E, 0x3F, 0x47, 0x4E, 0x65, 0xDE, 0xEC, 0xDC, 0xCE, 0xD9, 0xEB, -0x5F, 0x54, 0x51, 0x47, 0x46, 0x4C, 0x58, 0xFC, 0xD8, 0xC4, 0xBB, 0xBA, 0xB8, 0xB5, 0xB2, 0xAF, -0xB0, 0xB6, 0xBD, 0xCC, 0x66, 0x47, 0x3B, 0x34, 0x32, 0x32, 0x34, 0x38, 0x3B, 0x3F, 0x4B, 0x58, -0x69, 0xE9, 0xD9, 0xD4, 0xDB, 0x77, 0x5C, 0x59, 0x4F, 0x4A, 0x4B, 0x51, 0x69, 0xE0, 0xCE, 0xC2, -0xBD, 0xBC, 0xBA, 0xB8, 0xB7, 0xB4, 0xB2, 0xB7, 0xC3, 0xCE, 0xD4, 0x67, 0x44, 0x3D, 0x3C, 0x3B, -0x38, 0x38, 0x3B, 0x3F, 0x42, 0x46, 0x4E, 0x5F, 0x6A, 0x6B, 0xFD, 0xF7, 0x70, 0x5C, 0x54, 0x58, -0x58, 0x53, 0x5B, 0x73, 0xE5, 0xD2, 0xCA, 0xC6, 0xC2, 0xBF, 0xBE, 0xBE, 0xBD, 0xBB, 0xBC, 0xC3, -0xCA, 0xD0, 0xE2, 0x5F, 0x4E, 0x4A, 0x44, 0x3E, 0x3D, 0x3D, 0x3F, 0x42, 0x44, 0x4B, 0x55, 0x57, -0x5F, 0x69, 0x68, 0x63, 0x58, 0x56, 0x5B, 0x56, 0x57, 0x66, 0x79, 0xE8, 0xD9, 0xCF, 0xCB, 0xCB, -0xC8, 0xC4, 0xC5, 0xC6, 0xC9, 0xC9, 0xC6, 0xCD, 0xD4, 0xD8, 0xE2, 0xF1, 0x66, 0x5C, 0x57, 0x4C, -0x49, 0x49, 0x48, 0x49, 0x49, 0x4B, 0x51, 0x51, 0x4F, 0x53, 0x56, 0x58, 0x58, 0x54, 0x58, 0x5F, -0x5E, 0x5B, 0x63, 0xF2, 0xE5, 0xE5, 0xD7, 0xCF, 0xD2, 0xD6, 0xD1, 0xCF, 0xD6, 0xD6, 0xD2, 0xCF, -0xCE, 0xD0, 0xD8, 0xDB, 0xDB, 0xE5, 0x6D, 0x67, 0x65, 0x5C, 0x58, 0x54, 0x59, 0x5D, 0x57, 0x57, -0x5B, 0x5B, 0x59, 0x56, 0x57, 0x5A, 0x56, 0x52, 0x5A, 0x5C, 0x5D, 0x7D, 0xF1, 0xF3, 0xE7, 0xE3, -0xDF, 0xDB, 0xDA, 0xE7, 0xEC, 0xDE, 0xE5, 0xE9, 0xE6, 0xE4, 0xD6, 0xDF, 0xF8, 0xDE, 0xE9, 0x7C, -0xEE, 0xFB, 0x7A, 0x6B, 0x65, 0xFF, 0x79, 0x69, 0x6B, 0x63, 0x65, 0x62, 0x56, 0x5A, 0x60, 0x55, -0x58, 0x62, 0x5E, 0x64, 0x79, 0x7C, 0x78, 0xED, 0xE1, 0xEC, 0xF0, 0xE4, 0xF0, 0x6E, 0x7C, 0xED, -0xDD, 0xDB, 0xFE, 0x73, 0xED, 0xF0, 0xFF, 0xF9, 0xDE, 0xDC, 0x76, 0x6E, 0xFB, 0x7B, 0xFB, 0x6F, -0x6F, 0xEF, 0x7B, 0x6E, 0xF8, 0xE9, 0x7E, 0x5B, 0x5F, 0xF3, 0xFD, 0x67, 0x74, 0xEA, 0xEF, 0x77, -0x6D, 0x7C, 0xE8, 0xE2, 0xEE, 0xFB, 0xE6, 0xED, 0x66, 0x6C, 0x7B, 0x7C, 0xF4, 0xEF, 0xE2, 0xE6, -0x72, 0x70, 0xF0, 0xEE, 0x6E, 0x6B, 0xFB, 0xF5, 0xF6, 0x71, 0x6A, 0x6C, 0x65, 0x67, 0x5F, 0x5D, -0x6B, 0x62, 0x65, 0xFD, 0xED, 0xE9, 0xF2, 0xED, 0xE3, 0xE7, 0xE4, 0xE8, 0xED, 0xEF, 0x66, 0x5E, -0x79, 0x7E, 0x78, 0xF5, 0xFA, 0x79, 0x7A, 0xF5, 0xE7, 0xE2, 0xE4, 0xF2, 0xFF, 0x73, 0x66, 0x6B, -0x70, 0xFD, 0xEF, 0x6F, 0x67, 0x5F, 0x5C, 0x6B, 0x6E, 0x78, 0x77, 0x6D, 0xF1, 0xF4, 0xF8, 0xE5, -0xE9, 0xEB, 0xEC, 0xEF, 0xEF, 0xF0, 0xE7, 0xED, 0x6B, 0x6F, 0xF0, 0xFF, 0x6A, 0x6F, 0x7E, 0x6F, -0x69, 0xED, 0xDF, 0xFF, 0x7C, 0xEB, 0xF3, 0xF8, 0x7E, 0x7A, 0xFB, 0x6E, 0x5E, 0x60, 0x70, 0x7A, -0xFC, 0xF4, 0xFF, 0xEF, 0xF5, 0x72, 0xF1, 0xEC, 0xEA, 0xE1, 0xE9, 0xED, 0xF2, 0xFC, 0xE7, 0xF0, -0x68, 0x76, 0xEF, 0xF4, 0xF9, 0x77, 0x79, 0xFB, 0xFC, 0xF6, 0xEE, 0xE9, 0xF2, 0x6D, 0x70, 0x6F, -0x6F, 0xFE, 0x6A, 0x69, 0x7F, 0x6F, 0x6F, 0x79, 0x78, 0x77, 0x6E, 0xFE, 0xEE, 0xF0, 0xEF, 0x7E, -0xF4, 0xE9, 0xF8, 0xFD, 0x7C, 0x77, 0x7D, 0x78, 0x7D, 0xFE, 0x79, 0x72, 0x6E, 0x72, 0x7B, 0x73, -0x6B, 0x74, 0x76, 0x6C, 0x72, 0x70, 0x75, 0x6D, 0x5A, 0x5C, 0x6A, 0x77, 0xFE, 0x71, 0x7A, 0xF2, -0xE9, 0xE7, 0xEA, 0xDE, 0xE6, 0xF5, 0xEB, 0xF5, 0xEE, 0xEA, 0xF3, 0xEE, 0xF4, 0xEE, 0xF5, 0x73, -0xF4, 0xF6, 0x73, 0x7C, 0xEC, 0xE9, 0x72, 0x67, 0x6C, 0x70, 0x6E, 0x69, 0x6F, 0x68, 0x5D, 0x64, -0x71, 0x75, 0x6B, 0x6D, 0xF9, 0x79, 0x6F, 0xF4, 0xEA, 0xF5, 0x79, 0x7B, 0x7D, 0xFA, 0xF3, 0xF7, -0xF4, 0xF4, 0xF9, 0x7F, 0x77, 0x7F, 0xF5, 0xFD, 0x71, 0x71, 0x7B, 0x78, 0x7A, 0x73, 0x68, 0x71, -0x7A, 0x6B, 0x6C, 0x6E, 0x69, 0x6E, 0x71, 0x6C, 0x69, 0x6C, 0x7A, 0x7D, 0xF6, 0xEB, 0xF4, 0xF2, -0xF4, 0x78, 0xF8, 0xF1, 0xF6, 0xFE, 0x71, 0x75, 0x7C, 0x7B, 0x7D, 0x7E, 0xFB, 0x7E, 0x77, 0x76, -0xFF, 0xF7, 0x79, 0x70, 0x6E, 0x6C, 0x71, 0x6F, 0x6C, 0x6A, 0x70, 0x6E, 0x5F, 0x65, 0x6C, 0x66, -0x6D, 0x7A, 0xF1, 0x78, 0x6B, 0xED, 0xFB, 0x6C, 0x7C, 0x74, 0xF1, 0xEC, 0x76, 0xF9, 0xF8, 0x75, -0x71, 0x7A, 0xEC, 0xFA, 0x6C, 0x76, 0x7C, 0x7F, 0x6E, 0x6A, 0x76, 0x6C, 0x76, 0xF2, 0x7C, 0x76, -0x66, 0x62, 0x7D, 0xF9, 0x78, 0x69, 0x6A, 0xF8, 0x78, 0x6D, 0xFC, 0xF8, 0xF3, 0xF7, 0x7D, 0xEF, -0xF1, 0x7C, 0xF1, 0xE9, 0xEB, 0xEE, 0xF3, 0xFD, 0x73, 0x7D, 0xFA, 0x74, 0x78, 0x7A, 0x6E, 0x70, -0x76, 0x73, 0x6F, 0x6D, 0x6C, 0x68, 0x6D, 0x7D, 0x6E, 0x64, 0x6D, 0xFC, 0xFA, 0x71, 0x6F, 0xFF, -0x70, 0x70, 0xF0, 0xEE, 0xEF, 0xEB, 0xEC, 0xEC, 0xED, 0xF0, 0xEE, 0xE9, 0xEB, 0xF8, 0xFB, 0xED, -0xE9, 0xF7, 0xFF, 0xED, 0xEE, 0xEF, 0xF3, 0x6E, 0x70, 0xF3, 0xFF, 0x6F, 0x6F, 0x6F, 0x79, 0x7C, -0x79, 0x7E, 0x77, 0x6E, 0x6E, 0x7B, 0x7C, 0x6B, 0x72, 0xF6, 0xFF, 0x7D, 0x7D, 0x72, 0x78, 0xFB, -0xFD, 0xFB, 0xFA, 0x7D, 0x7A, 0x6D, 0x68, 0x74, 0x75, 0xF1, 0xE7, 0x7B, 0x76, 0x6B, 0x66, 0xFD, -0x73, 0x68, 0x6B, 0x73, 0x7C, 0x62, 0x64, 0x70, 0x64, 0x6D, 0x79, 0x70, 0x70, 0x74, 0xF8, 0x7C, -0x7C, 0xF8, 0x6B, 0x70, 0xF9, 0x7D, 0xF1, 0xF0, 0xFF, 0x7F, 0xF8, 0xED, 0xF2, 0xFC, 0xFF, 0x76, -0x7B, 0x7C, 0xFE, 0xFE, 0x6C, 0x7C, 0xED, 0x79, 0x77, 0x71, 0x69, 0x76, 0x7A, 0x76, 0x7A, 0x6F, -0x6E, 0x6E, 0x73, 0xFF, 0x78, 0x76, 0x7F, 0x7A, 0x6F, 0x78, 0xFE, 0x77, 0xFB, 0xEE, 0xEE, 0xF1, -0x7A, 0xFB, 0xEE, 0x75, 0x70, 0xFE, 0x7D, 0x72, 0x6D, 0x6F, 0x7B, 0xFB, 0xF9, 0x7C, 0x7E, 0x7A, -0x70, 0x76, 0x7B, 0xF7, 0xF5, 0x70, 0x74, 0xFF, 0x78, 0xFA, 0xFC, 0x79, 0x78, 0x6D, 0x7A, 0xFA, -0x77, 0xFC, 0xF4, 0xF1, 0xF1, 0xF7, 0xEB, 0xED, 0xFB, 0xF7, 0xEF, 0xF2, 0x78, 0x79, 0xF0, 0xF3, -0xFC, 0xFC, 0x7E, 0x77, 0xFF, 0xFC, 0x78, 0xF6, 0xF9, 0x6F, 0x7A, 0x78, 0x6F, 0xFF, 0xF9, 0x7E, -0x76, 0x72, 0x76, 0x78, 0x79, 0xFD, 0xFA, 0x7A, 0x7E, 0xF1, 0xFB, 0x7A, 0xF2, 0xEF, 0xFF, 0x74, -0x75, 0x7E, 0xFF, 0xF6, 0xE9, 0xF4, 0x71, 0x74, 0x74, 0x7C, 0xF8, 0x79, 0x75, 0x74, 0x73, 0xF9, -0xFE, 0xFF, 0xFA, 0x6A, 0x6C, 0xFE, 0x70, 0x72, 0x7C, 0x7D, 0x70, 0x67, 0x6F, 0x76, 0x7B, 0xF0, -0x7E, 0x6E, 0x6E, 0x76, 0xF1, 0xF2, 0x7A, 0x72, 0x7B, 0xFD, 0x79, 0x77, 0x6E, 0x6A, 0x6D, 0x6E, -0x74, 0x72, 0x77, 0xF5, 0x7C, 0x6D, 0x6C, 0x6D, 0x70, 0x76, 0xFD, 0xFC, 0xFF, 0xFE, 0xFE, 0xFA, -0x7D, 0x77, 0x74, 0x6F, 0xFB, 0xFA, 0x71, 0xFC, 0xF8, 0xFE, 0xEB, 0xE5, 0xEE, 0x7F, 0xF6, 0xED, -0xFA, 0x78, 0xF6, 0xF1, 0xF8, 0xF6, 0x79, 0x70, 0x7C, 0x75, 0x78, 0xF6, 0xFA, 0xFC, 0xFB, 0x7B, -0x7D, 0xF9, 0xF7, 0xF7, 0x7E, 0x6B, 0x68, 0xFA, 0xE6, 0xEE, 0x7B, 0x7B, 0x79, 0x7E, 0xFB, 0xF2, -0xEA, 0xEE, 0xF1, 0xF6, 0x79, 0xFB, 0xF0, 0xFB, 0xFF, 0xF0, 0xEE, 0xF4, 0xEF, 0xFB, 0x6F, 0x6C, -0x72, 0xFF, 0x71, 0x6C, 0x6A, 0x6D, 0xF4, 0xFB, 0x7C, 0xF3, 0xFA, 0xFC, 0x6F, 0x73, 0xFB, 0x72, -0x7D, 0x78, 0x76, 0xEF, 0xF3, 0x7C, 0x71, 0xFA, 0xF2, 0xFB, 0xEF, 0xF0, 0xEA, 0xFD, 0x6B, 0xED, -0xF2, 0x77, 0x6E, 0x6D, 0xFD, 0x64, 0xF3, 0xDF, 0x5C, 0x61, 0xED, 0xF2, 0x7E, 0x66, 0x73, 0x6E, -0x66, 0xFF, 0x6F, 0x72, 0x70, 0x66, 0xF3, 0xF7, 0x6F, 0x72, 0x75, 0xED, 0xEF, 0xF4, 0xED, 0xEF, -0xEF, 0x6E, 0x6F, 0xF7, 0x72, 0x7E, 0x78, 0x6F, 0xF9, 0x77, 0xFC, 0xF4, 0x6C, 0x66, 0x6A, 0x76, -0x65, 0x5C, 0x6D, 0xFF, 0xF8, 0xEA, 0xE2, 0xEF, 0x65, 0x70, 0xEB, 0xE8, 0xE2, 0xDF, 0xDA, 0xD9, -0xE3, 0xF0, 0xFA, 0xE6, 0xDD, 0xDF, 0xDF, 0xE0, 0xE4, 0xFC, 0x63, 0x60, 0x64, 0x63, 0x66, 0x78, -0x65, 0x57, 0x60, 0x67, 0x64, 0x67, 0x5F, 0x6E, 0xF3, 0x7F, 0x75, 0xFE, 0xEA, 0xF4, 0xF8, 0xE0, -0xE0, 0xE4, 0xE3, 0xE7, 0xEA, 0xFB, 0x6F, 0x6E, 0x75, 0x72, 0x68, 0x6E, 0x77, 0x74, 0x6D, 0x73, -0xF9, 0x74, 0xF2, 0xE2, 0xEF, 0xDE, 0xDD, 0x79, 0xFD, 0xF4, 0x6F, 0x6A, 0x6E, 0xFE, 0x7A, 0x68, -0x60, 0x63, 0x6B, 0x66, 0x67, 0x76, 0xFE, 0x78, 0x65, 0x63, 0x7A, 0xFF, 0x72, 0x72, 0x74, 0x7D, -0x7C, 0x6B, 0x72, 0xEF, 0xF6, 0x73, 0x74, 0x7C, 0x74, 0x68, 0x68, 0x73, 0xFA, 0xF6, 0x6F, 0x67, -0x6F, 0x6D, 0x6A, 0x69, 0x68, 0x74, 0x6D, 0x64, 0x6F, 0x75, 0x77, 0xFA, 0x7F, 0xF5, 0xEF, 0x78, -0x77, 0x7D, 0x7A, 0xFE, 0x77, 0x73, 0xF8, 0xF4, 0xFE, 0x6F, 0x71, 0xF7, 0x74, 0x79, 0xEF, 0x7B, -0xF9, 0xFA, 0x68, 0x71, 0x7F, 0x76, 0x73, 0x71, 0x7D, 0x7D, 0x65, 0x5D, 0x69, 0x6E, 0x5F, 0x67, -0x6F, 0x6D, 0xFF, 0x7F, 0x6E, 0x6F, 0x73, 0x77, 0xF2, 0xDE, 0xD4, 0xD0, 0xD0, 0xCF, 0xCE, 0xD0, -0xD2, 0xD6, 0xDA, 0xDB, 0xE7, 0x6D, 0x5B, 0x52, 0x4C, 0x47, 0x44, 0x43, 0x44, 0x47, 0x49, 0x4B, -0x4E, 0x52, 0x56, 0x5A, 0x5D, 0x64, 0x75, 0xE6, 0xCF, 0xC5, 0xBF, 0xBD, 0xBB, 0xB7, 0xB5, 0xB1, -0xAF, 0xB5, 0xC1, 0xDF, 0x51, 0x44, 0x3A, 0x33, 0x33, 0x37, 0x3D, 0x44, 0x48, 0x4D, 0x51, 0x54, -0x53, 0x4D, 0x49, 0x44, 0x43, 0x45, 0x46, 0x4C, 0x54, 0x65, 0xE4, 0xCF, 0xC4, 0xBB, 0xB4, 0xAF, -0xAD, 0xAC, 0xAA, 0xAB, 0xB5, 0xD1, 0x49, 0x3B, 0x35, 0x2F, 0x2D, 0x32, 0x3D, 0x4E, 0x57, 0x51, -0x4F, 0x50, 0x4C, 0x42, 0x3D, 0x3F, 0x46, 0x4A, 0x4F, 0x5E, 0xEC, 0xD9, 0xDA, 0xD2, 0xC8, 0xBE, -0xB7, 0xB0, 0xAD, 0xAB, 0xA9, 0xA8, 0xAD, 0xC4, 0x48, 0x36, 0x31, 0x2E, 0x2D, 0x30, 0x3E, 0x67, -0xE2, 0x63, 0x47, 0x43, 0x42, 0x39, 0x36, 0x3B, 0x46, 0x6B, 0xE1, 0xDB, 0xCC, 0xC8, 0xCC, 0xD7, -0xDD, 0xC6, 0xBA, 0xB2, 0xAC, 0xAA, 0xA7, 0xA7, 0xB0, 0x69, 0x32, 0x2D, 0x2D, 0x2C, 0x2D, 0x39, -0xF1, 0xC2, 0xCA, 0x5E, 0x3D, 0x38, 0x34, 0x2E, 0x2F, 0x3E, 0x69, 0xCC, 0xC3, 0xBD, 0xBD, 0xC2, -0xCD, 0xEC, 0xF4, 0xCD, 0xC0, 0xB7, 0xAC, 0xA7, 0xA4, 0xA4, 0xB7, 0x3A, 0x2A, 0x29, 0x2A, 0x2B, -0x30, 0x56, 0xBA, 0xB6, 0xCD, 0x4A, 0x33, 0x2C, 0x2C, 0x2B, 0x34, 0x65, 0xC3, 0xBB, 0xBB, 0xBC, -0xC1, 0xDA, 0x7F, 0x6A, 0x75, 0xD1, 0xC2, 0xB8, 0xAC, 0xA6, 0xA5, 0xA4, 0xB0, 0x35, 0x23, 0x25, -0x29, 0x2F, 0x38, 0x73, 0xB3, 0xAF, 0xC8, 0x3E, 0x2E, 0x29, 0x26, 0x2C, 0x3D, 0xDF, 0xB8, 0xB5, -0xBB, 0xC5, 0xE7, 0x5A, 0x53, 0x68, 0xD9, 0xC8, 0xBA, 0xB3, 0xAD, 0xA8, 0xA7, 0xA6, 0xAF, 0x34, -0x1F, 0x24, 0x2E, 0x3B, 0x48, 0xDA, 0xB3, 0xB0, 0xD6, 0x33, 0x29, 0x29, 0x29, 0x2F, 0x5B, 0xC3, -0xB9, 0xB8, 0xC1, 0xDB, 0x53, 0x46, 0x4E, 0xEE, 0xCB, 0xC5, 0xBF, 0xBA, 0xB6, 0xAE, 0xAA, 0xA8, -0xAA, 0xDB, 0x26, 0x20, 0x2B, 0x3E, 0x5E, 0xEE, 0xC1, 0xB6, 0xC1, 0x3F, 0x2A, 0x29, 0x2A, 0x2F, -0x4F, 0xCA, 0xC0, 0xBE, 0xC5, 0xDC, 0x51, 0x44, 0x4B, 0x7D, 0xCB, 0xC5, 0xC5, 0xC2, 0xBF, 0xBD, -0xB1, 0xA9, 0xA8, 0xAA, 0xCB, 0x28, 0x20, 0x2C, 0x44, 0x7E, 0xDE, 0xC8, 0xBB, 0xC6, 0x3F, 0x2B, -0x29, 0x2E, 0x35, 0x4C, 0xCB, 0xBF, 0xC3, 0xCA, 0xE6, 0x4E, 0x43, 0x44, 0x6A, 0xC8, 0xC3, 0xC3, -0xC8, 0xC8, 0xBE, 0xB5, 0xAB, 0xA7, 0xA8, 0xBC, 0x2D, 0x1F, 0x29, 0x42, 0xD7, 0xD0, 0xCD, 0xBF, -0xC5, 0x4C, 0x2E, 0x2B, 0x2F, 0x36, 0x4A, 0xD7, 0xBE, 0xBD, 0xD5, 0x74, 0x50, 0x42, 0x45, 0x53, -0xD1, 0xBE, 0xBE, 0xC5, 0xD2, 0xCD, 0xBC, 0xAE, 0xA7, 0xA7, 0xB5, 0x36, 0x21, 0x28, 0x41, 0xD1, -0xC9, 0xD4, 0xCB, 0xCB, 0x51, 0x31, 0x2B, 0x2F, 0x39, 0x47, 0xE9, 0xC5, 0xC0, 0xCD, 0xED, 0x50, -0x3F, 0x3F, 0x52, 0xCD, 0xBB, 0xBC, 0xC6, 0xDE, 0xE7, 0xCB, 0xB5, 0xA8, 0xA4, 0xA9, 0xCC, 0x28, -0x20, 0x2E, 0x6F, 0xC2, 0xCF, 0xF7, 0xDA, 0xEB, 0x3F, 0x2E, 0x2D, 0x34, 0x3E, 0x5D, 0xCD, 0xBF, -0xC7, 0x73, 0x53, 0x43, 0x3C, 0x49, 0xDD, 0xBC, 0xB7, 0xC2, 0xE4, 0x62, 0xEC, 0xBD, 0xAA, 0xA3, -0xA4, 0xB3, 0x32, 0x1F, 0x26, 0x42, 0xC3, 0xC0, 0xF2, 0x68, 0x73, 0x4D, 0x37, 0x2D, 0x2F, 0x39, -0x47, 0xDD, 0xC2, 0xBE, 0xD2, 0x4A, 0x3E, 0x3B, 0x42, 0xEB, 0xBE, 0xB5, 0xB9, 0xD5, 0x54, 0x54, -0xCB, 0xAD, 0xA3, 0xA2, 0xAC, 0x4D, 0x23, 0x21, 0x34, 0xCF, 0xBA, 0xD0, 0x5E, 0x73, 0x5D, 0x43, -0x34, 0x30, 0x38, 0x3C, 0x46, 0xCE, 0xB9, 0xBE, 0x5F, 0x3E, 0x3B, 0x3E, 0x62, 0xC0, 0xB5, 0xB6, -0xC9, 0x54, 0x48, 0xE3, 0xB1, 0xA4, 0xA0, 0xA6, 0xC3, 0x2B, 0x1E, 0x29, 0x5D, 0xB9, 0xBD, 0x72, -0x50, 0x5B, 0x50, 0x3C, 0x30, 0x30, 0x36, 0x3F, 0x7C, 0xC0, 0xBA, 0xD0, 0x45, 0x3A, 0x38, 0x46, -0xCB, 0xB7, 0xB5, 0xC4, 0x5A, 0x48, 0x62, 0xBA, 0xA8, 0xA1, 0xA3, 0xB0, 0x3C, 0x20, 0x20, 0x39, -0xBD, 0xB1, 0xC7, 0x4F, 0x4A, 0x4E, 0x48, 0x35, 0x2E, 0x31, 0x39, 0x56, 0xC0, 0xB8, 0xC2, 0x4D, -0x39, 0x37, 0x3E, 0xE2, 0xBC, 0xB6, 0xBB, 0xDC, 0x4B, 0x4A, 0xD3, 0xAE, 0xA3, 0xA0, 0xA8, 0xD5, -0x29, 0x1F, 0x2B, 0xE3, 0xB3, 0xBA, 0x65, 0x47, 0x4C, 0x4F, 0x3D, 0x2F, 0x2D, 0x30, 0x41, 0xCB, -0xB7, 0xBA, 0x76, 0x3D, 0x38, 0x39, 0x51, 0xC5, 0xB6, 0xB6, 0xCC, 0x50, 0x46, 0x7E, 0xB4, 0xA6, -0xA1, 0xA4, 0xB8, 0x35, 0x20, 0x25, 0x48, 0xB8, 0xB5, 0xDB, 0x47, 0x47, 0x52, 0x4A, 0x34, 0x2D, -0x2E, 0x39, 0xEC, 0xBA, 0xB6, 0xCF, 0x3F, 0x38, 0x37, 0x41, 0xD0, 0xB8, 0xB4, 0xBF, 0x6A, 0x4A, -0x5B, 0xBC, 0xA8, 0xA1, 0xA2, 0xAF, 0x3E, 0x22, 0x24, 0x3E, 0xBA, 0xB3, 0xD4, 0x45, 0x41, 0x4F, -0x52, 0x37, 0x2D, 0x2D, 0x36, 0x65, 0xBB, 0xB6, 0xC9, 0x46, 0x38, 0x35, 0x3D, 0xDC, 0xB7, 0xB0, -0xBA, 0xF0, 0x48, 0x4E, 0xC1, 0xAA, 0xA2, 0xA1, 0xAB, 0x5E, 0x27, 0x21, 0x32, 0xC7, 0xB4, 0xC8, -0x48, 0x3E, 0x4B, 0x58, 0x3D, 0x2E, 0x2C, 0x2F, 0x48, 0xBF, 0xB5, 0xBF, 0x4C, 0x36, 0x34, 0x3A, -0x67, 0xBC, 0xB2, 0xB7, 0xD6, 0x4C, 0x4A, 0xCE, 0xAD, 0xA3, 0xA0, 0xA7, 0xD8, 0x29, 0x20, 0x2F, -0xD2, 0xB5, 0xC4, 0x4C, 0x40, 0x4B, 0x64, 0x44, 0x2F, 0x2C, 0x2D, 0x3F, 0xC4, 0xB4, 0xB9, 0x5F, -0x39, 0x36, 0x39, 0x5D, 0xBE, 0xB3, 0xB4, 0xC8, 0x59, 0x4B, 0xDC, 0xAF, 0xA3, 0x9F, 0xA5, 0xC5, -0x2C, 0x21, 0x2C, 0xFB, 0xB9, 0xC1, 0x53, 0x42, 0x4A, 0x5F, 0x49, 0x31, 0x2C, 0x2C, 0x3A, 0xCF, -0xB6, 0xBA, 0xF7, 0x3E, 0x39, 0x3A, 0x4C, 0xCA, 0xB7, 0xB4, 0xBF, 0x79, 0x4D, 0xE5, 0xB1, 0xA4, -0x9F, 0xA4, 0xC6, 0x2B, 0x20, 0x2C, 0xEC, 0xB7, 0xC1, 0x57, 0x43, 0x49, 0x5C, 0x47, 0x31, 0x2C, -0x2C, 0x39, 0xD3, 0xB7, 0xBA, 0xDC, 0x46, 0x3C, 0x39, 0x47, 0xCE, 0xB9, 0xB5, 0xBD, 0xDE, 0x5E, -0xD3, 0xB0, 0xA4, 0xA0, 0xA6, 0xCF, 0x2A, 0x21, 0x2D, 0xF6, 0xBB, 0xC8, 0x55, 0x44, 0x48, 0x51, -0x3F, 0x2F, 0x2C, 0x2D, 0x3B, 0xD8, 0xBC, 0xBF, 0xE7, 0x4E, 0x45, 0x3C, 0x44, 0xEB, 0xBE, 0xB5, -0xBA, 0xCA, 0xE3, 0xC9, 0xAF, 0xA5, 0xA0, 0xA7, 0xE6, 0x28, 0x22, 0x2E, 0xEA, 0xBD, 0xC8, 0x5D, -0x46, 0x4A, 0x4D, 0x3B, 0x2F, 0x2D, 0x2F, 0x3F, 0xD0, 0xBE, 0xC3, 0xE6, 0x56, 0x4B, 0x43, 0x4C, -0xFA, 0xC8, 0xBB, 0xBB, 0xC3, 0xC8, 0xBD, 0xAE, 0xA7, 0xA3, 0xAA, 0x6C, 0x2A, 0x25, 0x30, 0x5A, -0xCD, 0xD3, 0x5F, 0x4D, 0x50, 0x4C, 0x3B, 0x2F, 0x2D, 0x2F, 0x3D, 0xE6, 0xCC, 0xD3, 0xDA, 0xDB, -0x79, 0x55, 0x56, 0x68, 0xE0, 0xCA, 0xC2, 0xC0, 0xBC, 0xB1, 0xAB, 0xA6, 0xA5, 0xAE, 0x53, 0x2C, -0x29, 0x30, 0x41, 0x59, 0x62, 0x53, 0x57, 0x7F, 0x5D, 0x40, 0x35, 0x2E, 0x2F, 0x3D, 0x58, 0x78, -0xE5, 0xCD, 0xC8, 0xCF, 0xDA, 0xEC, 0x7B, 0xE4, 0xD1, 0xCA, 0xC4, 0xBA, 0xB0, 0xAC, 0xAA, 0xAB, -0xBA, 0x4F, 0x39, 0x39, 0x3D, 0x3F, 0x42, 0x3D, 0x3C, 0x45, 0x51, 0x52, 0x4C, 0x42, 0x3B, 0x3E, -0x4A, 0x4C, 0x4D, 0x57, 0x69, 0xEE, 0xDE, 0xE4, 0xFD, 0xED, 0xDC, 0xD3, 0xCD, 0xCA, 0xC3, 0xBD, -0xB9, 0xB6, 0xB8, 0xC3, 0xCE, 0xC8, 0xC1, 0xC5, 0xCE, 0xF9, 0x4A, 0x3F, 0x3F, 0x41, 0x3F, 0x3D, -0x39, 0x38, 0x3B, 0x3C, 0x3A, 0x3C, 0x43, 0x4C, 0x52, 0x58, 0x5B, 0x59, 0x65, 0xDC, 0xCB, 0xC3, -0xBD, 0xB8, 0xB6, 0xB2, 0xAF, 0xB2, 0xB6, 0xB2, 0xB0, 0xB6, 0xBF, 0xD7, 0x4F, 0x40, 0x3F, 0x3D, -0x3A, 0x35, 0x2F, 0x2D, 0x2F, 0x32, 0x33, 0x34, 0x39, 0x3E, 0x46, 0x51, 0x59, 0x5C, 0x6F, 0xD8, -0xC6, 0xBD, 0xB8, 0xB4, 0xB2, 0xAF, 0xAC, 0xAD, 0xAF, 0xAE, 0xAE, 0xB2, 0xBC, 0xCF, 0x55, 0x42, -0x3E, 0x3B, 0x36, 0x31, 0x2D, 0x2A, 0x2B, 0x2F, 0x32, 0x33, 0x36, 0x3B, 0x40, 0x4A, 0x57, 0x69, -0xEE, 0xD6, 0xC8, 0xBF, 0xB9, 0xB3, 0xB1, 0xAF, 0xAC, 0xAB, 0xAE, 0xAF, 0xAF, 0xB1, 0xB9, 0xC6, -0x75, 0x46, 0x3D, 0x3A, 0x36, 0x30, 0x2D, 0x2B, 0x2A, 0x2D, 0x31, 0x34, 0x36, 0x39, 0x3E, 0x46, -0x56, 0x77, 0xE3, 0xD4, 0xCA, 0xC3, 0xBD, 0xB6, 0xB1, 0xAF, 0xAC, 0xAB, 0xAC, 0xAF, 0xAF, 0xB0, -0xB5, 0xBE, 0xDA, 0x4E, 0x3E, 0x3A, 0x36, 0x31, 0x2D, 0x2C, 0x2B, 0x2C, 0x2F, 0x32, 0x34, 0x38, -0x3D, 0x43, 0x4D, 0x66, 0xE7, 0xD6, 0xCB, 0xC5, 0xC0, 0xBA, 0xB3, 0xAF, 0xAD, 0xAB, 0xAC, 0xAE, -0xAF, 0xAF, 0xB3, 0xBB, 0xCD, 0x5A, 0x40, 0x3A, 0x36, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2F, 0x31, -0x32, 0x38, 0x3D, 0x41, 0x4B, 0x5C, 0xF8, 0xD8, 0xCA, 0xC3, 0xBF, 0xBA, 0xB4, 0xB0, 0xAD, 0xAB, -0xAB, 0xAE, 0xAF, 0xB0, 0xB3, 0xBA, 0xC9, 0x68, 0x46, 0x3C, 0x37, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, -0x2F, 0x30, 0x31, 0x36, 0x3C, 0x3F, 0x49, 0x58, 0x70, 0xDD, 0xCA, 0xC2, 0xBE, 0xB9, 0xB3, 0xB0, -0xAD, 0xAA, 0xAB, 0xAE, 0xAF, 0xAF, 0xB4, 0xBC, 0xCB, 0x61, 0x46, 0x3D, 0x36, 0x30, 0x2E, 0x2C, -0x2B, 0x2D, 0x2F, 0x2F, 0x31, 0x37, 0x3B, 0x3F, 0x4B, 0x5C, 0xFF, 0xD8, 0xC8, 0xC1, 0xBC, 0xB6, -0xB2, 0xAF, 0xAC, 0xAA, 0xAB, 0xAD, 0xAE, 0xAF, 0xB5, 0xBD, 0xCF, 0x5C, 0x45, 0x3C, 0x35, 0x2F, -0x2D, 0x2C, 0x2C, 0x2D, 0x2F, 0x2F, 0x32, 0x37, 0x3B, 0x3F, 0x4B, 0x5F, 0xEE, 0xD4, 0xC8, 0xC1, -0xBC, 0xB5, 0xB0, 0xAE, 0xAB, 0xAA, 0xAB, 0xAD, 0xAF, 0xB1, 0xB7, 0xC0, 0xD9, 0x53, 0x42, 0x3B, -0x34, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x30, 0x33, 0x37, 0x3C, 0x43, 0x4D, 0x5E, 0xEC, 0xD0, -0xC7, 0xC0, 0xBB, 0xB6, 0xB0, 0xAE, 0xAB, 0xAA, 0xAC, 0xAE, 0xAF, 0xB3, 0xB9, 0xC5, 0xE2, 0x4E, -0x3F, 0x39, 0x32, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x2F, 0x33, 0x39, 0x3D, 0x44, 0x4F, 0x65, -0xE3, 0xCE, 0xC5, 0xBF, 0xBA, 0xB4, 0xAF, 0xAD, 0xAA, 0xAA, 0xAC, 0xAE, 0xB0, 0xB5, 0xBB, 0xC8, -0xF8, 0x4C, 0x3E, 0x38, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2E, 0x2F, 0x31, 0x35, 0x39, 0x3E, 0x4A, -0x5C, 0xF9, 0xD8, 0xCB, 0xC2, 0xBC, 0xB7, 0xB2, 0xAE, 0xAB, 0xA9, 0xAA, 0xAC, 0xAE, 0xB2, 0xB8, -0xBE, 0xCE, 0x72, 0x48, 0x3B, 0x34, 0x2F, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x36, 0x3A, -0x3E, 0x4A, 0x5F, 0xEA, 0xD0, 0xC9, 0xC1, 0xBB, 0xB5, 0xB0, 0xAE, 0xAB, 0xA9, 0xAB, 0xAC, 0xAE, -0xB4, 0xBB, 0xC4, 0xD6, 0x60, 0x45, 0x39, 0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x32, -0x35, 0x3A, 0x43, 0x51, 0x6A, 0xDF, 0xCB, 0xC3, 0xBD, 0xB8, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, -0xAC, 0xAF, 0xB7, 0xBD, 0xCC, 0xF1, 0x51, 0x3F, 0x36, 0x2F, 0x2D, 0x2B, 0x2A, 0x2C, 0x2D, 0x2E, -0x2F, 0x33, 0x37, 0x3B, 0x45, 0x58, 0x77, 0xD5, 0xC8, 0xC0, 0xBB, 0xB6, 0xB1, 0xAE, 0xAB, 0xA9, -0xAA, 0xAB, 0xAC, 0xB1, 0xB9, 0xC0, 0xD3, 0x6A, 0x4A, 0x3C, 0x33, 0x2E, 0x2D, 0x2B, 0x2B, 0x2C, -0x2D, 0x2E, 0x31, 0x34, 0x38, 0x3F, 0x4C, 0x5D, 0xEA, 0xCE, 0xC6, 0xBE, 0xB8, 0xB4, 0xAF, 0xAD, -0xAB, 0xAA, 0xAA, 0xAB, 0xAD, 0xB2, 0xB9, 0xC3, 0xD8, 0x61, 0x47, 0x3A, 0x32, 0x2E, 0x2C, 0x2B, -0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x38, 0x3F, 0x4D, 0x62, 0xDD, 0xCC, 0xC3, 0xBC, 0xB7, 0xB2, -0xAE, 0xAC, 0xAA, 0xAA, 0xAA, 0xAB, 0xAE, 0xB3, 0xBA, 0xC6, 0xE1, 0x55, 0x41, 0x37, 0x30, 0x2D, -0x2B, 0x2A, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x39, 0x40, 0x4D, 0x6A, 0xD8, 0xC9, 0xC1, 0xBC, -0xB7, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, 0xAC, 0xAF, 0xB7, 0xBB, 0xC6, 0x79, 0x55, 0x44, 0x37, -0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2D, 0x2F, 0x33, 0x35, 0x39, 0x42, 0x51, 0x6C, 0xDA, 0xCA, -0xC4, 0xBE, 0xBA, 0xB6, 0xB0, 0xAD, 0xAC, 0xAC, 0xAC, 0xAD, 0xAF, 0xB4, 0xB9, 0xC0, 0xD0, 0x65, -0x47, 0x3A, 0x32, 0x2F, 0x2C, 0x2B, 0x2B, 0x2C, 0x2D, 0x2E, 0x31, 0x36, 0x3A, 0x3F, 0x4A, 0x5E, -0xDC, 0xCC, 0xC4, 0xBE, 0xBA, 0xB6, 0xB2, 0xAF, 0xAE, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB8, 0xBE, -0xCA, 0xE6, 0x4F, 0x3F, 0x38, 0x31, 0x2E, 0x2C, 0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x35, 0x3A, 0x3F, -0x4B, 0x64, 0xDD, 0xCB, 0xC3, 0xBD, 0xBA, 0xB7, 0xB4, 0xB1, 0xAF, 0xAE, 0xAE, 0xB0, 0xB3, 0xB5, -0xB9, 0xBE, 0xC6, 0xD3, 0x74, 0x4E, 0x40, 0x3A, 0x35, 0x32, 0x30, 0x2F, 0x2F, 0x30, 0x33, 0x36, -0x3A, 0x3F, 0x48, 0x52, 0x6C, 0xDF, 0xCE, 0xC7, 0xC1, 0xBE, 0xBB, 0xB9, 0xB8, 0xB7, 0xB6, 0xB6, -0xB7, 0xB9, 0xBB, 0xBE, 0xC4, 0xCA, 0xD9, 0x6C, 0x50, 0x45, 0x3D, 0x3A, 0x37, 0x35, 0x35, 0x35, -0x36, 0x37, 0x39, 0x3C, 0x3F, 0x46, 0x4F, 0x5E, 0xF1, 0xD9, 0xCF, 0xCC, 0xC9, 0xC5, 0xC1, 0xBE, -0xBC, 0xBC, 0xBC, 0xBD, 0xBF, 0xC2, 0xC4, 0xC7, 0xCC, 0xD5, 0xE8, 0x64, 0x52, 0x4A, 0x45, 0x41, -0x3F, 0x3E, 0x3D, 0x3D, 0x3E, 0x41, 0x45, 0x49, 0x4D, 0x53, 0x5C, 0x71, 0xE9, 0xDD, 0xD6, 0xD1, -0xCE, 0xCB, 0xC9, 0xC8, 0xC8, 0xC7, 0xC7, 0xC8, 0xC9, 0xCC, 0xCF, 0xD4, 0xDA, 0xE4, 0xF7, 0x69, -0x5B, 0x53, 0x4F, 0x4E, 0x4D, 0x4D, 0x4D, 0x4E, 0x51, 0x58, 0x5F, 0x68, 0x6F, 0x77, 0xFC, 0xEE, -0xE8, 0xE5, 0xE1, 0xDD, 0xDE, 0xDE, 0xDE, 0xE2, 0xE6, 0xE6, 0xEB, 0xF0, 0xED, 0xEA, 0xEC, 0xEE, -0xF8, 0x6A, 0x5C, 0x57, 0x55, 0x56, 0x58, 0x59, 0x58, 0x58, 0x5B, 0x5E, 0x63, 0x71, 0xF7, 0xEE, -0xE9, 0xE3, 0xE4, 0xE8, 0xE7, 0xEA, 0xEE, 0xEE, 0xF2, 0xFB, 0xFF, 0x7B, 0x74, 0x6E, 0x6B, 0x65, -0x60, 0x65, 0x67, 0x61, 0x60, 0x61, 0x5E, 0x5E, 0x62, 0x69, 0x70, 0x7F, 0xF6, 0xF2, 0xEC, 0xE7, -0xE6, 0xE3, 0xDF, 0xDE, 0xDE, 0xDD, 0xDE, 0xE0, 0xE5, 0xEC, 0xF6, 0x7F, 0x78, 0x75, 0x70, 0x6B, -0x64, 0x5E, 0x5A, 0x58, 0x58, 0x59, 0x5A, 0x5C, 0x5D, 0x5E, 0x61, 0x67, 0x6C, 0x75, 0xF8, 0xEC, -0xE6, 0xE0, 0xDD, 0xDD, 0xDE, 0xDF, 0xE0, 0xE2, 0xE2, 0xE4, 0xE6, 0xE9, 0xEE, 0xF9, 0x7D, 0x75, -0x6E, 0x6A, 0x65, 0x61, 0x5E, 0x5C, 0x5B, 0x5C, 0x5D, 0x5E, 0x60, 0x63, 0x66, 0x6C, 0x76, 0xFA, -0xEE, 0xE9, 0xE4, 0xE1, 0xDF, 0xDD, 0xDE, 0xDF, 0xE2, 0xE6, 0xEA, 0xEE, 0xF4, 0xFA, 0x7E, 0x7A, -0x75, 0x72, 0x74, 0x74, 0x71, 0x70, 0x6D, 0x6A, 0x6A, 0x6B, 0x6D, 0x70, 0x74, 0x78, 0x7A, 0x7D, -0xFA, 0xF0, 0xEA, 0xE5, 0xE3, 0xE2, 0xE0, 0xDF, 0xE1, 0xE3, 0xE4, 0xE8, 0xEB, 0xEE, 0xF4, 0xFB, -0x7E, 0x75, 0x6D, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x65, 0x64, 0x63, 0x64, 0x66, 0x69, 0x6D, 0x72, -0x77, 0x7B, 0xFE, 0xF7, 0xF0, 0xEB, 0xE8, 0xE7, 0xE6, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xEA, 0xED, -0xF3, 0xFC, 0x79, 0x72, 0x6F, 0x6C, 0x6B, 0x6B, 0x69, 0x66, 0x64, 0x63, 0x62, 0x63, 0x67, 0x6C, -0x73, 0x7C, 0xFE, 0xFD, 0xFA, 0xF4, 0xEE, 0xEA, 0xE5, 0xE1, 0xE1, 0xE2, 0xE5, 0xE9, 0xED, 0xEF, -0xF1, 0xF2, 0xF4, 0xF8, 0xFF, 0x76, 0x6E, 0x6A, 0x68, 0x67, 0x66, 0x65, 0x64, 0x62, 0x61, 0x61, -0x63, 0x67, 0x6B, 0x72, 0x7E, 0xFA, 0xF5, 0xF1, 0xEE, 0xED, 0xEC, 0xE9, 0xE8, 0xE7, 0xE7, 0xE9, -0xEC, 0xF0, 0xF9, 0x7D, 0x77, 0x73, 0x70, 0x6F, 0x6E, 0x6C, 0x69, 0x67, 0x65, 0x66, 0x66, 0x68, -0x69, 0x69, 0x6A, 0x6C, 0x6E, 0x75, 0x7F, 0xF8, 0xF1, 0xED, 0xEB, 0xEA, 0xEA, 0xEB, 0xEB, 0xEB, -0xEA, 0xE9, 0xEA, 0xEC, 0xEF, 0xF4, 0xFB, 0x7D, 0x77, 0x73, 0x71, 0x6F, 0x6D, 0x6B, 0x69, 0x67, -0x66, 0x67, 0x68, 0x69, 0x6B, 0x6D, 0x6F, 0x74, 0x79, 0x7F, 0xF9, 0xF3, 0xEF, 0xEE, 0xEE, 0xEE, -0xEE, 0xED, 0xED, 0xED, 0xEE, 0xEC, 0xEC, 0xF1, 0xF3, 0xF6, 0xFD, 0xFF, 0x7D, 0x78, 0x78, 0x76, -0x70, 0x6F, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x71, 0x73, 0x77, 0x7B, 0x7D, 0xFF, 0xFB, 0xF8, 0xF8, -0xFA, 0xFB, 0xFE, 0x7E, 0x7D, 0x7A, 0x79, 0x7A, 0x76, 0x76, 0x76, 0x72, 0x70, 0x6F, 0x6D, 0x6E, -0x6D, 0x6B, 0x6E, 0x65, 0x66, 0x57, 0x41, 0x59, 0xC7, 0x62, 0x57, 0xCD, 0x64, 0x6B, 0xCC, 0x6D, -0xF6, 0xD1, 0x69, 0x6E, 0xDA, 0x7D, 0x61, 0xEE, 0xF1, 0xFD, 0xFF, 0x6E, 0xE7, 0x74, 0x66, 0xE9, -0x6A, 0xFC, 0xF2, 0x64, 0xEE, 0x6F, 0x6B, 0x7B, 0x69, 0xF2, 0x68, 0x74, 0xEC, 0x5F, 0xED, 0xFC, -0x5F, 0xDE, 0x72, 0x65, 0xDC, 0x51, 0x4C, 0xE8, 0x5F, 0xEF, 0xD7, 0x4E, 0xF3, 0xF9, 0x52, 0xC3, -0xE2, 0x56, 0xC9, 0x5B, 0x59, 0xE4, 0x50, 0x53, 0x47, 0x66, 0xF9, 0x47, 0xC9, 0xCB, 0x59, 0xD4, -0x55, 0x58, 0xD3, 0x5C, 0xF9, 0xCE, 0xD7, 0x6D, 0x61, 0xDB, 0xE4, 0xE8, 0x70, 0x79, 0xCD, 0x6B, -0x5D, 0xEC, 0x66, 0xDC, 0x6C, 0x5F, 0xD3, 0xF9, 0xFB, 0x66, 0x55, 0xDE, 0xFB, 0x64, 0xD7, 0xDA, -0xF1, 0xF1, 0xF1, 0xE5, 0xDB, 0xF4, 0x75, 0xDF, 0xE7, 0xFD, 0x79, 0xEC, 0xD9, 0xF0, 0x6E, 0xF5, -0xE4, 0xE5, 0x64, 0x74, 0xDF, 0x7D, 0x68, 0x75, 0xF0, 0xFD, 0x7B, 0xFC, 0x7B, 0xDE, 0xEF, 0x64, -0xDF, 0xE8, 0xFF, 0xE9, 0xFF, 0xE2, 0xE1, 0x76, 0xF6, 0xEF, 0xEC, 0xF9, 0x6D, 0x7C, 0x73, 0x6D, -0x69, 0x67, 0x76, 0x75, 0x73, 0x64, 0x66, 0xFD, 0x60, 0x5F, 0x77, 0x67, 0x70, 0x74, 0x60, 0x78, -0x7A, 0x5C, 0x67, 0x79, 0x6C, 0x77, 0x63, 0x63, 0xEF, 0x6C, 0x66, 0x73, 0x6D, 0xF8, 0x72, 0x74, -0xE6, 0xFB, 0x7B, 0xF3, 0xF6, 0xF1, 0xFE, 0x7B, 0xF5, 0xF1, 0x6D, 0x63, 0x75, 0x6E, 0x60, 0x64, -0x67, 0x67, 0x68, 0x67, 0x67, 0x6C, 0x64, 0x5B, 0x65, 0x6E, 0x69, 0x72, 0x76, 0x74, 0xFE, 0xFD, -0xFF, 0xF6, 0xF3, 0x7C, 0x7A, 0xFC, 0xFE, 0xFB, 0x7E, 0x75, 0xF5, 0xEE, 0xFC, 0xF7, 0xF3, 0xFF, -0xFE, 0x74, 0x6B, 0x6F, 0x6D, 0x6A, 0x6C, 0x6A, 0x7A, 0xF9, 0x71, 0x7C, 0xF5, 0x7C, 0x7B, 0x7F, -0xFE, 0x72, 0x6E, 0xFF, 0x6F, 0x66, 0x6B, 0x6A, 0x6E, 0x76, 0x71, 0x7C, 0x7A, 0x6E, 0x6C, 0x69, -0x6C, 0x6D, 0x63, 0x65, 0x6A, 0x66, 0x63, 0x65, 0x6C, 0x68, 0x64, 0x69, 0x6A, 0x6E, 0x79, 0x7B, -0x78, 0x6D, 0x6E, 0x79, 0x77, 0xFA, 0xED, 0xEF, 0xEF, 0xEC, 0xE8, 0xEF, 0xFB, 0xF6, 0xEF, 0xEE, -0xF7, 0xF9, 0xF3, 0xF7, 0xF1, 0xF3, 0xFD, 0xFD, 0x7A, 0x7B, 0xFE, 0x79, 0x7C, 0x7B, 0x6E, 0x72, -0x7A, 0x72, 0x71, 0x79, 0x79, 0x6F, 0x6F, 0x78, 0x74, 0x72, 0x7B, 0x72, 0x78, 0xF6, 0xF7, 0xF9, -0x78, 0x79, 0xEE, 0xF5, 0x74, 0x76, 0x7A, 0xFE, 0x7E, 0x75, 0x7A, 0x7E, 0x74, 0x70, 0x7D, 0xF8, -0xF8, 0x7D, 0x77, 0xF8, 0xF0, 0x7F, 0x7E, 0xF2, 0xED, 0xF0, 0xF4, 0xEB, 0xE9, 0xFE, 0x74, 0xEF, -0xE1, 0xE0, 0xDC, 0xD9, 0xD7, 0xD3, 0xD7, 0xDD, 0xD9, 0xD9, 0xDF, 0xE6, 0xEB, 0xF2, 0x78, 0x65, -0x61, 0x65, 0x5F, 0x5A, 0x5B, 0x5B, 0x5A, 0x5C, 0x5B, 0x5D, 0x5E, 0x5C, 0x5B, 0x5B, 0x5B, 0x5C, -0x5E, 0x6B, 0xEA, 0xD9, 0xD2, 0xD1, 0xCD, 0xC8, 0xC6, 0xC5, 0xC5, 0xC3, 0xC3, 0xC6, 0xCA, 0xD2, -0xE8, 0x67, 0x51, 0x49, 0x42, 0x3D, 0x3D, 0x3E, 0x3F, 0x41, 0x44, 0x49, 0x4E, 0x50, 0x55, 0x5A, -0x5F, 0x6F, 0xEF, 0xDA, 0xCD, 0xCA, 0xC8, 0xC4, 0xBF, 0xBD, 0xBB, 0xB9, 0xB7, 0xB6, 0xBA, 0xC2, -0xCC, 0xE2, 0x56, 0x43, 0x3B, 0x39, 0x37, 0x36, 0x37, 0x3B, 0x3E, 0x42, 0x47, 0x4B, 0x51, 0x5A, -0x5B, 0x5E, 0x67, 0x7A, 0xED, 0xE8, 0xDB, 0xCF, 0xCB, 0xC5, 0xBD, 0xB9, 0xB6, 0xB2, 0xB0, 0xB4, -0xB9, 0xBF, 0xCD, 0xFC, 0x49, 0x3B, 0x37, 0x33, 0x31, 0x32, 0x33, 0x38, 0x3E, 0x45, 0x4F, 0x5F, -0x74, 0xF0, 0xEF, 0xF1, 0xF4, 0xFF, 0x77, 0x72, 0xFB, 0xE4, 0xD9, 0xCE, 0xC3, 0xBA, 0xB6, 0xB2, -0xB0, 0xB2, 0xB6, 0xBB, 0xC8, 0xE4, 0x51, 0x3E, 0x38, 0x33, 0x2F, 0x2F, 0x31, 0x35, 0x3A, 0x3E, -0x49, 0x5D, 0xFE, 0xE4, 0xDD, 0xD9, 0xD9, 0xE1, 0xEB, 0xEE, 0xEE, 0xE7, 0xDD, 0xD2, 0xC7, 0xBD, -0xB9, 0xB5, 0xB2, 0xB5, 0xB8, 0xBB, 0xC6, 0xDA, 0x5F, 0x45, 0x3D, 0x37, 0x33, 0x31, 0x31, 0x35, -0x39, 0x3D, 0x45, 0x53, 0x6F, 0xE3, 0xD9, 0xD0, 0xCF, 0xD2, 0xD5, 0xD9, 0xD9, 0xD8, 0xD4, 0xCE, -0xC8, 0xC0, 0xBD, 0xB9, 0xB8, 0xBB, 0xBD, 0xC1, 0xCD, 0xDF, 0x5F, 0x4A, 0x41, 0x3B, 0x37, 0x36, -0x35, 0x36, 0x3A, 0x3D, 0x44, 0x4E, 0x5F, 0xEC, 0xDB, 0xD6, 0xD2, 0xD4, 0xD6, 0xDA, 0xDD, 0xDB, -0xD8, 0xD2, 0xCD, 0xC9, 0xC3, 0xBF, 0xBE, 0xBF, 0xC3, 0xC4, 0xCA, 0xD6, 0xED, 0x5E, 0x50, 0x48, -0x3F, 0x3C, 0x3B, 0x3A, 0x3A, 0x3D, 0x40, 0x4A, 0x55, 0x6A, 0xE6, 0xDC, 0xD8, 0xD6, 0xD8, 0xD8, -0xDB, 0xDE, 0xDF, 0xE2, 0xDE, 0xDC, 0xD9, 0xD0, 0xCB, 0xC8, 0xC8, 0xCC, 0xCD, 0xCD, 0xD1, 0xDB, -0xF2, 0x67, 0x5B, 0x51, 0x49, 0x44, 0x42, 0x41, 0x42, 0x44, 0x49, 0x4E, 0x55, 0x5C, 0x6A, 0x7E, -0xF3, 0xED, 0xED, 0xEF, 0xEC, 0xED, 0xF4, 0xF7, 0xF0, 0xEB, 0xE4, 0xDF, 0xDA, 0xD2, 0xCD, 0xCC, -0xCC, 0xCF, 0xCF, 0xCE, 0xD3, 0xDB, 0xE7, 0x7C, 0x69, 0x5E, 0x54, 0x4F, 0x4E, 0x4D, 0x4E, 0x4F, -0x52, 0x58, 0x5B, 0x5E, 0x63, 0x67, 0x6B, 0x6B, 0x6A, 0x6B, 0x6C, 0x6E, 0x6F, 0x73, 0x7D, 0xF3, -0xEA, 0xE1, 0xDC, 0xD8, 0xD3, 0xD1, 0xCF, 0xCE, 0xD1, 0xD2, 0xD2, 0xD6, 0xDB, 0xE2, 0xEF, 0xFD, -0x73, 0x66, 0x5F, 0x5C, 0x5A, 0x59, 0x58, 0x56, 0x56, 0x57, 0x57, 0x58, 0x58, 0x5A, 0x5C, 0x5D, -0x61, 0x65, 0x6A, 0x74, 0x7E, 0xF4, 0xEA, 0xE2, 0xDD, 0xDA, 0xD7, 0xD5, 0xD2, 0xD1, 0xD0, 0xD1, -0xD3, 0xD3, 0xD4, 0xD7, 0xDB, 0xE0, 0xE8, 0xEF, 0x7B, 0x69, 0x5F, 0x5B, 0x57, 0x53, 0x50, 0x4F, -0x4F, 0x4F, 0x4F, 0x50, 0x52, 0x56, 0x59, 0x5C, 0x60, 0x68, 0x6E, 0x7A, 0xFB, 0xF1, 0xEB, 0xE7, -0xE2, 0xDE, 0xDC, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD3, 0xD5, 0xD5, 0xD8, 0xDC, 0xE4, 0xF2, 0x78, -0x6A, 0x5E, 0x59, 0x55, 0x52, 0x50, 0x4F, 0x4F, 0x50, 0x52, 0x55, 0x58, 0x5A, 0x5D, 0x61, 0x64, -0x69, 0x6E, 0x74, 0xFF, 0xF6, 0xEE, 0xE9, 0xE4, 0xDF, 0xDC, 0xD8, 0xD5, 0xD2, 0xD0, 0xD1, 0xD1, -0xD2, 0xD6, 0xD7, 0xDA, 0xDF, 0xE8, 0xF8, 0x71, 0x69, 0x60, 0x5C, 0x58, 0x56, 0x54, 0x53, 0x53, -0x53, 0x55, 0x56, 0x58, 0x5A, 0x5C, 0x5F, 0x63, 0x69, 0x71, 0xFF, 0xEF, 0xEA, 0xE6, 0xE1, 0xDF, -0xDE, 0xDB, 0xDA, 0xDA, 0xD7, 0xD4, 0xD1, 0xD1, 0xD2, 0xD4, 0xD7, 0xD8, 0xDB, 0xE1, 0xED, 0x78, -0x69, 0x61, 0x5A, 0x53, 0x50, 0x4F, 0x4E, 0x4F, 0x4F, 0x51, 0x55, 0x59, 0x5D, 0x60, 0x65, 0x6C, -0x6F, 0x76, 0x7E, 0xFC, 0xF5, 0xF2, 0xF2, 0xED, 0xE7, 0xE1, 0xDD, 0xD9, 0xD4, 0xCE, 0xCB, 0xCA, -0xC8, 0xCA, 0xCF, 0xD0, 0xD7, 0xE6, 0x7C, 0x5E, 0x53, 0x4F, 0x4C, 0x4A, 0x4A, 0x4A, 0x4C, 0x4E, -0x4F, 0x51, 0x57, 0x5D, 0x62, 0x66, 0x69, 0x6D, 0x6D, 0x67, 0x63, 0x65, 0x6B, 0x70, 0x75, 0xFE, -0xEA, 0xDC, 0xD3, 0xCE, 0xC9, 0xC2, 0xBE, 0xBC, 0xBC, 0xC1, 0xC8, 0xCB, 0xDC, 0x69, 0x50, 0x46, -0x42, 0x3F, 0x3D, 0x3D, 0x3F, 0x43, 0x4B, 0x4F, 0x55, 0x61, 0x6F, 0xFC, 0xF0, 0xFA, 0xFD, 0x7B, -0x63, 0x5A, 0x54, 0x52, 0x54, 0x58, 0x62, 0x7D, 0xDE, 0xCC, 0xC4, 0xBC, 0xB6, 0xB1, 0xAE, 0xB2, -0xBA, 0xC1, 0xDA, 0x5A, 0x45, 0x38, 0x33, 0x32, 0x33, 0x36, 0x3A, 0x3E, 0x4B, 0x66, 0xEA, 0xD6, -0xCE, 0xCF, 0xD3, 0xE0, 0x6E, 0x5C, 0x51, 0x4D, 0x4B, 0x4A, 0x4F, 0x5B, 0x7A, 0xD6, 0xC6, 0xBA, -0xB1, 0xAE, 0xAA, 0xAA, 0xAF, 0xBA, 0xD1, 0x4E, 0x3D, 0x31, 0x2B, 0x2B, 0x2C, 0x30, 0x38, 0x3E, -0x4E, 0xEA, 0xCD, 0xC7, 0xC8, 0xCB, 0xCE, 0xDD, 0x64, 0x4F, 0x48, 0x48, 0x47, 0x46, 0x4D, 0x62, -0xDD, 0xCA, 0xBD, 0xB1, 0xAC, 0xA9, 0xA7, 0xAA, 0xB2, 0xC4, 0x51, 0x3A, 0x2F, 0x29, 0x28, 0x2A, -0x2E, 0x39, 0x45, 0x5A, 0xDB, 0xC8, 0xC2, 0xC5, 0xCD, 0xD5, 0xE8, 0x5B, 0x4C, 0x46, 0x47, 0x4C, -0x4E, 0x59, 0xF3, 0xD3, 0xC6, 0xBE, 0xB5, 0xAD, 0xAA, 0xA6, 0xA8, 0xB2, 0xC5, 0x54, 0x38, 0x2F, -0x28, 0x26, 0x2A, 0x2F, 0x3A, 0x4B, 0x73, 0xCF, 0xC5, 0xC4, 0xC9, 0xD9, 0xF8, 0x5F, 0x4C, 0x47, -0x47, 0x48, 0x4F, 0x5A, 0x74, 0xD9, 0xCE, 0xC7, 0xBF, 0xBA, 0xB0, 0xAC, 0xAA, 0xA9, 0xB0, 0xC5, -0x5C, 0x3B, 0x30, 0x2B, 0x27, 0x29, 0x2E, 0x39, 0x49, 0x6C, 0xD2, 0xC7, 0xC5, 0xCA, 0xDA, 0x7A, -0x5E, 0x4D, 0x48, 0x49, 0x4B, 0x52, 0x5E, 0x70, 0xDC, 0xCE, 0xC9, 0xC4, 0xBE, 0xB5, 0xAE, 0xAC, -0xAA, 0xAD, 0xBB, 0xE1, 0x43, 0x35, 0x2E, 0x29, 0x28, 0x2B, 0x32, 0x3D, 0x4E, 0x7E, 0xD2, 0xC9, -0xC7, 0xCC, 0xDF, 0xFE, 0x61, 0x4F, 0x4C, 0x4B, 0x4C, 0x54, 0x5D, 0x72, 0xDA, 0xCE, 0xC7, 0xC0, -0xB9, 0xB0, 0xAD, 0xAA, 0xAA, 0xB1, 0xC5, 0x5D, 0x3D, 0x33, 0x2C, 0x29, 0x29, 0x2D, 0x35, 0x3F, -0x4F, 0x78, 0xD7, 0xCA, 0xC7, 0xCD, 0xD9, 0xE3, 0x71, 0x5C, 0x54, 0x4D, 0x4E, 0x55, 0x5A, 0x6E, -0xE3, 0xD3, 0xC8, 0xBE, 0xB6, 0xAF, 0xAC, 0xAA, 0xAC, 0xB7, 0xCE, 0x53, 0x3D, 0x34, 0x2D, 0x2A, -0x2A, 0x2E, 0x35, 0x3E, 0x4A, 0x5C, 0xE5, 0xCD, 0xC8, 0xCB, 0xCE, 0xD5, 0xE2, 0xF7, 0x66, 0x57, -0x54, 0x56, 0x5B, 0x6E, 0xE7, 0xD5, 0xC9, 0xBE, 0xB6, 0xB1, 0xAE, 0xAE, 0xB4, 0xBE, 0xD3, 0x5C, -0x46, 0x3C, 0x34, 0x30, 0x2F, 0x32, 0x38, 0x3E, 0x45, 0x4E, 0x69, 0xDC, 0xCF, 0xCD, 0xCF, 0xD3, -0xD9, 0xDF, 0xEF, 0x6F, 0x68, 0x67, 0x6F, 0xF7, 0xE7, 0xDC, 0xD2, 0xC8, 0xC1, 0xBE, 0xBC, 0xBD, -0xC3, 0xCB, 0xD5, 0xEA, 0x6A, 0x58, 0x4D, 0x47, 0x43, 0x43, 0x44, 0x47, 0x4A, 0x4D, 0x52, 0x5D, -0x6D, 0x78, 0x77, 0x78, 0x76, 0x73, 0x75, 0x72, 0x72, 0x78, 0x7E, 0xF6, 0xEB, 0xE3, 0xDC, 0xD6, -0xD2, 0xCF, 0xCE, 0xCE, 0xCD, 0xCF, 0xD2, 0xD4, 0xD7, 0xDA, 0xDD, 0xE3, 0xEF, 0x7A, 0x6C, 0x65, -0x5F, 0x5B, 0x57, 0x53, 0x4F, 0x4E, 0x4D, 0x4C, 0x4A, 0x4A, 0x4A, 0x4B, 0x4D, 0x4F, 0x53, 0x59, -0x5F, 0x6C, 0xFE, 0xEC, 0xE3, 0xDE, 0xDC, 0xDA, 0xD9, 0xD8, 0xD7, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, -0xD8, 0xDA, 0xDC, 0xDE, 0xE3, 0xEC, 0xFB, 0x6F, 0x63, 0x5B, 0x55, 0x4F, 0x4D, 0x4C, 0x4B, 0x4C, -0x4C, 0x4D, 0x4F, 0x53, 0x58, 0x5E, 0x67, 0x73, 0xFB, 0xEE, 0xE8, 0xE3, 0xDF, 0xDC, 0xDA, 0xD9, -0xD8, 0xD8, 0xD8, 0xD9, 0xDB, 0xDD, 0xDF, 0xE1, 0xE5, 0xE9, 0xEE, 0xF6, 0x7C, 0x6E, 0x66, 0x5F, -0x5C, 0x5A, 0x58, 0x56, 0x56, 0x57, 0x58, 0x5A, 0x5D, 0x60, 0x66, 0x6D, 0x74, 0x7C, 0xFB, 0xF4, -0xEE, 0xEA, 0xE7, 0xE5, 0xE4, 0xE4, 0xE4, 0xE7, 0xEA, 0xEC, 0xED, 0xED, 0xEC, 0xED, 0xEC, 0xED, -0xEE, 0xF1, 0xF9, 0x7F, 0x79, 0x75, 0x70, 0x6D, 0x6C, 0x6C, 0x6E, 0x73, 0x79, 0xFE, 0xF9, 0xF3, -0xEE, 0xEB, 0xE9, 0xE8, 0xE6, 0xE5, 0xE6, 0xE8, 0xEA, 0xED, 0xF1, 0xF8, 0xFD, 0x7E, 0x7E, 0xFE, -0xFC, 0xF9, 0xF5, 0xF5, 0xF6, 0xFB, 0x7C, 0x77, 0x71, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6B, 0x6E, -0x70, 0x75, 0x7A, 0xFE, 0xF6, 0xF1, 0xEE, 0xEC, 0xEB, 0xEB, 0xEC, 0xEE, 0xF1, 0xF5, 0xFB, 0x7D, -0x7B, 0x7A, 0x7C, 0xFE, 0xFA, 0xF4, 0xF1, 0xF0, 0xF0, 0xF3, 0xF7, 0xFB, 0xFD, 0xFF, 0xFF, 0x7F, -0x7F, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0xFD, 0xFC, 0xFA, 0xF5, 0xF4, 0xF1, 0xEF, 0xEF, 0xEF, 0xF0, -0xF4, 0xF8, 0xFD, 0x7D, 0x78, 0x77, 0x78, 0x7A, 0x7C, 0x7C, 0x7E, 0x7C, 0x7A, 0x79, 0x76, 0x77, -0x78, 0x77, 0x7B, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0x7E, 0xFE, 0xFB, -0xFA, 0xF9, 0xFA, 0xFB, 0xFE, 0x7F, 0x7C, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7C, 0x7D, 0x7E, 0x7B, -0x77, 0x74, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x76, 0x76, 0x75, 0x76, -0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x77, 0x74, 0x72, 0x70, 0x6F, 0x6E, 0x6E, 0x6E, 0x70, 0x74, -0x78, 0x7B, 0x7D, 0x7D, 0x7C, 0x7C, 0x7A, 0x76, 0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x72, 0x72, -0x74, 0x76, 0x78, 0x7B, 0x7F, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF7, 0xFC, 0xFF, 0x7C, 0x79, 0x78, -0x77, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xFA, 0xFC, 0xFE, 0x7D, 0x7A, 0x76, -0x74, 0x74, 0x73, 0x75, 0x76, 0x76, 0x78, 0x7A, 0x7C, 0x7E, 0xFF, 0xFB, 0xF9, 0xF8, 0xF9, 0xFD, -0x7E, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x7C, 0x7F, 0xFB, 0xF6, 0xF5, 0xF2, 0xF2, 0xF3, -0xF4, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFA, -0xF7, 0xF6, 0xF8, 0xFC, 0x7F, 0x7C, 0x79, 0x72, 0x6F, 0x6E, 0x6E, 0x6E, 0x6F, 0x73, 0x77, 0x77, -0x7B, 0x7D, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x77, 0x75, 0x71, 0x6F, 0x6E, 0x6D, 0x6E, 0x6F, 0x70, -0x73, 0x74, 0x77, 0x79, 0x7C, 0x7D, 0x7D, 0x7D, 0x7B, 0x7A, 0x79, 0x76, 0x73, 0x70, 0x6F, 0x71, -0x73, 0x78, 0x7B, 0x7F, 0xFB, 0xF8, 0xF5, 0xF3, 0xF5, 0xF6, 0xF6, 0xF8, 0xF9, 0xFC, 0xFE, 0xFF, -0x7F, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xF7, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF6, 0xF7, 0xF9, -0xFA, 0xFC, 0xFF, 0xFF, 0x7F, 0x7F, 0xFE, 0xFD, 0xFE, 0xFD, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7C, -0x7A, 0x79, 0x77, 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7C, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, -0x7D, 0x7E, 0x7C, 0x7E, 0x7F, 0x7E, 0x7E, 0xFF, 0xFD, 0xFC, 0xFB, 0xF8, 0xF8, 0xFA, 0xFA, 0xFC, -0xFE, 0x7D, 0x78, 0x75, 0x72, 0x70, 0x70, 0x73, 0x75, 0x76, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x78, -0x77, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7D, 0x7F, 0xFC, 0xF8, 0xF6, -0xF4, 0xF2, 0xF3, 0xF7, 0xF9, 0xFB, 0x7E, 0x78, 0x75, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, -0x75, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x76, 0x79, 0x7B, -0x7C, 0x7E, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF6, 0xF7, 0xF9, 0xFC, 0xFE, 0x7C, 0x79, 0x77, 0x76, -0x75, 0x74, 0x74, 0x75, 0x74, 0x76, 0x77, 0x78, 0x79, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x78, 0x78, -0x77, 0x76, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7C, 0xFF, 0xFD, 0xFA, 0xF8, 0xF6, 0xF7, 0xF8, 0xF7, -0xF8, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, 0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFD, 0xFC, 0xFD, 0xFE, -0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, 0x7C, -0x7C, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x71, 0x70, 0x6F, 0x6F, 0x6E, -0x6D, 0x6C, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6F, 0x6E, 0x6F, 0x70, 0x70, 0x72, 0x75, 0x78, 0x7B, -0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFC, 0xFA, 0xFA, 0xF9, 0xF7, 0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF9, -0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFB, -0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0x7F, 0xFC, 0xFA, 0xFB, 0xFA, 0xFA, 0xF9, -0xFA, 0xFC, 0xFC, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFD, 0xFA, 0xFA, 0xF9, 0xF8, -0xFA, 0xF8, 0xFA, 0xFA, 0xFB, 0xFE, 0xFB, 0xFF, 0xFD, 0xFD, 0xFF, 0xFB, 0xFF, 0xFA, 0xFC, 0x7F, -0xFC, 0x70, 0x6A, 0x64, 0x61, 0x67, 0x6C, 0x73, 0x61, 0x60, 0x5A, 0x47, 0x53, 0xDF, 0x7D, 0x6F, -0x71, 0x69, 0x7F, 0x72, 0x70, 0x68, 0x5A, 0x5B, 0x59, 0x55, 0x5A, 0x5D, 0x4E, 0x46, 0x51, 0x77, -0xF6, 0xEC, 0xE8, 0xE6, 0xE5, 0xE4, 0xE1, 0xE5, 0xFD, 0x60, 0x65, 0xE6, 0xDB, 0xDD, 0xE1, 0xE4, -0xE2, 0xDC, 0xD4, 0xCF, 0xCF, 0xCF, 0xD1, 0xD2, 0xCF, 0xCD, 0xCC, 0xCD, 0xD0, 0xD4, 0xD7, 0xD5, -0xCE, 0xCD, 0xD3, 0xD9, 0xDB, 0xDA, 0xD9, 0xDC, 0xE2, 0xE5, 0xF1, 0xEE, 0xD7, 0xD2, 0xD9, 0xDC, -0xDD, 0xD9, 0xDC, 0xE7, 0xDF, 0xD9, 0xDD, 0x74, 0x62, 0xFC, 0xE9, 0xF2, 0x6C, 0x5D, 0x5D, 0x61, -0x6B, 0x6C, 0x5C, 0x5D, 0x70, 0x64, 0x5B, 0x6D, 0x78, 0x61, 0x57, 0x58, 0x65, 0x62, 0x53, 0x51, -0x69, 0xF5, 0x59, 0x53, 0x69, 0x68, 0x54, 0x4F, 0x67, 0xFA, 0x5B, 0x58, 0x5D, 0x60, 0x5D, 0x4E, -0x53, 0x61, 0x5A, 0x5F, 0x63, 0x61, 0x5E, 0x4C, 0x4C, 0x5A, 0x6B, 0xF7, 0x58, 0x47, 0x51, 0x6D, -0x68, 0x5A, 0x55, 0x53, 0x4A, 0x4E, 0xEE, 0xE1, 0x56, 0x46, 0x4D, 0x74, 0x70, 0x59, 0x53, 0x4C, -0x4E, 0x62, 0xF2, 0xF3, 0x5A, 0x4A, 0x4F, 0x6D, 0x6B, 0x57, 0x63, 0xED, 0x79, 0x69, 0x62, 0x5D, -0x6C, 0x67, 0x5E, 0xF5, 0xEA, 0x69, 0x63, 0x76, 0xFA, 0x6A, 0x59, 0x5D, 0xFB, 0xF6, 0x72, 0xFB, -0x71, 0x5D, 0x65, 0x7D, 0xFC, 0x79, 0xFB, 0xE9, 0xE2, 0xDD, 0xE3, 0xF9, 0xFA, 0xF3, 0xEA, 0xEC, -0x7D, 0xF1, 0xE5, 0xF2, 0x78, 0x6D, 0x6D, 0xED, 0xE4, 0xE5, 0xE4, 0xF6, 0x7A, 0xF8, 0xE5, 0xDC, -0xEA, 0xDF, 0xCF, 0xD3, 0xE7, 0x6C, 0x78, 0xCF, 0xC9, 0xD5, 0x7E, 0x64, 0x7E, 0xD7, 0xCF, 0xD7, -0xE0, 0xE8, 0xDC, 0xCB, 0xC5, 0xCC, 0xE6, 0x73, 0xE9, 0xD2, 0xC9, 0xCA, 0xD3, 0xED, 0x68, 0xF3, -0xD9, 0xDA, 0xDC, 0xDA, 0xD7, 0xDB, 0xE1, 0xE1, 0xEA, 0x69, 0x59, 0x60, 0xEE, 0xE0, 0xDC, 0xDF, -0xE5, 0xDD, 0xE1, 0xED, 0xED, 0xF4, 0xF6, 0xF2, 0xEE, 0xED, 0xFC, 0x6F, 0x64, 0x5C, 0x5C, 0x61, -0x76, 0xEA, 0xE1, 0xEB, 0x73, 0x66, 0x60, 0x69, 0xFB, 0x7E, 0x70, 0x76, 0xFF, 0x78, 0x73, 0xEB, -0xE2, 0x6F, 0x5C, 0x69, 0xE9, 0xDB, 0xDE, 0x73, 0x5E, 0x6D, 0xED, 0xEB, 0xF4, 0xFF, 0x77, 0xFD, -0xE7, 0xE2, 0xFB, 0x66, 0x69, 0xFE, 0xFA, 0x6B, 0x63, 0x69, 0x74, 0x74, 0x66, 0x63, 0x6F, 0xFB, -0xFD, 0x73, 0x71, 0x7B, 0xF4, 0xE8, 0xE2, 0xE8, 0xF2, 0xEB, 0xDE, 0xDC, 0xDE, 0xE2, 0xE7, 0xE5, -0xDF, 0xDF, 0xE8, 0xFC, 0x6D, 0x6A, 0x66, 0x5C, 0x53, 0x51, 0x56, 0x5B, 0x59, 0x56, 0x56, 0x5A, -0x5E, 0x5A, 0x53, 0x53, 0x59, 0x5D, 0x5F, 0x64, 0x74, 0xE9, 0xD6, 0xCB, 0xCB, 0xD3, 0xDC, 0xD4, -0xC8, 0xC1, 0xBF, 0xBE, 0xBE, 0xC5, 0xCE, 0xDC, 0xEA, 0x68, 0x4B, 0x3E, 0x3B, 0x3B, 0x3D, 0x3E, -0x41, 0x45, 0x47, 0x48, 0x4A, 0x4C, 0x4A, 0x47, 0x49, 0x4F, 0x5E, 0x6D, 0xF5, 0xDB, 0xCC, 0xC5, -0xC1, 0xBF, 0xBE, 0xBC, 0xBA, 0xB7, 0xB2, 0xAF, 0xAE, 0xB7, 0xDA, 0x43, 0x38, 0x35, 0x32, 0x31, -0x33, 0x3A, 0x46, 0x54, 0x5D, 0x56, 0x4A, 0x44, 0x43, 0x46, 0x44, 0x3F, 0x40, 0x4B, 0x61, 0x7B, -0xFD, 0xE7, 0xD4, 0xCA, 0xC5, 0xBF, 0xBB, 0xB6, 0xB1, 0xAF, 0xAD, 0xAC, 0xAC, 0xB4, 0xD8, 0x3C, -0x2D, 0x2B, 0x2D, 0x2F, 0x37, 0x41, 0x54, 0x76, 0xFF, 0x68, 0x54, 0x46, 0x40, 0x44, 0x49, 0x4A, -0x49, 0x4C, 0x5C, 0xFB, 0xE9, 0xE5, 0xDB, 0xCE, 0xC8, 0xC3, 0xBE, 0xBA, 0xB6, 0xB1, 0xAE, 0xAB, -0xA9, 0xAB, 0xBD, 0x3F, 0x2A, 0x26, 0x2A, 0x31, 0x3A, 0x43, 0x58, 0xE9, 0xDB, 0xE8, 0x5E, 0x46, -0x3C, 0x3D, 0x48, 0x55, 0x56, 0x55, 0x61, 0xF3, 0xE8, 0xE6, 0xDC, 0xCF, 0xC9, 0xC0, 0xB9, 0xB4, -0xB3, 0xB3, 0xAF, 0xAA, 0xA8, 0xAF, 0x75, 0x2C, 0x22, 0x24, 0x2D, 0x3F, 0x56, 0x72, 0xE0, 0xCF, -0xD4, 0x59, 0x3F, 0x38, 0x38, 0x3E, 0x4C, 0x68, 0xE8, 0xE3, 0xEA, 0x7E, 0x67, 0x64, 0x79, 0xDC, -0xCB, 0xBF, 0xB7, 0xB1, 0xAF, 0xAE, 0xAC, 0xAA, 0xB1, 0x56, 0x29, 0x1F, 0x20, 0x2B, 0x45, 0xD1, -0xC4, 0xC7, 0xCB, 0xD8, 0x4B, 0x33, 0x2E, 0x34, 0x42, 0x6D, 0xCD, 0xC5, 0xC8, 0xD1, 0xE0, 0x69, -0x52, 0x52, 0x6D, 0xD4, 0xC6, 0xBB, 0xB1, 0xAC, 0xAB, 0xAA, 0xA8, 0xAE, 0x68, 0x28, 0x1D, 0x1E, -0x2B, 0x53, 0xBC, 0xB6, 0xBD, 0xCA, 0xE1, 0x4E, 0x33, 0x2A, 0x2C, 0x3B, 0x7D, 0xBF, 0xBB, 0xC1, -0xD5, 0xED, 0x6A, 0x4F, 0x4C, 0x58, 0x7E, 0xD6, 0xC7, 0xBB, 0xB2, 0xAD, 0xA9, 0xA6, 0xA9, 0xC3, -0x2D, 0x1D, 0x1B, 0x23, 0x41, 0xBC, 0xAF, 0xB5, 0xC2, 0xDE, 0x4F, 0x3B, 0x2D, 0x27, 0x2D, 0x49, -0xC3, 0xB5, 0xB9, 0xCB, 0x64, 0x54, 0x56, 0x51, 0x58, 0x75, 0xE3, 0xD1, 0xCA, 0xC1, 0xB6, 0xAB, -0xA6, 0xA3, 0xA6, 0xC0, 0x2B, 0x1C, 0x1A, 0x24, 0x4D, 0xB0, 0xAA, 0xB0, 0xC3, 0xF0, 0x46, 0x38, -0x2D, 0x28, 0x2B, 0x4C, 0xBC, 0xB2, 0xB6, 0xD1, 0x4B, 0x46, 0x4F, 0x58, 0x61, 0xEE, 0xE1, 0xDB, -0xCF, 0xCB, 0xBD, 0xAE, 0xA7, 0xA3, 0xA2, 0xB6, 0x2C, 0x1B, 0x19, 0x21, 0x52, 0xAB, 0xA5, 0xAE, -0xC9, 0x4F, 0x3B, 0x37, 0x32, 0x2A, 0x2A, 0x3D, 0xC9, 0xB2, 0xB1, 0xCA, 0x44, 0x3D, 0x49, 0x5F, -0xDD, 0xD8, 0x77, 0x6E, 0xED, 0xDB, 0xC7, 0xB7, 0xAB, 0xA5, 0xA3, 0xA6, 0xC8, 0x26, 0x1A, 0x1A, -0x27, 0xC5, 0xA4, 0xA3, 0xAF, 0xE9, 0x3B, 0x33, 0x34, 0x31, 0x2D, 0x31, 0x57, 0xBF, 0xB3, 0xBA, -0x78, 0x41, 0x3E, 0x4E, 0xDC, 0xCE, 0xD4, 0x78, 0x5B, 0x67, 0xDC, 0xC4, 0xB7, 0xAC, 0xA6, 0xA5, -0xA5, 0xBA, 0x2C, 0x1B, 0x19, 0x23, 0xD8, 0xA3, 0x9F, 0xAB, 0xDA, 0x34, 0x2D, 0x30, 0x33, 0x33, -0x37, 0x54, 0xC1, 0xB7, 0xBD, 0x6E, 0x41, 0x3D, 0x4A, 0xD8, 0xCA, 0xD0, 0xEB, 0x56, 0x54, 0x74, -0xCE, 0xBD, 0xAF, 0xA8, 0xA6, 0xA5, 0xAE, 0x3B, 0x1E, 0x19, 0x1E, 0x43, 0xA8, 0x9E, 0xA6, 0xC8, -0x33, 0x29, 0x2C, 0x32, 0x39, 0x3D, 0x4E, 0xCD, 0xBE, 0xC2, 0xFF, 0x40, 0x3D, 0x48, 0xE0, 0xC4, -0xCB, 0xEA, 0x4F, 0x48, 0x59, 0xD7, 0xBE, 0xB5, 0xAD, 0xA9, 0xA9, 0xA7, 0xB3, 0x34, 0x1D, 0x19, -0x20, 0xEE, 0xA2, 0x9D, 0xA8, 0x60, 0x2A, 0x26, 0x2D, 0x3B, 0x4A, 0x4E, 0x64, 0xCE, 0xC6, 0xCF, -0x57, 0x42, 0x47, 0x67, 0xCB, 0xC3, 0xD4, 0x5C, 0x48, 0x47, 0x63, 0xCA, 0xBA, 0xB2, 0xAE, 0xAC, -0xAC, 0xAB, 0xB3, 0x3D, 0x1F, 0x1B, 0x20, 0x51, 0xA5, 0x9E, 0xA8, 0x6C, 0x2A, 0x24, 0x2B, 0x3E, -0x5E, 0x6C, 0x66, 0xFA, 0xE0, 0xE4, 0x60, 0x4B, 0x4E, 0x71, 0xD2, 0xC8, 0xD8, 0x5A, 0x4A, 0x49, -0x6E, 0xC6, 0xB9, 0xB3, 0xB1, 0xAF, 0xAE, 0xAC, 0xAF, 0x48, 0x21, 0x1B, 0x1F, 0x4C, 0xA5, 0x9D, -0xA7, 0x64, 0x28, 0x23, 0x2C, 0x4A, 0xD6, 0xD9, 0x61, 0x59, 0x6C, 0xEF, 0xF8, 0x5B, 0x5B, 0xEE, -0xD5, 0xCD, 0xDB, 0x5C, 0x4D, 0x4C, 0x6E, 0xC8, 0xBB, 0xB8, 0xB8, 0xB6, 0xB3, 0xAD, 0xA8, 0xBC, -0x2D, 0x1D, 0x1B, 0x2B, 0xB7, 0x9F, 0xA1, 0xB9, 0x33, 0x23, 0x28, 0x3A, 0xEB, 0xCF, 0x77, 0x50, -0x56, 0x6E, 0xE2, 0x73, 0x55, 0x5D, 0xE6, 0xCF, 0xD9, 0x5B, 0x4B, 0x47, 0x59, 0xD2, 0xC3, 0xBD, -0xBD, 0xBC, 0xB6, 0xAE, 0xA9, 0xAB, 0x68, 0x24, 0x1B, 0x1E, 0x3C, 0xAA, 0x9E, 0xA6, 0xDE, 0x2A, -0x23, 0x2C, 0x47, 0xD1, 0xCE, 0x72, 0x55, 0x58, 0x6A, 0x78, 0x5D, 0x5B, 0xF9, 0xDA, 0xD3, 0xDE, -0x5A, 0x49, 0x4A, 0x5F, 0xD1, 0xC0, 0xBD, 0xBC, 0xB9, 0xB3, 0xAD, 0xA9, 0xB1, 0x3C, 0x1F, 0x1C, -0x24, 0xE1, 0xA4, 0x9F, 0xAD, 0x44, 0x26, 0x25, 0x32, 0x6E, 0xC3, 0xCD, 0x64, 0x4F, 0x4F, 0x62, -0x70, 0x5C, 0x68, 0xE1, 0xD4, 0xD3, 0xF6, 0x4E, 0x45, 0x4B, 0x78, 0xCA, 0xBE, 0xBC, 0xBC, 0xB8, -0xB3, 0xAC, 0xA9, 0xBC, 0x2F, 0x1E, 0x1C, 0x2A, 0xBC, 0xA0, 0xA1, 0xB7, 0x35, 0x24, 0x28, 0x3B, -0xD8, 0xC4, 0xDC, 0x53, 0x4B, 0x4F, 0x67, 0x6D, 0x65, 0xEA, 0xDB, 0xD5, 0xDA, 0x5E, 0x4B, 0x48, -0x53, 0xDB, 0xC4, 0xBD, 0xBD, 0xBB, 0xB5, 0xAE, 0xA8, 0xAB, 0x75, 0x25, 0x1B, 0x1E, 0x3D, 0xAA, -0x9E, 0xA6, 0xDC, 0x2B, 0x25, 0x2E, 0x4E, 0xCC, 0xCC, 0x66, 0x4B, 0x4C, 0x5A, 0x74, 0x6C, 0x6D, -0xDF, 0xD6, 0xD6, 0xED, 0x4D, 0x43, 0x46, 0x59, 0xD0, 0xBF, 0xBC, 0xBB, 0xB8, 0xB3, 0xAD, 0xA9, -0xB3, 0x38, 0x1E, 0x1B, 0x24, 0xCF, 0xA2, 0x9F, 0xAF, 0x3E, 0x26, 0x27, 0x36, 0x6A, 0xCD, 0xE6, -0x4F, 0x4D, 0x55, 0x6E, 0xEF, 0x63, 0x7B, 0xDA, 0xDB, 0xDF, 0x5F, 0x49, 0x47, 0x4F, 0xE8, 0xC5, -0xBD, 0xBC, 0xBB, 0xB6, 0xAF, 0xAA, 0xAA, 0xCD, 0x29, 0x1C, 0x1D, 0x34, 0xAE, 0x9F, 0xA4, 0xC7, -0x2E, 0x25, 0x2C, 0x41, 0xDB, 0xD2, 0x75, 0x5B, 0x59, 0x60, 0x6E, 0x5B, 0x5C, 0xDF, 0xD0, 0xD8, -0x74, 0x4B, 0x43, 0x4B, 0x6E, 0xCC, 0xBF, 0xBD, 0xBE, 0xBC, 0xB5, 0xAD, 0xA8, 0xAD, 0x4B, 0x22, -0x1C, 0x22, 0x65, 0xA6, 0x9F, 0xAC, 0x4C, 0x2A, 0x28, 0x33, 0x50, 0xDE, 0xF2, 0x65, 0x7C, 0xF8, -0x79, 0x5A, 0x4B, 0x5E, 0xD7, 0xCF, 0xD6, 0x5F, 0x45, 0x43, 0x4C, 0xFB, 0xC9, 0xBF, 0xBD, 0xBC, -0xB8, 0xB2, 0xAD, 0xAA, 0xB7, 0x38, 0x20, 0x1D, 0x29, 0xC6, 0xA5, 0xA4, 0xB8, 0x3C, 0x2A, 0x2C, -0x39, 0x53, 0x7F, 0x6F, 0x79, 0xE8, 0xF9, 0x61, 0x4D, 0x4B, 0xFF, 0xD0, 0xD3, 0xEC, 0x4F, 0x45, -0x49, 0x58, 0xDF, 0xC7, 0xBF, 0xBD, 0xBB, 0xB5, 0xAF, 0xA9, 0xAA, 0xCA, 0x2C, 0x1D, 0x1E, 0x36, -0xB1, 0xA2, 0xA8, 0xCE, 0x33, 0x2B, 0x30, 0x3E, 0x4F, 0x5A, 0x6D, 0xD8, 0xD2, 0xF5, 0x4F, 0x46, -0x54, 0xD4, 0xCA, 0xD7, 0x65, 0x48, 0x43, 0x4C, 0x61, 0xD7, 0xC4, 0xBF, 0xBD, 0xB7, 0xB1, 0xAD, -0xAA, 0xB0, 0x48, 0x23, 0x1D, 0x24, 0x5D, 0xAA, 0xA4, 0xB0, 0x56, 0x30, 0x2E, 0x34, 0x3E, 0x47, -0x52, 0xE3, 0xC9, 0xCE, 0x65, 0x45, 0x43, 0x6A, 0xCE, 0xCD, 0xDE, 0x58, 0x49, 0x49, 0x4F, 0x6D, -0xD1, 0xC0, 0xBB, 0xB6, 0xAF, 0xAE, 0xAA, 0xAB, 0xCF, 0x2B, 0x1D, 0x1E, 0x36, 0xB2, 0xA4, 0xA9, -0xC7, 0x3B, 0x2F, 0x31, 0x37, 0x3D, 0x46, 0x6E, 0xC7, 0xC5, 0xE5, 0x4C, 0x41, 0x50, 0xD5, 0xCB, -0xDF, 0x58, 0x4C, 0x49, 0x4E, 0x62, 0xE4, 0xC8, 0xBD, 0xB9, 0xB4, 0xAF, 0xAD, 0xA9, 0xB2, 0x41, -0x22, 0x1D, 0x26, 0xEB, 0xAA, 0xA6, 0xB3, 0x5D, 0x38, 0x32, 0x32, 0x34, 0x39, 0x4D, 0xCC, 0xBD, -0xC7, 0x60, 0x44, 0x47, 0x6D, 0xDC, 0xE2, 0xEF, 0x63, 0x58, 0x50, 0x4D, 0x5A, 0xDB, 0xC3, 0xBA, -0xB3, 0xAF, 0xAD, 0xAC, 0xAE, 0xD3, 0x2D, 0x1F, 0x20, 0x38, 0xB9, 0xA9, 0xAD, 0xC4, 0x4C, 0x39, -0x33, 0x30, 0x32, 0x3C, 0xFA, 0xBE, 0xBE, 0xD5, 0x51, 0x46, 0x4F, 0x6F, 0x7B, 0x65, 0x68, 0x76, -0x60, 0x54, 0x52, 0x61, 0xCF, 0xBF, 0xB7, 0xAE, 0xAC, 0xAB, 0xAB, 0xBC, 0x39, 0x22, 0x1E, 0x2B, -0xE7, 0xAF, 0xAC, 0xB6, 0xD1, 0x4E, 0x3A, 0x2F, 0x2D, 0x31, 0x45, 0xCC, 0xBC, 0xC2, 0xDA, 0x58, -0x4D, 0x55, 0x52, 0x52, 0x68, 0xED, 0xF4, 0x66, 0x55, 0x59, 0xEF, 0xCE, 0xBF, 0xB5, 0xAD, 0xAB, -0xAB, 0xAE, 0xCC, 0x31, 0x22, 0x22, 0x2F, 0xE8, 0xB6, 0xB1, 0xB8, 0xC4, 0x73, 0x3D, 0x2F, 0x2B, -0x2F, 0x3F, 0xDD, 0xC0, 0xBF, 0xC7, 0xD8, 0x73, 0x55, 0x46, 0x44, 0x53, 0x7B, 0xEE, 0xED, 0xF2, -0xED, 0xDC, 0xCF, 0xC1, 0xB3, 0xAC, 0xA9, 0xA9, 0xB2, 0x58, 0x2C, 0x24, 0x28, 0x36, 0x5C, 0xC7, -0xBA, 0xB6, 0xB7, 0xCA, 0x49, 0x34, 0x2D, 0x2E, 0x37, 0x49, 0xE0, 0xC4, 0xBD, 0xBE, 0xC7, 0xEA, -0x4C, 0x42, 0x44, 0x49, 0x50, 0x69, 0xDD, 0xD0, 0xCB, 0xC6, 0xBD, 0xB3, 0xAD, 0xAB, 0xAB, 0xBA, -0x49, 0x2F, 0x2B, 0x2D, 0x32, 0x3A, 0x4B, 0xD6, 0xBC, 0xB6, 0xBD, 0xD7, 0x51, 0x3D, 0x36, 0x34, -0x37, 0x3E, 0x52, 0xDE, 0xC8, 0xC3, 0xC7, 0xCE, 0xDE, 0x72, 0x56, 0x4F, 0x53, 0x5D, 0xFF, 0xDA, -0xC9, 0xBD, 0xB7, 0xB4, 0xB2, 0xB6, 0xC6, 0x62, 0x47, 0x3F, 0x3D, 0x3B, 0x3B, 0x40, 0x4E, 0x6F, -0xEC, 0x7B, 0x67, 0x5E, 0x5B, 0x59, 0x55, 0x5A, 0x65, 0x5E, 0x5A, 0x5F, 0x61, 0x5E, 0x63, 0x65, -0x61, 0x6D, 0xF5, 0xFA, 0x7A, 0x77, 0x77, 0xFF, 0xEB, 0xDC, 0xD5, 0xCE, 0xCA, 0xC8, 0xC8, 0xCD, -0xD9, 0xEC, 0x76, 0x70, 0xFD, 0xED, 0xEA, 0xEE, 0x7D, 0x66, 0x59, 0x53, 0x50, 0x4F, 0x50, 0x54, -0x56, 0x58, 0x59, 0x5A, 0x5A, 0x5C, 0x5F, 0x6B, 0xF6, 0xE5, 0xE1, 0xE7, 0xEF, 0xF5, 0xF2, 0xEA, -0xDF, 0xD8, 0xCE, 0xC8, 0xC4, 0xC5, 0xCB, 0xD4, 0xDF, 0xE9, 0xE7, 0xE1, 0xDD, 0xDB, 0xDE, 0xEE, -0x68, 0x57, 0x4F, 0x4D, 0x4D, 0x4E, 0x4F, 0x4F, 0x52, 0x54, 0x53, 0x51, 0x53, 0x57, 0x5E, 0x6F, -0xFA, 0xEF, 0xEF, 0xF3, 0xF1, 0xF1, 0xEE, 0xE6, 0xDE, 0xD6, 0xCF, 0xCD, 0xCE, 0xD3, 0xDA, 0xDC, -0xDF, 0xDF, 0xD9, 0xD5, 0xD4, 0xD7, 0xE0, 0xFE, 0x6B, 0x5F, 0x5A, 0x58, 0x56, 0x54, 0x54, 0x53, -0x53, 0x50, 0x4E, 0x4F, 0x52, 0x56, 0x5C, 0x64, 0x67, 0x66, 0x69, 0x6C, 0x6D, 0x74, 0xFA, 0xEC, -0xDF, 0xD7, 0xD6, 0xDD, 0xE6, 0xF3, 0x7B, 0xF7, 0xE8, 0xDC, 0xD3, 0xD0, 0xD2, 0xD9, 0xE1, 0xE7, -0xEB, 0xF6, 0x7B, 0x74, 0x6F, 0x6B, 0x66, 0x5E, 0x59, 0x55, 0x53, 0x52, 0x56, 0x59, 0x5C, 0x61, -0x5F, 0x64, 0x65, 0x62, 0x6F, 0x7B, 0xFC, 0xE4, 0xDC, 0xD9, 0xE2, 0x7E, 0xFF, 0xFE, 0xFF, 0xEE, -0xDF, 0xD8, 0xD6, 0xD7, 0xDB, 0xDD, 0xDD, 0xE8, 0xE7, 0xE3, 0xEA, 0xE7, 0xF9, 0x72, 0x7C, 0x5F, -0x56, 0x58, 0x58, 0x56, 0x57, 0x57, 0x53, 0x54, 0x4A, 0x42, 0x4F, 0x67, 0x6A, 0xE0, 0xD4, 0xD8, -0xD7, 0xDD, 0xFD, 0xFE, 0xE4, 0x7B, 0xFF, 0xD9, 0xDF, 0xDE, 0xD7, 0xDA, 0xCF, 0xCF, 0xD3, 0xCD, -0xD3, 0xDF, 0xDD, 0xDE, 0xF3, 0x6D, 0x5F, 0x55, 0x54, 0x55, 0x51, 0x51, 0x50, 0x4F, 0x51, 0x53, -0x57, 0x59, 0x60, 0x73, 0xFB, 0xE7, 0xE1, 0xEA, 0xF4, 0x7D, 0x6D, 0x6F, 0x7F, 0x78, 0xF5, 0xE7, -0xEA, 0xE0, 0xDE, 0xD9, 0xCD, 0xCB, 0xC5, 0xC2, 0xC5, 0xCB, 0xDB, 0xDD, 0xEC, 0x53, 0x4C, 0x45, -0x42, 0x49, 0x48, 0x49, 0x4D, 0x51, 0x5A, 0x55, 0x55, 0x5D, 0x64, 0xF4, 0xED, 0xF5, 0xEB, 0xF2, -0x7A, 0x6D, 0x60, 0x5E, 0x6E, 0xF3, 0xF7, 0xE9, 0xDF, 0xDD, 0xD4, 0xCD, 0xC8, 0xC1, 0xBC, 0xB8, -0xB5, 0xB8, 0xC7, 0xF5, 0x52, 0x3E, 0x38, 0x37, 0x36, 0x3D, 0x4B, 0x59, 0xFD, 0xDF, 0xE3, 0xFE, -0x5C, 0x54, 0x52, 0x4E, 0x50, 0x55, 0x5D, 0xFF, 0xF2, 0xF1, 0xE9, 0xFB, 0xFD, 0x74, 0x5E, 0x62, -0x7A, 0xE3, 0xD2, 0xCA, 0xC0, 0xB9, 0xB1, 0xAD, 0xAE, 0xBC, 0x68, 0x3E, 0x31, 0x2D, 0x2E, 0x30, -0x3B, 0x5B, 0xD4, 0xC7, 0xC9, 0xD6, 0x65, 0x4A, 0x46, 0x3E, 0x3D, 0x47, 0x51, 0x7F, 0xD5, 0xD0, -0xCE, 0xD2, 0xE2, 0x6E, 0x57, 0x55, 0x61, 0xEA, 0xCD, 0xBE, 0xB7, 0xB2, 0xAD, 0xAB, 0xB0, 0xCE, -0x40, 0x2F, 0x2B, 0x2D, 0x2F, 0x38, 0x59, 0xCA, 0xBD, 0xBE, 0xCF, 0x70, 0x45, 0x39, 0x3A, 0x3B, -0x3F, 0x5D, 0xD9, 0xCB, 0xC4, 0xC5, 0xCF, 0xEA, 0x62, 0x52, 0x50, 0x5C, 0x7E, 0xD1, 0xBE, 0xB5, -0xAF, 0xAE, 0xAB, 0xAC, 0xC2, 0x44, 0x2F, 0x2A, 0x2D, 0x32, 0x38, 0x55, 0xC6, 0xBA, 0xBC, 0xCF, -0x5B, 0x40, 0x36, 0x34, 0x38, 0x40, 0x66, 0xCD, 0xC4, 0xC2, 0xC6, 0xD1, 0xFE, 0x52, 0x4C, 0x4F, -0x5C, 0xEF, 0xCF, 0xC1, 0xB7, 0xAF, 0xAD, 0xAB, 0xAD, 0xC9, 0x3C, 0x2D, 0x29, 0x2D, 0x35, 0x3D, -0xF1, 0xBD, 0xB8, 0xBF, 0xE1, 0x4C, 0x3C, 0x32, 0x31, 0x39, 0x47, 0xF7, 0xCB, 0xC4, 0xC2, 0xC7, -0xD9, 0x6F, 0x54, 0x4D, 0x4F, 0x5D, 0xEF, 0xCF, 0xC1, 0xB8, 0xAF, 0xAD, 0xAB, 0xAC, 0xC9, 0x3A, -0x2C, 0x29, 0x2D, 0x37, 0x44, 0xD8, 0xB9, 0xB7, 0xC4, 0x6C, 0x44, 0x38, 0x31, 0x30, 0x39, 0x4E, -0xDF, 0xCA, 0xC5, 0xC6, 0xCD, 0xEF, 0x5E, 0x5A, 0x53, 0x55, 0x64, 0xE8, 0xCD, 0xC4, 0xBB, 0xB0, -0xAC, 0xAA, 0xAC, 0xD0, 0x36, 0x2C, 0x2B, 0x2E, 0x39, 0x4A, 0xCB, 0xB6, 0xB7, 0xC8, 0x5D, 0x43, -0x39, 0x31, 0x32, 0x3D, 0x58, 0xD9, 0xCD, 0xCA, 0xC9, 0xD6, 0x73, 0x62, 0x63, 0x62, 0x68, 0x72, -0xE9, 0xCE, 0xC6, 0xBB, 0xAF, 0xAD, 0xAB, 0xAE, 0xD7, 0x38, 0x2D, 0x2C, 0x2F, 0x3B, 0x4F, 0xCA, -0xB6, 0xB8, 0xCB, 0x5D, 0x41, 0x39, 0x32, 0x33, 0x3E, 0x59, 0xDC, 0xCF, 0xCD, 0xCB, 0xD8, 0x63, -0x53, 0x5A, 0x5E, 0x61, 0x6F, 0xEA, 0xCF, 0xC6, 0xBC, 0xB0, 0xAD, 0xAB, 0xAE, 0xEE, 0x32, 0x2C, -0x2C, 0x30, 0x3B, 0x50, 0xC9, 0xB6, 0xB9, 0xCF, 0x5D, 0x47, 0x3A, 0x32, 0x33, 0x3F, 0x63, 0xDB, -0xD5, 0xCC, 0xC8, 0xD7, 0x66, 0x56, 0x58, 0x5C, 0x5A, 0x5B, 0x7E, 0xCE, 0xC4, 0xBB, 0xB0, 0xAD, -0xAB, 0xAF, 0x7B, 0x2F, 0x2C, 0x2E, 0x31, 0x39, 0x52, 0xC6, 0xB6, 0xBA, 0xD1, 0x5C, 0x4E, 0x3E, -0x32, 0x33, 0x3F, 0x64, 0xEA, 0xFD, 0xCE, 0xC2, 0xD0, 0x6C, 0x57, 0x5D, 0x64, 0x56, 0x53, 0x6C, -0xCE, 0xC4, 0xBD, 0xB1, 0xAD, 0xAA, 0xAE, 0x6F, 0x31, 0x2F, 0x31, 0x31, 0x37, 0x4F, 0xC5, 0xB6, -0xBA, 0xD2, 0xFC, 0x60, 0x45, 0x36, 0x35, 0x41, 0x56, 0xF8, 0xF2, 0xE4, 0xC6, 0xC8, 0x7C, 0x5A, -0x6A, 0x6A, 0x57, 0x52, 0x5B, 0xDA, 0xC6, 0xC0, 0xB6, 0xAE, 0xAA, 0xAC, 0xDD, 0x33, 0x30, 0x35, -0x31, 0x30, 0x42, 0xCE, 0xBA, 0xBA, 0xCC, 0xD9, 0xD9, 0x53, 0x3A, 0x35, 0x3E, 0x4D, 0x52, 0x60, -0xD6, 0xC5, 0xD2, 0x71, 0xE7, 0x7C, 0x55, 0x53, 0x51, 0x5B, 0xEE, 0xDC, 0xD3, 0xBE, 0xB2, 0xB0, -0xAD, 0xAE, 0x67, 0x31, 0x38, 0x39, 0x2F, 0x32, 0x49, 0xD5, 0xBE, 0xBF, 0xCF, 0xCD, 0xCA, 0x5C, -0x3D, 0x3C, 0x41, 0x41, 0x47, 0x5D, 0xE1, 0xC9, 0xC7, 0xD4, 0xDD, 0xFC, 0x51, 0x4C, 0x4C, 0x4C, -0x5F, 0xE2, 0xDC, 0xCA, 0xBF, 0xBD, 0xB9, 0xB5, 0xAF, 0xBA, 0x43, 0x35, 0x44, 0x3E, 0x2F, 0x36, -0x53, 0xD4, 0xC8, 0xCC, 0xD1, 0xC3, 0xC5, 0x5E, 0x41, 0x45, 0x49, 0x42, 0x44, 0x55, 0xE9, 0xD0, -0xD1, 0xDA, 0xD6, 0xD7, 0xFD, 0x5A, 0x58, 0x5B, 0x5A, 0x5B, 0x5F, 0x6C, 0x7A, 0xE1, 0xD3, 0xD2, -0xCC, 0xC8, 0xC4, 0xBF, 0xBD, 0xBA, 0xC2, 0x49, 0x3C, 0x4C, 0x41, 0x35, 0x3B, 0x52, 0xF3, 0xD6, -0xD1, 0xCE, 0xC3, 0xC6, 0x7A, 0x53, 0x57, 0x4E, 0x44, 0x46, 0x4F, 0x64, 0xE8, 0xDF, 0xDD, 0xD4, -0xD6, 0xEC, 0x56, 0x49, 0x54, 0x5E, 0x4F, 0x57, 0xFA, 0xE1, 0xDC, 0xE0, 0xE3, 0xD6, 0xD0, 0xDC, -0xD9, 0xC9, 0xC2, 0xBD, 0xC5, 0x58, 0x50, 0xE6, 0x4B, 0x37, 0x3F, 0x4F, 0x4D, 0x52, 0x6D, 0xDD, -0xC8, 0xC8, 0xDC, 0xDC, 0xD1, 0x72, 0x4A, 0x4A, 0x4E, 0x4B, 0x4E, 0x57, 0x6A, 0xDF, 0xD7, 0xDB, -0xD5, 0xCF, 0xDA, 0xF4, 0x74, 0x67, 0x5E, 0x5E, 0x5E, 0x66, 0xF9, 0xED, 0xEC, 0xE8, 0xE4, 0xE8, -0xF4, 0xF7, 0x60, 0x52, 0x6D, 0xF3, 0x5B, 0x66, 0xE7, 0xE1, 0xE0, 0xDF, 0xDF, 0xD8, 0xD1, 0xEA, -0x6B, 0xD9, 0xD1, 0xE5, 0xE6, 0xCC, 0xC4, 0xE7, 0x52, 0xEA, 0xE4, 0x4C, 0x48, 0x59, 0x5D, 0x59, -0x5D, 0x60, 0xF7, 0xDF, 0x79, 0x6A, 0xDF, 0xDC, 0xFE, 0xF8, 0xE2, 0xF0, 0x6F, 0x6B, 0x61, 0x5F, -0x62, 0x5D, 0x5E, 0x6C, 0x76, 0x70, 0xF7, 0xE5, 0xE6, 0xE7, 0xE5, 0xEA, 0xF4, 0x7D, 0x6C, 0x66, -0x68, 0x66, 0x66, 0x73, 0xF8, 0xF3, 0xF4, 0xF6, 0xFB, 0x7E, 0x7A, 0x7E, 0xF6, 0xEF, 0xED, 0xE9, -0xE9, 0xEF, 0xFB, 0x78, 0x6E, 0x69, 0x64, 0x63, 0x68, 0x6E, 0x74, 0x7B, 0xFA, 0xF6, 0xF3, 0xFF, -0x6B, 0x69, 0x69, 0x60, 0x5F, 0x65, 0x6C, 0x73, 0x7C, 0xF3, 0xEB, 0xE9, 0xEA, 0xE8, 0xE6, 0xE6, -0xE7, 0xE4, 0xDE, 0xDD, 0xE2, 0xE2, 0xE1, 0xE9, 0xF8, 0x77, 0x6B, 0x62, 0x5D, 0x5B, 0x5A, 0x59, -0x5A, 0x5B, 0x5D, 0x5E, 0x5E, 0x5E, 0x5F, 0x62, 0x67, 0x6D, 0x78, 0xFA, 0xF2, 0xEE, 0xEF, 0xF3, -0xF7, 0xF8, 0xFA, 0xFE, 0xFA, 0xF3, 0xF1, 0xEF, 0xEA, 0xE7, 0xE5, 0xE6, 0xE9, 0xEF, 0xFB, 0x79, -0x70, 0x6C, 0x6A, 0x6C, 0x6F, 0x77, 0x7C, 0xFD, 0xFB, 0x7F, 0x73, 0x6C, 0x69, 0x69, 0x6C, 0x73, -0xFA, 0xED, 0xE9, 0xE5, 0xE1, 0xE4, 0xE8, 0xE8, 0xE7, 0xE7, 0xE5, 0xE2, 0xE0, 0xDD, 0xDC, 0xE1, -0xE3, 0xE2, 0xEC, 0x7C, 0x6C, 0x63, 0x5D, 0x5B, 0x59, 0x58, 0x5A, 0x5B, 0x5B, 0x5C, 0x5F, 0x60, -0x5F, 0x60, 0x65, 0x6A, 0x75, 0xF8, 0xEC, 0xE7, 0xE6, 0xE7, 0xEA, 0xF0, 0xF8, 0xF9, 0xF4, 0xED, -0xE9, 0xE5, 0xE3, 0xE3, 0xE6, 0xEB, 0xF6, 0x76, 0x6C, 0x67, 0x62, 0x5F, 0x61, 0x64, 0x69, 0x6F, -0x73, 0x73, 0x75, 0x75, 0x70, 0x6E, 0x6F, 0x6E, 0x6E, 0x75, 0xFE, 0xF3, 0xEC, 0xE9, 0xE9, 0xE9, -0xED, 0xFA, 0x7A, 0x74, 0x71, 0x72, 0x73, 0x74, 0x7A, 0xFF, 0xFF, 0x7B, 0x72, 0x6E, 0x6D, 0x6C, -0x6C, 0x6E, 0x73, 0x7C, 0xFC, 0xF7, 0xF0, 0xEB, 0xE6, 0xE0, 0xDD, 0xDB, 0xDB, 0xDB, 0xDC, 0xDF, -0xE2, 0xE3, 0xE8, 0xF2, 0x7D, 0x6C, 0x61, 0x5D, 0x5A, 0x58, 0x59, 0x5C, 0x5E, 0x61, 0x66, 0x69, -0x6A, 0x6B, 0x6C, 0x6B, 0x6C, 0x75, 0xFE, 0xF7, 0xEE, 0xEA, 0xE8, 0xE6, 0xE9, 0xEC, 0xEB, 0xEB, -0xEE, 0xF0, 0xF2, 0xF6, 0xF9, 0xFD, 0x7F, 0xFF, 0x7C, 0x74, 0x6D, 0x69, 0x66, 0x64, 0x64, 0x68, -0x6B, 0x6D, 0x75, 0x7D, 0xFC, 0xF8, 0xFA, 0xFC, 0xFA, 0xF7, 0xF5, 0xF0, 0xEB, 0xE6, 0xE4, 0xE5, -0xE9, 0xED, 0xF2, 0xFC, 0x7A, 0x74, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x6E, -0x6D, 0x6E, 0x70, 0x71, 0x74, 0x79, 0x7B, 0x7E, 0xFB, 0xF6, 0xF8, 0xF9, 0xF6, 0xF5, 0xF8, 0xFA, -0xF7, 0xF0, 0xEE, 0xF0, 0xF7, 0xFC, 0x7D, 0x73, 0x6C, 0x6B, 0x6B, 0x6A, 0x6B, 0x6B, 0x6B, 0x6B, -0x6C, 0x6D, 0x6D, 0x6E, 0x71, 0x71, 0x71, 0x72, 0x77, 0x7D, 0xFC, 0xF7, 0xF3, 0xED, 0xEB, 0xEB, -0xEE, 0xF4, 0xF9, 0xFE, 0x79, 0x77, 0x7B, 0x7F, 0x7F, 0xFF, 0xFF, 0x7B, 0x77, 0x76, 0x77, 0x79, -0x79, 0x7A, 0x7C, 0xFF, 0xFC, 0xFC, 0xFA, 0xF8, 0xF9, 0xF9, 0xFA, 0xFD, 0xFE, 0xFD, 0xFA, 0xF8, -0xF5, 0xF2, 0xF1, 0xF2, 0xF4, 0xF8, 0xFE, 0x7C, 0x79, 0x77, 0x77, 0x7A, 0x7E, 0x7F, 0x7C, 0x79, -0x78, 0x75, 0x73, 0x72, 0x71, 0x73, 0x75, 0x76, 0x78, 0x7D, 0xFD, 0xFB, 0xFC, 0xFF, 0x7D, 0x79, -0x76, 0x76, 0x77, 0x7C, 0xFB, 0xF5, 0xF3, 0xF3, 0xF3, 0xF7, 0x7D, 0x74, 0x6F, 0x6D, 0x6B, 0x6C, -0x6E, 0x73, 0x77, 0x77, 0x77, 0x7A, 0x7A, 0x76, 0x73, 0x72, 0x6F, 0x6D, 0x6B, 0x6C, 0x6F, 0x76, -0x7A, 0x7D, 0xFE, 0xFC, 0x7E, 0x7A, 0x75, 0x71, 0x6E, 0x6D, 0x6E, 0x71, 0x77, 0x7D, 0xFE, 0xFC, -0xFC, 0xFE, 0xFF, 0x7D, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFC, 0xF9, 0xF7, 0xF6, 0xF8, 0xFA, 0xFC, -0xFF, 0x7E, 0x7F, 0xFF, 0xFD, 0xFB, 0xF7, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFD, 0x7D, 0x7A, 0x7A, -0x7D, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFD, 0xFD, -0xFB, 0xF8, 0xF7, 0xF9, 0xFD, 0x7C, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x75, 0x75, 0x75, 0x75, -0x75, 0x74, 0x76, 0x78, 0x79, 0x7B, 0x7D, 0x7F, 0xFD, 0xFB, 0xFF, 0x7A, 0x79, 0x7D, 0xFE, 0xFD, -0xFD, 0xFC, 0xFD, 0xFA, 0xF5, 0xF2, 0xF3, 0xF6, 0xF8, 0xF9, 0xFC, 0xFF, 0xFD, 0xF8, 0xF5, 0xF5, -0xF6, 0xFA, 0xFC, 0xFD, 0x7F, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x77, 0x7B, 0x7E, 0x7E, 0x7E, 0x7F, -0x7E, 0x7C, 0x79, 0x76, 0x76, 0x78, 0x79, 0x78, 0x7B, 0x7E, 0xFF, 0x7F, 0x7C, 0x7A, 0x78, 0x75, -0x73, 0x73, 0x74, 0x76, 0x77, 0x78, 0x7B, 0x7B, 0x79, 0x79, 0x78, 0x77, 0x78, 0x74, 0x71, 0x72, -0x73, 0x76, 0x77, 0x77, 0x79, 0x79, 0x77, 0x76, 0x75, 0x76, 0x78, 0x7B, 0x7F, 0xFC, 0xFB, 0xFB, -0xFA, 0xFB, 0xFE, 0x7C, 0x79, 0x79, 0x78, 0x78, 0x7B, 0xFF, 0xFD, 0xFD, 0xFC, 0xFC, 0xFE, 0x7E, -0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7B, 0x77, 0x78, 0x7A, -0x7A, 0x7A, 0x7C, 0x7E, 0xFF, 0x7F, 0x7F, 0xFF, 0xFF, 0x7F, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, -0x79, 0x79, 0x7B, 0x7E, 0x7E, 0x7F, 0xFD, 0xFC, 0xFD, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, -0xFF, 0x7E, 0x7D, 0x7F, 0xFF, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFE, 0x7E, 0x7F, 0x7E, 0x7B, -0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x77, 0x7A, -0x7C, 0x7D, 0x7E, 0x7E, 0x7C, 0x79, 0x76, 0x77, 0x79, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, -0x7D, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7B, 0x7C, -0x7C, 0x7C, 0x7D, 0xFF, 0xFC, 0xFB, 0xFB, 0xFC, 0xFF, 0x7C, 0x79, 0x77, 0x74, 0x75, 0x77, 0x7A, -0x7D, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7B, 0x7A, 0x7B, 0x7D, 0x7E, 0xFE, 0xFD, -0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x78, 0x76, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7C, -0x7A, 0x79, 0x78, 0x78, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7B, 0x7A, -0x7B, 0x7C, 0x7D, 0xFE, 0xFC, 0xFA, 0xF9, 0xFA, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFA, 0xF8, 0xF7, -0xF6, 0xF7, 0xF9, 0xFB, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x79, 0x7B, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, -0x7E, 0x7C, 0x7B, 0x79, 0x7A, 0x7C, 0x7C, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7E, 0x7C, 0x7B, 0x79, -0x77, 0x76, 0x76, 0x78, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7B, -0x7D, 0x79, 0x79, 0x7E, 0x79, 0x78, 0x79, 0x78, 0x7A, 0x78, 0x7D, 0x7D, 0x7C, 0xFF, 0x7D, 0x7F, -0x7E, 0x7B, 0x7A, 0x76, 0x79, 0x76, 0x78, 0x7B, 0x79, 0xFF, 0x7D, 0xFB, 0xFD, 0x7D, 0xF9, 0x7B, -0xFF, 0x79, 0x75, 0xFF, 0x6E, 0x7F, 0x71, 0x73, 0x79, 0x51, 0x60, 0xE2, 0x6F, 0x7D, 0xF7, 0xF5, -0x77, 0x72, 0xE4, 0x50, 0x4C, 0xDE, 0xFB, 0x66, 0xE5, 0xF6, 0x6F, 0x6C, 0xE7, 0xDC, 0x6E, 0xFD, -0xE6, 0x7E, 0xE9, 0x77, 0x62, 0xE3, 0xE9, 0x6C, 0x71, 0xEA, 0xDE, 0x75, 0x7E, 0xE8, 0x75, 0xF8, -0x7A, 0xFC, 0xF2, 0x65, 0xF8, 0xEE, 0xF9, 0xF4, 0x73, 0xE4, 0xF9, 0x6E, 0xE5, 0x75, 0x67, 0x5A, -0x50, 0x57, 0x5A, 0x7D, 0x6C, 0x64, 0xDA, 0xED, 0x64, 0xEA, 0xE9, 0xF5, 0x7E, 0x6F, 0xFC, 0xF2, -0x66, 0x63, 0xF7, 0x7D, 0x78, 0xF6, 0xF8, 0xE1, 0xE2, 0xF9, 0xEB, 0xE4, 0xED, 0xFE, 0xFA, 0xF6, -0xF1, 0xF2, 0x6F, 0xFE, 0xE8, 0xFF, 0x7F, 0xEA, 0xE8, 0xED, 0xEE, 0xEA, 0xEB, 0xED, 0xF8, 0xEF, -0xE8, 0x7F, 0xF5, 0xE6, 0xF7, 0xF2, 0xF3, 0xF2, 0xDF, 0xEB, 0xF5, 0xE3, 0xEC, 0xF2, 0xEF, 0xFC, -0xED, 0xEF, 0xFD, 0xED, 0xF0, 0x7C, 0x77, 0xFE, 0xF1, 0x77, 0x79, 0xEF, 0xF6, 0xF8, 0xFB, 0x72, -0x75, 0x79, 0x78, 0x70, 0x6E, 0x7C, 0x7D, 0x74, 0x79, 0x77, 0x6E, 0x71, 0x7D, 0x6F, 0x6B, 0x7D, -0xFE, 0x76, 0x7A, 0x7D, 0x7F, 0x75, 0x6C, 0x7B, 0xF7, 0x7A, 0x7B, 0x7E, 0x74, 0x79, 0x75, 0x70, -0x7C, 0x79, 0xFD, 0xF6, 0x6E, 0x6E, 0x7B, 0x6B, 0x67, 0x6D, 0x6E, 0x6A, 0x67, 0x6A, 0x6D, 0x6F, -0x6B, 0x67, 0x6D, 0x6C, 0x65, 0x63, 0x5E, 0x65, 0x6A, 0x5F, 0x68, 0x6C, 0x60, 0x6C, 0x7D, 0x6D, -0x6E, 0x7D, 0x7C, 0xFF, 0xEE, 0xEB, 0xEC, 0xE3, 0xDE, 0xE1, 0xE4, 0xE0, 0xE8, 0xF8, 0xEE, 0xFA, -0x6D, 0x69, 0x5C, 0x58, 0x59, 0x53, 0x50, 0x4E, 0x4D, 0x4E, 0x4F, 0x4F, 0x53, 0x51, 0x51, 0x54, -0x55, 0x56, 0x5A, 0x5E, 0x69, 0xF7, 0xE2, 0xD8, 0xCF, 0xCE, 0xCD, 0xCC, 0xCE, 0xCE, 0xCA, 0xC7, -0xC2, 0xBF, 0xBE, 0xBD, 0xC2, 0xD5, 0xF1, 0x62, 0x4B, 0x3F, 0x3D, 0x3D, 0x3E, 0x40, 0x42, 0x4A, -0x51, 0x51, 0x51, 0x55, 0x56, 0x4F, 0x4D, 0x4E, 0x50, 0x52, 0x55, 0x5C, 0x69, 0xFA, 0xE4, 0xD9, -0xCD, 0xC9, 0xC5, 0xC1, 0xBF, 0xBB, 0xBB, 0xBD, 0xB9, 0xB7, 0xB5, 0xB7, 0xC8, 0xDD, 0x61, 0x43, -0x3C, 0x38, 0x38, 0x3D, 0x40, 0x46, 0x4E, 0x5A, 0x60, 0x5D, 0x5B, 0x5B, 0x5A, 0x58, 0x56, 0x58, -0x5C, 0x5E, 0x5E, 0x64, 0x6B, 0x6D, 0xF9, 0xED, 0xE5, 0xDC, 0xD9, 0xD2, 0xCC, 0xC5, 0xBF, 0xBF, -0xBA, 0xB7, 0xB6, 0xB1, 0xB7, 0xCB, 0xFA, 0x49, 0x3A, 0x35, 0x31, 0x33, 0x3A, 0x42, 0x4C, 0x5C, -0xFD, 0xE1, 0xEE, 0x68, 0x66, 0x5C, 0x51, 0x4F, 0x4D, 0x55, 0x5F, 0x5D, 0x64, 0x71, 0xFA, 0xED, -0xEF, 0xEB, 0xDE, 0xD3, 0xCC, 0xC3, 0xBE, 0xBD, 0xB9, 0xB8, 0xB5, 0xAF, 0xB7, 0xCC, 0x60, 0x3F, -0x39, 0x34, 0x2F, 0x31, 0x3A, 0x47, 0x56, 0x6F, 0xE3, 0xDA, 0xD5, 0xEC, 0x56, 0x50, 0x4E, 0x4B, -0x4B, 0x4C, 0x57, 0x7B, 0xE7, 0xE0, 0xDC, 0xD5, 0xD6, 0xDE, 0xEC, 0xEF, 0xDE, 0xD7, 0xCC, 0xC1, -0xBD, 0xB8, 0xB5, 0xB4, 0xB0, 0xB6, 0xCB, 0x58, 0x3E, 0x38, 0x34, 0x2F, 0x2F, 0x38, 0x45, 0x59, -0x7D, 0xDD, 0xD1, 0xCE, 0xDD, 0x63, 0x53, 0x4E, 0x4C, 0x4A, 0x4B, 0x53, 0x69, 0xE7, 0xDB, 0xD5, -0xD0, 0xCE, 0xD3, 0xDC, 0xE4, 0xEA, 0xE8, 0xE2, 0xD5, 0xC8, 0xC0, 0xBB, 0xB8, 0xB5, 0xB2, 0xB9, -0xD1, 0x54, 0x40, 0x3A, 0x34, 0x2F, 0x2F, 0x36, 0x3F, 0x4C, 0x5B, 0x7E, 0xDE, 0xD4, 0xDB, 0xFF, -0x62, 0x58, 0x55, 0x53, 0x4F, 0x52, 0x5D, 0x6F, 0xF0, 0xE4, 0xDE, 0xDA, 0xD8, 0xDC, 0xE1, 0xE5, -0xDF, 0xDC, 0xD6, 0xCC, 0xC6, 0xC1, 0xBE, 0xBB, 0xB8, 0xBC, 0xCE, 0x67, 0x4B, 0x44, 0x3E, 0x38, -0x35, 0x37, 0x3D, 0x45, 0x4B, 0x53, 0x61, 0xFA, 0xE4, 0xEC, 0x7F, 0x79, 0x78, 0x79, 0x70, 0x68, -0x68, 0x70, 0x7B, 0x7D, 0x7D, 0xF9, 0xEE, 0xEA, 0xE8, 0xE6, 0xE1, 0xDB, 0xD6, 0xCF, 0xCB, 0xC8, -0xC5, 0xC1, 0xBE, 0xBF, 0xC7, 0xD5, 0xF9, 0x5F, 0x55, 0x4A, 0x42, 0x3E, 0x3E, 0x41, 0x45, 0x48, -0x4C, 0x56, 0x5F, 0x6F, 0xF8, 0xEF, 0xE7, 0xE4, 0xE6, 0xE2, 0xEA, 0xF5, 0xFD, 0x75, 0x75, 0x79, -0x75, 0x76, 0x7E, 0xFA, 0xF1, 0xE9, 0xE0, 0xDA, 0xD3, 0xCF, 0xCC, 0xCA, 0xC7, 0xC4, 0xC5, 0xCC, -0xD3, 0xDF, 0xFF, 0x69, 0x58, 0x4C, 0x47, 0x43, 0x42, 0x42, 0x43, 0x46, 0x4C, 0x55, 0x59, 0x62, -0x77, 0xFD, 0xEE, 0xEC, 0xF3, 0xEC, 0xF2, 0x76, 0x76, 0x6F, 0x6E, 0x79, 0x79, 0x7F, 0xF3, 0xED, -0xE4, 0xDD, 0xDB, 0xD7, 0xD3, 0xD0, 0xCE, 0xCC, 0xCB, 0xCA, 0xCC, 0xD1, 0xD6, 0xDD, 0xEA, 0x7E, -0x62, 0x56, 0x4F, 0x4C, 0x49, 0x48, 0x49, 0x4C, 0x50, 0x56, 0x58, 0x5C, 0x67, 0x6F, 0x6C, 0x6E, -0x6D, 0x6A, 0x6F, 0x6D, 0x6B, 0x6E, 0x6D, 0x76, 0xFA, 0xF9, 0xF1, 0xEB, 0xE7, 0xE1, 0xDE, 0xDD, -0xDB, 0xD8, 0xD7, 0xD4, 0xD2, 0xD0, 0xCF, 0xD4, 0xD8, 0xDA, 0xDF, 0xEA, 0xF8, 0x6D, 0x60, 0x5C, -0x58, 0x56, 0x56, 0x56, 0x57, 0x59, 0x5B, 0x5B, 0x5A, 0x5C, 0x5F, 0x5F, 0x5F, 0x63, 0x66, 0x6B, -0x72, 0x77, 0x7E, 0xF7, 0xF0, 0xEC, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xEA, 0xE7, 0xE6, 0xE5, -0xE3, 0xE1, 0xDD, 0xDA, 0xD9, 0xD8, 0xDD, 0xDF, 0xDD, 0xE0, 0xE7, 0xEE, 0xFE, 0x74, 0x6C, 0x62, -0x5C, 0x59, 0x56, 0x54, 0x52, 0x51, 0x51, 0x52, 0x55, 0x58, 0x59, 0x5D, 0x62, 0x68, 0x70, 0x75, -0x7D, 0xF9, 0xF8, 0xF4, 0xF5, 0xF9, 0xF5, 0xF3, 0xF3, 0xF2, 0xF2, 0xEF, 0xED, 0xEB, 0xEA, 0xE6, -0xE3, 0xE0, 0xDC, 0xDA, 0xD7, 0xD8, 0xDB, 0xDB, 0xDA, 0xDC, 0xDF, 0xE8, 0xF6, 0x7F, 0x6E, 0x60, -0x5B, 0x58, 0x56, 0x54, 0x53, 0x52, 0x53, 0x59, 0x5C, 0x5E, 0x63, 0x68, 0x6F, 0x7B, 0x7C, 0xFF, -0xFC, 0xFC, 0xFB, 0xFC, 0xFD, 0xF8, 0xF7, 0xF6, 0xF4, 0xF5, 0xF3, 0xF0, 0xEF, 0xED, 0xEB, 0xE8, -0xE4, 0xE0, 0xDD, 0xDA, 0xD9, 0xDA, 0xDC, 0xDC, 0xDC, 0xE0, 0xE9, 0xF8, 0x76, 0x6B, 0x61, 0x5C, -0x5A, 0x5A, 0x5A, 0x5B, 0x5C, 0x5E, 0x62, 0x67, 0x6B, 0x6D, 0x6F, 0x72, 0x75, 0x76, 0x76, 0x75, -0x74, 0x79, 0x7E, 0x7B, 0x78, 0x7D, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF5, 0xF2, 0xEF, 0xEC, 0xE9, -0xE4, 0xDF, 0xDE, 0xDE, 0xE0, 0xE7, 0xEA, 0xEC, 0xF2, 0xFE, 0x76, 0x6F, 0x6F, 0x6D, 0x6A, 0x6A, -0x6B, 0x6C, 0x6C, 0x69, 0x67, 0x67, 0x66, 0x65, 0x64, 0x64, 0x65, 0x66, 0x67, 0x69, 0x6B, 0x6E, -0x71, 0x76, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF4, 0xF0, 0xEE, 0xEC, 0xEA, 0xE9, 0xE8, 0xE9, -0xEB, 0xEB, 0xEC, 0xED, 0xEE, 0xED, 0xEB, 0xE9, 0xEA, 0xE9, 0xE9, 0xEA, 0xEC, 0xF0, 0xF6, 0xFD, -0x78, 0x71, 0x6D, 0x69, 0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x66, 0x66, 0x67, 0x67, 0x66, 0x66, -0x69, 0x6B, 0x6D, 0x73, 0x7A, 0xFE, 0xF7, 0xF3, 0xEF, 0xEE, 0xEE, 0xEC, 0xEB, 0xEA, 0xE8, 0xE7, -0xE5, 0xE3, 0xE1, 0xE1, 0xE1, 0xE3, 0xE6, 0xE8, 0xEB, 0xEF, 0xF8, 0x7E, 0x75, 0x6F, 0x6B, 0x69, -0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, -0x70, 0x6F, 0x6F, 0x6F, 0x72, 0x75, 0x79, 0xFF, 0xFB, 0xF6, 0xF2, 0xEF, 0xEE, 0xED, 0xEE, 0xF0, -0xF3, 0xF6, 0xF8, 0xFC, 0xFF, 0x7D, 0x79, 0x76, 0x72, 0x6E, 0x6D, 0x6B, 0x6B, 0x6C, 0x6C, 0x6D, -0x6E, 0x71, 0x76, 0x7B, 0xFF, 0xFE, 0xFD, 0xFC, 0xFD, 0x7F, 0x7B, 0x78, 0x75, 0x74, 0x75, 0x77, -0x7A, 0x7E, 0xFC, 0xF9, 0xF6, 0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xF8, 0xF7, 0xF6, 0xF5, 0xF5, -0xF6, 0xF8, 0xFA, 0xFC, 0x7F, 0x7B, 0x79, 0x78, 0x77, 0x77, 0x79, 0x7D, 0xFD, 0xF9, 0xF4, 0xF2, -0xF1, 0xF1, 0xF3, 0xF5, 0xFA, 0xFE, 0x7F, 0xFF, 0xFD, 0xFC, 0xFB, 0xF7, 0xF5, 0xF4, 0xF4, 0xF6, -0xF8, 0xFB, 0xFD, 0xFF, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7B, 0x79, 0x77, -0x76, 0x75, 0x74, 0x74, 0x75, 0x78, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0x7E, 0x7C, 0x7B, 0x79, -0x79, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xF9, 0xFB, 0xFD, 0x7F, 0x7B, 0x78, 0x76, 0x75, -0x74, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x7A, 0x7C, -0x7E, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x78, 0x77, 0x77, 0x76, 0x79, 0x7B, 0x7E, 0xFF, -0xFE, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7C, 0x7B, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x74, 0x74, -0x74, 0x74, 0x75, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFC, 0xF8, 0xF7, 0xF6, 0xF7, 0xF7, 0xF7, 0xF9, -0xFC, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7F, 0xFF, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, -0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xFA, 0xFD, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7D, 0x7E, 0xFE, -0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF9, 0xF9, 0xFA, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x79, 0x77, 0x75, -0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x71, 0x70, 0x71, 0x72, 0x71, 0x72, 0x71, 0x72, 0x73, 0x72, -0x72, 0x71, 0x71, 0x71, 0x72, 0x74, 0x74, 0x76, 0x77, 0x77, 0x77, 0x78, 0x77, 0x78, 0x78, 0x78, -0x7A, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, -0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7C, 0x7E, 0xFF, 0xFD, -0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7D, -0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, -0xFF, 0xFF, 0xFF, 0xFD, 0xFA, 0xF9, 0xF7, 0xF5, 0xF4, 0xF3, 0xF1, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, -0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFE, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, -0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7A, 0x7D, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, -0x77, 0x76, 0x75, 0x76, 0x75, 0x74, 0x74, 0x75, 0x74, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, 0x74, -0x72, 0x70, 0x70, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x70, 0x70, 0x70, 0x71, 0x72, 0x73, 0x73, 0x76, -0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7F, 0x7D, 0x7C, 0x7B, 0x7B, 0x7C, -0x7B, 0x7B, 0x7A, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0xFF, 0x7D, 0x7E, 0x7C, 0x7C, 0x7B, 0x78, -0x7C, 0x7A, 0x7C, 0x7D, 0x7B, 0x7E, 0x7C, 0x7F, 0x7D, 0x7A, 0x7E, 0x78, 0x7B, 0x6F, 0x68, 0x5C, -0x4C, 0x58, 0xDD, 0xE1, 0xEB, 0xE1, 0xE9, 0xEF, 0xF8, 0xE9, 0xE1, 0xED, 0xF9, 0xFC, 0xF2, 0xED, -0x7D, 0x76, 0xFB, 0xF9, 0x7C, 0x70, 0x6F, 0x78, 0x79, 0x6D, 0x6D, 0x76, 0x7D, 0xFE, 0x7A, 0x79, -0xFC, 0xFD, 0xFD, 0xFA, 0xFB, 0xFA, 0xFC, 0xFF, 0xFC, 0xFC, 0xFE, 0xFD, 0xFE, 0xFB, 0xFB, 0xFE, -0xFE, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x78, 0x7D, 0x7D, 0xFF, 0xFA, 0xFF, 0xF9, 0xF9, 0xFA, 0xF7, -0x7F, 0xF9, 0x7A, 0x7A, 0x6F, 0x51, 0x52, 0x6E, 0x71, 0xF1, 0xD8, 0xD3, 0xDB, 0xEF, 0xE2, 0xDB, -0xED, 0xF6, 0xF3, 0xEF, 0xF4, 0x6A, 0x74, 0x73, 0x57, 0x5E, 0x77, 0x6E, 0xFD, 0xF4, 0xFC, 0x7D, -0x73, 0xE9, 0xDE, 0xE2, 0xDE, 0xE3, 0xE5, 0xE8, 0xFA, 0xF7, 0xFA, 0x6F, 0x6C, 0x6A, 0x6B, 0x6A, -0x66, 0x6B, 0x75, 0x70, 0x74, 0xFA, 0xFB, 0xFD, 0xF8, 0xF3, 0xF2, 0xFB, 0xF5, 0xED, 0xEF, 0xEB, -0xE5, 0xDF, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD4, 0xD8, 0xE0, 0xEE, 0x76, 0x5D, 0x53, 0x4D, 0x49, -0x46, 0x43, 0x42, 0x43, 0x43, 0x45, 0x48, 0x4B, 0x4F, 0x57, 0x60, 0x6D, 0xF7, 0xE3, 0xDB, 0xD4, -0xCF, 0xCB, 0xC8, 0xC4, 0xBE, 0xBC, 0xB9, 0xB4, 0xB6, 0xBC, 0xC1, 0xC3, 0xD5, 0x4F, 0x4B, 0x43, -0x36, 0x33, 0x34, 0x32, 0x31, 0x36, 0x3B, 0x3F, 0x48, 0x60, 0xDF, 0xD2, 0xC9, 0xC1, 0xC3, 0xC6, -0xC7, 0xCF, 0xE3, 0x67, 0x56, 0x47, 0x3E, 0x3F, 0x3C, 0x3B, 0x43, 0x48, 0x4F, 0xFA, 0xD5, 0xC5, -0xBD, 0xB7, 0xB1, 0xAE, 0xAC, 0xAE, 0xB1, 0xB5, 0xC0, 0xD7, 0x5D, 0x40, 0x38, 0x31, 0x2E, 0x2D, -0x2C, 0x2E, 0x32, 0x37, 0x3F, 0x4F, 0xF8, 0xD0, 0xC4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBE, 0xC7, 0xD0, -0xF1, 0x56, 0x48, 0x40, 0x3D, 0x3B, 0x3D, 0x42, 0x49, 0x63, 0xDA, 0xCB, 0xBC, 0xB6, 0xB0, 0xAE, -0xAF, 0xAF, 0xB4, 0xBC, 0xC6, 0xFE, 0x4C, 0x3E, 0x34, 0x30, 0x2E, 0x2D, 0x2E, 0x30, 0x35, 0x3C, -0x46, 0x62, 0xDE, 0xCA, 0xBE, 0xBD, 0xBB, 0xBA, 0xBD, 0xC3, 0xCB, 0xDC, 0x6B, 0x59, 0x51, 0x52, -0x60, 0xFF, 0xD5, 0xC4, 0xBE, 0xBC, 0xBA, 0xB9, 0xBB, 0xC3, 0xC8, 0xD6, 0x5A, 0x4C, 0x42, 0x39, -0x36, 0x35, 0x32, 0x34, 0x36, 0x39, 0x41, 0x47, 0x58, 0xE0, 0xDA, 0xC9, 0xC1, 0xC4, 0xC0, 0xC0, -0xC6, 0xCA, 0xD1, 0xDC, 0xF3, 0x6E, 0xFC, 0xE8, 0xDB, 0xCB, 0xC2, 0xBE, 0xBD, 0xBE, 0xBD, 0xC0, -0xCD, 0xCE, 0xEC, 0x4E, 0x4C, 0x40, 0x38, 0x39, 0x37, 0x35, 0x38, 0x38, 0x3B, 0x43, 0x49, 0x54, -0xEA, 0xDB, 0xCE, 0xC5, 0xC5, 0xC3, 0xC1, 0xC7, 0xCA, 0xCF, 0xDB, 0xE9, 0xFD, 0xF7, 0xE9, 0xDD, -0xCE, 0xC6, 0xC1, 0xBF, 0xC0, 0xBF, 0xC3, 0xCF, 0xD0, 0xE6, 0x51, 0x4E, 0x43, 0x3A, 0x3B, 0x38, -0x35, 0x38, 0x38, 0x3A, 0x3F, 0x44, 0x4E, 0x5F, 0xEF, 0xD7, 0xCD, 0xC8, 0xC6, 0xC4, 0xC6, 0xC9, -0xCC, 0xD4, 0xDD, 0xE6, 0xE1, 0xDA, 0xD7, 0xCA, 0xC3, 0xC4, 0xC4, 0xC1, 0xC3, 0xCC, 0xCF, 0xD8, -0x60, 0x54, 0x4E, 0x3F, 0x3D, 0x3D, 0x39, 0x3A, 0x3C, 0x3B, 0x3D, 0x47, 0x48, 0x51, 0x79, 0xFA, -0xDD, 0xCD, 0xCF, 0xCC, 0xC8, 0xCD, 0xCE, 0xCE, 0xD7, 0xDC, 0xDC, 0xD7, 0xD4, 0xCC, 0xC3, 0xC1, -0xBF, 0xBF, 0xC2, 0xC1, 0xCE, 0xDB, 0xDD, 0x54, 0x4C, 0x49, 0x3C, 0x3B, 0x3B, 0x38, 0x3A, 0x3B, -0x3C, 0x3E, 0x48, 0x4C, 0x55, 0xF3, 0xEC, 0xDB, 0xCD, 0xD1, 0xCD, 0xCB, 0xD2, 0xD1, 0xD6, 0xDD, -0xE1, 0xE2, 0xD7, 0xD3, 0xCA, 0xC0, 0xBE, 0xBE, 0xBF, 0xBE, 0xC1, 0xCF, 0xD0, 0xED, 0x4E, 0x4D, -0x41, 0x3A, 0x3A, 0x37, 0x35, 0x38, 0x3A, 0x3A, 0x3F, 0x49, 0x4A, 0x62, 0xE7, 0xEA, 0xCE, 0xCB, -0xCF, 0xC8, 0xCB, 0xD1, 0xCF, 0xD7, 0xE2, 0xE5, 0xE5, 0xDF, 0xD5, 0xCC, 0xC5, 0xBE, 0xBE, 0xC0, -0xBC, 0xC0, 0xCD, 0xC8, 0xDC, 0x58, 0x5B, 0x47, 0x3C, 0x3D, 0x39, 0x36, 0x39, 0x3A, 0x39, 0x3E, -0x47, 0x49, 0x59, 0xEA, 0xEC, 0xD0, 0xC9, 0xCD, 0xC7, 0xC8, 0xCE, 0xCD, 0xD2, 0xDC, 0xDF, 0xDF, -0xDD, 0xD6, 0xCB, 0xC6, 0xBF, 0xBF, 0xC4, 0xBD, 0xC4, 0xD1, 0xC9, 0xEF, 0x55, 0x5D, 0x43, 0x3D, -0x3E, 0x38, 0x37, 0x3A, 0x3A, 0x3A, 0x3E, 0x45, 0x48, 0x56, 0x74, 0xF8, 0xD8, 0xCF, 0xD0, 0xCB, -0xCB, 0xCE, 0xCE, 0xD2, 0xD9, 0xDC, 0xDC, 0xD7, 0xD3, 0xCA, 0xC4, 0xC0, 0xBF, 0xC2, 0xBE, 0xC3, -0xCF, 0xCB, 0xE5, 0x58, 0x5C, 0x45, 0x3D, 0x3E, 0x39, 0x37, 0x39, 0x3A, 0x3A, 0x3D, 0x45, 0x46, -0x52, 0x79, 0x73, 0xD7, 0xCD, 0xD1, 0xC8, 0xC8, 0xCD, 0xCA, 0xCF, 0xD5, 0xD7, 0xDC, 0xDA, 0xD4, -0xCD, 0xC7, 0xC1, 0xC0, 0xC5, 0xBF, 0xC2, 0xD1, 0xCA, 0xDA, 0x5A, 0x68, 0x4C, 0x3E, 0x42, 0x3B, -0x38, 0x3B, 0x3A, 0x3A, 0x3D, 0x42, 0x44, 0x4B, 0x62, 0x66, 0xF1, 0xD0, 0xD6, 0xCD, 0xC8, 0xCE, -0xCA, 0xCB, 0xD1, 0xCF, 0xD2, 0xD2, 0xCE, 0xC9, 0xC5, 0xC1, 0xBF, 0xC5, 0xC1, 0xC0, 0xD3, 0xCE, -0xD6, 0x57, 0x5F, 0x4E, 0x3E, 0x41, 0x3D, 0x39, 0x3B, 0x3B, 0x3A, 0x3D, 0x42, 0x44, 0x4C, 0x5A, -0x5E, 0xEC, 0xDD, 0xDC, 0xCE, 0xD0, 0xD1, 0xCD, 0xD4, 0xD4, 0xD4, 0xDA, 0xD3, 0xCE, 0xCB, 0xC4, -0xBF, 0xBE, 0xC2, 0xBE, 0xBF, 0xCD, 0xCB, 0xD5, 0x5B, 0x5F, 0x4D, 0x3E, 0x3F, 0x3B, 0x37, 0x39, -0x3A, 0x39, 0x3C, 0x3F, 0x42, 0x4B, 0x59, 0x61, 0xEA, 0xDA, 0xD6, 0xCD, 0xCD, 0xCE, 0xCD, 0xCF, -0xD3, 0xD6, 0xDA, 0xD7, 0xD2, 0xCE, 0xC7, 0xC2, 0xBF, 0xC0, 0xC1, 0xBE, 0xC8, 0xCE, 0xCB, 0x79, -0x5A, 0x5C, 0x41, 0x3F, 0x3E, 0x38, 0x39, 0x3A, 0x39, 0x3A, 0x3E, 0x42, 0x45, 0x51, 0x62, 0x65, -0xDD, 0xD5, 0xD7, 0xCA, 0xCC, 0xCE, 0xCA, 0xCE, 0xD0, 0xCF, 0xCF, 0xCD, 0xC9, 0xC4, 0xBF, 0xBD, -0xBE, 0xBF, 0xBD, 0xC5, 0xCE, 0xCB, 0xF8, 0x58, 0x5B, 0x43, 0x3E, 0x3E, 0x39, 0x38, 0x3A, 0x39, -0x3A, 0x3E, 0x44, 0x45, 0x51, 0x6E, 0x69, 0xDC, 0xCF, 0xD7, 0xCA, 0xCB, 0xD0, 0xCC, 0xD1, 0xD5, -0xD5, 0xD5, 0xCF, 0xCB, 0xC5, 0xBF, 0xBC, 0xBD, 0xBF, 0xBB, 0xC3, 0xCC, 0xC8, 0xEF, 0x5B, 0x5D, -0x41, 0x3D, 0x3D, 0x37, 0x37, 0x38, 0x37, 0x38, 0x3B, 0x41, 0x43, 0x4E, 0x6B, 0x67, 0xDC, 0xCE, -0xD4, 0xC9, 0xC8, 0xCE, 0xCA, 0xCE, 0xD5, 0xD4, 0xD5, 0xD3, 0xCE, 0xC7, 0xC3, 0xBE, 0xBE, 0xC3, -0xBD, 0xC2, 0xD0, 0xC9, 0xDE, 0x57, 0x61, 0x47, 0x3D, 0x3F, 0x39, 0x36, 0x38, 0x38, 0x38, 0x3A, -0x41, 0x40, 0x48, 0x6A, 0x5C, 0xF7, 0xCD, 0xDB, 0xCD, 0xC6, 0xD1, 0xCC, 0xCC, 0xD6, 0xD5, 0xD3, -0xCF, 0xCE, 0xC6, 0xC0, 0xBF, 0xBE, 0xBF, 0xBE, 0xC0, 0xCC, 0xCB, 0xDB, 0x5D, 0x5B, 0x49, 0x3E, -0x3E, 0x39, 0x37, 0x38, 0x38, 0x38, 0x3B, 0x40, 0x42, 0x4A, 0x63, 0x66, 0xE5, 0xCE, 0xD0, 0xCA, -0xC7, 0xCA, 0xCA, 0xCC, 0xCE, 0xD1, 0xCF, 0xCC, 0xCC, 0xC4, 0xBF, 0xBF, 0xBE, 0xC0, 0xBE, 0xC2, -0xCE, 0xCC, 0xE2, 0x58, 0x59, 0x47, 0x3D, 0x3D, 0x39, 0x37, 0x39, 0x39, 0x39, 0x3C, 0x40, 0x44, -0x4D, 0x5D, 0x6F, 0xE0, 0xD4, 0xCF, 0xCC, 0xCB, 0xCB, 0xCD, 0xCF, 0xCF, 0xD4, 0xD1, 0xCC, 0xCA, -0xC4, 0xBF, 0xBD, 0xBF, 0xBF, 0xBE, 0xC7, 0xCF, 0xCE, 0x79, 0x52, 0x51, 0x41, 0x3C, 0x3B, 0x38, -0x36, 0x38, 0x39, 0x38, 0x3D, 0x44, 0x44, 0x55, 0x70, 0x76, 0xD5, 0xCF, 0xCF, 0xC9, 0xCB, 0xCB, -0xCD, 0xD1, 0xD1, 0xD9, 0xD2, 0xCD, 0xCD, 0xC4, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xC9, 0xCF, 0xD0, -0x6A, 0x53, 0x4F, 0x3F, 0x3C, 0x3B, 0x38, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x56, 0x75, -0xE7, 0xD7, 0xCD, 0xCB, 0xCA, 0xC9, 0xCA, 0xCD, 0xCE, 0xCF, 0xD3, 0xCE, 0xCA, 0xC7, 0xC0, 0xBE, -0xBE, 0xBF, 0xBF, 0xC1, 0xCD, 0xD2, 0xDB, 0x5C, 0x4F, 0x4A, 0x3E, 0x3C, 0x3B, 0x39, 0x38, 0x3A, -0x3A, 0x3C, 0x43, 0x46, 0x4E, 0x71, 0x7A, 0xDD, 0xCE, 0xD0, 0xCB, 0xCA, 0xCD, 0xCC, 0xD1, 0xD2, -0xD5, 0xD7, 0xCC, 0xCC, 0xC7, 0xBE, 0xBF, 0xBF, 0xBE, 0xC0, 0xC6, 0xCD, 0xD5, 0xEE, 0x54, 0x4D, -0x45, 0x3C, 0x3B, 0x39, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x59, 0x71, 0xE8, 0xD4, 0xCE, -0xCC, 0xC9, 0xCB, 0xCB, 0xCE, 0xD2, 0xD4, 0xD7, 0xD2, 0xCD, 0xCB, 0xC4, 0xBF, 0xBF, 0xC0, 0xC0, -0xC0, 0xC9, 0xD1, 0xD8, 0x73, 0x52, 0x4B, 0x42, 0x3C, 0x3A, 0x39, 0x38, 0x38, 0x39, 0x3C, 0x3F, -0x41, 0x4E, 0x5D, 0x63, 0xDF, 0xD3, 0xD1, 0xCD, 0xCB, 0xCC, 0xD1, 0xD1, 0xD3, 0xDE, 0xDA, 0xD1, -0xCF, 0xCC, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, 0xD2, 0xE3, 0x63, 0x4F, 0x4A, 0x42, 0x3C, -0x3B, 0x3A, 0x39, 0x3A, 0x3B, 0x3F, 0x42, 0x47, 0x5A, 0x62, 0x7C, 0xD5, 0xD2, 0xCF, 0xCC, 0xCD, -0xCE, 0xD5, 0xD6, 0xD9, 0xE0, 0xD9, 0xD2, 0xCE, 0xCB, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, -0xD4, 0xE2, 0x67, 0x4F, 0x4B, 0x43, 0x3D, 0x3C, 0x3B, 0x3B, 0x3B, 0x3C, 0x42, 0x43, 0x49, 0x60, -0x6B, 0xF5, 0xD4, 0xD2, 0xD0, 0xD2, 0xD2, 0xD4, 0xDF, 0xDD, 0xDF, 0xEA, 0xDC, 0xD5, 0xD0, 0xCB, -0xC4, 0xC0, 0xC2, 0xBF, 0xC0, 0xC7, 0xC9, 0xD0, 0xDD, 0x7A, 0x57, 0x52, 0x48, 0x3F, 0x3F, 0x3D, -0x3C, 0x3C, 0x3D, 0x42, 0x44, 0x49, 0x5B, 0x64, 0x7C, 0xDE, 0xDB, 0xDB, 0xDC, 0xDA, 0xDF, 0xEE, -0xE9, 0xE6, 0xE8, 0xE3, 0xDB, 0xD0, 0xCD, 0xCC, 0xC5, 0xC3, 0xC5, 0xC2, 0xC3, 0xC8, 0xCD, 0xD1, -0xDE, 0x6F, 0x5B, 0x50, 0x4A, 0x44, 0x40, 0x3F, 0x3E, 0x3E, 0x42, 0x43, 0x47, 0x4F, 0x58, 0x5F, -0x69, 0xF6, 0xED, 0xF7, 0xEB, 0xE8, 0xEA, 0xEC, 0xE8, 0xE0, 0xE0, 0xDD, 0xD7, 0xD0, 0xCE, 0xCC, -0xC8, 0xC7, 0xC6, 0xC4, 0xC8, 0xC9, 0xCB, 0xD2, 0xDA, 0xEF, 0x71, 0x5B, 0x4F, 0x4E, 0x49, 0x45, -0x46, 0x45, 0x47, 0x47, 0x4A, 0x4E, 0x4E, 0x54, 0x5A, 0x5D, 0x62, 0x65, 0x70, 0x6C, 0x69, 0xFA, -0x7A, 0x7A, 0xE6, 0xE2, 0xDF, 0xDA, 0xD5, 0xCF, 0xD1, 0xD1, 0xCB, 0xCE, 0xD4, 0xCE, 0xD1, 0xD9, -0xDB, 0xE0, 0xE1, 0xEE, 0x6A, 0x74, 0x6C, 0x5A, 0x5B, 0x5A, 0x56, 0x56, 0x53, 0x56, 0x57, 0x53, -0x57, 0x5B, 0x59, 0x59, 0x5D, 0x65, 0x60, 0x61, 0x6F, 0x73, 0xF7, 0xEF, 0xEA, 0xDD, 0xDF, 0xDC, -0xD5, 0xD8, 0xDC, 0xDC, 0xDA, 0xDF, 0xE5, 0xE1, 0xEB, 0xED, 0xED, 0xFC, 0xFF, 0x70, 0x6C, 0x6C, -0x66, 0x5F, 0x5F, 0x62, 0x5F, 0x60, 0x60, 0x5A, 0x5F, 0x64, 0x5C, 0x64, 0x6E, 0x5F, 0x5E, 0x69, -0x6B, 0x7B, 0xF0, 0xFA, 0xE9, 0xE4, 0xE8, 0xDF, 0xE6, 0xEB, 0xE1, 0xE2, 0xE6, 0xE3, 0xE8, 0xED, -0xE5, 0xFC, 0x71, 0xE9, 0xFE, 0x7A, 0xEC, 0x73, 0x7E, 0x77, 0x64, 0xFD, 0x74, 0x66, 0x7B, 0x6C, -0x6B, 0x72, 0x6A, 0x79, 0x73, 0x71, 0xF4, 0x79, 0xFC, 0xEF, 0xF9, 0xEB, 0xF1, 0xF0, 0xE2, 0xE3, -0xE0, 0xE2, 0xE3, 0xEB, 0xFC, 0xEA, 0xF8, 0x6F, 0x70, 0x69, 0x77, 0x6C, 0x6D, 0xEF, 0x6B, 0x67, -0x6D, 0x65, 0x76, 0x75, 0x6F, 0x7E, 0x69, 0x67, 0x6F, 0x68, 0x6F, 0x73, 0x68, 0x69, 0x68, 0x69, -0x75, 0xFA, 0xEE, 0xF2, 0xEA, 0xDE, 0xE2, 0xE7, 0xE5, 0xEB, 0xF3, 0xED, 0xE8, 0xF7, 0x7F, 0xFA, -0x74, 0x6A, 0x68, 0x65, 0x66, 0x68, 0x64, 0x65, 0x68, 0x64, 0x6D, 0x77, 0x72, 0x70, 0x69, 0x77, -0x78, 0x64, 0x6B, 0x68, 0x60, 0x66, 0x67, 0x67, 0x61, 0x6D, 0xEB, 0xE8, 0xEC, 0xEB, 0xEA, 0xF7, -0xF5, 0xE2, 0xE5, 0xF6, 0xF8, 0xF0, 0x7E, 0x77, 0xFA, 0x76, 0x77, 0x7D, 0x6E, 0x74, 0x74, 0x72, -0x72, 0x6D, 0x75, 0x74, 0x74, 0x75, 0x76, 0xEF, 0xEE, 0xEF, 0xEA, 0xFA, 0x7F, 0xF2, 0xF6, 0xF7, -0xEF, 0xEA, 0xE4, 0xE5, 0xE7, 0xE3, 0xE9, 0xEC, 0xE8, 0xEB, 0xF0, 0xF8, 0xFC, 0x7F, 0x73, 0x73, -0x70, 0x72, 0x75, 0x69, 0x67, 0x6A, 0x6C, 0x6D, 0x6C, 0x70, 0x6D, 0x6D, 0x78, 0x72, 0x6F, 0x6E, -0x6C, 0x6F, 0x77, 0xF7, 0xEF, 0xF1, 0xF6, 0xF4, 0xF1, 0xFC, 0xF8, 0xEE, 0xF0, 0xEE, 0xEF, 0xEF, -0xEC, 0xEE, 0xF3, 0xF4, 0x76, 0x69, 0x77, 0xFA, 0x70, 0x75, 0x7E, 0x6E, 0x6D, 0x6E, 0x6E, 0x6E, -0x6D, 0x70, 0x74, 0x79, 0xFE, 0x7D, 0x78, 0x7C, 0x7A, 0x75, 0x78, 0x75, 0x70, 0x7C, 0xFC, 0xFB, -0xF4, 0xF3, 0xED, 0xEC, 0xF6, 0xF1, 0xEF, 0xF6, 0xF0, 0xFB, 0x7A, 0x7C, 0x74, 0x79, 0x74, 0x6C, -0x6C, 0x63, 0x67, 0x6C, 0x62, 0x66, 0x67, 0x68, 0x6C, 0x6A, 0x7D, 0x78, 0x6B, 0x7B, 0x71, 0x75, -0xFB, 0x75, 0x76, 0x7E, 0xEE, 0xED, 0xFA, 0xE8, 0xEE, 0x7F, 0xE4, 0xE9, 0xED, 0xE1, 0xEC, 0xEE, -0xE6, 0xF6, 0xFE, 0xF7, 0xFF, 0x7B, 0x72, 0x7C, 0x7F, 0x6B, 0x6C, 0x66, 0x67, 0x71, 0x66, 0x72, -0xFF, 0x69, 0x7B, 0xF7, 0xFF, 0xF3, 0xF6, 0xF3, 0xF2, 0xEE, 0xED, 0xFF, 0xF6, 0xED, 0xFB, 0xF2, -0xE9, 0xF0, 0xEC, 0xE6, 0xF4, 0xF2, 0xF5, 0x7C, 0xED, 0x7E, 0x6B, 0x7B, 0x77, 0xFE, 0x7A, 0x69, -0x68, 0x60, 0x65, 0x66, 0x61, 0x71, 0x74, 0x74, 0xFC, 0x7E, 0xFA, 0xFF, 0x7E, 0xF9, 0xFB, 0xEE, -0xED, 0xEF, 0xEF, 0xF4, 0xEC, 0xEC, 0xF2, 0xF0, 0xEF, 0xED, 0xF4, 0xF6, 0xEF, 0xFD, 0xF8, 0xF1, -0x77, 0x74, 0x7A, 0x70, 0x6F, 0x79, 0x76, 0x6A, 0x68, 0x6C, 0x6C, 0x69, 0x65, 0x66, 0x6E, 0x73, -0x6C, 0x6D, 0x7A, 0x79, 0x7A, 0xFE, 0x73, 0x72, 0x7A, 0x7E, 0xF3, 0xEF, 0xEE, 0xF1, 0xF6, 0xEC, -0xEF, 0xFA, 0xEE, 0xF5, 0xFE, 0xF2, 0xF0, 0xF7, 0xFA, 0xF9, 0xFB, 0xFB, 0x7A, 0x6B, 0x6B, 0x72, -0x6C, 0x6A, 0x76, 0x74, 0x6E, 0x72, 0x6C, 0x6B, 0x6F, 0x6B, 0x6E, 0x71, 0x6D, 0x75, 0x76, 0x70, -0x78, 0x7C, 0xFA, 0xF2, 0xF7, 0xF1, 0xED, 0xF3, 0xF4, 0xF6, 0xFA, 0xF0, 0xEF, 0xFD, 0x7B, 0xFF, -0x78, 0x6C, 0x70, 0x72, 0x6E, 0x73, 0x6D, 0x6D, 0x6D, 0x65, 0x65, 0x69, 0x6F, 0x70, 0x6B, 0x6E, -0x71, 0x6E, 0x6E, 0x6F, 0x7A, 0x7D, 0x7E, 0xEF, 0xF4, 0x7D, 0xFB, 0xF3, 0xEC, 0xEB, 0xF0, 0xEF, -0xEE, 0xEE, 0xF3, 0xF0, 0xED, 0xFF, 0xFF, 0xF3, 0x7E, 0xFB, 0xFF, 0x73, 0x7E, 0x7A, 0x76, 0x6F, -0x6C, 0x7A, 0x74, 0x6F, 0xFF, 0x7B, 0x79, 0xF7, 0xF5, 0xFB, 0xF6, 0xF3, 0x7E, 0x7D, 0xFA, 0xFD, -0xF6, 0xF5, 0x7D, 0x7B, 0x7A, 0xFF, 0xFB, 0x7D, 0x75, 0x76, 0xF3, 0xF3, 0x78, 0xFE, 0x76, 0x6B, -0x7B, 0xFB, 0x75, 0x69, 0x6C, 0xF6, 0xF6, 0x7B, 0x6F, 0x69, 0x6E, 0x72, 0x70, 0x74, 0x78, 0xFF, -0x7F, 0xFD, 0xF5, 0xF8, 0xF5, 0xF9, 0x75, 0x74, 0x7D, 0xF7, 0xFB, 0x70, 0x7E, 0xE9, 0xEF, 0xF7, -0xE6, 0xED, 0x74, 0x7A, 0xF7, 0x7D, 0x71, 0x77, 0xFE, 0xF6, 0xFC, 0x6B, 0x6B, 0x72, 0x69, 0x6D, -0x7B, 0x7C, 0xFD, 0x6F, 0x6B, 0xFC, 0x7F, 0x73, 0xF9, 0xF5, 0x70, 0x6E, 0xFD, 0xFF, 0x7C, 0xFB, -0x70, 0x76, 0xEF, 0x7D, 0x75, 0xFB, 0xF6, 0xEF, 0xF6, 0x7C, 0x79, 0x76, 0xFE, 0x7D, 0x73, 0xFD, -0xFE, 0x76, 0x6E, 0x66, 0x6B, 0x75, 0x6D, 0x7D, 0xF2, 0x6D, 0x75, 0xED, 0x7A, 0x6D, 0x7E, 0xF9, -0xFE, 0x6E, 0x78, 0xF4, 0x6E, 0x73, 0xF8, 0x74, 0xFF, 0xFE, 0x77, 0xF6, 0x7C, 0x71, 0x7F, 0x7E, -0x7E, 0x79, 0x78, 0x7C, 0x6E, 0x6F, 0x70, 0x6D, 0xFD, 0xFA, 0x6C, 0x6B, 0x71, 0x70, 0x7B, 0x7A, -0x7C, 0xFD, 0x6D, 0x75, 0xED, 0xF8, 0xFC, 0xF7, 0xFB, 0xEE, 0xEF, 0x79, 0xFF, 0xED, 0xF8, 0x7A, -0xF1, 0xED, 0xF7, 0xFC, 0xF8, 0xF1, 0xF8, 0x79, 0x7D, 0xF6, 0x78, 0x6E, 0xFD, 0xFB, 0x72, 0x6E, -0x6C, 0x74, 0xFE, 0xFF, 0xF7, 0xFE, 0x6D, 0x75, 0x79, 0x6F, 0x7C, 0x7D, 0x76, 0x78, 0x7A, 0x7F, -0x75, 0x7D, 0xF7, 0xF8, 0xEF, 0x7B, 0x7A, 0xF3, 0xFF, 0xEF, 0xF8, 0xFE, 0xF6, 0x6E, 0xF4, 0xED, -0x6F, 0x7C, 0x74, 0x75, 0xF2, 0x7C, 0x75, 0xF9, 0xEE, 0xFF, 0x70, 0x7C, 0x7F, 0xFD, 0xFD, 0xFA, -0x79, 0x6C, 0x7C, 0x7F, 0xFD, 0xF3, 0x78, 0xFE, 0xF7, 0xFC, 0xED, 0xF1, 0xFD, 0xFE, 0x7D, 0xF4, -0xED, 0xF4, 0xFA, 0xFD, 0x70, 0x73, 0xF6, 0xFF, 0x7D, 0xF7, 0x79, 0x72, 0x78, 0x7D, 0x77, 0x6E, -0x71, 0x6C, 0x6A, 0x7D, 0x74, 0x71, 0x7D, 0x6E, 0x79, 0xF8, 0x70, 0x7C, 0xFE, 0x6D, 0x6F, 0x6E, -0x6D, 0x7D, 0xFD, 0xFB, 0xFA, 0x7C, 0xFD, 0xFA, 0xF7, 0xF4, 0xFD, 0x7B, 0x76, 0x7D, 0xF3, 0xF5, -0xFD, 0xF5, 0xED, 0x7A, 0x6D, 0xF5, 0x7C, 0x76, 0xEF, 0x77, 0x6E, 0xFF, 0x74, 0x79, 0xFD, 0x76, -0x7A, 0x7E, 0x7B, 0x7D, 0x78, 0x73, 0x7A, 0xFB, 0xFB, 0x7E, 0xFB, 0xF2, 0xF8, 0xF9, 0xFB, 0xFE, -0xF5, 0xF6, 0xF9, 0x7E, 0x73, 0xF7, 0xFA, 0x74, 0xFC, 0x7B, 0x70, 0xFF, 0xFC, 0x7E, 0x7C, 0xFE, -0xFF, 0x7C, 0xFC, 0x7E, 0x79, 0xFF, 0x7C, 0x79, 0x79, 0x79, 0x7A, 0x79, 0x7A, 0x7C, 0x7A, 0x75, -0x72, 0x7C, 0xFC, 0xFE, 0xFE, 0xFC, 0xF9, 0xFE, 0xFE, 0xFA, 0x7C, 0xFD, 0xFC, 0x77, 0x7B, 0x7A, -0x73, 0x78, 0x7A, 0x78, 0x7B, 0x77, 0x6E, 0x70, 0x7B, 0x7A, 0x72, 0x74, 0x76, 0x75, 0x77, 0x75, -0x70, 0x6F, 0x6F, 0x6F, 0x74, 0x77, 0x72, 0x6F, 0x70, 0x79, 0x79, 0x6F, 0x7E, 0xFA, 0x72, 0x79, -0x79, 0x78, 0xFE, 0x78, 0xFF, 0xFE, 0x76, 0xFF, 0xFF, 0x7D, 0xFF, 0x7E, 0x7B, 0x78, 0x7C, 0x75, -0x75, 0xFF, 0xFF, 0xF8, 0xF6, 0xFD, 0xF5, 0xF4, 0xF6, 0xFC, 0x7C, 0x7C, 0x7B, 0xFC, 0xFD, 0xFD, -0xFD, 0x77, 0x7A, 0x7F, 0x7E, 0xFC, 0xFA, 0xF7, 0xFF, 0xFE, 0xF1, 0xFD, 0xFD, 0xF0, 0xF9, 0xF8, -0xEE, 0xEF, 0xF8, 0x7E, 0x79, 0x77, 0x6C, 0x66, 0x6A, 0x68, 0x67, 0x71, 0x74, 0x77, 0x7E, 0x7B, -0xFD, 0xFD, 0x7F, 0xFF, 0x79, 0xFE, 0xFE, 0x75, 0x78, 0x7A, 0x74, 0x70, 0x76, 0x77, 0x75, 0x7C, -0x7C, 0x79, 0x78, 0x77, 0x78, 0x7C, 0x7E, 0x77, 0x74, 0x79, 0x77, 0x78, 0x78, 0x77, 0x7B, 0x78, -0x77, 0x77, 0x7A, 0xFE, 0x7D, 0xFE, 0xF6, 0xFB, 0xFC, 0xF8, 0xF6, 0xFA, 0xFD, 0xFB, 0xFC, 0x7D, -0x7B, 0xFB, 0xF5, 0xFC, 0xFF, 0xFD, 0xFE, 0xFF, 0x7F, 0xFC, 0xF8, 0xFF, 0x7F, 0xF7, 0xF9, 0xFA, -0xF9, 0xFB, 0xFA, 0xFA, 0xFA, 0xF8, 0xF8, 0xFD, 0x7E, 0xF8, 0xF7, 0xEF, 0xE0, 0xE1, 0xF7, 0x6E, -0x69, 0x65, 0x5C, 0x5B, 0x61, 0x69, 0x6E, 0x76, 0xF8, 0xEF, 0xF2, 0xEB, 0xE3, 0xDE, 0xE2, 0xFA, -0x66, 0x5B, 0x5F, 0x6E, 0x6E, 0xFB, 0xED, 0xED, 0xEC, 0xF8, 0x7E, 0x7B, 0x6E, 0x67, 0x60, 0x65, -0x6E, 0x6F, 0x78, 0xFB, 0x7E, 0x7D, 0xFA, 0xF9, 0xF7, 0xF5, 0xF7, 0xEE, 0xEB, 0xF3, 0xFA, 0x7A, -0x6D, 0x69, 0x6A, 0x69, 0x64, 0x69, 0x6E, 0x6F, 0x78, 0xFB, 0xFB, 0x7C, 0xF8, 0xF1, 0xFB, 0xF4, -0xF9, 0x7D, 0xF8, 0x7D, 0xFD, 0xF3, 0x7C, 0xFD, 0xF4, 0x7A, 0x6F, 0x79, 0xFF, 0x75, 0x78, 0xFA, -0xFB, 0xFE, 0xFB, 0xF9, 0xFE, 0xFF, 0xFF, 0xFC, 0xF5, 0xFD, 0x79, 0xFF, 0xF9, 0xFA, 0xFF, 0xFF, -0x7B, 0x74, 0x75, 0x6F, 0x71, 0x7D, 0x74, 0x75, 0x79, 0x71, 0x77, 0x7E, 0x7E, 0x7C, 0x74, 0x71, -0x77, 0x7A, 0x7F, 0xFB, 0x72, 0x69, 0x74, 0x74, 0x6A, 0x74, 0x7E, 0x79, 0x76, 0x74, 0x7F, 0x7C, -0x76, 0xF8, 0xF8, 0x7E, 0x7D, 0x7E, 0xFE, 0x77, 0x7B, 0xF8, 0x7B, 0xFF, 0xF3, 0xFC, 0xFF, 0xFE, -0xFD, 0xF5, 0xF6, 0xF3, 0xF2, 0xFA, 0xF8, 0xF3, 0xFB, 0x7E, 0xFA, 0xFA, 0x7E, 0xFE, 0xFC, 0x7C, -0x78, 0x7D, 0xFB, 0xF3, 0xFD, 0x74, 0xF7, 0xF5, 0x76, 0xF9, 0xF8, 0xFF, 0xF5, 0x76, 0x7B, 0xFA, -0x77, 0xFD, 0x7C, 0x77, 0x7D, 0x6F, 0x7D, 0xF7, 0xFC, 0xFD, 0x7B, 0xF5, 0xF8, 0x7A, 0xF4, 0xFB, -0x77, 0x7B, 0x76, 0x74, 0x7D, 0x7E, 0x72, 0x71, 0x70, 0x70, 0x77, 0x70, 0x7B, 0xFD, 0x6F, 0x72, -0x7D, 0x7A, 0x71, 0x79, 0xF8, 0x77, 0x6F, 0x74, 0x7A, 0x78, 0x7C, 0xF6, 0x7C, 0xFB, 0x7D, 0x6C, -0xEF, 0xFC, 0x6D, 0xF1, 0xF5, 0x7D, 0x79, 0xFA, 0xF5, 0x75, 0xF4, 0x7C, 0xFC, 0xE6, 0x68, 0x78, -0xE4, 0x6E, 0x77, 0xF2, 0x7E, 0x70, 0x69, 0xF9, 0xF7, 0x6C, 0x74, 0xF3, 0xEE, 0x79, 0x7E, 0xFB, -0x7A, 0xF6, 0x6C, 0x6B, 0xED, 0x77, 0x6A, 0x70, 0x6F, 0xFC, 0x7E, 0x79, 0xF2, 0xEE, 0xF8, 0x7D, -0xEF, 0xEB, 0x7E, 0x72, 0x7D, 0x74, 0x6B, 0xFA, 0xE5, 0xE7, 0xE4, 0xEB, 0xF8, 0xEC, 0xEA, 0xF3, -0xFB, 0xFA, 0xEF, 0xF6, 0x7C, 0xFF, 0x7B, 0x72, 0x78, 0x7C, 0x6F, 0x6E, 0xFF, 0xFF, 0x75, 0x74, -0x74, 0x76, 0x6C, 0x6A, 0x7F, 0x78, 0x6D, 0x74, 0x6E, 0x76, 0x7B, 0x69, 0x6B, 0x79, 0x72, 0x6A, -0x6D, 0x77, 0xFD, 0xFC, 0x6F, 0x7C, 0xEE, 0x76, 0x69, 0x74, 0xFB, 0x74, 0x6A, 0x7D, 0xF0, 0xFF, -0x6B, 0x71, 0xEF, 0x7D, 0x74, 0xF8, 0x75, 0x74, 0x77, 0x6C, 0x6E, 0x71, 0x73, 0x72, 0x70, 0xF4, -0xF0, 0x79, 0x7B, 0xFB, 0xF3, 0xF4, 0x78, 0x79, 0xF7, 0xFC, 0x6E, 0x70, 0xF8, 0xF8, 0x79, 0x6D, -0x70, 0xFB, 0x6E, 0x64, 0x6B, 0x72, 0x6F, 0x65, 0x71, 0xFC, 0x71, 0x76, 0x6E, 0x71, 0xF9, 0xFF, -0xFD, 0x73, 0x7A, 0xFF, 0x66, 0x70, 0xFE, 0x79, 0xFD, 0x7D, 0xF1, 0xF6, 0x76, 0x79, 0x6D, 0x79, -0xFF, 0x72, 0x7F, 0xF8, 0xF0, 0xFF, 0x71, 0xEC, 0xE9, 0x7C, 0x7C, 0xF1, 0xF7, 0xF7, 0xF5, 0xFA, -0xF1, 0x7C, 0x70, 0x7D, 0xFB, 0xF4, 0x7C, 0x7D, 0xF6, 0xFD, 0xEF, 0xF6, 0xEE, 0xE1, 0xEE, 0xF4, -0xF3, 0xEE, 0xF4, 0x78, 0xEC, 0xF7, 0x72, 0x74, 0x6E, 0xF5, 0x6A, 0x7B, 0xDF, 0x69, 0x7F, 0xE7, -0x6F, 0x7C, 0x68, 0xF4, 0xEE, 0x5C, 0x72, 0x6B, 0x6D, 0xEC, 0x60, 0x7E, 0xEB, 0x66, 0x6D, 0x6A, -0x7A, 0xFF, 0x6A, 0x6E, 0x74, 0xED, 0x79, 0x6B, 0xED, 0xFA, 0xFC, 0x70, 0x65, 0xF6, 0x75, 0x67, -0x78, 0x78, 0xF4, 0xFF, 0x5F, 0xF9, 0xE3, 0x6D, 0xF1, 0x7A, 0x70, 0xDB, 0x6A, 0xF9, 0xDC, 0x66, -0xDB, 0xF8, 0x65, 0xD6, 0x6A, 0xF2, 0xE6, 0x5E, 0xE1, 0x76, 0x6F, 0xF5, 0x65, 0xEF, 0x5F, 0x66, -0x6F, 0x5A, 0xFB, 0x5E, 0x65, 0x7E, 0x60, 0xF2, 0x5D, 0x72, 0xE8, 0x5A, 0xEA, 0x6E, 0x62, 0xE4, -0x5E, 0x6F, 0x74, 0x67, 0xEA, 0x64, 0x77, 0xF3, 0x69, 0xF1, 0x6B, 0x6E, 0xEB, 0x74, 0x74, 0x74, -0xF6, 0xF5, 0x66, 0xF5, 0xF7, 0x6C, 0xE9, 0x70, 0x6F, 0xE4, 0x6E, 0xF0, 0xF4, 0x63, 0xE1, 0xFE, -0x6D, 0xE4, 0x6D, 0xF2, 0xEF, 0x6C, 0xE8, 0x7B, 0xFC, 0xED, 0x74, 0xEB, 0xFE, 0xFC, 0xEF, 0x6D, -0xEC, 0xFB, 0x71, 0xEB, 0x77, 0xF3, 0xF8, 0x6F, 0xE9, 0xFE, 0xFC, 0xEE, 0x6F, 0xEB, 0xED, 0x7A, -0xEE, 0xF4, 0xF3, 0xF8, 0xF1, 0xEE, 0x79, 0xF4, 0xF3, 0xFC, 0xF1, 0x7C, 0xF4, 0xF9, 0x76, 0xE8, -0xF8, 0x75, 0xE3, 0x7B, 0x6E, 0xE0, 0x75, 0x72, 0xE3, 0x6C, 0xF8, 0xE7, 0x6D, 0xEA, 0xF4, 0x75, -0xEA, 0x71, 0xFA, 0xED, 0x6A, 0xF2, 0xFB, 0x70, 0xEB, 0x6F, 0x71, 0xEE, 0x6C, 0xF6, 0xF2, 0x68, -0xF3, 0xF8, 0x6D, 0x7A, 0xFC, 0x75, 0x6D, 0xF3, 0x6E, 0x6E, 0xEE, 0x61, 0x7C, 0xFE, 0x60, 0xF2, -0x6D, 0x78, 0x7C, 0x63, 0xEB, 0x64, 0x71, 0xED, 0x5C, 0xEB, 0x6F, 0x69, 0xEA, 0x5D, 0xE7, 0xF8, -0x5E, 0xE6, 0x6F, 0xFA, 0x79, 0x72, 0xE8, 0x5E, 0xE9, 0xFB, 0x5F, 0xDE, 0x61, 0xFA, 0xE3, 0x5A, -0xE3, 0x79, 0x62, 0xDF, 0x64, 0x76, 0xE4, 0x63, 0xFE, 0xE9, 0x64, 0xF8, 0xE6, 0x5F, 0xF2, 0xE8, -0x62, 0xE7, 0xFB, 0x6A, 0xF0, 0x77, 0xF9, 0x77, 0xE9, 0x78, 0x59, 0xE3, 0x71, 0x6C, 0xDF, 0x5F, -0xEF, 0xE9, 0x5F, 0xFA, 0x76, 0xF9, 0x7D, 0x67, 0xEE, 0x7B, 0x6F, 0x7E, 0x6B, 0x6D, 0xF7, 0x6E, -0x6B, 0xF0, 0x63, 0xF0, 0x75, 0x57, 0xD4, 0x59, 0x57, 0xCD, 0x4F, 0xEE, 0xDE, 0x4B, 0xCF, 0x68, -0x5B, 0xD4, 0x50, 0xE0, 0xEF, 0x54, 0xD5, 0x57, 0x6A, 0xD3, 0x54, 0x79, 0xDF, 0x5E, 0xFC, 0xE6, -0x5F, 0x71, 0xE0, 0x64, 0x76, 0xFC, 0x5D, 0xEA, 0xF8, 0x58, 0x79, 0xDB, 0x68, 0x59, 0xDF, 0x76, -0x64, 0xDA, 0x63, 0x5A, 0xD9, 0xE0, 0x51, 0xF3, 0xD3, 0x4D, 0xDE, 0xCF, 0x3F, 0xDA, 0xC2, 0x41, -0x6A, 0xC3, 0x50, 0x55, 0xC6, 0x5A, 0x4B, 0xC2, 0x7A, 0x46, 0xCA, 0xDF, 0x4C, 0xD8, 0xDE, 0x4F, -0xE2, 0xD2, 0x4D, 0x6B, 0xCD, 0x5C, 0x56, 0xD8, 0xEB, 0x54, 0xEF, 0xDE, 0x4F, 0x78, 0xD7, 0x54, -0x5B, 0xDA, 0xFA, 0x56, 0xF6, 0xE9, 0x58, 0xF1, 0xE5, 0x59, 0x6D, 0xE8, 0x7B, 0x64, 0x7E, 0xE2, -0x60, 0x6D, 0xDC, 0x63, 0x67, 0xDC, 0x6F, 0x62, 0xE2, 0x7B, 0x60, 0xEC, 0xF3, 0x67, 0x77, 0xF1, -0x7C, 0x75, 0xF0, 0x79, 0x6F, 0xED, 0x76, 0x6B, 0xF3, 0xFF, 0x74, 0xF4, 0xF8, 0x6B, 0x6C, 0xE6, -0xE7, 0x61, 0x79, 0xDD, 0x6F, 0x77, 0xDE, 0x6D, 0x6E, 0xE4, 0x7E, 0xF9, 0xE8, 0x6D, 0x6F, 0xDE, -0xEF, 0x5C, 0xEF, 0xDB, 0x64, 0x6B, 0xDF, 0xF9, 0x6C, 0xF4, 0xF5, 0x72, 0xF5, 0xF7, 0x66, 0x7D, -0xE9, 0x7D, 0x70, 0x79, 0xF6, 0x7B, 0x6C, 0xF3, 0xF2, 0x6A, 0x76, 0xED, 0x79, 0x6B, 0xF2, 0xF1, -0x6B, 0x78, 0xEF, 0x73, 0x74, 0xED, 0x73, 0x6A, 0xEB, 0xF2, 0x64, 0x6F, 0xE2, 0xF8, 0x5E, 0xF3, -0xE8, 0x64, 0x74, 0xEF, 0x7B, 0x77, 0x74, 0x78, 0x6D, 0xF8, 0xEA, 0x63, 0x68, 0xEC, 0xEF, 0x6E, -0x63, 0xEE, 0xFA, 0x5F, 0xE5, 0xEB, 0x58, 0x73, 0xD1, 0xF3, 0x4D, 0xF2, 0xCD, 0x5D, 0x54, 0xDF, -0xDD, 0x61, 0x5B, 0xD9, 0xDF, 0x50, 0xF0, 0xD3, 0x5F, 0x5D, 0xE4, 0xDF, 0x6E, 0x5B, 0xED, 0xD8, -0x68, 0x56, 0xEA, 0xD3, 0x70, 0x52, 0xF0, 0xD3, 0x74, 0x57, 0xF5, 0xD8, 0x6A, 0x58, 0xE4, 0xE2, -0x5C, 0x7A, 0xD8, 0x77, 0x5A, 0xE8, 0xD9, 0x73, 0x5F, 0x7D, 0xE3, 0xEC, 0x73, 0x72, 0x6E, 0xF6, -0xDF, 0xF7, 0x62, 0x6B, 0xE5, 0xDD, 0x6B, 0x58, 0xF7, 0xDB, 0x73, 0x5E, 0x75, 0x7E, 0xF6, 0xFE, -0x66, 0x71, 0x7B, 0x7E, 0xEE, 0x6C, 0x6B, 0xEB, 0x76, 0x6C, 0xEA, 0x7A, 0x67, 0xE5, 0xE8, 0x5F, -0x75, 0xDE, 0xEE, 0x6F, 0x7A, 0xED, 0xE8, 0xF8, 0xFB, 0xF4, 0x78, 0xF1, 0xE4, 0x6E, 0x62, 0xEB, -0xEC, 0x65, 0x6D, 0x7E, 0x6B, 0x69, 0x6E, 0x72, 0x78, 0x68, 0x5E, 0x74, 0xE9, 0x6F, 0x5E, 0x72, -0xEB, 0x7A, 0x6F, 0xF1, 0x78, 0x75, 0xE5, 0xE6, 0xE2, 0xDD, 0xE0, 0xD6, 0xD1, 0xD5, 0xD1, 0xD3, -0xDE, 0xE0, 0xDD, 0xE9, 0x68, 0x57, 0x52, 0x50, 0x4B, 0x48, 0x48, 0x48, 0x48, 0x4B, 0x51, 0x56, -0x56, 0x5D, 0x68, 0x6A, 0x69, 0x7C, 0xE8, 0xED, 0xED, 0xDC, 0xD5, 0xCD, 0xCB, 0xCD, 0xC5, 0xBE, -0xBE, 0xBC, 0xBC, 0xBF, 0xC5, 0xD2, 0x72, 0x52, 0x48, 0x40, 0x3C, 0x39, 0x39, 0x3B, 0x3D, 0x40, -0x4A, 0x5A, 0x6C, 0x7E, 0xDF, 0xCF, 0xCE, 0xDB, 0x6F, 0x63, 0x6E, 0x60, 0x4D, 0x47, 0x4D, 0x5E, -0x7C, 0xFA, 0xE4, 0xCD, 0xC1, 0xBD, 0xBC, 0xBA, 0xB7, 0xB4, 0xB5, 0xBE, 0xD7, 0xEB, 0xF2, 0x4E, -0x3B, 0x36, 0x37, 0x39, 0x38, 0x39, 0x3D, 0x48, 0x58, 0xFE, 0xDA, 0xD6, 0xD8, 0xCF, 0xC8, 0xCD, -0xF3, 0x5A, 0x59, 0x58, 0x4E, 0x47, 0x48, 0x4F, 0x5F, 0xF2, 0xD9, 0xCE, 0xC6, 0xBF, 0xBB, 0xBA, -0xB9, 0xB7, 0xB5, 0xB7, 0xC0, 0xD9, 0x68, 0x57, 0x49, 0x3B, 0x35, 0x35, 0x38, 0x3A, 0x3B, 0x3F, -0x4B, 0x60, 0xE7, 0xD8, 0xD5, 0xD4, 0xCE, 0xCA, 0xCF, 0xF9, 0x59, 0x51, 0x4E, 0x4C, 0x48, 0x46, -0x49, 0x56, 0xFB, 0xD9, 0xD1, 0xC9, 0xBE, 0xB8, 0xB6, 0xB5, 0xB3, 0xB2, 0xB6, 0xC3, 0xE5, 0x60, -0x4E, 0x3F, 0x37, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x41, 0x4E, 0x6F, 0xDA, 0xD2, 0xD4, 0xD1, 0xCA, -0xC9, 0xD7, 0x6F, 0x59, 0x4D, 0x47, 0x47, 0x48, 0x45, 0x46, 0x52, 0xEE, 0xD7, 0xD0, 0xC7, 0xBC, -0xB5, 0xB3, 0xB3, 0xB1, 0xB0, 0xB7, 0xCA, 0x68, 0x4F, 0x45, 0x3B, 0x32, 0x2E, 0x30, 0x35, 0x39, -0x3D, 0x44, 0x52, 0xEC, 0xD0, 0xCF, 0xD3, 0xD0, 0xCD, 0xCF, 0xE3, 0x63, 0x5B, 0x59, 0x52, 0x4D, -0x4C, 0x4F, 0x5A, 0x6D, 0xE5, 0xD2, 0xC8, 0xBE, 0xB9, 0xB5, 0xB3, 0xB1, 0xAF, 0xB1, 0xBD, 0xE3, -0x53, 0x4B, 0x40, 0x35, 0x2E, 0x2F, 0x34, 0x39, 0x3B, 0x3F, 0x4C, 0x75, 0xDA, 0xD6, 0xD2, 0xCE, -0xCE, 0xD0, 0xD9, 0xEF, 0x62, 0x56, 0x55, 0x55, 0x4F, 0x4E, 0x52, 0x61, 0xEF, 0xDB, 0xCC, 0xBF, -0xB9, 0xB5, 0xB3, 0xB0, 0xAE, 0xB4, 0xC8, 0x63, 0x4D, 0x45, 0x39, 0x2E, 0x2C, 0x2F, 0x35, 0x38, -0x3B, 0x43, 0x5A, 0xDD, 0xCE, 0xCD, 0xCC, 0xCB, 0xCD, 0xD2, 0xDE, 0x76, 0x5A, 0x52, 0x53, 0x51, -0x4E, 0x4F, 0x5C, 0x7C, 0xE2, 0xD2, 0xC5, 0xBB, 0xB5, 0xB2, 0xB0, 0xAE, 0xAE, 0xB6, 0xCF, 0x55, -0x48, 0x3F, 0x34, 0x2C, 0x2C, 0x2F, 0x36, 0x39, 0x3D, 0x4A, 0x7D, 0xCE, 0xCA, 0xCB, 0xCB, 0xCB, -0xCD, 0xD9, 0x76, 0x59, 0x4F, 0x4C, 0x4C, 0x4A, 0x4C, 0x54, 0x68, 0xEC, 0xD8, 0xCB, 0xBF, 0xB8, -0xB3, 0xB0, 0xAE, 0xAD, 0xAE, 0xBC, 0xF5, 0x4C, 0x43, 0x39, 0x2E, 0x2A, 0x2D, 0x32, 0x37, 0x3B, -0x44, 0x5F, 0xD5, 0xC8, 0xC7, 0xC9, 0xCB, 0xCE, 0xD3, 0xE9, 0x5A, 0x4D, 0x4D, 0x4D, 0x4B, 0x4B, -0x50, 0x63, 0xF6, 0xDE, 0xCE, 0xC5, 0xBD, 0xB7, 0xB2, 0xB0, 0xAF, 0xAD, 0xAF, 0xBF, 0x5E, 0x45, -0x40, 0x37, 0x2C, 0x29, 0x2D, 0x34, 0x38, 0x3C, 0x48, 0x77, 0xCD, 0xC6, 0xC7, 0xCB, 0xCB, 0xCF, -0xE9, 0x59, 0x4E, 0x4B, 0x47, 0x44, 0x47, 0x4D, 0x57, 0x69, 0xEB, 0xD7, 0xCA, 0xBF, 0xB9, 0xB3, -0xAF, 0xAE, 0xAD, 0xAC, 0xB5, 0xDE, 0x49, 0x43, 0x3B, 0x2D, 0x28, 0x2A, 0x30, 0x36, 0x3A, 0x44, -0x6A, 0xCD, 0xC2, 0xC2, 0xC6, 0xCA, 0xCC, 0xD8, 0x60, 0x4C, 0x48, 0x46, 0x44, 0x43, 0x49, 0x54, -0x68, 0xEC, 0xD8, 0xCB, 0xC2, 0xBC, 0xB8, 0xB2, 0xAF, 0xAE, 0xAE, 0xAE, 0xBA, 0x74, 0x45, 0x3F, -0x36, 0x2C, 0x29, 0x2C, 0x32, 0x37, 0x3E, 0x4E, 0xE3, 0xC7, 0xC2, 0xC5, 0xC6, 0xC8, 0xD2, 0x71, -0x52, 0x4D, 0x49, 0x42, 0x41, 0x47, 0x51, 0x60, 0x7B, 0xDE, 0xCE, 0xC6, 0xC0, 0xBE, 0xB9, 0xB2, -0xAF, 0xAF, 0xAE, 0xAE, 0xBC, 0x6B, 0x47, 0x3F, 0x34, 0x2C, 0x2A, 0x2D, 0x32, 0x39, 0x3F, 0x4F, -0xDF, 0xC5, 0xC4, 0xCD, 0xCA, 0xC7, 0xDB, 0x5A, 0x4E, 0x4D, 0x48, 0x42, 0x40, 0x45, 0x54, 0x6F, -0x74, 0xEC, 0xCD, 0xC4, 0xC4, 0xC1, 0xBB, 0xB3, 0xAF, 0xB0, 0xAE, 0xAE, 0xBC, 0x6F, 0x4A, 0x3F, -0x34, 0x2C, 0x2B, 0x2E, 0x34, 0x3B, 0x42, 0x56, 0xCF, 0xBF, 0xC2, 0xCB, 0xC6, 0xC6, 0xE6, 0x52, -0x4B, 0x47, 0x45, 0x3F, 0x3D, 0x45, 0x5E, 0x7A, 0x72, 0xDB, 0xC7, 0xC3, 0xC5, 0xC2, 0xBC, 0xB5, -0xB1, 0xB3, 0xB0, 0xAE, 0xB9, 0xF0, 0x4C, 0x43, 0x38, 0x2E, 0x2B, 0x2D, 0x34, 0x3A, 0x3E, 0x4F, -0xD3, 0xC1, 0xC4, 0xCD, 0xCC, 0xC8, 0xDE, 0x4D, 0x45, 0x47, 0x47, 0x41, 0x3D, 0x47, 0x6D, 0xF7, -0x79, 0xDA, 0xC9, 0xC6, 0xC8, 0xC9, 0xC0, 0xB8, 0xB4, 0xB5, 0xB0, 0xAC, 0xB1, 0xCF, 0x5A, 0x4E, -0x3E, 0x30, 0x2B, 0x2D, 0x33, 0x38, 0x3B, 0x48, 0xDC, 0xC4, 0xC5, 0xCA, 0xCB, 0xCB, 0xD9, 0x50, -0x46, 0x4B, 0x46, 0x3E, 0x3F, 0x48, 0x55, 0x76, 0x7E, 0xE3, 0xCA, 0xC9, 0xCE, 0xCB, 0xC6, 0xBE, -0xBA, 0xB8, 0xB4, 0xAE, 0xAE, 0xBD, 0xEA, 0x62, 0x48, 0x35, 0x2D, 0x2C, 0x30, 0x35, 0x37, 0x3F, -0x6F, 0xCB, 0xCA, 0xC9, 0xC7, 0xCE, 0xD9, 0x60, 0x46, 0x46, 0x48, 0x40, 0x40, 0x49, 0x52, 0x69, -0xED, 0xE1, 0xD1, 0xCC, 0xD0, 0xD2, 0xD0, 0xCD, 0xC2, 0xBD, 0xB9, 0xB2, 0xAE, 0xAF, 0xBA, 0xE0, -0x67, 0x4C, 0x34, 0x2D, 0x2E, 0x30, 0x34, 0x37, 0x41, 0xF4, 0xCD, 0xCC, 0xC7, 0xC5, 0xD0, 0xED, -0x64, 0x4D, 0x45, 0x47, 0x43, 0x44, 0x4F, 0x51, 0x69, 0xD9, 0xDD, 0xD1, 0xCB, 0xD1, 0xCF, 0xD2, -0xCD, 0xBF, 0xBC, 0xB8, 0xB0, 0xAD, 0xAE, 0xBC, 0xD9, 0x76, 0x48, 0x32, 0x2D, 0x2F, 0x30, 0x32, -0x38, 0x49, 0xE6, 0xD1, 0xCB, 0xC1, 0xC1, 0xD2, 0x7A, 0x6F, 0x51, 0x42, 0x43, 0x45, 0x4A, 0x4D, -0x4E, 0x72, 0xD7, 0xDB, 0xD8, 0xCE, 0xCF, 0xD7, 0xDD, 0xD3, 0xC6, 0xBF, 0xBB, 0xB3, 0xAD, 0xAE, -0xB8, 0xCD, 0xE2, 0x52, 0x35, 0x2E, 0x2F, 0x2F, 0x2F, 0x35, 0x43, 0x62, 0xE5, 0xCF, 0xC1, 0xC0, -0xD1, 0xE1, 0xDB, 0x5E, 0x46, 0x49, 0x4D, 0x4A, 0x49, 0x51, 0x6A, 0xEE, 0xEB, 0xDE, 0xD0, 0xD4, -0xDF, 0xDC, 0xD7, 0xCF, 0xC5, 0xBE, 0xB7, 0xB1, 0xAE, 0xAF, 0xBC, 0xD3, 0xE7, 0x48, 0x31, 0x2E, -0x2F, 0x2E, 0x2F, 0x36, 0x44, 0x5B, 0xF4, 0xCC, 0xBF, 0xC2, 0xD4, 0xD1, 0xCF, 0x59, 0x4B, 0x51, -0x4B, 0x46, 0x44, 0x4C, 0x56, 0x51, 0x66, 0xE5, 0xE6, 0xE0, 0xDF, 0xD6, 0xD1, 0xCD, 0xC0, 0xBB, -0xB7, 0xB0, 0xAD, 0xB0, 0xBD, 0xCE, 0xEF, 0x44, 0x31, 0x2F, 0x30, 0x2E, 0x2E, 0x39, 0x46, 0x56, -0xF0, 0xC7, 0xBD, 0xC2, 0xC9, 0xC8, 0xCC, 0x7A, 0x50, 0x57, 0x4F, 0x42, 0x42, 0x4A, 0x4C, 0x4C, -0x5D, 0xEF, 0xEE, 0xE3, 0xD6, 0xD1, 0xD2, 0xCC, 0xC0, 0xBC, 0xBA, 0xB3, 0xAE, 0xAF, 0xBA, 0xC9, -0xD6, 0x4F, 0x36, 0x30, 0x30, 0x2E, 0x2D, 0x34, 0x3E, 0x45, 0x5C, 0xCF, 0xC1, 0xC0, 0xC1, 0xC0, -0xC9, 0xD9, 0xF5, 0x54, 0x4A, 0x47, 0x40, 0x41, 0x42, 0x45, 0x4E, 0x53, 0x68, 0xE8, 0xE1, 0xD1, -0xCD, 0xCC, 0xC5, 0xBF, 0xBB, 0xB8, 0xB4, 0xAF, 0xB0, 0xBD, 0xCB, 0xD8, 0x4B, 0x36, 0x34, 0x33, -0x2E, 0x2E, 0x37, 0x3D, 0x44, 0x62, 0xCD, 0xC4, 0xC0, 0xBE, 0xBF, 0xC5, 0xCF, 0xEE, 0x66, 0x4F, -0x45, 0x43, 0x40, 0x41, 0x44, 0x47, 0x51, 0x5B, 0x71, 0xDD, 0xD8, 0xCE, 0xC8, 0xC6, 0xC1, 0xBD, -0xB9, 0xB7, 0xB2, 0xAF, 0xB9, 0xC3, 0xCC, 0x71, 0x40, 0x37, 0x36, 0x31, 0x2E, 0x33, 0x3A, 0x3D, -0x4A, 0xE6, 0xCF, 0xC7, 0xBE, 0xBF, 0xC2, 0xCA, 0xD3, 0xE6, 0x50, 0x4C, 0x4B, 0x3E, 0x3E, 0x43, -0x41, 0x47, 0x4D, 0x59, 0x75, 0xE4, 0xD0, 0xCC, 0xC9, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB3, 0xB3, -0xBB, 0xC3, 0xCD, 0x6A, 0x42, 0x3A, 0x38, 0x31, 0x30, 0x36, 0x39, 0x3C, 0x4B, 0x7A, 0xDB, 0xCB, -0xC1, 0xC3, 0xC5, 0xC5, 0xD5, 0xE5, 0x6B, 0x4E, 0x4C, 0x43, 0x40, 0x45, 0x42, 0x48, 0x50, 0x55, -0x6C, 0xE8, 0xD7, 0xCD, 0xCC, 0xC7, 0xC3, 0xC0, 0xBD, 0xBC, 0xB8, 0xB2, 0xB5, 0xBD, 0xC2, 0xD0, -0x5D, 0x45, 0x3C, 0x38, 0x32, 0x32, 0x37, 0x37, 0x3C, 0x4C, 0x5E, 0xEE, 0xCD, 0xC5, 0xC8, 0xC6, -0xC5, 0xD0, 0xE2, 0xF9, 0x5D, 0x4D, 0x47, 0x46, 0x42, 0x41, 0x47, 0x4B, 0x4E, 0x63, 0xEA, 0xE3, -0xD3, 0xC9, 0xCB, 0xC8, 0xC0, 0xBF, 0xBD, 0xBA, 0xB5, 0xB6, 0xBC, 0xC1, 0xCC, 0x7E, 0x4B, 0x3F, -0x3B, 0x35, 0x32, 0x37, 0x37, 0x3A, 0x45, 0x50, 0x6D, 0xD7, 0xC8, 0xC6, 0xC7, 0xC2, 0xCA, 0xD7, -0xDB, 0x6D, 0x59, 0x4F, 0x48, 0x48, 0x45, 0x46, 0x4D, 0x4F, 0x5E, 0xFF, 0xE6, 0xD7, 0xD4, 0xCF, -0xD1, 0xD5, 0xD0, 0xD3, 0xCD, 0xC6, 0xC1, 0xBA, 0xB8, 0xBB, 0xC2, 0xC4, 0xCD, 0x58, 0x4C, 0x48, -0x39, 0x36, 0x39, 0x36, 0x37, 0x3E, 0x44, 0x4B, 0x66, 0xDC, 0xD4, 0xCA, 0xC3, 0xC5, 0xC7, 0xCA, -0xCE, 0xDD, 0x6D, 0x5F, 0x4F, 0x46, 0x47, 0x46, 0x43, 0x49, 0x4E, 0x53, 0x65, 0xF1, 0xE4, 0xD9, -0xCF, 0xCE, 0xCD, 0xC6, 0xC3, 0xC0, 0xBA, 0xB7, 0xB7, 0xBD, 0xC4, 0xC5, 0xFD, 0x4A, 0x4C, 0x3B, -0x33, 0x37, 0x34, 0x32, 0x3A, 0x3F, 0x47, 0x5B, 0xDC, 0xCB, 0xC8, 0xBE, 0xBC, 0xC3, 0xC0, 0xC7, -0xDE, 0xEC, 0x5B, 0x49, 0x45, 0x3F, 0x3E, 0x3F, 0x40, 0x49, 0x4E, 0x5B, 0xEF, 0xDF, 0xD4, 0xCC, -0xCA, 0xC7, 0xC5, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB8, 0xC0, 0xCB, 0xCA, 0x68, 0x45, 0x4D, 0x3D, -0x35, 0x3C, 0x3A, 0x38, 0x41, 0x49, 0x4D, 0x69, 0xDB, 0xD3, 0xCD, 0xC5, 0xC6, 0xCC, 0xCB, 0xD0, -0xEB, 0x76, 0x5C, 0x4C, 0x48, 0x44, 0x41, 0x41, 0x44, 0x49, 0x4E, 0x5D, 0x7E, 0xE6, 0xD4, 0xCE, -0xCE, 0xCB, 0xCB, 0xCE, 0xCE, 0xCA, 0xC9, 0xC6, 0xBE, 0xBC, 0xC6, 0xCA, 0xC4, 0xE0, 0x58, 0x77, -0x4A, 0x3D, 0x45, 0x3D, 0x39, 0x3F, 0x41, 0x40, 0x4C, 0x61, 0x6D, 0xE7, 0xCE, 0xCC, 0xCC, 0xC9, -0xCA, 0xD1, 0xDB, 0xE2, 0x66, 0x54, 0x50, 0x48, 0x45, 0x47, 0x47, 0x4B, 0x51, 0x5A, 0x71, 0xEB, -0xDD, 0xD5, 0xD2, 0xCF, 0xCC, 0xCC, 0xCA, 0xC4, 0xC3, 0xBF, 0xB9, 0xBD, 0xCB, 0xC0, 0xC9, 0x56, -0x71, 0x5A, 0x3A, 0x3F, 0x3E, 0x34, 0x3A, 0x3E, 0x3C, 0x42, 0x54, 0x62, 0x73, 0xCF, 0xC8, 0xCC, -0xC3, 0xC3, 0xCD, 0xCF, 0xDD, 0x6D, 0x56, 0x4D, 0x48, 0x42, 0x42, 0x44, 0x45, 0x4D, 0x57, 0x61, -0xED, 0xDB, 0xD5, 0xCD, 0xCD, 0xCD, 0xCD, 0xD0, 0xCD, 0xD1, 0xCA, 0xC4, 0xC7, 0xBA, 0xC2, 0xD8, -0xBB, 0xD7, 0x53, 0xCC, 0x4E, 0x3E, 0x57, 0x3E, 0x3B, 0x43, 0x3F, 0x3E, 0x46, 0x52, 0x50, 0x60, -0xD6, 0xD9, 0xD4, 0xC6, 0xCA, 0xCF, 0xCB, 0xD5, 0xF4, 0xFB, 0x5D, 0x4E, 0x4C, 0x4B, 0x46, 0x45, -0x4F, 0x4E, 0x4D, 0x7E, 0x6F, 0x71, 0xD4, 0xE1, 0xDF, 0xCE, 0xD9, 0xD5, 0xCD, 0xCD, 0xC5, 0xBF, -0xB9, 0xBA, 0xC6, 0xBA, 0xBF, 0x6C, 0xCE, 0xFB, 0x3D, 0x4D, 0x40, 0x35, 0x3C, 0x3B, 0x38, 0x3E, -0x47, 0x4B, 0x52, 0xDF, 0xD8, 0xD6, 0xC3, 0xC6, 0xCB, 0xC5, 0xCD, 0xDD, 0xE4, 0x6B, 0x50, 0x4D, -0x49, 0x44, 0x45, 0x47, 0x48, 0x49, 0x50, 0x5D, 0x5C, 0xEE, 0xDD, 0xE7, 0xD1, 0xD5, 0xDC, 0xD0, -0xDA, 0xD8, 0xD1, 0xCD, 0xC6, 0xBF, 0xBA, 0xC1, 0xC4, 0xBA, 0xD3, 0xE1, 0xCC, 0x4D, 0x49, 0x4F, -0x3B, 0x3B, 0x3E, 0x3A, 0x3C, 0x42, 0x4A, 0x4C, 0x6D, 0xD9, 0xDC, 0xC9, 0xC4, 0xCA, 0xC6, 0xC8, -0xD0, 0xD8, 0xE5, 0x68, 0x58, 0x53, 0x4C, 0x4A, 0x4B, 0x4C, 0x4E, 0x56, 0x5F, 0x69, 0xEA, 0xE0, -0xE8, 0xD5, 0xDD, 0xE7, 0xD9, 0xFB, 0xF9, 0xF5, 0x64, 0x75, 0x6D, 0xF5, 0xE5, 0xD8, 0xC8, 0xC4, -0xBB, 0xBF, 0xC4, 0xB7, 0xCC, 0xD6, 0xC3, 0x56, 0x52, 0x5F, 0x3D, 0x3E, 0x3E, 0x39, 0x3A, 0x3D, -0x41, 0x41, 0x4F, 0x6B, 0x63, 0xD6, 0xCD, 0xD1, 0xC7, 0xC8, 0xCE, 0xCE, 0xD6, 0xE8, 0x71, 0x67, -0x55, 0x4F, 0x52, 0x4D, 0x4F, 0x56, 0x56, 0x5E, 0x6D, 0x7E, 0xF5, 0xDF, 0xE3, 0xEE, 0xDC, 0x7B, -0x73, 0xED, 0x5C, 0x6A, 0x69, 0x5B, 0x70, 0x6D, 0xEF, 0xE1, 0xCF, 0xC8, 0xC4, 0xB9, 0xC5, 0xC2, -0xB6, 0xDC, 0xCD, 0xC3, 0x49, 0x60, 0x57, 0x3A, 0x40, 0x3D, 0x38, 0x3A, 0x3E, 0x3F, 0x3E, 0x53, -0x58, 0x59, 0xD3, 0xD7, 0xD2, 0xC4, 0xC9, 0xCA, 0xC8, 0xCD, 0xD8, 0xDE, 0xEE, 0x5F, 0x5D, 0x59, -0x4F, 0x54, 0x56, 0x54, 0x5D, 0x69, 0x6D, 0xF2, 0xE1, 0xDF, 0xDB, 0xD8, 0xDD, 0xE8, 0xEB, 0x71, -0x5D, 0x66, 0x56, 0x52, 0x62, 0x52, 0x5C, 0x74, 0x63, 0xE2, 0xDD, 0xD4, 0xCA, 0xC9, 0xBF, 0xC0, -0xBB, 0xBB, 0xCC, 0xBB, 0xC8, 0x68, 0xC8, 0x58, 0x44, 0x5D, 0x3C, 0x3B, 0x40, 0x3A, 0x3B, 0x3F, -0x44, 0x43, 0x52, 0x7A, 0x62, 0xD4, 0xCB, 0xD1, 0xC3, 0xC4, 0xC8, 0xC5, 0xCA, 0xD0, 0xD9, 0xE1, -0x6C, 0x5C, 0x5B, 0x4E, 0x4D, 0x50, 0x4C, 0x50, 0x58, 0x58, 0x63, 0x79, 0xFE, 0xED, 0xE1, 0xE7, -0xEE, 0xE6, 0xFB, 0x6D, 0x7A, 0x61, 0x5D, 0x62, 0x59, 0x5B, 0x5E, 0x5C, 0x64, 0x69, 0x72, 0xFE, -0xF1, 0xE6, 0xE2, 0xDB, 0xD9, 0xD6, 0xD3, 0xD3, 0xD0, 0xD0, 0xCF, 0xCE, 0xCD, 0xCD, 0xDA, 0xDB, -0xDA, 0x64, 0x69, 0x63, 0x4C, 0x4F, 0x4D, 0x46, 0x4A, 0x4A, 0x48, 0x4D, 0x52, 0x52, 0x5C, 0x70, -0x71, 0xEB, 0xDC, 0xDE, 0xD7, 0xD4, 0xD8, 0xD5, 0xD7, 0xDD, 0xDF, 0xE7, 0xFD, 0x71, 0x69, 0x5D, -0x5A, 0x5A, 0x57, 0x56, 0x5B, 0x59, 0x5A, 0x69, 0x62, 0x6A, 0xF5, 0x73, 0xF1, 0xE7, 0xF4, 0xE6, -0xE6, 0xEE, 0xEA, 0xED, 0xF5, 0xF1, 0xED, 0xF0, 0xEA, 0xE4, 0xE7, 0xDF, 0xDE, 0xDF, 0xDC, 0xDE, -0xDF, 0xE1, 0xE8, 0xEE, 0xFD, 0x77, 0x6B, 0x64, 0x61, 0x5C, 0x5C, 0x5C, 0x5B, 0x5F, 0x61, 0x67, -0x6E, 0x78, 0xF8, 0xF1, 0xEA, 0xE5, 0xE4, 0xE2, 0xE1, 0xE5, 0xEA, 0xED, 0xFA, 0x77, 0x6E, 0x66, -0x62, 0x5D, 0x5C, 0x5A, 0x59, 0x59, 0x59, 0x5B, 0x5C, 0x5D, 0x64, 0x64, 0x6C, 0x77, 0x7C, 0xEE, -0xEB, 0xE0, 0xDB, 0xD7, 0xCF, 0xCF, 0xCA, 0xC8, 0xC5, 0xC4, 0xCD, 0xC7, 0xCB, 0xE8, 0xD3, 0xFD, -0x55, 0x67, 0x4B, 0x45, 0x48, 0x40, 0x3F, 0x42, 0x43, 0x43, 0x4A, 0x50, 0x50, 0x6C, 0xF5, 0xF2, -0xD4, 0xD2, 0xD1, 0xCB, 0xCC, 0xCE, 0xCE, 0xD0, 0xDA, 0xDC, 0xDF, 0xFD, 0x7D, 0x6F, 0x5E, 0x5F, -0x5D, 0x59, 0x5A, 0x5C, 0x5C, 0x5F, 0x68, 0x68, 0x6F, 0xFC, 0xFC, 0xEF, 0xE9, 0xEB, 0xE9, 0xE9, -0xED, 0xEF, 0xF2, 0xF8, 0xFE, 0xFE, 0x7C, 0x7C, 0x7E, 0x79, 0xFE, 0xFB, 0xFE, 0xF7, 0xF6, 0xF9, -0xF6, 0xF8, 0xFD, 0xFF, 0x7C, 0x73, 0x70, 0x6E, 0x6A, 0x6A, 0x69, 0x68, 0x6A, 0x6B, 0x6C, 0x6F, -0x74, 0x79, 0xFF, 0xFA, 0xF8, 0xF2, 0xF4, 0xF6, 0xF3, 0xFE, 0xFB, 0x74, 0x62, 0x69, 0x5F, 0x5A, -0x66, 0x5B, 0x5D, 0x70, 0x61, 0x78, 0xED, 0xF4, 0xDB, 0xD7, 0xD0, 0xCB, 0xC9, 0xC3, 0xCC, 0xC9, -0xC4, 0xDD, 0xD2, 0xD7, 0x59, 0x6E, 0x57, 0x45, 0x4B, 0x45, 0x3F, 0x43, 0x44, 0x43, 0x49, 0x51, -0x4F, 0x5E, 0xFB, 0x70, 0xDE, 0xD8, 0xDC, 0xD1, 0xD2, 0xD7, 0xD4, 0xD6, 0xDD, 0xDF, 0xDF, 0xF1, -0xF2, 0xF2, 0x6F, 0x73, 0x72, 0x69, 0x6D, 0x6F, 0x6D, 0x72, 0x7B, 0x79, 0x7E, 0xF8, 0xFD, 0xF9, -0xF6, 0xFD, 0xFA, 0xFA, 0xFD, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF8, 0xF3, 0xF2, 0xF4, 0xEF, 0xF1, -0xF4, 0xF2, 0xF6, 0xF9, 0xF8, 0xF9, 0xFD, 0xFD, 0xFC, 0x7F, 0x7E, 0x7D, 0x79, 0x76, 0x74, 0x71, -0x6F, 0x6E, 0x6C, 0x6C, 0x6D, 0x6B, 0x6C, 0x6D, 0x6C, 0x71, 0x71, 0x70, 0x7E, 0x79, 0x7C, 0xFA, -0x7B, 0xFD, 0xFC, 0x7A, 0xFE, 0x7C, 0x78, 0x7B, 0x76, 0x76, 0x78, 0x77, 0x77, 0x7C, 0x7E, 0xFF, -0xF2, 0xF3, 0xED, 0xE7, 0xE8, 0xE0, 0xDE, 0xDC, 0xD7, 0xD8, 0xD3, 0xD4, 0xDA, 0xD7, 0xDF, 0xEB, -0xED, 0x6A, 0x60, 0x5C, 0x52, 0x4F, 0x4D, 0x4B, 0x4A, 0x4B, 0x4B, 0x4D, 0x50, 0x54, 0x5B, 0x66, -0x6F, 0xF1, 0xE6, 0xDF, 0xDA, 0xD8, 0xD8, 0xD7, 0xD9, 0xDB, 0xDE, 0xE2, 0xEA, 0xF1, 0xFA, 0x78, -0x70, 0x6D, 0x69, 0x68, 0x66, 0x65, 0x65, 0x66, 0x66, 0x67, 0x6A, 0x6B, 0x6C, 0x70, 0x74, 0x79, -0xFB, 0xF5, 0xEF, 0xEB, 0xE9, 0xE6, 0xE3, 0xE2, 0xE1, 0xE0, 0xE0, 0xE0, 0xE1, 0xE3, 0xE3, 0xE6, -0xE9, 0xEB, 0xEF, 0xF7, 0x7F, 0x75, 0x6E, 0x6A, 0x66, 0x62, 0x61, 0x5F, 0x5F, 0x60, 0x5F, 0x62, -0x65, 0x66, 0x6C, 0x6E, 0x72, 0x7D, 0xFE, 0xF6, 0xEF, 0xED, 0xE9, 0xE7, 0xE4, 0xE3, 0xE0, 0xDF, -0xE1, 0xDF, 0xE1, 0xE3, 0xE3, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xF5, 0xF6, 0xF9, 0x75, -0x76, 0x6E, 0x66, 0x65, 0x5E, 0x5B, 0x5A, 0x56, 0x55, 0x54, 0x53, 0x54, 0x55, 0x57, 0x59, 0x5D, -0x60, 0x66, 0x70, 0x79, 0xFA, 0xF0, 0xEE, 0xEC, 0xED, 0xED, 0xF0, 0xF5, 0xF8, 0xFF, 0xFD, 0x7E, -0x7D, 0xFE, 0x7E, 0xFD, 0xF8, 0xF6, 0xEF, 0xED, 0xEB, 0xE8, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDC, -0xDD, 0xDC, 0xDD, 0xE1, 0xE2, 0xE9, 0xF3, 0x7A, 0x65, 0x61, 0x5B, 0x56, 0x56, 0x51, 0x50, 0x52, -0x50, 0x55, 0x58, 0x59, 0x5F, 0x68, 0x70, 0xFC, 0xEE, 0xE9, 0xE4, 0xE1, 0xE4, 0xE4, 0xE7, 0xED, -0xEE, 0xF8, 0xFF, 0x7D, 0x76, 0x76, 0x7A, 0x7B, 0xFF, 0xF9, 0xF7, 0xF1, 0xED, 0xED, 0xEB, 0xE9, -0xEA, 0xEA, 0xEC, 0xED, 0xEE, 0xF0, 0xF1, 0xF2, 0xF2, 0xF3, 0xF0, 0xF1, 0xF3, 0xEF, 0xF3, 0xF5, -0xF4, 0xFB, 0xFC, 0xFC, 0x7C, 0x7A, 0x76, 0x70, 0x6F, 0x6F, 0x6C, 0x6C, 0x6C, 0x68, 0x6B, 0x6B, -0x68, 0x6D, 0x6B, 0x6B, 0x6F, 0x6E, 0x70, 0x77, 0x76, 0x7A, 0x7F, 0xFF, 0xFD, 0xF6, 0xF7, 0xF5, -0xEF, 0xF4, 0xF1, 0xEF, 0xF2, 0xEE, 0xF0, 0xF1, 0xEE, 0xF0, 0xF1, 0xF1, 0xF2, 0xF6, 0xF9, 0xFA, -0x7F, 0x7E, 0x7A, 0x76, 0x7A, 0x73, 0x72, 0x74, 0x6F, 0x73, 0x75, 0x73, 0x75, 0x74, 0x76, 0x73, -0x77, 0x7A, 0x76, 0x7E, 0x78, 0x76, 0x7E, 0x76, 0x7A, 0x79, 0x74, 0x7D, 0x77, 0x77, 0x79, 0x74, -0x76, 0x77, 0x7A, 0x79, 0x7C, 0xFF, 0x79, 0xFC, 0xFA, 0x7E, 0xF4, 0xF9, 0xFC, 0xF6, 0x7E, 0xFF, -0xFF, 0x7B, 0x7C, 0x77, 0x75, 0x76, 0x78, 0x76, 0x74, 0x7B, 0x74, 0x75, 0x7E, 0x74, 0x7B, 0x7C, -0x72, 0x7A, 0x77, 0x74, 0x7A, 0x75, 0x72, 0x73, 0x72, 0x6E, 0x6E, 0x70, 0x6D, 0x70, 0x71, 0x6E, -0x75, 0x73, 0x72, 0x79, 0x78, 0x7B, 0xFF, 0xFF, 0xFD, 0xFA, 0xFC, 0xFB, 0xF7, 0xFD, 0xFE, 0xFA, -0x7D, 0x7D, 0xFE, 0x79, 0x7B, 0x7C, 0x7B, 0x7E, 0x7E, 0xFD, 0xFA, 0xFA, 0xF7, 0xF8, 0xF9, 0xF9, -0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x7D, 0x7B, 0x77, 0x78, 0x74, 0x71, 0x74, 0x6F, 0x6F, 0x71, 0x6D, -0x6F, 0x71, 0x6F, 0x73, 0x74, 0x77, 0x7B, 0x7D, 0x7F, 0xFF, 0xFC, 0xFE, 0xFB, 0xF8, 0xFB, 0xF7, -0xF9, 0xFE, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7E, 0x7B, 0x7B, 0x7E, 0x7C, 0xFF, 0xFE, -0xFE, 0xFB, 0xFE, 0xFF, 0xFD, 0xFE, 0x7E, 0x7F, 0x7A, 0x78, 0x79, 0x75, 0x74, 0x75, 0x73, 0x75, -0x77, 0x77, 0x79, 0x7B, 0x7D, 0xFF, 0xFA, 0xF8, 0xF4, 0xF2, 0xF5, 0xF1, 0xF2, 0xF6, 0xF3, 0xF6, -0xFA, 0xFB, 0xFC, 0x7D, 0x7A, 0x7A, 0x74, 0x77, 0x78, 0x74, 0x7A, 0x77, 0x7A, 0xFF, 0x7F, 0xF9, -0xFB, 0xFB, 0xF9, 0xFF, 0x7F, 0x7C, 0x7A, 0x77, 0x72, 0x73, 0x6E, 0x6E, 0x6E, 0x6D, 0x70, 0x70, -0x75, 0x7D, 0x7B, 0xFE, 0xFD, 0xFF, 0xFC, 0xFF, 0x7E, 0xFF, 0x7E, 0x7A, 0x79, 0x76, 0x6F, 0x72, -0x72, 0x6F, 0x73, 0x6F, 0x6E, 0x74, 0x72, 0x74, 0x7C, 0x7C, 0xFF, 0xF9, 0xFA, 0xF9, 0xF5, 0xF7, -0xF7, 0xF5, 0xFA, 0xFA, 0xF7, 0xFA, 0xF9, 0xF8, 0xFC, 0xF9, 0xF8, 0xFA, 0xF6, 0xF9, 0xFC, 0xFA, -0xFD, 0xFE, 0xFD, 0xFF, 0x7E, 0x7E, 0x7D, 0x7A, 0x7C, 0x7B, 0x79, 0x7C, 0x7B, 0x7B, 0xFF, 0x7E, -0xFF, 0xFC, 0xFE, 0xFE, 0xFB, 0xFD, 0x7C, 0x7F, 0x7F, 0x76, 0x78, 0x78, 0x74, 0x78, 0x78, 0x78, -0x7B, 0x7A, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x78, 0x7A, 0x7B, 0x7A, 0x7C, 0x7F, 0x7D, 0xFF, 0xFC, -0xFD, 0xFA, 0xFB, 0xFD, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x7B, 0x7D, 0x7D, 0x7E, 0x7E, 0x7D, -0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, -0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, 0xFD, 0xFF, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x77, 0x78, -0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFC, 0xFC, 0xFC, -0xFE, 0xFF, 0xFF, 0x7E, 0x7B, 0x78, 0x77, 0x76, 0x74, 0x73, 0x73, 0x71, 0x72, 0x73, 0x73, 0x74, -0x75, 0x76, 0x77, 0x77, 0x78, 0x78, 0x7A, 0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0x7F, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7A, -0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7A, 0x7A, 0x79, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, -0x74, 0x77, 0x79, 0x7A, 0x7D, 0x7F, 0xFE, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFF, -0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4C, 0x49, 0x53, 0x54, 0x4A, 0x00, -0x00, 0x00, 0x49, 0x4E, 0x46, 0x4F, 0x49, 0x53, 0x46, 0x54, 0x3E, 0x00, 0x00, 0x00, 0x46, 0x69, -0x6C, 0x65, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x6F, -0x6C, 0x64, 0x57, 0x61, 0x76, 0x65, 0x2E, 0x20, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x57, 0x61, 0x76, -0x65, 0x20, 0x63, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, -0x43, 0x68, 0x72, 0x69, 0x73, 0x20, 0x43, 0x72, 0x61, 0x69, 0x67, 0x00 - -}; - -static const uint8_t shaun_png[] PROGMEM = { - 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x08, 0x06, 0x00, 0x00, 0x00, 0xF2, 0x0C, 0xE0, - 0x57, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4B, 0x47, 0x44, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xA0, - 0xBD, 0xA7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x42, 0x8A, 0x00, - 0x00, 0x42, 0x8A, 0x01, 0x34, 0xA8, 0x6C, 0x25, 0x00, 0x00, 0x00, 0x09, 0x76, 0x70, 0x41, 0x67, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x00, 0x73, 0x4D, 0x3B, 0xD6, 0x00, 0x00, 0x1B, - 0x47, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0xED, 0x9D, 0x79, 0x74, 0x14, 0x55, 0xBE, 0xC7, 0x3F, - 0x55, 0xDD, 0x49, 0x67, 0x5F, 0x3A, 0x7B, 0x42, 0x82, 0x61, 0x49, 0x02, 0x81, 0xB0, 0x29, 0x32, - 0x22, 0x3C, 0x16, 0x41, 0x45, 0x10, 0x15, 0x7D, 0x13, 0x65, 0xD0, 0x81, 0xE3, 0x7B, 0xCC, 0xD3, - 0x51, 0x04, 0xF5, 0xE1, 0xB8, 0xCE, 0xE6, 0x28, 0x22, 0x23, 0x33, 0x2C, 0x2A, 0x22, 0xEE, 0x02, - 0x22, 0x0C, 0x2A, 0x83, 0x28, 0x7B, 0x20, 0xC8, 0x92, 0x10, 0xD9, 0x97, 0x40, 0x08, 0x81, 0x90, - 0x3D, 0x64, 0x21, 0xE9, 0x4E, 0x3A, 0x5D, 0xF7, 0xFD, 0x71, 0xBB, 0x93, 0x0E, 0x10, 0xD2, 0x59, - 0x3A, 0x01, 0xCF, 0xFB, 0x9E, 0xD3, 0xE7, 0xA4, 0x6E, 0xA5, 0x6E, 0xDD, 0xFA, 0xFD, 0xEA, 0xFE, - 0xEE, 0xEF, 0xFE, 0xB6, 0x52, 0xB8, 0xFE, 0xA1, 0x03, 0x7A, 0x01, 0x43, 0x81, 0x9B, 0x80, 0x6A, - 0x60, 0x3F, 0xA0, 0x02, 0x8F, 0x00, 0xB7, 0x03, 0xA1, 0x80, 0x00, 0x72, 0x81, 0xAD, 0xC0, 0xC7, - 0xC0, 0x6E, 0xA0, 0xAE, 0xB3, 0x07, 0xFF, 0x4B, 0x43, 0x30, 0xF0, 0x67, 0x20, 0x1B, 0xB0, 0x20, - 0x89, 0xAE, 0x01, 0x95, 0x40, 0xB9, 0xED, 0xF8, 0x6A, 0xBF, 0x3C, 0xDB, 0x75, 0x81, 0xCD, 0xF4, - 0xAF, 0x03, 0x8C, 0x40, 0x2C, 0xD0, 0x13, 0x88, 0x00, 0x0C, 0x9D, 0xF9, 0xC0, 0x4A, 0x27, 0xDD, - 0xD7, 0x13, 0x88, 0x07, 0xFA, 0x03, 0x51, 0x36, 0x22, 0xE4, 0x03, 0x87, 0x80, 0x83, 0x48, 0x62, - 0x1B, 0x81, 0x85, 0x40, 0x72, 0x2B, 0xC7, 0xA9, 0x01, 0x5F, 0x00, 0x2F, 0x03, 0x35, 0xB6, 0xE3, - 0x0A, 0xDB, 0xDF, 0xDE, 0xC0, 0x48, 0x60, 0x22, 0x30, 0x08, 0xC9, 0x78, 0x3D, 0x92, 0xD1, 0x99, - 0xC0, 0x0F, 0xC0, 0x5A, 0xE0, 0x5C, 0x47, 0x13, 0xA6, 0xA3, 0x19, 0xA2, 0x07, 0x46, 0x00, 0x4F, - 0x22, 0x45, 0x4D, 0xD0, 0x65, 0x63, 0xB8, 0x84, 0x14, 0x47, 0xEF, 0x03, 0x09, 0xC0, 0x4B, 0x48, - 0xD1, 0x44, 0x40, 0x40, 0x00, 0x31, 0x31, 0x31, 0x54, 0x56, 0x56, 0x92, 0x93, 0x93, 0x83, 0xD5, - 0x6A, 0x25, 0x3A, 0x3A, 0x9A, 0x89, 0x13, 0x27, 0x32, 0x60, 0xC0, 0x00, 0xAC, 0x56, 0x2B, 0xBB, - 0x77, 0xEF, 0x66, 0xDD, 0xBA, 0x75, 0x14, 0x16, 0x16, 0xDA, 0xFB, 0xAB, 0x03, 0x4E, 0x23, 0x67, - 0x4D, 0x9D, 0x8D, 0xC0, 0xFB, 0x90, 0x22, 0xF0, 0x1E, 0xC0, 0xAB, 0x89, 0x71, 0x6A, 0xC0, 0x11, - 0xE0, 0x0D, 0xE0, 0x6B, 0xE4, 0xEC, 0xFC, 0xC5, 0xC1, 0x07, 0x78, 0x0D, 0x28, 0xA5, 0x69, 0x51, - 0x63, 0xFF, 0x99, 0x80, 0x2A, 0xFB, 0xF1, 0xC0, 0x81, 0x03, 0xC5, 0xA6, 0x4D, 0x9B, 0x44, 0x49, - 0x49, 0x89, 0xC8, 0xCA, 0xCA, 0x12, 0xAF, 0xBF, 0xFE, 0xBA, 0x78, 0xFC, 0xF1, 0xC7, 0x45, 0x5A, - 0x5A, 0x9A, 0xD0, 0x34, 0x4D, 0xD8, 0x51, 0x57, 0x57, 0x27, 0xB6, 0x6E, 0xDD, 0x2A, 0xFA, 0xF7, - 0xEF, 0xDF, 0x5C, 0xFF, 0x8D, 0x7E, 0x8A, 0xA2, 0x08, 0x55, 0x55, 0xAF, 0x76, 0xAE, 0x02, 0x78, - 0x0E, 0xF9, 0x22, 0x75, 0x08, 0x3A, 0x6A, 0x86, 0x78, 0x02, 0x7F, 0x05, 0x9E, 0x02, 0xDC, 0x00, - 0x14, 0x45, 0x21, 0x24, 0x24, 0x84, 0xE8, 0xE8, 0x68, 0xDC, 0xDD, 0xDD, 0xB9, 0x70, 0xE1, 0x02, - 0xB9, 0xB9, 0xB9, 0xD4, 0xD5, 0x35, 0x5E, 0x87, 0xBD, 0xBC, 0xBC, 0x58, 0xB1, 0x62, 0x05, 0x13, - 0x26, 0x4C, 0xA8, 0x6F, 0x13, 0x42, 0x20, 0x84, 0x40, 0x55, 0xD5, 0xAB, 0xDE, 0x6C, 0xD7, 0xAE, - 0x5D, 0x3C, 0xFC, 0xF0, 0xC3, 0xE4, 0xE4, 0xE4, 0x34, 0xFD, 0xE0, 0x8A, 0x42, 0x7C, 0x7C, 0x3C, - 0xF7, 0xDC, 0x73, 0x0F, 0xFD, 0xFA, 0xF5, 0xC3, 0xC3, 0xC3, 0x83, 0xEC, 0xEC, 0x6C, 0x36, 0x6C, - 0xD8, 0x40, 0x6A, 0x6A, 0x2A, 0x35, 0x35, 0x35, 0xF6, 0x7F, 0xAD, 0xB4, 0x8D, 0xFB, 0x73, 0xC0, - 0xDA, 0x41, 0xF4, 0x72, 0x39, 0x7E, 0x8F, 0x7C, 0xEB, 0x05, 0x20, 0xC2, 0xC2, 0xC2, 0xC4, 0x2B, - 0xAF, 0xBC, 0x22, 0x0E, 0x1E, 0x3C, 0x28, 0x2E, 0x5E, 0xBC, 0x28, 0x2A, 0x2A, 0x2A, 0x44, 0x56, - 0x56, 0x96, 0x58, 0xBC, 0x78, 0xB1, 0x48, 0x48, 0x48, 0x68, 0xF4, 0x96, 0xC6, 0xC4, 0xC4, 0x88, - 0x33, 0x67, 0xCE, 0x88, 0x96, 0xE2, 0xE3, 0x8F, 0x3F, 0x16, 0x77, 0xDE, 0x79, 0xA7, 0x78, 0xFE, - 0xF9, 0xE7, 0xC5, 0xBB, 0xEF, 0xBE, 0x2B, 0xDE, 0x7E, 0xFB, 0x6D, 0xF1, 0xE0, 0x83, 0x0F, 0x0A, - 0xA3, 0xD1, 0x28, 0xDC, 0xDC, 0xDC, 0xC4, 0xD4, 0xA9, 0x53, 0xC5, 0xE9, 0xD3, 0xA7, 0xAF, 0xB8, - 0xAE, 0xA2, 0xA2, 0x42, 0x2C, 0x58, 0xB0, 0x40, 0x04, 0x07, 0x07, 0x3B, 0x8E, 0xA3, 0x00, 0x58, - 0x0D, 0xFC, 0x0E, 0x08, 0xEF, 0x6C, 0x62, 0xB6, 0x15, 0x7D, 0x80, 0x33, 0xF6, 0x87, 0x8B, 0x8D, - 0x8D, 0x15, 0xEB, 0xD7, 0xAF, 0x6F, 0x24, 0x6A, 0x1C, 0x91, 0x91, 0x91, 0x21, 0x06, 0x0F, 0x1E, - 0x2C, 0x00, 0x61, 0x30, 0x18, 0xC4, 0xAF, 0x7F, 0xFD, 0x6B, 0x51, 0x51, 0x51, 0xD1, 0x62, 0x86, - 0x58, 0xAD, 0x56, 0x61, 0x36, 0x9B, 0x1B, 0xDD, 0xA7, 0xA6, 0xA6, 0x46, 0xEC, 0xD8, 0xB1, 0x43, - 0xAC, 0x5A, 0xB5, 0x4A, 0x94, 0x97, 0x97, 0x37, 0x79, 0xAD, 0xA6, 0x69, 0x62, 0xF1, 0xE2, 0xC5, - 0xC2, 0xC3, 0xC3, 0xE3, 0x72, 0x11, 0x66, 0x05, 0x76, 0x02, 0x43, 0x3A, 0x9B, 0xA8, 0x6D, 0xC1, - 0xDB, 0xF6, 0x07, 0xF2, 0xF5, 0xF5, 0x15, 0x2B, 0x56, 0xAC, 0x68, 0x96, 0x98, 0xC7, 0x8E, 0x1D, - 0x13, 0xF3, 0xE7, 0xCF, 0x17, 0x1B, 0x36, 0x6C, 0x10, 0xA5, 0xA5, 0xA5, 0x2D, 0x66, 0x46, 0x7B, - 0xA0, 0xB2, 0xB2, 0x52, 0x4C, 0x98, 0x30, 0xA1, 0xA9, 0x75, 0xE7, 0x00, 0x52, 0x31, 0x68, 0x77, - 0xB8, 0x7A, 0x0D, 0x89, 0x02, 0x36, 0xDA, 0x07, 0x3F, 0x79, 0xF2, 0x64, 0x3E, 0xFC, 0xF0, 0x43, - 0x0C, 0x86, 0x4E, 0x55, 0xF5, 0x9D, 0xC6, 0xC1, 0x83, 0x07, 0x59, 0xBB, 0x76, 0x2D, 0x16, 0x8B, - 0x85, 0x94, 0x94, 0x14, 0x52, 0x53, 0x53, 0xB1, 0x5A, 0xEB, 0x97, 0x91, 0xF7, 0x91, 0xDA, 0xE2, - 0x0D, 0xB5, 0xAE, 0x8C, 0x07, 0xCC, 0x80, 0xF0, 0xF4, 0xF4, 0x14, 0xEB, 0xD6, 0xAD, 0xEB, 0x94, - 0xB7, 0xBD, 0x3D, 0x50, 0x54, 0x54, 0x24, 0x92, 0x93, 0x93, 0x1D, 0x67, 0x49, 0x36, 0xD0, 0xBD, - 0xB3, 0x09, 0xDC, 0x12, 0x84, 0x00, 0xAB, 0xEC, 0x0F, 0x10, 0x1F, 0x1F, 0x2F, 0x72, 0x73, 0x73, - 0x3B, 0x9B, 0xAE, 0x6D, 0xC2, 0x96, 0x2D, 0x5B, 0x84, 0x8F, 0x8F, 0x8F, 0xA3, 0x6A, 0x7E, 0x47, - 0x7B, 0x13, 0x4D, 0x6D, 0x7B, 0x17, 0x57, 0x85, 0x37, 0x72, 0x53, 0x35, 0xC9, 0xDE, 0xD0, 0xAD, - 0x5B, 0x37, 0x8C, 0x46, 0xA3, 0x8B, 0x6E, 0xD7, 0x31, 0xF0, 0xF5, 0xF5, 0x45, 0xAF, 0xAF, 0xDF, - 0x92, 0xA8, 0x80, 0x47, 0x7B, 0xDF, 0xC3, 0x55, 0x0C, 0xF9, 0x4F, 0xE0, 0x37, 0xD8, 0xD6, 0xA8, - 0x84, 0x84, 0x04, 0x9E, 0x7E, 0xFA, 0x69, 0x3C, 0x3C, 0xDA, 0x7D, 0xFC, 0x1D, 0x8A, 0x5D, 0xBB, - 0x76, 0x51, 0x56, 0x56, 0x66, 0x3F, 0xAC, 0x42, 0xDA, 0xCC, 0xDA, 0x15, 0xAE, 0xD8, 0x81, 0x1A, - 0x81, 0xC7, 0xB1, 0x19, 0xE9, 0x12, 0x12, 0x12, 0xF8, 0xEC, 0xB3, 0xCF, 0xB8, 0xF9, 0xE6, 0x9B, - 0x5D, 0x44, 0xA6, 0x8E, 0x43, 0x5E, 0x5E, 0x23, 0xFA, 0x0B, 0x5C, 0xF7, 0x42, 0xB7, 0x2B, 0x46, - 0x21, 0x6D, 0x52, 0x42, 0xAF, 0xD7, 0x8B, 0x25, 0x4B, 0x96, 0x74, 0xB6, 0xE8, 0x6F, 0x37, 0xEC, - 0xDD, 0xBB, 0x57, 0x84, 0x86, 0x86, 0x3A, 0x2E, 0xEC, 0xB3, 0xDB, 0x9B, 0x78, 0xAE, 0xE0, 0x70, - 0x12, 0x72, 0x0D, 0xA1, 0x6B, 0xD7, 0xAE, 0x8C, 0x1D, 0x3B, 0xD6, 0x85, 0xBC, 0xEF, 0x58, 0x24, - 0x25, 0x25, 0x31, 0x64, 0x48, 0xA3, 0x3D, 0xE1, 0x2D, 0xB4, 0xB3, 0x94, 0x71, 0x05, 0x43, 0x22, - 0xED, 0x7F, 0x44, 0x47, 0x47, 0x13, 0x12, 0x12, 0xE2, 0x1A, 0xEA, 0x74, 0x02, 0x0C, 0x06, 0x03, - 0x89, 0x89, 0x89, 0x8E, 0x4D, 0x51, 0x48, 0x3B, 0x5D, 0xBB, 0xC1, 0x15, 0x0C, 0xA9, 0xEF, 0x53, - 0xA7, 0xD3, 0x35, 0x69, 0x00, 0xBC, 0x51, 0xE1, 0xEB, 0xEB, 0xEB, 0x78, 0x68, 0xE0, 0x06, 0x98, - 0x21, 0xF5, 0xCE, 0x88, 0xBC, 0xBC, 0x3C, 0x47, 0xAD, 0xE4, 0x17, 0x81, 0xD2, 0xD2, 0x52, 0xC7, - 0xC3, 0x6A, 0xDA, 0xD9, 0x57, 0xE2, 0x0A, 0x86, 0x1C, 0x46, 0xEE, 0xCE, 0xC9, 0xCA, 0xCA, 0x22, - 0x35, 0x35, 0xD5, 0x65, 0xC4, 0xE9, 0x68, 0x54, 0x55, 0x55, 0x91, 0x91, 0x91, 0xE1, 0xD8, 0x94, - 0x8D, 0x64, 0xCA, 0x75, 0x8D, 0x70, 0xE0, 0x67, 0x6C, 0x9A, 0xC8, 0xD0, 0xA1, 0x43, 0x45, 0x76, - 0x76, 0x76, 0x67, 0x2B, 0x48, 0xED, 0x82, 0x1F, 0x7E, 0xF8, 0x41, 0xF8, 0xF9, 0xF9, 0x39, 0x6A, - 0x59, 0x4F, 0x74, 0x36, 0xB1, 0x9D, 0xC5, 0x73, 0x48, 0xA3, 0x9B, 0x00, 0xC4, 0xC8, 0x91, 0x23, - 0xC5, 0x8F, 0x3F, 0xFE, 0x28, 0xCC, 0x66, 0xB3, 0xCB, 0x88, 0x65, 0xB5, 0x5A, 0x5D, 0xCA, 0x8C, - 0xAC, 0xAC, 0x2C, 0x31, 0x6C, 0xD8, 0x30, 0x47, 0x66, 0x64, 0x01, 0x71, 0x9D, 0x4D, 0x68, 0x67, - 0x61, 0x04, 0xD6, 0x39, 0x0C, 0x5E, 0xF8, 0xF8, 0xF8, 0x88, 0x05, 0x0B, 0x16, 0xB8, 0x84, 0x58, - 0x99, 0x99, 0x99, 0x62, 0xFA, 0xF4, 0xE9, 0x62, 0xD9, 0xB2, 0x65, 0xC2, 0x64, 0x32, 0x5D, 0x71, - 0x5E, 0xD3, 0x34, 0x71, 0xEE, 0xDC, 0x39, 0x91, 0x97, 0x97, 0xD7, 0xAA, 0xFE, 0x4F, 0x9E, 0x3C, - 0x29, 0x46, 0x8C, 0x18, 0x71, 0xB9, 0x09, 0xFE, 0xF5, 0xCE, 0x26, 0xB2, 0xB3, 0x08, 0x46, 0x5A, - 0x79, 0x1B, 0x31, 0x04, 0x10, 0x49, 0x49, 0x49, 0x22, 0x27, 0x27, 0xA7, 0x5D, 0x99, 0x61, 0xB5, - 0x5A, 0xC5, 0x8C, 0x19, 0x33, 0x04, 0x20, 0xBC, 0xBC, 0xBC, 0xC4, 0xA3, 0x8F, 0x3E, 0x2A, 0x36, - 0x6F, 0xDE, 0x2C, 0xCE, 0x9F, 0x3F, 0x2F, 0x0A, 0x0B, 0x0B, 0xC5, 0xE1, 0xC3, 0x87, 0xC5, 0xDC, - 0xB9, 0x73, 0x45, 0x42, 0x42, 0x82, 0x18, 0x33, 0x66, 0x8C, 0x28, 0x28, 0x28, 0x68, 0xF1, 0x3D, - 0x96, 0x2E, 0x5D, 0x7A, 0x39, 0x33, 0x34, 0x60, 0x3B, 0xF0, 0xDF, 0x40, 0x37, 0x64, 0x38, 0xD1, - 0x75, 0x87, 0x28, 0xA4, 0xEF, 0x79, 0x2F, 0x36, 0x93, 0x3B, 0x57, 0x09, 0x26, 0x98, 0x35, 0x6B, - 0x56, 0xBB, 0x8A, 0xAE, 0x6D, 0xDB, 0xB6, 0x89, 0xD0, 0xD0, 0x50, 0xE1, 0xED, 0x69, 0x10, 0xE1, - 0xC1, 0x01, 0x02, 0x10, 0x9E, 0x5E, 0x5E, 0xA2, 0x5B, 0xB7, 0xEE, 0xA2, 0x57, 0xAF, 0x5E, 0x22, - 0x38, 0x24, 0x44, 0x28, 0x8A, 0x22, 0x00, 0xE1, 0xE6, 0xE6, 0x26, 0x3E, 0xFA, 0xE8, 0xA3, 0x16, - 0xDF, 0x63, 0xCD, 0x9A, 0x35, 0x42, 0xAF, 0xD7, 0x5F, 0xCD, 0x51, 0x55, 0x87, 0x14, 0x5D, 0x0B, - 0x80, 0x5B, 0x01, 0xF7, 0xB6, 0x12, 0xB1, 0x3D, 0x38, 0x1B, 0x0A, 0x4C, 0x07, 0xE6, 0x21, 0x0D, - 0x8A, 0x5D, 0x70, 0xD0, 0xCD, 0x75, 0x3A, 0x1D, 0xE1, 0xE1, 0xE1, 0x24, 0x25, 0x25, 0x61, 0x36, - 0x9B, 0x49, 0x4D, 0x4D, 0xC5, 0x64, 0x32, 0xD1, 0xB7, 0x6F, 0x5F, 0x7C, 0x7C, 0x7C, 0x00, 0x19, - 0xB4, 0x50, 0x50, 0x50, 0x40, 0x59, 0x59, 0x19, 0xBE, 0xBE, 0xBE, 0x28, 0x8A, 0x73, 0x7E, 0xB3, - 0xEC, 0xEC, 0x6C, 0x9E, 0x7E, 0xFA, 0x69, 0x8E, 0x1D, 0x3B, 0xC6, 0x8C, 0x87, 0xC7, 0x31, 0x77, - 0xC6, 0x14, 0x02, 0xFD, 0x7C, 0xA8, 0xAA, 0x36, 0x51, 0x5A, 0x5A, 0x42, 0x65, 0x45, 0x39, 0x81, - 0x3E, 0x06, 0xEE, 0xFC, 0x55, 0x7F, 0x86, 0x0D, 0x48, 0x20, 0xFD, 0xE8, 0x69, 0xB2, 0xB3, 0xCF, - 0x72, 0xC7, 0x1D, 0x77, 0xB4, 0xC8, 0xF2, 0xBC, 0x7E, 0xFD, 0x7A, 0x36, 0x6C, 0xD8, 0x80, 0x9F, - 0x9F, 0x1F, 0x3A, 0x9D, 0x0E, 0x8B, 0xA5, 0x5E, 0xD3, 0x55, 0x91, 0xC1, 0x78, 0x83, 0x81, 0xFB, - 0x81, 0xDE, 0x40, 0x11, 0xD2, 0xE8, 0xA8, 0xB5, 0x03, 0x6D, 0x5B, 0x04, 0x37, 0xA4, 0x68, 0x4A, - 0x45, 0xBE, 0x29, 0x8D, 0x66, 0x42, 0x97, 0x2E, 0x5D, 0xC4, 0x23, 0x8F, 0x3C, 0x22, 0x3E, 0xF9, - 0xE4, 0x13, 0x71, 0xEC, 0xD8, 0x31, 0x51, 0x55, 0x55, 0x25, 0x5E, 0x7A, 0xE9, 0x25, 0x01, 0x08, - 0x9D, 0x4E, 0x27, 0x06, 0x0E, 0x1A, 0x24, 0x66, 0xCF, 0x9E, 0x2D, 0xE6, 0xCF, 0x9F, 0x2F, 0x66, - 0xCE, 0x9C, 0x29, 0xFA, 0xF4, 0xE9, 0x23, 0x7A, 0xF7, 0xEE, 0x2D, 0xD6, 0xAC, 0x59, 0xE3, 0xD4, - 0x02, 0x9D, 0x99, 0x99, 0x29, 0xC6, 0x8D, 0x1B, 0x27, 0x95, 0x86, 0x9B, 0x13, 0x45, 0xEE, 0x86, - 0x25, 0x42, 0x64, 0xAC, 0x16, 0x5A, 0xFA, 0x2A, 0x51, 0xB6, 0xED, 0x63, 0x71, 0xFA, 0x9B, 0x05, - 0xE2, 0xF8, 0xD7, 0xF3, 0xC5, 0x85, 0x0D, 0xEF, 0x0B, 0xCB, 0xDE, 0x15, 0xA2, 0x74, 0xFB, 0x27, - 0x62, 0xFC, 0xB0, 0x41, 0x02, 0x10, 0x77, 0xDF, 0x7D, 0xB7, 0x38, 0x7A, 0xF4, 0x68, 0xA3, 0xFE, - 0x34, 0x4D, 0x13, 0xFB, 0xF7, 0xEF, 0x17, 0x6F, 0xBD, 0xF5, 0x96, 0xD8, 0xBD, 0x7B, 0xB7, 0xB0, - 0x58, 0x2C, 0xC2, 0x62, 0xB1, 0x88, 0x6D, 0xDB, 0xB6, 0x89, 0xB8, 0xB8, 0x38, 0xE1, 0xEE, 0xEE, - 0x2E, 0xDE, 0x7B, 0xEF, 0x3D, 0xB1, 0x69, 0xD3, 0x26, 0xF1, 0xDC, 0x73, 0xCF, 0x89, 0x7E, 0xFD, - 0xFA, 0x09, 0x77, 0x77, 0xF7, 0xAB, 0xCD, 0x9A, 0x12, 0xE0, 0x03, 0x64, 0x10, 0x60, 0x87, 0xC5, - 0xBD, 0x45, 0x20, 0x67, 0x44, 0x99, 0xE3, 0x60, 0x74, 0x3A, 0x9D, 0x48, 0x4A, 0x4A, 0x12, 0x6F, - 0xBE, 0xF9, 0xA6, 0x38, 0x76, 0xEC, 0x98, 0xB0, 0x58, 0x2C, 0xF5, 0x0F, 0x6C, 0x32, 0x99, 0xC4, - 0xA4, 0x49, 0x93, 0x04, 0x20, 0xBA, 0x84, 0x1A, 0x85, 0xA7, 0xC1, 0xAD, 0xD1, 0x83, 0x78, 0xB8, - 0xBB, 0x09, 0x9D, 0xAA, 0x8A, 0xA0, 0xA0, 0x20, 0xF1, 0xDA, 0x6B, 0xAF, 0x89, 0xB3, 0x67, 0xCF, - 0x5E, 0x35, 0x10, 0xA2, 0xA2, 0xA2, 0x42, 0xAC, 0x5C, 0xB9, 0x52, 0x0C, 0x18, 0x30, 0x40, 0x00, - 0xE2, 0x96, 0xDE, 0xDD, 0xC5, 0xC1, 0x95, 0x6F, 0x0B, 0xB1, 0xFF, 0x6B, 0x21, 0xD2, 0xBE, 0x92, - 0xBF, 0xF4, 0x55, 0x42, 0xEC, 0x5F, 0x25, 0xDB, 0xD2, 0x57, 0xC9, 0xB6, 0xFD, 0x5F, 0x8B, 0xC3, - 0x5F, 0xFD, 0x5D, 0x0C, 0x4E, 0xEC, 0x21, 0x00, 0xD1, 0xA3, 0x47, 0x0F, 0xF1, 0x87, 0x3F, 0xFC, - 0x41, 0xAC, 0x5A, 0xB5, 0x4A, 0xAC, 0x5C, 0xB9, 0x52, 0xCC, 0x9A, 0x35, 0x4B, 0xC4, 0xC4, 0xC4, - 0x08, 0x40, 0x84, 0x87, 0x87, 0x8B, 0xFB, 0xEE, 0xBB, 0x4F, 0x4C, 0x9C, 0x38, 0xB1, 0xDE, 0x98, - 0x38, 0x79, 0xF2, 0xE4, 0xFA, 0x60, 0x0B, 0x4D, 0xD3, 0x44, 0x7E, 0x7E, 0xBE, 0x58, 0xBE, 0x7C, - 0xB9, 0x18, 0x3F, 0x7E, 0xBC, 0xF0, 0xF5, 0xF5, 0xBD, 0x1A, 0x63, 0xCE, 0x21, 0x8D, 0x8F, 0xC1, - 0x2D, 0x21, 0x6C, 0x4B, 0x39, 0xA8, 0x20, 0x83, 0x9E, 0x5F, 0x07, 0x86, 0x39, 0x5E, 0x1F, 0x17, - 0x17, 0xC7, 0xF4, 0xE9, 0xD3, 0x49, 0x4E, 0x4E, 0x26, 0x32, 0x32, 0xF2, 0x8A, 0x0B, 0x77, 0xEC, - 0xD8, 0xC1, 0x84, 0x09, 0x13, 0xF0, 0xD4, 0x2B, 0x2C, 0xFF, 0xDB, 0x33, 0x58, 0xEA, 0xEA, 0x48, - 0x3B, 0x7A, 0x9A, 0xD2, 0x8A, 0x4B, 0x04, 0x07, 0xF8, 0x31, 0xA8, 0x57, 0x37, 0x52, 0x7F, 0x3E, - 0xCE, 0x3F, 0x96, 0xAF, 0xA7, 0xEC, 0x52, 0x35, 0x71, 0xF1, 0xF1, 0xDC, 0x39, 0x76, 0x2C, 0x03, - 0x07, 0x0E, 0x24, 0x28, 0x28, 0x88, 0xAA, 0xAA, 0x2A, 0x4E, 0x9C, 0x38, 0xC1, 0x96, 0x2D, 0x5B, - 0xD8, 0xB3, 0x67, 0x0F, 0x96, 0xDA, 0x5A, 0xEE, 0xBA, 0xAD, 0x3F, 0x73, 0x9F, 0x99, 0x42, 0xAF, - 0x6E, 0xD1, 0xA0, 0x39, 0x21, 0x21, 0x54, 0x95, 0x13, 0x67, 0xCE, 0xF3, 0xA7, 0x25, 0xAB, 0xF8, - 0x76, 0x7B, 0x1A, 0x55, 0xE6, 0x1A, 0xDB, 0x23, 0x08, 0x00, 0x02, 0x7C, 0xBD, 0x49, 0xEA, 0x19, - 0xC3, 0xD1, 0xAC, 0xF3, 0x14, 0x97, 0x55, 0xA2, 0x28, 0x0A, 0xE1, 0xE1, 0xE1, 0x24, 0x27, 0x27, - 0x33, 0x7B, 0xF6, 0x6C, 0xC2, 0xC2, 0xC2, 0xAE, 0xE8, 0xB2, 0xBA, 0xBA, 0x9A, 0xD4, 0xD4, 0x54, - 0x96, 0x2E, 0x5D, 0xCA, 0xF7, 0xDF, 0x7F, 0x4F, 0x65, 0x65, 0xA5, 0xE3, 0x69, 0x2B, 0xB0, 0x03, - 0xF8, 0x13, 0x90, 0x82, 0x13, 0x62, 0xAC, 0x25, 0x0C, 0x71, 0x03, 0x26, 0x03, 0x7F, 0x41, 0xAE, - 0x13, 0x80, 0xB4, 0xED, 0x4C, 0x99, 0x32, 0x85, 0x99, 0x33, 0x67, 0xD2, 0xA3, 0x47, 0x8F, 0xAB, - 0x5E, 0x28, 0x84, 0x60, 0xC6, 0x8C, 0x19, 0x2C, 0x58, 0xB0, 0x80, 0xA9, 0xF7, 0x8E, 0x64, 0xC9, - 0x2B, 0xBF, 0xB3, 0x79, 0xDE, 0x84, 0xA4, 0x85, 0x22, 0x87, 0x52, 0x67, 0xA9, 0x63, 0xEB, 0xDE, - 0x43, 0xFC, 0x73, 0xE5, 0xF7, 0x6C, 0x4F, 0x3F, 0x42, 0x65, 0xB5, 0x59, 0x0E, 0x52, 0x51, 0x11, - 0x42, 0x3E, 0x8B, 0x5E, 0xA7, 0x92, 0xD8, 0x2D, 0x9A, 0x69, 0x13, 0x47, 0x32, 0xE5, 0x9E, 0xFF, - 0x20, 0xD0, 0xDF, 0xD7, 0x39, 0x66, 0x38, 0x30, 0xA5, 0xDA, 0x64, 0x66, 0xD7, 0x81, 0x13, 0x6C, - 0xD9, 0x77, 0x98, 0xAC, 0xDC, 0x02, 0x54, 0x45, 0xA1, 0x67, 0x4C, 0x04, 0x63, 0x6E, 0x4D, 0x62, - 0x50, 0xAF, 0x6E, 0x7C, 0xBA, 0x6E, 0x3B, 0x4F, 0xCE, 0x59, 0x4A, 0x78, 0x44, 0x24, 0x5F, 0x7E, - 0xF9, 0x25, 0x43, 0x87, 0x0E, 0x45, 0xA7, 0xBB, 0xF6, 0x72, 0x6B, 0x36, 0x9B, 0xD9, 0xB6, 0x6D, - 0x1B, 0x0B, 0x17, 0x2E, 0x64, 0xD3, 0xA6, 0x4D, 0x8E, 0x81, 0x76, 0x20, 0xE3, 0xBA, 0xDE, 0x04, - 0x96, 0xD0, 0xCC, 0xCE, 0xDE, 0x59, 0x86, 0xF8, 0x02, 0xFF, 0x0B, 0x3C, 0x83, 0x0C, 0x09, 0x05, - 0x20, 0x31, 0x31, 0x91, 0x3F, 0xFE, 0xF1, 0x8F, 0xDC, 0x7B, 0xEF, 0xBD, 0xB8, 0xBB, 0x37, 0xAD, - 0x60, 0x9C, 0x39, 0x73, 0x86, 0x31, 0x63, 0xC7, 0x92, 0x9B, 0x73, 0x96, 0x7F, 0xCD, 0x7B, 0x9E, - 0xBB, 0x6E, 0x1F, 0x08, 0xD6, 0x26, 0x88, 0xA8, 0x53, 0xA9, 0xAA, 0x32, 0xF1, 0xF3, 0xF1, 0x33, - 0xEC, 0x3C, 0x70, 0x82, 0xE3, 0xD9, 0xB9, 0x54, 0x5C, 0xAA, 0xC6, 0xD3, 0xC3, 0x40, 0x4C, 0x78, - 0x30, 0x83, 0x13, 0xBB, 0x33, 0xA4, 0x6F, 0x1C, 0xE1, 0x21, 0x81, 0x36, 0xE1, 0x20, 0x9C, 0x67, - 0x86, 0xE3, 0x53, 0xAB, 0x2A, 0x08, 0xD0, 0xEA, 0xAC, 0xA0, 0x80, 0xAA, 0xD3, 0xD5, 0x4F, 0x96, - 0xBC, 0xA2, 0x52, 0xEE, 0x7A, 0xF2, 0xAF, 0x1C, 0x3D, 0x9B, 0xC7, 0x8A, 0xE5, 0xCB, 0x99, 0x34, - 0x69, 0x92, 0xD3, 0x5D, 0x57, 0x56, 0x56, 0xB2, 0x62, 0xC5, 0x0A, 0xE6, 0xCD, 0x9B, 0xC7, 0x89, - 0x13, 0x27, 0x1C, 0x4F, 0xD5, 0x00, 0xCB, 0x80, 0x57, 0x81, 0xE2, 0xB6, 0x30, 0x24, 0x10, 0x29, - 0xA2, 0xFE, 0x0B, 0x9B, 0xF6, 0xA4, 0xD7, 0xEB, 0x79, 0xE0, 0x81, 0x07, 0xF8, 0xF3, 0x9F, 0xFF, - 0x4C, 0x7C, 0x7C, 0x7C, 0xB3, 0x1D, 0x2C, 0x59, 0xB2, 0x84, 0xE9, 0xD3, 0xA7, 0x33, 0x6C, 0x40, - 0x02, 0xDF, 0xBE, 0xF3, 0x02, 0x01, 0xBE, 0xDE, 0xD7, 0x26, 0xA4, 0x9D, 0x60, 0x80, 0xB0, 0x6A, - 0x68, 0x9A, 0x86, 0xAA, 0x28, 0x28, 0x3A, 0x1D, 0x28, 0x8A, 0x9C, 0x11, 0xAD, 0x61, 0x84, 0xB3, - 0x50, 0x14, 0x5E, 0x5A, 0xB4, 0x9C, 0xBF, 0x2D, 0x5B, 0x43, 0x72, 0x72, 0x32, 0x9F, 0x7E, 0xFA, - 0x29, 0x6E, 0x6E, 0x6E, 0x2D, 0xEA, 0x22, 0x33, 0x33, 0x93, 0xD7, 0x5F, 0x7F, 0x9D, 0x15, 0x2B, - 0x56, 0x38, 0xCE, 0x16, 0x0D, 0x19, 0x01, 0x39, 0x13, 0x99, 0xCB, 0x72, 0x05, 0x9A, 0x33, 0x2E, - 0x86, 0x00, 0xFF, 0x40, 0xAA, 0xB5, 0x7A, 0x90, 0x22, 0xEA, 0x85, 0x17, 0x5E, 0x60, 0xC9, 0x92, - 0x25, 0x4E, 0x31, 0xC3, 0x6C, 0x36, 0xB3, 0x6E, 0xDD, 0x3A, 0x00, 0x26, 0x0C, 0xBF, 0x99, 0x00, - 0x7F, 0x9F, 0xE6, 0x89, 0x29, 0x90, 0x33, 0xC8, 0xAA, 0xA1, 0x00, 0x3A, 0x55, 0x95, 0xAA, 0xB0, - 0xA6, 0x81, 0xD5, 0xEA, 0x5A, 0x66, 0x00, 0xA8, 0x0A, 0x13, 0x86, 0x0F, 0x22, 0xC0, 0xD7, 0x8B, - 0x94, 0x94, 0x14, 0x32, 0x33, 0x33, 0x5B, 0xDC, 0x45, 0xCF, 0x9E, 0x3D, 0x59, 0xBC, 0x78, 0x31, - 0x73, 0xE6, 0xCC, 0x71, 0xF4, 0x09, 0xA9, 0xC0, 0x43, 0xC8, 0x7D, 0x4B, 0xC4, 0x55, 0x6F, 0x7D, - 0x8D, 0x3E, 0x8D, 0x34, 0xEC, 0x2D, 0x54, 0x80, 0x90, 0x90, 0x10, 0xDE, 0x79, 0xE7, 0x1D, 0x5E, - 0x7D, 0xF5, 0x55, 0xFC, 0xFD, 0xFD, 0x9D, 0x1A, 0xD8, 0xF1, 0xE3, 0xC7, 0xF9, 0x69, 0xF7, 0x6E, - 0x42, 0x02, 0xFD, 0x18, 0x3B, 0xA4, 0x9F, 0x7D, 0xFD, 0xBC, 0xBE, 0xA1, 0x69, 0xF4, 0xED, 0x11, - 0xC3, 0x2D, 0x89, 0x3D, 0xB8, 0x70, 0xE1, 0x02, 0x5B, 0xB7, 0x6E, 0x6D, 0x55, 0x37, 0x5E, 0x5E, - 0x5E, 0x3C, 0xF5, 0xD4, 0x53, 0x7C, 0xF0, 0xC1, 0x07, 0xC4, 0xC6, 0xC6, 0x3A, 0x9E, 0xBA, 0x1F, - 0x98, 0x03, 0x5C, 0x41, 0xC4, 0xA6, 0x18, 0xE2, 0x89, 0x4C, 0x1D, 0x98, 0x8C, 0x4D, 0xAC, 0x45, - 0x45, 0x45, 0xB1, 0x68, 0xD1, 0x22, 0xA6, 0x4D, 0x9B, 0xD6, 0xA2, 0xE9, 0xBB, 0x7D, 0xFB, 0x76, - 0x8A, 0x8B, 0x8A, 0xB8, 0xB5, 0x4F, 0x4F, 0xE2, 0xBB, 0x46, 0xB6, 0x6C, 0x01, 0xEE, 0x2C, 0x08, - 0xF0, 0xF6, 0xF6, 0x64, 0xDC, 0xD0, 0x01, 0x00, 0x6C, 0xD8, 0xB0, 0x01, 0xB3, 0xD9, 0xDC, 0xAA, - 0xAE, 0x54, 0x55, 0x65, 0xE2, 0xC4, 0x89, 0x2C, 0x5D, 0xBA, 0xF4, 0x72, 0xA5, 0xE7, 0x11, 0xE4, - 0xBA, 0xDC, 0xC8, 0xC1, 0x75, 0x35, 0x86, 0x28, 0xC0, 0xFF, 0x20, 0xC5, 0x94, 0x0A, 0x92, 0x19, - 0xEF, 0xBE, 0xFB, 0x2E, 0x0F, 0x3D, 0xF4, 0x90, 0xD3, 0xBB, 0x68, 0x90, 0xE2, 0x6A, 0xD3, 0xA6, - 0x4D, 0x00, 0x8C, 0x19, 0x92, 0x84, 0x87, 0xE7, 0x8D, 0x11, 0x42, 0x0A, 0x80, 0x80, 0x11, 0x83, - 0x12, 0x09, 0xF2, 0xF7, 0x21, 0x2D, 0x2D, 0x9D, 0xAC, 0xAC, 0xAC, 0x36, 0x75, 0x37, 0x6A, 0xD4, - 0x28, 0x16, 0x2D, 0x5A, 0x44, 0x54, 0x54, 0x94, 0xBD, 0x49, 0x87, 0xCC, 0x0A, 0xB8, 0xDF, 0xF1, - 0xFF, 0xAE, 0xC6, 0x90, 0x31, 0xC8, 0x0D, 0x8D, 0x01, 0xC0, 0x68, 0x34, 0x32, 0x6F, 0xDE, 0xBC, - 0x46, 0xF9, 0x19, 0xCE, 0x22, 0x3B, 0x3B, 0x9B, 0xF4, 0xFD, 0xFB, 0x09, 0xF2, 0xF7, 0x61, 0xF8, - 0x80, 0x5E, 0x37, 0x86, 0xB8, 0xB2, 0x43, 0x68, 0xC4, 0xC5, 0x44, 0x30, 0x20, 0x3E, 0x96, 0xFC, - 0xFC, 0x3C, 0x76, 0xED, 0xDA, 0xD5, 0xE6, 0x2E, 0xC7, 0x8E, 0x1D, 0xCB, 0x1B, 0x6F, 0xBC, 0xE1, - 0xE8, 0x06, 0xF6, 0x43, 0x66, 0x89, 0xDD, 0x64, 0x6F, 0xB8, 0x9C, 0x21, 0x91, 0x48, 0x51, 0x15, - 0x0A, 0xD2, 0xA9, 0xFF, 0xF2, 0xCB, 0x2F, 0xF3, 0xD0, 0x43, 0x0F, 0xB5, 0x6A, 0x00, 0xE9, 0xE9, - 0xE9, 0xE4, 0x5D, 0xC8, 0xA3, 0x4F, 0xF7, 0x18, 0x7A, 0x44, 0x87, 0x3B, 0xBF, 0x18, 0xAB, 0x2A, - 0xA8, 0xAA, 0x4C, 0xCC, 0x01, 0xD0, 0xA9, 0x52, 0xBB, 0x6A, 0x2D, 0x54, 0x05, 0x54, 0x15, 0xAB, - 0xA6, 0x61, 0xD5, 0xB4, 0xFA, 0xFE, 0xAF, 0x09, 0x01, 0x5E, 0x5E, 0x9E, 0x0C, 0x1F, 0xD8, 0x1B, - 0x80, 0x9D, 0x3B, 0x77, 0xA2, 0xB5, 0x83, 0xB8, 0x4D, 0x4E, 0x4E, 0x66, 0xFA, 0xF4, 0xE9, 0x8E, - 0x4D, 0xFD, 0x90, 0x41, 0xDB, 0x2A, 0x34, 0x96, 0x5F, 0x0A, 0x32, 0x21, 0xE5, 0x36, 0x7B, 0xC3, - 0x23, 0x8F, 0x3C, 0xC2, 0xF4, 0xE9, 0xD3, 0x5B, 0x1D, 0xA8, 0x20, 0xDD, 0xB7, 0x82, 0xDB, 0xFA, - 0xC5, 0xE3, 0xE3, 0xED, 0x09, 0x5A, 0x33, 0x0C, 0x51, 0x14, 0xAC, 0x9A, 0x46, 0xFA, 0xA1, 0x93, - 0xFC, 0x7B, 0xE7, 0x7E, 0x4E, 0x9D, 0xCB, 0xC7, 0xDB, 0xD3, 0xC0, 0x6D, 0x49, 0xF1, 0x8C, 0xBB, - 0x7D, 0x20, 0xA1, 0x41, 0x01, 0x2D, 0x5F, 0x83, 0x14, 0x85, 0x53, 0x39, 0x79, 0xFC, 0x6B, 0xCB, - 0x5E, 0xD2, 0x8F, 0x67, 0x61, 0xB5, 0x6A, 0x24, 0x76, 0x8F, 0xE6, 0xFE, 0x11, 0xB7, 0xD0, 0x37, - 0xEE, 0xA6, 0x6B, 0xAB, 0x99, 0x8A, 0xC2, 0xAD, 0x7D, 0x7B, 0xE2, 0xAE, 0xD7, 0x91, 0x91, 0x91, - 0x41, 0x49, 0x49, 0x49, 0x9B, 0xA3, 0x68, 0xDC, 0xDC, 0xDC, 0x78, 0xE6, 0x99, 0x67, 0x48, 0x49, - 0x49, 0x61, 0xEF, 0xDE, 0xBD, 0xF6, 0xE6, 0xC9, 0xC0, 0x72, 0x60, 0xBF, 0x23, 0x43, 0xFA, 0x03, - 0x53, 0xED, 0x07, 0x7D, 0xFA, 0xF4, 0xE1, 0xC5, 0x17, 0x5F, 0xC4, 0xCB, 0xCB, 0xCB, 0xE9, 0x9B, - 0x39, 0xA2, 0xAC, 0xAC, 0x8C, 0xFD, 0xFB, 0xF7, 0xA3, 0x53, 0x15, 0x86, 0xF4, 0xED, 0x09, 0x8A, - 0x4A, 0x73, 0x91, 0xFB, 0xB5, 0x96, 0x3A, 0x16, 0xAE, 0xFC, 0x9E, 0x39, 0x1F, 0x7F, 0x43, 0xE1, - 0xC5, 0xF2, 0xFA, 0xF6, 0x65, 0xDF, 0x6C, 0x65, 0xD8, 0x80, 0x04, 0xDE, 0x79, 0x76, 0x2A, 0xFD, - 0x13, 0x62, 0x9D, 0x67, 0x8A, 0xA2, 0xF0, 0x7D, 0xEA, 0x7E, 0x9E, 0x7D, 0xE7, 0x53, 0x8E, 0x9D, - 0x69, 0x50, 0xFB, 0xBF, 0xDE, 0xBC, 0x9B, 0x0F, 0xD7, 0x6E, 0xE6, 0x2F, 0xFF, 0x93, 0xCC, 0xA3, - 0xE3, 0xFF, 0x03, 0xB5, 0xA9, 0xD9, 0xA7, 0x69, 0xF4, 0x8E, 0xED, 0x42, 0xD7, 0x88, 0x10, 0x4E, - 0x67, 0x65, 0x71, 0xF2, 0xE4, 0xC9, 0x76, 0x09, 0x6B, 0x8A, 0x8A, 0x8A, 0x62, 0xE6, 0xCC, 0x99, - 0x4C, 0x9D, 0x3A, 0xD5, 0xAE, 0x2C, 0x44, 0x00, 0x8F, 0x02, 0x19, 0xF6, 0x17, 0x44, 0x05, 0xA6, - 0x61, 0x33, 0x89, 0xB8, 0xBB, 0xBB, 0x33, 0x6B, 0xD6, 0xAC, 0x26, 0x4D, 0x21, 0xCE, 0xE0, 0xEC, - 0xD9, 0xB3, 0x64, 0x9E, 0x3A, 0x45, 0x44, 0x70, 0x20, 0xBD, 0xBB, 0x75, 0x01, 0xD1, 0x0C, 0x11, - 0x55, 0x95, 0x55, 0x9B, 0x7E, 0xE2, 0xD5, 0xF7, 0xBE, 0x6A, 0xC4, 0x0C, 0x2F, 0x2F, 0x2F, 0xFC, - 0xFC, 0xFD, 0xD9, 0x96, 0x7E, 0x94, 0x67, 0xDE, 0xFE, 0x88, 0x82, 0xE2, 0x8B, 0xCE, 0x89, 0x2F, - 0x55, 0xE5, 0xF0, 0xE9, 0x1C, 0x66, 0xBC, 0xFD, 0x71, 0x23, 0x66, 0x18, 0x0C, 0x06, 0xC2, 0xC2, - 0xC2, 0x28, 0x2C, 0xAB, 0xE2, 0xF9, 0x7F, 0x7C, 0xCE, 0x96, 0x7D, 0x87, 0x9B, 0x16, 0x5F, 0x42, - 0x10, 0x1E, 0xE4, 0x4F, 0xBF, 0xB8, 0x9B, 0xA8, 0xBA, 0x74, 0x89, 0xB4, 0xB4, 0xB4, 0x36, 0x33, - 0xC3, 0x8E, 0x71, 0xE3, 0xC6, 0x31, 0x7C, 0xF8, 0x70, 0xC7, 0xA6, 0x7B, 0x80, 0x04, 0xFB, 0x48, - 0x12, 0x80, 0xFB, 0xEC, 0x67, 0x46, 0x8C, 0x18, 0xC1, 0x03, 0x0F, 0x3C, 0xD0, 0xA6, 0x1B, 0x1E, - 0x3D, 0x7A, 0x94, 0xD2, 0x92, 0x12, 0xE2, 0xBB, 0x46, 0x12, 0x19, 0x62, 0xBC, 0xB6, 0xB8, 0x52, - 0x14, 0xCA, 0x2B, 0x2E, 0xF1, 0xFE, 0xEA, 0x8D, 0x54, 0x99, 0x1A, 0xD4, 0xCB, 0xBE, 0x7D, 0xFB, - 0xB2, 0x72, 0xE5, 0x4A, 0x36, 0x6F, 0xDE, 0xCC, 0x13, 0x4F, 0x3C, 0xC1, 0x4F, 0x87, 0x32, 0xF9, - 0x2E, 0x25, 0x4D, 0xAE, 0x09, 0xCD, 0x41, 0x08, 0xBE, 0x58, 0xBF, 0x83, 0xCC, 0x9C, 0x86, 0x78, - 0x5C, 0xA3, 0xD1, 0xC8, 0xFC, 0xF9, 0xF3, 0x49, 0x49, 0x49, 0xE1, 0xBD, 0xF7, 0xDE, 0x45, 0xE8, - 0xDD, 0xF9, 0x60, 0xCD, 0x26, 0x2C, 0xB5, 0x4D, 0x47, 0xF2, 0xE8, 0xDD, 0xDD, 0xE4, 0x0C, 0x07, - 0xF6, 0xEC, 0xD9, 0xE3, 0x98, 0xB0, 0xD3, 0x26, 0xF8, 0xF9, 0xF9, 0x31, 0x79, 0xF2, 0x64, 0xC7, - 0x68, 0xFA, 0x58, 0x60, 0xBC, 0x9D, 0x21, 0xE3, 0xB1, 0xCD, 0x0E, 0x83, 0xC1, 0xC0, 0xB4, 0x69, - 0xD3, 0x9C, 0xDE, 0xF8, 0x35, 0x85, 0x43, 0x87, 0x0E, 0x01, 0x90, 0xD8, 0x3D, 0x06, 0x2F, 0x8F, - 0x66, 0xD4, 0x5D, 0x45, 0xE1, 0x6C, 0x5E, 0x11, 0xC7, 0xCE, 0x9C, 0x6F, 0xD4, 0xFC, 0xE4, 0x93, - 0x4F, 0x32, 0x7E, 0xFC, 0x78, 0x06, 0x0C, 0x18, 0xC0, 0x8B, 0x2F, 0xBE, 0x48, 0x74, 0xD7, 0x9B, - 0x48, 0xFD, 0xF9, 0x78, 0xD3, 0x76, 0x30, 0x07, 0x98, 0xCC, 0x35, 0xEC, 0x3D, 0x72, 0xAA, 0x51, - 0xDB, 0x98, 0x31, 0x63, 0x78, 0xFC, 0xF1, 0xC7, 0x89, 0x8B, 0x8B, 0xE3, 0xB1, 0xC7, 0x1E, 0x63, - 0xC2, 0x84, 0x09, 0xA4, 0x1F, 0x3B, 0x4D, 0x71, 0x59, 0xE5, 0x35, 0x66, 0x9D, 0x42, 0xBF, 0xB8, - 0x9B, 0x70, 0xD7, 0xEB, 0x38, 0x7E, 0xFC, 0x38, 0xE5, 0xE5, 0xE5, 0xCD, 0xDE, 0xDB, 0x59, 0x8C, - 0x1A, 0x35, 0x8A, 0xEE, 0xDD, 0xEB, 0x73, 0x7E, 0x74, 0xC0, 0x44, 0x15, 0xB9, 0x5B, 0xBC, 0xDB, - 0xDE, 0xDA, 0xB7, 0x6F, 0x5F, 0x46, 0x8F, 0x1E, 0xDD, 0xA6, 0x1B, 0x59, 0x2C, 0x16, 0x8E, 0x1E, - 0x3D, 0x2A, 0xFB, 0xEB, 0x11, 0xD3, 0xBC, 0x46, 0xA3, 0x80, 0xB9, 0xD6, 0x42, 0xAD, 0xA5, 0xF1, - 0xDB, 0x27, 0x1C, 0xB4, 0x32, 0x21, 0x04, 0x08, 0x41, 0xB5, 0xB9, 0x06, 0xAD, 0x39, 0x6D, 0x4D, - 0x01, 0xAB, 0x55, 0xC3, 0x5C, 0xD3, 0xF8, 0xCD, 0xB7, 0x58, 0x2C, 0xF5, 0x9A, 0x92, 0xA6, 0x69, - 0xD4, 0xD6, 0xD6, 0x52, 0x6B, 0xA9, 0xA3, 0xCE, 0x6A, 0x6D, 0xDA, 0xAA, 0x27, 0x34, 0x62, 0x23, - 0x43, 0x09, 0x35, 0xFA, 0x93, 0x9D, 0x9D, 0x4D, 0x4A, 0x4A, 0x0A, 0x15, 0x15, 0x15, 0x8D, 0xC6, - 0xD6, 0x52, 0x54, 0x57, 0x57, 0x93, 0x9E, 0x9E, 0xCE, 0xFB, 0xEF, 0xBF, 0x7F, 0x79, 0xE0, 0x5D, - 0x92, 0x1E, 0x48, 0x44, 0x66, 0xCA, 0x02, 0x70, 0xF7, 0xDD, 0x77, 0x13, 0x1C, 0xDC, 0x22, 0x9F, - 0xCA, 0x15, 0xA8, 0xA8, 0xA8, 0xE0, 0xCC, 0x99, 0x33, 0x78, 0xB8, 0xEB, 0xE9, 0x19, 0x13, 0x4E, - 0xB3, 0x1B, 0x10, 0x21, 0x08, 0x0F, 0x0A, 0x20, 0xD4, 0xE8, 0x47, 0x45, 0x55, 0x83, 0x75, 0x7A, - 0xD1, 0xA2, 0x45, 0x44, 0x44, 0x44, 0x10, 0x15, 0x15, 0xC5, 0x87, 0x1F, 0x7E, 0xC8, 0xE9, 0xAC, - 0xD3, 0x3C, 0x3C, 0xA2, 0x9F, 0xB4, 0xCC, 0x5E, 0x6B, 0x61, 0x17, 0xE0, 0xE5, 0x61, 0xA0, 0x47, - 0x74, 0x38, 0xBB, 0x0E, 0x36, 0x58, 0x5C, 0x37, 0x6E, 0xDC, 0xC8, 0xDC, 0xB9, 0x73, 0x19, 0x33, - 0x66, 0x0C, 0x3B, 0x76, 0xEC, 0xE0, 0xBB, 0xEF, 0xD6, 0x31, 0xA0, 0x47, 0x24, 0x81, 0xBE, 0xDE, - 0x4D, 0x0F, 0x51, 0x40, 0xA8, 0xD1, 0x9F, 0xAE, 0x11, 0x21, 0xA4, 0x1E, 0x38, 0xC1, 0x6F, 0x7F, - 0xFB, 0x5B, 0x12, 0x12, 0x12, 0x18, 0x32, 0x64, 0x08, 0x83, 0x07, 0x0F, 0xA6, 0x7B, 0xF7, 0xEE, - 0x44, 0x45, 0x45, 0x11, 0x18, 0x18, 0x88, 0xC1, 0x60, 0x40, 0xA7, 0xD3, 0xD5, 0x6F, 0x9E, 0x35, - 0x4D, 0xC3, 0x62, 0xB1, 0x50, 0x5D, 0x5D, 0x4D, 0x71, 0x71, 0x31, 0xA7, 0x4F, 0x9F, 0x26, 0x2D, - 0x2D, 0x8D, 0x94, 0x94, 0x14, 0x32, 0x32, 0x32, 0x28, 0x2E, 0xBE, 0xC2, 0xE8, 0x9B, 0xAB, 0x47, - 0xAA, 0xB9, 0x46, 0x00, 0x6F, 0x6F, 0x6F, 0x46, 0x8C, 0x18, 0xD1, 0x26, 0x66, 0x00, 0x14, 0x14, - 0x14, 0x90, 0x97, 0x9F, 0x4F, 0x90, 0xBF, 0x2F, 0x51, 0xA1, 0xC6, 0xE6, 0x37, 0x84, 0x9A, 0xA0, - 0x4B, 0x58, 0x10, 0xE3, 0x6E, 0x1F, 0xC8, 0x3F, 0x97, 0xAF, 0xAF, 0x6F, 0x3E, 0x7C, 0xF8, 0x30, - 0x0F, 0x3F, 0xFC, 0x30, 0xEE, 0xEE, 0xEE, 0x94, 0x57, 0x54, 0x10, 0x66, 0xF4, 0x63, 0xC2, 0xF0, - 0x41, 0x4E, 0x8D, 0x41, 0x75, 0xD3, 0x31, 0x69, 0xF4, 0xAD, 0xAC, 0xD9, 0xBA, 0x87, 0x4B, 0x36, - 0xBF, 0x4A, 0x65, 0x65, 0x25, 0xAF, 0xBD, 0xF6, 0x1A, 0x73, 0xE6, 0xCC, 0xA1, 0xBA, 0xBA, 0x1A, - 0x10, 0x3C, 0x74, 0xC7, 0x6D, 0xF8, 0xF8, 0x78, 0x35, 0xCD, 0x60, 0x21, 0xF0, 0xF1, 0xF2, 0x20, - 0xBE, 0x6B, 0x24, 0xA9, 0x07, 0x4E, 0x50, 0x5E, 0x5E, 0xCE, 0x9E, 0x3D, 0x7B, 0xD8, 0xB3, 0x67, - 0x0F, 0x3A, 0x9D, 0x0E, 0x1F, 0x1F, 0x1F, 0x42, 0x42, 0x42, 0x88, 0x88, 0x88, 0x20, 0x28, 0x28, - 0x08, 0x5F, 0x5F, 0x5F, 0x0C, 0x06, 0x03, 0x9A, 0xA6, 0x51, 0x5D, 0x5D, 0x4D, 0x59, 0x59, 0x19, - 0x85, 0x85, 0x85, 0x14, 0x14, 0x14, 0x50, 0x52, 0x52, 0xD2, 0x94, 0x09, 0x46, 0x43, 0x66, 0xF6, - 0xBE, 0xAA, 0x47, 0x3A, 0xE8, 0x55, 0x80, 0x2E, 0x5D, 0xBA, 0x90, 0x90, 0x90, 0xD0, 0x6A, 0x46, - 0x98, 0xCD, 0x66, 0x32, 0x32, 0x32, 0x58, 0xB8, 0x70, 0x21, 0x45, 0x85, 0x45, 0x0C, 0x4C, 0x88, - 0x25, 0xC8, 0xDF, 0xD7, 0xA9, 0x0D, 0xA1, 0xAA, 0x53, 0x99, 0xF9, 0xC8, 0x3D, 0x1C, 0x3C, 0x79, - 0x96, 0x6D, 0xE9, 0x47, 0xEA, 0xDB, 0x4D, 0x26, 0x13, 0x26, 0x93, 0x09, 0x1F, 0x4F, 0x0F, 0x66, - 0x3F, 0x76, 0x1F, 0x37, 0xF7, 0xEE, 0xEE, 0x9C, 0xDA, 0x6B, 0xD5, 0xB8, 0xEB, 0xB6, 0xFE, 0x3C, - 0x9D, 0x7C, 0x37, 0xF3, 0x3E, 0x5F, 0x47, 0x8D, 0x6D, 0xE1, 0xB6, 0x5A, 0xAD, 0x54, 0x56, 0x56, - 0xA2, 0x53, 0x55, 0x7E, 0x33, 0x6E, 0x38, 0x53, 0xC6, 0x0D, 0x6B, 0x76, 0x7C, 0x8A, 0x4E, 0x27, - 0x35, 0xC5, 0xCB, 0x6F, 0x61, 0xB5, 0x52, 0x5E, 0x5E, 0x4E, 0x79, 0x79, 0x39, 0xA7, 0x4E, 0x9D, - 0xA2, 0x15, 0xA8, 0x46, 0x46, 0x79, 0xAE, 0x04, 0xD6, 0x00, 0xE7, 0xF5, 0xC8, 0x48, 0x09, 0x40, - 0x9A, 0x8C, 0x5B, 0x2A, 0xAE, 0xEA, 0xEA, 0xEA, 0x38, 0x7F, 0xFE, 0x3C, 0x5B, 0xB7, 0x6E, 0x65, - 0xCD, 0x9A, 0x35, 0xEC, 0xDA, 0xB5, 0xAB, 0x5E, 0x2E, 0x46, 0x04, 0x07, 0xE0, 0xED, 0x61, 0x70, - 0x6E, 0x87, 0xAE, 0x09, 0x6E, 0x8A, 0x0A, 0xE5, 0xE3, 0x3F, 0x3D, 0xC9, 0x3F, 0x97, 0xAF, 0x67, - 0xDD, 0xCE, 0x74, 0x8A, 0x4A, 0x2B, 0x70, 0x73, 0xD3, 0xD3, 0x3B, 0xB6, 0x0B, 0xBF, 0x7B, 0x70, - 0x0C, 0xF7, 0x8F, 0xBA, 0x15, 0x55, 0x55, 0x9C, 0x36, 0xC1, 0xB8, 0xBB, 0xB9, 0xF1, 0xF2, 0xE3, - 0x0F, 0xD2, 0xA3, 0x4B, 0x38, 0x1F, 0x7D, 0xB7, 0x8D, 0x53, 0xE7, 0xF2, 0xD1, 0x34, 0x8D, 0xE8, - 0xB0, 0x20, 0x92, 0xEF, 0x1C, 0xCA, 0xB4, 0x89, 0xA3, 0xF1, 0x6F, 0xCE, 0x37, 0x63, 0x43, 0xD7, - 0x88, 0x10, 0x74, 0x3A, 0x15, 0xAB, 0x54, 0x28, 0x34, 0xA4, 0x93, 0xC9, 0x1B, 0x59, 0xC0, 0xC6, - 0x59, 0x33, 0x42, 0x1D, 0x32, 0x0E, 0xE1, 0x14, 0x32, 0x38, 0xE4, 0x47, 0x64, 0xD8, 0x54, 0x99, - 0xFD, 0x1F, 0xF4, 0x38, 0xD8, 0xE5, 0x2D, 0x16, 0x0B, 0x07, 0x0F, 0x1E, 0x24, 0x2A, 0x2A, 0x0A, - 0x3F, 0x3F, 0x3F, 0x0C, 0x06, 0x03, 0xAA, 0xCD, 0x17, 0xA1, 0x69, 0x1A, 0x75, 0x75, 0x75, 0x98, - 0x4C, 0x26, 0x4A, 0x4B, 0x4B, 0xC9, 0xCE, 0xCE, 0xE6, 0xC0, 0x81, 0x03, 0xEC, 0xDE, 0xBD, 0x9B, - 0x7D, 0xFB, 0xF6, 0x71, 0xEE, 0xDC, 0xB9, 0x2B, 0xEA, 0x94, 0x44, 0x86, 0x04, 0xE2, 0xEE, 0xD6, - 0x82, 0x68, 0x7D, 0x4D, 0xD0, 0x35, 0x32, 0x84, 0xB7, 0x9E, 0x99, 0xC2, 0xAC, 0xC9, 0xE3, 0x29, - 0xBC, 0x58, 0x8E, 0xC1, 0xDD, 0x8D, 0xE8, 0xB0, 0x20, 0x7C, 0x7D, 0xBC, 0x6D, 0x8E, 0x29, 0xE7, - 0xBB, 0x43, 0x08, 0x3C, 0x0D, 0x6E, 0x4C, 0xBD, 0x6F, 0x34, 0x93, 0x46, 0x0F, 0x21, 0xBF, 0xF8, - 0x22, 0x56, 0x4D, 0x10, 0x16, 0xE4, 0x4F, 0xA0, 0xBF, 0xAF, 0xA4, 0xA2, 0x53, 0x8B, 0xB3, 0x5C, - 0xE3, 0x3C, 0xDD, 0xDD, 0xB9, 0x24, 0xD5, 0xF2, 0x3A, 0xE0, 0x0F, 0xC8, 0x52, 0x4E, 0x7D, 0x80, - 0x18, 0x64, 0x5C, 0x5A, 0x28, 0x32, 0x11, 0x54, 0x8F, 0xD4, 0x9A, 0xAA, 0x6D, 0xC4, 0x2E, 0x45, - 0xC6, 0x6F, 0x1D, 0x47, 0x56, 0x27, 0x3A, 0x8B, 0x2C, 0x6C, 0x73, 0xC5, 0xCD, 0xF5, 0x38, 0x64, - 0x92, 0x6E, 0xDC, 0xB8, 0x91, 0x3D, 0x7B, 0xF6, 0x10, 0x1A, 0x1A, 0x4A, 0x68, 0x68, 0x28, 0x46, - 0xA3, 0x11, 0x2F, 0x2F, 0x2F, 0x54, 0x55, 0xA5, 0xB6, 0xB6, 0x96, 0xCA, 0xCA, 0x4A, 0x8A, 0x8B, - 0x8B, 0x29, 0x2C, 0x2C, 0xA4, 0xA4, 0xA4, 0x04, 0x93, 0xC9, 0x74, 0x4D, 0x6D, 0x23, 0x24, 0xD0, - 0x5F, 0x6A, 0x58, 0x2D, 0x31, 0x77, 0x68, 0x02, 0x9D, 0xA2, 0x10, 0x15, 0x16, 0x44, 0x54, 0x78, - 0x70, 0x3D, 0x61, 0x5B, 0x6D, 0xB6, 0x17, 0x80, 0xD0, 0xF0, 0xF3, 0xF1, 0xC2, 0xCF, 0xD7, 0xBB, - 0xA1, 0xBF, 0x96, 0x68, 0x49, 0x02, 0x42, 0x02, 0xFD, 0xF0, 0xF5, 0xF6, 0xB0, 0x33, 0xC4, 0x1D, - 0x39, 0x4B, 0x76, 0xD8, 0x7E, 0x20, 0x67, 0x89, 0x3B, 0x52, 0xFC, 0xEB, 0x6C, 0xC7, 0x16, 0x1B, - 0xF3, 0x9C, 0xAE, 0x6C, 0xA7, 0x07, 0x7E, 0x02, 0x46, 0x83, 0xD4, 0x0A, 0xCA, 0xCA, 0xCA, 0x28, - 0x2B, 0x2B, 0xE3, 0xE4, 0xC9, 0x93, 0x2D, 0x7D, 0xF4, 0x3A, 0xE0, 0x02, 0xD2, 0xCB, 0xE8, 0x09, - 0x10, 0xE4, 0xEF, 0xD3, 0x7A, 0xA3, 0x60, 0x4B, 0x89, 0xE6, 0xCA, 0xFE, 0x84, 0x20, 0xD0, 0xD7, - 0x9B, 0x40, 0x3F, 0x1F, 0xF2, 0x8A, 0xCB, 0xEC, 0xAD, 0x51, 0x97, 0xFF, 0x17, 0xD2, 0x6F, 0xDE, - 0x26, 0xE8, 0x91, 0x36, 0xF9, 0x67, 0x80, 0xE1, 0xC8, 0xCD, 0xA1, 0x0F, 0xCE, 0xC9, 0xC4, 0x3A, - 0xE4, 0xB4, 0xCB, 0x46, 0xCA, 0xC1, 0x6D, 0xC0, 0x79, 0x64, 0x15, 0xB7, 0xAE, 0x00, 0x7E, 0xDE, - 0xED, 0x9A, 0xED, 0xD5, 0x89, 0x10, 0x78, 0x7B, 0x7A, 0x60, 0xF4, 0xF3, 0x71, 0x6C, 0x0C, 0x72, - 0xC5, 0x9D, 0xF4, 0x48, 0xB9, 0xF6, 0x7B, 0x64, 0x40, 0x57, 0x37, 0xE4, 0xBE, 0xA4, 0x2B, 0xD2, - 0x14, 0x1F, 0x8C, 0x9C, 0x86, 0x3A, 0xA4, 0x65, 0xB0, 0x0C, 0x29, 0x0F, 0xCF, 0x03, 0x27, 0x69, - 0x90, 0x87, 0x17, 0x91, 0x6F, 0x48, 0x4F, 0x1C, 0xEA, 0x61, 0x79, 0x7A, 0x18, 0x3A, 0xAF, 0x88, - 0x60, 0x7B, 0x42, 0x80, 0x9B, 0x5E, 0x87, 0xBF, 0x4F, 0x23, 0x43, 0x6B, 0xDB, 0x4C, 0x19, 0x4D, - 0xC0, 0xBE, 0xE2, 0xD6, 0x21, 0x6B, 0x1E, 0xE6, 0x03, 0x76, 0x4F, 0x8C, 0x62, 0x3B, 0xEF, 0xB8, - 0xCD, 0xAE, 0xE3, 0xDA, 0x26, 0x5B, 0x9D, 0xFD, 0xFF, 0x55, 0x45, 0xC1, 0x5D, 0xAF, 0xBB, 0xB1, - 0x9C, 0x52, 0xD7, 0x22, 0x94, 0x5E, 0x87, 0x6F, 0xE3, 0x19, 0xEF, 0x47, 0xC3, 0x8B, 0xDA, 0x7E, - 0xF7, 0xB9, 0xC6, 0x39, 0xC1, 0x2F, 0xB4, 0xD6, 0x60, 0x6B, 0xA0, 0x2A, 0x0A, 0x9E, 0x86, 0x46, - 0xB1, 0x67, 0x9E, 0xB8, 0x80, 0x21, 0xED, 0x9D, 0x63, 0x58, 0x3F, 0x1F, 0x84, 0x10, 0xD2, 0x3B, - 0xF7, 0x4B, 0x10, 0x59, 0x00, 0x8A, 0x82, 0xA1, 0xB1, 0x0A, 0x6F, 0xD7, 0xA4, 0xDA, 0x15, 0xED, - 0xCD, 0x90, 0x1A, 0xA0, 0x16, 0x40, 0x13, 0x82, 0x6A, 0x73, 0xED, 0x2F, 0x46, 0x64, 0x01, 0x97, - 0x07, 0x78, 0xDC, 0x30, 0x0C, 0x31, 0xD9, 0x0F, 0x2A, 0xAA, 0x4C, 0x6D, 0xE8, 0xEA, 0x3A, 0x83, - 0x10, 0xD2, 0x2A, 0xDC, 0x00, 0x0D, 0x17, 0xBC, 0x6E, 0xED, 0xCD, 0x10, 0x13, 0xB2, 0xCE, 0x09, - 0x00, 0x45, 0xA5, 0xE5, 0xAE, 0x8F, 0x32, 0xEC, 0x20, 0x08, 0x21, 0x30, 0x35, 0x36, 0xE7, 0x9B, - 0x70, 0x41, 0x35, 0x39, 0x57, 0x30, 0xA4, 0xBE, 0x70, 0xC0, 0x85, 0xE2, 0x8B, 0x88, 0x1B, 0x21, - 0x30, 0xCE, 0x09, 0x58, 0x35, 0x8D, 0x4B, 0xD5, 0x8D, 0x66, 0xFC, 0x0D, 0xC1, 0x90, 0x1A, 0x1C, - 0x82, 0x88, 0xCF, 0xE6, 0x15, 0x61, 0x32, 0xB7, 0x79, 0xF3, 0xDA, 0xF9, 0x50, 0xA0, 0xA6, 0xB6, - 0x8E, 0x92, 0xF2, 0x4B, 0x8E, 0xAD, 0xC5, 0xDC, 0x00, 0x22, 0x0B, 0xE4, 0x66, 0x11, 0x80, 0x9C, - 0xFC, 0x62, 0xF9, 0x10, 0x6D, 0x89, 0xA9, 0xBA, 0x2E, 0xA0, 0x70, 0xC9, 0x64, 0x96, 0xAE, 0xDE, - 0x06, 0xB4, 0x7B, 0xF1, 0x32, 0x70, 0x5D, 0x69, 0x8D, 0x5A, 0x80, 0xFC, 0x92, 0x32, 0x4E, 0x9D, - 0xCB, 0x77, 0x2E, 0x28, 0xE1, 0x7A, 0x86, 0xA2, 0x50, 0x50, 0x5A, 0x4E, 0x51, 0x43, 0x34, 0x8C, - 0x40, 0x5A, 0x2B, 0xDA, 0x1D, 0xAE, 0x60, 0xC8, 0x49, 0x64, 0x26, 0x2A, 0x55, 0xA6, 0x2B, 0x03, - 0x0D, 0x6E, 0x48, 0x28, 0x0A, 0xA7, 0xCE, 0xE5, 0x53, 0x7E, 0xA9, 0xDE, 0xBD, 0x5C, 0x89, 0xF4, - 0x69, 0xB4, 0x3B, 0x5C, 0xC1, 0x90, 0x73, 0xC8, 0xCF, 0x4E, 0x00, 0xB0, 0x65, 0xDF, 0x61, 0xAA, - 0xAB, 0xCD, 0x9D, 0xBF, 0x41, 0x54, 0x14, 0x19, 0x92, 0xDA, 0x9A, 0x28, 0x4C, 0x21, 0xD8, 0x77, - 0xE4, 0x14, 0x96, 0xBA, 0xFA, 0x35, 0x3C, 0x1F, 0x69, 0xC3, 0x6B, 0x77, 0xB8, 0x82, 0x21, 0x26, - 0xE4, 0x57, 0x6E, 0x00, 0x48, 0x3F, 0x96, 0xC5, 0xE1, 0x53, 0x39, 0xAD, 0x23, 0x84, 0x1D, 0x8A, - 0xD2, 0x40, 0xD0, 0x96, 0xAE, 0x47, 0x0A, 0xA0, 0xD3, 0x51, 0x71, 0xA9, 0x9A, 0x9D, 0xE9, 0x47, - 0x39, 0x9E, 0xD5, 0xC2, 0x4F, 0x82, 0x28, 0x0A, 0xE5, 0x95, 0x97, 0xD8, 0x91, 0x71, 0xDC, 0xB1, - 0xF5, 0x20, 0x36, 0x29, 0xD0, 0xDE, 0x70, 0xD5, 0x67, 0x18, 0x36, 0xDB, 0x06, 0x1C, 0x52, 0x52, - 0x5E, 0xC9, 0xAA, 0x4D, 0xBB, 0x19, 0xDC, 0xA7, 0xF5, 0x51, 0x90, 0xCB, 0x37, 0xEC, 0x64, 0xF7, - 0xA1, 0x4C, 0x46, 0xDF, 0xD2, 0x87, 0x61, 0x03, 0x7B, 0x39, 0x9F, 0xE8, 0xA9, 0x28, 0x54, 0x9B, - 0x6B, 0xF8, 0xF1, 0xA7, 0x03, 0x2C, 0x59, 0xB3, 0x91, 0xED, 0xFB, 0x8F, 0xD2, 0x3B, 0x36, 0x9A, - 0xB5, 0xF3, 0x9E, 0x27, 0x2A, 0x2C, 0xC8, 0xB9, 0x3D, 0x92, 0xAA, 0xB0, 0xF7, 0xC8, 0x69, 0x0E, - 0x64, 0x66, 0xDB, 0x5B, 0x84, 0xED, 0xF9, 0x5C, 0x62, 0xE7, 0x73, 0x55, 0x8D, 0x8E, 0x12, 0x64, - 0xAC, 0x70, 0x1F, 0x80, 0x0B, 0xC5, 0xA5, 0x8C, 0x1D, 0xD2, 0x8F, 0x90, 0xA0, 0x80, 0x96, 0x6D, - 0x14, 0x6D, 0x8B, 0xE9, 0xF4, 0xD7, 0xDF, 0xE7, 0xDB, 0x94, 0x34, 0xD6, 0x6E, 0xDF, 0xC7, 0xB6, - 0xB4, 0x23, 0x18, 0xFD, 0x7C, 0xE8, 0xD9, 0x35, 0xB2, 0xE9, 0x98, 0x5C, 0xDB, 0xB5, 0x85, 0x17, - 0xCB, 0xF9, 0xDF, 0x7F, 0x7C, 0xC6, 0x6B, 0xEF, 0x7F, 0xC5, 0xB1, 0xEC, 0x5C, 0x2C, 0x75, 0x56, - 0xAA, 0xCC, 0x35, 0xDC, 0x3F, 0x62, 0x30, 0x51, 0xE1, 0xCE, 0x31, 0xA4, 0xCE, 0x6A, 0xE5, 0x8D, - 0x65, 0xFF, 0x62, 0xEF, 0xE1, 0xFA, 0x25, 0xE3, 0x3C, 0x32, 0x13, 0xB9, 0xB8, 0xD9, 0x8B, 0x5B, - 0x01, 0x57, 0xD5, 0xDF, 0xAB, 0x45, 0x3A, 0xAA, 0xAA, 0x01, 0xB2, 0x2F, 0x14, 0xB1, 0x74, 0xED, - 0x16, 0xB4, 0x56, 0x84, 0x61, 0x6A, 0x9A, 0x46, 0x8D, 0x45, 0x7A, 0x40, 0xCD, 0x35, 0xB5, 0xA4, - 0x1E, 0x38, 0xC1, 0xB4, 0x3F, 0x2D, 0xE6, 0x93, 0xEF, 0xB6, 0x35, 0xBD, 0x2E, 0xD9, 0x66, 0xC6, - 0x4B, 0x0B, 0x97, 0xB3, 0x74, 0xED, 0x16, 0xCC, 0x0E, 0xA1, 0xA2, 0x31, 0xE1, 0xC1, 0x44, 0x85, - 0x19, 0x9B, 0x8F, 0xC4, 0x07, 0xD0, 0xA9, 0xEC, 0x3B, 0x72, 0x8A, 0x75, 0x3B, 0xD2, 0x1D, 0x5B, - 0xBF, 0x47, 0xFA, 0xD2, 0x5D, 0x02, 0x57, 0x16, 0x44, 0xDC, 0x82, 0x8C, 0xAA, 0x00, 0xE0, 0xCB, - 0xEF, 0x77, 0xB0, 0xEB, 0xE0, 0x49, 0xB9, 0x0E, 0x38, 0x0B, 0x21, 0x08, 0x33, 0x06, 0x70, 0xD7, - 0x6D, 0xFD, 0xEB, 0x9B, 0xBC, 0x3D, 0x0D, 0x18, 0xDC, 0xDD, 0x78, 0xE5, 0xDD, 0x15, 0xEC, 0xFC, - 0xF9, 0xC4, 0xD5, 0xD7, 0x26, 0x45, 0x61, 0xD5, 0xC6, 0x9F, 0xF8, 0xF4, 0xDF, 0xDB, 0x19, 0x79, - 0x73, 0x62, 0xFD, 0xF5, 0xC1, 0x01, 0xBE, 0x3C, 0x3F, 0xE5, 0x5E, 0x19, 0x6B, 0xEC, 0x44, 0xF4, - 0xA3, 0xD9, 0x5C, 0xC3, 0xA2, 0xAF, 0x7E, 0xA0, 0xE8, 0x62, 0x85, 0xBD, 0xB5, 0x14, 0x17, 0x7F, - 0xD8, 0xC5, 0x95, 0x65, 0x85, 0x2C, 0x48, 0xD1, 0x75, 0x2F, 0xE0, 0x51, 0x65, 0xAA, 0xA1, 0xE8, - 0x62, 0x05, 0xF7, 0x0C, 0x1D, 0x88, 0x87, 0xC1, 0xF9, 0xA2, 0x39, 0x8A, 0xAA, 0x92, 0xD4, 0xB3, - 0x2B, 0x25, 0x65, 0x95, 0x14, 0x94, 0x94, 0x73, 0xEF, 0xF0, 0x9B, 0x99, 0xFD, 0xD8, 0x44, 0xBE, - 0x4D, 0x49, 0x27, 0x33, 0x27, 0x8F, 0x7B, 0x87, 0x0D, 0xC2, 0xE0, 0xD8, 0x9F, 0xA2, 0x90, 0x5B, - 0x58, 0xC2, 0xEF, 0xDF, 0x5A, 0x86, 0x5E, 0xA7, 0x63, 0xD9, 0x1F, 0x9F, 0xE0, 0x81, 0x91, 0xB7, - 0x12, 0xDF, 0x35, 0x82, 0x19, 0x0F, 0x8F, 0x63, 0xDC, 0xED, 0x03, 0x9D, 0xDB, 0x16, 0xE9, 0x54, - 0x56, 0x6F, 0xDA, 0xCD, 0x9C, 0x8F, 0xBF, 0x71, 0xD4, 0xAE, 0xBE, 0x44, 0x7E, 0x15, 0xC1, 0x65, - 0xF6, 0x20, 0x57, 0xD7, 0x79, 0x3A, 0x87, 0x0C, 0x33, 0x1A, 0x0C, 0x70, 0xE6, 0x42, 0x21, 0x46, - 0x3F, 0x6F, 0x7E, 0x95, 0x14, 0xD7, 0x22, 0x2D, 0xD8, 0xD7, 0xDB, 0x8B, 0x3B, 0x6F, 0xEB, 0xCF, - 0x83, 0xA3, 0x87, 0x30, 0x69, 0xF4, 0x10, 0x92, 0xE2, 0x63, 0x11, 0x42, 0xE3, 0x93, 0x75, 0xDB, - 0xE9, 0xD3, 0x3D, 0x9A, 0xC4, 0x9E, 0x31, 0x0D, 0x6F, 0xBC, 0x4E, 0xE5, 0x8B, 0x7F, 0xA7, 0xF0, - 0xD9, 0xFA, 0x14, 0x5E, 0xFD, 0xAF, 0x87, 0xB8, 0x7F, 0xD4, 0xAD, 0x04, 0xFA, 0x7B, 0x73, 0x4B, - 0xDF, 0x38, 0x62, 0x22, 0x42, 0x9C, 0x13, 0x09, 0xAA, 0xCA, 0x89, 0xEC, 0x5C, 0x9E, 0x7A, 0x6B, - 0x19, 0xB9, 0x85, 0xF5, 0xB1, 0xB7, 0x39, 0xC0, 0xB3, 0x34, 0x91, 0x5F, 0xDE, 0x5E, 0x70, 0x35, - 0x43, 0x34, 0xE4, 0x46, 0x71, 0x14, 0x10, 0xAA, 0x69, 0x82, 0x03, 0x27, 0xCF, 0xD2, 0x3F, 0x3E, - 0x96, 0xEE, 0x31, 0x11, 0x2D, 0x5A, 0xE0, 0xDD, 0x74, 0x3A, 0x8C, 0x81, 0x7E, 0x78, 0xB8, 0xCB, - 0x0C, 0xE0, 0xB8, 0xAE, 0x91, 0x6C, 0xDE, 0x7B, 0x88, 0xFC, 0x92, 0x8B, 0xDC, 0x3F, 0xE2, 0x96, - 0xFA, 0x05, 0xBE, 0xB6, 0xD6, 0xC2, 0x5F, 0x96, 0x7E, 0x8D, 0x97, 0x87, 0x81, 0x37, 0x9F, 0xFE, - 0x0D, 0x3E, 0x9E, 0x86, 0x86, 0x88, 0x13, 0x67, 0xEE, 0xA7, 0x28, 0x94, 0x55, 0x56, 0xF1, 0xEC, - 0xDF, 0x3F, 0x61, 0x6B, 0x5A, 0x7D, 0x04, 0xA5, 0x15, 0xF9, 0x71, 0x81, 0xD5, 0x2E, 0xA6, 0x57, - 0x87, 0xD4, 0x2E, 0x3F, 0x8D, 0xAC, 0x04, 0x51, 0x09, 0x50, 0x50, 0x2A, 0x35, 0x9F, 0xA3, 0xA7, - 0x72, 0x5A, 0xB6, 0x9E, 0x40, 0x43, 0x05, 0x07, 0x21, 0x08, 0x31, 0xFA, 0xF3, 0xDB, 0x09, 0x23, - 0x38, 0x73, 0xA1, 0x88, 0xCA, 0x2A, 0x53, 0xFD, 0x5E, 0xA5, 0xFC, 0x52, 0x35, 0x39, 0xF9, 0xC5, - 0xFC, 0xE7, 0xD8, 0xDB, 0x08, 0x0B, 0x0E, 0x68, 0xB1, 0x56, 0x67, 0xAE, 0xAD, 0xE5, 0xAF, 0x4B, - 0x57, 0xB3, 0x7A, 0xF3, 0x1E, 0xC7, 0x33, 0xDF, 0x21, 0x4B, 0x2E, 0xB9, 0x1C, 0x1D, 0x55, 0xE5, - 0x78, 0x35, 0xF0, 0x1E, 0x36, 0xEB, 0xE8, 0xCF, 0x27, 0xB2, 0x99, 0x31, 0xF7, 0x23, 0x72, 0x72, - 0x0B, 0x5B, 0xBF, 0x61, 0x14, 0x82, 0x31, 0x43, 0xFA, 0xD1, 0x2D, 0x2A, 0x94, 0x3A, 0x87, 0x7C, - 0x91, 0x3A, 0xAB, 0x95, 0x40, 0x3F, 0x1F, 0xC6, 0xDE, 0x9A, 0xD4, 0x32, 0x5B, 0xAC, 0xA2, 0x60, - 0xAE, 0xB5, 0x30, 0xE7, 0xA3, 0xB5, 0x2C, 0xFC, 0x6A, 0x83, 0x74, 0x3F, 0x4B, 0x1C, 0x01, 0x5E, - 0xC1, 0x21, 0xDC, 0xD3, 0x95, 0xE8, 0xA8, 0x5A, 0x81, 0x1A, 0x90, 0x81, 0x0C, 0x13, 0xEA, 0x05, - 0x90, 0x95, 0x5B, 0xC8, 0xC9, 0xB3, 0x17, 0xB8, 0xBD, 0x7F, 0x82, 0x73, 0xE5, 0x36, 0x2E, 0x87, - 0x00, 0x7F, 0x1F, 0x4F, 0x06, 0x27, 0xF6, 0x20, 0xD4, 0xE8, 0x57, 0x2F, 0xB2, 0xF4, 0x3A, 0x1D, - 0x91, 0x21, 0x46, 0x6E, 0xE9, 0xDD, 0x1D, 0x37, 0x9D, 0x93, 0x8F, 0xA7, 0xAA, 0x54, 0x56, 0x9B, - 0xF9, 0xDB, 0xD2, 0xD5, 0xCC, 0xFD, 0xFC, 0xBB, 0xFA, 0xC0, 0x6C, 0x64, 0xE0, 0xDF, 0x13, 0xC8, - 0x60, 0xC2, 0x0E, 0x41, 0x47, 0x16, 0x6F, 0xAC, 0x46, 0x7E, 0x65, 0x73, 0x10, 0x32, 0x16, 0x96, - 0xCC, 0x73, 0xF9, 0x1C, 0x3A, 0x95, 0xC3, 0xA0, 0x84, 0x6E, 0x84, 0xB6, 0x54, 0xBC, 0x20, 0x23, - 0x41, 0x02, 0xFC, 0x7D, 0x1A, 0x6D, 0x10, 0xDD, 0xF4, 0x3A, 0xE2, 0x6E, 0x8A, 0x72, 0x9E, 0x19, - 0x3A, 0x95, 0xF3, 0xF9, 0xC5, 0xBC, 0xF0, 0xCF, 0xCF, 0x79, 0x77, 0xF5, 0x8F, 0xD4, 0x5A, 0xEA, - 0xA3, 0x3E, 0x8B, 0x90, 0x45, 0x62, 0xBE, 0xE9, 0x40, 0x1A, 0x75, 0x78, 0x35, 0xCD, 0x8B, 0x48, - 0xA6, 0x0C, 0xC4, 0x96, 0x42, 0x77, 0x26, 0xB7, 0x90, 0x9D, 0x3F, 0x1F, 0x27, 0x36, 0x3C, 0x84, - 0xD8, 0xE8, 0xF0, 0x6B, 0xEF, 0xBE, 0xAF, 0x86, 0xAB, 0xF1, 0xD0, 0x49, 0x93, 0x88, 0x26, 0x20, - 0x25, 0xED, 0x08, 0x4F, 0xCE, 0x59, 0xCA, 0xB7, 0xDB, 0xD3, 0xB0, 0x36, 0x6C, 0x16, 0x0B, 0x90, - 0xCC, 0x58, 0xD1, 0xC1, 0xF4, 0xE9, 0x94, 0xF2, 0xA6, 0x85, 0xC8, 0x4F, 0x6B, 0xF7, 0xC5, 0x16, - 0x72, 0x5A, 0x50, 0x5A, 0xCE, 0x86, 0x9F, 0x7E, 0xA6, 0xA6, 0xA6, 0x96, 0x5E, 0x37, 0x45, 0xC9, - 0x04, 0x1A, 0x57, 0xC1, 0x66, 0xA4, 0xCC, 0x2D, 0x28, 0xE1, 0xEF, 0x9F, 0x7F, 0xC7, 0xEC, 0x05, - 0x5F, 0x34, 0xCA, 0xD2, 0x45, 0x2A, 0x21, 0x4F, 0x22, 0xF3, 0x35, 0x3A, 0x3C, 0x20, 0xA0, 0xB3, - 0xEA, 0xCD, 0x16, 0x21, 0x2D, 0xC2, 0x5D, 0x90, 0x5F, 0x8D, 0x56, 0x4D, 0xE6, 0x5A, 0x76, 0x64, - 0x1C, 0x27, 0xF5, 0xE7, 0xE3, 0xF8, 0x79, 0x79, 0x10, 0x13, 0x1E, 0x8C, 0xA1, 0xB9, 0x64, 0xD1, - 0x96, 0x40, 0x95, 0x96, 0xE2, 0xC2, 0xD2, 0x32, 0xBE, 0xF8, 0xF7, 0x0E, 0x9E, 0x7D, 0xE7, 0x13, - 0x56, 0x6D, 0xFC, 0xC9, 0x1E, 0xCD, 0x0E, 0x92, 0xF8, 0xDB, 0x91, 0xC5, 0x13, 0x5A, 0x57, 0xFE, - 0xA7, 0x1D, 0xD0, 0xD9, 0x5E, 0x8A, 0x40, 0xA4, 0x68, 0xF8, 0x3D, 0x0E, 0xDF, 0x3E, 0xF7, 0x34, - 0xB8, 0x33, 0x6C, 0x40, 0x2F, 0xA6, 0x8C, 0x1B, 0xCE, 0xE8, 0xC1, 0x7D, 0x09, 0x0F, 0x09, 0x40, - 0x51, 0x75, 0x36, 0x95, 0xD7, 0xC9, 0x1C, 0x11, 0x45, 0xB1, 0x79, 0x2A, 0x15, 0x6A, 0x6B, 0x6A, - 0x38, 0x95, 0x93, 0xCF, 0xBA, 0x9D, 0xE9, 0x7C, 0xB5, 0xF1, 0x27, 0x0E, 0x9C, 0x3C, 0x7B, 0x79, - 0x48, 0x4F, 0x39, 0xF0, 0x21, 0xF2, 0x23, 0x98, 0x2E, 0x71, 0xCD, 0x3A, 0x8B, 0xCE, 0x66, 0x08, - 0x48, 0x17, 0xC0, 0x9D, 0xC0, 0x8B, 0xC8, 0x62, 0xC4, 0xF5, 0xB3, 0xD6, 0x4D, 0xAF, 0x23, 0xBE, - 0x6B, 0x24, 0x23, 0x6F, 0xEE, 0xC3, 0xA8, 0x5B, 0x12, 0xE9, 0xD3, 0x3D, 0x86, 0x88, 0xE0, 0x40, - 0xBC, 0x3C, 0xDC, 0x1B, 0xAA, 0xCB, 0x35, 0x82, 0x00, 0x4D, 0x50, 0x6B, 0xB1, 0x50, 0x56, 0x51, - 0xC5, 0x99, 0x0B, 0x85, 0xEC, 0x3B, 0x7A, 0x9A, 0x2D, 0xFB, 0x0E, 0xB3, 0xFB, 0x50, 0x26, 0xF9, - 0x25, 0x65, 0x97, 0xE7, 0xB3, 0xD4, 0x21, 0x3F, 0xA5, 0x3A, 0x17, 0xF9, 0x01, 0xCC, 0x4E, 0x0F, - 0x9D, 0xBD, 0x1E, 0x18, 0x62, 0x47, 0x28, 0xB2, 0xB4, 0xC7, 0x34, 0xA4, 0x7A, 0xDC, 0x68, 0x6C, - 0xEE, 0x6E, 0x7A, 0x42, 0x8D, 0xFE, 0x74, 0x8B, 0x0C, 0x25, 0x36, 0x2A, 0x8C, 0x2E, 0xA1, 0x46, - 0x82, 0xFC, 0x7D, 0xF0, 0xF2, 0x34, 0xA0, 0x2A, 0x2A, 0xE6, 0x5A, 0x0B, 0x15, 0x97, 0xAA, 0xB9, - 0x50, 0x7C, 0x91, 0x9C, 0xFC, 0x62, 0xCE, 0xE4, 0x16, 0x72, 0xBE, 0xB0, 0x84, 0x8A, 0xAA, 0xAB, - 0x26, 0x15, 0xD5, 0x21, 0x93, 0x2C, 0x97, 0x02, 0x5F, 0x21, 0x8D, 0x86, 0xFF, 0x8F, 0xAB, 0x40, - 0x41, 0xA6, 0x44, 0xBC, 0x88, 0xDC, 0xB7, 0xD4, 0xD0, 0x82, 0xEF, 0xA2, 0x3B, 0xF1, 0x2B, 0x03, - 0x7E, 0x40, 0x32, 0x3D, 0xB4, 0xB3, 0x1F, 0xB6, 0x29, 0x02, 0x5C, 0xAF, 0x08, 0x45, 0xD6, 0x06, - 0xBE, 0x0B, 0xF8, 0x15, 0x72, 0xEF, 0xE2, 0x6C, 0x32, 0x91, 0x1D, 0x16, 0xA4, 0x23, 0xE9, 0x38, - 0x32, 0xA1, 0x68, 0x13, 0x72, 0x66, 0x54, 0x75, 0xF6, 0xC3, 0x35, 0x85, 0xEB, 0x99, 0x21, 0x76, - 0xE8, 0x90, 0x16, 0xE3, 0x3E, 0x48, 0xAB, 0x71, 0x5F, 0xA0, 0x07, 0x92, 0x61, 0x01, 0x34, 0xE4, - 0xF5, 0xD5, 0x22, 0x09, 0x5D, 0x8C, 0xF4, 0xEA, 0x1D, 0x45, 0xA6, 0x1C, 0x67, 0x20, 0x23, 0x44, - 0x2A, 0x5B, 0x76, 0xDB, 0xCE, 0xC1, 0xFF, 0x01, 0xCE, 0x34, 0xF5, 0xEC, 0x2D, 0xA9, 0x9C, 0xA8, - 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, 0x31, - 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0xED, 0x4F, 0xCC, - 0x0D, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x6D, 0x6F, - 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, - 0x31, 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x9C, 0x12, - 0x74, 0xB1, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, - 0x72, 0x65, 0x00, 0x77, 0x77, 0x77, 0x2E, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2E, - 0x6F, 0x72, 0x67, 0x9B, 0xEE, 0x3C, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, +#include + +static const uint8_t mu_law_wave[] PROGMEM = { +0x52, 0x49, 0x46, 0x46, 0x84, 0x5D, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20, +0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, +0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x66, 0x61, 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0x00, 0x5D, +0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x5D, 0x00, 0x00, 0xFB, 0xFD, 0xFF, 0xFE, 0xFF, 0x7F, +0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7C, 0x7D, +0x7C, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7E, 0xFF, 0x7F, +0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7C, 0x7C, 0x7B, +0x7B, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, +0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x79, 0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7C, 0x7E, 0xFF, 0xFE, 0xFE, +0xFF, 0x7E, 0x7C, 0x7D, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x79, 0x78, 0x79, +0x7A, 0x79, 0x78, 0x78, 0x78, 0x77, 0x78, 0x78, 0x79, 0x79, 0x78, 0x77, 0x77, 0x78, 0x78, 0x79, +0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, +0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF8, +0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFB, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, +0xFF, 0xFF, 0xFE, 0x7E, 0x7D, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7C, +0x7B, 0x7A, 0x79, 0x79, 0x79, 0x77, 0x77, 0x78, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, +0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x79, +0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, +0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7A, 0x79, +0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, 0xFB, 0xFC, +0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, +0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, +0x7C, 0x7B, 0x79, 0x7A, 0x7A, 0x7A, 0x7A, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7C, 0x79, 0x79, 0x7A, +0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7C, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFE, +0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, +0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, +0x78, 0x78, 0x77, 0x77, 0x77, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, 0x72, 0x73, 0x73, +0x74, 0x74, 0x74, 0x75, 0x77, 0x78, 0x78, 0x77, 0x76, 0x77, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, +0x78, 0x79, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, +0x7E, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFD, 0xFE, 0x7F, 0xFF, +0x7F, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7D, 0x7F, +0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7D, +0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFC, 0xFC, 0xFD, +0xFC, 0xFB, 0xFB, 0xFC, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFD, 0xFE, +0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x79, +0x78, 0x78, 0x78, 0x76, 0x74, 0x74, 0x73, 0x72, 0x75, 0x77, 0x77, 0x76, 0x75, 0x75, 0x76, 0x77, +0x77, 0x76, 0x74, 0x74, 0x74, 0x74, 0x76, 0x76, 0x76, 0x77, 0x75, 0x76, 0x78, 0x79, 0x77, 0x77, +0x79, 0x7B, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFE, +0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7F, 0x7F, 0x7D, 0x7E, 0xFF, 0x7F, +0x7F, 0xFF, 0x7F, 0x7E, 0x7D, 0x7E, 0xFF, 0x7E, 0x7F, 0x7F, 0x7C, 0x7D, 0x7F, 0x7D, 0x7E, 0x7E, +0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x7D, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, +0x7D, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFB, 0xFB, +0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, +0x78, 0x79, 0x78, 0x75, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x73, 0x74, 0x73, 0x72, 0x73, +0x75, 0x75, 0x74, 0x76, 0x74, 0x72, 0x73, 0x74, 0x75, 0x75, 0x76, 0x77, 0x77, 0x78, 0x77, 0x77, +0x77, 0x78, 0x78, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, +0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7C, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, +0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, +0xFE, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0xFF, 0x7E, 0x7E, 0x7E, 0x7D, +0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, +0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7B, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7D, 0x7C, 0x7C, +0x7D, 0x7C, 0x7C, 0x7E, 0x7E, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, +0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, +0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, +0x7E, 0x7E, 0x7E, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7F, +0x7D, 0x7B, 0x7C, 0x7C, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7E, +0x7F, 0x7E, 0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x74, 0x73, +0x72, 0x73, 0x74, 0x75, 0x77, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, +0x7C, 0x7D, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, +0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x79, 0x79, +0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, +0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7D, 0x7D, +0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, +0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, +0x7A, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, +0x7D, 0x7E, 0xFF, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, +0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7C, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x78, +0x78, 0x77, 0x77, 0x76, 0x75, 0x74, 0x74, 0x74, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x76, 0x75, +0x74, 0x75, 0x77, 0x78, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, +0xFC, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, +0xF8, 0xFA, 0xF8, 0xF6, 0xF7, 0xF7, 0xF8, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFB, +0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, +0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFD, 0xFE, 0xFF, +0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, +0x7D, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x78, 0x79, 0x78, 0x77, 0x76, +0x76, 0x75, 0x73, 0x74, 0x73, 0x71, 0x70, 0x70, 0x71, 0x72, 0x71, 0x71, 0x70, 0x6F, 0x6F, 0x6F, +0x70, 0x71, 0x71, 0x72, 0x73, 0x74, 0x74, 0x74, 0x76, 0x77, 0x76, 0x78, 0x79, 0x79, 0x79, 0x78, +0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, +0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7D, +0x7D, 0x7D, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7C, 0x7A, 0x78, 0x79, 0x78, 0x77, +0x76, 0x78, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, +0x7E, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, 0xFA, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, +0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF7, 0xF9, 0xF9, 0xF8, 0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFD, 0xFD, +0xFC, 0xFD, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0x7F, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, +0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x75, 0x76, 0x76, 0x75, 0x76, 0x77, +0x78, 0x79, 0x7B, 0x7B, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7A, 0x7B, 0x7B, 0x7A, +0x7B, 0x7D, 0x7E, 0x7B, 0x7C, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFE, 0xFF, +0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7D, 0x7F, 0x7F, 0x7C, 0x7B, +0x7A, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7C, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7C, 0x7C, +0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, +0x7D, 0xFE, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF9, 0xF8, 0xF5, 0xF4, 0xF7, 0xF8, +0xF8, 0xF8, 0xF9, 0xFB, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, +0x7A, 0x7B, 0x7B, 0x7A, 0x78, 0x78, 0x77, 0x76, 0x76, 0x75, 0x76, 0x76, 0x76, 0x77, 0x75, 0x75, +0x76, 0x75, 0x76, 0x76, 0x78, 0x78, 0x77, 0x78, 0x76, 0x74, 0x75, 0x77, 0x79, 0x7A, 0x7A, 0x7B, +0x7C, 0x7D, 0x7D, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, +0xFE, 0x7F, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0xFF, 0xFD, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, +0xFC, 0xFD, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, +0x7B, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7E, 0x7E, 0xFF, +0xFF, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, +0x7C, 0x7D, 0xFF, 0x7E, 0x7C, 0x7D, 0xFF, 0xFF, 0xFF, 0xFD, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, 0x7E, +0x7F, 0x7E, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x79, +0x77, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7C, 0x7D, 0x7D, 0x7E, 0xFD, 0xFD, 0xFE, 0xFC, 0xFC, 0xFB, +0xFB, 0xFC, 0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, +0xFF, 0xFF, 0xFD, 0xFC, 0xFD, 0xFD, 0xFC, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7C, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, +0x7B, 0x7C, 0x7D, 0x7B, 0x7B, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x75, 0x73, 0x72, +0x72, 0x72, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x74, +0x75, 0x76, 0x76, 0x76, 0x77, 0x78, 0x77, 0x78, 0x79, 0x77, 0x78, 0x78, 0x79, 0x7A, 0x7A, 0x7A, +0x7A, 0x79, 0x77, 0x76, 0x76, 0x78, 0x78, 0x77, 0x77, 0x77, 0x75, 0x74, 0x74, 0x75, 0x75, 0x76, +0x79, 0x79, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7D, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFE, 0xFC, +0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF4, 0xF6, 0xF8, 0xF7, 0xF7, 0xF9, 0xF9, +0xF9, 0xF8, 0xF8, 0xFB, 0xFA, 0xF9, 0xFA, 0xFB, 0xFC, 0xFE, 0xFC, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, +0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, +0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7F, 0xFE, 0xFE, 0xFD, 0xFD, +0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFB, 0xFC, +0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, +0x7C, 0x7B, 0x7B, 0x7C, 0x79, 0x79, 0x79, 0x78, 0x76, 0x75, 0x76, 0x78, 0x77, 0x76, 0x76, 0x77, +0x76, 0x74, 0x74, 0x75, 0x75, 0x75, 0x74, 0x74, 0x76, 0x77, 0x78, 0x7A, 0x7C, 0x7B, 0x7A, 0x7D, +0x7E, 0x7E, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, +0xFF, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFE, 0xFD, 0xFC, 0xFE, +0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7F, 0xFE, 0xFC, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0x7F, 0x7E, 0xFF, +0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7E, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, +0x7E, 0x7D, 0x7E, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7B, 0x7B, +0x7D, 0x7E, 0x7E, 0x7D, 0xFF, 0xFF, 0x7F, 0x7F, 0x7E, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x77, 0x77, +0x77, 0x78, 0x78, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x74, 0x74, 0x75, 0x74, 0x72, 0x74, +0x76, 0x74, 0x74, 0x76, 0x76, 0x74, 0x73, 0x73, 0x72, 0x73, 0x74, 0x76, 0x77, 0x75, 0x73, 0x75, +0x77, 0x78, 0x75, 0x75, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7B, +0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7C, 0x7F, +0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x79, 0x77, 0x77, +0x78, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7B, 0x7C, 0x7B, 0x7C, 0x7D, 0xFF, +0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, +0xFA, 0xF9, 0xF9, 0xF7, 0xF7, 0xF7, 0xF4, 0xF4, 0xF4, 0xF2, 0xEF, 0xEE, 0xEF, 0xF2, 0xF2, 0xF1, +0xF2, 0xF5, 0xF5, 0xF3, 0xF1, 0xF2, 0xF5, 0xF7, 0xF8, 0xFA, 0xFB, 0xFC, 0xFC, 0xFB, 0xFC, 0xFC, +0xFD, 0xFF, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, 0x78, 0x77, 0x76, 0x75, 0x75, 0x74, 0x71, 0x70, 0x71, +0x71, 0x71, 0x70, 0x6F, 0x71, 0x71, 0x71, 0x73, 0x75, 0x77, 0x77, 0x76, 0x79, 0x7A, 0x79, 0x79, +0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0x7E, 0x7D, 0x7E, 0x7E, 0x7D, 0x7D, +0x7E, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x78, +0x7A, 0x7C, 0x7C, 0x7A, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7D, 0x7C, +0x7C, 0x7E, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7E, +0x7D, 0x7D, 0xFF, 0xFF, 0x7F, 0xFF, 0xFC, 0xFC, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, +0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7F, 0x7F, 0x7E, 0x7D, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, +0x7B, 0x7C, 0x7C, 0x7A, 0x78, 0x78, 0x7B, 0x7A, 0x77, 0x75, 0x76, 0x75, 0x76, 0x76, 0x76, 0x76, +0x78, 0x79, 0x78, 0x75, 0x75, 0x76, 0x77, 0x7A, 0x7D, 0xFF, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFA, +0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0x7E, 0x78, 0x76, 0x72, 0x70, 0x71, 0x75, 0x77, 0x77, 0x79, 0x7A, +0x7A, 0x7A, 0x7B, 0xFF, 0xFB, 0xFA, 0xF9, 0xFB, 0xFD, 0xFE, 0x7E, 0x7F, 0xFF, 0xFC, 0xF6, 0xF3, +0xF7, 0xFC, 0xFF, 0x7A, 0x73, 0x6E, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6E, 0x6F, 0x74, 0x73, 0x72, +0x75, 0x7A, 0x7D, 0x7D, 0xFF, 0xFF, 0x7C, 0x7C, 0x7D, 0x7B, 0x7A, 0x79, 0x7B, 0xFF, 0xFF, 0x7D, +0x7C, 0xFF, 0xFE, 0x7D, 0xFC, 0xF3, 0xF6, 0xFC, 0xFE, 0xFE, 0xFF, 0x78, 0x75, 0x79, 0x7A, 0x7E, +0xF8, 0xF6, 0xF6, 0xF2, 0xEF, 0xEE, 0xF0, 0xF7, 0xFD, 0xFE, 0xFD, 0x7B, 0x77, 0x7C, 0xFF, 0xFB, +0xFD, 0x7D, 0xFF, 0x7C, 0x78, 0x7A, 0x7A, 0xFF, 0xF9, 0xF5, 0xF1, 0xF4, 0xFA, 0xFC, 0xFC, 0xFA, +0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFF, 0x7D, 0x7B, 0x7D, 0x7E, 0x7A, 0x76, 0x76, 0x75, +0x72, 0x75, 0x7B, 0x7D, 0x7A, 0x7A, 0x7D, 0xFF, 0x7C, 0x7C, 0xFF, 0x7D, 0x7A, 0x7B, 0x7C, 0x7E, +0xFC, 0xFC, 0x7F, 0xFE, 0xFD, 0xFE, 0xFC, 0xF8, 0xF9, 0xFA, 0xFB, 0xFE, 0x7E, 0x79, 0x72, 0x72, +0x74, 0x76, 0x78, 0x76, 0x78, 0x7A, 0x75, 0x76, 0x77, 0x75, 0x73, 0x73, 0x73, 0x73, 0x74, 0x73, +0x73, 0x77, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x73, 0x73, 0x7B, 0x7C, 0x7C, 0xFC, 0xFC, 0xFE, 0x7F, +0x76, 0x73, 0x76, 0x73, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0x7D, 0x7B, 0x7B, +0x7C, 0x7A, 0x78, 0x7B, 0x7B, 0x7D, 0x7F, 0x7A, 0x77, 0x73, 0x6F, 0x70, 0x72, 0x73, 0x72, 0x72, +0x73, 0x74, 0x74, 0x76, 0x7D, 0xFE, 0x7D, 0x7C, 0x7C, 0x78, 0x76, 0x77, 0x79, 0x7B, 0xFF, 0xFD, +0xFE, 0x7E, 0x7B, 0x7A, 0x78, 0x78, 0x7B, 0x7C, 0x7C, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x79, 0x7B, +0xFF, 0xFA, 0xF9, 0xFD, 0x7E, 0x7D, 0x7C, 0x7B, 0x7E, 0xFE, 0xFC, 0xFF, 0x7E, 0xFE, 0xFD, 0xFE, +0xFD, 0xFC, 0xFB, 0xFC, 0xFC, 0xFD, 0xF9, 0xF3, 0xF2, 0xF3, 0xF4, 0xF6, 0xF6, 0xF8, 0xFA, 0xFC, +0xFB, 0xF7, 0xF9, 0xFC, 0xFC, 0xFD, 0xFD, 0x7E, 0x7C, 0x7F, 0xFF, 0x7D, 0x7A, 0x7A, 0x7B, 0x78, +0x78, 0x78, 0x75, 0x75, 0x76, 0x79, 0x7A, 0x79, 0x7C, 0x7F, 0xFD, 0xFF, 0x7E, 0xFF, 0x7D, 0x79, +0x77, 0x78, 0x79, 0x78, 0x79, 0x7C, 0x7D, 0x7F, 0x7E, 0x7E, 0xFE, 0xFC, 0xF8, 0xF7, 0xFA, 0xFB, +0xFC, 0xFD, 0xFF, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, 0x7B, 0x7D, 0xFE, 0xF9, 0xF5, 0xF6, 0xF6, 0xF4, +0xF6, 0xFA, 0xFE, 0x7D, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFF, 0xFF, 0xFA, 0xFA, 0xFE, +0x7C, 0x75, 0x71, 0x72, 0x74, 0x75, 0x74, 0x75, 0x75, 0x77, 0x79, 0x79, 0x77, 0x74, 0x74, 0x74, +0x72, 0x71, 0x70, 0x71, 0x70, 0x6F, 0x72, 0x73, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7A, 0x78, +0x77, 0x77, 0x76, 0x74, 0x73, 0x72, 0x70, 0x71, 0x75, 0x78, 0x7B, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, +0x7E, 0xFF, 0xFD, 0x7F, 0x7C, 0x7B, 0x7F, 0xFD, 0xFF, 0xFE, 0xFC, 0xFE, 0xFD, 0xFC, 0xFA, 0xF7, +0xF7, 0xFB, 0xFD, 0xFE, 0x7E, 0x7C, 0x7B, 0x7A, 0x7B, 0x79, 0x75, 0x75, 0x76, 0x78, 0x7D, 0xFF, +0x7E, 0x7D, 0x7E, 0x7C, 0x77, 0x75, 0x76, 0x76, 0x78, 0x7E, 0xFD, 0xFB, 0xFC, 0xFD, 0xFE, 0x7C, +0x78, 0x78, 0x7A, 0x7B, 0x7E, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x78, 0x79, 0x7B, 0x7A, 0x7D, 0xFC, +0xFD, 0x7E, 0xFF, 0xFB, 0xF7, 0xF6, 0xF7, 0xF7, 0xF6, 0xFA, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0xFF, +0xFC, 0xFB, 0xF9, 0xFD, 0xFE, 0xFD, 0x7E, 0x79, 0x76, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x72, 0x76, +0x7A, 0x7E, 0xFF, 0xFF, 0x7C, 0x7B, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7E, 0xFF, 0xFF, 0x7E, 0x7D, +0x7D, 0x7E, 0x7C, 0x78, 0x79, 0x7A, 0x7B, 0xFF, 0xFF, 0x7F, 0x7E, 0x7B, 0x79, 0x79, 0x76, 0x72, +0x73, 0x7B, 0xFF, 0xFE, 0xFB, 0xFA, 0xFA, 0xFC, 0x7D, 0x78, 0x77, 0x78, 0x79, 0x79, 0x78, 0x79, +0x77, 0x73, 0x74, 0x76, 0x77, 0x79, 0x7A, 0x7B, 0x7F, 0xFD, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0x7C, +0x78, 0x78, 0x7B, 0x7B, 0x7A, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0x7E, 0xFF, 0xFD, 0xFC, 0xF9, 0xF5, +0xF2, 0xF0, 0xF2, 0xF3, 0xF0, 0xF1, 0xF2, 0xF1, 0xF4, 0xF7, 0xF8, 0xFC, 0xFC, 0xF6, 0xF3, 0xF4, +0xF5, 0xF5, 0xF6, 0xFB, 0xFF, 0xFF, 0xFF, 0x7D, 0x7D, 0x7E, 0x7D, 0x79, 0x75, 0x74, 0x75, 0x72, +0x72, 0x75, 0x75, 0x74, 0x77, 0x7A, 0x7A, 0x7A, 0x7A, 0x77, 0x74, 0x73, 0x72, 0x74, 0x75, 0x76, +0x77, 0x74, 0x74, 0x77, 0x79, 0x79, 0x79, 0x78, 0x77, 0x74, 0x70, 0x6F, 0x70, 0x6F, 0x6E, 0x6E, +0x6E, 0x6F, 0x6F, 0x72, 0x75, 0x72, 0x74, 0x79, 0x7B, 0x7B, 0x7B, 0x7D, 0xFF, 0x7E, 0x7F, 0xFE, +0xFE, 0x7F, 0x7D, 0x7D, 0xFF, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7E, 0x7C, 0x79, 0x77, 0x75, 0x76, +0x77, 0x78, 0x78, 0x74, 0x75, 0x7A, 0x7F, 0xFB, 0xF9, 0xF9, 0xF8, 0xFD, 0x7E, 0x7B, 0x76, 0x78, +0x7B, 0x7C, 0x7E, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7C, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x7D, 0x7B, +0x7B, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0x7F, 0x7F, 0xFF, 0xFD, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0x7D, +0x7C, 0x7F, 0xFB, 0xF7, 0xF6, 0xFC, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0x7C, +0x76, 0x74, 0x74, 0x79, 0x79, 0x76, 0x77, 0x79, 0x7C, 0x7D, 0x7B, 0x7B, 0x7B, 0x7E, 0xFD, 0xFB, +0xF9, 0xF9, 0xFE, 0x7C, 0x79, 0x79, 0x77, 0x76, 0x79, 0x7B, 0x7D, 0x7C, 0x7C, 0x7D, 0x7C, 0x78, +0x75, 0x74, 0x72, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0x7F, 0x7F, 0x7D, +0x7A, 0x78, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x7B, 0xFF, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, +0xF8, 0xF9, 0xFE, 0x7E, 0xFF, 0xFE, 0xFE, 0x7D, 0x7A, 0x78, 0x75, 0x75, 0x77, 0x7A, 0x7A, 0x79, +0x7B, 0x7D, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF7, +0xF8, 0xFA, 0xF8, 0xF9, 0xFC, 0xFD, 0xFD, 0xFC, 0xF9, 0xF7, 0xF8, 0xFC, 0x7E, 0x7B, 0x7A, 0x7A, +0x79, 0x79, 0x7A, 0x7A, 0x7A, 0x77, 0x72, 0x72, 0x74, 0x76, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, +0x7D, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, +0x7A, 0x7A, 0x77, 0x75, 0x75, 0x74, 0x73, 0x70, 0x6E, 0x6E, 0x6E, 0x6F, 0x72, 0x75, 0x77, 0x7A, +0x7D, 0x7D, 0x7D, 0x7E, 0xFF, 0x7D, 0x7A, 0x7A, 0x7A, 0x7B, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, +0x7D, 0x7B, 0x78, 0x75, 0x73, 0x74, 0x75, 0x75, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7D, 0xFE, 0xFC, +0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, 0xF6, 0xF8, 0xFB, 0xFC, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x7C, +0x7C, 0x7B, 0x7C, 0x7B, 0x79, 0x79, 0x7A, 0x79, 0x76, 0x74, 0x72, 0x72, 0x73, 0x74, 0x75, 0x77, +0x78, 0x78, 0x78, 0x77, 0x76, 0x75, 0x75, 0x78, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, +0xFE, 0xFC, 0xFC, 0xFC, 0xFA, 0xF8, 0xF7, 0xF7, 0xF8, 0xF7, 0xF5, 0xF5, 0xF5, 0xF4, 0xF5, 0xF6, +0xF7, 0xF8, 0xF9, 0xFB, 0xFE, 0x7F, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7D, 0x7A, 0x7A, 0x7A, +0x7A, 0x79, 0x79, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7A, 0x7A, 0x79, 0x77, 0x76, +0x77, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7B, +0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0xFE, +0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, +0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x76, 0x77, 0x78, 0x77, 0x79, +0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7D, 0x7B, 0x7B, 0x7D, 0x7C, 0x7D, 0xFF, 0x7E, +0xFF, 0xFD, 0xFB, 0xF9, 0xF8, 0xF9, 0xF9, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF3, 0xF5, 0xF6, 0xF6, +0xF7, 0xF9, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFC, 0xFB, 0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xF8, +0xF8, 0xF9, 0xFB, 0xFD, 0x7E, 0x7B, 0x78, 0x78, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x75, 0x75, +0x73, 0x71, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x6E, 0x6E, 0x6E, 0x6D, +0x6D, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x70, 0x72, 0x73, 0x74, 0x75, 0x79, 0x7C, 0x7D, 0x7E, 0xFF, +0xFF, 0xFF, 0xFD, 0xFC, 0xFA, 0xF9, 0xFB, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0x7E, 0x7B, 0x7A, +0x79, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7C, 0x7C, 0x7B, 0x79, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x7C, +0x7E, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0xFD, +0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFB, 0xFB, +0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFD, 0xFC, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF7, +0xF6, 0xF7, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7D, 0x7C, 0x7C, +0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, +0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x78, 0x77, 0x76, 0x75, 0x75, 0x75, 0x76, 0x76, 0x75, 0x76, +0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFE, +0xFD, 0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFF, 0x7F, 0x7E, 0x7C, 0x7C, 0x7B, +0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7B, +0x7A, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7B, 0x7F, 0xFD, 0x7D, 0x79, 0xFE, +0xFA, 0xFE, 0xFC, 0xF8, 0xFC, 0xFF, 0xFF, 0xFE, 0xFB, 0xFC, 0x7F, 0xFF, 0x7F, 0x7C, 0x7D, 0x7D, +0x7E, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, +0x7D, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, +0x7D, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x74, 0x73, +0x74, 0x75, 0x74, 0x74, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x77, 0x77, 0x79, 0x7B, 0x7C, 0x7D, +0x7D, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFB, 0xFC, 0xFD, +0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, +0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, +0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, +0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, +0x7D, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x77, 0x78, 0x76, 0x76, 0x78, 0x7A, 0x78, 0x78, 0x78, 0x77, +0x77, 0x76, 0x75, 0x76, 0x75, 0x75, 0x77, 0x77, 0x76, 0x74, 0x74, 0x75, 0x76, 0x75, 0x76, 0x76, +0x75, 0x76, 0x76, 0x75, 0x74, 0x73, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x78, 0x7A, 0x7A, 0x7B, +0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFD, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xFE, +0xFE, 0xFE, 0x7F, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFD, 0xFD, 0xFD, +0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0xFE, 0xFC, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF9, 0xFA, +0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0xFE, 0xFF, 0x7F, 0xFF, 0x7E, 0x7D, 0x7B, 0x79, 0x79, 0x7B, 0x7C, +0x7C, 0x7D, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x78, 0x75, 0x75, 0x76, 0x76, +0x78, 0x75, 0x76, 0x77, 0x73, 0x75, 0x73, 0x77, 0x76, 0x73, 0x78, 0x73, 0x78, 0x77, 0x75, 0x7B, +0x70, 0x7E, 0x68, 0x5B, 0xE4, 0xD9, 0x77, 0x66, 0x5F, 0x6B, 0xEB, 0x78, 0x6B, 0xEC, 0xE9, 0x67, +0x5A, 0x62, 0xF8, 0xE2, 0xF1, 0x6B, 0x6F, 0x72, 0x6E, 0x6D, 0x72, 0xEF, 0xE7, 0xF7, 0x6D, 0x6A, +0x70, 0x7B, 0xFC, 0xF5, 0xED, 0xEF, 0x7D, 0x71, 0x70, 0xFF, 0xEE, 0xEF, 0xF8, 0xFC, 0x7B, 0x73, +0x6F, 0x71, 0x7E, 0xF2, 0xF2, 0x76, 0x67, 0x68, 0x78, 0xF7, 0xF5, 0xFC, 0x7E, 0x7B, 0x73, 0x70, +0x79, 0xF4, 0xEB, 0xEC, 0xF8, 0x7C, 0x7B, 0xFF, 0xF6, 0xEF, 0xEF, 0xF4, 0xF8, 0xFE, 0x7D, 0xFE, +0xF8, 0xF4, 0xF4, 0xF9, 0xFE, 0x7E, 0x7C, 0x7C, 0xFD, 0xF8, 0xF8, 0xFD, 0x7D, 0x7A, 0x79, 0x7C, +0xFF, 0xFD, 0xFB, 0xFC, 0x7D, 0x7B, 0x7D, 0x7F, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7A, 0x79, 0x7C, +0x7E, 0x7D, 0x7D, 0x7B, 0x78, 0x79, 0x7B, 0x7A, 0x78, 0x79, 0x77, 0x76, 0x78, 0x71, 0x70, 0x78, +0x7E, 0xF6, 0xFE, 0x67, 0x68, 0xF4, 0xEF, 0x74, 0x69, 0x6A, 0xFF, 0x7E, 0x6E, 0xF2, 0xFB, 0x69, +0x66, 0x69, 0xDD, 0xD9, 0x71, 0x7B, 0x74, 0x5F, 0x69, 0x61, 0x6A, 0xE6, 0xEC, 0x66, 0x55, 0x50, +0x5C, 0xFB, 0xED, 0xF5, 0xFA, 0x6F, 0x6E, 0x7B, 0xE8, 0xCF, 0xC7, 0xC6, 0xCA, 0xCB, 0xDB, 0x3A, +0x2E, 0x49, 0xBD, 0xB7, 0xC6, 0x4D, 0x41, 0x4B, 0x49, 0x4D, 0xD9, 0xBF, 0xC2, 0xFD, 0x3F, 0x3D, +0x51, 0xDF, 0xCD, 0xCC, 0xD5, 0xF4, 0x50, 0x46, 0x4D, 0xF0, 0xCB, 0xCA, 0xDA, 0x61, 0x51, 0x52, +0x5B, 0xE6, 0xD0, 0xCE, 0xDC, 0x5D, 0x53, 0x51, 0x6A, 0xF9, 0x48, 0x67, 0xC2, 0xE0, 0x5F, 0x5B, +0x4C, 0x71, 0xFA, 0x6E, 0xCE, 0xCF, 0x7A, 0x64, 0x79, 0xD8, 0xCE, 0xD1, 0xCD, 0xC3, 0xC5, 0xCD, +0xC7, 0xDC, 0x42, 0x3E, 0x53, 0xD2, 0xC0, 0xDE, 0x44, 0x48, 0x58, 0x53, 0x59, 0xFA, 0xD9, 0xD6, +0x5E, 0x43, 0x47, 0x61, 0xE1, 0xD8, 0xEA, 0x64, 0x46, 0x3C, 0x51, 0x7F, 0x77, 0xD0, 0xF6, 0x4B, +0x4B, 0x4A, 0x6F, 0xCA, 0xC6, 0xC9, 0xC7, 0xC2, 0xC8, 0xBD, 0xB0, 0xAB, 0xBB, 0x1F, 0x19, 0x5F, +0xA3, 0xA5, 0xBA, 0x30, 0x30, 0x47, 0x31, 0x37, 0xBC, 0xAB, 0xB8, 0x3D, 0x2B, 0x30, 0x4E, 0xBD, +0xB4, 0xC4, 0x5D, 0x3F, 0x38, 0x41, 0x6E, 0xC8, 0xC1, 0xDC, 0x4B, 0x3B, 0x3F, 0xE5, 0xBF, 0xBC, +0xC8, 0xE5, 0xDE, 0xC0, 0xAE, 0xAD, 0xAF, 0xC1, 0x20, 0x1A, 0x63, 0xA8, 0xA7, 0xB5, 0x36, 0x2E, +0x3D, 0x32, 0x3F, 0xBD, 0xB1, 0xC1, 0x39, 0x2E, 0x42, 0xE8, 0xCA, 0xC3, 0xDB, 0x5F, 0x47, 0x39, +0x47, 0xD5, 0xCB, 0xD1, 0x70, 0x4B, 0x4D, 0xF0, 0xC1, 0xB3, 0xAE, 0xB4, 0xBE, 0xB8, 0xB8, 0x34, +0x1C, 0x27, 0xB6, 0xA3, 0xAC, 0x4F, 0x2C, 0x32, 0x3B, 0x3E, 0xEB, 0xB9, 0xBB, 0x45, 0x2E, 0x39, +0x60, 0xC3, 0xBB, 0xD8, 0x4D, 0x45, 0x41, 0x57, 0xD6, 0xDE, 0x79, 0x5D, 0x50, 0x5B, 0xDB, 0xBE, +0xB4, 0xB3, 0xBC, 0xC4, 0xB6, 0xAC, 0xC2, 0x26, 0x1A, 0x30, 0xAB, 0xA9, 0xBB, 0x61, 0x33, 0x30, +0x36, 0x39, 0xCF, 0xB9, 0x64, 0x41, 0x42, 0x3E, 0x5E, 0xD3, 0xCF, 0xC4, 0xEC, 0x47, 0x56, 0x5C, +0x50, 0x57, 0x62, 0xDF, 0xD2, 0xD3, 0xC4, 0xB6, 0xB3, 0xBA, 0xB8, 0xAD, 0xAF, 0x3C, 0x1C, 0x1E, +0xCB, 0xA1, 0xA9, 0xFE, 0x2D, 0x2C, 0x39, 0x3D, 0x64, 0xBE, 0xD5, 0x4B, 0x42, 0x3A, 0x40, 0xEC, +0xC4, 0xBE, 0xD1, 0x4A, 0x3E, 0x47, 0x62, 0xE4, 0xD7, 0xD6, 0xDC, 0xDE, 0xCD, 0xB6, 0xAD, 0xAE, +0xAC, 0xAD, 0xE6, 0x22, 0x19, 0x2E, 0xA6, 0x9E, 0xB2, 0x39, 0x28, 0x2D, 0x39, 0x4E, 0xC2, 0xBE, +0x5B, 0x3E, 0x3B, 0x3C, 0x58, 0xC6, 0xBD, 0xC7, 0x60, 0x3F, 0x3F, 0x51, 0xED, 0xCF, 0xC8, 0xD1, +0xE0, 0xD9, 0xBC, 0xAC, 0xAB, 0xAB, 0xA9, 0xC2, 0x25, 0x17, 0x22, 0xAE, 0x9D, 0xA9, 0x47, 0x26, +0x29, 0x34, 0x47, 0xC5, 0xBB, 0x77, 0x3F, 0x3A, 0x38, 0x4E, 0xC6, 0xBC, 0xBE, 0xE6, 0x3D, 0x39, +0x43, 0x67, 0xCE, 0xC7, 0xD6, 0xED, 0xD9, 0xBD, 0xAB, 0xAB, 0xAE, 0xA9, 0xB4, 0x30, 0x1A, 0x1B, +0xD5, 0x9D, 0xA3, 0xDA, 0x2A, 0x26, 0x31, 0x3C, 0x6C, 0xBF, 0xCE, 0x5E, 0x42, 0x32, 0x3C, 0xD6, +0xBC, 0xB8, 0xCC, 0x3F, 0x37, 0x3B, 0x51, 0xCC, 0xC1, 0xCC, 0xE2, 0xDE, 0xBD, 0xAC, 0xAA, 0xA9, +0xA7, 0xC5, 0x26, 0x18, 0x1F, 0xB7, 0x9D, 0xA6, 0xDF, 0x2B, 0x26, 0x2D, 0x37, 0xEB, 0xBA, 0xCB, +0x5E, 0x3C, 0x30, 0x44, 0xC9, 0xBB, 0xB8, 0xCF, 0x3D, 0x34, 0x3B, 0x5F, 0xC1, 0xBE, 0xCE, 0xD6, +0xCE, 0xB8, 0xAB, 0xAA, 0xA4, 0xA8, 0x42, 0x1C, 0x18, 0x31, 0xA4, 0x9F, 0xAF, 0x48, 0x29, 0x28, +0x2C, 0x37, 0xCC, 0xBA, 0xC7, 0x57, 0x30, 0x31, 0x5A, 0xC6, 0xB6, 0xB7, 0x5F, 0x38, 0x34, 0x3D, +0xE2, 0xBD, 0xBD, 0xC7, 0xD2, 0xCA, 0xB2, 0xAB, 0xA7, 0xA2, 0xB3, 0x29, 0x18, 0x1C, 0xD2, 0x9F, +0xA5, 0xBC, 0x3A, 0x2A, 0x29, 0x2A, 0x3E, 0xC3, 0xBB, 0xC1, 0x43, 0x2D, 0x3A, 0xF5, 0xC1, 0xB5, +0xBE, 0x4F, 0x36, 0x32, 0x3F, 0xD2, 0xBB, 0xBA, 0xBE, 0xC5, 0xBF, 0xB1, 0xAB, 0xA4, 0xA7, 0x75, +0x1F, 0x18, 0x27, 0xAE, 0xA2, 0xAD, 0xD6, 0x36, 0x2B, 0x28, 0x2C, 0x4E, 0xC2, 0xB8, 0xC9, 0x35, +0x2F, 0x42, 0x71, 0xBA, 0xB4, 0xD2, 0x44, 0x34, 0x34, 0x4C, 0xCD, 0xBE, 0xBB, 0xB9, 0xBC, 0xB3, +0xAE, 0xAB, 0xA3, 0xB0, 0x2C, 0x1A, 0x1C, 0x5F, 0xA4, 0xA9, 0xBA, 0x6F, 0x34, 0x28, 0x26, 0x32, +0x77, 0xB9, 0xB3, 0x5E, 0x32, 0x38, 0x40, 0xD8, 0xB6, 0xBE, 0xF4, 0x40, 0x34, 0x3A, 0x5B, 0xC7, +0xB7, 0xB4, 0xB7, 0xB4, 0xB2, 0xAE, 0xA5, 0xAB, 0x3B, 0x1D, 0x1B, 0x34, 0xAE, 0xAA, 0xB4, 0xC7, +0x42, 0x2C, 0x25, 0x2B, 0x43, 0xCF, 0xB5, 0xBE, 0x3F, 0x38, 0x3D, 0x4D, 0xC4, 0xBD, 0xCF, 0x5D, +0x3E, 0x38, 0x43, 0xE4, 0xBF, 0xB4, 0xAF, 0xB0, 0xAF, 0xAE, 0xA8, 0xA7, 0xF6, 0x21, 0x1A, 0x27, +0xBA, 0xAC, 0xB5, 0xB9, 0xE2, 0x36, 0x26, 0x25, 0x33, 0x4E, 0xBA, 0xB2, 0x64, 0x41, 0x3F, 0x3D, +0xE6, 0xC6, 0xCD, 0xD4, 0x50, 0x3D, 0x3C, 0x48, 0xD4, 0xB9, 0xAF, 0xAD, 0xAE, 0xAE, 0xAA, 0xA7, +0xC0, 0x2A, 0x1B, 0x1F, 0x65, 0xAF, 0xB5, 0xB5, 0xBF, 0x4C, 0x2C, 0x23, 0x2A, 0x37, 0xE6, 0xAF, +0xBC, 0x5B, 0x4B, 0x3B, 0x49, 0xCF, 0xCE, 0xD0, 0xDE, 0x4F, 0x40, 0x3F, 0x57, 0xC7, 0xB3, 0xAA, +0xA9, 0xAC, 0xAE, 0xA9, 0xAE, 0x3B, 0x1E, 0x1E, 0x37, 0xBA, 0xB7, 0xB7, 0xB5, 0xC9, 0x3A, 0x26, +0x27, 0x2E, 0x37, 0xC1, 0xB1, 0xCA, 0xE8, 0x49, 0x3E, 0x62, 0x78, 0xEF, 0xD7, 0x69, 0x4F, 0x44, +0x48, 0xFB, 0xC5, 0xAF, 0xA9, 0xA8, 0xAA, 0xAB, 0xAA, 0xCF, 0x26, 0x1C, 0x22, 0x4A, 0xBD, 0xBB, +0xAF, 0xB1, 0xD7, 0x31, 0x25, 0x27, 0x28, 0x38, 0xB9, 0xB6, 0xC3, 0xCB, 0x4B, 0x45, 0x4E, 0x47, +0x62, 0xE0, 0xF9, 0x5C, 0x4C, 0x5C, 0xE4, 0xBF, 0xAD, 0xA8, 0xA5, 0xA7, 0xA9, 0xB2, 0x36, 0x20, +0x1E, 0x29, 0x56, 0xCC, 0xB8, 0xAC, 0xB5, 0xFA, 0x2F, 0x28, 0x25, 0x25, 0x45, 0xBE, 0xBF, 0xB8, +0xC5, 0x5F, 0x54, 0x41, 0x43, 0x4F, 0x56, 0x75, 0x70, 0xFE, 0xE2, 0xD3, 0xB9, 0xAD, 0xA8, 0xA6, +0xA6, 0xA8, 0xCA, 0x2D, 0x22, 0x21, 0x2E, 0x47, 0x77, 0xB4, 0xAD, 0xB7, 0xDC, 0x39, 0x2D, 0x24, +0x28, 0x40, 0x5A, 0xC7, 0xB5, 0xBD, 0xC0, 0xDB, 0x4E, 0x4C, 0x40, 0x44, 0x4E, 0x56, 0xDA, 0xCC, +0xC0, 0xB1, 0xAC, 0xA7, 0xA5, 0xA6, 0xAD, 0x4F, 0x2A, 0x23, 0x25, 0x2F, 0x39, 0x6C, 0xB6, 0xB1, +0xB7, 0xD6, 0x43, 0x2F, 0x26, 0x2C, 0x35, 0x3A, 0xDF, 0xC7, 0xBE, 0xBA, 0xCB, 0xD4, 0x6E, 0x48, +0x44, 0x3E, 0x4A, 0x6C, 0xD6, 0xB9, 0xB0, 0xA8, 0xA4, 0xA5, 0xA4, 0xB5, 0x42, 0x2C, 0x23, 0x27, +0x2B, 0x2E, 0x55, 0xC2, 0xB9, 0xB6, 0xC5, 0xF4, 0x3C, 0x32, 0x34, 0x2F, 0x37, 0x4A, 0x5B, 0xCF, +0xC9, 0xC6, 0xC0, 0xCA, 0xCF, 0xF4, 0x52, 0x51, 0x4E, 0xF8, 0xC4, 0xB7, 0xAD, 0xA9, 0xA6, 0xA7, +0xB8, 0x5D, 0x38, 0x2F, 0x2E, 0x2B, 0x2C, 0x35, 0x42, 0x5D, 0x7D, 0xE3, 0xDF, 0x6F, 0x73, 0x5A, +0x4D, 0x55, 0x4F, 0x4F, 0x58, 0x5C, 0x6E, 0xFA, 0xE2, 0xD4, 0xD4, 0xD6, 0xD9, 0xD6, 0xCC, 0xC6, +0xBF, 0xBB, 0xB8, 0xB6, 0xBC, 0xC9, 0xDC, 0x60, 0x59, 0x53, 0x4A, 0x49, 0x46, 0x45, 0x46, 0x43, +0x45, 0x45, 0x49, 0x56, 0x5A, 0x5D, 0x6E, 0x72, 0x7C, 0x74, 0x6D, 0x7A, 0x7A, 0xFC, 0xED, 0xE8, +0xEB, 0xFF, 0xFD, 0xEC, 0xDE, 0xD2, 0xCC, 0xC7, 0xC5, 0xCA, 0xD2, 0xD9, 0xDB, 0xD4, 0xCF, 0xD1, +0xD9, 0xE7, 0xFC, 0x6E, 0x60, 0x57, 0x50, 0x4C, 0x49, 0x47, 0x46, 0x45, 0x47, 0x4A, 0x4D, 0x4F, +0x4F, 0x53, 0x5A, 0x5F, 0x62, 0x60, 0x62, 0x6B, 0x77, 0xEC, 0xD8, 0xCC, 0xC7, 0xC7, 0xCB, 0xCF, +0xD3, 0xD3, 0xCE, 0xCB, 0xCA, 0xCC, 0xCF, 0xD4, 0xD9, 0xDF, 0xEB, 0xFE, 0x6A, 0x58, 0x4D, 0x46, +0x43, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x52, 0x54, 0x55, 0x54, 0x57, 0x5C, 0x61, 0x72, 0xE5, +0xD4, 0xCC, 0xCB, 0xCD, 0xD0, 0xD4, 0xD3, 0xD1, 0xD0, 0xCF, 0xD1, 0xD2, 0xD4, 0xD6, 0xD9, 0xDB, +0xDB, 0xDD, 0xEC, 0x6B, 0x59, 0x53, 0x54, 0x57, 0x59, 0x58, 0x57, 0x5A, 0x5C, 0x5A, 0x55, 0x52, +0x52, 0x51, 0x51, 0x57, 0x61, 0xFC, 0xE3, 0xDF, 0xE0, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDD, 0xDE, +0xDD, 0xDF, 0xE0, 0xDF, 0xDC, 0xD9, 0xDC, 0xE7, 0x7E, 0x6B, 0x6D, 0x7C, 0xEE, 0xE6, 0xE7, 0xEA, +0xEC, 0xF5, 0x7A, 0x6A, 0x61, 0x5A, 0x51, 0x4F, 0x50, 0x55, 0x5D, 0x62, 0x63, 0x60, 0x5F, 0x61, +0x65, 0x68, 0x6D, 0x75, 0xFA, 0xF1, 0xF1, 0xEE, 0xE6, 0xDD, 0xDB, 0xDE, 0xEB, 0x79, 0x6B, 0x6F, +0xF7, 0xE2, 0xDC, 0xDB, 0xDA, 0xDA, 0xDC, 0xDD, 0xDE, 0xE0, 0xF1, 0x6B, 0x5F, 0x5F, 0x66, 0x6B, +0x6A, 0x65, 0x5E, 0x5B, 0x5A, 0x59, 0x5A, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x68, 0xFC, 0xE8, 0xE5, +0xEB, 0xFB, 0x71, 0x6D, 0x78, 0xEE, 0xE2, 0xDE, 0xDD, 0xDC, 0xDE, 0xDF, 0xDC, 0xD9, 0xD9, 0xE0, +0xED, 0xF0, 0xEC, 0xE4, 0xE2, 0xE6, 0xEE, 0x7C, 0x6D, 0x65, 0x5E, 0x5E, 0x62, 0x64, 0x61, 0x5C, +0x5B, 0x5F, 0x70, 0xF7, 0xF8, 0x78, 0x6B, 0x65, 0x61, 0x69, 0xFA, 0xE9, 0xE5, 0xE2, 0xE5, 0xEA, +0xED, 0xEB, 0xE5, 0xE5, 0xED, 0xF9, 0xFC, 0xEF, 0xE3, 0xDE, 0xDE, 0xE1, 0xE9, 0xF4, 0x74, 0x6A, +0x6B, 0x6F, 0x6F, 0x67, 0x5E, 0x5C, 0x5F, 0x6A, 0x6F, 0x6C, 0x66, 0x5F, 0x5D, 0x5E, 0x64, 0x6F, +0xFE, 0xEF, 0xEC, 0xF2, 0xFD, 0x7E, 0xFB, 0xF6, 0xFF, 0x6F, 0x6A, 0x6A, 0x74, 0xF4, 0xE9, 0xE4, +0xE7, 0xEE, 0x7D, 0x6A, 0x69, 0x6F, 0xFE, 0xF7, 0x7B, 0x6B, 0x68, 0x6E, 0x79, 0x78, 0x6F, 0x69, +0x62, 0x5F, 0x60, 0x66, 0x72, 0xF6, 0xEB, 0xEC, 0xF3, 0xFC, 0xFA, 0xF2, 0xF2, 0xFE, 0x70, 0x69, +0x69, 0x71, 0xF7, 0xE8, 0xE3, 0xE4, 0xED, 0x76, 0x69, 0x6A, 0x6F, 0x7E, 0xFB, 0x7D, 0x75, 0x73, +0x7C, 0xFB, 0xFC, 0x7D, 0x73, 0x6D, 0x6A, 0x69, 0x6F, 0xFD, 0xEC, 0xE8, 0xED, 0xF6, 0xF7, 0xF1, +0xED, 0xEF, 0xF6, 0x7E, 0x76, 0x78, 0xFB, 0xEC, 0xE2, 0xDE, 0xE0, 0xEB, 0xFE, 0x73, 0x73, 0x7E, +0xFA, 0xFC, 0xFF, 0x7B, 0x7D, 0xFC, 0xFE, 0x7B, 0x74, 0x6F, 0x6D, 0x6C, 0x6E, 0x77, 0xFA, 0xEE, +0xED, 0xF6, 0x7A, 0x73, 0x77, 0x7B, 0x7C, 0x78, 0x6E, 0x6B, 0x6F, 0x7C, 0xEF, 0xE7, 0xE2, 0xE6, +0xF2, 0x7A, 0x71, 0x75, 0x7D, 0xFE, 0xFD, 0xFD, 0xFB, 0xF5, 0xF7, 0xFE, 0x77, 0x6E, 0x6A, 0x67, +0x67, 0x6C, 0x76, 0xF7, 0xEE, 0xEF, 0xFA, 0x7B, 0x78, 0x7B, 0xFF, 0x7F, 0x78, 0x6F, 0x6C, 0x6C, +0x72, 0xFE, 0xEF, 0xEC, 0xEF, 0xFD, 0x76, 0x70, 0x71, 0x75, 0x7A, 0x7E, 0x7E, 0xFF, 0xFC, 0xFD, +0x7C, 0x73, 0x6D, 0x69, 0x65, 0x63, 0x65, 0x6B, 0x79, 0xFB, 0xFD, 0x78, 0x70, 0x70, 0x74, 0x79, +0x7C, 0x7B, 0x79, 0x77, 0x78, 0x7F, 0xF4, 0xED, 0xED, 0xF2, 0xFB, 0x7A, 0x74, 0x74, 0x76, 0x7A, +0x7F, 0xFB, 0xF5, 0xF4, 0xF6, 0xFA, 0x7D, 0x75, 0x6E, 0x6B, 0x6B, 0x6F, 0x7D, 0xF3, 0xEF, 0xF4, +0x7E, 0x78, 0x7A, 0xFF, 0xFA, 0xF7, 0xF5, 0xF4, 0xF4, 0xF1, 0xED, 0xE9, 0xE6, 0xE8, 0xEE, 0xF8, +0x7F, 0x7C, 0x7A, 0x7A, 0x7B, 0x7D, 0xFD, 0xF8, 0xF8, 0xF9, 0xFC, 0x7D, 0x74, 0x6C, 0x69, 0x69, +0x6C, 0x76, 0xFA, 0xF6, 0xFD, 0x78, 0x71, 0x6F, 0x6F, 0x6F, 0x71, 0x74, 0x77, 0x7C, 0xFD, 0xF5, +0xEC, 0xE9, 0xEA, 0xEF, 0xFB, 0x7A, 0x74, 0x73, 0x73, 0x73, 0x73, 0x78, 0x7E, 0xFE, 0xFD, 0xFE, +0x7B, 0x74, 0x6D, 0x68, 0x66, 0x69, 0x6F, 0x7B, 0x7F, 0x7C, 0x77, 0x73, 0x72, 0x6F, 0x6D, 0x6D, +0x6D, 0x6D, 0x6E, 0x72, 0x7A, 0xFA, 0xF1, 0xEE, 0xEF, 0xF6, 0xFD, 0x7D, 0x7B, 0x7A, 0x78, 0x78, +0x79, 0x79, 0x7A, 0x7C, 0x7D, 0x7E, 0x7D, 0x77, 0x70, 0x6E, 0x71, 0x79, 0x7E, 0x7E, 0x7E, 0x7D, +0x7E, 0x7D, 0x7C, 0x7A, 0x78, 0x76, 0x74, 0x73, 0x75, 0x7A, 0xFC, 0xF6, 0xF4, 0xF4, 0xF6, 0xF6, +0xF6, 0xF9, 0xF9, 0xF7, 0xF5, 0xF3, 0xF1, 0xF1, 0xF3, 0xF5, 0xF7, 0xFA, 0x7B, 0x6F, 0x6D, 0x6D, +0x6F, 0x6F, 0x6E, 0x6E, 0x70, 0x70, 0x71, 0x74, 0x78, 0x7C, 0x7D, 0x7E, 0x7D, 0xFF, 0xFB, 0xF7, +0xF4, 0xF4, 0xF6, 0xF8, 0xFB, 0xFD, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x7F, 0xFF, 0xFC, 0xF8, +0xF9, 0xFD, 0x7D, 0x7C, 0x7F, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x79, 0x76, +0x71, 0x6F, 0x6F, 0x71, 0x76, 0x78, 0x78, 0x78, 0x7B, 0x7D, 0x7A, 0x77, 0x76, 0x76, 0x78, 0x79, +0x78, 0x79, 0x7C, 0xFD, 0xF4, 0xF1, 0xF2, 0xF5, 0xF9, 0xFB, 0x7F, 0x79, 0x76, 0x76, 0x78, 0x77, +0x77, 0x7B, 0xFF, 0xFA, 0xF6, 0xF6, 0xF7, 0xF6, 0xF6, 0xF7, 0xF9, 0xFA, 0xF9, 0xF6, 0xF6, 0xF9, +0xFB, 0xFE, 0x7F, 0x7E, 0x7C, 0x79, 0x7A, 0xFE, 0xF5, 0xEF, 0xEE, 0xEF, 0xF1, 0xF3, 0xF4, 0xFB, +0x79, 0x73, 0x72, 0x6E, 0x6B, 0x68, 0x68, 0x6C, 0x73, 0x7A, 0x7C, 0x7B, 0x7B, 0x7D, 0x7D, 0xFD, +0xF6, 0xF0, 0xEE, 0xEF, 0xF6, 0xFB, 0xFF, 0x7D, 0x7F, 0x7D, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, 0x7B, +0x7A, 0xFF, 0xFD, 0xFF, 0x7E, 0x7A, 0x75, 0x74, 0x71, 0x6F, 0x6F, 0x70, 0x77, 0x7A, 0x78, 0x75, +0x72, 0x75, 0x73, 0x6F, 0x6F, 0x70, 0x75, 0x77, 0x76, 0x78, 0x75, 0x78, 0x7B, 0x7B, 0x7F, 0x7B, +0x7E, 0x7F, 0x7E, 0x7E, 0x77, 0x79, 0x73, 0x71, 0x71, 0x6B, 0x6F, 0x60, 0x5B, 0x6F, 0x72, 0x69, +0x71, 0x72, 0x7E, 0xFC, 0xF7, 0xEE, 0xF4, 0xFB, 0x7E, 0x7E, 0xFC, 0xF9, 0xFD, 0x7F, 0xFC, 0x72, +0x78, 0x64, 0x53, 0x71, 0xDF, 0xF0, 0xEB, 0xE9, 0xF0, 0x7C, 0x7B, 0xEA, 0xF6, 0x7E, 0x79, 0x6C, +0x79, 0x5F, 0x5B, 0xEC, 0xE2, 0xEF, 0xED, 0xF1, 0xF7, 0xFE, 0x7C, 0xFE, 0x75, 0x6E, 0x75, 0x79, +0x7A, 0x72, 0x6E, 0x75, 0x7A, 0x7B, 0x77, 0x77, 0xFE, 0xF8, 0xF6, 0xF5, 0xEB, 0xE9, 0xEC, 0xE8, +0xEE, 0xEC, 0xED, 0x77, 0xFD, 0x61, 0x51, 0x66, 0xE7, 0xDC, 0xD8, 0xD3, 0xD3, 0x6C, 0x52, 0x63, +0x6F, 0x73, 0x7F, 0xFB, 0xF4, 0x79, 0x7B, 0xF1, 0xED, 0xEC, 0xFA, 0x76, 0x7A, 0x74, 0x6B, 0x6B, +0x75, 0x7C, 0x7C, 0x79, 0xFE, 0xF6, 0xFE, 0x7A, 0x71, 0x75, 0xFF, 0x70, 0x6D, 0x6E, 0x69, 0x66, +0x5E, 0x62, 0xFA, 0xEA, 0xE5, 0xE0, 0xE1, 0xE5, 0xEE, 0xF1, 0xE5, 0xE4, 0xEA, 0xE8, 0xE7, 0xE7, +0xE3, 0xE7, 0xE8, 0xE8, 0xEF, 0xF7, 0x78, 0x6E, 0x6D, 0x60, 0x5A, 0x57, 0x54, 0x53, 0x51, 0x50, +0x52, 0x54, 0x57, 0x59, 0x5D, 0x67, 0x70, 0x7B, 0xF5, 0xE5, 0xDA, 0xD5, 0xD2, 0xCD, 0xC4, 0xBE, +0xBB, 0xB7, 0xB5, 0xBB, 0xCB, 0xDE, 0xE9, 0x56, 0x3F, 0x3A, 0x39, 0x3B, 0x3B, 0x3A, 0x3F, 0x4E, +0x5D, 0x69, 0xF2, 0xDD, 0xD9, 0xE2, 0xF3, 0xF4, 0x72, 0x5C, 0x53, 0x4E, 0x4D, 0x4E, 0x4E, 0x4F, +0x58, 0x7E, 0xDA, 0xCB, 0xBF, 0xBA, 0xB7, 0xB4, 0xB0, 0xAE, 0xB2, 0xBE, 0xD7, 0x70, 0x4E, 0x3B, +0x32, 0x30, 0x33, 0x35, 0x35, 0x3A, 0x49, 0x5F, 0x7E, 0xEF, 0xE1, 0xD2, 0xD1, 0xE6, 0xEF, 0xF7, +0x5F, 0x4F, 0x48, 0x48, 0x4B, 0x48, 0x4B, 0x55, 0x72, 0xE1, 0xD2, 0xC2, 0xBA, 0xB6, 0xB3, 0xB0, +0xAD, 0xAE, 0xBA, 0xD0, 0x64, 0x4C, 0x3C, 0x30, 0x2E, 0x2F, 0x33, 0x35, 0x3A, 0x47, 0x6C, 0xE6, +0xEB, 0xD0, 0xC6, 0xCC, 0xD6, 0xE3, 0xEF, 0x69, 0x4E, 0x4B, 0x4B, 0x47, 0x46, 0x48, 0x4F, 0x61, +0xFE, 0xD1, 0xBE, 0xB8, 0xB5, 0xB2, 0xAF, 0xAD, 0xAE, 0xBA, 0xCD, 0x5F, 0x47, 0x3B, 0x2F, 0x2D, +0x2E, 0x30, 0x35, 0x3B, 0x47, 0x6C, 0xF4, 0xE2, 0xCB, 0xC7, 0xCD, 0xD7, 0xDD, 0xE3, 0x6E, 0x4E, +0x4A, 0x4B, 0x48, 0x47, 0x4A, 0x5B, 0xE4, 0xD3, 0xC0, 0xB7, 0xB3, 0xB0, 0xAF, 0xAC, 0xAC, 0xB3, +0xC4, 0x7D, 0x4C, 0x3E, 0x30, 0x2C, 0x2E, 0x31, 0x35, 0x3A, 0x45, 0x62, 0xFA, 0xEB, 0xCE, 0xCA, +0xD2, 0xDA, 0xE7, 0xE9, 0x6D, 0x4C, 0x49, 0x49, 0x47, 0x48, 0x4C, 0x68, 0xD7, 0xCA, 0xBC, 0xB5, +0xB2, 0xB0, 0xAE, 0xAC, 0xAE, 0xB9, 0xCE, 0x5D, 0x45, 0x39, 0x2F, 0x2D, 0x2E, 0x31, 0x36, 0x3B, +0x47, 0x5C, 0x6E, 0xE4, 0xD3, 0xD3, 0xD4, 0xDA, 0xDE, 0xEB, 0x5B, 0x4D, 0x4A, 0x47, 0x48, 0x49, +0x54, 0xEB, 0xCE, 0xBE, 0xB8, 0xB7, 0xB3, 0xB3, 0xB5, 0xB3, 0xBB, 0xC9, 0xC8, 0xED, 0x47, 0x42, +0x3A, 0x36, 0x37, 0x34, 0x39, 0x3E, 0x3F, 0x47, 0x4E, 0x65, 0xDE, 0xEC, 0xDC, 0xCE, 0xD9, 0xEB, +0x5F, 0x54, 0x51, 0x47, 0x46, 0x4C, 0x58, 0xFC, 0xD8, 0xC4, 0xBB, 0xBA, 0xB8, 0xB5, 0xB2, 0xAF, +0xB0, 0xB6, 0xBD, 0xCC, 0x66, 0x47, 0x3B, 0x34, 0x32, 0x32, 0x34, 0x38, 0x3B, 0x3F, 0x4B, 0x58, +0x69, 0xE9, 0xD9, 0xD4, 0xDB, 0x77, 0x5C, 0x59, 0x4F, 0x4A, 0x4B, 0x51, 0x69, 0xE0, 0xCE, 0xC2, +0xBD, 0xBC, 0xBA, 0xB8, 0xB7, 0xB4, 0xB2, 0xB7, 0xC3, 0xCE, 0xD4, 0x67, 0x44, 0x3D, 0x3C, 0x3B, +0x38, 0x38, 0x3B, 0x3F, 0x42, 0x46, 0x4E, 0x5F, 0x6A, 0x6B, 0xFD, 0xF7, 0x70, 0x5C, 0x54, 0x58, +0x58, 0x53, 0x5B, 0x73, 0xE5, 0xD2, 0xCA, 0xC6, 0xC2, 0xBF, 0xBE, 0xBE, 0xBD, 0xBB, 0xBC, 0xC3, +0xCA, 0xD0, 0xE2, 0x5F, 0x4E, 0x4A, 0x44, 0x3E, 0x3D, 0x3D, 0x3F, 0x42, 0x44, 0x4B, 0x55, 0x57, +0x5F, 0x69, 0x68, 0x63, 0x58, 0x56, 0x5B, 0x56, 0x57, 0x66, 0x79, 0xE8, 0xD9, 0xCF, 0xCB, 0xCB, +0xC8, 0xC4, 0xC5, 0xC6, 0xC9, 0xC9, 0xC6, 0xCD, 0xD4, 0xD8, 0xE2, 0xF1, 0x66, 0x5C, 0x57, 0x4C, +0x49, 0x49, 0x48, 0x49, 0x49, 0x4B, 0x51, 0x51, 0x4F, 0x53, 0x56, 0x58, 0x58, 0x54, 0x58, 0x5F, +0x5E, 0x5B, 0x63, 0xF2, 0xE5, 0xE5, 0xD7, 0xCF, 0xD2, 0xD6, 0xD1, 0xCF, 0xD6, 0xD6, 0xD2, 0xCF, +0xCE, 0xD0, 0xD8, 0xDB, 0xDB, 0xE5, 0x6D, 0x67, 0x65, 0x5C, 0x58, 0x54, 0x59, 0x5D, 0x57, 0x57, +0x5B, 0x5B, 0x59, 0x56, 0x57, 0x5A, 0x56, 0x52, 0x5A, 0x5C, 0x5D, 0x7D, 0xF1, 0xF3, 0xE7, 0xE3, +0xDF, 0xDB, 0xDA, 0xE7, 0xEC, 0xDE, 0xE5, 0xE9, 0xE6, 0xE4, 0xD6, 0xDF, 0xF8, 0xDE, 0xE9, 0x7C, +0xEE, 0xFB, 0x7A, 0x6B, 0x65, 0xFF, 0x79, 0x69, 0x6B, 0x63, 0x65, 0x62, 0x56, 0x5A, 0x60, 0x55, +0x58, 0x62, 0x5E, 0x64, 0x79, 0x7C, 0x78, 0xED, 0xE1, 0xEC, 0xF0, 0xE4, 0xF0, 0x6E, 0x7C, 0xED, +0xDD, 0xDB, 0xFE, 0x73, 0xED, 0xF0, 0xFF, 0xF9, 0xDE, 0xDC, 0x76, 0x6E, 0xFB, 0x7B, 0xFB, 0x6F, +0x6F, 0xEF, 0x7B, 0x6E, 0xF8, 0xE9, 0x7E, 0x5B, 0x5F, 0xF3, 0xFD, 0x67, 0x74, 0xEA, 0xEF, 0x77, +0x6D, 0x7C, 0xE8, 0xE2, 0xEE, 0xFB, 0xE6, 0xED, 0x66, 0x6C, 0x7B, 0x7C, 0xF4, 0xEF, 0xE2, 0xE6, +0x72, 0x70, 0xF0, 0xEE, 0x6E, 0x6B, 0xFB, 0xF5, 0xF6, 0x71, 0x6A, 0x6C, 0x65, 0x67, 0x5F, 0x5D, +0x6B, 0x62, 0x65, 0xFD, 0xED, 0xE9, 0xF2, 0xED, 0xE3, 0xE7, 0xE4, 0xE8, 0xED, 0xEF, 0x66, 0x5E, +0x79, 0x7E, 0x78, 0xF5, 0xFA, 0x79, 0x7A, 0xF5, 0xE7, 0xE2, 0xE4, 0xF2, 0xFF, 0x73, 0x66, 0x6B, +0x70, 0xFD, 0xEF, 0x6F, 0x67, 0x5F, 0x5C, 0x6B, 0x6E, 0x78, 0x77, 0x6D, 0xF1, 0xF4, 0xF8, 0xE5, +0xE9, 0xEB, 0xEC, 0xEF, 0xEF, 0xF0, 0xE7, 0xED, 0x6B, 0x6F, 0xF0, 0xFF, 0x6A, 0x6F, 0x7E, 0x6F, +0x69, 0xED, 0xDF, 0xFF, 0x7C, 0xEB, 0xF3, 0xF8, 0x7E, 0x7A, 0xFB, 0x6E, 0x5E, 0x60, 0x70, 0x7A, +0xFC, 0xF4, 0xFF, 0xEF, 0xF5, 0x72, 0xF1, 0xEC, 0xEA, 0xE1, 0xE9, 0xED, 0xF2, 0xFC, 0xE7, 0xF0, +0x68, 0x76, 0xEF, 0xF4, 0xF9, 0x77, 0x79, 0xFB, 0xFC, 0xF6, 0xEE, 0xE9, 0xF2, 0x6D, 0x70, 0x6F, +0x6F, 0xFE, 0x6A, 0x69, 0x7F, 0x6F, 0x6F, 0x79, 0x78, 0x77, 0x6E, 0xFE, 0xEE, 0xF0, 0xEF, 0x7E, +0xF4, 0xE9, 0xF8, 0xFD, 0x7C, 0x77, 0x7D, 0x78, 0x7D, 0xFE, 0x79, 0x72, 0x6E, 0x72, 0x7B, 0x73, +0x6B, 0x74, 0x76, 0x6C, 0x72, 0x70, 0x75, 0x6D, 0x5A, 0x5C, 0x6A, 0x77, 0xFE, 0x71, 0x7A, 0xF2, +0xE9, 0xE7, 0xEA, 0xDE, 0xE6, 0xF5, 0xEB, 0xF5, 0xEE, 0xEA, 0xF3, 0xEE, 0xF4, 0xEE, 0xF5, 0x73, +0xF4, 0xF6, 0x73, 0x7C, 0xEC, 0xE9, 0x72, 0x67, 0x6C, 0x70, 0x6E, 0x69, 0x6F, 0x68, 0x5D, 0x64, +0x71, 0x75, 0x6B, 0x6D, 0xF9, 0x79, 0x6F, 0xF4, 0xEA, 0xF5, 0x79, 0x7B, 0x7D, 0xFA, 0xF3, 0xF7, +0xF4, 0xF4, 0xF9, 0x7F, 0x77, 0x7F, 0xF5, 0xFD, 0x71, 0x71, 0x7B, 0x78, 0x7A, 0x73, 0x68, 0x71, +0x7A, 0x6B, 0x6C, 0x6E, 0x69, 0x6E, 0x71, 0x6C, 0x69, 0x6C, 0x7A, 0x7D, 0xF6, 0xEB, 0xF4, 0xF2, +0xF4, 0x78, 0xF8, 0xF1, 0xF6, 0xFE, 0x71, 0x75, 0x7C, 0x7B, 0x7D, 0x7E, 0xFB, 0x7E, 0x77, 0x76, +0xFF, 0xF7, 0x79, 0x70, 0x6E, 0x6C, 0x71, 0x6F, 0x6C, 0x6A, 0x70, 0x6E, 0x5F, 0x65, 0x6C, 0x66, +0x6D, 0x7A, 0xF1, 0x78, 0x6B, 0xED, 0xFB, 0x6C, 0x7C, 0x74, 0xF1, 0xEC, 0x76, 0xF9, 0xF8, 0x75, +0x71, 0x7A, 0xEC, 0xFA, 0x6C, 0x76, 0x7C, 0x7F, 0x6E, 0x6A, 0x76, 0x6C, 0x76, 0xF2, 0x7C, 0x76, +0x66, 0x62, 0x7D, 0xF9, 0x78, 0x69, 0x6A, 0xF8, 0x78, 0x6D, 0xFC, 0xF8, 0xF3, 0xF7, 0x7D, 0xEF, +0xF1, 0x7C, 0xF1, 0xE9, 0xEB, 0xEE, 0xF3, 0xFD, 0x73, 0x7D, 0xFA, 0x74, 0x78, 0x7A, 0x6E, 0x70, +0x76, 0x73, 0x6F, 0x6D, 0x6C, 0x68, 0x6D, 0x7D, 0x6E, 0x64, 0x6D, 0xFC, 0xFA, 0x71, 0x6F, 0xFF, +0x70, 0x70, 0xF0, 0xEE, 0xEF, 0xEB, 0xEC, 0xEC, 0xED, 0xF0, 0xEE, 0xE9, 0xEB, 0xF8, 0xFB, 0xED, +0xE9, 0xF7, 0xFF, 0xED, 0xEE, 0xEF, 0xF3, 0x6E, 0x70, 0xF3, 0xFF, 0x6F, 0x6F, 0x6F, 0x79, 0x7C, +0x79, 0x7E, 0x77, 0x6E, 0x6E, 0x7B, 0x7C, 0x6B, 0x72, 0xF6, 0xFF, 0x7D, 0x7D, 0x72, 0x78, 0xFB, +0xFD, 0xFB, 0xFA, 0x7D, 0x7A, 0x6D, 0x68, 0x74, 0x75, 0xF1, 0xE7, 0x7B, 0x76, 0x6B, 0x66, 0xFD, +0x73, 0x68, 0x6B, 0x73, 0x7C, 0x62, 0x64, 0x70, 0x64, 0x6D, 0x79, 0x70, 0x70, 0x74, 0xF8, 0x7C, +0x7C, 0xF8, 0x6B, 0x70, 0xF9, 0x7D, 0xF1, 0xF0, 0xFF, 0x7F, 0xF8, 0xED, 0xF2, 0xFC, 0xFF, 0x76, +0x7B, 0x7C, 0xFE, 0xFE, 0x6C, 0x7C, 0xED, 0x79, 0x77, 0x71, 0x69, 0x76, 0x7A, 0x76, 0x7A, 0x6F, +0x6E, 0x6E, 0x73, 0xFF, 0x78, 0x76, 0x7F, 0x7A, 0x6F, 0x78, 0xFE, 0x77, 0xFB, 0xEE, 0xEE, 0xF1, +0x7A, 0xFB, 0xEE, 0x75, 0x70, 0xFE, 0x7D, 0x72, 0x6D, 0x6F, 0x7B, 0xFB, 0xF9, 0x7C, 0x7E, 0x7A, +0x70, 0x76, 0x7B, 0xF7, 0xF5, 0x70, 0x74, 0xFF, 0x78, 0xFA, 0xFC, 0x79, 0x78, 0x6D, 0x7A, 0xFA, +0x77, 0xFC, 0xF4, 0xF1, 0xF1, 0xF7, 0xEB, 0xED, 0xFB, 0xF7, 0xEF, 0xF2, 0x78, 0x79, 0xF0, 0xF3, +0xFC, 0xFC, 0x7E, 0x77, 0xFF, 0xFC, 0x78, 0xF6, 0xF9, 0x6F, 0x7A, 0x78, 0x6F, 0xFF, 0xF9, 0x7E, +0x76, 0x72, 0x76, 0x78, 0x79, 0xFD, 0xFA, 0x7A, 0x7E, 0xF1, 0xFB, 0x7A, 0xF2, 0xEF, 0xFF, 0x74, +0x75, 0x7E, 0xFF, 0xF6, 0xE9, 0xF4, 0x71, 0x74, 0x74, 0x7C, 0xF8, 0x79, 0x75, 0x74, 0x73, 0xF9, +0xFE, 0xFF, 0xFA, 0x6A, 0x6C, 0xFE, 0x70, 0x72, 0x7C, 0x7D, 0x70, 0x67, 0x6F, 0x76, 0x7B, 0xF0, +0x7E, 0x6E, 0x6E, 0x76, 0xF1, 0xF2, 0x7A, 0x72, 0x7B, 0xFD, 0x79, 0x77, 0x6E, 0x6A, 0x6D, 0x6E, +0x74, 0x72, 0x77, 0xF5, 0x7C, 0x6D, 0x6C, 0x6D, 0x70, 0x76, 0xFD, 0xFC, 0xFF, 0xFE, 0xFE, 0xFA, +0x7D, 0x77, 0x74, 0x6F, 0xFB, 0xFA, 0x71, 0xFC, 0xF8, 0xFE, 0xEB, 0xE5, 0xEE, 0x7F, 0xF6, 0xED, +0xFA, 0x78, 0xF6, 0xF1, 0xF8, 0xF6, 0x79, 0x70, 0x7C, 0x75, 0x78, 0xF6, 0xFA, 0xFC, 0xFB, 0x7B, +0x7D, 0xF9, 0xF7, 0xF7, 0x7E, 0x6B, 0x68, 0xFA, 0xE6, 0xEE, 0x7B, 0x7B, 0x79, 0x7E, 0xFB, 0xF2, +0xEA, 0xEE, 0xF1, 0xF6, 0x79, 0xFB, 0xF0, 0xFB, 0xFF, 0xF0, 0xEE, 0xF4, 0xEF, 0xFB, 0x6F, 0x6C, +0x72, 0xFF, 0x71, 0x6C, 0x6A, 0x6D, 0xF4, 0xFB, 0x7C, 0xF3, 0xFA, 0xFC, 0x6F, 0x73, 0xFB, 0x72, +0x7D, 0x78, 0x76, 0xEF, 0xF3, 0x7C, 0x71, 0xFA, 0xF2, 0xFB, 0xEF, 0xF0, 0xEA, 0xFD, 0x6B, 0xED, +0xF2, 0x77, 0x6E, 0x6D, 0xFD, 0x64, 0xF3, 0xDF, 0x5C, 0x61, 0xED, 0xF2, 0x7E, 0x66, 0x73, 0x6E, +0x66, 0xFF, 0x6F, 0x72, 0x70, 0x66, 0xF3, 0xF7, 0x6F, 0x72, 0x75, 0xED, 0xEF, 0xF4, 0xED, 0xEF, +0xEF, 0x6E, 0x6F, 0xF7, 0x72, 0x7E, 0x78, 0x6F, 0xF9, 0x77, 0xFC, 0xF4, 0x6C, 0x66, 0x6A, 0x76, +0x65, 0x5C, 0x6D, 0xFF, 0xF8, 0xEA, 0xE2, 0xEF, 0x65, 0x70, 0xEB, 0xE8, 0xE2, 0xDF, 0xDA, 0xD9, +0xE3, 0xF0, 0xFA, 0xE6, 0xDD, 0xDF, 0xDF, 0xE0, 0xE4, 0xFC, 0x63, 0x60, 0x64, 0x63, 0x66, 0x78, +0x65, 0x57, 0x60, 0x67, 0x64, 0x67, 0x5F, 0x6E, 0xF3, 0x7F, 0x75, 0xFE, 0xEA, 0xF4, 0xF8, 0xE0, +0xE0, 0xE4, 0xE3, 0xE7, 0xEA, 0xFB, 0x6F, 0x6E, 0x75, 0x72, 0x68, 0x6E, 0x77, 0x74, 0x6D, 0x73, +0xF9, 0x74, 0xF2, 0xE2, 0xEF, 0xDE, 0xDD, 0x79, 0xFD, 0xF4, 0x6F, 0x6A, 0x6E, 0xFE, 0x7A, 0x68, +0x60, 0x63, 0x6B, 0x66, 0x67, 0x76, 0xFE, 0x78, 0x65, 0x63, 0x7A, 0xFF, 0x72, 0x72, 0x74, 0x7D, +0x7C, 0x6B, 0x72, 0xEF, 0xF6, 0x73, 0x74, 0x7C, 0x74, 0x68, 0x68, 0x73, 0xFA, 0xF6, 0x6F, 0x67, +0x6F, 0x6D, 0x6A, 0x69, 0x68, 0x74, 0x6D, 0x64, 0x6F, 0x75, 0x77, 0xFA, 0x7F, 0xF5, 0xEF, 0x78, +0x77, 0x7D, 0x7A, 0xFE, 0x77, 0x73, 0xF8, 0xF4, 0xFE, 0x6F, 0x71, 0xF7, 0x74, 0x79, 0xEF, 0x7B, +0xF9, 0xFA, 0x68, 0x71, 0x7F, 0x76, 0x73, 0x71, 0x7D, 0x7D, 0x65, 0x5D, 0x69, 0x6E, 0x5F, 0x67, +0x6F, 0x6D, 0xFF, 0x7F, 0x6E, 0x6F, 0x73, 0x77, 0xF2, 0xDE, 0xD4, 0xD0, 0xD0, 0xCF, 0xCE, 0xD0, +0xD2, 0xD6, 0xDA, 0xDB, 0xE7, 0x6D, 0x5B, 0x52, 0x4C, 0x47, 0x44, 0x43, 0x44, 0x47, 0x49, 0x4B, +0x4E, 0x52, 0x56, 0x5A, 0x5D, 0x64, 0x75, 0xE6, 0xCF, 0xC5, 0xBF, 0xBD, 0xBB, 0xB7, 0xB5, 0xB1, +0xAF, 0xB5, 0xC1, 0xDF, 0x51, 0x44, 0x3A, 0x33, 0x33, 0x37, 0x3D, 0x44, 0x48, 0x4D, 0x51, 0x54, +0x53, 0x4D, 0x49, 0x44, 0x43, 0x45, 0x46, 0x4C, 0x54, 0x65, 0xE4, 0xCF, 0xC4, 0xBB, 0xB4, 0xAF, +0xAD, 0xAC, 0xAA, 0xAB, 0xB5, 0xD1, 0x49, 0x3B, 0x35, 0x2F, 0x2D, 0x32, 0x3D, 0x4E, 0x57, 0x51, +0x4F, 0x50, 0x4C, 0x42, 0x3D, 0x3F, 0x46, 0x4A, 0x4F, 0x5E, 0xEC, 0xD9, 0xDA, 0xD2, 0xC8, 0xBE, +0xB7, 0xB0, 0xAD, 0xAB, 0xA9, 0xA8, 0xAD, 0xC4, 0x48, 0x36, 0x31, 0x2E, 0x2D, 0x30, 0x3E, 0x67, +0xE2, 0x63, 0x47, 0x43, 0x42, 0x39, 0x36, 0x3B, 0x46, 0x6B, 0xE1, 0xDB, 0xCC, 0xC8, 0xCC, 0xD7, +0xDD, 0xC6, 0xBA, 0xB2, 0xAC, 0xAA, 0xA7, 0xA7, 0xB0, 0x69, 0x32, 0x2D, 0x2D, 0x2C, 0x2D, 0x39, +0xF1, 0xC2, 0xCA, 0x5E, 0x3D, 0x38, 0x34, 0x2E, 0x2F, 0x3E, 0x69, 0xCC, 0xC3, 0xBD, 0xBD, 0xC2, +0xCD, 0xEC, 0xF4, 0xCD, 0xC0, 0xB7, 0xAC, 0xA7, 0xA4, 0xA4, 0xB7, 0x3A, 0x2A, 0x29, 0x2A, 0x2B, +0x30, 0x56, 0xBA, 0xB6, 0xCD, 0x4A, 0x33, 0x2C, 0x2C, 0x2B, 0x34, 0x65, 0xC3, 0xBB, 0xBB, 0xBC, +0xC1, 0xDA, 0x7F, 0x6A, 0x75, 0xD1, 0xC2, 0xB8, 0xAC, 0xA6, 0xA5, 0xA4, 0xB0, 0x35, 0x23, 0x25, +0x29, 0x2F, 0x38, 0x73, 0xB3, 0xAF, 0xC8, 0x3E, 0x2E, 0x29, 0x26, 0x2C, 0x3D, 0xDF, 0xB8, 0xB5, +0xBB, 0xC5, 0xE7, 0x5A, 0x53, 0x68, 0xD9, 0xC8, 0xBA, 0xB3, 0xAD, 0xA8, 0xA7, 0xA6, 0xAF, 0x34, +0x1F, 0x24, 0x2E, 0x3B, 0x48, 0xDA, 0xB3, 0xB0, 0xD6, 0x33, 0x29, 0x29, 0x29, 0x2F, 0x5B, 0xC3, +0xB9, 0xB8, 0xC1, 0xDB, 0x53, 0x46, 0x4E, 0xEE, 0xCB, 0xC5, 0xBF, 0xBA, 0xB6, 0xAE, 0xAA, 0xA8, +0xAA, 0xDB, 0x26, 0x20, 0x2B, 0x3E, 0x5E, 0xEE, 0xC1, 0xB6, 0xC1, 0x3F, 0x2A, 0x29, 0x2A, 0x2F, +0x4F, 0xCA, 0xC0, 0xBE, 0xC5, 0xDC, 0x51, 0x44, 0x4B, 0x7D, 0xCB, 0xC5, 0xC5, 0xC2, 0xBF, 0xBD, +0xB1, 0xA9, 0xA8, 0xAA, 0xCB, 0x28, 0x20, 0x2C, 0x44, 0x7E, 0xDE, 0xC8, 0xBB, 0xC6, 0x3F, 0x2B, +0x29, 0x2E, 0x35, 0x4C, 0xCB, 0xBF, 0xC3, 0xCA, 0xE6, 0x4E, 0x43, 0x44, 0x6A, 0xC8, 0xC3, 0xC3, +0xC8, 0xC8, 0xBE, 0xB5, 0xAB, 0xA7, 0xA8, 0xBC, 0x2D, 0x1F, 0x29, 0x42, 0xD7, 0xD0, 0xCD, 0xBF, +0xC5, 0x4C, 0x2E, 0x2B, 0x2F, 0x36, 0x4A, 0xD7, 0xBE, 0xBD, 0xD5, 0x74, 0x50, 0x42, 0x45, 0x53, +0xD1, 0xBE, 0xBE, 0xC5, 0xD2, 0xCD, 0xBC, 0xAE, 0xA7, 0xA7, 0xB5, 0x36, 0x21, 0x28, 0x41, 0xD1, +0xC9, 0xD4, 0xCB, 0xCB, 0x51, 0x31, 0x2B, 0x2F, 0x39, 0x47, 0xE9, 0xC5, 0xC0, 0xCD, 0xED, 0x50, +0x3F, 0x3F, 0x52, 0xCD, 0xBB, 0xBC, 0xC6, 0xDE, 0xE7, 0xCB, 0xB5, 0xA8, 0xA4, 0xA9, 0xCC, 0x28, +0x20, 0x2E, 0x6F, 0xC2, 0xCF, 0xF7, 0xDA, 0xEB, 0x3F, 0x2E, 0x2D, 0x34, 0x3E, 0x5D, 0xCD, 0xBF, +0xC7, 0x73, 0x53, 0x43, 0x3C, 0x49, 0xDD, 0xBC, 0xB7, 0xC2, 0xE4, 0x62, 0xEC, 0xBD, 0xAA, 0xA3, +0xA4, 0xB3, 0x32, 0x1F, 0x26, 0x42, 0xC3, 0xC0, 0xF2, 0x68, 0x73, 0x4D, 0x37, 0x2D, 0x2F, 0x39, +0x47, 0xDD, 0xC2, 0xBE, 0xD2, 0x4A, 0x3E, 0x3B, 0x42, 0xEB, 0xBE, 0xB5, 0xB9, 0xD5, 0x54, 0x54, +0xCB, 0xAD, 0xA3, 0xA2, 0xAC, 0x4D, 0x23, 0x21, 0x34, 0xCF, 0xBA, 0xD0, 0x5E, 0x73, 0x5D, 0x43, +0x34, 0x30, 0x38, 0x3C, 0x46, 0xCE, 0xB9, 0xBE, 0x5F, 0x3E, 0x3B, 0x3E, 0x62, 0xC0, 0xB5, 0xB6, +0xC9, 0x54, 0x48, 0xE3, 0xB1, 0xA4, 0xA0, 0xA6, 0xC3, 0x2B, 0x1E, 0x29, 0x5D, 0xB9, 0xBD, 0x72, +0x50, 0x5B, 0x50, 0x3C, 0x30, 0x30, 0x36, 0x3F, 0x7C, 0xC0, 0xBA, 0xD0, 0x45, 0x3A, 0x38, 0x46, +0xCB, 0xB7, 0xB5, 0xC4, 0x5A, 0x48, 0x62, 0xBA, 0xA8, 0xA1, 0xA3, 0xB0, 0x3C, 0x20, 0x20, 0x39, +0xBD, 0xB1, 0xC7, 0x4F, 0x4A, 0x4E, 0x48, 0x35, 0x2E, 0x31, 0x39, 0x56, 0xC0, 0xB8, 0xC2, 0x4D, +0x39, 0x37, 0x3E, 0xE2, 0xBC, 0xB6, 0xBB, 0xDC, 0x4B, 0x4A, 0xD3, 0xAE, 0xA3, 0xA0, 0xA8, 0xD5, +0x29, 0x1F, 0x2B, 0xE3, 0xB3, 0xBA, 0x65, 0x47, 0x4C, 0x4F, 0x3D, 0x2F, 0x2D, 0x30, 0x41, 0xCB, +0xB7, 0xBA, 0x76, 0x3D, 0x38, 0x39, 0x51, 0xC5, 0xB6, 0xB6, 0xCC, 0x50, 0x46, 0x7E, 0xB4, 0xA6, +0xA1, 0xA4, 0xB8, 0x35, 0x20, 0x25, 0x48, 0xB8, 0xB5, 0xDB, 0x47, 0x47, 0x52, 0x4A, 0x34, 0x2D, +0x2E, 0x39, 0xEC, 0xBA, 0xB6, 0xCF, 0x3F, 0x38, 0x37, 0x41, 0xD0, 0xB8, 0xB4, 0xBF, 0x6A, 0x4A, +0x5B, 0xBC, 0xA8, 0xA1, 0xA2, 0xAF, 0x3E, 0x22, 0x24, 0x3E, 0xBA, 0xB3, 0xD4, 0x45, 0x41, 0x4F, +0x52, 0x37, 0x2D, 0x2D, 0x36, 0x65, 0xBB, 0xB6, 0xC9, 0x46, 0x38, 0x35, 0x3D, 0xDC, 0xB7, 0xB0, +0xBA, 0xF0, 0x48, 0x4E, 0xC1, 0xAA, 0xA2, 0xA1, 0xAB, 0x5E, 0x27, 0x21, 0x32, 0xC7, 0xB4, 0xC8, +0x48, 0x3E, 0x4B, 0x58, 0x3D, 0x2E, 0x2C, 0x2F, 0x48, 0xBF, 0xB5, 0xBF, 0x4C, 0x36, 0x34, 0x3A, +0x67, 0xBC, 0xB2, 0xB7, 0xD6, 0x4C, 0x4A, 0xCE, 0xAD, 0xA3, 0xA0, 0xA7, 0xD8, 0x29, 0x20, 0x2F, +0xD2, 0xB5, 0xC4, 0x4C, 0x40, 0x4B, 0x64, 0x44, 0x2F, 0x2C, 0x2D, 0x3F, 0xC4, 0xB4, 0xB9, 0x5F, +0x39, 0x36, 0x39, 0x5D, 0xBE, 0xB3, 0xB4, 0xC8, 0x59, 0x4B, 0xDC, 0xAF, 0xA3, 0x9F, 0xA5, 0xC5, +0x2C, 0x21, 0x2C, 0xFB, 0xB9, 0xC1, 0x53, 0x42, 0x4A, 0x5F, 0x49, 0x31, 0x2C, 0x2C, 0x3A, 0xCF, +0xB6, 0xBA, 0xF7, 0x3E, 0x39, 0x3A, 0x4C, 0xCA, 0xB7, 0xB4, 0xBF, 0x79, 0x4D, 0xE5, 0xB1, 0xA4, +0x9F, 0xA4, 0xC6, 0x2B, 0x20, 0x2C, 0xEC, 0xB7, 0xC1, 0x57, 0x43, 0x49, 0x5C, 0x47, 0x31, 0x2C, +0x2C, 0x39, 0xD3, 0xB7, 0xBA, 0xDC, 0x46, 0x3C, 0x39, 0x47, 0xCE, 0xB9, 0xB5, 0xBD, 0xDE, 0x5E, +0xD3, 0xB0, 0xA4, 0xA0, 0xA6, 0xCF, 0x2A, 0x21, 0x2D, 0xF6, 0xBB, 0xC8, 0x55, 0x44, 0x48, 0x51, +0x3F, 0x2F, 0x2C, 0x2D, 0x3B, 0xD8, 0xBC, 0xBF, 0xE7, 0x4E, 0x45, 0x3C, 0x44, 0xEB, 0xBE, 0xB5, +0xBA, 0xCA, 0xE3, 0xC9, 0xAF, 0xA5, 0xA0, 0xA7, 0xE6, 0x28, 0x22, 0x2E, 0xEA, 0xBD, 0xC8, 0x5D, +0x46, 0x4A, 0x4D, 0x3B, 0x2F, 0x2D, 0x2F, 0x3F, 0xD0, 0xBE, 0xC3, 0xE6, 0x56, 0x4B, 0x43, 0x4C, +0xFA, 0xC8, 0xBB, 0xBB, 0xC3, 0xC8, 0xBD, 0xAE, 0xA7, 0xA3, 0xAA, 0x6C, 0x2A, 0x25, 0x30, 0x5A, +0xCD, 0xD3, 0x5F, 0x4D, 0x50, 0x4C, 0x3B, 0x2F, 0x2D, 0x2F, 0x3D, 0xE6, 0xCC, 0xD3, 0xDA, 0xDB, +0x79, 0x55, 0x56, 0x68, 0xE0, 0xCA, 0xC2, 0xC0, 0xBC, 0xB1, 0xAB, 0xA6, 0xA5, 0xAE, 0x53, 0x2C, +0x29, 0x30, 0x41, 0x59, 0x62, 0x53, 0x57, 0x7F, 0x5D, 0x40, 0x35, 0x2E, 0x2F, 0x3D, 0x58, 0x78, +0xE5, 0xCD, 0xC8, 0xCF, 0xDA, 0xEC, 0x7B, 0xE4, 0xD1, 0xCA, 0xC4, 0xBA, 0xB0, 0xAC, 0xAA, 0xAB, +0xBA, 0x4F, 0x39, 0x39, 0x3D, 0x3F, 0x42, 0x3D, 0x3C, 0x45, 0x51, 0x52, 0x4C, 0x42, 0x3B, 0x3E, +0x4A, 0x4C, 0x4D, 0x57, 0x69, 0xEE, 0xDE, 0xE4, 0xFD, 0xED, 0xDC, 0xD3, 0xCD, 0xCA, 0xC3, 0xBD, +0xB9, 0xB6, 0xB8, 0xC3, 0xCE, 0xC8, 0xC1, 0xC5, 0xCE, 0xF9, 0x4A, 0x3F, 0x3F, 0x41, 0x3F, 0x3D, +0x39, 0x38, 0x3B, 0x3C, 0x3A, 0x3C, 0x43, 0x4C, 0x52, 0x58, 0x5B, 0x59, 0x65, 0xDC, 0xCB, 0xC3, +0xBD, 0xB8, 0xB6, 0xB2, 0xAF, 0xB2, 0xB6, 0xB2, 0xB0, 0xB6, 0xBF, 0xD7, 0x4F, 0x40, 0x3F, 0x3D, +0x3A, 0x35, 0x2F, 0x2D, 0x2F, 0x32, 0x33, 0x34, 0x39, 0x3E, 0x46, 0x51, 0x59, 0x5C, 0x6F, 0xD8, +0xC6, 0xBD, 0xB8, 0xB4, 0xB2, 0xAF, 0xAC, 0xAD, 0xAF, 0xAE, 0xAE, 0xB2, 0xBC, 0xCF, 0x55, 0x42, +0x3E, 0x3B, 0x36, 0x31, 0x2D, 0x2A, 0x2B, 0x2F, 0x32, 0x33, 0x36, 0x3B, 0x40, 0x4A, 0x57, 0x69, +0xEE, 0xD6, 0xC8, 0xBF, 0xB9, 0xB3, 0xB1, 0xAF, 0xAC, 0xAB, 0xAE, 0xAF, 0xAF, 0xB1, 0xB9, 0xC6, +0x75, 0x46, 0x3D, 0x3A, 0x36, 0x30, 0x2D, 0x2B, 0x2A, 0x2D, 0x31, 0x34, 0x36, 0x39, 0x3E, 0x46, +0x56, 0x77, 0xE3, 0xD4, 0xCA, 0xC3, 0xBD, 0xB6, 0xB1, 0xAF, 0xAC, 0xAB, 0xAC, 0xAF, 0xAF, 0xB0, +0xB5, 0xBE, 0xDA, 0x4E, 0x3E, 0x3A, 0x36, 0x31, 0x2D, 0x2C, 0x2B, 0x2C, 0x2F, 0x32, 0x34, 0x38, +0x3D, 0x43, 0x4D, 0x66, 0xE7, 0xD6, 0xCB, 0xC5, 0xC0, 0xBA, 0xB3, 0xAF, 0xAD, 0xAB, 0xAC, 0xAE, +0xAF, 0xAF, 0xB3, 0xBB, 0xCD, 0x5A, 0x40, 0x3A, 0x36, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2F, 0x31, +0x32, 0x38, 0x3D, 0x41, 0x4B, 0x5C, 0xF8, 0xD8, 0xCA, 0xC3, 0xBF, 0xBA, 0xB4, 0xB0, 0xAD, 0xAB, +0xAB, 0xAE, 0xAF, 0xB0, 0xB3, 0xBA, 0xC9, 0x68, 0x46, 0x3C, 0x37, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, +0x2F, 0x30, 0x31, 0x36, 0x3C, 0x3F, 0x49, 0x58, 0x70, 0xDD, 0xCA, 0xC2, 0xBE, 0xB9, 0xB3, 0xB0, +0xAD, 0xAA, 0xAB, 0xAE, 0xAF, 0xAF, 0xB4, 0xBC, 0xCB, 0x61, 0x46, 0x3D, 0x36, 0x30, 0x2E, 0x2C, +0x2B, 0x2D, 0x2F, 0x2F, 0x31, 0x37, 0x3B, 0x3F, 0x4B, 0x5C, 0xFF, 0xD8, 0xC8, 0xC1, 0xBC, 0xB6, +0xB2, 0xAF, 0xAC, 0xAA, 0xAB, 0xAD, 0xAE, 0xAF, 0xB5, 0xBD, 0xCF, 0x5C, 0x45, 0x3C, 0x35, 0x2F, +0x2D, 0x2C, 0x2C, 0x2D, 0x2F, 0x2F, 0x32, 0x37, 0x3B, 0x3F, 0x4B, 0x5F, 0xEE, 0xD4, 0xC8, 0xC1, +0xBC, 0xB5, 0xB0, 0xAE, 0xAB, 0xAA, 0xAB, 0xAD, 0xAF, 0xB1, 0xB7, 0xC0, 0xD9, 0x53, 0x42, 0x3B, +0x34, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x30, 0x33, 0x37, 0x3C, 0x43, 0x4D, 0x5E, 0xEC, 0xD0, +0xC7, 0xC0, 0xBB, 0xB6, 0xB0, 0xAE, 0xAB, 0xAA, 0xAC, 0xAE, 0xAF, 0xB3, 0xB9, 0xC5, 0xE2, 0x4E, +0x3F, 0x39, 0x32, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x2F, 0x33, 0x39, 0x3D, 0x44, 0x4F, 0x65, +0xE3, 0xCE, 0xC5, 0xBF, 0xBA, 0xB4, 0xAF, 0xAD, 0xAA, 0xAA, 0xAC, 0xAE, 0xB0, 0xB5, 0xBB, 0xC8, +0xF8, 0x4C, 0x3E, 0x38, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2E, 0x2F, 0x31, 0x35, 0x39, 0x3E, 0x4A, +0x5C, 0xF9, 0xD8, 0xCB, 0xC2, 0xBC, 0xB7, 0xB2, 0xAE, 0xAB, 0xA9, 0xAA, 0xAC, 0xAE, 0xB2, 0xB8, +0xBE, 0xCE, 0x72, 0x48, 0x3B, 0x34, 0x2F, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x36, 0x3A, +0x3E, 0x4A, 0x5F, 0xEA, 0xD0, 0xC9, 0xC1, 0xBB, 0xB5, 0xB0, 0xAE, 0xAB, 0xA9, 0xAB, 0xAC, 0xAE, +0xB4, 0xBB, 0xC4, 0xD6, 0x60, 0x45, 0x39, 0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x32, +0x35, 0x3A, 0x43, 0x51, 0x6A, 0xDF, 0xCB, 0xC3, 0xBD, 0xB8, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, +0xAC, 0xAF, 0xB7, 0xBD, 0xCC, 0xF1, 0x51, 0x3F, 0x36, 0x2F, 0x2D, 0x2B, 0x2A, 0x2C, 0x2D, 0x2E, +0x2F, 0x33, 0x37, 0x3B, 0x45, 0x58, 0x77, 0xD5, 0xC8, 0xC0, 0xBB, 0xB6, 0xB1, 0xAE, 0xAB, 0xA9, +0xAA, 0xAB, 0xAC, 0xB1, 0xB9, 0xC0, 0xD3, 0x6A, 0x4A, 0x3C, 0x33, 0x2E, 0x2D, 0x2B, 0x2B, 0x2C, +0x2D, 0x2E, 0x31, 0x34, 0x38, 0x3F, 0x4C, 0x5D, 0xEA, 0xCE, 0xC6, 0xBE, 0xB8, 0xB4, 0xAF, 0xAD, +0xAB, 0xAA, 0xAA, 0xAB, 0xAD, 0xB2, 0xB9, 0xC3, 0xD8, 0x61, 0x47, 0x3A, 0x32, 0x2E, 0x2C, 0x2B, +0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x38, 0x3F, 0x4D, 0x62, 0xDD, 0xCC, 0xC3, 0xBC, 0xB7, 0xB2, +0xAE, 0xAC, 0xAA, 0xAA, 0xAA, 0xAB, 0xAE, 0xB3, 0xBA, 0xC6, 0xE1, 0x55, 0x41, 0x37, 0x30, 0x2D, +0x2B, 0x2A, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x39, 0x40, 0x4D, 0x6A, 0xD8, 0xC9, 0xC1, 0xBC, +0xB7, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, 0xAC, 0xAF, 0xB7, 0xBB, 0xC6, 0x79, 0x55, 0x44, 0x37, +0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2D, 0x2F, 0x33, 0x35, 0x39, 0x42, 0x51, 0x6C, 0xDA, 0xCA, +0xC4, 0xBE, 0xBA, 0xB6, 0xB0, 0xAD, 0xAC, 0xAC, 0xAC, 0xAD, 0xAF, 0xB4, 0xB9, 0xC0, 0xD0, 0x65, +0x47, 0x3A, 0x32, 0x2F, 0x2C, 0x2B, 0x2B, 0x2C, 0x2D, 0x2E, 0x31, 0x36, 0x3A, 0x3F, 0x4A, 0x5E, +0xDC, 0xCC, 0xC4, 0xBE, 0xBA, 0xB6, 0xB2, 0xAF, 0xAE, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB8, 0xBE, +0xCA, 0xE6, 0x4F, 0x3F, 0x38, 0x31, 0x2E, 0x2C, 0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x35, 0x3A, 0x3F, +0x4B, 0x64, 0xDD, 0xCB, 0xC3, 0xBD, 0xBA, 0xB7, 0xB4, 0xB1, 0xAF, 0xAE, 0xAE, 0xB0, 0xB3, 0xB5, +0xB9, 0xBE, 0xC6, 0xD3, 0x74, 0x4E, 0x40, 0x3A, 0x35, 0x32, 0x30, 0x2F, 0x2F, 0x30, 0x33, 0x36, +0x3A, 0x3F, 0x48, 0x52, 0x6C, 0xDF, 0xCE, 0xC7, 0xC1, 0xBE, 0xBB, 0xB9, 0xB8, 0xB7, 0xB6, 0xB6, +0xB7, 0xB9, 0xBB, 0xBE, 0xC4, 0xCA, 0xD9, 0x6C, 0x50, 0x45, 0x3D, 0x3A, 0x37, 0x35, 0x35, 0x35, +0x36, 0x37, 0x39, 0x3C, 0x3F, 0x46, 0x4F, 0x5E, 0xF1, 0xD9, 0xCF, 0xCC, 0xC9, 0xC5, 0xC1, 0xBE, +0xBC, 0xBC, 0xBC, 0xBD, 0xBF, 0xC2, 0xC4, 0xC7, 0xCC, 0xD5, 0xE8, 0x64, 0x52, 0x4A, 0x45, 0x41, +0x3F, 0x3E, 0x3D, 0x3D, 0x3E, 0x41, 0x45, 0x49, 0x4D, 0x53, 0x5C, 0x71, 0xE9, 0xDD, 0xD6, 0xD1, +0xCE, 0xCB, 0xC9, 0xC8, 0xC8, 0xC7, 0xC7, 0xC8, 0xC9, 0xCC, 0xCF, 0xD4, 0xDA, 0xE4, 0xF7, 0x69, +0x5B, 0x53, 0x4F, 0x4E, 0x4D, 0x4D, 0x4D, 0x4E, 0x51, 0x58, 0x5F, 0x68, 0x6F, 0x77, 0xFC, 0xEE, +0xE8, 0xE5, 0xE1, 0xDD, 0xDE, 0xDE, 0xDE, 0xE2, 0xE6, 0xE6, 0xEB, 0xF0, 0xED, 0xEA, 0xEC, 0xEE, +0xF8, 0x6A, 0x5C, 0x57, 0x55, 0x56, 0x58, 0x59, 0x58, 0x58, 0x5B, 0x5E, 0x63, 0x71, 0xF7, 0xEE, +0xE9, 0xE3, 0xE4, 0xE8, 0xE7, 0xEA, 0xEE, 0xEE, 0xF2, 0xFB, 0xFF, 0x7B, 0x74, 0x6E, 0x6B, 0x65, +0x60, 0x65, 0x67, 0x61, 0x60, 0x61, 0x5E, 0x5E, 0x62, 0x69, 0x70, 0x7F, 0xF6, 0xF2, 0xEC, 0xE7, +0xE6, 0xE3, 0xDF, 0xDE, 0xDE, 0xDD, 0xDE, 0xE0, 0xE5, 0xEC, 0xF6, 0x7F, 0x78, 0x75, 0x70, 0x6B, +0x64, 0x5E, 0x5A, 0x58, 0x58, 0x59, 0x5A, 0x5C, 0x5D, 0x5E, 0x61, 0x67, 0x6C, 0x75, 0xF8, 0xEC, +0xE6, 0xE0, 0xDD, 0xDD, 0xDE, 0xDF, 0xE0, 0xE2, 0xE2, 0xE4, 0xE6, 0xE9, 0xEE, 0xF9, 0x7D, 0x75, +0x6E, 0x6A, 0x65, 0x61, 0x5E, 0x5C, 0x5B, 0x5C, 0x5D, 0x5E, 0x60, 0x63, 0x66, 0x6C, 0x76, 0xFA, +0xEE, 0xE9, 0xE4, 0xE1, 0xDF, 0xDD, 0xDE, 0xDF, 0xE2, 0xE6, 0xEA, 0xEE, 0xF4, 0xFA, 0x7E, 0x7A, +0x75, 0x72, 0x74, 0x74, 0x71, 0x70, 0x6D, 0x6A, 0x6A, 0x6B, 0x6D, 0x70, 0x74, 0x78, 0x7A, 0x7D, +0xFA, 0xF0, 0xEA, 0xE5, 0xE3, 0xE2, 0xE0, 0xDF, 0xE1, 0xE3, 0xE4, 0xE8, 0xEB, 0xEE, 0xF4, 0xFB, +0x7E, 0x75, 0x6D, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x65, 0x64, 0x63, 0x64, 0x66, 0x69, 0x6D, 0x72, +0x77, 0x7B, 0xFE, 0xF7, 0xF0, 0xEB, 0xE8, 0xE7, 0xE6, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xEA, 0xED, +0xF3, 0xFC, 0x79, 0x72, 0x6F, 0x6C, 0x6B, 0x6B, 0x69, 0x66, 0x64, 0x63, 0x62, 0x63, 0x67, 0x6C, +0x73, 0x7C, 0xFE, 0xFD, 0xFA, 0xF4, 0xEE, 0xEA, 0xE5, 0xE1, 0xE1, 0xE2, 0xE5, 0xE9, 0xED, 0xEF, +0xF1, 0xF2, 0xF4, 0xF8, 0xFF, 0x76, 0x6E, 0x6A, 0x68, 0x67, 0x66, 0x65, 0x64, 0x62, 0x61, 0x61, +0x63, 0x67, 0x6B, 0x72, 0x7E, 0xFA, 0xF5, 0xF1, 0xEE, 0xED, 0xEC, 0xE9, 0xE8, 0xE7, 0xE7, 0xE9, +0xEC, 0xF0, 0xF9, 0x7D, 0x77, 0x73, 0x70, 0x6F, 0x6E, 0x6C, 0x69, 0x67, 0x65, 0x66, 0x66, 0x68, +0x69, 0x69, 0x6A, 0x6C, 0x6E, 0x75, 0x7F, 0xF8, 0xF1, 0xED, 0xEB, 0xEA, 0xEA, 0xEB, 0xEB, 0xEB, +0xEA, 0xE9, 0xEA, 0xEC, 0xEF, 0xF4, 0xFB, 0x7D, 0x77, 0x73, 0x71, 0x6F, 0x6D, 0x6B, 0x69, 0x67, +0x66, 0x67, 0x68, 0x69, 0x6B, 0x6D, 0x6F, 0x74, 0x79, 0x7F, 0xF9, 0xF3, 0xEF, 0xEE, 0xEE, 0xEE, +0xEE, 0xED, 0xED, 0xED, 0xEE, 0xEC, 0xEC, 0xF1, 0xF3, 0xF6, 0xFD, 0xFF, 0x7D, 0x78, 0x78, 0x76, +0x70, 0x6F, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x71, 0x73, 0x77, 0x7B, 0x7D, 0xFF, 0xFB, 0xF8, 0xF8, +0xFA, 0xFB, 0xFE, 0x7E, 0x7D, 0x7A, 0x79, 0x7A, 0x76, 0x76, 0x76, 0x72, 0x70, 0x6F, 0x6D, 0x6E, +0x6D, 0x6B, 0x6E, 0x65, 0x66, 0x57, 0x41, 0x59, 0xC7, 0x62, 0x57, 0xCD, 0x64, 0x6B, 0xCC, 0x6D, +0xF6, 0xD1, 0x69, 0x6E, 0xDA, 0x7D, 0x61, 0xEE, 0xF1, 0xFD, 0xFF, 0x6E, 0xE7, 0x74, 0x66, 0xE9, +0x6A, 0xFC, 0xF2, 0x64, 0xEE, 0x6F, 0x6B, 0x7B, 0x69, 0xF2, 0x68, 0x74, 0xEC, 0x5F, 0xED, 0xFC, +0x5F, 0xDE, 0x72, 0x65, 0xDC, 0x51, 0x4C, 0xE8, 0x5F, 0xEF, 0xD7, 0x4E, 0xF3, 0xF9, 0x52, 0xC3, +0xE2, 0x56, 0xC9, 0x5B, 0x59, 0xE4, 0x50, 0x53, 0x47, 0x66, 0xF9, 0x47, 0xC9, 0xCB, 0x59, 0xD4, +0x55, 0x58, 0xD3, 0x5C, 0xF9, 0xCE, 0xD7, 0x6D, 0x61, 0xDB, 0xE4, 0xE8, 0x70, 0x79, 0xCD, 0x6B, +0x5D, 0xEC, 0x66, 0xDC, 0x6C, 0x5F, 0xD3, 0xF9, 0xFB, 0x66, 0x55, 0xDE, 0xFB, 0x64, 0xD7, 0xDA, +0xF1, 0xF1, 0xF1, 0xE5, 0xDB, 0xF4, 0x75, 0xDF, 0xE7, 0xFD, 0x79, 0xEC, 0xD9, 0xF0, 0x6E, 0xF5, +0xE4, 0xE5, 0x64, 0x74, 0xDF, 0x7D, 0x68, 0x75, 0xF0, 0xFD, 0x7B, 0xFC, 0x7B, 0xDE, 0xEF, 0x64, +0xDF, 0xE8, 0xFF, 0xE9, 0xFF, 0xE2, 0xE1, 0x76, 0xF6, 0xEF, 0xEC, 0xF9, 0x6D, 0x7C, 0x73, 0x6D, +0x69, 0x67, 0x76, 0x75, 0x73, 0x64, 0x66, 0xFD, 0x60, 0x5F, 0x77, 0x67, 0x70, 0x74, 0x60, 0x78, +0x7A, 0x5C, 0x67, 0x79, 0x6C, 0x77, 0x63, 0x63, 0xEF, 0x6C, 0x66, 0x73, 0x6D, 0xF8, 0x72, 0x74, +0xE6, 0xFB, 0x7B, 0xF3, 0xF6, 0xF1, 0xFE, 0x7B, 0xF5, 0xF1, 0x6D, 0x63, 0x75, 0x6E, 0x60, 0x64, +0x67, 0x67, 0x68, 0x67, 0x67, 0x6C, 0x64, 0x5B, 0x65, 0x6E, 0x69, 0x72, 0x76, 0x74, 0xFE, 0xFD, +0xFF, 0xF6, 0xF3, 0x7C, 0x7A, 0xFC, 0xFE, 0xFB, 0x7E, 0x75, 0xF5, 0xEE, 0xFC, 0xF7, 0xF3, 0xFF, +0xFE, 0x74, 0x6B, 0x6F, 0x6D, 0x6A, 0x6C, 0x6A, 0x7A, 0xF9, 0x71, 0x7C, 0xF5, 0x7C, 0x7B, 0x7F, +0xFE, 0x72, 0x6E, 0xFF, 0x6F, 0x66, 0x6B, 0x6A, 0x6E, 0x76, 0x71, 0x7C, 0x7A, 0x6E, 0x6C, 0x69, +0x6C, 0x6D, 0x63, 0x65, 0x6A, 0x66, 0x63, 0x65, 0x6C, 0x68, 0x64, 0x69, 0x6A, 0x6E, 0x79, 0x7B, +0x78, 0x6D, 0x6E, 0x79, 0x77, 0xFA, 0xED, 0xEF, 0xEF, 0xEC, 0xE8, 0xEF, 0xFB, 0xF6, 0xEF, 0xEE, +0xF7, 0xF9, 0xF3, 0xF7, 0xF1, 0xF3, 0xFD, 0xFD, 0x7A, 0x7B, 0xFE, 0x79, 0x7C, 0x7B, 0x6E, 0x72, +0x7A, 0x72, 0x71, 0x79, 0x79, 0x6F, 0x6F, 0x78, 0x74, 0x72, 0x7B, 0x72, 0x78, 0xF6, 0xF7, 0xF9, +0x78, 0x79, 0xEE, 0xF5, 0x74, 0x76, 0x7A, 0xFE, 0x7E, 0x75, 0x7A, 0x7E, 0x74, 0x70, 0x7D, 0xF8, +0xF8, 0x7D, 0x77, 0xF8, 0xF0, 0x7F, 0x7E, 0xF2, 0xED, 0xF0, 0xF4, 0xEB, 0xE9, 0xFE, 0x74, 0xEF, +0xE1, 0xE0, 0xDC, 0xD9, 0xD7, 0xD3, 0xD7, 0xDD, 0xD9, 0xD9, 0xDF, 0xE6, 0xEB, 0xF2, 0x78, 0x65, +0x61, 0x65, 0x5F, 0x5A, 0x5B, 0x5B, 0x5A, 0x5C, 0x5B, 0x5D, 0x5E, 0x5C, 0x5B, 0x5B, 0x5B, 0x5C, +0x5E, 0x6B, 0xEA, 0xD9, 0xD2, 0xD1, 0xCD, 0xC8, 0xC6, 0xC5, 0xC5, 0xC3, 0xC3, 0xC6, 0xCA, 0xD2, +0xE8, 0x67, 0x51, 0x49, 0x42, 0x3D, 0x3D, 0x3E, 0x3F, 0x41, 0x44, 0x49, 0x4E, 0x50, 0x55, 0x5A, +0x5F, 0x6F, 0xEF, 0xDA, 0xCD, 0xCA, 0xC8, 0xC4, 0xBF, 0xBD, 0xBB, 0xB9, 0xB7, 0xB6, 0xBA, 0xC2, +0xCC, 0xE2, 0x56, 0x43, 0x3B, 0x39, 0x37, 0x36, 0x37, 0x3B, 0x3E, 0x42, 0x47, 0x4B, 0x51, 0x5A, +0x5B, 0x5E, 0x67, 0x7A, 0xED, 0xE8, 0xDB, 0xCF, 0xCB, 0xC5, 0xBD, 0xB9, 0xB6, 0xB2, 0xB0, 0xB4, +0xB9, 0xBF, 0xCD, 0xFC, 0x49, 0x3B, 0x37, 0x33, 0x31, 0x32, 0x33, 0x38, 0x3E, 0x45, 0x4F, 0x5F, +0x74, 0xF0, 0xEF, 0xF1, 0xF4, 0xFF, 0x77, 0x72, 0xFB, 0xE4, 0xD9, 0xCE, 0xC3, 0xBA, 0xB6, 0xB2, +0xB0, 0xB2, 0xB6, 0xBB, 0xC8, 0xE4, 0x51, 0x3E, 0x38, 0x33, 0x2F, 0x2F, 0x31, 0x35, 0x3A, 0x3E, +0x49, 0x5D, 0xFE, 0xE4, 0xDD, 0xD9, 0xD9, 0xE1, 0xEB, 0xEE, 0xEE, 0xE7, 0xDD, 0xD2, 0xC7, 0xBD, +0xB9, 0xB5, 0xB2, 0xB5, 0xB8, 0xBB, 0xC6, 0xDA, 0x5F, 0x45, 0x3D, 0x37, 0x33, 0x31, 0x31, 0x35, +0x39, 0x3D, 0x45, 0x53, 0x6F, 0xE3, 0xD9, 0xD0, 0xCF, 0xD2, 0xD5, 0xD9, 0xD9, 0xD8, 0xD4, 0xCE, +0xC8, 0xC0, 0xBD, 0xB9, 0xB8, 0xBB, 0xBD, 0xC1, 0xCD, 0xDF, 0x5F, 0x4A, 0x41, 0x3B, 0x37, 0x36, +0x35, 0x36, 0x3A, 0x3D, 0x44, 0x4E, 0x5F, 0xEC, 0xDB, 0xD6, 0xD2, 0xD4, 0xD6, 0xDA, 0xDD, 0xDB, +0xD8, 0xD2, 0xCD, 0xC9, 0xC3, 0xBF, 0xBE, 0xBF, 0xC3, 0xC4, 0xCA, 0xD6, 0xED, 0x5E, 0x50, 0x48, +0x3F, 0x3C, 0x3B, 0x3A, 0x3A, 0x3D, 0x40, 0x4A, 0x55, 0x6A, 0xE6, 0xDC, 0xD8, 0xD6, 0xD8, 0xD8, +0xDB, 0xDE, 0xDF, 0xE2, 0xDE, 0xDC, 0xD9, 0xD0, 0xCB, 0xC8, 0xC8, 0xCC, 0xCD, 0xCD, 0xD1, 0xDB, +0xF2, 0x67, 0x5B, 0x51, 0x49, 0x44, 0x42, 0x41, 0x42, 0x44, 0x49, 0x4E, 0x55, 0x5C, 0x6A, 0x7E, +0xF3, 0xED, 0xED, 0xEF, 0xEC, 0xED, 0xF4, 0xF7, 0xF0, 0xEB, 0xE4, 0xDF, 0xDA, 0xD2, 0xCD, 0xCC, +0xCC, 0xCF, 0xCF, 0xCE, 0xD3, 0xDB, 0xE7, 0x7C, 0x69, 0x5E, 0x54, 0x4F, 0x4E, 0x4D, 0x4E, 0x4F, +0x52, 0x58, 0x5B, 0x5E, 0x63, 0x67, 0x6B, 0x6B, 0x6A, 0x6B, 0x6C, 0x6E, 0x6F, 0x73, 0x7D, 0xF3, +0xEA, 0xE1, 0xDC, 0xD8, 0xD3, 0xD1, 0xCF, 0xCE, 0xD1, 0xD2, 0xD2, 0xD6, 0xDB, 0xE2, 0xEF, 0xFD, +0x73, 0x66, 0x5F, 0x5C, 0x5A, 0x59, 0x58, 0x56, 0x56, 0x57, 0x57, 0x58, 0x58, 0x5A, 0x5C, 0x5D, +0x61, 0x65, 0x6A, 0x74, 0x7E, 0xF4, 0xEA, 0xE2, 0xDD, 0xDA, 0xD7, 0xD5, 0xD2, 0xD1, 0xD0, 0xD1, +0xD3, 0xD3, 0xD4, 0xD7, 0xDB, 0xE0, 0xE8, 0xEF, 0x7B, 0x69, 0x5F, 0x5B, 0x57, 0x53, 0x50, 0x4F, +0x4F, 0x4F, 0x4F, 0x50, 0x52, 0x56, 0x59, 0x5C, 0x60, 0x68, 0x6E, 0x7A, 0xFB, 0xF1, 0xEB, 0xE7, +0xE2, 0xDE, 0xDC, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD3, 0xD5, 0xD5, 0xD8, 0xDC, 0xE4, 0xF2, 0x78, +0x6A, 0x5E, 0x59, 0x55, 0x52, 0x50, 0x4F, 0x4F, 0x50, 0x52, 0x55, 0x58, 0x5A, 0x5D, 0x61, 0x64, +0x69, 0x6E, 0x74, 0xFF, 0xF6, 0xEE, 0xE9, 0xE4, 0xDF, 0xDC, 0xD8, 0xD5, 0xD2, 0xD0, 0xD1, 0xD1, +0xD2, 0xD6, 0xD7, 0xDA, 0xDF, 0xE8, 0xF8, 0x71, 0x69, 0x60, 0x5C, 0x58, 0x56, 0x54, 0x53, 0x53, +0x53, 0x55, 0x56, 0x58, 0x5A, 0x5C, 0x5F, 0x63, 0x69, 0x71, 0xFF, 0xEF, 0xEA, 0xE6, 0xE1, 0xDF, +0xDE, 0xDB, 0xDA, 0xDA, 0xD7, 0xD4, 0xD1, 0xD1, 0xD2, 0xD4, 0xD7, 0xD8, 0xDB, 0xE1, 0xED, 0x78, +0x69, 0x61, 0x5A, 0x53, 0x50, 0x4F, 0x4E, 0x4F, 0x4F, 0x51, 0x55, 0x59, 0x5D, 0x60, 0x65, 0x6C, +0x6F, 0x76, 0x7E, 0xFC, 0xF5, 0xF2, 0xF2, 0xED, 0xE7, 0xE1, 0xDD, 0xD9, 0xD4, 0xCE, 0xCB, 0xCA, +0xC8, 0xCA, 0xCF, 0xD0, 0xD7, 0xE6, 0x7C, 0x5E, 0x53, 0x4F, 0x4C, 0x4A, 0x4A, 0x4A, 0x4C, 0x4E, +0x4F, 0x51, 0x57, 0x5D, 0x62, 0x66, 0x69, 0x6D, 0x6D, 0x67, 0x63, 0x65, 0x6B, 0x70, 0x75, 0xFE, +0xEA, 0xDC, 0xD3, 0xCE, 0xC9, 0xC2, 0xBE, 0xBC, 0xBC, 0xC1, 0xC8, 0xCB, 0xDC, 0x69, 0x50, 0x46, +0x42, 0x3F, 0x3D, 0x3D, 0x3F, 0x43, 0x4B, 0x4F, 0x55, 0x61, 0x6F, 0xFC, 0xF0, 0xFA, 0xFD, 0x7B, +0x63, 0x5A, 0x54, 0x52, 0x54, 0x58, 0x62, 0x7D, 0xDE, 0xCC, 0xC4, 0xBC, 0xB6, 0xB1, 0xAE, 0xB2, +0xBA, 0xC1, 0xDA, 0x5A, 0x45, 0x38, 0x33, 0x32, 0x33, 0x36, 0x3A, 0x3E, 0x4B, 0x66, 0xEA, 0xD6, +0xCE, 0xCF, 0xD3, 0xE0, 0x6E, 0x5C, 0x51, 0x4D, 0x4B, 0x4A, 0x4F, 0x5B, 0x7A, 0xD6, 0xC6, 0xBA, +0xB1, 0xAE, 0xAA, 0xAA, 0xAF, 0xBA, 0xD1, 0x4E, 0x3D, 0x31, 0x2B, 0x2B, 0x2C, 0x30, 0x38, 0x3E, +0x4E, 0xEA, 0xCD, 0xC7, 0xC8, 0xCB, 0xCE, 0xDD, 0x64, 0x4F, 0x48, 0x48, 0x47, 0x46, 0x4D, 0x62, +0xDD, 0xCA, 0xBD, 0xB1, 0xAC, 0xA9, 0xA7, 0xAA, 0xB2, 0xC4, 0x51, 0x3A, 0x2F, 0x29, 0x28, 0x2A, +0x2E, 0x39, 0x45, 0x5A, 0xDB, 0xC8, 0xC2, 0xC5, 0xCD, 0xD5, 0xE8, 0x5B, 0x4C, 0x46, 0x47, 0x4C, +0x4E, 0x59, 0xF3, 0xD3, 0xC6, 0xBE, 0xB5, 0xAD, 0xAA, 0xA6, 0xA8, 0xB2, 0xC5, 0x54, 0x38, 0x2F, +0x28, 0x26, 0x2A, 0x2F, 0x3A, 0x4B, 0x73, 0xCF, 0xC5, 0xC4, 0xC9, 0xD9, 0xF8, 0x5F, 0x4C, 0x47, +0x47, 0x48, 0x4F, 0x5A, 0x74, 0xD9, 0xCE, 0xC7, 0xBF, 0xBA, 0xB0, 0xAC, 0xAA, 0xA9, 0xB0, 0xC5, +0x5C, 0x3B, 0x30, 0x2B, 0x27, 0x29, 0x2E, 0x39, 0x49, 0x6C, 0xD2, 0xC7, 0xC5, 0xCA, 0xDA, 0x7A, +0x5E, 0x4D, 0x48, 0x49, 0x4B, 0x52, 0x5E, 0x70, 0xDC, 0xCE, 0xC9, 0xC4, 0xBE, 0xB5, 0xAE, 0xAC, +0xAA, 0xAD, 0xBB, 0xE1, 0x43, 0x35, 0x2E, 0x29, 0x28, 0x2B, 0x32, 0x3D, 0x4E, 0x7E, 0xD2, 0xC9, +0xC7, 0xCC, 0xDF, 0xFE, 0x61, 0x4F, 0x4C, 0x4B, 0x4C, 0x54, 0x5D, 0x72, 0xDA, 0xCE, 0xC7, 0xC0, +0xB9, 0xB0, 0xAD, 0xAA, 0xAA, 0xB1, 0xC5, 0x5D, 0x3D, 0x33, 0x2C, 0x29, 0x29, 0x2D, 0x35, 0x3F, +0x4F, 0x78, 0xD7, 0xCA, 0xC7, 0xCD, 0xD9, 0xE3, 0x71, 0x5C, 0x54, 0x4D, 0x4E, 0x55, 0x5A, 0x6E, +0xE3, 0xD3, 0xC8, 0xBE, 0xB6, 0xAF, 0xAC, 0xAA, 0xAC, 0xB7, 0xCE, 0x53, 0x3D, 0x34, 0x2D, 0x2A, +0x2A, 0x2E, 0x35, 0x3E, 0x4A, 0x5C, 0xE5, 0xCD, 0xC8, 0xCB, 0xCE, 0xD5, 0xE2, 0xF7, 0x66, 0x57, +0x54, 0x56, 0x5B, 0x6E, 0xE7, 0xD5, 0xC9, 0xBE, 0xB6, 0xB1, 0xAE, 0xAE, 0xB4, 0xBE, 0xD3, 0x5C, +0x46, 0x3C, 0x34, 0x30, 0x2F, 0x32, 0x38, 0x3E, 0x45, 0x4E, 0x69, 0xDC, 0xCF, 0xCD, 0xCF, 0xD3, +0xD9, 0xDF, 0xEF, 0x6F, 0x68, 0x67, 0x6F, 0xF7, 0xE7, 0xDC, 0xD2, 0xC8, 0xC1, 0xBE, 0xBC, 0xBD, +0xC3, 0xCB, 0xD5, 0xEA, 0x6A, 0x58, 0x4D, 0x47, 0x43, 0x43, 0x44, 0x47, 0x4A, 0x4D, 0x52, 0x5D, +0x6D, 0x78, 0x77, 0x78, 0x76, 0x73, 0x75, 0x72, 0x72, 0x78, 0x7E, 0xF6, 0xEB, 0xE3, 0xDC, 0xD6, +0xD2, 0xCF, 0xCE, 0xCE, 0xCD, 0xCF, 0xD2, 0xD4, 0xD7, 0xDA, 0xDD, 0xE3, 0xEF, 0x7A, 0x6C, 0x65, +0x5F, 0x5B, 0x57, 0x53, 0x4F, 0x4E, 0x4D, 0x4C, 0x4A, 0x4A, 0x4A, 0x4B, 0x4D, 0x4F, 0x53, 0x59, +0x5F, 0x6C, 0xFE, 0xEC, 0xE3, 0xDE, 0xDC, 0xDA, 0xD9, 0xD8, 0xD7, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, +0xD8, 0xDA, 0xDC, 0xDE, 0xE3, 0xEC, 0xFB, 0x6F, 0x63, 0x5B, 0x55, 0x4F, 0x4D, 0x4C, 0x4B, 0x4C, +0x4C, 0x4D, 0x4F, 0x53, 0x58, 0x5E, 0x67, 0x73, 0xFB, 0xEE, 0xE8, 0xE3, 0xDF, 0xDC, 0xDA, 0xD9, +0xD8, 0xD8, 0xD8, 0xD9, 0xDB, 0xDD, 0xDF, 0xE1, 0xE5, 0xE9, 0xEE, 0xF6, 0x7C, 0x6E, 0x66, 0x5F, +0x5C, 0x5A, 0x58, 0x56, 0x56, 0x57, 0x58, 0x5A, 0x5D, 0x60, 0x66, 0x6D, 0x74, 0x7C, 0xFB, 0xF4, +0xEE, 0xEA, 0xE7, 0xE5, 0xE4, 0xE4, 0xE4, 0xE7, 0xEA, 0xEC, 0xED, 0xED, 0xEC, 0xED, 0xEC, 0xED, +0xEE, 0xF1, 0xF9, 0x7F, 0x79, 0x75, 0x70, 0x6D, 0x6C, 0x6C, 0x6E, 0x73, 0x79, 0xFE, 0xF9, 0xF3, +0xEE, 0xEB, 0xE9, 0xE8, 0xE6, 0xE5, 0xE6, 0xE8, 0xEA, 0xED, 0xF1, 0xF8, 0xFD, 0x7E, 0x7E, 0xFE, +0xFC, 0xF9, 0xF5, 0xF5, 0xF6, 0xFB, 0x7C, 0x77, 0x71, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6B, 0x6E, +0x70, 0x75, 0x7A, 0xFE, 0xF6, 0xF1, 0xEE, 0xEC, 0xEB, 0xEB, 0xEC, 0xEE, 0xF1, 0xF5, 0xFB, 0x7D, +0x7B, 0x7A, 0x7C, 0xFE, 0xFA, 0xF4, 0xF1, 0xF0, 0xF0, 0xF3, 0xF7, 0xFB, 0xFD, 0xFF, 0xFF, 0x7F, +0x7F, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0xFD, 0xFC, 0xFA, 0xF5, 0xF4, 0xF1, 0xEF, 0xEF, 0xEF, 0xF0, +0xF4, 0xF8, 0xFD, 0x7D, 0x78, 0x77, 0x78, 0x7A, 0x7C, 0x7C, 0x7E, 0x7C, 0x7A, 0x79, 0x76, 0x77, +0x78, 0x77, 0x7B, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0x7E, 0xFE, 0xFB, +0xFA, 0xF9, 0xFA, 0xFB, 0xFE, 0x7F, 0x7C, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7C, 0x7D, 0x7E, 0x7B, +0x77, 0x74, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x76, 0x76, 0x75, 0x76, +0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x77, 0x74, 0x72, 0x70, 0x6F, 0x6E, 0x6E, 0x6E, 0x70, 0x74, +0x78, 0x7B, 0x7D, 0x7D, 0x7C, 0x7C, 0x7A, 0x76, 0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x72, 0x72, +0x74, 0x76, 0x78, 0x7B, 0x7F, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF7, 0xFC, 0xFF, 0x7C, 0x79, 0x78, +0x77, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xFA, 0xFC, 0xFE, 0x7D, 0x7A, 0x76, +0x74, 0x74, 0x73, 0x75, 0x76, 0x76, 0x78, 0x7A, 0x7C, 0x7E, 0xFF, 0xFB, 0xF9, 0xF8, 0xF9, 0xFD, +0x7E, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x7C, 0x7F, 0xFB, 0xF6, 0xF5, 0xF2, 0xF2, 0xF3, +0xF4, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFA, +0xF7, 0xF6, 0xF8, 0xFC, 0x7F, 0x7C, 0x79, 0x72, 0x6F, 0x6E, 0x6E, 0x6E, 0x6F, 0x73, 0x77, 0x77, +0x7B, 0x7D, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x77, 0x75, 0x71, 0x6F, 0x6E, 0x6D, 0x6E, 0x6F, 0x70, +0x73, 0x74, 0x77, 0x79, 0x7C, 0x7D, 0x7D, 0x7D, 0x7B, 0x7A, 0x79, 0x76, 0x73, 0x70, 0x6F, 0x71, +0x73, 0x78, 0x7B, 0x7F, 0xFB, 0xF8, 0xF5, 0xF3, 0xF5, 0xF6, 0xF6, 0xF8, 0xF9, 0xFC, 0xFE, 0xFF, +0x7F, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xF7, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF6, 0xF7, 0xF9, +0xFA, 0xFC, 0xFF, 0xFF, 0x7F, 0x7F, 0xFE, 0xFD, 0xFE, 0xFD, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7C, +0x7A, 0x79, 0x77, 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7C, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, +0x7D, 0x7E, 0x7C, 0x7E, 0x7F, 0x7E, 0x7E, 0xFF, 0xFD, 0xFC, 0xFB, 0xF8, 0xF8, 0xFA, 0xFA, 0xFC, +0xFE, 0x7D, 0x78, 0x75, 0x72, 0x70, 0x70, 0x73, 0x75, 0x76, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x78, +0x77, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7D, 0x7F, 0xFC, 0xF8, 0xF6, +0xF4, 0xF2, 0xF3, 0xF7, 0xF9, 0xFB, 0x7E, 0x78, 0x75, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, +0x75, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x76, 0x79, 0x7B, +0x7C, 0x7E, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF6, 0xF7, 0xF9, 0xFC, 0xFE, 0x7C, 0x79, 0x77, 0x76, +0x75, 0x74, 0x74, 0x75, 0x74, 0x76, 0x77, 0x78, 0x79, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x78, 0x78, +0x77, 0x76, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7C, 0xFF, 0xFD, 0xFA, 0xF8, 0xF6, 0xF7, 0xF8, 0xF7, +0xF8, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, 0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFD, 0xFC, 0xFD, 0xFE, +0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, 0x7C, +0x7C, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x71, 0x70, 0x6F, 0x6F, 0x6E, +0x6D, 0x6C, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6F, 0x6E, 0x6F, 0x70, 0x70, 0x72, 0x75, 0x78, 0x7B, +0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFC, 0xFA, 0xFA, 0xF9, 0xF7, 0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF9, +0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFB, +0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0x7F, 0xFC, 0xFA, 0xFB, 0xFA, 0xFA, 0xF9, +0xFA, 0xFC, 0xFC, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFD, 0xFA, 0xFA, 0xF9, 0xF8, +0xFA, 0xF8, 0xFA, 0xFA, 0xFB, 0xFE, 0xFB, 0xFF, 0xFD, 0xFD, 0xFF, 0xFB, 0xFF, 0xFA, 0xFC, 0x7F, +0xFC, 0x70, 0x6A, 0x64, 0x61, 0x67, 0x6C, 0x73, 0x61, 0x60, 0x5A, 0x47, 0x53, 0xDF, 0x7D, 0x6F, +0x71, 0x69, 0x7F, 0x72, 0x70, 0x68, 0x5A, 0x5B, 0x59, 0x55, 0x5A, 0x5D, 0x4E, 0x46, 0x51, 0x77, +0xF6, 0xEC, 0xE8, 0xE6, 0xE5, 0xE4, 0xE1, 0xE5, 0xFD, 0x60, 0x65, 0xE6, 0xDB, 0xDD, 0xE1, 0xE4, +0xE2, 0xDC, 0xD4, 0xCF, 0xCF, 0xCF, 0xD1, 0xD2, 0xCF, 0xCD, 0xCC, 0xCD, 0xD0, 0xD4, 0xD7, 0xD5, +0xCE, 0xCD, 0xD3, 0xD9, 0xDB, 0xDA, 0xD9, 0xDC, 0xE2, 0xE5, 0xF1, 0xEE, 0xD7, 0xD2, 0xD9, 0xDC, +0xDD, 0xD9, 0xDC, 0xE7, 0xDF, 0xD9, 0xDD, 0x74, 0x62, 0xFC, 0xE9, 0xF2, 0x6C, 0x5D, 0x5D, 0x61, +0x6B, 0x6C, 0x5C, 0x5D, 0x70, 0x64, 0x5B, 0x6D, 0x78, 0x61, 0x57, 0x58, 0x65, 0x62, 0x53, 0x51, +0x69, 0xF5, 0x59, 0x53, 0x69, 0x68, 0x54, 0x4F, 0x67, 0xFA, 0x5B, 0x58, 0x5D, 0x60, 0x5D, 0x4E, +0x53, 0x61, 0x5A, 0x5F, 0x63, 0x61, 0x5E, 0x4C, 0x4C, 0x5A, 0x6B, 0xF7, 0x58, 0x47, 0x51, 0x6D, +0x68, 0x5A, 0x55, 0x53, 0x4A, 0x4E, 0xEE, 0xE1, 0x56, 0x46, 0x4D, 0x74, 0x70, 0x59, 0x53, 0x4C, +0x4E, 0x62, 0xF2, 0xF3, 0x5A, 0x4A, 0x4F, 0x6D, 0x6B, 0x57, 0x63, 0xED, 0x79, 0x69, 0x62, 0x5D, +0x6C, 0x67, 0x5E, 0xF5, 0xEA, 0x69, 0x63, 0x76, 0xFA, 0x6A, 0x59, 0x5D, 0xFB, 0xF6, 0x72, 0xFB, +0x71, 0x5D, 0x65, 0x7D, 0xFC, 0x79, 0xFB, 0xE9, 0xE2, 0xDD, 0xE3, 0xF9, 0xFA, 0xF3, 0xEA, 0xEC, +0x7D, 0xF1, 0xE5, 0xF2, 0x78, 0x6D, 0x6D, 0xED, 0xE4, 0xE5, 0xE4, 0xF6, 0x7A, 0xF8, 0xE5, 0xDC, +0xEA, 0xDF, 0xCF, 0xD3, 0xE7, 0x6C, 0x78, 0xCF, 0xC9, 0xD5, 0x7E, 0x64, 0x7E, 0xD7, 0xCF, 0xD7, +0xE0, 0xE8, 0xDC, 0xCB, 0xC5, 0xCC, 0xE6, 0x73, 0xE9, 0xD2, 0xC9, 0xCA, 0xD3, 0xED, 0x68, 0xF3, +0xD9, 0xDA, 0xDC, 0xDA, 0xD7, 0xDB, 0xE1, 0xE1, 0xEA, 0x69, 0x59, 0x60, 0xEE, 0xE0, 0xDC, 0xDF, +0xE5, 0xDD, 0xE1, 0xED, 0xED, 0xF4, 0xF6, 0xF2, 0xEE, 0xED, 0xFC, 0x6F, 0x64, 0x5C, 0x5C, 0x61, +0x76, 0xEA, 0xE1, 0xEB, 0x73, 0x66, 0x60, 0x69, 0xFB, 0x7E, 0x70, 0x76, 0xFF, 0x78, 0x73, 0xEB, +0xE2, 0x6F, 0x5C, 0x69, 0xE9, 0xDB, 0xDE, 0x73, 0x5E, 0x6D, 0xED, 0xEB, 0xF4, 0xFF, 0x77, 0xFD, +0xE7, 0xE2, 0xFB, 0x66, 0x69, 0xFE, 0xFA, 0x6B, 0x63, 0x69, 0x74, 0x74, 0x66, 0x63, 0x6F, 0xFB, +0xFD, 0x73, 0x71, 0x7B, 0xF4, 0xE8, 0xE2, 0xE8, 0xF2, 0xEB, 0xDE, 0xDC, 0xDE, 0xE2, 0xE7, 0xE5, +0xDF, 0xDF, 0xE8, 0xFC, 0x6D, 0x6A, 0x66, 0x5C, 0x53, 0x51, 0x56, 0x5B, 0x59, 0x56, 0x56, 0x5A, +0x5E, 0x5A, 0x53, 0x53, 0x59, 0x5D, 0x5F, 0x64, 0x74, 0xE9, 0xD6, 0xCB, 0xCB, 0xD3, 0xDC, 0xD4, +0xC8, 0xC1, 0xBF, 0xBE, 0xBE, 0xC5, 0xCE, 0xDC, 0xEA, 0x68, 0x4B, 0x3E, 0x3B, 0x3B, 0x3D, 0x3E, +0x41, 0x45, 0x47, 0x48, 0x4A, 0x4C, 0x4A, 0x47, 0x49, 0x4F, 0x5E, 0x6D, 0xF5, 0xDB, 0xCC, 0xC5, +0xC1, 0xBF, 0xBE, 0xBC, 0xBA, 0xB7, 0xB2, 0xAF, 0xAE, 0xB7, 0xDA, 0x43, 0x38, 0x35, 0x32, 0x31, +0x33, 0x3A, 0x46, 0x54, 0x5D, 0x56, 0x4A, 0x44, 0x43, 0x46, 0x44, 0x3F, 0x40, 0x4B, 0x61, 0x7B, +0xFD, 0xE7, 0xD4, 0xCA, 0xC5, 0xBF, 0xBB, 0xB6, 0xB1, 0xAF, 0xAD, 0xAC, 0xAC, 0xB4, 0xD8, 0x3C, +0x2D, 0x2B, 0x2D, 0x2F, 0x37, 0x41, 0x54, 0x76, 0xFF, 0x68, 0x54, 0x46, 0x40, 0x44, 0x49, 0x4A, +0x49, 0x4C, 0x5C, 0xFB, 0xE9, 0xE5, 0xDB, 0xCE, 0xC8, 0xC3, 0xBE, 0xBA, 0xB6, 0xB1, 0xAE, 0xAB, +0xA9, 0xAB, 0xBD, 0x3F, 0x2A, 0x26, 0x2A, 0x31, 0x3A, 0x43, 0x58, 0xE9, 0xDB, 0xE8, 0x5E, 0x46, +0x3C, 0x3D, 0x48, 0x55, 0x56, 0x55, 0x61, 0xF3, 0xE8, 0xE6, 0xDC, 0xCF, 0xC9, 0xC0, 0xB9, 0xB4, +0xB3, 0xB3, 0xAF, 0xAA, 0xA8, 0xAF, 0x75, 0x2C, 0x22, 0x24, 0x2D, 0x3F, 0x56, 0x72, 0xE0, 0xCF, +0xD4, 0x59, 0x3F, 0x38, 0x38, 0x3E, 0x4C, 0x68, 0xE8, 0xE3, 0xEA, 0x7E, 0x67, 0x64, 0x79, 0xDC, +0xCB, 0xBF, 0xB7, 0xB1, 0xAF, 0xAE, 0xAC, 0xAA, 0xB1, 0x56, 0x29, 0x1F, 0x20, 0x2B, 0x45, 0xD1, +0xC4, 0xC7, 0xCB, 0xD8, 0x4B, 0x33, 0x2E, 0x34, 0x42, 0x6D, 0xCD, 0xC5, 0xC8, 0xD1, 0xE0, 0x69, +0x52, 0x52, 0x6D, 0xD4, 0xC6, 0xBB, 0xB1, 0xAC, 0xAB, 0xAA, 0xA8, 0xAE, 0x68, 0x28, 0x1D, 0x1E, +0x2B, 0x53, 0xBC, 0xB6, 0xBD, 0xCA, 0xE1, 0x4E, 0x33, 0x2A, 0x2C, 0x3B, 0x7D, 0xBF, 0xBB, 0xC1, +0xD5, 0xED, 0x6A, 0x4F, 0x4C, 0x58, 0x7E, 0xD6, 0xC7, 0xBB, 0xB2, 0xAD, 0xA9, 0xA6, 0xA9, 0xC3, +0x2D, 0x1D, 0x1B, 0x23, 0x41, 0xBC, 0xAF, 0xB5, 0xC2, 0xDE, 0x4F, 0x3B, 0x2D, 0x27, 0x2D, 0x49, +0xC3, 0xB5, 0xB9, 0xCB, 0x64, 0x54, 0x56, 0x51, 0x58, 0x75, 0xE3, 0xD1, 0xCA, 0xC1, 0xB6, 0xAB, +0xA6, 0xA3, 0xA6, 0xC0, 0x2B, 0x1C, 0x1A, 0x24, 0x4D, 0xB0, 0xAA, 0xB0, 0xC3, 0xF0, 0x46, 0x38, +0x2D, 0x28, 0x2B, 0x4C, 0xBC, 0xB2, 0xB6, 0xD1, 0x4B, 0x46, 0x4F, 0x58, 0x61, 0xEE, 0xE1, 0xDB, +0xCF, 0xCB, 0xBD, 0xAE, 0xA7, 0xA3, 0xA2, 0xB6, 0x2C, 0x1B, 0x19, 0x21, 0x52, 0xAB, 0xA5, 0xAE, +0xC9, 0x4F, 0x3B, 0x37, 0x32, 0x2A, 0x2A, 0x3D, 0xC9, 0xB2, 0xB1, 0xCA, 0x44, 0x3D, 0x49, 0x5F, +0xDD, 0xD8, 0x77, 0x6E, 0xED, 0xDB, 0xC7, 0xB7, 0xAB, 0xA5, 0xA3, 0xA6, 0xC8, 0x26, 0x1A, 0x1A, +0x27, 0xC5, 0xA4, 0xA3, 0xAF, 0xE9, 0x3B, 0x33, 0x34, 0x31, 0x2D, 0x31, 0x57, 0xBF, 0xB3, 0xBA, +0x78, 0x41, 0x3E, 0x4E, 0xDC, 0xCE, 0xD4, 0x78, 0x5B, 0x67, 0xDC, 0xC4, 0xB7, 0xAC, 0xA6, 0xA5, +0xA5, 0xBA, 0x2C, 0x1B, 0x19, 0x23, 0xD8, 0xA3, 0x9F, 0xAB, 0xDA, 0x34, 0x2D, 0x30, 0x33, 0x33, +0x37, 0x54, 0xC1, 0xB7, 0xBD, 0x6E, 0x41, 0x3D, 0x4A, 0xD8, 0xCA, 0xD0, 0xEB, 0x56, 0x54, 0x74, +0xCE, 0xBD, 0xAF, 0xA8, 0xA6, 0xA5, 0xAE, 0x3B, 0x1E, 0x19, 0x1E, 0x43, 0xA8, 0x9E, 0xA6, 0xC8, +0x33, 0x29, 0x2C, 0x32, 0x39, 0x3D, 0x4E, 0xCD, 0xBE, 0xC2, 0xFF, 0x40, 0x3D, 0x48, 0xE0, 0xC4, +0xCB, 0xEA, 0x4F, 0x48, 0x59, 0xD7, 0xBE, 0xB5, 0xAD, 0xA9, 0xA9, 0xA7, 0xB3, 0x34, 0x1D, 0x19, +0x20, 0xEE, 0xA2, 0x9D, 0xA8, 0x60, 0x2A, 0x26, 0x2D, 0x3B, 0x4A, 0x4E, 0x64, 0xCE, 0xC6, 0xCF, +0x57, 0x42, 0x47, 0x67, 0xCB, 0xC3, 0xD4, 0x5C, 0x48, 0x47, 0x63, 0xCA, 0xBA, 0xB2, 0xAE, 0xAC, +0xAC, 0xAB, 0xB3, 0x3D, 0x1F, 0x1B, 0x20, 0x51, 0xA5, 0x9E, 0xA8, 0x6C, 0x2A, 0x24, 0x2B, 0x3E, +0x5E, 0x6C, 0x66, 0xFA, 0xE0, 0xE4, 0x60, 0x4B, 0x4E, 0x71, 0xD2, 0xC8, 0xD8, 0x5A, 0x4A, 0x49, +0x6E, 0xC6, 0xB9, 0xB3, 0xB1, 0xAF, 0xAE, 0xAC, 0xAF, 0x48, 0x21, 0x1B, 0x1F, 0x4C, 0xA5, 0x9D, +0xA7, 0x64, 0x28, 0x23, 0x2C, 0x4A, 0xD6, 0xD9, 0x61, 0x59, 0x6C, 0xEF, 0xF8, 0x5B, 0x5B, 0xEE, +0xD5, 0xCD, 0xDB, 0x5C, 0x4D, 0x4C, 0x6E, 0xC8, 0xBB, 0xB8, 0xB8, 0xB6, 0xB3, 0xAD, 0xA8, 0xBC, +0x2D, 0x1D, 0x1B, 0x2B, 0xB7, 0x9F, 0xA1, 0xB9, 0x33, 0x23, 0x28, 0x3A, 0xEB, 0xCF, 0x77, 0x50, +0x56, 0x6E, 0xE2, 0x73, 0x55, 0x5D, 0xE6, 0xCF, 0xD9, 0x5B, 0x4B, 0x47, 0x59, 0xD2, 0xC3, 0xBD, +0xBD, 0xBC, 0xB6, 0xAE, 0xA9, 0xAB, 0x68, 0x24, 0x1B, 0x1E, 0x3C, 0xAA, 0x9E, 0xA6, 0xDE, 0x2A, +0x23, 0x2C, 0x47, 0xD1, 0xCE, 0x72, 0x55, 0x58, 0x6A, 0x78, 0x5D, 0x5B, 0xF9, 0xDA, 0xD3, 0xDE, +0x5A, 0x49, 0x4A, 0x5F, 0xD1, 0xC0, 0xBD, 0xBC, 0xB9, 0xB3, 0xAD, 0xA9, 0xB1, 0x3C, 0x1F, 0x1C, +0x24, 0xE1, 0xA4, 0x9F, 0xAD, 0x44, 0x26, 0x25, 0x32, 0x6E, 0xC3, 0xCD, 0x64, 0x4F, 0x4F, 0x62, +0x70, 0x5C, 0x68, 0xE1, 0xD4, 0xD3, 0xF6, 0x4E, 0x45, 0x4B, 0x78, 0xCA, 0xBE, 0xBC, 0xBC, 0xB8, +0xB3, 0xAC, 0xA9, 0xBC, 0x2F, 0x1E, 0x1C, 0x2A, 0xBC, 0xA0, 0xA1, 0xB7, 0x35, 0x24, 0x28, 0x3B, +0xD8, 0xC4, 0xDC, 0x53, 0x4B, 0x4F, 0x67, 0x6D, 0x65, 0xEA, 0xDB, 0xD5, 0xDA, 0x5E, 0x4B, 0x48, +0x53, 0xDB, 0xC4, 0xBD, 0xBD, 0xBB, 0xB5, 0xAE, 0xA8, 0xAB, 0x75, 0x25, 0x1B, 0x1E, 0x3D, 0xAA, +0x9E, 0xA6, 0xDC, 0x2B, 0x25, 0x2E, 0x4E, 0xCC, 0xCC, 0x66, 0x4B, 0x4C, 0x5A, 0x74, 0x6C, 0x6D, +0xDF, 0xD6, 0xD6, 0xED, 0x4D, 0x43, 0x46, 0x59, 0xD0, 0xBF, 0xBC, 0xBB, 0xB8, 0xB3, 0xAD, 0xA9, +0xB3, 0x38, 0x1E, 0x1B, 0x24, 0xCF, 0xA2, 0x9F, 0xAF, 0x3E, 0x26, 0x27, 0x36, 0x6A, 0xCD, 0xE6, +0x4F, 0x4D, 0x55, 0x6E, 0xEF, 0x63, 0x7B, 0xDA, 0xDB, 0xDF, 0x5F, 0x49, 0x47, 0x4F, 0xE8, 0xC5, +0xBD, 0xBC, 0xBB, 0xB6, 0xAF, 0xAA, 0xAA, 0xCD, 0x29, 0x1C, 0x1D, 0x34, 0xAE, 0x9F, 0xA4, 0xC7, +0x2E, 0x25, 0x2C, 0x41, 0xDB, 0xD2, 0x75, 0x5B, 0x59, 0x60, 0x6E, 0x5B, 0x5C, 0xDF, 0xD0, 0xD8, +0x74, 0x4B, 0x43, 0x4B, 0x6E, 0xCC, 0xBF, 0xBD, 0xBE, 0xBC, 0xB5, 0xAD, 0xA8, 0xAD, 0x4B, 0x22, +0x1C, 0x22, 0x65, 0xA6, 0x9F, 0xAC, 0x4C, 0x2A, 0x28, 0x33, 0x50, 0xDE, 0xF2, 0x65, 0x7C, 0xF8, +0x79, 0x5A, 0x4B, 0x5E, 0xD7, 0xCF, 0xD6, 0x5F, 0x45, 0x43, 0x4C, 0xFB, 0xC9, 0xBF, 0xBD, 0xBC, +0xB8, 0xB2, 0xAD, 0xAA, 0xB7, 0x38, 0x20, 0x1D, 0x29, 0xC6, 0xA5, 0xA4, 0xB8, 0x3C, 0x2A, 0x2C, +0x39, 0x53, 0x7F, 0x6F, 0x79, 0xE8, 0xF9, 0x61, 0x4D, 0x4B, 0xFF, 0xD0, 0xD3, 0xEC, 0x4F, 0x45, +0x49, 0x58, 0xDF, 0xC7, 0xBF, 0xBD, 0xBB, 0xB5, 0xAF, 0xA9, 0xAA, 0xCA, 0x2C, 0x1D, 0x1E, 0x36, +0xB1, 0xA2, 0xA8, 0xCE, 0x33, 0x2B, 0x30, 0x3E, 0x4F, 0x5A, 0x6D, 0xD8, 0xD2, 0xF5, 0x4F, 0x46, +0x54, 0xD4, 0xCA, 0xD7, 0x65, 0x48, 0x43, 0x4C, 0x61, 0xD7, 0xC4, 0xBF, 0xBD, 0xB7, 0xB1, 0xAD, +0xAA, 0xB0, 0x48, 0x23, 0x1D, 0x24, 0x5D, 0xAA, 0xA4, 0xB0, 0x56, 0x30, 0x2E, 0x34, 0x3E, 0x47, +0x52, 0xE3, 0xC9, 0xCE, 0x65, 0x45, 0x43, 0x6A, 0xCE, 0xCD, 0xDE, 0x58, 0x49, 0x49, 0x4F, 0x6D, +0xD1, 0xC0, 0xBB, 0xB6, 0xAF, 0xAE, 0xAA, 0xAB, 0xCF, 0x2B, 0x1D, 0x1E, 0x36, 0xB2, 0xA4, 0xA9, +0xC7, 0x3B, 0x2F, 0x31, 0x37, 0x3D, 0x46, 0x6E, 0xC7, 0xC5, 0xE5, 0x4C, 0x41, 0x50, 0xD5, 0xCB, +0xDF, 0x58, 0x4C, 0x49, 0x4E, 0x62, 0xE4, 0xC8, 0xBD, 0xB9, 0xB4, 0xAF, 0xAD, 0xA9, 0xB2, 0x41, +0x22, 0x1D, 0x26, 0xEB, 0xAA, 0xA6, 0xB3, 0x5D, 0x38, 0x32, 0x32, 0x34, 0x39, 0x4D, 0xCC, 0xBD, +0xC7, 0x60, 0x44, 0x47, 0x6D, 0xDC, 0xE2, 0xEF, 0x63, 0x58, 0x50, 0x4D, 0x5A, 0xDB, 0xC3, 0xBA, +0xB3, 0xAF, 0xAD, 0xAC, 0xAE, 0xD3, 0x2D, 0x1F, 0x20, 0x38, 0xB9, 0xA9, 0xAD, 0xC4, 0x4C, 0x39, +0x33, 0x30, 0x32, 0x3C, 0xFA, 0xBE, 0xBE, 0xD5, 0x51, 0x46, 0x4F, 0x6F, 0x7B, 0x65, 0x68, 0x76, +0x60, 0x54, 0x52, 0x61, 0xCF, 0xBF, 0xB7, 0xAE, 0xAC, 0xAB, 0xAB, 0xBC, 0x39, 0x22, 0x1E, 0x2B, +0xE7, 0xAF, 0xAC, 0xB6, 0xD1, 0x4E, 0x3A, 0x2F, 0x2D, 0x31, 0x45, 0xCC, 0xBC, 0xC2, 0xDA, 0x58, +0x4D, 0x55, 0x52, 0x52, 0x68, 0xED, 0xF4, 0x66, 0x55, 0x59, 0xEF, 0xCE, 0xBF, 0xB5, 0xAD, 0xAB, +0xAB, 0xAE, 0xCC, 0x31, 0x22, 0x22, 0x2F, 0xE8, 0xB6, 0xB1, 0xB8, 0xC4, 0x73, 0x3D, 0x2F, 0x2B, +0x2F, 0x3F, 0xDD, 0xC0, 0xBF, 0xC7, 0xD8, 0x73, 0x55, 0x46, 0x44, 0x53, 0x7B, 0xEE, 0xED, 0xF2, +0xED, 0xDC, 0xCF, 0xC1, 0xB3, 0xAC, 0xA9, 0xA9, 0xB2, 0x58, 0x2C, 0x24, 0x28, 0x36, 0x5C, 0xC7, +0xBA, 0xB6, 0xB7, 0xCA, 0x49, 0x34, 0x2D, 0x2E, 0x37, 0x49, 0xE0, 0xC4, 0xBD, 0xBE, 0xC7, 0xEA, +0x4C, 0x42, 0x44, 0x49, 0x50, 0x69, 0xDD, 0xD0, 0xCB, 0xC6, 0xBD, 0xB3, 0xAD, 0xAB, 0xAB, 0xBA, +0x49, 0x2F, 0x2B, 0x2D, 0x32, 0x3A, 0x4B, 0xD6, 0xBC, 0xB6, 0xBD, 0xD7, 0x51, 0x3D, 0x36, 0x34, +0x37, 0x3E, 0x52, 0xDE, 0xC8, 0xC3, 0xC7, 0xCE, 0xDE, 0x72, 0x56, 0x4F, 0x53, 0x5D, 0xFF, 0xDA, +0xC9, 0xBD, 0xB7, 0xB4, 0xB2, 0xB6, 0xC6, 0x62, 0x47, 0x3F, 0x3D, 0x3B, 0x3B, 0x40, 0x4E, 0x6F, +0xEC, 0x7B, 0x67, 0x5E, 0x5B, 0x59, 0x55, 0x5A, 0x65, 0x5E, 0x5A, 0x5F, 0x61, 0x5E, 0x63, 0x65, +0x61, 0x6D, 0xF5, 0xFA, 0x7A, 0x77, 0x77, 0xFF, 0xEB, 0xDC, 0xD5, 0xCE, 0xCA, 0xC8, 0xC8, 0xCD, +0xD9, 0xEC, 0x76, 0x70, 0xFD, 0xED, 0xEA, 0xEE, 0x7D, 0x66, 0x59, 0x53, 0x50, 0x4F, 0x50, 0x54, +0x56, 0x58, 0x59, 0x5A, 0x5A, 0x5C, 0x5F, 0x6B, 0xF6, 0xE5, 0xE1, 0xE7, 0xEF, 0xF5, 0xF2, 0xEA, +0xDF, 0xD8, 0xCE, 0xC8, 0xC4, 0xC5, 0xCB, 0xD4, 0xDF, 0xE9, 0xE7, 0xE1, 0xDD, 0xDB, 0xDE, 0xEE, +0x68, 0x57, 0x4F, 0x4D, 0x4D, 0x4E, 0x4F, 0x4F, 0x52, 0x54, 0x53, 0x51, 0x53, 0x57, 0x5E, 0x6F, +0xFA, 0xEF, 0xEF, 0xF3, 0xF1, 0xF1, 0xEE, 0xE6, 0xDE, 0xD6, 0xCF, 0xCD, 0xCE, 0xD3, 0xDA, 0xDC, +0xDF, 0xDF, 0xD9, 0xD5, 0xD4, 0xD7, 0xE0, 0xFE, 0x6B, 0x5F, 0x5A, 0x58, 0x56, 0x54, 0x54, 0x53, +0x53, 0x50, 0x4E, 0x4F, 0x52, 0x56, 0x5C, 0x64, 0x67, 0x66, 0x69, 0x6C, 0x6D, 0x74, 0xFA, 0xEC, +0xDF, 0xD7, 0xD6, 0xDD, 0xE6, 0xF3, 0x7B, 0xF7, 0xE8, 0xDC, 0xD3, 0xD0, 0xD2, 0xD9, 0xE1, 0xE7, +0xEB, 0xF6, 0x7B, 0x74, 0x6F, 0x6B, 0x66, 0x5E, 0x59, 0x55, 0x53, 0x52, 0x56, 0x59, 0x5C, 0x61, +0x5F, 0x64, 0x65, 0x62, 0x6F, 0x7B, 0xFC, 0xE4, 0xDC, 0xD9, 0xE2, 0x7E, 0xFF, 0xFE, 0xFF, 0xEE, +0xDF, 0xD8, 0xD6, 0xD7, 0xDB, 0xDD, 0xDD, 0xE8, 0xE7, 0xE3, 0xEA, 0xE7, 0xF9, 0x72, 0x7C, 0x5F, +0x56, 0x58, 0x58, 0x56, 0x57, 0x57, 0x53, 0x54, 0x4A, 0x42, 0x4F, 0x67, 0x6A, 0xE0, 0xD4, 0xD8, +0xD7, 0xDD, 0xFD, 0xFE, 0xE4, 0x7B, 0xFF, 0xD9, 0xDF, 0xDE, 0xD7, 0xDA, 0xCF, 0xCF, 0xD3, 0xCD, +0xD3, 0xDF, 0xDD, 0xDE, 0xF3, 0x6D, 0x5F, 0x55, 0x54, 0x55, 0x51, 0x51, 0x50, 0x4F, 0x51, 0x53, +0x57, 0x59, 0x60, 0x73, 0xFB, 0xE7, 0xE1, 0xEA, 0xF4, 0x7D, 0x6D, 0x6F, 0x7F, 0x78, 0xF5, 0xE7, +0xEA, 0xE0, 0xDE, 0xD9, 0xCD, 0xCB, 0xC5, 0xC2, 0xC5, 0xCB, 0xDB, 0xDD, 0xEC, 0x53, 0x4C, 0x45, +0x42, 0x49, 0x48, 0x49, 0x4D, 0x51, 0x5A, 0x55, 0x55, 0x5D, 0x64, 0xF4, 0xED, 0xF5, 0xEB, 0xF2, +0x7A, 0x6D, 0x60, 0x5E, 0x6E, 0xF3, 0xF7, 0xE9, 0xDF, 0xDD, 0xD4, 0xCD, 0xC8, 0xC1, 0xBC, 0xB8, +0xB5, 0xB8, 0xC7, 0xF5, 0x52, 0x3E, 0x38, 0x37, 0x36, 0x3D, 0x4B, 0x59, 0xFD, 0xDF, 0xE3, 0xFE, +0x5C, 0x54, 0x52, 0x4E, 0x50, 0x55, 0x5D, 0xFF, 0xF2, 0xF1, 0xE9, 0xFB, 0xFD, 0x74, 0x5E, 0x62, +0x7A, 0xE3, 0xD2, 0xCA, 0xC0, 0xB9, 0xB1, 0xAD, 0xAE, 0xBC, 0x68, 0x3E, 0x31, 0x2D, 0x2E, 0x30, +0x3B, 0x5B, 0xD4, 0xC7, 0xC9, 0xD6, 0x65, 0x4A, 0x46, 0x3E, 0x3D, 0x47, 0x51, 0x7F, 0xD5, 0xD0, +0xCE, 0xD2, 0xE2, 0x6E, 0x57, 0x55, 0x61, 0xEA, 0xCD, 0xBE, 0xB7, 0xB2, 0xAD, 0xAB, 0xB0, 0xCE, +0x40, 0x2F, 0x2B, 0x2D, 0x2F, 0x38, 0x59, 0xCA, 0xBD, 0xBE, 0xCF, 0x70, 0x45, 0x39, 0x3A, 0x3B, +0x3F, 0x5D, 0xD9, 0xCB, 0xC4, 0xC5, 0xCF, 0xEA, 0x62, 0x52, 0x50, 0x5C, 0x7E, 0xD1, 0xBE, 0xB5, +0xAF, 0xAE, 0xAB, 0xAC, 0xC2, 0x44, 0x2F, 0x2A, 0x2D, 0x32, 0x38, 0x55, 0xC6, 0xBA, 0xBC, 0xCF, +0x5B, 0x40, 0x36, 0x34, 0x38, 0x40, 0x66, 0xCD, 0xC4, 0xC2, 0xC6, 0xD1, 0xFE, 0x52, 0x4C, 0x4F, +0x5C, 0xEF, 0xCF, 0xC1, 0xB7, 0xAF, 0xAD, 0xAB, 0xAD, 0xC9, 0x3C, 0x2D, 0x29, 0x2D, 0x35, 0x3D, +0xF1, 0xBD, 0xB8, 0xBF, 0xE1, 0x4C, 0x3C, 0x32, 0x31, 0x39, 0x47, 0xF7, 0xCB, 0xC4, 0xC2, 0xC7, +0xD9, 0x6F, 0x54, 0x4D, 0x4F, 0x5D, 0xEF, 0xCF, 0xC1, 0xB8, 0xAF, 0xAD, 0xAB, 0xAC, 0xC9, 0x3A, +0x2C, 0x29, 0x2D, 0x37, 0x44, 0xD8, 0xB9, 0xB7, 0xC4, 0x6C, 0x44, 0x38, 0x31, 0x30, 0x39, 0x4E, +0xDF, 0xCA, 0xC5, 0xC6, 0xCD, 0xEF, 0x5E, 0x5A, 0x53, 0x55, 0x64, 0xE8, 0xCD, 0xC4, 0xBB, 0xB0, +0xAC, 0xAA, 0xAC, 0xD0, 0x36, 0x2C, 0x2B, 0x2E, 0x39, 0x4A, 0xCB, 0xB6, 0xB7, 0xC8, 0x5D, 0x43, +0x39, 0x31, 0x32, 0x3D, 0x58, 0xD9, 0xCD, 0xCA, 0xC9, 0xD6, 0x73, 0x62, 0x63, 0x62, 0x68, 0x72, +0xE9, 0xCE, 0xC6, 0xBB, 0xAF, 0xAD, 0xAB, 0xAE, 0xD7, 0x38, 0x2D, 0x2C, 0x2F, 0x3B, 0x4F, 0xCA, +0xB6, 0xB8, 0xCB, 0x5D, 0x41, 0x39, 0x32, 0x33, 0x3E, 0x59, 0xDC, 0xCF, 0xCD, 0xCB, 0xD8, 0x63, +0x53, 0x5A, 0x5E, 0x61, 0x6F, 0xEA, 0xCF, 0xC6, 0xBC, 0xB0, 0xAD, 0xAB, 0xAE, 0xEE, 0x32, 0x2C, +0x2C, 0x30, 0x3B, 0x50, 0xC9, 0xB6, 0xB9, 0xCF, 0x5D, 0x47, 0x3A, 0x32, 0x33, 0x3F, 0x63, 0xDB, +0xD5, 0xCC, 0xC8, 0xD7, 0x66, 0x56, 0x58, 0x5C, 0x5A, 0x5B, 0x7E, 0xCE, 0xC4, 0xBB, 0xB0, 0xAD, +0xAB, 0xAF, 0x7B, 0x2F, 0x2C, 0x2E, 0x31, 0x39, 0x52, 0xC6, 0xB6, 0xBA, 0xD1, 0x5C, 0x4E, 0x3E, +0x32, 0x33, 0x3F, 0x64, 0xEA, 0xFD, 0xCE, 0xC2, 0xD0, 0x6C, 0x57, 0x5D, 0x64, 0x56, 0x53, 0x6C, +0xCE, 0xC4, 0xBD, 0xB1, 0xAD, 0xAA, 0xAE, 0x6F, 0x31, 0x2F, 0x31, 0x31, 0x37, 0x4F, 0xC5, 0xB6, +0xBA, 0xD2, 0xFC, 0x60, 0x45, 0x36, 0x35, 0x41, 0x56, 0xF8, 0xF2, 0xE4, 0xC6, 0xC8, 0x7C, 0x5A, +0x6A, 0x6A, 0x57, 0x52, 0x5B, 0xDA, 0xC6, 0xC0, 0xB6, 0xAE, 0xAA, 0xAC, 0xDD, 0x33, 0x30, 0x35, +0x31, 0x30, 0x42, 0xCE, 0xBA, 0xBA, 0xCC, 0xD9, 0xD9, 0x53, 0x3A, 0x35, 0x3E, 0x4D, 0x52, 0x60, +0xD6, 0xC5, 0xD2, 0x71, 0xE7, 0x7C, 0x55, 0x53, 0x51, 0x5B, 0xEE, 0xDC, 0xD3, 0xBE, 0xB2, 0xB0, +0xAD, 0xAE, 0x67, 0x31, 0x38, 0x39, 0x2F, 0x32, 0x49, 0xD5, 0xBE, 0xBF, 0xCF, 0xCD, 0xCA, 0x5C, +0x3D, 0x3C, 0x41, 0x41, 0x47, 0x5D, 0xE1, 0xC9, 0xC7, 0xD4, 0xDD, 0xFC, 0x51, 0x4C, 0x4C, 0x4C, +0x5F, 0xE2, 0xDC, 0xCA, 0xBF, 0xBD, 0xB9, 0xB5, 0xAF, 0xBA, 0x43, 0x35, 0x44, 0x3E, 0x2F, 0x36, +0x53, 0xD4, 0xC8, 0xCC, 0xD1, 0xC3, 0xC5, 0x5E, 0x41, 0x45, 0x49, 0x42, 0x44, 0x55, 0xE9, 0xD0, +0xD1, 0xDA, 0xD6, 0xD7, 0xFD, 0x5A, 0x58, 0x5B, 0x5A, 0x5B, 0x5F, 0x6C, 0x7A, 0xE1, 0xD3, 0xD2, +0xCC, 0xC8, 0xC4, 0xBF, 0xBD, 0xBA, 0xC2, 0x49, 0x3C, 0x4C, 0x41, 0x35, 0x3B, 0x52, 0xF3, 0xD6, +0xD1, 0xCE, 0xC3, 0xC6, 0x7A, 0x53, 0x57, 0x4E, 0x44, 0x46, 0x4F, 0x64, 0xE8, 0xDF, 0xDD, 0xD4, +0xD6, 0xEC, 0x56, 0x49, 0x54, 0x5E, 0x4F, 0x57, 0xFA, 0xE1, 0xDC, 0xE0, 0xE3, 0xD6, 0xD0, 0xDC, +0xD9, 0xC9, 0xC2, 0xBD, 0xC5, 0x58, 0x50, 0xE6, 0x4B, 0x37, 0x3F, 0x4F, 0x4D, 0x52, 0x6D, 0xDD, +0xC8, 0xC8, 0xDC, 0xDC, 0xD1, 0x72, 0x4A, 0x4A, 0x4E, 0x4B, 0x4E, 0x57, 0x6A, 0xDF, 0xD7, 0xDB, +0xD5, 0xCF, 0xDA, 0xF4, 0x74, 0x67, 0x5E, 0x5E, 0x5E, 0x66, 0xF9, 0xED, 0xEC, 0xE8, 0xE4, 0xE8, +0xF4, 0xF7, 0x60, 0x52, 0x6D, 0xF3, 0x5B, 0x66, 0xE7, 0xE1, 0xE0, 0xDF, 0xDF, 0xD8, 0xD1, 0xEA, +0x6B, 0xD9, 0xD1, 0xE5, 0xE6, 0xCC, 0xC4, 0xE7, 0x52, 0xEA, 0xE4, 0x4C, 0x48, 0x59, 0x5D, 0x59, +0x5D, 0x60, 0xF7, 0xDF, 0x79, 0x6A, 0xDF, 0xDC, 0xFE, 0xF8, 0xE2, 0xF0, 0x6F, 0x6B, 0x61, 0x5F, +0x62, 0x5D, 0x5E, 0x6C, 0x76, 0x70, 0xF7, 0xE5, 0xE6, 0xE7, 0xE5, 0xEA, 0xF4, 0x7D, 0x6C, 0x66, +0x68, 0x66, 0x66, 0x73, 0xF8, 0xF3, 0xF4, 0xF6, 0xFB, 0x7E, 0x7A, 0x7E, 0xF6, 0xEF, 0xED, 0xE9, +0xE9, 0xEF, 0xFB, 0x78, 0x6E, 0x69, 0x64, 0x63, 0x68, 0x6E, 0x74, 0x7B, 0xFA, 0xF6, 0xF3, 0xFF, +0x6B, 0x69, 0x69, 0x60, 0x5F, 0x65, 0x6C, 0x73, 0x7C, 0xF3, 0xEB, 0xE9, 0xEA, 0xE8, 0xE6, 0xE6, +0xE7, 0xE4, 0xDE, 0xDD, 0xE2, 0xE2, 0xE1, 0xE9, 0xF8, 0x77, 0x6B, 0x62, 0x5D, 0x5B, 0x5A, 0x59, +0x5A, 0x5B, 0x5D, 0x5E, 0x5E, 0x5E, 0x5F, 0x62, 0x67, 0x6D, 0x78, 0xFA, 0xF2, 0xEE, 0xEF, 0xF3, +0xF7, 0xF8, 0xFA, 0xFE, 0xFA, 0xF3, 0xF1, 0xEF, 0xEA, 0xE7, 0xE5, 0xE6, 0xE9, 0xEF, 0xFB, 0x79, +0x70, 0x6C, 0x6A, 0x6C, 0x6F, 0x77, 0x7C, 0xFD, 0xFB, 0x7F, 0x73, 0x6C, 0x69, 0x69, 0x6C, 0x73, +0xFA, 0xED, 0xE9, 0xE5, 0xE1, 0xE4, 0xE8, 0xE8, 0xE7, 0xE7, 0xE5, 0xE2, 0xE0, 0xDD, 0xDC, 0xE1, +0xE3, 0xE2, 0xEC, 0x7C, 0x6C, 0x63, 0x5D, 0x5B, 0x59, 0x58, 0x5A, 0x5B, 0x5B, 0x5C, 0x5F, 0x60, +0x5F, 0x60, 0x65, 0x6A, 0x75, 0xF8, 0xEC, 0xE7, 0xE6, 0xE7, 0xEA, 0xF0, 0xF8, 0xF9, 0xF4, 0xED, +0xE9, 0xE5, 0xE3, 0xE3, 0xE6, 0xEB, 0xF6, 0x76, 0x6C, 0x67, 0x62, 0x5F, 0x61, 0x64, 0x69, 0x6F, +0x73, 0x73, 0x75, 0x75, 0x70, 0x6E, 0x6F, 0x6E, 0x6E, 0x75, 0xFE, 0xF3, 0xEC, 0xE9, 0xE9, 0xE9, +0xED, 0xFA, 0x7A, 0x74, 0x71, 0x72, 0x73, 0x74, 0x7A, 0xFF, 0xFF, 0x7B, 0x72, 0x6E, 0x6D, 0x6C, +0x6C, 0x6E, 0x73, 0x7C, 0xFC, 0xF7, 0xF0, 0xEB, 0xE6, 0xE0, 0xDD, 0xDB, 0xDB, 0xDB, 0xDC, 0xDF, +0xE2, 0xE3, 0xE8, 0xF2, 0x7D, 0x6C, 0x61, 0x5D, 0x5A, 0x58, 0x59, 0x5C, 0x5E, 0x61, 0x66, 0x69, +0x6A, 0x6B, 0x6C, 0x6B, 0x6C, 0x75, 0xFE, 0xF7, 0xEE, 0xEA, 0xE8, 0xE6, 0xE9, 0xEC, 0xEB, 0xEB, +0xEE, 0xF0, 0xF2, 0xF6, 0xF9, 0xFD, 0x7F, 0xFF, 0x7C, 0x74, 0x6D, 0x69, 0x66, 0x64, 0x64, 0x68, +0x6B, 0x6D, 0x75, 0x7D, 0xFC, 0xF8, 0xFA, 0xFC, 0xFA, 0xF7, 0xF5, 0xF0, 0xEB, 0xE6, 0xE4, 0xE5, +0xE9, 0xED, 0xF2, 0xFC, 0x7A, 0x74, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x6E, +0x6D, 0x6E, 0x70, 0x71, 0x74, 0x79, 0x7B, 0x7E, 0xFB, 0xF6, 0xF8, 0xF9, 0xF6, 0xF5, 0xF8, 0xFA, +0xF7, 0xF0, 0xEE, 0xF0, 0xF7, 0xFC, 0x7D, 0x73, 0x6C, 0x6B, 0x6B, 0x6A, 0x6B, 0x6B, 0x6B, 0x6B, +0x6C, 0x6D, 0x6D, 0x6E, 0x71, 0x71, 0x71, 0x72, 0x77, 0x7D, 0xFC, 0xF7, 0xF3, 0xED, 0xEB, 0xEB, +0xEE, 0xF4, 0xF9, 0xFE, 0x79, 0x77, 0x7B, 0x7F, 0x7F, 0xFF, 0xFF, 0x7B, 0x77, 0x76, 0x77, 0x79, +0x79, 0x7A, 0x7C, 0xFF, 0xFC, 0xFC, 0xFA, 0xF8, 0xF9, 0xF9, 0xFA, 0xFD, 0xFE, 0xFD, 0xFA, 0xF8, +0xF5, 0xF2, 0xF1, 0xF2, 0xF4, 0xF8, 0xFE, 0x7C, 0x79, 0x77, 0x77, 0x7A, 0x7E, 0x7F, 0x7C, 0x79, +0x78, 0x75, 0x73, 0x72, 0x71, 0x73, 0x75, 0x76, 0x78, 0x7D, 0xFD, 0xFB, 0xFC, 0xFF, 0x7D, 0x79, +0x76, 0x76, 0x77, 0x7C, 0xFB, 0xF5, 0xF3, 0xF3, 0xF3, 0xF7, 0x7D, 0x74, 0x6F, 0x6D, 0x6B, 0x6C, +0x6E, 0x73, 0x77, 0x77, 0x77, 0x7A, 0x7A, 0x76, 0x73, 0x72, 0x6F, 0x6D, 0x6B, 0x6C, 0x6F, 0x76, +0x7A, 0x7D, 0xFE, 0xFC, 0x7E, 0x7A, 0x75, 0x71, 0x6E, 0x6D, 0x6E, 0x71, 0x77, 0x7D, 0xFE, 0xFC, +0xFC, 0xFE, 0xFF, 0x7D, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFC, 0xF9, 0xF7, 0xF6, 0xF8, 0xFA, 0xFC, +0xFF, 0x7E, 0x7F, 0xFF, 0xFD, 0xFB, 0xF7, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFD, 0x7D, 0x7A, 0x7A, +0x7D, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFD, 0xFD, +0xFB, 0xF8, 0xF7, 0xF9, 0xFD, 0x7C, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x75, 0x75, 0x75, 0x75, +0x75, 0x74, 0x76, 0x78, 0x79, 0x7B, 0x7D, 0x7F, 0xFD, 0xFB, 0xFF, 0x7A, 0x79, 0x7D, 0xFE, 0xFD, +0xFD, 0xFC, 0xFD, 0xFA, 0xF5, 0xF2, 0xF3, 0xF6, 0xF8, 0xF9, 0xFC, 0xFF, 0xFD, 0xF8, 0xF5, 0xF5, +0xF6, 0xFA, 0xFC, 0xFD, 0x7F, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x77, 0x7B, 0x7E, 0x7E, 0x7E, 0x7F, +0x7E, 0x7C, 0x79, 0x76, 0x76, 0x78, 0x79, 0x78, 0x7B, 0x7E, 0xFF, 0x7F, 0x7C, 0x7A, 0x78, 0x75, +0x73, 0x73, 0x74, 0x76, 0x77, 0x78, 0x7B, 0x7B, 0x79, 0x79, 0x78, 0x77, 0x78, 0x74, 0x71, 0x72, +0x73, 0x76, 0x77, 0x77, 0x79, 0x79, 0x77, 0x76, 0x75, 0x76, 0x78, 0x7B, 0x7F, 0xFC, 0xFB, 0xFB, +0xFA, 0xFB, 0xFE, 0x7C, 0x79, 0x79, 0x78, 0x78, 0x7B, 0xFF, 0xFD, 0xFD, 0xFC, 0xFC, 0xFE, 0x7E, +0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7B, 0x77, 0x78, 0x7A, +0x7A, 0x7A, 0x7C, 0x7E, 0xFF, 0x7F, 0x7F, 0xFF, 0xFF, 0x7F, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, +0x79, 0x79, 0x7B, 0x7E, 0x7E, 0x7F, 0xFD, 0xFC, 0xFD, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, +0xFF, 0x7E, 0x7D, 0x7F, 0xFF, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFE, 0x7E, 0x7F, 0x7E, 0x7B, +0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x77, 0x7A, +0x7C, 0x7D, 0x7E, 0x7E, 0x7C, 0x79, 0x76, 0x77, 0x79, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, +0x7D, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7B, 0x7C, +0x7C, 0x7C, 0x7D, 0xFF, 0xFC, 0xFB, 0xFB, 0xFC, 0xFF, 0x7C, 0x79, 0x77, 0x74, 0x75, 0x77, 0x7A, +0x7D, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7B, 0x7A, 0x7B, 0x7D, 0x7E, 0xFE, 0xFD, +0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x78, 0x76, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7C, +0x7A, 0x79, 0x78, 0x78, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7B, 0x7A, +0x7B, 0x7C, 0x7D, 0xFE, 0xFC, 0xFA, 0xF9, 0xFA, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFA, 0xF8, 0xF7, +0xF6, 0xF7, 0xF9, 0xFB, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x79, 0x7B, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, +0x7E, 0x7C, 0x7B, 0x79, 0x7A, 0x7C, 0x7C, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7E, 0x7C, 0x7B, 0x79, +0x77, 0x76, 0x76, 0x78, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7B, +0x7D, 0x79, 0x79, 0x7E, 0x79, 0x78, 0x79, 0x78, 0x7A, 0x78, 0x7D, 0x7D, 0x7C, 0xFF, 0x7D, 0x7F, +0x7E, 0x7B, 0x7A, 0x76, 0x79, 0x76, 0x78, 0x7B, 0x79, 0xFF, 0x7D, 0xFB, 0xFD, 0x7D, 0xF9, 0x7B, +0xFF, 0x79, 0x75, 0xFF, 0x6E, 0x7F, 0x71, 0x73, 0x79, 0x51, 0x60, 0xE2, 0x6F, 0x7D, 0xF7, 0xF5, +0x77, 0x72, 0xE4, 0x50, 0x4C, 0xDE, 0xFB, 0x66, 0xE5, 0xF6, 0x6F, 0x6C, 0xE7, 0xDC, 0x6E, 0xFD, +0xE6, 0x7E, 0xE9, 0x77, 0x62, 0xE3, 0xE9, 0x6C, 0x71, 0xEA, 0xDE, 0x75, 0x7E, 0xE8, 0x75, 0xF8, +0x7A, 0xFC, 0xF2, 0x65, 0xF8, 0xEE, 0xF9, 0xF4, 0x73, 0xE4, 0xF9, 0x6E, 0xE5, 0x75, 0x67, 0x5A, +0x50, 0x57, 0x5A, 0x7D, 0x6C, 0x64, 0xDA, 0xED, 0x64, 0xEA, 0xE9, 0xF5, 0x7E, 0x6F, 0xFC, 0xF2, +0x66, 0x63, 0xF7, 0x7D, 0x78, 0xF6, 0xF8, 0xE1, 0xE2, 0xF9, 0xEB, 0xE4, 0xED, 0xFE, 0xFA, 0xF6, +0xF1, 0xF2, 0x6F, 0xFE, 0xE8, 0xFF, 0x7F, 0xEA, 0xE8, 0xED, 0xEE, 0xEA, 0xEB, 0xED, 0xF8, 0xEF, +0xE8, 0x7F, 0xF5, 0xE6, 0xF7, 0xF2, 0xF3, 0xF2, 0xDF, 0xEB, 0xF5, 0xE3, 0xEC, 0xF2, 0xEF, 0xFC, +0xED, 0xEF, 0xFD, 0xED, 0xF0, 0x7C, 0x77, 0xFE, 0xF1, 0x77, 0x79, 0xEF, 0xF6, 0xF8, 0xFB, 0x72, +0x75, 0x79, 0x78, 0x70, 0x6E, 0x7C, 0x7D, 0x74, 0x79, 0x77, 0x6E, 0x71, 0x7D, 0x6F, 0x6B, 0x7D, +0xFE, 0x76, 0x7A, 0x7D, 0x7F, 0x75, 0x6C, 0x7B, 0xF7, 0x7A, 0x7B, 0x7E, 0x74, 0x79, 0x75, 0x70, +0x7C, 0x79, 0xFD, 0xF6, 0x6E, 0x6E, 0x7B, 0x6B, 0x67, 0x6D, 0x6E, 0x6A, 0x67, 0x6A, 0x6D, 0x6F, +0x6B, 0x67, 0x6D, 0x6C, 0x65, 0x63, 0x5E, 0x65, 0x6A, 0x5F, 0x68, 0x6C, 0x60, 0x6C, 0x7D, 0x6D, +0x6E, 0x7D, 0x7C, 0xFF, 0xEE, 0xEB, 0xEC, 0xE3, 0xDE, 0xE1, 0xE4, 0xE0, 0xE8, 0xF8, 0xEE, 0xFA, +0x6D, 0x69, 0x5C, 0x58, 0x59, 0x53, 0x50, 0x4E, 0x4D, 0x4E, 0x4F, 0x4F, 0x53, 0x51, 0x51, 0x54, +0x55, 0x56, 0x5A, 0x5E, 0x69, 0xF7, 0xE2, 0xD8, 0xCF, 0xCE, 0xCD, 0xCC, 0xCE, 0xCE, 0xCA, 0xC7, +0xC2, 0xBF, 0xBE, 0xBD, 0xC2, 0xD5, 0xF1, 0x62, 0x4B, 0x3F, 0x3D, 0x3D, 0x3E, 0x40, 0x42, 0x4A, +0x51, 0x51, 0x51, 0x55, 0x56, 0x4F, 0x4D, 0x4E, 0x50, 0x52, 0x55, 0x5C, 0x69, 0xFA, 0xE4, 0xD9, +0xCD, 0xC9, 0xC5, 0xC1, 0xBF, 0xBB, 0xBB, 0xBD, 0xB9, 0xB7, 0xB5, 0xB7, 0xC8, 0xDD, 0x61, 0x43, +0x3C, 0x38, 0x38, 0x3D, 0x40, 0x46, 0x4E, 0x5A, 0x60, 0x5D, 0x5B, 0x5B, 0x5A, 0x58, 0x56, 0x58, +0x5C, 0x5E, 0x5E, 0x64, 0x6B, 0x6D, 0xF9, 0xED, 0xE5, 0xDC, 0xD9, 0xD2, 0xCC, 0xC5, 0xBF, 0xBF, +0xBA, 0xB7, 0xB6, 0xB1, 0xB7, 0xCB, 0xFA, 0x49, 0x3A, 0x35, 0x31, 0x33, 0x3A, 0x42, 0x4C, 0x5C, +0xFD, 0xE1, 0xEE, 0x68, 0x66, 0x5C, 0x51, 0x4F, 0x4D, 0x55, 0x5F, 0x5D, 0x64, 0x71, 0xFA, 0xED, +0xEF, 0xEB, 0xDE, 0xD3, 0xCC, 0xC3, 0xBE, 0xBD, 0xB9, 0xB8, 0xB5, 0xAF, 0xB7, 0xCC, 0x60, 0x3F, +0x39, 0x34, 0x2F, 0x31, 0x3A, 0x47, 0x56, 0x6F, 0xE3, 0xDA, 0xD5, 0xEC, 0x56, 0x50, 0x4E, 0x4B, +0x4B, 0x4C, 0x57, 0x7B, 0xE7, 0xE0, 0xDC, 0xD5, 0xD6, 0xDE, 0xEC, 0xEF, 0xDE, 0xD7, 0xCC, 0xC1, +0xBD, 0xB8, 0xB5, 0xB4, 0xB0, 0xB6, 0xCB, 0x58, 0x3E, 0x38, 0x34, 0x2F, 0x2F, 0x38, 0x45, 0x59, +0x7D, 0xDD, 0xD1, 0xCE, 0xDD, 0x63, 0x53, 0x4E, 0x4C, 0x4A, 0x4B, 0x53, 0x69, 0xE7, 0xDB, 0xD5, +0xD0, 0xCE, 0xD3, 0xDC, 0xE4, 0xEA, 0xE8, 0xE2, 0xD5, 0xC8, 0xC0, 0xBB, 0xB8, 0xB5, 0xB2, 0xB9, +0xD1, 0x54, 0x40, 0x3A, 0x34, 0x2F, 0x2F, 0x36, 0x3F, 0x4C, 0x5B, 0x7E, 0xDE, 0xD4, 0xDB, 0xFF, +0x62, 0x58, 0x55, 0x53, 0x4F, 0x52, 0x5D, 0x6F, 0xF0, 0xE4, 0xDE, 0xDA, 0xD8, 0xDC, 0xE1, 0xE5, +0xDF, 0xDC, 0xD6, 0xCC, 0xC6, 0xC1, 0xBE, 0xBB, 0xB8, 0xBC, 0xCE, 0x67, 0x4B, 0x44, 0x3E, 0x38, +0x35, 0x37, 0x3D, 0x45, 0x4B, 0x53, 0x61, 0xFA, 0xE4, 0xEC, 0x7F, 0x79, 0x78, 0x79, 0x70, 0x68, +0x68, 0x70, 0x7B, 0x7D, 0x7D, 0xF9, 0xEE, 0xEA, 0xE8, 0xE6, 0xE1, 0xDB, 0xD6, 0xCF, 0xCB, 0xC8, +0xC5, 0xC1, 0xBE, 0xBF, 0xC7, 0xD5, 0xF9, 0x5F, 0x55, 0x4A, 0x42, 0x3E, 0x3E, 0x41, 0x45, 0x48, +0x4C, 0x56, 0x5F, 0x6F, 0xF8, 0xEF, 0xE7, 0xE4, 0xE6, 0xE2, 0xEA, 0xF5, 0xFD, 0x75, 0x75, 0x79, +0x75, 0x76, 0x7E, 0xFA, 0xF1, 0xE9, 0xE0, 0xDA, 0xD3, 0xCF, 0xCC, 0xCA, 0xC7, 0xC4, 0xC5, 0xCC, +0xD3, 0xDF, 0xFF, 0x69, 0x58, 0x4C, 0x47, 0x43, 0x42, 0x42, 0x43, 0x46, 0x4C, 0x55, 0x59, 0x62, +0x77, 0xFD, 0xEE, 0xEC, 0xF3, 0xEC, 0xF2, 0x76, 0x76, 0x6F, 0x6E, 0x79, 0x79, 0x7F, 0xF3, 0xED, +0xE4, 0xDD, 0xDB, 0xD7, 0xD3, 0xD0, 0xCE, 0xCC, 0xCB, 0xCA, 0xCC, 0xD1, 0xD6, 0xDD, 0xEA, 0x7E, +0x62, 0x56, 0x4F, 0x4C, 0x49, 0x48, 0x49, 0x4C, 0x50, 0x56, 0x58, 0x5C, 0x67, 0x6F, 0x6C, 0x6E, +0x6D, 0x6A, 0x6F, 0x6D, 0x6B, 0x6E, 0x6D, 0x76, 0xFA, 0xF9, 0xF1, 0xEB, 0xE7, 0xE1, 0xDE, 0xDD, +0xDB, 0xD8, 0xD7, 0xD4, 0xD2, 0xD0, 0xCF, 0xD4, 0xD8, 0xDA, 0xDF, 0xEA, 0xF8, 0x6D, 0x60, 0x5C, +0x58, 0x56, 0x56, 0x56, 0x57, 0x59, 0x5B, 0x5B, 0x5A, 0x5C, 0x5F, 0x5F, 0x5F, 0x63, 0x66, 0x6B, +0x72, 0x77, 0x7E, 0xF7, 0xF0, 0xEC, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xEA, 0xE7, 0xE6, 0xE5, +0xE3, 0xE1, 0xDD, 0xDA, 0xD9, 0xD8, 0xDD, 0xDF, 0xDD, 0xE0, 0xE7, 0xEE, 0xFE, 0x74, 0x6C, 0x62, +0x5C, 0x59, 0x56, 0x54, 0x52, 0x51, 0x51, 0x52, 0x55, 0x58, 0x59, 0x5D, 0x62, 0x68, 0x70, 0x75, +0x7D, 0xF9, 0xF8, 0xF4, 0xF5, 0xF9, 0xF5, 0xF3, 0xF3, 0xF2, 0xF2, 0xEF, 0xED, 0xEB, 0xEA, 0xE6, +0xE3, 0xE0, 0xDC, 0xDA, 0xD7, 0xD8, 0xDB, 0xDB, 0xDA, 0xDC, 0xDF, 0xE8, 0xF6, 0x7F, 0x6E, 0x60, +0x5B, 0x58, 0x56, 0x54, 0x53, 0x52, 0x53, 0x59, 0x5C, 0x5E, 0x63, 0x68, 0x6F, 0x7B, 0x7C, 0xFF, +0xFC, 0xFC, 0xFB, 0xFC, 0xFD, 0xF8, 0xF7, 0xF6, 0xF4, 0xF5, 0xF3, 0xF0, 0xEF, 0xED, 0xEB, 0xE8, +0xE4, 0xE0, 0xDD, 0xDA, 0xD9, 0xDA, 0xDC, 0xDC, 0xDC, 0xE0, 0xE9, 0xF8, 0x76, 0x6B, 0x61, 0x5C, +0x5A, 0x5A, 0x5A, 0x5B, 0x5C, 0x5E, 0x62, 0x67, 0x6B, 0x6D, 0x6F, 0x72, 0x75, 0x76, 0x76, 0x75, +0x74, 0x79, 0x7E, 0x7B, 0x78, 0x7D, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF5, 0xF2, 0xEF, 0xEC, 0xE9, +0xE4, 0xDF, 0xDE, 0xDE, 0xE0, 0xE7, 0xEA, 0xEC, 0xF2, 0xFE, 0x76, 0x6F, 0x6F, 0x6D, 0x6A, 0x6A, +0x6B, 0x6C, 0x6C, 0x69, 0x67, 0x67, 0x66, 0x65, 0x64, 0x64, 0x65, 0x66, 0x67, 0x69, 0x6B, 0x6E, +0x71, 0x76, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF4, 0xF0, 0xEE, 0xEC, 0xEA, 0xE9, 0xE8, 0xE9, +0xEB, 0xEB, 0xEC, 0xED, 0xEE, 0xED, 0xEB, 0xE9, 0xEA, 0xE9, 0xE9, 0xEA, 0xEC, 0xF0, 0xF6, 0xFD, +0x78, 0x71, 0x6D, 0x69, 0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x66, 0x66, 0x67, 0x67, 0x66, 0x66, +0x69, 0x6B, 0x6D, 0x73, 0x7A, 0xFE, 0xF7, 0xF3, 0xEF, 0xEE, 0xEE, 0xEC, 0xEB, 0xEA, 0xE8, 0xE7, +0xE5, 0xE3, 0xE1, 0xE1, 0xE1, 0xE3, 0xE6, 0xE8, 0xEB, 0xEF, 0xF8, 0x7E, 0x75, 0x6F, 0x6B, 0x69, +0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, +0x70, 0x6F, 0x6F, 0x6F, 0x72, 0x75, 0x79, 0xFF, 0xFB, 0xF6, 0xF2, 0xEF, 0xEE, 0xED, 0xEE, 0xF0, +0xF3, 0xF6, 0xF8, 0xFC, 0xFF, 0x7D, 0x79, 0x76, 0x72, 0x6E, 0x6D, 0x6B, 0x6B, 0x6C, 0x6C, 0x6D, +0x6E, 0x71, 0x76, 0x7B, 0xFF, 0xFE, 0xFD, 0xFC, 0xFD, 0x7F, 0x7B, 0x78, 0x75, 0x74, 0x75, 0x77, +0x7A, 0x7E, 0xFC, 0xF9, 0xF6, 0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xF8, 0xF7, 0xF6, 0xF5, 0xF5, +0xF6, 0xF8, 0xFA, 0xFC, 0x7F, 0x7B, 0x79, 0x78, 0x77, 0x77, 0x79, 0x7D, 0xFD, 0xF9, 0xF4, 0xF2, +0xF1, 0xF1, 0xF3, 0xF5, 0xFA, 0xFE, 0x7F, 0xFF, 0xFD, 0xFC, 0xFB, 0xF7, 0xF5, 0xF4, 0xF4, 0xF6, +0xF8, 0xFB, 0xFD, 0xFF, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7B, 0x79, 0x77, +0x76, 0x75, 0x74, 0x74, 0x75, 0x78, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0x7E, 0x7C, 0x7B, 0x79, +0x79, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xF9, 0xFB, 0xFD, 0x7F, 0x7B, 0x78, 0x76, 0x75, +0x74, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x7A, 0x7C, +0x7E, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x78, 0x77, 0x77, 0x76, 0x79, 0x7B, 0x7E, 0xFF, +0xFE, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7C, 0x7B, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x74, 0x74, +0x74, 0x74, 0x75, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFC, 0xF8, 0xF7, 0xF6, 0xF7, 0xF7, 0xF7, 0xF9, +0xFC, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7F, 0xFF, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, +0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xFA, 0xFD, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7D, 0x7E, 0xFE, +0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF9, 0xF9, 0xFA, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x79, 0x77, 0x75, +0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x71, 0x70, 0x71, 0x72, 0x71, 0x72, 0x71, 0x72, 0x73, 0x72, +0x72, 0x71, 0x71, 0x71, 0x72, 0x74, 0x74, 0x76, 0x77, 0x77, 0x77, 0x78, 0x77, 0x78, 0x78, 0x78, +0x7A, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, +0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7C, 0x7E, 0xFF, 0xFD, +0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7D, +0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, +0xFF, 0xFF, 0xFF, 0xFD, 0xFA, 0xF9, 0xF7, 0xF5, 0xF4, 0xF3, 0xF1, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, +0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFE, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, +0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7A, 0x7D, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, +0x77, 0x76, 0x75, 0x76, 0x75, 0x74, 0x74, 0x75, 0x74, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, 0x74, +0x72, 0x70, 0x70, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x70, 0x70, 0x70, 0x71, 0x72, 0x73, 0x73, 0x76, +0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7F, 0x7D, 0x7C, 0x7B, 0x7B, 0x7C, +0x7B, 0x7B, 0x7A, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0xFF, 0x7D, 0x7E, 0x7C, 0x7C, 0x7B, 0x78, +0x7C, 0x7A, 0x7C, 0x7D, 0x7B, 0x7E, 0x7C, 0x7F, 0x7D, 0x7A, 0x7E, 0x78, 0x7B, 0x6F, 0x68, 0x5C, +0x4C, 0x58, 0xDD, 0xE1, 0xEB, 0xE1, 0xE9, 0xEF, 0xF8, 0xE9, 0xE1, 0xED, 0xF9, 0xFC, 0xF2, 0xED, +0x7D, 0x76, 0xFB, 0xF9, 0x7C, 0x70, 0x6F, 0x78, 0x79, 0x6D, 0x6D, 0x76, 0x7D, 0xFE, 0x7A, 0x79, +0xFC, 0xFD, 0xFD, 0xFA, 0xFB, 0xFA, 0xFC, 0xFF, 0xFC, 0xFC, 0xFE, 0xFD, 0xFE, 0xFB, 0xFB, 0xFE, +0xFE, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x78, 0x7D, 0x7D, 0xFF, 0xFA, 0xFF, 0xF9, 0xF9, 0xFA, 0xF7, +0x7F, 0xF9, 0x7A, 0x7A, 0x6F, 0x51, 0x52, 0x6E, 0x71, 0xF1, 0xD8, 0xD3, 0xDB, 0xEF, 0xE2, 0xDB, +0xED, 0xF6, 0xF3, 0xEF, 0xF4, 0x6A, 0x74, 0x73, 0x57, 0x5E, 0x77, 0x6E, 0xFD, 0xF4, 0xFC, 0x7D, +0x73, 0xE9, 0xDE, 0xE2, 0xDE, 0xE3, 0xE5, 0xE8, 0xFA, 0xF7, 0xFA, 0x6F, 0x6C, 0x6A, 0x6B, 0x6A, +0x66, 0x6B, 0x75, 0x70, 0x74, 0xFA, 0xFB, 0xFD, 0xF8, 0xF3, 0xF2, 0xFB, 0xF5, 0xED, 0xEF, 0xEB, +0xE5, 0xDF, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD4, 0xD8, 0xE0, 0xEE, 0x76, 0x5D, 0x53, 0x4D, 0x49, +0x46, 0x43, 0x42, 0x43, 0x43, 0x45, 0x48, 0x4B, 0x4F, 0x57, 0x60, 0x6D, 0xF7, 0xE3, 0xDB, 0xD4, +0xCF, 0xCB, 0xC8, 0xC4, 0xBE, 0xBC, 0xB9, 0xB4, 0xB6, 0xBC, 0xC1, 0xC3, 0xD5, 0x4F, 0x4B, 0x43, +0x36, 0x33, 0x34, 0x32, 0x31, 0x36, 0x3B, 0x3F, 0x48, 0x60, 0xDF, 0xD2, 0xC9, 0xC1, 0xC3, 0xC6, +0xC7, 0xCF, 0xE3, 0x67, 0x56, 0x47, 0x3E, 0x3F, 0x3C, 0x3B, 0x43, 0x48, 0x4F, 0xFA, 0xD5, 0xC5, +0xBD, 0xB7, 0xB1, 0xAE, 0xAC, 0xAE, 0xB1, 0xB5, 0xC0, 0xD7, 0x5D, 0x40, 0x38, 0x31, 0x2E, 0x2D, +0x2C, 0x2E, 0x32, 0x37, 0x3F, 0x4F, 0xF8, 0xD0, 0xC4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBE, 0xC7, 0xD0, +0xF1, 0x56, 0x48, 0x40, 0x3D, 0x3B, 0x3D, 0x42, 0x49, 0x63, 0xDA, 0xCB, 0xBC, 0xB6, 0xB0, 0xAE, +0xAF, 0xAF, 0xB4, 0xBC, 0xC6, 0xFE, 0x4C, 0x3E, 0x34, 0x30, 0x2E, 0x2D, 0x2E, 0x30, 0x35, 0x3C, +0x46, 0x62, 0xDE, 0xCA, 0xBE, 0xBD, 0xBB, 0xBA, 0xBD, 0xC3, 0xCB, 0xDC, 0x6B, 0x59, 0x51, 0x52, +0x60, 0xFF, 0xD5, 0xC4, 0xBE, 0xBC, 0xBA, 0xB9, 0xBB, 0xC3, 0xC8, 0xD6, 0x5A, 0x4C, 0x42, 0x39, +0x36, 0x35, 0x32, 0x34, 0x36, 0x39, 0x41, 0x47, 0x58, 0xE0, 0xDA, 0xC9, 0xC1, 0xC4, 0xC0, 0xC0, +0xC6, 0xCA, 0xD1, 0xDC, 0xF3, 0x6E, 0xFC, 0xE8, 0xDB, 0xCB, 0xC2, 0xBE, 0xBD, 0xBE, 0xBD, 0xC0, +0xCD, 0xCE, 0xEC, 0x4E, 0x4C, 0x40, 0x38, 0x39, 0x37, 0x35, 0x38, 0x38, 0x3B, 0x43, 0x49, 0x54, +0xEA, 0xDB, 0xCE, 0xC5, 0xC5, 0xC3, 0xC1, 0xC7, 0xCA, 0xCF, 0xDB, 0xE9, 0xFD, 0xF7, 0xE9, 0xDD, +0xCE, 0xC6, 0xC1, 0xBF, 0xC0, 0xBF, 0xC3, 0xCF, 0xD0, 0xE6, 0x51, 0x4E, 0x43, 0x3A, 0x3B, 0x38, +0x35, 0x38, 0x38, 0x3A, 0x3F, 0x44, 0x4E, 0x5F, 0xEF, 0xD7, 0xCD, 0xC8, 0xC6, 0xC4, 0xC6, 0xC9, +0xCC, 0xD4, 0xDD, 0xE6, 0xE1, 0xDA, 0xD7, 0xCA, 0xC3, 0xC4, 0xC4, 0xC1, 0xC3, 0xCC, 0xCF, 0xD8, +0x60, 0x54, 0x4E, 0x3F, 0x3D, 0x3D, 0x39, 0x3A, 0x3C, 0x3B, 0x3D, 0x47, 0x48, 0x51, 0x79, 0xFA, +0xDD, 0xCD, 0xCF, 0xCC, 0xC8, 0xCD, 0xCE, 0xCE, 0xD7, 0xDC, 0xDC, 0xD7, 0xD4, 0xCC, 0xC3, 0xC1, +0xBF, 0xBF, 0xC2, 0xC1, 0xCE, 0xDB, 0xDD, 0x54, 0x4C, 0x49, 0x3C, 0x3B, 0x3B, 0x38, 0x3A, 0x3B, +0x3C, 0x3E, 0x48, 0x4C, 0x55, 0xF3, 0xEC, 0xDB, 0xCD, 0xD1, 0xCD, 0xCB, 0xD2, 0xD1, 0xD6, 0xDD, +0xE1, 0xE2, 0xD7, 0xD3, 0xCA, 0xC0, 0xBE, 0xBE, 0xBF, 0xBE, 0xC1, 0xCF, 0xD0, 0xED, 0x4E, 0x4D, +0x41, 0x3A, 0x3A, 0x37, 0x35, 0x38, 0x3A, 0x3A, 0x3F, 0x49, 0x4A, 0x62, 0xE7, 0xEA, 0xCE, 0xCB, +0xCF, 0xC8, 0xCB, 0xD1, 0xCF, 0xD7, 0xE2, 0xE5, 0xE5, 0xDF, 0xD5, 0xCC, 0xC5, 0xBE, 0xBE, 0xC0, +0xBC, 0xC0, 0xCD, 0xC8, 0xDC, 0x58, 0x5B, 0x47, 0x3C, 0x3D, 0x39, 0x36, 0x39, 0x3A, 0x39, 0x3E, +0x47, 0x49, 0x59, 0xEA, 0xEC, 0xD0, 0xC9, 0xCD, 0xC7, 0xC8, 0xCE, 0xCD, 0xD2, 0xDC, 0xDF, 0xDF, +0xDD, 0xD6, 0xCB, 0xC6, 0xBF, 0xBF, 0xC4, 0xBD, 0xC4, 0xD1, 0xC9, 0xEF, 0x55, 0x5D, 0x43, 0x3D, +0x3E, 0x38, 0x37, 0x3A, 0x3A, 0x3A, 0x3E, 0x45, 0x48, 0x56, 0x74, 0xF8, 0xD8, 0xCF, 0xD0, 0xCB, +0xCB, 0xCE, 0xCE, 0xD2, 0xD9, 0xDC, 0xDC, 0xD7, 0xD3, 0xCA, 0xC4, 0xC0, 0xBF, 0xC2, 0xBE, 0xC3, +0xCF, 0xCB, 0xE5, 0x58, 0x5C, 0x45, 0x3D, 0x3E, 0x39, 0x37, 0x39, 0x3A, 0x3A, 0x3D, 0x45, 0x46, +0x52, 0x79, 0x73, 0xD7, 0xCD, 0xD1, 0xC8, 0xC8, 0xCD, 0xCA, 0xCF, 0xD5, 0xD7, 0xDC, 0xDA, 0xD4, +0xCD, 0xC7, 0xC1, 0xC0, 0xC5, 0xBF, 0xC2, 0xD1, 0xCA, 0xDA, 0x5A, 0x68, 0x4C, 0x3E, 0x42, 0x3B, +0x38, 0x3B, 0x3A, 0x3A, 0x3D, 0x42, 0x44, 0x4B, 0x62, 0x66, 0xF1, 0xD0, 0xD6, 0xCD, 0xC8, 0xCE, +0xCA, 0xCB, 0xD1, 0xCF, 0xD2, 0xD2, 0xCE, 0xC9, 0xC5, 0xC1, 0xBF, 0xC5, 0xC1, 0xC0, 0xD3, 0xCE, +0xD6, 0x57, 0x5F, 0x4E, 0x3E, 0x41, 0x3D, 0x39, 0x3B, 0x3B, 0x3A, 0x3D, 0x42, 0x44, 0x4C, 0x5A, +0x5E, 0xEC, 0xDD, 0xDC, 0xCE, 0xD0, 0xD1, 0xCD, 0xD4, 0xD4, 0xD4, 0xDA, 0xD3, 0xCE, 0xCB, 0xC4, +0xBF, 0xBE, 0xC2, 0xBE, 0xBF, 0xCD, 0xCB, 0xD5, 0x5B, 0x5F, 0x4D, 0x3E, 0x3F, 0x3B, 0x37, 0x39, +0x3A, 0x39, 0x3C, 0x3F, 0x42, 0x4B, 0x59, 0x61, 0xEA, 0xDA, 0xD6, 0xCD, 0xCD, 0xCE, 0xCD, 0xCF, +0xD3, 0xD6, 0xDA, 0xD7, 0xD2, 0xCE, 0xC7, 0xC2, 0xBF, 0xC0, 0xC1, 0xBE, 0xC8, 0xCE, 0xCB, 0x79, +0x5A, 0x5C, 0x41, 0x3F, 0x3E, 0x38, 0x39, 0x3A, 0x39, 0x3A, 0x3E, 0x42, 0x45, 0x51, 0x62, 0x65, +0xDD, 0xD5, 0xD7, 0xCA, 0xCC, 0xCE, 0xCA, 0xCE, 0xD0, 0xCF, 0xCF, 0xCD, 0xC9, 0xC4, 0xBF, 0xBD, +0xBE, 0xBF, 0xBD, 0xC5, 0xCE, 0xCB, 0xF8, 0x58, 0x5B, 0x43, 0x3E, 0x3E, 0x39, 0x38, 0x3A, 0x39, +0x3A, 0x3E, 0x44, 0x45, 0x51, 0x6E, 0x69, 0xDC, 0xCF, 0xD7, 0xCA, 0xCB, 0xD0, 0xCC, 0xD1, 0xD5, +0xD5, 0xD5, 0xCF, 0xCB, 0xC5, 0xBF, 0xBC, 0xBD, 0xBF, 0xBB, 0xC3, 0xCC, 0xC8, 0xEF, 0x5B, 0x5D, +0x41, 0x3D, 0x3D, 0x37, 0x37, 0x38, 0x37, 0x38, 0x3B, 0x41, 0x43, 0x4E, 0x6B, 0x67, 0xDC, 0xCE, +0xD4, 0xC9, 0xC8, 0xCE, 0xCA, 0xCE, 0xD5, 0xD4, 0xD5, 0xD3, 0xCE, 0xC7, 0xC3, 0xBE, 0xBE, 0xC3, +0xBD, 0xC2, 0xD0, 0xC9, 0xDE, 0x57, 0x61, 0x47, 0x3D, 0x3F, 0x39, 0x36, 0x38, 0x38, 0x38, 0x3A, +0x41, 0x40, 0x48, 0x6A, 0x5C, 0xF7, 0xCD, 0xDB, 0xCD, 0xC6, 0xD1, 0xCC, 0xCC, 0xD6, 0xD5, 0xD3, +0xCF, 0xCE, 0xC6, 0xC0, 0xBF, 0xBE, 0xBF, 0xBE, 0xC0, 0xCC, 0xCB, 0xDB, 0x5D, 0x5B, 0x49, 0x3E, +0x3E, 0x39, 0x37, 0x38, 0x38, 0x38, 0x3B, 0x40, 0x42, 0x4A, 0x63, 0x66, 0xE5, 0xCE, 0xD0, 0xCA, +0xC7, 0xCA, 0xCA, 0xCC, 0xCE, 0xD1, 0xCF, 0xCC, 0xCC, 0xC4, 0xBF, 0xBF, 0xBE, 0xC0, 0xBE, 0xC2, +0xCE, 0xCC, 0xE2, 0x58, 0x59, 0x47, 0x3D, 0x3D, 0x39, 0x37, 0x39, 0x39, 0x39, 0x3C, 0x40, 0x44, +0x4D, 0x5D, 0x6F, 0xE0, 0xD4, 0xCF, 0xCC, 0xCB, 0xCB, 0xCD, 0xCF, 0xCF, 0xD4, 0xD1, 0xCC, 0xCA, +0xC4, 0xBF, 0xBD, 0xBF, 0xBF, 0xBE, 0xC7, 0xCF, 0xCE, 0x79, 0x52, 0x51, 0x41, 0x3C, 0x3B, 0x38, +0x36, 0x38, 0x39, 0x38, 0x3D, 0x44, 0x44, 0x55, 0x70, 0x76, 0xD5, 0xCF, 0xCF, 0xC9, 0xCB, 0xCB, +0xCD, 0xD1, 0xD1, 0xD9, 0xD2, 0xCD, 0xCD, 0xC4, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xC9, 0xCF, 0xD0, +0x6A, 0x53, 0x4F, 0x3F, 0x3C, 0x3B, 0x38, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x56, 0x75, +0xE7, 0xD7, 0xCD, 0xCB, 0xCA, 0xC9, 0xCA, 0xCD, 0xCE, 0xCF, 0xD3, 0xCE, 0xCA, 0xC7, 0xC0, 0xBE, +0xBE, 0xBF, 0xBF, 0xC1, 0xCD, 0xD2, 0xDB, 0x5C, 0x4F, 0x4A, 0x3E, 0x3C, 0x3B, 0x39, 0x38, 0x3A, +0x3A, 0x3C, 0x43, 0x46, 0x4E, 0x71, 0x7A, 0xDD, 0xCE, 0xD0, 0xCB, 0xCA, 0xCD, 0xCC, 0xD1, 0xD2, +0xD5, 0xD7, 0xCC, 0xCC, 0xC7, 0xBE, 0xBF, 0xBF, 0xBE, 0xC0, 0xC6, 0xCD, 0xD5, 0xEE, 0x54, 0x4D, +0x45, 0x3C, 0x3B, 0x39, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x59, 0x71, 0xE8, 0xD4, 0xCE, +0xCC, 0xC9, 0xCB, 0xCB, 0xCE, 0xD2, 0xD4, 0xD7, 0xD2, 0xCD, 0xCB, 0xC4, 0xBF, 0xBF, 0xC0, 0xC0, +0xC0, 0xC9, 0xD1, 0xD8, 0x73, 0x52, 0x4B, 0x42, 0x3C, 0x3A, 0x39, 0x38, 0x38, 0x39, 0x3C, 0x3F, +0x41, 0x4E, 0x5D, 0x63, 0xDF, 0xD3, 0xD1, 0xCD, 0xCB, 0xCC, 0xD1, 0xD1, 0xD3, 0xDE, 0xDA, 0xD1, +0xCF, 0xCC, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, 0xD2, 0xE3, 0x63, 0x4F, 0x4A, 0x42, 0x3C, +0x3B, 0x3A, 0x39, 0x3A, 0x3B, 0x3F, 0x42, 0x47, 0x5A, 0x62, 0x7C, 0xD5, 0xD2, 0xCF, 0xCC, 0xCD, +0xCE, 0xD5, 0xD6, 0xD9, 0xE0, 0xD9, 0xD2, 0xCE, 0xCB, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, +0xD4, 0xE2, 0x67, 0x4F, 0x4B, 0x43, 0x3D, 0x3C, 0x3B, 0x3B, 0x3B, 0x3C, 0x42, 0x43, 0x49, 0x60, +0x6B, 0xF5, 0xD4, 0xD2, 0xD0, 0xD2, 0xD2, 0xD4, 0xDF, 0xDD, 0xDF, 0xEA, 0xDC, 0xD5, 0xD0, 0xCB, +0xC4, 0xC0, 0xC2, 0xBF, 0xC0, 0xC7, 0xC9, 0xD0, 0xDD, 0x7A, 0x57, 0x52, 0x48, 0x3F, 0x3F, 0x3D, +0x3C, 0x3C, 0x3D, 0x42, 0x44, 0x49, 0x5B, 0x64, 0x7C, 0xDE, 0xDB, 0xDB, 0xDC, 0xDA, 0xDF, 0xEE, +0xE9, 0xE6, 0xE8, 0xE3, 0xDB, 0xD0, 0xCD, 0xCC, 0xC5, 0xC3, 0xC5, 0xC2, 0xC3, 0xC8, 0xCD, 0xD1, +0xDE, 0x6F, 0x5B, 0x50, 0x4A, 0x44, 0x40, 0x3F, 0x3E, 0x3E, 0x42, 0x43, 0x47, 0x4F, 0x58, 0x5F, +0x69, 0xF6, 0xED, 0xF7, 0xEB, 0xE8, 0xEA, 0xEC, 0xE8, 0xE0, 0xE0, 0xDD, 0xD7, 0xD0, 0xCE, 0xCC, +0xC8, 0xC7, 0xC6, 0xC4, 0xC8, 0xC9, 0xCB, 0xD2, 0xDA, 0xEF, 0x71, 0x5B, 0x4F, 0x4E, 0x49, 0x45, +0x46, 0x45, 0x47, 0x47, 0x4A, 0x4E, 0x4E, 0x54, 0x5A, 0x5D, 0x62, 0x65, 0x70, 0x6C, 0x69, 0xFA, +0x7A, 0x7A, 0xE6, 0xE2, 0xDF, 0xDA, 0xD5, 0xCF, 0xD1, 0xD1, 0xCB, 0xCE, 0xD4, 0xCE, 0xD1, 0xD9, +0xDB, 0xE0, 0xE1, 0xEE, 0x6A, 0x74, 0x6C, 0x5A, 0x5B, 0x5A, 0x56, 0x56, 0x53, 0x56, 0x57, 0x53, +0x57, 0x5B, 0x59, 0x59, 0x5D, 0x65, 0x60, 0x61, 0x6F, 0x73, 0xF7, 0xEF, 0xEA, 0xDD, 0xDF, 0xDC, +0xD5, 0xD8, 0xDC, 0xDC, 0xDA, 0xDF, 0xE5, 0xE1, 0xEB, 0xED, 0xED, 0xFC, 0xFF, 0x70, 0x6C, 0x6C, +0x66, 0x5F, 0x5F, 0x62, 0x5F, 0x60, 0x60, 0x5A, 0x5F, 0x64, 0x5C, 0x64, 0x6E, 0x5F, 0x5E, 0x69, +0x6B, 0x7B, 0xF0, 0xFA, 0xE9, 0xE4, 0xE8, 0xDF, 0xE6, 0xEB, 0xE1, 0xE2, 0xE6, 0xE3, 0xE8, 0xED, +0xE5, 0xFC, 0x71, 0xE9, 0xFE, 0x7A, 0xEC, 0x73, 0x7E, 0x77, 0x64, 0xFD, 0x74, 0x66, 0x7B, 0x6C, +0x6B, 0x72, 0x6A, 0x79, 0x73, 0x71, 0xF4, 0x79, 0xFC, 0xEF, 0xF9, 0xEB, 0xF1, 0xF0, 0xE2, 0xE3, +0xE0, 0xE2, 0xE3, 0xEB, 0xFC, 0xEA, 0xF8, 0x6F, 0x70, 0x69, 0x77, 0x6C, 0x6D, 0xEF, 0x6B, 0x67, +0x6D, 0x65, 0x76, 0x75, 0x6F, 0x7E, 0x69, 0x67, 0x6F, 0x68, 0x6F, 0x73, 0x68, 0x69, 0x68, 0x69, +0x75, 0xFA, 0xEE, 0xF2, 0xEA, 0xDE, 0xE2, 0xE7, 0xE5, 0xEB, 0xF3, 0xED, 0xE8, 0xF7, 0x7F, 0xFA, +0x74, 0x6A, 0x68, 0x65, 0x66, 0x68, 0x64, 0x65, 0x68, 0x64, 0x6D, 0x77, 0x72, 0x70, 0x69, 0x77, +0x78, 0x64, 0x6B, 0x68, 0x60, 0x66, 0x67, 0x67, 0x61, 0x6D, 0xEB, 0xE8, 0xEC, 0xEB, 0xEA, 0xF7, +0xF5, 0xE2, 0xE5, 0xF6, 0xF8, 0xF0, 0x7E, 0x77, 0xFA, 0x76, 0x77, 0x7D, 0x6E, 0x74, 0x74, 0x72, +0x72, 0x6D, 0x75, 0x74, 0x74, 0x75, 0x76, 0xEF, 0xEE, 0xEF, 0xEA, 0xFA, 0x7F, 0xF2, 0xF6, 0xF7, +0xEF, 0xEA, 0xE4, 0xE5, 0xE7, 0xE3, 0xE9, 0xEC, 0xE8, 0xEB, 0xF0, 0xF8, 0xFC, 0x7F, 0x73, 0x73, +0x70, 0x72, 0x75, 0x69, 0x67, 0x6A, 0x6C, 0x6D, 0x6C, 0x70, 0x6D, 0x6D, 0x78, 0x72, 0x6F, 0x6E, +0x6C, 0x6F, 0x77, 0xF7, 0xEF, 0xF1, 0xF6, 0xF4, 0xF1, 0xFC, 0xF8, 0xEE, 0xF0, 0xEE, 0xEF, 0xEF, +0xEC, 0xEE, 0xF3, 0xF4, 0x76, 0x69, 0x77, 0xFA, 0x70, 0x75, 0x7E, 0x6E, 0x6D, 0x6E, 0x6E, 0x6E, +0x6D, 0x70, 0x74, 0x79, 0xFE, 0x7D, 0x78, 0x7C, 0x7A, 0x75, 0x78, 0x75, 0x70, 0x7C, 0xFC, 0xFB, +0xF4, 0xF3, 0xED, 0xEC, 0xF6, 0xF1, 0xEF, 0xF6, 0xF0, 0xFB, 0x7A, 0x7C, 0x74, 0x79, 0x74, 0x6C, +0x6C, 0x63, 0x67, 0x6C, 0x62, 0x66, 0x67, 0x68, 0x6C, 0x6A, 0x7D, 0x78, 0x6B, 0x7B, 0x71, 0x75, +0xFB, 0x75, 0x76, 0x7E, 0xEE, 0xED, 0xFA, 0xE8, 0xEE, 0x7F, 0xE4, 0xE9, 0xED, 0xE1, 0xEC, 0xEE, +0xE6, 0xF6, 0xFE, 0xF7, 0xFF, 0x7B, 0x72, 0x7C, 0x7F, 0x6B, 0x6C, 0x66, 0x67, 0x71, 0x66, 0x72, +0xFF, 0x69, 0x7B, 0xF7, 0xFF, 0xF3, 0xF6, 0xF3, 0xF2, 0xEE, 0xED, 0xFF, 0xF6, 0xED, 0xFB, 0xF2, +0xE9, 0xF0, 0xEC, 0xE6, 0xF4, 0xF2, 0xF5, 0x7C, 0xED, 0x7E, 0x6B, 0x7B, 0x77, 0xFE, 0x7A, 0x69, +0x68, 0x60, 0x65, 0x66, 0x61, 0x71, 0x74, 0x74, 0xFC, 0x7E, 0xFA, 0xFF, 0x7E, 0xF9, 0xFB, 0xEE, +0xED, 0xEF, 0xEF, 0xF4, 0xEC, 0xEC, 0xF2, 0xF0, 0xEF, 0xED, 0xF4, 0xF6, 0xEF, 0xFD, 0xF8, 0xF1, +0x77, 0x74, 0x7A, 0x70, 0x6F, 0x79, 0x76, 0x6A, 0x68, 0x6C, 0x6C, 0x69, 0x65, 0x66, 0x6E, 0x73, +0x6C, 0x6D, 0x7A, 0x79, 0x7A, 0xFE, 0x73, 0x72, 0x7A, 0x7E, 0xF3, 0xEF, 0xEE, 0xF1, 0xF6, 0xEC, +0xEF, 0xFA, 0xEE, 0xF5, 0xFE, 0xF2, 0xF0, 0xF7, 0xFA, 0xF9, 0xFB, 0xFB, 0x7A, 0x6B, 0x6B, 0x72, +0x6C, 0x6A, 0x76, 0x74, 0x6E, 0x72, 0x6C, 0x6B, 0x6F, 0x6B, 0x6E, 0x71, 0x6D, 0x75, 0x76, 0x70, +0x78, 0x7C, 0xFA, 0xF2, 0xF7, 0xF1, 0xED, 0xF3, 0xF4, 0xF6, 0xFA, 0xF0, 0xEF, 0xFD, 0x7B, 0xFF, +0x78, 0x6C, 0x70, 0x72, 0x6E, 0x73, 0x6D, 0x6D, 0x6D, 0x65, 0x65, 0x69, 0x6F, 0x70, 0x6B, 0x6E, +0x71, 0x6E, 0x6E, 0x6F, 0x7A, 0x7D, 0x7E, 0xEF, 0xF4, 0x7D, 0xFB, 0xF3, 0xEC, 0xEB, 0xF0, 0xEF, +0xEE, 0xEE, 0xF3, 0xF0, 0xED, 0xFF, 0xFF, 0xF3, 0x7E, 0xFB, 0xFF, 0x73, 0x7E, 0x7A, 0x76, 0x6F, +0x6C, 0x7A, 0x74, 0x6F, 0xFF, 0x7B, 0x79, 0xF7, 0xF5, 0xFB, 0xF6, 0xF3, 0x7E, 0x7D, 0xFA, 0xFD, +0xF6, 0xF5, 0x7D, 0x7B, 0x7A, 0xFF, 0xFB, 0x7D, 0x75, 0x76, 0xF3, 0xF3, 0x78, 0xFE, 0x76, 0x6B, +0x7B, 0xFB, 0x75, 0x69, 0x6C, 0xF6, 0xF6, 0x7B, 0x6F, 0x69, 0x6E, 0x72, 0x70, 0x74, 0x78, 0xFF, +0x7F, 0xFD, 0xF5, 0xF8, 0xF5, 0xF9, 0x75, 0x74, 0x7D, 0xF7, 0xFB, 0x70, 0x7E, 0xE9, 0xEF, 0xF7, +0xE6, 0xED, 0x74, 0x7A, 0xF7, 0x7D, 0x71, 0x77, 0xFE, 0xF6, 0xFC, 0x6B, 0x6B, 0x72, 0x69, 0x6D, +0x7B, 0x7C, 0xFD, 0x6F, 0x6B, 0xFC, 0x7F, 0x73, 0xF9, 0xF5, 0x70, 0x6E, 0xFD, 0xFF, 0x7C, 0xFB, +0x70, 0x76, 0xEF, 0x7D, 0x75, 0xFB, 0xF6, 0xEF, 0xF6, 0x7C, 0x79, 0x76, 0xFE, 0x7D, 0x73, 0xFD, +0xFE, 0x76, 0x6E, 0x66, 0x6B, 0x75, 0x6D, 0x7D, 0xF2, 0x6D, 0x75, 0xED, 0x7A, 0x6D, 0x7E, 0xF9, +0xFE, 0x6E, 0x78, 0xF4, 0x6E, 0x73, 0xF8, 0x74, 0xFF, 0xFE, 0x77, 0xF6, 0x7C, 0x71, 0x7F, 0x7E, +0x7E, 0x79, 0x78, 0x7C, 0x6E, 0x6F, 0x70, 0x6D, 0xFD, 0xFA, 0x6C, 0x6B, 0x71, 0x70, 0x7B, 0x7A, +0x7C, 0xFD, 0x6D, 0x75, 0xED, 0xF8, 0xFC, 0xF7, 0xFB, 0xEE, 0xEF, 0x79, 0xFF, 0xED, 0xF8, 0x7A, +0xF1, 0xED, 0xF7, 0xFC, 0xF8, 0xF1, 0xF8, 0x79, 0x7D, 0xF6, 0x78, 0x6E, 0xFD, 0xFB, 0x72, 0x6E, +0x6C, 0x74, 0xFE, 0xFF, 0xF7, 0xFE, 0x6D, 0x75, 0x79, 0x6F, 0x7C, 0x7D, 0x76, 0x78, 0x7A, 0x7F, +0x75, 0x7D, 0xF7, 0xF8, 0xEF, 0x7B, 0x7A, 0xF3, 0xFF, 0xEF, 0xF8, 0xFE, 0xF6, 0x6E, 0xF4, 0xED, +0x6F, 0x7C, 0x74, 0x75, 0xF2, 0x7C, 0x75, 0xF9, 0xEE, 0xFF, 0x70, 0x7C, 0x7F, 0xFD, 0xFD, 0xFA, +0x79, 0x6C, 0x7C, 0x7F, 0xFD, 0xF3, 0x78, 0xFE, 0xF7, 0xFC, 0xED, 0xF1, 0xFD, 0xFE, 0x7D, 0xF4, +0xED, 0xF4, 0xFA, 0xFD, 0x70, 0x73, 0xF6, 0xFF, 0x7D, 0xF7, 0x79, 0x72, 0x78, 0x7D, 0x77, 0x6E, +0x71, 0x6C, 0x6A, 0x7D, 0x74, 0x71, 0x7D, 0x6E, 0x79, 0xF8, 0x70, 0x7C, 0xFE, 0x6D, 0x6F, 0x6E, +0x6D, 0x7D, 0xFD, 0xFB, 0xFA, 0x7C, 0xFD, 0xFA, 0xF7, 0xF4, 0xFD, 0x7B, 0x76, 0x7D, 0xF3, 0xF5, +0xFD, 0xF5, 0xED, 0x7A, 0x6D, 0xF5, 0x7C, 0x76, 0xEF, 0x77, 0x6E, 0xFF, 0x74, 0x79, 0xFD, 0x76, +0x7A, 0x7E, 0x7B, 0x7D, 0x78, 0x73, 0x7A, 0xFB, 0xFB, 0x7E, 0xFB, 0xF2, 0xF8, 0xF9, 0xFB, 0xFE, +0xF5, 0xF6, 0xF9, 0x7E, 0x73, 0xF7, 0xFA, 0x74, 0xFC, 0x7B, 0x70, 0xFF, 0xFC, 0x7E, 0x7C, 0xFE, +0xFF, 0x7C, 0xFC, 0x7E, 0x79, 0xFF, 0x7C, 0x79, 0x79, 0x79, 0x7A, 0x79, 0x7A, 0x7C, 0x7A, 0x75, +0x72, 0x7C, 0xFC, 0xFE, 0xFE, 0xFC, 0xF9, 0xFE, 0xFE, 0xFA, 0x7C, 0xFD, 0xFC, 0x77, 0x7B, 0x7A, +0x73, 0x78, 0x7A, 0x78, 0x7B, 0x77, 0x6E, 0x70, 0x7B, 0x7A, 0x72, 0x74, 0x76, 0x75, 0x77, 0x75, +0x70, 0x6F, 0x6F, 0x6F, 0x74, 0x77, 0x72, 0x6F, 0x70, 0x79, 0x79, 0x6F, 0x7E, 0xFA, 0x72, 0x79, +0x79, 0x78, 0xFE, 0x78, 0xFF, 0xFE, 0x76, 0xFF, 0xFF, 0x7D, 0xFF, 0x7E, 0x7B, 0x78, 0x7C, 0x75, +0x75, 0xFF, 0xFF, 0xF8, 0xF6, 0xFD, 0xF5, 0xF4, 0xF6, 0xFC, 0x7C, 0x7C, 0x7B, 0xFC, 0xFD, 0xFD, +0xFD, 0x77, 0x7A, 0x7F, 0x7E, 0xFC, 0xFA, 0xF7, 0xFF, 0xFE, 0xF1, 0xFD, 0xFD, 0xF0, 0xF9, 0xF8, +0xEE, 0xEF, 0xF8, 0x7E, 0x79, 0x77, 0x6C, 0x66, 0x6A, 0x68, 0x67, 0x71, 0x74, 0x77, 0x7E, 0x7B, +0xFD, 0xFD, 0x7F, 0xFF, 0x79, 0xFE, 0xFE, 0x75, 0x78, 0x7A, 0x74, 0x70, 0x76, 0x77, 0x75, 0x7C, +0x7C, 0x79, 0x78, 0x77, 0x78, 0x7C, 0x7E, 0x77, 0x74, 0x79, 0x77, 0x78, 0x78, 0x77, 0x7B, 0x78, +0x77, 0x77, 0x7A, 0xFE, 0x7D, 0xFE, 0xF6, 0xFB, 0xFC, 0xF8, 0xF6, 0xFA, 0xFD, 0xFB, 0xFC, 0x7D, +0x7B, 0xFB, 0xF5, 0xFC, 0xFF, 0xFD, 0xFE, 0xFF, 0x7F, 0xFC, 0xF8, 0xFF, 0x7F, 0xF7, 0xF9, 0xFA, +0xF9, 0xFB, 0xFA, 0xFA, 0xFA, 0xF8, 0xF8, 0xFD, 0x7E, 0xF8, 0xF7, 0xEF, 0xE0, 0xE1, 0xF7, 0x6E, +0x69, 0x65, 0x5C, 0x5B, 0x61, 0x69, 0x6E, 0x76, 0xF8, 0xEF, 0xF2, 0xEB, 0xE3, 0xDE, 0xE2, 0xFA, +0x66, 0x5B, 0x5F, 0x6E, 0x6E, 0xFB, 0xED, 0xED, 0xEC, 0xF8, 0x7E, 0x7B, 0x6E, 0x67, 0x60, 0x65, +0x6E, 0x6F, 0x78, 0xFB, 0x7E, 0x7D, 0xFA, 0xF9, 0xF7, 0xF5, 0xF7, 0xEE, 0xEB, 0xF3, 0xFA, 0x7A, +0x6D, 0x69, 0x6A, 0x69, 0x64, 0x69, 0x6E, 0x6F, 0x78, 0xFB, 0xFB, 0x7C, 0xF8, 0xF1, 0xFB, 0xF4, +0xF9, 0x7D, 0xF8, 0x7D, 0xFD, 0xF3, 0x7C, 0xFD, 0xF4, 0x7A, 0x6F, 0x79, 0xFF, 0x75, 0x78, 0xFA, +0xFB, 0xFE, 0xFB, 0xF9, 0xFE, 0xFF, 0xFF, 0xFC, 0xF5, 0xFD, 0x79, 0xFF, 0xF9, 0xFA, 0xFF, 0xFF, +0x7B, 0x74, 0x75, 0x6F, 0x71, 0x7D, 0x74, 0x75, 0x79, 0x71, 0x77, 0x7E, 0x7E, 0x7C, 0x74, 0x71, +0x77, 0x7A, 0x7F, 0xFB, 0x72, 0x69, 0x74, 0x74, 0x6A, 0x74, 0x7E, 0x79, 0x76, 0x74, 0x7F, 0x7C, +0x76, 0xF8, 0xF8, 0x7E, 0x7D, 0x7E, 0xFE, 0x77, 0x7B, 0xF8, 0x7B, 0xFF, 0xF3, 0xFC, 0xFF, 0xFE, +0xFD, 0xF5, 0xF6, 0xF3, 0xF2, 0xFA, 0xF8, 0xF3, 0xFB, 0x7E, 0xFA, 0xFA, 0x7E, 0xFE, 0xFC, 0x7C, +0x78, 0x7D, 0xFB, 0xF3, 0xFD, 0x74, 0xF7, 0xF5, 0x76, 0xF9, 0xF8, 0xFF, 0xF5, 0x76, 0x7B, 0xFA, +0x77, 0xFD, 0x7C, 0x77, 0x7D, 0x6F, 0x7D, 0xF7, 0xFC, 0xFD, 0x7B, 0xF5, 0xF8, 0x7A, 0xF4, 0xFB, +0x77, 0x7B, 0x76, 0x74, 0x7D, 0x7E, 0x72, 0x71, 0x70, 0x70, 0x77, 0x70, 0x7B, 0xFD, 0x6F, 0x72, +0x7D, 0x7A, 0x71, 0x79, 0xF8, 0x77, 0x6F, 0x74, 0x7A, 0x78, 0x7C, 0xF6, 0x7C, 0xFB, 0x7D, 0x6C, +0xEF, 0xFC, 0x6D, 0xF1, 0xF5, 0x7D, 0x79, 0xFA, 0xF5, 0x75, 0xF4, 0x7C, 0xFC, 0xE6, 0x68, 0x78, +0xE4, 0x6E, 0x77, 0xF2, 0x7E, 0x70, 0x69, 0xF9, 0xF7, 0x6C, 0x74, 0xF3, 0xEE, 0x79, 0x7E, 0xFB, +0x7A, 0xF6, 0x6C, 0x6B, 0xED, 0x77, 0x6A, 0x70, 0x6F, 0xFC, 0x7E, 0x79, 0xF2, 0xEE, 0xF8, 0x7D, +0xEF, 0xEB, 0x7E, 0x72, 0x7D, 0x74, 0x6B, 0xFA, 0xE5, 0xE7, 0xE4, 0xEB, 0xF8, 0xEC, 0xEA, 0xF3, +0xFB, 0xFA, 0xEF, 0xF6, 0x7C, 0xFF, 0x7B, 0x72, 0x78, 0x7C, 0x6F, 0x6E, 0xFF, 0xFF, 0x75, 0x74, +0x74, 0x76, 0x6C, 0x6A, 0x7F, 0x78, 0x6D, 0x74, 0x6E, 0x76, 0x7B, 0x69, 0x6B, 0x79, 0x72, 0x6A, +0x6D, 0x77, 0xFD, 0xFC, 0x6F, 0x7C, 0xEE, 0x76, 0x69, 0x74, 0xFB, 0x74, 0x6A, 0x7D, 0xF0, 0xFF, +0x6B, 0x71, 0xEF, 0x7D, 0x74, 0xF8, 0x75, 0x74, 0x77, 0x6C, 0x6E, 0x71, 0x73, 0x72, 0x70, 0xF4, +0xF0, 0x79, 0x7B, 0xFB, 0xF3, 0xF4, 0x78, 0x79, 0xF7, 0xFC, 0x6E, 0x70, 0xF8, 0xF8, 0x79, 0x6D, +0x70, 0xFB, 0x6E, 0x64, 0x6B, 0x72, 0x6F, 0x65, 0x71, 0xFC, 0x71, 0x76, 0x6E, 0x71, 0xF9, 0xFF, +0xFD, 0x73, 0x7A, 0xFF, 0x66, 0x70, 0xFE, 0x79, 0xFD, 0x7D, 0xF1, 0xF6, 0x76, 0x79, 0x6D, 0x79, +0xFF, 0x72, 0x7F, 0xF8, 0xF0, 0xFF, 0x71, 0xEC, 0xE9, 0x7C, 0x7C, 0xF1, 0xF7, 0xF7, 0xF5, 0xFA, +0xF1, 0x7C, 0x70, 0x7D, 0xFB, 0xF4, 0x7C, 0x7D, 0xF6, 0xFD, 0xEF, 0xF6, 0xEE, 0xE1, 0xEE, 0xF4, +0xF3, 0xEE, 0xF4, 0x78, 0xEC, 0xF7, 0x72, 0x74, 0x6E, 0xF5, 0x6A, 0x7B, 0xDF, 0x69, 0x7F, 0xE7, +0x6F, 0x7C, 0x68, 0xF4, 0xEE, 0x5C, 0x72, 0x6B, 0x6D, 0xEC, 0x60, 0x7E, 0xEB, 0x66, 0x6D, 0x6A, +0x7A, 0xFF, 0x6A, 0x6E, 0x74, 0xED, 0x79, 0x6B, 0xED, 0xFA, 0xFC, 0x70, 0x65, 0xF6, 0x75, 0x67, +0x78, 0x78, 0xF4, 0xFF, 0x5F, 0xF9, 0xE3, 0x6D, 0xF1, 0x7A, 0x70, 0xDB, 0x6A, 0xF9, 0xDC, 0x66, +0xDB, 0xF8, 0x65, 0xD6, 0x6A, 0xF2, 0xE6, 0x5E, 0xE1, 0x76, 0x6F, 0xF5, 0x65, 0xEF, 0x5F, 0x66, +0x6F, 0x5A, 0xFB, 0x5E, 0x65, 0x7E, 0x60, 0xF2, 0x5D, 0x72, 0xE8, 0x5A, 0xEA, 0x6E, 0x62, 0xE4, +0x5E, 0x6F, 0x74, 0x67, 0xEA, 0x64, 0x77, 0xF3, 0x69, 0xF1, 0x6B, 0x6E, 0xEB, 0x74, 0x74, 0x74, +0xF6, 0xF5, 0x66, 0xF5, 0xF7, 0x6C, 0xE9, 0x70, 0x6F, 0xE4, 0x6E, 0xF0, 0xF4, 0x63, 0xE1, 0xFE, +0x6D, 0xE4, 0x6D, 0xF2, 0xEF, 0x6C, 0xE8, 0x7B, 0xFC, 0xED, 0x74, 0xEB, 0xFE, 0xFC, 0xEF, 0x6D, +0xEC, 0xFB, 0x71, 0xEB, 0x77, 0xF3, 0xF8, 0x6F, 0xE9, 0xFE, 0xFC, 0xEE, 0x6F, 0xEB, 0xED, 0x7A, +0xEE, 0xF4, 0xF3, 0xF8, 0xF1, 0xEE, 0x79, 0xF4, 0xF3, 0xFC, 0xF1, 0x7C, 0xF4, 0xF9, 0x76, 0xE8, +0xF8, 0x75, 0xE3, 0x7B, 0x6E, 0xE0, 0x75, 0x72, 0xE3, 0x6C, 0xF8, 0xE7, 0x6D, 0xEA, 0xF4, 0x75, +0xEA, 0x71, 0xFA, 0xED, 0x6A, 0xF2, 0xFB, 0x70, 0xEB, 0x6F, 0x71, 0xEE, 0x6C, 0xF6, 0xF2, 0x68, +0xF3, 0xF8, 0x6D, 0x7A, 0xFC, 0x75, 0x6D, 0xF3, 0x6E, 0x6E, 0xEE, 0x61, 0x7C, 0xFE, 0x60, 0xF2, +0x6D, 0x78, 0x7C, 0x63, 0xEB, 0x64, 0x71, 0xED, 0x5C, 0xEB, 0x6F, 0x69, 0xEA, 0x5D, 0xE7, 0xF8, +0x5E, 0xE6, 0x6F, 0xFA, 0x79, 0x72, 0xE8, 0x5E, 0xE9, 0xFB, 0x5F, 0xDE, 0x61, 0xFA, 0xE3, 0x5A, +0xE3, 0x79, 0x62, 0xDF, 0x64, 0x76, 0xE4, 0x63, 0xFE, 0xE9, 0x64, 0xF8, 0xE6, 0x5F, 0xF2, 0xE8, +0x62, 0xE7, 0xFB, 0x6A, 0xF0, 0x77, 0xF9, 0x77, 0xE9, 0x78, 0x59, 0xE3, 0x71, 0x6C, 0xDF, 0x5F, +0xEF, 0xE9, 0x5F, 0xFA, 0x76, 0xF9, 0x7D, 0x67, 0xEE, 0x7B, 0x6F, 0x7E, 0x6B, 0x6D, 0xF7, 0x6E, +0x6B, 0xF0, 0x63, 0xF0, 0x75, 0x57, 0xD4, 0x59, 0x57, 0xCD, 0x4F, 0xEE, 0xDE, 0x4B, 0xCF, 0x68, +0x5B, 0xD4, 0x50, 0xE0, 0xEF, 0x54, 0xD5, 0x57, 0x6A, 0xD3, 0x54, 0x79, 0xDF, 0x5E, 0xFC, 0xE6, +0x5F, 0x71, 0xE0, 0x64, 0x76, 0xFC, 0x5D, 0xEA, 0xF8, 0x58, 0x79, 0xDB, 0x68, 0x59, 0xDF, 0x76, +0x64, 0xDA, 0x63, 0x5A, 0xD9, 0xE0, 0x51, 0xF3, 0xD3, 0x4D, 0xDE, 0xCF, 0x3F, 0xDA, 0xC2, 0x41, +0x6A, 0xC3, 0x50, 0x55, 0xC6, 0x5A, 0x4B, 0xC2, 0x7A, 0x46, 0xCA, 0xDF, 0x4C, 0xD8, 0xDE, 0x4F, +0xE2, 0xD2, 0x4D, 0x6B, 0xCD, 0x5C, 0x56, 0xD8, 0xEB, 0x54, 0xEF, 0xDE, 0x4F, 0x78, 0xD7, 0x54, +0x5B, 0xDA, 0xFA, 0x56, 0xF6, 0xE9, 0x58, 0xF1, 0xE5, 0x59, 0x6D, 0xE8, 0x7B, 0x64, 0x7E, 0xE2, +0x60, 0x6D, 0xDC, 0x63, 0x67, 0xDC, 0x6F, 0x62, 0xE2, 0x7B, 0x60, 0xEC, 0xF3, 0x67, 0x77, 0xF1, +0x7C, 0x75, 0xF0, 0x79, 0x6F, 0xED, 0x76, 0x6B, 0xF3, 0xFF, 0x74, 0xF4, 0xF8, 0x6B, 0x6C, 0xE6, +0xE7, 0x61, 0x79, 0xDD, 0x6F, 0x77, 0xDE, 0x6D, 0x6E, 0xE4, 0x7E, 0xF9, 0xE8, 0x6D, 0x6F, 0xDE, +0xEF, 0x5C, 0xEF, 0xDB, 0x64, 0x6B, 0xDF, 0xF9, 0x6C, 0xF4, 0xF5, 0x72, 0xF5, 0xF7, 0x66, 0x7D, +0xE9, 0x7D, 0x70, 0x79, 0xF6, 0x7B, 0x6C, 0xF3, 0xF2, 0x6A, 0x76, 0xED, 0x79, 0x6B, 0xF2, 0xF1, +0x6B, 0x78, 0xEF, 0x73, 0x74, 0xED, 0x73, 0x6A, 0xEB, 0xF2, 0x64, 0x6F, 0xE2, 0xF8, 0x5E, 0xF3, +0xE8, 0x64, 0x74, 0xEF, 0x7B, 0x77, 0x74, 0x78, 0x6D, 0xF8, 0xEA, 0x63, 0x68, 0xEC, 0xEF, 0x6E, +0x63, 0xEE, 0xFA, 0x5F, 0xE5, 0xEB, 0x58, 0x73, 0xD1, 0xF3, 0x4D, 0xF2, 0xCD, 0x5D, 0x54, 0xDF, +0xDD, 0x61, 0x5B, 0xD9, 0xDF, 0x50, 0xF0, 0xD3, 0x5F, 0x5D, 0xE4, 0xDF, 0x6E, 0x5B, 0xED, 0xD8, +0x68, 0x56, 0xEA, 0xD3, 0x70, 0x52, 0xF0, 0xD3, 0x74, 0x57, 0xF5, 0xD8, 0x6A, 0x58, 0xE4, 0xE2, +0x5C, 0x7A, 0xD8, 0x77, 0x5A, 0xE8, 0xD9, 0x73, 0x5F, 0x7D, 0xE3, 0xEC, 0x73, 0x72, 0x6E, 0xF6, +0xDF, 0xF7, 0x62, 0x6B, 0xE5, 0xDD, 0x6B, 0x58, 0xF7, 0xDB, 0x73, 0x5E, 0x75, 0x7E, 0xF6, 0xFE, +0x66, 0x71, 0x7B, 0x7E, 0xEE, 0x6C, 0x6B, 0xEB, 0x76, 0x6C, 0xEA, 0x7A, 0x67, 0xE5, 0xE8, 0x5F, +0x75, 0xDE, 0xEE, 0x6F, 0x7A, 0xED, 0xE8, 0xF8, 0xFB, 0xF4, 0x78, 0xF1, 0xE4, 0x6E, 0x62, 0xEB, +0xEC, 0x65, 0x6D, 0x7E, 0x6B, 0x69, 0x6E, 0x72, 0x78, 0x68, 0x5E, 0x74, 0xE9, 0x6F, 0x5E, 0x72, +0xEB, 0x7A, 0x6F, 0xF1, 0x78, 0x75, 0xE5, 0xE6, 0xE2, 0xDD, 0xE0, 0xD6, 0xD1, 0xD5, 0xD1, 0xD3, +0xDE, 0xE0, 0xDD, 0xE9, 0x68, 0x57, 0x52, 0x50, 0x4B, 0x48, 0x48, 0x48, 0x48, 0x4B, 0x51, 0x56, +0x56, 0x5D, 0x68, 0x6A, 0x69, 0x7C, 0xE8, 0xED, 0xED, 0xDC, 0xD5, 0xCD, 0xCB, 0xCD, 0xC5, 0xBE, +0xBE, 0xBC, 0xBC, 0xBF, 0xC5, 0xD2, 0x72, 0x52, 0x48, 0x40, 0x3C, 0x39, 0x39, 0x3B, 0x3D, 0x40, +0x4A, 0x5A, 0x6C, 0x7E, 0xDF, 0xCF, 0xCE, 0xDB, 0x6F, 0x63, 0x6E, 0x60, 0x4D, 0x47, 0x4D, 0x5E, +0x7C, 0xFA, 0xE4, 0xCD, 0xC1, 0xBD, 0xBC, 0xBA, 0xB7, 0xB4, 0xB5, 0xBE, 0xD7, 0xEB, 0xF2, 0x4E, +0x3B, 0x36, 0x37, 0x39, 0x38, 0x39, 0x3D, 0x48, 0x58, 0xFE, 0xDA, 0xD6, 0xD8, 0xCF, 0xC8, 0xCD, +0xF3, 0x5A, 0x59, 0x58, 0x4E, 0x47, 0x48, 0x4F, 0x5F, 0xF2, 0xD9, 0xCE, 0xC6, 0xBF, 0xBB, 0xBA, +0xB9, 0xB7, 0xB5, 0xB7, 0xC0, 0xD9, 0x68, 0x57, 0x49, 0x3B, 0x35, 0x35, 0x38, 0x3A, 0x3B, 0x3F, +0x4B, 0x60, 0xE7, 0xD8, 0xD5, 0xD4, 0xCE, 0xCA, 0xCF, 0xF9, 0x59, 0x51, 0x4E, 0x4C, 0x48, 0x46, +0x49, 0x56, 0xFB, 0xD9, 0xD1, 0xC9, 0xBE, 0xB8, 0xB6, 0xB5, 0xB3, 0xB2, 0xB6, 0xC3, 0xE5, 0x60, +0x4E, 0x3F, 0x37, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x41, 0x4E, 0x6F, 0xDA, 0xD2, 0xD4, 0xD1, 0xCA, +0xC9, 0xD7, 0x6F, 0x59, 0x4D, 0x47, 0x47, 0x48, 0x45, 0x46, 0x52, 0xEE, 0xD7, 0xD0, 0xC7, 0xBC, +0xB5, 0xB3, 0xB3, 0xB1, 0xB0, 0xB7, 0xCA, 0x68, 0x4F, 0x45, 0x3B, 0x32, 0x2E, 0x30, 0x35, 0x39, +0x3D, 0x44, 0x52, 0xEC, 0xD0, 0xCF, 0xD3, 0xD0, 0xCD, 0xCF, 0xE3, 0x63, 0x5B, 0x59, 0x52, 0x4D, +0x4C, 0x4F, 0x5A, 0x6D, 0xE5, 0xD2, 0xC8, 0xBE, 0xB9, 0xB5, 0xB3, 0xB1, 0xAF, 0xB1, 0xBD, 0xE3, +0x53, 0x4B, 0x40, 0x35, 0x2E, 0x2F, 0x34, 0x39, 0x3B, 0x3F, 0x4C, 0x75, 0xDA, 0xD6, 0xD2, 0xCE, +0xCE, 0xD0, 0xD9, 0xEF, 0x62, 0x56, 0x55, 0x55, 0x4F, 0x4E, 0x52, 0x61, 0xEF, 0xDB, 0xCC, 0xBF, +0xB9, 0xB5, 0xB3, 0xB0, 0xAE, 0xB4, 0xC8, 0x63, 0x4D, 0x45, 0x39, 0x2E, 0x2C, 0x2F, 0x35, 0x38, +0x3B, 0x43, 0x5A, 0xDD, 0xCE, 0xCD, 0xCC, 0xCB, 0xCD, 0xD2, 0xDE, 0x76, 0x5A, 0x52, 0x53, 0x51, +0x4E, 0x4F, 0x5C, 0x7C, 0xE2, 0xD2, 0xC5, 0xBB, 0xB5, 0xB2, 0xB0, 0xAE, 0xAE, 0xB6, 0xCF, 0x55, +0x48, 0x3F, 0x34, 0x2C, 0x2C, 0x2F, 0x36, 0x39, 0x3D, 0x4A, 0x7D, 0xCE, 0xCA, 0xCB, 0xCB, 0xCB, +0xCD, 0xD9, 0x76, 0x59, 0x4F, 0x4C, 0x4C, 0x4A, 0x4C, 0x54, 0x68, 0xEC, 0xD8, 0xCB, 0xBF, 0xB8, +0xB3, 0xB0, 0xAE, 0xAD, 0xAE, 0xBC, 0xF5, 0x4C, 0x43, 0x39, 0x2E, 0x2A, 0x2D, 0x32, 0x37, 0x3B, +0x44, 0x5F, 0xD5, 0xC8, 0xC7, 0xC9, 0xCB, 0xCE, 0xD3, 0xE9, 0x5A, 0x4D, 0x4D, 0x4D, 0x4B, 0x4B, +0x50, 0x63, 0xF6, 0xDE, 0xCE, 0xC5, 0xBD, 0xB7, 0xB2, 0xB0, 0xAF, 0xAD, 0xAF, 0xBF, 0x5E, 0x45, +0x40, 0x37, 0x2C, 0x29, 0x2D, 0x34, 0x38, 0x3C, 0x48, 0x77, 0xCD, 0xC6, 0xC7, 0xCB, 0xCB, 0xCF, +0xE9, 0x59, 0x4E, 0x4B, 0x47, 0x44, 0x47, 0x4D, 0x57, 0x69, 0xEB, 0xD7, 0xCA, 0xBF, 0xB9, 0xB3, +0xAF, 0xAE, 0xAD, 0xAC, 0xB5, 0xDE, 0x49, 0x43, 0x3B, 0x2D, 0x28, 0x2A, 0x30, 0x36, 0x3A, 0x44, +0x6A, 0xCD, 0xC2, 0xC2, 0xC6, 0xCA, 0xCC, 0xD8, 0x60, 0x4C, 0x48, 0x46, 0x44, 0x43, 0x49, 0x54, +0x68, 0xEC, 0xD8, 0xCB, 0xC2, 0xBC, 0xB8, 0xB2, 0xAF, 0xAE, 0xAE, 0xAE, 0xBA, 0x74, 0x45, 0x3F, +0x36, 0x2C, 0x29, 0x2C, 0x32, 0x37, 0x3E, 0x4E, 0xE3, 0xC7, 0xC2, 0xC5, 0xC6, 0xC8, 0xD2, 0x71, +0x52, 0x4D, 0x49, 0x42, 0x41, 0x47, 0x51, 0x60, 0x7B, 0xDE, 0xCE, 0xC6, 0xC0, 0xBE, 0xB9, 0xB2, +0xAF, 0xAF, 0xAE, 0xAE, 0xBC, 0x6B, 0x47, 0x3F, 0x34, 0x2C, 0x2A, 0x2D, 0x32, 0x39, 0x3F, 0x4F, +0xDF, 0xC5, 0xC4, 0xCD, 0xCA, 0xC7, 0xDB, 0x5A, 0x4E, 0x4D, 0x48, 0x42, 0x40, 0x45, 0x54, 0x6F, +0x74, 0xEC, 0xCD, 0xC4, 0xC4, 0xC1, 0xBB, 0xB3, 0xAF, 0xB0, 0xAE, 0xAE, 0xBC, 0x6F, 0x4A, 0x3F, +0x34, 0x2C, 0x2B, 0x2E, 0x34, 0x3B, 0x42, 0x56, 0xCF, 0xBF, 0xC2, 0xCB, 0xC6, 0xC6, 0xE6, 0x52, +0x4B, 0x47, 0x45, 0x3F, 0x3D, 0x45, 0x5E, 0x7A, 0x72, 0xDB, 0xC7, 0xC3, 0xC5, 0xC2, 0xBC, 0xB5, +0xB1, 0xB3, 0xB0, 0xAE, 0xB9, 0xF0, 0x4C, 0x43, 0x38, 0x2E, 0x2B, 0x2D, 0x34, 0x3A, 0x3E, 0x4F, +0xD3, 0xC1, 0xC4, 0xCD, 0xCC, 0xC8, 0xDE, 0x4D, 0x45, 0x47, 0x47, 0x41, 0x3D, 0x47, 0x6D, 0xF7, +0x79, 0xDA, 0xC9, 0xC6, 0xC8, 0xC9, 0xC0, 0xB8, 0xB4, 0xB5, 0xB0, 0xAC, 0xB1, 0xCF, 0x5A, 0x4E, +0x3E, 0x30, 0x2B, 0x2D, 0x33, 0x38, 0x3B, 0x48, 0xDC, 0xC4, 0xC5, 0xCA, 0xCB, 0xCB, 0xD9, 0x50, +0x46, 0x4B, 0x46, 0x3E, 0x3F, 0x48, 0x55, 0x76, 0x7E, 0xE3, 0xCA, 0xC9, 0xCE, 0xCB, 0xC6, 0xBE, +0xBA, 0xB8, 0xB4, 0xAE, 0xAE, 0xBD, 0xEA, 0x62, 0x48, 0x35, 0x2D, 0x2C, 0x30, 0x35, 0x37, 0x3F, +0x6F, 0xCB, 0xCA, 0xC9, 0xC7, 0xCE, 0xD9, 0x60, 0x46, 0x46, 0x48, 0x40, 0x40, 0x49, 0x52, 0x69, +0xED, 0xE1, 0xD1, 0xCC, 0xD0, 0xD2, 0xD0, 0xCD, 0xC2, 0xBD, 0xB9, 0xB2, 0xAE, 0xAF, 0xBA, 0xE0, +0x67, 0x4C, 0x34, 0x2D, 0x2E, 0x30, 0x34, 0x37, 0x41, 0xF4, 0xCD, 0xCC, 0xC7, 0xC5, 0xD0, 0xED, +0x64, 0x4D, 0x45, 0x47, 0x43, 0x44, 0x4F, 0x51, 0x69, 0xD9, 0xDD, 0xD1, 0xCB, 0xD1, 0xCF, 0xD2, +0xCD, 0xBF, 0xBC, 0xB8, 0xB0, 0xAD, 0xAE, 0xBC, 0xD9, 0x76, 0x48, 0x32, 0x2D, 0x2F, 0x30, 0x32, +0x38, 0x49, 0xE6, 0xD1, 0xCB, 0xC1, 0xC1, 0xD2, 0x7A, 0x6F, 0x51, 0x42, 0x43, 0x45, 0x4A, 0x4D, +0x4E, 0x72, 0xD7, 0xDB, 0xD8, 0xCE, 0xCF, 0xD7, 0xDD, 0xD3, 0xC6, 0xBF, 0xBB, 0xB3, 0xAD, 0xAE, +0xB8, 0xCD, 0xE2, 0x52, 0x35, 0x2E, 0x2F, 0x2F, 0x2F, 0x35, 0x43, 0x62, 0xE5, 0xCF, 0xC1, 0xC0, +0xD1, 0xE1, 0xDB, 0x5E, 0x46, 0x49, 0x4D, 0x4A, 0x49, 0x51, 0x6A, 0xEE, 0xEB, 0xDE, 0xD0, 0xD4, +0xDF, 0xDC, 0xD7, 0xCF, 0xC5, 0xBE, 0xB7, 0xB1, 0xAE, 0xAF, 0xBC, 0xD3, 0xE7, 0x48, 0x31, 0x2E, +0x2F, 0x2E, 0x2F, 0x36, 0x44, 0x5B, 0xF4, 0xCC, 0xBF, 0xC2, 0xD4, 0xD1, 0xCF, 0x59, 0x4B, 0x51, +0x4B, 0x46, 0x44, 0x4C, 0x56, 0x51, 0x66, 0xE5, 0xE6, 0xE0, 0xDF, 0xD6, 0xD1, 0xCD, 0xC0, 0xBB, +0xB7, 0xB0, 0xAD, 0xB0, 0xBD, 0xCE, 0xEF, 0x44, 0x31, 0x2F, 0x30, 0x2E, 0x2E, 0x39, 0x46, 0x56, +0xF0, 0xC7, 0xBD, 0xC2, 0xC9, 0xC8, 0xCC, 0x7A, 0x50, 0x57, 0x4F, 0x42, 0x42, 0x4A, 0x4C, 0x4C, +0x5D, 0xEF, 0xEE, 0xE3, 0xD6, 0xD1, 0xD2, 0xCC, 0xC0, 0xBC, 0xBA, 0xB3, 0xAE, 0xAF, 0xBA, 0xC9, +0xD6, 0x4F, 0x36, 0x30, 0x30, 0x2E, 0x2D, 0x34, 0x3E, 0x45, 0x5C, 0xCF, 0xC1, 0xC0, 0xC1, 0xC0, +0xC9, 0xD9, 0xF5, 0x54, 0x4A, 0x47, 0x40, 0x41, 0x42, 0x45, 0x4E, 0x53, 0x68, 0xE8, 0xE1, 0xD1, +0xCD, 0xCC, 0xC5, 0xBF, 0xBB, 0xB8, 0xB4, 0xAF, 0xB0, 0xBD, 0xCB, 0xD8, 0x4B, 0x36, 0x34, 0x33, +0x2E, 0x2E, 0x37, 0x3D, 0x44, 0x62, 0xCD, 0xC4, 0xC0, 0xBE, 0xBF, 0xC5, 0xCF, 0xEE, 0x66, 0x4F, +0x45, 0x43, 0x40, 0x41, 0x44, 0x47, 0x51, 0x5B, 0x71, 0xDD, 0xD8, 0xCE, 0xC8, 0xC6, 0xC1, 0xBD, +0xB9, 0xB7, 0xB2, 0xAF, 0xB9, 0xC3, 0xCC, 0x71, 0x40, 0x37, 0x36, 0x31, 0x2E, 0x33, 0x3A, 0x3D, +0x4A, 0xE6, 0xCF, 0xC7, 0xBE, 0xBF, 0xC2, 0xCA, 0xD3, 0xE6, 0x50, 0x4C, 0x4B, 0x3E, 0x3E, 0x43, +0x41, 0x47, 0x4D, 0x59, 0x75, 0xE4, 0xD0, 0xCC, 0xC9, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB3, 0xB3, +0xBB, 0xC3, 0xCD, 0x6A, 0x42, 0x3A, 0x38, 0x31, 0x30, 0x36, 0x39, 0x3C, 0x4B, 0x7A, 0xDB, 0xCB, +0xC1, 0xC3, 0xC5, 0xC5, 0xD5, 0xE5, 0x6B, 0x4E, 0x4C, 0x43, 0x40, 0x45, 0x42, 0x48, 0x50, 0x55, +0x6C, 0xE8, 0xD7, 0xCD, 0xCC, 0xC7, 0xC3, 0xC0, 0xBD, 0xBC, 0xB8, 0xB2, 0xB5, 0xBD, 0xC2, 0xD0, +0x5D, 0x45, 0x3C, 0x38, 0x32, 0x32, 0x37, 0x37, 0x3C, 0x4C, 0x5E, 0xEE, 0xCD, 0xC5, 0xC8, 0xC6, +0xC5, 0xD0, 0xE2, 0xF9, 0x5D, 0x4D, 0x47, 0x46, 0x42, 0x41, 0x47, 0x4B, 0x4E, 0x63, 0xEA, 0xE3, +0xD3, 0xC9, 0xCB, 0xC8, 0xC0, 0xBF, 0xBD, 0xBA, 0xB5, 0xB6, 0xBC, 0xC1, 0xCC, 0x7E, 0x4B, 0x3F, +0x3B, 0x35, 0x32, 0x37, 0x37, 0x3A, 0x45, 0x50, 0x6D, 0xD7, 0xC8, 0xC6, 0xC7, 0xC2, 0xCA, 0xD7, +0xDB, 0x6D, 0x59, 0x4F, 0x48, 0x48, 0x45, 0x46, 0x4D, 0x4F, 0x5E, 0xFF, 0xE6, 0xD7, 0xD4, 0xCF, +0xD1, 0xD5, 0xD0, 0xD3, 0xCD, 0xC6, 0xC1, 0xBA, 0xB8, 0xBB, 0xC2, 0xC4, 0xCD, 0x58, 0x4C, 0x48, +0x39, 0x36, 0x39, 0x36, 0x37, 0x3E, 0x44, 0x4B, 0x66, 0xDC, 0xD4, 0xCA, 0xC3, 0xC5, 0xC7, 0xCA, +0xCE, 0xDD, 0x6D, 0x5F, 0x4F, 0x46, 0x47, 0x46, 0x43, 0x49, 0x4E, 0x53, 0x65, 0xF1, 0xE4, 0xD9, +0xCF, 0xCE, 0xCD, 0xC6, 0xC3, 0xC0, 0xBA, 0xB7, 0xB7, 0xBD, 0xC4, 0xC5, 0xFD, 0x4A, 0x4C, 0x3B, +0x33, 0x37, 0x34, 0x32, 0x3A, 0x3F, 0x47, 0x5B, 0xDC, 0xCB, 0xC8, 0xBE, 0xBC, 0xC3, 0xC0, 0xC7, +0xDE, 0xEC, 0x5B, 0x49, 0x45, 0x3F, 0x3E, 0x3F, 0x40, 0x49, 0x4E, 0x5B, 0xEF, 0xDF, 0xD4, 0xCC, +0xCA, 0xC7, 0xC5, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB8, 0xC0, 0xCB, 0xCA, 0x68, 0x45, 0x4D, 0x3D, +0x35, 0x3C, 0x3A, 0x38, 0x41, 0x49, 0x4D, 0x69, 0xDB, 0xD3, 0xCD, 0xC5, 0xC6, 0xCC, 0xCB, 0xD0, +0xEB, 0x76, 0x5C, 0x4C, 0x48, 0x44, 0x41, 0x41, 0x44, 0x49, 0x4E, 0x5D, 0x7E, 0xE6, 0xD4, 0xCE, +0xCE, 0xCB, 0xCB, 0xCE, 0xCE, 0xCA, 0xC9, 0xC6, 0xBE, 0xBC, 0xC6, 0xCA, 0xC4, 0xE0, 0x58, 0x77, +0x4A, 0x3D, 0x45, 0x3D, 0x39, 0x3F, 0x41, 0x40, 0x4C, 0x61, 0x6D, 0xE7, 0xCE, 0xCC, 0xCC, 0xC9, +0xCA, 0xD1, 0xDB, 0xE2, 0x66, 0x54, 0x50, 0x48, 0x45, 0x47, 0x47, 0x4B, 0x51, 0x5A, 0x71, 0xEB, +0xDD, 0xD5, 0xD2, 0xCF, 0xCC, 0xCC, 0xCA, 0xC4, 0xC3, 0xBF, 0xB9, 0xBD, 0xCB, 0xC0, 0xC9, 0x56, +0x71, 0x5A, 0x3A, 0x3F, 0x3E, 0x34, 0x3A, 0x3E, 0x3C, 0x42, 0x54, 0x62, 0x73, 0xCF, 0xC8, 0xCC, +0xC3, 0xC3, 0xCD, 0xCF, 0xDD, 0x6D, 0x56, 0x4D, 0x48, 0x42, 0x42, 0x44, 0x45, 0x4D, 0x57, 0x61, +0xED, 0xDB, 0xD5, 0xCD, 0xCD, 0xCD, 0xCD, 0xD0, 0xCD, 0xD1, 0xCA, 0xC4, 0xC7, 0xBA, 0xC2, 0xD8, +0xBB, 0xD7, 0x53, 0xCC, 0x4E, 0x3E, 0x57, 0x3E, 0x3B, 0x43, 0x3F, 0x3E, 0x46, 0x52, 0x50, 0x60, +0xD6, 0xD9, 0xD4, 0xC6, 0xCA, 0xCF, 0xCB, 0xD5, 0xF4, 0xFB, 0x5D, 0x4E, 0x4C, 0x4B, 0x46, 0x45, +0x4F, 0x4E, 0x4D, 0x7E, 0x6F, 0x71, 0xD4, 0xE1, 0xDF, 0xCE, 0xD9, 0xD5, 0xCD, 0xCD, 0xC5, 0xBF, +0xB9, 0xBA, 0xC6, 0xBA, 0xBF, 0x6C, 0xCE, 0xFB, 0x3D, 0x4D, 0x40, 0x35, 0x3C, 0x3B, 0x38, 0x3E, +0x47, 0x4B, 0x52, 0xDF, 0xD8, 0xD6, 0xC3, 0xC6, 0xCB, 0xC5, 0xCD, 0xDD, 0xE4, 0x6B, 0x50, 0x4D, +0x49, 0x44, 0x45, 0x47, 0x48, 0x49, 0x50, 0x5D, 0x5C, 0xEE, 0xDD, 0xE7, 0xD1, 0xD5, 0xDC, 0xD0, +0xDA, 0xD8, 0xD1, 0xCD, 0xC6, 0xBF, 0xBA, 0xC1, 0xC4, 0xBA, 0xD3, 0xE1, 0xCC, 0x4D, 0x49, 0x4F, +0x3B, 0x3B, 0x3E, 0x3A, 0x3C, 0x42, 0x4A, 0x4C, 0x6D, 0xD9, 0xDC, 0xC9, 0xC4, 0xCA, 0xC6, 0xC8, +0xD0, 0xD8, 0xE5, 0x68, 0x58, 0x53, 0x4C, 0x4A, 0x4B, 0x4C, 0x4E, 0x56, 0x5F, 0x69, 0xEA, 0xE0, +0xE8, 0xD5, 0xDD, 0xE7, 0xD9, 0xFB, 0xF9, 0xF5, 0x64, 0x75, 0x6D, 0xF5, 0xE5, 0xD8, 0xC8, 0xC4, +0xBB, 0xBF, 0xC4, 0xB7, 0xCC, 0xD6, 0xC3, 0x56, 0x52, 0x5F, 0x3D, 0x3E, 0x3E, 0x39, 0x3A, 0x3D, +0x41, 0x41, 0x4F, 0x6B, 0x63, 0xD6, 0xCD, 0xD1, 0xC7, 0xC8, 0xCE, 0xCE, 0xD6, 0xE8, 0x71, 0x67, +0x55, 0x4F, 0x52, 0x4D, 0x4F, 0x56, 0x56, 0x5E, 0x6D, 0x7E, 0xF5, 0xDF, 0xE3, 0xEE, 0xDC, 0x7B, +0x73, 0xED, 0x5C, 0x6A, 0x69, 0x5B, 0x70, 0x6D, 0xEF, 0xE1, 0xCF, 0xC8, 0xC4, 0xB9, 0xC5, 0xC2, +0xB6, 0xDC, 0xCD, 0xC3, 0x49, 0x60, 0x57, 0x3A, 0x40, 0x3D, 0x38, 0x3A, 0x3E, 0x3F, 0x3E, 0x53, +0x58, 0x59, 0xD3, 0xD7, 0xD2, 0xC4, 0xC9, 0xCA, 0xC8, 0xCD, 0xD8, 0xDE, 0xEE, 0x5F, 0x5D, 0x59, +0x4F, 0x54, 0x56, 0x54, 0x5D, 0x69, 0x6D, 0xF2, 0xE1, 0xDF, 0xDB, 0xD8, 0xDD, 0xE8, 0xEB, 0x71, +0x5D, 0x66, 0x56, 0x52, 0x62, 0x52, 0x5C, 0x74, 0x63, 0xE2, 0xDD, 0xD4, 0xCA, 0xC9, 0xBF, 0xC0, +0xBB, 0xBB, 0xCC, 0xBB, 0xC8, 0x68, 0xC8, 0x58, 0x44, 0x5D, 0x3C, 0x3B, 0x40, 0x3A, 0x3B, 0x3F, +0x44, 0x43, 0x52, 0x7A, 0x62, 0xD4, 0xCB, 0xD1, 0xC3, 0xC4, 0xC8, 0xC5, 0xCA, 0xD0, 0xD9, 0xE1, +0x6C, 0x5C, 0x5B, 0x4E, 0x4D, 0x50, 0x4C, 0x50, 0x58, 0x58, 0x63, 0x79, 0xFE, 0xED, 0xE1, 0xE7, +0xEE, 0xE6, 0xFB, 0x6D, 0x7A, 0x61, 0x5D, 0x62, 0x59, 0x5B, 0x5E, 0x5C, 0x64, 0x69, 0x72, 0xFE, +0xF1, 0xE6, 0xE2, 0xDB, 0xD9, 0xD6, 0xD3, 0xD3, 0xD0, 0xD0, 0xCF, 0xCE, 0xCD, 0xCD, 0xDA, 0xDB, +0xDA, 0x64, 0x69, 0x63, 0x4C, 0x4F, 0x4D, 0x46, 0x4A, 0x4A, 0x48, 0x4D, 0x52, 0x52, 0x5C, 0x70, +0x71, 0xEB, 0xDC, 0xDE, 0xD7, 0xD4, 0xD8, 0xD5, 0xD7, 0xDD, 0xDF, 0xE7, 0xFD, 0x71, 0x69, 0x5D, +0x5A, 0x5A, 0x57, 0x56, 0x5B, 0x59, 0x5A, 0x69, 0x62, 0x6A, 0xF5, 0x73, 0xF1, 0xE7, 0xF4, 0xE6, +0xE6, 0xEE, 0xEA, 0xED, 0xF5, 0xF1, 0xED, 0xF0, 0xEA, 0xE4, 0xE7, 0xDF, 0xDE, 0xDF, 0xDC, 0xDE, +0xDF, 0xE1, 0xE8, 0xEE, 0xFD, 0x77, 0x6B, 0x64, 0x61, 0x5C, 0x5C, 0x5C, 0x5B, 0x5F, 0x61, 0x67, +0x6E, 0x78, 0xF8, 0xF1, 0xEA, 0xE5, 0xE4, 0xE2, 0xE1, 0xE5, 0xEA, 0xED, 0xFA, 0x77, 0x6E, 0x66, +0x62, 0x5D, 0x5C, 0x5A, 0x59, 0x59, 0x59, 0x5B, 0x5C, 0x5D, 0x64, 0x64, 0x6C, 0x77, 0x7C, 0xEE, +0xEB, 0xE0, 0xDB, 0xD7, 0xCF, 0xCF, 0xCA, 0xC8, 0xC5, 0xC4, 0xCD, 0xC7, 0xCB, 0xE8, 0xD3, 0xFD, +0x55, 0x67, 0x4B, 0x45, 0x48, 0x40, 0x3F, 0x42, 0x43, 0x43, 0x4A, 0x50, 0x50, 0x6C, 0xF5, 0xF2, +0xD4, 0xD2, 0xD1, 0xCB, 0xCC, 0xCE, 0xCE, 0xD0, 0xDA, 0xDC, 0xDF, 0xFD, 0x7D, 0x6F, 0x5E, 0x5F, +0x5D, 0x59, 0x5A, 0x5C, 0x5C, 0x5F, 0x68, 0x68, 0x6F, 0xFC, 0xFC, 0xEF, 0xE9, 0xEB, 0xE9, 0xE9, +0xED, 0xEF, 0xF2, 0xF8, 0xFE, 0xFE, 0x7C, 0x7C, 0x7E, 0x79, 0xFE, 0xFB, 0xFE, 0xF7, 0xF6, 0xF9, +0xF6, 0xF8, 0xFD, 0xFF, 0x7C, 0x73, 0x70, 0x6E, 0x6A, 0x6A, 0x69, 0x68, 0x6A, 0x6B, 0x6C, 0x6F, +0x74, 0x79, 0xFF, 0xFA, 0xF8, 0xF2, 0xF4, 0xF6, 0xF3, 0xFE, 0xFB, 0x74, 0x62, 0x69, 0x5F, 0x5A, +0x66, 0x5B, 0x5D, 0x70, 0x61, 0x78, 0xED, 0xF4, 0xDB, 0xD7, 0xD0, 0xCB, 0xC9, 0xC3, 0xCC, 0xC9, +0xC4, 0xDD, 0xD2, 0xD7, 0x59, 0x6E, 0x57, 0x45, 0x4B, 0x45, 0x3F, 0x43, 0x44, 0x43, 0x49, 0x51, +0x4F, 0x5E, 0xFB, 0x70, 0xDE, 0xD8, 0xDC, 0xD1, 0xD2, 0xD7, 0xD4, 0xD6, 0xDD, 0xDF, 0xDF, 0xF1, +0xF2, 0xF2, 0x6F, 0x73, 0x72, 0x69, 0x6D, 0x6F, 0x6D, 0x72, 0x7B, 0x79, 0x7E, 0xF8, 0xFD, 0xF9, +0xF6, 0xFD, 0xFA, 0xFA, 0xFD, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF8, 0xF3, 0xF2, 0xF4, 0xEF, 0xF1, +0xF4, 0xF2, 0xF6, 0xF9, 0xF8, 0xF9, 0xFD, 0xFD, 0xFC, 0x7F, 0x7E, 0x7D, 0x79, 0x76, 0x74, 0x71, +0x6F, 0x6E, 0x6C, 0x6C, 0x6D, 0x6B, 0x6C, 0x6D, 0x6C, 0x71, 0x71, 0x70, 0x7E, 0x79, 0x7C, 0xFA, +0x7B, 0xFD, 0xFC, 0x7A, 0xFE, 0x7C, 0x78, 0x7B, 0x76, 0x76, 0x78, 0x77, 0x77, 0x7C, 0x7E, 0xFF, +0xF2, 0xF3, 0xED, 0xE7, 0xE8, 0xE0, 0xDE, 0xDC, 0xD7, 0xD8, 0xD3, 0xD4, 0xDA, 0xD7, 0xDF, 0xEB, +0xED, 0x6A, 0x60, 0x5C, 0x52, 0x4F, 0x4D, 0x4B, 0x4A, 0x4B, 0x4B, 0x4D, 0x50, 0x54, 0x5B, 0x66, +0x6F, 0xF1, 0xE6, 0xDF, 0xDA, 0xD8, 0xD8, 0xD7, 0xD9, 0xDB, 0xDE, 0xE2, 0xEA, 0xF1, 0xFA, 0x78, +0x70, 0x6D, 0x69, 0x68, 0x66, 0x65, 0x65, 0x66, 0x66, 0x67, 0x6A, 0x6B, 0x6C, 0x70, 0x74, 0x79, +0xFB, 0xF5, 0xEF, 0xEB, 0xE9, 0xE6, 0xE3, 0xE2, 0xE1, 0xE0, 0xE0, 0xE0, 0xE1, 0xE3, 0xE3, 0xE6, +0xE9, 0xEB, 0xEF, 0xF7, 0x7F, 0x75, 0x6E, 0x6A, 0x66, 0x62, 0x61, 0x5F, 0x5F, 0x60, 0x5F, 0x62, +0x65, 0x66, 0x6C, 0x6E, 0x72, 0x7D, 0xFE, 0xF6, 0xEF, 0xED, 0xE9, 0xE7, 0xE4, 0xE3, 0xE0, 0xDF, +0xE1, 0xDF, 0xE1, 0xE3, 0xE3, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xF5, 0xF6, 0xF9, 0x75, +0x76, 0x6E, 0x66, 0x65, 0x5E, 0x5B, 0x5A, 0x56, 0x55, 0x54, 0x53, 0x54, 0x55, 0x57, 0x59, 0x5D, +0x60, 0x66, 0x70, 0x79, 0xFA, 0xF0, 0xEE, 0xEC, 0xED, 0xED, 0xF0, 0xF5, 0xF8, 0xFF, 0xFD, 0x7E, +0x7D, 0xFE, 0x7E, 0xFD, 0xF8, 0xF6, 0xEF, 0xED, 0xEB, 0xE8, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDC, +0xDD, 0xDC, 0xDD, 0xE1, 0xE2, 0xE9, 0xF3, 0x7A, 0x65, 0x61, 0x5B, 0x56, 0x56, 0x51, 0x50, 0x52, +0x50, 0x55, 0x58, 0x59, 0x5F, 0x68, 0x70, 0xFC, 0xEE, 0xE9, 0xE4, 0xE1, 0xE4, 0xE4, 0xE7, 0xED, +0xEE, 0xF8, 0xFF, 0x7D, 0x76, 0x76, 0x7A, 0x7B, 0xFF, 0xF9, 0xF7, 0xF1, 0xED, 0xED, 0xEB, 0xE9, +0xEA, 0xEA, 0xEC, 0xED, 0xEE, 0xF0, 0xF1, 0xF2, 0xF2, 0xF3, 0xF0, 0xF1, 0xF3, 0xEF, 0xF3, 0xF5, +0xF4, 0xFB, 0xFC, 0xFC, 0x7C, 0x7A, 0x76, 0x70, 0x6F, 0x6F, 0x6C, 0x6C, 0x6C, 0x68, 0x6B, 0x6B, +0x68, 0x6D, 0x6B, 0x6B, 0x6F, 0x6E, 0x70, 0x77, 0x76, 0x7A, 0x7F, 0xFF, 0xFD, 0xF6, 0xF7, 0xF5, +0xEF, 0xF4, 0xF1, 0xEF, 0xF2, 0xEE, 0xF0, 0xF1, 0xEE, 0xF0, 0xF1, 0xF1, 0xF2, 0xF6, 0xF9, 0xFA, +0x7F, 0x7E, 0x7A, 0x76, 0x7A, 0x73, 0x72, 0x74, 0x6F, 0x73, 0x75, 0x73, 0x75, 0x74, 0x76, 0x73, +0x77, 0x7A, 0x76, 0x7E, 0x78, 0x76, 0x7E, 0x76, 0x7A, 0x79, 0x74, 0x7D, 0x77, 0x77, 0x79, 0x74, +0x76, 0x77, 0x7A, 0x79, 0x7C, 0xFF, 0x79, 0xFC, 0xFA, 0x7E, 0xF4, 0xF9, 0xFC, 0xF6, 0x7E, 0xFF, +0xFF, 0x7B, 0x7C, 0x77, 0x75, 0x76, 0x78, 0x76, 0x74, 0x7B, 0x74, 0x75, 0x7E, 0x74, 0x7B, 0x7C, +0x72, 0x7A, 0x77, 0x74, 0x7A, 0x75, 0x72, 0x73, 0x72, 0x6E, 0x6E, 0x70, 0x6D, 0x70, 0x71, 0x6E, +0x75, 0x73, 0x72, 0x79, 0x78, 0x7B, 0xFF, 0xFF, 0xFD, 0xFA, 0xFC, 0xFB, 0xF7, 0xFD, 0xFE, 0xFA, +0x7D, 0x7D, 0xFE, 0x79, 0x7B, 0x7C, 0x7B, 0x7E, 0x7E, 0xFD, 0xFA, 0xFA, 0xF7, 0xF8, 0xF9, 0xF9, +0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x7D, 0x7B, 0x77, 0x78, 0x74, 0x71, 0x74, 0x6F, 0x6F, 0x71, 0x6D, +0x6F, 0x71, 0x6F, 0x73, 0x74, 0x77, 0x7B, 0x7D, 0x7F, 0xFF, 0xFC, 0xFE, 0xFB, 0xF8, 0xFB, 0xF7, +0xF9, 0xFE, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7E, 0x7B, 0x7B, 0x7E, 0x7C, 0xFF, 0xFE, +0xFE, 0xFB, 0xFE, 0xFF, 0xFD, 0xFE, 0x7E, 0x7F, 0x7A, 0x78, 0x79, 0x75, 0x74, 0x75, 0x73, 0x75, +0x77, 0x77, 0x79, 0x7B, 0x7D, 0xFF, 0xFA, 0xF8, 0xF4, 0xF2, 0xF5, 0xF1, 0xF2, 0xF6, 0xF3, 0xF6, +0xFA, 0xFB, 0xFC, 0x7D, 0x7A, 0x7A, 0x74, 0x77, 0x78, 0x74, 0x7A, 0x77, 0x7A, 0xFF, 0x7F, 0xF9, +0xFB, 0xFB, 0xF9, 0xFF, 0x7F, 0x7C, 0x7A, 0x77, 0x72, 0x73, 0x6E, 0x6E, 0x6E, 0x6D, 0x70, 0x70, +0x75, 0x7D, 0x7B, 0xFE, 0xFD, 0xFF, 0xFC, 0xFF, 0x7E, 0xFF, 0x7E, 0x7A, 0x79, 0x76, 0x6F, 0x72, +0x72, 0x6F, 0x73, 0x6F, 0x6E, 0x74, 0x72, 0x74, 0x7C, 0x7C, 0xFF, 0xF9, 0xFA, 0xF9, 0xF5, 0xF7, +0xF7, 0xF5, 0xFA, 0xFA, 0xF7, 0xFA, 0xF9, 0xF8, 0xFC, 0xF9, 0xF8, 0xFA, 0xF6, 0xF9, 0xFC, 0xFA, +0xFD, 0xFE, 0xFD, 0xFF, 0x7E, 0x7E, 0x7D, 0x7A, 0x7C, 0x7B, 0x79, 0x7C, 0x7B, 0x7B, 0xFF, 0x7E, +0xFF, 0xFC, 0xFE, 0xFE, 0xFB, 0xFD, 0x7C, 0x7F, 0x7F, 0x76, 0x78, 0x78, 0x74, 0x78, 0x78, 0x78, +0x7B, 0x7A, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x78, 0x7A, 0x7B, 0x7A, 0x7C, 0x7F, 0x7D, 0xFF, 0xFC, +0xFD, 0xFA, 0xFB, 0xFD, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x7B, 0x7D, 0x7D, 0x7E, 0x7E, 0x7D, +0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, +0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, 0xFD, 0xFF, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x77, 0x78, +0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFC, 0xFC, 0xFC, +0xFE, 0xFF, 0xFF, 0x7E, 0x7B, 0x78, 0x77, 0x76, 0x74, 0x73, 0x73, 0x71, 0x72, 0x73, 0x73, 0x74, +0x75, 0x76, 0x77, 0x77, 0x78, 0x78, 0x7A, 0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0x7F, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7A, +0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7A, 0x7A, 0x79, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, +0x74, 0x77, 0x79, 0x7A, 0x7D, 0x7F, 0xFE, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFF, +0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4C, 0x49, 0x53, 0x54, 0x4A, 0x00, +0x00, 0x00, 0x49, 0x4E, 0x46, 0x4F, 0x49, 0x53, 0x46, 0x54, 0x3E, 0x00, 0x00, 0x00, 0x46, 0x69, +0x6C, 0x65, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x6F, +0x6C, 0x64, 0x57, 0x61, 0x76, 0x65, 0x2E, 0x20, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x57, 0x61, 0x76, +0x65, 0x20, 0x63, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, +0x43, 0x68, 0x72, 0x69, 0x73, 0x20, 0x43, 0x72, 0x61, 0x69, 0x67, 0x00 + +}; + +static const uint8_t shaun_png[] PROGMEM = { + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x08, 0x06, 0x00, 0x00, 0x00, 0xF2, 0x0C, 0xE0, + 0x57, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4B, 0x47, 0x44, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xA0, + 0xBD, 0xA7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x42, 0x8A, 0x00, + 0x00, 0x42, 0x8A, 0x01, 0x34, 0xA8, 0x6C, 0x25, 0x00, 0x00, 0x00, 0x09, 0x76, 0x70, 0x41, 0x67, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x00, 0x73, 0x4D, 0x3B, 0xD6, 0x00, 0x00, 0x1B, + 0x47, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0xED, 0x9D, 0x79, 0x74, 0x14, 0x55, 0xBE, 0xC7, 0x3F, + 0x55, 0xDD, 0x49, 0x67, 0x5F, 0x3A, 0x7B, 0x42, 0x82, 0x61, 0x49, 0x02, 0x81, 0xB0, 0x29, 0x32, + 0x22, 0x3C, 0x16, 0x41, 0x45, 0x10, 0x15, 0x7D, 0x13, 0x65, 0xD0, 0x81, 0xE3, 0x7B, 0xCC, 0xD3, + 0x51, 0x04, 0xF5, 0xE1, 0xB8, 0xCE, 0xE6, 0x28, 0x22, 0x23, 0x33, 0x2C, 0x2A, 0x22, 0xEE, 0x02, + 0x22, 0x0C, 0x2A, 0x83, 0x28, 0x7B, 0x20, 0xC8, 0x92, 0x10, 0xD9, 0x97, 0x40, 0x08, 0x81, 0x90, + 0x3D, 0x64, 0x21, 0xE9, 0x4E, 0x3A, 0x5D, 0xF7, 0xFD, 0x71, 0xBB, 0x93, 0x0E, 0x10, 0xD2, 0x59, + 0x3A, 0x01, 0xCF, 0xFB, 0x9E, 0xD3, 0xE7, 0xA4, 0x6E, 0xA5, 0x6E, 0xDD, 0xFA, 0xFD, 0xEA, 0xFE, + 0xEE, 0xEF, 0xFE, 0xB6, 0x52, 0xB8, 0xFE, 0xA1, 0x03, 0x7A, 0x01, 0x43, 0x81, 0x9B, 0x80, 0x6A, + 0x60, 0x3F, 0xA0, 0x02, 0x8F, 0x00, 0xB7, 0x03, 0xA1, 0x80, 0x00, 0x72, 0x81, 0xAD, 0xC0, 0xC7, + 0xC0, 0x6E, 0xA0, 0xAE, 0xB3, 0x07, 0xFF, 0x4B, 0x43, 0x30, 0xF0, 0x67, 0x20, 0x1B, 0xB0, 0x20, + 0x89, 0xAE, 0x01, 0x95, 0x40, 0xB9, 0xED, 0xF8, 0x6A, 0xBF, 0x3C, 0xDB, 0x75, 0x81, 0xCD, 0xF4, + 0xAF, 0x03, 0x8C, 0x40, 0x2C, 0xD0, 0x13, 0x88, 0x00, 0x0C, 0x9D, 0xF9, 0xC0, 0x4A, 0x27, 0xDD, + 0xD7, 0x13, 0x88, 0x07, 0xFA, 0x03, 0x51, 0x36, 0x22, 0xE4, 0x03, 0x87, 0x80, 0x83, 0x48, 0x62, + 0x1B, 0x81, 0x85, 0x40, 0x72, 0x2B, 0xC7, 0xA9, 0x01, 0x5F, 0x00, 0x2F, 0x03, 0x35, 0xB6, 0xE3, + 0x0A, 0xDB, 0xDF, 0xDE, 0xC0, 0x48, 0x60, 0x22, 0x30, 0x08, 0xC9, 0x78, 0x3D, 0x92, 0xD1, 0x99, + 0xC0, 0x0F, 0xC0, 0x5A, 0xE0, 0x5C, 0x47, 0x13, 0xA6, 0xA3, 0x19, 0xA2, 0x07, 0x46, 0x00, 0x4F, + 0x22, 0x45, 0x4D, 0xD0, 0x65, 0x63, 0xB8, 0x84, 0x14, 0x47, 0xEF, 0x03, 0x09, 0xC0, 0x4B, 0x48, + 0xD1, 0x44, 0x40, 0x40, 0x00, 0x31, 0x31, 0x31, 0x54, 0x56, 0x56, 0x92, 0x93, 0x93, 0x83, 0xD5, + 0x6A, 0x25, 0x3A, 0x3A, 0x9A, 0x89, 0x13, 0x27, 0x32, 0x60, 0xC0, 0x00, 0xAC, 0x56, 0x2B, 0xBB, + 0x77, 0xEF, 0x66, 0xDD, 0xBA, 0x75, 0x14, 0x16, 0x16, 0xDA, 0xFB, 0xAB, 0x03, 0x4E, 0x23, 0x67, + 0x4D, 0x9D, 0x8D, 0xC0, 0xFB, 0x90, 0x22, 0xF0, 0x1E, 0xC0, 0xAB, 0x89, 0x71, 0x6A, 0xC0, 0x11, + 0xE0, 0x0D, 0xE0, 0x6B, 0xE4, 0xEC, 0xFC, 0xC5, 0xC1, 0x07, 0x78, 0x0D, 0x28, 0xA5, 0x69, 0x51, + 0x63, 0xFF, 0x99, 0x80, 0x2A, 0xFB, 0xF1, 0xC0, 0x81, 0x03, 0xC5, 0xA6, 0x4D, 0x9B, 0x44, 0x49, + 0x49, 0x89, 0xC8, 0xCA, 0xCA, 0x12, 0xAF, 0xBF, 0xFE, 0xBA, 0x78, 0xFC, 0xF1, 0xC7, 0x45, 0x5A, + 0x5A, 0x9A, 0xD0, 0x34, 0x4D, 0xD8, 0x51, 0x57, 0x57, 0x27, 0xB6, 0x6E, 0xDD, 0x2A, 0xFA, 0xF7, + 0xEF, 0xDF, 0x5C, 0xFF, 0x8D, 0x7E, 0x8A, 0xA2, 0x08, 0x55, 0x55, 0xAF, 0x76, 0xAE, 0x02, 0x78, + 0x0E, 0xF9, 0x22, 0x75, 0x08, 0x3A, 0x6A, 0x86, 0x78, 0x02, 0x7F, 0x05, 0x9E, 0x02, 0xDC, 0x00, + 0x14, 0x45, 0x21, 0x24, 0x24, 0x84, 0xE8, 0xE8, 0x68, 0xDC, 0xDD, 0xDD, 0xB9, 0x70, 0xE1, 0x02, + 0xB9, 0xB9, 0xB9, 0xD4, 0xD5, 0x35, 0x5E, 0x87, 0xBD, 0xBC, 0xBC, 0x58, 0xB1, 0x62, 0x05, 0x13, + 0x26, 0x4C, 0xA8, 0x6F, 0x13, 0x42, 0x20, 0x84, 0x40, 0x55, 0xD5, 0xAB, 0xDE, 0x6C, 0xD7, 0xAE, + 0x5D, 0x3C, 0xFC, 0xF0, 0xC3, 0xE4, 0xE4, 0xE4, 0x34, 0xFD, 0xE0, 0x8A, 0x42, 0x7C, 0x7C, 0x3C, + 0xF7, 0xDC, 0x73, 0x0F, 0xFD, 0xFA, 0xF5, 0xC3, 0xC3, 0xC3, 0x83, 0xEC, 0xEC, 0x6C, 0x36, 0x6C, + 0xD8, 0x40, 0x6A, 0x6A, 0x2A, 0x35, 0x35, 0x35, 0xF6, 0x7F, 0xAD, 0xB4, 0x8D, 0xFB, 0x73, 0xC0, + 0xDA, 0x41, 0xF4, 0x72, 0x39, 0x7E, 0x8F, 0x7C, 0xEB, 0x05, 0x20, 0xC2, 0xC2, 0xC2, 0xC4, 0x2B, + 0xAF, 0xBC, 0x22, 0x0E, 0x1E, 0x3C, 0x28, 0x2E, 0x5E, 0xBC, 0x28, 0x2A, 0x2A, 0x2A, 0x44, 0x56, + 0x56, 0x96, 0x58, 0xBC, 0x78, 0xB1, 0x48, 0x48, 0x48, 0x68, 0xF4, 0x96, 0xC6, 0xC4, 0xC4, 0x88, + 0x33, 0x67, 0xCE, 0x88, 0x96, 0xE2, 0xE3, 0x8F, 0x3F, 0x16, 0x77, 0xDE, 0x79, 0xA7, 0x78, 0xFE, + 0xF9, 0xE7, 0xC5, 0xBB, 0xEF, 0xBE, 0x2B, 0xDE, 0x7E, 0xFB, 0x6D, 0xF1, 0xE0, 0x83, 0x0F, 0x0A, + 0xA3, 0xD1, 0x28, 0xDC, 0xDC, 0xDC, 0xC4, 0xD4, 0xA9, 0x53, 0xC5, 0xE9, 0xD3, 0xA7, 0xAF, 0xB8, + 0xAE, 0xA2, 0xA2, 0x42, 0x2C, 0x58, 0xB0, 0x40, 0x04, 0x07, 0x07, 0x3B, 0x8E, 0xA3, 0x00, 0x58, + 0x0D, 0xFC, 0x0E, 0x08, 0xEF, 0x6C, 0x62, 0xB6, 0x15, 0x7D, 0x80, 0x33, 0xF6, 0x87, 0x8B, 0x8D, + 0x8D, 0x15, 0xEB, 0xD7, 0xAF, 0x6F, 0x24, 0x6A, 0x1C, 0x91, 0x91, 0x91, 0x21, 0x06, 0x0F, 0x1E, + 0x2C, 0x00, 0x61, 0x30, 0x18, 0xC4, 0xAF, 0x7F, 0xFD, 0x6B, 0x51, 0x51, 0x51, 0xD1, 0x62, 0x86, + 0x58, 0xAD, 0x56, 0x61, 0x36, 0x9B, 0x1B, 0xDD, 0xA7, 0xA6, 0xA6, 0x46, 0xEC, 0xD8, 0xB1, 0x43, + 0xAC, 0x5A, 0xB5, 0x4A, 0x94, 0x97, 0x97, 0x37, 0x79, 0xAD, 0xA6, 0x69, 0x62, 0xF1, 0xE2, 0xC5, + 0xC2, 0xC3, 0xC3, 0xE3, 0x72, 0x11, 0x66, 0x05, 0x76, 0x02, 0x43, 0x3A, 0x9B, 0xA8, 0x6D, 0xC1, + 0xDB, 0xF6, 0x07, 0xF2, 0xF5, 0xF5, 0x15, 0x2B, 0x56, 0xAC, 0x68, 0x96, 0x98, 0xC7, 0x8E, 0x1D, + 0x13, 0xF3, 0xE7, 0xCF, 0x17, 0x1B, 0x36, 0x6C, 0x10, 0xA5, 0xA5, 0xA5, 0x2D, 0x66, 0x46, 0x7B, + 0xA0, 0xB2, 0xB2, 0x52, 0x4C, 0x98, 0x30, 0xA1, 0xA9, 0x75, 0xE7, 0x00, 0x52, 0x31, 0x68, 0x77, + 0xB8, 0x7A, 0x0D, 0x89, 0x02, 0x36, 0xDA, 0x07, 0x3F, 0x79, 0xF2, 0x64, 0x3E, 0xFC, 0xF0, 0x43, + 0x0C, 0x86, 0x4E, 0x55, 0xF5, 0x9D, 0xC6, 0xC1, 0x83, 0x07, 0x59, 0xBB, 0x76, 0x2D, 0x16, 0x8B, + 0x85, 0x94, 0x94, 0x14, 0x52, 0x53, 0x53, 0xB1, 0x5A, 0xEB, 0x97, 0x91, 0xF7, 0x91, 0xDA, 0xE2, + 0x0D, 0xB5, 0xAE, 0x8C, 0x07, 0xCC, 0x80, 0xF0, 0xF4, 0xF4, 0x14, 0xEB, 0xD6, 0xAD, 0xEB, 0x94, + 0xB7, 0xBD, 0x3D, 0x50, 0x54, 0x54, 0x24, 0x92, 0x93, 0x93, 0x1D, 0x67, 0x49, 0x36, 0xD0, 0xBD, + 0xB3, 0x09, 0xDC, 0x12, 0x84, 0x00, 0xAB, 0xEC, 0x0F, 0x10, 0x1F, 0x1F, 0x2F, 0x72, 0x73, 0x73, + 0x3B, 0x9B, 0xAE, 0x6D, 0xC2, 0x96, 0x2D, 0x5B, 0x84, 0x8F, 0x8F, 0x8F, 0xA3, 0x6A, 0x7E, 0x47, + 0x7B, 0x13, 0x4D, 0x6D, 0x7B, 0x17, 0x57, 0x85, 0x37, 0x72, 0x53, 0x35, 0xC9, 0xDE, 0xD0, 0xAD, + 0x5B, 0x37, 0x8C, 0x46, 0xA3, 0x8B, 0x6E, 0xD7, 0x31, 0xF0, 0xF5, 0xF5, 0x45, 0xAF, 0xAF, 0xDF, + 0x92, 0xA8, 0x80, 0x47, 0x7B, 0xDF, 0xC3, 0x55, 0x0C, 0xF9, 0x4F, 0xE0, 0x37, 0xD8, 0xD6, 0xA8, + 0x84, 0x84, 0x04, 0x9E, 0x7E, 0xFA, 0x69, 0x3C, 0x3C, 0xDA, 0x7D, 0xFC, 0x1D, 0x8A, 0x5D, 0xBB, + 0x76, 0x51, 0x56, 0x56, 0x66, 0x3F, 0xAC, 0x42, 0xDA, 0xCC, 0xDA, 0x15, 0xAE, 0xD8, 0x81, 0x1A, + 0x81, 0xC7, 0xB1, 0x19, 0xE9, 0x12, 0x12, 0x12, 0xF8, 0xEC, 0xB3, 0xCF, 0xB8, 0xF9, 0xE6, 0x9B, + 0x5D, 0x44, 0xA6, 0x8E, 0x43, 0x5E, 0x5E, 0x23, 0xFA, 0x0B, 0x5C, 0xF7, 0x42, 0xB7, 0x2B, 0x46, + 0x21, 0x6D, 0x52, 0x42, 0xAF, 0xD7, 0x8B, 0x25, 0x4B, 0x96, 0x74, 0xB6, 0xE8, 0x6F, 0x37, 0xEC, + 0xDD, 0xBB, 0x57, 0x84, 0x86, 0x86, 0x3A, 0x2E, 0xEC, 0xB3, 0xDB, 0x9B, 0x78, 0xAE, 0xE0, 0x70, + 0x12, 0x72, 0x0D, 0xA1, 0x6B, 0xD7, 0xAE, 0x8C, 0x1D, 0x3B, 0xD6, 0x85, 0xBC, 0xEF, 0x58, 0x24, + 0x25, 0x25, 0x31, 0x64, 0x48, 0xA3, 0x3D, 0xE1, 0x2D, 0xB4, 0xB3, 0x94, 0x71, 0x05, 0x43, 0x22, + 0xED, 0x7F, 0x44, 0x47, 0x47, 0x13, 0x12, 0x12, 0xE2, 0x1A, 0xEA, 0x74, 0x02, 0x0C, 0x06, 0x03, + 0x89, 0x89, 0x89, 0x8E, 0x4D, 0x51, 0x48, 0x3B, 0x5D, 0xBB, 0xC1, 0x15, 0x0C, 0xA9, 0xEF, 0x53, + 0xA7, 0xD3, 0x35, 0x69, 0x00, 0xBC, 0x51, 0xE1, 0xEB, 0xEB, 0xEB, 0x78, 0x68, 0xE0, 0x06, 0x98, + 0x21, 0xF5, 0xCE, 0x88, 0xBC, 0xBC, 0x3C, 0x47, 0xAD, 0xE4, 0x17, 0x81, 0xD2, 0xD2, 0x52, 0xC7, + 0xC3, 0x6A, 0xDA, 0xD9, 0x57, 0xE2, 0x0A, 0x86, 0x1C, 0x46, 0xEE, 0xCE, 0xC9, 0xCA, 0xCA, 0x22, + 0x35, 0x35, 0xD5, 0x65, 0xC4, 0xE9, 0x68, 0x54, 0x55, 0x55, 0x91, 0x91, 0x91, 0xE1, 0xD8, 0x94, + 0x8D, 0x64, 0xCA, 0x75, 0x8D, 0x70, 0xE0, 0x67, 0x6C, 0x9A, 0xC8, 0xD0, 0xA1, 0x43, 0x45, 0x76, + 0x76, 0x76, 0x67, 0x2B, 0x48, 0xED, 0x82, 0x1F, 0x7E, 0xF8, 0x41, 0xF8, 0xF9, 0xF9, 0x39, 0x6A, + 0x59, 0x4F, 0x74, 0x36, 0xB1, 0x9D, 0xC5, 0x73, 0x48, 0xA3, 0x9B, 0x00, 0xC4, 0xC8, 0x91, 0x23, + 0xC5, 0x8F, 0x3F, 0xFE, 0x28, 0xCC, 0x66, 0xB3, 0xCB, 0x88, 0x65, 0xB5, 0x5A, 0x5D, 0xCA, 0x8C, + 0xAC, 0xAC, 0x2C, 0x31, 0x6C, 0xD8, 0x30, 0x47, 0x66, 0x64, 0x01, 0x71, 0x9D, 0x4D, 0x68, 0x67, + 0x61, 0x04, 0xD6, 0x39, 0x0C, 0x5E, 0xF8, 0xF8, 0xF8, 0x88, 0x05, 0x0B, 0x16, 0xB8, 0x84, 0x58, + 0x99, 0x99, 0x99, 0x62, 0xFA, 0xF4, 0xE9, 0x62, 0xD9, 0xB2, 0x65, 0xC2, 0x64, 0x32, 0x5D, 0x71, + 0x5E, 0xD3, 0x34, 0x71, 0xEE, 0xDC, 0x39, 0x91, 0x97, 0x97, 0xD7, 0xAA, 0xFE, 0x4F, 0x9E, 0x3C, + 0x29, 0x46, 0x8C, 0x18, 0x71, 0xB9, 0x09, 0xFE, 0xF5, 0xCE, 0x26, 0xB2, 0xB3, 0x08, 0x46, 0x5A, + 0x79, 0x1B, 0x31, 0x04, 0x10, 0x49, 0x49, 0x49, 0x22, 0x27, 0x27, 0xA7, 0x5D, 0x99, 0x61, 0xB5, + 0x5A, 0xC5, 0x8C, 0x19, 0x33, 0x04, 0x20, 0xBC, 0xBC, 0xBC, 0xC4, 0xA3, 0x8F, 0x3E, 0x2A, 0x36, + 0x6F, 0xDE, 0x2C, 0xCE, 0x9F, 0x3F, 0x2F, 0x0A, 0x0B, 0x0B, 0xC5, 0xE1, 0xC3, 0x87, 0xC5, 0xDC, + 0xB9, 0x73, 0x45, 0x42, 0x42, 0x82, 0x18, 0x33, 0x66, 0x8C, 0x28, 0x28, 0x28, 0x68, 0xF1, 0x3D, + 0x96, 0x2E, 0x5D, 0x7A, 0x39, 0x33, 0x34, 0x60, 0x3B, 0xF0, 0xDF, 0x40, 0x37, 0x64, 0x38, 0xD1, + 0x75, 0x87, 0x28, 0xA4, 0xEF, 0x79, 0x2F, 0x36, 0x93, 0x3B, 0x57, 0x09, 0x26, 0x98, 0x35, 0x6B, + 0x56, 0xBB, 0x8A, 0xAE, 0x6D, 0xDB, 0xB6, 0x89, 0xD0, 0xD0, 0x50, 0xE1, 0xED, 0x69, 0x10, 0xE1, + 0xC1, 0x01, 0x02, 0x10, 0x9E, 0x5E, 0x5E, 0xA2, 0x5B, 0xB7, 0xEE, 0xA2, 0x57, 0xAF, 0x5E, 0x22, + 0x38, 0x24, 0x44, 0x28, 0x8A, 0x22, 0x00, 0xE1, 0xE6, 0xE6, 0x26, 0x3E, 0xFA, 0xE8, 0xA3, 0x16, + 0xDF, 0x63, 0xCD, 0x9A, 0x35, 0x42, 0xAF, 0xD7, 0x5F, 0xCD, 0x51, 0x55, 0x87, 0x14, 0x5D, 0x0B, + 0x80, 0x5B, 0x01, 0xF7, 0xB6, 0x12, 0xB1, 0x3D, 0x38, 0x1B, 0x0A, 0x4C, 0x07, 0xE6, 0x21, 0x0D, + 0x8A, 0x5D, 0x70, 0xD0, 0xCD, 0x75, 0x3A, 0x1D, 0xE1, 0xE1, 0xE1, 0x24, 0x25, 0x25, 0x61, 0x36, + 0x9B, 0x49, 0x4D, 0x4D, 0xC5, 0x64, 0x32, 0xD1, 0xB7, 0x6F, 0x5F, 0x7C, 0x7C, 0x7C, 0x00, 0x19, + 0xB4, 0x50, 0x50, 0x50, 0x40, 0x59, 0x59, 0x19, 0xBE, 0xBE, 0xBE, 0x28, 0x8A, 0x73, 0x7E, 0xB3, + 0xEC, 0xEC, 0x6C, 0x9E, 0x7E, 0xFA, 0x69, 0x8E, 0x1D, 0x3B, 0xC6, 0x8C, 0x87, 0xC7, 0x31, 0x77, + 0xC6, 0x14, 0x02, 0xFD, 0x7C, 0xA8, 0xAA, 0x36, 0x51, 0x5A, 0x5A, 0x42, 0x65, 0x45, 0x39, 0x81, + 0x3E, 0x06, 0xEE, 0xFC, 0x55, 0x7F, 0x86, 0x0D, 0x48, 0x20, 0xFD, 0xE8, 0x69, 0xB2, 0xB3, 0xCF, + 0x72, 0xC7, 0x1D, 0x77, 0xB4, 0xC8, 0xF2, 0xBC, 0x7E, 0xFD, 0x7A, 0x36, 0x6C, 0xD8, 0x80, 0x9F, + 0x9F, 0x1F, 0x3A, 0x9D, 0x0E, 0x8B, 0xA5, 0x5E, 0xD3, 0x55, 0x91, 0xC1, 0x78, 0x83, 0x81, 0xFB, + 0x81, 0xDE, 0x40, 0x11, 0xD2, 0xE8, 0xA8, 0xB5, 0x03, 0x6D, 0x5B, 0x04, 0x37, 0xA4, 0x68, 0x4A, + 0x45, 0xBE, 0x29, 0x8D, 0x66, 0x42, 0x97, 0x2E, 0x5D, 0xC4, 0x23, 0x8F, 0x3C, 0x22, 0x3E, 0xF9, + 0xE4, 0x13, 0x71, 0xEC, 0xD8, 0x31, 0x51, 0x55, 0x55, 0x25, 0x5E, 0x7A, 0xE9, 0x25, 0x01, 0x08, + 0x9D, 0x4E, 0x27, 0x06, 0x0E, 0x1A, 0x24, 0x66, 0xCF, 0x9E, 0x2D, 0xE6, 0xCF, 0x9F, 0x2F, 0x66, + 0xCE, 0x9C, 0x29, 0xFA, 0xF4, 0xE9, 0x23, 0x7A, 0xF7, 0xEE, 0x2D, 0xD6, 0xAC, 0x59, 0xE3, 0xD4, + 0x02, 0x9D, 0x99, 0x99, 0x29, 0xC6, 0x8D, 0x1B, 0x27, 0x95, 0x86, 0x9B, 0x13, 0x45, 0xEE, 0x86, + 0x25, 0x42, 0x64, 0xAC, 0x16, 0x5A, 0xFA, 0x2A, 0x51, 0xB6, 0xED, 0x63, 0x71, 0xFA, 0x9B, 0x05, + 0xE2, 0xF8, 0xD7, 0xF3, 0xC5, 0x85, 0x0D, 0xEF, 0x0B, 0xCB, 0xDE, 0x15, 0xA2, 0x74, 0xFB, 0x27, + 0x62, 0xFC, 0xB0, 0x41, 0x02, 0x10, 0x77, 0xDF, 0x7D, 0xB7, 0x38, 0x7A, 0xF4, 0x68, 0xA3, 0xFE, + 0x34, 0x4D, 0x13, 0xFB, 0xF7, 0xEF, 0x17, 0x6F, 0xBD, 0xF5, 0x96, 0xD8, 0xBD, 0x7B, 0xB7, 0xB0, + 0x58, 0x2C, 0xC2, 0x62, 0xB1, 0x88, 0x6D, 0xDB, 0xB6, 0x89, 0xB8, 0xB8, 0x38, 0xE1, 0xEE, 0xEE, + 0x2E, 0xDE, 0x7B, 0xEF, 0x3D, 0xB1, 0x69, 0xD3, 0x26, 0xF1, 0xDC, 0x73, 0xCF, 0x89, 0x7E, 0xFD, + 0xFA, 0x09, 0x77, 0x77, 0xF7, 0xAB, 0xCD, 0x9A, 0x12, 0xE0, 0x03, 0x64, 0x10, 0x60, 0x87, 0xC5, + 0xBD, 0x45, 0x20, 0x67, 0x44, 0x99, 0xE3, 0x60, 0x74, 0x3A, 0x9D, 0x48, 0x4A, 0x4A, 0x12, 0x6F, + 0xBE, 0xF9, 0xA6, 0x38, 0x76, 0xEC, 0x98, 0xB0, 0x58, 0x2C, 0xF5, 0x0F, 0x6C, 0x32, 0x99, 0xC4, + 0xA4, 0x49, 0x93, 0x04, 0x20, 0xBA, 0x84, 0x1A, 0x85, 0xA7, 0xC1, 0xAD, 0xD1, 0x83, 0x78, 0xB8, + 0xBB, 0x09, 0x9D, 0xAA, 0x8A, 0xA0, 0xA0, 0x20, 0xF1, 0xDA, 0x6B, 0xAF, 0x89, 0xB3, 0x67, 0xCF, + 0x5E, 0x35, 0x10, 0xA2, 0xA2, 0xA2, 0x42, 0xAC, 0x5C, 0xB9, 0x52, 0x0C, 0x18, 0x30, 0x40, 0x00, + 0xE2, 0x96, 0xDE, 0xDD, 0xC5, 0xC1, 0x95, 0x6F, 0x0B, 0xB1, 0xFF, 0x6B, 0x21, 0xD2, 0xBE, 0x92, + 0xBF, 0xF4, 0x55, 0x42, 0xEC, 0x5F, 0x25, 0xDB, 0xD2, 0x57, 0xC9, 0xB6, 0xFD, 0x5F, 0x8B, 0xC3, + 0x5F, 0xFD, 0x5D, 0x0C, 0x4E, 0xEC, 0x21, 0x00, 0xD1, 0xA3, 0x47, 0x0F, 0xF1, 0x87, 0x3F, 0xFC, + 0x41, 0xAC, 0x5A, 0xB5, 0x4A, 0xAC, 0x5C, 0xB9, 0x52, 0xCC, 0x9A, 0x35, 0x4B, 0xC4, 0xC4, 0xC4, + 0x08, 0x40, 0x84, 0x87, 0x87, 0x8B, 0xFB, 0xEE, 0xBB, 0x4F, 0x4C, 0x9C, 0x38, 0xB1, 0xDE, 0x98, + 0x38, 0x79, 0xF2, 0xE4, 0xFA, 0x60, 0x0B, 0x4D, 0xD3, 0x44, 0x7E, 0x7E, 0xBE, 0x58, 0xBE, 0x7C, + 0xB9, 0x18, 0x3F, 0x7E, 0xBC, 0xF0, 0xF5, 0xF5, 0xBD, 0x1A, 0x63, 0xCE, 0x21, 0x8D, 0x8F, 0xC1, + 0x2D, 0x21, 0x6C, 0x4B, 0x39, 0xA8, 0x20, 0x83, 0x9E, 0x5F, 0x07, 0x86, 0x39, 0x5E, 0x1F, 0x17, + 0x17, 0xC7, 0xF4, 0xE9, 0xD3, 0x49, 0x4E, 0x4E, 0x26, 0x32, 0x32, 0xF2, 0x8A, 0x0B, 0x77, 0xEC, + 0xD8, 0xC1, 0x84, 0x09, 0x13, 0xF0, 0xD4, 0x2B, 0x2C, 0xFF, 0xDB, 0x33, 0x58, 0xEA, 0xEA, 0x48, + 0x3B, 0x7A, 0x9A, 0xD2, 0x8A, 0x4B, 0x04, 0x07, 0xF8, 0x31, 0xA8, 0x57, 0x37, 0x52, 0x7F, 0x3E, + 0xCE, 0x3F, 0x96, 0xAF, 0xA7, 0xEC, 0x52, 0x35, 0x71, 0xF1, 0xF1, 0xDC, 0x39, 0x76, 0x2C, 0x03, + 0x07, 0x0E, 0x24, 0x28, 0x28, 0x88, 0xAA, 0xAA, 0x2A, 0x4E, 0x9C, 0x38, 0xC1, 0x96, 0x2D, 0x5B, + 0xD8, 0xB3, 0x67, 0x0F, 0x96, 0xDA, 0x5A, 0xEE, 0xBA, 0xAD, 0x3F, 0x73, 0x9F, 0x99, 0x42, 0xAF, + 0x6E, 0xD1, 0xA0, 0x39, 0x21, 0x21, 0x54, 0x95, 0x13, 0x67, 0xCE, 0xF3, 0xA7, 0x25, 0xAB, 0xF8, + 0x76, 0x7B, 0x1A, 0x55, 0xE6, 0x1A, 0xDB, 0x23, 0x08, 0x00, 0x02, 0x7C, 0xBD, 0x49, 0xEA, 0x19, + 0xC3, 0xD1, 0xAC, 0xF3, 0x14, 0x97, 0x55, 0xA2, 0x28, 0x0A, 0xE1, 0xE1, 0xE1, 0x24, 0x27, 0x27, + 0x33, 0x7B, 0xF6, 0x6C, 0xC2, 0xC2, 0xC2, 0xAE, 0xE8, 0xB2, 0xBA, 0xBA, 0x9A, 0xD4, 0xD4, 0x54, + 0x96, 0x2E, 0x5D, 0xCA, 0xF7, 0xDF, 0x7F, 0x4F, 0x65, 0x65, 0xA5, 0xE3, 0x69, 0x2B, 0xB0, 0x03, + 0xF8, 0x13, 0x90, 0x82, 0x13, 0x62, 0xAC, 0x25, 0x0C, 0x71, 0x03, 0x26, 0x03, 0x7F, 0x41, 0xAE, + 0x13, 0x80, 0xB4, 0xED, 0x4C, 0x99, 0x32, 0x85, 0x99, 0x33, 0x67, 0xD2, 0xA3, 0x47, 0x8F, 0xAB, + 0x5E, 0x28, 0x84, 0x60, 0xC6, 0x8C, 0x19, 0x2C, 0x58, 0xB0, 0x80, 0xA9, 0xF7, 0x8E, 0x64, 0xC9, + 0x2B, 0xBF, 0xB3, 0x79, 0xDE, 0x84, 0xA4, 0x85, 0x22, 0x87, 0x52, 0x67, 0xA9, 0x63, 0xEB, 0xDE, + 0x43, 0xFC, 0x73, 0xE5, 0xF7, 0x6C, 0x4F, 0x3F, 0x42, 0x65, 0xB5, 0x59, 0x0E, 0x52, 0x51, 0x11, + 0x42, 0x3E, 0x8B, 0x5E, 0xA7, 0x92, 0xD8, 0x2D, 0x9A, 0x69, 0x13, 0x47, 0x32, 0xE5, 0x9E, 0xFF, + 0x20, 0xD0, 0xDF, 0xD7, 0x39, 0x66, 0x38, 0x30, 0xA5, 0xDA, 0x64, 0x66, 0xD7, 0x81, 0x13, 0x6C, + 0xD9, 0x77, 0x98, 0xAC, 0xDC, 0x02, 0x54, 0x45, 0xA1, 0x67, 0x4C, 0x04, 0x63, 0x6E, 0x4D, 0x62, + 0x50, 0xAF, 0x6E, 0x7C, 0xBA, 0x6E, 0x3B, 0x4F, 0xCE, 0x59, 0x4A, 0x78, 0x44, 0x24, 0x5F, 0x7E, + 0xF9, 0x25, 0x43, 0x87, 0x0E, 0x45, 0xA7, 0xBB, 0xF6, 0x72, 0x6B, 0x36, 0x9B, 0xD9, 0xB6, 0x6D, + 0x1B, 0x0B, 0x17, 0x2E, 0x64, 0xD3, 0xA6, 0x4D, 0x8E, 0x81, 0x76, 0x20, 0xE3, 0xBA, 0xDE, 0x04, + 0x96, 0xD0, 0xCC, 0xCE, 0xDE, 0x59, 0x86, 0xF8, 0x02, 0xFF, 0x0B, 0x3C, 0x83, 0x0C, 0x09, 0x05, + 0x20, 0x31, 0x31, 0x91, 0x3F, 0xFE, 0xF1, 0x8F, 0xDC, 0x7B, 0xEF, 0xBD, 0xB8, 0xBB, 0x37, 0xAD, + 0x60, 0x9C, 0x39, 0x73, 0x86, 0x31, 0x63, 0xC7, 0x92, 0x9B, 0x73, 0x96, 0x7F, 0xCD, 0x7B, 0x9E, + 0xBB, 0x6E, 0x1F, 0x08, 0xD6, 0x26, 0x88, 0xA8, 0x53, 0xA9, 0xAA, 0x32, 0xF1, 0xF3, 0xF1, 0x33, + 0xEC, 0x3C, 0x70, 0x82, 0xE3, 0xD9, 0xB9, 0x54, 0x5C, 0xAA, 0xC6, 0xD3, 0xC3, 0x40, 0x4C, 0x78, + 0x30, 0x83, 0x13, 0xBB, 0x33, 0xA4, 0x6F, 0x1C, 0xE1, 0x21, 0x81, 0x36, 0xE1, 0x20, 0x9C, 0x67, + 0x86, 0xE3, 0x53, 0xAB, 0x2A, 0x08, 0xD0, 0xEA, 0xAC, 0xA0, 0x80, 0xAA, 0xD3, 0xD5, 0x4F, 0x96, + 0xBC, 0xA2, 0x52, 0xEE, 0x7A, 0xF2, 0xAF, 0x1C, 0x3D, 0x9B, 0xC7, 0x8A, 0xE5, 0xCB, 0x99, 0x34, + 0x69, 0x92, 0xD3, 0x5D, 0x57, 0x56, 0x56, 0xB2, 0x62, 0xC5, 0x0A, 0xE6, 0xCD, 0x9B, 0xC7, 0x89, + 0x13, 0x27, 0x1C, 0x4F, 0xD5, 0x00, 0xCB, 0x80, 0x57, 0x81, 0xE2, 0xB6, 0x30, 0x24, 0x10, 0x29, + 0xA2, 0xFE, 0x0B, 0x9B, 0xF6, 0xA4, 0xD7, 0xEB, 0x79, 0xE0, 0x81, 0x07, 0xF8, 0xF3, 0x9F, 0xFF, + 0x4C, 0x7C, 0x7C, 0x7C, 0xB3, 0x1D, 0x2C, 0x59, 0xB2, 0x84, 0xE9, 0xD3, 0xA7, 0x33, 0x6C, 0x40, + 0x02, 0xDF, 0xBE, 0xF3, 0x02, 0x01, 0xBE, 0xDE, 0xD7, 0x26, 0xA4, 0x9D, 0x60, 0x80, 0xB0, 0x6A, + 0x68, 0x9A, 0x86, 0xAA, 0x28, 0x28, 0x3A, 0x1D, 0x28, 0x8A, 0x9C, 0x11, 0xAD, 0x61, 0x84, 0xB3, + 0x50, 0x14, 0x5E, 0x5A, 0xB4, 0x9C, 0xBF, 0x2D, 0x5B, 0x43, 0x72, 0x72, 0x32, 0x9F, 0x7E, 0xFA, + 0x29, 0x6E, 0x6E, 0x6E, 0x2D, 0xEA, 0x22, 0x33, 0x33, 0x93, 0xD7, 0x5F, 0x7F, 0x9D, 0x15, 0x2B, + 0x56, 0x38, 0xCE, 0x16, 0x0D, 0x19, 0x01, 0x39, 0x13, 0x99, 0xCB, 0x72, 0x05, 0x9A, 0x33, 0x2E, + 0x86, 0x00, 0xFF, 0x40, 0xAA, 0xB5, 0x7A, 0x90, 0x22, 0xEA, 0x85, 0x17, 0x5E, 0x60, 0xC9, 0x92, + 0x25, 0x4E, 0x31, 0xC3, 0x6C, 0x36, 0xB3, 0x6E, 0xDD, 0x3A, 0x00, 0x26, 0x0C, 0xBF, 0x99, 0x00, + 0x7F, 0x9F, 0xE6, 0x89, 0x29, 0x90, 0x33, 0xC8, 0xAA, 0xA1, 0x00, 0x3A, 0x55, 0x95, 0xAA, 0xB0, + 0xA6, 0x81, 0xD5, 0xEA, 0x5A, 0x66, 0x00, 0xA8, 0x0A, 0x13, 0x86, 0x0F, 0x22, 0xC0, 0xD7, 0x8B, + 0x94, 0x94, 0x14, 0x32, 0x33, 0x33, 0x5B, 0xDC, 0x45, 0xCF, 0x9E, 0x3D, 0x59, 0xBC, 0x78, 0x31, + 0x73, 0xE6, 0xCC, 0x71, 0xF4, 0x09, 0xA9, 0xC0, 0x43, 0xC8, 0x7D, 0x4B, 0xC4, 0x55, 0x6F, 0x7D, + 0x8D, 0x3E, 0x8D, 0x34, 0xEC, 0x2D, 0x54, 0x80, 0x90, 0x90, 0x10, 0xDE, 0x79, 0xE7, 0x1D, 0x5E, + 0x7D, 0xF5, 0x55, 0xFC, 0xFD, 0xFD, 0x9D, 0x1A, 0xD8, 0xF1, 0xE3, 0xC7, 0xF9, 0x69, 0xF7, 0x6E, + 0x42, 0x02, 0xFD, 0x18, 0x3B, 0xA4, 0x9F, 0x7D, 0xFD, 0xBC, 0xBE, 0xA1, 0x69, 0xF4, 0xED, 0x11, + 0xC3, 0x2D, 0x89, 0x3D, 0xB8, 0x70, 0xE1, 0x02, 0x5B, 0xB7, 0x6E, 0x6D, 0x55, 0x37, 0x5E, 0x5E, + 0x5E, 0x3C, 0xF5, 0xD4, 0x53, 0x7C, 0xF0, 0xC1, 0x07, 0xC4, 0xC6, 0xC6, 0x3A, 0x9E, 0xBA, 0x1F, + 0x98, 0x03, 0x5C, 0x41, 0xC4, 0xA6, 0x18, 0xE2, 0x89, 0x4C, 0x1D, 0x98, 0x8C, 0x4D, 0xAC, 0x45, + 0x45, 0x45, 0xB1, 0x68, 0xD1, 0x22, 0xA6, 0x4D, 0x9B, 0xD6, 0xA2, 0xE9, 0xBB, 0x7D, 0xFB, 0x76, + 0x8A, 0x8B, 0x8A, 0xB8, 0xB5, 0x4F, 0x4F, 0xE2, 0xBB, 0x46, 0xB6, 0x6C, 0x01, 0xEE, 0x2C, 0x08, + 0xF0, 0xF6, 0xF6, 0x64, 0xDC, 0xD0, 0x01, 0x00, 0x6C, 0xD8, 0xB0, 0x01, 0xB3, 0xD9, 0xDC, 0xAA, + 0xAE, 0x54, 0x55, 0x65, 0xE2, 0xC4, 0x89, 0x2C, 0x5D, 0xBA, 0xF4, 0x72, 0xA5, 0xE7, 0x11, 0xE4, + 0xBA, 0xDC, 0xC8, 0xC1, 0x75, 0x35, 0x86, 0x28, 0xC0, 0xFF, 0x20, 0xC5, 0x94, 0x0A, 0x92, 0x19, + 0xEF, 0xBE, 0xFB, 0x2E, 0x0F, 0x3D, 0xF4, 0x90, 0xD3, 0xBB, 0x68, 0x90, 0xE2, 0x6A, 0xD3, 0xA6, + 0x4D, 0x00, 0x8C, 0x19, 0x92, 0x84, 0x87, 0xE7, 0x8D, 0x11, 0x42, 0x0A, 0x80, 0x80, 0x11, 0x83, + 0x12, 0x09, 0xF2, 0xF7, 0x21, 0x2D, 0x2D, 0x9D, 0xAC, 0xAC, 0xAC, 0x36, 0x75, 0x37, 0x6A, 0xD4, + 0x28, 0x16, 0x2D, 0x5A, 0x44, 0x54, 0x54, 0x94, 0xBD, 0x49, 0x87, 0xCC, 0x0A, 0xB8, 0xDF, 0xF1, + 0xFF, 0xAE, 0xC6, 0x90, 0x31, 0xC8, 0x0D, 0x8D, 0x01, 0xC0, 0x68, 0x34, 0x32, 0x6F, 0xDE, 0xBC, + 0x46, 0xF9, 0x19, 0xCE, 0x22, 0x3B, 0x3B, 0x9B, 0xF4, 0xFD, 0xFB, 0x09, 0xF2, 0xF7, 0x61, 0xF8, + 0x80, 0x5E, 0x37, 0x86, 0xB8, 0xB2, 0x43, 0x68, 0xC4, 0xC5, 0x44, 0x30, 0x20, 0x3E, 0x96, 0xFC, + 0xFC, 0x3C, 0x76, 0xED, 0xDA, 0xD5, 0xE6, 0x2E, 0xC7, 0x8E, 0x1D, 0xCB, 0x1B, 0x6F, 0xBC, 0xE1, + 0xE8, 0x06, 0xF6, 0x43, 0x66, 0x89, 0xDD, 0x64, 0x6F, 0xB8, 0x9C, 0x21, 0x91, 0x48, 0x51, 0x15, + 0x0A, 0xD2, 0xA9, 0xFF, 0xF2, 0xCB, 0x2F, 0xF3, 0xD0, 0x43, 0x0F, 0xB5, 0x6A, 0x00, 0xE9, 0xE9, + 0xE9, 0xE4, 0x5D, 0xC8, 0xA3, 0x4F, 0xF7, 0x18, 0x7A, 0x44, 0x87, 0x3B, 0xBF, 0x18, 0xAB, 0x2A, + 0xA8, 0xAA, 0x4C, 0xCC, 0x01, 0xD0, 0xA9, 0x52, 0xBB, 0x6A, 0x2D, 0x54, 0x05, 0x54, 0x15, 0xAB, + 0xA6, 0x61, 0xD5, 0xB4, 0xFA, 0xFE, 0xAF, 0x09, 0x01, 0x5E, 0x5E, 0x9E, 0x0C, 0x1F, 0xD8, 0x1B, + 0x80, 0x9D, 0x3B, 0x77, 0xA2, 0xB5, 0x83, 0xB8, 0x4D, 0x4E, 0x4E, 0x66, 0xFA, 0xF4, 0xE9, 0x8E, + 0x4D, 0xFD, 0x90, 0x41, 0xDB, 0x2A, 0x34, 0x96, 0x5F, 0x0A, 0x32, 0x21, 0xE5, 0x36, 0x7B, 0xC3, + 0x23, 0x8F, 0x3C, 0xC2, 0xF4, 0xE9, 0xD3, 0x5B, 0x1D, 0xA8, 0x20, 0xDD, 0xB7, 0x82, 0xDB, 0xFA, + 0xC5, 0xE3, 0xE3, 0xED, 0x09, 0x5A, 0x33, 0x0C, 0x51, 0x14, 0xAC, 0x9A, 0x46, 0xFA, 0xA1, 0x93, + 0xFC, 0x7B, 0xE7, 0x7E, 0x4E, 0x9D, 0xCB, 0xC7, 0xDB, 0xD3, 0xC0, 0x6D, 0x49, 0xF1, 0x8C, 0xBB, + 0x7D, 0x20, 0xA1, 0x41, 0x01, 0x2D, 0x5F, 0x83, 0x14, 0x85, 0x53, 0x39, 0x79, 0xFC, 0x6B, 0xCB, + 0x5E, 0xD2, 0x8F, 0x67, 0x61, 0xB5, 0x6A, 0x24, 0x76, 0x8F, 0xE6, 0xFE, 0x11, 0xB7, 0xD0, 0x37, + 0xEE, 0xA6, 0x6B, 0xAB, 0x99, 0x8A, 0xC2, 0xAD, 0x7D, 0x7B, 0xE2, 0xAE, 0xD7, 0x91, 0x91, 0x91, + 0x41, 0x49, 0x49, 0x49, 0x9B, 0xA3, 0x68, 0xDC, 0xDC, 0xDC, 0x78, 0xE6, 0x99, 0x67, 0x48, 0x49, + 0x49, 0x61, 0xEF, 0xDE, 0xBD, 0xF6, 0xE6, 0xC9, 0xC0, 0x72, 0x60, 0xBF, 0x23, 0x43, 0xFA, 0x03, + 0x53, 0xED, 0x07, 0x7D, 0xFA, 0xF4, 0xE1, 0xC5, 0x17, 0x5F, 0xC4, 0xCB, 0xCB, 0xCB, 0xE9, 0x9B, + 0x39, 0xA2, 0xAC, 0xAC, 0x8C, 0xFD, 0xFB, 0xF7, 0xA3, 0x53, 0x15, 0x86, 0xF4, 0xED, 0x09, 0x8A, + 0x4A, 0x73, 0x91, 0xFB, 0xB5, 0x96, 0x3A, 0x16, 0xAE, 0xFC, 0x9E, 0x39, 0x1F, 0x7F, 0x43, 0xE1, + 0xC5, 0xF2, 0xFA, 0xF6, 0x65, 0xDF, 0x6C, 0x65, 0xD8, 0x80, 0x04, 0xDE, 0x79, 0x76, 0x2A, 0xFD, + 0x13, 0x62, 0x9D, 0x67, 0x8A, 0xA2, 0xF0, 0x7D, 0xEA, 0x7E, 0x9E, 0x7D, 0xE7, 0x53, 0x8E, 0x9D, + 0x69, 0x50, 0xFB, 0xBF, 0xDE, 0xBC, 0x9B, 0x0F, 0xD7, 0x6E, 0xE6, 0x2F, 0xFF, 0x93, 0xCC, 0xA3, + 0xE3, 0xFF, 0x03, 0xB5, 0xA9, 0xD9, 0xA7, 0x69, 0xF4, 0x8E, 0xED, 0x42, 0xD7, 0x88, 0x10, 0x4E, + 0x67, 0x65, 0x71, 0xF2, 0xE4, 0xC9, 0x76, 0x09, 0x6B, 0x8A, 0x8A, 0x8A, 0x62, 0xE6, 0xCC, 0x99, + 0x4C, 0x9D, 0x3A, 0xD5, 0xAE, 0x2C, 0x44, 0x00, 0x8F, 0x02, 0x19, 0xF6, 0x17, 0x44, 0x05, 0xA6, + 0x61, 0x33, 0x89, 0xB8, 0xBB, 0xBB, 0x33, 0x6B, 0xD6, 0xAC, 0x26, 0x4D, 0x21, 0xCE, 0xE0, 0xEC, + 0xD9, 0xB3, 0x64, 0x9E, 0x3A, 0x45, 0x44, 0x70, 0x20, 0xBD, 0xBB, 0x75, 0x01, 0xD1, 0x0C, 0x11, + 0x55, 0x95, 0x55, 0x9B, 0x7E, 0xE2, 0xD5, 0xF7, 0xBE, 0x6A, 0xC4, 0x0C, 0x2F, 0x2F, 0x2F, 0xFC, + 0xFC, 0xFD, 0xD9, 0x96, 0x7E, 0x94, 0x67, 0xDE, 0xFE, 0x88, 0x82, 0xE2, 0x8B, 0xCE, 0x89, 0x2F, + 0x55, 0xE5, 0xF0, 0xE9, 0x1C, 0x66, 0xBC, 0xFD, 0x71, 0x23, 0x66, 0x18, 0x0C, 0x06, 0xC2, 0xC2, + 0xC2, 0x28, 0x2C, 0xAB, 0xE2, 0xF9, 0x7F, 0x7C, 0xCE, 0x96, 0x7D, 0x87, 0x9B, 0x16, 0x5F, 0x42, + 0x10, 0x1E, 0xE4, 0x4F, 0xBF, 0xB8, 0x9B, 0xA8, 0xBA, 0x74, 0x89, 0xB4, 0xB4, 0xB4, 0x36, 0x33, + 0xC3, 0x8E, 0x71, 0xE3, 0xC6, 0x31, 0x7C, 0xF8, 0x70, 0xC7, 0xA6, 0x7B, 0x80, 0x04, 0xFB, 0x48, + 0x12, 0x80, 0xFB, 0xEC, 0x67, 0x46, 0x8C, 0x18, 0xC1, 0x03, 0x0F, 0x3C, 0xD0, 0xA6, 0x1B, 0x1E, + 0x3D, 0x7A, 0x94, 0xD2, 0x92, 0x12, 0xE2, 0xBB, 0x46, 0x12, 0x19, 0x62, 0xBC, 0xB6, 0xB8, 0x52, + 0x14, 0xCA, 0x2B, 0x2E, 0xF1, 0xFE, 0xEA, 0x8D, 0x54, 0x99, 0x1A, 0xD4, 0xCB, 0xBE, 0x7D, 0xFB, + 0xB2, 0x72, 0xE5, 0x4A, 0x36, 0x6F, 0xDE, 0xCC, 0x13, 0x4F, 0x3C, 0xC1, 0x4F, 0x87, 0x32, 0xF9, + 0x2E, 0x25, 0x4D, 0xAE, 0x09, 0xCD, 0x41, 0x08, 0xBE, 0x58, 0xBF, 0x83, 0xCC, 0x9C, 0x86, 0x78, + 0x5C, 0xA3, 0xD1, 0xC8, 0xFC, 0xF9, 0xF3, 0x49, 0x49, 0x49, 0xE1, 0xBD, 0xF7, 0xDE, 0x45, 0xE8, + 0xDD, 0xF9, 0x60, 0xCD, 0x26, 0x2C, 0xB5, 0x4D, 0x47, 0xF2, 0xE8, 0xDD, 0xDD, 0xE4, 0x0C, 0x07, + 0xF6, 0xEC, 0xD9, 0xE3, 0x98, 0xB0, 0xD3, 0x26, 0xF8, 0xF9, 0xF9, 0x31, 0x79, 0xF2, 0x64, 0xC7, + 0x68, 0xFA, 0x58, 0x60, 0xBC, 0x9D, 0x21, 0xE3, 0xB1, 0xCD, 0x0E, 0x83, 0xC1, 0xC0, 0xB4, 0x69, + 0xD3, 0x9C, 0xDE, 0xF8, 0x35, 0x85, 0x43, 0x87, 0x0E, 0x01, 0x90, 0xD8, 0x3D, 0x06, 0x2F, 0x8F, + 0x66, 0xD4, 0x5D, 0x45, 0xE1, 0x6C, 0x5E, 0x11, 0xC7, 0xCE, 0x9C, 0x6F, 0xD4, 0xFC, 0xE4, 0x93, + 0x4F, 0x32, 0x7E, 0xFC, 0x78, 0x06, 0x0C, 0x18, 0xC0, 0x8B, 0x2F, 0xBE, 0x48, 0x74, 0xD7, 0x9B, + 0x48, 0xFD, 0xF9, 0x78, 0xD3, 0x76, 0x30, 0x07, 0x98, 0xCC, 0x35, 0xEC, 0x3D, 0x72, 0xAA, 0x51, + 0xDB, 0x98, 0x31, 0x63, 0x78, 0xFC, 0xF1, 0xC7, 0x89, 0x8B, 0x8B, 0xE3, 0xB1, 0xC7, 0x1E, 0x63, + 0xC2, 0x84, 0x09, 0xA4, 0x1F, 0x3B, 0x4D, 0x71, 0x59, 0xE5, 0x35, 0x66, 0x9D, 0x42, 0xBF, 0xB8, + 0x9B, 0x70, 0xD7, 0xEB, 0x38, 0x7E, 0xFC, 0x38, 0xE5, 0xE5, 0xE5, 0xCD, 0xDE, 0xDB, 0x59, 0x8C, + 0x1A, 0x35, 0x8A, 0xEE, 0xDD, 0xEB, 0x73, 0x7E, 0x74, 0xC0, 0x44, 0x15, 0xB9, 0x5B, 0xBC, 0xDB, + 0xDE, 0xDA, 0xB7, 0x6F, 0x5F, 0x46, 0x8F, 0x1E, 0xDD, 0xA6, 0x1B, 0x59, 0x2C, 0x16, 0x8E, 0x1E, + 0x3D, 0x2A, 0xFB, 0xEB, 0x11, 0xD3, 0xBC, 0x46, 0xA3, 0x80, 0xB9, 0xD6, 0x42, 0xAD, 0xA5, 0xF1, + 0xDB, 0x27, 0x1C, 0xB4, 0x32, 0x21, 0x04, 0x08, 0x41, 0xB5, 0xB9, 0x06, 0xAD, 0x39, 0x6D, 0x4D, + 0x01, 0xAB, 0x55, 0xC3, 0x5C, 0xD3, 0xF8, 0xCD, 0xB7, 0x58, 0x2C, 0xF5, 0x9A, 0x92, 0xA6, 0x69, + 0xD4, 0xD6, 0xD6, 0x52, 0x6B, 0xA9, 0xA3, 0xCE, 0x6A, 0x6D, 0xDA, 0xAA, 0x27, 0x34, 0x62, 0x23, + 0x43, 0x09, 0x35, 0xFA, 0x93, 0x9D, 0x9D, 0x4D, 0x4A, 0x4A, 0x0A, 0x15, 0x15, 0x15, 0x8D, 0xC6, + 0xD6, 0x52, 0x54, 0x57, 0x57, 0x93, 0x9E, 0x9E, 0xCE, 0xFB, 0xEF, 0xBF, 0x7F, 0x79, 0xE0, 0x5D, + 0x92, 0x1E, 0x48, 0x44, 0x66, 0xCA, 0x02, 0x70, 0xF7, 0xDD, 0x77, 0x13, 0x1C, 0xDC, 0x22, 0x9F, + 0xCA, 0x15, 0xA8, 0xA8, 0xA8, 0xE0, 0xCC, 0x99, 0x33, 0x78, 0xB8, 0xEB, 0xE9, 0x19, 0x13, 0x4E, + 0xB3, 0x1B, 0x10, 0x21, 0x08, 0x0F, 0x0A, 0x20, 0xD4, 0xE8, 0x47, 0x45, 0x55, 0x83, 0x75, 0x7A, + 0xD1, 0xA2, 0x45, 0x44, 0x44, 0x44, 0x10, 0x15, 0x15, 0xC5, 0x87, 0x1F, 0x7E, 0xC8, 0xE9, 0xAC, + 0xD3, 0x3C, 0x3C, 0xA2, 0x9F, 0xB4, 0xCC, 0x5E, 0x6B, 0x61, 0x17, 0xE0, 0xE5, 0x61, 0xA0, 0x47, + 0x74, 0x38, 0xBB, 0x0E, 0x36, 0x58, 0x5C, 0x37, 0x6E, 0xDC, 0xC8, 0xDC, 0xB9, 0x73, 0x19, 0x33, + 0x66, 0x0C, 0x3B, 0x76, 0xEC, 0xE0, 0xBB, 0xEF, 0xD6, 0x31, 0xA0, 0x47, 0x24, 0x81, 0xBE, 0xDE, + 0x4D, 0x0F, 0x51, 0x40, 0xA8, 0xD1, 0x9F, 0xAE, 0x11, 0x21, 0xA4, 0x1E, 0x38, 0xC1, 0x6F, 0x7F, + 0xFB, 0x5B, 0x12, 0x12, 0x12, 0x18, 0x32, 0x64, 0x08, 0x83, 0x07, 0x0F, 0xA6, 0x7B, 0xF7, 0xEE, + 0x44, 0x45, 0x45, 0x11, 0x18, 0x18, 0x88, 0xC1, 0x60, 0x40, 0xA7, 0xD3, 0xD5, 0x6F, 0x9E, 0x35, + 0x4D, 0xC3, 0x62, 0xB1, 0x50, 0x5D, 0x5D, 0x4D, 0x71, 0x71, 0x31, 0xA7, 0x4F, 0x9F, 0x26, 0x2D, + 0x2D, 0x8D, 0x94, 0x94, 0x14, 0x32, 0x32, 0x32, 0x28, 0x2E, 0xBE, 0xC2, 0xE8, 0x9B, 0xAB, 0x47, + 0xAA, 0xB9, 0x46, 0x00, 0x6F, 0x6F, 0x6F, 0x46, 0x8C, 0x18, 0xD1, 0x26, 0x66, 0x00, 0x14, 0x14, + 0x14, 0x90, 0x97, 0x9F, 0x4F, 0x90, 0xBF, 0x2F, 0x51, 0xA1, 0xC6, 0xE6, 0x37, 0x84, 0x9A, 0xA0, + 0x4B, 0x58, 0x10, 0xE3, 0x6E, 0x1F, 0xC8, 0x3F, 0x97, 0xAF, 0xAF, 0x6F, 0x3E, 0x7C, 0xF8, 0x30, + 0x0F, 0x3F, 0xFC, 0x30, 0xEE, 0xEE, 0xEE, 0x94, 0x57, 0x54, 0x10, 0x66, 0xF4, 0x63, 0xC2, 0xF0, + 0x41, 0x4E, 0x8D, 0x41, 0x75, 0xD3, 0x31, 0x69, 0xF4, 0xAD, 0xAC, 0xD9, 0xBA, 0x87, 0x4B, 0x36, + 0xBF, 0x4A, 0x65, 0x65, 0x25, 0xAF, 0xBD, 0xF6, 0x1A, 0x73, 0xE6, 0xCC, 0xA1, 0xBA, 0xBA, 0x1A, + 0x10, 0x3C, 0x74, 0xC7, 0x6D, 0xF8, 0xF8, 0x78, 0x35, 0xCD, 0x60, 0x21, 0xF0, 0xF1, 0xF2, 0x20, + 0xBE, 0x6B, 0x24, 0xA9, 0x07, 0x4E, 0x50, 0x5E, 0x5E, 0xCE, 0x9E, 0x3D, 0x7B, 0xD8, 0xB3, 0x67, + 0x0F, 0x3A, 0x9D, 0x0E, 0x1F, 0x1F, 0x1F, 0x42, 0x42, 0x42, 0x88, 0x88, 0x88, 0x20, 0x28, 0x28, + 0x08, 0x5F, 0x5F, 0x5F, 0x0C, 0x06, 0x03, 0x9A, 0xA6, 0x51, 0x5D, 0x5D, 0x4D, 0x59, 0x59, 0x19, + 0x85, 0x85, 0x85, 0x14, 0x14, 0x14, 0x50, 0x52, 0x52, 0xD2, 0x94, 0x09, 0x46, 0x43, 0x66, 0xF6, + 0xBE, 0xAA, 0x47, 0x3A, 0xE8, 0x55, 0x80, 0x2E, 0x5D, 0xBA, 0x90, 0x90, 0x90, 0xD0, 0x6A, 0x46, + 0x98, 0xCD, 0x66, 0x32, 0x32, 0x32, 0x58, 0xB8, 0x70, 0x21, 0x45, 0x85, 0x45, 0x0C, 0x4C, 0x88, + 0x25, 0xC8, 0xDF, 0xD7, 0xA9, 0x0D, 0xA1, 0xAA, 0x53, 0x99, 0xF9, 0xC8, 0x3D, 0x1C, 0x3C, 0x79, + 0x96, 0x6D, 0xE9, 0x47, 0xEA, 0xDB, 0x4D, 0x26, 0x13, 0x26, 0x93, 0x09, 0x1F, 0x4F, 0x0F, 0x66, + 0x3F, 0x76, 0x1F, 0x37, 0xF7, 0xEE, 0xEE, 0x9C, 0xDA, 0x6B, 0xD5, 0xB8, 0xEB, 0xB6, 0xFE, 0x3C, + 0x9D, 0x7C, 0x37, 0xF3, 0x3E, 0x5F, 0x47, 0x8D, 0x6D, 0xE1, 0xB6, 0x5A, 0xAD, 0x54, 0x56, 0x56, + 0xA2, 0x53, 0x55, 0x7E, 0x33, 0x6E, 0x38, 0x53, 0xC6, 0x0D, 0x6B, 0x76, 0x7C, 0x8A, 0x4E, 0x27, + 0x35, 0xC5, 0xCB, 0x6F, 0x61, 0xB5, 0x52, 0x5E, 0x5E, 0x4E, 0x79, 0x79, 0x39, 0xA7, 0x4E, 0x9D, + 0xA2, 0x15, 0xA8, 0x46, 0x46, 0x79, 0xAE, 0x04, 0xD6, 0x00, 0xE7, 0xF5, 0xC8, 0x48, 0x09, 0x40, + 0x9A, 0x8C, 0x5B, 0x2A, 0xAE, 0xEA, 0xEA, 0xEA, 0x38, 0x7F, 0xFE, 0x3C, 0x5B, 0xB7, 0x6E, 0x65, + 0xCD, 0x9A, 0x35, 0xEC, 0xDA, 0xB5, 0xAB, 0x5E, 0x2E, 0x46, 0x04, 0x07, 0xE0, 0xED, 0x61, 0x70, + 0x6E, 0x87, 0xAE, 0x09, 0x6E, 0x8A, 0x0A, 0xE5, 0xE3, 0x3F, 0x3D, 0xC9, 0x3F, 0x97, 0xAF, 0x67, + 0xDD, 0xCE, 0x74, 0x8A, 0x4A, 0x2B, 0x70, 0x73, 0xD3, 0xD3, 0x3B, 0xB6, 0x0B, 0xBF, 0x7B, 0x70, + 0x0C, 0xF7, 0x8F, 0xBA, 0x15, 0x55, 0x55, 0x9C, 0x36, 0xC1, 0xB8, 0xBB, 0xB9, 0xF1, 0xF2, 0xE3, + 0x0F, 0xD2, 0xA3, 0x4B, 0x38, 0x1F, 0x7D, 0xB7, 0x8D, 0x53, 0xE7, 0xF2, 0xD1, 0x34, 0x8D, 0xE8, + 0xB0, 0x20, 0x92, 0xEF, 0x1C, 0xCA, 0xB4, 0x89, 0xA3, 0xF1, 0x6F, 0xCE, 0x37, 0x63, 0x43, 0xD7, + 0x88, 0x10, 0x74, 0x3A, 0x15, 0xAB, 0x54, 0x28, 0x34, 0xA4, 0x93, 0xC9, 0x1B, 0x59, 0xC0, 0xC6, + 0x59, 0x33, 0x42, 0x1D, 0x32, 0x0E, 0xE1, 0x14, 0x32, 0x38, 0xE4, 0x47, 0x64, 0xD8, 0x54, 0x99, + 0xFD, 0x1F, 0xF4, 0x38, 0xD8, 0xE5, 0x2D, 0x16, 0x0B, 0x07, 0x0F, 0x1E, 0x24, 0x2A, 0x2A, 0x0A, + 0x3F, 0x3F, 0x3F, 0x0C, 0x06, 0x03, 0xAA, 0xCD, 0x17, 0xA1, 0x69, 0x1A, 0x75, 0x75, 0x75, 0x98, + 0x4C, 0x26, 0x4A, 0x4B, 0x4B, 0xC9, 0xCE, 0xCE, 0xE6, 0xC0, 0x81, 0x03, 0xEC, 0xDE, 0xBD, 0x9B, + 0x7D, 0xFB, 0xF6, 0x71, 0xEE, 0xDC, 0xB9, 0x2B, 0xEA, 0x94, 0x44, 0x86, 0x04, 0xE2, 0xEE, 0xD6, + 0x82, 0x68, 0x7D, 0x4D, 0xD0, 0x35, 0x32, 0x84, 0xB7, 0x9E, 0x99, 0xC2, 0xAC, 0xC9, 0xE3, 0x29, + 0xBC, 0x58, 0x8E, 0xC1, 0xDD, 0x8D, 0xE8, 0xB0, 0x20, 0x7C, 0x7D, 0xBC, 0x6D, 0x8E, 0x29, 0xE7, + 0xBB, 0x43, 0x08, 0x3C, 0x0D, 0x6E, 0x4C, 0xBD, 0x6F, 0x34, 0x93, 0x46, 0x0F, 0x21, 0xBF, 0xF8, + 0x22, 0x56, 0x4D, 0x10, 0x16, 0xE4, 0x4F, 0xA0, 0xBF, 0xAF, 0xA4, 0xA2, 0x53, 0x8B, 0xB3, 0x5C, + 0xE3, 0x3C, 0xDD, 0xDD, 0xB9, 0x24, 0xD5, 0xF2, 0x3A, 0xE0, 0x0F, 0xC8, 0x52, 0x4E, 0x7D, 0x80, + 0x18, 0x64, 0x5C, 0x5A, 0x28, 0x32, 0x11, 0x54, 0x8F, 0xD4, 0x9A, 0xAA, 0x6D, 0xC4, 0x2E, 0x45, + 0xC6, 0x6F, 0x1D, 0x47, 0x56, 0x27, 0x3A, 0x8B, 0x2C, 0x6C, 0x73, 0xC5, 0xCD, 0xF5, 0x38, 0x64, + 0x92, 0x6E, 0xDC, 0xB8, 0x91, 0x3D, 0x7B, 0xF6, 0x10, 0x1A, 0x1A, 0x4A, 0x68, 0x68, 0x28, 0x46, + 0xA3, 0x11, 0x2F, 0x2F, 0x2F, 0x54, 0x55, 0xA5, 0xB6, 0xB6, 0x96, 0xCA, 0xCA, 0x4A, 0x8A, 0x8B, + 0x8B, 0x29, 0x2C, 0x2C, 0xA4, 0xA4, 0xA4, 0x04, 0x93, 0xC9, 0x74, 0x4D, 0x6D, 0x23, 0x24, 0xD0, + 0x5F, 0x6A, 0x58, 0x2D, 0x31, 0x77, 0x68, 0x02, 0x9D, 0xA2, 0x10, 0x15, 0x16, 0x44, 0x54, 0x78, + 0x70, 0x3D, 0x61, 0x5B, 0x6D, 0xB6, 0x17, 0x80, 0xD0, 0xF0, 0xF3, 0xF1, 0xC2, 0xCF, 0xD7, 0xBB, + 0xA1, 0xBF, 0x96, 0x68, 0x49, 0x02, 0x42, 0x02, 0xFD, 0xF0, 0xF5, 0xF6, 0xB0, 0x33, 0xC4, 0x1D, + 0x39, 0x4B, 0x76, 0xD8, 0x7E, 0x20, 0x67, 0x89, 0x3B, 0x52, 0xFC, 0xEB, 0x6C, 0xC7, 0x16, 0x1B, + 0xF3, 0x9C, 0xAE, 0x6C, 0xA7, 0x07, 0x7E, 0x02, 0x46, 0x83, 0xD4, 0x0A, 0xCA, 0xCA, 0xCA, 0x28, + 0x2B, 0x2B, 0xE3, 0xE4, 0xC9, 0x93, 0x2D, 0x7D, 0xF4, 0x3A, 0xE0, 0x02, 0xD2, 0xCB, 0xE8, 0x09, + 0x10, 0xE4, 0xEF, 0xD3, 0x7A, 0xA3, 0x60, 0x4B, 0x89, 0xE6, 0xCA, 0xFE, 0x84, 0x20, 0xD0, 0xD7, + 0x9B, 0x40, 0x3F, 0x1F, 0xF2, 0x8A, 0xCB, 0xEC, 0xAD, 0x51, 0x97, 0xFF, 0x17, 0xD2, 0x6F, 0xDE, + 0x26, 0xE8, 0x91, 0x36, 0xF9, 0x67, 0x80, 0xE1, 0xC8, 0xCD, 0xA1, 0x0F, 0xCE, 0xC9, 0xC4, 0x3A, + 0xE4, 0xB4, 0xCB, 0x46, 0xCA, 0xC1, 0x6D, 0xC0, 0x79, 0x64, 0x15, 0xB7, 0xAE, 0x00, 0x7E, 0xDE, + 0xED, 0x9A, 0xED, 0xD5, 0x89, 0x10, 0x78, 0x7B, 0x7A, 0x60, 0xF4, 0xF3, 0x71, 0x6C, 0x0C, 0x72, + 0xC5, 0x9D, 0xF4, 0x48, 0xB9, 0xF6, 0x7B, 0x64, 0x40, 0x57, 0x37, 0xE4, 0xBE, 0xA4, 0x2B, 0xD2, + 0x14, 0x1F, 0x8C, 0x9C, 0x86, 0x3A, 0xA4, 0x65, 0xB0, 0x0C, 0x29, 0x0F, 0xCF, 0x03, 0x27, 0x69, + 0x90, 0x87, 0x17, 0x91, 0x6F, 0x48, 0x4F, 0x1C, 0xEA, 0x61, 0x79, 0x7A, 0x18, 0x3A, 0xAF, 0x88, + 0x60, 0x7B, 0x42, 0x80, 0x9B, 0x5E, 0x87, 0xBF, 0x4F, 0x23, 0x43, 0x6B, 0xDB, 0x4C, 0x19, 0x4D, + 0xC0, 0xBE, 0xE2, 0xD6, 0x21, 0x6B, 0x1E, 0xE6, 0x03, 0x76, 0x4F, 0x8C, 0x62, 0x3B, 0xEF, 0xB8, + 0xCD, 0xAE, 0xE3, 0xDA, 0x26, 0x5B, 0x9D, 0xFD, 0xFF, 0x55, 0x45, 0xC1, 0x5D, 0xAF, 0xBB, 0xB1, + 0x9C, 0x52, 0xD7, 0x22, 0x94, 0x5E, 0x87, 0x6F, 0xE3, 0x19, 0xEF, 0x47, 0xC3, 0x8B, 0xDA, 0x7E, + 0xF7, 0xB9, 0xC6, 0x39, 0xC1, 0x2F, 0xB4, 0xD6, 0x60, 0x6B, 0xA0, 0x2A, 0x0A, 0x9E, 0x86, 0x46, + 0xB1, 0x67, 0x9E, 0xB8, 0x80, 0x21, 0xED, 0x9D, 0x63, 0x58, 0x3F, 0x1F, 0x84, 0x10, 0xD2, 0x3B, + 0xF7, 0x4B, 0x10, 0x59, 0x00, 0x8A, 0x82, 0xA1, 0xB1, 0x0A, 0x6F, 0xD7, 0xA4, 0xDA, 0x15, 0xED, + 0xCD, 0x90, 0x1A, 0xA0, 0x16, 0x40, 0x13, 0x82, 0x6A, 0x73, 0xED, 0x2F, 0x46, 0x64, 0x01, 0x97, + 0x07, 0x78, 0xDC, 0x30, 0x0C, 0x31, 0xD9, 0x0F, 0x2A, 0xAA, 0x4C, 0x6D, 0xE8, 0xEA, 0x3A, 0x83, + 0x10, 0xD2, 0x2A, 0xDC, 0x00, 0x0D, 0x17, 0xBC, 0x6E, 0xED, 0xCD, 0x10, 0x13, 0xB2, 0xCE, 0x09, + 0x00, 0x45, 0xA5, 0xE5, 0xAE, 0x8F, 0x32, 0xEC, 0x20, 0x08, 0x21, 0x30, 0x35, 0x36, 0xE7, 0x9B, + 0x70, 0x41, 0x35, 0x39, 0x57, 0x30, 0xA4, 0xBE, 0x70, 0xC0, 0x85, 0xE2, 0x8B, 0x88, 0x1B, 0x21, + 0x30, 0xCE, 0x09, 0x58, 0x35, 0x8D, 0x4B, 0xD5, 0x8D, 0x66, 0xFC, 0x0D, 0xC1, 0x90, 0x1A, 0x1C, + 0x82, 0x88, 0xCF, 0xE6, 0x15, 0x61, 0x32, 0xB7, 0x79, 0xF3, 0xDA, 0xF9, 0x50, 0xA0, 0xA6, 0xB6, + 0x8E, 0x92, 0xF2, 0x4B, 0x8E, 0xAD, 0xC5, 0xDC, 0x00, 0x22, 0x0B, 0xE4, 0x66, 0x11, 0x80, 0x9C, + 0xFC, 0x62, 0xF9, 0x10, 0x6D, 0x89, 0xA9, 0xBA, 0x2E, 0xA0, 0x70, 0xC9, 0x64, 0x96, 0xAE, 0xDE, + 0x06, 0xB4, 0x7B, 0xF1, 0x32, 0x70, 0x5D, 0x69, 0x8D, 0x5A, 0x80, 0xFC, 0x92, 0x32, 0x4E, 0x9D, + 0xCB, 0x77, 0x2E, 0x28, 0xE1, 0x7A, 0x86, 0xA2, 0x50, 0x50, 0x5A, 0x4E, 0x51, 0x43, 0x34, 0x8C, + 0x40, 0x5A, 0x2B, 0xDA, 0x1D, 0xAE, 0x60, 0xC8, 0x49, 0x64, 0x26, 0x2A, 0x55, 0xA6, 0x2B, 0x03, + 0x0D, 0x6E, 0x48, 0x28, 0x0A, 0xA7, 0xCE, 0xE5, 0x53, 0x7E, 0xA9, 0xDE, 0xBD, 0x5C, 0x89, 0xF4, + 0x69, 0xB4, 0x3B, 0x5C, 0xC1, 0x90, 0x73, 0xC8, 0xCF, 0x4E, 0x00, 0xB0, 0x65, 0xDF, 0x61, 0xAA, + 0xAB, 0xCD, 0x9D, 0xBF, 0x41, 0x54, 0x14, 0x19, 0x92, 0xDA, 0x9A, 0x28, 0x4C, 0x21, 0xD8, 0x77, + 0xE4, 0x14, 0x96, 0xBA, 0xFA, 0x35, 0x3C, 0x1F, 0x69, 0xC3, 0x6B, 0x77, 0xB8, 0x82, 0x21, 0x26, + 0xE4, 0x57, 0x6E, 0x00, 0x48, 0x3F, 0x96, 0xC5, 0xE1, 0x53, 0x39, 0xAD, 0x23, 0x84, 0x1D, 0x8A, + 0xD2, 0x40, 0xD0, 0x96, 0xAE, 0x47, 0x0A, 0xA0, 0xD3, 0x51, 0x71, 0xA9, 0x9A, 0x9D, 0xE9, 0x47, + 0x39, 0x9E, 0xD5, 0xC2, 0x4F, 0x82, 0x28, 0x0A, 0xE5, 0x95, 0x97, 0xD8, 0x91, 0x71, 0xDC, 0xB1, + 0xF5, 0x20, 0x36, 0x29, 0xD0, 0xDE, 0x70, 0xD5, 0x67, 0x18, 0x36, 0xDB, 0x06, 0x1C, 0x52, 0x52, + 0x5E, 0xC9, 0xAA, 0x4D, 0xBB, 0x19, 0xDC, 0xA7, 0xF5, 0x51, 0x90, 0xCB, 0x37, 0xEC, 0x64, 0xF7, + 0xA1, 0x4C, 0x46, 0xDF, 0xD2, 0x87, 0x61, 0x03, 0x7B, 0x39, 0x9F, 0xE8, 0xA9, 0x28, 0x54, 0x9B, + 0x6B, 0xF8, 0xF1, 0xA7, 0x03, 0x2C, 0x59, 0xB3, 0x91, 0xED, 0xFB, 0x8F, 0xD2, 0x3B, 0x36, 0x9A, + 0xB5, 0xF3, 0x9E, 0x27, 0x2A, 0x2C, 0xC8, 0xB9, 0x3D, 0x92, 0xAA, 0xB0, 0xF7, 0xC8, 0x69, 0x0E, + 0x64, 0x66, 0xDB, 0x5B, 0x84, 0xED, 0xF9, 0x5C, 0x62, 0xE7, 0x73, 0x55, 0x8D, 0x8E, 0x12, 0x64, + 0xAC, 0x70, 0x1F, 0x80, 0x0B, 0xC5, 0xA5, 0x8C, 0x1D, 0xD2, 0x8F, 0x90, 0xA0, 0x80, 0x96, 0x6D, + 0x14, 0x6D, 0x8B, 0xE9, 0xF4, 0xD7, 0xDF, 0xE7, 0xDB, 0x94, 0x34, 0xD6, 0x6E, 0xDF, 0xC7, 0xB6, + 0xB4, 0x23, 0x18, 0xFD, 0x7C, 0xE8, 0xD9, 0x35, 0xB2, 0xE9, 0x98, 0x5C, 0xDB, 0xB5, 0x85, 0x17, + 0xCB, 0xF9, 0xDF, 0x7F, 0x7C, 0xC6, 0x6B, 0xEF, 0x7F, 0xC5, 0xB1, 0xEC, 0x5C, 0x2C, 0x75, 0x56, + 0xAA, 0xCC, 0x35, 0xDC, 0x3F, 0x62, 0x30, 0x51, 0xE1, 0xCE, 0x31, 0xA4, 0xCE, 0x6A, 0xE5, 0x8D, + 0x65, 0xFF, 0x62, 0xEF, 0xE1, 0xFA, 0x25, 0xE3, 0x3C, 0x32, 0x13, 0xB9, 0xB8, 0xD9, 0x8B, 0x5B, + 0x01, 0x57, 0xD5, 0xDF, 0xAB, 0x45, 0x3A, 0xAA, 0xAA, 0x01, 0xB2, 0x2F, 0x14, 0xB1, 0x74, 0xED, + 0x16, 0xB4, 0x56, 0x84, 0x61, 0x6A, 0x9A, 0x46, 0x8D, 0x45, 0x7A, 0x40, 0xCD, 0x35, 0xB5, 0xA4, + 0x1E, 0x38, 0xC1, 0xB4, 0x3F, 0x2D, 0xE6, 0x93, 0xEF, 0xB6, 0x35, 0xBD, 0x2E, 0xD9, 0x66, 0xC6, + 0x4B, 0x0B, 0x97, 0xB3, 0x74, 0xED, 0x16, 0xCC, 0x0E, 0xA1, 0xA2, 0x31, 0xE1, 0xC1, 0x44, 0x85, + 0x19, 0x9B, 0x8F, 0xC4, 0x07, 0xD0, 0xA9, 0xEC, 0x3B, 0x72, 0x8A, 0x75, 0x3B, 0xD2, 0x1D, 0x5B, + 0xBF, 0x47, 0xFA, 0xD2, 0x5D, 0x02, 0x57, 0x16, 0x44, 0xDC, 0x82, 0x8C, 0xAA, 0x00, 0xE0, 0xCB, + 0xEF, 0x77, 0xB0, 0xEB, 0xE0, 0x49, 0xB9, 0x0E, 0x38, 0x0B, 0x21, 0x08, 0x33, 0x06, 0x70, 0xD7, + 0x6D, 0xFD, 0xEB, 0x9B, 0xBC, 0x3D, 0x0D, 0x18, 0xDC, 0xDD, 0x78, 0xE5, 0xDD, 0x15, 0xEC, 0xFC, + 0xF9, 0xC4, 0xD5, 0xD7, 0x26, 0x45, 0x61, 0xD5, 0xC6, 0x9F, 0xF8, 0xF4, 0xDF, 0xDB, 0x19, 0x79, + 0x73, 0x62, 0xFD, 0xF5, 0xC1, 0x01, 0xBE, 0x3C, 0x3F, 0xE5, 0x5E, 0x19, 0x6B, 0xEC, 0x44, 0xF4, + 0xA3, 0xD9, 0x5C, 0xC3, 0xA2, 0xAF, 0x7E, 0xA0, 0xE8, 0x62, 0x85, 0xBD, 0xB5, 0x14, 0x17, 0x7F, + 0xD8, 0xC5, 0x95, 0x65, 0x85, 0x2C, 0x48, 0xD1, 0x75, 0x2F, 0xE0, 0x51, 0x65, 0xAA, 0xA1, 0xE8, + 0x62, 0x05, 0xF7, 0x0C, 0x1D, 0x88, 0x87, 0xC1, 0xF9, 0xA2, 0x39, 0x8A, 0xAA, 0x92, 0xD4, 0xB3, + 0x2B, 0x25, 0x65, 0x95, 0x14, 0x94, 0x94, 0x73, 0xEF, 0xF0, 0x9B, 0x99, 0xFD, 0xD8, 0x44, 0xBE, + 0x4D, 0x49, 0x27, 0x33, 0x27, 0x8F, 0x7B, 0x87, 0x0D, 0xC2, 0xE0, 0xD8, 0x9F, 0xA2, 0x90, 0x5B, + 0x58, 0xC2, 0xEF, 0xDF, 0x5A, 0x86, 0x5E, 0xA7, 0x63, 0xD9, 0x1F, 0x9F, 0xE0, 0x81, 0x91, 0xB7, + 0x12, 0xDF, 0x35, 0x82, 0x19, 0x0F, 0x8F, 0x63, 0xDC, 0xED, 0x03, 0x9D, 0xDB, 0x16, 0xE9, 0x54, + 0x56, 0x6F, 0xDA, 0xCD, 0x9C, 0x8F, 0xBF, 0x71, 0xD4, 0xAE, 0xBE, 0x44, 0x7E, 0x15, 0xC1, 0x65, + 0xF6, 0x20, 0x57, 0xD7, 0x79, 0x3A, 0x87, 0x0C, 0x33, 0x1A, 0x0C, 0x70, 0xE6, 0x42, 0x21, 0x46, + 0x3F, 0x6F, 0x7E, 0x95, 0x14, 0xD7, 0x22, 0x2D, 0xD8, 0xD7, 0xDB, 0x8B, 0x3B, 0x6F, 0xEB, 0xCF, + 0x83, 0xA3, 0x87, 0x30, 0x69, 0xF4, 0x10, 0x92, 0xE2, 0x63, 0x11, 0x42, 0xE3, 0x93, 0x75, 0xDB, + 0xE9, 0xD3, 0x3D, 0x9A, 0xC4, 0x9E, 0x31, 0x0D, 0x6F, 0xBC, 0x4E, 0xE5, 0x8B, 0x7F, 0xA7, 0xF0, + 0xD9, 0xFA, 0x14, 0x5E, 0xFD, 0xAF, 0x87, 0xB8, 0x7F, 0xD4, 0xAD, 0x04, 0xFA, 0x7B, 0x73, 0x4B, + 0xDF, 0x38, 0x62, 0x22, 0x42, 0x9C, 0x13, 0x09, 0xAA, 0xCA, 0x89, 0xEC, 0x5C, 0x9E, 0x7A, 0x6B, + 0x19, 0xB9, 0x85, 0xF5, 0xB1, 0xB7, 0x39, 0xC0, 0xB3, 0x34, 0x91, 0x5F, 0xDE, 0x5E, 0x70, 0x35, + 0x43, 0x34, 0xE4, 0x46, 0x71, 0x14, 0x10, 0xAA, 0x69, 0x82, 0x03, 0x27, 0xCF, 0xD2, 0x3F, 0x3E, + 0x96, 0xEE, 0x31, 0x11, 0x2D, 0x5A, 0xE0, 0xDD, 0x74, 0x3A, 0x8C, 0x81, 0x7E, 0x78, 0xB8, 0xCB, + 0x0C, 0xE0, 0xB8, 0xAE, 0x91, 0x6C, 0xDE, 0x7B, 0x88, 0xFC, 0x92, 0x8B, 0xDC, 0x3F, 0xE2, 0x96, + 0xFA, 0x05, 0xBE, 0xB6, 0xD6, 0xC2, 0x5F, 0x96, 0x7E, 0x8D, 0x97, 0x87, 0x81, 0x37, 0x9F, 0xFE, + 0x0D, 0x3E, 0x9E, 0x86, 0x86, 0x88, 0x13, 0x67, 0xEE, 0xA7, 0x28, 0x94, 0x55, 0x56, 0xF1, 0xEC, + 0xDF, 0x3F, 0x61, 0x6B, 0x5A, 0x7D, 0x04, 0xA5, 0x15, 0xF9, 0x71, 0x81, 0xD5, 0x2E, 0xA6, 0x57, + 0x87, 0xD4, 0x2E, 0x3F, 0x8D, 0xAC, 0x04, 0x51, 0x09, 0x50, 0x50, 0x2A, 0x35, 0x9F, 0xA3, 0xA7, + 0x72, 0x5A, 0xB6, 0x9E, 0x40, 0x43, 0x05, 0x07, 0x21, 0x08, 0x31, 0xFA, 0xF3, 0xDB, 0x09, 0x23, + 0x38, 0x73, 0xA1, 0x88, 0xCA, 0x2A, 0x53, 0xFD, 0x5E, 0xA5, 0xFC, 0x52, 0x35, 0x39, 0xF9, 0xC5, + 0xFC, 0xE7, 0xD8, 0xDB, 0x08, 0x0B, 0x0E, 0x68, 0xB1, 0x56, 0x67, 0xAE, 0xAD, 0xE5, 0xAF, 0x4B, + 0x57, 0xB3, 0x7A, 0xF3, 0x1E, 0xC7, 0x33, 0xDF, 0x21, 0x4B, 0x2E, 0xB9, 0x1C, 0x1D, 0x55, 0xE5, + 0x78, 0x35, 0xF0, 0x1E, 0x36, 0xEB, 0xE8, 0xCF, 0x27, 0xB2, 0x99, 0x31, 0xF7, 0x23, 0x72, 0x72, + 0x0B, 0x5B, 0xBF, 0x61, 0x14, 0x82, 0x31, 0x43, 0xFA, 0xD1, 0x2D, 0x2A, 0x94, 0x3A, 0x87, 0x7C, + 0x91, 0x3A, 0xAB, 0x95, 0x40, 0x3F, 0x1F, 0xC6, 0xDE, 0x9A, 0xD4, 0x32, 0x5B, 0xAC, 0xA2, 0x60, + 0xAE, 0xB5, 0x30, 0xE7, 0xA3, 0xB5, 0x2C, 0xFC, 0x6A, 0x83, 0x74, 0x3F, 0x4B, 0x1C, 0x01, 0x5E, + 0xC1, 0x21, 0xDC, 0xD3, 0x95, 0xE8, 0xA8, 0x5A, 0x81, 0x1A, 0x90, 0x81, 0x0C, 0x13, 0xEA, 0x05, + 0x90, 0x95, 0x5B, 0xC8, 0xC9, 0xB3, 0x17, 0xB8, 0xBD, 0x7F, 0x82, 0x73, 0xE5, 0x36, 0x2E, 0x87, + 0x00, 0x7F, 0x1F, 0x4F, 0x06, 0x27, 0xF6, 0x20, 0xD4, 0xE8, 0x57, 0x2F, 0xB2, 0xF4, 0x3A, 0x1D, + 0x91, 0x21, 0x46, 0x6E, 0xE9, 0xDD, 0x1D, 0x37, 0x9D, 0x93, 0x8F, 0xA7, 0xAA, 0x54, 0x56, 0x9B, + 0xF9, 0xDB, 0xD2, 0xD5, 0xCC, 0xFD, 0xFC, 0xBB, 0xFA, 0xC0, 0x6C, 0x64, 0xE0, 0xDF, 0x13, 0xC8, + 0x60, 0xC2, 0x0E, 0x41, 0x47, 0x16, 0x6F, 0xAC, 0x46, 0x7E, 0x65, 0x73, 0x10, 0x32, 0x16, 0x96, + 0xCC, 0x73, 0xF9, 0x1C, 0x3A, 0x95, 0xC3, 0xA0, 0x84, 0x6E, 0x84, 0xB6, 0x54, 0xBC, 0x20, 0x23, + 0x41, 0x02, 0xFC, 0x7D, 0x1A, 0x6D, 0x10, 0xDD, 0xF4, 0x3A, 0xE2, 0x6E, 0x8A, 0x72, 0x9E, 0x19, + 0x3A, 0x95, 0xF3, 0xF9, 0xC5, 0xBC, 0xF0, 0xCF, 0xCF, 0x79, 0x77, 0xF5, 0x8F, 0xD4, 0x5A, 0xEA, + 0xA3, 0x3E, 0x8B, 0x90, 0x45, 0x62, 0xBE, 0xE9, 0x40, 0x1A, 0x75, 0x78, 0x35, 0xCD, 0x8B, 0x48, + 0xA6, 0x0C, 0xC4, 0x96, 0x42, 0x77, 0x26, 0xB7, 0x90, 0x9D, 0x3F, 0x1F, 0x27, 0x36, 0x3C, 0x84, + 0xD8, 0xE8, 0xF0, 0x6B, 0xEF, 0xBE, 0xAF, 0x86, 0xAB, 0xF1, 0xD0, 0x49, 0x93, 0x88, 0x26, 0x20, + 0x25, 0xED, 0x08, 0x4F, 0xCE, 0x59, 0xCA, 0xB7, 0xDB, 0xD3, 0xB0, 0x36, 0x6C, 0x16, 0x0B, 0x90, + 0xCC, 0x58, 0xD1, 0xC1, 0xF4, 0xE9, 0x94, 0xF2, 0xA6, 0x85, 0xC8, 0x4F, 0x6B, 0xF7, 0xC5, 0x16, + 0x72, 0x5A, 0x50, 0x5A, 0xCE, 0x86, 0x9F, 0x7E, 0xA6, 0xA6, 0xA6, 0x96, 0x5E, 0x37, 0x45, 0xC9, + 0x04, 0x1A, 0x57, 0xC1, 0x66, 0xA4, 0xCC, 0x2D, 0x28, 0xE1, 0xEF, 0x9F, 0x7F, 0xC7, 0xEC, 0x05, + 0x5F, 0x34, 0xCA, 0xD2, 0x45, 0x2A, 0x21, 0x4F, 0x22, 0xF3, 0x35, 0x3A, 0x3C, 0x20, 0xA0, 0xB3, + 0xEA, 0xCD, 0x16, 0x21, 0x2D, 0xC2, 0x5D, 0x90, 0x5F, 0x8D, 0x56, 0x4D, 0xE6, 0x5A, 0x76, 0x64, + 0x1C, 0x27, 0xF5, 0xE7, 0xE3, 0xF8, 0x79, 0x79, 0x10, 0x13, 0x1E, 0x8C, 0xA1, 0xB9, 0x64, 0xD1, + 0x96, 0x40, 0x95, 0x96, 0xE2, 0xC2, 0xD2, 0x32, 0xBE, 0xF8, 0xF7, 0x0E, 0x9E, 0x7D, 0xE7, 0x13, + 0x56, 0x6D, 0xFC, 0xC9, 0x1E, 0xCD, 0x0E, 0x92, 0xF8, 0xDB, 0x91, 0xC5, 0x13, 0x5A, 0x57, 0xFE, + 0xA7, 0x1D, 0xD0, 0xD9, 0x5E, 0x8A, 0x40, 0xA4, 0x68, 0xF8, 0x3D, 0x0E, 0xDF, 0x3E, 0xF7, 0x34, + 0xB8, 0x33, 0x6C, 0x40, 0x2F, 0xA6, 0x8C, 0x1B, 0xCE, 0xE8, 0xC1, 0x7D, 0x09, 0x0F, 0x09, 0x40, + 0x51, 0x75, 0x36, 0x95, 0xD7, 0xC9, 0x1C, 0x11, 0x45, 0xB1, 0x79, 0x2A, 0x15, 0x6A, 0x6B, 0x6A, + 0x38, 0x95, 0x93, 0xCF, 0xBA, 0x9D, 0xE9, 0x7C, 0xB5, 0xF1, 0x27, 0x0E, 0x9C, 0x3C, 0x7B, 0x79, + 0x48, 0x4F, 0x39, 0xF0, 0x21, 0xF2, 0x23, 0x98, 0x2E, 0x71, 0xCD, 0x3A, 0x8B, 0xCE, 0x66, 0x08, + 0x48, 0x17, 0xC0, 0x9D, 0xC0, 0x8B, 0xC8, 0x62, 0xC4, 0xF5, 0xB3, 0xD6, 0x4D, 0xAF, 0x23, 0xBE, + 0x6B, 0x24, 0x23, 0x6F, 0xEE, 0xC3, 0xA8, 0x5B, 0x12, 0xE9, 0xD3, 0x3D, 0x86, 0x88, 0xE0, 0x40, + 0xBC, 0x3C, 0xDC, 0x1B, 0xAA, 0xCB, 0x35, 0x82, 0x00, 0x4D, 0x50, 0x6B, 0xB1, 0x50, 0x56, 0x51, + 0xC5, 0x99, 0x0B, 0x85, 0xEC, 0x3B, 0x7A, 0x9A, 0x2D, 0xFB, 0x0E, 0xB3, 0xFB, 0x50, 0x26, 0xF9, + 0x25, 0x65, 0x97, 0xE7, 0xB3, 0xD4, 0x21, 0x3F, 0xA5, 0x3A, 0x17, 0xF9, 0x01, 0xCC, 0x4E, 0x0F, + 0x9D, 0xBD, 0x1E, 0x18, 0x62, 0x47, 0x28, 0xB2, 0xB4, 0xC7, 0x34, 0xA4, 0x7A, 0xDC, 0x68, 0x6C, + 0xEE, 0x6E, 0x7A, 0x42, 0x8D, 0xFE, 0x74, 0x8B, 0x0C, 0x25, 0x36, 0x2A, 0x8C, 0x2E, 0xA1, 0x46, + 0x82, 0xFC, 0x7D, 0xF0, 0xF2, 0x34, 0xA0, 0x2A, 0x2A, 0xE6, 0x5A, 0x0B, 0x15, 0x97, 0xAA, 0xB9, + 0x50, 0x7C, 0x91, 0x9C, 0xFC, 0x62, 0xCE, 0xE4, 0x16, 0x72, 0xBE, 0xB0, 0x84, 0x8A, 0xAA, 0xAB, + 0x26, 0x15, 0xD5, 0x21, 0x93, 0x2C, 0x97, 0x02, 0x5F, 0x21, 0x8D, 0x86, 0xFF, 0x8F, 0xAB, 0x40, + 0x41, 0xA6, 0x44, 0xBC, 0x88, 0xDC, 0xB7, 0xD4, 0xD0, 0x82, 0xEF, 0xA2, 0x3B, 0xF1, 0x2B, 0x03, + 0x7E, 0x40, 0x32, 0x3D, 0xB4, 0xB3, 0x1F, 0xB6, 0x29, 0x02, 0x5C, 0xAF, 0x08, 0x45, 0xD6, 0x06, + 0xBE, 0x0B, 0xF8, 0x15, 0x72, 0xEF, 0xE2, 0x6C, 0x32, 0x91, 0x1D, 0x16, 0xA4, 0x23, 0xE9, 0x38, + 0x32, 0xA1, 0x68, 0x13, 0x72, 0x66, 0x54, 0x75, 0xF6, 0xC3, 0x35, 0x85, 0xEB, 0x99, 0x21, 0x76, + 0xE8, 0x90, 0x16, 0xE3, 0x3E, 0x48, 0xAB, 0x71, 0x5F, 0xA0, 0x07, 0x92, 0x61, 0x01, 0x34, 0xE4, + 0xF5, 0xD5, 0x22, 0x09, 0x5D, 0x8C, 0xF4, 0xEA, 0x1D, 0x45, 0xA6, 0x1C, 0x67, 0x20, 0x23, 0x44, + 0x2A, 0x5B, 0x76, 0xDB, 0xCE, 0xC1, 0xFF, 0x01, 0xCE, 0x34, 0xF5, 0xEC, 0x2D, 0xA9, 0x9C, 0xA8, + 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, 0x31, + 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0xED, 0x4F, 0xCC, + 0x0D, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x6D, 0x6F, + 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, + 0x31, 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x9C, 0x12, + 0x74, 0xB1, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, + 0x72, 0x65, 0x00, 0x77, 0x77, 0x77, 0x2E, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2E, + 0x6F, 0x72, 0x67, 0x9B, 0xEE, 0x3C, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82}; \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_List/Copy_Messages_List.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_List/Copy_Messages_List.ino new file mode 100644 index 000000000000..3a1511777324 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_List/Copy_Messages_List.ino @@ -0,0 +1,220 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to copy messages from the mailbox to other folder. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Define the MessageList class to add the message to copy */ + MessageList toCopy; + + /* Add message uid to copy to the list */ + toCopy.add(3); + toCopy.add(4); + + // imap.createFolder("test"); + + /* Copy all messages in the list to the folder "test" */ + if (imap.copyMessages(&toCopy, F("test"))) + MailClient.printf("\nMessages copied\n"); + + /* Delete all messages in the list from the opened folder (move to trash) */ + // imap.deleteMessages(&toCopy); + + // imap.deleteolder("test"); + // imap.deleteolder("test2"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_Message_Numbers_Ranges/Copy_Messages_Message_Numbers_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_Message_Numbers_Ranges/Copy_Messages_Message_Numbers_Ranges.ino new file mode 100644 index 000000000000..958037525cfd --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_Message_Numbers_Ranges/Copy_Messages_Message_Numbers_Ranges.ino @@ -0,0 +1,214 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to copy messages from the mailbox to other folder using message numbers ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Copy all messages using message sequence ranges (last 10 message numbers) to the folder "test"*/ + int msg_last = imap.selectedFolder().msgCount(); + int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + String sequence_set2 = String(msg_begin) + ":" + String(msg_last); + + if (imap.copyMessages(sequence_set2, false /* if sequence set are message numbers not UIDs */, F("test"))) + MailClient.printf("\nCopying messages using message numbers ranges success\n"); + else + MailClient.printf("\nError, copying messages using message numbers ranges\n"); + + // imap.deleteolder("test"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_UIDs_Ranges/Copy_Messages_UIDs_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_UIDs_Ranges/Copy_Messages_UIDs_Ranges.ino new file mode 100644 index 000000000000..1fdc5c6bf895 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_UIDs_Ranges/Copy_Messages_UIDs_Ranges.ino @@ -0,0 +1,214 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to copy messages from the mailbox to other folder using UIDs ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Copy all messages using UIDs ranges (last 10 UIDs) to the folder "test" */ + int uid_last = imap.getUID(imap.selectedFolder().msgCount()); + int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + String sequence_set1 = String(uid_begin) + ":" + String(uid_last); + + if (imap.copyMessages(sequence_set1, true /* if sequence set are the UIDs */, F("test"))) + MailClient.printf("\nCopying messages using UIDs ranges success\n"); + else + MailClient.printf("\nError, copying messages using UIDs ranges\n"); + + // imap.deleteolder("test"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Character_Decoding/Custom_Character_Decoding.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Character_Decoding/Custom_Character_Decoding.ino new file mode 100644 index 000000000000..f703bd316df8 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Character_Decoding/Custom_Character_Decoding.ino @@ -0,0 +1,498 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example shows how to read Email with custom character decoding for local language. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// Provide the SD card interfaces setting and mounting +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Callback function to decode the string based on character set of the content */ +void customCharacterDecodingCallback(IMAP_Decoding_Info *decoding); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /* Set the callback function to decode the string based on the caracter set of string */ + imap.characterDecodingCallback(customCharacterDecodingCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_sd; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /** Message UID to fetch or read e.g. 100. + * In this case we will get the UID from the max message number (lastest message) + */ + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + // or fetch via the message sequence number + // imap_data.fetch.number = imap.selectedFolder().msgCount(); + + // if both imap_data.fetch.uid and imap_data.fetch.number were set, + // then total 2 messages will be fetched i.e. one using uid and other using number. + + /* Set seen flag */ + + // The message with "Seen" flagged means the message was already read or seen by user. + // The default value of this option is set to false. + // If you want to set the message flag as "Seen", set this option to true. + // If this option is false, the message flag was unchanged. + // To set or remove flag from message, see Set_Flags.ino example. + + // imap_data.fetch.set_seen = true; + + /* Read or search the Email and close the session */ + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +void To_UTF8(IMAP_Decoding_Info *decoding) +{ + decoding->decodedString = "fake decoded string "; // return the decoded string +} + +void customCharacterDecodingCallback(IMAP_Decoding_Info *decoding) +{ + // Serial.println("***** Data Type *****"); + // 0 or IMAP_Decoding_Info::message_part_type_header or + // 1 or IMAP_Decoding_Info::message_part_type_text + // Serial.println(decoding->type); + + // Serial.println("***** Charset *****"); + // Serial.println(decoding->charset); + // Serial.println("***** String to Decode *****"); + // Serial.println(decoding->encoded); + + // The original or decoded string should be return to the process via + // decoding->decodedString + + // Then rturn the decoded string back to the process. + if (strlen(decoding->charset) == 0 || strcasecmp(decoding->charset, "utf-8") == 0 || strcasecmp(decoding->charset, "us-ascii") == 0) // return original + decoding->decodedString = decoding->data; + else // decode to UTF-8 or ASCII + To_UTF8(decoding); +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + MailClient.printf(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and + * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename + * (> 13 characters) is not support in the SD.h library. + * To show how its original file name, use imap.fileList(). + */ + // Serial.println(imap.fileList()); + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Append_Message/Append_Message.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Append_Message/Append_Message.ino new file mode 100644 index 000000000000..9ef89294ef50 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Append_Message/Append_Message.ino @@ -0,0 +1,221 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to append new message to mailbox using the custom IMAP command. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(IMAP_Response res) +{ + // The server responses will included tagged and/or untagged data. + + // Tagged data is the status which begins with command identifier (tag) i.e. "A01" in this case. + // Tagged status responses included OK, NO, BAD, PREAUTH and BYE. + + // Untagged data is the information or result of the request which begins with * + + // When you send multiple commands with different tag simultaneously, + // tag will be used as command identifier. + + MailClient.printf("> C: TAG %s\n", res.tag.c_str()); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.completed) + { + MailClient.printf("> C: Response finished with status %s\n\n", res.status.c_str()); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + + /* Connect to the server */ + if (!imap.customConnect(&config, customCommandCallback, F("A01") /* tag */)) + return; + + String cmd = F("LOGIN "); + cmd += AUTHOR_EMAIL; + cmd += F(" "); + cmd += AUTHOR_PASSWORD; + + // You can also assign tag to the begining of the command e.g. "A01 FETCH 1 UID" + // Do not assign tag to command when you assign tag to the last parameter of function. + + imap.sendCustomCommand(cmd, customCommandCallback, F("A02") /* tag */); + + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in.\n"); + else + Serial.println("\nConnected with no Auth.\n"); + + imap.sendCustomCommand(F("SELECT \"INBOX\""), customCommandCallback, F("A03") /* tag */); + + imap.sendCustomCommand(F("LIST \"\" *"), customCommandCallback, F("A04") /* tag */); + + String appendMsg = "Date: Thu, 16 Jun 2022 12:30:25 -0800 (PST)\r\n"; + + appendMsg += "From: Jack \r\n"; + + appendMsg += "Subject: Greeting from ESP Mail\r\n"; + + appendMsg += "To: joe@host.com\r\n"; + + appendMsg += "Message-Id: \r\n"; + + appendMsg += "MIME-Version: 1.0\r\n"; + + appendMsg += "Content-Type: text/plain; charset=\"us-ascii\"\r\n"; + + appendMsg += "Content-transfer-encoding: 7bit\r\n"; + + appendMsg += "\r\n"; + + appendMsg += "Hello Joe, this is the append message\r\n"; + + String appendMsgCmd = "APPEND INBOX {" + String(appendMsg.length()) + "}"; + + imap.sendCustomCommand(appendMsgCmd, customCommandCallback, F("A05") /* tag */); + + imap.sendCustomData(appendMsg, true /* flag states the last data to send */); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Basic_Auth/Basic_Auth.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Basic_Auth/Basic_Auth.ino new file mode 100644 index 000000000000..9485ee7e6c49 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Basic_Auth/Basic_Auth.ino @@ -0,0 +1,197 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send custom IMAP command and get the response. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(IMAP_Response res) +{ + // The server responses will included tagged and/or untagged data. + + // Tagged data is the status which begins with command identifier (tag) i.e. "A01" in this case. + // Tagged status responses included OK, NO, BAD, PREAUTH and BYE. + + // Untagged data is the information or result of the request which begins with * + + // When you send multiple commands with different tag simultaneously, + // tag will be used as command identifier. + + MailClient.printf("> C: TAG %s\n", res.tag.c_str()); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.completed) + { + MailClient.printf("> C: Response finished with status %s\n\n", res.status.c_str()); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + // This debug required for showing debug info from imap.connect + imap.debug(1); + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in.\n"); + else + Serial.println("\nConnected with no Auth.\n"); + + // You can also assign tag to the begining of the command e.g. "A01 FETCH 1 UID" + // Do not assign tag to command when you assign tag to the last parameter of function. + + imap.sendCustomCommand(F("SELECT \"INBOX\""), customCommandCallback, F("A01") /* tag */); + + imap.sendCustomCommand(F("LIST \"\" *"), customCommandCallback, F("A02") /* tag */); + + imap.sendCustomCommand(F("FETCH 1 UID"), customCommandCallback, F("A03") /* tag */); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Custom_Auth/Custom_Auth.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Custom_Auth/Custom_Auth.ino new file mode 100644 index 000000000000..afb3ef9c2f2d --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Custom_Auth/Custom_Auth.ino @@ -0,0 +1,197 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send custom IMAP command and get the response. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(IMAP_Response res) +{ + // The server responses will included tagged and/or untagged data. + + // Tagged data is the status which begins with command identifier (tag) i.e. "A01" in this case. + // Tagged status responses included OK, NO, BAD, PREAUTH and BYE. + + // Untagged data is the information or result of the request which begins with * + + // When you send multiple commands with different tag simultaneously, + // tag will be used as command identifier. + + MailClient.printf("> C: TAG %s\n", res.tag.c_str()); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.completed) + { + MailClient.printf("> C: Response finished with status %s\n\n", res.status.c_str()); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + + /* Connect to the server */ + if (!imap.customConnect(&config, customCommandCallback, F("A01") /* tag */)) + return; + + String cmd = F("LOGIN "); + cmd += AUTHOR_EMAIL; + cmd += F(" "); + cmd += AUTHOR_PASSWORD; + + // You can also assign tag to the begining of the command e.g. "A01 FETCH 1 UID" + // Do not assign tag to command when you assign tag to the last parameter of function. + + imap.sendCustomCommand(cmd, customCommandCallback, F("A02") /* tag */); + + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in.\n"); + else + Serial.println("\nConnected with no Auth.\n"); + + imap.sendCustomCommand(F("SELECT \"INBOX\""), customCommandCallback, F("A03") /* tag */); + + imap.sendCustomCommand(F("LIST \"\" *"), customCommandCallback, F("A04") /* tag */); + + imap.sendCustomCommand(F("FETCH 1 UID"), customCommandCallback, F("A05") /* tag */); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Idle/Idle.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Idle/Idle.ino new file mode 100644 index 000000000000..5a704e6bc6f7 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Idle/Idle.ino @@ -0,0 +1,220 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to receive mailbox updates by sending the custom IMAP command IDLE. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +unsigned long lastIdleTerminatedMillis = 0; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(IMAP_Response res) +{ + // The server responses will included tagged and/or untagged data. + + // Tagged data is the status which begins with command identifier (tag) i.e. "A01" in this case. + // Tagged status responses included OK, NO, BAD, PREAUTH and BYE. + + // Untagged data is the information or result of the request which begins with * + + // When you send multiple commands with different tag simultaneously, + // tag will be used as command identifier. + + MailClient.printf("> C: TAG %s\n", res.tag.c_str()); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.completed) + { + MailClient.printf("> C: Response finished with status %s\n\n", res.status.c_str()); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + + /* Connect to the server */ + if (!imap.customConnect(&config, customCommandCallback, F("A01") /* tag */)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in.\n"); + else + Serial.println("\nConnected with no Auth.\n"); + + String cmd = F("LOGIN "); + cmd += AUTHOR_EMAIL; + cmd += F(" "); + cmd += AUTHOR_PASSWORD; + + // You can also assign tag to the begining of the command e.g. "A01 FETCH 1 UID" + // Do not assign tag to command when you assign tag to the last parameter of function. + + imap.sendCustomCommand(cmd, customCommandCallback, F("A02") /* tag */); + + imap.sendCustomCommand(F("SELECT \"INBOX\""), customCommandCallback, F("A03") /* tag */); + + imap.sendCustomCommand(F("LIST \"\" *"), customCommandCallback, F("A04") /* tag */); +} + +void loop() +{ + + if (imap.connected()) + { + if (!imap.sendCustomCommand(F("IDLE"), customCommandCallback, F("A05") /* tag */)) + { + // If error, need to re-connect if imap.connected() returns false and re-log in again + Serial.println("\nTCP connection closed!"); + return; + } + + if (millis() - lastIdleTerminatedMillis > 20 * 60 * 1000) // terminate the IDLE every 20 min. + { + lastIdleTerminatedMillis = millis(); + imap.sendCustomCommand(F("DONE"), customCommandCallback, "" /* don't include tag for DONE command */); + } + } +} + +/** + * The server MAY consider a client inactive if it has an IDLE command + * running, and if such a server has an inactivity timeout it MAY log + * the client off implicitly at the end of its timeout period. Because + * of that, clients using IDLE are advised to terminate the IDLE and + * re-issue it at least every 29 minutes to avoid being logged off. + */ \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Ports/Custom_Ports.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Ports/Custom_Ports.ino new file mode 100644 index 000000000000..b870aa5ab93d --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Ports/Custom_Ports.ino @@ -0,0 +1,256 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to assign the custom ports with protocols to access IMAP server. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 // Plain or TLS with STARTTLS + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT esp_mail_imap_port_143 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Set the ports and protocols + * The port that assigned with config.server.port will map with the + * protocol assigned here + */ + + config.ports_functions.list = new port_function[2]; + config.ports_functions.size = 2; + + config.ports_functions.list[0].port = 143; + config.ports_functions.list[0].protocol = esp_mail_protocol_tls; + + config.ports_functions.list[1].port = 993; + config.ports_functions.list[1].protocol = esp_mail_protocol_ssl; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /* Close the seeion in case the session is still open */ + imap.closeSession(); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Data_Stream_Callback/Data_Stream_Callback.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Data_Stream_Callback/Data_Stream_Callback.ino new file mode 100644 index 000000000000..c06f4342e2ee --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Data_Stream_Callback/Data_Stream_Callback.ino @@ -0,0 +1,368 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to read Email and collect the stream data to print or store via the callback function. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// Provide the SD card interfaces setting and mounting +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +void mimeDataStreamCallback(MIME_Data_Stream_Info streaminfo); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +int progress = 0; +int lastProgress = -1; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h +#endif + + /* Set the callback function to get MIME Data stream */ + imap.mimeDataStreamCallback(mimeDataStreamCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_sd; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /** Message UID to fetch or read e.g. 100. + * In this case we will get the UID from the max message number (lastest message) + */ + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + /* Set seen flag */ + + // The message with "Seen" flagged means the message was already read or seen by user. + // The default value of this option is set to false. + // If you want to set the message flag as "Seen", set this option to true. + // If this option is false, the message flag was unchanged. + // To set or remove flag from message, see Set_Flags.ino example. + + // imap_data.fetch.set_seen = true; + + /* Read or search the Email and close the session */ + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +void mimeDataStreamCallback(MIME_Data_Stream_Info streaminfo) +{ + if (streaminfo.isFirstData) + { + progress = 0; + lastProgress = -1; + + Serial.print("Message UID: "); + Serial.println(streaminfo.uid); + + Serial.print("Content Type: "); + Serial.println(streaminfo.type); + + Serial.print("Content Disposition: "); + Serial.println(streaminfo.disposition); + + Serial.print("Text Character Set: "); + Serial.println(streaminfo.charSet); + + Serial.print("Content Transfer Encoding: "); + Serial.println(streaminfo.transfer_encoding); + + // The total octets of encoded or non-encoded MIME content. + // The size of decoded content may be different. + Serial.print("Total Octets: "); + Serial.println(streaminfo.octet_size); + + if (strcmp(streaminfo.disposition, "attachment") == 0 || strcmp(streaminfo.disposition, "inline") == 0) + { + + if (strcmp(streaminfo.disposition, "inline") == 0) + { + Serial.print("Content ID: "); + Serial.println(streaminfo.cid); + } + + Serial.print("Name: "); + Serial.println(streaminfo.name); + + Serial.print("File Name: "); + Serial.println(streaminfo.filename); + + Serial.print("Size: "); + Serial.println(streaminfo.size); + + Serial.print("Content Description: "); + Serial.println(streaminfo.description); + + Serial.print("Creation Date: "); + Serial.println(streaminfo.date); + } + + Serial.println("Content:"); + } + + progress = 100 * streaminfo.octet_count / streaminfo.octet_size; + + if (progress != lastProgress && (progress == 0 || progress == 100 || lastProgress + 5 <= progress)) + { + + lastProgress = progress; + + // The size of current decoded chunk data + Serial.print("Data Length: "); + Serial.print(streaminfo.data_size); + + Serial.print(", Reading %: "); + Serial.println(progress); + } + + // Decoded chunk data is available here + if (streaminfo.data) + { + + // If streaminfo.transfer_encoding is 'base64', + // to print or send null terminated string from stream data + + /** + char str[streaminfo.data_size + 1]; + memcpy(str, streaminfo.data, streaminfo.data_size); + str[streaminfo.data_size] = 0; + Serial.print(str); + */ + + // If streaminfo.transfer_encoding is not 'base64', the string can be + // taken directly from casting streaminfo.data as (const char*)streaminfo.data + + // To write data to file (if fs is File class object that open in appended mode) + // fs.write((uint8_t *)streaminfo.data, streaminfo.data_size); + + // streaminfo.data_size is not more than 512 + } + + if (streaminfo.isLastData) + { + Serial.println(); + Serial.println(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_List/Delete_Messages_List.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_List/Delete_Messages_List.ino new file mode 100644 index 000000000000..42020a5c9bd7 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_List/Delete_Messages_List.ino @@ -0,0 +1,218 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to delete messages from the mailbox. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Define the MessageList class to add the message to delete */ + MessageList toDelete; + + /** Add message uid to delete to the list + * In this case we will delete last 10 messages by get the UID of these message + * and add it to the list + */ + for (int i = imap.selectedFolder().msgCount(); i > (int)imap.selectedFolder().msgCount() - 10 && i > 0; i--) + toDelete.add(imap.getUID(i)); + + /* Delete all messages in the list (move to trash) */ + if (imap.deleteMessages(&toDelete)) + Serial.println("\nMessages deleted"); + + /* Delete all messages permanently by assign the second param to true*/ + // imap.deleteMessages(&toDelete, true); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_Message_Numbers_Ranges/Delete_Messages_Message_Numbers_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_Message_Numbers_Ranges/Delete_Messages_Message_Numbers_Ranges.ino new file mode 100644 index 000000000000..8d589e625869 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_Message_Numbers_Ranges/Delete_Messages_Message_Numbers_Ranges.ino @@ -0,0 +1,229 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to delete messages from the mailbox using message numbers ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Copy all messages using UIDs ranges (last 10 message numbers) to the folder "test" */ + int msg_last = imap.selectedFolder().msgCount(); + int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + String sequence_set1 = String(msg_begin) + ":" + String(msg_last); + + if (imap.copyMessages(sequence_set1, true /* if sequence set are the UIDs */, F("test"))) + Serial.println("\nCopying messages using message numbers ranges success"); + else + Serial.println("\nError, copying messages using message numbers ranges"); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("test"))) + return; + + delay(10000); + + /* Delete all messages using UIDs ranges (last 10 message numbers) from the folder "test" */ + msg_last = imap.selectedFolder().msgCount(); + msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + sequence_set1 = String(msg_begin) + ":" + String(msg_last); + + if (imap.deleteMessages(sequence_set1, true /* if sequence set are the UIDs */, false)) + Serial.println("\nDeleting messages using message numbers ranges success"); + else + Serial.println("\nError, Deleting messages using message numbers ranges"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_UIDs_Ranges/Delete_Messages_UIDs_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_UIDs_Ranges/Delete_Messages_UIDs_Ranges.ino new file mode 100644 index 000000000000..cb0c90d7fcb9 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_UIDs_Ranges/Delete_Messages_UIDs_Ranges.ino @@ -0,0 +1,229 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to delete messages from the mailbox using UIDs ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Copy all messages using UIDs ranges (last 10 UIDs) to the folder "test" */ + int uid_last = imap.getUID(imap.selectedFolder().msgCount()); + int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + String sequence_set1 = String(uid_begin) + ":" + String(uid_last); + + if (imap.copyMessages(sequence_set1, true /* if sequence set are the UIDs */, F("test"))) + Serial.println("Copying messages using UIDs ranges success"); + else + Serial.println("Error, copying messages using UIDs ranges"); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("test"))) + return; + + delay(10000); + + /* Delete all messages using UIDs ranges (last 10 UIDs) from the folder "test" */ + uid_last = imap.getUID(imap.selectedFolder().msgCount()); + uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + sequence_set1 = String(uid_begin) + ":" + String(uid_last); + + if (imap.deleteMessages(sequence_set1, true /* if sequence set are the UIDs */, false)) + Serial.println("Deleting messages using UIDs ranges success"); + else + Serial.println("Error, Deleting messages using UIDs ranges"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/External_Client/External_Client.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/External_Client/External_Client.ino new file mode 100644 index 000000000000..65e11b7b3ec2 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/External_Client/External_Client.ino @@ -0,0 +1,334 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +/** + * This example shows how to send Email using EthernetClient. + * + * This example used ESP32 and WIZnet W5500 Ethernet module. + * + * Please see examples/SMTP/Ethernet and examples/SMTP/External_Client for more usage + */ + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include + +#include + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define IMAP_HOST "" +#define IMAP_PORT 993 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +void imapCallback(IMAP_Status status); + +void printAllMailboxesInfo(IMAPSession &imap); + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +void printMessages(std::vector &msgItems, bool headerOnly); + +void printAttacements(std::vector &atts); + +IMAPSession imap; + +EthernetClient eth_client; + +void networkConnection() +{ + // Reset the network connection + WiFi.disconnect(); + + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + Serial.print("Connecting to Wi-Fi"); + unsigned long ms = millis(); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); + if (millis() - ms >= 5000) + { + Serial.println(" failed!"); + return; + } + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); +} + +void networkStatusRequestCallback() +{ + imap.setNetworkStatus(WiFi.status() == WL_CONNECTED); +} + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + + MailClient.networkReconnect(true); + + // The WiFi credentials are required for SAMD21 + // due to it does not have reconnect feature. + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); + + networkConnection(); + + imap.debug(1); + + /* + For internal NTP client + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + MailClient.setUDPClient(&udp_client, 0 /* GMT offset */); + + MailClient.networkReconnect(true); + + imap.callback(imapCallback); + + Session_Config config; + + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + IMAP_Data imap_data; + + imap_data.search.criteria.clear(); + + imap_data.search.unseen_msg = true; + + imap_data.storage.saved_path = F("/email_data"); + + imap_data.storage.type = esp_mail_file_storage_type_flash; + + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + imap_data.enable.html = true; + imap_data.enable.text = true; + + imap_data.enable.recent_sort = true; + + imap_data.enable.download_status = true; + + imap_data.limit.search = 5; + + imap_data.limit.msg_size = 512; + + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + imap.setClient(ð_client); + + imap.networkConnectionRequestCallback(networkConnection); + + imap.networkStatusRequestCallback(networkStatusRequestCallback); + + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + printAllMailboxesInfo(imap); + + if (!imap.selectFolder(F("INBOX"))) + return; + + printSelectedMailboxInfo(imap.selectedFolder()); + + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + MailClient.readMail(&imap); + + imap.empty(); +} + +void loop() +{ +} + +void imapCallback(IMAP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + FoldersCollection folders; + + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + for (size_t i = 0; i < msgItems.size(); i++) + { + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Firmware_Update_Attachment/Firmware_Update_Attachment.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Firmware_Update_Attachment/Firmware_Update_Attachment.ino new file mode 100644 index 000000000000..15f706daa616 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Firmware_Update_Attachment/Firmware_Update_Attachment.ino @@ -0,0 +1,464 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to read Email and update firmware if firmware file name in attachments matches. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// Provide the SD card interfaces setting and mounting +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Assign the attachment filename to compare, update firmware if it matches */ + imap_data.firmware_update.attach_filename = "firmware.bin"; + /* save (download) firmware to file? */ + imap_data.firmware_update.save_to_file = false; + + /** + * Device will reboot in if imap.isFirmwareUpdated() returns true in imapCallback function. + * To disable firmware update, call imap_data.firmware_update.attach_filename.clear(); or + * imap_data.firmware_update.attach_filename = ""; + * + */ + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /** Message UID to fetch or read e.g. 100. + * In this case we will get the UID from the max message number (lastest message) + */ + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + // or fetch via the message sequence number + // imap_data.fetch.number = imap.selectedFolder().msgCount(); + + // if both imap_data.fetch.uid and imap_data.fetch.number were set, + // then total 2 messages will be fetched i.e. one using uid and other using number. + + /* Set seen flag */ + + // The message with "Seen" flagged means the message was already read or seen by user. + // The default value of this option is set to false. + // If you want to set the message flag as "Seen", set this option to true. + // If this option is false, the message flag was unchanged. + // To set or remove flag from message, see Set_Flags.ino example. + + // imap_data.fetch.set_seen = true; + + /* Read or search the Email and close the session */ + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + + if (imap.isFirmwareUpdateSuccess()) + { + Serial.println("****************************"); + Serial.println("Firmware is already updated, restarting device..."); + delay(2000); +#if defined(ESP32) || defined(ESP8266) + ESP.restart(); +#elif defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_NANO_RP2040_CONNECT) + rp2040.restart(); +#endif + } + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and + * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename + * (> 13 characters) is not support in the SD.h library. + * To show how its original file name, use imap.fileList(). + */ + // Serial.println(imap.fileList()); + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Get_Quota/Get_Quota.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Get_Quota/Get_Quota.ino new file mode 100644 index 000000000000..aae7f050d936 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Get_Quota/Get_Quota.ino @@ -0,0 +1,215 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to get the quota root's resource usage and limits. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + IMAP_Quota_Root_Info info; + + Serial.println("\nGet quota root..."); + + if (!imap.getQuota("", &info)) + { + Serial.println("Get quota root failed"); + } + else + { + MailClient.printf("Quota root: %s, Resource name: %s, Usage (k): %d, Limit (k): %d\n", info.quota_root.c_str(), info.name.c_str(), (int)info.usage, (int)info.limit); + } + + IMAP_Quota_Roots_List quota_roots; + + Serial.println("\nGet quota roots list for INBOX folder..."); + + if (!imap.getQuotaRoot("INBOX", "a_roots)) + { + Serial.println("\nGet quota roots list failed"); + } + else + { + for (size_t i = 0; i < quota_roots.size(); i++) + MailClient.printf("%d, Quota root: %s, Resource name: %s, Usage (k): %d, Limit (k): %d\n", (int)i + 1, quota_roots[i].quota_root.c_str(), quota_roots[i].name.c_str(), (int)quota_roots[i].usage, (int)quota_roots[i].limit); + } + + Serial.println("\nSet quota root..."); + + info.name = "STORAGE"; + info.limit = 1024 * 1024; // 1048576 k or 1 G. + + if (!imap.setQuota("", &info)) + { + Serial.println("\nSet quota root failed"); + } + else + { + Serial.println("\nSet quota root success"); + } + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Mailbox_Changes_Notification/Mailbox_Changes_Notification.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Mailbox_Changes_Notification/Mailbox_Changes_Notification.ino new file mode 100644 index 000000000000..271a9f53ae0d --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Mailbox_Changes_Notification/Mailbox_Changes_Notification.ino @@ -0,0 +1,446 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to get notification in realtime when incoming message arrived and other mailbox changes. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the selected folder update info */ +void printPollingStatus(IMAPSession &imap); + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +/* Declare the global used Session_Config for user defined session credentials */ +Session_Config config; + +/* Define the IMAP_Data object used for user defined IMAP operating options. */ +IMAP_Data imap_data; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void connectWiFi() +{ + WiFi.disconnect(); + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + connectWiFi(); + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /** Assign internet connection handler function + * in case of lost internet connection for re-listening the mailbox. + */ + config.network_connection_handler = connectWiFi; + + // You can use TCP KeepAlive for more reliable of listen (idle) operation, please read this for detail. + // https://github.com/mobizt/ESP-Mail-Client#using-tcp-session-keepalive-in-esp8266-and-esp32 + // You can use keepAlive in ESP8266 core version newer than v3.1.2. + // Or you can use git version (v3.1.2) https://github.com/esp8266/Arduino +#if defined(ESP32) + imap.keepAlive(5, 5, 1); +#endif + + /* Set the TCP response read timeout in seconds */ + // smtp.setTCPTimeout(10); + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); +} + +void loop() +{ + /* imap.connect and imap.selectFolder or imap.openFolder nedded to be called once prior to listen */ + + // Listen for mailbox changes + if (!imap.listen()) + return; + + // Check the changes + if (imap.folderChanged()) + printPollingStatus(imap); + + // To stop listen, use imap.stopListen(); and to listen again, call imap.listen() +} + +void printPollingStatus(IMAPSession &imap) +{ + /* Declare the selected folder info class to get the info of selected mailbox folder */ + SelectedFolderInfo sFolder = imap.selectedFolder(); + + /* Show the mailbox info */ + MailClient.printf("\nMailbox status changed\n----------------------\nTotal Messages: %d\n", sFolder.msgCount()); + + if (sFolder.pollingStatus().type == imap_polling_status_type_new_message) + { + + MailClient.printf("New message %d, has been addedd, reading message...\n", (int)sFolder.pollingStatus().messageNum); + + // if (sFolder.recentCount() > 0) + // MailClient.printf("\nMesssage count which recent flag set: %d\n", sFolder.recentCount()); + + // we need to stop polling before do anything + imap.stopListen(); + + // Get the UID of new message and fetch + imap_data.fetch.uid = imap.getUID(sFolder.pollingStatus().messageNum); + MailClient.readMail(&imap, false); + } + else if (sFolder.pollingStatus().type == imap_polling_status_type_remove_message) + MailClient.printf("Message %d, has been removed\n\n", (int)sFolder.pollingStatus().messageNum); + else if (sFolder.pollingStatus().type == imap_polling_status_type_fetch_message) + MailClient.printf("Message %d, has been fetched with the argument %s\n\n", (int)sFolder.pollingStatus().messageNum, sFolder.pollingStatus().argument.c_str()); +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("RFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_List/Move_Messages_List.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_List/Move_Messages_List.ino new file mode 100644 index 000000000000..bf95fcc20a25 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_List/Move_Messages_List.ino @@ -0,0 +1,214 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to move messages from the mailbox to other folder. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Define the MessageList class to add the message to move */ + MessageList toMove; + + /* Add message uid to move to the list */ + toMove.add(3); + toMove.add(4); + + // imap.createFolder("test"); + + /* Move all messages in the list to the folder "test" */ + if (imap.moveMessages(&toMove, F("test"))) + Serial.println("\nMessages moved"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_Message_Numbers_Ranges/Move_Messages_Message_Numbers_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_Message_Numbers_Ranges/Move_Messages_Message_Numbers_Ranges.ino new file mode 100644 index 000000000000..329c9db990db --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_Message_Numbers_Ranges/Move_Messages_Message_Numbers_Ranges.ino @@ -0,0 +1,213 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to move messages from the mailbox to other folder using message numbers ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Move all messages using message sequence ranges (last 10 message numbers) to the folder "test"*/ + int msg_last = imap.selectedFolder().msgCount(); + int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + String sequence_set2 = String(msg_begin) + ":" + String(msg_last); + + if (imap.moveMessages(sequence_set2, false /* if sequence set are message numbers not UIDs */, F("test"))) + Serial.println("\nMoving messages using message numbers ranges success"); + else + Serial.println("\nError, moving messages using message numbers ranges"); + + // imap.deleteolder("test"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_UIDs_Ranges/Move_Messages_UIDs_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_UIDs_Ranges/Move_Messages_UIDs_Ranges.ino new file mode 100644 index 000000000000..3d75cc0653dc --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_UIDs_Ranges/Move_Messages_UIDs_Ranges.ino @@ -0,0 +1,214 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to move messages from the mailbox to other folder using UIDs ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Move all messages using UIDs ranges (last 10 UIDs) to the folder "test" */ + int uid_last = imap.getUID(imap.selectedFolder().msgCount()); + int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + String sequence_set1 = String(uid_begin) + ":" + String(uid_last); + + if (imap.moveMessages(sequence_set1, true /* if sequence set are the UIDs */, F("test"))) + Serial.println("\nMoving messages using UIDs ranges success"); + else + Serial.println("\nError, moving messages using UIDs ranges"); + + // imap.deleteolder("test"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Namespaces/Namespaces.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Namespaces/Namespaces.ino new file mode 100644 index 000000000000..533d90dcf2dc --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Namespaces/Namespaces.ino @@ -0,0 +1,216 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to get the namespaces. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + IMAP_Namespaces_List ns_list; + + Serial.println("\nGet namespaces..."); + + if (!imap.getNamespace(&ns_list)) + { + Serial.println("\nGet namespaces failed"); + } + else + { + if (ns_list.personal_namespaces.size() > 0) + { + Serial.println("\nPersonal Namespaces..."); + for (size_t i = 0; i < ns_list.personal_namespaces.size(); i++) + { + MailClient.printf("Prefix: %s, Delimiter: %s\n", ns_list.personal_namespaces[i].prefix.c_str(), ns_list.personal_namespaces[i].delimiter.c_str()); + } + } + + if (ns_list.other_users_namespaces.size() > 0) + { + Serial.println("\nOther Users Namespaces..."); + for (size_t i = 0; i < ns_list.other_users_namespaces.size(); i++) + { + MailClient.printf("Prefix: %s, Delimiter: %s\n", ns_list.other_users_namespaces[i].prefix.c_str(), ns_list.other_users_namespaces[i].delimiter.c_str()); + } + } + + if (ns_list.shared_namespaces.size() > 0) + { + Serial.println("\nShared Namespaces..."); + for (size_t i = 0; i < ns_list.shared_namespaces.size(); i++) + { + MailClient.printf("Prefix: %s, Delimiter: %s\n", ns_list.shared_namespaces[i].prefix.c_str(), ns_list.shared_namespaces[i].delimiter.c_str()); + } + } + } + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Email_Access_Token/Read_Email_Access_Token.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Email_Access_Token/Read_Email_Access_Token.ino new file mode 100644 index 000000000000..26b32a91bbbc --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Email_Access_Token/Read_Email_Access_Token.ino @@ -0,0 +1,472 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example will log in with the SASL XOAUTH2 mechanisme using OAuth2.0 access token. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" + +/** The OAuth2.0 access token + * The generation, exchange and refresh of the access token are not available + * in this library. + * + * To test this using GMail, get the OAuth2.0 access token from this web site + * https://developers.google.com/oauthplayground/ + * + * 1. Select the following scope (in Step 1) from Gmail API V1 + * https://mail.google.com/ + * https://mail.google.com/ + * + * 2. Click Authorize APIs button. + * 3. Cick Exchangeauthorization code for tokens. + * 4. From the response, look at access_token from the JSON payload node. + * 5. Copy that access token and paste to the AUTHOR_ACCESS_TOKEN value. + * + * The token will be expired in 3600 seconds (1 Hr). + * The AUTHOR_EMAIL above is the Email address that you granted to access the Gmail services. + */ +#define AUTHOR_ACCESS_TOKEN "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.accessToken = AUTHOR_ACCESS_TOKEN; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Message UID to fetch or read e.g. 100 */ + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + /* Set seen flag*/ + // imap_data.fetch.set_seen = true; + + /* Search criteria */ + imap_data.search.criteria.clear(); + + /* Also search the unseen message */ + imap_data.search.unseen_msg = true; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_flash; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /* Read or search the Email and close the session */ + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and + * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename + * (> 13 characters) is not support in the SD.h library. + * To show how its original file name, use imap.fileList(). + */ + // Serial.println(imap.fileList()); + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Sequence_Set/Read_Sequence_Set.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Sequence_Set/Read_Sequence_Set.ino new file mode 100644 index 000000000000..63ce16c97dc1 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Sequence_Set/Read_Sequence_Set.ino @@ -0,0 +1,477 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to read Email using UIDs ranges or message numbers ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the Session_Config for user defined session credentials */ +Session_Config config; + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +/* Define the IMAP_Data object used for user defined IMAP operating options. */ +IMAP_Data imap_data; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void readEmailsUIDS() +{ + + int uid_last = imap.getUID(imap.selectedFolder().msgCount()); + int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + // Fetch last 10 UIDs + String sequence_set = String(uid_begin) + ":" + String(uid_last); + + imap_data.fetch.sequence_set.string = sequence_set; + + imap_data.fetch.sequence_set.UID = true; // The sequence set are UIDs ranges + + imap_data.fetch.sequence_set.headerOnly = true; // Do not fetch the content, header only + + MailClient.readMail(&imap, false /* do not close sessiopn */); + + imap_data.limit.fetch = 5; // Set the limit of number of messages in the fetch results +} + +void readEmailsNumbers() +{ + int msg_last = imap.selectedFolder().msgCount(); + int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + String sequence_set = String(msg_begin) + ":" + String(msg_last); + + imap_data.fetch.sequence_set.string = sequence_set; + + imap_data.fetch.sequence_set.UID = false; // The sequence set are not UIDs + + imap_data.fetch.sequence_set.headerOnly = true; // Do not fetch the content, header only + + imap_data.limit.fetch = 5; // Set the limit of number of messages in the fetch results + + // Read Email and close session + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + // If ID extension was supported by IMAP server, assign the client identification + // name, version, vendor, os, os_version, support_url, address, command, arguments, environment + // Server ID can be optained from imap.serverID() after calling imap.connect and imap.id. + + // imap_data.identification.name = "User"; + // imap_data.identification.version = "1.0"; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + // Client identification can be sent to server later with + /** + * IMAP_Identification iden; + * iden.name = "user"; + * iden.version = "1.0"; + * + * if (imap.id(&iden)) + * { + * Serial.println("\nSend Identification success"); + * Serial.println(imap.serverID()); + * } + * else + * MailClient.printf("nIdentification sending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + */ + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + Serial.println("::::::::::::::::: Reading Emails using the UIDs ranges ::::::::::::::::"); + readEmailsUIDS(); + + Serial.println("::::::::::: Reading Emails using the message numbers ranges :::::::::::"); + readEmailsNumbers(); +} + +void loop() +{ +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and + * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename + * (> 13 characters) is not support in the SD.h library. + * To show how its original file name, use imap.fileList(). + */ + // Serial.println(imap.fileList()); + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email/Read_Single_Email.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email/Read_Single_Email.ino new file mode 100644 index 000000000000..c8533ed92dd9 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email/Read_Single_Email.ino @@ -0,0 +1,516 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to read Email and store the message in SD card. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// Provide the SD card interfaces setting and mounting +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_sd; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + // If ID extension was supported by IMAP server, assign the client identification + // name, version, vendor, os, os_version, support_url, address, command, arguments, environment + // Server ID can be optained from imap.serverID() after calling imap.connect and imap.id. + + // imap_data.identification.name = "User"; + // imap_data.identification.version = "1.0"; + + /* Set the TCP response read timeout in seconds */ + // imap.setTCPTimeout(10); + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + /** Or connect without log in and log in later + + if (!imap.connect(&config, &imap_data, false)) + return; + + if (!imap.loginWithPassword(AUTHOR_EMAIL, AUTHOR_PASSWORD)) + return; + */ + + // Client identification can be sent to server later with + /** + * IMAP_Identification iden; + * iden.name = "user"; + * iden.version = "1.0"; + * + * if (imap.id(&iden)) + * { + * Serial.println("\nSend Identification success"); + * Serial.println(imap.serverID()); + * } + * else + * MailClient.printf("nIdentification sending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + */ + + if (!imap.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /** Message UID to fetch or read e.g. 100. + * In this case we will get the UID from the max message number (lastest message) + */ + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + // if IMAP server supports CONDSTORE extension, the modification sequence can be assign to fetch command + // Note that modsequence value supports in this library is 32-bit integer + imap_data.fetch.modsequence = 123; + + // To fetch only header part + // imap_data.fetch.headerOnly = true; + + // or fetch via the message sequence number + // imap_data.fetch.number = imap.selectedFolder().msgCount(); + + // if both imap_data.fetch.uid and imap_data.fetch.number were set, + // then total 2 messages will be fetched i.e. one using uid and other using number. + + /* Set seen flag */ + + // The message with "Seen" flagged means the message was already read or seen by user. + // The default value of this option is set to false. + // If you want to set the message flag as "Seen", set this option to true. + // If this option is false, the message flag was unchanged. + // To set or remove flag from message, see Set_Flags.ino example. + + // imap_data.fetch.set_seen = true; + + /* Fetch or read only message header */ + // imap_data.fetch.headerOnly = true; + + /* Read or search the Email and close the session */ + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and + * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename + * (> 13 characters) is not support in the SD.h library. + * To show how its original file name, use imap.fileList(). + */ + // Serial.println(imap.fileList()); + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop/Read_Single_Email_Loop.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop/Read_Single_Email_Loop.ino new file mode 100644 index 000000000000..96d1d5568c49 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop/Read_Single_Email_Loop.ino @@ -0,0 +1,561 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to read Email repeatedly. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// Provide the SD card interfaces setting and mounting +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +unsigned long readMillis = 0; +int totalMessage = 0; +int msgNum = 0; +int sign = -1; + +/* Declare the global used Session_Config for user defined session credentials */ +Session_Config config; + +/* Define the IMAP_Data object used for user defined IMAP operating options. */ +IMAP_Data imap_data; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +// For Free Heap checking +#include "HeapStat.h" +HeapStat heapInfo; + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Message UID to fetch or read */ + imap_data.fetch.uid.clear(); + + /* Search criteria */ + imap_data.search.criteria.clear(); + + /* Also search the unseen message */ + imap_data.search.unseen_msg = true; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_sd; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = false; + imap_data.download.text = false; + imap_data.download.html = false; + imap_data.download.attachment = false; + imap_data.download.inlineImg = false; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + // If ID extension was supported by IMAP server, assign the client identification + // name, version, vendor, os, os_version, support_url, address, command, arguments, environment + // Server ID can be optained from imap.serverID() after calling imap.connect and imap.id. + + // imap_data.identification.name = "User"; + // imap_data.identification.version = "1.0"; + + /* Set the TCP response read timeout in seconds */ + // imap.setTCPTimeout(10); + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + // Client identification can be sent to server later with + /** + * IMAP_Identification iden; + * iden.name = "user"; + * iden.version = "1.0"; + * + * if (imap.id(&iden)) + * { + * Serial.println("\nSend Identification success"); + * Serial.println(imap.serverID()); + * } + * else + * MailClient.printf("nIdentification sending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + */ + + if (!imap.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + totalMessage = imap.selectedFolder().msgCount(); + + /* Start fetch from last message */ + msgNum = totalMessage; + sign = -1; // count down + + /* To start fetch from first message */ + // msgNum = 1; + // sign = 1;// count up +} + +void loop() +{ + if (millis() - readMillis > 10000 || readMillis == 0) + { + readMillis = millis(); + + // If session was closed, reconnect and re-select the mailbox + if (!imap.connected()) + { + if (!imap.connect(&config, &imap_data)) + return; + + if (!imap.selectFolder(F("INBOX"))) + return; + + if (totalMessage == 0) + { + totalMessage = imap.selectedFolder().msgCount(); + msgNum = totalMessage; + sign = -1; + } + } + + if (msgNum <= 0) + { + msgNum = 1; + sign = 1; + } + else if (msgNum >= totalMessage) + { + msgNum = totalMessage; + sign = -1; + } + + /* Message number to fetch or read */ + imap_data.fetch.number = msgNum; + + /* Set seen flag */ + // imap_data.fetch.set_seen = true; + + /* Fetch or read only message header */ + // imap_data.fetch.headerOnly = true; + + /** Read or search the Email and keep the TCP session to open + * The second parameter is for close the session. + */ + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + if (MailClient.readMail(&imap, false)) + msgNum += sign; + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + + msgNum += sign; + } +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + + // Collect memory info + heapInfo.collect(); + + // Print memory info + heapInfo.print(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and + * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename + * (> 13 characters) is not support in the SD.h library. + * To show how its original file name, use imap.fileList(). + */ + // Serial.println(imap.fileList()); + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop_Silent_Mode/Read_Single_Email_Loop_Silent_Mode.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop_Silent_Mode/Read_Single_Email_Loop_Silent_Mode.ino new file mode 100644 index 000000000000..94183bbd792e --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop_Silent_Mode/Read_Single_Email_Loop_Silent_Mode.ino @@ -0,0 +1,402 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to read Email repeatedly. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** + * To use library in silent mode (no debug printing and callback), please define this macro in src/ESP_Mail_FS.h. + * #define SILENT_MODE + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define IMAP_HOST "" + +#define IMAP_PORT 993 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +void printImapData(IMAP_Status status); + +void printAllMailboxesInfo(IMAPSession &imap); + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +void printMessages(std::vector &msgItems, bool headerOnly); + +void printAttacements(std::vector &atts); + +IMAPSession imap; + +unsigned long readMillis = 0; +int totalMessage = 0; +int msgNum = 0; +int sign = -1; + +Session_Config config; + +IMAP_Data imap_data; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +// For Free Heap checking +#include "HeapStat.h" +HeapStat heapInfo; + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h +#endif + + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + imap_data.fetch.uid.clear(); + + imap_data.search.criteria.clear(); + + imap_data.search.unseen_msg = true; + + imap_data.storage.saved_path = F("/email_data"); + + imap_data.storage.type = esp_mail_file_storage_type_sd; + + imap_data.download.header = false; + imap_data.download.text = false; + imap_data.download.html = false; + imap_data.download.attachment = false; + imap_data.download.inlineImg = false; + + imap_data.enable.html = true; + imap_data.enable.text = true; + + imap_data.enable.recent_sort = true; + + imap_data.enable.download_status = true; + + imap_data.limit.search = 5; + + imap_data.limit.msg_size = 512; + + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + if (!imap.connect(&config, &imap_data)) + { + MailClient.printf("Connection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + return; + } + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + printAllMailboxesInfo(imap); + + if (!imap.selectFolder(F("INBOX"))) + { + MailClient.printf("Folder selection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + return; + } + + printSelectedMailboxInfo(imap.selectedFolder()); + + totalMessage = imap.selectedFolder().msgCount(); + + msgNum = totalMessage; + sign = -1; // count down +} + +void loop() +{ + if (millis() - readMillis > 10000 || readMillis == 0) + { + readMillis = millis(); + + if (!imap.connected()) + { + if (!imap.connect(&config, &imap_data)) + return; + + if (!imap.selectFolder(F("INBOX"))) + return; + + if (totalMessage == 0) + { + totalMessage = imap.selectedFolder().msgCount(); + msgNum = totalMessage; + sign = -1; + } + } + + if (msgNum <= 0) + { + msgNum = 1; + sign = 1; + } + else if (msgNum >= totalMessage) + { + msgNum = totalMessage; + sign = -1; + } + + imap_data.fetch.number = msgNum; + + if (MailClient.readMail(&imap, false)) + { + printImapData(imap.status()); + } + else + { + MailClient.printf("Message reading error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + } + + imap.empty(); + + msgNum += sign; + } +} + +void printImapData(IMAP_Status status) +{ + + if (status.success()) + { + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + imap.empty(); + + heapInfo.collect(); + + heapInfo.print(); + + Serial.println(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + + FoldersCollection folders; + + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + for (size_t i = 0; i < msgItems.size(); i++) + { + + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_And_Read/Search_And_Read.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_And_Read/Search_And_Read.ino new file mode 100644 index 000000000000..7ad828a1e9f1 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_And_Read/Search_And_Read.ino @@ -0,0 +1,352 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to search the unread messages and read them. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** + * To use library in silent mode (no debug printing and callback), please define this macro in src/ESP_Mail_FS.h. + * #define SILENT_MODE + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define IMAP_HOST "" + +#define IMAP_PORT 993 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +void imapCallback(IMAP_Status status); + +void printAllMailboxesInfo(IMAPSession &imap); + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +void printMessageData(); + +IMAPSession imap; + +Session_Config config; + +IMAP_Data imap_data; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +// Max messages in the search result +int max_result = 5; + +// Array to store the UID of messages in search result +int msg_uid[5]; + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + // Clear all these fetch options to perform search + imap_data.fetch.uid.clear(); + imap_data.fetch.number.clear(); + imap_data.fetch.sequence_set.string.clear(); + + imap_data.search.unseen_msg = true; + + // Don't download all to filesystem + imap_data.download.header = false; + imap_data.download.text = false; + imap_data.download.html = false; + imap_data.download.attachment = false; + imap_data.download.inlineImg = false; + + // Store html/text message body in IMAPSession object + imap_data.enable.html = true; + imap_data.enable.text = true; + + imap_data.enable.recent_sort = true; + + // Max messages in the search result + imap_data.limit.search = max_result; + + imap_data.limit.msg_size = 128; + + if (!imap.connect(&config, &imap_data)) + { + MailClient.printf("Connection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + return; + } + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + printAllMailboxesInfo(imap); + + if (!imap.selectFolder(F("INBOX"))) + { + MailClient.printf("Folder selection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + return; + } + + printSelectedMailboxInfo(imap.selectedFolder()); + + // We search the unseen messages first to get its UID and stored in msg_uid. + imap_data.search.criteria = F("SEARCH UNSEEN"); + + MailClient.readMail(&imap, false /* keep session open for fetching message in opened mailbox later */); + + // We already get the search result message, fetch it + + // Fetch the messages using UID stored in msg_uid one by one + for (int i = 0; i < max_result; i++) + { + imap_data.search.criteria.clear(); + + // Mark this message as read + MailClient.addFlag(&imap, msg_uid[i], F("\\Seen"), false /* Close session */, false /* Ignore response */); + + // Now Fech message by UID stored in msg_uid + imap_data.fetch.uid = msg_uid[i]; + + MailClient.readMail(&imap, false /* keep session open for fetching message in opened mailbox later */); + } + + imap.closeSession(); + imap.empty(); +} + +void loop() +{ +} + +void imapCallback(IMAP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + // If this is the search result (imap contains only header info), + // store the message UID that we can fetch for its body later. + if (imap.headerOnly()) + { + max_result = imap.data().msgItems.size(); + for (size_t i = 0; i < imap.data().msgItems.size(); i++) + msg_uid[i] = imap.data().msgItems[i].UID; + } + else + { + // This is the fetch result, print the whole message (header + body) + printMessageData(); + } + + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + + FoldersCollection folders; + + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printMessageData() +{ + + IMAP_MSG_Item msg = imap.data().msgItems[0]; // msgItems contains only one message from fetch + + Serial.println("****************************"); + + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + Serial.println(); +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails/Search_Emails.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails/Search_Emails.ino new file mode 100644 index 000000000000..597b25652eb1 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails/Search_Emails.ino @@ -0,0 +1,533 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example shows how to search all messages with the keywords in the opened mailbox folder. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 // Plain or TLS with STARTTLS + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT esp_mail_imap_port_143 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Declare the IMAP_Data object used for user defined IMAP operating options + * and contains the IMAP operating result + */ + IMAP_Data imap_data; + + /* We will clear fetching message UID as it used to determine the reading mode i.e., search and fetch */ + imap_data.fetch.uid.clear(); + + /** Search criteria + * + * A search key can also be a parenthesized list of one or more search keys + * (e.g., for use with the OR and NOT keys). + * + * Since IMAP protocol uses Polish notation, the search criteria which in the polish notation form can be. + * + * To search the message from "someone@email.com" with the subject "my subject" since 1 Jan 2021, your search criteria can be + * UID SEARCH (OR SUBJECT "my subject" FROM "someone@email.com") SINCE "Fri, 1 Jan 2021 21:52:25 -0800" + * + * To search the message from "mail1@domain.com" or from "mail2@domain.com", the search criteria will be + * UID SEARCH OR FROM mail1@domain.com FROM mail2@domain.com + * + * For more details on using parentheses, AND, OR and NOT search keys in search criteria. + * https://www.limilabs.com/blog/imap-search-requires-parentheses + * + *For keywords used in search criteria, see + * https://github.com/mobizt/ESP-Mail-Client/tree/master/src#search-criteria + * + * Use "SEARCH UNSEEN" for unread messages search + * Use "SEARCH RECENT" for messages with the \\RECENT flag set + * Use "ON _date_" for messages with Date header matching _date_ + * Use "BEFORE _date_" for messages with Date header before _date_ + */ + imap_data.search.criteria = F("SEARCH RECENT"); + + /* Also search the unseen message */ + imap_data.search.unseen_msg = true; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_flash; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + // If ID extension was supported by IMAP server, assign the client identification + // name, version, vendor, os, os_version, support_url, address, command, arguments, environment + // Server ID can be optained from imap.serverID() after calling imap.connect and imap.id. + + // imap_data.identification.name = "User"; + // imap_data.identification.version = "1.0"; + + /* Set the TCP response read timeout in seconds */ + // imap.setTCPTimeout(10); + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + /** Or connect without log in and log in later + + if (!imap.connect(&config, &imap_data, false)) + return; + + if (!imap.loginWithPassword(AUTHOR_EMAIL, AUTHOR_PASSWORD)) + return; + */ + + // Client identification can be sent to server later with + /** + * IMAP_Identification iden; + * iden.name = "user"; + * iden.version = "1.0"; + * + * if (imap.id(&iden)) + * { + * Serial.println("\nSend Identification success"); + * Serial.println(imap.serverID()); + * } + * else + * MailClient.printf("nIdentification sending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + */ + + if (!imap.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /** Read or search the Email and keep the TCP session to open + * The second parameter is for close the session. + */ + MailClient.readMail(&imap, false); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + + /** Open or select other mailbox folder + * The folder that previousely opened will be closed + */ + if (imap.selectFolder(F("Junk"))) + { + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /** Config to search all messages in the opened mailboax (Search mode) + * For keywords used in search criteria, see + * https://github.com/mobizt/ESP-Mail-Client/tree/master/src#search-criteria + */ + imap_data.search.criteria = F("SEARCH ALL"); // or "SEARCH NEW" for recent received messages + + /* We will clear fetching message UID as it used to determine the reading mode i.e., search and fetch */ + imap_data.fetch.uid.clear(); + + /* Search the Email and close the session */ + MailClient.readMail(&imap); + } + + /* Close the seeion in case the session is still open */ + imap.closeSession(); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + // Message sequence number + MailClient.printf("Number: %d\n", msg.msgNo); + // Message UID + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails_Silent_Mode/Search_Emails_Silent_Mode.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails_Silent_Mode/Search_Emails_Silent_Mode.ino new file mode 100644 index 000000000000..5f6367ef87f0 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails_Silent_Mode/Search_Emails_Silent_Mode.ino @@ -0,0 +1,327 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to search all messages with the keywords in the opened mailbox folder. + +/** + * To use library in silent mode (no debug printing and callback), please define this macro in src/ESP_Mail_FS.h. + * #define SILENT_MODE + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define IMAP_HOST "" + +#define IMAP_PORT esp_mail_imap_port_143 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +void printImapData(IMAP_Status status); + +void printAllMailboxesInfo(IMAPSession &imap); + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +void printMessages(std::vector &msgItems, bool headerOnly); + +void printAttacements(std::vector &atts); + +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + Session_Config config; + + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + IMAP_Data imap_data; + + imap_data.fetch.uid.clear(); + + imap_data.search.criteria = F("SEARCH RECENT"); + + imap_data.search.unseen_msg = true; + + imap_data.storage.saved_path = F("/email_data"); + + imap_data.storage.type = esp_mail_file_storage_type_flash; + + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + imap_data.enable.html = true; + imap_data.enable.text = true; + + imap_data.enable.recent_sort = true; + + imap_data.enable.download_status = true; + + imap_data.limit.search = 5; + + imap_data.limit.msg_size = 512; + + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + imap.setTCPTimeout(10); + + if (!imap.connect(&config, &imap_data)) + { + MailClient.printf("Connection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + return; + } + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + printAllMailboxesInfo(imap); + + if (!imap.selectFolder(F("INBOX"))) + { + MailClient.printf("Folder selection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + return; + } + + printSelectedMailboxInfo(imap.selectedFolder()); + + if (MailClient.readMail(&imap, false)) + { + printImapData(imap.status()); + } + else + { + MailClient.printf("Message searching error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + } + + imap.closeSession(); + + imap.empty(); +} + +void loop() +{ +} + +void printImapData(IMAP_Status status) +{ + + if (status.success()) + { + MailClient.printf("\nFound %d messages\n\n", imap.selectedFolder().searchCount()); + + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + FoldersCollection folders; + + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + for (size_t i = 0; i < msgItems.size(); i++) + { + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_List/Set_Flags_List.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_List/Set_Flags_List.ino new file mode 100644 index 000000000000..3aedc902162a --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_List/Set_Flags_List.ino @@ -0,0 +1,339 @@ +/** + * This example shows how to set messages flags. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + * + */ + +// This example shows how to set messages flags. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set seen flag */ + // imap_data.fetch.set_seen = true; + + /* Search criteria */ + imap_data.search.criteria.clear(); + + /* Also search the unseen message */ + imap_data.search.unseen_msg = true; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_flash; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /* Message UID to fetch or read e.g. 100 */ + int uid = imap.getUID(imap.selectedFolder().msgCount()); + + /** Set \Seen and \Answered to flags for message with UID + * The seesion will keep open. + */ + if (MailClient.setFlag(&imap, uid, F("\\Seen \\Answered"), false)) + Serial.println("\nSetting FLAG success"); + else + Serial.println("\nError, setting FLAG"); + + /* Add \Seen and \Answered to flags for message with UID 100 */ + // MailClient.addFlag(imap, 100, "\\Seen \\Answered", false); + + /* Remove \Seen and \Answered from flags for message with UID 100 */ + // MailClient.removeFlag(imap, 100, "\\Seen \\Answered", false); + + /* Remove Seen and Answered flags from messages using UID ranges (last 10 UIDs) */ + int uid_last = imap.getUID(imap.selectedFolder().msgCount()); + int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + String sequence_set1 = String(uid_begin) + ":" + String(uid_last); + + if (MailClient.removeFlag(&imap, sequence_set1, true /* if sequence set are the UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) + Serial.println("\nRemoving FLAG with UIDs ranges success"); + else + Serial.println("\nError, removing FLAG with UIDs ranges"); + + /* Remove Seen and Answered flags from messages using message sequence ranges (last 10 message numbers) */ + int msg_last = imap.selectedFolder().msgCount(); + int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + String sequence_set2 = String(msg_begin) + ":" + String(msg_last); + + if (MailClient.removeFlag(&imap, sequence_set2, false /* if sequence set are message numbers not UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) + Serial.println("\nRemoving FLAG with message numbers ranges success"); + else + Serial.println("\nError, removing FLAG with message numbers ranges"); + + imap_data.fetch.uid = uid; + + /* Read or search the Email and close the session */ + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_Message_Numbers_Ranges/Set_Flags_Message_Numbers_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_Message_Numbers_Ranges/Set_Flags_Message_Numbers_Ranges.ino new file mode 100644 index 000000000000..0e2645f25437 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_Message_Numbers_Ranges/Set_Flags_Message_Numbers_Ranges.ino @@ -0,0 +1,309 @@ +/** + * This example shows how to set messages flags. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + * + */ + +// This example shows how to set messages flags using message numbers ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set seen flag */ + // imap_data.fetch.set_seen = true; + + /* Search criteria */ + imap_data.search.criteria.clear(); + + /* Also search the unseen message */ + imap_data.search.unseen_msg = true; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_flash; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /* Add Seen and Answered flags from messages using message numbers ranges (last 10 message numbers) */ + int msg_last = imap.selectedFolder().msgCount(); + int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + String sequence_set1 = String(msg_begin) + ":" + String(msg_last); + + if (MailClient.addFlag(&imap, sequence_set1, false /* if sequence set are message numbers not UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) + Serial.println("\nAdding FLAG with message numbers ranges success"); + else + Serial.println("\nError, adding FLAG with message numbers ranges"); + + /* Remove Seen and Answered flags from messages using message numbers ranges (last 10 message numbers) */ + if (MailClient.removeFlag(&imap, sequence_set1, false /* if sequence set are message numbers not UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) + Serial.println("\nRemoving FLAG with message numbers ranges success"); + else + Serial.println("\nError, removing FLAG with message numbers ranges"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_UIDs_Ranges/Set_Flags_UIDs_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_UIDs_Ranges/Set_Flags_UIDs_Ranges.ino new file mode 100644 index 000000000000..4e3ccc2ad733 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_UIDs_Ranges/Set_Flags_UIDs_Ranges.ino @@ -0,0 +1,310 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to set messages flags. + +// This example shows how to set messages flags using UIDs ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set seen flag */ + // imap_data.fetch.set_seen = true; + + /* Search criteria */ + imap_data.search.criteria.clear(); + + /* Also search the unseen message */ + imap_data.search.unseen_msg = true; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_flash; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /* Add Seen and Answered flags from messages using UID ranges (last 10 UIDs) */ + int uid_last = imap.getUID(imap.selectedFolder().msgCount()); + int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + String sequence_set1 = String(uid_begin) + ":" + String(uid_last); + + if (MailClient.addFlag(&imap, sequence_set1, true /* if sequence set are the UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) + Serial.println("\nAdding FLAG with UIDs ranges success"); + else + Serial.println("\nError, adding FLAG with UIDs ranges"); + + /* Remove Seen and Answered flags from messages using UID ranges (last 10 UIDs) */ + if (MailClient.removeFlag(&imap, sequence_set1, true /* if sequence set are the UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) + Serial.println("\nRemoving FLAG with UIDs ranges success"); + else + Serial.println("\nError, removing FLAG with UIDs ranges"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Basic_Auth/Basic_Auth.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Basic_Auth/Basic_Auth.ino new file mode 100644 index 000000000000..c43a149eb7e2 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Basic_Auth/Basic_Auth.ino @@ -0,0 +1,219 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example showes how to send Email using custom commands. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 // See STARTTLS.ino example + */ +#define SMTP_PORT esp_mail_smtp_port_465 // port 465 is not available for Outlook.com + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "-----END CERTIFICATE-----\n"; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(SMTP_Response res) +{ + + // The res.id is the command identifier number that use to identify the source of command. + + // The command identifier number can be set via the last parameter of customConnect and sendCustomCommand functions. + + // If command identifier number was not set in those functions, the res.id received will be auto increased and begins with 0 + + MailClient.printf("> C: Command ID %d\n", res.id); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.statusCode > 0) + { + MailClient.printf("> C: Response finished with status code %d\n\n", res.statusCode); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* Connect to the server */ + if (!smtp.connect(&config)) + return; + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + // Please don't forget to change sender@xxxxxx.com to your email + if (smtp.sendCustomCommand(F("MAIL FROM:"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Please don't forget to change recipient@xxxxx.com with your recipient email + if (smtp.sendCustomCommand(F("RCPT TO:"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(F("DATA"), customCommandCallback) != 354) + { + smtp.closeSession(); + return; + } + + // Send data with command which terminated with dot '.' + if (smtp.sendCustomCommand(F("Subject: Test sending Email\r\nHello World!\r\n."), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Do not use this command in ESP8266 due to memory leaks in ESP8266 core BearSSL. + // smtp.sendCustomCommand(F("QUIT"), customCommandCallback); + + smtp.closeSession(); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Custom_Auth/Custom_Auth.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Custom_Auth/Custom_Auth.ino new file mode 100644 index 000000000000..13f50920c1cb --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Custom_Auth/Custom_Auth.ino @@ -0,0 +1,248 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example showes how to send Email using custom commands. + + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 // See STARTTLS.ino example + */ +#define SMTP_PORT esp_mail_smtp_port_465 // port 465 is not available for Outlook.com + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "-----END CERTIFICATE-----\n"; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(SMTP_Response res) +{ + + // The res.id is the command identifier number that use to identify the source of command. + + // The command identifier number can be set via the last parameter of customConnect and sendCustomCommand functions. + + // If command identifier number was not set in those functions, the res.id received will be auto increased and begins with 0 + + MailClient.printf("> C: Command ID %d\n", res.id); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.statusCode > 0) + { + MailClient.printf("> C: Response finished with status code %d\n\n", res.statusCode); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Connect to the server */ + if (smtp.customConnect(&config /* session credentials */, customCommandCallback) != 220) + { + Serial.println("! E: Unable to connect to server"); + return; + } + + if (smtp.sendCustomCommand(F("EHLO 127.0.0.1"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(F("AUTH LOGIN"), customCommandCallback) != 334) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(MailClient.toBase64(config.login.email), customCommandCallback) != 334) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(MailClient.toBase64(config.login.password), customCommandCallback) != 235) + { + smtp.closeSession(); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("Successfully logged in.\n"); + else + Serial.println("Connected with no Auth.\n"); + + // Please don't forget to change sender@xxxxxx.com to your email + if (smtp.sendCustomCommand(F("MAIL FROM:"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Please don't forget to change recipient@xxxxx.com with your recipient email + if (smtp.sendCustomCommand(F("RCPT TO:"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(F("DATA"), customCommandCallback) != 354) + { + smtp.closeSession(); + return; + } + + if (!smtp.sendCustomData(F("Subject: Test sending Email\r\n"))) + { + smtp.closeSession(); + return; + } + + if (!smtp.sendCustomData(F("Hello World!\r\n"))) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(F("."), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Do not use this command in ESP8266 due to memory leaks in ESP8266 core BearSSL. + // smtp.sendCustomCommand(F("QUIT"), customCommandCallback); + + smtp.closeSession(); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/STARTTLS/STARTTLS.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/STARTTLS/STARTTLS.ino new file mode 100644 index 000000000000..64788c7999cc --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/STARTTLS/STARTTLS.ino @@ -0,0 +1,268 @@ + + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example showes how to send Email using custom commands. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 // port 465 is not available for Outlook.com + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 // for STARTTLS + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "-----END CERTIFICATE-----\n"; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(SMTP_Response res) +{ + + // The res.id is the command identifier number that use to identify the source of command. + + // The command identifier number can be set via the last parameter of customConnect and sendCustomCommand functions. + + // If command identifier number was not set in those functions, the res.id received will be auto increased and begins with 0 + + MailClient.printf("> C: Command ID %d\n", res.id); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.statusCode > 0) + { + MailClient.printf("> C: Response finished with status code %d\n\n", res.statusCode); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + bool tls = false; + + /* Connect to the server */ + if (smtp.customConnect(&config /* session credentials */, customCommandCallback) != 220) + { + Serial.println("! E: Unable to connect to server"); + return; + } + +init: + + if (smtp.sendCustomCommand(F("EHLO 127.0.0.1"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Only for SMTP port 587 in supported server that accepts STARTTLS + + if (!tls) + { + if (smtp.sendCustomCommand(F("STARTTLS"), customCommandCallback) != 220) + { + smtp.closeSession(); + return; + } + + tls = true; + + // Send greeting again + goto init; + } + + if (smtp.sendCustomCommand(F("AUTH LOGIN"), customCommandCallback) != 334) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(MailClient.toBase64(config.login.email), customCommandCallback) != 334) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(MailClient.toBase64(config.login.password), customCommandCallback) != 235) + { + smtp.closeSession(); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("Successfully logged in.\n"); + else + Serial.println("Connected with no Auth.\n"); + + // Please don't forget to change sender@xxxxxx.com to your email + if (smtp.sendCustomCommand(F("MAIL FROM:"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Please don't forget to change recipient@xxxxx.com with your recipient email + if (smtp.sendCustomCommand(F("RCPT TO:"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(F("DATA"), customCommandCallback) != 354) + { + smtp.closeSession(); + return; + } + + if (!smtp.sendCustomData(F("Subject: Test sending Email\r\n"))) + { + smtp.closeSession(); + return; + } + + if (!smtp.sendCustomData(F("Hello World!\r\n"))) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(F("."), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Do not use this command in ESP8266 due to memory leaks in ESP8266 core BearSSL. + // smtp.sendCustomCommand(F("QUIT"), customCommandCallback); + + smtp.closeSession(); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Ports/Custom_Ports.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Ports/Custom_Ports.ino new file mode 100644 index 000000000000..95b1b0330af6 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Ports/Custom_Ports.ino @@ -0,0 +1,376 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example showes how to send text Email via the custom port. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT 2525 // non-standard port (TLS) + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "-----END CERTIFICATE-----\n"; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /** Set the ports and protocols + * This allows non-standard port to work with this library + * The port that assigned with config.server.port will map with the + * protocol assigned here + */ + + config.ports_functions.list = new port_function[4]; + config.ports_functions.size = 4; + + config.ports_functions.list[0].port = 25; + config.ports_functions.list[0].protocol = esp_mail_protocol_plain_text; + + config.ports_functions.list[1].port = 465; + config.ports_functions.list[1].protocol = esp_mail_protocol_ssl; + + config.ports_functions.list[2].port = 587; + config.ports_functions.list[2].protocol = esp_mail_protocol_tls; + + config.ports_functions.list[3].port = 2525; + config.ports_functions.list[3].protocol = esp_mail_protocol_tls; + + /** In ESP32, timezone environment will not keep after wake up boot from sleep. + * The local time will equal to GMT time. + * + * To sync or set time with NTP server with the valid local time after wake up boot, + * set both gmt and day light offsets to 0 and assign the timezone environment string e.g. + + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 0; + config.time.day_light_offset = 0; + config.time.timezone_env_string = "JST-9"; // for Tokyo + + * The library will get (sync) the time from NTP server without GMT time offset adjustment + * and set the timezone environment variable later. + * + * This timezone environment string will be stored to flash or SD file named "/tz_env.txt" + * which set via config.time.timezone_file. + * + * See the timezone environment string list from + * https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv + * + */ + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); // This witll be used with 'MAIL FROM' command and 'From' header field. + message.sender.email = AUTHOR_EMAIL; // This witll be used with 'From' header field. + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); // This will be used with RCPT TO command and 'To' header field. + + String textMsg = "This is simple plain text message"; + message.text.content = textMsg; + + /** If the message to send is a large string, to reduce the memory used from internal copying while sending, + * you can assign string to message.text.blob by cast your string to uint8_t array like this + * + * String myBigString = "..... ......"; + * message.text.blob.data = (uint8_t *)myBigString.c_str(); + * message.text.blob.size = myBigString.length(); + * + * or assign string to message.text.nonCopyContent, like this + * + * message.text.nonCopyContent = myBigString.c_str(); + * + * Only base64 encoding is supported for content transfer encoding in this case. + */ + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + // If this is a reply message + // message.in_reply_to = ""; + // message.references = " "; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + // message.response.reply_to = "someone@somemail.com"; + // message.response.return_path = "someone@somemail.com"; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + // For Root CA certificate verification (ESP8266 and ESP32 only) + // config.certificate.cert_data = rootCACert; + // or + // config.certificate.cert_file = "/path/to/der/file"; + // config.certificate.cert_file_storage_type = esp_mail_file_storage_type_flash; // esp_mail_file_storage_type_sd + // config.certificate.verify = true; + + // The WiFiNINA firmware the Root CA certification can be added via the option in Firmware update tool in Arduino IDE + + /* Connect to server with the session config */ + + // Library will be trying to sync the time with NTP server if time is never sync or set. + // This is 10 seconds blocking process. + // If time reading was timed out, the error "NTP server time reading timed out" will show via debug and callback function. + // You can manually sync time by yourself with NTP library or calling configTime in ESP32 and ESP8266. + // Time can be set manually with provided timestamp to function smtp.setSystemTime. + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP32/Send_Text/Send_Text.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP32/Send_Text/Send_Text.ino new file mode 100644 index 000000000000..60a05519ec79 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP32/Send_Text/Send_Text.ino @@ -0,0 +1,287 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email using ESP32 and LAN8720 Ethernet module. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** + * There are many sources for LAN8720 and ESP32 interconnection on the internet which may + * work for your LAN8720 board. + * + * Some methods worked unless no IP is available. + * + * This modification and interconnection provided in this example are mostly worked as + * the 50 MHz clock was created internally in ESP32 which GPIO 17 is set to be output of this clock + * and feeds to the LAN8720 chip XTAL input. + * + * The on-board LAN8720 50 MHz XTAL chip will be disabled by connect its enable pin or pin 1 to GND. + * + * Please see the images in the folder "modified_LAN8720_board_images" for how to modify the LAN8720 board. + * + * The LAN8720 Ethernet modified board and ESP32 board wiring connection. + * + * ESP32 LAN8720 + * + * GPIO17 - EMAC_CLK_OUT_180 nINT/REFCLK - LAN8720 XTAL1/CLKIN 4k7 Pulldown + * GPIO22 - EMAC_TXD1 TX1 + * GPIO19 - EMAC_TXD0 TX0 + * GPIO21 - EMAC_TX_EN TX_EN + * GPIO26 - EMAC_RXD1 RX1 + * GPIO25 - EMAC_RXD0 RX0 + * GPIO27 - EMAC_RX_DV CRS + * GPIO23 - MDC MDC + * GPIO18 - MDIO MDIO + * GND GND + * 3V3 VCC + * + * + * ESP32 Arduino SDK native Ethernet using ETH.h is currently support Ethernet PHY chips + * + * LAN8720, TLK101, RTL8201, DP83848, DM9051, KSZ8041 and KSZ8081. + * + * For ESP32 and other SPI MAC Ethernet modules, the external Client was used, + * see examples/SMTP/External_Client/EthernetClient/EthernetClient.ino + * + */ + +#include + +#ifdef ETH_CLK_MODE +#undef ETH_CLK_MODE +#endif +#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT // RMII clock output from GPIO17 + +// Pin# of the enable signal for the external crystal oscillator (-1 to disable) +#define ETH_POWER_PIN -1 + +// Type of the Ethernet PHY (LAN8720 or TLK110) +#define ETH_TYPE ETH_PHY_LAN8720 + +// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110) +#define ETH_ADDR 1 + +// Pin# of the I²C clock signal for the Ethernet PHY +#define ETH_MDC_PIN 23 + +// Pin# of the I²C IO signal for the Ethernet PHY +#define ETH_MDIO_PIN 18 + +static bool eth_connected = false; + +#define SMTP_HOST "" +#define SMTP_PORT 25 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +void smtpCallback(SMTP_Status status); + +unsigned long sendMillis = 0; + +void WiFiEvent(WiFiEvent_t event) +{ + // Do not run any function here to prevent stack overflow or nested interrupt + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) + + switch (event) + { + case ARDUINO_EVENT_ETH_START: + Serial.println("ETH Started"); + // set eth hostname here + ETH.setHostname("esp32-ethernet"); + break; + case ARDUINO_EVENT_ETH_CONNECTED: + Serial.println("ETH Connected"); + break; + case ARDUINO_EVENT_ETH_GOT_IP: + Serial.print("ETH MAC: "); + Serial.print(ETH.macAddress()); + Serial.print(", IPv4: "); + Serial.print(ETH.localIP()); + if (ETH.fullDuplex()) + { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); + eth_connected = true; + break; + case ARDUINO_EVENT_ETH_DISCONNECTED: + Serial.println("ETH Disconnected"); + eth_connected = false; + break; + case ARDUINO_EVENT_ETH_STOP: + Serial.println("ETH Stopped"); + eth_connected = false; + break; + default: + break; + } + +#else + switch (event) + { + case SYSTEM_EVENT_ETH_START: + Serial.println("ETH Started"); + // set eth hostname here + ETH.setHostname("esp32-ethernet"); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + Serial.println("ETH Connected"); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + Serial.print("ETH MAC: "); + Serial.print(ETH.macAddress()); + Serial.print(", IPv4: "); + Serial.print(ETH.localIP()); + if (ETH.fullDuplex()) + { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); + eth_connected = true; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + Serial.println("ETH Disconnected"); + eth_connected = false; + break; + case SYSTEM_EVENT_ETH_STOP: + Serial.println("ETH Stopped"); + eth_connected = false; + break; + default: + break; + } +#endif +} + +void sendMail() +{ + + smtp.debug(1); + + smtp.callback(smtpCallback); + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + String textMsg = "This is simple plain text message"; + message.text.content = textMsg; + + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); +} + +void setup() +{ + Serial.begin(115200); + Serial.println(); + + WiFi.onEvent(WiFiEvent); + + ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE); +} + +void loop() +{ + if (eth_connected && (millis() - sendMillis > 300000 || sendMillis == 0)) + { + sendMillis = millis(); + sendMail(); + } +} + +void smtpCallback(SMTP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/lib_mail/examples/ESP32_Ethernet_Send_Text/modified_LAN8720_board_images/lan8720_modified_board.png b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP32/Send_Text/modified_LAN8720_board_images/lan8720_modified_board.png similarity index 100% rename from lib/libesp32/lib_mail/examples/ESP32_Ethernet_Send_Text/modified_LAN8720_board_images/lan8720_modified_board.png rename to lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP32/Send_Text/modified_LAN8720_board_images/lan8720_modified_board.png diff --git a/lib/libesp32/lib_mail/examples/ESP32_Ethernet_Send_Text/modified_LAN8720_board_images/lan8720_modified_schematic.png b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP32/Send_Text/modified_LAN8720_board_images/lan8720_modified_schematic.png similarity index 100% rename from lib/libesp32/lib_mail/examples/ESP32_Ethernet_Send_Text/modified_LAN8720_board_images/lan8720_modified_schematic.png rename to lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP32/Send_Text/modified_LAN8720_board_images/lan8720_modified_schematic.png diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP8266/Send_Text/Send_Text.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP8266/Send_Text/Send_Text.ino new file mode 100644 index 000000000000..4f677fa88dd5 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP8266/Send_Text/Send_Text.ino @@ -0,0 +1,230 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email using ESP8266 and ENC28J60 Ethernet module. + +// This example requires ESP8266 Arduino Core SDK v3.x.x + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** + * + * The ENC28J60 Ethernet module and ESP8266 board, SPI port wiring connection. + * + * ESP8266 (Wemos D1 Mini or NodeMCU) ENC28J60 + * + * GPIO12 (D6) - MISO SO + * GPIO13 (D7) - MOSI SI + * GPIO14 (D5) - SCK SCK + * GPIO16 (D0) - CS CS + * GND GND + * 3V3 VCC + * + */ + +#if defined(ESP8266) +#include +#endif + +#include +// #include +// #include + +/** + * For ENC28J60 ethernet module, uncomment this line in ESP_Mail_FS.h + #define ENABLE_ESP8266_ENC28J60_ETH + + * For W5500 ethernet module, uncomment this line in ESP_Mail_FS.h + #define ENABLE_ESP8266_W5500_ETH + + * For W5100 ethernet module, uncomment this line in ESP_Mail_FS.h + #define ENABLE_ESP8266_W5100_ETH +*/ + +#include + +#define SMTP_HOST "" +#define SMTP_PORT 25 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +void smtpCallback(SMTP_Status status); + +unsigned long sendMillis = 0; + +#ifdef ESP8266_CORE_SDK_V3_X_X + +#define ETH_CS_PIN 16 // D0 +ENC28J60lwIP eth(ETH_CS_PIN); +// Wiznet5100lwIP eth(ETH_CS_PIN); +// Wiznet5500lwIP eth(ETH_CS_PIN); + +#endif + +void sendMail() +{ + + smtp.debug(1); + + smtp.callback(smtpCallback); + + Session_Config config; + + /* Assign the pointer to Ethernet module lwip interface */ +#ifdef ESP8266_CORE_SDK_V3_X_X +#if defined(ENABLE_ESP8266_ENC28J60_ETH) + config.spi_ethernet_module.enc28j60 = ð +#elif defined(ENABLE_ESP8266_W5100_ETH) + config.spi_ethernet_module.w5100 = ð +#elif defined(ENABLE_ESP8266_W5500_ETH) + config.spi_ethernet_module.w5500 = ð +#endif +#endif + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + String textMsg = "This is simple plain text message"; + message.text.content = textMsg; + + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); +} + +void setup() +{ + Serial.begin(115200); + Serial.println(); + +#ifdef ESP8266_CORE_SDK_V3_X_X + + SPI.begin(); + SPI.setClockDivider(SPI_CLOCK_DIV4); // 4 MHz? + SPI.setBitOrder(MSBFIRST); + SPI.setDataMode(SPI_MODE0); + eth.setDefault(); // use ethernet for default route + if (!eth.begin()) + { + Serial.println("ethernet hardware not found ... sleeping"); + while (1) + { + delay(1000); + } + } + else + { + Serial.print("connecting ethernet"); + while (!eth.connected()) + { + Serial.print("."); + delay(1000); + } + } + Serial.println(); + Serial.print("ethernet IP address: "); + Serial.println(eth.localIP()); + +#else + Serial.println("This example requires ESP8266 Arduino Core SDK v3.x.x, please update."); +#endif +} + +void loop() +{ +#ifdef ESP8266_CORE_SDK_V3_X_X + if (millis() - sendMillis > 300000 || sendMillis == 0) + { + sendMillis = millis(); + sendMail(); + } +#endif +} + +void smtpCallback(SMTP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/EthernetClient/EthernetClient.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/EthernetClient/EthernetClient.ino new file mode 100644 index 000000000000..ec9fd07ef006 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/EthernetClient/EthernetClient.ino @@ -0,0 +1,224 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +/** + * This example shows how to send Email using EthernetClient. + * + * This example used ESP32 and WIZnet W5500 Ethernet module. + * + * For ESP32 and LAN8720 see examples/SMTP/Ethernet/ESP32/Send_Text.ino + * + * ESP32 Arduino SDK native Ethernet using ETH.h is currently support Ethernet PHY chips + * + * LAN8720, TLK101, RTL8201, DP83848, DM9051, KSZ8041 and KSZ8081. + * + * For ESP8266, the native Ethernet is currently supported ENC28J60, W5100 and W5500. + * + * You do not need to set external Client with native Ethernet support PHY/MAC chips. + * + * + */ + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include + +#include + +#include + +#define SMTP_HOST "smtp.gmail.com" +#define SMTP_PORT 587 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +#define WIZNET_RESET_PIN 26 // Connect W5500 Reset pin to GPIO 26 of ESP32 +#define WIZNET_CS_PIN 5 // Connect W5500 CS pin to GPIO 5 of ESP32 +#define WIZNET_MISO_PIN 19 // Connect W5500 MISO pin to GPIO 19 of ESP32 +#define WIZNET_MOSI_PIN 23 // Connect W5500 MOSI pin to GPIO 23 of ESP32 +#define WIZNET_SCLK_PIN 18 // Connect W5500 SCLK pin to GPIO 18 of ESP32 + +unsigned long sentMillis = 0; + +const int analog_pin = 34; + +uint8_t Eth_MAC[] = {0x02, 0xF0, 0x0D, 0xBE, 0xEF, 0x01}; + +SMTPSession smtp; + +EthernetClient eth_client; + +void smtpCallback(SMTP_Status status); + +void ResetEthernet() +{ + Serial.println("Resetting WIZnet W5500 Ethernet Board... "); + pinMode(WIZNET_RESET_PIN, OUTPUT); + digitalWrite(WIZNET_RESET_PIN, HIGH); + delay(200); + digitalWrite(WIZNET_RESET_PIN, LOW); + delay(50); + digitalWrite(WIZNET_RESET_PIN, HIGH); + delay(200); +} + +void networkConnection() +{ + + Ethernet.init(WIZNET_CS_PIN); + + ResetEthernet(); + + Serial.println("Starting Ethernet connection..."); + Ethernet.begin(Eth_MAC); + + unsigned long to = millis(); + + while (Ethernet.linkStatus() == LinkOFF || millis() - to < 2000) + { + delay(100); + } + + if (Ethernet.linkStatus() == LinkON) + { + Serial.print("Connected with IP "); + Serial.println(Ethernet.localIP()); + } + else + { + Serial.println("Can't connect"); + } +} + +void networkStatusRequestCallback() +{ + smtp.setNetworkStatus(Ethernet.linkStatus() == LinkON); +} + +void sendEmail() +{ + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + config.login.user_domain = F("127.0.0.1"); + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email"); + + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + message.text.content = "This is simple plain text message"; + + smtp.setClient(ð_client); + + smtp.networkConnectionRequestCallback(networkConnection); + + smtp.networkStatusRequestCallback(networkStatusRequestCallback); + + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + + networkConnection(); + + /* + For internal NTP client + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + MailClient.setUDPClient(&udp_client, 0 /* GMT offset */); + + smtp.debug(1); + + smtp.callback(smtpCallback); +} + +void loop() +{ + if (millis() - sentMillis > 120000 || sentMillis == 0) + { + sentMillis = millis(); + sendEmail(); + } +} + +void smtpCallback(SMTP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/GSMClient/GSMClient.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/GSMClient/GSMClient.ino new file mode 100644 index 000000000000..9d1026d4e34d --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/GSMClient/GSMClient.ino @@ -0,0 +1,213 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example used TTGO T-A7670 (ESP32 with SIMCom SIMA7670) and TinyGSMClient. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +// To allow TinyGSM library integration, the following macro should be defined in src/ESP_Mail_FS.h or +// your custom config file src/Custom_ESP_Mail_FS.h. +// #define TINY_GSM_MODEM_SIM7600 + +#define TINY_GSM_MODEM_SIM7600 // SIMA7670 Compatible with SIM7600 AT instructions + +// Set serial for debug console (to the Serial Monitor, default speed 115200) +#define SerialMon Serial + +// Set serial for AT commands (to the module) +// Use Hardware Serial on Mega, Leonardo, Micro +#define SerialAT Serial1 + +// See all AT commands, if wanted +// #define DUMP_AT_COMMANDS + +// Define the serial console for debug prints, if needed +#define TINY_GSM_DEBUG SerialMon + +#define TINY_GSM_USE_GPRS true +#define TINY_GSM_USE_WIFI false + +// set GSM PIN, if any +#define GSM_PIN "" + +// Your GPRS credentials, if any +const char apn[] = "YourAPN"; +const char gprsUser[] = ""; +const char gprsPass[] = ""; + +#define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds +#define TIME_TO_SLEEP 600 // Time ESP32 will go to sleep (in seconds) + +#define UART_BAUD 115200 +#define PIN_DTR 25 +#define PIN_TX 26 +#define PIN_RX 27 +#define PWR_PIN 4 +#define BAT_ADC 35 +#define BAT_EN 12 +#define PIN_RI 33 +#define PIN_DTR 25 +#define RESET 5 + +#define SD_MISO 2 +#define SD_MOSI 15 +#define SD_SCLK 14 +#define SD_CS 13 + +#include +#include + +TinyGsm modem(SerialAT); + +TinyGsmClient gsm_client(modem); + +#define SMTP_HOST "" +#define SMTP_PORT esp_mail_smtp_port_587 +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +void smtpCallback(SMTP_Status status); + +void setup() +{ + + SerialMon.begin(115200); + + smtp.debug(1); + + smtp.callback(smtpCallback); + + delay(10); + pinMode(BAT_EN, OUTPUT); + digitalWrite(BAT_EN, HIGH); + + // A7670 Reset + pinMode(RESET, OUTPUT); + digitalWrite(RESET, LOW); + delay(100); + digitalWrite(RESET, HIGH); + delay(3000); + digitalWrite(RESET, LOW); + + pinMode(PWR_PIN, OUTPUT); + digitalWrite(PWR_PIN, LOW); + delay(100); + digitalWrite(PWR_PIN, HIGH); + delay(1000); + digitalWrite(PWR_PIN, LOW); + + DBG("Wait..."); + + delay(3000); + + SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX); + + // Restart takes quite some time + // To skip it, call init() instead of restart() + DBG("Initializing modem..."); + if (!modem.init()) + { + DBG("Failed to restart modem, delaying 10s and retrying"); + return; + } + + /* + 2 Automatic + 13 GSM Only + 14 WCDMA Only + 38 LTE Only + */ + modem.setNetworkMode(38); + if (modem.waitResponse(10000L) != 1) + { + DBG(" setNetworkMode faill"); + } + + String name = modem.getModemName(); + DBG("Modem Name:", name); + + String modemInfo = modem.getModemInfo(); + DBG("Modem Info:", modemInfo); + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + config.login.user_domain = F("127.0.0.1"); + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email using GSM module"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + message.text.content = "This is simple plain text message"; + + smtp.setGSMClient(&gsm_client, &modem, GSM_PIN, apn, gprsUser, gprsPass); + + smtp.connect(&config); + + if (!MailClient.sendMail(&smtp, &message)) + Serial.println("Error sending Email, " + smtp.errorReason()); +} + +void loop() +{ +} + +void smtpCallback(SMTP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/WiFiClient/WiFiClient.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/WiFiClient/WiFiClient.ino new file mode 100644 index 000000000000..6e80e110196b --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/WiFiClient/WiFiClient.ino @@ -0,0 +1,187 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email using external WiFiClient. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define SMTP_HOST "" +#define SMTP_PORT esp_mail_smtp_port_587 +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +WiFiClient wifi_client; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void smtpCallback(SMTP_Status status); + +void networkStatusRequestCallback() +{ + smtp.setNetworkStatus(WiFi.status() == WL_CONNECTED); +} + +void networkConnectionRequestCallback() +{ + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); +} + +void setup() +{ + + Serial.begin(115200); + + networkConnectionRequestCallback(); + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + smtp.debug(1); + + smtp.callback(smtpCallback); + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + config.login.user_domain = F("127.0.0.1"); + + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + + smtp.setClient(&wifi_client); + + smtp.networkStatusRequestCallback(networkStatusRequestCallback); + + smtp.networkConnectionRequestCallback(networkConnectionRequestCallback); + + smtp.connect(&config); + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + message.text.content = "This is simple plain text message"; + + if (!MailClient.sendMail(&smtp, &message)) + Serial.println("Error sending Email, " + smtp.errorReason()); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void smtpCallback(SMTP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Reply_Text/Reply_Text.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Reply_Text/Reply_Text.ino new file mode 100644 index 000000000000..76ce8091b1f2 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Reply_Text/Reply_Text.ino @@ -0,0 +1,497 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example showes how to send a reply message when specific email was received. + +// The account 2 will send Hello message to account 1. + +// The account 1 will poll the mailbox for incoming message, when new message received with matched subject +// and sent from account 2, the account 1 will send a reply messsage to account 2. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" +#define IMAP_PORT 993 + +#define IMAP_AUTHOR_EMAIL "" +#define IMAP_AUTHOR_PASSWORD "" + +#define REPLY_SMTP_AUTHOR_EMAIL "" +#define REPLY_SMTP_AUTHOR_PASSWORD "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define REPLY_SMTP_PORT 587 +#define REPLY_SMTP_HOST "" + +#define HELLO_SMTP_AUTHOR_EMAIL "" +#define HELLO_SMTP_AUTHOR_PASSWORD "" + +#define HELLO_SMTP_PORT 587 +#define HELLO_SMTP_HOST "" + +void setupIMAP(); + +bool setupHelloSMTP(); + +bool setupReplySMTP(); + +void sendHelloMessage(); + +void sendReplyMessage(const char *subject, const char *reply_email, const char *msgID, const char *references); + +/* Print the selected folder update info */ +void printPollingStatus(IMAPSession &imap); + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Callback function to get the Email sending status */ +void helloSMTPCallback(SMTP_Status status); + +void replySMTPCallback(SMTP_Status status); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +/* Declare the global used Session_Config for user defined IMAP session credentials */ +Session_Config imap_config; + +/** Define the IMAP_Data object used for user defined IMAP operating options + * and contains the IMAP operating result + */ +IMAP_Data imap_data; + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession hello_smtp; +SMTPSession reply_smtp; + +/* Declare the global used Session_Config for user defined SMTP session credentials */ +Session_Config hello_smtp_config; +Session_Config reply_smtp_config; + +bool imapSetupOk = false; + +unsigned long helloSendingMillis = 0; + +String sendingSubject = "ESP Mail Hello Test!"; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Setup and connect to IMAP server... "); + + setupIMAP(); + + if (!imapSetupOk) + return; +} + +void loop() +{ + + /* imap.connect and imap.selectFolder or imap.openFolder nedded to be called once prior to listen */ + + // Listen for mailbox changes + if (!imap.listen()) + return; + + // Check the changes + if (imap.folderChanged()) + printPollingStatus(imap); + + // To stop listen, use imap.stopListen(); and to listen again, call imap.listen() + + if (millis() - helloSendingMillis > 5 * 60 * 1000 || helloSendingMillis == 0) + { + helloSendingMillis = millis(); + Serial.print("Sending Hello message... "); + sendHelloMessage(); + } +} + +void setupIMAP() +{ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /* Set the imap app config */ + imap_config.server.host_name = IMAP_HOST; + imap_config.server.port = IMAP_PORT; + imap_config.login.email = IMAP_AUTHOR_EMAIL; + imap_config.login.password = IMAP_AUTHOR_PASSWORD; + + /* Connect to the server */ + if (!imap.connect(&imap_config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nIMAP client, successfully logged in."); + else + Serial.println("\nIMAP client, connected with no Auth."); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + imapSetupOk = true; +} + +bool setupHelloSMTP() +{ + hello_smtp.debug(1); + + /* Set the callback function to get the sending results */ + hello_smtp.callback(helloSMTPCallback); + + /* Set the session config */ + hello_smtp_config.server.host_name = HELLO_SMTP_HOST; + hello_smtp_config.server.port = HELLO_SMTP_PORT; + hello_smtp_config.login.email = HELLO_SMTP_AUTHOR_EMAIL; + hello_smtp_config.login.password = HELLO_SMTP_AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + hello_smtp_config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + hello_smtp_config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + hello_smtp_config.time.gmt_offset = 3; + hello_smtp_config.time.day_light_offset = 0; + + /* Connect to the server */ + if (!hello_smtp.connect(&hello_smtp_config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", hello_smtp.statusCode(), hello_smtp.errorCode(), hello_smtp.errorReason().c_str()); + return false; + } + + if (imap.isAuthenticated()) + Serial.println("\nHello SMTP client, successfully logged in."); + else + Serial.println("\nHello SMTP client, connected with no Auth."); + + return true; +} + +bool setupReplySMTP() +{ + reply_smtp.debug(1); + + /* Set the callback function to get the sending results */ + reply_smtp.callback(replySMTPCallback); + + /* Set the session config */ + reply_smtp_config.server.host_name = REPLY_SMTP_HOST; + reply_smtp_config.server.port = REPLY_SMTP_PORT; + reply_smtp_config.login.email = REPLY_SMTP_AUTHOR_EMAIL; + reply_smtp_config.login.password = REPLY_SMTP_AUTHOR_PASSWORD; + reply_smtp_config.login.user_domain = F("127.0.0.1"); + + /* Connect to the server */ + if (!reply_smtp.connect(&reply_smtp_config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", reply_smtp.statusCode(), reply_smtp.errorCode(), reply_smtp.errorReason().c_str()); + return false; + } + + if (imap.isAuthenticated()) + Serial.println("\nReply SMTP client, successfully logged in."); + else + Serial.println("\nReply SMTP client, connected with no Auth."); + + return true; +} + +void sendHelloMessage() +{ + + if (!setupHelloSMTP()) + return; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = HELLO_SMTP_AUTHOR_EMAIL; + message.subject = sendingSubject.c_str(); + message.addRecipient(F("Me"), IMAP_AUTHOR_EMAIL); + message.response.reply_to = HELLO_SMTP_AUTHOR_EMAIL; // only email address, excluded < and > + message.text.content = F("Hello Me!"); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&hello_smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", hello_smtp.statusCode(), hello_smtp.errorCode(), hello_smtp.errorReason().c_str()); +} + +void sendReplyMessage(const char *subject, const char *reply_email, const char *msgID, const char *references) +{ + + if (!setupReplySMTP()) + return; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = REPLY_SMTP_AUTHOR_EMAIL; + String reSubject = "RE: "; + reSubject += subject; + message.subject = reSubject; + message.addRecipient(F("Me"), reply_email); + + message.in_reply_to = msgID; + + String ref = references; + if (strlen(references) > 0) + ref += " "; + ref += msgID; + + message.references = ref; + message.text.content = F("Yeah!, it works."); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&reply_smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", reply_smtp.statusCode(), reply_smtp.errorCode(), reply_smtp.errorReason().c_str()); +} + +void printPollingStatus(IMAPSession &imap) +{ + /* Declare the selected folder info class to get the info of selected mailbox folder */ + SelectedFolderInfo sFolder = imap.selectedFolder(); + + if (sFolder.pollingStatus().type == imap_polling_status_type_new_message) + { + /* Show the mailbox info */ + MailClient.printf("\nMailbox status changed\n----------------------\nTotal Messages: %d\n", sFolder.msgCount()); + + MailClient.printf("New message %d, has been addedd, reading message...\n", (int)sFolder.pollingStatus().messageNum); + + // we need to stop polling before do anything + imap.stopListen(); + + // Get the UID of new message and fetch + imap_data.fetch.uid = imap.getUID(sFolder.pollingStatus().messageNum); + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + MailClient.readMail(&imap, false); + } +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + + if (strcmp(msgList.msgItems[0].subject, sendingSubject.c_str()) == 0) + { + Serial.print("Sending Reply message... "); + std::string replyEmail = msgList.msgItems[0].reply_to; + + // remove < at the beginning and > at the end. + replyEmail.erase(0, 1); + replyEmail.pop_back(); + + sendReplyMessage(msgList.msgItems[0].subject, replyEmail.c_str(), msgList.msgItems[0].ID, msgList.msgItems[0].references); + } + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +/* Callback function to get the Email sending status */ +void helloSMTPCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + struct tm dt; + + for (size_t i = 0; i < hello_smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = hello_smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up + hello_smtp.sendingResult.clear(); + } +} + +void replySMTPCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + struct tm dt; + + for (size_t i = 0; i < reply_smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = reply_smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + reply_smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Access_Token/Send_Access_Token.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Access_Token/Send_Access_Token.ino new file mode 100644 index 000000000000..cb0cdb6bf2b7 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Access_Token/Send_Access_Token.ino @@ -0,0 +1,304 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to log in with the SASL XOAUTH2 mechanisme using OAuth2.0 access token and send Email. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For Gmail, to send the Email via port 465 (SSL), less secure app option + * should be enabled in the account settings. https://myaccount.google.com/lesssecureapps?pli=1 + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT 25 + +/* The user Email for OAuth2.0 access token */ +#define AUTHOR_EMAIL "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/** The OAuth2.0 access token + * The generation, exchange and refresh of the access token are not available + * in this library. + * + * To test this using GMail, get the OAuth2.0 access token from this web site + * https://developers.google.com/oauthplayground/ + * + * + * 1. Select the following scope (in Step 1) from Gmail API V1 + * https://mail.google.com/ + * https://mail.google.com/ + * + * 2. Click Authorize APIs button. + * 3. Cick Exchangeauthorization code for tokens. + * 4. From the response, look at access_token from the JSON payload node. + * 5. Copy that access token and paste to the AUTHOR_ACCESS_TOKEN value. + * + * The token will be expired in 3600 seconds (1 Hr). + * The AUTHOR_EMAIL above is the Email address that you granted to access the Gmail services. + */ +#define AUTHOR_ACCESS_TOKEN "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.accessToken = AUTHOR_ACCESS_TOKEN; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending Email using Access token"); + message.addRecipient(F("Admin"), RECIPIENT_EMAIL); + + message.text.content = F("This is simple plain text message"); + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/Send_Attachment_Blob.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/Send_Attachment_Blob.ino new file mode 100644 index 000000000000..b408c8f81c65 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/Send_Attachment_Blob.ino @@ -0,0 +1,369 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email with attachments and inline images. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +/* This is for attachment data */ +#include "blob_data.h" + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Enable the chunked data transfer with pipelining for large message if server supported */ + message.enable.chunking = true; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + message.subject = F("Test sending Email with attachments and inline images"); + message.addRecipient(F("user1"), RECIPIENT_EMAIL); + + message.html.content = F("This message contains 3 inline images and 1 attachment file.

"); + + /** The HTML text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; + + message.text.content = F("This message contains 3 inline images and 1 attachment file.\r\nThe inline images were not shown in the plain text message."); + message.text.charSet = F("utf-8"); + message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* The attachment data item */ + SMTP_Attachment att[4]; + int attIndex = 0; + + /** Set the inline image info e.g. + * file name, MIME type, BLOB data, BLOB data size, + * transfer encoding (should be base64 for inline image) + */ + att[attIndex].descr.filename = F("firebase_logo.png"); + att[attIndex].descr.mime = F("image/png"); + att[attIndex].blob.data = firebase_logo_png; + att[attIndex].blob.size = sizeof(firebase_logo_png); + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att[attIndex]); + + /** Set the inline image info e.g. + * file name, MIME type, BLOB data, BLOB data size. + * The default transfer encoding is base64. + */ + attIndex++; + att[attIndex].descr.filename = F("tree.gif"); + att[attIndex].descr.mime = F("image/gif"); + att[attIndex].blob.data = tree_img_gif; + att[attIndex].blob.size = sizeof(tree_img_gif); + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att[attIndex]); + + /** Set the inline image info e.g. + * file name, MIME type, BLOB data, BLOB data size. + * The default transfer encoding is base64. + */ + attIndex++; + att[attIndex].descr.filename = F("bird.gif"); + att[attIndex].descr.mime = F("image/gif"); + att[attIndex].blob.data = bird_img_gif; + att[attIndex].blob.size = sizeof(bird_img_gif); + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att[attIndex]); + + /* Prepare the attachment data (from ram) */ + uint8_t *a = new uint8_t[512]; + int j = 0; + + for (int i = 0; i < 512; i++) + { + a[i] = j; + j++; + if (j > 255) + j = 0; + } + + /** Set the attachment info e.g. + * file name, MIME type, BLOB data, BLOB data size. + * The default transfer encoding is base64. + */ + attIndex++; + att[attIndex].descr.filename = F("test.dat"); + att[attIndex].descr.mime = F("application/octet-stream"); + att[attIndex].blob.data = a; + att[attIndex].blob.size = 512; + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + /* Add attachment to the message */ + message.addAttachment(att[attIndex]); + + /* Connect to the server */ + if (!smtp.connect(&config)) + return; + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending the Email and close the session */ + if (!MailClient.sendMail(&smtp, &message, true)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/lib_mail/examples/Send_RFC822_Attachment/image.h b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/blob_data.h similarity index 98% rename from lib/libesp32/lib_mail/examples/Send_RFC822_Attachment/image.h rename to lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/blob_data.h index 80ce0a0e7cee..c853cded3198 100644 --- a/lib/libesp32/lib_mail/examples/Send_RFC822_Attachment/image.h +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/blob_data.h @@ -1,1851 +1,1851 @@ -#include - -static const uint8_t firebase_png[] PROGMEM = { - 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x02, 0x58, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9A, 0x76, 0x82, - 0x70, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, - 0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61, 0x05, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01, 0xC7, - 0x6F, 0xA8, 0x64, 0x00, 0x00, 0x55, 0x14, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5E, 0xED, 0xDD, 0x59, - 0x90, 0x1D, 0xF5, 0x81, 0xE7, 0x7B, 0x3F, 0xF4, 0xC3, 0x84, 0x91, 0x40, 0x6E, 0xEF, 0xC6, 0x8B, - 0x30, 0x92, 0x4A, 0x1B, 0x58, 0x98, 0xCD, 0xA0, 0xA5, 0x4A, 0x12, 0x20, 0x6C, 0x9A, 0xB6, 0xBA, - 0x01, 0x63, 0x4F, 0x3F, 0x8C, 0x1E, 0x26, 0xC2, 0xF7, 0xE5, 0xC6, 0x25, 0xE2, 0xDE, 0x97, 0x3B, - 0x7D, 0x67, 0xAC, 0x6E, 0x63, 0x63, 0x83, 0x8D, 0xBC, 0xB1, 0x99, 0xA5, 0x10, 0x08, 0xED, 0x52, - 0x69, 0xAD, 0x92, 0xA0, 0xBB, 0xAB, 0xA7, 0xED, 0x6E, 0x77, 0xB7, 0x81, 0x42, 0x9B, 0x99, 0x89, - 0x89, 0xDB, 0x9A, 0xB9, 0x0E, 0x2F, 0x2C, 0x76, 0x61, 0x16, 0x49, 0x85, 0xA4, 0xFC, 0xDF, 0xFF, - 0x3F, 0x4F, 0xE6, 0xA9, 0x3C, 0x79, 0x7E, 0xE7, 0x9C, 0xCC, 0x3C, 0x99, 0x75, 0xCE, 0xC9, 0xFA, - 0x7E, 0x22, 0x7E, 0xA1, 0x6E, 0x2F, 0x42, 0xC2, 0x94, 0xE2, 0xFF, 0x8D, 0x7F, 0x65, 0x9E, 0xF7, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x28, 0x82, 0x79, 0x6E, 0xCD, 0x80, 0xBF, 0xC3, 0x5F, 0x58, 0x12, 0xFC, - 0x4B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x1F, 0x73, 0x78, 0xCD, 0x3A, 0xEF, 0xB9, 0x35, 0x63, 0xE6, - 0xB9, 0x9B, 0x4D, 0x75, 0xCF, 0xAE, 0xF1, 0xE7, 0x3D, 0x7B, 0xD3, 0xA0, 0x0B, 0x92, 0xE0, 0x3F, - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x98, 0x91, 0x35, 0xB3, 0xEB, 0xC2, 0x23, 0x12, 0x1F, 0xD1, - 0x79, 0x87, 0xD7, 0x6C, 0x08, 0xFE, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x8E, 0xFB, 0x16, 0x2B, - 0xEF, 0xD9, 0x35, 0xE3, 0x95, 0xE0, 0xB8, 0xD1, 0x98, 0x03, 0x57, 0x19, 0xB3, 0x7B, 0xAE, 0x31, - 0x3B, 0x3E, 0x65, 0xCC, 0xB6, 0x8F, 0x1A, 0xB3, 0xF3, 0xD3, 0xC6, 0x0C, 0x2D, 0x34, 0x66, 0x78, - 0xD9, 0x64, 0x84, 0x3C, 0x7B, 0xD3, 0x60, 0xF0, 0x5F, 0x07, 0x00, 0x00, 0x00, 0x80, 0xE4, 0xAA, - 0x37, 0x1F, 0x2E, 0x3C, 0x76, 0x7C, 0xC2, 0x98, 0xED, 0x1F, 0xAB, 0x84, 0x87, 0xDA, 0x2E, 0x1B, - 0x26, 0x87, 0x6F, 0xA8, 0x84, 0xC8, 0xA1, 0x9B, 0xD6, 0x06, 0x3F, 0x05, 0x00, 0x00, 0x00, 0x00, - 0xB4, 0xE6, 0x9E, 0xF9, 0xF0, 0xE3, 0x63, 0xCF, 0xA2, 0x4A, 0x78, 0x34, 0x8B, 0x8F, 0x70, 0xDB, - 0x3F, 0x6E, 0xCC, 0xC8, 0x0A, 0xF7, 0xAD, 0x58, 0xE3, 0x66, 0xB4, 0x7F, 0x56, 0xF0, 0x53, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x73, 0xDE, 0x73, 0x37, 0x9F, 0x34, 0xFB, 0xAF, 0x48, 0x1E, 0x1F, 0xE1, - 0x76, 0x5E, 0x62, 0xCC, 0xE1, 0xD5, 0x76, 0x37, 0xAE, 0x0F, 0x7E, 0x2A, 0x00, 0x00, 0x00, 0x00, - 0x68, 0xCC, 0x3D, 0x78, 0x6E, 0x0E, 0xAF, 0x4A, 0x1F, 0x1F, 0xFE, 0x3E, 0x62, 0xCC, 0xBE, 0xCF, - 0x18, 0xEF, 0xF0, 0x4D, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x68, 0xCD, 0xFF, 0x8C, 0x8F, 0xBD, - 0x97, 0x67, 0x8B, 0x0F, 0xB7, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x20, 0x19, 0x1B, - 0x20, 0xEB, 0xCD, 0xAE, 0x4F, 0xC7, 0xE2, 0xA2, 0xD5, 0x82, 0xF8, 0x08, 0xB7, 0x67, 0xB1, 0x31, - 0xCF, 0xDE, 0x64, 0xDC, 0x6D, 0x4A, 0xF0, 0xD3, 0x02, 0x00, 0x00, 0x00, 0x40, 0x3D, 0xEF, 0xB9, - 0x9B, 0x07, 0x75, 0x64, 0x34, 0x5A, 0x2C, 0x3E, 0xC2, 0x1D, 0x1A, 0xE0, 0xB5, 0xBC, 0x00, 0x00, - 0x00, 0x00, 0x9A, 0xF3, 0x0E, 0x2E, 0x1B, 0xD5, 0xA1, 0xA1, 0x26, 0xC2, 0x23, 0xDC, 0xD0, 0x02, - 0x6E, 0x41, 0x00, 0x00, 0x00, 0x00, 0x34, 0xE7, 0x1D, 0xB8, 0x76, 0x5C, 0xC7, 0x46, 0x7C, 0x22, - 0x3A, 0xE2, 0x1B, 0x59, 0x6E, 0xBC, 0xC3, 0x37, 0x8E, 0x06, 0x3F, 0x35, 0x00, 0x00, 0x00, 0x00, - 0x4C, 0x72, 0x6F, 0xAE, 0x32, 0xFB, 0x96, 0xD8, 0x78, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x0D, 0xB5, - 0x5D, 0x73, 0x2A, 0xB7, 0x20, 0xCF, 0xAD, 0x19, 0x08, 0xFE, 0x12, 0x00, 0x00, 0x00, 0x00, 0x50, - 0xE1, 0xBF, 0x01, 0x6B, 0x77, 0x9F, 0x8D, 0x07, 0x15, 0x1D, 0xE1, 0x44, 0x68, 0x34, 0xDB, 0xF0, - 0xF5, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xE7, 0x7F, 0x02, 0xFA, 0xAE, 0xB9, 0x36, 0x1C, - 0x54, 0x78, 0xB8, 0x89, 0xC0, 0x68, 0xB5, 0x5D, 0x97, 0x1A, 0xF3, 0xEC, 0x8D, 0xC6, 0x3C, 0xB7, - 0x9A, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x93, 0x6C, 0x80, 0xAC, 0xD7, 0xE1, 0xE1, 0x26, 0xE2, - 0xA2, 0xE5, 0x3E, 0x5C, 0xD9, 0x81, 0xAB, 0x8C, 0xF7, 0xEC, 0x0D, 0x27, 0x83, 0xBF, 0x0C, 0x00, - 0x00, 0x00, 0x00, 0xBC, 0xE7, 0x3D, 0xDE, 0xF0, 0x8A, 0x06, 0x6F, 0xC0, 0x52, 0x71, 0xD1, 0x6A, - 0x41, 0x7C, 0xB8, 0xED, 0xF8, 0x44, 0xE5, 0x16, 0xE4, 0xF0, 0x8D, 0xEB, 0x82, 0xBF, 0x14, 0x00, - 0x00, 0x00, 0x80, 0xE9, 0xCE, 0x3B, 0x70, 0xFD, 0xC9, 0xDC, 0xE3, 0x23, 0x1C, 0xB7, 0x20, 0x00, - 0x00, 0x00, 0x00, 0xA2, 0xCC, 0xFE, 0x2B, 0x6D, 0x2C, 0x14, 0x10, 0x1F, 0x6E, 0xEE, 0x16, 0xE4, - 0xF0, 0x2A, 0x77, 0x0B, 0xB2, 0x3E, 0xF8, 0xCB, 0x01, 0x00, 0x00, 0x00, 0x98, 0xAE, 0x6C, 0x18, - 0x2C, 0x31, 0x7B, 0x2E, 0xB3, 0xB1, 0x50, 0x40, 0x7C, 0x84, 0xDB, 0x77, 0xB9, 0x7B, 0x23, 0xD6, - 0xB8, 0x7B, 0xDD, 0x6F, 0xF0, 0x97, 0x05, 0x00, 0x00, 0x00, 0x30, 0x1D, 0x99, 0x43, 0x37, 0xAD, - 0x9D, 0x7C, 0x03, 0x96, 0x8A, 0x8B, 0x56, 0x13, 0xC1, 0x11, 0xDF, 0xF6, 0x8F, 0x71, 0x0B, 0x02, - 0x00, 0x00, 0x00, 0x20, 0x78, 0x03, 0xD6, 0xF6, 0x8F, 0xDB, 0x50, 0x50, 0x71, 0xD1, 0x6A, 0x22, - 0x36, 0x1A, 0x8D, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xB3, 0x37, 0x0D, 0xEA, 0xB8, 0x68, - 0x35, 0x11, 0x19, 0xAD, 0x76, 0xA8, 0xDF, 0x3D, 0x90, 0x3E, 0x18, 0xFC, 0xA5, 0x01, 0x00, 0x00, - 0x00, 0x4C, 0x37, 0xDE, 0x81, 0x6B, 0x46, 0x75, 0x60, 0x34, 0x9B, 0x88, 0x8B, 0x56, 0xDB, 0xFA, - 0x21, 0x63, 0x86, 0xE6, 0x57, 0x5E, 0xCB, 0x3B, 0xB2, 0x66, 0x76, 0xF0, 0x97, 0x07, 0x00, 0x00, - 0x00, 0x30, 0x9D, 0x98, 0x03, 0x57, 0xDB, 0x40, 0x50, 0x91, 0xD1, 0x68, 0x22, 0x2E, 0x5A, 0xCD, - 0xC5, 0x47, 0x38, 0x6E, 0x41, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC9, 0xDD, 0x44, 0x98, 0x7D, 0x9F, - 0xB1, 0x91, 0xA0, 0x42, 0x43, 0x4D, 0xC4, 0x45, 0xAB, 0x45, 0xE3, 0xC3, 0x6D, 0xF7, 0xDC, 0xCA, - 0x2D, 0xC8, 0x73, 0xAB, 0x07, 0x82, 0x5F, 0x06, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC0, 0x3C, 0xB7, - 0x66, 0xC0, 0xEC, 0x9E, 0x67, 0x43, 0x41, 0xC5, 0x46, 0x7C, 0x22, 0x2E, 0x5A, 0x2D, 0x1E, 0x1F, - 0xE1, 0x86, 0xAF, 0x73, 0x0F, 0xA4, 0x8F, 0x06, 0xBF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x81, - 0xF7, 0xEC, 0x4D, 0x77, 0x99, 0x9D, 0x97, 0xD8, 0x58, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x8B, 0x56, - 0x53, 0xE1, 0x11, 0x6E, 0xD7, 0xA7, 0xB9, 0x05, 0x01, 0x00, 0x00, 0x00, 0xA6, 0x1B, 0xEF, 0xF0, - 0x8D, 0x1B, 0x74, 0x70, 0x44, 0x27, 0xE2, 0xA2, 0xD5, 0x54, 0x74, 0xC4, 0xC7, 0x2D, 0x08, 0x00, - 0x00, 0x00, 0x30, 0xBD, 0x78, 0x07, 0xAF, 0x6F, 0xF1, 0x06, 0x2C, 0x11, 0x17, 0xAD, 0xA6, 0x62, - 0x43, 0xCD, 0x7D, 0xF6, 0x88, 0xBB, 0x05, 0x39, 0x7C, 0xE3, 0xBA, 0xE0, 0x97, 0x03, 0x00, 0x00, - 0x00, 0xA0, 0xCC, 0xBC, 0x03, 0xD7, 0x9D, 0xD4, 0xE1, 0xE1, 0x26, 0xE2, 0xA2, 0xD5, 0x54, 0x68, - 0x34, 0xDB, 0xFE, 0x2B, 0xDD, 0x1B, 0xB1, 0x4E, 0x06, 0xBF, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xD6, 0xF8, 0x0D, 0x58, 0x22, 0x2E, 0x5A, 0x4D, 0x05, 0x46, 0xAB, 0xB9, 0x5B, 0x90, 0xC3, 0x37, - 0x70, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x94, 0x9D, 0xFF, 0x06, 0xAC, 0xA1, 0x05, 0x36, 0x1E, 0x3A, - 0x14, 0x1F, 0xFE, 0x3E, 0x68, 0x5C, 0x04, 0x79, 0x87, 0x6E, 0x18, 0x37, 0xA3, 0xFD, 0xB3, 0x82, - 0x5F, 0x1A, 0x00, 0x00, 0x00, 0x80, 0xB2, 0x71, 0xB7, 0x0E, 0x66, 0xD7, 0x1C, 0x1B, 0x10, 0x1D, - 0x8C, 0x0F, 0x37, 0xF7, 0xD7, 0x3D, 0xB4, 0xD2, 0x98, 0xC3, 0xAB, 0xD7, 0x07, 0xBF, 0x34, 0x00, - 0x00, 0x00, 0x00, 0x65, 0x63, 0x03, 0x64, 0xBD, 0xD9, 0x7E, 0x71, 0x25, 0x00, 0x3A, 0x15, 0x1F, - 0xE1, 0xF6, 0x5E, 0xC6, 0x2D, 0x08, 0x00, 0x00, 0x00, 0x50, 0x66, 0xDE, 0xC8, 0xCA, 0xA1, 0xAE, - 0x88, 0x0F, 0xB7, 0xE0, 0x16, 0xC4, 0x3B, 0xBC, 0x7A, 0x43, 0xF0, 0xCB, 0x03, 0x00, 0x00, 0x00, - 0x50, 0x26, 0xDE, 0xC1, 0x6B, 0xC7, 0xBA, 0x22, 0x3E, 0xC2, 0xED, 0xEE, 0xAB, 0x3C, 0x90, 0x3E, - 0xB2, 0x66, 0x76, 0xF0, 0x4B, 0x04, 0x00, 0x00, 0x00, 0x50, 0x16, 0x66, 0xFF, 0x67, 0x75, 0x5C, - 0xB4, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0xD1, 0x11, 0xDF, 0xC8, 0x0A, 0xE3, 0x1D, 0x5A, 0x3D, 0x18, - 0xFC, 0x12, 0x01, 0x00, 0x00, 0x00, 0x94, 0x81, 0xBB, 0x65, 0x30, 0xFB, 0x2E, 0xD7, 0x81, 0xD1, - 0x6C, 0x32, 0x2C, 0x92, 0x4C, 0xC4, 0x86, 0x1A, 0xB7, 0x20, 0x00, 0x00, 0x00, 0x40, 0xF9, 0x98, - 0xE7, 0x56, 0x0F, 0x98, 0x5D, 0x97, 0xEA, 0xC8, 0x68, 0x34, 0x19, 0x16, 0x49, 0x26, 0x42, 0xA3, - 0xD9, 0x0E, 0x7E, 0xCE, 0x78, 0x87, 0x6F, 0x18, 0x0D, 0x7E, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x7A, - 0x9D, 0xFF, 0x06, 0xAC, 0x1D, 0x9F, 0xD0, 0xA1, 0xA1, 0x26, 0xC3, 0x22, 0xC9, 0x44, 0x60, 0xB4, - 0xDA, 0xCE, 0x4B, 0x82, 0x5B, 0x90, 0xD5, 0x03, 0xC1, 0x2F, 0x17, 0x00, 0x00, 0x00, 0x40, 0x2F, - 0xF3, 0x9E, 0xBD, 0x61, 0x50, 0x86, 0x86, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0x71, 0x91, 0x74, 0x07, - 0xAF, 0x35, 0xDE, 0xE1, 0x55, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x65, 0xE0, 0x1D, 0xBC, 0x6E, - 0x54, 0xC6, 0x46, 0x7C, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, 0x6D, 0xF9, 0x80, 0x31, 0x3B, - 0x67, 0xBB, 0x0F, 0x26, 0x34, 0xE6, 0xD0, 0xAA, 0xB5, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, 0x40, - 0xAF, 0xF2, 0x0E, 0x5C, 0x33, 0x2E, 0x83, 0x23, 0x3A, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, - 0x5C, 0x7C, 0x84, 0xDB, 0x77, 0x85, 0xFB, 0x5C, 0x90, 0x93, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, - 0x40, 0x2F, 0x72, 0x9F, 0x36, 0xDE, 0xF2, 0x0D, 0x58, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, - 0x45, 0xE3, 0xC3, 0x6D, 0xDB, 0xC7, 0x2A, 0xB7, 0x20, 0x87, 0x57, 0xAD, 0x0B, 0x7E, 0xE9, 0x00, - 0x00, 0x00, 0x00, 0x7A, 0x8D, 0xFF, 0x06, 0xAC, 0xDD, 0x73, 0xEB, 0xA3, 0x23, 0x9C, 0x0C, 0x8B, - 0x24, 0x13, 0x51, 0x91, 0x74, 0xF1, 0xF8, 0x08, 0xC7, 0x2D, 0x08, 0x00, 0x00, 0x00, 0xD0, 0xDB, - 0xCC, 0xE1, 0x1B, 0xD7, 0x35, 0x7C, 0x05, 0xAF, 0x0C, 0x8B, 0x24, 0x13, 0x51, 0x91, 0x74, 0x2A, - 0x3C, 0xC2, 0x6D, 0xB5, 0xBF, 0xA6, 0x43, 0x03, 0xEE, 0x26, 0x64, 0x7D, 0xF0, 0xCB, 0x07, 0x00, - 0x00, 0x00, 0xD0, 0x4B, 0xFC, 0x57, 0xF0, 0xF6, 0x42, 0x7C, 0x84, 0xDB, 0xB3, 0xD8, 0x7D, 0x3A, - 0xFA, 0xB8, 0xFB, 0xD6, 0xB1, 0xE0, 0xB7, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x57, 0x78, 0xC3, 0xCB, - 0xEB, 0xDF, 0x80, 0x25, 0xC3, 0x22, 0xC9, 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x0D, 0x35, 0x6E, 0x41, - 0x00, 0x00, 0x00, 0x80, 0xDE, 0xE5, 0x1D, 0xBC, 0x76, 0xAC, 0x67, 0xE2, 0x23, 0xDC, 0x9E, 0x45, - 0xC6, 0x3B, 0xB4, 0x6A, 0xDC, 0x8C, 0xF4, 0xCF, 0x0E, 0x7E, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x7A, - 0x81, 0xD9, 0x7F, 0x45, 0x6F, 0xC5, 0x87, 0xBF, 0xF7, 0x1B, 0x33, 0xB2, 0xCC, 0x46, 0xC8, 0xCA, - 0xC1, 0xE0, 0xB7, 0x01, 0x00, 0x00, 0x00, 0xA0, 0xDB, 0x99, 0xC3, 0x37, 0x2E, 0x71, 0xB7, 0x09, - 0x3D, 0x17, 0x1F, 0x6E, 0xEE, 0xCD, 0x5D, 0x87, 0x57, 0xD9, 0x10, 0xE9, 0xCD, 0x5B, 0x10, 0xF7, - 0xEB, 0xB6, 0x1B, 0x08, 0xC6, 0x4D, 0x0E, 0x00, 0x00, 0x00, 0xCA, 0xCF, 0x1C, 0xBA, 0x69, 0xAD, - 0xFF, 0x06, 0x2C, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x5A, 0x10, 0x1F, - 0xE1, 0x7A, 0xEC, 0x16, 0xC4, 0xFF, 0xCC, 0x95, 0x91, 0xFE, 0xF5, 0xDE, 0xA1, 0x81, 0x93, 0xFE, - 0x73, 0x2C, 0x91, 0xF9, 0xFF, 0x9A, 0xFD, 0xF7, 0x78, 0xB8, 0x1E, 0x00, 0x00, 0x00, 0xA5, 0x55, - 0x79, 0x03, 0xD6, 0x47, 0x6D, 0x10, 0xA8, 0xB8, 0x68, 0x35, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, - 0xD5, 0x62, 0xF1, 0xE1, 0xB6, 0xF3, 0x53, 0xC1, 0x2D, 0xC8, 0xEA, 0x81, 0xE0, 0xB7, 0xD4, 0xB5, - 0xCC, 0xA1, 0xFE, 0xB5, 0xDE, 0xC8, 0xC0, 0x78, 0x3C, 0x3C, 0xE2, 0xAB, 0xFC, 0x67, 0xFA, 0xD7, - 0x06, 0xFF, 0x35, 0x00, 0x00, 0x00, 0xA0, 0x3C, 0xBC, 0x67, 0x6F, 0x18, 0xD4, 0x71, 0xD1, 0x6A, - 0x22, 0x2A, 0x92, 0x4E, 0xC6, 0x45, 0xAB, 0x89, 0xF8, 0x08, 0x77, 0xF0, 0x1A, 0xE3, 0x1D, 0x5E, - 0x39, 0x1A, 0xFC, 0x96, 0xBA, 0x92, 0x19, 0xE9, 0x5F, 0x57, 0x8D, 0x8C, 0x91, 0xE5, 0xFE, 0x43, - 0xF4, 0x66, 0xC7, 0xC7, 0x6B, 0xE7, 0xFE, 0x35, 0xF7, 0xEF, 0xF9, 0xFF, 0x99, 0x7E, 0x37, 0x3E, - 0xF1, 0x1D, 0x00, 0x00, 0x00, 0xE5, 0xE2, 0x1D, 0xB8, 0x7A, 0x54, 0x07, 0x46, 0xB3, 0x89, 0xA8, - 0x48, 0x3A, 0x19, 0x17, 0xAD, 0x26, 0xA2, 0x23, 0xBA, 0x2E, 0xBF, 0x05, 0xB1, 0x21, 0x31, 0xBB, - 0x7A, 0xF3, 0x31, 0x34, 0xBF, 0xF2, 0x6B, 0xDE, 0x3C, 0x4B, 0xCF, 0xFD, 0x7B, 0x43, 0x7D, 0x7E, - 0x80, 0x78, 0x23, 0x2B, 0x78, 0xCB, 0x17, 0x00, 0x00, 0x00, 0xCA, 0xC5, 0xEC, 0xBF, 0xD2, 0x86, - 0x81, 0x8A, 0x8C, 0x46, 0x13, 0x51, 0x91, 0x74, 0x32, 0x2E, 0x5A, 0x2D, 0x12, 0x1A, 0xCD, 0xE6, - 0x6E, 0x41, 0x0E, 0xAD, 0x1A, 0x0B, 0x7E, 0x5B, 0x5D, 0xC5, 0xC6, 0xC7, 0x90, 0x1F, 0x1F, 0xBB, - 0x3E, 0xAD, 0xA3, 0xA3, 0x66, 0x17, 0x55, 0xB6, 0xF3, 0x92, 0x4A, 0x84, 0x0C, 0xAF, 0xE8, 0xEA, - 0x9B, 0x1D, 0x00, 0x00, 0x00, 0x20, 0x31, 0xFF, 0x81, 0xE8, 0xBD, 0x97, 0xDB, 0x38, 0x50, 0xA1, - 0xA1, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x9A, 0x08, 0x8D, 0x46, 0x73, 0xCF, 0xB1, 0xB8, - 0x5B, 0x90, 0xC3, 0xAB, 0xBA, 0xEA, 0xDB, 0x96, 0x6C, 0x44, 0x0C, 0xF8, 0xF1, 0xE1, 0xDE, 0xD8, - 0x25, 0x83, 0x23, 0xBA, 0x20, 0x3E, 0x62, 0x11, 0xE2, 0x7E, 0x8E, 0xE0, 0xA7, 0x03, 0x00, 0x00, - 0x00, 0x7A, 0x97, 0x79, 0x6E, 0xF5, 0x80, 0x7F, 0x30, 0x96, 0xB1, 0x11, 0x9F, 0x88, 0x8A, 0xA4, - 0x93, 0x71, 0xD1, 0x6A, 0x22, 0x32, 0x5A, 0x6D, 0xDF, 0x12, 0xE3, 0x1D, 0x5E, 0x75, 0x32, 0xF8, - 0xED, 0x75, 0x05, 0xEF, 0xD0, 0xC0, 0xA8, 0x39, 0x70, 0x55, 0x10, 0x18, 0xCD, 0x16, 0x8B, 0x8F, - 0x70, 0xFB, 0xAF, 0xE4, 0x16, 0x04, 0x00, 0x00, 0x00, 0xE5, 0xE0, 0x3D, 0x7B, 0xC3, 0x5D, 0x66, - 0xC7, 0xA7, 0x6C, 0x24, 0xA8, 0xE0, 0x88, 0x4E, 0x44, 0x45, 0xD2, 0xC9, 0xB8, 0x68, 0x35, 0x11, - 0x17, 0x49, 0x16, 0xDC, 0x82, 0x78, 0x87, 0x56, 0xDD, 0x15, 0xFC, 0x16, 0x3B, 0xAA, 0x7A, 0xFB, - 0xE1, 0x1E, 0x30, 0x97, 0xD1, 0x11, 0x4E, 0x84, 0x47, 0xB8, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, - 0x00, 0x80, 0x72, 0xF0, 0x0E, 0xDF, 0xB8, 0x41, 0x07, 0x47, 0x74, 0x22, 0x2A, 0x92, 0x4E, 0xC6, - 0x45, 0xAB, 0x89, 0xB0, 0x48, 0xB3, 0x3D, 0x0B, 0x8D, 0x37, 0xB2, 0x72, 0xBC, 0x1B, 0x3E, 0x4B, - 0x23, 0xD9, 0xED, 0x87, 0x88, 0x8E, 0xF8, 0xB8, 0x05, 0x01, 0x00, 0x00, 0x40, 0x19, 0x78, 0x07, - 0xAF, 0x6B, 0xF1, 0x06, 0x2C, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, 0xD5, 0x44, 0x50, 0xA4, 0xDA, - 0x1F, 0x57, 0xFE, 0xDA, 0x23, 0x2B, 0xEC, 0x56, 0xAE, 0x0F, 0x7E, 0x9B, 0x1D, 0xE1, 0x3E, 0xC7, - 0xC3, 0xBF, 0xFD, 0x70, 0x7F, 0x1F, 0x65, 0x78, 0xB8, 0x89, 0xD8, 0x50, 0xF3, 0x7F, 0x4F, 0xFD, - 0xC6, 0x1C, 0xE4, 0xB3, 0x41, 0x00, 0x00, 0x00, 0xD0, 0xC3, 0xBC, 0x03, 0x9F, 0x3B, 0x59, 0x1F, - 0x1D, 0xE1, 0x22, 0x31, 0x91, 0x76, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xD9, 0xF8, 0x08, - 0xD7, 0x05, 0xB7, 0x20, 0xFE, 0xA7, 0x9A, 0xBB, 0x07, 0xFC, 0x65, 0x78, 0xB8, 0x89, 0xD0, 0x68, - 0xB6, 0xBD, 0x97, 0xB9, 0x5B, 0x90, 0xAE, 0x7A, 0xBE, 0x05, 0x00, 0x00, 0x00, 0x48, 0xA5, 0xF1, - 0x1B, 0xB0, 0x44, 0x54, 0x24, 0x9D, 0x8C, 0x8B, 0x56, 0x53, 0x41, 0x91, 0x66, 0x91, 0xF8, 0x70, - 0x73, 0xBF, 0x8E, 0xE1, 0xA5, 0xEE, 0x13, 0xC5, 0x37, 0x04, 0xBF, 0xD5, 0x29, 0x65, 0xC2, 0x0F, - 0x1D, 0x74, 0x7F, 0x2F, 0xF3, 0x88, 0x0F, 0x37, 0xF7, 0x7B, 0xF2, 0x9F, 0x05, 0x59, 0xCE, 0x87, - 0x13, 0x02, 0x00, 0x00, 0xA0, 0xF7, 0xF8, 0x6F, 0xC0, 0x72, 0x1F, 0x8A, 0x57, 0xB6, 0xF8, 0x08, - 0xB7, 0x6B, 0x8E, 0x31, 0x87, 0x56, 0xBA, 0x43, 0xFB, 0x94, 0x7F, 0x90, 0x5F, 0xF3, 0xDB, 0x0F, - 0x11, 0x17, 0x49, 0xB7, 0x67, 0xB1, 0xF1, 0x86, 0x97, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x80, 0xDE, - 0x63, 0x0E, 0xDD, 0xB4, 0xD6, 0xFF, 0x60, 0xBC, 0x32, 0xC6, 0x47, 0x38, 0x77, 0x0B, 0x72, 0x68, - 0xE5, 0x60, 0xF0, 0x5B, 0x9E, 0x12, 0xCD, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0xDD, 0x33, 0x17, 0xDA, - 0xDF, 0x93, 0xFD, 0x7B, 0x66, 0x7F, 0x4F, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0xE7, 0x98, 0xC3, - 0x37, 0xAE, 0xF7, 0x5F, 0x5B, 0x5B, 0xD6, 0xF8, 0x70, 0x0B, 0x6F, 0x41, 0x0E, 0xF7, 0x2F, 0x09, - 0x7E, 0xDB, 0x85, 0x72, 0xCF, 0x9C, 0xF8, 0xB7, 0x1F, 0xEE, 0x66, 0x29, 0xEF, 0xF8, 0x08, 0xB7, - 0x7B, 0x9E, 0xF1, 0x46, 0x96, 0x8F, 0x9B, 0xA1, 0xCE, 0xBF, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, - 0xCC, 0x1B, 0x59, 0x39, 0x54, 0xEA, 0xF8, 0x08, 0x77, 0xE0, 0x6A, 0x77, 0x0B, 0x32, 0x25, 0xAF, - 0xB0, 0x35, 0x23, 0xFD, 0xEB, 0xCD, 0xC8, 0x72, 0xFB, 0xD7, 0xB5, 0xBF, 0xC6, 0x22, 0xE2, 0xC3, - 0x6D, 0xF3, 0xFB, 0xC2, 0x5B, 0x90, 0x8E, 0xBE, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, 0xC5, 0xDB, - 0x7F, 0xED, 0x58, 0xE9, 0xE3, 0xC3, 0x6D, 0xC7, 0x27, 0xC3, 0x67, 0x41, 0x0A, 0xFD, 0x20, 0x3F, - 0xFF, 0xF6, 0x63, 0x64, 0x60, 0xBC, 0xFE, 0xF6, 0x43, 0x44, 0x45, 0xD2, 0xC5, 0xE3, 0x23, 0x1C, - 0xB7, 0x20, 0x00, 0x00, 0x00, 0xE8, 0x35, 0x66, 0xDF, 0x12, 0x1D, 0x15, 0x49, 0x27, 0xE3, 0xA2, - 0xD5, 0x54, 0x50, 0xA4, 0x99, 0x08, 0x8C, 0x56, 0x73, 0x37, 0x06, 0x53, 0x70, 0x0B, 0xA2, 0x6F, - 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8F, 0x70, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0x97, 0x98, - 0x91, 0x35, 0xB3, 0xDD, 0xE7, 0x4A, 0xC8, 0xB0, 0x48, 0x32, 0x19, 0x17, 0xAD, 0x16, 0x8F, 0x89, - 0xB4, 0x13, 0x71, 0xD1, 0x6A, 0xEE, 0xA0, 0xEE, 0xB6, 0xED, 0x63, 0x95, 0x5B, 0x90, 0x43, 0xC5, - 0x7C, 0x90, 0x9F, 0xBE, 0xFD, 0x10, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0xE2, 0xE3, 0x16, 0x04, 0x00, - 0x00, 0x00, 0xBD, 0xC2, 0x8C, 0xAC, 0x1E, 0x30, 0x3B, 0x2F, 0xD1, 0x71, 0xD1, 0x6A, 0x32, 0x2E, - 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0x30, 0x3E, 0xC2, 0xED, 0xFD, 0x8C, 0xBB, - 0x05, 0x29, 0xE4, 0x15, 0xB6, 0xEE, 0xF3, 0x46, 0xCC, 0xF0, 0xF5, 0xF6, 0xAF, 0x33, 0x45, 0xF1, - 0x11, 0xEE, 0xE0, 0xE7, 0x6C, 0x84, 0xAC, 0xE8, 0xC8, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x89, - 0x99, 0xC3, 0xAB, 0xD7, 0x9B, 0xED, 0x17, 0xEB, 0xC0, 0x68, 0x36, 0x19, 0x17, 0xAD, 0xA6, 0x82, - 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x5A, 0x3C, 0x3E, 0xDC, 0xB6, 0x7E, 0x38, 0x7C, 0x16, 0x24, 0xD7, - 0x57, 0xD8, 0xDA, 0x9F, 0x6F, 0xB6, 0xFF, 0xDA, 0x5D, 0xF7, 0x4A, 0xE3, 0xA9, 0x8C, 0x0F, 0xB7, - 0x9D, 0xB3, 0xED, 0xEF, 0x67, 0x85, 0xFB, 0x3D, 0x4D, 0xF9, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, - 0x89, 0x79, 0x87, 0x57, 0x6F, 0x90, 0x81, 0xD1, 0x6C, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, - 0x89, 0xB8, 0x68, 0x35, 0x15, 0x1F, 0xE1, 0x82, 0x5B, 0x10, 0xF7, 0x2D, 0x53, 0xC1, 0xDF, 0x8A, - 0xB6, 0x79, 0x87, 0x06, 0x06, 0x27, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8C, 0x24, 0x73, - 0xB7, 0x20, 0xC3, 0x2B, 0xA6, 0xF4, 0xB3, 0x4E, 0x00, 0x00, 0x00, 0x80, 0x54, 0xBC, 0x83, 0x9F, - 0x1B, 0x95, 0x91, 0xD1, 0x68, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0x35, - 0x15, 0x1D, 0xD1, 0xB9, 0x5F, 0x97, 0x7F, 0x63, 0xB0, 0x32, 0x97, 0x87, 0xB7, 0x6B, 0x6F, 0x3F, - 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8B, 0xA4, 0xE3, 0x16, 0x04, 0x00, 0x00, 0x00, 0xDD, 0xCE, 0xDB, - 0x7F, 0xD5, 0xB8, 0x0C, 0x0D, 0xB5, 0xBA, 0xB0, 0x48, 0x32, 0x15, 0x14, 0x69, 0x26, 0xE2, 0xA2, - 0xD5, 0x54, 0x70, 0xA8, 0x0D, 0x2D, 0x30, 0xDE, 0xC8, 0xCA, 0xF1, 0x3C, 0x6E, 0x41, 0xFC, 0xDB, - 0x8F, 0x03, 0xD7, 0xDA, 0x9F, 0x57, 0x44, 0x45, 0xD2, 0xA9, 0xA8, 0x48, 0x3B, 0xF7, 0x96, 0xAF, - 0xE1, 0x65, 0xDC, 0x82, 0x34, 0x60, 0xC6, 0xFE, 0xC3, 0x2C, 0xF3, 0xF2, 0xBF, 0x5F, 0x67, 0x4E, - 0x7C, 0x65, 0x7D, 0x64, 0x6B, 0xDD, 0xBF, 0x1E, 0xFC, 0x47, 0x00, 0x00, 0x00, 0x50, 0x14, 0x77, - 0xF0, 0x4E, 0xFC, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, - 0x0A, 0x8D, 0x46, 0x73, 0xBF, 0xC6, 0x1C, 0x6E, 0x41, 0xDC, 0xA7, 0xAB, 0xFB, 0xB7, 0x1F, 0xEE, - 0x59, 0x1A, 0x15, 0x16, 0x49, 0xA6, 0x62, 0x22, 0xCB, 0xB6, 0x7F, 0xD4, 0xFE, 0x7E, 0x96, 0xDB, - 0x2D, 0x2D, 0xF4, 0xB3, 0x4E, 0x7A, 0x8D, 0x0B, 0x0C, 0xEF, 0xC4, 0x97, 0x07, 0xCD, 0x2F, 0xBE, - 0x62, 0xE4, 0x4E, 0x7C, 0xC9, 0xF8, 0xFF, 0x3E, 0x21, 0x02, 0x00, 0x00, 0x50, 0x1C, 0xFF, 0x0D, - 0x58, 0xBB, 0xE6, 0xE8, 0xE0, 0x88, 0xAE, 0x2E, 0x2C, 0x92, 0x4C, 0x05, 0x45, 0x9A, 0x89, 0xB8, - 0x68, 0x35, 0x15, 0x19, 0xAD, 0xE6, 0xBF, 0xC2, 0x76, 0xE5, 0x78, 0x3B, 0xDF, 0xB6, 0xE4, 0x1D, - 0x1A, 0x18, 0x35, 0xFB, 0xAF, 0xB4, 0x3F, 0x9F, 0x08, 0x8B, 0x24, 0x53, 0x21, 0x91, 0x69, 0x33, - 0x2B, 0xDB, 0x7F, 0x85, 0xF1, 0x86, 0x97, 0x4F, 0xC9, 0x27, 0xBE, 0xF7, 0x02, 0x73, 0xFC, 0xDF, - 0x2F, 0xF1, 0x7E, 0xF1, 0xE5, 0xF1, 0xDA, 0xE0, 0xB8, 0xDD, 0x98, 0xE3, 0x5F, 0xF4, 0xC3, 0x23, - 0xFA, 0xAF, 0xFB, 0xFF, 0x39, 0xFB, 0x9F, 0x0F, 0xFE, 0xAB, 0x00, 0x00, 0x00, 0xC8, 0x93, 0x39, - 0x7C, 0xE3, 0xBA, 0x96, 0xAF, 0xE0, 0x95, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, - 0xAB, 0xA9, 0xB8, 0x48, 0xBA, 0xE1, 0xEB, 0x8D, 0xFB, 0x16, 0xAA, 0xE0, 0x6F, 0x4B, 0x2A, 0x36, - 0x5C, 0x06, 0xEC, 0xB2, 0xDF, 0x7E, 0xC8, 0x90, 0xC8, 0xB2, 0x20, 0x3E, 0xDC, 0xB8, 0x05, 0xA9, - 0xAA, 0x89, 0x0F, 0x17, 0x1D, 0x2F, 0xD9, 0xFF, 0xAD, 0x5E, 0xB0, 0xB1, 0xF8, 0xFC, 0x92, 0xC9, - 0xBD, 0x70, 0xB5, 0xFD, 0xD7, 0x57, 0x55, 0xFE, 0x7D, 0x22, 0x04, 0x00, 0x00, 0xA0, 0x38, 0xFE, - 0x2B, 0x78, 0x55, 0x74, 0x84, 0x93, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, - 0xA9, 0xA8, 0x48, 0xBC, 0x59, 0x95, 0x07, 0xC7, 0xDD, 0xB7, 0x50, 0x65, 0xB8, 0x05, 0xF1, 0x86, - 0x57, 0x64, 0xBF, 0xFD, 0x90, 0x21, 0x91, 0x65, 0x91, 0xF8, 0x08, 0xC7, 0x2D, 0x48, 0x6D, 0x7C, - 0x1C, 0xB9, 0xB1, 0x36, 0x3A, 0xD4, 0x5C, 0x98, 0x1C, 0xFD, 0x42, 0x25, 0x42, 0x4E, 0x7C, 0x85, - 0x1B, 0x24, 0x00, 0x00, 0x80, 0xBC, 0x79, 0x07, 0x97, 0x35, 0x7E, 0x03, 0x96, 0x8C, 0x8B, 0x56, - 0x53, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0x85, 0x1F, 0x16, 0x68, 0xE7, - 0x6E, 0x41, 0x46, 0x06, 0x86, 0x82, 0xBF, 0x35, 0x89, 0xB4, 0x75, 0xFB, 0x21, 0x43, 0x22, 0xCB, - 0x44, 0x7C, 0xB8, 0x6D, 0xFD, 0xD0, 0xB4, 0xBE, 0x05, 0xA9, 0x89, 0x0F, 0x77, 0xEB, 0xA1, 0x82, - 0xA3, 0xD1, 0x5C, 0xAC, 0xF8, 0x37, 0x26, 0x5F, 0x29, 0xE4, 0xD3, 0xF2, 0x01, 0x00, 0x00, 0xA6, - 0x2D, 0x6F, 0xFF, 0x35, 0x63, 0xC4, 0x47, 0xB0, 0xED, 0x1F, 0xB7, 0x87, 0x75, 0xFF, 0x16, 0x24, - 0xF1, 0x81, 0xDD, 0x1B, 0x59, 0x31, 0xE6, 0x3F, 0xC4, 0xAF, 0x02, 0xA3, 0xD9, 0x64, 0x48, 0x64, - 0x99, 0x08, 0x8F, 0xE8, 0xF6, 0x2C, 0xB2, 0x51, 0xB5, 0x7C, 0x2C, 0xF8, 0xE5, 0x4E, 0x1B, 0x6D, - 0xC5, 0x47, 0xB8, 0x63, 0x7F, 0xE2, 0x3F, 0x94, 0x1E, 0xFC, 0x94, 0x00, 0x00, 0x00, 0xC8, 0x83, - 0xD9, 0xF7, 0x19, 0xE2, 0xC3, 0xED, 0x99, 0x60, 0xFB, 0xAF, 0x32, 0xDE, 0xF0, 0x40, 0xA2, 0x6F, - 0xBD, 0xB1, 0xA1, 0xB2, 0xCE, 0xBF, 0xFD, 0x70, 0x7F, 0xCF, 0x54, 0x64, 0x34, 0x9A, 0x0C, 0x89, - 0x2C, 0x13, 0xC1, 0x11, 0x9F, 0xFB, 0x7B, 0xEB, 0xDF, 0x82, 0x2C, 0xCF, 0xF5, 0x13, 0xDF, 0xBB, - 0x59, 0x2E, 0xF1, 0xE1, 0xF6, 0xC2, 0xD5, 0xEE, 0xDB, 0xB0, 0x4E, 0x06, 0x3F, 0x2D, 0x00, 0x00, - 0x00, 0xDA, 0x65, 0x0E, 0xDF, 0xB8, 0xC4, 0x0C, 0x2D, 0x9C, 0xBE, 0xF1, 0x11, 0x46, 0x47, 0xF0, - 0x7F, 0x7B, 0x6E, 0xDB, 0x3F, 0xEE, 0xBE, 0x0D, 0x2B, 0xD1, 0x2D, 0x88, 0x37, 0xBC, 0xE2, 0x64, - 0xEA, 0xDB, 0x0F, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, 0xD1, 0xDC, 0x2D, 0xC8, 0xF0, 0xB2, 0x69, - 0x71, 0x90, 0xCE, 0x2D, 0x3E, 0xC2, 0x1D, 0xBB, 0xC5, 0x04, 0x3F, 0x35, 0x00, 0x00, 0x00, 0xDA, - 0x65, 0x0E, 0xAD, 0x5A, 0x5B, 0xF3, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, - 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0xAB, 0x8F, 0x0F, 0x3F, 0x3C, 0xC2, 0x6D, 0xB2, 0xDB, 0x7B, - 0x85, 0x39, 0x3F, 0x3C, 0xD0, 0xF4, 0xC0, 0x9E, 0xE9, 0xF6, 0x43, 0x86, 0x44, 0x96, 0x89, 0xC8, - 0x68, 0x36, 0xF7, 0xF7, 0x79, 0x1A, 0xDC, 0x82, 0xE4, 0x1E, 0x1F, 0xCF, 0x7F, 0xC6, 0x98, 0x23, - 0x37, 0x18, 0xF3, 0xF2, 0x9D, 0x7C, 0x9E, 0x0A, 0x00, 0x00, 0x40, 0x1E, 0xFC, 0x37, 0x60, 0x6D, - 0xFB, 0xC8, 0xF4, 0x8D, 0x8F, 0x68, 0x78, 0xB8, 0xB9, 0xF8, 0x70, 0xDB, 0xFC, 0x21, 0xF7, 0x6D, - 0x58, 0xEE, 0x16, 0xA4, 0xE1, 0x81, 0xDD, 0xBF, 0xFD, 0xD8, 0xB3, 0xD0, 0xFE, 0x7C, 0x22, 0x34, - 0xD4, 0x64, 0x48, 0x64, 0x99, 0x08, 0x8C, 0x24, 0x1B, 0x9A, 0x5F, 0xEA, 0x5B, 0x90, 0x42, 0xE2, - 0xC3, 0x6D, 0xEC, 0x3A, 0x17, 0x20, 0xD3, 0xE6, 0xDB, 0xD7, 0x00, 0x00, 0x00, 0x0A, 0xE5, 0x1D, - 0x5A, 0x3D, 0x38, 0xED, 0xE2, 0x23, 0x12, 0x20, 0xD5, 0xE8, 0x88, 0xC4, 0xC7, 0xF9, 0x70, 0x43, - 0x97, 0x9B, 0x73, 0x07, 0xF5, 0x2D, 0xC8, 0xF9, 0x91, 0xFE, 0xF5, 0x66, 0x78, 0x99, 0xFD, 0xB9, - 0xDC, 0xAF, 0x49, 0xC4, 0x46, 0x7C, 0x32, 0x24, 0xB2, 0x4C, 0x84, 0x45, 0xD2, 0xB9, 0xDF, 0xF7, - 0xF0, 0xF5, 0xEE, 0x16, 0xA4, 0xAD, 0x4F, 0x7C, 0xEF, 0x46, 0x85, 0xC5, 0x87, 0xDB, 0x0B, 0x57, - 0x19, 0x73, 0xE2, 0xCE, 0xD2, 0xFD, 0x3D, 0x03, 0x00, 0x00, 0xE8, 0x08, 0x6F, 0xDF, 0x55, 0xA3, - 0x3A, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xC5, 0xC2, 0x22, 0xC9, 0x64, 0x54, 0x24, 0x5D, 0x24, - 0x3E, 0x82, 0xD5, 0xDC, 0x78, 0x84, 0xD1, 0xF1, 0x74, 0x64, 0x9B, 0x3F, 0x64, 0xCE, 0x1F, 0x5C, - 0x6E, 0xCE, 0x0D, 0xF7, 0xDF, 0x15, 0xFC, 0xED, 0xF2, 0x99, 0xA1, 0xFE, 0x59, 0xE7, 0x47, 0x56, - 0x8C, 0x9B, 0xDD, 0x7D, 0xF6, 0x60, 0x2F, 0x62, 0x23, 0x3E, 0x19, 0x12, 0x59, 0x26, 0xA2, 0x22, - 0xED, 0x76, 0xCF, 0x35, 0xDE, 0xC8, 0xB2, 0x71, 0xF7, 0x7B, 0x08, 0x7E, 0x3B, 0x3D, 0xAF, 0xD0, - 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x9F, 0x07, 0x02, 0x00, 0x00, 0x90, 0x07, 0xB3, 0xEF, 0x0A, - 0x7B, 0xB8, 0x57, 0x81, 0xD1, 0x6C, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, 0x48, - 0xBA, 0x48, 0x78, 0x44, 0x6F, 0x3E, 0xE2, 0xB7, 0x1E, 0x7E, 0x78, 0xBC, 0xCF, 0x9C, 0x7B, 0x6A, - 0x72, 0xE7, 0x77, 0xCE, 0x77, 0xB7, 0x20, 0x35, 0x07, 0xF6, 0xF3, 0x07, 0xFB, 0xD7, 0x7B, 0xC3, - 0xCB, 0x8C, 0xE7, 0x6E, 0x3F, 0x5A, 0x05, 0x88, 0x0C, 0x89, 0x2C, 0x13, 0x31, 0x91, 0x76, 0x9B, - 0x66, 0xD8, 0x1F, 0xED, 0xAF, 0xA9, 0x44, 0xB7, 0x20, 0x53, 0x11, 0x1F, 0x6E, 0xDE, 0xD1, 0x5B, - 0xA6, 0xDD, 0x6B, 0x8C, 0x01, 0x00, 0x00, 0x72, 0x67, 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x8B, 0xED, - 0x01, 0x5F, 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x58, 0x24, 0x99, 0x8C, 0x8A, 0xA4, - 0x8B, 0xC4, 0x47, 0x83, 0x00, 0x09, 0xE3, 0xE3, 0x5C, 0x24, 0x3E, 0xCE, 0x6E, 0x0C, 0xF6, 0xD4, - 0xFB, 0xCD, 0xF9, 0x03, 0xCB, 0x8D, 0x8B, 0x0E, 0xFF, 0xEF, 0x99, 0x0D, 0x91, 0x73, 0xC3, 0x2B, - 0xC6, 0xBD, 0x5D, 0x7D, 0xF6, 0xBF, 0x7F, 0x91, 0x3F, 0xFF, 0x50, 0xAF, 0x42, 0x44, 0x86, 0x44, - 0x96, 0x89, 0x98, 0x48, 0x3B, 0x17, 0x1F, 0xE1, 0x4A, 0x72, 0x0B, 0x32, 0x55, 0xF1, 0xE1, 0xEF, - 0xE8, 0xE7, 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xBB, 0xCC, 0xC8, 0xEA, 0x01, 0xB3, 0xEB, 0x52, - 0x7B, 0xC8, 0x57, 0xA1, 0xA1, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, - 0x4B, 0x1F, 0x1F, 0xD5, 0xF0, 0x78, 0xD2, 0x6D, 0x96, 0xBF, 0x73, 0x3B, 0xE6, 0x9B, 0xB3, 0x07, - 0x2A, 0xB7, 0x20, 0x2E, 0x44, 0xCE, 0x1F, 0x5C, 0x66, 0xFF, 0xFB, 0x7F, 0xDC, 0x3C, 0x40, 0x64, - 0x48, 0x64, 0x99, 0x88, 0x89, 0xB4, 0x8B, 0xC6, 0x87, 0x9B, 0xFB, 0xB5, 0x1E, 0xBC, 0xB6, 0xA7, - 0x6F, 0x41, 0xA6, 0x34, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0xEC, 0x5F, 0x33, 0xF8, 0xCB, 0x03, 0x00, - 0x00, 0x20, 0x0B, 0xEF, 0xD0, 0xAA, 0xBB, 0xCC, 0xF6, 0x4F, 0xD8, 0x83, 0xBE, 0x8A, 0x8D, 0xF8, - 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, 0x74, 0xB1, 0xF8, 0x08, 0x02, 0x24, - 0x49, 0x7C, 0xBC, 0x6B, 0xE3, 0xE3, 0xDD, 0xC1, 0x59, 0x93, 0xDB, 0xF8, 0x7E, 0x73, 0x6E, 0xEF, - 0xF5, 0xE6, 0xDC, 0x81, 0x81, 0x51, 0xF7, 0xED, 0x58, 0xE7, 0xB7, 0x5F, 0x62, 0xFF, 0xBB, 0x36, - 0x3E, 0xDC, 0x54, 0x84, 0xC8, 0x90, 0xC8, 0x32, 0x11, 0x13, 0x69, 0x17, 0x8F, 0x8F, 0x70, 0x3B, - 0x3E, 0xE9, 0x02, 0xC4, 0xBD, 0xE5, 0x6B, 0x76, 0xF0, 0x8F, 0x43, 0xCF, 0x98, 0xF2, 0xF8, 0x70, - 0x1B, 0x5B, 0x66, 0xCC, 0x89, 0xAF, 0xAC, 0x0D, 0x7E, 0x09, 0x00, 0x00, 0x00, 0xC8, 0xC2, 0x3B, - 0xBC, 0x7A, 0x83, 0x8E, 0x8D, 0xF8, 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, - 0x74, 0x3A, 0x3E, 0xEA, 0x02, 0xC4, 0x86, 0x47, 0xF8, 0xCC, 0x47, 0x3C, 0x3E, 0x26, 0xDC, 0x9E, - 0xA8, 0xCC, 0xFD, 0xFF, 0x67, 0xB7, 0x7C, 0xDA, 0x4C, 0x3C, 0xD3, 0x6F, 0xCE, 0x0D, 0xD9, 0x10, - 0x79, 0xCA, 0xFD, 0x77, 0x2F, 0xD2, 0x11, 0xB2, 0x49, 0x85, 0x44, 0x96, 0x89, 0x98, 0x48, 0x3B, - 0x15, 0x1E, 0xD1, 0x1D, 0xBC, 0xD6, 0xBD, 0x96, 0x77, 0x30, 0xF8, 0xC7, 0xA1, 0x27, 0x74, 0x24, - 0x3E, 0xDC, 0x5E, 0xBC, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0xB4, 0xCB, 0x3B, 0x78, 0x4D, 0x82, - 0x37, 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0xE1, 0x11, - 0x2E, 0x1E, 0x1F, 0xE1, 0xED, 0x47, 0xE4, 0x99, 0x0F, 0x17, 0x1F, 0xD1, 0xF0, 0x98, 0x78, 0x3C, - 0x98, 0xFB, 0xBF, 0x1F, 0x9B, 0x65, 0x4E, 0x3F, 0x72, 0x9D, 0x39, 0xF3, 0xF0, 0x25, 0x7E, 0x80, - 0x9C, 0xF3, 0x1F, 0x58, 0x8F, 0x05, 0x88, 0x8B, 0x8F, 0x5C, 0x02, 0x44, 0xC4, 0x44, 0xDA, 0xA9, - 0xE0, 0x88, 0xAF, 0xC7, 0x6E, 0x41, 0x3A, 0x16, 0x1F, 0xC1, 0xBC, 0x5F, 0xDC, 0x39, 0x14, 0xFC, - 0x52, 0x00, 0x00, 0x00, 0x90, 0x85, 0xB7, 0xFF, 0xEA, 0x93, 0x3A, 0x3A, 0xC2, 0xA9, 0xA0, 0x48, - 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x78, 0xB8, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, - 0xDE, 0x7E, 0xD4, 0x7E, 0xEB, 0x55, 0x34, 0x3E, 0xCE, 0xD8, 0xE8, 0x38, 0xF3, 0xF8, 0xFB, 0x82, - 0x55, 0x22, 0xE4, 0xF4, 0xFD, 0x17, 0x99, 0x53, 0xF7, 0x5E, 0x6C, 0x4E, 0xDD, 0x7D, 0x91, 0x39, - 0x6B, 0xFF, 0x33, 0x75, 0xB7, 0x20, 0x36, 0x3C, 0xDC, 0xDA, 0x0F, 0x10, 0x11, 0x13, 0x69, 0xA7, - 0x62, 0xA3, 0xD1, 0x7A, 0xE4, 0x16, 0xA4, 0xD3, 0xF1, 0xE1, 0xE6, 0x1D, 0xFB, 0x53, 0xDE, 0x84, - 0x05, 0x00, 0x00, 0xD0, 0x8E, 0xE6, 0x6F, 0xC0, 0x52, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, - 0x46, 0x45, 0xD2, 0xC5, 0xA2, 0x23, 0xBA, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDC, 0x7E, 0xD4, 0x7C, - 0xDB, 0x55, 0x18, 0x1F, 0x8F, 0xD9, 0xF0, 0xB0, 0x3B, 0x1D, 0xFC, 0x78, 0xE6, 0x91, 0xF7, 0xF9, - 0xE1, 0x11, 0xEE, 0xF4, 0x7D, 0x36, 0x42, 0x36, 0x4E, 0x46, 0x88, 0xF7, 0x74, 0x25, 0x3E, 0xAA, - 0x01, 0x92, 0x39, 0x42, 0x44, 0x4C, 0xA4, 0x9D, 0x8A, 0x8C, 0x66, 0xDB, 0x7E, 0x71, 0xD7, 0xDF, - 0x82, 0x74, 0x43, 0x7C, 0xF8, 0x3B, 0x76, 0x0B, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xC8, 0xCA, 0x7F, - 0x03, 0xD6, 0xEE, 0x79, 0xF6, 0xE0, 0x5F, 0xFE, 0xF8, 0x70, 0x3F, 0x36, 0xBF, 0xFD, 0xB0, 0xF1, - 0xE1, 0x02, 0x24, 0x88, 0x0F, 0x17, 0x1E, 0xA7, 0x1F, 0x9D, 0xDC, 0xA9, 0x7B, 0x67, 0xD5, 0x04, - 0x88, 0xDB, 0xBB, 0x3F, 0x0E, 0x02, 0xE4, 0xA9, 0x0B, 0xED, 0xCF, 0x67, 0xE3, 0x23, 0x1E, 0x21, - 0x32, 0x30, 0x9A, 0x4D, 0xC4, 0x44, 0xDA, 0xA9, 0xC0, 0x48, 0xB2, 0x7D, 0x57, 0x18, 0x6F, 0x78, - 0x79, 0x57, 0x7E, 0xD0, 0x5E, 0xD7, 0xC4, 0x87, 0x9B, 0x7B, 0x13, 0xD6, 0xCB, 0x77, 0xF6, 0xDC, - 0x43, 0xFB, 0x00, 0x00, 0x00, 0x5D, 0xC1, 0x1C, 0x5A, 0xB5, 0xD6, 0xEC, 0x9C, 0x6D, 0x0F, 0xFF, - 0x25, 0x8E, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDD, 0x7E, 0xB8, 0xD7, 0xEC, 0x46, 0x6F, - 0x3F, 0xE2, 0xF1, 0x71, 0xFA, 0x81, 0xDA, 0xDB, 0x8F, 0x70, 0xEE, 0x16, 0xE4, 0xDC, 0x93, 0x76, - 0x1B, 0x2F, 0xF2, 0x23, 0xA4, 0x26, 0x40, 0x5C, 0x50, 0xA4, 0x8A, 0x10, 0x11, 0x13, 0x69, 0xA7, - 0xC2, 0x22, 0xE9, 0xB6, 0x7D, 0x24, 0xB8, 0x05, 0x59, 0x3A, 0x10, 0xFC, 0xE3, 0xD1, 0x15, 0xBA, - 0x2A, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0xB3, 0xAB, 0xFE, 0x1E, 0x01, 0x00, 0x00, 0xF4, - 0x0C, 0x73, 0x78, 0xF5, 0x7A, 0xB3, 0xF5, 0xC3, 0x36, 0x00, 0x4A, 0x1C, 0x1F, 0xC1, 0xD4, 0xED, - 0xC7, 0x59, 0x3F, 0x40, 0x6C, 0x7C, 0xB8, 0xDB, 0x8F, 0xC8, 0xB7, 0x5E, 0x55, 0xC3, 0xE3, 0xC7, - 0x95, 0xA9, 0xDB, 0x0F, 0x7F, 0x5F, 0xBF, 0xD0, 0xBC, 0xFB, 0x48, 0x25, 0x40, 0xCE, 0xB5, 0x75, - 0x0B, 0x22, 0x62, 0x22, 0xED, 0x54, 0x54, 0xA4, 0x9D, 0xBB, 0x05, 0x39, 0xB8, 0xAC, 0x6B, 0x6E, - 0x41, 0xBA, 0x2E, 0x3E, 0xDC, 0x78, 0x13, 0x16, 0x00, 0x00, 0x40, 0x76, 0xDE, 0xC8, 0x8A, 0xA1, - 0xD2, 0xC7, 0x47, 0xC3, 0xDB, 0x8F, 0x59, 0xD5, 0xF8, 0xA8, 0xDE, 0x7E, 0x84, 0xF1, 0x11, 0x84, - 0x87, 0x1F, 0x1F, 0x3F, 0xD2, 0xB7, 0x1F, 0x2E, 0x3E, 0xDC, 0x4E, 0x7F, 0xEB, 0x42, 0x73, 0xB6, - 0xAD, 0x5B, 0x10, 0x11, 0x13, 0x69, 0xA7, 0x62, 0x22, 0xCB, 0xB6, 0xD9, 0x18, 0x1D, 0x5E, 0xD6, - 0x15, 0xB7, 0x20, 0x5D, 0x19, 0x1F, 0xC1, 0xBC, 0x13, 0x5F, 0xEE, 0xA9, 0xD7, 0x16, 0x03, 0x00, - 0x00, 0x74, 0x0D, 0x6F, 0xDF, 0x55, 0x63, 0x65, 0xBF, 0xF9, 0x70, 0xAB, 0xBF, 0xFD, 0x88, 0x04, - 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x70, 0x44, 0x02, 0xE4, 0x94, 0x7B, 0xE8, 0xDC, 0xED, 0xDB, 0xE2, - 0xF6, 0x23, 0x88, 0x8F, 0x70, 0x13, 0x0F, 0x64, 0xBD, 0x05, 0x11, 0x31, 0x91, 0x76, 0x2A, 0x24, - 0x32, 0xED, 0x82, 0xCA, 0xF6, 0x5C, 0xD6, 0xF1, 0x5B, 0x90, 0x6E, 0x8E, 0x0F, 0x37, 0xEF, 0xF8, - 0x9F, 0x75, 0xE5, 0xB3, 0x32, 0x00, 0x00, 0x00, 0x5D, 0xCF, 0xEC, 0xBD, 0xDC, 0x86, 0x40, 0x89, - 0xE3, 0x23, 0xC1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xC1, 0xB7, 0x5E, 0x9D, 0x0A, 0x03, 0xE4, 0x07, - 0xAD, 0xE3, 0xC3, 0xED, 0xF4, 0x3D, 0x2D, 0x6E, 0x41, 0xE4, 0x44, 0x4C, 0xA4, 0x9D, 0x0C, 0x89, - 0x2C, 0x0B, 0xE2, 0xC3, 0xCD, 0xFD, 0xFD, 0xF5, 0x6F, 0x41, 0x96, 0xAF, 0x0B, 0xFE, 0x31, 0x99, - 0x52, 0xDD, 0x1E, 0x1F, 0xFE, 0x8E, 0xFF, 0x29, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x48, 0xCB, 0xBD, - 0x72, 0xD5, 0xEC, 0x59, 0x64, 0x63, 0x40, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0xBA, 0xA0, - 0x48, 0x33, 0x11, 0x1A, 0x8D, 0x16, 0x0F, 0x90, 0xE0, 0xF6, 0xE3, 0x6C, 0x92, 0xDB, 0x8F, 0x87, - 0xED, 0xEE, 0x69, 0x1D, 0x1F, 0xE1, 0xC2, 0x5B, 0x90, 0x64, 0x6F, 0xC4, 0x12, 0x31, 0x91, 0x76, - 0x32, 0x24, 0xB2, 0x2C, 0x12, 0x1F, 0xE1, 0x86, 0x16, 0x1A, 0xEF, 0xE0, 0xD2, 0x93, 0xC1, 0x3F, - 0x2A, 0x53, 0xA6, 0x27, 0xE2, 0xC3, 0xED, 0xC8, 0x6A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0x90, 0x96, - 0xFF, 0x0A, 0xDE, 0x9D, 0x9F, 0xB2, 0x41, 0xA0, 0xA2, 0x22, 0xE9, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, - 0x8A, 0xA4, 0x13, 0x91, 0xA1, 0x66, 0x83, 0xA3, 0x1A, 0x1F, 0x36, 0x3C, 0x12, 0xDF, 0x7E, 0x44, - 0xBF, 0xF5, 0xEA, 0xFB, 0xB1, 0xDB, 0x0F, 0x11, 0x1D, 0xD1, 0x25, 0xBF, 0x05, 0x11, 0x31, 0x91, - 0x76, 0x32, 0x24, 0xB2, 0x4C, 0xC4, 0x87, 0x9B, 0xFB, 0x7B, 0x3D, 0xC5, 0xB7, 0x20, 0x3D, 0x13, - 0x1F, 0x3F, 0xBF, 0xDC, 0x98, 0xB1, 0x15, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x20, 0x2D, 0x73, 0x78, - 0xE5, 0x7A, 0xB3, 0xED, 0xA3, 0x36, 0x0A, 0x54, 0x58, 0x24, 0x99, 0x88, 0x8B, 0x56, 0xAB, 0x0B, - 0x8A, 0x34, 0x8B, 0x45, 0x46, 0xB3, 0x45, 0x03, 0xC4, 0xAE, 0x12, 0x1F, 0x36, 0x0E, 0xC2, 0x00, - 0x69, 0xF4, 0xDA, 0xDD, 0x46, 0xB7, 0x1F, 0x22, 0x38, 0xD4, 0x26, 0x7E, 0x50, 0x09, 0x90, 0x9A, - 0x67, 0x41, 0x82, 0x10, 0xA9, 0xDC, 0x82, 0x88, 0x98, 0x48, 0x3B, 0x19, 0x12, 0x59, 0x26, 0xC2, - 0x23, 0xBA, 0x29, 0xBC, 0x05, 0xE9, 0xA9, 0xF8, 0x70, 0x7B, 0xF1, 0x3A, 0x63, 0x7F, 0xBD, 0x77, - 0x05, 0xBF, 0x7C, 0x00, 0x00, 0x00, 0x24, 0xE1, 0x1D, 0x5E, 0xB9, 0x41, 0x87, 0x45, 0x92, 0x89, - 0xB8, 0x68, 0x35, 0x19, 0x15, 0x49, 0x17, 0x0B, 0x8C, 0x66, 0x8B, 0xC5, 0x47, 0xE5, 0xF6, 0x23, - 0x12, 0x1F, 0xCD, 0x6E, 0x3F, 0xC2, 0x00, 0x89, 0xDE, 0x7E, 0x88, 0xD0, 0x68, 0xB8, 0x6F, 0x5C, - 0x68, 0xCE, 0x3E, 0xD1, 0xE0, 0x16, 0x64, 0x93, 0x88, 0x89, 0xB4, 0x93, 0x21, 0x91, 0x65, 0x22, - 0x38, 0xE2, 0x73, 0x7F, 0xDF, 0x0F, 0x5E, 0x57, 0xF8, 0x2D, 0x48, 0xCF, 0xC5, 0x47, 0x30, 0xEF, - 0xC4, 0x9D, 0x1B, 0x82, 0xDF, 0x02, 0x00, 0x00, 0x00, 0x92, 0xF0, 0x0E, 0x5E, 0x3D, 0xAA, 0xE3, - 0xA2, 0xD5, 0x44, 0x5C, 0xB4, 0x5A, 0x5D, 0x50, 0xA4, 0x59, 0x2C, 0x30, 0x9A, 0xAD, 0x41, 0x7C, - 0xF8, 0xB7, 0x1F, 0x2E, 0x3E, 0xD4, 0xED, 0x47, 0x10, 0x1F, 0xD5, 0xDB, 0x8F, 0x87, 0xEC, 0xBE, - 0x91, 0x21, 0x3E, 0x82, 0x85, 0xB7, 0x20, 0xE7, 0x9F, 0x72, 0x7F, 0xDD, 0x20, 0x42, 0x9E, 0x9E, - 0x69, 0x7F, 0x2D, 0x2E, 0x20, 0x82, 0xA9, 0xB8, 0x68, 0x35, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, - 0xD1, 0x76, 0xCD, 0x31, 0xDE, 0xF0, 0xD2, 0x71, 0x33, 0xD4, 0x3F, 0x2B, 0xF8, 0xC7, 0x26, 0x57, - 0xBD, 0x1A, 0x1F, 0x7E, 0x80, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x74, 0xBC, 0xFD, 0x9F, 0x1D, - 0xD7, 0x81, 0xD1, 0x6C, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xC5, 0x02, 0xA3, 0xD5, 0xEA, - 0x02, 0x24, 0x88, 0x8F, 0xF8, 0xED, 0x47, 0x10, 0x1F, 0xF2, 0xD9, 0x8F, 0xFB, 0x83, 0xDB, 0x0F, - 0x11, 0x17, 0x89, 0x16, 0xBB, 0x05, 0x39, 0x1F, 0xC4, 0x47, 0x5B, 0x01, 0x22, 0x43, 0x22, 0xCB, - 0x44, 0x64, 0x34, 0x9B, 0x7B, 0x66, 0xC5, 0xDD, 0x82, 0x1C, 0x5C, 0x9A, 0xFB, 0x07, 0xEF, 0xF5, - 0x72, 0x7C, 0xB8, 0x79, 0xC7, 0xFE, 0x64, 0x3C, 0xF8, 0xAD, 0x00, 0x00, 0x00, 0xA0, 0x15, 0x33, - 0xDA, 0x3F, 0x2B, 0xFD, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x8B, 0xC5, 0x45, - 0x92, 0xC5, 0xE3, 0x23, 0x7A, 0xFB, 0x11, 0xC4, 0x47, 0xCD, 0x9B, 0xAF, 0x1A, 0xDD, 0x7E, 0xA8, - 0xB0, 0x48, 0xB1, 0x33, 0xDF, 0xBB, 0x70, 0xF2, 0x59, 0x90, 0xA7, 0x6C, 0x7C, 0xB4, 0x13, 0x21, - 0x32, 0x24, 0xB2, 0x4C, 0x04, 0x46, 0x92, 0x15, 0x70, 0x0B, 0xD2, 0xEB, 0xF1, 0xE1, 0xEF, 0xC8, - 0x4D, 0xC6, 0x8C, 0xFD, 0x87, 0x42, 0x6E, 0x86, 0x00, 0x00, 0x00, 0x4A, 0xC7, 0x7F, 0x03, 0xD6, - 0xAE, 0x4F, 0xDB, 0x48, 0x50, 0xA1, 0xA1, 0x26, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, - 0x8B, 0x56, 0xB3, 0xD1, 0x31, 0x19, 0x20, 0x17, 0x55, 0x02, 0x24, 0xB8, 0xFD, 0xA8, 0xBE, 0x76, - 0xB7, 0x7A, 0xFB, 0xF1, 0xBE, 0xC6, 0xB7, 0x1F, 0x22, 0x28, 0xB2, 0xEC, 0xEC, 0x63, 0x2E, 0x42, - 0x2A, 0x01, 0xE2, 0xDF, 0x82, 0x64, 0x89, 0x10, 0x19, 0x12, 0x59, 0x26, 0xC2, 0x22, 0xE9, 0x72, - 0xBE, 0x05, 0x29, 0x45, 0x7C, 0xB8, 0xBD, 0x34, 0xC0, 0x9B, 0xB0, 0x00, 0x00, 0x00, 0x92, 0x32, - 0x87, 0x57, 0xAD, 0x4B, 0xFE, 0x0A, 0x5E, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x61, - 0x91, 0x74, 0xF1, 0xF8, 0xC8, 0x74, 0xFB, 0xA1, 0x63, 0x22, 0xFD, 0x66, 0x9A, 0x33, 0xF7, 0xCF, - 0x34, 0x67, 0x9F, 0x9C, 0x8C, 0x90, 0xD4, 0x01, 0x22, 0x43, 0x22, 0xCB, 0x44, 0x54, 0xA4, 0xDD, - 0xCE, 0xD9, 0xC6, 0x1B, 0xBE, 0xBE, 0xED, 0x5B, 0x90, 0xD2, 0xC4, 0x87, 0x1B, 0x6F, 0xC2, 0x02, - 0x00, 0x00, 0x48, 0xCE, 0xB8, 0x57, 0xF0, 0xCA, 0xD8, 0x88, 0x4F, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, - 0x48, 0x3A, 0x11, 0x16, 0x49, 0xE6, 0x6E, 0x3F, 0xEC, 0x8F, 0x7E, 0x7C, 0xC4, 0x6E, 0x3F, 0xEA, - 0x9F, 0xFD, 0x68, 0x70, 0xFB, 0x71, 0x5F, 0xFB, 0xDF, 0x7A, 0x55, 0xD9, 0xCC, 0xEA, 0xDE, 0x0D, - 0x6E, 0x41, 0xCE, 0x35, 0xBA, 0x05, 0x51, 0xE1, 0xE1, 0x26, 0x43, 0x22, 0xCB, 0x44, 0x4C, 0x64, - 0xDA, 0x7B, 0x8D, 0x39, 0x70, 0xB5, 0x7B, 0x2D, 0xEF, 0x60, 0xF0, 0x8F, 0x50, 0x6A, 0xA5, 0x8A, - 0x0F, 0xB7, 0xE7, 0xAF, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x49, 0x79, 0x07, 0xAF, 0x4B, 0xF0, - 0x06, 0x2C, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x51, 0x91, 0x66, 0xE1, 0xCD, 0x47, - 0x83, 0xDB, 0x8F, 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0x78, 0x30, 0xAF, 0x6F, 0xBD, 0x9A, 0x8C, 0x0F, - 0xB7, 0x4C, 0xB7, 0x20, 0x32, 0x24, 0xB2, 0x4C, 0x85, 0x44, 0x96, 0xD9, 0xF8, 0x70, 0xDB, 0xFE, - 0x71, 0xF7, 0x6D, 0x58, 0xC6, 0x8C, 0x5C, 0x9B, 0xFA, 0x13, 0xC0, 0x4B, 0x17, 0x1F, 0xC1, 0xBC, - 0x13, 0x77, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x24, 0xBC, 0x7D, 0x57, 0x8E, 0xE9, 0xE8, 0x08, - 0x27, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, 0x8A, 0xA4, 0xF3, 0x6F, 0x3F, 0x82, 0xF8, - 0x88, 0xDD, 0x7E, 0xA8, 0x67, 0x3F, 0xEA, 0x3F, 0x74, 0xD0, 0xC6, 0x47, 0x2E, 0xB7, 0x1F, 0xB5, - 0xF1, 0x11, 0xEE, 0xDD, 0x47, 0x5A, 0x3C, 0x0B, 0xD2, 0x0B, 0xF1, 0xF1, 0x74, 0xB0, 0xFD, 0xE9, - 0x6F, 0x41, 0xCA, 0x1A, 0x1F, 0x6E, 0xDE, 0xB1, 0x5B, 0xA6, 0xE4, 0x83, 0x1A, 0x01, 0x00, 0x00, - 0x7A, 0x9E, 0xD9, 0x7B, 0x99, 0x8D, 0x06, 0x15, 0x1E, 0x6E, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, - 0xD2, 0xC5, 0x82, 0x22, 0xED, 0xC2, 0xF0, 0x68, 0x70, 0xFB, 0x51, 0xF7, 0xEC, 0x47, 0x10, 0x20, - 0x95, 0xDB, 0x0F, 0x1B, 0x1F, 0xB9, 0xDC, 0x7E, 0xE8, 0xF8, 0x70, 0x3B, 0x7D, 0xEF, 0x4C, 0x73, - 0xAE, 0xD1, 0x2D, 0x88, 0x1F, 0x1D, 0x3D, 0x12, 0x1F, 0xF6, 0xFF, 0xF6, 0xB6, 0x7F, 0xDC, 0x05, - 0x48, 0xE2, 0x5B, 0x90, 0x32, 0xC7, 0x87, 0xBF, 0x23, 0x37, 0x99, 0xE0, 0xB7, 0x0A, 0x00, 0x00, - 0x80, 0x46, 0xCC, 0xE1, 0xFE, 0x25, 0x66, 0x68, 0xBE, 0x0D, 0x87, 0x72, 0xC4, 0x47, 0xCB, 0xDB, - 0x0F, 0x11, 0x1F, 0x95, 0xDB, 0x0F, 0x1B, 0x1E, 0xB9, 0xDC, 0x7E, 0xE8, 0xF0, 0x88, 0x2E, 0xBC, - 0x05, 0x69, 0xF8, 0x2C, 0x88, 0x0C, 0x89, 0x2C, 0x53, 0x21, 0x91, 0x65, 0x22, 0x3E, 0xEC, 0x8F, - 0xFE, 0xF6, 0x7C, 0xC6, 0x9C, 0x3F, 0x70, 0xFD, 0x50, 0xF0, 0x8F, 0x53, 0x43, 0xA5, 0x8F, 0x0F, - 0x37, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x9A, 0xFF, 0x0A, 0x5E, 0xF9, 0x06, 0x2C, 0x11, 0x17, - 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x50, 0xA4, 0x9A, 0x8D, 0x8F, 0x30, 0x3C, 0xC2, 0xF8, 0x48, - 0x7A, 0xFB, 0xF1, 0x63, 0x1B, 0x1E, 0x2E, 0x40, 0x7E, 0xD8, 0xEE, 0xED, 0x87, 0x0E, 0x8E, 0xF8, - 0xDC, 0x2D, 0x48, 0xE3, 0x67, 0x41, 0x54, 0x48, 0x64, 0x99, 0x0A, 0x89, 0x2C, 0x6B, 0x12, 0x1F, - 0x4F, 0xBD, 0xD7, 0x9C, 0xDF, 0xF2, 0x21, 0x73, 0x7E, 0xFF, 0x32, 0x73, 0x76, 0xFF, 0xD2, 0x86, - 0x07, 0xEF, 0x69, 0x11, 0x1F, 0x6E, 0x2F, 0x5E, 0xE7, 0x02, 0x64, 0x5D, 0xF0, 0xDB, 0x06, 0x00, - 0x00, 0x80, 0xE2, 0xBF, 0x01, 0x6B, 0xEB, 0x87, 0x6C, 0x40, 0xF4, 0x7E, 0x7C, 0x64, 0xB9, 0xFD, - 0xA8, 0xC6, 0x87, 0xBB, 0xFD, 0xF8, 0x56, 0x3B, 0xB7, 0x1F, 0x3A, 0x36, 0x1A, 0x6D, 0xE2, 0x21, - 0x75, 0x0B, 0x32, 0xC3, 0x9F, 0x0E, 0x8A, 0x34, 0x53, 0x21, 0x91, 0x65, 0x2D, 0xE2, 0xC3, 0x6D, - 0xE3, 0x05, 0xE6, 0xFC, 0xEE, 0x25, 0xE6, 0xDC, 0xDE, 0x65, 0xF2, 0x01, 0xEC, 0x69, 0x13, 0x1F, - 0x6E, 0xCF, 0x5F, 0x69, 0xCC, 0x89, 0x3B, 0x73, 0xFF, 0x94, 0x78, 0x00, 0x00, 0x80, 0x52, 0xF1, - 0x0E, 0xAD, 0x1C, 0xEC, 0xF9, 0xF8, 0xC8, 0x78, 0xFB, 0x71, 0xEA, 0x51, 0x1B, 0x1D, 0xB9, 0xDC, - 0x7E, 0xE8, 0xC8, 0x68, 0xB6, 0xD3, 0xF7, 0xC4, 0x6F, 0x41, 0x2A, 0xF1, 0xD1, 0x7E, 0x80, 0xA8, - 0x90, 0xC8, 0xB2, 0x64, 0xF1, 0x71, 0xEE, 0x49, 0xBB, 0x4D, 0x1F, 0x76, 0x01, 0x62, 0xCE, 0x0E, - 0xD5, 0xDE, 0x82, 0x4C, 0xAB, 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x6F, 0xC2, 0x02, 0x00, 0x00, - 0x68, 0xC6, 0xDB, 0x77, 0x45, 0xE4, 0x15, 0xBC, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xA9, - 0xA0, 0x48, 0xB3, 0x20, 0x3E, 0x82, 0xA5, 0xBB, 0xFD, 0x88, 0xC4, 0x47, 0x5B, 0xB7, 0x1F, 0x3A, - 0x30, 0x92, 0x6C, 0xE2, 0x81, 0xE8, 0x2D, 0x88, 0x8D, 0x8F, 0xB6, 0x23, 0x44, 0x85, 0x44, 0x96, - 0x25, 0x8F, 0x8F, 0xB3, 0x83, 0x76, 0x4F, 0x5C, 0x60, 0xDE, 0xDD, 0xB1, 0xC4, 0x4C, 0xEC, 0x5E, - 0x5E, 0x3D, 0x7C, 0x4F, 0xC7, 0xF8, 0x70, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x2D, 0x98, 0x7D, - 0xF6, 0x70, 0xD7, 0xEB, 0xF1, 0x91, 0xE6, 0xF6, 0x23, 0x8C, 0x8F, 0x5C, 0x6E, 0x3F, 0x74, 0x58, - 0x24, 0x5D, 0xE5, 0x16, 0x64, 0xA6, 0x8D, 0x10, 0x1B, 0x20, 0x4F, 0xB5, 0x1B, 0x20, 0x2A, 0x24, - 0xB2, 0x2C, 0x43, 0x7C, 0x3C, 0x7E, 0x81, 0x39, 0x33, 0xF8, 0x41, 0x17, 0x20, 0xE6, 0xF4, 0x8E, - 0xA5, 0x03, 0xD3, 0x35, 0x3E, 0xFC, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x00, 0x34, 0x62, - 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x0B, 0x75, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, - 0x66, 0x91, 0xF8, 0x08, 0xA6, 0x6E, 0x3F, 0xAA, 0x01, 0x52, 0x73, 0xFB, 0x31, 0xAB, 0xFE, 0xF6, - 0xE3, 0x9B, 0x2A, 0x2E, 0x5A, 0x4D, 0x47, 0x45, 0x9A, 0xBD, 0xF3, 0xD7, 0x33, 0xCC, 0x99, 0x1F, - 0x4E, 0x06, 0x48, 0xF6, 0x5B, 0x10, 0x15, 0x12, 0x59, 0x96, 0x31, 0x3E, 0x1E, 0x9D, 0x61, 0x4E, - 0xFF, 0xD8, 0xEE, 0x99, 0x45, 0x66, 0xE2, 0xC0, 0xAA, 0x93, 0xD3, 0x36, 0x3E, 0xDC, 0x8E, 0xAC, - 0x32, 0xE6, 0xF8, 0x1D, 0x4B, 0x82, 0x2F, 0x31, 0x00, 0x00, 0x00, 0x44, 0x99, 0x91, 0xFE, 0x01, - 0xB3, 0xF3, 0x12, 0x1D, 0x18, 0xCD, 0x26, 0xA3, 0x22, 0xE9, 0x54, 0x50, 0xA4, 0x59, 0x2C, 0x3E, - 0x12, 0xDC, 0x7E, 0x4C, 0xB8, 0x00, 0x79, 0xDC, 0xDD, 0x7E, 0xC4, 0xE2, 0xC3, 0xED, 0x7B, 0x59, - 0xBE, 0xF5, 0x4A, 0x07, 0x45, 0x9A, 0xB9, 0xF8, 0xF0, 0x77, 0xF7, 0x0C, 0x7B, 0x90, 0x6F, 0xE7, - 0x16, 0x44, 0x85, 0x44, 0x96, 0xB5, 0x17, 0x1F, 0xA7, 0x1E, 0x76, 0x01, 0x32, 0xDB, 0x98, 0x63, - 0x77, 0x9A, 0x69, 0x1B, 0x1F, 0x3F, 0xBF, 0xCC, 0x98, 0x17, 0x3F, 0x67, 0xCC, 0x89, 0x2F, 0xAD, - 0x0D, 0xBE, 0xC4, 0x00, 0x00, 0x00, 0x10, 0xE5, 0x1D, 0x5A, 0x75, 0x97, 0xD9, 0x7E, 0xB1, 0x8E, - 0x8C, 0x46, 0x93, 0x51, 0x91, 0x74, 0x2A, 0x28, 0xD2, 0x2C, 0x16, 0x1F, 0x2A, 0x40, 0x1A, 0x3E, - 0xFB, 0x61, 0xE3, 0x23, 0x97, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0x56, 0x8D, 0x8F, 0x60, 0x67, 0xBE, - 0x5F, 0x09, 0x90, 0x73, 0xD1, 0x5B, 0x90, 0x20, 0x44, 0x74, 0x74, 0x84, 0x53, 0x21, 0x91, 0x65, - 0x39, 0xC4, 0xC7, 0xD3, 0x1F, 0x33, 0xDE, 0xD1, 0xDB, 0xA7, 0x77, 0x7C, 0xB8, 0x3D, 0xFF, 0x59, - 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x88, 0x19, 0x59, 0xB9, 0x5E, 0x46, 0x46, 0xA3, 0xC9, 0xA8, - 0x48, 0x3A, 0x15, 0x14, 0x69, 0x56, 0x1F, 0x1E, 0xD5, 0xF8, 0xB0, 0xE1, 0x31, 0x79, 0xFB, 0x11, - 0xF9, 0xD6, 0xAB, 0xEA, 0xED, 0xC7, 0x45, 0x95, 0xDB, 0x0F, 0xBB, 0xF6, 0x6E, 0x3F, 0x74, 0x50, - 0xA4, 0x59, 0x3C, 0x3E, 0xFC, 0x65, 0xBA, 0x05, 0x51, 0x21, 0x91, 0x65, 0xC4, 0x47, 0xFB, 0x0B, - 0xE2, 0x23, 0x98, 0xF7, 0x8B, 0x3B, 0x5B, 0x7E, 0x30, 0x23, 0x00, 0x00, 0xC0, 0xB4, 0xE4, 0x1D, - 0xB8, 0x7A, 0x54, 0x86, 0x86, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, 0x66, 0xB1, 0xF8, 0x88, - 0x07, 0x88, 0x5D, 0xF5, 0x5B, 0xAF, 0xC2, 0x00, 0xA9, 0x3E, 0x78, 0x6E, 0xE3, 0xC3, 0x06, 0x48, - 0xFB, 0xB7, 0x1F, 0x3A, 0x28, 0xD2, 0x4C, 0xC6, 0x47, 0xB0, 0xF0, 0x16, 0xC4, 0xBD, 0x92, 0xB7, - 0xF5, 0x2D, 0x88, 0x0A, 0x89, 0x2C, 0x23, 0x3E, 0xDA, 0x5F, 0x6D, 0x7C, 0xF8, 0x01, 0x72, 0xF4, - 0xD6, 0xB1, 0xE0, 0x4B, 0x0C, 0x00, 0x00, 0x00, 0x51, 0xDE, 0xFE, 0x2B, 0x4F, 0xCA, 0xD8, 0x88, - 0x4F, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x78, 0x88, 0xF8, 0x08, 0x6F, 0x3F, 0x6A, - 0x1E, 0x3C, 0xF7, 0x6F, 0x3F, 0x2E, 0x9A, 0xBC, 0xFD, 0x08, 0xE3, 0x23, 0x0C, 0x90, 0xFB, 0xD3, - 0xDC, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x1D, 0x35, 0x73, 0xB7, 0x20, 0x8F, 0x4D, 0xDE, 0x82, - 0xF8, 0x11, 0x62, 0x63, 0xA3, 0x3E, 0x40, 0x54, 0x48, 0x64, 0x19, 0xF1, 0xD1, 0xFE, 0xEA, 0xE3, - 0xC3, 0xDF, 0xB1, 0x2F, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x00, 0x25, 0xD1, 0x1B, 0xB0, 0x64, 0x54, - 0x24, 0x9D, 0x0A, 0x8A, 0x34, 0x8B, 0x85, 0x47, 0x93, 0xF8, 0xA8, 0x3E, 0x78, 0x5E, 0xBD, 0xFD, - 0xB0, 0xF1, 0x11, 0xDE, 0x7E, 0xC4, 0xE3, 0xE3, 0x21, 0xBB, 0xBB, 0x55, 0x68, 0xA8, 0xE9, 0xA0, - 0x48, 0x33, 0x19, 0x1C, 0x62, 0xA7, 0xBF, 0x3B, 0x23, 0x78, 0x16, 0xA4, 0xC1, 0xB7, 0x62, 0x3D, - 0xAD, 0x42, 0x22, 0xCB, 0x88, 0x8F, 0xF6, 0x27, 0xC2, 0x23, 0x1C, 0x6F, 0xC2, 0x02, 0x00, 0x00, - 0xA8, 0xE7, 0xBF, 0x01, 0x6B, 0xD7, 0x1C, 0x1D, 0x1D, 0xE1, 0x64, 0x54, 0x24, 0x9D, 0x0A, 0x8A, - 0x34, 0x8B, 0x85, 0x47, 0x38, 0x15, 0x20, 0xF1, 0xD7, 0xEE, 0x3E, 0x39, 0x19, 0x1F, 0xF2, 0xCD, - 0x57, 0x89, 0x6F, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0A, 0x8D, 0x66, 0x7B, 0x37, 0x7E, 0x0B, 0x12, - 0x46, 0x88, 0x8B, 0x8F, 0x70, 0x32, 0x2A, 0x92, 0x8E, 0xF8, 0x68, 0x7F, 0x22, 0x3A, 0xA2, 0x7B, - 0xF1, 0x7A, 0x63, 0x5E, 0xBE, 0xB3, 0xE6, 0x53, 0xE1, 0x01, 0x00, 0x00, 0xA6, 0x3D, 0x73, 0xA8, - 0x7F, 0xAD, 0xD9, 0xF1, 0x49, 0x1D, 0x1E, 0x6E, 0x32, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, 0xC5, - 0xA2, 0x23, 0xBA, 0x78, 0x7C, 0x44, 0x6F, 0x3F, 0x82, 0xF8, 0x98, 0xBC, 0xFD, 0x10, 0xDF, 0x7A, - 0x95, 0xF8, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xA9, 0xC0, 0x68, 0x35, 0x77, 0x0B, 0x52, 0xF7, 0xE1, - 0x84, 0x36, 0x3A, 0xF2, 0x09, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xE0, 0x88, 0xEF, 0x85, 0xAB, 0x79, - 0x13, 0x16, 0x00, 0x00, 0x40, 0x9C, 0xFF, 0x06, 0xAC, 0xAD, 0x1F, 0xEC, 0xB9, 0xF8, 0x68, 0x74, - 0xFB, 0xE1, 0xE2, 0xE3, 0x6C, 0x2C, 0x3E, 0xB2, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x17, - 0x49, 0xF7, 0xEE, 0x8F, 0x2B, 0x01, 0xE2, 0xBF, 0x96, 0xF7, 0x29, 0x1B, 0x1F, 0x6E, 0xD1, 0x08, - 0x91, 0x71, 0xD1, 0x6A, 0xC4, 0x47, 0xFB, 0x13, 0xB1, 0xD1, 0x60, 0xDE, 0x89, 0x2F, 0x0D, 0x06, - 0x5F, 0x6A, 0x00, 0x00, 0x00, 0x70, 0xBC, 0xE1, 0xE5, 0x43, 0x3D, 0x15, 0x1F, 0x6E, 0xF1, 0xF8, - 0x88, 0xDE, 0x7E, 0xB8, 0xF8, 0x68, 0x75, 0xFB, 0xF1, 0xA0, 0x9D, 0x0C, 0x8E, 0xE8, 0x74, 0x50, - 0xA4, 0x99, 0x8A, 0x8A, 0x34, 0x3B, 0xFD, 0xED, 0xE0, 0x16, 0xE4, 0x49, 0x1B, 0x20, 0x36, 0x0A, - 0xEA, 0x02, 0x24, 0x75, 0x84, 0x10, 0x1F, 0xED, 0x4F, 0x87, 0x46, 0xA3, 0x79, 0x47, 0x6F, 0x1D, - 0x0D, 0xBE, 0xD4, 0x00, 0x00, 0x00, 0xE0, 0x78, 0x7B, 0xAF, 0xA8, 0x7F, 0x05, 0xAF, 0x8C, 0x8A, - 0xA4, 0x53, 0x41, 0x91, 0x66, 0x22, 0x38, 0xA2, 0xB3, 0xD1, 0xE1, 0x7E, 0xAC, 0xBB, 0xFD, 0xB0, - 0xF1, 0x71, 0x6E, 0xE3, 0x45, 0xC9, 0x6E, 0x3F, 0xEE, 0x6B, 0x75, 0xFB, 0xA1, 0x83, 0x22, 0xCD, - 0x54, 0x50, 0x64, 0xD9, 0xBB, 0xF6, 0xD0, 0x1F, 0x06, 0x48, 0x7B, 0xB7, 0x20, 0xC4, 0x47, 0xFB, - 0xD3, 0x91, 0xD1, 0x74, 0xC7, 0x6E, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x51, 0x66, 0xEF, 0xE2, - 0xDE, 0x89, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x08, 0x03, 0x24, 0x88, 0x8F, 0x78, 0x80, 0xD4, - 0xC5, 0x47, 0xCB, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0xA6, 0x42, 0x22, 0xDB, 0x2E, 0x30, 0xA7, 0xBF, - 0x6D, 0xA3, 0x60, 0x70, 0x32, 0x42, 0x6A, 0x02, 0xC4, 0x85, 0x45, 0xA2, 0x08, 0x21, 0x3E, 0xDA, - 0x9F, 0x88, 0x8B, 0x24, 0x73, 0x6F, 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x1B, 0x00, 0x00, - 0xC0, 0xF4, 0x66, 0x46, 0xFA, 0x67, 0xD7, 0xBC, 0x82, 0x57, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, - 0x33, 0x11, 0x1B, 0xF1, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, 0xDF, 0x7E, 0xD8, 0xF0, 0x10, 0xB7, 0x1F, - 0xF2, 0x43, 0x07, 0x9B, 0xDE, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x76, 0x41, 0x75, - 0xE1, 0x2D, 0xC8, 0xB9, 0x4C, 0xB7, 0x20, 0xC4, 0x47, 0xFB, 0x13, 0x61, 0x91, 0x74, 0x63, 0xCB, - 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xC8, 0x7F, 0x05, 0x6F, 0xF8, 0x06, 0x2C, 0x19, 0x15, 0x49, - 0xA7, 0x82, 0x22, 0xCD, 0x62, 0xA1, 0xD1, 0x68, 0x61, 0x78, 0x84, 0xF1, 0xE1, 0xF6, 0xD4, 0x85, - 0x35, 0xDF, 0x7A, 0x15, 0x0F, 0x90, 0x53, 0x2E, 0x40, 0xC2, 0xDB, 0x8F, 0x1F, 0xD9, 0xC9, 0xF0, - 0x70, 0xD3, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x6C, 0x32, 0x3E, 0xDC, 0x4E, 0x7D, 0xD3, 0xC5, - 0x41, 0x96, 0x5B, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xA8, 0x48, 0xB3, 0x17, 0x3F, 0xC7, 0x9B, 0xB0, - 0x00, 0x00, 0x00, 0x42, 0xFE, 0x1B, 0xB0, 0xB6, 0x7D, 0xC4, 0x1E, 0xEE, 0x55, 0x54, 0x24, 0x9D, - 0x0A, 0x8A, 0x34, 0x13, 0xA1, 0xA1, 0x66, 0xA3, 0xC3, 0xFD, 0x58, 0x7B, 0xFB, 0x61, 0xE3, 0x23, - 0xCD, 0xED, 0xC7, 0xB7, 0x1A, 0xDD, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x56, 0x1B, - 0x1F, 0xE1, 0x26, 0x7E, 0x94, 0xF6, 0x16, 0x84, 0xF8, 0x68, 0x7F, 0x22, 0x28, 0x32, 0x8C, 0x37, - 0x61, 0x01, 0x00, 0x00, 0x04, 0xBC, 0x91, 0x81, 0x0D, 0x3A, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, - 0xC5, 0x22, 0xA3, 0xD9, 0xC2, 0xF0, 0x88, 0xC4, 0x47, 0xA2, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x68, - 0xD7, 0xA3, 0xF1, 0xE1, 0xD6, 0xF2, 0x16, 0x84, 0xF8, 0xC8, 0x79, 0x3A, 0x26, 0xB2, 0xCC, 0x3B, - 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0x38, 0xDE, 0x81, 0xAB, 0x47, 0x75, 0x58, 0x24, 0x99, - 0x0A, 0x8A, 0x34, 0x13, 0x91, 0xD1, 0x62, 0xD5, 0x00, 0x09, 0xE3, 0xA3, 0xED, 0xDB, 0x0F, 0x1D, - 0x14, 0x69, 0xA6, 0x43, 0x22, 0xCB, 0x74, 0x78, 0x44, 0x17, 0xDE, 0x82, 0xB8, 0x78, 0x68, 0x7C, - 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x12, 0x59, 0xE7, 0x1D, 0xBB, 0x65, 0x3C, 0xF8, 0x92, 0x03, - 0x00, 0x00, 0x98, 0xDE, 0xBC, 0x7D, 0x57, 0x8C, 0xEB, 0xB8, 0x68, 0x35, 0x15, 0x14, 0x69, 0xA6, - 0x03, 0xA3, 0xE1, 0x6A, 0x6E, 0x3F, 0x6C, 0x7C, 0x34, 0xBB, 0xFD, 0x08, 0xE3, 0xA3, 0xE5, 0xED, - 0x87, 0x0E, 0x8A, 0x34, 0xD3, 0x21, 0x91, 0x65, 0x3A, 0x38, 0xE2, 0xF3, 0x6F, 0x41, 0x1E, 0x6F, - 0x76, 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x11, 0x6D, 0xCD, 0xBD, 0x09, 0x6B, 0xEC, 0x8B, 0xB3, - 0x82, 0x2F, 0x3B, 0x00, 0x00, 0x80, 0xE9, 0xCB, 0x0C, 0x2D, 0xB0, 0x07, 0x7C, 0x15, 0x18, 0xCD, - 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x60, 0x24, 0x58, 0x18, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xB9, 0x1F, - 0xC9, 0x6E, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0E, 0x89, 0x2C, 0xD3, 0xB1, 0xD1, 0x68, 0x67, 0xBE, - 0x2F, 0x9E, 0x05, 0xF1, 0x43, 0x24, 0x12, 0x1E, 0x6E, 0xC4, 0x47, 0x86, 0x89, 0x78, 0xC8, 0x63, - 0x63, 0xCB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x80, 0xFF, 0x06, 0xAC, 0x9D, 0xB3, 0xED, 0xE1, 0x5E, - 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0x33, 0x1D, 0x17, 0x4D, 0x17, 0xB9, 0xF9, 0xF0, 0xE3, 0x43, - 0xDC, 0x7E, 0x4C, 0xB8, 0x3D, 0x1E, 0xB9, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xE5, 0x89, 0x0F, - 0x7F, 0x77, 0xAB, 0x5B, 0x90, 0x4A, 0x68, 0x18, 0x1B, 0x19, 0xC4, 0x47, 0xD6, 0x89, 0x70, 0xC8, - 0x65, 0x8B, 0x8D, 0x79, 0xF1, 0x5A, 0xE3, 0xFD, 0xE2, 0x4B, 0x77, 0x05, 0x5F, 0x7A, 0x00, 0x00, - 0x00, 0xD3, 0x93, 0x0D, 0x90, 0x75, 0x66, 0xC7, 0x27, 0xEC, 0x21, 0x5F, 0x85, 0x86, 0x9A, 0x0A, - 0x8A, 0x34, 0x13, 0x71, 0x91, 0x64, 0x61, 0x7C, 0xC4, 0x6E, 0x3F, 0x12, 0x3F, 0xFB, 0xF1, 0xCD, - 0x12, 0xC5, 0x47, 0xB0, 0x33, 0xDF, 0x8B, 0x3E, 0x0B, 0x52, 0x89, 0x8C, 0x70, 0x2E, 0x40, 0xC2, - 0xF0, 0x20, 0x3E, 0x92, 0x4E, 0x85, 0x43, 0x1E, 0xB3, 0xF1, 0xE1, 0x66, 0x7F, 0xED, 0xDE, 0x89, - 0x3B, 0x36, 0x04, 0x5F, 0x7A, 0x00, 0x00, 0x00, 0xD3, 0x93, 0xFF, 0x0A, 0x5E, 0x19, 0x1A, 0x6A, - 0x2A, 0x28, 0xD2, 0x4C, 0x84, 0x45, 0xAB, 0xD9, 0xF0, 0xA8, 0xC6, 0x87, 0x0D, 0x8F, 0xC9, 0xDB, - 0x8F, 0xD8, 0xB7, 0x5E, 0x45, 0x6F, 0x3F, 0xEC, 0x1A, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, - 0x12, 0x59, 0xA6, 0xC3, 0x22, 0xF1, 0xAA, 0xB7, 0x20, 0x36, 0x40, 0x36, 0xBA, 0xC0, 0x08, 0x82, - 0x23, 0x12, 0x1E, 0xC4, 0x47, 0xD2, 0xA9, 0x70, 0xC8, 0x63, 0x41, 0x7C, 0x04, 0xF3, 0x4E, 0xFC, - 0x39, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x9B, 0x77, 0xF0, 0xBA, 0x84, 0x6F, 0xC0, 0x52, 0x41, - 0x91, 0x66, 0xB1, 0xB0, 0x48, 0x3A, 0x17, 0x20, 0xE1, 0xCD, 0x87, 0x5D, 0xF5, 0x5B, 0xAF, 0xE4, - 0xB3, 0x1F, 0x17, 0xB5, 0xB8, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x04, 0x45, - 0x86, 0x9D, 0xFE, 0xCE, 0x7B, 0xFD, 0xB0, 0x08, 0x23, 0xA4, 0x1A, 0x1C, 0x2E, 0x3E, 0x82, 0x28, - 0x21, 0x3E, 0x5A, 0x4D, 0x85, 0x43, 0x1E, 0xAB, 0x8D, 0x0F, 0x3F, 0x40, 0x8E, 0x7D, 0x81, 0x37, - 0x61, 0x01, 0x00, 0x80, 0xE9, 0xCD, 0xDB, 0xFB, 0xD9, 0x31, 0x1D, 0x1C, 0xD1, 0xA9, 0xA0, 0x48, - 0xB3, 0x58, 0x54, 0x24, 0x5D, 0x2C, 0x3E, 0xC2, 0xDB, 0x8F, 0xBA, 0xF8, 0x88, 0xDE, 0x7E, 0x84, - 0xF1, 0x11, 0x06, 0xC8, 0x86, 0xF0, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xE9, 0x90, 0xC8, 0x32, 0x1D, - 0x13, 0xA9, 0xF7, 0x57, 0xEF, 0xF5, 0xF7, 0xEE, 0xA3, 0x93, 0x01, 0x12, 0x9F, 0x1F, 0x27, 0x2E, - 0x3C, 0x88, 0x8F, 0x06, 0x53, 0xE1, 0x90, 0xC7, 0xEA, 0xE3, 0xC3, 0xDF, 0x91, 0x1B, 0x4C, 0xF0, - 0xA5, 0x07, 0x00, 0x00, 0x30, 0x3D, 0x99, 0x3D, 0xF6, 0x50, 0x24, 0xA3, 0x23, 0x9C, 0x0A, 0x8A, - 0x34, 0x8B, 0x45, 0x45, 0xD2, 0x35, 0x88, 0x8F, 0xEA, 0x83, 0xE7, 0xEA, 0xF6, 0x23, 0x1E, 0x1F, - 0x0F, 0xD9, 0xDD, 0x5D, 0xEE, 0xF8, 0x70, 0x73, 0xB7, 0x20, 0x7E, 0x60, 0xD8, 0x9D, 0x7B, 0xD2, - 0x86, 0x87, 0xDD, 0xB9, 0x68, 0x7C, 0xD8, 0xF0, 0x38, 0x6B, 0xC3, 0x83, 0xF8, 0x88, 0x4F, 0x85, - 0x43, 0x1E, 0x8B, 0x45, 0x47, 0x74, 0x2F, 0xAD, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xFA, 0x32, - 0x87, 0xFB, 0x97, 0x98, 0xDD, 0xF3, 0xEC, 0x81, 0x5F, 0x85, 0x87, 0x9B, 0x0A, 0x8A, 0x34, 0x8B, - 0x45, 0x45, 0x9A, 0xD9, 0xE8, 0xA8, 0x0B, 0x90, 0x26, 0xDF, 0x7A, 0x25, 0xDF, 0x7C, 0x75, 0xBF, - 0xBB, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x45, 0xE2, 0x23, - 0x9C, 0xBB, 0x05, 0xF1, 0x43, 0x63, 0xD0, 0xC6, 0x88, 0x0D, 0x90, 0xB3, 0xB1, 0x6F, 0xB9, 0x7A, - 0xF7, 0x31, 0xE2, 0xA3, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x88, 0x8E, 0xE8, 0x5E, 0xBC, 0xD6, 0x06, - 0xC8, 0x1D, 0xEB, 0x82, 0x2F, 0x41, 0x00, 0x00, 0x80, 0xE9, 0xC5, 0x7F, 0x05, 0x6F, 0xC3, 0x37, - 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x15, 0x49, 0xF7, 0x8C, 0x88, 0x8F, 0xE8, 0xED, 0x87, 0x8B, - 0x8F, 0x9A, 0x00, 0x11, 0xDF, 0x7A, 0xE5, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, - 0x26, 0x42, 0x22, 0xCB, 0x44, 0x7C, 0xBC, 0xBD, 0xFE, 0xBD, 0xE6, 0xD4, 0x3D, 0x36, 0x42, 0x5C, - 0x68, 0xB8, 0xE0, 0x70, 0x21, 0x12, 0xFC, 0xE8, 0xFE, 0xB5, 0x09, 0x17, 0x1F, 0x36, 0x3C, 0x4E, - 0x3F, 0x42, 0x7C, 0x54, 0xA6, 0xC2, 0x21, 0x8F, 0x89, 0xE0, 0x88, 0xCF, 0xFD, 0xBE, 0x4E, 0xDC, - 0xB1, 0x3E, 0xF8, 0x12, 0x04, 0x00, 0x00, 0x98, 0x5E, 0xFC, 0x37, 0x60, 0x6D, 0xF9, 0x80, 0x3D, - 0xF4, 0x77, 0x5F, 0x7C, 0x34, 0xBA, 0xFD, 0x50, 0xAF, 0xDD, 0xD5, 0xB7, 0x1F, 0xED, 0x7F, 0xEB, - 0x95, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0x0D, 0xE2, 0x23, 0xDC, 0x99, 0x07, 0x6D, 0x6C, - 0x3C, 0x3E, 0xA3, 0x12, 0x22, 0x41, 0x78, 0x4C, 0x3C, 0x7A, 0x81, 0x7F, 0xEB, 0x41, 0x7C, 0x84, - 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x6C, 0x34, 0x98, 0x77, 0xE2, 0x0E, 0xDE, 0x84, 0x05, 0x00, 0x00, - 0xA6, 0x27, 0xEF, 0xD0, 0xCA, 0xC1, 0xAE, 0x8B, 0x8F, 0x5C, 0x6E, 0x3F, 0x2E, 0x6A, 0xFB, 0xF6, - 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0xD6, 0xD7, 0xEC, 0xBF, 0xF6, - 0x4D, 0x17, 0x1D, 0x33, 0xFC, 0x9D, 0xB1, 0xE1, 0xE1, 0xE6, 0x7F, 0xCB, 0x55, 0x18, 0x1F, 0x4F, - 0x11, 0x1F, 0xC5, 0x4C, 0x87, 0x46, 0xA3, 0x79, 0xC7, 0xBE, 0x70, 0x32, 0xF8, 0x12, 0x04, 0x00, - 0x00, 0x98, 0x5E, 0xBC, 0xBD, 0x57, 0xC4, 0x5E, 0xC1, 0xAB, 0x82, 0x22, 0xCD, 0x44, 0x54, 0x24, - 0x5D, 0x24, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0xA3, 0xFE, 0xD9, 0x0F, 0x75, 0xFB, 0x61, 0xE3, 0xE3, - 0xBE, 0xF6, 0x6E, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x4B, 0x10, 0x1F, 0x6F, 0x7D, - 0xED, 0x02, 0xF3, 0xD6, 0x7F, 0xB9, 0xC0, 0x9C, 0xFA, 0xA1, 0x0D, 0x0D, 0x77, 0xE3, 0xF1, 0x63, - 0x1B, 0x1F, 0x41, 0x78, 0xBC, 0xF3, 0x90, 0xFD, 0x91, 0xF8, 0x28, 0x68, 0x3A, 0x32, 0x9A, 0xEE, - 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x4C, 0x4F, 0x66, 0xAF, 0x3D, 0xF0, 0x75, 0x53, 0x7C, - 0x04, 0x01, 0xD2, 0xEC, 0xF6, 0x23, 0x1E, 0x20, 0x75, 0xF1, 0xF1, 0x60, 0x7B, 0x0F, 0x9E, 0xEB, - 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x96, 0x22, 0x3E, 0xDE, 0xFC, 0xCF, 0xF6, 0xC7, 0xBB, 0x6D, - 0x84, 0x04, 0xD1, 0xE1, 0xEF, 0x41, 0xE2, 0x43, 0x87, 0x43, 0x1E, 0x13, 0x71, 0x91, 0x64, 0x47, - 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xFD, 0x98, 0xD1, 0xFE, 0x59, 0x66, 0x68, 0x81, 0x0D, - 0x80, 0xEE, 0x8A, 0x0F, 0xF7, 0xA3, 0xBA, 0xFD, 0x50, 0xCF, 0x7E, 0xD4, 0x7E, 0xE8, 0xA0, 0x0D, - 0x8F, 0x87, 0xDB, 0xBB, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x2C, 0x65, 0x7C, 0xB8, - 0xFD, 0xE1, 0xFF, 0xB1, 0xFF, 0xFF, 0x77, 0x66, 0x98, 0xB7, 0x1F, 0x98, 0x69, 0x67, 0xE3, 0x63, - 0x23, 0xF1, 0x51, 0xCC, 0x44, 0x58, 0x24, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x2F, 0xAD, 0x0D, 0xBE, - 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0xFF, 0x0D, 0x58, 0x3B, 0x67, 0xDB, 0x08, 0x50, 0x41, 0x91, - 0x66, 0x22, 0x2A, 0x92, 0x2E, 0x1A, 0x1F, 0x41, 0x80, 0x34, 0xBB, 0xFD, 0x70, 0xF1, 0x11, 0x0F, - 0x90, 0x6A, 0x7C, 0xB4, 0x79, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, 0x64, 0x59, 0xC6, 0xF8, - 0x78, 0xE3, 0x2F, 0x67, 0x98, 0xF1, 0xFF, 0x3C, 0xC3, 0xBC, 0xF5, 0x23, 0xFB, 0x7B, 0x7A, 0x92, - 0xF8, 0x28, 0x66, 0x22, 0x2A, 0xD2, 0xEC, 0xF9, 0x2B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x7E, - 0xBC, 0x43, 0xAB, 0xEE, 0x32, 0xDB, 0x3E, 0x6A, 0x43, 0x40, 0x45, 0x45, 0xD2, 0x89, 0xA8, 0x48, - 0x3A, 0x11, 0x1F, 0xEE, 0xC7, 0xD4, 0xB7, 0x1F, 0x61, 0x7C, 0xB8, 0xDB, 0x8F, 0x7B, 0xB3, 0xDD, - 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x4E, 0x7C, 0xFC, 0xA7, 0x19, 0xE6, 0xF7, - 0xFF, 0xF7, 0x0C, 0xF3, 0xE6, 0x03, 0xC4, 0x47, 0x31, 0x13, 0x41, 0x91, 0x61, 0xDE, 0x2F, 0xEE, - 0x18, 0x0A, 0xBE, 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0x33, 0xD2, 0xBF, 0x5E, 0x47, 0x45, 0xD2, - 0x89, 0xA8, 0x48, 0xBA, 0x78, 0x7C, 0xB8, 0x85, 0xE1, 0x11, 0xC6, 0x47, 0xAB, 0xDB, 0x0F, 0xFF, - 0x5B, 0xAF, 0x82, 0xF8, 0x70, 0xFB, 0xA1, 0x9D, 0x88, 0x8B, 0x56, 0xD3, 0x21, 0x91, 0x65, 0x22, - 0x24, 0xB2, 0x2C, 0x87, 0xF8, 0x78, 0xE3, 0xDB, 0x36, 0x3E, 0x5E, 0x22, 0x3E, 0xF2, 0x9F, 0x8E, - 0x89, 0x2C, 0xF3, 0x8E, 0xDE, 0x3C, 0x16, 0x7C, 0x29, 0x02, 0x00, 0x00, 0x4C, 0x0F, 0xDE, 0x81, - 0xAB, 0x46, 0x75, 0x58, 0x24, 0x99, 0x88, 0x8A, 0xA4, 0x6B, 0x10, 0x1F, 0xEE, 0xC7, 0x54, 0xB7, - 0x1F, 0xD1, 0xF8, 0x70, 0xB7, 0x1F, 0xDF, 0x4A, 0x7F, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, - 0x64, 0x19, 0xF1, 0x91, 0xC3, 0x54, 0x38, 0xE4, 0x31, 0x1D, 0x12, 0x99, 0xC7, 0x9B, 0xB0, 0x00, - 0x00, 0xC0, 0x74, 0xE3, 0xED, 0xFF, 0xEC, 0x49, 0x1D, 0x17, 0xAD, 0x26, 0xA2, 0x22, 0xE9, 0xE2, - 0xE1, 0x11, 0x2E, 0x0C, 0x8F, 0x30, 0x3E, 0x9A, 0xDD, 0x7E, 0x3C, 0x76, 0x91, 0x39, 0xFD, 0xA8, - 0x0D, 0x8E, 0x36, 0x6F, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, - 0x0A, 0x87, 0x3C, 0x26, 0x02, 0xA2, 0xDD, 0xB9, 0x37, 0x61, 0x1D, 0xBF, 0x63, 0x49, 0xF0, 0xE5, - 0x08, 0x00, 0x00, 0x50, 0x7E, 0x66, 0x68, 0xBE, 0x8D, 0x02, 0x15, 0x18, 0xCD, 0x26, 0xA2, 0x22, - 0xE9, 0x54, 0x78, 0x44, 0x96, 0xE8, 0xF6, 0x23, 0x88, 0x8F, 0x76, 0x6F, 0x3F, 0x74, 0x48, 0x64, - 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0x26, 0xE2, 0x21, 0x8F, 0xBD, - 0x78, 0x1D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x87, 0xFF, 0x06, 0xAC, 0x5D, 0x9F, 0xB6, 0x61, - 0xA0, 0x22, 0xA3, 0xD1, 0x44, 0x54, 0x24, 0x9D, 0x08, 0x8E, 0xEA, 0x92, 0xDE, 0x7E, 0x3C, 0x6E, - 0x03, 0x24, 0x8C, 0x8F, 0x68, 0x80, 0xFC, 0x80, 0xF8, 0x20, 0x3E, 0x54, 0x38, 0xE4, 0x31, 0x11, - 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x3E, 0xCC, 0xA1, 0xFE, 0xB5, - 0x66, 0xC7, 0xC7, 0x6D, 0x1C, 0xA8, 0xD0, 0x50, 0x13, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0x62, 0x53, - 0xB7, 0x1F, 0xD1, 0x00, 0xF1, 0xE3, 0xA3, 0xD1, 0xED, 0xC7, 0x37, 0x75, 0x68, 0xA8, 0xE9, 0x90, - 0xC8, 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x44, 0x43, 0xCE, - 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xDA, 0xF0, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0x36, 0x10, 0x54, - 0x6C, 0xC4, 0x27, 0xA2, 0x22, 0xE9, 0x44, 0x6C, 0xD4, 0x2C, 0xC1, 0xED, 0x87, 0xFB, 0xD6, 0xAB, - 0x89, 0xC7, 0x2E, 0x9C, 0xBC, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xC9, 0x6F, 0x3F, 0x74, 0x48, - 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0xA6, 0x83, 0x21, 0xEF, - 0x79, 0x47, 0xFF, 0x64, 0x34, 0xF8, 0x92, 0x04, 0x00, 0x00, 0x28, 0x37, 0x6F, 0x78, 0xE9, 0x90, - 0x8E, 0x8D, 0xF8, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8E, 0xF8, 0xE2, 0x01, 0xA2, 0x9E, 0xFD, 0x78, - 0xDC, 0xC6, 0x47, 0x9B, 0xB7, 0x1F, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x11, 0x1F, 0x39, - 0x4C, 0x85, 0x43, 0x1E, 0xD3, 0xB1, 0x50, 0xC8, 0x8E, 0x7D, 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, - 0xE9, 0xC1, 0xDB, 0xBB, 0x24, 0xC1, 0x2B, 0x78, 0x45, 0x54, 0x24, 0x9D, 0x8A, 0x8D, 0xE8, 0x6C, - 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, 0x47, 0xEC, 0x5B, 0xAF, 0x9E, 0xB8, 0x70, 0xF2, - 0xF6, 0xC3, 0x2E, 0xCB, 0xED, 0x87, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, - 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x24, 0x14, 0xB6, 0x45, 0x95, 0x37, 0x61, 0xBD, 0x7C, 0xE7, 0xEC, - 0xE0, 0xCB, 0x12, 0x00, 0x00, 0xA0, 0xBC, 0xCC, 0x1E, 0x7B, 0xF8, 0x91, 0xD1, 0x11, 0x4E, 0x44, - 0x45, 0xD2, 0xA9, 0xE0, 0x88, 0x2F, 0x1A, 0x20, 0x76, 0xD5, 0x6F, 0xBD, 0x8A, 0x06, 0x88, 0x8B, - 0x0F, 0xFF, 0xF6, 0xE3, 0xC2, 0xFA, 0xDB, 0x8F, 0x87, 0xEC, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, - 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xB3, - 0x5F, 0x7F, 0x6E, 0x2F, 0x7E, 0xCE, 0x05, 0xC8, 0x40, 0xF0, 0x65, 0x09, 0x00, 0x00, 0x50, 0x4E, - 0x66, 0xA4, 0x7F, 0x76, 0xF3, 0x57, 0xF0, 0x8A, 0xA8, 0x48, 0x3A, 0x15, 0x1B, 0xF1, 0xC5, 0xE2, - 0x23, 0xBC, 0xFD, 0xA8, 0x7D, 0xF0, 0xDC, 0xC6, 0x47, 0xF4, 0xF6, 0x23, 0xFE, 0xAD, 0x57, 0xF7, - 0xB7, 0xBE, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, - 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x16, 0xC4, 0x87, 0x1F, 0x20, 0xD7, 0xF0, 0x26, 0x2C, 0x00, 0x00, - 0x50, 0x7E, 0xFE, 0x2B, 0x78, 0x1B, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, 0xA9, 0xD8, 0x88, 0xAF, - 0x41, 0x7C, 0x54, 0x1F, 0x3C, 0x77, 0xB3, 0xF1, 0x51, 0x73, 0xFB, 0x11, 0x7F, 0xF0, 0xDC, 0xDD, - 0x7E, 0xDC, 0xAD, 0xA3, 0x23, 0x9C, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, - 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0xB5, 0x48, 0x7C, 0x04, 0xF3, 0x4E, 0x7C, 0x69, 0x30, - 0xF8, 0xD2, 0x04, 0x00, 0x00, 0x28, 0x27, 0xFF, 0x0D, 0x58, 0x5B, 0x3F, 0x64, 0xA3, 0x61, 0x8A, - 0xE3, 0xC3, 0x4D, 0x05, 0x48, 0xCD, 0xB7, 0x5E, 0xD9, 0xF8, 0x70, 0xB7, 0x1F, 0x41, 0x7C, 0x64, - 0xB9, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x56, 0x1F, 0x1F, 0x6E, 0xDE, 0xF1, 0x3F, 0xE5, 0x4D, 0x58, 0x00, 0x00, - 0xA0, 0xDC, 0xBC, 0x91, 0x81, 0x0D, 0x1D, 0x89, 0x0F, 0xB7, 0x78, 0x7C, 0x54, 0x6F, 0x3F, 0x2E, - 0xAC, 0xC6, 0xC7, 0xE4, 0xED, 0x47, 0x2C, 0x3E, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, - 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xF1, 0xE1, - 0xEF, 0xD8, 0x2D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x94, 0x9B, 0x77, 0xE0, 0xAA, 0xD8, 0x1B, 0xB0, - 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x8C, 0x46, 0xB3, 0xD1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0x44, 0x02, - 0x24, 0x8C, 0x0F, 0xF9, 0xB9, 0x1F, 0xDF, 0x69, 0x7C, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, - 0x64, 0x59, 0x34, 0x3A, 0x88, 0x8F, 0x8C, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x11, - 0x1D, 0xD1, 0xB9, 0x37, 0x61, 0x8D, 0x7D, 0x71, 0x56, 0xF0, 0xE5, 0x09, 0x00, 0x00, 0x50, 0x3E, - 0xDE, 0xBE, 0x25, 0xE3, 0x53, 0x1E, 0x1F, 0x6E, 0xF1, 0xF8, 0x48, 0x7B, 0xFB, 0xF1, 0xA0, 0x9D, - 0x08, 0x0F, 0x37, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x52, 0xC4, 0x47, 0x18, 0x20, 0x2E, - 0x3E, 0xFE, 0x40, 0x7C, 0x44, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x38, 0xE2, - 0x1B, 0x5B, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB9, 0x4D, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, - 0xA9, 0xC0, 0x68, 0x36, 0x1B, 0x1D, 0xEE, 0x47, 0x75, 0xFB, 0x11, 0x0D, 0x90, 0xA6, 0xB7, 0x1F, - 0xF7, 0xE9, 0xDB, 0x0F, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x22, 0xF1, 0x11, 0xAE, 0x3E, - 0x3E, 0xEC, 0x5C, 0x78, 0x84, 0xB7, 0x1F, 0xC4, 0x47, 0x6C, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, - 0xA2, 0x26, 0x62, 0x43, 0xED, 0xC5, 0x6B, 0x8C, 0xF7, 0x8B, 0x2F, 0xDD, 0x15, 0x7C, 0x79, 0x02, - 0x00, 0x00, 0x94, 0x8B, 0xFF, 0x06, 0xAC, 0x9D, 0x9F, 0xD2, 0x51, 0x91, 0x74, 0xF1, 0xB8, 0x48, - 0xB2, 0x30, 0x3C, 0xC2, 0xF8, 0xF0, 0x03, 0x64, 0x66, 0x35, 0x3E, 0x6A, 0xDF, 0x7C, 0x95, 0xFC, - 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0x76, 0x24, 0x3E, 0xE2, - 0x37, 0x1F, 0x6F, 0x04, 0xF1, 0xF1, 0x07, 0xE2, 0xA3, 0xA0, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x34, - 0x9A, 0xCC, 0x3B, 0x71, 0xC7, 0x86, 0xE0, 0x4B, 0x14, 0x00, 0x00, 0xA0, 0x5C, 0x6C, 0x80, 0xAC, - 0x33, 0xDB, 0x2F, 0xD6, 0x61, 0x91, 0x64, 0x2A, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0xF6, - 0xF6, 0xC3, 0xC6, 0x47, 0x83, 0x67, 0x3F, 0xEA, 0x3E, 0x74, 0xD0, 0xBD, 0xF9, 0x4A, 0xDC, 0x7E, - 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x22, 0x3E, 0xA2, 0x37, 0x1F, 0x61, 0x7C, 0x84, - 0x37, 0x1F, 0xC4, 0x47, 0x38, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x91, 0xD1, 0x6C, - 0xDE, 0x89, 0x3F, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x9C, 0xFC, 0x57, 0xF0, 0xAA, 0xB0, 0x48, - 0xB2, 0x78, 0x58, 0x24, 0x5D, 0x18, 0x1E, 0x61, 0x7C, 0x3C, 0x3D, 0xB3, 0xE6, 0xF6, 0xA3, 0xEE, - 0xD9, 0x0F, 0x1B, 0x20, 0xA7, 0xA2, 0x01, 0xF2, 0x23, 0xBB, 0x1E, 0x8C, 0x0F, 0xB7, 0xBA, 0x00, - 0x69, 0x10, 0x1F, 0xE3, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0xC0, - 0x68, 0x35, 0xEF, 0xD8, 0x17, 0xC6, 0x83, 0x2F, 0x51, 0x00, 0x00, 0x80, 0x72, 0xF1, 0x0E, 0x5C, - 0x33, 0x2A, 0xE3, 0xA2, 0xD5, 0x54, 0x58, 0x24, 0x99, 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, - 0xF1, 0x11, 0xBD, 0xFD, 0x88, 0xC5, 0x47, 0xDD, 0xED, 0xC7, 0xB7, 0x6A, 0x6F, 0x3F, 0x74, 0x48, - 0x64, 0x99, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x56, 0x17, 0x1F, 0xEA, 0x8D, 0x57, 0xC4, 0x47, - 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x71, 0x91, 0x68, 0x47, 0x56, 0xF3, 0x26, - 0x2C, 0x00, 0x00, 0x50, 0x4E, 0xDE, 0xDE, 0x25, 0x63, 0x32, 0x30, 0x9A, 0x2D, 0x1E, 0x15, 0x69, - 0x16, 0x86, 0x47, 0x18, 0x1F, 0x69, 0x6F, 0x3F, 0x7E, 0x68, 0x57, 0xB6, 0xF8, 0x70, 0x37, 0x1F, - 0x2E, 0x3E, 0xDC, 0x43, 0xE7, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, - 0xA8, 0x48, 0xB3, 0x97, 0x56, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x4E, 0x66, 0xCF, 0x42, 0x1D, - 0x19, 0x8D, 0xA6, 0xA2, 0x22, 0xE5, 0x2A, 0x01, 0x32, 0xB3, 0xED, 0xDB, 0x0F, 0x1D, 0x12, 0x59, - 0x26, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0xB5, 0x8C, 0x8F, 0xBF, 0x9C, 0xFC, 0xAC, 0x8F, 0x3F, - 0xDC, 0x4B, 0x7C, 0x14, 0x33, 0x15, 0x09, 0x45, 0x4D, 0x04, 0x45, 0xDA, 0xBD, 0x78, 0x8D, 0x0D, - 0x90, 0x3B, 0xD6, 0x05, 0x5F, 0xA6, 0x00, 0x00, 0x00, 0xE5, 0x60, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, - 0xE6, 0xE8, 0xD0, 0x50, 0x13, 0x31, 0x91, 0x6A, 0xD5, 0xDB, 0x8F, 0x20, 0x3E, 0x9A, 0xDD, 0x7E, - 0x84, 0xF1, 0xD1, 0xE0, 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, - 0x0D, 0xE3, 0x23, 0x08, 0x90, 0xE8, 0x07, 0x0D, 0x12, 0x1F, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, - 0xA2, 0x26, 0x62, 0x22, 0xCB, 0x9E, 0xB7, 0x7F, 0x3F, 0x4E, 0xDC, 0xB1, 0x3E, 0xF8, 0x52, 0x05, - 0x00, 0x00, 0x28, 0x07, 0xFF, 0x15, 0xBC, 0x49, 0xDF, 0x80, 0xA5, 0x82, 0x22, 0xC3, 0xFC, 0xF8, - 0x88, 0xDD, 0x7E, 0x54, 0x03, 0xA4, 0xD5, 0xED, 0xC7, 0x3D, 0xBD, 0x1B, 0x1F, 0x95, 0xD7, 0xED, - 0x12, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x24, 0xDA, 0x18, 0x6F, - 0xC2, 0x02, 0x00, 0x00, 0xA5, 0xE3, 0xBF, 0x01, 0x6B, 0xEB, 0x07, 0x75, 0x70, 0x44, 0x27, 0x42, - 0x22, 0xF5, 0xC2, 0x9B, 0x8F, 0x26, 0xB7, 0x1F, 0x13, 0x2E, 0x40, 0x1E, 0x8B, 0xDC, 0x7E, 0x84, - 0xF1, 0xE1, 0xF6, 0xBD, 0xCA, 0xB7, 0x5E, 0xE9, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x26, 0xC2, - 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x11, 0xD1, 0xCE, - 0xBC, 0x63, 0x5F, 0x38, 0x19, 0x7C, 0xA9, 0x02, 0x00, 0x00, 0x94, 0x83, 0x37, 0xBC, 0x62, 0x50, - 0x06, 0x47, 0x74, 0x2A, 0x26, 0xB2, 0x2C, 0x8C, 0x8F, 0xD8, 0xED, 0x47, 0xE2, 0x67, 0x3F, 0xBE, - 0xC9, 0xB7, 0x5D, 0x25, 0x9B, 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, - 0x2A, 0x12, 0x8A, 0x9A, 0x0E, 0x88, 0xB6, 0x77, 0x64, 0xB5, 0x09, 0xBE, 0x54, 0x01, 0x00, 0x00, - 0xCA, 0xC1, 0xDB, 0x7B, 0x79, 0xF3, 0x57, 0xF0, 0xAA, 0x90, 0x48, 0xBB, 0x4D, 0x6E, 0x93, 0xE1, - 0x31, 0x79, 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xFC, 0xF6, 0x43, 0x87, 0x44, - 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0x0D, 0xE3, 0xC3, 0x3D, 0x70, 0x1E, 0x8B, 0x8F, - 0xF1, 0xFF, 0x32, 0xCB, 0x9C, 0xFF, 0xD7, 0x5B, 0x83, 0xF8, 0x58, 0x65, 0x0F, 0xFA, 0x2A, 0x28, - 0xD2, 0x4C, 0x84, 0x43, 0x1E, 0x93, 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, - 0x4D, 0x84, 0x43, 0x5E, 0x3B, 0xB2, 0x92, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF1, 0xF6, 0x2C, - 0x1A, 0x97, 0xE1, 0xE1, 0xA6, 0x62, 0x22, 0xCB, 0x6C, 0x78, 0x44, 0x6F, 0x3F, 0xAA, 0xDF, 0x7A, - 0x15, 0x06, 0x48, 0xCD, 0x6B, 0x77, 0x2F, 0x94, 0xB7, 0x1F, 0xEF, 0x7C, 0x23, 0xAF, 0xDB, 0x0F, - 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x2D, 0x6D, 0x7C, 0x9C, 0xFB, 0xE9, 0x17, 0x2A, 0xF1, 0x71, - 0xD4, 0xFE, 0x28, 0x83, 0x22, 0xCD, 0x44, 0x38, 0xE4, 0x31, 0x19, 0x0E, 0x79, 0x4C, 0x85, 0x43, - 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x44, 0x34, 0xE4, 0x39, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xCA, 0xC4, - 0x0C, 0xF5, 0xCF, 0x32, 0x43, 0x7D, 0x53, 0x1A, 0x1F, 0xE1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xCD, - 0x9E, 0xFD, 0x70, 0xF1, 0x71, 0x7F, 0x5E, 0xB7, 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, - 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x82, 0x21, 0xEF, 0xB9, 0xFF, - 0x6D, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0x0B, 0xFF, 0x0D, 0x58, 0x3B, 0x3E, 0x39, 0xE5, 0xF1, - 0x51, 0x7D, 0xF0, 0x5C, 0xDD, 0x7E, 0xC4, 0x1E, 0x3C, 0x7F, 0xE7, 0x41, 0x1B, 0x1F, 0x5F, 0x57, - 0x31, 0x91, 0x76, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x62, 0xA1, 0xA0, 0x79, 0x27, 0xEE, 0xE0, 0x4D, 0x58, 0x00, 0x00, - 0xA0, 0x1C, 0xBC, 0xE1, 0xFE, 0xBB, 0xCC, 0xB6, 0x8F, 0x14, 0x13, 0x1F, 0xCF, 0x54, 0xE2, 0xA3, - 0x2E, 0x40, 0xE2, 0xAF, 0xDD, 0x75, 0xB7, 0x1F, 0x41, 0x7C, 0xC4, 0x6F, 0x3F, 0xDE, 0x79, 0xD8, - 0xC6, 0xC7, 0x77, 0xF3, 0xF8, 0xD6, 0x2B, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, - 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xA1, 0x50, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, - 0x82, 0x2F, 0x59, 0x00, 0x00, 0x80, 0xDE, 0xE6, 0xBF, 0x82, 0xB7, 0xA8, 0xF8, 0x08, 0x02, 0xA4, - 0xE1, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0x8A, 0xC7, 0x47, 0x2E, 0xB7, 0x1F, 0x22, 0x24, - 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0xA6, - 0x23, 0xA1, 0xD0, 0x1D, 0xB9, 0x91, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF0, 0x0E, 0x5C, 0x33, - 0xF9, 0x06, 0x2C, 0x19, 0x12, 0x59, 0x36, 0x19, 0x1F, 0x8D, 0x6E, 0x3F, 0xAA, 0xAF, 0xDD, 0xAD, - 0xDE, 0x7E, 0x5C, 0x14, 0xBB, 0xFD, 0xB0, 0xE1, 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, - 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x38, 0x98, - 0x8A, 0xBD, 0x34, 0x60, 0xCC, 0xF1, 0x3B, 0x96, 0x04, 0x5F, 0xB6, 0x00, 0x00, 0x00, 0xBD, 0xCB, - 0xDB, 0x77, 0xC5, 0xC9, 0x42, 0xE2, 0xA3, 0xAD, 0xDB, 0x8F, 0x20, 0x3E, 0x1E, 0x68, 0xF7, 0xF6, - 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, - 0x50, 0xD4, 0x44, 0x18, 0x4C, 0xD5, 0xDC, 0x9B, 0xB0, 0x4E, 0x7C, 0x69, 0x6D, 0xF0, 0x65, 0x0B, - 0x00, 0x00, 0xD0, 0xBB, 0xCC, 0xEE, 0xBE, 0x48, 0x3C, 0xB4, 0xBB, 0xDA, 0xF8, 0x70, 0x3F, 0xAA, - 0xDB, 0x8F, 0xFA, 0x67, 0x3F, 0xA2, 0xB7, 0x1F, 0x41, 0x7C, 0xB8, 0xDD, 0xDB, 0xCE, 0xED, 0x87, - 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, - 0xA8, 0x89, 0x28, 0x98, 0xCA, 0xBD, 0x70, 0x25, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xCF, 0x1C, - 0xE8, 0x5F, 0x62, 0x76, 0xCE, 0x0E, 0xE2, 0xA1, 0xDD, 0x45, 0xE2, 0x23, 0x08, 0x90, 0x66, 0xB7, - 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xE1, 0x6E, 0x3F, 0x64, 0x58, 0x24, 0x99, 0x08, 0x89, 0x2C, - 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x20, - 0xE8, 0xC0, 0xBC, 0xE3, 0xB7, 0x0F, 0x05, 0x5F, 0xBA, 0x00, 0x00, 0x00, 0xBD, 0xC9, 0x1C, 0x5C, - 0xB6, 0xD6, 0x6C, 0xFF, 0x58, 0x10, 0x10, 0xED, 0xAC, 0x3E, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0x43, - 0x3D, 0xFB, 0x51, 0xF9, 0xD0, 0xC1, 0x0B, 0x27, 0x03, 0xE4, 0x21, 0xBB, 0xCC, 0xB7, 0x1F, 0x22, - 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, - 0xA6, 0x63, 0xA0, 0x13, 0xF3, 0x8E, 0xDE, 0xC2, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x33, 0x23, - 0xCB, 0xD7, 0x9B, 0xCD, 0xEF, 0xB3, 0xB1, 0xA0, 0xA2, 0x22, 0xE9, 0x62, 0xF1, 0xE1, 0x16, 0x86, - 0x47, 0x18, 0x1F, 0xB1, 0xDB, 0x8F, 0xBA, 0x67, 0x3F, 0x1E, 0xB5, 0xF1, 0xE1, 0x02, 0xA4, 0xED, - 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, - 0x45, 0x42, 0x51, 0xD3, 0x21, 0xD0, 0xB1, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, - 0xE6, 0x1D, 0xB8, 0x7E, 0xA8, 0x36, 0x26, 0xD2, 0x4E, 0xC7, 0x87, 0xFB, 0xB1, 0xE9, 0xED, 0x47, - 0x2C, 0x3E, 0xEA, 0x6E, 0x3F, 0xEE, 0xC9, 0x72, 0xFB, 0x21, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, - 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x00, 0x3A, 0x3D, 0xF7, - 0x26, 0xAC, 0x97, 0xEF, 0x9C, 0x1D, 0x7C, 0xF9, 0x02, 0x00, 0x00, 0xF4, 0x1E, 0x6F, 0xEF, 0x65, - 0xA3, 0xF5, 0x51, 0x91, 0x74, 0xB1, 0xF0, 0x08, 0x17, 0x86, 0x47, 0x18, 0x1F, 0x4D, 0x6F, 0x3F, - 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x4E, 0x06, 0x46, 0xB3, 0x89, 0x90, 0xC8, - 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, - 0xFC, 0x77, 0xC3, 0x5E, 0xFC, 0x9C, 0x31, 0xC7, 0x6E, 0x1B, 0x08, 0xBE, 0x7C, 0x01, 0x00, 0x00, - 0x7A, 0x8F, 0xD9, 0x63, 0x0F, 0x5B, 0x32, 0x2E, 0x5A, 0x4D, 0x84, 0x47, 0x64, 0xC9, 0x6E, 0x3F, - 0x2A, 0xF1, 0xD1, 0xFE, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, - 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xFE, 0xDD, 0x32, 0xDE, 0x84, 0x05, 0x00, - 0x00, 0x7A, 0x99, 0x19, 0xE9, 0x9F, 0x6D, 0x76, 0xCF, 0xB3, 0xC1, 0xA0, 0x02, 0xA3, 0xD9, 0x74, - 0x74, 0xF8, 0x4B, 0x7C, 0xFB, 0x31, 0xD3, 0x9C, 0x09, 0xE3, 0xA3, 0xAD, 0xDB, 0x0F, 0x11, 0x12, - 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xFE, 0x2E, 0x9B, 0x77, 0xE2, 0xF6, 0xC1, 0xE0, 0x4B, 0x18, 0x00, 0x00, 0xA0, 0xB7, 0xD8, - 0x00, 0x19, 0x48, 0xFF, 0x06, 0x2C, 0x11, 0x1D, 0xB1, 0xA9, 0xDB, 0x8F, 0x6A, 0x80, 0x84, 0xF1, - 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, - 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7F, 0xB7, 0xCD, 0x3B, 0xFA, 0x85, 0xD1, 0xE0, 0x4B, - 0x18, 0x00, 0x00, 0xA0, 0xB7, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0x3E, 0x60, 0xA3, 0x41, 0x85, - 0x86, 0x9A, 0x0E, 0x8E, 0xEA, 0x12, 0xDC, 0x7E, 0x4C, 0x3C, 0x31, 0xD3, 0x4C, 0x3C, 0x16, 0xB9, - 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0xFB, 0xC4, 0x47, 0x65, 0x22, 0x1C, 0xF2, 0x98, 0x0C, 0x87, 0x3C, - 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0xB0, 0xDF, 0x95, 0x3B, 0x76, 0x0B, 0x6F, - 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xC9, 0x1B, 0x59, 0xB1, 0xA1, 0x3E, 0x32, 0x1A, 0x4D, 0x04, 0x47, - 0x7C, 0xF1, 0x00, 0xA9, 0x7B, 0xF6, 0xC3, 0xC6, 0x47, 0xB3, 0xDB, 0x8F, 0x6F, 0xA8, 0xD0, 0x50, - 0x13, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, - 0x14, 0x35, 0x71, 0xC8, 0xEF, 0xE6, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xAB, 0xBC, 0x7D, 0x57, - 0x24, 0x7C, 0x03, 0x96, 0x88, 0x8D, 0xE8, 0x6C, 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, - 0x47, 0xE4, 0x5B, 0xAF, 0x06, 0x6D, 0x7C, 0x44, 0x6F, 0x3F, 0xEC, 0x6A, 0x6E, 0x3F, 0x36, 0x24, - 0xBD, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, - 0x54, 0x24, 0x14, 0x35, 0x71, 0xC0, 0xEF, 0xF6, 0x8D, 0x2D, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0xA0, - 0x37, 0x79, 0x7B, 0x2F, 0x1B, 0xAF, 0x8F, 0x8D, 0xF8, 0x62, 0xB1, 0xA1, 0x16, 0x0D, 0x10, 0xBB, - 0xEA, 0xB7, 0x5E, 0x85, 0x01, 0x62, 0xE3, 0x63, 0xF2, 0xF6, 0x63, 0x66, 0x1B, 0xB7, 0x1F, 0x22, - 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, - 0x26, 0x0E, 0xF7, 0xBD, 0xB0, 0x17, 0xAF, 0x31, 0xDE, 0x2F, 0x6E, 0xBF, 0x2B, 0xF8, 0x32, 0x06, - 0x00, 0x00, 0xE8, 0x1D, 0xAD, 0xDF, 0x80, 0x15, 0x0B, 0x0D, 0xB5, 0x58, 0x7C, 0x84, 0xB7, 0x1F, - 0x93, 0x0F, 0x9E, 0xDB, 0xF8, 0x88, 0xDF, 0x7E, 0x84, 0xF1, 0x11, 0x06, 0x48, 0xA2, 0xDB, 0x0F, - 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, - 0x51, 0x13, 0x07, 0xFB, 0x1E, 0x9A, 0x77, 0xFC, 0x8E, 0x0D, 0xC1, 0x97, 0x31, 0x00, 0x00, 0x40, - 0x6F, 0xF0, 0xDF, 0x80, 0xB5, 0x73, 0xB6, 0x8D, 0x08, 0x15, 0x1E, 0x6E, 0xB1, 0xD0, 0x50, 0x6B, - 0x10, 0x1F, 0xD5, 0x07, 0xCF, 0x37, 0xCE, 0xAC, 0xBF, 0xFD, 0x08, 0xE2, 0xA3, 0x7A, 0xFB, 0xF1, - 0xA0, 0xDD, 0xD7, 0x55, 0x70, 0x44, 0x27, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, - 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0x50, 0xDF, 0x4B, 0xF3, 0x8E, 0xDE, 0xCA, - 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x31, 0x23, 0xCB, 0xD7, 0x35, 0x7E, 0x05, 0x6F, 0x2C, 0x34, - 0x1A, 0x4D, 0x05, 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x41, 0x7C, 0xC8, 0x37, - 0x5F, 0x7D, 0xB7, 0xD5, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, - 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7D, 0xAF, 0xCD, 0x3B, 0xFA, 0xF9, 0xF1, - 0xE0, 0x4B, 0x19, 0x00, 0x00, 0xA0, 0x37, 0xD8, 0x00, 0x59, 0x5F, 0x1F, 0x1E, 0x29, 0xE2, 0xC3, - 0x2D, 0x1E, 0x1F, 0xD5, 0xDB, 0x8F, 0xC9, 0xF8, 0xA8, 0x79, 0xF3, 0x55, 0xEA, 0xDB, 0x0F, 0x11, - 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, - 0xD3, 0x87, 0xF9, 0x9E, 0x9C, 0x7B, 0x13, 0xD6, 0xD8, 0x17, 0x67, 0x05, 0x5F, 0xCE, 0x00, 0x00, - 0x00, 0xDD, 0xCF, 0x3B, 0x70, 0xD5, 0x50, 0xBB, 0xF1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0xD4, 0xDD, - 0x7E, 0x5C, 0x98, 0xE1, 0xF6, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, - 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBE, 0x97, 0x37, 0xB6, 0x9C, 0x37, 0x61, - 0x01, 0x00, 0x80, 0xDE, 0xE2, 0xED, 0xBD, 0x7C, 0x2C, 0x73, 0x7C, 0xB8, 0xC5, 0xE3, 0xC3, 0x0F, - 0x90, 0x19, 0x39, 0xDD, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, - 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xC0, 0xF7, 0xFA, 0x78, 0x13, 0x16, 0x00, 0x00, - 0xE8, 0x35, 0x66, 0x68, 0x81, 0x0D, 0x89, 0xEC, 0xF1, 0xE1, 0x7E, 0xAC, 0xBD, 0xFD, 0xB0, 0xF1, - 0x11, 0xFB, 0xF6, 0xAB, 0xA6, 0xB7, 0x1F, 0xF7, 0x35, 0xBA, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, - 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x78, 0x2F, - 0xC3, 0x9E, 0xBF, 0x9C, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, 0x61, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, - 0x2E, 0xB5, 0x11, 0x91, 0x21, 0x3E, 0xDC, 0xC2, 0xF0, 0x08, 0xE3, 0xE3, 0xE9, 0x19, 0x35, 0xB7, - 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xF1, 0x80, 0x1D, 0xF1, 0x91, 0xCF, 0x64, 0x38, 0xE4, 0x31, - 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x07, 0xF7, 0x12, 0xCD, 0x3B, 0xFE, 0x67, 0xBC, - 0x09, 0x0B, 0x00, 0x00, 0xF4, 0x06, 0xFF, 0x15, 0xBC, 0xFE, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, - 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, 0xF1, 0xD1, 0xE0, 0xD9, 0x0F, 0xF9, 0xA1, 0x83, 0xF7, - 0xAA, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, - 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x87, 0xF6, 0x32, 0xCD, 0x3B, 0xFA, 0xF9, 0x93, 0xC1, 0x97, 0x34, - 0x00, 0x00, 0x40, 0x77, 0xF3, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0xF5, 0x71, 0x91, 0x64, 0x61, 0x78, - 0x84, 0xF1, 0x11, 0xBB, 0xFD, 0xA8, 0x7B, 0xF6, 0xC3, 0x06, 0xC8, 0x29, 0x17, 0x20, 0x4D, 0x6F, - 0x3F, 0x44, 0x48, 0x64, 0x99, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, - 0x09, 0x45, 0x4D, 0x1F, 0xD8, 0x4B, 0xB7, 0x23, 0xAB, 0x4C, 0xF0, 0x25, 0x0D, 0x00, 0x00, 0xD0, - 0xDD, 0xBC, 0xE1, 0x65, 0x83, 0x32, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0x12, 0x20, 0x33, - 0xF4, 0xED, 0x47, 0x2C, 0x3E, 0x5A, 0xDF, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, - 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA8, 0x97, 0x75, 0x63, 0xCB, - 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0D, 0xDE, 0xDE, 0xCB, 0x46, 0xEB, 0xE2, 0x22, 0xC9, 0xAA, - 0xB7, 0x1F, 0x41, 0x7C, 0x24, 0xBD, 0xFD, 0x08, 0x03, 0xE4, 0x07, 0x76, 0xC4, 0x47, 0x7B, 0x93, - 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0xBA, 0x7F, - 0x5D, 0x68, 0xCC, 0x0B, 0x57, 0x1B, 0x73, 0xFC, 0x8E, 0x75, 0xC1, 0x97, 0x35, 0x00, 0x00, 0x40, - 0xF7, 0xF2, 0xF6, 0x2C, 0x18, 0x97, 0x81, 0xD1, 0x6C, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0x59, 0x6F, - 0x3F, 0xEE, 0x89, 0xDE, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, - 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2E, 0x3E, 0xDC, 0x7E, 0x6E, - 0xFF, 0x99, 0x38, 0x71, 0xDB, 0xFA, 0xE0, 0xCB, 0x1A, 0x00, 0x00, 0xA0, 0x3B, 0x99, 0xA1, 0xFE, - 0x59, 0x66, 0xF7, 0xDC, 0xFA, 0xC0, 0x68, 0xB5, 0xF0, 0xE6, 0x23, 0x97, 0xDB, 0x0F, 0x11, 0x12, - 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xF4, 0xB2, 0x2E, 0x8C, 0x8F, 0x60, 0xDE, 0x89, 0xDB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, - 0x6E, 0x66, 0x64, 0xE9, 0x80, 0xD9, 0xF1, 0x71, 0x1D, 0x19, 0xCD, 0x16, 0xC6, 0x47, 0xDB, 0xB7, - 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, - 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x5D, 0x2C, 0x3E, 0xFC, 0x00, 0x39, 0x7A, 0x33, 0x6F, 0xC2, - 0x02, 0x00, 0x00, 0xDD, 0xCD, 0x1B, 0x5E, 0x7E, 0x97, 0xD9, 0xFA, 0x21, 0x1D, 0x19, 0x8D, 0x16, - 0x8F, 0x8F, 0x66, 0xB7, 0x1F, 0x61, 0x7C, 0xC8, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, - 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, - 0xC4, 0x87, 0xBF, 0x23, 0x37, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xDD, 0xFC, 0x57, 0xF0, 0xAA, - 0xC8, 0x68, 0x34, 0x1B, 0x1D, 0x8D, 0x6E, 0x3F, 0xAA, 0x01, 0xD2, 0xEA, 0xF6, 0xE3, 0x1B, 0xC4, - 0x47, 0xA6, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, - 0x65, 0x9D, 0x0A, 0x8F, 0x70, 0x2F, 0xF5, 0xBB, 0x07, 0xD1, 0x97, 0x04, 0x5F, 0xDE, 0x00, 0x00, - 0x00, 0xDD, 0xC7, 0x3B, 0x70, 0x75, 0xF2, 0x37, 0x60, 0x45, 0xE3, 0xC3, 0x86, 0x47, 0xA3, 0xDB, - 0x8F, 0x09, 0x17, 0x20, 0x8F, 0x45, 0x6E, 0x3F, 0xC2, 0xF8, 0x70, 0xDB, 0xE0, 0xBE, 0xF5, 0x4A, - 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, - 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xD1, 0x11, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x3F, 0x5F, 0x1B, - 0x7C, 0x79, 0x03, 0x00, 0x00, 0x74, 0x1F, 0x6F, 0xDF, 0xE5, 0x27, 0x65, 0x6C, 0xC4, 0x17, 0xC4, - 0x47, 0xA3, 0xDB, 0x8F, 0xC4, 0xCF, 0x7E, 0x7C, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, - 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xC1, - 0x11, 0x1F, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xDD, 0x2E, 0xD1, 0x1B, 0xB0, 0xE2, 0xF1, 0x51, 0x73, - 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xED, 0xED, 0x47, 0x4E, 0xDF, 0x7A, 0x25, - 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, - 0xB2, 0x4E, 0xC5, 0x46, 0x83, 0x79, 0xC7, 0x6F, 0x1F, 0x0A, 0xBE, 0xBC, 0x01, 0x00, 0x00, 0xBA, - 0x8B, 0x39, 0x70, 0xFD, 0x12, 0xB3, 0xF3, 0x53, 0x3A, 0x3A, 0xC2, 0x45, 0xE2, 0xA3, 0x1A, 0x20, - 0x76, 0xD5, 0x6F, 0xBD, 0x0A, 0x03, 0xA4, 0xE6, 0xB5, 0xBB, 0x33, 0xC5, 0xED, 0xC7, 0xCC, 0x7C, - 0x6E, 0x3F, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, - 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0xC8, 0x68, 0x36, 0xEF, 0xC8, 0x9A, 0xB1, 0xE0, 0x4B, 0x1C, 0x00, - 0x00, 0xA0, 0xBB, 0x98, 0x83, 0xCB, 0xD6, 0x9A, 0xED, 0x1F, 0xD5, 0xE1, 0xE1, 0x16, 0x09, 0x8F, - 0x68, 0x7C, 0x84, 0xB7, 0x1F, 0x35, 0x0F, 0x9E, 0x37, 0x7A, 0xF6, 0xC3, 0x0F, 0x10, 0x1B, 0x1F, - 0xDF, 0xCD, 0xE1, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, - 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x08, 0x8C, 0x96, 0x3B, 0xBA, 0x86, 0x37, 0x61, 0x01, - 0x00, 0x80, 0xEE, 0xE4, 0xBF, 0x01, 0x6B, 0xF3, 0xAC, 0x4C, 0xF1, 0x51, 0x7D, 0xF0, 0x5C, 0xDD, - 0x7E, 0x04, 0xF1, 0x51, 0xB9, 0xFD, 0xB0, 0xF1, 0xF1, 0xA0, 0xDD, 0xD7, 0x45, 0x50, 0xA4, 0x99, - 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, - 0xCB, 0x3A, 0x15, 0x17, 0x49, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB7, 0xF2, 0x0E, 0x7C, 0x6E, - 0x28, 0x49, 0x7C, 0xD4, 0x05, 0x48, 0xFC, 0xB5, 0xBB, 0xEE, 0xF6, 0x23, 0x88, 0x8F, 0xDA, 0x37, - 0x5F, 0xD9, 0xF0, 0xC8, 0xE3, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x0A, 0x8B, 0xA4, 0x7B, 0xE1, 0x5A, 0x63, - 0x8E, 0xDD, 0x36, 0x10, 0x7C, 0x99, 0x03, 0x00, 0x00, 0x74, 0x0F, 0x6F, 0xEF, 0x65, 0xF5, 0xAF, - 0xE0, 0x8D, 0x44, 0x87, 0x8C, 0x8F, 0xE8, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0xAA, 0xDE, - 0x7E, 0x04, 0xF1, 0xD1, 0xEE, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, - 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x15, 0x69, 0xF6, 0xFC, 0x67, 0x79, - 0x13, 0x16, 0x00, 0x00, 0xE8, 0x4E, 0x66, 0x8F, 0x3D, 0xEC, 0xB4, 0x88, 0x0F, 0x37, 0x75, 0xFB, - 0x51, 0x7D, 0xED, 0x6E, 0xF5, 0xF6, 0xE3, 0xC2, 0xC8, 0xED, 0x47, 0x10, 0x1F, 0xED, 0xDE, 0x7E, - 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x62, 0x07, - 0xF4, 0x32, 0x4F, 0x05, 0x45, 0x86, 0x79, 0x27, 0x6E, 0x1B, 0x0C, 0xBE, 0xCC, 0x01, 0x00, 0x00, - 0xBA, 0x83, 0x19, 0xE9, 0x9F, 0x5D, 0xF3, 0x0A, 0xDE, 0x48, 0x70, 0x44, 0x97, 0xFE, 0xF6, 0x63, - 0xE6, 0x64, 0x80, 0x3C, 0x60, 0xA7, 0xC2, 0x22, 0xC9, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, - 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0x90, 0xC8, 0x3A, 0xEF, - 0xC8, 0xE7, 0x47, 0x83, 0x2F, 0x75, 0x00, 0x00, 0x80, 0xEE, 0x60, 0x46, 0x96, 0x0E, 0x54, 0xDF, - 0x80, 0x15, 0x09, 0x8E, 0xF8, 0xD4, 0xED, 0x47, 0xFD, 0xB3, 0x1F, 0xE1, 0xED, 0x47, 0x24, 0x3E, - 0xDC, 0xEE, 0xCD, 0x78, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, - 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x44, 0x44, 0x5B, 0xE3, 0x4D, 0x58, 0x00, 0x00, - 0xA0, 0xDB, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0xDE, 0x2F, 0xA3, 0x23, 0x5C, 0xB3, 0xDB, 0x8F, - 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0xC8, 0x7A, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, - 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x05, 0x44, 0xBB, 0x73, 0x6F, - 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x3B, 0x00, 0x00, 0x40, 0xE7, 0x79, 0x23, 0xCB, 0x36, - 0xA8, 0xE8, 0x88, 0x4E, 0xDD, 0x7E, 0xD4, 0x3F, 0xFB, 0xE1, 0x3E, 0x74, 0xD0, 0xBD, 0x7A, 0x37, - 0x12, 0x20, 0xEE, 0x43, 0x07, 0xB3, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, - 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xF1, 0x90, 0xC7, 0x5E, 0xBC, - 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, 0xEE, 0xE2, 0xED, 0xBD, 0x62, 0x54, 0x45, 0x47, 0xB8, 0x66, - 0xB7, 0x1F, 0xD5, 0x67, 0x3F, 0xFC, 0xD7, 0xEE, 0x06, 0xF1, 0xE1, 0xD6, 0xCE, 0xED, 0x87, 0x08, - 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, - 0x3A, 0x15, 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x2E, 0xDE, 0xDE, - 0xC5, 0xE3, 0x2A, 0x3C, 0xC2, 0x35, 0xBD, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC5, 0x87, 0xBA, 0xFD, - 0xB8, 0x27, 0xE5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, - 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x0D, 0x39, 0xCF, 0x3B, 0xB6, 0x96, 0x37, 0x61, - 0x01, 0x00, 0x80, 0xEE, 0xE1, 0xBF, 0x01, 0x2B, 0x12, 0x1C, 0xD1, 0xB5, 0xBC, 0xFD, 0xB0, 0xF1, - 0x31, 0xF1, 0xD8, 0x8C, 0xDA, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x60, 0xA7, 0x22, 0xA3, 0xD1, 0x44, - 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, - 0xD6, 0x89, 0x58, 0x28, 0x62, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0E, 0xFE, - 0x1B, 0xB0, 0x76, 0x7C, 0x52, 0xC6, 0x87, 0x5B, 0xCB, 0xDB, 0x8F, 0x30, 0x3E, 0xDA, 0xBD, 0xFD, - 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, - 0x7A, 0x59, 0x27, 0x42, 0xA1, 0xA8, 0x79, 0x47, 0x6F, 0x1E, 0x0F, 0xBE, 0xE4, 0x01, 0x00, 0x00, - 0x3A, 0xCB, 0x8C, 0x2C, 0x5F, 0x67, 0xB6, 0x7D, 0xA4, 0x75, 0x7C, 0xC8, 0xDB, 0x8F, 0x19, 0xF9, - 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, - 0xC4, 0x21, 0xBD, 0xAC, 0x13, 0x91, 0x50, 0xE8, 0xDC, 0x9B, 0xB0, 0xC6, 0xBE, 0x38, 0x2B, 0xF8, - 0xB2, 0x07, 0x00, 0x00, 0xE8, 0x1C, 0x1B, 0x20, 0xEB, 0x55, 0x7C, 0xB8, 0xA9, 0xDB, 0x0F, 0x3F, - 0x40, 0x44, 0x7C, 0x64, 0xBE, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, - 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA1, 0xE8, 0xF1, 0x26, 0x2C, 0x00, - 0x00, 0xD0, 0x2D, 0xBC, 0x03, 0x57, 0x0D, 0x35, 0x8C, 0x0F, 0x1B, 0x1E, 0xF2, 0xF6, 0xE3, 0x09, - 0x1B, 0x1F, 0x2E, 0x40, 0x1E, 0x8D, 0xDC, 0x7E, 0x84, 0xF1, 0xE1, 0xB6, 0x81, 0xF8, 0xA8, 0x9B, - 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xA9, - 0x38, 0x98, 0x8A, 0xBD, 0x70, 0xB5, 0xF1, 0x7E, 0x71, 0xFB, 0x5D, 0xC1, 0x97, 0x3D, 0x00, 0x00, - 0x40, 0xE7, 0x78, 0x7B, 0x2F, 0x1B, 0x6B, 0x18, 0x20, 0x6E, 0x91, 0xDB, 0x0F, 0x17, 0x1F, 0x67, - 0x07, 0x67, 0xD4, 0xDE, 0x7E, 0xA8, 0x67, 0x3F, 0xBE, 0x21, 0x62, 0x23, 0x3E, 0x11, 0x1E, 0x6E, - 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2A, - 0x0C, 0xA6, 0x70, 0xDE, 0xF1, 0xDB, 0x36, 0x04, 0x5F, 0xF6, 0x00, 0x00, 0x00, 0x9D, 0x63, 0x86, - 0xE6, 0xEB, 0xF8, 0xA8, 0xB9, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC6, 0x47, 0x1E, 0xB7, 0x1F, 0x22, - 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, - 0xEB, 0x44, 0x10, 0x4C, 0xF5, 0xBC, 0xE3, 0x7F, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x67, 0x99, - 0x91, 0xFE, 0xD9, 0x66, 0xE7, 0x25, 0x3A, 0x40, 0xEC, 0xA2, 0xDF, 0x7A, 0x75, 0xEE, 0xC9, 0x19, - 0xE6, 0xAC, 0x8D, 0x8F, 0xC9, 0xDB, 0x8F, 0x19, 0xFA, 0xD9, 0x8F, 0x56, 0xB7, 0x1F, 0x22, 0x3C, - 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, - 0x44, 0x0C, 0x74, 0x62, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x74, 0x9C, 0xFF, 0x0A, 0xDE, 0xD8, 0x1B, - 0xB0, 0x6A, 0xBE, 0xF5, 0xCA, 0xEE, 0x9C, 0x0B, 0x10, 0x17, 0x1F, 0xF1, 0xDB, 0x8F, 0x68, 0x7C, - 0x84, 0x01, 0x72, 0x7F, 0x8B, 0xDB, 0x0F, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, - 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x22, 0x04, 0x3A, 0xB6, 0x97, 0x56, 0x99, - 0xE0, 0x4B, 0x1F, 0x00, 0x00, 0xA0, 0x33, 0xFC, 0x37, 0x60, 0x6D, 0xFE, 0xE3, 0x86, 0xF1, 0x51, - 0xB9, 0xFD, 0xB0, 0xF1, 0xD1, 0xE0, 0xF6, 0xC3, 0xC5, 0x47, 0xF5, 0xF6, 0xE3, 0x41, 0xBB, 0xAF, - 0x8B, 0xE8, 0x08, 0x27, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, - 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x45, 0x40, 0x27, 0x37, 0xB6, 0x8C, 0x37, 0x61, 0x01, 0x00, - 0x80, 0xCE, 0xF2, 0x86, 0x97, 0x0D, 0x36, 0xBC, 0xFD, 0x08, 0xE2, 0xA3, 0xE6, 0xF6, 0x23, 0x88, - 0x8F, 0x9A, 0xDB, 0x8F, 0xF0, 0xD9, 0x8F, 0xEF, 0x36, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, - 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA0, - 0xD3, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0xF2, 0x07, 0x00, 0x00, 0x98, 0x7A, - 0xDE, 0xDE, 0xCB, 0x46, 0x1B, 0xDE, 0x7E, 0x6C, 0xBC, 0xA0, 0x26, 0x3E, 0xEA, 0x3E, 0x74, 0x30, - 0xE9, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, - 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x75, 0xF8, 0xEF, 0xF8, 0x16, 0xD8, 0x5F, 0x9B, 0xFD, 0xDF, 0xE1, - 0xC4, 0x6D, 0xEB, 0x83, 0x2F, 0x7F, 0x00, 0x00, 0x80, 0xA9, 0xE7, 0xED, 0x9E, 0x3F, 0xAE, 0x6F, - 0x3F, 0x6C, 0x7C, 0x84, 0xDF, 0x7A, 0x55, 0x73, 0xFB, 0x31, 0x33, 0xDD, 0xED, 0x87, 0x08, 0x0F, - 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0xB1, 0x78, 0x20, 0x14, 0x39, 0x71, 0x48, 0x2F, 0xEB, - 0xE4, 0xE1, 0xBF, 0xD3, 0xB3, 0xF1, 0x11, 0xCC, 0x3B, 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x80, - 0xCE, 0x30, 0x43, 0xFD, 0xB3, 0xCC, 0xEE, 0xB9, 0x32, 0x3E, 0x72, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, - 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, - 0x0F, 0xFF, 0x9D, 0xDE, 0x64, 0x7C, 0xF8, 0x01, 0x72, 0xF4, 0xE6, 0x93, 0xC1, 0x1F, 0x01, 0x00, - 0x00, 0x00, 0x53, 0xCB, 0x7F, 0x03, 0xD6, 0xF6, 0x8B, 0x6B, 0x03, 0x24, 0x8C, 0x0F, 0xF9, 0xEC, - 0x47, 0x83, 0xDB, 0x8F, 0x7B, 0xC5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, - 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x6A, 0xE3, - 0xC3, 0xDF, 0x91, 0x1B, 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0C, 0x33, 0xB2, 0x7C, 0x9D, 0xD9, - 0xFA, 0xC1, 0xC8, 0xED, 0x87, 0x8D, 0x8F, 0xD8, 0xED, 0x47, 0xED, 0x9B, 0xAF, 0x44, 0x7C, 0x3C, - 0x60, 0x47, 0x7C, 0x14, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, - 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x11, 0x1F, 0x6E, 0x2F, 0xF5, 0xF3, 0x26, 0x2C, 0x00, 0x00, 0xD0, - 0x19, 0xE6, 0xE0, 0xF2, 0xF5, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xEC, 0xC7, - 0xE9, 0x78, 0x80, 0xB8, 0x0F, 0x1D, 0x8C, 0xDF, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, - 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, - 0x84, 0x47, 0x38, 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x00, 0x00, 0x00, 0x60, - 0xEA, 0x78, 0xFB, 0xAE, 0x1E, 0xAD, 0x89, 0x8F, 0x24, 0xCF, 0x7E, 0xB8, 0x35, 0xBA, 0xFD, 0x10, - 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, - 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x88, 0x8E, 0xE8, 0xDC, 0x3F, 0x67, 0xBC, 0x09, 0x0B, 0x00, - 0x00, 0x74, 0x82, 0xB7, 0xF7, 0xF2, 0x93, 0x7E, 0x7C, 0x34, 0xBA, 0xFD, 0x88, 0xC6, 0x87, 0xBA, - 0xFD, 0xF8, 0x76, 0xE4, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, - 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x38, 0xC4, 0xBC, - 0xE3, 0xB7, 0x0F, 0x05, 0x7F, 0x0C, 0x00, 0x00, 0x00, 0x4C, 0x1D, 0x6F, 0xE7, 0x9C, 0xF4, 0xB7, - 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x8E, 0xF8, 0xC8, 0x71, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, - 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x36, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, - 0x82, 0x3F, 0x06, 0x00, 0x00, 0x00, 0xA6, 0x86, 0x39, 0x70, 0xFD, 0x12, 0x6F, 0xFB, 0x27, 0xB2, - 0xDF, 0x7E, 0xDC, 0x13, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, - 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x87, 0x46, 0xC3, - 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xD5, 0xCC, 0xC1, 0x65, 0x6B, 0xBD, 0xAD, 0x1F, 0x6E, 0xEF, - 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, - 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x30, 0x5A, 0xCD, 0xBD, 0x09, 0xEB, 0xF8, - 0x1D, 0x4B, 0x82, 0x3F, 0x0E, 0x00, 0x00, 0x00, 0x8A, 0x77, 0xFE, 0xE0, 0xD2, 0xF5, 0xDE, 0xA6, - 0x0B, 0x33, 0xDE, 0x7E, 0x10, 0x1F, 0xF9, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, - 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC4, 0x45, 0x92, 0xBD, 0x70, 0x0D, 0x6F, 0xC2, - 0x02, 0x00, 0x00, 0x53, 0xEB, 0xFC, 0xFE, 0x6B, 0x06, 0xB3, 0xDD, 0x7E, 0xCC, 0x90, 0xE1, 0xE1, - 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, - 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x8B, 0xA4, 0x7B, 0xFE, 0x0A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xA6, - 0xD6, 0xF9, 0xDD, 0x8B, 0x47, 0xA3, 0xB7, 0x1F, 0xD5, 0x00, 0x89, 0xC5, 0x47, 0xDD, 0xED, 0xC7, - 0xDD, 0xC4, 0x47, 0xFB, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, - 0xE4, 0xE1, 0xBF, 0xD3, 0x13, 0x51, 0x91, 0x72, 0xDE, 0xB1, 0xB5, 0xBC, 0x09, 0x0B, 0x00, 0x00, - 0x4C, 0x1D, 0x6F, 0xF7, 0x42, 0x79, 0xFB, 0x31, 0xE1, 0x02, 0xE4, 0xD1, 0xC8, 0xED, 0x47, 0x18, - 0x1F, 0x6E, 0xF7, 0xEB, 0x6F, 0xBD, 0x22, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, - 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x07, 0x45, 0xDA, 0x79, 0x47, 0x3E, - 0x3F, 0x1A, 0xFC, 0x71, 0x00, 0x00, 0x00, 0x50, 0x2C, 0x33, 0xD2, 0x3F, 0xDB, 0xDB, 0x31, 0x27, - 0xDD, 0xB3, 0x1F, 0x0F, 0xCE, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, - 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x98, 0xC8, 0xB4, 0xA3, - 0x6B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x1A, 0x66, 0xFF, 0xD2, 0x81, 0xF3, 0x5B, 0x3E, 0x6C, - 0x03, 0x24, 0xF2, 0xAD, 0x57, 0xCD, 0x6E, 0x3F, 0x1E, 0xB2, 0xF1, 0x21, 0x6E, 0x3F, 0x88, 0x8F, - 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, - 0xD3, 0x13, 0x11, 0xD1, 0xCE, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0x73, 0x76, 0xF0, 0xC7, 0x02, 0x00, - 0x00, 0x40, 0x71, 0xCE, 0xED, 0x5F, 0x7A, 0xD7, 0xF9, 0x4D, 0xEF, 0x9B, 0x7C, 0xF6, 0xA3, 0xE6, - 0xC1, 0xF3, 0x19, 0xB5, 0xCF, 0x7E, 0xB8, 0xF8, 0x78, 0xA0, 0xFE, 0xF6, 0x83, 0xF8, 0x48, 0x33, - 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, - 0x11, 0x10, 0xED, 0xCE, 0xBD, 0x09, 0xEB, 0xD8, 0x6D, 0x03, 0xC1, 0x1F, 0x0B, 0x00, 0x00, 0x00, - 0xC5, 0x39, 0x7F, 0x60, 0xD9, 0x86, 0x9A, 0x07, 0xCF, 0xA3, 0xB7, 0x1F, 0xD1, 0xF8, 0x78, 0xD8, - 0x86, 0x87, 0x0B, 0x90, 0xEF, 0xD4, 0xDE, 0x7E, 0x10, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x21, 0x8F, 0xF1, - 0x26, 0x2C, 0x00, 0x00, 0x30, 0x55, 0xCE, 0xEF, 0x5E, 0x32, 0xEA, 0xC7, 0x47, 0x83, 0xDB, 0x0F, - 0x17, 0x1F, 0xA7, 0xC2, 0xF8, 0x70, 0xB7, 0x1F, 0x7F, 0x4D, 0x7C, 0x64, 0x9B, 0x0A, 0x87, 0x3C, - 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x87, 0x1C, - 0xE7, 0x9D, 0xB8, 0x6D, 0x30, 0xF8, 0x63, 0x01, 0x00, 0x00, 0xA0, 0x38, 0xE7, 0x76, 0x2E, 0x3A, - 0x59, 0x73, 0xFB, 0x11, 0xC4, 0x47, 0xF5, 0xD9, 0x8F, 0x30, 0x3E, 0x62, 0xB7, 0x1F, 0xC4, 0x47, - 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, - 0xE9, 0xE9, 0x68, 0xC8, 0x73, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0xDE, 0xF9, - 0xED, 0x73, 0xAA, 0xF1, 0x51, 0xF7, 0xA1, 0x83, 0x8F, 0xCC, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, - 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, - 0xE9, 0x60, 0xC8, 0x7D, 0x47, 0x3F, 0xCF, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB1, 0xCE, 0xEE, 0x5F, - 0x3A, 0x70, 0x6E, 0xCB, 0x27, 0x63, 0xB7, 0x1F, 0x33, 0x2B, 0xCF, 0x7E, 0x44, 0xE3, 0xC3, 0xED, - 0xDE, 0xCA, 0xED, 0x07, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, - 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x14, 0x8A, 0x9A, 0x7B, 0x13, 0xD6, 0xD8, 0x17, - 0x67, 0x05, 0x7F, 0x3C, 0x00, 0x00, 0x00, 0xE4, 0xEF, 0xDC, 0xDE, 0xE5, 0xEB, 0xCE, 0x6D, 0xFA, - 0x48, 0xEC, 0xF6, 0x63, 0x46, 0x35, 0x3E, 0xAA, 0x01, 0xF2, 0x23, 0x3B, 0xE2, 0x23, 0xE5, 0x54, - 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x44, - 0x24, 0x14, 0xB9, 0x17, 0xAF, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x58, 0xE7, 0xF7, 0x2E, 0x5F, - 0x5F, 0xF7, 0xEC, 0xC7, 0x8F, 0x27, 0x03, 0xA4, 0x7A, 0xFB, 0xF1, 0xED, 0x0B, 0x88, 0x8F, 0x54, - 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, - 0x13, 0x81, 0x50, 0xF4, 0x5E, 0xB8, 0xCA, 0x78, 0xBF, 0xB8, 0xFD, 0xAE, 0xE0, 0x8F, 0x07, 0x00, - 0x00, 0x80, 0xFC, 0x9D, 0xDB, 0x7D, 0xD5, 0x50, 0xCD, 0x9B, 0xAF, 0xC2, 0xF8, 0x88, 0x06, 0xC8, - 0x8F, 0x66, 0x10, 0x1F, 0xA9, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, - 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x60, 0x8A, 0xE6, 0x1D, 0xBF, 0x6D, 0x43, 0xF0, 0xC7, - 0x03, 0x00, 0x00, 0x40, 0xFE, 0xCE, 0xED, 0xB8, 0x6C, 0x6C, 0xF2, 0xF6, 0xE3, 0x02, 0x79, 0xFB, - 0xF1, 0x76, 0xE4, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x06, 0x53, 0x35, 0xDE, 0x84, 0x05, 0x00, - 0x00, 0x0A, 0x75, 0x76, 0xDB, 0xFC, 0xE0, 0xF6, 0xC3, 0xC6, 0x87, 0x78, 0xF6, 0xE3, 0xED, 0x1F, - 0x4C, 0xDE, 0x7E, 0x10, 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, - 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0xA3, 0x60, 0x2A, 0xE7, 0x1D, 0xBD, 0x79, 0x3C, 0xF8, - 0xE3, 0x01, 0x00, 0x00, 0x20, 0x5F, 0x66, 0xA8, 0x7F, 0xF6, 0xD9, 0xCD, 0x97, 0x04, 0xF1, 0x51, - 0x7B, 0xFB, 0x71, 0x2A, 0xBC, 0xFD, 0xF8, 0x66, 0xE5, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, - 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x04, - 0x53, 0xBE, 0x97, 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x8C, 0xB3, 0x43, 0x4B, 0x07, 0xDE, - 0xDD, 0xF8, 0xE1, 0x6A, 0x80, 0x9C, 0xB6, 0x01, 0x52, 0xF3, 0xEC, 0xC7, 0xF7, 0x2B, 0xB7, 0x1F, - 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, - 0xF0, 0xDF, 0xE9, 0x89, 0x10, 0xE8, 0xD4, 0xC6, 0x96, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x0C, - 0x1B, 0x20, 0xEB, 0x27, 0x06, 0xDF, 0x57, 0x73, 0xFB, 0x11, 0x7D, 0xFE, 0xC3, 0xDD, 0x7E, 0x10, - 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, - 0x7F, 0xA7, 0x27, 0x22, 0xA0, 0x93, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0x63, - 0x02, 0x00, 0x00, 0x20, 0x3F, 0xEF, 0xEE, 0x59, 0x3A, 0xE8, 0xDF, 0x7E, 0x88, 0xF8, 0x70, 0xB7, - 0x1F, 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, - 0xF2, 0xF0, 0xDF, 0xE9, 0x89, 0x00, 0xE8, 0xF4, 0xDC, 0x3F, 0x17, 0x27, 0x6E, 0x5B, 0x1F, 0xFC, - 0x31, 0x01, 0x00, 0x00, 0x90, 0x9F, 0x89, 0x6D, 0x8B, 0x47, 0xEB, 0xDE, 0x7C, 0x15, 0xDE, 0x7E, - 0xDC, 0x4D, 0x7C, 0x34, 0x9F, 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xE9, 0x65, - 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xE2, 0xF0, 0xDF, 0x25, 0xF3, 0x8E, 0xAF, 0xE5, 0x4D, 0x58, 0x00, - 0x00, 0x20, 0x7F, 0x13, 0x5B, 0xFA, 0xC6, 0xE5, 0xC3, 0xE7, 0xF7, 0xBB, 0x6F, 0xBD, 0x22, 0x3E, - 0x1A, 0x4F, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, - 0x4E, 0x4F, 0x1F, 0xFC, 0xBB, 0x65, 0xDE, 0xD1, 0x9B, 0x4F, 0x06, 0x7F, 0x4C, 0x00, 0x00, 0x00, - 0xE4, 0xC3, 0x0C, 0xF5, 0xCF, 0x7A, 0xF7, 0x99, 0x39, 0x95, 0xF8, 0xB0, 0x8B, 0x3E, 0x7C, 0xFE, - 0xD6, 0x5F, 0x11, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, - 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFD, 0x5D, 0xB5, 0x97, 0x56, 0x9A, 0xE0, 0x8F, 0x0A, - 0x00, 0x00, 0x80, 0x7C, 0xB8, 0x37, 0x60, 0x4D, 0x6C, 0xFC, 0x98, 0x0D, 0x90, 0x0B, 0xCC, 0xE9, - 0x47, 0xEC, 0xDC, 0xED, 0x87, 0x0B, 0x90, 0xFB, 0x6D, 0x80, 0x10, 0x1F, 0x0D, 0xA6, 0xC2, 0x21, - 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xFB, - 0xDD, 0x38, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x7C, 0xDD, 0xC4, 0x13, 0x1F, - 0x30, 0xA7, 0xFD, 0x00, 0x09, 0xBE, 0xFD, 0xEA, 0xE1, 0x99, 0xFE, 0xED, 0x07, 0xF1, 0xA1, 0xA6, - 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, - 0x0E, 0xFA, 0xDD, 0x3A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x74, 0x7D, 0x78, - 0xFB, 0x71, 0xCA, 0xCD, 0xDD, 0x7E, 0x7C, 0x67, 0x06, 0xF1, 0x21, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF9, 0xDD, 0x3C, - 0xF7, 0xCF, 0x3D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x79, 0x9A, 0xD8, 0x79, 0xD5, 0x68, 0xF5, 0xDB, - 0xAF, 0xDC, 0x0D, 0x88, 0x7B, 0xF6, 0xE3, 0x6B, 0xC4, 0x47, 0xFD, 0x54, 0x38, 0xE4, 0x31, 0x15, - 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, 0x01, 0xBF, 0x07, 0xC6, - 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xAE, 0x26, 0xB6, 0x5D, 0x76, 0xB2, 0x7A, 0x03, 0xF2, 0xF0, 0x0C, - 0xF3, 0xF6, 0x7D, 0xC1, 0xED, 0x87, 0x8D, 0x8F, 0x3F, 0x10, 0x1F, 0xC1, 0x54, 0x38, 0xE4, 0x31, - 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0xE1, 0xBE, 0x17, - 0xE6, 0x1D, 0x59, 0x33, 0x16, 0xFC, 0x71, 0x01, 0x00, 0x00, 0xD0, 0xBE, 0x09, 0xFF, 0x0D, 0x58, - 0x93, 0xB7, 0x1F, 0x6F, 0x7E, 0x6D, 0xF2, 0xE6, 0xE3, 0x0D, 0xE2, 0xC3, 0x4E, 0x85, 0x43, 0x1E, - 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xEC, 0x7B, - 0x66, 0x47, 0x6E, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x20, 0x1F, 0x13, 0x43, 0xD7, 0x2F, 0x99, 0x78, - 0xFA, 0x13, 0xE6, 0xCC, 0xA3, 0x95, 0xCF, 0xFF, 0x70, 0xB7, 0x1F, 0x95, 0xF8, 0xB8, 0xC0, 0xBF, - 0xF9, 0x78, 0x83, 0xF8, 0x28, 0x68, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, - 0xDF, 0xE9, 0x89, 0x03, 0x7D, 0xAF, 0xED, 0xA5, 0x7E, 0xF7, 0x20, 0xFA, 0x92, 0xE0, 0x8F, 0x0D, - 0x00, 0x00, 0x80, 0xEC, 0xCE, 0x0C, 0x2D, 0x5B, 0x3B, 0xF1, 0xE4, 0x87, 0x2B, 0x9F, 0x01, 0xF2, - 0x60, 0xE5, 0xB5, 0xBB, 0xD5, 0xDB, 0x8F, 0xAF, 0xD9, 0xF8, 0xF8, 0x47, 0xE2, 0x23, 0xFF, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF3, 0xBD, 0x38, - 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x03, 0x00, 0x00, 0x20, 0x3B, 0xF7, 0x06, - 0xAC, 0x89, 0xC7, 0x2F, 0xF2, 0x03, 0xE4, 0xED, 0x6F, 0x55, 0x9E, 0xFB, 0x20, 0x3E, 0xDC, 0x54, - 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, - 0x41, 0xBE, 0x57, 0xE7, 0xBE, 0x26, 0x78, 0x13, 0x16, 0x00, 0x00, 0xC8, 0xC3, 0xD9, 0x5D, 0xD7, - 0x0C, 0x4E, 0x3C, 0x36, 0xC3, 0x9C, 0x71, 0xCF, 0x7E, 0x04, 0x6F, 0xBD, 0xFA, 0xC3, 0x7A, 0xE2, - 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, - 0xF1, 0x3D, 0xBB, 0xF9, 0xFE, 0xBC, 0xE3, 0xB7, 0x0D, 0x05, 0x7F, 0x6C, 0x00, 0x00, 0x00, 0x64, - 0xF7, 0xEE, 0xB6, 0xC5, 0xA3, 0x13, 0x8F, 0xCF, 0x30, 0xEF, 0x7C, 0xBB, 0x72, 0xFB, 0xF1, 0xE6, - 0x5F, 0x5D, 0x44, 0x7C, 0x14, 0x32, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, - 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x57, 0x89, 0x0F, 0x3F, 0x40, 0x8E, 0xDC, 0xCC, 0x9B, 0xB0, - 0x00, 0x00, 0x40, 0xFB, 0xCE, 0x6D, 0x5F, 0x60, 0x26, 0x1E, 0xB9, 0xC0, 0xBC, 0xE5, 0x5E, 0xBB, - 0xFB, 0xD7, 0xC4, 0x47, 0x31, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, - 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0xE1, 0xEF, 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, - 0x00, 0xB4, 0xC7, 0x0C, 0x5D, 0x3B, 0xFB, 0xDC, 0xB6, 0x4B, 0xCD, 0x3B, 0xDF, 0xB4, 0x01, 0xF2, - 0x75, 0xE2, 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, - 0xA7, 0x0E, 0xF1, 0xBD, 0xBA, 0x58, 0x7C, 0xB8, 0xBD, 0xB4, 0xC2, 0x98, 0x97, 0xBF, 0x38, 0x3B, - 0xF8, 0xE3, 0x03, 0x00, 0x00, 0x20, 0xBD, 0xB3, 0xFB, 0x97, 0x0E, 0xBC, 0xFB, 0xD8, 0x87, 0xCC, - 0xDB, 0x77, 0x5F, 0x64, 0xCE, 0x13, 0x1F, 0x05, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, - 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x89, 0xF8, 0x70, 0x7B, 0xE1, 0x6A, 0x63, - 0x8E, 0xDD, 0x36, 0x10, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDE, 0x99, 0x5D, 0x9F, 0xBB, 0xEB, - 0xD4, 0x86, 0x0F, 0x98, 0xF3, 0xFF, 0x44, 0x7C, 0xE4, 0x3F, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, - 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x27, 0xC2, 0x23, 0x98, 0xF7, 0xAF, - 0x4B, 0xCC, 0xE9, 0x9F, 0xDD, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x76, 0xAF, 0x3D, 0x70, 0xED, - 0x86, 0xF1, 0xDD, 0xAB, 0xCD, 0xD9, 0x17, 0xBF, 0x44, 0x7C, 0xE4, 0x3A, 0x15, 0x09, 0x45, 0x4D, - 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0xA7, 0xC3, 0xC3, 0xED, - 0xD4, 0xB3, 0xF3, 0xCC, 0xEF, 0x77, 0xCC, 0x31, 0xBF, 0xDB, 0x77, 0xD3, 0x60, 0xF0, 0xC7, 0x07, - 0x00, 0x00, 0x40, 0x7A, 0xAF, 0xEF, 0xB9, 0x75, 0xF8, 0xF7, 0x07, 0x6F, 0x35, 0xBF, 0xDF, 0xB7, - 0xD2, 0xBC, 0x79, 0xE0, 0x32, 0x73, 0xFE, 0x9F, 0x55, 0x54, 0x24, 0x9D, 0x08, 0x87, 0x3C, 0x26, - 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, - 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0x4E, 0x87, 0xC7, 0x99, 0xBF, 0xEB, 0x33, 0xE3, 0xBB, - 0xE6, 0x9A, 0xDF, 0x6D, 0xB3, 0xF1, 0xE1, 0xB6, 0x67, 0x39, 0xAF, 0xE2, 0x05, 0x00, 0x00, 0xD9, - 0xFD, 0xF3, 0xFF, 0xFE, 0x17, 0x17, 0xFE, 0x76, 0xFB, 0xEA, 0xFB, 0x7E, 0xB7, 0x6D, 0xF1, 0x5B, - 0xBF, 0xDF, 0xB9, 0xD8, 0xB8, 0xBD, 0x7D, 0xE8, 0x72, 0xFF, 0x5B, 0x2D, 0x74, 0x64, 0x34, 0x9A, - 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, - 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0xAE, 0x3E, 0x3C, 0xCE, 0xFE, - 0x43, 0x9F, 0x79, 0x73, 0xEF, 0x64, 0x78, 0xBC, 0xBE, 0x75, 0xCE, 0xF8, 0xEF, 0xB6, 0x5D, 0xBA, - 0x7E, 0xB4, 0xFF, 0x3D, 0x7F, 0x14, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDD, 0x7F, 0xBF, 0xFB, - 0x33, 0x17, 0xBF, 0xB6, 0x79, 0xF1, 0x96, 0x30, 0x42, 0xC6, 0x77, 0x2F, 0x36, 0xA7, 0xFF, 0xC6, - 0x1E, 0xD4, 0x65, 0x6C, 0xC4, 0x27, 0xC2, 0x21, 0x8F, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, 0xDF, - 0xAB, 0xAB, 0x0D, 0x8F, 0xF3, 0xFF, 0x34, 0xDF, 0xBC, 0xB5, 0x3F, 0x72, 0xE3, 0x61, 0xF7, 0xEA, - 0x33, 0x73, 0x7E, 0x34, 0x3E, 0xF4, 0xA9, 0x59, 0xC1, 0x1F, 0x17, 0x00, 0x00, 0x00, 0xF9, 0xF9, - 0xEF, 0xDF, 0x5D, 0xF2, 0x99, 0xD7, 0xB6, 0x2C, 0xFA, 0x59, 0x18, 0x22, 0x6F, 0xEC, 0xB9, 0xCC, - 0x4C, 0xFC, 0xBD, 0x0B, 0x02, 0x15, 0x1E, 0x6E, 0xB1, 0x68, 0xC8, 0x6B, 0x32, 0x1C, 0xF2, 0x98, - 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, - 0x3A, 0xC4, 0xF7, 0xEA, 0x26, 0xC3, 0xC3, 0xFB, 0xE7, 0xF9, 0xE6, 0x9D, 0x91, 0x79, 0x35, 0xE1, - 0xF1, 0xDA, 0xE6, 0x4B, 0xF7, 0x8F, 0x6F, 0xE9, 0xE3, 0xB5, 0xBB, 0x00, 0x00, 0xA0, 0x78, 0xFF, - 0xEB, 0xA1, 0xCB, 0xBE, 0xF8, 0xBB, 0x6D, 0x8B, 0x7E, 0x19, 0x86, 0x88, 0x7B, 0x3E, 0xE4, 0xEC, - 0x4F, 0x5D, 0x1C, 0x10, 0x1F, 0xF5, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, - 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0x51, 0x7D, 0xC0, 0x3C, 0x08, 0x8F, 0xD7, - 0xB7, 0x5E, 0x3A, 0xF6, 0xDA, 0x96, 0x4B, 0x79, 0xDD, 0x2E, 0x00, 0x00, 0x98, 0x5A, 0xA3, 0xFD, - 0xFD, 0x7F, 0xF4, 0xAB, 0x27, 0x2E, 0xFB, 0x3F, 0xA2, 0xCF, 0x87, 0xBC, 0x35, 0xEC, 0x1E, 0x54, - 0x17, 0xD1, 0x90, 0xD7, 0x64, 0x38, 0xE4, 0x31, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x55, 0xC2, 0x23, 0xFE, - 0x80, 0xB9, 0x8D, 0x8E, 0x5F, 0xBE, 0xBE, 0x7D, 0xEE, 0xBA, 0xE0, 0x8F, 0x00, 0x00, 0x00, 0x80, - 0xCE, 0xF8, 0xD5, 0x23, 0x57, 0x7E, 0xE0, 0x37, 0x4F, 0x2E, 0xDE, 0x30, 0x19, 0x22, 0x8B, 0xCC, - 0xE9, 0xBF, 0xB9, 0xCC, 0x78, 0xFF, 0x2A, 0x02, 0xA2, 0x9D, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, - 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, - 0xDF, 0xAB, 0x6B, 0xFC, 0x80, 0x39, 0xCF, 0x79, 0x00, 0x00, 0x80, 0xAE, 0x72, 0xF2, 0x91, 0xC5, - 0xF3, 0x5F, 0x7D, 0x66, 0xF1, 0x0E, 0x17, 0x20, 0x6E, 0xE3, 0xBB, 0x17, 0x99, 0x33, 0x7F, 0x67, - 0x0F, 0xE2, 0x2A, 0x26, 0xD2, 0x4E, 0x86, 0x43, 0x1E, 0x8B, 0x47, 0x43, 0x5E, 0x53, 0x91, 0x50, - 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x73, 0xEA, 0x01, - 0xF3, 0xDF, 0x6D, 0xBD, 0x74, 0xF0, 0xBF, 0x7D, 0x67, 0xDE, 0x07, 0x82, 0x2F, 0x73, 0x00, 0x00, - 0x80, 0xEE, 0xF3, 0xAB, 0x8D, 0x8B, 0xD6, 0xBC, 0xFA, 0xCC, 0xC2, 0x9F, 0x87, 0x21, 0xF2, 0xC6, - 0x9E, 0xC5, 0xE6, 0xDD, 0x7F, 0xB0, 0x87, 0x7D, 0x15, 0x16, 0x49, 0x26, 0xC3, 0x21, 0x8F, 0xA9, - 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, - 0x83, 0x7C, 0xAF, 0xCD, 0xFB, 0xE7, 0x05, 0x75, 0x0F, 0x98, 0xDB, 0x8D, 0xFE, 0x7F, 0x8F, 0x5E, - 0x3A, 0x27, 0xF8, 0xB2, 0x06, 0x00, 0x00, 0xE8, 0x6E, 0xFE, 0xF3, 0x21, 0x83, 0x8B, 0xFF, 0xE2, - 0x77, 0xDB, 0x16, 0xFE, 0x32, 0x0C, 0x91, 0x37, 0x0F, 0x2C, 0x36, 0x67, 0x7F, 0x6A, 0x0F, 0xFE, - 0x2A, 0x32, 0x1A, 0x4D, 0x86, 0x43, 0x1E, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, - 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x87, 0xF9, 0x5E, 0xDB, 0xE9, 0xBF, 0xE9, 0xAB, - 0x79, 0xC0, 0xFC, 0xB5, 0x67, 0xE6, 0x1C, 0xE3, 0x01, 0x73, 0x00, 0x00, 0xD0, 0xB3, 0x6C, 0x88, - 0xFC, 0xBB, 0x57, 0x37, 0x2F, 0xBA, 0xE7, 0x77, 0xDB, 0x16, 0xBD, 0x15, 0x86, 0xC8, 0xDB, 0x87, - 0x12, 0x3E, 0xA8, 0x2E, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, - 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xC3, 0x7C, 0x2F, 0x6D, 0xE2, 0xEF, 0xE7, 0xF3, - 0x80, 0x39, 0x00, 0x00, 0x28, 0xAF, 0x93, 0xF7, 0x2E, 0xFC, 0xC8, 0x2B, 0x9B, 0x16, 0x3F, 0x1A, - 0x46, 0x88, 0x7B, 0x3E, 0xA4, 0xE9, 0x83, 0xEA, 0x32, 0x1C, 0xF2, 0x98, 0x0A, 0x87, 0x3C, 0xA6, - 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x3E, 0xD0, 0xF7, 0xCA, - 0xCE, 0xFE, 0xC3, 0x7C, 0xF3, 0xE6, 0x5E, 0xF7, 0xED, 0x56, 0x95, 0xF8, 0xE0, 0x01, 0x73, 0x00, - 0x00, 0x50, 0x6A, 0xFF, 0xE3, 0xFE, 0xCF, 0x2C, 0x7A, 0x75, 0xF3, 0xA2, 0xE7, 0xA2, 0x21, 0x32, - 0xF1, 0xF7, 0x36, 0x0C, 0x88, 0x8F, 0x84, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, - 0x7D, 0xA8, 0xEF, 0x85, 0x9D, 0xFF, 0xA7, 0x05, 0xE6, 0xED, 0x83, 0x7D, 0x41, 0x78, 0x04, 0x37, - 0x1F, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0xA6, 0x8B, 0x5F, 0x3E, 0xB6, 0xF8, 0x96, 0xD7, 0xB7, 0x2E, - 0x7C, 0x39, 0x0C, 0x11, 0xF7, 0xA0, 0xBA, 0xFF, 0x7C, 0x88, 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, - 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xF6, - 0xDD, 0x3E, 0xF7, 0x80, 0xF9, 0xA9, 0x67, 0xA3, 0xE1, 0xE1, 0xC7, 0x07, 0x0F, 0x98, 0x03, 0x00, - 0x80, 0xE9, 0xC7, 0x3D, 0xA8, 0xFE, 0xDB, 0xA7, 0x17, 0x7F, 0xF5, 0xF5, 0xAD, 0x8B, 0x7E, 0xE3, - 0x22, 0xE4, 0x77, 0x3B, 0x16, 0x9A, 0x37, 0xF7, 0x2F, 0x32, 0xE7, 0xFE, 0xD1, 0x1D, 0xEC, 0x55, - 0x44, 0x64, 0x5D, 0x3C, 0x1A, 0xF2, 0x9A, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, - 0xFC, 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xED, 0xAB, 0x3C, 0x60, 0x3E, 0x19, 0x1E, 0xAF, 0x3D, 0x33, - 0x97, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x7E, 0xF5, 0xC8, 0xBC, 0x0F, 0xFC, 0xE6, 0xE9, 0x85, 0xF7, - 0xBD, 0xBE, 0x75, 0xC1, 0x5B, 0x2E, 0x42, 0xDC, 0xDE, 0x1E, 0x59, 0x6C, 0xBC, 0x7F, 0x51, 0x31, - 0x91, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, - 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xCD, 0xAB, 0x3C, 0x60, 0x1E, 0x3E, 0xE7, 0x61, 0xC3, 0x63, 0xCB, - 0x5C, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x88, 0x1B, 0xFB, 0x4F, 0x9F, 0xB9, 0xF8, 0x95, 0xCD, 0x0B, - 0xB7, 0x84, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCD, 0xA9, 0xE7, 0xDA, 0x09, 0x11, 0x15, 0x0E, 0x79, - 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC0, 0xEF, - 0xD6, 0xD5, 0x3E, 0x60, 0x3E, 0xD7, 0xBC, 0xBE, 0x75, 0xEE, 0xB8, 0xFD, 0x91, 0x07, 0xCC, 0x01, - 0x00, 0x00, 0x9A, 0xF9, 0x9F, 0x0F, 0x2D, 0x5A, 0xFA, 0xEA, 0xE6, 0x85, 0x3F, 0x0B, 0x43, 0x64, - 0x7C, 0x68, 0x91, 0x39, 0x33, 0xEA, 0x0E, 0xFE, 0x2A, 0x32, 0x1A, 0x2D, 0x1E, 0x0D, 0x79, 0x4D, - 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC8, 0xEF, 0xC6, - 0xD5, 0x3F, 0x60, 0x6E, 0xB7, 0x75, 0x0E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA4, 0xF1, 0xBF, 0x1E, - 0x5A, 0xF0, 0xC5, 0xD7, 0xB6, 0x2E, 0xF8, 0x65, 0x18, 0x22, 0x6F, 0xEC, 0x5D, 0x64, 0xCE, 0xFE, - 0xC4, 0x45, 0x80, 0x0A, 0x8E, 0xE8, 0xE2, 0xD1, 0x90, 0xD7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, - 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x07, 0xFD, 0x6E, 0x9B, 0x7E, 0xC0, 0x7C, 0x2E, 0x0F, - 0x98, 0x03, 0x00, 0x00, 0x64, 0xE5, 0x1E, 0x54, 0xFF, 0xF5, 0xC6, 0x45, 0x7F, 0x19, 0x7D, 0x3E, - 0xC4, 0x3D, 0xA8, 0x7E, 0xFE, 0x67, 0x2A, 0x3C, 0xDC, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, - 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0x61, 0xBF, 0xDB, 0xC6, 0x03, 0xE6, - 0x00, 0x00, 0x00, 0x05, 0x72, 0x0F, 0xAA, 0xFF, 0xFA, 0xC9, 0x85, 0x1B, 0xC2, 0x08, 0x71, 0x7B, - 0xE7, 0x70, 0xFC, 0xF9, 0x10, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, - 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xD8, 0xEF, 0xA6, 0xF1, 0x80, 0x39, 0x00, 0x00, 0xC0, 0x14, - 0x3A, 0xF9, 0xC8, 0xE2, 0xF9, 0xBF, 0xDD, 0xB4, 0x60, 0x47, 0x18, 0x21, 0xE1, 0x83, 0xEA, 0x3A, - 0x1C, 0xF2, 0x58, 0x3C, 0x10, 0x8A, 0x9C, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, - 0x03, 0x7F, 0xB7, 0x8C, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x3A, 0xE8, 0x57, 0x1B, 0x17, 0xAD, 0x79, - 0x65, 0xD3, 0x82, 0x9F, 0x57, 0x42, 0x64, 0x81, 0x19, 0x1F, 0x5A, 0x68, 0xCE, 0x8C, 0xBA, 0x43, - 0xBC, 0x8A, 0x88, 0xAC, 0x8B, 0x07, 0x42, 0x91, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, - 0x3D, 0x7D, 0xE8, 0xEF, 0x86, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x40, 0x97, 0xA8, 0x7C, 0x90, 0xE1, - 0xC2, 0xAF, 0xBE, 0xB6, 0x75, 0xFE, 0x2F, 0x5D, 0x84, 0xB8, 0xBD, 0xB9, 0x7F, 0xA1, 0x39, 0xFB, - 0x13, 0x77, 0xA0, 0x57, 0x41, 0x91, 0x66, 0xF1, 0x40, 0x28, 0x72, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, - 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFE, 0x9D, 0x5E, 0xA3, 0x07, 0xCC, 0x4F, 0x7E, 0xE7, 0x53, 0xF3, - 0x83, 0x2F, 0x01, 0x00, 0x00, 0x00, 0x74, 0xC2, 0x60, 0xFF, 0xA7, 0xFE, 0xDD, 0xAB, 0x9B, 0x16, - 0xDC, 0xF3, 0xFA, 0xD6, 0xF9, 0x6F, 0x85, 0x21, 0xF2, 0xF6, 0x88, 0x7B, 0x50, 0x5D, 0x85, 0x45, - 0x92, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFF, - 0x9D, 0x9E, 0x7A, 0xC0, 0xFC, 0xB7, 0x1B, 0xE7, 0xDE, 0x10, 0xFC, 0x23, 0x0F, 0x00, 0x00, 0x80, - 0x6E, 0xF0, 0xFF, 0x7E, 0x63, 0xF1, 0x87, 0x7F, 0xF3, 0xD4, 0x82, 0x47, 0xC3, 0x08, 0x71, 0x3B, - 0xF5, 0xDC, 0x22, 0xE3, 0xFD, 0x8B, 0x8A, 0x8C, 0x46, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, - 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xFE, 0x3B, 0xB9, 0xF8, 0x03, 0xE6, 0xEE, 0x39, 0x8F, - 0x57, 0x9F, 0xBE, 0xF4, 0x3F, 0x06, 0xFF, 0x88, 0x03, 0x00, 0x00, 0xA0, 0x1B, 0xFD, 0x8F, 0xFB, - 0x17, 0x2C, 0x7A, 0x75, 0xF3, 0x82, 0x9F, 0x85, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCC, 0xE9, 0xBF, - 0x75, 0x07, 0x61, 0x15, 0x1C, 0xD1, 0xA9, 0x48, 0x28, 0x6A, 0xB1, 0x03, 0x7A, 0x99, 0x27, 0x0F, - 0xFF, 0x9D, 0x9E, 0x0E, 0x80, 0x4E, 0xAD, 0xEE, 0x01, 0xF3, 0xCD, 0x73, 0xDE, 0xB2, 0x3F, 0xF2, - 0x80, 0x39, 0x00, 0x00, 0x40, 0x2F, 0xF9, 0xE5, 0xC3, 0xF3, 0x6F, 0x79, 0x75, 0xCB, 0x82, 0x97, - 0xC3, 0x10, 0x71, 0x0F, 0xAA, 0x4F, 0xFC, 0x57, 0x77, 0xF8, 0x27, 0x3E, 0xA6, 0x6C, 0xF2, 0xF0, - 0xDF, 0xE9, 0xE9, 0x08, 0xE8, 0xC4, 0x1A, 0x3D, 0x60, 0x3E, 0xBE, 0xA5, 0x6F, 0x76, 0xF0, 0x8F, - 0x31, 0x00, 0x00, 0x00, 0x7A, 0x49, 0xF8, 0xA0, 0x7A, 0xF4, 0xF9, 0x10, 0xF7, 0xA0, 0xFA, 0xB9, - 0x7F, 0x74, 0x21, 0x40, 0x7C, 0x14, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x74, 0x08, 0x4C, 0xF5, 0x1A, - 0x3D, 0x60, 0xFE, 0xEB, 0xC7, 0x3E, 0x7D, 0x55, 0xF0, 0x8F, 0x2E, 0x00, 0x00, 0x00, 0x7A, 0x99, - 0xFB, 0x20, 0xC3, 0xDF, 0x6C, 0x9C, 0x7F, 0x5F, 0xED, 0x83, 0xEA, 0x0B, 0xCD, 0xF9, 0x9F, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x63, 0x60, 0xAA, 0x17, - 0x7F, 0xC0, 0xFC, 0xF5, 0x6D, 0x73, 0x4E, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x40, 0x49, 0xFD, 0xDB, - 0x83, 0x7D, 0x7D, 0xAF, 0x6C, 0x5E, 0xB0, 0xA5, 0x12, 0x21, 0xF3, 0xCD, 0xEF, 0x77, 0xCD, 0x37, - 0xA7, 0x9E, 0x5B, 0x68, 0xBC, 0x7F, 0x51, 0xC1, 0x90, 0xE7, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, - 0xFF, 0x4E, 0x4F, 0xC7, 0xC0, 0x54, 0x8E, 0x07, 0xCC, 0x01, 0x00, 0x00, 0xA6, 0xB1, 0xFF, 0xF9, - 0xD0, 0xBC, 0xA5, 0xAF, 0x6E, 0xEE, 0xFB, 0x99, 0x8B, 0x90, 0x30, 0x44, 0xCE, 0x8C, 0xBA, 0x03, - 0xB4, 0x8A, 0x87, 0x76, 0x17, 0x3B, 0xA0, 0x97, 0x79, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x20, 0x98, - 0xAA, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xAA, 0x7E, 0xF5, 0x58, 0xDF, 0x5F, 0x54, 0x3E, 0xC8, - 0xB0, 0x12, 0x22, 0xE3, 0x43, 0xF6, 0xC0, 0xF8, 0x13, 0x77, 0x98, 0x56, 0x21, 0x91, 0x65, 0xB1, - 0x03, 0x7A, 0x99, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x82, 0xA9, 0x18, 0x0F, 0x98, 0x03, 0x00, - 0x00, 0x40, 0x72, 0x0F, 0xAA, 0xFF, 0x7A, 0x63, 0xDF, 0x5F, 0xBE, 0xBE, 0xB5, 0xEF, 0xAD, 0x30, - 0x44, 0xDE, 0xDC, 0x6F, 0x0F, 0x90, 0x6D, 0x3F, 0x1F, 0x22, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, - 0x77, 0x7A, 0x3A, 0x0C, 0x8A, 0x1E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x20, 0x11, 0xFF, 0x41, 0xF5, - 0xA7, 0xFA, 0x1E, 0x0D, 0x23, 0xC4, 0xCD, 0x3D, 0xA8, 0x9E, 0xED, 0xF9, 0x10, 0x71, 0x48, 0x2F, - 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x71, 0x50, 0xF4, 0xCE, 0xFC, 0xDD, 0x7C, 0x1E, 0x30, 0x07, - 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x41, 0xF5, 0x57, 0x9F, 0x99, 0x3F, 0x12, 0x46, 0x48, 0xFA, 0x07, - 0xD5, 0xC5, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x41, 0x91, 0x73, 0xCF, 0x79, - 0xF0, 0x80, 0x39, 0x00, 0x00, 0x00, 0xDA, 0xF2, 0xAB, 0x27, 0xFA, 0xD6, 0x44, 0x1F, 0x54, 0x77, - 0xCF, 0x87, 0xB4, 0x7E, 0x50, 0x3D, 0x76, 0x40, 0x2F, 0xF3, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x81, - 0x50, 0xD4, 0xCE, 0xFD, 0x94, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x90, 0xA3, 0xCA, 0x07, 0x19, 0xF6, - 0x7D, 0x35, 0xFA, 0xA0, 0xBA, 0x7B, 0x3E, 0x44, 0x3F, 0xA8, 0x1E, 0x3B, 0xA0, 0x97, 0x79, 0xF2, - 0xF0, 0xDF, 0xE9, 0xE9, 0x48, 0x28, 0x62, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x42, 0xB9, 0xE7, - 0x43, 0x5E, 0xDD, 0xD4, 0x77, 0x4F, 0xF4, 0x41, 0xF5, 0xB7, 0x0E, 0x46, 0x1F, 0x54, 0x17, 0x87, - 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0A, 0x79, 0x2F, 0x7C, 0xC0, 0x3C, 0xFA, 0x9C, - 0x87, 0x1D, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA0, 0x18, 0x47, 0xBF, 0xB1, 0xF8, 0xC3, 0xAF, 0x6C, - 0xEE, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0x3B, 0x87, 0xEC, 0xC1, 0xF4, 0x5F, 0xC4, 0x41, 0xBD, 0x8C, - 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x42, 0xDE, 0x53, 0x0F, 0x98, 0xFF, 0xFA, 0xE1, 0x4B, 0x6F, - 0x0E, 0xFE, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xE3, 0x3F, 0xA8, 0xEE, 0x9E, 0x0F, 0xD9, 0xDE, - 0x67, 0xDC, 0x7E, 0xBF, 0xB3, 0xCF, 0x9C, 0x7A, 0xCE, 0x1E, 0x54, 0xD5, 0xA1, 0xBD, 0x2C, 0x93, - 0x87, 0xFF, 0x4E, 0xAF, 0x3E, 0x14, 0xF2, 0x9E, 0x7A, 0xC0, 0xFC, 0xD7, 0x83, 0x73, 0xFE, 0xB7, - 0xE0, 0x1F, 0x05, 0x00, 0x00, 0x00, 0x60, 0xEA, 0xFC, 0xF2, 0xE1, 0xB9, 0xB7, 0xBC, 0xB6, 0xB5, - 0xEF, 0x97, 0x61, 0x88, 0x8C, 0xEF, 0x9E, 0x6F, 0x26, 0xFE, 0xAB, 0x3D, 0x18, 0xAB, 0x03, 0x7C, - 0x2F, 0x4F, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0C, 0x79, 0x4D, 0x3D, 0x60, 0xFE, 0xDA, 0xA6, 0x39, - 0x77, 0xF3, 0x80, 0x39, 0x00, 0x00, 0x00, 0x3A, 0xCA, 0x7F, 0x50, 0xFD, 0xC9, 0xBE, 0xAF, 0xBE, - 0xBE, 0x65, 0xDE, 0x5B, 0x61, 0x88, 0xBC, 0xB9, 0x6F, 0xBE, 0x39, 0xFB, 0x13, 0x7B, 0x48, 0x56, - 0x87, 0xF9, 0x5E, 0x9B, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x1A, 0xF2, 0x98, 0x7A, 0xC0, 0xFC, 0xD5, - 0xCD, 0x73, 0x37, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xBA, 0x8A, 0x7B, 0x50, 0xFD, 0xB7, 0x9B, - 0xFA, 0xEE, 0x09, 0x23, 0xC4, 0xED, 0xED, 0x61, 0xF7, 0xA0, 0xBA, 0x38, 0xD4, 0xF7, 0xCA, 0xE4, - 0xE1, 0xBF, 0xD3, 0xD3, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0x3D, 0xC9, 0x3D, - 0x1F, 0xF2, 0xCA, 0xA6, 0xBE, 0x2D, 0xD1, 0x10, 0x71, 0xCF, 0x87, 0xF4, 0xDC, 0x83, 0xEA, 0xF2, - 0xF0, 0xDF, 0xE9, 0xE9, 0x78, 0x68, 0x77, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x9E, 0x57, 0xF9, - 0x20, 0xC3, 0x79, 0x35, 0x0F, 0xAA, 0x9F, 0xFE, 0x5B, 0x7B, 0xE0, 0x55, 0x87, 0xFD, 0x6E, 0x9B, - 0x3C, 0xFC, 0x77, 0x7A, 0xF5, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xA5, 0xF3, - 0xAB, 0xC7, 0xFA, 0xFE, 0x22, 0xFE, 0xA0, 0x7A, 0x57, 0x3F, 0x1F, 0x22, 0x0F, 0xFF, 0x9D, 0x9E, - 0x0E, 0x88, 0xAC, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0x94, 0x9A, 0x7B, 0x50, 0xFD, 0xB5, 0x2D, - 0xF3, 0xBE, 0x1E, 0x7F, 0x50, 0xFD, 0xDC, 0x3F, 0xDA, 0xC3, 0xB5, 0x8A, 0x80, 0x4E, 0x4D, 0x1E, - 0xFE, 0x3B, 0x3D, 0x1D, 0x11, 0x59, 0xC6, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x98, 0x56, 0xDC, 0x83, - 0xEA, 0xBF, 0x79, 0xAA, 0xEF, 0xC7, 0x61, 0x84, 0xB8, 0x75, 0xCD, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, - 0xE9, 0xE9, 0x90, 0x48, 0xBB, 0x46, 0x0F, 0x98, 0xBF, 0xB6, 0xE5, 0xD2, 0x81, 0xE0, 0x7F, 0x1A, - 0x00, 0x00, 0x00, 0xA0, 0xBC, 0xFC, 0x0F, 0x32, 0xDC, 0xD4, 0x37, 0x12, 0x46, 0x48, 0xF8, 0x41, - 0x86, 0x1D, 0x7B, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x13, 0x69, 0xA7, 0x1E, 0x30, 0x7F, - 0xE5, 0xC9, 0x39, 0xB7, 0x07, 0xFF, 0x53, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x87, 0x7B, 0x50, 0xFD, - 0xB5, 0x2D, 0xF3, 0x8E, 0x85, 0x21, 0xE2, 0x9E, 0x0F, 0x39, 0x33, 0x6A, 0x0F, 0xDF, 0x2A, 0x12, - 0x8A, 0x9A, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x26, 0xD2, 0x4C, 0x3D, 0x60, 0xFE, 0xCA, 0xA6, 0xB9, - 0xFF, 0x57, 0xF0, 0xB7, 0x1E, 0x00, 0x00, 0x00, 0x98, 0x9E, 0xC2, 0x0F, 0x32, 0x8C, 0x3E, 0xA8, - 0xFE, 0xC6, 0x9E, 0x29, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x14, 0x49, 0x17, 0x7F, - 0xC0, 0xDC, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x98, 0xF0, 0x83, 0x0C, 0xE3, 0x0F, 0xAA, - 0x17, 0xF6, 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2A, 0x92, 0x8C, 0x07, 0xCC, 0x01, 0x00, - 0x00, 0x80, 0x0C, 0x5E, 0x79, 0x72, 0xCE, 0xA5, 0xF1, 0x0F, 0x32, 0x74, 0x0F, 0xAA, 0xE7, 0xFA, - 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2C, 0x5A, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, - 0x1C, 0xFC, 0x7A, 0x63, 0xDF, 0x55, 0xAF, 0x6E, 0x9E, 0xF7, 0x4F, 0x61, 0x84, 0x84, 0x0F, 0xAA, - 0xCB, 0xA0, 0x48, 0x33, 0x79, 0xF8, 0xEF, 0xF4, 0xEA, 0xC3, 0x22, 0xC9, 0x78, 0xC0, 0x1C, 0x00, - 0x00, 0x00, 0xC8, 0xD9, 0x2F, 0x1F, 0x9E, 0x7B, 0x4B, 0xFC, 0x83, 0x0C, 0x33, 0x3F, 0xA8, 0x2E, - 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x8B, 0x66, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, 0x40, 0xFE, - 0x07, 0x19, 0x6E, 0xEE, 0xFB, 0x3F, 0xE3, 0xCF, 0x87, 0xA4, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, - 0x3D, 0x1D, 0x18, 0x8D, 0xA6, 0x1E, 0x30, 0xFF, 0xED, 0xC6, 0x4B, 0xBF, 0xC5, 0x03, 0xE6, 0x00, - 0x00, 0x00, 0x40, 0x01, 0xC2, 0x07, 0xD5, 0xC3, 0x08, 0x71, 0x7B, 0xEB, 0x40, 0x82, 0x07, 0xD5, - 0xE5, 0xE1, 0xBF, 0xD3, 0xD3, 0x91, 0xA1, 0xE6, 0x9E, 0xF3, 0x88, 0x3F, 0x60, 0xFE, 0xCA, 0x53, - 0x73, 0xB6, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x00, 0x30, 0x05, 0xDC, 0x07, 0x19, 0xBE, 0xBE, 0x75, - 0xDE, 0xFE, 0x68, 0x88, 0xBC, 0x73, 0xA8, 0xC1, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xD0, - 0x88, 0x4F, 0x3D, 0x60, 0xFE, 0xDA, 0xE6, 0x39, 0x3F, 0xE1, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, - 0x03, 0xDC, 0x07, 0x19, 0xC6, 0x1F, 0x54, 0x3F, 0xFD, 0xB7, 0xF6, 0xF0, 0x5E, 0x82, 0xF8, 0x70, - 0x0F, 0x98, 0xD7, 0x3C, 0xE7, 0xC1, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x40, 0x77, 0x88, 0x7F, 0x90, - 0xE1, 0xF8, 0xEE, 0x3E, 0x33, 0xF1, 0xF7, 0xEE, 0x20, 0xAF, 0x02, 0xA0, 0x93, 0xAB, 0x0F, 0x8D, - 0xF8, 0xDC, 0x03, 0xE6, 0x6F, 0x0C, 0xD5, 0x3F, 0x60, 0x3E, 0xDA, 0xFF, 0x9E, 0x3F, 0x0A, 0x7E, - 0xBB, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xCD, 0x7F, 0x50, 0x7D, 0xCB, 0xBC, 0xAF, 0x57, 0x1E, 0x54, - 0xB7, 0x07, 0x78, 0xBB, 0x37, 0xF7, 0xF5, 0xD9, 0x03, 0xBD, 0x3B, 0xD8, 0xAB, 0x18, 0x98, 0xEA, - 0xD5, 0xC7, 0x46, 0x74, 0xEE, 0x83, 0x04, 0x79, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xE8, 0x31, 0xEE, - 0x41, 0xF5, 0x57, 0x36, 0xCD, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0xDB, 0xC3, 0xF3, 0xED, 0x01, 0x5F, - 0x45, 0xC1, 0x54, 0x4D, 0x47, 0x87, 0x1B, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x6F, - 0x1B, 0xFA, 0xFA, 0x5E, 0xDB, 0x32, 0xF7, 0x27, 0x61, 0x84, 0xFC, 0x7E, 0xE7, 0x3C, 0x73, 0xEA, - 0xD9, 0xF9, 0xF6, 0xC0, 0xAF, 0x02, 0xA1, 0xC8, 0x35, 0x0E, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, - 0x00, 0x4A, 0xE6, 0x57, 0x4F, 0x5C, 0xBA, 0xC6, 0x86, 0xC8, 0xB1, 0x68, 0x88, 0x9C, 0xF9, 0x3B, - 0x17, 0x01, 0x2A, 0x16, 0xF2, 0x5E, 0x7D, 0x78, 0xB8, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0x50, - 0x62, 0xEE, 0x01, 0xEE, 0xDF, 0x3E, 0x39, 0xF7, 0xAB, 0xAF, 0x6F, 0x9B, 0x37, 0x1E, 0x86, 0x88, - 0x7B, 0x50, 0xBD, 0xD8, 0xE7, 0x43, 0xEA, 0xC3, 0x83, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x69, - 0xA4, 0xF2, 0x41, 0x86, 0x73, 0xEF, 0x79, 0x7D, 0xCB, 0xDC, 0x9A, 0x07, 0xD5, 0xCF, 0xFD, 0x34, - 0xEF, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, 0xA6, 0xB1, 0x57, 0x9E, 0x9C, - 0x73, 0xA9, 0x7A, 0x50, 0x3D, 0x9F, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, - 0xE0, 0x7B, 0x6D, 0x47, 0xDF, 0x40, 0xE5, 0x83, 0x0C, 0x27, 0x43, 0xE4, 0x8D, 0x3D, 0x7D, 0xFE, - 0x33, 0x22, 0xD9, 0xDE, 0x9A, 0x55, 0x79, 0xB8, 0xDC, 0x3D, 0xE3, 0x11, 0xBF, 0xF1, 0xE0, 0x01, - 0x73, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x57, 0x9E, 0x99, 0x73, 0xDB, 0xEB, 0xDB, 0xE7, 0x9E, 0x8C, - 0x86, 0x48, 0x18, 0x23, 0xEF, 0x1C, 0x9A, 0x6F, 0x4E, 0xFF, 0xCD, 0x7C, 0xFF, 0x79, 0x91, 0xF8, - 0x0D, 0x89, 0xFB, 0xFF, 0xDD, 0xBF, 0xEE, 0xFE, 0xFD, 0x77, 0x0E, 0xF5, 0xD5, 0x3C, 0xDF, 0x11, - 0xCE, 0x3D, 0x60, 0x6E, 0x7F, 0xEE, 0x75, 0xC1, 0x5F, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xDC, - 0x1B, 0xB3, 0x5E, 0x79, 0x66, 0xEE, 0x70, 0x3C, 0x44, 0x5A, 0x2E, 0x16, 0x1D, 0x95, 0xCD, 0x19, - 0xFA, 0xF5, 0xA3, 0x97, 0xDE, 0x1C, 0xFC, 0xD4, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xB9, 0x87, 0xD5, - 0x7F, 0xB3, 0x71, 0xDE, 0x9D, 0xAF, 0x3E, 0x3D, 0xEF, 0xA1, 0x57, 0x37, 0xCF, 0x7D, 0x59, 0x46, - 0x47, 0xB8, 0x20, 0x38, 0x5E, 0xDB, 0x3C, 0xF7, 0xD8, 0xAB, 0xCF, 0xCC, 0x7D, 0xDA, 0xDD, 0x76, - 0xFC, 0xB7, 0xEF, 0xCC, 0xFB, 0x40, 0xF0, 0x53, 0x01, 0x00, 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x35, - 0xB9, 0xFE, 0x07, 0x1B, 0xEE, 0xE8, 0x1B, 0x88, 0xEF, 0xDF, 0x36, 0xCC, 0xEE, 0x0B, 0xFE, 0x63, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xD0, 0x15, 0xDE, 0xF3, 0x9E, 0xFF, 0x1F, 0x5B, 0xE2, 0x94, 0x1D, 0x86, - 0x86, 0x23, 0x09, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82}; - -static const uint8_t tree_gif[] PROGMEM = { - - 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x28, 0x00, 0x3C, 0x00, 0x83, 0x0B, 0x00, 0x00, 0xFF, 0xFF, - 0x00, 0x21, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x94, 0x00, 0x00, 0xB5, 0x00, 0x00, - 0xDE, 0x00, 0x00, 0xFF, 0x00, 0x6B, 0x00, 0x00, 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, - 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x00, 0xCC, 0x00, 0x00, 0x21, 0xFF, 0x0B, - 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0xA0, 0x0F, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, - 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, - 0x8C, 0xCA, 0xE8, 0x85, 0xE8, 0xA5, 0xAC, 0x67, 0xEA, 0x8A, 0xE5, 0x2B, 0x2F, 0xE3, 0x31, 0xCE, - 0xAF, 0x41, 0x1C, 0xB8, 0x1B, 0x24, 0x80, 0x04, 0xAF, 0x87, 0x02, 0x26, 0x88, 0xA1, 0x07, 0x60, - 0xB9, 0x44, 0x82, 0x04, 0x02, 0x80, 0x61, 0x30, 0x70, 0x6E, 0x0C, 0x86, 0x03, 0x60, 0x20, 0xB0, - 0x6A, 0xA8, 0xD3, 0x03, 0x21, 0xEC, 0xAD, 0x18, 0x12, 0xE8, 0xF4, 0xB1, 0x4C, 0x51, 0xA0, 0x07, - 0xEA, 0x07, 0x5B, 0xF2, 0x70, 0x13, 0x76, 0xD4, 0xA8, 0xBC, 0xBC, 0xEA, 0x1F, 0x06, 0x77, 0x51, - 0x73, 0x50, 0x0A, 0x80, 0x7F, 0x04, 0x4C, 0x4D, 0x65, 0x06, 0x0A, 0x3B, 0x3B, 0x62, 0x5A, 0x53, - 0x65, 0x05, 0x02, 0x04, 0x68, 0x0C, 0x6A, 0x00, 0x5D, 0x5E, 0x0F, 0x0F, 0x6A, 0x98, 0x6A, 0x09, - 0x7B, 0x56, 0x9D, 0x09, 0x0C, 0xA7, 0xA7, 0x7F, 0x06, 0x9D, 0xA3, 0x44, 0x02, 0x01, 0x03, 0x90, - 0x0C, 0x87, 0x03, 0x06, 0x02, 0x05, 0x56, 0x06, 0x01, 0x02, 0x53, 0xB1, 0xB3, 0x04, 0x79, 0xAF, - 0x55, 0x48, 0x51, 0xB0, 0x87, 0xC0, 0x7F, 0x07, 0x95, 0x05, 0x85, 0x44, 0xB6, 0x00, 0x05, 0x53, - 0x96, 0x6A, 0x60, 0x02, 0x0A, 0x48, 0x89, 0x00, 0x07, 0xA1, 0x69, 0x7D, 0x2B, 0x3D, 0x9D, 0x41, - 0xA1, 0x04, 0xA0, 0xDD, 0x9D, 0x38, 0x02, 0xE1, 0x6A, 0x07, 0x62, 0x0C, 0x77, 0xE6, 0xAD, 0x2F, - 0x05, 0x01, 0xB6, 0x90, 0x07, 0xA8, 0xA7, 0x54, 0xB5, 0xBC, 0x06, 0x33, 0x50, 0x53, 0x3A, 0x00, - 0x39, 0x62, 0x10, 0x6B, 0xDF, 0xBE, 0x19, 0x03, 0x18, 0x40, 0xA9, 0x15, 0x4B, 0xCC, 0x0E, 0x77, - 0x3B, 0x04, 0xC4, 0x02, 0x38, 0x43, 0x21, 0x96, 0x2C, 0xD3, 0xD6, 0x81, 0x01, 0x26, 0x2A, 0xFB, - 0xDE, 0x07, 0x7C, 0x0A, 0xB7, 0x71, 0x1B, 0x79, 0xEE, 0xC5, 0x83, 0x72, 0xDD, 0x84, 0xBC, 0x4B, - 0x13, 0xA4, 0x13, 0x15, 0x17, 0xAB, 0x18, 0x78, 0x4A, 0x43, 0x40, 0x81, 0x43, 0x76, 0x8E, 0xB6, - 0x04, 0x7C, 0x19, 0x02, 0x98, 0xC4, 0x86, 0x35, 0xBD, 0xE1, 0x1C, 0x90, 0x4D, 0x62, 0xBF, 0x14, - 0xFC, 0x7E, 0x02, 0x1A, 0x60, 0xD3, 0xD1, 0x9D, 0x3B, 0x3A, 0x09, 0xFC, 0x44, 0xB1, 0xD0, 0x96, - 0x8E, 0x43, 0x8D, 0x9E, 0xDA, 0xDB, 0x22, 0x11, 0x8A, 0x42, 0x10, 0x5C, 0x00, 0x1A, 0x2D, 0x38, - 0xF2, 0x0E, 0xA0, 0x4A, 0x03, 0x4E, 0xA2, 0xF0, 0xF4, 0x80, 0x17, 0x95, 0x8C, 0x23, 0xD1, 0xD8, - 0x12, 0x00, 0x92, 0x03, 0xAB, 0x99, 0x23, 0x71, 0x3E, 0x8D, 0xEB, 0x6E, 0x18, 0x07, 0x66, 0x23, - 0x05, 0x3E, 0x72, 0xE4, 0x06, 0x0D, 0x81, 0x02, 0xE4, 0x36, 0x5D, 0xD9, 0xA5, 0xC0, 0xAD, 0x59, - 0xA2, 0x86, 0x6E, 0xD6, 0xC4, 0x73, 0xEB, 0x15, 0xA5, 0xC5, 0xDE, 0x14, 0xF4, 0x62, 0x07, 0xC0, - 0xE9, 0x9D, 0xCC, 0x58, 0x02, 0x14, 0xA0, 0x84, 0x45, 0x83, 0x68, 0x7A, 0x8D, 0x81, 0x66, 0xC3, - 0xE9, 0xD0, 0xA6, 0x3E, 0x03, 0xF3, 0x80, 0x7D, 0x90, 0xD8, 0x58, 0xA2, 0x59, 0x2D, 0x90, 0x68, - 0xD6, 0x64, 0x17, 0x76, 0x5A, 0x23, 0xBF, 0x13, 0x58, 0x89, 0x7A, 0xC3, 0xF0, 0x8F, 0xB6, 0xB8, - 0x4B, 0xD3, 0x74, 0x52, 0x50, 0x92, 0xC2, 0x03, 0xD1, 0x78, 0xD7, 0x89, 0x4C, 0x23, 0x26, 0x6E, - 0x82, 0xCC, 0x15, 0x5E, 0x05, 0x08, 0x30, 0x06, 0x8A, 0x75, 0x64, 0xFA, 0x42, 0xF1, 0x12, 0xAD, - 0x60, 0xDE, 0x51, 0x0A, 0x94, 0xBA, 0x5E, 0x2C, 0x8C, 0x86, 0xDD, 0x3D, 0xDE, 0x8F, 0x0A, 0x70, - 0x51, 0x5F, 0xFE, 0xF2, 0x84, 0xD1, 0xD0, 0xA6, 0x68, 0xB7, 0x96, 0x62, 0x14, 0x0C, 0xC1, 0xB7, - 0x90, 0x68, 0x72, 0xD1, 0x7C, 0xD9, 0x3D, 0xA3, 0x94, 0x35, 0xDE, 0x54, 0x06, 0x92, 0x51, 0x50, - 0x68, 0xC2, 0xC5, 0x44, 0xB7, 0x30, 0x70, 0xDE, 0x6A, 0x49, 0x69, 0x86, 0xC5, 0x2D, 0xA3, 0x29, - 0x04, 0x05, 0x2F, 0xD9, 0xC4, 0x02, 0x0C, 0x6C, 0x0C, 0x48, 0xB0, 0x94, 0x01, 0xDA, 0x3C, 0xF2, - 0x56, 0x21, 0xFA, 0xE8, 0xA3, 0xA1, 0x55, 0x12, 0xE9, 0xF4, 0x56, 0x42, 0xF8, 0x50, 0x00, 0x40, - 0x08, 0x08, 0xD4, 0x88, 0x80, 0x05, 0x33, 0x66, 0x10, 0xA2, 0x0C, 0xDC, 0xA0, 0xB0, 0xA3, 0x0B, - 0x71, 0xCD, 0xB1, 0x80, 0x75, 0x69, 0x20, 0x41, 0xE4, 0x91, 0x6B, 0x64, 0x10, 0x01, 0x00, 0x21, - 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, 0x00, - 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, 0x8C, - 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0x31, 0x1C, 0x34, - 0x1B, 0x24, 0x4C, 0x82, 0xE7, 0x28, 0x5E, 0x02, 0x78, 0x7A, 0x30, 0x8E, 0x47, 0x62, 0x48, 0x20, - 0x60, 0xD8, 0x06, 0x4A, 0x8E, 0xC1, 0x70, 0x60, 0x0C, 0x04, 0xD1, 0xCD, 0x60, 0x60, 0x3B, 0x10, - 0xBA, 0x59, 0x8B, 0x21, 0x41, 0x2E, 0x0F, 0xC3, 0x16, 0xF2, 0xC0, 0xAC, 0x40, 0x4F, 0x1E, 0x80, - 0x04, 0x81, 0x70, 0xD8, 0x0A, 0x14, 0x0F, 0xF7, 0x42, 0x00, 0xA0, 0xD6, 0x09, 0x0A, 0x81, 0x81, - 0x68, 0x00, 0x85, 0x85, 0x7F, 0x07, 0x07, 0x0A, 0x06, 0x7A, 0x06, 0x00, 0x74, 0x74, 0x5E, 0x8A, - 0x36, 0x68, 0x05, 0x7C, 0x66, 0x3D, 0x64, 0x58, 0x61, 0x0F, 0x0F, 0x66, 0x64, 0x99, 0x64, 0x79, - 0x9C, 0x9E, 0xA0, 0x48, 0x4E, 0x9D, 0xA3, 0x4A, 0x02, 0x01, 0x37, 0x90, 0x55, 0x04, 0x5C, 0x02, - 0x05, 0x59, 0x06, 0x01, 0x02, 0x4F, 0x89, 0x55, 0x76, 0xAC, 0x50, 0xAB, 0x0A, 0xAD, 0x7F, 0xB1, - 0x75, 0x07, 0x02, 0x04, 0x05, 0x00, 0xBE, 0x39, 0x06, 0x77, 0x05, 0x36, 0x04, 0x9F, 0x5B, 0xCC, - 0x00, 0x4A, 0x82, 0x81, 0x07, 0x9F, 0x65, 0x86, 0x85, 0x40, 0x9D, 0x0A, 0x9F, 0x0C, 0xD0, 0x9F, - 0x00, 0x9D, 0x39, 0x02, 0xDE, 0x66, 0xB0, 0x73, 0xE2, 0x09, 0xE4, 0xAA, 0x2F, 0x05, 0x01, 0xCC, - 0x5E, 0xA7, 0x56, 0x75, 0xD2, 0xB8, 0x8C, 0x2F, 0x4C, 0x36, 0x06, 0xB1, 0x73, 0xE1, 0x88, 0xC9, - 0x92, 0x45, 0x43, 0x96, 0x00, 0x2E, 0x37, 0xE8, 0x79, 0x99, 0x53, 0xEC, 0x86, 0x0D, 0x06, 0x05, - 0xF3, 0x51, 0x61, 0x57, 0xE6, 0x9E, 0xBF, 0x35, 0x0C, 0xDE, 0x81, 0xE8, 0x64, 0x10, 0xFB, 0x5B, - 0xB6, 0x6C, 0xF5, 0x56, 0x94, 0x22, 0x13, 0xA7, 0xE2, 0x9C, 0x04, 0xDF, 0xCA, 0x74, 0xB2, 0xB2, - 0xC2, 0x40, 0x2A, 0x92, 0x72, 0x20, 0x45, 0x52, 0xE0, 0x45, 0x1A, 0x01, 0x2B, 0xCA, 0x3E, 0xC4, - 0x3A, 0x38, 0x60, 0xDB, 0x23, 0x86, 0xD6, 0x14, 0x0C, 0x20, 0xC0, 0x84, 0xCB, 0x8A, 0x7C, 0x3C, - 0x1F, 0x25, 0x94, 0xA9, 0x80, 0x21, 0x17, 0xA2, 0x5B, 0x4E, 0x34, 0x91, 0xE5, 0x2F, 0x99, 0x4C, - 0xA0, 0x89, 0xEC, 0x5C, 0xC1, 0xB5, 0x89, 0xC3, 0x15, 0x2B, 0xCC, 0x10, 0xD6, 0xF9, 0x38, 0x67, - 0xA8, 0xB1, 0x01, 0xE5, 0x40, 0xD4, 0x7B, 0x42, 0xF1, 0x63, 0x02, 0x66, 0x02, 0x12, 0xA4, 0xFA, - 0x90, 0x2A, 0x54, 0xB6, 0x44, 0xEB, 0xDA, 0x96, 0x19, 0x9A, 0x53, 0x43, 0x01, 0xBB, 0x64, 0x84, - 0xAE, 0xC3, 0xBB, 0xB0, 0xCC, 0x31, 0x40, 0x5D, 0x35, 0xD8, 0x62, 0x82, 0x6B, 0x68, 0xAC, 0xA6, - 0x43, 0xF1, 0xD2, 0x01, 0x20, 0xE9, 0x8A, 0x25, 0x05, 0x96, 0x36, 0xD8, 0x8A, 0xD7, 0xD8, 0x46, - 0xD0, 0x85, 0xEB, 0x7E, 0x72, 0x31, 0x10, 0x54, 0x9F, 0x85, 0x00, 0xF1, 0xA6, 0x1C, 0x94, 0x2C, - 0x34, 0xB2, 0x17, 0x9F, 0x5B, 0xB8, 0x14, 0x80, 0xFC, 0x41, 0x28, 0x63, 0xC7, 0x03, 0x9A, 0x4A, - 0x32, 0x9C, 0x2C, 0x2B, 0x2E, 0x40, 0x72, 0x63, 0x59, 0x48, 0x85, 0x47, 0x8D, 0xD8, 0xC8, 0xD9, - 0xE2, 0xF0, 0x55, 0x99, 0x4A, 0xE3, 0x82, 0x07, 0x41, 0x3F, 0x25, 0x92, 0xAE, 0xD7, 0x4C, 0x3C, - 0xE7, 0xAC, 0x02, 0x04, 0x58, 0xC4, 0xC4, 0xAD, 0x9C, 0x1B, 0xB1, 0x3F, 0xE1, 0x42, 0x3D, 0x4B, - 0x9E, 0x85, 0xCB, 0x57, 0xA6, 0x30, 0x4B, 0x97, 0x88, 0x26, 0xA2, 0x03, 0x7F, 0x8B, 0x72, 0x2D, - 0x90, 0x79, 0x02, 0xFD, 0x59, 0x36, 0xB2, 0xF3, 0x41, 0x2A, 0x65, 0xAD, 0x75, 0x64, 0x3A, 0x0C, - 0x48, 0xB4, 0x15, 0x35, 0x13, 0xE0, 0xC2, 0xC0, 0x2D, 0xB1, 0x15, 0x95, 0x0C, 0x13, 0x97, 0x59, - 0x73, 0x90, 0x01, 0xF5, 0xAC, 0x36, 0x8D, 0x79, 0x12, 0x40, 0xB8, 0x45, 0x22, 0xB8, 0xF8, 0xC4, - 0x0C, 0x7D, 0xB3, 0x31, 0x96, 0xCF, 0x00, 0x01, 0x76, 0x41, 0x80, 0x4F, 0x0B, 0x80, 0x78, 0x4A, - 0x24, 0x5B, 0x8C, 0x18, 0xDB, 0x8A, 0x0A, 0xF0, 0xC3, 0x15, 0x88, 0x08, 0xF1, 0xC5, 0xC7, 0x3C, - 0x13, 0x40, 0x94, 0x01, 0x81, 0x13, 0x20, 0xA0, 0x23, 0x02, 0x27, 0xE0, 0x58, 0x63, 0x08, 0xD9, - 0xE8, 0x41, 0x81, 0x5B, 0x42, 0x7A, 0x57, 0x86, 0x12, 0x46, 0x26, 0x79, 0x46, 0x06, 0x11, 0x00, - 0x00, 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, - 0x3C, 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, - 0xE4, 0x8C, 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0xA1, - 0x1C, 0x34, 0x1B, 0x24, 0x4A, 0x82, 0xE7, 0x27, 0x85, 0x50, 0x08, 0x0C, 0x3D, 0x12, 0xBC, 0xC4, - 0xA3, 0x18, 0x12, 0x08, 0x14, 0x86, 0xC1, 0x80, 0xC9, 0x31, 0x18, 0x0E, 0x84, 0x81, 0x80, 0xBA, - 0x91, 0x46, 0xB1, 0x51, 0x06, 0xD7, 0x62, 0x40, 0x9A, 0x91, 0xE2, 0x71, 0xA5, 0x37, 0x40, 0x33, - 0xDE, 0xE9, 0xF1, 0xE3, 0xA1, 0x20, 0x10, 0x0E, 0x52, 0x01, 0x63, 0xA9, 0x5E, 0x0C, 0x85, 0x03, - 0x76, 0x7A, 0x7D, 0x0B, 0x4E, 0x03, 0x75, 0x78, 0x77, 0x78, 0x06, 0x84, 0x51, 0x37, 0x8A, 0x77, - 0x02, 0x51, 0x6A, 0x05, 0x02, 0x04, 0x67, 0x67, 0x5B, 0x72, 0x47, 0x98, 0x98, 0x7C, 0x5C, 0x73, - 0x66, 0x58, 0x07, 0x8B, 0x0F, 0x00, 0x9F, 0x45, 0x02, 0x01, 0x03, 0xA3, 0x0C, 0x89, 0x03, 0x06, - 0x02, 0x00, 0x5C, 0x06, 0x01, 0x92, 0x52, 0x07, 0xAE, 0x59, 0x03, 0x00, 0xBD, 0xBD, 0x4C, 0x02, - 0x05, 0xAB, 0xB9, 0x70, 0x0C, 0xAC, 0x96, 0x00, 0x52, 0x45, 0x36, 0xC1, 0x51, 0x97, 0x0C, 0x66, - 0x5E, 0x00, 0x8C, 0x4C, 0x0A, 0x05, 0x5F, 0x68, 0x98, 0x4E, 0x56, 0x40, 0x7F, 0x3D, 0x67, 0x97, - 0x9D, 0x73, 0x39, 0x02, 0x74, 0x9C, 0x48, 0xA4, 0x76, 0x76, 0x66, 0x73, 0xA8, 0x2C, 0x05, 0x50, - 0x02, 0xA3, 0xA3, 0x59, 0x78, 0x5E, 0x92, 0xD4, 0x2C, 0xDB, 0xB0, 0x59, 0x76, 0x07, 0x00, 0x78, - 0x16, 0x09, 0x80, 0xF5, 0xE4, 0x05, 0xC1, 0x81, 0x5F, 0xB0, 0x10, 0x00, 0xA0, 0xEE, 0xC0, 0xC0, - 0x03, 0x8E, 0x68, 0x68, 0xB1, 0x72, 0xE5, 0x92, 0xAF, 0x5E, 0xF6, 0x0C, 0x10, 0xF0, 0x86, 0x62, - 0xFB, 0xCE, 0xC1, 0x03, 0x98, 0x00, 0x74, 0x42, 0x42, 0xE7, 0xC5, 0xB9, 0x4E, 0xFF, 0xC2, 0x9D, - 0x99, 0xA3, 0x60, 0x0A, 0x0A, 0x03, 0xED, 0xC0, 0xDD, 0xF1, 0x47, 0xCF, 0xCB, 0x2E, 0x97, 0x20, - 0x92, 0x0D, 0x64, 0x85, 0xA5, 0x65, 0x43, 0x2C, 0x3C, 0x19, 0x10, 0x30, 0x94, 0x2F, 0x27, 0xBE, - 0x9D, 0x87, 0x78, 0xCE, 0x54, 0x47, 0xC0, 0x98, 0xC6, 0x9D, 0x39, 0x2F, 0xC6, 0xB2, 0xF1, 0x87, - 0x29, 0x96, 0x62, 0xC6, 0xB6, 0x69, 0xE2, 0xC0, 0x2B, 0x4A, 0x2C, 0x58, 0x49, 0x47, 0xDA, 0x11, - 0x6A, 0x69, 0xC0, 0xB8, 0x10, 0x22, 0x1F, 0xDC, 0x0A, 0xF4, 0x6D, 0x64, 0x02, 0x06, 0xB1, 0x04, - 0x28, 0x39, 0xBB, 0xA1, 0xDD, 0x49, 0x4C, 0xE9, 0xD4, 0xB9, 0x4D, 0x0A, 0xA2, 0x40, 0x81, 0x91, - 0x81, 0x68, 0x2E, 0x35, 0x43, 0xA0, 0xC0, 0x50, 0x05, 0x1F, 0x6A, 0x39, 0xB9, 0x65, 0x47, 0x4A, - 0xBF, 0xBC, 0xF4, 0xF0, 0x04, 0xE3, 0x98, 0xA1, 0x96, 0x02, 0x5B, 0x5E, 0x71, 0xA5, 0x53, 0xA8, - 0x4E, 0x68, 0x16, 0x2B, 0x01, 0xFC, 0x42, 0x29, 0x4A, 0x21, 0xF4, 0xE8, 0x87, 0x0A, 0xA5, 0x04, - 0xDA, 0xDC, 0x94, 0x95, 0x6A, 0x03, 0xC2, 0x5A, 0x6E, 0xF0, 0x66, 0xC8, 0x0E, 0xC0, 0x99, 0x20, - 0xDF, 0x16, 0x93, 0xAC, 0x91, 0x64, 0x16, 0x0B, 0xED, 0x14, 0x70, 0xF2, 0xC2, 0x6B, 0x75, 0x27, - 0x68, 0x81, 0xDA, 0x90, 0xB4, 0x0B, 0xDC, 0x74, 0xC8, 0x8B, 0x67, 0xB0, 0xBC, 0x75, 0x2B, 0xCC, - 0x5D, 0xA1, 0x00, 0xD8, 0x09, 0xC4, 0x3D, 0x23, 0x92, 0xB0, 0x6B, 0x29, 0xDA, 0x6A, 0x55, 0x12, - 0x46, 0x7A, 0x41, 0xA5, 0x81, 0xF8, 0x62, 0x25, 0xE8, 0x4E, 0x2A, 0x60, 0x22, 0x52, 0x05, 0xB4, - 0xB4, 0x94, 0x14, 0xAC, 0x12, 0x05, 0xBF, 0xCD, 0xB4, 0x60, 0xA7, 0x6F, 0x66, 0x65, 0xE7, 0x57, - 0xC7, 0xA3, 0xC8, 0x67, 0x85, 0x16, 0x5B, 0x49, 0xF0, 0x84, 0x2A, 0x48, 0x19, 0x92, 0x47, 0x30, - 0x4E, 0x00, 0x60, 0xC9, 0x57, 0x71, 0x79, 0x03, 0x51, 0x30, 0xD3, 0x4C, 0xA0, 0xC0, 0x4E, 0xA4, - 0x1C, 0x45, 0x51, 0x2C, 0x7E, 0x39, 0xB8, 0x18, 0x3E, 0x04, 0xB5, 0x04, 0x14, 0x6C, 0xB3, 0xF8, - 0xF1, 0xC7, 0x3C, 0x00, 0xAA, 0xC6, 0xCB, 0x45, 0xFC, 0x21, 0xD5, 0x52, 0x72, 0x17, 0x95, 0x88, - 0xD8, 0x09, 0x08, 0x00, 0x80, 0x00, 0x02, 0x28, 0x94, 0x28, 0xC1, 0x8C, 0x20, 0x20, 0xD1, 0x5D, - 0x02, 0x27, 0xE8, 0x88, 0x82, 0x5B, 0x84, 0x2C, 0xE0, 0xD6, 0x19, 0x4C, 0x1C, 0xA9, 0xA4, 0x19, - 0x1B, 0x44, 0x00, 0x00, 0x21, 0xFE, 0x19, 0x42, 0x6F, 0x79, 0x27, 0x73, 0x20, 0x48, 0x61, 0x70, - 0x70, 0x79, 0x20, 0x48, 0x6F, 0x6C, 0x69, 0x64, 0x61, 0x79, 0x73, 0x20, 0x50, 0x61, 0x67, 0x65, - 0x00, 0x3B - -}; - -static const uint8_t bird_gif[] PROGMEM = { - 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x74, 0x00, 0x4E, 0x00, 0xCC, 0x13, 0x00, 0xFF, 0xFF, 0xFF, - 0xEF, 0xFF, 0xFF, 0xBD, 0xE7, 0xE7, 0xD6, 0xEF, 0xEF, 0x63, 0x63, 0x63, 0xAD, 0xAD, 0xAD, 0xCE, - 0xCE, 0xCE, 0xD6, 0xDE, 0xDE, 0x4A, 0x4A, 0x4A, 0x7B, 0x84, 0x84, 0x94, 0x9C, 0x9C, 0xE7, 0xE7, - 0xE7, 0x84, 0x94, 0x94, 0xB5, 0xC6, 0xC6, 0x73, 0x7B, 0x7B, 0x31, 0x31, 0x31, 0xF7, 0xF7, 0xF7, - 0x18, 0x10, 0x10, 0xCE, 0x63, 0x39, 0x6B, 0x39, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xFF, 0x0B, - 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x4B, - 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0xAE, 0xEC, 0x68, 0x2C, - 0x6D, 0x2C, 0xCF, 0x74, 0x6D, 0x03, 0x46, 0x84, 0x40, 0x77, 0xEF, 0xFF, 0x40, 0x51, 0x42, 0x41, - 0x0C, 0x1A, 0x8F, 0x48, 0x13, 0xC1, 0xD0, 0x20, 0x00, 0x0E, 0x8E, 0x42, 0x72, 0x4A, 0xAD, 0x21, - 0x0E, 0xCD, 0x05, 0xE1, 0x80, 0xA8, 0x7A, 0xBF, 0x29, 0xC2, 0xA0, 0x91, 0x28, 0x34, 0x02, 0x5D, - 0xB0, 0x5A, 0xFD, 0x08, 0x34, 0x14, 0x84, 0x00, 0x7A, 0x4D, 0xF7, 0x22, 0xDC, 0x89, 0xB8, 0xC1, - 0xB9, 0x80, 0xD5, 0xFF, 0x40, 0x0B, 0x77, 0x0C, 0x0F, 0x05, 0x01, 0x0C, 0x0A, 0x0B, 0x0F, 0x08, - 0x06, 0x80, 0x8E, 0x37, 0x7B, 0x01, 0x09, 0x11, 0x03, 0x68, 0x5C, 0x4C, 0x0A, 0x8F, 0x9A, 0x33, - 0x06, 0x09, 0x01, 0x0E, 0x71, 0x68, 0x88, 0x92, 0x07, 0x9B, 0xA6, 0x2C, 0x0A, 0x86, 0x07, 0x95, - 0x05, 0x04, 0xA1, 0x5D, 0x8D, 0xA7, 0xB2, 0x26, 0x09, 0x06, 0x72, 0x72, 0x0E, 0x94, 0x01, 0xA9, - 0x04, 0x08, 0x52, 0xB3, 0xC0, 0x00, 0x09, 0x95, 0xB7, 0x0D, 0x86, 0x01, 0x04, 0x0A, 0xC3, 0x09, - 0x34, 0x43, 0xC1, 0x54, 0x0E, 0xB7, 0xD2, 0x87, 0xAE, 0xBB, 0x99, 0x32, 0x7B, 0x0E, 0xCF, 0x49, - 0x0B, 0xD1, 0xD3, 0x72, 0x0C, 0xDE, 0x57, 0x33, 0xBE, 0xCC, 0xDB, 0x47, 0x05, 0x0C, 0xDF, 0xD3, - 0x05, 0xD7, 0x31, 0x0C, 0xE1, 0xA5, 0xE7, 0x46, 0xBE, 0xEB, 0xD2, 0x04, 0x05, 0xBF, 0x2C, 0x5C, - 0x4D, 0xF3, 0x46, 0x0B, 0x11, 0x56, 0xD9, 0x3B, 0x14, 0x01, 0x14, 0x0F, 0x16, 0x04, 0x1A, 0x30, - 0x28, 0x00, 0x81, 0xA1, 0x3F, 0x1F, 0xAD, 0x02, 0x10, 0x5B, 0x87, 0x6F, 0x0E, 0x8B, 0x02, 0x0E, - 0x04, 0x5C, 0x41, 0x10, 0xF0, 0x61, 0x8F, 0x25, 0x03, 0x26, 0xDA, 0x43, 0xC4, 0x42, 0x8B, 0x00, - 0x05, 0x0E, 0x7C, 0xFF, 0xED, 0xF0, 0x68, 0x83, 0x8B, 0x44, 0x91, 0xDF, 0x06, 0xAC, 0x54, 0x01, - 0x21, 0xA1, 0x80, 0x07, 0x0F, 0x1A, 0x38, 0x70, 0xC7, 0x72, 0x46, 0xC2, 0x97, 0x03, 0x3F, 0xC5, - 0x52, 0xE1, 0x80, 0x81, 0x00, 0x01, 0x19, 0x1B, 0x3C, 0x38, 0xD8, 0x53, 0xC6, 0x81, 0x38, 0x21, - 0x61, 0x4A, 0xEB, 0xB7, 0x42, 0x01, 0x82, 0xA3, 0x58, 0x7D, 0xC9, 0x6B, 0x1A, 0x63, 0x0B, 0xD0, - 0x81, 0x11, 0x08, 0x74, 0x44, 0x61, 0xE0, 0x01, 0xD6, 0xA3, 0x05, 0x16, 0x2D, 0xE5, 0xDA, 0xC2, - 0x80, 0xB7, 0x90, 0x41, 0xCB, 0xA4, 0x39, 0xC1, 0xEF, 0x2C, 0x56, 0xAA, 0x6C, 0x57, 0x38, 0xA8, - 0x14, 0x35, 0xA8, 0x35, 0x14, 0x10, 0x10, 0x34, 0xB0, 0x9B, 0xD5, 0x4F, 0xDE, 0x14, 0x06, 0x8E, - 0xF5, 0x1D, 0xC8, 0x25, 0x85, 0x83, 0xC1, 0x84, 0x05, 0x20, 0x32, 0x30, 0xF4, 0x30, 0x2D, 0x39, - 0x8B, 0x07, 0x32, 0x42, 0xA1, 0x00, 0x72, 0xE4, 0x45, 0x08, 0x7C, 0x59, 0x36, 0x91, 0x18, 0x73, - 0xE6, 0x6F, 0x79, 0x38, 0x2B, 0x88, 0x7C, 0x54, 0xE7, 0xE0, 0x2D, 0xA3, 0x4B, 0x78, 0x7A, 0x79, - 0x7A, 0x1A, 0xCE, 0x04, 0x4C, 0x85, 0xAC, 0x66, 0x7D, 0x96, 0x80, 0xB9, 0xD8, 0x22, 0x4A, 0x4B, - 0x14, 0x00, 0x97, 0xF1, 0xD3, 0x12, 0x3B, 0x79, 0x9F, 0x45, 0xC0, 0x13, 0xB8, 0xB7, 0xE1, 0xC5, - 0x19, 0x33, 0xEB, 0x53, 0xD3, 0xA8, 0x72, 0x01, 0x0D, 0x44, 0x97, 0x5C, 0x90, 0x7B, 0x9B, 0x01, - 0x05, 0xA6, 0x89, 0xFB, 0x3D, 0x54, 0x20, 0x81, 0xDA, 0x8C, 0xD7, 0x91, 0x16, 0x22, 0x91, 0xF8, - 0x80, 0x9F, 0x86, 0x08, 0x1E, 0xF4, 0xF2, 0xD5, 0x7D, 0x96, 0x18, 0xCC, 0x47, 0xA3, 0xDB, 0x7B, - 0xCA, 0x60, 0x40, 0xCA, 0xF4, 0x58, 0x81, 0xE2, 0x42, 0x04, 0x11, 0x4C, 0x80, 0x53, 0x7C, 0x3F, - 0xC9, 0xB1, 0xC7, 0xFF, 0x7A, 0xC1, 0x18, 0xA0, 0x0E, 0x7E, 0xC4, 0x49, 0xA5, 0x99, 0x67, 0xD7, - 0xA5, 0xB4, 0x15, 0x04, 0x93, 0x48, 0xA0, 0xA1, 0x81, 0x7C, 0x49, 0xB3, 0xC7, 0x38, 0xF6, 0x11, - 0x13, 0x52, 0x7E, 0x12, 0xAE, 0x63, 0xC0, 0x55, 0x00, 0x82, 0x62, 0xD8, 0x08, 0x0B, 0x24, 0xA0, - 0xA1, 0x86, 0x57, 0x3C, 0xF0, 0xE0, 0x2D, 0x05, 0x68, 0x67, 0x4A, 0x27, 0xB7, 0x0C, 0x80, 0x95, - 0x7E, 0x41, 0x11, 0x80, 0x5E, 0x85, 0xBF, 0x9D, 0xD0, 0xC0, 0x04, 0x2F, 0x2E, 0x62, 0xCB, 0x34, - 0x03, 0xE4, 0xB1, 0xA2, 0x23, 0x5E, 0x41, 0xC8, 0x63, 0x50, 0x0E, 0x9A, 0x75, 0x5D, 0x68, 0x5B, - 0x9D, 0xA0, 0x45, 0x04, 0x38, 0x2D, 0x72, 0xCC, 0x34, 0x7B, 0x24, 0xF2, 0x88, 0x5B, 0x39, 0xEA, - 0x18, 0xE1, 0x78, 0xD2, 0x58, 0x05, 0x20, 0x6C, 0x2B, 0xD4, 0x78, 0x64, 0x89, 0x6E, 0xB8, 0xF2, - 0xC2, 0x1F, 0x4D, 0xBE, 0x44, 0x22, 0x99, 0x72, 0xE4, 0x01, 0x60, 0x19, 0x31, 0x68, 0xB1, 0xC4, - 0x78, 0x50, 0xF4, 0xE2, 0x9B, 0x43, 0x5E, 0x80, 0x99, 0xE3, 0x8E, 0x6C, 0x4E, 0xE3, 0x63, 0x7A, - 0xD9, 0x55, 0xD6, 0x82, 0x4E, 0x04, 0x30, 0xD0, 0xC0, 0x01, 0x7C, 0x2A, 0xE4, 0xA3, 0xA2, 0x47, - 0xDC, 0x37, 0xE8, 0x9C, 0xE3, 0xC9, 0x64, 0x9D, 0x72, 0x70, 0x54, 0x29, 0x03, 0x04, 0xDF, 0xE5, - 0xE1, 0x4A, 0x19, 0x06, 0xB0, 0xD9, 0xC4, 0x66, 0x48, 0x7C, 0x27, 0xCD, 0x88, 0x98, 0x92, 0x89, - 0xE2, 0x75, 0x69, 0x2D, 0x69, 0xC3, 0x02, 0x07, 0xA4, 0x03, 0x8A, 0x2B, 0x8E, 0xC2, 0x04, 0x05, - 0x03, 0x48, 0x3C, 0x17, 0x5E, 0xAB, 0x7E, 0x61, 0x04, 0x20, 0x03, 0x33, 0x21, 0x01, 0xC1, 0x02, - 0xDF, 0x81, 0x52, 0x8B, 0x34, 0xAD, 0xC8, 0x6A, 0x43, 0x3E, 0x48, 0x9E, 0xF5, 0x24, 0x45, 0xAF, - 0xF2, 0x96, 0x9D, 0xFF, 0x03, 0xF5, 0x51, 0xD1, 0xA2, 0x03, 0x90, 0xCA, 0xF1, 0x94, 0x3E, 0x37, - 0x68, 0x81, 0xA4, 0x98, 0xC0, 0x9A, 0xF8, 0xC0, 0x8F, 0xCA, 0x39, 0xA0, 0xCD, 0x1F, 0x0B, 0x10, - 0x21, 0x0D, 0x03, 0xB8, 0x7D, 0x74, 0x64, 0x98, 0xD2, 0x16, 0x8A, 0x0C, 0xBA, 0xCA, 0x29, 0xF5, - 0x48, 0x8B, 0x53, 0xA1, 0x19, 0x03, 0xA8, 0x18, 0x85, 0xB2, 0x2A, 0xB9, 0x63, 0x06, 0x45, 0x06, - 0x80, 0x48, 0x05, 0xC9, 0x6E, 0x9C, 0x4F, 0xE1, 0xA3, 0xC2, 0x77, 0xF0, 0x16, 0x95, 0x4B, 0xB7, - 0xF4, 0x12, 0xEA, 0x57, 0x59, 0x14, 0xB2, 0x46, 0x08, 0xB8, 0x8E, 0x08, 0x72, 0x06, 0xB3, 0x3E, - 0xA6, 0xF2, 0x28, 0x46, 0x8B, 0x2C, 0xEB, 0xED, 0x03, 0xF3, 0x56, 0x5C, 0xF0, 0x40, 0xE6, 0xED, - 0xA6, 0x9C, 0x7C, 0xD9, 0x02, 0xA2, 0x48, 0xCA, 0x98, 0x25, 0xD6, 0xCE, 0x4E, 0x14, 0x2B, 0x18, - 0xE7, 0xC0, 0xE5, 0xAE, 0x93, 0x00, 0xC2, 0x45, 0x01, 0xB3, 0xC0, 0x8C, 0x74, 0xFA, 0xF7, 0x80, - 0x84, 0xAC, 0xAE, 0x6C, 0xCF, 0x00, 0x04, 0xA4, 0x47, 0x2C, 0x02, 0xCE, 0x6A, 0xF2, 0x06, 0x9D, - 0x98, 0xE5, 0x3C, 0xB0, 0x98, 0xB5, 0x4D, 0xD3, 0x40, 0x04, 0x05, 0x28, 0x57, 0x40, 0x04, 0x0A, - 0x50, 0x2A, 0x4B, 0x02, 0x1F, 0x53, 0xBD, 0x74, 0x54, 0x59, 0xBF, 0x1B, 0x5A, 0x41, 0xAC, 0x65, - 0xA7, 0xF0, 0x33, 0x0C, 0x58, 0x6D, 0xB6, 0x69, 0x68, 0x4F, 0x2B, 0x87, 0x55, 0xB7, 0x38, 0x50, - 0xC8, 0x5D, 0x7E, 0x8A, 0x1D, 0x0C, 0x04, 0x8F, 0xCD, 0x1D, 0x94, 0xDD, 0x4F, 0xA1, 0xEC, 0xA1, - 0x7C, 0xAD, 0x8D, 0xC5, 0x52, 0x4D, 0xBE, 0x0A, 0x3E, 0x9E, 0x55, 0x32, 0xDA, 0xA3, 0x37, 0x03, - 0xBD, 0x44, 0x3D, 0x8F, 0x55, 0x34, 0x3B, 0x6E, 0x4F, 0x03, 0x99, 0x73, 0x89, 0x93, 0xE5, 0xFE, - 0x74, 0x13, 0xB7, 0xCB, 0xE6, 0xA4, 0x4B, 0x63, 0x90, 0x65, 0xED, 0x16, 0x25, 0x77, 0xE9, 0x54, - 0x67, 0x11, 0xDB, 0x89, 0x44, 0xB3, 0x6E, 0xF6, 0x89, 0x7E, 0x37, 0x05, 0x47, 0xE7, 0xB2, 0xFB, - 0xF5, 0x2D, 0x70, 0xDD, 0x80, 0x37, 0xDE, 0x0A, 0x8E, 0xFB, 0x06, 0x1C, 0x00, 0x4D, 0xE0, 0x1E, - 0x80, 0x0C, 0x73, 0xFB, 0x47, 0x00, 0xE8, 0x2C, 0x89, 0x6E, 0xCF, 0x0C, 0x66, 0x87, 0x64, 0x55, - 0x73, 0x87, 0xB5, 0xD2, 0x39, 0xF2, 0x54, 0xA3, 0xAD, 0x24, 0xEF, 0x09, 0xC4, 0x2E, 0x47, 0x0C, - 0x83, 0x4F, 0x44, 0x6E, 0x25, 0xA9, 0x0C, 0x8F, 0x43, 0xE0, 0xD3, 0xB4, 0x30, 0x50, 0x54, 0xF9, - 0x41, 0x57, 0xC9, 0x63, 0xE6, 0x03, 0x00, 0xC1, 0xED, 0xE9, 0xAB, 0x60, 0x4F, 0x62, 0x94, 0x41, - 0x2A, 0xFE, 0x01, 0x56, 0x11, 0x10, 0xB3, 0x65, 0x4F, 0x11, 0xCC, 0x37, 0x4A, 0x10, 0x2C, 0x8E, - 0x3C, 0x80, 0x40, 0x3A, 0x30, 0x20, 0x02, 0x96, 0x10, 0x3F, 0x13, 0x64, 0xA7, 0x1E, 0x17, 0x53, - 0x90, 0x02, 0x28, 0x87, 0x00, 0xB2, 0xC1, 0xE0, 0x29, 0x08, 0x24, 0x50, 0xC9, 0xFE, 0x37, 0x3C, - 0x28, 0x30, 0x67, 0x75, 0x01, 0x9C, 0x20, 0x4E, 0x0A, 0xE0, 0xAC, 0xAF, 0x21, 0x90, 0x3E, 0x0D, - 0x4C, 0x41, 0xBB, 0x42, 0x13, 0x05, 0x63, 0xA4, 0x64, 0x81, 0x43, 0x28, 0x40, 0xED, 0x44, 0x00, - 0x01, 0x2C, 0x78, 0x29, 0x85, 0x2C, 0x38, 0x56, 0x62, 0x1A, 0xC0, 0x1D, 0x35, 0x84, 0x00, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, - 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, - 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, - 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, - 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, - 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, - 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, - 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, - 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, - 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, - 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, - 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, - 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, - 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, - 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, - 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, - 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, - 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, - 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, - 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, - 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, - 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, - 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, - 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, - 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, - 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, - 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, - 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, - 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, - 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, - 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, - 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, - 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, - 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, - 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, - 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, - 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, - 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, - 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, - 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, - 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, - 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, - 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, - 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, - 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, - 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, - 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, - 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, - 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, - 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, - 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, - 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, - 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, - 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, - 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, - 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, - 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, - 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, - 0x0D, 0x21, 0x00, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, - 0x00, 0x6A, 0x00, 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, - 0xAE, 0x6C, 0xEB, 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, - 0x0A, 0xC7, 0x03, 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, - 0xA4, 0x10, 0xA8, 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, - 0x9E, 0x18, 0x02, 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, - 0xD4, 0x81, 0x01, 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, - 0x0D, 0x08, 0x05, 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, - 0x04, 0x06, 0x10, 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, - 0x93, 0x09, 0x0C, 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, - 0x0C, 0x39, 0x9A, 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, - 0xAB, 0x5B, 0x4A, 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, - 0x0D, 0x0D, 0x07, 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, - 0x0E, 0x7B, 0x04, 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, - 0x92, 0x0C, 0x0E, 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, - 0x5B, 0x03, 0x0E, 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, - 0x98, 0xBE, 0x73, 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, - 0xB0, 0x6A, 0xA3, 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, - 0xBC, 0xA5, 0x0C, 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, - 0x04, 0x32, 0x53, 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, - 0x67, 0x8E, 0xA2, 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, - 0x33, 0xA0, 0x2B, 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, - 0x0E, 0x10, 0xC0, 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, - 0x0A, 0x08, 0xF8, 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, - 0x1D, 0x8A, 0x47, 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, - 0x22, 0x22, 0x82, 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, - 0x6B, 0x50, 0xE0, 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, - 0xA3, 0x2D, 0x60, 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, - 0x94, 0x14, 0x7F, 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, - 0x05, 0x30, 0x4A, 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, - 0x53, 0x20, 0xC1, 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, - 0x10, 0x03, 0x80, 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, - 0x26, 0x0F, 0x28, 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, - 0xC6, 0x0A, 0x02, 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, - 0xA0, 0xC0, 0x28, 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, - 0x42, 0x01, 0x5A, 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, - 0x88, 0x33, 0x14, 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, - 0x6A, 0xC4, 0x80, 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, - 0x28, 0xC2, 0xE2, 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, - 0x21, 0xA4, 0x0C, 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, - 0x4A, 0x93, 0x29, 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, - 0x94, 0x0C, 0x38, 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, - 0x56, 0x74, 0x54, 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, - 0x99, 0x83, 0x8A, 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, - 0x10, 0x02, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, - 0x6A, 0x00, 0x2E, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x00, 0x40, 0x62, 0xB9, 0x28, 0x08, 0x41, 0x28, - 0x4B, 0xE9, 0xBE, 0x70, 0x2C, 0xCF, 0x74, 0x6D, 0xDF, 0xE5, 0xF1, 0x3C, 0x69, 0x52, 0x24, 0x0F, - 0x82, 0xE1, 0x60, 0x00, 0x26, 0x5A, 0xB8, 0xA4, 0x72, 0xC9, 0x94, 0xE9, 0x22, 0x12, 0xC9, 0x64, - 0xF2, 0x18, 0x04, 0xAE, 0xD7, 0x01, 0xB0, 0xD0, 0xEC, 0x7A, 0xBF, 0x31, 0x48, 0x61, 0x12, 0x95, - 0x32, 0x02, 0x8E, 0x06, 0x36, 0x70, 0x50, 0x21, 0xC1, 0xF0, 0x78, 0x72, 0x91, 0x20, 0x4B, 0x55, - 0x85, 0xF5, 0xB5, 0x81, 0xE0, 0xCA, 0xFF, 0x80, 0x32, 0x0D, 0x0F, 0x53, 0x11, 0x11, 0x04, 0x07, - 0x7A, 0x57, 0x0E, 0x04, 0x6F, 0x81, 0x8F, 0x7F, 0x0B, 0x2A, 0x06, 0x94, 0x6A, 0x8A, 0x01, 0x06, - 0x04, 0x05, 0x07, 0x0B, 0x0B, 0x44, 0x94, 0xA0, 0x43, 0x24, 0x90, 0xA4, 0x37, 0x05, 0x04, 0x96, - 0x97, 0x58, 0x45, 0x09, 0x0A, 0x0C, 0x0C, 0x0A, 0x05, 0x0D, 0xB3, 0x05, 0x0A, 0x09, 0x0C, 0x05, - 0x06, 0xA3, 0x4D, 0x9F, 0xA0, 0x0B, 0xBB, 0xA5, 0x33, 0x6D, 0x08, 0x0C, 0x89, 0xAA, 0xC7, 0x8A, - 0x07, 0xAE, 0x3E, 0xC0, 0x32, 0x10, 0x07, 0x3F, 0x2A, 0x0E, 0x8C, 0x2A, 0x08, 0xD6, 0x29, 0x0E, - 0xB9, 0xCD, 0xC1, 0x22, 0x10, 0x45, 0xD2, 0xB8, 0x07, 0x56, 0x97, 0x22, 0xC8, 0x01, 0x0D, 0x0C, - 0x3E, 0x9C, 0x25, 0xCF, 0xA7, 0x04, 0xD9, 0xE2, 0xC8, 0x03, 0xD0, 0x09, 0x04, 0xD6, 0x09, 0xBA, - 0xDC, 0x30, 0x10, 0x0B, 0x06, 0xB6, 0x2A, 0x04, 0x12, 0xDC, 0x52, 0x40, 0x90, 0x60, 0x81, 0x5C, - 0x07, 0x20, 0xA8, 0x1A, 0xD0, 0x20, 0x01, 0x35, 0x07, 0x3C, 0x1C, 0x18, 0x30, 0x87, 0xCC, 0x00, - 0x03, 0x02, 0x0F, 0x12, 0x34, 0xD8, 0xA6, 0xCF, 0x44, 0xA7, 0x8F, 0x9D, 0x0E, 0x88, 0xAC, 0x75, - 0x6B, 0x22, 0xC5, 0x4B, 0x44, 0x4E, 0xFF, 0x26, 0x63, 0x80, 0x20, 0xE3, 0x81, 0x8E, 0x5D, 0x0E, - 0xA4, 0x33, 0xA6, 0x92, 0x8D, 0x03, 0x04, 0x35, 0x2F, 0x35, 0xC0, 0x98, 0xE0, 0x25, 0x4C, 0x26, - 0x07, 0x7C, 0xE4, 0xBC, 0x82, 0x40, 0xE1, 0x50, 0x3D, 0xCA, 0x52, 0x38, 0xFA, 0x89, 0xE3, 0x47, - 0xCE, 0x1F, 0x00, 0x8E, 0xAA, 0x02, 0xC2, 0x80, 0xE9, 0x92, 0x86, 0x2A, 0x0D, 0x3C, 0xA0, 0x29, - 0x55, 0xD1, 0x00, 0x8C, 0x06, 0xAC, 0x26, 0x31, 0x80, 0xC0, 0x24, 0x32, 0x04, 0x09, 0xBA, 0x9A, - 0x1B, 0x94, 0x80, 0xA3, 0x58, 0x18, 0x5A, 0xCF, 0x1C, 0x13, 0x78, 0x69, 0x9C, 0xDA, 0x2C, 0x04, - 0x22, 0x34, 0x78, 0x6B, 0x03, 0x82, 0x02, 0x44, 0x97, 0x5E, 0xD5, 0x1D, 0x60, 0xF7, 0xEE, 0xB9, - 0x07, 0x61, 0xF9, 0xD6, 0x58, 0xC0, 0x20, 0xDB, 0x1A, 0x82, 0x0B, 0x09, 0x17, 0xBE, 0xFB, 0x55, - 0x81, 0xE2, 0x1B, 0x99, 0x10, 0x39, 0xF6, 0x2A, 0x99, 0xB0, 0x61, 0x3D, 0x0E, 0x2F, 0xDF, 0x18, - 0x94, 0x87, 0xF3, 0x00, 0x01, 0x02, 0x24, 0x7F, 0x7E, 0x8C, 0x60, 0xA9, 0x68, 0x17, 0x6D, 0xCC, - 0x62, 0x91, 0x8C, 0x1A, 0x75, 0xE7, 0x2B, 0x30, 0xBA, 0xF2, 0xF1, 0xF9, 0xDA, 0x45, 0x26, 0xAE, - 0x59, 0x4E, 0xD7, 0x4E, 0xED, 0x19, 0xF7, 0x8C, 0xA3, 0x5A, 0xF7, 0xF6, 0x16, 0xF1, 0xC3, 0x68, - 0x70, 0xE1, 0xC3, 0x8B, 0xAF, 0xA1, 0x31, 0xF4, 0xB4, 0xD2, 0xD7, 0x10, 0x60, 0xE9, 0x21, 0x3C, - 0x3C, 0xFA, 0x64, 0xE3, 0x32, 0x6A, 0xD2, 0x56, 0xF0, 0xC0, 0x0F, 0x5F, 0x3A, 0xA9, 0x02, 0x70, - 0xEF, 0x4E, 0x5C, 0x3A, 0x68, 0xD7, 0xE5, 0x54, 0x72, 0xB7, 0xF2, 0xD5, 0xBC, 0xD5, 0xA0, 0x34, - 0xD7, 0xDB, 0x6E, 0xAF, 0x5A, 0x95, 0x03, 0xDE, 0x2F, 0x98, 0x73, 0xDB, 0x70, 0x01, 0xC4, 0xF2, - 0x96, 0x45, 0xB3, 0x41, 0x67, 0x5B, 0xFF, 0x7F, 0xE6, 0x00, 0x20, 0x51, 0x0C, 0xF2, 0xD0, 0x47, - 0x9C, 0x7A, 0xEA, 0x91, 0x07, 0x20, 0x4C, 0x05, 0xC8, 0xA5, 0x9E, 0x70, 0xA7, 0x31, 0x78, 0x92, - 0x24, 0x89, 0xB9, 0x70, 0x4C, 0x26, 0x41, 0x04, 0xA4, 0x40, 0x03, 0x19, 0x32, 0x72, 0xC8, 0x85, - 0x1D, 0xB9, 0x92, 0x20, 0x7F, 0xEE, 0x9D, 0x94, 0xE1, 0x49, 0x0C, 0xDD, 0x84, 0x16, 0x79, 0x11, - 0xF4, 0x11, 0x0B, 0x42, 0x62, 0x41, 0x70, 0xCB, 0x73, 0x1E, 0x0E, 0xE5, 0x20, 0x70, 0x7B, 0x10, - 0x40, 0x58, 0x5E, 0xC4, 0xE4, 0x23, 0x42, 0x02, 0x86, 0x34, 0xA2, 0x98, 0x24, 0x0A, 0x00, 0x19, - 0x63, 0x4E, 0xFD, 0x10, 0x43, 0x93, 0x32, 0x79, 0xF1, 0x90, 0x42, 0x88, 0x2E, 0x2C, 0xF0, 0x80, - 0x21, 0x0F, 0x30, 0x00, 0x5F, 0x30, 0x62, 0xF4, 0xB1, 0x61, 0x90, 0x47, 0x39, 0x18, 0xCB, 0x3F, - 0xEF, 0xF8, 0x60, 0xC0, 0x2F, 0x36, 0x3C, 0xB1, 0x22, 0x53, 0x99, 0x20, 0x90, 0x08, 0x9A, 0x5D, - 0x79, 0xD9, 0x80, 0x00, 0x29, 0xB4, 0xD6, 0x04, 0x59, 0x2C, 0xFC, 0x24, 0x13, 0x2A, 0x78, 0x76, - 0xF5, 0x95, 0x03, 0x0C, 0xA0, 0xA6, 0xA3, 0x17, 0x6E, 0x3D, 0xB2, 0xC0, 0x0F, 0x0A, 0x10, 0xB9, - 0xDA, 0x39, 0x08, 0x08, 0x90, 0x86, 0x00, 0x4E, 0x2E, 0x17, 0x86, 0x3B, 0xA5, 0x4D, 0xAA, 0x87, - 0x42, 0xAF, 0x0C, 0xE2, 0x00, 0xA6, 0x63, 0x8A, 0xF6, 0xA8, 0x0A, 0x91, 0x06, 0xF0, 0x4B, 0x9E, - 0xCE, 0x29, 0xF2, 0x17, 0x4B, 0x96, 0x16, 0x50, 0xA9, 0x9F, 0x9A, 0x02, 0x50, 0x00, 0x23, 0x81, - 0x9E, 0x1A, 0x41, 0x94, 0x47, 0x31, 0x10, 0xE6, 0x01, 0xD3, 0x98, 0xA5, 0x10, 0x2A, 0x2D, 0xF1, - 0x21, 0x46, 0x40, 0xB5, 0xDA, 0x8A, 0xD8, 0x02, 0x0D, 0x21, 0x9A, 0x80, 0x99, 0x98, 0xE0, 0x63, - 0xCE, 0x10, 0x01, 0xC8, 0x7A, 0xC2, 0x79, 0x11, 0x50, 0x65, 0x26, 0x2B, 0x9F, 0x64, 0xF9, 0xD1, - 0xE8, 0x93, 0x29, 0x32, 0x30, 0x84, 0x03, 0x0A, 0x28, 0x04, 0x2C, 0x46, 0x0B, 0x5C, 0x91, 0xAE, - 0x22, 0x64, 0x21, 0xB0, 0x13, 0x30, 0x99, 0xDC, 0xB4, 0xD3, 0xB3, 0xE9, 0x00, 0x50, 0x6A, 0xB2, - 0x00, 0xB4, 0xD1, 0x42, 0x50, 0x42, 0x00, 0xF6, 0x55, 0x51, 0xAA, 0x6A, 0x82, 0x09, 0x22, 0x08, - 0x38, 0xB0, 0x4D, 0xB7, 0x88, 0x2C, 0x60, 0x0D, 0x8B, 0xF8, 0xBE, 0x90, 0x89, 0x02, 0x0E, 0xE0, - 0x03, 0x81, 0xC0, 0x99, 0xDC, 0xAA, 0x2A, 0x44, 0xB3, 0xF8, 0xE9, 0x16, 0x04, 0x08, 0xD8, 0xC2, - 0x1C, 0x97, 0x0D, 0xCB, 0xE0, 0xC9, 0x28, 0x3A, 0x28, 0xF3, 0x5F, 0x6B, 0xBF, 0xD9, 0x72, 0xC4, - 0x62, 0x1D, 0x7F, 0x1B, 0x72, 0x0D, 0xCA, 0xBC, 0xD4, 0x86, 0x2D, 0x3E, 0xB9, 0xBC, 0x5C, 0x08, - 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, 0x6A, 0x00, - 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, 0xAE, 0x6C, 0xEB, - 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, 0x0A, 0xC7, 0x03, - 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, 0xA4, 0x10, 0xA8, - 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, 0x9E, 0x18, 0x02, - 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, 0xD4, 0x81, 0x01, - 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, 0x0D, 0x08, 0x05, - 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, 0x04, 0x06, 0x10, - 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, 0x93, 0x09, 0x0C, - 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, 0x0C, 0x39, 0x9A, - 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, 0xAB, 0x5B, 0x4A, - 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, 0x0D, 0x0D, 0x07, - 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, 0x0E, 0x7B, 0x04, - 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, 0x92, 0x0C, 0x0E, - 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, 0x5B, 0x03, 0x0E, - 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, 0x98, 0xBE, 0x73, - 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, 0xB0, 0x6A, 0xA3, - 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, 0xBC, 0xA5, 0x0C, - 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, 0x04, 0x32, 0x53, - 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, 0x67, 0x8E, 0xA2, - 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, 0x33, 0xA0, 0x2B, - 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, 0x0E, 0x10, 0xC0, - 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, 0x0A, 0x08, 0xF8, - 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, 0x1D, 0x8A, 0x47, - 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, 0x22, 0x22, 0x82, - 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, 0x6B, 0x50, 0xE0, - 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, 0xA3, 0x2D, 0x60, - 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, 0x94, 0x14, 0x7F, - 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, 0x05, 0x30, 0x4A, - 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, 0x53, 0x20, 0xC1, - 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, 0x10, 0x03, 0x80, - 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, 0x26, 0x0F, 0x28, - 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, 0xC6, 0x0A, 0x02, - 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, 0xA0, 0xC0, 0x28, - 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, 0x42, 0x01, 0x5A, - 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, 0x88, 0x33, 0x14, - 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, 0x6A, 0xC4, 0x80, - 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, 0x28, 0xC2, 0xE2, - 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, 0x21, 0xA4, 0x0C, - 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, 0x4A, 0x93, 0x29, - 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, 0x94, 0x0C, 0x38, - 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, 0x56, 0x74, 0x54, - 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, 0x99, 0x83, 0x8A, - 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, 0x10, 0x02, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, - 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, - 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, - 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, - 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, - 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, - 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, - 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, - 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, - 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, - 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, - 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, - 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, - 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, - 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, - 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, - 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, - 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, - 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, - 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, - 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, - 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, - 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, - 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, - 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, - 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, - 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, - 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, - 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, - 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, - 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, - 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, - 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, - 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, - 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, - 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, - 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, - 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, - 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, - 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, - 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, - 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, - 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, - 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, - 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, - 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, - 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, - 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, - 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, - 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, - 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, - 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, - 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, - 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, - 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, - 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, - 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, - 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, - 0x0D, 0x21, 0x00, 0x00, 0x3B}; +#include + +static const uint8_t firebase_logo_png[] PROGMEM = { + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x02, 0x58, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9A, 0x76, 0x82, + 0x70, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, + 0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61, 0x05, 0x00, 0x00, + 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01, 0xC7, + 0x6F, 0xA8, 0x64, 0x00, 0x00, 0x55, 0x14, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5E, 0xED, 0xDD, 0x59, + 0x90, 0x1D, 0xF5, 0x81, 0xE7, 0x7B, 0x3F, 0xF4, 0xC3, 0x84, 0x91, 0x40, 0x6E, 0xEF, 0xC6, 0x8B, + 0x30, 0x92, 0x4A, 0x1B, 0x58, 0x98, 0xCD, 0xA0, 0xA5, 0x4A, 0x12, 0x20, 0x6C, 0x9A, 0xB6, 0xBA, + 0x01, 0x63, 0x4F, 0x3F, 0x8C, 0x1E, 0x26, 0xC2, 0xF7, 0xE5, 0xC6, 0x25, 0xE2, 0xDE, 0x97, 0x3B, + 0x7D, 0x67, 0xAC, 0x6E, 0x63, 0x63, 0x83, 0x8D, 0xBC, 0xB1, 0x99, 0xA5, 0x10, 0x08, 0xED, 0x52, + 0x69, 0xAD, 0x92, 0xA0, 0xBB, 0xAB, 0xA7, 0xED, 0x6E, 0x77, 0xB7, 0x81, 0x42, 0x9B, 0x99, 0x89, + 0x89, 0xDB, 0x9A, 0xB9, 0x0E, 0x2F, 0x2C, 0x76, 0x61, 0x16, 0x49, 0x85, 0xA4, 0xFC, 0xDF, 0xFF, + 0x3F, 0x4F, 0xE6, 0xA9, 0x3C, 0x79, 0x7E, 0xE7, 0x9C, 0xCC, 0x3C, 0x99, 0x75, 0xCE, 0xC9, 0xFA, + 0x7E, 0x22, 0x7E, 0xA1, 0x6E, 0x2F, 0x42, 0xC2, 0x94, 0xE2, 0xFF, 0x8D, 0x7F, 0x65, 0x9E, 0xF7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x82, 0x79, 0x6E, 0xCD, 0x80, 0xBF, 0xC3, 0x5F, 0x58, 0x12, 0xFC, + 0x4B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x1F, 0x73, 0x78, 0xCD, 0x3A, 0xEF, 0xB9, 0x35, 0x63, 0xE6, + 0xB9, 0x9B, 0x4D, 0x75, 0xCF, 0xAE, 0xF1, 0xE7, 0x3D, 0x7B, 0xD3, 0xA0, 0x0B, 0x92, 0xE0, 0x3F, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x98, 0x91, 0x35, 0xB3, 0xEB, 0xC2, 0x23, 0x12, 0x1F, 0xD1, + 0x79, 0x87, 0xD7, 0x6C, 0x08, 0xFE, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x8E, 0xFB, 0x16, 0x2B, + 0xEF, 0xD9, 0x35, 0xE3, 0x95, 0xE0, 0xB8, 0xD1, 0x98, 0x03, 0x57, 0x19, 0xB3, 0x7B, 0xAE, 0x31, + 0x3B, 0x3E, 0x65, 0xCC, 0xB6, 0x8F, 0x1A, 0xB3, 0xF3, 0xD3, 0xC6, 0x0C, 0x2D, 0x34, 0x66, 0x78, + 0xD9, 0x64, 0x84, 0x3C, 0x7B, 0xD3, 0x60, 0xF0, 0x5F, 0x07, 0x00, 0x00, 0x00, 0x80, 0xE4, 0xAA, + 0x37, 0x1F, 0x2E, 0x3C, 0x76, 0x7C, 0xC2, 0x98, 0xED, 0x1F, 0xAB, 0x84, 0x87, 0xDA, 0x2E, 0x1B, + 0x26, 0x87, 0x6F, 0xA8, 0x84, 0xC8, 0xA1, 0x9B, 0xD6, 0x06, 0x3F, 0x05, 0x00, 0x00, 0x00, 0x00, + 0xB4, 0xE6, 0x9E, 0xF9, 0xF0, 0xE3, 0x63, 0xCF, 0xA2, 0x4A, 0x78, 0x34, 0x8B, 0x8F, 0x70, 0xDB, + 0x3F, 0x6E, 0xCC, 0xC8, 0x0A, 0xF7, 0xAD, 0x58, 0xE3, 0x66, 0xB4, 0x7F, 0x56, 0xF0, 0x53, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x73, 0xDE, 0x73, 0x37, 0x9F, 0x34, 0xFB, 0xAF, 0x48, 0x1E, 0x1F, 0xE1, + 0x76, 0x5E, 0x62, 0xCC, 0xE1, 0xD5, 0x76, 0x37, 0xAE, 0x0F, 0x7E, 0x2A, 0x00, 0x00, 0x00, 0x00, + 0x68, 0xCC, 0x3D, 0x78, 0x6E, 0x0E, 0xAF, 0x4A, 0x1F, 0x1F, 0xFE, 0x3E, 0x62, 0xCC, 0xBE, 0xCF, + 0x18, 0xEF, 0xF0, 0x4D, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x68, 0xCD, 0xFF, 0x8C, 0x8F, 0xBD, + 0x97, 0x67, 0x8B, 0x0F, 0xB7, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x20, 0x19, 0x1B, + 0x20, 0xEB, 0xCD, 0xAE, 0x4F, 0xC7, 0xE2, 0xA2, 0xD5, 0x82, 0xF8, 0x08, 0xB7, 0x67, 0xB1, 0x31, + 0xCF, 0xDE, 0x64, 0xDC, 0x6D, 0x4A, 0xF0, 0xD3, 0x02, 0x00, 0x00, 0x00, 0x40, 0x3D, 0xEF, 0xB9, + 0x9B, 0x07, 0x75, 0x64, 0x34, 0x5A, 0x2C, 0x3E, 0xC2, 0x1D, 0x1A, 0xE0, 0xB5, 0xBC, 0x00, 0x00, + 0x00, 0x00, 0x9A, 0xF3, 0x0E, 0x2E, 0x1B, 0xD5, 0xA1, 0xA1, 0x26, 0xC2, 0x23, 0xDC, 0xD0, 0x02, + 0x6E, 0x41, 0x00, 0x00, 0x00, 0x00, 0x34, 0xE7, 0x1D, 0xB8, 0x76, 0x5C, 0xC7, 0x46, 0x7C, 0x22, + 0x3A, 0xE2, 0x1B, 0x59, 0x6E, 0xBC, 0xC3, 0x37, 0x8E, 0x06, 0x3F, 0x35, 0x00, 0x00, 0x00, 0x00, + 0x4C, 0x72, 0x6F, 0xAE, 0x32, 0xFB, 0x96, 0xD8, 0x78, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x0D, 0xB5, + 0x5D, 0x73, 0x2A, 0xB7, 0x20, 0xCF, 0xAD, 0x19, 0x08, 0xFE, 0x12, 0x00, 0x00, 0x00, 0x00, 0x50, + 0xE1, 0xBF, 0x01, 0x6B, 0x77, 0x9F, 0x8D, 0x07, 0x15, 0x1D, 0xE1, 0x44, 0x68, 0x34, 0xDB, 0xF0, + 0xF5, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xE7, 0x7F, 0x02, 0xFA, 0xAE, 0xB9, 0x36, 0x1C, + 0x54, 0x78, 0xB8, 0x89, 0xC0, 0x68, 0xB5, 0x5D, 0x97, 0x1A, 0xF3, 0xEC, 0x8D, 0xC6, 0x3C, 0xB7, + 0x9A, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x93, 0x6C, 0x80, 0xAC, 0xD7, 0xE1, 0xE1, 0x26, 0xE2, + 0xA2, 0xE5, 0x3E, 0x5C, 0xD9, 0x81, 0xAB, 0x8C, 0xF7, 0xEC, 0x0D, 0x27, 0x83, 0xBF, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0xBC, 0xE7, 0x3D, 0xDE, 0xF0, 0x8A, 0x06, 0x6F, 0xC0, 0x52, 0x71, 0xD1, 0x6A, + 0x41, 0x7C, 0xB8, 0xED, 0xF8, 0x44, 0xE5, 0x16, 0xE4, 0xF0, 0x8D, 0xEB, 0x82, 0xBF, 0x14, 0x00, + 0x00, 0x00, 0x80, 0xE9, 0xCE, 0x3B, 0x70, 0xFD, 0xC9, 0xDC, 0xE3, 0x23, 0x1C, 0xB7, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xA2, 0xCC, 0xFE, 0x2B, 0x6D, 0x2C, 0x14, 0x10, 0x1F, 0x6E, 0xEE, 0x16, 0xE4, + 0xF0, 0x2A, 0x77, 0x0B, 0xB2, 0x3E, 0xF8, 0xCB, 0x01, 0x00, 0x00, 0x00, 0x98, 0xAE, 0x6C, 0x18, + 0x2C, 0x31, 0x7B, 0x2E, 0xB3, 0xB1, 0x50, 0x40, 0x7C, 0x84, 0xDB, 0x77, 0xB9, 0x7B, 0x23, 0xD6, + 0xB8, 0x7B, 0xDD, 0x6F, 0xF0, 0x97, 0x05, 0x00, 0x00, 0x00, 0x30, 0x1D, 0x99, 0x43, 0x37, 0xAD, + 0x9D, 0x7C, 0x03, 0x96, 0x8A, 0x8B, 0x56, 0x13, 0xC1, 0x11, 0xDF, 0xF6, 0x8F, 0x71, 0x0B, 0x02, + 0x00, 0x00, 0x00, 0x20, 0x78, 0x03, 0xD6, 0xF6, 0x8F, 0xDB, 0x50, 0x50, 0x71, 0xD1, 0x6A, 0x22, + 0x36, 0x1A, 0x8D, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xB3, 0x37, 0x0D, 0xEA, 0xB8, 0x68, + 0x35, 0x11, 0x19, 0xAD, 0x76, 0xA8, 0xDF, 0x3D, 0x90, 0x3E, 0x18, 0xFC, 0xA5, 0x01, 0x00, 0x00, + 0x00, 0x4C, 0x37, 0xDE, 0x81, 0x6B, 0x46, 0x75, 0x60, 0x34, 0x9B, 0x88, 0x8B, 0x56, 0xDB, 0xFA, + 0x21, 0x63, 0x86, 0xE6, 0x57, 0x5E, 0xCB, 0x3B, 0xB2, 0x66, 0x76, 0xF0, 0x97, 0x07, 0x00, 0x00, + 0x00, 0x30, 0x9D, 0x98, 0x03, 0x57, 0xDB, 0x40, 0x50, 0x91, 0xD1, 0x68, 0x22, 0x2E, 0x5A, 0xCD, + 0xC5, 0x47, 0x38, 0x6E, 0x41, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC9, 0xDD, 0x44, 0x98, 0x7D, 0x9F, + 0xB1, 0x91, 0xA0, 0x42, 0x43, 0x4D, 0xC4, 0x45, 0xAB, 0x45, 0xE3, 0xC3, 0x6D, 0xF7, 0xDC, 0xCA, + 0x2D, 0xC8, 0x73, 0xAB, 0x07, 0x82, 0x5F, 0x06, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC0, 0x3C, 0xB7, + 0x66, 0xC0, 0xEC, 0x9E, 0x67, 0x43, 0x41, 0xC5, 0x46, 0x7C, 0x22, 0x2E, 0x5A, 0x2D, 0x1E, 0x1F, + 0xE1, 0x86, 0xAF, 0x73, 0x0F, 0xA4, 0x8F, 0x06, 0xBF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x81, + 0xF7, 0xEC, 0x4D, 0x77, 0x99, 0x9D, 0x97, 0xD8, 0x58, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x8B, 0x56, + 0x53, 0xE1, 0x11, 0x6E, 0xD7, 0xA7, 0xB9, 0x05, 0x01, 0x00, 0x00, 0x00, 0xA6, 0x1B, 0xEF, 0xF0, + 0x8D, 0x1B, 0x74, 0x70, 0x44, 0x27, 0xE2, 0xA2, 0xD5, 0x54, 0x74, 0xC4, 0xC7, 0x2D, 0x08, 0x00, + 0x00, 0x00, 0x30, 0xBD, 0x78, 0x07, 0xAF, 0x6F, 0xF1, 0x06, 0x2C, 0x11, 0x17, 0xAD, 0xA6, 0x62, + 0x43, 0xCD, 0x7D, 0xF6, 0x88, 0xBB, 0x05, 0x39, 0x7C, 0xE3, 0xBA, 0xE0, 0x97, 0x03, 0x00, 0x00, + 0x00, 0xA0, 0xCC, 0xBC, 0x03, 0xD7, 0x9D, 0xD4, 0xE1, 0xE1, 0x26, 0xE2, 0xA2, 0xD5, 0x54, 0x68, + 0x34, 0xDB, 0xFE, 0x2B, 0xDD, 0x1B, 0xB1, 0x4E, 0x06, 0xBF, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x65, + 0xD6, 0xF8, 0x0D, 0x58, 0x22, 0x2E, 0x5A, 0x4D, 0x05, 0x46, 0xAB, 0xB9, 0x5B, 0x90, 0xC3, 0x37, + 0x70, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x94, 0x9D, 0xFF, 0x06, 0xAC, 0xA1, 0x05, 0x36, 0x1E, 0x3A, + 0x14, 0x1F, 0xFE, 0x3E, 0x68, 0x5C, 0x04, 0x79, 0x87, 0x6E, 0x18, 0x37, 0xA3, 0xFD, 0xB3, 0x82, + 0x5F, 0x1A, 0x00, 0x00, 0x00, 0x80, 0xB2, 0x71, 0xB7, 0x0E, 0x66, 0xD7, 0x1C, 0x1B, 0x10, 0x1D, + 0x8C, 0x0F, 0x37, 0xF7, 0xD7, 0x3D, 0xB4, 0xD2, 0x98, 0xC3, 0xAB, 0xD7, 0x07, 0xBF, 0x34, 0x00, + 0x00, 0x00, 0x00, 0x65, 0x63, 0x03, 0x64, 0xBD, 0xD9, 0x7E, 0x71, 0x25, 0x00, 0x3A, 0x15, 0x1F, + 0xE1, 0xF6, 0x5E, 0xC6, 0x2D, 0x08, 0x00, 0x00, 0x00, 0x50, 0x66, 0xDE, 0xC8, 0xCA, 0xA1, 0xAE, + 0x88, 0x0F, 0xB7, 0xE0, 0x16, 0xC4, 0x3B, 0xBC, 0x7A, 0x43, 0xF0, 0xCB, 0x03, 0x00, 0x00, 0x00, + 0x50, 0x26, 0xDE, 0xC1, 0x6B, 0xC7, 0xBA, 0x22, 0x3E, 0xC2, 0xED, 0xEE, 0xAB, 0x3C, 0x90, 0x3E, + 0xB2, 0x66, 0x76, 0xF0, 0x4B, 0x04, 0x00, 0x00, 0x00, 0x50, 0x16, 0x66, 0xFF, 0x67, 0x75, 0x5C, + 0xB4, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0xD1, 0x11, 0xDF, 0xC8, 0x0A, 0xE3, 0x1D, 0x5A, 0x3D, 0x18, + 0xFC, 0x12, 0x01, 0x00, 0x00, 0x00, 0x94, 0x81, 0xBB, 0x65, 0x30, 0xFB, 0x2E, 0xD7, 0x81, 0xD1, + 0x6C, 0x32, 0x2C, 0x92, 0x4C, 0xC4, 0x86, 0x1A, 0xB7, 0x20, 0x00, 0x00, 0x00, 0x40, 0xF9, 0x98, + 0xE7, 0x56, 0x0F, 0x98, 0x5D, 0x97, 0xEA, 0xC8, 0x68, 0x34, 0x19, 0x16, 0x49, 0x26, 0x42, 0xA3, + 0xD9, 0x0E, 0x7E, 0xCE, 0x78, 0x87, 0x6F, 0x18, 0x0D, 0x7E, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x7A, + 0x9D, 0xFF, 0x06, 0xAC, 0x1D, 0x9F, 0xD0, 0xA1, 0xA1, 0x26, 0xC3, 0x22, 0xC9, 0x44, 0x60, 0xB4, + 0xDA, 0xCE, 0x4B, 0x82, 0x5B, 0x90, 0xD5, 0x03, 0xC1, 0x2F, 0x17, 0x00, 0x00, 0x00, 0x40, 0x2F, + 0xF3, 0x9E, 0xBD, 0x61, 0x50, 0x86, 0x86, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0x71, 0x91, 0x74, 0x07, + 0xAF, 0x35, 0xDE, 0xE1, 0x55, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x65, 0xE0, 0x1D, 0xBC, 0x6E, + 0x54, 0xC6, 0x46, 0x7C, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, 0x6D, 0xF9, 0x80, 0x31, 0x3B, + 0x67, 0xBB, 0x0F, 0x26, 0x34, 0xE6, 0xD0, 0xAA, 0xB5, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, 0x40, + 0xAF, 0xF2, 0x0E, 0x5C, 0x33, 0x2E, 0x83, 0x23, 0x3A, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, + 0x5C, 0x7C, 0x84, 0xDB, 0x77, 0x85, 0xFB, 0x5C, 0x90, 0x93, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, + 0x40, 0x2F, 0x72, 0x9F, 0x36, 0xDE, 0xF2, 0x0D, 0x58, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, + 0x45, 0xE3, 0xC3, 0x6D, 0xDB, 0xC7, 0x2A, 0xB7, 0x20, 0x87, 0x57, 0xAD, 0x0B, 0x7E, 0xE9, 0x00, + 0x00, 0x00, 0x00, 0x7A, 0x8D, 0xFF, 0x06, 0xAC, 0xDD, 0x73, 0xEB, 0xA3, 0x23, 0x9C, 0x0C, 0x8B, + 0x24, 0x13, 0x51, 0x91, 0x74, 0xF1, 0xF8, 0x08, 0xC7, 0x2D, 0x08, 0x00, 0x00, 0x00, 0xD0, 0xDB, + 0xCC, 0xE1, 0x1B, 0xD7, 0x35, 0x7C, 0x05, 0xAF, 0x0C, 0x8B, 0x24, 0x13, 0x51, 0x91, 0x74, 0x2A, + 0x3C, 0xC2, 0x6D, 0xB5, 0xBF, 0xA6, 0x43, 0x03, 0xEE, 0x26, 0x64, 0x7D, 0xF0, 0xCB, 0x07, 0x00, + 0x00, 0x00, 0xD0, 0x4B, 0xFC, 0x57, 0xF0, 0xF6, 0x42, 0x7C, 0x84, 0xDB, 0xB3, 0xD8, 0x7D, 0x3A, + 0xFA, 0xB8, 0xFB, 0xD6, 0xB1, 0xE0, 0xB7, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x57, 0x78, 0xC3, 0xCB, + 0xEB, 0xDF, 0x80, 0x25, 0xC3, 0x22, 0xC9, 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x0D, 0x35, 0x6E, 0x41, + 0x00, 0x00, 0x00, 0x80, 0xDE, 0xE5, 0x1D, 0xBC, 0x76, 0xAC, 0x67, 0xE2, 0x23, 0xDC, 0x9E, 0x45, + 0xC6, 0x3B, 0xB4, 0x6A, 0xDC, 0x8C, 0xF4, 0xCF, 0x0E, 0x7E, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x7A, + 0x81, 0xD9, 0x7F, 0x45, 0x6F, 0xC5, 0x87, 0xBF, 0xF7, 0x1B, 0x33, 0xB2, 0xCC, 0x46, 0xC8, 0xCA, + 0xC1, 0xE0, 0xB7, 0x01, 0x00, 0x00, 0x00, 0xA0, 0xDB, 0x99, 0xC3, 0x37, 0x2E, 0x71, 0xB7, 0x09, + 0x3D, 0x17, 0x1F, 0x6E, 0xEE, 0xCD, 0x5D, 0x87, 0x57, 0xD9, 0x10, 0xE9, 0xCD, 0x5B, 0x10, 0xF7, + 0xEB, 0xB6, 0x1B, 0x08, 0xC6, 0x4D, 0x0E, 0x00, 0x00, 0x00, 0xCA, 0xCF, 0x1C, 0xBA, 0x69, 0xAD, + 0xFF, 0x06, 0x2C, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x5A, 0x10, 0x1F, + 0xE1, 0x7A, 0xEC, 0x16, 0xC4, 0xFF, 0xCC, 0x95, 0x91, 0xFE, 0xF5, 0xDE, 0xA1, 0x81, 0x93, 0xFE, + 0x73, 0x2C, 0x91, 0xF9, 0xFF, 0x9A, 0xFD, 0xF7, 0x78, 0xB8, 0x1E, 0x00, 0x00, 0x00, 0xA5, 0x55, + 0x79, 0x03, 0xD6, 0x47, 0x6D, 0x10, 0xA8, 0xB8, 0x68, 0x35, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, + 0xD5, 0x62, 0xF1, 0xE1, 0xB6, 0xF3, 0x53, 0xC1, 0x2D, 0xC8, 0xEA, 0x81, 0xE0, 0xB7, 0xD4, 0xB5, + 0xCC, 0xA1, 0xFE, 0xB5, 0xDE, 0xC8, 0xC0, 0x78, 0x3C, 0x3C, 0xE2, 0xAB, 0xFC, 0x67, 0xFA, 0xD7, + 0x06, 0xFF, 0x35, 0x00, 0x00, 0x00, 0xA0, 0x3C, 0xBC, 0x67, 0x6F, 0x18, 0xD4, 0x71, 0xD1, 0x6A, + 0x22, 0x2A, 0x92, 0x4E, 0xC6, 0x45, 0xAB, 0x89, 0xF8, 0x08, 0x77, 0xF0, 0x1A, 0xE3, 0x1D, 0x5E, + 0x39, 0x1A, 0xFC, 0x96, 0xBA, 0x92, 0x19, 0xE9, 0x5F, 0x57, 0x8D, 0x8C, 0x91, 0xE5, 0xFE, 0x43, + 0xF4, 0x66, 0xC7, 0xC7, 0x6B, 0xE7, 0xFE, 0x35, 0xF7, 0xEF, 0xF9, 0xFF, 0x99, 0x7E, 0x37, 0x3E, + 0xF1, 0x1D, 0x00, 0x00, 0x00, 0xE5, 0xE2, 0x1D, 0xB8, 0x7A, 0x54, 0x07, 0x46, 0xB3, 0x89, 0xA8, + 0x48, 0x3A, 0x19, 0x17, 0xAD, 0x26, 0xA2, 0x23, 0xBA, 0x2E, 0xBF, 0x05, 0xB1, 0x21, 0x31, 0xBB, + 0x7A, 0xF3, 0x31, 0x34, 0xBF, 0xF2, 0x6B, 0xDE, 0x3C, 0x4B, 0xCF, 0xFD, 0x7B, 0x43, 0x7D, 0x7E, + 0x80, 0x78, 0x23, 0x2B, 0x78, 0xCB, 0x17, 0x00, 0x00, 0x00, 0xCA, 0xC5, 0xEC, 0xBF, 0xD2, 0x86, + 0x81, 0x8A, 0x8C, 0x46, 0x13, 0x51, 0x91, 0x74, 0x32, 0x2E, 0x5A, 0x2D, 0x12, 0x1A, 0xCD, 0xE6, + 0x6E, 0x41, 0x0E, 0xAD, 0x1A, 0x0B, 0x7E, 0x5B, 0x5D, 0xC5, 0xC6, 0xC7, 0x90, 0x1F, 0x1F, 0xBB, + 0x3E, 0xAD, 0xA3, 0xA3, 0x66, 0x17, 0x55, 0xB6, 0xF3, 0x92, 0x4A, 0x84, 0x0C, 0xAF, 0xE8, 0xEA, + 0x9B, 0x1D, 0x00, 0x00, 0x00, 0x20, 0x31, 0xFF, 0x81, 0xE8, 0xBD, 0x97, 0xDB, 0x38, 0x50, 0xA1, + 0xA1, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x9A, 0x08, 0x8D, 0x46, 0x73, 0xCF, 0xB1, 0xB8, + 0x5B, 0x90, 0xC3, 0xAB, 0xBA, 0xEA, 0xDB, 0x96, 0x6C, 0x44, 0x0C, 0xF8, 0xF1, 0xE1, 0xDE, 0xD8, + 0x25, 0x83, 0x23, 0xBA, 0x20, 0x3E, 0x62, 0x11, 0xE2, 0x7E, 0x8E, 0xE0, 0xA7, 0x03, 0x00, 0x00, + 0x00, 0x7A, 0x97, 0x79, 0x6E, 0xF5, 0x80, 0x7F, 0x30, 0x96, 0xB1, 0x11, 0x9F, 0x88, 0x8A, 0xA4, + 0x93, 0x71, 0xD1, 0x6A, 0x22, 0x32, 0x5A, 0x6D, 0xDF, 0x12, 0xE3, 0x1D, 0x5E, 0x75, 0x32, 0xF8, + 0xED, 0x75, 0x05, 0xEF, 0xD0, 0xC0, 0xA8, 0x39, 0x70, 0x55, 0x10, 0x18, 0xCD, 0x16, 0x8B, 0x8F, + 0x70, 0xFB, 0xAF, 0xE4, 0x16, 0x04, 0x00, 0x00, 0x00, 0xE5, 0xE0, 0x3D, 0x7B, 0xC3, 0x5D, 0x66, + 0xC7, 0xA7, 0x6C, 0x24, 0xA8, 0xE0, 0x88, 0x4E, 0x44, 0x45, 0xD2, 0xC9, 0xB8, 0x68, 0x35, 0x11, + 0x17, 0x49, 0x16, 0xDC, 0x82, 0x78, 0x87, 0x56, 0xDD, 0x15, 0xFC, 0x16, 0x3B, 0xAA, 0x7A, 0xFB, + 0xE1, 0x1E, 0x30, 0x97, 0xD1, 0x11, 0x4E, 0x84, 0x47, 0xB8, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, + 0x00, 0x80, 0x72, 0xF0, 0x0E, 0xDF, 0xB8, 0x41, 0x07, 0x47, 0x74, 0x22, 0x2A, 0x92, 0x4E, 0xC6, + 0x45, 0xAB, 0x89, 0xB0, 0x48, 0xB3, 0x3D, 0x0B, 0x8D, 0x37, 0xB2, 0x72, 0xBC, 0x1B, 0x3E, 0x4B, + 0x23, 0xD9, 0xED, 0x87, 0x88, 0x8E, 0xF8, 0xB8, 0x05, 0x01, 0x00, 0x00, 0x40, 0x19, 0x78, 0x07, + 0xAF, 0x6B, 0xF1, 0x06, 0x2C, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, 0xD5, 0x44, 0x50, 0xA4, 0xDA, + 0x1F, 0x57, 0xFE, 0xDA, 0x23, 0x2B, 0xEC, 0x56, 0xAE, 0x0F, 0x7E, 0x9B, 0x1D, 0xE1, 0x3E, 0xC7, + 0xC3, 0xBF, 0xFD, 0x70, 0x7F, 0x1F, 0x65, 0x78, 0xB8, 0x89, 0xD8, 0x50, 0xF3, 0x7F, 0x4F, 0xFD, + 0xC6, 0x1C, 0xE4, 0xB3, 0x41, 0x00, 0x00, 0x00, 0xD0, 0xC3, 0xBC, 0x03, 0x9F, 0x3B, 0x59, 0x1F, + 0x1D, 0xE1, 0x22, 0x31, 0x91, 0x76, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xD9, 0xF8, 0x08, + 0xD7, 0x05, 0xB7, 0x20, 0xFE, 0xA7, 0x9A, 0xBB, 0x07, 0xFC, 0x65, 0x78, 0xB8, 0x89, 0xD0, 0x68, + 0xB6, 0xBD, 0x97, 0xB9, 0x5B, 0x90, 0xAE, 0x7A, 0xBE, 0x05, 0x00, 0x00, 0x00, 0x48, 0xA5, 0xF1, + 0x1B, 0xB0, 0x44, 0x54, 0x24, 0x9D, 0x8C, 0x8B, 0x56, 0x53, 0x41, 0x91, 0x66, 0x91, 0xF8, 0x70, + 0x73, 0xBF, 0x8E, 0xE1, 0xA5, 0xEE, 0x13, 0xC5, 0x37, 0x04, 0xBF, 0xD5, 0x29, 0x65, 0xC2, 0x0F, + 0x1D, 0x74, 0x7F, 0x2F, 0xF3, 0x88, 0x0F, 0x37, 0xF7, 0x7B, 0xF2, 0x9F, 0x05, 0x59, 0xCE, 0x87, + 0x13, 0x02, 0x00, 0x00, 0xA0, 0xF7, 0xF8, 0x6F, 0xC0, 0x72, 0x1F, 0x8A, 0x57, 0xB6, 0xF8, 0x08, + 0xB7, 0x6B, 0x8E, 0x31, 0x87, 0x56, 0xBA, 0x43, 0xFB, 0x94, 0x7F, 0x90, 0x5F, 0xF3, 0xDB, 0x0F, + 0x11, 0x17, 0x49, 0xB7, 0x67, 0xB1, 0xF1, 0x86, 0x97, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x80, 0xDE, + 0x63, 0x0E, 0xDD, 0xB4, 0xD6, 0xFF, 0x60, 0xBC, 0x32, 0xC6, 0x47, 0x38, 0x77, 0x0B, 0x72, 0x68, + 0xE5, 0x60, 0xF0, 0x5B, 0x9E, 0x12, 0xCD, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0xDD, 0x33, 0x17, 0xDA, + 0xDF, 0x93, 0xFD, 0x7B, 0x66, 0x7F, 0x4F, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0xE7, 0x98, 0xC3, + 0x37, 0xAE, 0xF7, 0x5F, 0x5B, 0x5B, 0xD6, 0xF8, 0x70, 0x0B, 0x6F, 0x41, 0x0E, 0xF7, 0x2F, 0x09, + 0x7E, 0xDB, 0x85, 0x72, 0xCF, 0x9C, 0xF8, 0xB7, 0x1F, 0xEE, 0x66, 0x29, 0xEF, 0xF8, 0x08, 0xB7, + 0x7B, 0x9E, 0xF1, 0x46, 0x96, 0x8F, 0x9B, 0xA1, 0xCE, 0xBF, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, + 0xCC, 0x1B, 0x59, 0x39, 0x54, 0xEA, 0xF8, 0x08, 0x77, 0xE0, 0x6A, 0x77, 0x0B, 0x32, 0x25, 0xAF, + 0xB0, 0x35, 0x23, 0xFD, 0xEB, 0xCD, 0xC8, 0x72, 0xFB, 0xD7, 0xB5, 0xBF, 0xC6, 0x22, 0xE2, 0xC3, + 0x6D, 0xF3, 0xFB, 0xC2, 0x5B, 0x90, 0x8E, 0xBE, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, 0xC5, 0xDB, + 0x7F, 0xED, 0x58, 0xE9, 0xE3, 0xC3, 0x6D, 0xC7, 0x27, 0xC3, 0x67, 0x41, 0x0A, 0xFD, 0x20, 0x3F, + 0xFF, 0xF6, 0x63, 0x64, 0x60, 0xBC, 0xFE, 0xF6, 0x43, 0x44, 0x45, 0xD2, 0xC5, 0xE3, 0x23, 0x1C, + 0xB7, 0x20, 0x00, 0x00, 0x00, 0xE8, 0x35, 0x66, 0xDF, 0x12, 0x1D, 0x15, 0x49, 0x27, 0xE3, 0xA2, + 0xD5, 0x54, 0x50, 0xA4, 0x99, 0x08, 0x8C, 0x56, 0x73, 0x37, 0x06, 0x53, 0x70, 0x0B, 0xA2, 0x6F, + 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8F, 0x70, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0x97, 0x98, + 0x91, 0x35, 0xB3, 0xDD, 0xE7, 0x4A, 0xC8, 0xB0, 0x48, 0x32, 0x19, 0x17, 0xAD, 0x16, 0x8F, 0x89, + 0xB4, 0x13, 0x71, 0xD1, 0x6A, 0xEE, 0xA0, 0xEE, 0xB6, 0xED, 0x63, 0x95, 0x5B, 0x90, 0x43, 0xC5, + 0x7C, 0x90, 0x9F, 0xBE, 0xFD, 0x10, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0xE2, 0xE3, 0x16, 0x04, 0x00, + 0x00, 0x00, 0xBD, 0xC2, 0x8C, 0xAC, 0x1E, 0x30, 0x3B, 0x2F, 0xD1, 0x71, 0xD1, 0x6A, 0x32, 0x2E, + 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0x30, 0x3E, 0xC2, 0xED, 0xFD, 0x8C, 0xBB, + 0x05, 0x29, 0xE4, 0x15, 0xB6, 0xEE, 0xF3, 0x46, 0xCC, 0xF0, 0xF5, 0xF6, 0xAF, 0x33, 0x45, 0xF1, + 0x11, 0xEE, 0xE0, 0xE7, 0x6C, 0x84, 0xAC, 0xE8, 0xC8, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x89, + 0x99, 0xC3, 0xAB, 0xD7, 0x9B, 0xED, 0x17, 0xEB, 0xC0, 0x68, 0x36, 0x19, 0x17, 0xAD, 0xA6, 0x82, + 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x5A, 0x3C, 0x3E, 0xDC, 0xB6, 0x7E, 0x38, 0x7C, 0x16, 0x24, 0xD7, + 0x57, 0xD8, 0xDA, 0x9F, 0x6F, 0xB6, 0xFF, 0xDA, 0x5D, 0xF7, 0x4A, 0xE3, 0xA9, 0x8C, 0x0F, 0xB7, + 0x9D, 0xB3, 0xED, 0xEF, 0x67, 0x85, 0xFB, 0x3D, 0x4D, 0xF9, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x79, 0x87, 0x57, 0x6F, 0x90, 0x81, 0xD1, 0x6C, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, + 0x89, 0xB8, 0x68, 0x35, 0x15, 0x1F, 0xE1, 0x82, 0x5B, 0x10, 0xF7, 0x2D, 0x53, 0xC1, 0xDF, 0x8A, + 0xB6, 0x79, 0x87, 0x06, 0x06, 0x27, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8C, 0x24, 0x73, + 0xB7, 0x20, 0xC3, 0x2B, 0xA6, 0xF4, 0xB3, 0x4E, 0x00, 0x00, 0x00, 0x80, 0x54, 0xBC, 0x83, 0x9F, + 0x1B, 0x95, 0x91, 0xD1, 0x68, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0x35, + 0x15, 0x1D, 0xD1, 0xB9, 0x5F, 0x97, 0x7F, 0x63, 0xB0, 0x32, 0x97, 0x87, 0xB7, 0x6B, 0x6F, 0x3F, + 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8B, 0xA4, 0xE3, 0x16, 0x04, 0x00, 0x00, 0x00, 0xDD, 0xCE, 0xDB, + 0x7F, 0xD5, 0xB8, 0x0C, 0x0D, 0xB5, 0xBA, 0xB0, 0x48, 0x32, 0x15, 0x14, 0x69, 0x26, 0xE2, 0xA2, + 0xD5, 0x54, 0x70, 0xA8, 0x0D, 0x2D, 0x30, 0xDE, 0xC8, 0xCA, 0xF1, 0x3C, 0x6E, 0x41, 0xFC, 0xDB, + 0x8F, 0x03, 0xD7, 0xDA, 0x9F, 0x57, 0x44, 0x45, 0xD2, 0xA9, 0xA8, 0x48, 0x3B, 0xF7, 0x96, 0xAF, + 0xE1, 0x65, 0xDC, 0x82, 0x34, 0x60, 0xC6, 0xFE, 0xC3, 0x2C, 0xF3, 0xF2, 0xBF, 0x5F, 0x67, 0x4E, + 0x7C, 0x65, 0x7D, 0x64, 0x6B, 0xDD, 0xBF, 0x1E, 0xFC, 0x47, 0x00, 0x00, 0x00, 0x50, 0x14, 0x77, + 0xF0, 0x4E, 0xFC, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, + 0x0A, 0x8D, 0x46, 0x73, 0xBF, 0xC6, 0x1C, 0x6E, 0x41, 0xDC, 0xA7, 0xAB, 0xFB, 0xB7, 0x1F, 0xEE, + 0x59, 0x1A, 0x15, 0x16, 0x49, 0xA6, 0x62, 0x22, 0xCB, 0xB6, 0x7F, 0xD4, 0xFE, 0x7E, 0x96, 0xDB, + 0x2D, 0x2D, 0xF4, 0xB3, 0x4E, 0x7A, 0x8D, 0x0B, 0x0C, 0xEF, 0xC4, 0x97, 0x07, 0xCD, 0x2F, 0xBE, + 0x62, 0xE4, 0x4E, 0x7C, 0xC9, 0xF8, 0xFF, 0x3E, 0x21, 0x02, 0x00, 0x00, 0x50, 0x1C, 0xFF, 0x0D, + 0x58, 0xBB, 0xE6, 0xE8, 0xE0, 0x88, 0xAE, 0x2E, 0x2C, 0x92, 0x4C, 0x05, 0x45, 0x9A, 0x89, 0xB8, + 0x68, 0x35, 0x15, 0x19, 0xAD, 0xE6, 0xBF, 0xC2, 0x76, 0xE5, 0x78, 0x3B, 0xDF, 0xB6, 0xE4, 0x1D, + 0x1A, 0x18, 0x35, 0xFB, 0xAF, 0xB4, 0x3F, 0x9F, 0x08, 0x8B, 0x24, 0x53, 0x21, 0x91, 0x69, 0x33, + 0x2B, 0xDB, 0x7F, 0x85, 0xF1, 0x86, 0x97, 0x4F, 0xC9, 0x27, 0xBE, 0xF7, 0x02, 0x73, 0xFC, 0xDF, + 0x2F, 0xF1, 0x7E, 0xF1, 0xE5, 0xF1, 0xDA, 0xE0, 0xB8, 0xDD, 0x98, 0xE3, 0x5F, 0xF4, 0xC3, 0x23, + 0xFA, 0xAF, 0xFB, 0xFF, 0x39, 0xFB, 0x9F, 0x0F, 0xFE, 0xAB, 0x00, 0x00, 0x00, 0xC8, 0x93, 0x39, + 0x7C, 0xE3, 0xBA, 0x96, 0xAF, 0xE0, 0x95, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, + 0xAB, 0xA9, 0xB8, 0x48, 0xBA, 0xE1, 0xEB, 0x8D, 0xFB, 0x16, 0xAA, 0xE0, 0x6F, 0x4B, 0x2A, 0x36, + 0x5C, 0x06, 0xEC, 0xB2, 0xDF, 0x7E, 0xC8, 0x90, 0xC8, 0xB2, 0x20, 0x3E, 0xDC, 0xB8, 0x05, 0xA9, + 0xAA, 0x89, 0x0F, 0x17, 0x1D, 0x2F, 0xD9, 0xFF, 0xAD, 0x5E, 0xB0, 0xB1, 0xF8, 0xFC, 0x92, 0xC9, + 0xBD, 0x70, 0xB5, 0xFD, 0xD7, 0x57, 0x55, 0xFE, 0x7D, 0x22, 0x04, 0x00, 0x00, 0xA0, 0x38, 0xFE, + 0x2B, 0x78, 0x55, 0x74, 0x84, 0x93, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, + 0xA9, 0xA8, 0x48, 0xBC, 0x59, 0x95, 0x07, 0xC7, 0xDD, 0xB7, 0x50, 0x65, 0xB8, 0x05, 0xF1, 0x86, + 0x57, 0x64, 0xBF, 0xFD, 0x90, 0x21, 0x91, 0x65, 0x91, 0xF8, 0x08, 0xC7, 0x2D, 0x48, 0x6D, 0x7C, + 0x1C, 0xB9, 0xB1, 0x36, 0x3A, 0xD4, 0x5C, 0x98, 0x1C, 0xFD, 0x42, 0x25, 0x42, 0x4E, 0x7C, 0x85, + 0x1B, 0x24, 0x00, 0x00, 0x80, 0xBC, 0x79, 0x07, 0x97, 0x35, 0x7E, 0x03, 0x96, 0x8C, 0x8B, 0x56, + 0x53, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0x85, 0x1F, 0x16, 0x68, 0xE7, + 0x6E, 0x41, 0x46, 0x06, 0x86, 0x82, 0xBF, 0x35, 0x89, 0xB4, 0x75, 0xFB, 0x21, 0x43, 0x22, 0xCB, + 0x44, 0x7C, 0xB8, 0x6D, 0xFD, 0xD0, 0xB4, 0xBE, 0x05, 0xA9, 0x89, 0x0F, 0x77, 0xEB, 0xA1, 0x82, + 0xA3, 0xD1, 0x5C, 0xAC, 0xF8, 0x37, 0x26, 0x5F, 0x29, 0xE4, 0xD3, 0xF2, 0x01, 0x00, 0x00, 0xA6, + 0x2D, 0x6F, 0xFF, 0x35, 0x63, 0xC4, 0x47, 0xB0, 0xED, 0x1F, 0xB7, 0x87, 0x75, 0xFF, 0x16, 0x24, + 0xF1, 0x81, 0xDD, 0x1B, 0x59, 0x31, 0xE6, 0x3F, 0xC4, 0xAF, 0x02, 0xA3, 0xD9, 0x64, 0x48, 0x64, + 0x99, 0x08, 0x8F, 0xE8, 0xF6, 0x2C, 0xB2, 0x51, 0xB5, 0x7C, 0x2C, 0xF8, 0xE5, 0x4E, 0x1B, 0x6D, + 0xC5, 0x47, 0xB8, 0x63, 0x7F, 0xE2, 0x3F, 0x94, 0x1E, 0xFC, 0x94, 0x00, 0x00, 0x00, 0xC8, 0x83, + 0xD9, 0xF7, 0x19, 0xE2, 0xC3, 0xED, 0x99, 0x60, 0xFB, 0xAF, 0x32, 0xDE, 0xF0, 0x40, 0xA2, 0x6F, + 0xBD, 0xB1, 0xA1, 0xB2, 0xCE, 0xBF, 0xFD, 0x70, 0x7F, 0xCF, 0x54, 0x64, 0x34, 0x9A, 0x0C, 0x89, + 0x2C, 0x13, 0xC1, 0x11, 0x9F, 0xFB, 0x7B, 0xEB, 0xDF, 0x82, 0x2C, 0xCF, 0xF5, 0x13, 0xDF, 0xBB, + 0x59, 0x2E, 0xF1, 0xE1, 0xF6, 0xC2, 0xD5, 0xEE, 0xDB, 0xB0, 0x4E, 0x06, 0x3F, 0x2D, 0x00, 0x00, + 0x00, 0xDA, 0x65, 0x0E, 0xDF, 0xB8, 0xC4, 0x0C, 0x2D, 0x9C, 0xBE, 0xF1, 0x11, 0x46, 0x47, 0xF0, + 0x7F, 0x7B, 0x6E, 0xDB, 0x3F, 0xEE, 0xBE, 0x0D, 0x2B, 0xD1, 0x2D, 0x88, 0x37, 0xBC, 0xE2, 0x64, + 0xEA, 0xDB, 0x0F, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, 0xD1, 0xDC, 0x2D, 0xC8, 0xF0, 0xB2, 0x69, + 0x71, 0x90, 0xCE, 0x2D, 0x3E, 0xC2, 0x1D, 0xBB, 0xC5, 0x04, 0x3F, 0x35, 0x00, 0x00, 0x00, 0xDA, + 0x65, 0x0E, 0xAD, 0x5A, 0x5B, 0xF3, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, + 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0xAB, 0x8F, 0x0F, 0x3F, 0x3C, 0xC2, 0x6D, 0xB2, 0xDB, 0x7B, + 0x85, 0x39, 0x3F, 0x3C, 0xD0, 0xF4, 0xC0, 0x9E, 0xE9, 0xF6, 0x43, 0x86, 0x44, 0x96, 0x89, 0xC8, + 0x68, 0x36, 0xF7, 0xF7, 0x79, 0x1A, 0xDC, 0x82, 0xE4, 0x1E, 0x1F, 0xCF, 0x7F, 0xC6, 0x98, 0x23, + 0x37, 0x18, 0xF3, 0xF2, 0x9D, 0x7C, 0x9E, 0x0A, 0x00, 0x00, 0x40, 0x1E, 0xFC, 0x37, 0x60, 0x6D, + 0xFB, 0xC8, 0xF4, 0x8D, 0x8F, 0x68, 0x78, 0xB8, 0xB9, 0xF8, 0x70, 0xDB, 0xFC, 0x21, 0xF7, 0x6D, + 0x58, 0xEE, 0x16, 0xA4, 0xE1, 0x81, 0xDD, 0xBF, 0xFD, 0xD8, 0xB3, 0xD0, 0xFE, 0x7C, 0x22, 0x34, + 0xD4, 0x64, 0x48, 0x64, 0x99, 0x08, 0x8C, 0x24, 0x1B, 0x9A, 0x5F, 0xEA, 0x5B, 0x90, 0x42, 0xE2, + 0xC3, 0x6D, 0xEC, 0x3A, 0x17, 0x20, 0xD3, 0xE6, 0xDB, 0xD7, 0x00, 0x00, 0x00, 0x0A, 0xE5, 0x1D, + 0x5A, 0x3D, 0x38, 0xED, 0xE2, 0x23, 0x12, 0x20, 0xD5, 0xE8, 0x88, 0xC4, 0xC7, 0xF9, 0x70, 0x43, + 0x97, 0x9B, 0x73, 0x07, 0xF5, 0x2D, 0xC8, 0xF9, 0x91, 0xFE, 0xF5, 0x66, 0x78, 0x99, 0xFD, 0xB9, + 0xDC, 0xAF, 0x49, 0xC4, 0x46, 0x7C, 0x32, 0x24, 0xB2, 0x4C, 0x84, 0x45, 0xD2, 0xB9, 0xDF, 0xF7, + 0xF0, 0xF5, 0xEE, 0x16, 0xA4, 0xAD, 0x4F, 0x7C, 0xEF, 0x46, 0x85, 0xC5, 0x87, 0xDB, 0x0B, 0x57, + 0x19, 0x73, 0xE2, 0xCE, 0xD2, 0xFD, 0x3D, 0x03, 0x00, 0x00, 0xE8, 0x08, 0x6F, 0xDF, 0x55, 0xA3, + 0x3A, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xC5, 0xC2, 0x22, 0xC9, 0x64, 0x54, 0x24, 0x5D, 0x24, + 0x3E, 0x82, 0xD5, 0xDC, 0x78, 0x84, 0xD1, 0xF1, 0x74, 0x64, 0x9B, 0x3F, 0x64, 0xCE, 0x1F, 0x5C, + 0x6E, 0xCE, 0x0D, 0xF7, 0xDF, 0x15, 0xFC, 0xED, 0xF2, 0x99, 0xA1, 0xFE, 0x59, 0xE7, 0x47, 0x56, + 0x8C, 0x9B, 0xDD, 0x7D, 0xF6, 0x60, 0x2F, 0x62, 0x23, 0x3E, 0x19, 0x12, 0x59, 0x26, 0xA2, 0x22, + 0xED, 0x76, 0xCF, 0x35, 0xDE, 0xC8, 0xB2, 0x71, 0xF7, 0x7B, 0x08, 0x7E, 0x3B, 0x3D, 0xAF, 0xD0, + 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x9F, 0x07, 0x02, 0x00, 0x00, 0x90, 0x07, 0xB3, 0xEF, 0x0A, + 0x7B, 0xB8, 0x57, 0x81, 0xD1, 0x6C, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, 0x48, + 0xBA, 0x48, 0x78, 0x44, 0x6F, 0x3E, 0xE2, 0xB7, 0x1E, 0x7E, 0x78, 0xBC, 0xCF, 0x9C, 0x7B, 0x6A, + 0x72, 0xE7, 0x77, 0xCE, 0x77, 0xB7, 0x20, 0x35, 0x07, 0xF6, 0xF3, 0x07, 0xFB, 0xD7, 0x7B, 0xC3, + 0xCB, 0x8C, 0xE7, 0x6E, 0x3F, 0x5A, 0x05, 0x88, 0x0C, 0x89, 0x2C, 0x13, 0x31, 0x91, 0x76, 0x9B, + 0x66, 0xD8, 0x1F, 0xED, 0xAF, 0xA9, 0x44, 0xB7, 0x20, 0x53, 0x11, 0x1F, 0x6E, 0xDE, 0xD1, 0x5B, + 0xA6, 0xDD, 0x6B, 0x8C, 0x01, 0x00, 0x00, 0x72, 0x67, 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x8B, 0xED, + 0x01, 0x5F, 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x58, 0x24, 0x99, 0x8C, 0x8A, 0xA4, + 0x8B, 0xC4, 0x47, 0x83, 0x00, 0x09, 0xE3, 0xE3, 0x5C, 0x24, 0x3E, 0xCE, 0x6E, 0x0C, 0xF6, 0xD4, + 0xFB, 0xCD, 0xF9, 0x03, 0xCB, 0x8D, 0x8B, 0x0E, 0xFF, 0xEF, 0x99, 0x0D, 0x91, 0x73, 0xC3, 0x2B, + 0xC6, 0xBD, 0x5D, 0x7D, 0xF6, 0xBF, 0x7F, 0x91, 0x3F, 0xFF, 0x50, 0xAF, 0x42, 0x44, 0x86, 0x44, + 0x96, 0x89, 0x98, 0x48, 0x3B, 0x17, 0x1F, 0xE1, 0x4A, 0x72, 0x0B, 0x32, 0x55, 0xF1, 0xE1, 0xEF, + 0xE8, 0xE7, 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xBB, 0xCC, 0xC8, 0xEA, 0x01, 0xB3, 0xEB, 0x52, + 0x7B, 0xC8, 0x57, 0xA1, 0xA1, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, + 0x4B, 0x1F, 0x1F, 0xD5, 0xF0, 0x78, 0xD2, 0x6D, 0x96, 0xBF, 0x73, 0x3B, 0xE6, 0x9B, 0xB3, 0x07, + 0x2A, 0xB7, 0x20, 0x2E, 0x44, 0xCE, 0x1F, 0x5C, 0x66, 0xFF, 0xFB, 0x7F, 0xDC, 0x3C, 0x40, 0x64, + 0x48, 0x64, 0x99, 0x88, 0x89, 0xB4, 0x8B, 0xC6, 0x87, 0x9B, 0xFB, 0xB5, 0x1E, 0xBC, 0xB6, 0xA7, + 0x6F, 0x41, 0xA6, 0x34, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0xEC, 0x5F, 0x33, 0xF8, 0xCB, 0x03, 0x00, + 0x00, 0x20, 0x0B, 0xEF, 0xD0, 0xAA, 0xBB, 0xCC, 0xF6, 0x4F, 0xD8, 0x83, 0xBE, 0x8A, 0x8D, 0xF8, + 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, 0x74, 0xB1, 0xF8, 0x08, 0x02, 0x24, + 0x49, 0x7C, 0xBC, 0x6B, 0xE3, 0xE3, 0xDD, 0xC1, 0x59, 0x93, 0xDB, 0xF8, 0x7E, 0x73, 0x6E, 0xEF, + 0xF5, 0xE6, 0xDC, 0x81, 0x81, 0x51, 0xF7, 0xED, 0x58, 0xE7, 0xB7, 0x5F, 0x62, 0xFF, 0xBB, 0x36, + 0x3E, 0xDC, 0x54, 0x84, 0xC8, 0x90, 0xC8, 0x32, 0x11, 0x13, 0x69, 0x17, 0x8F, 0x8F, 0x70, 0x3B, + 0x3E, 0xE9, 0x02, 0xC4, 0xBD, 0xE5, 0x6B, 0x76, 0xF0, 0x8F, 0x43, 0xCF, 0x98, 0xF2, 0xF8, 0x70, + 0x1B, 0x5B, 0x66, 0xCC, 0x89, 0xAF, 0xAC, 0x0D, 0x7E, 0x09, 0x00, 0x00, 0x00, 0xC8, 0xC2, 0x3B, + 0xBC, 0x7A, 0x83, 0x8E, 0x8D, 0xF8, 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, + 0x74, 0x3A, 0x3E, 0xEA, 0x02, 0xC4, 0x86, 0x47, 0xF8, 0xCC, 0x47, 0x3C, 0x3E, 0x26, 0xDC, 0x9E, + 0xA8, 0xCC, 0xFD, 0xFF, 0x67, 0xB7, 0x7C, 0xDA, 0x4C, 0x3C, 0xD3, 0x6F, 0xCE, 0x0D, 0xD9, 0x10, + 0x79, 0xCA, 0xFD, 0x77, 0x2F, 0xD2, 0x11, 0xB2, 0x49, 0x85, 0x44, 0x96, 0x89, 0x98, 0x48, 0x3B, + 0x15, 0x1E, 0xD1, 0x1D, 0xBC, 0xD6, 0xBD, 0x96, 0x77, 0x30, 0xF8, 0xC7, 0xA1, 0x27, 0x74, 0x24, + 0x3E, 0xDC, 0x5E, 0xBC, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0xB4, 0xCB, 0x3B, 0x78, 0x4D, 0x82, + 0x37, 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0xE1, 0x11, + 0x2E, 0x1E, 0x1F, 0xE1, 0xED, 0x47, 0xE4, 0x99, 0x0F, 0x17, 0x1F, 0xD1, 0xF0, 0x98, 0x78, 0x3C, + 0x98, 0xFB, 0xBF, 0x1F, 0x9B, 0x65, 0x4E, 0x3F, 0x72, 0x9D, 0x39, 0xF3, 0xF0, 0x25, 0x7E, 0x80, + 0x9C, 0xF3, 0x1F, 0x58, 0x8F, 0x05, 0x88, 0x8B, 0x8F, 0x5C, 0x02, 0x44, 0xC4, 0x44, 0xDA, 0xA9, + 0xE0, 0x88, 0xAF, 0xC7, 0x6E, 0x41, 0x3A, 0x16, 0x1F, 0xC1, 0xBC, 0x5F, 0xDC, 0x39, 0x14, 0xFC, + 0x52, 0x00, 0x00, 0x00, 0x90, 0x85, 0xB7, 0xFF, 0xEA, 0x93, 0x3A, 0x3A, 0xC2, 0xA9, 0xA0, 0x48, + 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x78, 0xB8, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, + 0xDE, 0x7E, 0xD4, 0x7E, 0xEB, 0x55, 0x34, 0x3E, 0xCE, 0xD8, 0xE8, 0x38, 0xF3, 0xF8, 0xFB, 0x82, + 0x55, 0x22, 0xE4, 0xF4, 0xFD, 0x17, 0x99, 0x53, 0xF7, 0x5E, 0x6C, 0x4E, 0xDD, 0x7D, 0x91, 0x39, + 0x6B, 0xFF, 0x33, 0x75, 0xB7, 0x20, 0x36, 0x3C, 0xDC, 0xDA, 0x0F, 0x10, 0x11, 0x13, 0x69, 0xA7, + 0x62, 0xA3, 0xD1, 0x7A, 0xE4, 0x16, 0xA4, 0xD3, 0xF1, 0xE1, 0xE6, 0x1D, 0xFB, 0x53, 0xDE, 0x84, + 0x05, 0x00, 0x00, 0xD0, 0x8E, 0xE6, 0x6F, 0xC0, 0x52, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, + 0x46, 0x45, 0xD2, 0xC5, 0xA2, 0x23, 0xBA, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDC, 0x7E, 0xD4, 0x7C, + 0xDB, 0x55, 0x18, 0x1F, 0x8F, 0xD9, 0xF0, 0xB0, 0x3B, 0x1D, 0xFC, 0x78, 0xE6, 0x91, 0xF7, 0xF9, + 0xE1, 0x11, 0xEE, 0xF4, 0x7D, 0x36, 0x42, 0x36, 0x4E, 0x46, 0x88, 0xF7, 0x74, 0x25, 0x3E, 0xAA, + 0x01, 0x92, 0x39, 0x42, 0x44, 0x4C, 0xA4, 0x9D, 0x8A, 0x8C, 0x66, 0xDB, 0x7E, 0x71, 0xD7, 0xDF, + 0x82, 0x74, 0x43, 0x7C, 0xF8, 0x3B, 0x76, 0x0B, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xC8, 0xCA, 0x7F, + 0x03, 0xD6, 0xEE, 0x79, 0xF6, 0xE0, 0x5F, 0xFE, 0xF8, 0x70, 0x3F, 0x36, 0xBF, 0xFD, 0xB0, 0xF1, + 0xE1, 0x02, 0x24, 0x88, 0x0F, 0x17, 0x1E, 0xA7, 0x1F, 0x9D, 0xDC, 0xA9, 0x7B, 0x67, 0xD5, 0x04, + 0x88, 0xDB, 0xBB, 0x3F, 0x0E, 0x02, 0xE4, 0xA9, 0x0B, 0xED, 0xCF, 0x67, 0xE3, 0x23, 0x1E, 0x21, + 0x32, 0x30, 0x9A, 0x4D, 0xC4, 0x44, 0xDA, 0xA9, 0xC0, 0x48, 0xB2, 0x7D, 0x57, 0x18, 0x6F, 0x78, + 0x79, 0x57, 0x7E, 0xD0, 0x5E, 0xD7, 0xC4, 0x87, 0x9B, 0x7B, 0x13, 0xD6, 0xCB, 0x77, 0xF6, 0xDC, + 0x43, 0xFB, 0x00, 0x00, 0x00, 0x5D, 0xC1, 0x1C, 0x5A, 0xB5, 0xD6, 0xEC, 0x9C, 0x6D, 0x0F, 0xFF, + 0x25, 0x8E, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDD, 0x7E, 0xB8, 0xD7, 0xEC, 0x46, 0x6F, + 0x3F, 0xE2, 0xF1, 0x71, 0xFA, 0x81, 0xDA, 0xDB, 0x8F, 0x70, 0xEE, 0x16, 0xE4, 0xDC, 0x93, 0x76, + 0x1B, 0x2F, 0xF2, 0x23, 0xA4, 0x26, 0x40, 0x5C, 0x50, 0xA4, 0x8A, 0x10, 0x11, 0x13, 0x69, 0xA7, + 0xC2, 0x22, 0xE9, 0xB6, 0x7D, 0x24, 0xB8, 0x05, 0x59, 0x3A, 0x10, 0xFC, 0xE3, 0xD1, 0x15, 0xBA, + 0x2A, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0xB3, 0xAB, 0xFE, 0x1E, 0x01, 0x00, 0x00, 0xF4, + 0x0C, 0x73, 0x78, 0xF5, 0x7A, 0xB3, 0xF5, 0xC3, 0x36, 0x00, 0x4A, 0x1C, 0x1F, 0xC1, 0xD4, 0xED, + 0xC7, 0x59, 0x3F, 0x40, 0x6C, 0x7C, 0xB8, 0xDB, 0x8F, 0xC8, 0xB7, 0x5E, 0x55, 0xC3, 0xE3, 0xC7, + 0x95, 0xA9, 0xDB, 0x0F, 0x7F, 0x5F, 0xBF, 0xD0, 0xBC, 0xFB, 0x48, 0x25, 0x40, 0xCE, 0xB5, 0x75, + 0x0B, 0x22, 0x62, 0x22, 0xED, 0x54, 0x54, 0xA4, 0x9D, 0xBB, 0x05, 0x39, 0xB8, 0xAC, 0x6B, 0x6E, + 0x41, 0xBA, 0x2E, 0x3E, 0xDC, 0x78, 0x13, 0x16, 0x00, 0x00, 0x40, 0x76, 0xDE, 0xC8, 0x8A, 0xA1, + 0xD2, 0xC7, 0x47, 0xC3, 0xDB, 0x8F, 0x59, 0xD5, 0xF8, 0xA8, 0xDE, 0x7E, 0x84, 0xF1, 0x11, 0x84, + 0x87, 0x1F, 0x1F, 0x3F, 0xD2, 0xB7, 0x1F, 0x2E, 0x3E, 0xDC, 0x4E, 0x7F, 0xEB, 0x42, 0x73, 0xB6, + 0xAD, 0x5B, 0x10, 0x11, 0x13, 0x69, 0xA7, 0x62, 0x22, 0xCB, 0xB6, 0xD9, 0x18, 0x1D, 0x5E, 0xD6, + 0x15, 0xB7, 0x20, 0x5D, 0x19, 0x1F, 0xC1, 0xBC, 0x13, 0x5F, 0xEE, 0xA9, 0xD7, 0x16, 0x03, 0x00, + 0x00, 0x74, 0x0D, 0x6F, 0xDF, 0x55, 0x63, 0x65, 0xBF, 0xF9, 0x70, 0xAB, 0xBF, 0xFD, 0x88, 0x04, + 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x70, 0x44, 0x02, 0xE4, 0x94, 0x7B, 0xE8, 0xDC, 0xED, 0xDB, 0xE2, + 0xF6, 0x23, 0x88, 0x8F, 0x70, 0x13, 0x0F, 0x64, 0xBD, 0x05, 0x11, 0x31, 0x91, 0x76, 0x2A, 0x24, + 0x32, 0xED, 0x82, 0xCA, 0xF6, 0x5C, 0xD6, 0xF1, 0x5B, 0x90, 0x6E, 0x8E, 0x0F, 0x37, 0xEF, 0xF8, + 0x9F, 0x75, 0xE5, 0xB3, 0x32, 0x00, 0x00, 0x00, 0x5D, 0xCF, 0xEC, 0xBD, 0xDC, 0x86, 0x40, 0x89, + 0xE3, 0x23, 0xC1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xC1, 0xB7, 0x5E, 0x9D, 0x0A, 0x03, 0xE4, 0x07, + 0xAD, 0xE3, 0xC3, 0xED, 0xF4, 0x3D, 0x2D, 0x6E, 0x41, 0xE4, 0x44, 0x4C, 0xA4, 0x9D, 0x0C, 0x89, + 0x2C, 0x0B, 0xE2, 0xC3, 0xCD, 0xFD, 0xFD, 0xF5, 0x6F, 0x41, 0x96, 0xAF, 0x0B, 0xFE, 0x31, 0x99, + 0x52, 0xDD, 0x1E, 0x1F, 0xFE, 0x8E, 0xFF, 0x29, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x48, 0xCB, 0xBD, + 0x72, 0xD5, 0xEC, 0x59, 0x64, 0x63, 0x40, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0xBA, 0xA0, + 0x48, 0x33, 0x11, 0x1A, 0x8D, 0x16, 0x0F, 0x90, 0xE0, 0xF6, 0xE3, 0x6C, 0x92, 0xDB, 0x8F, 0x87, + 0xED, 0xEE, 0x69, 0x1D, 0x1F, 0xE1, 0xC2, 0x5B, 0x90, 0x64, 0x6F, 0xC4, 0x12, 0x31, 0x91, 0x76, + 0x32, 0x24, 0xB2, 0x2C, 0x12, 0x1F, 0xE1, 0x86, 0x16, 0x1A, 0xEF, 0xE0, 0xD2, 0x93, 0xC1, 0x3F, + 0x2A, 0x53, 0xA6, 0x27, 0xE2, 0xC3, 0xED, 0xC8, 0x6A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0x90, 0x96, + 0xFF, 0x0A, 0xDE, 0x9D, 0x9F, 0xB2, 0x41, 0xA0, 0xA2, 0x22, 0xE9, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, + 0x8A, 0xA4, 0x13, 0x91, 0xA1, 0x66, 0x83, 0xA3, 0x1A, 0x1F, 0x36, 0x3C, 0x12, 0xDF, 0x7E, 0x44, + 0xBF, 0xF5, 0xEA, 0xFB, 0xB1, 0xDB, 0x0F, 0x11, 0x1D, 0xD1, 0x25, 0xBF, 0x05, 0x11, 0x31, 0x91, + 0x76, 0x32, 0x24, 0xB2, 0x4C, 0xC4, 0x87, 0x9B, 0xFB, 0x7B, 0x3D, 0xC5, 0xB7, 0x20, 0x3D, 0x13, + 0x1F, 0x3F, 0xBF, 0xDC, 0x98, 0xB1, 0x15, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x20, 0x2D, 0x73, 0x78, + 0xE5, 0x7A, 0xB3, 0xED, 0xA3, 0x36, 0x0A, 0x54, 0x58, 0x24, 0x99, 0x88, 0x8B, 0x56, 0xAB, 0x0B, + 0x8A, 0x34, 0x8B, 0x45, 0x46, 0xB3, 0x45, 0x03, 0xC4, 0xAE, 0x12, 0x1F, 0x36, 0x0E, 0xC2, 0x00, + 0x69, 0xF4, 0xDA, 0xDD, 0x46, 0xB7, 0x1F, 0x22, 0x38, 0xD4, 0x26, 0x7E, 0x50, 0x09, 0x90, 0x9A, + 0x67, 0x41, 0x82, 0x10, 0xA9, 0xDC, 0x82, 0x88, 0x98, 0x48, 0x3B, 0x19, 0x12, 0x59, 0x26, 0xC2, + 0x23, 0xBA, 0x29, 0xBC, 0x05, 0xE9, 0xA9, 0xF8, 0x70, 0x7B, 0xF1, 0x3A, 0x63, 0x7F, 0xBD, 0x77, + 0x05, 0xBF, 0x7C, 0x00, 0x00, 0x00, 0x24, 0xE1, 0x1D, 0x5E, 0xB9, 0x41, 0x87, 0x45, 0x92, 0x89, + 0xB8, 0x68, 0x35, 0x19, 0x15, 0x49, 0x17, 0x0B, 0x8C, 0x66, 0x8B, 0xC5, 0x47, 0xE5, 0xF6, 0x23, + 0x12, 0x1F, 0xCD, 0x6E, 0x3F, 0xC2, 0x00, 0x89, 0xDE, 0x7E, 0x88, 0xD0, 0x68, 0xB8, 0x6F, 0x5C, + 0x68, 0xCE, 0x3E, 0xD1, 0xE0, 0x16, 0x64, 0x93, 0x88, 0x89, 0xB4, 0x93, 0x21, 0x91, 0x65, 0x22, + 0x38, 0xE2, 0x73, 0x7F, 0xDF, 0x0F, 0x5E, 0x57, 0xF8, 0x2D, 0x48, 0xCF, 0xC5, 0x47, 0x30, 0xEF, + 0xC4, 0x9D, 0x1B, 0x82, 0xDF, 0x02, 0x00, 0x00, 0x00, 0x92, 0xF0, 0x0E, 0x5E, 0x3D, 0xAA, 0xE3, + 0xA2, 0xD5, 0x44, 0x5C, 0xB4, 0x5A, 0x5D, 0x50, 0xA4, 0x59, 0x2C, 0x30, 0x9A, 0xAD, 0x41, 0x7C, + 0xF8, 0xB7, 0x1F, 0x2E, 0x3E, 0xD4, 0xED, 0x47, 0x10, 0x1F, 0xD5, 0xDB, 0x8F, 0x87, 0xEC, 0xBE, + 0x91, 0x21, 0x3E, 0x82, 0x85, 0xB7, 0x20, 0xE7, 0x9F, 0x72, 0x7F, 0xDD, 0x20, 0x42, 0x9E, 0x9E, + 0x69, 0x7F, 0x2D, 0x2E, 0x20, 0x82, 0xA9, 0xB8, 0x68, 0x35, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, + 0xD1, 0x76, 0xCD, 0x31, 0xDE, 0xF0, 0xD2, 0x71, 0x33, 0xD4, 0x3F, 0x2B, 0xF8, 0xC7, 0x26, 0x57, + 0xBD, 0x1A, 0x1F, 0x7E, 0x80, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x74, 0xBC, 0xFD, 0x9F, 0x1D, + 0xD7, 0x81, 0xD1, 0x6C, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xC5, 0x02, 0xA3, 0xD5, 0xEA, + 0x02, 0x24, 0x88, 0x8F, 0xF8, 0xED, 0x47, 0x10, 0x1F, 0xF2, 0xD9, 0x8F, 0xFB, 0x83, 0xDB, 0x0F, + 0x11, 0x17, 0x89, 0x16, 0xBB, 0x05, 0x39, 0x1F, 0xC4, 0x47, 0x5B, 0x01, 0x22, 0x43, 0x22, 0xCB, + 0x44, 0x64, 0x34, 0x9B, 0x7B, 0x66, 0xC5, 0xDD, 0x82, 0x1C, 0x5C, 0x9A, 0xFB, 0x07, 0xEF, 0xF5, + 0x72, 0x7C, 0xB8, 0x79, 0xC7, 0xFE, 0x64, 0x3C, 0xF8, 0xAD, 0x00, 0x00, 0x00, 0xA0, 0x15, 0x33, + 0xDA, 0x3F, 0x2B, 0xFD, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x8B, 0xC5, 0x45, + 0x92, 0xC5, 0xE3, 0x23, 0x7A, 0xFB, 0x11, 0xC4, 0x47, 0xCD, 0x9B, 0xAF, 0x1A, 0xDD, 0x7E, 0xA8, + 0xB0, 0x48, 0xB1, 0x33, 0xDF, 0xBB, 0x70, 0xF2, 0x59, 0x90, 0xA7, 0x6C, 0x7C, 0xB4, 0x13, 0x21, + 0x32, 0x24, 0xB2, 0x4C, 0x04, 0x46, 0x92, 0x15, 0x70, 0x0B, 0xD2, 0xEB, 0xF1, 0xE1, 0xEF, 0xC8, + 0x4D, 0xC6, 0x8C, 0xFD, 0x87, 0x42, 0x6E, 0x86, 0x00, 0x00, 0x00, 0x4A, 0xC7, 0x7F, 0x03, 0xD6, + 0xAE, 0x4F, 0xDB, 0x48, 0x50, 0xA1, 0xA1, 0x26, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, + 0x8B, 0x56, 0xB3, 0xD1, 0x31, 0x19, 0x20, 0x17, 0x55, 0x02, 0x24, 0xB8, 0xFD, 0xA8, 0xBE, 0x76, + 0xB7, 0x7A, 0xFB, 0xF1, 0xBE, 0xC6, 0xB7, 0x1F, 0x22, 0x28, 0xB2, 0xEC, 0xEC, 0x63, 0x2E, 0x42, + 0x2A, 0x01, 0xE2, 0xDF, 0x82, 0x64, 0x89, 0x10, 0x19, 0x12, 0x59, 0x26, 0xC2, 0x22, 0xE9, 0x72, + 0xBE, 0x05, 0x29, 0x45, 0x7C, 0xB8, 0xBD, 0x34, 0xC0, 0x9B, 0xB0, 0x00, 0x00, 0x00, 0x92, 0x32, + 0x87, 0x57, 0xAD, 0x4B, 0xFE, 0x0A, 0x5E, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x61, + 0x91, 0x74, 0xF1, 0xF8, 0xC8, 0x74, 0xFB, 0xA1, 0x63, 0x22, 0xFD, 0x66, 0x9A, 0x33, 0xF7, 0xCF, + 0x34, 0x67, 0x9F, 0x9C, 0x8C, 0x90, 0xD4, 0x01, 0x22, 0x43, 0x22, 0xCB, 0x44, 0x54, 0xA4, 0xDD, + 0xCE, 0xD9, 0xC6, 0x1B, 0xBE, 0xBE, 0xED, 0x5B, 0x90, 0xD2, 0xC4, 0x87, 0x1B, 0x6F, 0xC2, 0x02, + 0x00, 0x00, 0x48, 0xCE, 0xB8, 0x57, 0xF0, 0xCA, 0xD8, 0x88, 0x4F, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, + 0x48, 0x3A, 0x11, 0x16, 0x49, 0xE6, 0x6E, 0x3F, 0xEC, 0x8F, 0x7E, 0x7C, 0xC4, 0x6E, 0x3F, 0xEA, + 0x9F, 0xFD, 0x68, 0x70, 0xFB, 0x71, 0x5F, 0xFB, 0xDF, 0x7A, 0x55, 0xD9, 0xCC, 0xEA, 0xDE, 0x0D, + 0x6E, 0x41, 0xCE, 0x35, 0xBA, 0x05, 0x51, 0xE1, 0xE1, 0x26, 0x43, 0x22, 0xCB, 0x44, 0x4C, 0x64, + 0xDA, 0x7B, 0x8D, 0x39, 0x70, 0xB5, 0x7B, 0x2D, 0xEF, 0x60, 0xF0, 0x8F, 0x50, 0x6A, 0xA5, 0x8A, + 0x0F, 0xB7, 0xE7, 0xAF, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x49, 0x79, 0x07, 0xAF, 0x4B, 0xF0, + 0x06, 0x2C, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x51, 0x91, 0x66, 0xE1, 0xCD, 0x47, + 0x83, 0xDB, 0x8F, 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0x78, 0x30, 0xAF, 0x6F, 0xBD, 0x9A, 0x8C, 0x0F, + 0xB7, 0x4C, 0xB7, 0x20, 0x32, 0x24, 0xB2, 0x4C, 0x85, 0x44, 0x96, 0xD9, 0xF8, 0x70, 0xDB, 0xFE, + 0x71, 0xF7, 0x6D, 0x58, 0xC6, 0x8C, 0x5C, 0x9B, 0xFA, 0x13, 0xC0, 0x4B, 0x17, 0x1F, 0xC1, 0xBC, + 0x13, 0x77, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x24, 0xBC, 0x7D, 0x57, 0x8E, 0xE9, 0xE8, 0x08, + 0x27, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, 0x8A, 0xA4, 0xF3, 0x6F, 0x3F, 0x82, 0xF8, + 0x88, 0xDD, 0x7E, 0xA8, 0x67, 0x3F, 0xEA, 0x3F, 0x74, 0xD0, 0xC6, 0x47, 0x2E, 0xB7, 0x1F, 0xB5, + 0xF1, 0x11, 0xEE, 0xDD, 0x47, 0x5A, 0x3C, 0x0B, 0xD2, 0x0B, 0xF1, 0xF1, 0x74, 0xB0, 0xFD, 0xE9, + 0x6F, 0x41, 0xCA, 0x1A, 0x1F, 0x6E, 0xDE, 0xB1, 0x5B, 0xA6, 0xE4, 0x83, 0x1A, 0x01, 0x00, 0x00, + 0x7A, 0x9E, 0xD9, 0x7B, 0x99, 0x8D, 0x06, 0x15, 0x1E, 0x6E, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, + 0xD2, 0xC5, 0x82, 0x22, 0xED, 0xC2, 0xF0, 0x68, 0x70, 0xFB, 0x51, 0xF7, 0xEC, 0x47, 0x10, 0x20, + 0x95, 0xDB, 0x0F, 0x1B, 0x1F, 0xB9, 0xDC, 0x7E, 0xE8, 0xF8, 0x70, 0x3B, 0x7D, 0xEF, 0x4C, 0x73, + 0xAE, 0xD1, 0x2D, 0x88, 0x1F, 0x1D, 0x3D, 0x12, 0x1F, 0xF6, 0xFF, 0xF6, 0xB6, 0x7F, 0xDC, 0x05, + 0x48, 0xE2, 0x5B, 0x90, 0x32, 0xC7, 0x87, 0xBF, 0x23, 0x37, 0x99, 0xE0, 0xB7, 0x0A, 0x00, 0x00, + 0x80, 0x46, 0xCC, 0xE1, 0xFE, 0x25, 0x66, 0x68, 0xBE, 0x0D, 0x87, 0x72, 0xC4, 0x47, 0xCB, 0xDB, + 0x0F, 0x11, 0x1F, 0x95, 0xDB, 0x0F, 0x1B, 0x1E, 0xB9, 0xDC, 0x7E, 0xE8, 0xF0, 0x88, 0x2E, 0xBC, + 0x05, 0x69, 0xF8, 0x2C, 0x88, 0x0C, 0x89, 0x2C, 0x53, 0x21, 0x91, 0x65, 0x22, 0x3E, 0xEC, 0x8F, + 0xFE, 0xF6, 0x7C, 0xC6, 0x9C, 0x3F, 0x70, 0xFD, 0x50, 0xF0, 0x8F, 0x53, 0x43, 0xA5, 0x8F, 0x0F, + 0x37, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x9A, 0xFF, 0x0A, 0x5E, 0xF9, 0x06, 0x2C, 0x11, 0x17, + 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x50, 0xA4, 0x9A, 0x8D, 0x8F, 0x30, 0x3C, 0xC2, 0xF8, 0x48, + 0x7A, 0xFB, 0xF1, 0x63, 0x1B, 0x1E, 0x2E, 0x40, 0x7E, 0xD8, 0xEE, 0xED, 0x87, 0x0E, 0x8E, 0xF8, + 0xDC, 0x2D, 0x48, 0xE3, 0x67, 0x41, 0x54, 0x48, 0x64, 0x99, 0x0A, 0x89, 0x2C, 0x6B, 0x12, 0x1F, + 0x4F, 0xBD, 0xD7, 0x9C, 0xDF, 0xF2, 0x21, 0x73, 0x7E, 0xFF, 0x32, 0x73, 0x76, 0xFF, 0xD2, 0x86, + 0x07, 0xEF, 0x69, 0x11, 0x1F, 0x6E, 0x2F, 0x5E, 0xE7, 0x02, 0x64, 0x5D, 0xF0, 0xDB, 0x06, 0x00, + 0x00, 0x80, 0xE2, 0xBF, 0x01, 0x6B, 0xEB, 0x87, 0x6C, 0x40, 0xF4, 0x7E, 0x7C, 0x64, 0xB9, 0xFD, + 0xA8, 0xC6, 0x87, 0xBB, 0xFD, 0xF8, 0x56, 0x3B, 0xB7, 0x1F, 0x3A, 0x36, 0x1A, 0x6D, 0xE2, 0x21, + 0x75, 0x0B, 0x32, 0xC3, 0x9F, 0x0E, 0x8A, 0x34, 0x53, 0x21, 0x91, 0x65, 0x2D, 0xE2, 0xC3, 0x6D, + 0xE3, 0x05, 0xE6, 0xFC, 0xEE, 0x25, 0xE6, 0xDC, 0xDE, 0x65, 0xF2, 0x01, 0xEC, 0x69, 0x13, 0x1F, + 0x6E, 0xCF, 0x5F, 0x69, 0xCC, 0x89, 0x3B, 0x73, 0xFF, 0x94, 0x78, 0x00, 0x00, 0x80, 0x52, 0xF1, + 0x0E, 0xAD, 0x1C, 0xEC, 0xF9, 0xF8, 0xC8, 0x78, 0xFB, 0x71, 0xEA, 0x51, 0x1B, 0x1D, 0xB9, 0xDC, + 0x7E, 0xE8, 0xC8, 0x68, 0xB6, 0xD3, 0xF7, 0xC4, 0x6F, 0x41, 0x2A, 0xF1, 0xD1, 0x7E, 0x80, 0xA8, + 0x90, 0xC8, 0xB2, 0x64, 0xF1, 0x71, 0xEE, 0x49, 0xBB, 0x4D, 0x1F, 0x76, 0x01, 0x62, 0xCE, 0x0E, + 0xD5, 0xDE, 0x82, 0x4C, 0xAB, 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x6F, 0xC2, 0x02, 0x00, 0x00, + 0x68, 0xC6, 0xDB, 0x77, 0x45, 0xE4, 0x15, 0xBC, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xA9, + 0xA0, 0x48, 0xB3, 0x20, 0x3E, 0x82, 0xA5, 0xBB, 0xFD, 0x88, 0xC4, 0x47, 0x5B, 0xB7, 0x1F, 0x3A, + 0x30, 0x92, 0x6C, 0xE2, 0x81, 0xE8, 0x2D, 0x88, 0x8D, 0x8F, 0xB6, 0x23, 0x44, 0x85, 0x44, 0x96, + 0x25, 0x8F, 0x8F, 0xB3, 0x83, 0x76, 0x4F, 0x5C, 0x60, 0xDE, 0xDD, 0xB1, 0xC4, 0x4C, 0xEC, 0x5E, + 0x5E, 0x3D, 0x7C, 0x4F, 0xC7, 0xF8, 0x70, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x2D, 0x98, 0x7D, + 0xF6, 0x70, 0xD7, 0xEB, 0xF1, 0x91, 0xE6, 0xF6, 0x23, 0x8C, 0x8F, 0x5C, 0x6E, 0x3F, 0x74, 0x58, + 0x24, 0x5D, 0xE5, 0x16, 0x64, 0xA6, 0x8D, 0x10, 0x1B, 0x20, 0x4F, 0xB5, 0x1B, 0x20, 0x2A, 0x24, + 0xB2, 0x2C, 0x43, 0x7C, 0x3C, 0x7E, 0x81, 0x39, 0x33, 0xF8, 0x41, 0x17, 0x20, 0xE6, 0xF4, 0x8E, + 0xA5, 0x03, 0xD3, 0x35, 0x3E, 0xFC, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x00, 0x34, 0x62, + 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x0B, 0x75, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, + 0x66, 0x91, 0xF8, 0x08, 0xA6, 0x6E, 0x3F, 0xAA, 0x01, 0x52, 0x73, 0xFB, 0x31, 0xAB, 0xFE, 0xF6, + 0xE3, 0x9B, 0x2A, 0x2E, 0x5A, 0x4D, 0x47, 0x45, 0x9A, 0xBD, 0xF3, 0xD7, 0x33, 0xCC, 0x99, 0x1F, + 0x4E, 0x06, 0x48, 0xF6, 0x5B, 0x10, 0x15, 0x12, 0x59, 0x96, 0x31, 0x3E, 0x1E, 0x9D, 0x61, 0x4E, + 0xFF, 0xD8, 0xEE, 0x99, 0x45, 0x66, 0xE2, 0xC0, 0xAA, 0x93, 0xD3, 0x36, 0x3E, 0xDC, 0x8E, 0xAC, + 0x32, 0xE6, 0xF8, 0x1D, 0x4B, 0x82, 0x2F, 0x31, 0x00, 0x00, 0x00, 0x44, 0x99, 0x91, 0xFE, 0x01, + 0xB3, 0xF3, 0x12, 0x1D, 0x18, 0xCD, 0x26, 0xA3, 0x22, 0xE9, 0x54, 0x50, 0xA4, 0x59, 0x2C, 0x3E, + 0x12, 0xDC, 0x7E, 0x4C, 0xB8, 0x00, 0x79, 0xDC, 0xDD, 0x7E, 0xC4, 0xE2, 0xC3, 0xED, 0x7B, 0x59, + 0xBE, 0xF5, 0x4A, 0x07, 0x45, 0x9A, 0xB9, 0xF8, 0xF0, 0x77, 0xF7, 0x0C, 0x7B, 0x90, 0x6F, 0xE7, + 0x16, 0x44, 0x85, 0x44, 0x96, 0xB5, 0x17, 0x1F, 0xA7, 0x1E, 0x76, 0x01, 0x32, 0xDB, 0x98, 0x63, + 0x77, 0x9A, 0x69, 0x1B, 0x1F, 0x3F, 0xBF, 0xCC, 0x98, 0x17, 0x3F, 0x67, 0xCC, 0x89, 0x2F, 0xAD, + 0x0D, 0xBE, 0xC4, 0x00, 0x00, 0x00, 0x10, 0xE5, 0x1D, 0x5A, 0x75, 0x97, 0xD9, 0x7E, 0xB1, 0x8E, + 0x8C, 0x46, 0x93, 0x51, 0x91, 0x74, 0x2A, 0x28, 0xD2, 0x2C, 0x16, 0x1F, 0x2A, 0x40, 0x1A, 0x3E, + 0xFB, 0x61, 0xE3, 0x23, 0x97, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0x56, 0x8D, 0x8F, 0x60, 0x67, 0xBE, + 0x5F, 0x09, 0x90, 0x73, 0xD1, 0x5B, 0x90, 0x20, 0x44, 0x74, 0x74, 0x84, 0x53, 0x21, 0x91, 0x65, + 0x39, 0xC4, 0xC7, 0xD3, 0x1F, 0x33, 0xDE, 0xD1, 0xDB, 0xA7, 0x77, 0x7C, 0xB8, 0x3D, 0xFF, 0x59, + 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x88, 0x19, 0x59, 0xB9, 0x5E, 0x46, 0x46, 0xA3, 0xC9, 0xA8, + 0x48, 0x3A, 0x15, 0x14, 0x69, 0x56, 0x1F, 0x1E, 0xD5, 0xF8, 0xB0, 0xE1, 0x31, 0x79, 0xFB, 0x11, + 0xF9, 0xD6, 0xAB, 0xEA, 0xED, 0xC7, 0x45, 0x95, 0xDB, 0x0F, 0xBB, 0xF6, 0x6E, 0x3F, 0x74, 0x50, + 0xA4, 0x59, 0x3C, 0x3E, 0xFC, 0x65, 0xBA, 0x05, 0x51, 0x21, 0x91, 0x65, 0xC4, 0x47, 0xFB, 0x0B, + 0xE2, 0x23, 0x98, 0xF7, 0x8B, 0x3B, 0x5B, 0x7E, 0x30, 0x23, 0x00, 0x00, 0xC0, 0xB4, 0xE4, 0x1D, + 0xB8, 0x7A, 0x54, 0x86, 0x86, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, 0x66, 0xB1, 0xF8, 0x88, + 0x07, 0x88, 0x5D, 0xF5, 0x5B, 0xAF, 0xC2, 0x00, 0xA9, 0x3E, 0x78, 0x6E, 0xE3, 0xC3, 0x06, 0x48, + 0xFB, 0xB7, 0x1F, 0x3A, 0x28, 0xD2, 0x4C, 0xC6, 0x47, 0xB0, 0xF0, 0x16, 0xC4, 0xBD, 0x92, 0xB7, + 0xF5, 0x2D, 0x88, 0x0A, 0x89, 0x2C, 0x23, 0x3E, 0xDA, 0x5F, 0x6D, 0x7C, 0xF8, 0x01, 0x72, 0xF4, + 0xD6, 0xB1, 0xE0, 0x4B, 0x0C, 0x00, 0x00, 0x00, 0x51, 0xDE, 0xFE, 0x2B, 0x4F, 0xCA, 0xD8, 0x88, + 0x4F, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x78, 0x88, 0xF8, 0x08, 0x6F, 0x3F, 0x6A, + 0x1E, 0x3C, 0xF7, 0x6F, 0x3F, 0x2E, 0x9A, 0xBC, 0xFD, 0x08, 0xE3, 0x23, 0x0C, 0x90, 0xFB, 0xD3, + 0xDC, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x1D, 0x35, 0x73, 0xB7, 0x20, 0x8F, 0x4D, 0xDE, 0x82, + 0xF8, 0x11, 0x62, 0x63, 0xA3, 0x3E, 0x40, 0x54, 0x48, 0x64, 0x19, 0xF1, 0xD1, 0xFE, 0xEA, 0xE3, + 0xC3, 0xDF, 0xB1, 0x2F, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x00, 0x25, 0xD1, 0x1B, 0xB0, 0x64, 0x54, + 0x24, 0x9D, 0x0A, 0x8A, 0x34, 0x8B, 0x85, 0x47, 0x93, 0xF8, 0xA8, 0x3E, 0x78, 0x5E, 0xBD, 0xFD, + 0xB0, 0xF1, 0x11, 0xDE, 0x7E, 0xC4, 0xE3, 0xE3, 0x21, 0xBB, 0xBB, 0x55, 0x68, 0xA8, 0xE9, 0xA0, + 0x48, 0x33, 0x19, 0x1C, 0x62, 0xA7, 0xBF, 0x3B, 0x23, 0x78, 0x16, 0xA4, 0xC1, 0xB7, 0x62, 0x3D, + 0xAD, 0x42, 0x22, 0xCB, 0x88, 0x8F, 0xF6, 0x27, 0xC2, 0x23, 0x1C, 0x6F, 0xC2, 0x02, 0x00, 0x00, + 0xA8, 0xE7, 0xBF, 0x01, 0x6B, 0xD7, 0x1C, 0x1D, 0x1D, 0xE1, 0x64, 0x54, 0x24, 0x9D, 0x0A, 0x8A, + 0x34, 0x8B, 0x85, 0x47, 0x38, 0x15, 0x20, 0xF1, 0xD7, 0xEE, 0x3E, 0x39, 0x19, 0x1F, 0xF2, 0xCD, + 0x57, 0x89, 0x6F, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0A, 0x8D, 0x66, 0x7B, 0x37, 0x7E, 0x0B, 0x12, + 0x46, 0x88, 0x8B, 0x8F, 0x70, 0x32, 0x2A, 0x92, 0x8E, 0xF8, 0x68, 0x7F, 0x22, 0x3A, 0xA2, 0x7B, + 0xF1, 0x7A, 0x63, 0x5E, 0xBE, 0xB3, 0xE6, 0x53, 0xE1, 0x01, 0x00, 0x00, 0xA6, 0x3D, 0x73, 0xA8, + 0x7F, 0xAD, 0xD9, 0xF1, 0x49, 0x1D, 0x1E, 0x6E, 0x32, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, 0xC5, + 0xA2, 0x23, 0xBA, 0x78, 0x7C, 0x44, 0x6F, 0x3F, 0x82, 0xF8, 0x98, 0xBC, 0xFD, 0x10, 0xDF, 0x7A, + 0x95, 0xF8, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xA9, 0xC0, 0x68, 0x35, 0x77, 0x0B, 0x52, 0xF7, 0xE1, + 0x84, 0x36, 0x3A, 0xF2, 0x09, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xE0, 0x88, 0xEF, 0x85, 0xAB, 0x79, + 0x13, 0x16, 0x00, 0x00, 0x40, 0x9C, 0xFF, 0x06, 0xAC, 0xAD, 0x1F, 0xEC, 0xB9, 0xF8, 0x68, 0x74, + 0xFB, 0xE1, 0xE2, 0xE3, 0x6C, 0x2C, 0x3E, 0xB2, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x17, + 0x49, 0xF7, 0xEE, 0x8F, 0x2B, 0x01, 0xE2, 0xBF, 0x96, 0xF7, 0x29, 0x1B, 0x1F, 0x6E, 0xD1, 0x08, + 0x91, 0x71, 0xD1, 0x6A, 0xC4, 0x47, 0xFB, 0x13, 0xB1, 0xD1, 0x60, 0xDE, 0x89, 0x2F, 0x0D, 0x06, + 0x5F, 0x6A, 0x00, 0x00, 0x00, 0x70, 0xBC, 0xE1, 0xE5, 0x43, 0x3D, 0x15, 0x1F, 0x6E, 0xF1, 0xF8, + 0x88, 0xDE, 0x7E, 0xB8, 0xF8, 0x68, 0x75, 0xFB, 0xF1, 0xA0, 0x9D, 0x0C, 0x8E, 0xE8, 0x74, 0x50, + 0xA4, 0x99, 0x8A, 0x8A, 0x34, 0x3B, 0xFD, 0xED, 0xE0, 0x16, 0xE4, 0x49, 0x1B, 0x20, 0x36, 0x0A, + 0xEA, 0x02, 0x24, 0x75, 0x84, 0x10, 0x1F, 0xED, 0x4F, 0x87, 0x46, 0xA3, 0x79, 0x47, 0x6F, 0x1D, + 0x0D, 0xBE, 0xD4, 0x00, 0x00, 0x00, 0xE0, 0x78, 0x7B, 0xAF, 0xA8, 0x7F, 0x05, 0xAF, 0x8C, 0x8A, + 0xA4, 0x53, 0x41, 0x91, 0x66, 0x22, 0x38, 0xA2, 0xB3, 0xD1, 0xE1, 0x7E, 0xAC, 0xBB, 0xFD, 0xB0, + 0xF1, 0x71, 0x6E, 0xE3, 0x45, 0xC9, 0x6E, 0x3F, 0xEE, 0x6B, 0x75, 0xFB, 0xA1, 0x83, 0x22, 0xCD, + 0x54, 0x50, 0x64, 0xD9, 0xBB, 0xF6, 0xD0, 0x1F, 0x06, 0x48, 0x7B, 0xB7, 0x20, 0xC4, 0x47, 0xFB, + 0xD3, 0x91, 0xD1, 0x74, 0xC7, 0x6E, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x51, 0x66, 0xEF, 0xE2, + 0xDE, 0x89, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x08, 0x03, 0x24, 0x88, 0x8F, 0x78, 0x80, 0xD4, + 0xC5, 0x47, 0xCB, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0xA6, 0x42, 0x22, 0xDB, 0x2E, 0x30, 0xA7, 0xBF, + 0x6D, 0xA3, 0x60, 0x70, 0x32, 0x42, 0x6A, 0x02, 0xC4, 0x85, 0x45, 0xA2, 0x08, 0x21, 0x3E, 0xDA, + 0x9F, 0x88, 0x8B, 0x24, 0x73, 0x6F, 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x1B, 0x00, 0x00, + 0xC0, 0xF4, 0x66, 0x46, 0xFA, 0x67, 0xD7, 0xBC, 0x82, 0x57, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, + 0x33, 0x11, 0x1B, 0xF1, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, 0xDF, 0x7E, 0xD8, 0xF0, 0x10, 0xB7, 0x1F, + 0xF2, 0x43, 0x07, 0x9B, 0xDE, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x76, 0x41, 0x75, + 0xE1, 0x2D, 0xC8, 0xB9, 0x4C, 0xB7, 0x20, 0xC4, 0x47, 0xFB, 0x13, 0x61, 0x91, 0x74, 0x63, 0xCB, + 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xC8, 0x7F, 0x05, 0x6F, 0xF8, 0x06, 0x2C, 0x19, 0x15, 0x49, + 0xA7, 0x82, 0x22, 0xCD, 0x62, 0xA1, 0xD1, 0x68, 0x61, 0x78, 0x84, 0xF1, 0xE1, 0xF6, 0xD4, 0x85, + 0x35, 0xDF, 0x7A, 0x15, 0x0F, 0x90, 0x53, 0x2E, 0x40, 0xC2, 0xDB, 0x8F, 0x1F, 0xD9, 0xC9, 0xF0, + 0x70, 0xD3, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x6C, 0x32, 0x3E, 0xDC, 0x4E, 0x7D, 0xD3, 0xC5, + 0x41, 0x96, 0x5B, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xA8, 0x48, 0xB3, 0x17, 0x3F, 0xC7, 0x9B, 0xB0, + 0x00, 0x00, 0x00, 0x42, 0xFE, 0x1B, 0xB0, 0xB6, 0x7D, 0xC4, 0x1E, 0xEE, 0x55, 0x54, 0x24, 0x9D, + 0x0A, 0x8A, 0x34, 0x13, 0xA1, 0xA1, 0x66, 0xA3, 0xC3, 0xFD, 0x58, 0x7B, 0xFB, 0x61, 0xE3, 0x23, + 0xCD, 0xED, 0xC7, 0xB7, 0x1A, 0xDD, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x56, 0x1B, + 0x1F, 0xE1, 0x26, 0x7E, 0x94, 0xF6, 0x16, 0x84, 0xF8, 0x68, 0x7F, 0x22, 0x28, 0x32, 0x8C, 0x37, + 0x61, 0x01, 0x00, 0x00, 0x04, 0xBC, 0x91, 0x81, 0x0D, 0x3A, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, + 0xC5, 0x22, 0xA3, 0xD9, 0xC2, 0xF0, 0x88, 0xC4, 0x47, 0xA2, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x68, + 0xD7, 0xA3, 0xF1, 0xE1, 0xD6, 0xF2, 0x16, 0x84, 0xF8, 0xC8, 0x79, 0x3A, 0x26, 0xB2, 0xCC, 0x3B, + 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0x38, 0xDE, 0x81, 0xAB, 0x47, 0x75, 0x58, 0x24, 0x99, + 0x0A, 0x8A, 0x34, 0x13, 0x91, 0xD1, 0x62, 0xD5, 0x00, 0x09, 0xE3, 0xA3, 0xED, 0xDB, 0x0F, 0x1D, + 0x14, 0x69, 0xA6, 0x43, 0x22, 0xCB, 0x74, 0x78, 0x44, 0x17, 0xDE, 0x82, 0xB8, 0x78, 0x68, 0x7C, + 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x12, 0x59, 0xE7, 0x1D, 0xBB, 0x65, 0x3C, 0xF8, 0x92, 0x03, + 0x00, 0x00, 0x98, 0xDE, 0xBC, 0x7D, 0x57, 0x8C, 0xEB, 0xB8, 0x68, 0x35, 0x15, 0x14, 0x69, 0xA6, + 0x03, 0xA3, 0xE1, 0x6A, 0x6E, 0x3F, 0x6C, 0x7C, 0x34, 0xBB, 0xFD, 0x08, 0xE3, 0xA3, 0xE5, 0xED, + 0x87, 0x0E, 0x8A, 0x34, 0xD3, 0x21, 0x91, 0x65, 0x3A, 0x38, 0xE2, 0xF3, 0x6F, 0x41, 0x1E, 0x6F, + 0x76, 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x11, 0x6D, 0xCD, 0xBD, 0x09, 0x6B, 0xEC, 0x8B, 0xB3, + 0x82, 0x2F, 0x3B, 0x00, 0x00, 0x80, 0xE9, 0xCB, 0x0C, 0x2D, 0xB0, 0x07, 0x7C, 0x15, 0x18, 0xCD, + 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x60, 0x24, 0x58, 0x18, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xB9, 0x1F, + 0xC9, 0x6E, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0E, 0x89, 0x2C, 0xD3, 0xB1, 0xD1, 0x68, 0x67, 0xBE, + 0x2F, 0x9E, 0x05, 0xF1, 0x43, 0x24, 0x12, 0x1E, 0x6E, 0xC4, 0x47, 0x86, 0x89, 0x78, 0xC8, 0x63, + 0x63, 0xCB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x80, 0xFF, 0x06, 0xAC, 0x9D, 0xB3, 0xED, 0xE1, 0x5E, + 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0x33, 0x1D, 0x17, 0x4D, 0x17, 0xB9, 0xF9, 0xF0, 0xE3, 0x43, + 0xDC, 0x7E, 0x4C, 0xB8, 0x3D, 0x1E, 0xB9, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xE5, 0x89, 0x0F, + 0x7F, 0x77, 0xAB, 0x5B, 0x90, 0x4A, 0x68, 0x18, 0x1B, 0x19, 0xC4, 0x47, 0xD6, 0x89, 0x70, 0xC8, + 0x65, 0x8B, 0x8D, 0x79, 0xF1, 0x5A, 0xE3, 0xFD, 0xE2, 0x4B, 0x77, 0x05, 0x5F, 0x7A, 0x00, 0x00, + 0x00, 0xD3, 0x93, 0x0D, 0x90, 0x75, 0x66, 0xC7, 0x27, 0xEC, 0x21, 0x5F, 0x85, 0x86, 0x9A, 0x0A, + 0x8A, 0x34, 0x13, 0x71, 0x91, 0x64, 0x61, 0x7C, 0xC4, 0x6E, 0x3F, 0x12, 0x3F, 0xFB, 0xF1, 0xCD, + 0x12, 0xC5, 0x47, 0xB0, 0x33, 0xDF, 0x8B, 0x3E, 0x0B, 0x52, 0x89, 0x8C, 0x70, 0x2E, 0x40, 0xC2, + 0xF0, 0x20, 0x3E, 0x92, 0x4E, 0x85, 0x43, 0x1E, 0xB3, 0xF1, 0xE1, 0x66, 0x7F, 0xED, 0xDE, 0x89, + 0x3B, 0x36, 0x04, 0x5F, 0x7A, 0x00, 0x00, 0x00, 0xD3, 0x93, 0xFF, 0x0A, 0x5E, 0x19, 0x1A, 0x6A, + 0x2A, 0x28, 0xD2, 0x4C, 0x84, 0x45, 0xAB, 0xD9, 0xF0, 0xA8, 0xC6, 0x87, 0x0D, 0x8F, 0xC9, 0xDB, + 0x8F, 0xD8, 0xB7, 0x5E, 0x45, 0x6F, 0x3F, 0xEC, 0x1A, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, + 0x12, 0x59, 0xA6, 0xC3, 0x22, 0xF1, 0xAA, 0xB7, 0x20, 0x36, 0x40, 0x36, 0xBA, 0xC0, 0x08, 0x82, + 0x23, 0x12, 0x1E, 0xC4, 0x47, 0xD2, 0xA9, 0x70, 0xC8, 0x63, 0x41, 0x7C, 0x04, 0xF3, 0x4E, 0xFC, + 0x39, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x9B, 0x77, 0xF0, 0xBA, 0x84, 0x6F, 0xC0, 0x52, 0x41, + 0x91, 0x66, 0xB1, 0xB0, 0x48, 0x3A, 0x17, 0x20, 0xE1, 0xCD, 0x87, 0x5D, 0xF5, 0x5B, 0xAF, 0xE4, + 0xB3, 0x1F, 0x17, 0xB5, 0xB8, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x04, 0x45, + 0x86, 0x9D, 0xFE, 0xCE, 0x7B, 0xFD, 0xB0, 0x08, 0x23, 0xA4, 0x1A, 0x1C, 0x2E, 0x3E, 0x82, 0x28, + 0x21, 0x3E, 0x5A, 0x4D, 0x85, 0x43, 0x1E, 0xAB, 0x8D, 0x0F, 0x3F, 0x40, 0x8E, 0x7D, 0x81, 0x37, + 0x61, 0x01, 0x00, 0x80, 0xE9, 0xCD, 0xDB, 0xFB, 0xD9, 0x31, 0x1D, 0x1C, 0xD1, 0xA9, 0xA0, 0x48, + 0xB3, 0x58, 0x54, 0x24, 0x5D, 0x2C, 0x3E, 0xC2, 0xDB, 0x8F, 0xBA, 0xF8, 0x88, 0xDE, 0x7E, 0x84, + 0xF1, 0x11, 0x06, 0xC8, 0x86, 0xF0, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xE9, 0x90, 0xC8, 0x32, 0x1D, + 0x13, 0xA9, 0xF7, 0x57, 0xEF, 0xF5, 0xF7, 0xEE, 0xA3, 0x93, 0x01, 0x12, 0x9F, 0x1F, 0x27, 0x2E, + 0x3C, 0x88, 0x8F, 0x06, 0x53, 0xE1, 0x90, 0xC7, 0xEA, 0xE3, 0xC3, 0xDF, 0x91, 0x1B, 0x4C, 0xF0, + 0xA5, 0x07, 0x00, 0x00, 0x30, 0x3D, 0x99, 0x3D, 0xF6, 0x50, 0x24, 0xA3, 0x23, 0x9C, 0x0A, 0x8A, + 0x34, 0x8B, 0x45, 0x45, 0xD2, 0x35, 0x88, 0x8F, 0xEA, 0x83, 0xE7, 0xEA, 0xF6, 0x23, 0x1E, 0x1F, + 0x0F, 0xD9, 0xDD, 0x5D, 0xEE, 0xF8, 0x70, 0x73, 0xB7, 0x20, 0x7E, 0x60, 0xD8, 0x9D, 0x7B, 0xD2, + 0x86, 0x87, 0xDD, 0xB9, 0x68, 0x7C, 0xD8, 0xF0, 0x38, 0x6B, 0xC3, 0x83, 0xF8, 0x88, 0x4F, 0x85, + 0x43, 0x1E, 0x8B, 0x45, 0x47, 0x74, 0x2F, 0xAD, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xFA, 0x32, + 0x87, 0xFB, 0x97, 0x98, 0xDD, 0xF3, 0xEC, 0x81, 0x5F, 0x85, 0x87, 0x9B, 0x0A, 0x8A, 0x34, 0x8B, + 0x45, 0x45, 0x9A, 0xD9, 0xE8, 0xA8, 0x0B, 0x90, 0x26, 0xDF, 0x7A, 0x25, 0xDF, 0x7C, 0x75, 0xBF, + 0xBB, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x45, 0xE2, 0x23, + 0x9C, 0xBB, 0x05, 0xF1, 0x43, 0x63, 0xD0, 0xC6, 0x88, 0x0D, 0x90, 0xB3, 0xB1, 0x6F, 0xB9, 0x7A, + 0xF7, 0x31, 0xE2, 0xA3, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x88, 0x8E, 0xE8, 0x5E, 0xBC, 0xD6, 0x06, + 0xC8, 0x1D, 0xEB, 0x82, 0x2F, 0x41, 0x00, 0x00, 0x80, 0xE9, 0xC5, 0x7F, 0x05, 0x6F, 0xC3, 0x37, + 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x15, 0x49, 0xF7, 0x8C, 0x88, 0x8F, 0xE8, 0xED, 0x87, 0x8B, + 0x8F, 0x9A, 0x00, 0x11, 0xDF, 0x7A, 0xE5, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, + 0x26, 0x42, 0x22, 0xCB, 0x44, 0x7C, 0xBC, 0xBD, 0xFE, 0xBD, 0xE6, 0xD4, 0x3D, 0x36, 0x42, 0x5C, + 0x68, 0xB8, 0xE0, 0x70, 0x21, 0x12, 0xFC, 0xE8, 0xFE, 0xB5, 0x09, 0x17, 0x1F, 0x36, 0x3C, 0x4E, + 0x3F, 0x42, 0x7C, 0x54, 0xA6, 0xC2, 0x21, 0x8F, 0x89, 0xE0, 0x88, 0xCF, 0xFD, 0xBE, 0x4E, 0xDC, + 0xB1, 0x3E, 0xF8, 0x12, 0x04, 0x00, 0x00, 0x98, 0x5E, 0xFC, 0x37, 0x60, 0x6D, 0xF9, 0x80, 0x3D, + 0xF4, 0x77, 0x5F, 0x7C, 0x34, 0xBA, 0xFD, 0x50, 0xAF, 0xDD, 0xD5, 0xB7, 0x1F, 0xED, 0x7F, 0xEB, + 0x95, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0x0D, 0xE2, 0x23, 0xDC, 0x99, 0x07, 0x6D, 0x6C, + 0x3C, 0x3E, 0xA3, 0x12, 0x22, 0x41, 0x78, 0x4C, 0x3C, 0x7A, 0x81, 0x7F, 0xEB, 0x41, 0x7C, 0x84, + 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x6C, 0x34, 0x98, 0x77, 0xE2, 0x0E, 0xDE, 0x84, 0x05, 0x00, 0x00, + 0xA6, 0x27, 0xEF, 0xD0, 0xCA, 0xC1, 0xAE, 0x8B, 0x8F, 0x5C, 0x6E, 0x3F, 0x2E, 0x6A, 0xFB, 0xF6, + 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0xD6, 0xD7, 0xEC, 0xBF, 0xF6, + 0x4D, 0x17, 0x1D, 0x33, 0xFC, 0x9D, 0xB1, 0xE1, 0xE1, 0xE6, 0x7F, 0xCB, 0x55, 0x18, 0x1F, 0x4F, + 0x11, 0x1F, 0xC5, 0x4C, 0x87, 0x46, 0xA3, 0x79, 0xC7, 0xBE, 0x70, 0x32, 0xF8, 0x12, 0x04, 0x00, + 0x00, 0x98, 0x5E, 0xBC, 0xBD, 0x57, 0xC4, 0x5E, 0xC1, 0xAB, 0x82, 0x22, 0xCD, 0x44, 0x54, 0x24, + 0x5D, 0x24, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0xA3, 0xFE, 0xD9, 0x0F, 0x75, 0xFB, 0x61, 0xE3, 0xE3, + 0xBE, 0xF6, 0x6E, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x4B, 0x10, 0x1F, 0x6F, 0x7D, + 0xED, 0x02, 0xF3, 0xD6, 0x7F, 0xB9, 0xC0, 0x9C, 0xFA, 0xA1, 0x0D, 0x0D, 0x77, 0xE3, 0xF1, 0x63, + 0x1B, 0x1F, 0x41, 0x78, 0xBC, 0xF3, 0x90, 0xFD, 0x91, 0xF8, 0x28, 0x68, 0x3A, 0x32, 0x9A, 0xEE, + 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x4C, 0x4F, 0x66, 0xAF, 0x3D, 0xF0, 0x75, 0x53, 0x7C, + 0x04, 0x01, 0xD2, 0xEC, 0xF6, 0x23, 0x1E, 0x20, 0x75, 0xF1, 0xF1, 0x60, 0x7B, 0x0F, 0x9E, 0xEB, + 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x96, 0x22, 0x3E, 0xDE, 0xFC, 0xCF, 0xF6, 0xC7, 0xBB, 0x6D, + 0x84, 0x04, 0xD1, 0xE1, 0xEF, 0x41, 0xE2, 0x43, 0x87, 0x43, 0x1E, 0x13, 0x71, 0x91, 0x64, 0x47, + 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xFD, 0x98, 0xD1, 0xFE, 0x59, 0x66, 0x68, 0x81, 0x0D, + 0x80, 0xEE, 0x8A, 0x0F, 0xF7, 0xA3, 0xBA, 0xFD, 0x50, 0xCF, 0x7E, 0xD4, 0x7E, 0xE8, 0xA0, 0x0D, + 0x8F, 0x87, 0xDB, 0xBB, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x2C, 0x65, 0x7C, 0xB8, + 0xFD, 0xE1, 0xFF, 0xB1, 0xFF, 0xFF, 0x77, 0x66, 0x98, 0xB7, 0x1F, 0x98, 0x69, 0x67, 0xE3, 0x63, + 0x23, 0xF1, 0x51, 0xCC, 0x44, 0x58, 0x24, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x2F, 0xAD, 0x0D, 0xBE, + 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0xFF, 0x0D, 0x58, 0x3B, 0x67, 0xDB, 0x08, 0x50, 0x41, 0x91, + 0x66, 0x22, 0x2A, 0x92, 0x2E, 0x1A, 0x1F, 0x41, 0x80, 0x34, 0xBB, 0xFD, 0x70, 0xF1, 0x11, 0x0F, + 0x90, 0x6A, 0x7C, 0xB4, 0x79, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, 0x64, 0x59, 0xC6, 0xF8, + 0x78, 0xE3, 0x2F, 0x67, 0x98, 0xF1, 0xFF, 0x3C, 0xC3, 0xBC, 0xF5, 0x23, 0xFB, 0x7B, 0x7A, 0x92, + 0xF8, 0x28, 0x66, 0x22, 0x2A, 0xD2, 0xEC, 0xF9, 0x2B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x7E, + 0xBC, 0x43, 0xAB, 0xEE, 0x32, 0xDB, 0x3E, 0x6A, 0x43, 0x40, 0x45, 0x45, 0xD2, 0x89, 0xA8, 0x48, + 0x3A, 0x11, 0x1F, 0xEE, 0xC7, 0xD4, 0xB7, 0x1F, 0x61, 0x7C, 0xB8, 0xDB, 0x8F, 0x7B, 0xB3, 0xDD, + 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x4E, 0x7C, 0xFC, 0xA7, 0x19, 0xE6, 0xF7, + 0xFF, 0xF7, 0x0C, 0xF3, 0xE6, 0x03, 0xC4, 0x47, 0x31, 0x13, 0x41, 0x91, 0x61, 0xDE, 0x2F, 0xEE, + 0x18, 0x0A, 0xBE, 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0x33, 0xD2, 0xBF, 0x5E, 0x47, 0x45, 0xD2, + 0x89, 0xA8, 0x48, 0xBA, 0x78, 0x7C, 0xB8, 0x85, 0xE1, 0x11, 0xC6, 0x47, 0xAB, 0xDB, 0x0F, 0xFF, + 0x5B, 0xAF, 0x82, 0xF8, 0x70, 0xFB, 0xA1, 0x9D, 0x88, 0x8B, 0x56, 0xD3, 0x21, 0x91, 0x65, 0x22, + 0x24, 0xB2, 0x2C, 0x87, 0xF8, 0x78, 0xE3, 0xDB, 0x36, 0x3E, 0x5E, 0x22, 0x3E, 0xF2, 0x9F, 0x8E, + 0x89, 0x2C, 0xF3, 0x8E, 0xDE, 0x3C, 0x16, 0x7C, 0x29, 0x02, 0x00, 0x00, 0x4C, 0x0F, 0xDE, 0x81, + 0xAB, 0x46, 0x75, 0x58, 0x24, 0x99, 0x88, 0x8A, 0xA4, 0x6B, 0x10, 0x1F, 0xEE, 0xC7, 0x54, 0xB7, + 0x1F, 0xD1, 0xF8, 0x70, 0xB7, 0x1F, 0xDF, 0x4A, 0x7F, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, + 0x64, 0x19, 0xF1, 0x91, 0xC3, 0x54, 0x38, 0xE4, 0x31, 0x1D, 0x12, 0x99, 0xC7, 0x9B, 0xB0, 0x00, + 0x00, 0xC0, 0x74, 0xE3, 0xED, 0xFF, 0xEC, 0x49, 0x1D, 0x17, 0xAD, 0x26, 0xA2, 0x22, 0xE9, 0xE2, + 0xE1, 0x11, 0x2E, 0x0C, 0x8F, 0x30, 0x3E, 0x9A, 0xDD, 0x7E, 0x3C, 0x76, 0x91, 0x39, 0xFD, 0xA8, + 0x0D, 0x8E, 0x36, 0x6F, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, + 0x0A, 0x87, 0x3C, 0x26, 0x02, 0xA2, 0xDD, 0xB9, 0x37, 0x61, 0x1D, 0xBF, 0x63, 0x49, 0xF0, 0xE5, + 0x08, 0x00, 0x00, 0x50, 0x7E, 0x66, 0x68, 0xBE, 0x8D, 0x02, 0x15, 0x18, 0xCD, 0x26, 0xA2, 0x22, + 0xE9, 0x54, 0x78, 0x44, 0x96, 0xE8, 0xF6, 0x23, 0x88, 0x8F, 0x76, 0x6F, 0x3F, 0x74, 0x48, 0x64, + 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0x26, 0xE2, 0x21, 0x8F, 0xBD, + 0x78, 0x1D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x87, 0xFF, 0x06, 0xAC, 0x5D, 0x9F, 0xB6, 0x61, + 0xA0, 0x22, 0xA3, 0xD1, 0x44, 0x54, 0x24, 0x9D, 0x08, 0x8E, 0xEA, 0x92, 0xDE, 0x7E, 0x3C, 0x6E, + 0x03, 0x24, 0x8C, 0x8F, 0x68, 0x80, 0xFC, 0x80, 0xF8, 0x20, 0x3E, 0x54, 0x38, 0xE4, 0x31, 0x11, + 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x3E, 0xCC, 0xA1, 0xFE, 0xB5, + 0x66, 0xC7, 0xC7, 0x6D, 0x1C, 0xA8, 0xD0, 0x50, 0x13, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0x62, 0x53, + 0xB7, 0x1F, 0xD1, 0x00, 0xF1, 0xE3, 0xA3, 0xD1, 0xED, 0xC7, 0x37, 0x75, 0x68, 0xA8, 0xE9, 0x90, + 0xC8, 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x44, 0x43, 0xCE, + 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xDA, 0xF0, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0x36, 0x10, 0x54, + 0x6C, 0xC4, 0x27, 0xA2, 0x22, 0xE9, 0x44, 0x6C, 0xD4, 0x2C, 0xC1, 0xED, 0x87, 0xFB, 0xD6, 0xAB, + 0x89, 0xC7, 0x2E, 0x9C, 0xBC, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xC9, 0x6F, 0x3F, 0x74, 0x48, + 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0xA6, 0x83, 0x21, 0xEF, + 0x79, 0x47, 0xFF, 0x64, 0x34, 0xF8, 0x92, 0x04, 0x00, 0x00, 0x28, 0x37, 0x6F, 0x78, 0xE9, 0x90, + 0x8E, 0x8D, 0xF8, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8E, 0xF8, 0xE2, 0x01, 0xA2, 0x9E, 0xFD, 0x78, + 0xDC, 0xC6, 0x47, 0x9B, 0xB7, 0x1F, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x11, 0x1F, 0x39, + 0x4C, 0x85, 0x43, 0x1E, 0xD3, 0xB1, 0x50, 0xC8, 0x8E, 0x7D, 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, + 0xE9, 0xC1, 0xDB, 0xBB, 0x24, 0xC1, 0x2B, 0x78, 0x45, 0x54, 0x24, 0x9D, 0x8A, 0x8D, 0xE8, 0x6C, + 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, 0x47, 0xEC, 0x5B, 0xAF, 0x9E, 0xB8, 0x70, 0xF2, + 0xF6, 0xC3, 0x2E, 0xCB, 0xED, 0x87, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, + 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x24, 0x14, 0xB6, 0x45, 0x95, 0x37, 0x61, 0xBD, 0x7C, 0xE7, 0xEC, + 0xE0, 0xCB, 0x12, 0x00, 0x00, 0xA0, 0xBC, 0xCC, 0x1E, 0x7B, 0xF8, 0x91, 0xD1, 0x11, 0x4E, 0x44, + 0x45, 0xD2, 0xA9, 0xE0, 0x88, 0x2F, 0x1A, 0x20, 0x76, 0xD5, 0x6F, 0xBD, 0x8A, 0x06, 0x88, 0x8B, + 0x0F, 0xFF, 0xF6, 0xE3, 0xC2, 0xFA, 0xDB, 0x8F, 0x87, 0xEC, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, + 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xB3, + 0x5F, 0x7F, 0x6E, 0x2F, 0x7E, 0xCE, 0x05, 0xC8, 0x40, 0xF0, 0x65, 0x09, 0x00, 0x00, 0x50, 0x4E, + 0x66, 0xA4, 0x7F, 0x76, 0xF3, 0x57, 0xF0, 0x8A, 0xA8, 0x48, 0x3A, 0x15, 0x1B, 0xF1, 0xC5, 0xE2, + 0x23, 0xBC, 0xFD, 0xA8, 0x7D, 0xF0, 0xDC, 0xC6, 0x47, 0xF4, 0xF6, 0x23, 0xFE, 0xAD, 0x57, 0xF7, + 0xB7, 0xBE, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, + 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x16, 0xC4, 0x87, 0x1F, 0x20, 0xD7, 0xF0, 0x26, 0x2C, 0x00, 0x00, + 0x50, 0x7E, 0xFE, 0x2B, 0x78, 0x1B, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, 0xA9, 0xD8, 0x88, 0xAF, + 0x41, 0x7C, 0x54, 0x1F, 0x3C, 0x77, 0xB3, 0xF1, 0x51, 0x73, 0xFB, 0x11, 0x7F, 0xF0, 0xDC, 0xDD, + 0x7E, 0xDC, 0xAD, 0xA3, 0x23, 0x9C, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, + 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0xB5, 0x48, 0x7C, 0x04, 0xF3, 0x4E, 0x7C, 0x69, 0x30, + 0xF8, 0xD2, 0x04, 0x00, 0x00, 0x28, 0x27, 0xFF, 0x0D, 0x58, 0x5B, 0x3F, 0x64, 0xA3, 0x61, 0x8A, + 0xE3, 0xC3, 0x4D, 0x05, 0x48, 0xCD, 0xB7, 0x5E, 0xD9, 0xF8, 0x70, 0xB7, 0x1F, 0x41, 0x7C, 0x64, + 0xB9, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x56, 0x1F, 0x1F, 0x6E, 0xDE, 0xF1, 0x3F, 0xE5, 0x4D, 0x58, 0x00, 0x00, + 0xA0, 0xDC, 0xBC, 0x91, 0x81, 0x0D, 0x1D, 0x89, 0x0F, 0xB7, 0x78, 0x7C, 0x54, 0x6F, 0x3F, 0x2E, + 0xAC, 0xC6, 0xC7, 0xE4, 0xED, 0x47, 0x2C, 0x3E, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, + 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xF1, 0xE1, + 0xEF, 0xD8, 0x2D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x94, 0x9B, 0x77, 0xE0, 0xAA, 0xD8, 0x1B, 0xB0, + 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x8C, 0x46, 0xB3, 0xD1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0x44, 0x02, + 0x24, 0x8C, 0x0F, 0xF9, 0xB9, 0x1F, 0xDF, 0x69, 0x7C, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, + 0x64, 0x59, 0x34, 0x3A, 0x88, 0x8F, 0x8C, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x11, + 0x1D, 0xD1, 0xB9, 0x37, 0x61, 0x8D, 0x7D, 0x71, 0x56, 0xF0, 0xE5, 0x09, 0x00, 0x00, 0x50, 0x3E, + 0xDE, 0xBE, 0x25, 0xE3, 0x53, 0x1E, 0x1F, 0x6E, 0xF1, 0xF8, 0x48, 0x7B, 0xFB, 0xF1, 0xA0, 0x9D, + 0x08, 0x0F, 0x37, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x52, 0xC4, 0x47, 0x18, 0x20, 0x2E, + 0x3E, 0xFE, 0x40, 0x7C, 0x44, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x38, 0xE2, + 0x1B, 0x5B, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB9, 0x4D, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, + 0xA9, 0xC0, 0x68, 0x36, 0x1B, 0x1D, 0xEE, 0x47, 0x75, 0xFB, 0x11, 0x0D, 0x90, 0xA6, 0xB7, 0x1F, + 0xF7, 0xE9, 0xDB, 0x0F, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x22, 0xF1, 0x11, 0xAE, 0x3E, + 0x3E, 0xEC, 0x5C, 0x78, 0x84, 0xB7, 0x1F, 0xC4, 0x47, 0x6C, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, + 0xA2, 0x26, 0x62, 0x43, 0xED, 0xC5, 0x6B, 0x8C, 0xF7, 0x8B, 0x2F, 0xDD, 0x15, 0x7C, 0x79, 0x02, + 0x00, 0x00, 0x94, 0x8B, 0xFF, 0x06, 0xAC, 0x9D, 0x9F, 0xD2, 0x51, 0x91, 0x74, 0xF1, 0xB8, 0x48, + 0xB2, 0x30, 0x3C, 0xC2, 0xF8, 0xF0, 0x03, 0x64, 0x66, 0x35, 0x3E, 0x6A, 0xDF, 0x7C, 0x95, 0xFC, + 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0x76, 0x24, 0x3E, 0xE2, + 0x37, 0x1F, 0x6F, 0x04, 0xF1, 0xF1, 0x07, 0xE2, 0xA3, 0xA0, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x34, + 0x9A, 0xCC, 0x3B, 0x71, 0xC7, 0x86, 0xE0, 0x4B, 0x14, 0x00, 0x00, 0xA0, 0x5C, 0x6C, 0x80, 0xAC, + 0x33, 0xDB, 0x2F, 0xD6, 0x61, 0x91, 0x64, 0x2A, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0xF6, + 0xF6, 0xC3, 0xC6, 0x47, 0x83, 0x67, 0x3F, 0xEA, 0x3E, 0x74, 0xD0, 0xBD, 0xF9, 0x4A, 0xDC, 0x7E, + 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x22, 0x3E, 0xA2, 0x37, 0x1F, 0x61, 0x7C, 0x84, + 0x37, 0x1F, 0xC4, 0x47, 0x38, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x91, 0xD1, 0x6C, + 0xDE, 0x89, 0x3F, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x9C, 0xFC, 0x57, 0xF0, 0xAA, 0xB0, 0x48, + 0xB2, 0x78, 0x58, 0x24, 0x5D, 0x18, 0x1E, 0x61, 0x7C, 0x3C, 0x3D, 0xB3, 0xE6, 0xF6, 0xA3, 0xEE, + 0xD9, 0x0F, 0x1B, 0x20, 0xA7, 0xA2, 0x01, 0xF2, 0x23, 0xBB, 0x1E, 0x8C, 0x0F, 0xB7, 0xBA, 0x00, + 0x69, 0x10, 0x1F, 0xE3, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0xC0, + 0x68, 0x35, 0xEF, 0xD8, 0x17, 0xC6, 0x83, 0x2F, 0x51, 0x00, 0x00, 0x80, 0x72, 0xF1, 0x0E, 0x5C, + 0x33, 0x2A, 0xE3, 0xA2, 0xD5, 0x54, 0x58, 0x24, 0x99, 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, + 0xF1, 0x11, 0xBD, 0xFD, 0x88, 0xC5, 0x47, 0xDD, 0xED, 0xC7, 0xB7, 0x6A, 0x6F, 0x3F, 0x74, 0x48, + 0x64, 0x99, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x56, 0x17, 0x1F, 0xEA, 0x8D, 0x57, 0xC4, 0x47, + 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x71, 0x91, 0x68, 0x47, 0x56, 0xF3, 0x26, + 0x2C, 0x00, 0x00, 0x50, 0x4E, 0xDE, 0xDE, 0x25, 0x63, 0x32, 0x30, 0x9A, 0x2D, 0x1E, 0x15, 0x69, + 0x16, 0x86, 0x47, 0x18, 0x1F, 0x69, 0x6F, 0x3F, 0x7E, 0x68, 0x57, 0xB6, 0xF8, 0x70, 0x37, 0x1F, + 0x2E, 0x3E, 0xDC, 0x43, 0xE7, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, + 0xA8, 0x48, 0xB3, 0x97, 0x56, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x4E, 0x66, 0xCF, 0x42, 0x1D, + 0x19, 0x8D, 0xA6, 0xA2, 0x22, 0xE5, 0x2A, 0x01, 0x32, 0xB3, 0xED, 0xDB, 0x0F, 0x1D, 0x12, 0x59, + 0x26, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0xB5, 0x8C, 0x8F, 0xBF, 0x9C, 0xFC, 0xAC, 0x8F, 0x3F, + 0xDC, 0x4B, 0x7C, 0x14, 0x33, 0x15, 0x09, 0x45, 0x4D, 0x04, 0x45, 0xDA, 0xBD, 0x78, 0x8D, 0x0D, + 0x90, 0x3B, 0xD6, 0x05, 0x5F, 0xA6, 0x00, 0x00, 0x00, 0xE5, 0x60, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, + 0xE6, 0xE8, 0xD0, 0x50, 0x13, 0x31, 0x91, 0x6A, 0xD5, 0xDB, 0x8F, 0x20, 0x3E, 0x9A, 0xDD, 0x7E, + 0x84, 0xF1, 0xD1, 0xE0, 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, + 0x0D, 0xE3, 0x23, 0x08, 0x90, 0xE8, 0x07, 0x0D, 0x12, 0x1F, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, + 0xA2, 0x26, 0x62, 0x22, 0xCB, 0x9E, 0xB7, 0x7F, 0x3F, 0x4E, 0xDC, 0xB1, 0x3E, 0xF8, 0x52, 0x05, + 0x00, 0x00, 0x28, 0x07, 0xFF, 0x15, 0xBC, 0x49, 0xDF, 0x80, 0xA5, 0x82, 0x22, 0xC3, 0xFC, 0xF8, + 0x88, 0xDD, 0x7E, 0x54, 0x03, 0xA4, 0xD5, 0xED, 0xC7, 0x3D, 0xBD, 0x1B, 0x1F, 0x95, 0xD7, 0xED, + 0x12, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x24, 0xDA, 0x18, 0x6F, + 0xC2, 0x02, 0x00, 0x00, 0xA5, 0xE3, 0xBF, 0x01, 0x6B, 0xEB, 0x07, 0x75, 0x70, 0x44, 0x27, 0x42, + 0x22, 0xF5, 0xC2, 0x9B, 0x8F, 0x26, 0xB7, 0x1F, 0x13, 0x2E, 0x40, 0x1E, 0x8B, 0xDC, 0x7E, 0x84, + 0xF1, 0xE1, 0xF6, 0xBD, 0xCA, 0xB7, 0x5E, 0xE9, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x26, 0xC2, + 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x11, 0xD1, 0xCE, + 0xBC, 0x63, 0x5F, 0x38, 0x19, 0x7C, 0xA9, 0x02, 0x00, 0x00, 0x94, 0x83, 0x37, 0xBC, 0x62, 0x50, + 0x06, 0x47, 0x74, 0x2A, 0x26, 0xB2, 0x2C, 0x8C, 0x8F, 0xD8, 0xED, 0x47, 0xE2, 0x67, 0x3F, 0xBE, + 0xC9, 0xB7, 0x5D, 0x25, 0x9B, 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, + 0x2A, 0x12, 0x8A, 0x9A, 0x0E, 0x88, 0xB6, 0x77, 0x64, 0xB5, 0x09, 0xBE, 0x54, 0x01, 0x00, 0x00, + 0xCA, 0xC1, 0xDB, 0x7B, 0x79, 0xF3, 0x57, 0xF0, 0xAA, 0x90, 0x48, 0xBB, 0x4D, 0x6E, 0x93, 0xE1, + 0x31, 0x79, 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xFC, 0xF6, 0x43, 0x87, 0x44, + 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0x0D, 0xE3, 0xC3, 0x3D, 0x70, 0x1E, 0x8B, 0x8F, + 0xF1, 0xFF, 0x32, 0xCB, 0x9C, 0xFF, 0xD7, 0x5B, 0x83, 0xF8, 0x58, 0x65, 0x0F, 0xFA, 0x2A, 0x28, + 0xD2, 0x4C, 0x84, 0x43, 0x1E, 0x93, 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, + 0x4D, 0x84, 0x43, 0x5E, 0x3B, 0xB2, 0x92, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF1, 0xF6, 0x2C, + 0x1A, 0x97, 0xE1, 0xE1, 0xA6, 0x62, 0x22, 0xCB, 0x6C, 0x78, 0x44, 0x6F, 0x3F, 0xAA, 0xDF, 0x7A, + 0x15, 0x06, 0x48, 0xCD, 0x6B, 0x77, 0x2F, 0x94, 0xB7, 0x1F, 0xEF, 0x7C, 0x23, 0xAF, 0xDB, 0x0F, + 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x2D, 0x6D, 0x7C, 0x9C, 0xFB, 0xE9, 0x17, 0x2A, 0xF1, 0x71, + 0xD4, 0xFE, 0x28, 0x83, 0x22, 0xCD, 0x44, 0x38, 0xE4, 0x31, 0x19, 0x0E, 0x79, 0x4C, 0x85, 0x43, + 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x44, 0x34, 0xE4, 0x39, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xCA, 0xC4, + 0x0C, 0xF5, 0xCF, 0x32, 0x43, 0x7D, 0x53, 0x1A, 0x1F, 0xE1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xCD, + 0x9E, 0xFD, 0x70, 0xF1, 0x71, 0x7F, 0x5E, 0xB7, 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, + 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x82, 0x21, 0xEF, 0xB9, 0xFF, + 0x6D, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0x0B, 0xFF, 0x0D, 0x58, 0x3B, 0x3E, 0x39, 0xE5, 0xF1, + 0x51, 0x7D, 0xF0, 0x5C, 0xDD, 0x7E, 0xC4, 0x1E, 0x3C, 0x7F, 0xE7, 0x41, 0x1B, 0x1F, 0x5F, 0x57, + 0x31, 0x91, 0x76, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x62, 0xA1, 0xA0, 0x79, 0x27, 0xEE, 0xE0, 0x4D, 0x58, 0x00, 0x00, + 0xA0, 0x1C, 0xBC, 0xE1, 0xFE, 0xBB, 0xCC, 0xB6, 0x8F, 0x14, 0x13, 0x1F, 0xCF, 0x54, 0xE2, 0xA3, + 0x2E, 0x40, 0xE2, 0xAF, 0xDD, 0x75, 0xB7, 0x1F, 0x41, 0x7C, 0xC4, 0x6F, 0x3F, 0xDE, 0x79, 0xD8, + 0xC6, 0xC7, 0x77, 0xF3, 0xF8, 0xD6, 0x2B, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, + 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xA1, 0x50, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, + 0x82, 0x2F, 0x59, 0x00, 0x00, 0x80, 0xDE, 0xE6, 0xBF, 0x82, 0xB7, 0xA8, 0xF8, 0x08, 0x02, 0xA4, + 0xE1, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0x8A, 0xC7, 0x47, 0x2E, 0xB7, 0x1F, 0x22, 0x24, + 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0xA6, + 0x23, 0xA1, 0xD0, 0x1D, 0xB9, 0x91, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF0, 0x0E, 0x5C, 0x33, + 0xF9, 0x06, 0x2C, 0x19, 0x12, 0x59, 0x36, 0x19, 0x1F, 0x8D, 0x6E, 0x3F, 0xAA, 0xAF, 0xDD, 0xAD, + 0xDE, 0x7E, 0x5C, 0x14, 0xBB, 0xFD, 0xB0, 0xE1, 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, + 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x38, 0x98, + 0x8A, 0xBD, 0x34, 0x60, 0xCC, 0xF1, 0x3B, 0x96, 0x04, 0x5F, 0xB6, 0x00, 0x00, 0x00, 0xBD, 0xCB, + 0xDB, 0x77, 0xC5, 0xC9, 0x42, 0xE2, 0xA3, 0xAD, 0xDB, 0x8F, 0x20, 0x3E, 0x1E, 0x68, 0xF7, 0xF6, + 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, + 0x50, 0xD4, 0x44, 0x18, 0x4C, 0xD5, 0xDC, 0x9B, 0xB0, 0x4E, 0x7C, 0x69, 0x6D, 0xF0, 0x65, 0x0B, + 0x00, 0x00, 0xD0, 0xBB, 0xCC, 0xEE, 0xBE, 0x48, 0x3C, 0xB4, 0xBB, 0xDA, 0xF8, 0x70, 0x3F, 0xAA, + 0xDB, 0x8F, 0xFA, 0x67, 0x3F, 0xA2, 0xB7, 0x1F, 0x41, 0x7C, 0xB8, 0xDD, 0xDB, 0xCE, 0xED, 0x87, + 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, + 0xA8, 0x89, 0x28, 0x98, 0xCA, 0xBD, 0x70, 0x25, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xCF, 0x1C, + 0xE8, 0x5F, 0x62, 0x76, 0xCE, 0x0E, 0xE2, 0xA1, 0xDD, 0x45, 0xE2, 0x23, 0x08, 0x90, 0x66, 0xB7, + 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xE1, 0x6E, 0x3F, 0x64, 0x58, 0x24, 0x99, 0x08, 0x89, 0x2C, + 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x20, + 0xE8, 0xC0, 0xBC, 0xE3, 0xB7, 0x0F, 0x05, 0x5F, 0xBA, 0x00, 0x00, 0x00, 0xBD, 0xC9, 0x1C, 0x5C, + 0xB6, 0xD6, 0x6C, 0xFF, 0x58, 0x10, 0x10, 0xED, 0xAC, 0x3E, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0x43, + 0x3D, 0xFB, 0x51, 0xF9, 0xD0, 0xC1, 0x0B, 0x27, 0x03, 0xE4, 0x21, 0xBB, 0xCC, 0xB7, 0x1F, 0x22, + 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, + 0xA6, 0x63, 0xA0, 0x13, 0xF3, 0x8E, 0xDE, 0xC2, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x33, 0x23, + 0xCB, 0xD7, 0x9B, 0xCD, 0xEF, 0xB3, 0xB1, 0xA0, 0xA2, 0x22, 0xE9, 0x62, 0xF1, 0xE1, 0x16, 0x86, + 0x47, 0x18, 0x1F, 0xB1, 0xDB, 0x8F, 0xBA, 0x67, 0x3F, 0x1E, 0xB5, 0xF1, 0xE1, 0x02, 0xA4, 0xED, + 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, + 0x45, 0x42, 0x51, 0xD3, 0x21, 0xD0, 0xB1, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, + 0xE6, 0x1D, 0xB8, 0x7E, 0xA8, 0x36, 0x26, 0xD2, 0x4E, 0xC7, 0x87, 0xFB, 0xB1, 0xE9, 0xED, 0x47, + 0x2C, 0x3E, 0xEA, 0x6E, 0x3F, 0xEE, 0xC9, 0x72, 0xFB, 0x21, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, + 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x00, 0x3A, 0x3D, 0xF7, + 0x26, 0xAC, 0x97, 0xEF, 0x9C, 0x1D, 0x7C, 0xF9, 0x02, 0x00, 0x00, 0xF4, 0x1E, 0x6F, 0xEF, 0x65, + 0xA3, 0xF5, 0x51, 0x91, 0x74, 0xB1, 0xF0, 0x08, 0x17, 0x86, 0x47, 0x18, 0x1F, 0x4D, 0x6F, 0x3F, + 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x4E, 0x06, 0x46, 0xB3, 0x89, 0x90, 0xC8, + 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, + 0xFC, 0x77, 0xC3, 0x5E, 0xFC, 0x9C, 0x31, 0xC7, 0x6E, 0x1B, 0x08, 0xBE, 0x7C, 0x01, 0x00, 0x00, + 0x7A, 0x8F, 0xD9, 0x63, 0x0F, 0x5B, 0x32, 0x2E, 0x5A, 0x4D, 0x84, 0x47, 0x64, 0xC9, 0x6E, 0x3F, + 0x2A, 0xF1, 0xD1, 0xFE, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, + 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xFE, 0xDD, 0x32, 0xDE, 0x84, 0x05, 0x00, + 0x00, 0x7A, 0x99, 0x19, 0xE9, 0x9F, 0x6D, 0x76, 0xCF, 0xB3, 0xC1, 0xA0, 0x02, 0xA3, 0xD9, 0x74, + 0x74, 0xF8, 0x4B, 0x7C, 0xFB, 0x31, 0xD3, 0x9C, 0x09, 0xE3, 0xA3, 0xAD, 0xDB, 0x0F, 0x11, 0x12, + 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xFE, 0x2E, 0x9B, 0x77, 0xE2, 0xF6, 0xC1, 0xE0, 0x4B, 0x18, 0x00, 0x00, 0xA0, 0xB7, 0xD8, + 0x00, 0x19, 0x48, 0xFF, 0x06, 0x2C, 0x11, 0x1D, 0xB1, 0xA9, 0xDB, 0x8F, 0x6A, 0x80, 0x84, 0xF1, + 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, + 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7F, 0xB7, 0xCD, 0x3B, 0xFA, 0x85, 0xD1, 0xE0, 0x4B, + 0x18, 0x00, 0x00, 0xA0, 0xB7, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0x3E, 0x60, 0xA3, 0x41, 0x85, + 0x86, 0x9A, 0x0E, 0x8E, 0xEA, 0x12, 0xDC, 0x7E, 0x4C, 0x3C, 0x31, 0xD3, 0x4C, 0x3C, 0x16, 0xB9, + 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0xFB, 0xC4, 0x47, 0x65, 0x22, 0x1C, 0xF2, 0x98, 0x0C, 0x87, 0x3C, + 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0xB0, 0xDF, 0x95, 0x3B, 0x76, 0x0B, 0x6F, + 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xC9, 0x1B, 0x59, 0xB1, 0xA1, 0x3E, 0x32, 0x1A, 0x4D, 0x04, 0x47, + 0x7C, 0xF1, 0x00, 0xA9, 0x7B, 0xF6, 0xC3, 0xC6, 0x47, 0xB3, 0xDB, 0x8F, 0x6F, 0xA8, 0xD0, 0x50, + 0x13, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, + 0x14, 0x35, 0x71, 0xC8, 0xEF, 0xE6, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xAB, 0xBC, 0x7D, 0x57, + 0x24, 0x7C, 0x03, 0x96, 0x88, 0x8D, 0xE8, 0x6C, 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, + 0x47, 0xE4, 0x5B, 0xAF, 0x06, 0x6D, 0x7C, 0x44, 0x6F, 0x3F, 0xEC, 0x6A, 0x6E, 0x3F, 0x36, 0x24, + 0xBD, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, + 0x54, 0x24, 0x14, 0x35, 0x71, 0xC0, 0xEF, 0xF6, 0x8D, 0x2D, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0xA0, + 0x37, 0x79, 0x7B, 0x2F, 0x1B, 0xAF, 0x8F, 0x8D, 0xF8, 0x62, 0xB1, 0xA1, 0x16, 0x0D, 0x10, 0xBB, + 0xEA, 0xB7, 0x5E, 0x85, 0x01, 0x62, 0xE3, 0x63, 0xF2, 0xF6, 0x63, 0x66, 0x1B, 0xB7, 0x1F, 0x22, + 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, + 0x26, 0x0E, 0xF7, 0xBD, 0xB0, 0x17, 0xAF, 0x31, 0xDE, 0x2F, 0x6E, 0xBF, 0x2B, 0xF8, 0x32, 0x06, + 0x00, 0x00, 0xE8, 0x1D, 0xAD, 0xDF, 0x80, 0x15, 0x0B, 0x0D, 0xB5, 0x58, 0x7C, 0x84, 0xB7, 0x1F, + 0x93, 0x0F, 0x9E, 0xDB, 0xF8, 0x88, 0xDF, 0x7E, 0x84, 0xF1, 0x11, 0x06, 0x48, 0xA2, 0xDB, 0x0F, + 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, + 0x51, 0x13, 0x07, 0xFB, 0x1E, 0x9A, 0x77, 0xFC, 0x8E, 0x0D, 0xC1, 0x97, 0x31, 0x00, 0x00, 0x40, + 0x6F, 0xF0, 0xDF, 0x80, 0xB5, 0x73, 0xB6, 0x8D, 0x08, 0x15, 0x1E, 0x6E, 0xB1, 0xD0, 0x50, 0x6B, + 0x10, 0x1F, 0xD5, 0x07, 0xCF, 0x37, 0xCE, 0xAC, 0xBF, 0xFD, 0x08, 0xE2, 0xA3, 0x7A, 0xFB, 0xF1, + 0xA0, 0xDD, 0xD7, 0x55, 0x70, 0x44, 0x27, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, + 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0x50, 0xDF, 0x4B, 0xF3, 0x8E, 0xDE, 0xCA, + 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x31, 0x23, 0xCB, 0xD7, 0x35, 0x7E, 0x05, 0x6F, 0x2C, 0x34, + 0x1A, 0x4D, 0x05, 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x41, 0x7C, 0xC8, 0x37, + 0x5F, 0x7D, 0xB7, 0xD5, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, + 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7D, 0xAF, 0xCD, 0x3B, 0xFA, 0xF9, 0xF1, + 0xE0, 0x4B, 0x19, 0x00, 0x00, 0xA0, 0x37, 0xD8, 0x00, 0x59, 0x5F, 0x1F, 0x1E, 0x29, 0xE2, 0xC3, + 0x2D, 0x1E, 0x1F, 0xD5, 0xDB, 0x8F, 0xC9, 0xF8, 0xA8, 0x79, 0xF3, 0x55, 0xEA, 0xDB, 0x0F, 0x11, + 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, + 0xD3, 0x87, 0xF9, 0x9E, 0x9C, 0x7B, 0x13, 0xD6, 0xD8, 0x17, 0x67, 0x05, 0x5F, 0xCE, 0x00, 0x00, + 0x00, 0xDD, 0xCF, 0x3B, 0x70, 0xD5, 0x50, 0xBB, 0xF1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0xD4, 0xDD, + 0x7E, 0x5C, 0x98, 0xE1, 0xF6, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, + 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBE, 0x97, 0x37, 0xB6, 0x9C, 0x37, 0x61, + 0x01, 0x00, 0x80, 0xDE, 0xE2, 0xED, 0xBD, 0x7C, 0x2C, 0x73, 0x7C, 0xB8, 0xC5, 0xE3, 0xC3, 0x0F, + 0x90, 0x19, 0x39, 0xDD, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, + 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xC0, 0xF7, 0xFA, 0x78, 0x13, 0x16, 0x00, 0x00, + 0xE8, 0x35, 0x66, 0x68, 0x81, 0x0D, 0x89, 0xEC, 0xF1, 0xE1, 0x7E, 0xAC, 0xBD, 0xFD, 0xB0, 0xF1, + 0x11, 0xFB, 0xF6, 0xAB, 0xA6, 0xB7, 0x1F, 0xF7, 0x35, 0xBA, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, + 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x78, 0x2F, + 0xC3, 0x9E, 0xBF, 0x9C, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, 0x61, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, + 0x2E, 0xB5, 0x11, 0x91, 0x21, 0x3E, 0xDC, 0xC2, 0xF0, 0x08, 0xE3, 0xE3, 0xE9, 0x19, 0x35, 0xB7, + 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xF1, 0x80, 0x1D, 0xF1, 0x91, 0xCF, 0x64, 0x38, 0xE4, 0x31, + 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x07, 0xF7, 0x12, 0xCD, 0x3B, 0xFE, 0x67, 0xBC, + 0x09, 0x0B, 0x00, 0x00, 0xF4, 0x06, 0xFF, 0x15, 0xBC, 0xFE, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, + 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, 0xF1, 0xD1, 0xE0, 0xD9, 0x0F, 0xF9, 0xA1, 0x83, 0xF7, + 0xAA, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, + 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x87, 0xF6, 0x32, 0xCD, 0x3B, 0xFA, 0xF9, 0x93, 0xC1, 0x97, 0x34, + 0x00, 0x00, 0x40, 0x77, 0xF3, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0xF5, 0x71, 0x91, 0x64, 0x61, 0x78, + 0x84, 0xF1, 0x11, 0xBB, 0xFD, 0xA8, 0x7B, 0xF6, 0xC3, 0x06, 0xC8, 0x29, 0x17, 0x20, 0x4D, 0x6F, + 0x3F, 0x44, 0x48, 0x64, 0x99, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, + 0x09, 0x45, 0x4D, 0x1F, 0xD8, 0x4B, 0xB7, 0x23, 0xAB, 0x4C, 0xF0, 0x25, 0x0D, 0x00, 0x00, 0xD0, + 0xDD, 0xBC, 0xE1, 0x65, 0x83, 0x32, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0x12, 0x20, 0x33, + 0xF4, 0xED, 0x47, 0x2C, 0x3E, 0x5A, 0xDF, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, + 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA8, 0x97, 0x75, 0x63, 0xCB, + 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0D, 0xDE, 0xDE, 0xCB, 0x46, 0xEB, 0xE2, 0x22, 0xC9, 0xAA, + 0xB7, 0x1F, 0x41, 0x7C, 0x24, 0xBD, 0xFD, 0x08, 0x03, 0xE4, 0x07, 0x76, 0xC4, 0x47, 0x7B, 0x93, + 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0xBA, 0x7F, + 0x5D, 0x68, 0xCC, 0x0B, 0x57, 0x1B, 0x73, 0xFC, 0x8E, 0x75, 0xC1, 0x97, 0x35, 0x00, 0x00, 0x40, + 0xF7, 0xF2, 0xF6, 0x2C, 0x18, 0x97, 0x81, 0xD1, 0x6C, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0x59, 0x6F, + 0x3F, 0xEE, 0x89, 0xDE, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, + 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2E, 0x3E, 0xDC, 0x7E, 0x6E, + 0xFF, 0x99, 0x38, 0x71, 0xDB, 0xFA, 0xE0, 0xCB, 0x1A, 0x00, 0x00, 0xA0, 0x3B, 0x99, 0xA1, 0xFE, + 0x59, 0x66, 0xF7, 0xDC, 0xFA, 0xC0, 0x68, 0xB5, 0xF0, 0xE6, 0x23, 0x97, 0xDB, 0x0F, 0x11, 0x12, + 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xF4, 0xB2, 0x2E, 0x8C, 0x8F, 0x60, 0xDE, 0x89, 0xDB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, + 0x6E, 0x66, 0x64, 0xE9, 0x80, 0xD9, 0xF1, 0x71, 0x1D, 0x19, 0xCD, 0x16, 0xC6, 0x47, 0xDB, 0xB7, + 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, + 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x5D, 0x2C, 0x3E, 0xFC, 0x00, 0x39, 0x7A, 0x33, 0x6F, 0xC2, + 0x02, 0x00, 0x00, 0xDD, 0xCD, 0x1B, 0x5E, 0x7E, 0x97, 0xD9, 0xFA, 0x21, 0x1D, 0x19, 0x8D, 0x16, + 0x8F, 0x8F, 0x66, 0xB7, 0x1F, 0x61, 0x7C, 0xC8, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, + 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, + 0xC4, 0x87, 0xBF, 0x23, 0x37, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xDD, 0xFC, 0x57, 0xF0, 0xAA, + 0xC8, 0x68, 0x34, 0x1B, 0x1D, 0x8D, 0x6E, 0x3F, 0xAA, 0x01, 0xD2, 0xEA, 0xF6, 0xE3, 0x1B, 0xC4, + 0x47, 0xA6, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, + 0x65, 0x9D, 0x0A, 0x8F, 0x70, 0x2F, 0xF5, 0xBB, 0x07, 0xD1, 0x97, 0x04, 0x5F, 0xDE, 0x00, 0x00, + 0x00, 0xDD, 0xC7, 0x3B, 0x70, 0x75, 0xF2, 0x37, 0x60, 0x45, 0xE3, 0xC3, 0x86, 0x47, 0xA3, 0xDB, + 0x8F, 0x09, 0x17, 0x20, 0x8F, 0x45, 0x6E, 0x3F, 0xC2, 0xF8, 0x70, 0xDB, 0xE0, 0xBE, 0xF5, 0x4A, + 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, + 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xD1, 0x11, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x3F, 0x5F, 0x1B, + 0x7C, 0x79, 0x03, 0x00, 0x00, 0x74, 0x1F, 0x6F, 0xDF, 0xE5, 0x27, 0x65, 0x6C, 0xC4, 0x17, 0xC4, + 0x47, 0xA3, 0xDB, 0x8F, 0xC4, 0xCF, 0x7E, 0x7C, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, + 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xC1, + 0x11, 0x1F, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xDD, 0x2E, 0xD1, 0x1B, 0xB0, 0xE2, 0xF1, 0x51, 0x73, + 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xED, 0xED, 0x47, 0x4E, 0xDF, 0x7A, 0x25, + 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, + 0xB2, 0x4E, 0xC5, 0x46, 0x83, 0x79, 0xC7, 0x6F, 0x1F, 0x0A, 0xBE, 0xBC, 0x01, 0x00, 0x00, 0xBA, + 0x8B, 0x39, 0x70, 0xFD, 0x12, 0xB3, 0xF3, 0x53, 0x3A, 0x3A, 0xC2, 0x45, 0xE2, 0xA3, 0x1A, 0x20, + 0x76, 0xD5, 0x6F, 0xBD, 0x0A, 0x03, 0xA4, 0xE6, 0xB5, 0xBB, 0x33, 0xC5, 0xED, 0xC7, 0xCC, 0x7C, + 0x6E, 0x3F, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, + 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0xC8, 0x68, 0x36, 0xEF, 0xC8, 0x9A, 0xB1, 0xE0, 0x4B, 0x1C, 0x00, + 0x00, 0xA0, 0xBB, 0x98, 0x83, 0xCB, 0xD6, 0x9A, 0xED, 0x1F, 0xD5, 0xE1, 0xE1, 0x16, 0x09, 0x8F, + 0x68, 0x7C, 0x84, 0xB7, 0x1F, 0x35, 0x0F, 0x9E, 0x37, 0x7A, 0xF6, 0xC3, 0x0F, 0x10, 0x1B, 0x1F, + 0xDF, 0xCD, 0xE1, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, + 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x08, 0x8C, 0x96, 0x3B, 0xBA, 0x86, 0x37, 0x61, 0x01, + 0x00, 0x80, 0xEE, 0xE4, 0xBF, 0x01, 0x6B, 0xF3, 0xAC, 0x4C, 0xF1, 0x51, 0x7D, 0xF0, 0x5C, 0xDD, + 0x7E, 0x04, 0xF1, 0x51, 0xB9, 0xFD, 0xB0, 0xF1, 0xF1, 0xA0, 0xDD, 0xD7, 0x45, 0x50, 0xA4, 0x99, + 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, + 0xCB, 0x3A, 0x15, 0x17, 0x49, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB7, 0xF2, 0x0E, 0x7C, 0x6E, + 0x28, 0x49, 0x7C, 0xD4, 0x05, 0x48, 0xFC, 0xB5, 0xBB, 0xEE, 0xF6, 0x23, 0x88, 0x8F, 0xDA, 0x37, + 0x5F, 0xD9, 0xF0, 0xC8, 0xE3, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x0A, 0x8B, 0xA4, 0x7B, 0xE1, 0x5A, 0x63, + 0x8E, 0xDD, 0x36, 0x10, 0x7C, 0x99, 0x03, 0x00, 0x00, 0x74, 0x0F, 0x6F, 0xEF, 0x65, 0xF5, 0xAF, + 0xE0, 0x8D, 0x44, 0x87, 0x8C, 0x8F, 0xE8, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0xAA, 0xDE, + 0x7E, 0x04, 0xF1, 0xD1, 0xEE, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, + 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x15, 0x69, 0xF6, 0xFC, 0x67, 0x79, + 0x13, 0x16, 0x00, 0x00, 0xE8, 0x4E, 0x66, 0x8F, 0x3D, 0xEC, 0xB4, 0x88, 0x0F, 0x37, 0x75, 0xFB, + 0x51, 0x7D, 0xED, 0x6E, 0xF5, 0xF6, 0xE3, 0xC2, 0xC8, 0xED, 0x47, 0x10, 0x1F, 0xED, 0xDE, 0x7E, + 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x62, 0x07, + 0xF4, 0x32, 0x4F, 0x05, 0x45, 0x86, 0x79, 0x27, 0x6E, 0x1B, 0x0C, 0xBE, 0xCC, 0x01, 0x00, 0x00, + 0xBA, 0x83, 0x19, 0xE9, 0x9F, 0x5D, 0xF3, 0x0A, 0xDE, 0x48, 0x70, 0x44, 0x97, 0xFE, 0xF6, 0x63, + 0xE6, 0x64, 0x80, 0x3C, 0x60, 0xA7, 0xC2, 0x22, 0xC9, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, + 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0x90, 0xC8, 0x3A, 0xEF, + 0xC8, 0xE7, 0x47, 0x83, 0x2F, 0x75, 0x00, 0x00, 0x80, 0xEE, 0x60, 0x46, 0x96, 0x0E, 0x54, 0xDF, + 0x80, 0x15, 0x09, 0x8E, 0xF8, 0xD4, 0xED, 0x47, 0xFD, 0xB3, 0x1F, 0xE1, 0xED, 0x47, 0x24, 0x3E, + 0xDC, 0xEE, 0xCD, 0x78, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, + 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x44, 0x44, 0x5B, 0xE3, 0x4D, 0x58, 0x00, 0x00, + 0xA0, 0xDB, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0xDE, 0x2F, 0xA3, 0x23, 0x5C, 0xB3, 0xDB, 0x8F, + 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0xC8, 0x7A, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, + 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x05, 0x44, 0xBB, 0x73, 0x6F, + 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x3B, 0x00, 0x00, 0x40, 0xE7, 0x79, 0x23, 0xCB, 0x36, + 0xA8, 0xE8, 0x88, 0x4E, 0xDD, 0x7E, 0xD4, 0x3F, 0xFB, 0xE1, 0x3E, 0x74, 0xD0, 0xBD, 0x7A, 0x37, + 0x12, 0x20, 0xEE, 0x43, 0x07, 0xB3, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, + 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xF1, 0x90, 0xC7, 0x5E, 0xBC, + 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, 0xEE, 0xE2, 0xED, 0xBD, 0x62, 0x54, 0x45, 0x47, 0xB8, 0x66, + 0xB7, 0x1F, 0xD5, 0x67, 0x3F, 0xFC, 0xD7, 0xEE, 0x06, 0xF1, 0xE1, 0xD6, 0xCE, 0xED, 0x87, 0x08, + 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, + 0x3A, 0x15, 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x2E, 0xDE, 0xDE, + 0xC5, 0xE3, 0x2A, 0x3C, 0xC2, 0x35, 0xBD, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC5, 0x87, 0xBA, 0xFD, + 0xB8, 0x27, 0xE5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, + 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x0D, 0x39, 0xCF, 0x3B, 0xB6, 0x96, 0x37, 0x61, + 0x01, 0x00, 0x80, 0xEE, 0xE1, 0xBF, 0x01, 0x2B, 0x12, 0x1C, 0xD1, 0xB5, 0xBC, 0xFD, 0xB0, 0xF1, + 0x31, 0xF1, 0xD8, 0x8C, 0xDA, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x60, 0xA7, 0x22, 0xA3, 0xD1, 0x44, + 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, + 0xD6, 0x89, 0x58, 0x28, 0x62, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0E, 0xFE, + 0x1B, 0xB0, 0x76, 0x7C, 0x52, 0xC6, 0x87, 0x5B, 0xCB, 0xDB, 0x8F, 0x30, 0x3E, 0xDA, 0xBD, 0xFD, + 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, + 0x7A, 0x59, 0x27, 0x42, 0xA1, 0xA8, 0x79, 0x47, 0x6F, 0x1E, 0x0F, 0xBE, 0xE4, 0x01, 0x00, 0x00, + 0x3A, 0xCB, 0x8C, 0x2C, 0x5F, 0x67, 0xB6, 0x7D, 0xA4, 0x75, 0x7C, 0xC8, 0xDB, 0x8F, 0x19, 0xF9, + 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, + 0xC4, 0x21, 0xBD, 0xAC, 0x13, 0x91, 0x50, 0xE8, 0xDC, 0x9B, 0xB0, 0xC6, 0xBE, 0x38, 0x2B, 0xF8, + 0xB2, 0x07, 0x00, 0x00, 0xE8, 0x1C, 0x1B, 0x20, 0xEB, 0x55, 0x7C, 0xB8, 0xA9, 0xDB, 0x0F, 0x3F, + 0x40, 0x44, 0x7C, 0x64, 0xBE, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, + 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA1, 0xE8, 0xF1, 0x26, 0x2C, 0x00, + 0x00, 0xD0, 0x2D, 0xBC, 0x03, 0x57, 0x0D, 0x35, 0x8C, 0x0F, 0x1B, 0x1E, 0xF2, 0xF6, 0xE3, 0x09, + 0x1B, 0x1F, 0x2E, 0x40, 0x1E, 0x8D, 0xDC, 0x7E, 0x84, 0xF1, 0xE1, 0xB6, 0x81, 0xF8, 0xA8, 0x9B, + 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xA9, + 0x38, 0x98, 0x8A, 0xBD, 0x70, 0xB5, 0xF1, 0x7E, 0x71, 0xFB, 0x5D, 0xC1, 0x97, 0x3D, 0x00, 0x00, + 0x40, 0xE7, 0x78, 0x7B, 0x2F, 0x1B, 0x6B, 0x18, 0x20, 0x6E, 0x91, 0xDB, 0x0F, 0x17, 0x1F, 0x67, + 0x07, 0x67, 0xD4, 0xDE, 0x7E, 0xA8, 0x67, 0x3F, 0xBE, 0x21, 0x62, 0x23, 0x3E, 0x11, 0x1E, 0x6E, + 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2A, + 0x0C, 0xA6, 0x70, 0xDE, 0xF1, 0xDB, 0x36, 0x04, 0x5F, 0xF6, 0x00, 0x00, 0x00, 0x9D, 0x63, 0x86, + 0xE6, 0xEB, 0xF8, 0xA8, 0xB9, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC6, 0x47, 0x1E, 0xB7, 0x1F, 0x22, + 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, + 0xEB, 0x44, 0x10, 0x4C, 0xF5, 0xBC, 0xE3, 0x7F, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x67, 0x99, + 0x91, 0xFE, 0xD9, 0x66, 0xE7, 0x25, 0x3A, 0x40, 0xEC, 0xA2, 0xDF, 0x7A, 0x75, 0xEE, 0xC9, 0x19, + 0xE6, 0xAC, 0x8D, 0x8F, 0xC9, 0xDB, 0x8F, 0x19, 0xFA, 0xD9, 0x8F, 0x56, 0xB7, 0x1F, 0x22, 0x3C, + 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, + 0x44, 0x0C, 0x74, 0x62, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x74, 0x9C, 0xFF, 0x0A, 0xDE, 0xD8, 0x1B, + 0xB0, 0x6A, 0xBE, 0xF5, 0xCA, 0xEE, 0x9C, 0x0B, 0x10, 0x17, 0x1F, 0xF1, 0xDB, 0x8F, 0x68, 0x7C, + 0x84, 0x01, 0x72, 0x7F, 0x8B, 0xDB, 0x0F, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, + 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x22, 0x04, 0x3A, 0xB6, 0x97, 0x56, 0x99, + 0xE0, 0x4B, 0x1F, 0x00, 0x00, 0xA0, 0x33, 0xFC, 0x37, 0x60, 0x6D, 0xFE, 0xE3, 0x86, 0xF1, 0x51, + 0xB9, 0xFD, 0xB0, 0xF1, 0xD1, 0xE0, 0xF6, 0xC3, 0xC5, 0x47, 0xF5, 0xF6, 0xE3, 0x41, 0xBB, 0xAF, + 0x8B, 0xE8, 0x08, 0x27, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, + 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x45, 0x40, 0x27, 0x37, 0xB6, 0x8C, 0x37, 0x61, 0x01, 0x00, + 0x80, 0xCE, 0xF2, 0x86, 0x97, 0x0D, 0x36, 0xBC, 0xFD, 0x08, 0xE2, 0xA3, 0xE6, 0xF6, 0x23, 0x88, + 0x8F, 0x9A, 0xDB, 0x8F, 0xF0, 0xD9, 0x8F, 0xEF, 0x36, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, + 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA0, + 0xD3, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0xF2, 0x07, 0x00, 0x00, 0x98, 0x7A, + 0xDE, 0xDE, 0xCB, 0x46, 0x1B, 0xDE, 0x7E, 0x6C, 0xBC, 0xA0, 0x26, 0x3E, 0xEA, 0x3E, 0x74, 0x30, + 0xE9, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, + 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x75, 0xF8, 0xEF, 0xF8, 0x16, 0xD8, 0x5F, 0x9B, 0xFD, 0xDF, 0xE1, + 0xC4, 0x6D, 0xEB, 0x83, 0x2F, 0x7F, 0x00, 0x00, 0x80, 0xA9, 0xE7, 0xED, 0x9E, 0x3F, 0xAE, 0x6F, + 0x3F, 0x6C, 0x7C, 0x84, 0xDF, 0x7A, 0x55, 0x73, 0xFB, 0x31, 0x33, 0xDD, 0xED, 0x87, 0x08, 0x0F, + 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0xB1, 0x78, 0x20, 0x14, 0x39, 0x71, 0x48, 0x2F, 0xEB, + 0xE4, 0xE1, 0xBF, 0xD3, 0xB3, 0xF1, 0x11, 0xCC, 0x3B, 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x80, + 0xCE, 0x30, 0x43, 0xFD, 0xB3, 0xCC, 0xEE, 0xB9, 0x32, 0x3E, 0x72, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, + 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, + 0x0F, 0xFF, 0x9D, 0xDE, 0x64, 0x7C, 0xF8, 0x01, 0x72, 0xF4, 0xE6, 0x93, 0xC1, 0x1F, 0x01, 0x00, + 0x00, 0x00, 0x53, 0xCB, 0x7F, 0x03, 0xD6, 0xF6, 0x8B, 0x6B, 0x03, 0x24, 0x8C, 0x0F, 0xF9, 0xEC, + 0x47, 0x83, 0xDB, 0x8F, 0x7B, 0xC5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, + 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x6A, 0xE3, + 0xC3, 0xDF, 0x91, 0x1B, 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0C, 0x33, 0xB2, 0x7C, 0x9D, 0xD9, + 0xFA, 0xC1, 0xC8, 0xED, 0x87, 0x8D, 0x8F, 0xD8, 0xED, 0x47, 0xED, 0x9B, 0xAF, 0x44, 0x7C, 0x3C, + 0x60, 0x47, 0x7C, 0x14, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, + 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x11, 0x1F, 0x6E, 0x2F, 0xF5, 0xF3, 0x26, 0x2C, 0x00, 0x00, 0xD0, + 0x19, 0xE6, 0xE0, 0xF2, 0xF5, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xEC, 0xC7, + 0xE9, 0x78, 0x80, 0xB8, 0x0F, 0x1D, 0x8C, 0xDF, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, + 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, + 0x84, 0x47, 0x38, 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x00, 0x00, 0x00, 0x60, + 0xEA, 0x78, 0xFB, 0xAE, 0x1E, 0xAD, 0x89, 0x8F, 0x24, 0xCF, 0x7E, 0xB8, 0x35, 0xBA, 0xFD, 0x10, + 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, + 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x88, 0x8E, 0xE8, 0xDC, 0x3F, 0x67, 0xBC, 0x09, 0x0B, 0x00, + 0x00, 0x74, 0x82, 0xB7, 0xF7, 0xF2, 0x93, 0x7E, 0x7C, 0x34, 0xBA, 0xFD, 0x88, 0xC6, 0x87, 0xBA, + 0xFD, 0xF8, 0x76, 0xE4, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, + 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x38, 0xC4, 0xBC, + 0xE3, 0xB7, 0x0F, 0x05, 0x7F, 0x0C, 0x00, 0x00, 0x00, 0x4C, 0x1D, 0x6F, 0xE7, 0x9C, 0xF4, 0xB7, + 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x8E, 0xF8, 0xC8, 0x71, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, + 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x36, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, + 0x82, 0x3F, 0x06, 0x00, 0x00, 0x00, 0xA6, 0x86, 0x39, 0x70, 0xFD, 0x12, 0x6F, 0xFB, 0x27, 0xB2, + 0xDF, 0x7E, 0xDC, 0x13, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, + 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x87, 0x46, 0xC3, + 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xD5, 0xCC, 0xC1, 0x65, 0x6B, 0xBD, 0xAD, 0x1F, 0x6E, 0xEF, + 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, + 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x30, 0x5A, 0xCD, 0xBD, 0x09, 0xEB, 0xF8, + 0x1D, 0x4B, 0x82, 0x3F, 0x0E, 0x00, 0x00, 0x00, 0x8A, 0x77, 0xFE, 0xE0, 0xD2, 0xF5, 0xDE, 0xA6, + 0x0B, 0x33, 0xDE, 0x7E, 0x10, 0x1F, 0xF9, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, + 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC4, 0x45, 0x92, 0xBD, 0x70, 0x0D, 0x6F, 0xC2, + 0x02, 0x00, 0x00, 0x53, 0xEB, 0xFC, 0xFE, 0x6B, 0x06, 0xB3, 0xDD, 0x7E, 0xCC, 0x90, 0xE1, 0xE1, + 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, + 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x8B, 0xA4, 0x7B, 0xFE, 0x0A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xA6, + 0xD6, 0xF9, 0xDD, 0x8B, 0x47, 0xA3, 0xB7, 0x1F, 0xD5, 0x00, 0x89, 0xC5, 0x47, 0xDD, 0xED, 0xC7, + 0xDD, 0xC4, 0x47, 0xFB, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, + 0xE4, 0xE1, 0xBF, 0xD3, 0x13, 0x51, 0x91, 0x72, 0xDE, 0xB1, 0xB5, 0xBC, 0x09, 0x0B, 0x00, 0x00, + 0x4C, 0x1D, 0x6F, 0xF7, 0x42, 0x79, 0xFB, 0x31, 0xE1, 0x02, 0xE4, 0xD1, 0xC8, 0xED, 0x47, 0x18, + 0x1F, 0x6E, 0xF7, 0xEB, 0x6F, 0xBD, 0x22, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, + 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x07, 0x45, 0xDA, 0x79, 0x47, 0x3E, + 0x3F, 0x1A, 0xFC, 0x71, 0x00, 0x00, 0x00, 0x50, 0x2C, 0x33, 0xD2, 0x3F, 0xDB, 0xDB, 0x31, 0x27, + 0xDD, 0xB3, 0x1F, 0x0F, 0xCE, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, + 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x98, 0xC8, 0xB4, 0xA3, + 0x6B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x1A, 0x66, 0xFF, 0xD2, 0x81, 0xF3, 0x5B, 0x3E, 0x6C, + 0x03, 0x24, 0xF2, 0xAD, 0x57, 0xCD, 0x6E, 0x3F, 0x1E, 0xB2, 0xF1, 0x21, 0x6E, 0x3F, 0x88, 0x8F, + 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, + 0xD3, 0x13, 0x11, 0xD1, 0xCE, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0x73, 0x76, 0xF0, 0xC7, 0x02, 0x00, + 0x00, 0x40, 0x71, 0xCE, 0xED, 0x5F, 0x7A, 0xD7, 0xF9, 0x4D, 0xEF, 0x9B, 0x7C, 0xF6, 0xA3, 0xE6, + 0xC1, 0xF3, 0x19, 0xB5, 0xCF, 0x7E, 0xB8, 0xF8, 0x78, 0xA0, 0xFE, 0xF6, 0x83, 0xF8, 0x48, 0x33, + 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, + 0x11, 0x10, 0xED, 0xCE, 0xBD, 0x09, 0xEB, 0xD8, 0x6D, 0x03, 0xC1, 0x1F, 0x0B, 0x00, 0x00, 0x00, + 0xC5, 0x39, 0x7F, 0x60, 0xD9, 0x86, 0x9A, 0x07, 0xCF, 0xA3, 0xB7, 0x1F, 0xD1, 0xF8, 0x78, 0xD8, + 0x86, 0x87, 0x0B, 0x90, 0xEF, 0xD4, 0xDE, 0x7E, 0x10, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x21, 0x8F, 0xF1, + 0x26, 0x2C, 0x00, 0x00, 0x30, 0x55, 0xCE, 0xEF, 0x5E, 0x32, 0xEA, 0xC7, 0x47, 0x83, 0xDB, 0x0F, + 0x17, 0x1F, 0xA7, 0xC2, 0xF8, 0x70, 0xB7, 0x1F, 0x7F, 0x4D, 0x7C, 0x64, 0x9B, 0x0A, 0x87, 0x3C, + 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x87, 0x1C, + 0xE7, 0x9D, 0xB8, 0x6D, 0x30, 0xF8, 0x63, 0x01, 0x00, 0x00, 0xA0, 0x38, 0xE7, 0x76, 0x2E, 0x3A, + 0x59, 0x73, 0xFB, 0x11, 0xC4, 0x47, 0xF5, 0xD9, 0x8F, 0x30, 0x3E, 0x62, 0xB7, 0x1F, 0xC4, 0x47, + 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, + 0xE9, 0xE9, 0x68, 0xC8, 0x73, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0xDE, 0xF9, + 0xED, 0x73, 0xAA, 0xF1, 0x51, 0xF7, 0xA1, 0x83, 0x8F, 0xCC, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, + 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, + 0xE9, 0x60, 0xC8, 0x7D, 0x47, 0x3F, 0xCF, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB1, 0xCE, 0xEE, 0x5F, + 0x3A, 0x70, 0x6E, 0xCB, 0x27, 0x63, 0xB7, 0x1F, 0x33, 0x2B, 0xCF, 0x7E, 0x44, 0xE3, 0xC3, 0xED, + 0xDE, 0xCA, 0xED, 0x07, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, + 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x14, 0x8A, 0x9A, 0x7B, 0x13, 0xD6, 0xD8, 0x17, + 0x67, 0x05, 0x7F, 0x3C, 0x00, 0x00, 0x00, 0xE4, 0xEF, 0xDC, 0xDE, 0xE5, 0xEB, 0xCE, 0x6D, 0xFA, + 0x48, 0xEC, 0xF6, 0x63, 0x46, 0x35, 0x3E, 0xAA, 0x01, 0xF2, 0x23, 0x3B, 0xE2, 0x23, 0xE5, 0x54, + 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x44, + 0x24, 0x14, 0xB9, 0x17, 0xAF, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x58, 0xE7, 0xF7, 0x2E, 0x5F, + 0x5F, 0xF7, 0xEC, 0xC7, 0x8F, 0x27, 0x03, 0xA4, 0x7A, 0xFB, 0xF1, 0xED, 0x0B, 0x88, 0x8F, 0x54, + 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, + 0x13, 0x81, 0x50, 0xF4, 0x5E, 0xB8, 0xCA, 0x78, 0xBF, 0xB8, 0xFD, 0xAE, 0xE0, 0x8F, 0x07, 0x00, + 0x00, 0x80, 0xFC, 0x9D, 0xDB, 0x7D, 0xD5, 0x50, 0xCD, 0x9B, 0xAF, 0xC2, 0xF8, 0x88, 0x06, 0xC8, + 0x8F, 0x66, 0x10, 0x1F, 0xA9, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, + 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x60, 0x8A, 0xE6, 0x1D, 0xBF, 0x6D, 0x43, 0xF0, 0xC7, + 0x03, 0x00, 0x00, 0x40, 0xFE, 0xCE, 0xED, 0xB8, 0x6C, 0x6C, 0xF2, 0xF6, 0xE3, 0x02, 0x79, 0xFB, + 0xF1, 0x76, 0xE4, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x06, 0x53, 0x35, 0xDE, 0x84, 0x05, 0x00, + 0x00, 0x0A, 0x75, 0x76, 0xDB, 0xFC, 0xE0, 0xF6, 0xC3, 0xC6, 0x87, 0x78, 0xF6, 0xE3, 0xED, 0x1F, + 0x4C, 0xDE, 0x7E, 0x10, 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, + 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0xA3, 0x60, 0x2A, 0xE7, 0x1D, 0xBD, 0x79, 0x3C, 0xF8, + 0xE3, 0x01, 0x00, 0x00, 0x20, 0x5F, 0x66, 0xA8, 0x7F, 0xF6, 0xD9, 0xCD, 0x97, 0x04, 0xF1, 0x51, + 0x7B, 0xFB, 0x71, 0x2A, 0xBC, 0xFD, 0xF8, 0x66, 0xE5, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, + 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x04, + 0x53, 0xBE, 0x97, 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x8C, 0xB3, 0x43, 0x4B, 0x07, 0xDE, + 0xDD, 0xF8, 0xE1, 0x6A, 0x80, 0x9C, 0xB6, 0x01, 0x52, 0xF3, 0xEC, 0xC7, 0xF7, 0x2B, 0xB7, 0x1F, + 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, + 0xF0, 0xDF, 0xE9, 0x89, 0x10, 0xE8, 0xD4, 0xC6, 0x96, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x0C, + 0x1B, 0x20, 0xEB, 0x27, 0x06, 0xDF, 0x57, 0x73, 0xFB, 0x11, 0x7D, 0xFE, 0xC3, 0xDD, 0x7E, 0x10, + 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, + 0x7F, 0xA7, 0x27, 0x22, 0xA0, 0x93, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0x63, + 0x02, 0x00, 0x00, 0x20, 0x3F, 0xEF, 0xEE, 0x59, 0x3A, 0xE8, 0xDF, 0x7E, 0x88, 0xF8, 0x70, 0xB7, + 0x1F, 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, + 0xF2, 0xF0, 0xDF, 0xE9, 0x89, 0x00, 0xE8, 0xF4, 0xDC, 0x3F, 0x17, 0x27, 0x6E, 0x5B, 0x1F, 0xFC, + 0x31, 0x01, 0x00, 0x00, 0x90, 0x9F, 0x89, 0x6D, 0x8B, 0x47, 0xEB, 0xDE, 0x7C, 0x15, 0xDE, 0x7E, + 0xDC, 0x4D, 0x7C, 0x34, 0x9F, 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xE9, 0x65, + 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xE2, 0xF0, 0xDF, 0x25, 0xF3, 0x8E, 0xAF, 0xE5, 0x4D, 0x58, 0x00, + 0x00, 0x20, 0x7F, 0x13, 0x5B, 0xFA, 0xC6, 0xE5, 0xC3, 0xE7, 0xF7, 0xBB, 0x6F, 0xBD, 0x22, 0x3E, + 0x1A, 0x4F, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, + 0x4E, 0x4F, 0x1F, 0xFC, 0xBB, 0x65, 0xDE, 0xD1, 0x9B, 0x4F, 0x06, 0x7F, 0x4C, 0x00, 0x00, 0x00, + 0xE4, 0xC3, 0x0C, 0xF5, 0xCF, 0x7A, 0xF7, 0x99, 0x39, 0x95, 0xF8, 0xB0, 0x8B, 0x3E, 0x7C, 0xFE, + 0xD6, 0x5F, 0x11, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, + 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFD, 0x5D, 0xB5, 0x97, 0x56, 0x9A, 0xE0, 0x8F, 0x0A, + 0x00, 0x00, 0x80, 0x7C, 0xB8, 0x37, 0x60, 0x4D, 0x6C, 0xFC, 0x98, 0x0D, 0x90, 0x0B, 0xCC, 0xE9, + 0x47, 0xEC, 0xDC, 0xED, 0x87, 0x0B, 0x90, 0xFB, 0x6D, 0x80, 0x10, 0x1F, 0x0D, 0xA6, 0xC2, 0x21, + 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xFB, + 0xDD, 0x38, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x7C, 0xDD, 0xC4, 0x13, 0x1F, + 0x30, 0xA7, 0xFD, 0x00, 0x09, 0xBE, 0xFD, 0xEA, 0xE1, 0x99, 0xFE, 0xED, 0x07, 0xF1, 0xA1, 0xA6, + 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, + 0x0E, 0xFA, 0xDD, 0x3A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x74, 0x7D, 0x78, + 0xFB, 0x71, 0xCA, 0xCD, 0xDD, 0x7E, 0x7C, 0x67, 0x06, 0xF1, 0x21, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF9, 0xDD, 0x3C, + 0xF7, 0xCF, 0x3D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x79, 0x9A, 0xD8, 0x79, 0xD5, 0x68, 0xF5, 0xDB, + 0xAF, 0xDC, 0x0D, 0x88, 0x7B, 0xF6, 0xE3, 0x6B, 0xC4, 0x47, 0xFD, 0x54, 0x38, 0xE4, 0x31, 0x15, + 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, 0x01, 0xBF, 0x07, 0xC6, + 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xAE, 0x26, 0xB6, 0x5D, 0x76, 0xB2, 0x7A, 0x03, 0xF2, 0xF0, 0x0C, + 0xF3, 0xF6, 0x7D, 0xC1, 0xED, 0x87, 0x8D, 0x8F, 0x3F, 0x10, 0x1F, 0xC1, 0x54, 0x38, 0xE4, 0x31, + 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0xE1, 0xBE, 0x17, + 0xE6, 0x1D, 0x59, 0x33, 0x16, 0xFC, 0x71, 0x01, 0x00, 0x00, 0xD0, 0xBE, 0x09, 0xFF, 0x0D, 0x58, + 0x93, 0xB7, 0x1F, 0x6F, 0x7E, 0x6D, 0xF2, 0xE6, 0xE3, 0x0D, 0xE2, 0xC3, 0x4E, 0x85, 0x43, 0x1E, + 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xEC, 0x7B, + 0x66, 0x47, 0x6E, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x20, 0x1F, 0x13, 0x43, 0xD7, 0x2F, 0x99, 0x78, + 0xFA, 0x13, 0xE6, 0xCC, 0xA3, 0x95, 0xCF, 0xFF, 0x70, 0xB7, 0x1F, 0x95, 0xF8, 0xB8, 0xC0, 0xBF, + 0xF9, 0x78, 0x83, 0xF8, 0x28, 0x68, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, + 0xDF, 0xE9, 0x89, 0x03, 0x7D, 0xAF, 0xED, 0xA5, 0x7E, 0xF7, 0x20, 0xFA, 0x92, 0xE0, 0x8F, 0x0D, + 0x00, 0x00, 0x80, 0xEC, 0xCE, 0x0C, 0x2D, 0x5B, 0x3B, 0xF1, 0xE4, 0x87, 0x2B, 0x9F, 0x01, 0xF2, + 0x60, 0xE5, 0xB5, 0xBB, 0xD5, 0xDB, 0x8F, 0xAF, 0xD9, 0xF8, 0xF8, 0x47, 0xE2, 0x23, 0xFF, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF3, 0xBD, 0x38, + 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x03, 0x00, 0x00, 0x20, 0x3B, 0xF7, 0x06, + 0xAC, 0x89, 0xC7, 0x2F, 0xF2, 0x03, 0xE4, 0xED, 0x6F, 0x55, 0x9E, 0xFB, 0x20, 0x3E, 0xDC, 0x54, + 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, + 0x41, 0xBE, 0x57, 0xE7, 0xBE, 0x26, 0x78, 0x13, 0x16, 0x00, 0x00, 0xC8, 0xC3, 0xD9, 0x5D, 0xD7, + 0x0C, 0x4E, 0x3C, 0x36, 0xC3, 0x9C, 0x71, 0xCF, 0x7E, 0x04, 0x6F, 0xBD, 0xFA, 0xC3, 0x7A, 0xE2, + 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, + 0xF1, 0x3D, 0xBB, 0xF9, 0xFE, 0xBC, 0xE3, 0xB7, 0x0D, 0x05, 0x7F, 0x6C, 0x00, 0x00, 0x00, 0x64, + 0xF7, 0xEE, 0xB6, 0xC5, 0xA3, 0x13, 0x8F, 0xCF, 0x30, 0xEF, 0x7C, 0xBB, 0x72, 0xFB, 0xF1, 0xE6, + 0x5F, 0x5D, 0x44, 0x7C, 0x14, 0x32, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, + 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x57, 0x89, 0x0F, 0x3F, 0x40, 0x8E, 0xDC, 0xCC, 0x9B, 0xB0, + 0x00, 0x00, 0x40, 0xFB, 0xCE, 0x6D, 0x5F, 0x60, 0x26, 0x1E, 0xB9, 0xC0, 0xBC, 0xE5, 0x5E, 0xBB, + 0xFB, 0xD7, 0xC4, 0x47, 0x31, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, + 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0xE1, 0xEF, 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, + 0x00, 0xB4, 0xC7, 0x0C, 0x5D, 0x3B, 0xFB, 0xDC, 0xB6, 0x4B, 0xCD, 0x3B, 0xDF, 0xB4, 0x01, 0xF2, + 0x75, 0xE2, 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, + 0xA7, 0x0E, 0xF1, 0xBD, 0xBA, 0x58, 0x7C, 0xB8, 0xBD, 0xB4, 0xC2, 0x98, 0x97, 0xBF, 0x38, 0x3B, + 0xF8, 0xE3, 0x03, 0x00, 0x00, 0x20, 0xBD, 0xB3, 0xFB, 0x97, 0x0E, 0xBC, 0xFB, 0xD8, 0x87, 0xCC, + 0xDB, 0x77, 0x5F, 0x64, 0xCE, 0x13, 0x1F, 0x05, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, + 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x89, 0xF8, 0x70, 0x7B, 0xE1, 0x6A, 0x63, + 0x8E, 0xDD, 0x36, 0x10, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDE, 0x99, 0x5D, 0x9F, 0xBB, 0xEB, + 0xD4, 0x86, 0x0F, 0x98, 0xF3, 0xFF, 0x44, 0x7C, 0xE4, 0x3F, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, + 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x27, 0xC2, 0x23, 0x98, 0xF7, 0xAF, + 0x4B, 0xCC, 0xE9, 0x9F, 0xDD, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x76, 0xAF, 0x3D, 0x70, 0xED, + 0x86, 0xF1, 0xDD, 0xAB, 0xCD, 0xD9, 0x17, 0xBF, 0x44, 0x7C, 0xE4, 0x3A, 0x15, 0x09, 0x45, 0x4D, + 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0xA7, 0xC3, 0xC3, 0xED, + 0xD4, 0xB3, 0xF3, 0xCC, 0xEF, 0x77, 0xCC, 0x31, 0xBF, 0xDB, 0x77, 0xD3, 0x60, 0xF0, 0xC7, 0x07, + 0x00, 0x00, 0x40, 0x7A, 0xAF, 0xEF, 0xB9, 0x75, 0xF8, 0xF7, 0x07, 0x6F, 0x35, 0xBF, 0xDF, 0xB7, + 0xD2, 0xBC, 0x79, 0xE0, 0x32, 0x73, 0xFE, 0x9F, 0x55, 0x54, 0x24, 0x9D, 0x08, 0x87, 0x3C, 0x26, + 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, + 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0x4E, 0x87, 0xC7, 0x99, 0xBF, 0xEB, 0x33, 0xE3, 0xBB, + 0xE6, 0x9A, 0xDF, 0x6D, 0xB3, 0xF1, 0xE1, 0xB6, 0x67, 0x39, 0xAF, 0xE2, 0x05, 0x00, 0x00, 0xD9, + 0xFD, 0xF3, 0xFF, 0xFE, 0x17, 0x17, 0xFE, 0x76, 0xFB, 0xEA, 0xFB, 0x7E, 0xB7, 0x6D, 0xF1, 0x5B, + 0xBF, 0xDF, 0xB9, 0xD8, 0xB8, 0xBD, 0x7D, 0xE8, 0x72, 0xFF, 0x5B, 0x2D, 0x74, 0x64, 0x34, 0x9A, + 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, + 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0xAE, 0x3E, 0x3C, 0xCE, 0xFE, + 0x43, 0x9F, 0x79, 0x73, 0xEF, 0x64, 0x78, 0xBC, 0xBE, 0x75, 0xCE, 0xF8, 0xEF, 0xB6, 0x5D, 0xBA, + 0x7E, 0xB4, 0xFF, 0x3D, 0x7F, 0x14, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDD, 0x7F, 0xBF, 0xFB, + 0x33, 0x17, 0xBF, 0xB6, 0x79, 0xF1, 0x96, 0x30, 0x42, 0xC6, 0x77, 0x2F, 0x36, 0xA7, 0xFF, 0xC6, + 0x1E, 0xD4, 0x65, 0x6C, 0xC4, 0x27, 0xC2, 0x21, 0x8F, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, 0xDF, + 0xAB, 0xAB, 0x0D, 0x8F, 0xF3, 0xFF, 0x34, 0xDF, 0xBC, 0xB5, 0x3F, 0x72, 0xE3, 0x61, 0xF7, 0xEA, + 0x33, 0x73, 0x7E, 0x34, 0x3E, 0xF4, 0xA9, 0x59, 0xC1, 0x1F, 0x17, 0x00, 0x00, 0x00, 0xF9, 0xF9, + 0xEF, 0xDF, 0x5D, 0xF2, 0x99, 0xD7, 0xB6, 0x2C, 0xFA, 0x59, 0x18, 0x22, 0x6F, 0xEC, 0xB9, 0xCC, + 0x4C, 0xFC, 0xBD, 0x0B, 0x02, 0x15, 0x1E, 0x6E, 0xB1, 0x68, 0xC8, 0x6B, 0x32, 0x1C, 0xF2, 0x98, + 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, + 0x3A, 0xC4, 0xF7, 0xEA, 0x26, 0xC3, 0xC3, 0xFB, 0xE7, 0xF9, 0xE6, 0x9D, 0x91, 0x79, 0x35, 0xE1, + 0xF1, 0xDA, 0xE6, 0x4B, 0xF7, 0x8F, 0x6F, 0xE9, 0xE3, 0xB5, 0xBB, 0x00, 0x00, 0xA0, 0x78, 0xFF, + 0xEB, 0xA1, 0xCB, 0xBE, 0xF8, 0xBB, 0x6D, 0x8B, 0x7E, 0x19, 0x86, 0x88, 0x7B, 0x3E, 0xE4, 0xEC, + 0x4F, 0x5D, 0x1C, 0x10, 0x1F, 0xF5, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, + 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0x51, 0x7D, 0xC0, 0x3C, 0x08, 0x8F, 0xD7, + 0xB7, 0x5E, 0x3A, 0xF6, 0xDA, 0x96, 0x4B, 0x79, 0xDD, 0x2E, 0x00, 0x00, 0x98, 0x5A, 0xA3, 0xFD, + 0xFD, 0x7F, 0xF4, 0xAB, 0x27, 0x2E, 0xFB, 0x3F, 0xA2, 0xCF, 0x87, 0xBC, 0x35, 0xEC, 0x1E, 0x54, + 0x17, 0xD1, 0x90, 0xD7, 0x64, 0x38, 0xE4, 0x31, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x55, 0xC2, 0x23, 0xFE, + 0x80, 0xB9, 0x8D, 0x8E, 0x5F, 0xBE, 0xBE, 0x7D, 0xEE, 0xBA, 0xE0, 0x8F, 0x00, 0x00, 0x00, 0x80, + 0xCE, 0xF8, 0xD5, 0x23, 0x57, 0x7E, 0xE0, 0x37, 0x4F, 0x2E, 0xDE, 0x30, 0x19, 0x22, 0x8B, 0xCC, + 0xE9, 0xBF, 0xB9, 0xCC, 0x78, 0xFF, 0x2A, 0x02, 0xA2, 0x9D, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, + 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, + 0xDF, 0xAB, 0x6B, 0xFC, 0x80, 0x39, 0xCF, 0x79, 0x00, 0x00, 0x80, 0xAE, 0x72, 0xF2, 0x91, 0xC5, + 0xF3, 0x5F, 0x7D, 0x66, 0xF1, 0x0E, 0x17, 0x20, 0x6E, 0xE3, 0xBB, 0x17, 0x99, 0x33, 0x7F, 0x67, + 0x0F, 0xE2, 0x2A, 0x26, 0xD2, 0x4E, 0x86, 0x43, 0x1E, 0x8B, 0x47, 0x43, 0x5E, 0x53, 0x91, 0x50, + 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x73, 0xEA, 0x01, + 0xF3, 0xDF, 0x6D, 0xBD, 0x74, 0xF0, 0xBF, 0x7D, 0x67, 0xDE, 0x07, 0x82, 0x2F, 0x73, 0x00, 0x00, + 0x80, 0xEE, 0xF3, 0xAB, 0x8D, 0x8B, 0xD6, 0xBC, 0xFA, 0xCC, 0xC2, 0x9F, 0x87, 0x21, 0xF2, 0xC6, + 0x9E, 0xC5, 0xE6, 0xDD, 0x7F, 0xB0, 0x87, 0x7D, 0x15, 0x16, 0x49, 0x26, 0xC3, 0x21, 0x8F, 0xA9, + 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, + 0x83, 0x7C, 0xAF, 0xCD, 0xFB, 0xE7, 0x05, 0x75, 0x0F, 0x98, 0xDB, 0x8D, 0xFE, 0x7F, 0x8F, 0x5E, + 0x3A, 0x27, 0xF8, 0xB2, 0x06, 0x00, 0x00, 0xE8, 0x6E, 0xFE, 0xF3, 0x21, 0x83, 0x8B, 0xFF, 0xE2, + 0x77, 0xDB, 0x16, 0xFE, 0x32, 0x0C, 0x91, 0x37, 0x0F, 0x2C, 0x36, 0x67, 0x7F, 0x6A, 0x0F, 0xFE, + 0x2A, 0x32, 0x1A, 0x4D, 0x86, 0x43, 0x1E, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, + 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x87, 0xF9, 0x5E, 0xDB, 0xE9, 0xBF, 0xE9, 0xAB, + 0x79, 0xC0, 0xFC, 0xB5, 0x67, 0xE6, 0x1C, 0xE3, 0x01, 0x73, 0x00, 0x00, 0xD0, 0xB3, 0x6C, 0x88, + 0xFC, 0xBB, 0x57, 0x37, 0x2F, 0xBA, 0xE7, 0x77, 0xDB, 0x16, 0xBD, 0x15, 0x86, 0xC8, 0xDB, 0x87, + 0x12, 0x3E, 0xA8, 0x2E, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, + 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xC3, 0x7C, 0x2F, 0x6D, 0xE2, 0xEF, 0xE7, 0xF3, + 0x80, 0x39, 0x00, 0x00, 0x28, 0xAF, 0x93, 0xF7, 0x2E, 0xFC, 0xC8, 0x2B, 0x9B, 0x16, 0x3F, 0x1A, + 0x46, 0x88, 0x7B, 0x3E, 0xA4, 0xE9, 0x83, 0xEA, 0x32, 0x1C, 0xF2, 0x98, 0x0A, 0x87, 0x3C, 0xA6, + 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x3E, 0xD0, 0xF7, 0xCA, + 0xCE, 0xFE, 0xC3, 0x7C, 0xF3, 0xE6, 0x5E, 0xF7, 0xED, 0x56, 0x95, 0xF8, 0xE0, 0x01, 0x73, 0x00, + 0x00, 0x50, 0x6A, 0xFF, 0xE3, 0xFE, 0xCF, 0x2C, 0x7A, 0x75, 0xF3, 0xA2, 0xE7, 0xA2, 0x21, 0x32, + 0xF1, 0xF7, 0x36, 0x0C, 0x88, 0x8F, 0x84, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, + 0x7D, 0xA8, 0xEF, 0x85, 0x9D, 0xFF, 0xA7, 0x05, 0xE6, 0xED, 0x83, 0x7D, 0x41, 0x78, 0x04, 0x37, + 0x1F, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0xA6, 0x8B, 0x5F, 0x3E, 0xB6, 0xF8, 0x96, 0xD7, 0xB7, 0x2E, + 0x7C, 0x39, 0x0C, 0x11, 0xF7, 0xA0, 0xBA, 0xFF, 0x7C, 0x88, 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, + 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xF6, + 0xDD, 0x3E, 0xF7, 0x80, 0xF9, 0xA9, 0x67, 0xA3, 0xE1, 0xE1, 0xC7, 0x07, 0x0F, 0x98, 0x03, 0x00, + 0x80, 0xE9, 0xC7, 0x3D, 0xA8, 0xFE, 0xDB, 0xA7, 0x17, 0x7F, 0xF5, 0xF5, 0xAD, 0x8B, 0x7E, 0xE3, + 0x22, 0xE4, 0x77, 0x3B, 0x16, 0x9A, 0x37, 0xF7, 0x2F, 0x32, 0xE7, 0xFE, 0xD1, 0x1D, 0xEC, 0x55, + 0x44, 0x64, 0x5D, 0x3C, 0x1A, 0xF2, 0x9A, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, + 0xFC, 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xED, 0xAB, 0x3C, 0x60, 0x3E, 0x19, 0x1E, 0xAF, 0x3D, 0x33, + 0x97, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x7E, 0xF5, 0xC8, 0xBC, 0x0F, 0xFC, 0xE6, 0xE9, 0x85, 0xF7, + 0xBD, 0xBE, 0x75, 0xC1, 0x5B, 0x2E, 0x42, 0xDC, 0xDE, 0x1E, 0x59, 0x6C, 0xBC, 0x7F, 0x51, 0x31, + 0x91, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, + 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xCD, 0xAB, 0x3C, 0x60, 0x1E, 0x3E, 0xE7, 0x61, 0xC3, 0x63, 0xCB, + 0x5C, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x88, 0x1B, 0xFB, 0x4F, 0x9F, 0xB9, 0xF8, 0x95, 0xCD, 0x0B, + 0xB7, 0x84, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCD, 0xA9, 0xE7, 0xDA, 0x09, 0x11, 0x15, 0x0E, 0x79, + 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC0, 0xEF, + 0xD6, 0xD5, 0x3E, 0x60, 0x3E, 0xD7, 0xBC, 0xBE, 0x75, 0xEE, 0xB8, 0xFD, 0x91, 0x07, 0xCC, 0x01, + 0x00, 0x00, 0x9A, 0xF9, 0x9F, 0x0F, 0x2D, 0x5A, 0xFA, 0xEA, 0xE6, 0x85, 0x3F, 0x0B, 0x43, 0x64, + 0x7C, 0x68, 0x91, 0x39, 0x33, 0xEA, 0x0E, 0xFE, 0x2A, 0x32, 0x1A, 0x2D, 0x1E, 0x0D, 0x79, 0x4D, + 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC8, 0xEF, 0xC6, + 0xD5, 0x3F, 0x60, 0x6E, 0xB7, 0x75, 0x0E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA4, 0xF1, 0xBF, 0x1E, + 0x5A, 0xF0, 0xC5, 0xD7, 0xB6, 0x2E, 0xF8, 0x65, 0x18, 0x22, 0x6F, 0xEC, 0x5D, 0x64, 0xCE, 0xFE, + 0xC4, 0x45, 0x80, 0x0A, 0x8E, 0xE8, 0xE2, 0xD1, 0x90, 0xD7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, + 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x07, 0xFD, 0x6E, 0x9B, 0x7E, 0xC0, 0x7C, 0x2E, 0x0F, + 0x98, 0x03, 0x00, 0x00, 0x64, 0xE5, 0x1E, 0x54, 0xFF, 0xF5, 0xC6, 0x45, 0x7F, 0x19, 0x7D, 0x3E, + 0xC4, 0x3D, 0xA8, 0x7E, 0xFE, 0x67, 0x2A, 0x3C, 0xDC, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, + 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0x61, 0xBF, 0xDB, 0xC6, 0x03, 0xE6, + 0x00, 0x00, 0x00, 0x05, 0x72, 0x0F, 0xAA, 0xFF, 0xFA, 0xC9, 0x85, 0x1B, 0xC2, 0x08, 0x71, 0x7B, + 0xE7, 0x70, 0xFC, 0xF9, 0x10, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, + 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xD8, 0xEF, 0xA6, 0xF1, 0x80, 0x39, 0x00, 0x00, 0xC0, 0x14, + 0x3A, 0xF9, 0xC8, 0xE2, 0xF9, 0xBF, 0xDD, 0xB4, 0x60, 0x47, 0x18, 0x21, 0xE1, 0x83, 0xEA, 0x3A, + 0x1C, 0xF2, 0x58, 0x3C, 0x10, 0x8A, 0x9C, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, + 0x03, 0x7F, 0xB7, 0x8C, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x3A, 0xE8, 0x57, 0x1B, 0x17, 0xAD, 0x79, + 0x65, 0xD3, 0x82, 0x9F, 0x57, 0x42, 0x64, 0x81, 0x19, 0x1F, 0x5A, 0x68, 0xCE, 0x8C, 0xBA, 0x43, + 0xBC, 0x8A, 0x88, 0xAC, 0x8B, 0x07, 0x42, 0x91, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, + 0x3D, 0x7D, 0xE8, 0xEF, 0x86, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x40, 0x97, 0xA8, 0x7C, 0x90, 0xE1, + 0xC2, 0xAF, 0xBE, 0xB6, 0x75, 0xFE, 0x2F, 0x5D, 0x84, 0xB8, 0xBD, 0xB9, 0x7F, 0xA1, 0x39, 0xFB, + 0x13, 0x77, 0xA0, 0x57, 0x41, 0x91, 0x66, 0xF1, 0x40, 0x28, 0x72, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, + 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFE, 0x9D, 0x5E, 0xA3, 0x07, 0xCC, 0x4F, 0x7E, 0xE7, 0x53, 0xF3, + 0x83, 0x2F, 0x01, 0x00, 0x00, 0x00, 0x74, 0xC2, 0x60, 0xFF, 0xA7, 0xFE, 0xDD, 0xAB, 0x9B, 0x16, + 0xDC, 0xF3, 0xFA, 0xD6, 0xF9, 0x6F, 0x85, 0x21, 0xF2, 0xF6, 0x88, 0x7B, 0x50, 0x5D, 0x85, 0x45, + 0x92, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFF, + 0x9D, 0x9E, 0x7A, 0xC0, 0xFC, 0xB7, 0x1B, 0xE7, 0xDE, 0x10, 0xFC, 0x23, 0x0F, 0x00, 0x00, 0x80, + 0x6E, 0xF0, 0xFF, 0x7E, 0x63, 0xF1, 0x87, 0x7F, 0xF3, 0xD4, 0x82, 0x47, 0xC3, 0x08, 0x71, 0x3B, + 0xF5, 0xDC, 0x22, 0xE3, 0xFD, 0x8B, 0x8A, 0x8C, 0x46, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, + 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xFE, 0x3B, 0xB9, 0xF8, 0x03, 0xE6, 0xEE, 0x39, 0x8F, + 0x57, 0x9F, 0xBE, 0xF4, 0x3F, 0x06, 0xFF, 0x88, 0x03, 0x00, 0x00, 0xA0, 0x1B, 0xFD, 0x8F, 0xFB, + 0x17, 0x2C, 0x7A, 0x75, 0xF3, 0x82, 0x9F, 0x85, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCC, 0xE9, 0xBF, + 0x75, 0x07, 0x61, 0x15, 0x1C, 0xD1, 0xA9, 0x48, 0x28, 0x6A, 0xB1, 0x03, 0x7A, 0x99, 0x27, 0x0F, + 0xFF, 0x9D, 0x9E, 0x0E, 0x80, 0x4E, 0xAD, 0xEE, 0x01, 0xF3, 0xCD, 0x73, 0xDE, 0xB2, 0x3F, 0xF2, + 0x80, 0x39, 0x00, 0x00, 0x40, 0x2F, 0xF9, 0xE5, 0xC3, 0xF3, 0x6F, 0x79, 0x75, 0xCB, 0x82, 0x97, + 0xC3, 0x10, 0x71, 0x0F, 0xAA, 0x4F, 0xFC, 0x57, 0x77, 0xF8, 0x27, 0x3E, 0xA6, 0x6C, 0xF2, 0xF0, + 0xDF, 0xE9, 0xE9, 0x08, 0xE8, 0xC4, 0x1A, 0x3D, 0x60, 0x3E, 0xBE, 0xA5, 0x6F, 0x76, 0xF0, 0x8F, + 0x31, 0x00, 0x00, 0x00, 0x7A, 0x49, 0xF8, 0xA0, 0x7A, 0xF4, 0xF9, 0x10, 0xF7, 0xA0, 0xFA, 0xB9, + 0x7F, 0x74, 0x21, 0x40, 0x7C, 0x14, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x74, 0x08, 0x4C, 0xF5, 0x1A, + 0x3D, 0x60, 0xFE, 0xEB, 0xC7, 0x3E, 0x7D, 0x55, 0xF0, 0x8F, 0x2E, 0x00, 0x00, 0x00, 0x7A, 0x99, + 0xFB, 0x20, 0xC3, 0xDF, 0x6C, 0x9C, 0x7F, 0x5F, 0xED, 0x83, 0xEA, 0x0B, 0xCD, 0xF9, 0x9F, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x63, 0x60, 0xAA, 0x17, + 0x7F, 0xC0, 0xFC, 0xF5, 0x6D, 0x73, 0x4E, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x40, 0x49, 0xFD, 0xDB, + 0x83, 0x7D, 0x7D, 0xAF, 0x6C, 0x5E, 0xB0, 0xA5, 0x12, 0x21, 0xF3, 0xCD, 0xEF, 0x77, 0xCD, 0x37, + 0xA7, 0x9E, 0x5B, 0x68, 0xBC, 0x7F, 0x51, 0xC1, 0x90, 0xE7, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, + 0xFF, 0x4E, 0x4F, 0xC7, 0xC0, 0x54, 0x8E, 0x07, 0xCC, 0x01, 0x00, 0x00, 0xA6, 0xB1, 0xFF, 0xF9, + 0xD0, 0xBC, 0xA5, 0xAF, 0x6E, 0xEE, 0xFB, 0x99, 0x8B, 0x90, 0x30, 0x44, 0xCE, 0x8C, 0xBA, 0x03, + 0xB4, 0x8A, 0x87, 0x76, 0x17, 0x3B, 0xA0, 0x97, 0x79, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x20, 0x98, + 0xAA, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xAA, 0x7E, 0xF5, 0x58, 0xDF, 0x5F, 0x54, 0x3E, 0xC8, + 0xB0, 0x12, 0x22, 0xE3, 0x43, 0xF6, 0xC0, 0xF8, 0x13, 0x77, 0x98, 0x56, 0x21, 0x91, 0x65, 0xB1, + 0x03, 0x7A, 0x99, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x82, 0xA9, 0x18, 0x0F, 0x98, 0x03, 0x00, + 0x00, 0x40, 0x72, 0x0F, 0xAA, 0xFF, 0x7A, 0x63, 0xDF, 0x5F, 0xBE, 0xBE, 0xB5, 0xEF, 0xAD, 0x30, + 0x44, 0xDE, 0xDC, 0x6F, 0x0F, 0x90, 0x6D, 0x3F, 0x1F, 0x22, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, + 0x77, 0x7A, 0x3A, 0x0C, 0x8A, 0x1E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x20, 0x11, 0xFF, 0x41, 0xF5, + 0xA7, 0xFA, 0x1E, 0x0D, 0x23, 0xC4, 0xCD, 0x3D, 0xA8, 0x9E, 0xED, 0xF9, 0x10, 0x71, 0x48, 0x2F, + 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x71, 0x50, 0xF4, 0xCE, 0xFC, 0xDD, 0x7C, 0x1E, 0x30, 0x07, + 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x41, 0xF5, 0x57, 0x9F, 0x99, 0x3F, 0x12, 0x46, 0x48, 0xFA, 0x07, + 0xD5, 0xC5, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x41, 0x91, 0x73, 0xCF, 0x79, + 0xF0, 0x80, 0x39, 0x00, 0x00, 0x00, 0xDA, 0xF2, 0xAB, 0x27, 0xFA, 0xD6, 0x44, 0x1F, 0x54, 0x77, + 0xCF, 0x87, 0xB4, 0x7E, 0x50, 0x3D, 0x76, 0x40, 0x2F, 0xF3, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x81, + 0x50, 0xD4, 0xCE, 0xFD, 0x94, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x90, 0xA3, 0xCA, 0x07, 0x19, 0xF6, + 0x7D, 0x35, 0xFA, 0xA0, 0xBA, 0x7B, 0x3E, 0x44, 0x3F, 0xA8, 0x1E, 0x3B, 0xA0, 0x97, 0x79, 0xF2, + 0xF0, 0xDF, 0xE9, 0xE9, 0x48, 0x28, 0x62, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x42, 0xB9, 0xE7, + 0x43, 0x5E, 0xDD, 0xD4, 0x77, 0x4F, 0xF4, 0x41, 0xF5, 0xB7, 0x0E, 0x46, 0x1F, 0x54, 0x17, 0x87, + 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0A, 0x79, 0x2F, 0x7C, 0xC0, 0x3C, 0xFA, 0x9C, + 0x87, 0x1D, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA0, 0x18, 0x47, 0xBF, 0xB1, 0xF8, 0xC3, 0xAF, 0x6C, + 0xEE, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0x3B, 0x87, 0xEC, 0xC1, 0xF4, 0x5F, 0xC4, 0x41, 0xBD, 0x8C, + 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x42, 0xDE, 0x53, 0x0F, 0x98, 0xFF, 0xFA, 0xE1, 0x4B, 0x6F, + 0x0E, 0xFE, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xE3, 0x3F, 0xA8, 0xEE, 0x9E, 0x0F, 0xD9, 0xDE, + 0x67, 0xDC, 0x7E, 0xBF, 0xB3, 0xCF, 0x9C, 0x7A, 0xCE, 0x1E, 0x54, 0xD5, 0xA1, 0xBD, 0x2C, 0x93, + 0x87, 0xFF, 0x4E, 0xAF, 0x3E, 0x14, 0xF2, 0x9E, 0x7A, 0xC0, 0xFC, 0xD7, 0x83, 0x73, 0xFE, 0xB7, + 0xE0, 0x1F, 0x05, 0x00, 0x00, 0x00, 0x60, 0xEA, 0xFC, 0xF2, 0xE1, 0xB9, 0xB7, 0xBC, 0xB6, 0xB5, + 0xEF, 0x97, 0x61, 0x88, 0x8C, 0xEF, 0x9E, 0x6F, 0x26, 0xFE, 0xAB, 0x3D, 0x18, 0xAB, 0x03, 0x7C, + 0x2F, 0x4F, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0C, 0x79, 0x4D, 0x3D, 0x60, 0xFE, 0xDA, 0xA6, 0x39, + 0x77, 0xF3, 0x80, 0x39, 0x00, 0x00, 0x00, 0x3A, 0xCA, 0x7F, 0x50, 0xFD, 0xC9, 0xBE, 0xAF, 0xBE, + 0xBE, 0x65, 0xDE, 0x5B, 0x61, 0x88, 0xBC, 0xB9, 0x6F, 0xBE, 0x39, 0xFB, 0x13, 0x7B, 0x48, 0x56, + 0x87, 0xF9, 0x5E, 0x9B, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x1A, 0xF2, 0x98, 0x7A, 0xC0, 0xFC, 0xD5, + 0xCD, 0x73, 0x37, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xBA, 0x8A, 0x7B, 0x50, 0xFD, 0xB7, 0x9B, + 0xFA, 0xEE, 0x09, 0x23, 0xC4, 0xED, 0xED, 0x61, 0xF7, 0xA0, 0xBA, 0x38, 0xD4, 0xF7, 0xCA, 0xE4, + 0xE1, 0xBF, 0xD3, 0xD3, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0x3D, 0xC9, 0x3D, + 0x1F, 0xF2, 0xCA, 0xA6, 0xBE, 0x2D, 0xD1, 0x10, 0x71, 0xCF, 0x87, 0xF4, 0xDC, 0x83, 0xEA, 0xF2, + 0xF0, 0xDF, 0xE9, 0xE9, 0x78, 0x68, 0x77, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x9E, 0x57, 0xF9, + 0x20, 0xC3, 0x79, 0x35, 0x0F, 0xAA, 0x9F, 0xFE, 0x5B, 0x7B, 0xE0, 0x55, 0x87, 0xFD, 0x6E, 0x9B, + 0x3C, 0xFC, 0x77, 0x7A, 0xF5, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xA5, 0xF3, + 0xAB, 0xC7, 0xFA, 0xFE, 0x22, 0xFE, 0xA0, 0x7A, 0x57, 0x3F, 0x1F, 0x22, 0x0F, 0xFF, 0x9D, 0x9E, + 0x0E, 0x88, 0xAC, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0x94, 0x9A, 0x7B, 0x50, 0xFD, 0xB5, 0x2D, + 0xF3, 0xBE, 0x1E, 0x7F, 0x50, 0xFD, 0xDC, 0x3F, 0xDA, 0xC3, 0xB5, 0x8A, 0x80, 0x4E, 0x4D, 0x1E, + 0xFE, 0x3B, 0x3D, 0x1D, 0x11, 0x59, 0xC6, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x98, 0x56, 0xDC, 0x83, + 0xEA, 0xBF, 0x79, 0xAA, 0xEF, 0xC7, 0x61, 0x84, 0xB8, 0x75, 0xCD, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, + 0xE9, 0xE9, 0x90, 0x48, 0xBB, 0x46, 0x0F, 0x98, 0xBF, 0xB6, 0xE5, 0xD2, 0x81, 0xE0, 0x7F, 0x1A, + 0x00, 0x00, 0x00, 0xA0, 0xBC, 0xFC, 0x0F, 0x32, 0xDC, 0xD4, 0x37, 0x12, 0x46, 0x48, 0xF8, 0x41, + 0x86, 0x1D, 0x7B, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x13, 0x69, 0xA7, 0x1E, 0x30, 0x7F, + 0xE5, 0xC9, 0x39, 0xB7, 0x07, 0xFF, 0x53, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x87, 0x7B, 0x50, 0xFD, + 0xB5, 0x2D, 0xF3, 0x8E, 0x85, 0x21, 0xE2, 0x9E, 0x0F, 0x39, 0x33, 0x6A, 0x0F, 0xDF, 0x2A, 0x12, + 0x8A, 0x9A, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x26, 0xD2, 0x4C, 0x3D, 0x60, 0xFE, 0xCA, 0xA6, 0xB9, + 0xFF, 0x57, 0xF0, 0xB7, 0x1E, 0x00, 0x00, 0x00, 0x98, 0x9E, 0xC2, 0x0F, 0x32, 0x8C, 0x3E, 0xA8, + 0xFE, 0xC6, 0x9E, 0x29, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x14, 0x49, 0x17, 0x7F, + 0xC0, 0xDC, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x98, 0xF0, 0x83, 0x0C, 0xE3, 0x0F, 0xAA, + 0x17, 0xF6, 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2A, 0x92, 0x8C, 0x07, 0xCC, 0x01, 0x00, + 0x00, 0x80, 0x0C, 0x5E, 0x79, 0x72, 0xCE, 0xA5, 0xF1, 0x0F, 0x32, 0x74, 0x0F, 0xAA, 0xE7, 0xFA, + 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2C, 0x5A, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, + 0x1C, 0xFC, 0x7A, 0x63, 0xDF, 0x55, 0xAF, 0x6E, 0x9E, 0xF7, 0x4F, 0x61, 0x84, 0x84, 0x0F, 0xAA, + 0xCB, 0xA0, 0x48, 0x33, 0x79, 0xF8, 0xEF, 0xF4, 0xEA, 0xC3, 0x22, 0xC9, 0x78, 0xC0, 0x1C, 0x00, + 0x00, 0x00, 0xC8, 0xD9, 0x2F, 0x1F, 0x9E, 0x7B, 0x4B, 0xFC, 0x83, 0x0C, 0x33, 0x3F, 0xA8, 0x2E, + 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x8B, 0x66, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, 0x40, 0xFE, + 0x07, 0x19, 0x6E, 0xEE, 0xFB, 0x3F, 0xE3, 0xCF, 0x87, 0xA4, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, + 0x3D, 0x1D, 0x18, 0x8D, 0xA6, 0x1E, 0x30, 0xFF, 0xED, 0xC6, 0x4B, 0xBF, 0xC5, 0x03, 0xE6, 0x00, + 0x00, 0x00, 0x40, 0x01, 0xC2, 0x07, 0xD5, 0xC3, 0x08, 0x71, 0x7B, 0xEB, 0x40, 0x82, 0x07, 0xD5, + 0xE5, 0xE1, 0xBF, 0xD3, 0xD3, 0x91, 0xA1, 0xE6, 0x9E, 0xF3, 0x88, 0x3F, 0x60, 0xFE, 0xCA, 0x53, + 0x73, 0xB6, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x00, 0x30, 0x05, 0xDC, 0x07, 0x19, 0xBE, 0xBE, 0x75, + 0xDE, 0xFE, 0x68, 0x88, 0xBC, 0x73, 0xA8, 0xC1, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xD0, + 0x88, 0x4F, 0x3D, 0x60, 0xFE, 0xDA, 0xE6, 0x39, 0x3F, 0xE1, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, + 0x03, 0xDC, 0x07, 0x19, 0xC6, 0x1F, 0x54, 0x3F, 0xFD, 0xB7, 0xF6, 0xF0, 0x5E, 0x82, 0xF8, 0x70, + 0x0F, 0x98, 0xD7, 0x3C, 0xE7, 0xC1, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x40, 0x77, 0x88, 0x7F, 0x90, + 0xE1, 0xF8, 0xEE, 0x3E, 0x33, 0xF1, 0xF7, 0xEE, 0x20, 0xAF, 0x02, 0xA0, 0x93, 0xAB, 0x0F, 0x8D, + 0xF8, 0xDC, 0x03, 0xE6, 0x6F, 0x0C, 0xD5, 0x3F, 0x60, 0x3E, 0xDA, 0xFF, 0x9E, 0x3F, 0x0A, 0x7E, + 0xBB, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xCD, 0x7F, 0x50, 0x7D, 0xCB, 0xBC, 0xAF, 0x57, 0x1E, 0x54, + 0xB7, 0x07, 0x78, 0xBB, 0x37, 0xF7, 0xF5, 0xD9, 0x03, 0xBD, 0x3B, 0xD8, 0xAB, 0x18, 0x98, 0xEA, + 0xD5, 0xC7, 0x46, 0x74, 0xEE, 0x83, 0x04, 0x79, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xE8, 0x31, 0xEE, + 0x41, 0xF5, 0x57, 0x36, 0xCD, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0xDB, 0xC3, 0xF3, 0xED, 0x01, 0x5F, + 0x45, 0xC1, 0x54, 0x4D, 0x47, 0x87, 0x1B, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x6F, + 0x1B, 0xFA, 0xFA, 0x5E, 0xDB, 0x32, 0xF7, 0x27, 0x61, 0x84, 0xFC, 0x7E, 0xE7, 0x3C, 0x73, 0xEA, + 0xD9, 0xF9, 0xF6, 0xC0, 0xAF, 0x02, 0xA1, 0xC8, 0x35, 0x0E, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, + 0x00, 0x4A, 0xE6, 0x57, 0x4F, 0x5C, 0xBA, 0xC6, 0x86, 0xC8, 0xB1, 0x68, 0x88, 0x9C, 0xF9, 0x3B, + 0x17, 0x01, 0x2A, 0x16, 0xF2, 0x5E, 0x7D, 0x78, 0xB8, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0x50, + 0x62, 0xEE, 0x01, 0xEE, 0xDF, 0x3E, 0x39, 0xF7, 0xAB, 0xAF, 0x6F, 0x9B, 0x37, 0x1E, 0x86, 0x88, + 0x7B, 0x50, 0xBD, 0xD8, 0xE7, 0x43, 0xEA, 0xC3, 0x83, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x69, + 0xA4, 0xF2, 0x41, 0x86, 0x73, 0xEF, 0x79, 0x7D, 0xCB, 0xDC, 0x9A, 0x07, 0xD5, 0xCF, 0xFD, 0x34, + 0xEF, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, 0xA6, 0xB1, 0x57, 0x9E, 0x9C, + 0x73, 0xA9, 0x7A, 0x50, 0x3D, 0x9F, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, + 0xE0, 0x7B, 0x6D, 0x47, 0xDF, 0x40, 0xE5, 0x83, 0x0C, 0x27, 0x43, 0xE4, 0x8D, 0x3D, 0x7D, 0xFE, + 0x33, 0x22, 0xD9, 0xDE, 0x9A, 0x55, 0x79, 0xB8, 0xDC, 0x3D, 0xE3, 0x11, 0xBF, 0xF1, 0xE0, 0x01, + 0x73, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x57, 0x9E, 0x99, 0x73, 0xDB, 0xEB, 0xDB, 0xE7, 0x9E, 0x8C, + 0x86, 0x48, 0x18, 0x23, 0xEF, 0x1C, 0x9A, 0x6F, 0x4E, 0xFF, 0xCD, 0x7C, 0xFF, 0x79, 0x91, 0xF8, + 0x0D, 0x89, 0xFB, 0xFF, 0xDD, 0xBF, 0xEE, 0xFE, 0xFD, 0x77, 0x0E, 0xF5, 0xD5, 0x3C, 0xDF, 0x11, + 0xCE, 0x3D, 0x60, 0x6E, 0x7F, 0xEE, 0x75, 0xC1, 0x5F, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xDC, + 0x1B, 0xB3, 0x5E, 0x79, 0x66, 0xEE, 0x70, 0x3C, 0x44, 0x5A, 0x2E, 0x16, 0x1D, 0x95, 0xCD, 0x19, + 0xFA, 0xF5, 0xA3, 0x97, 0xDE, 0x1C, 0xFC, 0xD4, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xB9, 0x87, 0xD5, + 0x7F, 0xB3, 0x71, 0xDE, 0x9D, 0xAF, 0x3E, 0x3D, 0xEF, 0xA1, 0x57, 0x37, 0xCF, 0x7D, 0x59, 0x46, + 0x47, 0xB8, 0x20, 0x38, 0x5E, 0xDB, 0x3C, 0xF7, 0xD8, 0xAB, 0xCF, 0xCC, 0x7D, 0xDA, 0xDD, 0x76, + 0xFC, 0xB7, 0xEF, 0xCC, 0xFB, 0x40, 0xF0, 0x53, 0x01, 0x00, 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x35, + 0xB9, 0xFE, 0x07, 0x1B, 0xEE, 0xE8, 0x1B, 0x88, 0xEF, 0xDF, 0x36, 0xCC, 0xEE, 0x0B, 0xFE, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD0, 0x15, 0xDE, 0xF3, 0x9E, 0xFF, 0x1F, 0x5B, 0xE2, 0x94, 0x1D, 0x86, + 0x86, 0x23, 0x09, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82}; + +static const uint8_t tree_img_gif[] PROGMEM = { + + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x28, 0x00, 0x3C, 0x00, 0x83, 0x0B, 0x00, 0x00, 0xFF, 0xFF, + 0x00, 0x21, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x94, 0x00, 0x00, 0xB5, 0x00, 0x00, + 0xDE, 0x00, 0x00, 0xFF, 0x00, 0x6B, 0x00, 0x00, 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x00, 0xCC, 0x00, 0x00, 0x21, 0xFF, 0x0B, + 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0xA0, 0x0F, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, + 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, + 0x8C, 0xCA, 0xE8, 0x85, 0xE8, 0xA5, 0xAC, 0x67, 0xEA, 0x8A, 0xE5, 0x2B, 0x2F, 0xE3, 0x31, 0xCE, + 0xAF, 0x41, 0x1C, 0xB8, 0x1B, 0x24, 0x80, 0x04, 0xAF, 0x87, 0x02, 0x26, 0x88, 0xA1, 0x07, 0x60, + 0xB9, 0x44, 0x82, 0x04, 0x02, 0x80, 0x61, 0x30, 0x70, 0x6E, 0x0C, 0x86, 0x03, 0x60, 0x20, 0xB0, + 0x6A, 0xA8, 0xD3, 0x03, 0x21, 0xEC, 0xAD, 0x18, 0x12, 0xE8, 0xF4, 0xB1, 0x4C, 0x51, 0xA0, 0x07, + 0xEA, 0x07, 0x5B, 0xF2, 0x70, 0x13, 0x76, 0xD4, 0xA8, 0xBC, 0xBC, 0xEA, 0x1F, 0x06, 0x77, 0x51, + 0x73, 0x50, 0x0A, 0x80, 0x7F, 0x04, 0x4C, 0x4D, 0x65, 0x06, 0x0A, 0x3B, 0x3B, 0x62, 0x5A, 0x53, + 0x65, 0x05, 0x02, 0x04, 0x68, 0x0C, 0x6A, 0x00, 0x5D, 0x5E, 0x0F, 0x0F, 0x6A, 0x98, 0x6A, 0x09, + 0x7B, 0x56, 0x9D, 0x09, 0x0C, 0xA7, 0xA7, 0x7F, 0x06, 0x9D, 0xA3, 0x44, 0x02, 0x01, 0x03, 0x90, + 0x0C, 0x87, 0x03, 0x06, 0x02, 0x05, 0x56, 0x06, 0x01, 0x02, 0x53, 0xB1, 0xB3, 0x04, 0x79, 0xAF, + 0x55, 0x48, 0x51, 0xB0, 0x87, 0xC0, 0x7F, 0x07, 0x95, 0x05, 0x85, 0x44, 0xB6, 0x00, 0x05, 0x53, + 0x96, 0x6A, 0x60, 0x02, 0x0A, 0x48, 0x89, 0x00, 0x07, 0xA1, 0x69, 0x7D, 0x2B, 0x3D, 0x9D, 0x41, + 0xA1, 0x04, 0xA0, 0xDD, 0x9D, 0x38, 0x02, 0xE1, 0x6A, 0x07, 0x62, 0x0C, 0x77, 0xE6, 0xAD, 0x2F, + 0x05, 0x01, 0xB6, 0x90, 0x07, 0xA8, 0xA7, 0x54, 0xB5, 0xBC, 0x06, 0x33, 0x50, 0x53, 0x3A, 0x00, + 0x39, 0x62, 0x10, 0x6B, 0xDF, 0xBE, 0x19, 0x03, 0x18, 0x40, 0xA9, 0x15, 0x4B, 0xCC, 0x0E, 0x77, + 0x3B, 0x04, 0xC4, 0x02, 0x38, 0x43, 0x21, 0x96, 0x2C, 0xD3, 0xD6, 0x81, 0x01, 0x26, 0x2A, 0xFB, + 0xDE, 0x07, 0x7C, 0x0A, 0xB7, 0x71, 0x1B, 0x79, 0xEE, 0xC5, 0x83, 0x72, 0xDD, 0x84, 0xBC, 0x4B, + 0x13, 0xA4, 0x13, 0x15, 0x17, 0xAB, 0x18, 0x78, 0x4A, 0x43, 0x40, 0x81, 0x43, 0x76, 0x8E, 0xB6, + 0x04, 0x7C, 0x19, 0x02, 0x98, 0xC4, 0x86, 0x35, 0xBD, 0xE1, 0x1C, 0x90, 0x4D, 0x62, 0xBF, 0x14, + 0xFC, 0x7E, 0x02, 0x1A, 0x60, 0xD3, 0xD1, 0x9D, 0x3B, 0x3A, 0x09, 0xFC, 0x44, 0xB1, 0xD0, 0x96, + 0x8E, 0x43, 0x8D, 0x9E, 0xDA, 0xDB, 0x22, 0x11, 0x8A, 0x42, 0x10, 0x5C, 0x00, 0x1A, 0x2D, 0x38, + 0xF2, 0x0E, 0xA0, 0x4A, 0x03, 0x4E, 0xA2, 0xF0, 0xF4, 0x80, 0x17, 0x95, 0x8C, 0x23, 0xD1, 0xD8, + 0x12, 0x00, 0x92, 0x03, 0xAB, 0x99, 0x23, 0x71, 0x3E, 0x8D, 0xEB, 0x6E, 0x18, 0x07, 0x66, 0x23, + 0x05, 0x3E, 0x72, 0xE4, 0x06, 0x0D, 0x81, 0x02, 0xE4, 0x36, 0x5D, 0xD9, 0xA5, 0xC0, 0xAD, 0x59, + 0xA2, 0x86, 0x6E, 0xD6, 0xC4, 0x73, 0xEB, 0x15, 0xA5, 0xC5, 0xDE, 0x14, 0xF4, 0x62, 0x07, 0xC0, + 0xE9, 0x9D, 0xCC, 0x58, 0x02, 0x14, 0xA0, 0x84, 0x45, 0x83, 0x68, 0x7A, 0x8D, 0x81, 0x66, 0xC3, + 0xE9, 0xD0, 0xA6, 0x3E, 0x03, 0xF3, 0x80, 0x7D, 0x90, 0xD8, 0x58, 0xA2, 0x59, 0x2D, 0x90, 0x68, + 0xD6, 0x64, 0x17, 0x76, 0x5A, 0x23, 0xBF, 0x13, 0x58, 0x89, 0x7A, 0xC3, 0xF0, 0x8F, 0xB6, 0xB8, + 0x4B, 0xD3, 0x74, 0x52, 0x50, 0x92, 0xC2, 0x03, 0xD1, 0x78, 0xD7, 0x89, 0x4C, 0x23, 0x26, 0x6E, + 0x82, 0xCC, 0x15, 0x5E, 0x05, 0x08, 0x30, 0x06, 0x8A, 0x75, 0x64, 0xFA, 0x42, 0xF1, 0x12, 0xAD, + 0x60, 0xDE, 0x51, 0x0A, 0x94, 0xBA, 0x5E, 0x2C, 0x8C, 0x86, 0xDD, 0x3D, 0xDE, 0x8F, 0x0A, 0x70, + 0x51, 0x5F, 0xFE, 0xF2, 0x84, 0xD1, 0xD0, 0xA6, 0x68, 0xB7, 0x96, 0x62, 0x14, 0x0C, 0xC1, 0xB7, + 0x90, 0x68, 0x72, 0xD1, 0x7C, 0xD9, 0x3D, 0xA3, 0x94, 0x35, 0xDE, 0x54, 0x06, 0x92, 0x51, 0x50, + 0x68, 0xC2, 0xC5, 0x44, 0xB7, 0x30, 0x70, 0xDE, 0x6A, 0x49, 0x69, 0x86, 0xC5, 0x2D, 0xA3, 0x29, + 0x04, 0x05, 0x2F, 0xD9, 0xC4, 0x02, 0x0C, 0x6C, 0x0C, 0x48, 0xB0, 0x94, 0x01, 0xDA, 0x3C, 0xF2, + 0x56, 0x21, 0xFA, 0xE8, 0xA3, 0xA1, 0x55, 0x12, 0xE9, 0xF4, 0x56, 0x42, 0xF8, 0x50, 0x00, 0x40, + 0x08, 0x08, 0xD4, 0x88, 0x80, 0x05, 0x33, 0x66, 0x10, 0xA2, 0x0C, 0xDC, 0xA0, 0xB0, 0xA3, 0x0B, + 0x71, 0xCD, 0xB1, 0x80, 0x75, 0x69, 0x20, 0x41, 0xE4, 0x91, 0x6B, 0x64, 0x10, 0x01, 0x00, 0x21, + 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, 0x00, + 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, 0x8C, + 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0x31, 0x1C, 0x34, + 0x1B, 0x24, 0x4C, 0x82, 0xE7, 0x28, 0x5E, 0x02, 0x78, 0x7A, 0x30, 0x8E, 0x47, 0x62, 0x48, 0x20, + 0x60, 0xD8, 0x06, 0x4A, 0x8E, 0xC1, 0x70, 0x60, 0x0C, 0x04, 0xD1, 0xCD, 0x60, 0x60, 0x3B, 0x10, + 0xBA, 0x59, 0x8B, 0x21, 0x41, 0x2E, 0x0F, 0xC3, 0x16, 0xF2, 0xC0, 0xAC, 0x40, 0x4F, 0x1E, 0x80, + 0x04, 0x81, 0x70, 0xD8, 0x0A, 0x14, 0x0F, 0xF7, 0x42, 0x00, 0xA0, 0xD6, 0x09, 0x0A, 0x81, 0x81, + 0x68, 0x00, 0x85, 0x85, 0x7F, 0x07, 0x07, 0x0A, 0x06, 0x7A, 0x06, 0x00, 0x74, 0x74, 0x5E, 0x8A, + 0x36, 0x68, 0x05, 0x7C, 0x66, 0x3D, 0x64, 0x58, 0x61, 0x0F, 0x0F, 0x66, 0x64, 0x99, 0x64, 0x79, + 0x9C, 0x9E, 0xA0, 0x48, 0x4E, 0x9D, 0xA3, 0x4A, 0x02, 0x01, 0x37, 0x90, 0x55, 0x04, 0x5C, 0x02, + 0x05, 0x59, 0x06, 0x01, 0x02, 0x4F, 0x89, 0x55, 0x76, 0xAC, 0x50, 0xAB, 0x0A, 0xAD, 0x7F, 0xB1, + 0x75, 0x07, 0x02, 0x04, 0x05, 0x00, 0xBE, 0x39, 0x06, 0x77, 0x05, 0x36, 0x04, 0x9F, 0x5B, 0xCC, + 0x00, 0x4A, 0x82, 0x81, 0x07, 0x9F, 0x65, 0x86, 0x85, 0x40, 0x9D, 0x0A, 0x9F, 0x0C, 0xD0, 0x9F, + 0x00, 0x9D, 0x39, 0x02, 0xDE, 0x66, 0xB0, 0x73, 0xE2, 0x09, 0xE4, 0xAA, 0x2F, 0x05, 0x01, 0xCC, + 0x5E, 0xA7, 0x56, 0x75, 0xD2, 0xB8, 0x8C, 0x2F, 0x4C, 0x36, 0x06, 0xB1, 0x73, 0xE1, 0x88, 0xC9, + 0x92, 0x45, 0x43, 0x96, 0x00, 0x2E, 0x37, 0xE8, 0x79, 0x99, 0x53, 0xEC, 0x86, 0x0D, 0x06, 0x05, + 0xF3, 0x51, 0x61, 0x57, 0xE6, 0x9E, 0xBF, 0x35, 0x0C, 0xDE, 0x81, 0xE8, 0x64, 0x10, 0xFB, 0x5B, + 0xB6, 0x6C, 0xF5, 0x56, 0x94, 0x22, 0x13, 0xA7, 0xE2, 0x9C, 0x04, 0xDF, 0xCA, 0x74, 0xB2, 0xB2, + 0xC2, 0x40, 0x2A, 0x92, 0x72, 0x20, 0x45, 0x52, 0xE0, 0x45, 0x1A, 0x01, 0x2B, 0xCA, 0x3E, 0xC4, + 0x3A, 0x38, 0x60, 0xDB, 0x23, 0x86, 0xD6, 0x14, 0x0C, 0x20, 0xC0, 0x84, 0xCB, 0x8A, 0x7C, 0x3C, + 0x1F, 0x25, 0x94, 0xA9, 0x80, 0x21, 0x17, 0xA2, 0x5B, 0x4E, 0x34, 0x91, 0xE5, 0x2F, 0x99, 0x4C, + 0xA0, 0x89, 0xEC, 0x5C, 0xC1, 0xB5, 0x89, 0xC3, 0x15, 0x2B, 0xCC, 0x10, 0xD6, 0xF9, 0x38, 0x67, + 0xA8, 0xB1, 0x01, 0xE5, 0x40, 0xD4, 0x7B, 0x42, 0xF1, 0x63, 0x02, 0x66, 0x02, 0x12, 0xA4, 0xFA, + 0x90, 0x2A, 0x54, 0xB6, 0x44, 0xEB, 0xDA, 0x96, 0x19, 0x9A, 0x53, 0x43, 0x01, 0xBB, 0x64, 0x84, + 0xAE, 0xC3, 0xBB, 0xB0, 0xCC, 0x31, 0x40, 0x5D, 0x35, 0xD8, 0x62, 0x82, 0x6B, 0x68, 0xAC, 0xA6, + 0x43, 0xF1, 0xD2, 0x01, 0x20, 0xE9, 0x8A, 0x25, 0x05, 0x96, 0x36, 0xD8, 0x8A, 0xD7, 0xD8, 0x46, + 0xD0, 0x85, 0xEB, 0x7E, 0x72, 0x31, 0x10, 0x54, 0x9F, 0x85, 0x00, 0xF1, 0xA6, 0x1C, 0x94, 0x2C, + 0x34, 0xB2, 0x17, 0x9F, 0x5B, 0xB8, 0x14, 0x80, 0xFC, 0x41, 0x28, 0x63, 0xC7, 0x03, 0x9A, 0x4A, + 0x32, 0x9C, 0x2C, 0x2B, 0x2E, 0x40, 0x72, 0x63, 0x59, 0x48, 0x85, 0x47, 0x8D, 0xD8, 0xC8, 0xD9, + 0xE2, 0xF0, 0x55, 0x99, 0x4A, 0xE3, 0x82, 0x07, 0x41, 0x3F, 0x25, 0x92, 0xAE, 0xD7, 0x4C, 0x3C, + 0xE7, 0xAC, 0x02, 0x04, 0x58, 0xC4, 0xC4, 0xAD, 0x9C, 0x1B, 0xB1, 0x3F, 0xE1, 0x42, 0x3D, 0x4B, + 0x9E, 0x85, 0xCB, 0x57, 0xA6, 0x30, 0x4B, 0x97, 0x88, 0x26, 0xA2, 0x03, 0x7F, 0x8B, 0x72, 0x2D, + 0x90, 0x79, 0x02, 0xFD, 0x59, 0x36, 0xB2, 0xF3, 0x41, 0x2A, 0x65, 0xAD, 0x75, 0x64, 0x3A, 0x0C, + 0x48, 0xB4, 0x15, 0x35, 0x13, 0xE0, 0xC2, 0xC0, 0x2D, 0xB1, 0x15, 0x95, 0x0C, 0x13, 0x97, 0x59, + 0x73, 0x90, 0x01, 0xF5, 0xAC, 0x36, 0x8D, 0x79, 0x12, 0x40, 0xB8, 0x45, 0x22, 0xB8, 0xF8, 0xC4, + 0x0C, 0x7D, 0xB3, 0x31, 0x96, 0xCF, 0x00, 0x01, 0x76, 0x41, 0x80, 0x4F, 0x0B, 0x80, 0x78, 0x4A, + 0x24, 0x5B, 0x8C, 0x18, 0xDB, 0x8A, 0x0A, 0xF0, 0xC3, 0x15, 0x88, 0x08, 0xF1, 0xC5, 0xC7, 0x3C, + 0x13, 0x40, 0x94, 0x01, 0x81, 0x13, 0x20, 0xA0, 0x23, 0x02, 0x27, 0xE0, 0x58, 0x63, 0x08, 0xD9, + 0xE8, 0x41, 0x81, 0x5B, 0x42, 0x7A, 0x57, 0x86, 0x12, 0x46, 0x26, 0x79, 0x46, 0x06, 0x11, 0x00, + 0x00, 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x3C, 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, + 0xE4, 0x8C, 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0xA1, + 0x1C, 0x34, 0x1B, 0x24, 0x4A, 0x82, 0xE7, 0x27, 0x85, 0x50, 0x08, 0x0C, 0x3D, 0x12, 0xBC, 0xC4, + 0xA3, 0x18, 0x12, 0x08, 0x14, 0x86, 0xC1, 0x80, 0xC9, 0x31, 0x18, 0x0E, 0x84, 0x81, 0x80, 0xBA, + 0x91, 0x46, 0xB1, 0x51, 0x06, 0xD7, 0x62, 0x40, 0x9A, 0x91, 0xE2, 0x71, 0xA5, 0x37, 0x40, 0x33, + 0xDE, 0xE9, 0xF1, 0xE3, 0xA1, 0x20, 0x10, 0x0E, 0x52, 0x01, 0x63, 0xA9, 0x5E, 0x0C, 0x85, 0x03, + 0x76, 0x7A, 0x7D, 0x0B, 0x4E, 0x03, 0x75, 0x78, 0x77, 0x78, 0x06, 0x84, 0x51, 0x37, 0x8A, 0x77, + 0x02, 0x51, 0x6A, 0x05, 0x02, 0x04, 0x67, 0x67, 0x5B, 0x72, 0x47, 0x98, 0x98, 0x7C, 0x5C, 0x73, + 0x66, 0x58, 0x07, 0x8B, 0x0F, 0x00, 0x9F, 0x45, 0x02, 0x01, 0x03, 0xA3, 0x0C, 0x89, 0x03, 0x06, + 0x02, 0x00, 0x5C, 0x06, 0x01, 0x92, 0x52, 0x07, 0xAE, 0x59, 0x03, 0x00, 0xBD, 0xBD, 0x4C, 0x02, + 0x05, 0xAB, 0xB9, 0x70, 0x0C, 0xAC, 0x96, 0x00, 0x52, 0x45, 0x36, 0xC1, 0x51, 0x97, 0x0C, 0x66, + 0x5E, 0x00, 0x8C, 0x4C, 0x0A, 0x05, 0x5F, 0x68, 0x98, 0x4E, 0x56, 0x40, 0x7F, 0x3D, 0x67, 0x97, + 0x9D, 0x73, 0x39, 0x02, 0x74, 0x9C, 0x48, 0xA4, 0x76, 0x76, 0x66, 0x73, 0xA8, 0x2C, 0x05, 0x50, + 0x02, 0xA3, 0xA3, 0x59, 0x78, 0x5E, 0x92, 0xD4, 0x2C, 0xDB, 0xB0, 0x59, 0x76, 0x07, 0x00, 0x78, + 0x16, 0x09, 0x80, 0xF5, 0xE4, 0x05, 0xC1, 0x81, 0x5F, 0xB0, 0x10, 0x00, 0xA0, 0xEE, 0xC0, 0xC0, + 0x03, 0x8E, 0x68, 0x68, 0xB1, 0x72, 0xE5, 0x92, 0xAF, 0x5E, 0xF6, 0x0C, 0x10, 0xF0, 0x86, 0x62, + 0xFB, 0xCE, 0xC1, 0x03, 0x98, 0x00, 0x74, 0x42, 0x42, 0xE7, 0xC5, 0xB9, 0x4E, 0xFF, 0xC2, 0x9D, + 0x99, 0xA3, 0x60, 0x0A, 0x0A, 0x03, 0xED, 0xC0, 0xDD, 0xF1, 0x47, 0xCF, 0xCB, 0x2E, 0x97, 0x20, + 0x92, 0x0D, 0x64, 0x85, 0xA5, 0x65, 0x43, 0x2C, 0x3C, 0x19, 0x10, 0x30, 0x94, 0x2F, 0x27, 0xBE, + 0x9D, 0x87, 0x78, 0xCE, 0x54, 0x47, 0xC0, 0x98, 0xC6, 0x9D, 0x39, 0x2F, 0xC6, 0xB2, 0xF1, 0x87, + 0x29, 0x96, 0x62, 0xC6, 0xB6, 0x69, 0xE2, 0xC0, 0x2B, 0x4A, 0x2C, 0x58, 0x49, 0x47, 0xDA, 0x11, + 0x6A, 0x69, 0xC0, 0xB8, 0x10, 0x22, 0x1F, 0xDC, 0x0A, 0xF4, 0x6D, 0x64, 0x02, 0x06, 0xB1, 0x04, + 0x28, 0x39, 0xBB, 0xA1, 0xDD, 0x49, 0x4C, 0xE9, 0xD4, 0xB9, 0x4D, 0x0A, 0xA2, 0x40, 0x81, 0x91, + 0x81, 0x68, 0x2E, 0x35, 0x43, 0xA0, 0xC0, 0x50, 0x05, 0x1F, 0x6A, 0x39, 0xB9, 0x65, 0x47, 0x4A, + 0xBF, 0xBC, 0xF4, 0xF0, 0x04, 0xE3, 0x98, 0xA1, 0x96, 0x02, 0x5B, 0x5E, 0x71, 0xA5, 0x53, 0xA8, + 0x4E, 0x68, 0x16, 0x2B, 0x01, 0xFC, 0x42, 0x29, 0x4A, 0x21, 0xF4, 0xE8, 0x87, 0x0A, 0xA5, 0x04, + 0xDA, 0xDC, 0x94, 0x95, 0x6A, 0x03, 0xC2, 0x5A, 0x6E, 0xF0, 0x66, 0xC8, 0x0E, 0xC0, 0x99, 0x20, + 0xDF, 0x16, 0x93, 0xAC, 0x91, 0x64, 0x16, 0x0B, 0xED, 0x14, 0x70, 0xF2, 0xC2, 0x6B, 0x75, 0x27, + 0x68, 0x81, 0xDA, 0x90, 0xB4, 0x0B, 0xDC, 0x74, 0xC8, 0x8B, 0x67, 0xB0, 0xBC, 0x75, 0x2B, 0xCC, + 0x5D, 0xA1, 0x00, 0xD8, 0x09, 0xC4, 0x3D, 0x23, 0x92, 0xB0, 0x6B, 0x29, 0xDA, 0x6A, 0x55, 0x12, + 0x46, 0x7A, 0x41, 0xA5, 0x81, 0xF8, 0x62, 0x25, 0xE8, 0x4E, 0x2A, 0x60, 0x22, 0x52, 0x05, 0xB4, + 0xB4, 0x94, 0x14, 0xAC, 0x12, 0x05, 0xBF, 0xCD, 0xB4, 0x60, 0xA7, 0x6F, 0x66, 0x65, 0xE7, 0x57, + 0xC7, 0xA3, 0xC8, 0x67, 0x85, 0x16, 0x5B, 0x49, 0xF0, 0x84, 0x2A, 0x48, 0x19, 0x92, 0x47, 0x30, + 0x4E, 0x00, 0x60, 0xC9, 0x57, 0x71, 0x79, 0x03, 0x51, 0x30, 0xD3, 0x4C, 0xA0, 0xC0, 0x4E, 0xA4, + 0x1C, 0x45, 0x51, 0x2C, 0x7E, 0x39, 0xB8, 0x18, 0x3E, 0x04, 0xB5, 0x04, 0x14, 0x6C, 0xB3, 0xF8, + 0xF1, 0xC7, 0x3C, 0x00, 0xAA, 0xC6, 0xCB, 0x45, 0xFC, 0x21, 0xD5, 0x52, 0x72, 0x17, 0x95, 0x88, + 0xD8, 0x09, 0x08, 0x00, 0x80, 0x00, 0x02, 0x28, 0x94, 0x28, 0xC1, 0x8C, 0x20, 0x20, 0xD1, 0x5D, + 0x02, 0x27, 0xE8, 0x88, 0x82, 0x5B, 0x84, 0x2C, 0xE0, 0xD6, 0x19, 0x4C, 0x1C, 0xA9, 0xA4, 0x19, + 0x1B, 0x44, 0x00, 0x00, 0x21, 0xFE, 0x19, 0x42, 0x6F, 0x79, 0x27, 0x73, 0x20, 0x48, 0x61, 0x70, + 0x70, 0x79, 0x20, 0x48, 0x6F, 0x6C, 0x69, 0x64, 0x61, 0x79, 0x73, 0x20, 0x50, 0x61, 0x67, 0x65, + 0x00, 0x3B + +}; + +static const uint8_t bird_img_gif[] PROGMEM = { + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x74, 0x00, 0x4E, 0x00, 0xCC, 0x13, 0x00, 0xFF, 0xFF, 0xFF, + 0xEF, 0xFF, 0xFF, 0xBD, 0xE7, 0xE7, 0xD6, 0xEF, 0xEF, 0x63, 0x63, 0x63, 0xAD, 0xAD, 0xAD, 0xCE, + 0xCE, 0xCE, 0xD6, 0xDE, 0xDE, 0x4A, 0x4A, 0x4A, 0x7B, 0x84, 0x84, 0x94, 0x9C, 0x9C, 0xE7, 0xE7, + 0xE7, 0x84, 0x94, 0x94, 0xB5, 0xC6, 0xC6, 0x73, 0x7B, 0x7B, 0x31, 0x31, 0x31, 0xF7, 0xF7, 0xF7, + 0x18, 0x10, 0x10, 0xCE, 0x63, 0x39, 0x6B, 0x39, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xFF, 0x0B, + 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x4B, + 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0xAE, 0xEC, 0x68, 0x2C, + 0x6D, 0x2C, 0xCF, 0x74, 0x6D, 0x03, 0x46, 0x84, 0x40, 0x77, 0xEF, 0xFF, 0x40, 0x51, 0x42, 0x41, + 0x0C, 0x1A, 0x8F, 0x48, 0x13, 0xC1, 0xD0, 0x20, 0x00, 0x0E, 0x8E, 0x42, 0x72, 0x4A, 0xAD, 0x21, + 0x0E, 0xCD, 0x05, 0xE1, 0x80, 0xA8, 0x7A, 0xBF, 0x29, 0xC2, 0xA0, 0x91, 0x28, 0x34, 0x02, 0x5D, + 0xB0, 0x5A, 0xFD, 0x08, 0x34, 0x14, 0x84, 0x00, 0x7A, 0x4D, 0xF7, 0x22, 0xDC, 0x89, 0xB8, 0xC1, + 0xB9, 0x80, 0xD5, 0xFF, 0x40, 0x0B, 0x77, 0x0C, 0x0F, 0x05, 0x01, 0x0C, 0x0A, 0x0B, 0x0F, 0x08, + 0x06, 0x80, 0x8E, 0x37, 0x7B, 0x01, 0x09, 0x11, 0x03, 0x68, 0x5C, 0x4C, 0x0A, 0x8F, 0x9A, 0x33, + 0x06, 0x09, 0x01, 0x0E, 0x71, 0x68, 0x88, 0x92, 0x07, 0x9B, 0xA6, 0x2C, 0x0A, 0x86, 0x07, 0x95, + 0x05, 0x04, 0xA1, 0x5D, 0x8D, 0xA7, 0xB2, 0x26, 0x09, 0x06, 0x72, 0x72, 0x0E, 0x94, 0x01, 0xA9, + 0x04, 0x08, 0x52, 0xB3, 0xC0, 0x00, 0x09, 0x95, 0xB7, 0x0D, 0x86, 0x01, 0x04, 0x0A, 0xC3, 0x09, + 0x34, 0x43, 0xC1, 0x54, 0x0E, 0xB7, 0xD2, 0x87, 0xAE, 0xBB, 0x99, 0x32, 0x7B, 0x0E, 0xCF, 0x49, + 0x0B, 0xD1, 0xD3, 0x72, 0x0C, 0xDE, 0x57, 0x33, 0xBE, 0xCC, 0xDB, 0x47, 0x05, 0x0C, 0xDF, 0xD3, + 0x05, 0xD7, 0x31, 0x0C, 0xE1, 0xA5, 0xE7, 0x46, 0xBE, 0xEB, 0xD2, 0x04, 0x05, 0xBF, 0x2C, 0x5C, + 0x4D, 0xF3, 0x46, 0x0B, 0x11, 0x56, 0xD9, 0x3B, 0x14, 0x01, 0x14, 0x0F, 0x16, 0x04, 0x1A, 0x30, + 0x28, 0x00, 0x81, 0xA1, 0x3F, 0x1F, 0xAD, 0x02, 0x10, 0x5B, 0x87, 0x6F, 0x0E, 0x8B, 0x02, 0x0E, + 0x04, 0x5C, 0x41, 0x10, 0xF0, 0x61, 0x8F, 0x25, 0x03, 0x26, 0xDA, 0x43, 0xC4, 0x42, 0x8B, 0x00, + 0x05, 0x0E, 0x7C, 0xFF, 0xED, 0xF0, 0x68, 0x83, 0x8B, 0x44, 0x91, 0xDF, 0x06, 0xAC, 0x54, 0x01, + 0x21, 0xA1, 0x80, 0x07, 0x0F, 0x1A, 0x38, 0x70, 0xC7, 0x72, 0x46, 0xC2, 0x97, 0x03, 0x3F, 0xC5, + 0x52, 0xE1, 0x80, 0x81, 0x00, 0x01, 0x19, 0x1B, 0x3C, 0x38, 0xD8, 0x53, 0xC6, 0x81, 0x38, 0x21, + 0x61, 0x4A, 0xEB, 0xB7, 0x42, 0x01, 0x82, 0xA3, 0x58, 0x7D, 0xC9, 0x6B, 0x1A, 0x63, 0x0B, 0xD0, + 0x81, 0x11, 0x08, 0x74, 0x44, 0x61, 0xE0, 0x01, 0xD6, 0xA3, 0x05, 0x16, 0x2D, 0xE5, 0xDA, 0xC2, + 0x80, 0xB7, 0x90, 0x41, 0xCB, 0xA4, 0x39, 0xC1, 0xEF, 0x2C, 0x56, 0xAA, 0x6C, 0x57, 0x38, 0xA8, + 0x14, 0x35, 0xA8, 0x35, 0x14, 0x10, 0x10, 0x34, 0xB0, 0x9B, 0xD5, 0x4F, 0xDE, 0x14, 0x06, 0x8E, + 0xF5, 0x1D, 0xC8, 0x25, 0x85, 0x83, 0xC1, 0x84, 0x05, 0x20, 0x32, 0x30, 0xF4, 0x30, 0x2D, 0x39, + 0x8B, 0x07, 0x32, 0x42, 0xA1, 0x00, 0x72, 0xE4, 0x45, 0x08, 0x7C, 0x59, 0x36, 0x91, 0x18, 0x73, + 0xE6, 0x6F, 0x79, 0x38, 0x2B, 0x88, 0x7C, 0x54, 0xE7, 0xE0, 0x2D, 0xA3, 0x4B, 0x78, 0x7A, 0x79, + 0x7A, 0x1A, 0xCE, 0x04, 0x4C, 0x85, 0xAC, 0x66, 0x7D, 0x96, 0x80, 0xB9, 0xD8, 0x22, 0x4A, 0x4B, + 0x14, 0x00, 0x97, 0xF1, 0xD3, 0x12, 0x3B, 0x79, 0x9F, 0x45, 0xC0, 0x13, 0xB8, 0xB7, 0xE1, 0xC5, + 0x19, 0x33, 0xEB, 0x53, 0xD3, 0xA8, 0x72, 0x01, 0x0D, 0x44, 0x97, 0x5C, 0x90, 0x7B, 0x9B, 0x01, + 0x05, 0xA6, 0x89, 0xFB, 0x3D, 0x54, 0x20, 0x81, 0xDA, 0x8C, 0xD7, 0x91, 0x16, 0x22, 0x91, 0xF8, + 0x80, 0x9F, 0x86, 0x08, 0x1E, 0xF4, 0xF2, 0xD5, 0x7D, 0x96, 0x18, 0xCC, 0x47, 0xA3, 0xDB, 0x7B, + 0xCA, 0x60, 0x40, 0xCA, 0xF4, 0x58, 0x81, 0xE2, 0x42, 0x04, 0x11, 0x4C, 0x80, 0x53, 0x7C, 0x3F, + 0xC9, 0xB1, 0xC7, 0xFF, 0x7A, 0xC1, 0x18, 0xA0, 0x0E, 0x7E, 0xC4, 0x49, 0xA5, 0x99, 0x67, 0xD7, + 0xA5, 0xB4, 0x15, 0x04, 0x93, 0x48, 0xA0, 0xA1, 0x81, 0x7C, 0x49, 0xB3, 0xC7, 0x38, 0xF6, 0x11, + 0x13, 0x52, 0x7E, 0x12, 0xAE, 0x63, 0xC0, 0x55, 0x00, 0x82, 0x62, 0xD8, 0x08, 0x0B, 0x24, 0xA0, + 0xA1, 0x86, 0x57, 0x3C, 0xF0, 0xE0, 0x2D, 0x05, 0x68, 0x67, 0x4A, 0x27, 0xB7, 0x0C, 0x80, 0x95, + 0x7E, 0x41, 0x11, 0x80, 0x5E, 0x85, 0xBF, 0x9D, 0xD0, 0xC0, 0x04, 0x2F, 0x2E, 0x62, 0xCB, 0x34, + 0x03, 0xE4, 0xB1, 0xA2, 0x23, 0x5E, 0x41, 0xC8, 0x63, 0x50, 0x0E, 0x9A, 0x75, 0x5D, 0x68, 0x5B, + 0x9D, 0xA0, 0x45, 0x04, 0x38, 0x2D, 0x72, 0xCC, 0x34, 0x7B, 0x24, 0xF2, 0x88, 0x5B, 0x39, 0xEA, + 0x18, 0xE1, 0x78, 0xD2, 0x58, 0x05, 0x20, 0x6C, 0x2B, 0xD4, 0x78, 0x64, 0x89, 0x6E, 0xB8, 0xF2, + 0xC2, 0x1F, 0x4D, 0xBE, 0x44, 0x22, 0x99, 0x72, 0xE4, 0x01, 0x60, 0x19, 0x31, 0x68, 0xB1, 0xC4, + 0x78, 0x50, 0xF4, 0xE2, 0x9B, 0x43, 0x5E, 0x80, 0x99, 0xE3, 0x8E, 0x6C, 0x4E, 0xE3, 0x63, 0x7A, + 0xD9, 0x55, 0xD6, 0x82, 0x4E, 0x04, 0x30, 0xD0, 0xC0, 0x01, 0x7C, 0x2A, 0xE4, 0xA3, 0xA2, 0x47, + 0xDC, 0x37, 0xE8, 0x9C, 0xE3, 0xC9, 0x64, 0x9D, 0x72, 0x70, 0x54, 0x29, 0x03, 0x04, 0xDF, 0xE5, + 0xE1, 0x4A, 0x19, 0x06, 0xB0, 0xD9, 0xC4, 0x66, 0x48, 0x7C, 0x27, 0xCD, 0x88, 0x98, 0x92, 0x89, + 0xE2, 0x75, 0x69, 0x2D, 0x69, 0xC3, 0x02, 0x07, 0xA4, 0x03, 0x8A, 0x2B, 0x8E, 0xC2, 0x04, 0x05, + 0x03, 0x48, 0x3C, 0x17, 0x5E, 0xAB, 0x7E, 0x61, 0x04, 0x20, 0x03, 0x33, 0x21, 0x01, 0xC1, 0x02, + 0xDF, 0x81, 0x52, 0x8B, 0x34, 0xAD, 0xC8, 0x6A, 0x43, 0x3E, 0x48, 0x9E, 0xF5, 0x24, 0x45, 0xAF, + 0xF2, 0x96, 0x9D, 0xFF, 0x03, 0xF5, 0x51, 0xD1, 0xA2, 0x03, 0x90, 0xCA, 0xF1, 0x94, 0x3E, 0x37, + 0x68, 0x81, 0xA4, 0x98, 0xC0, 0x9A, 0xF8, 0xC0, 0x8F, 0xCA, 0x39, 0xA0, 0xCD, 0x1F, 0x0B, 0x10, + 0x21, 0x0D, 0x03, 0xB8, 0x7D, 0x74, 0x64, 0x98, 0xD2, 0x16, 0x8A, 0x0C, 0xBA, 0xCA, 0x29, 0xF5, + 0x48, 0x8B, 0x53, 0xA1, 0x19, 0x03, 0xA8, 0x18, 0x85, 0xB2, 0x2A, 0xB9, 0x63, 0x06, 0x45, 0x06, + 0x80, 0x48, 0x05, 0xC9, 0x6E, 0x9C, 0x4F, 0xE1, 0xA3, 0xC2, 0x77, 0xF0, 0x16, 0x95, 0x4B, 0xB7, + 0xF4, 0x12, 0xEA, 0x57, 0x59, 0x14, 0xB2, 0x46, 0x08, 0xB8, 0x8E, 0x08, 0x72, 0x06, 0xB3, 0x3E, + 0xA6, 0xF2, 0x28, 0x46, 0x8B, 0x2C, 0xEB, 0xED, 0x03, 0xF3, 0x56, 0x5C, 0xF0, 0x40, 0xE6, 0xED, + 0xA6, 0x9C, 0x7C, 0xD9, 0x02, 0xA2, 0x48, 0xCA, 0x98, 0x25, 0xD6, 0xCE, 0x4E, 0x14, 0x2B, 0x18, + 0xE7, 0xC0, 0xE5, 0xAE, 0x93, 0x00, 0xC2, 0x45, 0x01, 0xB3, 0xC0, 0x8C, 0x74, 0xFA, 0xF7, 0x80, + 0x84, 0xAC, 0xAE, 0x6C, 0xCF, 0x00, 0x04, 0xA4, 0x47, 0x2C, 0x02, 0xCE, 0x6A, 0xF2, 0x06, 0x9D, + 0x98, 0xE5, 0x3C, 0xB0, 0x98, 0xB5, 0x4D, 0xD3, 0x40, 0x04, 0x05, 0x28, 0x57, 0x40, 0x04, 0x0A, + 0x50, 0x2A, 0x4B, 0x02, 0x1F, 0x53, 0xBD, 0x74, 0x54, 0x59, 0xBF, 0x1B, 0x5A, 0x41, 0xAC, 0x65, + 0xA7, 0xF0, 0x33, 0x0C, 0x58, 0x6D, 0xB6, 0x69, 0x68, 0x4F, 0x2B, 0x87, 0x55, 0xB7, 0x38, 0x50, + 0xC8, 0x5D, 0x7E, 0x8A, 0x1D, 0x0C, 0x04, 0x8F, 0xCD, 0x1D, 0x94, 0xDD, 0x4F, 0xA1, 0xEC, 0xA1, + 0x7C, 0xAD, 0x8D, 0xC5, 0x52, 0x4D, 0xBE, 0x0A, 0x3E, 0x9E, 0x55, 0x32, 0xDA, 0xA3, 0x37, 0x03, + 0xBD, 0x44, 0x3D, 0x8F, 0x55, 0x34, 0x3B, 0x6E, 0x4F, 0x03, 0x99, 0x73, 0x89, 0x93, 0xE5, 0xFE, + 0x74, 0x13, 0xB7, 0xCB, 0xE6, 0xA4, 0x4B, 0x63, 0x90, 0x65, 0xED, 0x16, 0x25, 0x77, 0xE9, 0x54, + 0x67, 0x11, 0xDB, 0x89, 0x44, 0xB3, 0x6E, 0xF6, 0x89, 0x7E, 0x37, 0x05, 0x47, 0xE7, 0xB2, 0xFB, + 0xF5, 0x2D, 0x70, 0xDD, 0x80, 0x37, 0xDE, 0x0A, 0x8E, 0xFB, 0x06, 0x1C, 0x00, 0x4D, 0xE0, 0x1E, + 0x80, 0x0C, 0x73, 0xFB, 0x47, 0x00, 0xE8, 0x2C, 0x89, 0x6E, 0xCF, 0x0C, 0x66, 0x87, 0x64, 0x55, + 0x73, 0x87, 0xB5, 0xD2, 0x39, 0xF2, 0x54, 0xA3, 0xAD, 0x24, 0xEF, 0x09, 0xC4, 0x2E, 0x47, 0x0C, + 0x83, 0x4F, 0x44, 0x6E, 0x25, 0xA9, 0x0C, 0x8F, 0x43, 0xE0, 0xD3, 0xB4, 0x30, 0x50, 0x54, 0xF9, + 0x41, 0x57, 0xC9, 0x63, 0xE6, 0x03, 0x00, 0xC1, 0xED, 0xE9, 0xAB, 0x60, 0x4F, 0x62, 0x94, 0x41, + 0x2A, 0xFE, 0x01, 0x56, 0x11, 0x10, 0xB3, 0x65, 0x4F, 0x11, 0xCC, 0x37, 0x4A, 0x10, 0x2C, 0x8E, + 0x3C, 0x80, 0x40, 0x3A, 0x30, 0x20, 0x02, 0x96, 0x10, 0x3F, 0x13, 0x64, 0xA7, 0x1E, 0x17, 0x53, + 0x90, 0x02, 0x28, 0x87, 0x00, 0xB2, 0xC1, 0xE0, 0x29, 0x08, 0x24, 0x50, 0xC9, 0xFE, 0x37, 0x3C, + 0x28, 0x30, 0x67, 0x75, 0x01, 0x9C, 0x20, 0x4E, 0x0A, 0xE0, 0xAC, 0xAF, 0x21, 0x90, 0x3E, 0x0D, + 0x4C, 0x41, 0xBB, 0x42, 0x13, 0x05, 0x63, 0xA4, 0x64, 0x81, 0x43, 0x28, 0x40, 0xED, 0x44, 0x00, + 0x01, 0x2C, 0x78, 0x29, 0x85, 0x2C, 0x38, 0x56, 0x62, 0x1A, 0xC0, 0x1D, 0x35, 0x84, 0x00, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, + 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, + 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, + 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, + 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, + 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, + 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, + 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, + 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, + 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, + 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, + 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, + 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, + 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, + 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, + 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, + 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, + 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, + 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, + 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, + 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, + 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, + 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, + 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, + 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, + 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, + 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, + 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, + 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, + 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, + 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, + 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, + 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, + 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, + 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, + 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, + 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, + 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, + 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, + 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, + 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, + 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, + 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, + 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, + 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, + 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, + 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, + 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, + 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, + 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, + 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, + 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, + 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, + 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, + 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, + 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, + 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, + 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, + 0x0D, 0x21, 0x00, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, + 0x00, 0x6A, 0x00, 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, + 0xAE, 0x6C, 0xEB, 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, + 0x0A, 0xC7, 0x03, 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, + 0xA4, 0x10, 0xA8, 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, + 0x9E, 0x18, 0x02, 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, + 0xD4, 0x81, 0x01, 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, + 0x0D, 0x08, 0x05, 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, + 0x04, 0x06, 0x10, 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, + 0x93, 0x09, 0x0C, 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, + 0x0C, 0x39, 0x9A, 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, + 0xAB, 0x5B, 0x4A, 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, + 0x0D, 0x0D, 0x07, 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, + 0x0E, 0x7B, 0x04, 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, + 0x92, 0x0C, 0x0E, 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, + 0x5B, 0x03, 0x0E, 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, + 0x98, 0xBE, 0x73, 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, + 0xB0, 0x6A, 0xA3, 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, + 0xBC, 0xA5, 0x0C, 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, + 0x04, 0x32, 0x53, 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, + 0x67, 0x8E, 0xA2, 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, + 0x33, 0xA0, 0x2B, 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, + 0x0E, 0x10, 0xC0, 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, + 0x0A, 0x08, 0xF8, 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, + 0x1D, 0x8A, 0x47, 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, + 0x22, 0x22, 0x82, 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, + 0x6B, 0x50, 0xE0, 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, + 0xA3, 0x2D, 0x60, 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, + 0x94, 0x14, 0x7F, 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, + 0x05, 0x30, 0x4A, 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, + 0x53, 0x20, 0xC1, 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, + 0x10, 0x03, 0x80, 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, + 0x26, 0x0F, 0x28, 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, + 0xC6, 0x0A, 0x02, 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, + 0xA0, 0xC0, 0x28, 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, + 0x42, 0x01, 0x5A, 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, + 0x88, 0x33, 0x14, 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, + 0x6A, 0xC4, 0x80, 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, + 0x28, 0xC2, 0xE2, 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, + 0x21, 0xA4, 0x0C, 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, + 0x4A, 0x93, 0x29, 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, + 0x94, 0x0C, 0x38, 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, + 0x56, 0x74, 0x54, 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, + 0x99, 0x83, 0x8A, 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, + 0x10, 0x02, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, + 0x6A, 0x00, 0x2E, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x00, 0x40, 0x62, 0xB9, 0x28, 0x08, 0x41, 0x28, + 0x4B, 0xE9, 0xBE, 0x70, 0x2C, 0xCF, 0x74, 0x6D, 0xDF, 0xE5, 0xF1, 0x3C, 0x69, 0x52, 0x24, 0x0F, + 0x82, 0xE1, 0x60, 0x00, 0x26, 0x5A, 0xB8, 0xA4, 0x72, 0xC9, 0x94, 0xE9, 0x22, 0x12, 0xC9, 0x64, + 0xF2, 0x18, 0x04, 0xAE, 0xD7, 0x01, 0xB0, 0xD0, 0xEC, 0x7A, 0xBF, 0x31, 0x48, 0x61, 0x12, 0x95, + 0x32, 0x02, 0x8E, 0x06, 0x36, 0x70, 0x50, 0x21, 0xC1, 0xF0, 0x78, 0x72, 0x91, 0x20, 0x4B, 0x55, + 0x85, 0xF5, 0xB5, 0x81, 0xE0, 0xCA, 0xFF, 0x80, 0x32, 0x0D, 0x0F, 0x53, 0x11, 0x11, 0x04, 0x07, + 0x7A, 0x57, 0x0E, 0x04, 0x6F, 0x81, 0x8F, 0x7F, 0x0B, 0x2A, 0x06, 0x94, 0x6A, 0x8A, 0x01, 0x06, + 0x04, 0x05, 0x07, 0x0B, 0x0B, 0x44, 0x94, 0xA0, 0x43, 0x24, 0x90, 0xA4, 0x37, 0x05, 0x04, 0x96, + 0x97, 0x58, 0x45, 0x09, 0x0A, 0x0C, 0x0C, 0x0A, 0x05, 0x0D, 0xB3, 0x05, 0x0A, 0x09, 0x0C, 0x05, + 0x06, 0xA3, 0x4D, 0x9F, 0xA0, 0x0B, 0xBB, 0xA5, 0x33, 0x6D, 0x08, 0x0C, 0x89, 0xAA, 0xC7, 0x8A, + 0x07, 0xAE, 0x3E, 0xC0, 0x32, 0x10, 0x07, 0x3F, 0x2A, 0x0E, 0x8C, 0x2A, 0x08, 0xD6, 0x29, 0x0E, + 0xB9, 0xCD, 0xC1, 0x22, 0x10, 0x45, 0xD2, 0xB8, 0x07, 0x56, 0x97, 0x22, 0xC8, 0x01, 0x0D, 0x0C, + 0x3E, 0x9C, 0x25, 0xCF, 0xA7, 0x04, 0xD9, 0xE2, 0xC8, 0x03, 0xD0, 0x09, 0x04, 0xD6, 0x09, 0xBA, + 0xDC, 0x30, 0x10, 0x0B, 0x06, 0xB6, 0x2A, 0x04, 0x12, 0xDC, 0x52, 0x40, 0x90, 0x60, 0x81, 0x5C, + 0x07, 0x20, 0xA8, 0x1A, 0xD0, 0x20, 0x01, 0x35, 0x07, 0x3C, 0x1C, 0x18, 0x30, 0x87, 0xCC, 0x00, + 0x03, 0x02, 0x0F, 0x12, 0x34, 0xD8, 0xA6, 0xCF, 0x44, 0xA7, 0x8F, 0x9D, 0x0E, 0x88, 0xAC, 0x75, + 0x6B, 0x22, 0xC5, 0x4B, 0x44, 0x4E, 0xFF, 0x26, 0x63, 0x80, 0x20, 0xE3, 0x81, 0x8E, 0x5D, 0x0E, + 0xA4, 0x33, 0xA6, 0x92, 0x8D, 0x03, 0x04, 0x35, 0x2F, 0x35, 0xC0, 0x98, 0xE0, 0x25, 0x4C, 0x26, + 0x07, 0x7C, 0xE4, 0xBC, 0x82, 0x40, 0xE1, 0x50, 0x3D, 0xCA, 0x52, 0x38, 0xFA, 0x89, 0xE3, 0x47, + 0xCE, 0x1F, 0x00, 0x8E, 0xAA, 0x02, 0xC2, 0x80, 0xE9, 0x92, 0x86, 0x2A, 0x0D, 0x3C, 0xA0, 0x29, + 0x55, 0xD1, 0x00, 0x8C, 0x06, 0xAC, 0x26, 0x31, 0x80, 0xC0, 0x24, 0x32, 0x04, 0x09, 0xBA, 0x9A, + 0x1B, 0x94, 0x80, 0xA3, 0x58, 0x18, 0x5A, 0xCF, 0x1C, 0x13, 0x78, 0x69, 0x9C, 0xDA, 0x2C, 0x04, + 0x22, 0x34, 0x78, 0x6B, 0x03, 0x82, 0x02, 0x44, 0x97, 0x5E, 0xD5, 0x1D, 0x60, 0xF7, 0xEE, 0xB9, + 0x07, 0x61, 0xF9, 0xD6, 0x58, 0xC0, 0x20, 0xDB, 0x1A, 0x82, 0x0B, 0x09, 0x17, 0xBE, 0xFB, 0x55, + 0x81, 0xE2, 0x1B, 0x99, 0x10, 0x39, 0xF6, 0x2A, 0x99, 0xB0, 0x61, 0x3D, 0x0E, 0x2F, 0xDF, 0x18, + 0x94, 0x87, 0xF3, 0x00, 0x01, 0x02, 0x24, 0x7F, 0x7E, 0x8C, 0x60, 0xA9, 0x68, 0x17, 0x6D, 0xCC, + 0x62, 0x91, 0x8C, 0x1A, 0x75, 0xE7, 0x2B, 0x30, 0xBA, 0xF2, 0xF1, 0xF9, 0xDA, 0x45, 0x26, 0xAE, + 0x59, 0x4E, 0xD7, 0x4E, 0xED, 0x19, 0xF7, 0x8C, 0xA3, 0x5A, 0xF7, 0xF6, 0x16, 0xF1, 0xC3, 0x68, + 0x70, 0xE1, 0xC3, 0x8B, 0xAF, 0xA1, 0x31, 0xF4, 0xB4, 0xD2, 0xD7, 0x10, 0x60, 0xE9, 0x21, 0x3C, + 0x3C, 0xFA, 0x64, 0xE3, 0x32, 0x6A, 0xD2, 0x56, 0xF0, 0xC0, 0x0F, 0x5F, 0x3A, 0xA9, 0x02, 0x70, + 0xEF, 0x4E, 0x5C, 0x3A, 0x68, 0xD7, 0xE5, 0x54, 0x72, 0xB7, 0xF2, 0xD5, 0xBC, 0xD5, 0xA0, 0x34, + 0xD7, 0xDB, 0x6E, 0xAF, 0x5A, 0x95, 0x03, 0xDE, 0x2F, 0x98, 0x73, 0xDB, 0x70, 0x01, 0xC4, 0xF2, + 0x96, 0x45, 0xB3, 0x41, 0x67, 0x5B, 0xFF, 0x7F, 0xE6, 0x00, 0x20, 0x51, 0x0C, 0xF2, 0xD0, 0x47, + 0x9C, 0x7A, 0xEA, 0x91, 0x07, 0x20, 0x4C, 0x05, 0xC8, 0xA5, 0x9E, 0x70, 0xA7, 0x31, 0x78, 0x92, + 0x24, 0x89, 0xB9, 0x70, 0x4C, 0x26, 0x41, 0x04, 0xA4, 0x40, 0x03, 0x19, 0x32, 0x72, 0xC8, 0x85, + 0x1D, 0xB9, 0x92, 0x20, 0x7F, 0xEE, 0x9D, 0x94, 0xE1, 0x49, 0x0C, 0xDD, 0x84, 0x16, 0x79, 0x11, + 0xF4, 0x11, 0x0B, 0x42, 0x62, 0x41, 0x70, 0xCB, 0x73, 0x1E, 0x0E, 0xE5, 0x20, 0x70, 0x7B, 0x10, + 0x40, 0x58, 0x5E, 0xC4, 0xE4, 0x23, 0x42, 0x02, 0x86, 0x34, 0xA2, 0x98, 0x24, 0x0A, 0x00, 0x19, + 0x63, 0x4E, 0xFD, 0x10, 0x43, 0x93, 0x32, 0x79, 0xF1, 0x90, 0x42, 0x88, 0x2E, 0x2C, 0xF0, 0x80, + 0x21, 0x0F, 0x30, 0x00, 0x5F, 0x30, 0x62, 0xF4, 0xB1, 0x61, 0x90, 0x47, 0x39, 0x18, 0xCB, 0x3F, + 0xEF, 0xF8, 0x60, 0xC0, 0x2F, 0x36, 0x3C, 0xB1, 0x22, 0x53, 0x99, 0x20, 0x90, 0x08, 0x9A, 0x5D, + 0x79, 0xD9, 0x80, 0x00, 0x29, 0xB4, 0xD6, 0x04, 0x59, 0x2C, 0xFC, 0x24, 0x13, 0x2A, 0x78, 0x76, + 0xF5, 0x95, 0x03, 0x0C, 0xA0, 0xA6, 0xA3, 0x17, 0x6E, 0x3D, 0xB2, 0xC0, 0x0F, 0x0A, 0x10, 0xB9, + 0xDA, 0x39, 0x08, 0x08, 0x90, 0x86, 0x00, 0x4E, 0x2E, 0x17, 0x86, 0x3B, 0xA5, 0x4D, 0xAA, 0x87, + 0x42, 0xAF, 0x0C, 0xE2, 0x00, 0xA6, 0x63, 0x8A, 0xF6, 0xA8, 0x0A, 0x91, 0x06, 0xF0, 0x4B, 0x9E, + 0xCE, 0x29, 0xF2, 0x17, 0x4B, 0x96, 0x16, 0x50, 0xA9, 0x9F, 0x9A, 0x02, 0x50, 0x00, 0x23, 0x81, + 0x9E, 0x1A, 0x41, 0x94, 0x47, 0x31, 0x10, 0xE6, 0x01, 0xD3, 0x98, 0xA5, 0x10, 0x2A, 0x2D, 0xF1, + 0x21, 0x46, 0x40, 0xB5, 0xDA, 0x8A, 0xD8, 0x02, 0x0D, 0x21, 0x9A, 0x80, 0x99, 0x98, 0xE0, 0x63, + 0xCE, 0x10, 0x01, 0xC8, 0x7A, 0xC2, 0x79, 0x11, 0x50, 0x65, 0x26, 0x2B, 0x9F, 0x64, 0xF9, 0xD1, + 0xE8, 0x93, 0x29, 0x32, 0x30, 0x84, 0x03, 0x0A, 0x28, 0x04, 0x2C, 0x46, 0x0B, 0x5C, 0x91, 0xAE, + 0x22, 0x64, 0x21, 0xB0, 0x13, 0x30, 0x99, 0xDC, 0xB4, 0xD3, 0xB3, 0xE9, 0x00, 0x50, 0x6A, 0xB2, + 0x00, 0xB4, 0xD1, 0x42, 0x50, 0x42, 0x00, 0xF6, 0x55, 0x51, 0xAA, 0x6A, 0x82, 0x09, 0x22, 0x08, + 0x38, 0xB0, 0x4D, 0xB7, 0x88, 0x2C, 0x60, 0x0D, 0x8B, 0xF8, 0xBE, 0x90, 0x89, 0x02, 0x0E, 0xE0, + 0x03, 0x81, 0xC0, 0x99, 0xDC, 0xAA, 0x2A, 0x44, 0xB3, 0xF8, 0xE9, 0x16, 0x04, 0x08, 0xD8, 0xC2, + 0x1C, 0x97, 0x0D, 0xCB, 0xE0, 0xC9, 0x28, 0x3A, 0x28, 0xF3, 0x5F, 0x6B, 0xBF, 0xD9, 0x72, 0xC4, + 0x62, 0x1D, 0x7F, 0x1B, 0x72, 0x0D, 0xCA, 0xBC, 0xD4, 0x86, 0x2D, 0x3E, 0xB9, 0xBC, 0x5C, 0x08, + 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, 0x6A, 0x00, + 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, 0xAE, 0x6C, 0xEB, + 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, 0x0A, 0xC7, 0x03, + 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, 0xA4, 0x10, 0xA8, + 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, 0x9E, 0x18, 0x02, + 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, 0xD4, 0x81, 0x01, + 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, 0x0D, 0x08, 0x05, + 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, 0x04, 0x06, 0x10, + 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, 0x93, 0x09, 0x0C, + 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, 0x0C, 0x39, 0x9A, + 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, 0xAB, 0x5B, 0x4A, + 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, 0x0D, 0x0D, 0x07, + 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, 0x0E, 0x7B, 0x04, + 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, 0x92, 0x0C, 0x0E, + 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, 0x5B, 0x03, 0x0E, + 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, 0x98, 0xBE, 0x73, + 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, 0xB0, 0x6A, 0xA3, + 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, 0xBC, 0xA5, 0x0C, + 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, 0x04, 0x32, 0x53, + 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, 0x67, 0x8E, 0xA2, + 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, 0x33, 0xA0, 0x2B, + 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, 0x0E, 0x10, 0xC0, + 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, 0x0A, 0x08, 0xF8, + 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, 0x1D, 0x8A, 0x47, + 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, 0x22, 0x22, 0x82, + 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, 0x6B, 0x50, 0xE0, + 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, 0xA3, 0x2D, 0x60, + 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, 0x94, 0x14, 0x7F, + 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, 0x05, 0x30, 0x4A, + 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, 0x53, 0x20, 0xC1, + 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, 0x10, 0x03, 0x80, + 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, 0x26, 0x0F, 0x28, + 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, 0xC6, 0x0A, 0x02, + 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, 0xA0, 0xC0, 0x28, + 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, 0x42, 0x01, 0x5A, + 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, 0x88, 0x33, 0x14, + 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, 0x6A, 0xC4, 0x80, + 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, 0x28, 0xC2, 0xE2, + 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, 0x21, 0xA4, 0x0C, + 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, 0x4A, 0x93, 0x29, + 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, 0x94, 0x0C, 0x38, + 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, 0x56, 0x74, 0x54, + 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, 0x99, 0x83, 0x8A, + 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, 0x10, 0x02, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, + 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, + 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, + 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, + 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, + 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, + 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, + 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, + 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, + 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, + 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, + 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, + 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, + 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, + 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, + 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, + 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, + 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, + 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, + 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, + 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, + 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, + 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, + 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, + 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, + 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, + 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, + 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, + 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, + 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, + 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, + 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, + 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, + 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, + 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, + 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, + 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, + 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, + 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, + 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, + 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, + 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, + 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, + 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, + 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, + 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, + 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, + 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, + 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, + 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, + 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, + 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, + 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, + 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, + 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, + 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, + 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, + 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, + 0x0D, 0x21, 0x00, 0x00, 0x3B}; diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_File/Send_Attachment_File.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_File/Send_Attachment_File.ino new file mode 100644 index 000000000000..d615e9f3a245 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_File/Send_Attachment_File.ino @@ -0,0 +1,443 @@ + + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email with attachments and inline images stored in SD card. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// Provide the SD card interfaces setting and mounting +#include + +// To use only SMTP functions, you can exclude the IMAP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h + + Serial.println("Preparing SD file attachments..."); + + const char *orangeImg = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAoUlEQVR42u3RMQ0AMAgAsCFgftHLiQpsENJaaFT+fqwRQoQgRAhChCBECEKECBGCECEIEYIQIQgRghCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCBGCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQghAhCBGCECEIEYIQIUKEIEQIQoQg5LoBGi/oCaOpTXoAAAAASUVORK5CYII="; + + // Write demo data to file + + static uint8_t buf[512]; + +// SDFat? +#if defined(ESP_MAIL_USE_SDFAT) // ESP_MAIL_USE_SDFAT is auto defined when you set to use SdFat in src/ESP_Mail_FS.h + SdFile file; + file.open("/orange.png", O_RDWR | O_CREAT); + file.print(orangeImg); + file.close(); + + file.open("/bin1.dat", O_RDWR | O_CREAT); + buf[0] = 'H'; + buf[1] = 'E'; + buf[2] = 'A'; + buf[3] = 'D'; + file.write(buf, 4); + + size_t i; + + for (i = 0; i < 4; i++) + { + memset(buf, i + 1, 512); + file.write(buf, 512); + } + + buf[0] = 'T'; + buf[1] = 'A'; + buf[2] = 'I'; + buf[3] = 'L'; + file.write(buf, 4); + file.close(); + +#else + +#if defined(ESP32) + File file = ESP_MAIL_DEFAULT_SD_FS.open("/orange.png", FILE_WRITE); +#else + File file = ESP_MAIL_DEFAULT_SD_FS.open("/orange.png", "w"); +#endif + file.print(orangeImg); + file.close(); + +#if defined(ESP32) + file = ESP_MAIL_DEFAULT_SD_FS.open("/bin1.dat", FILE_WRITE); +#else + file = ESP_MAIL_DEFAULT_SD_FS.open("/bin1.dat", "w"); +#endif + + buf[0] = 'H'; + buf[1] = 'E'; + buf[2] = 'A'; + buf[3] = 'D'; + file.write(buf, 4); + + size_t i; + + for (i = 0; i < 4; i++) + { + memset(buf, i + 1, 512); + file.write(buf, 512); + } + + buf[0] = 'T'; + buf[1] = 'A'; + buf[2] = 'I'; + buf[3] = 'L'; + file.write(buf, 4); + file.close(); +#endif + +#endif + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Enable the chunked data transfer with pipelining for large message if server supported */ + message.enable.chunking = true; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + message.subject = F("Test sending Email with attachments and inline images from SD card and Flash"); + + message.addRecipient(F("user1"), RECIPIENT_EMAIL); + + /** Two alternative content versions are sending in this example e.g. plain text and html */ + String htmlMsg = "This message contains 1 inline image and 1 attachment file.

"; + + message.html.content = htmlMsg; + + /** The HTML text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; + + message.text.content = F("This message contains 1 inline image and 1 attachment file.\r\nThe inline image will not show in the plain text message."); + + message.text.charSet = F("utf-8"); + message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* The attachment data item */ + SMTP_Attachment att[2]; + int attIndex = 0; + + /** Set the inline image info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + att[attIndex].descr.filename = F("orange.png"); + att[attIndex].descr.mime = F("image/png"); + att[attIndex].file.path = F("/orange.png"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + att[attIndex].file.storage_type = esp_mail_file_storage_type_sd; + + /* Need to be base64 transfer encoding for inline image */ + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The orange.png file is already base64 encoded file. + * Then set the content encoding to match the transfer encoding + * which no encoding was taken place prior to sending. + */ + att[attIndex].descr.content_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att[attIndex]); + + /** Set the attachment info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + + attIndex++; + att[attIndex].descr.filename = F("bin1.dat"); + att[attIndex].descr.mime = F("application/octet-stream"); // binary data + att[attIndex].descr.description = F("This is binary data"); + att[attIndex].file.path = F("/bin1.dat"); + att[attIndex].file.storage_type = esp_mail_file_storage_type_sd; + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add attachment to the message */ + message.addAttachment(att[attIndex]); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending the Email and close the session */ + if (!MailClient.sendMail(&smtp, &message, true)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Flash/Send_Attachment_Flash.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Flash/Send_Attachment_Flash.ino new file mode 100644 index 000000000000..49ef4f54f290 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Flash/Send_Attachment_Flash.ino @@ -0,0 +1,411 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email with attachments and inline images stored in SPIFFS/LittleFS filesystem. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only SMTP functions, you can exclude the IMAP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_FLASH_FS) // defined in src/ESP_Mail_FS.h + + // Mount SPIFFS/LittleFS filesystem. + ESP_MAIL_DEFAULT_FLASH_FS.begin(); + + Serial.println("Preparing flash file attachments..."); + + const char *orangeImg = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAoUlEQVR42u3RMQ0AMAgAsCFgftHLiQpsENJaaFT+fqwRQoQgRAhChCBECEKECBGCECEIEYIQIQgRghCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCBGCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQghAhCBGCECEIEYIQIUKEIEQIQoQg5LoBGi/oCaOpTXoAAAAASUVORK5CYII="; + + // Write demo data to file + + static uint8_t buf[512]; + +#if defined(ESP32) + File file = ESP_MAIL_DEFAULT_FLASH_FS.open("/orange.png", FILE_WRITE); +#else + File file = ESP_MAIL_DEFAULT_FLASH_FS.open("/orange.png", "w"); +#endif + + file.print(orangeImg); + file.close(); + +#if defined(ESP32) + file = ESP_MAIL_DEFAULT_FLASH_FS.open("/bin1.dat", FILE_WRITE); +#else + file = ESP_MAIL_DEFAULT_FLASH_FS.open("/bin1.dat", "w"); +#endif + + buf[0] = 'H'; + buf[1] = 'E'; + buf[2] = 'A'; + buf[3] = 'D'; + file.write(buf, 4); + + size_t i; + + for (i = 0; i < 4; i++) + { + memset(buf, i + 1, 512); + file.write(buf, 512); + } + + buf[0] = 'T'; + buf[1] = 'A'; + buf[2] = 'I'; + buf[3] = 'L'; + file.write(buf, 4); + file.close(); + +#endif + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Enable the chunked data transfer with pipelining for large message if server supported */ + message.enable.chunking = true; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + message.subject = F("Test sending Email with attachments and inline images from flash filesystem"); + + message.addRecipient(F("user1"), RECIPIENT_EMAIL); + + /** Two alternative content versions are sending in this example e.g. plain text and html */ + String htmlMsg = "This message contains 1 inline image and 1 attachment file.

"; + + message.html.content = htmlMsg; + + /** The HTML text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; + + message.text.content = F("This message contains 1 inline image and 1 attachment file.\r\nThe inline image will not show in the plain text message."); + + message.text.charSet = F("utf-8"); + message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* The attachment data item */ + SMTP_Attachment att[2]; + int attIndex = 0; + + /** Set the inline image info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + att[attIndex].descr.filename = F("orange.png"); + att[attIndex].descr.mime = F("image/png"); + att[attIndex].file.path = F("/orange.png"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + att[attIndex].file.storage_type = esp_mail_file_storage_type_flash; + + /* Need to be base64 transfer encoding for inline image */ + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The orange.png file is already base64 encoded file. + * Then set the content encoding to match the transfer encoding + * which no encoding was taken place prior to sending. + */ + att[attIndex].descr.content_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att[attIndex]); + + /** Set the attachment info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + + attIndex++; + att[attIndex].descr.filename = F("bin1.dat"); + att[attIndex].descr.mime = F("application/octet-stream"); // binary data + att[attIndex].descr.description = F("This is binary data"); + att[attIndex].file.path = F("/bin1.dat"); + att[attIndex].file.storage_type = esp_mail_file_storage_type_flash; + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add attachment to the message */ + message.addAttachment(att[attIndex]); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending the Email and close the session */ + if (!MailClient.sendMail(&smtp, &message, true)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_PSRAM/Send_Attachment_PSRAM.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_PSRAM/Send_Attachment_PSRAM.ino new file mode 100644 index 000000000000..2cd102ea622e --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_PSRAM/Send_Attachment_PSRAM.ino @@ -0,0 +1,318 @@ + + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email with attachment stored in PSRAM (ESP32 only). + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) +#include +#elif defined(ESP8266) +#include +#endif + +#include + +// To use only SMTP functions, you can exclude the IMAP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "-----END CERTIFICATE-----\n"; + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email with PSRAM attachment"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + String textMsg = "This is simple plain text message with PSRAM attachment"; + message.text.content = textMsg; + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + // If this is a reply message + // message.in_reply_to = ""; + // message.references = " "; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + // message.response.reply_to = "someone@somemail.com"; + // message.response.return_path = "someone@somemail.com"; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + // For Root CA certificate verification (ESP8266 and ESP32 only) + // config.certificate.cert_data = rootCACert; + // or + // config.certificate.cert_file = "/path/to/der/file"; + // config.certificate.cert_file_storage_type = esp_mail_file_storage_type_flash; // esp_mail_file_storage_type_sd + // config.certificate.verify = true; + + // The WiFiNINA firmware the Root CA certification can be added via the option in Firmware update tool in Arduino IDE + + /* The attachment data item */ + SMTP_Attachment att[1]; + int attIndex = 0; + +#if defined(ESP32) + + int dlen = 3 * 1024 * 1024 + 512 * 1024; + uint8_t *data = (uint8_t *)ps_malloc(dlen); + + if (psramFound()) + { + memset(data, 0xff, dlen); + + att[attIndex].descr.filename = F("data.dat"); + att[attIndex].descr.mime = F("application/octet-stream"); + att[attIndex].descr.description = F("This is binary data"); + att[attIndex].blob.data = data; + att[attIndex].blob.size = dlen; + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att[attIndex]); + } + +#endif + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/ESP_Camera.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/ESP_Camera.ino new file mode 100644 index 000000000000..ca1d27850ed2 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/ESP_Camera.ino @@ -0,0 +1,325 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +/** + * This example shows how to send Email with inline image from ESP32 camera module. + * + * The ESP32 board used in this example is ESP32 PSRAM Timer Camera X (OV3660). + */ + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) +#include +#endif + +#include + +#include "esp_camera.h" + +// =================== +// Select camera model +// =================== +//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM +#define CAMERA_MODEL_ESP_EYE // Has PSRAM +//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM +//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM +//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM +//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM +//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM +//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM +//#define CAMERA_MODEL_AI_THINKER // Has PSRAM +//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM +//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM +// ** Espressif Internal Boards ** +//#define CAMERA_MODEL_ESP32_CAM_BOARD +//#define CAMERA_MODEL_ESP32S2_CAM_BOARD +//#define CAMERA_MODEL_ESP32S3_CAM_LCD +//#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM +//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM +#include "camera_pins.h" + +// The camera_pins.h was taken from +//https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Camera/CameraWebServer + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + + camera_config_t camCfg; + camCfg.ledc_channel = LEDC_CHANNEL_0; + camCfg.ledc_timer = LEDC_TIMER_0; + camCfg.pin_d0 = Y2_GPIO_NUM; + camCfg.pin_d1 = Y3_GPIO_NUM; + camCfg.pin_d2 = Y4_GPIO_NUM; + camCfg.pin_d3 = Y5_GPIO_NUM; + camCfg.pin_d4 = Y6_GPIO_NUM; + camCfg.pin_d5 = Y7_GPIO_NUM; + camCfg.pin_d6 = Y8_GPIO_NUM; + camCfg.pin_d7 = Y9_GPIO_NUM; + camCfg.pin_xclk = XCLK_GPIO_NUM; + camCfg.pin_pclk = PCLK_GPIO_NUM; + camCfg.pin_vsync = VSYNC_GPIO_NUM; + camCfg.pin_href = HREF_GPIO_NUM; + camCfg.pin_sscb_sda = SIOD_GPIO_NUM; + camCfg.pin_sscb_scl = SIOC_GPIO_NUM; + camCfg.pin_pwdn = PWDN_GPIO_NUM; + camCfg.pin_reset = RESET_GPIO_NUM; + camCfg.xclk_freq_hz = 20000000; + camCfg.pixel_format = PIXFORMAT_JPEG; + camCfg.frame_size = FRAMESIZE_QXGA; + camCfg.jpeg_quality = 10; + camCfg.fb_count = 2; + + // camera init + esp_err_t err = esp_camera_init(&camCfg); + if (err != ESP_OK) + { + Serial.printf("Camera init failed with error 0x%x", err); + return; + } + + Serial.print("Connecting to AP"); + + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(200); + } + + Serial.println(""); + Serial.println("WiFi connected."); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Enable the chunked data transfer with pipelining for large message if server supported */ + message.enable.chunking = true; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + message.subject = F("Test sending camera image"); + message.addRecipient(F("user1"), RECIPIENT_EMAIL); + + message.html.content = F("The camera image.

\"esp32"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) <- not supported for message from blob and file + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The HTML text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + camera_fb_t *fb = esp_camera_fb_get(); + + SMTP_Attachment att; + + /** Set the inline image info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + att.descr.filename = F("camera.jpg"); + att.descr.mime = F("image/jpg"); + + att.blob.data = fb->buf; + att.blob.size = fb->len; + + att.descr.content_id = F("image-001"); // The content id (cid) of camera.jpg image in the src tag + + /* Need to be base64 transfer encoding for inline image */ + att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending the Email and close the session */ + if (!MailClient.sendMail(&smtp, &message, true)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/camera_pins.h b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/camera_pins.h new file mode 100644 index 000000000000..fdbdd1a31d01 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/camera_pins.h @@ -0,0 +1,317 @@ + +#if defined(CAMERA_MODEL_WROVER_KIT) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 21 +#define SIOD_GPIO_NUM 26 +#define SIOC_GPIO_NUM 27 + +#define Y9_GPIO_NUM 35 +#define Y8_GPIO_NUM 34 +#define Y7_GPIO_NUM 39 +#define Y6_GPIO_NUM 36 +#define Y5_GPIO_NUM 19 +#define Y4_GPIO_NUM 18 +#define Y3_GPIO_NUM 5 +#define Y2_GPIO_NUM 4 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 23 +#define PCLK_GPIO_NUM 22 + +#elif defined(CAMERA_MODEL_ESP_EYE) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 4 +#define SIOD_GPIO_NUM 18 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 36 +#define Y8_GPIO_NUM 37 +#define Y7_GPIO_NUM 38 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 35 +#define Y4_GPIO_NUM 14 +#define Y3_GPIO_NUM 13 +#define Y2_GPIO_NUM 34 +#define VSYNC_GPIO_NUM 5 +#define HREF_GPIO_NUM 27 +#define PCLK_GPIO_NUM 25 + +#define LED_GPIO_NUM 22 + +#elif defined(CAMERA_MODEL_M5STACK_PSRAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 22 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_WIDE) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 22 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#define LED_GPIO_NUM 2 + +#elif defined(CAMERA_MODEL_M5STACK_ESP32CAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 17 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_UNITCAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_AI_THINKER) +#define PWDN_GPIO_NUM 32 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 0 +#define SIOD_GPIO_NUM 26 +#define SIOC_GPIO_NUM 27 + +#define Y9_GPIO_NUM 35 +#define Y8_GPIO_NUM 34 +#define Y7_GPIO_NUM 39 +#define Y6_GPIO_NUM 36 +#define Y5_GPIO_NUM 21 +#define Y4_GPIO_NUM 19 +#define Y3_GPIO_NUM 18 +#define Y2_GPIO_NUM 5 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 23 +#define PCLK_GPIO_NUM 22 + +// 4 for flash led or 33 for normal led +#define LED_GPIO_NUM 4 + +#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL) +#define PWDN_GPIO_NUM 0 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 17 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_XIAO_ESP32S3) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 10 +#define SIOD_GPIO_NUM 40 +#define SIOC_GPIO_NUM 39 + +#define Y9_GPIO_NUM 48 +#define Y8_GPIO_NUM 11 +#define Y7_GPIO_NUM 12 +#define Y6_GPIO_NUM 14 +#define Y5_GPIO_NUM 16 +#define Y4_GPIO_NUM 18 +#define Y3_GPIO_NUM 17 +#define Y2_GPIO_NUM 15 +#define VSYNC_GPIO_NUM 38 +#define HREF_GPIO_NUM 47 +#define PCLK_GPIO_NUM 13 + +#elif defined(CAMERA_MODEL_ESP32_CAM_BOARD) +// The 18 pin header on the board has Y5 and Y3 swapped +#define USE_BOARD_HEADER 0 +#define PWDN_GPIO_NUM 32 +#define RESET_GPIO_NUM 33 +#define XCLK_GPIO_NUM 4 +#define SIOD_GPIO_NUM 18 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 36 +#define Y8_GPIO_NUM 19 +#define Y7_GPIO_NUM 21 +#define Y6_GPIO_NUM 39 +#if USE_BOARD_HEADER +#define Y5_GPIO_NUM 13 +#else +#define Y5_GPIO_NUM 35 +#endif +#define Y4_GPIO_NUM 14 +#if USE_BOARD_HEADER +#define Y3_GPIO_NUM 35 +#else +#define Y3_GPIO_NUM 13 +#endif +#define Y2_GPIO_NUM 34 +#define VSYNC_GPIO_NUM 5 +#define HREF_GPIO_NUM 27 +#define PCLK_GPIO_NUM 25 + +#elif defined(CAMERA_MODEL_ESP32S3_CAM_LCD) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 40 +#define SIOD_GPIO_NUM 17 +#define SIOC_GPIO_NUM 18 + +#define Y9_GPIO_NUM 39 +#define Y8_GPIO_NUM 41 +#define Y7_GPIO_NUM 42 +#define Y6_GPIO_NUM 12 +#define Y5_GPIO_NUM 3 +#define Y4_GPIO_NUM 14 +#define Y3_GPIO_NUM 47 +#define Y2_GPIO_NUM 13 +#define VSYNC_GPIO_NUM 21 +#define HREF_GPIO_NUM 38 +#define PCLK_GPIO_NUM 11 + +#elif defined(CAMERA_MODEL_ESP32S2_CAM_BOARD) +// The 18 pin header on the board has Y5 and Y3 swapped +#define USE_BOARD_HEADER 0 +#define PWDN_GPIO_NUM 1 +#define RESET_GPIO_NUM 2 +#define XCLK_GPIO_NUM 42 +#define SIOD_GPIO_NUM 41 +#define SIOC_GPIO_NUM 18 + +#define Y9_GPIO_NUM 16 +#define Y8_GPIO_NUM 39 +#define Y7_GPIO_NUM 40 +#define Y6_GPIO_NUM 15 +#if USE_BOARD_HEADER +#define Y5_GPIO_NUM 12 +#else +#define Y5_GPIO_NUM 13 +#endif +#define Y4_GPIO_NUM 5 +#if USE_BOARD_HEADER +#define Y3_GPIO_NUM 13 +#else +#define Y3_GPIO_NUM 12 +#endif +#define Y2_GPIO_NUM 14 +#define VSYNC_GPIO_NUM 38 +#define HREF_GPIO_NUM 4 +#define PCLK_GPIO_NUM 3 + +#elif defined(CAMERA_MODEL_ESP32S3_EYE) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 15 +#define SIOD_GPIO_NUM 4 +#define SIOC_GPIO_NUM 5 + +#define Y2_GPIO_NUM 11 +#define Y3_GPIO_NUM 9 +#define Y4_GPIO_NUM 8 +#define Y5_GPIO_NUM 10 +#define Y6_GPIO_NUM 12 +#define Y7_GPIO_NUM 18 +#define Y8_GPIO_NUM 17 +#define Y9_GPIO_NUM 16 + +#define VSYNC_GPIO_NUM 6 +#define HREF_GPIO_NUM 7 +#define PCLK_GPIO_NUM 13 + +#elif defined(CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3) || defined(CAMERA_MODEL_DFRobot_Romeo_ESP32S3) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 45 +#define SIOD_GPIO_NUM 1 +#define SIOC_GPIO_NUM 2 + +#define Y9_GPIO_NUM 48 +#define Y8_GPIO_NUM 46 +#define Y7_GPIO_NUM 8 +#define Y6_GPIO_NUM 7 +#define Y5_GPIO_NUM 4 +#define Y4_GPIO_NUM 41 +#define Y3_GPIO_NUM 40 +#define Y2_GPIO_NUM 39 +#define VSYNC_GPIO_NUM 6 +#define HREF_GPIO_NUM 42 +#define PCLK_GPIO_NUM 5 + +#else +#error "Camera model not selected" +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Embedded_Message/Send_Embedded_Message.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Embedded_Message/Send_Embedded_Message.ino new file mode 100644 index 000000000000..2f4da480ed08 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Embedded_Message/Send_Embedded_Message.ino @@ -0,0 +1,303 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email which the html and text message will be embedded as attachment or inline content. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only SMTP functions, you can exclude the IMAP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending message as embedded files"); + message.addRecipient(F("Admin"), RECIPIENT_EMAIL); + + message.html.content = F("This is html message"); + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; + + /* Enable to send this message body as file */ + message.html.embed.enable = true; + + /* The name of embedded file */ + message.html.embed.filename = F("test.html"); + + /** The embedded type + * esp_mail_smtp_embed_message_type_attachment or 0 + * esp_mail_smtp_embed_message_type_inline or 1 + */ + message.html.embed.type = esp_mail_smtp_embed_message_type_attachment; + + message.text.content = F("This is simple plain text message"); + message.text.charSet = F("utf-8"); + message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; + message.text.embed.enable = true; + message.text.embed.filename = F("test.txt"); + message.text.embed.type = esp_mail_smtp_embed_message_type_inline; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Enriched_Text/Send_Enriched_Text.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Enriched_Text/Send_Enriched_Text.ino new file mode 100644 index 000000000000..99c162a6bf7b --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Enriched_Text/Send_Enriched_Text.ino @@ -0,0 +1,293 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email in enriched text version. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending enriched text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + message.text.content = F("This is enriched as defined in RFC 1896\r\n\r\nIsn't it cool?"); + + message.text.content_type = F("text/enriched"); + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Flash_Message_with_Inline_Image/Send_Flash_Message_with_Inline_Image.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Flash_Message_with_Inline_Image/Send_Flash_Message_with_Inline_Image.ino new file mode 100644 index 000000000000..dacf96434b24 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Flash_Message_with_Inline_Image/Send_Flash_Message_with_Inline_Image.ino @@ -0,0 +1,370 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email with inline images stored in flash memory. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +// The file systems for flash and sd memory can be changed in ESP_Mail_FS.h. + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + Serial.println("Mounting flash..."); + + const char *html = "This message contains inline image.

\"orange"; + const char *base64Img = "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAkGBggGBQkIBwgKCQkKDRYODQwMDRoTFBAWHxwhIB8cHh4jJzIqIyUvJR4eKzssLzM1ODg4ISo9QTw2QTI3ODX/2wBDAQkKCg0LDRkODhk1JB4kNTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTX/wgARCAFoAoADAREAAhEBAxEB/8QAGwABAQEBAQEBAQAAAAAAAAAAAAECAwUGBAf/xAAbAQEBAQADAQEAAAAAAAAAAAAAAQIDBAUGB//aAAwDAQACEAMQAAAAn5/+igVVBAAAFIWJQsAAAgAAAAAAAoIAAAAgKFBAAUIWAAAAAAASUIoKFCwAAAAAAAACUQAAAAACAAoICgAgKFCAAAAFECUAAAACCWgoAsAAAAAAAACoBCgAQACACghSAAUBCkCgAAAAAAAoIAACDN0BSFECkKAAAAAACpCgEKBABAKQAAAAUIAAoEAABSFACiUAAEgAloALQgARQAAAAEAAABBRAAAoBCkAFCAAABYCVSFAChAUAAIAEAKACgCgskKAAAAEAAABBRAAAoIAABUAABAFEoAAUKIAAAAARAFtEAoAAoACABFCQFAACAAAUAAQFAQAAAgAM7fIe10tRuXcu866YvXG95v6uLf7+rsKEABSAAIUUgUCiAAAQAUCQAAUIAABQACAFIAAAAQCoTkz/Gvtvi4zpdTW869Tqet+7rd39fDz+10ez7HR0AAAIUgAQtCgAAAAWJZRABBSFhRECgAAFABCkAAAAIACUG5/F/t/h86xELT2uj7fs9D1fQ63Y9Dr8nq9LQAAABSAAoAAAFAACCxAVAAKEQBQAAUAgAAAAABACUGp/GfuPh+WsELT3vP933PO9f8Af1+b9HHv1+jQAUAEKQALQACgJABQRKAECABQgFAgCgAAAAAAgoAQCgs/jn2/xPDfEID6Hzvd+g8z2f08XJ349ex0tQoCgAQpCpCrCgBRCoAEAgAqAABCywABRAoAAAAAIBQAgJQWfx/7b4n83JxCA+i873fovL9vrx67Y17PR0CgAAAAgKWVRICikKRKAEQAQUgKAlgAUARQAAAAQAUBBUAGp/Ivtfi/x8nAID6Lzfd+i8v2uuN9c32ehukWghQSgAAlUKIEKAAgFCIAIAAKEsACgCAAAABSACgIKgILP5L9r8Z+Hl64gPofO9z6Pyvc6410zfZ6PJQAAQpAUEKoAAAoAEgFQBAWIABBQCwBQAABAUAAAJQgIBp/J/s/jPP5usBD6Dzva+k8r3emd9cX2ejyAUgUAAAgqgAAAAUklCAACoAEEFABYFAAAEBQAAEFQEAJX8q+y+N83sdUCHv+f7P0vle90xvpm+z0eSwACiAAAJpQAAAABUAhZABUAASCgFAgUAAAAAAgBKAgoZr+XfX/AB3k9rqUA9zoex9N5Pv9Ma6Z17HS5NZFAACoAAaigAAAABBQJABUAgLIBQCiBQAAAQoIAAShBQhmv5j9d8f4/b6dAPb6Xr/TeP8AQdc63nXsdLk1mikAAIAKG8gKRRQEhQAgpCogCoAQIFAKIAFBACkKQACoCChAZr+Z/W/I+L3OjQD2en631HjfQ9c63nXr9Pk1i0AEAtgKRB0yBQAAQACoAKiACUhUCBQCiABQECILaQACoQCoCUP5p9Z8l4fd6AoPY6fqfU+N9H1zrWdev0+TeKBKpFAEKEh1yAKAAIVACCgJQJAKAiABQCgACKkAUKAgIKAgoZP5z9V8p8/3/OoB63U9L6rxfpeudbzr1upybxQCgCAUAOuIIFACkCoAQUBBRIAKEARQAACkLBAChZAogFCAVCL/ADz6n5X530PMAHqdX0frPF+l6Y1vOvW6nLvFAqwChACg64glqAFIUioABEoCUFQBBBQBFAIUAASUloICwAVAShCL/P8A6j5b5v0fMBB6XW9D67xPpumNdJv1enybxQpKoAQAEO2IChSBKsAgUEEFCWFEFEEAoEAAAUJCgLAABQgBKgJb8D9N8v8AL+n5IoPR63f+w8P6npi9Jv1OnydMUKKBABQEOuJSKAAAAQAJKCoAQUFCCRSgEAKQsCpBaEBUKQAGaAlvwv0fzXyfreMLA/fwdz7LwvrOuLvO/U6vJ0xRFAgLUABDtiAoAAAEQAWQUIKAgFCCwABQQApBFJVABAAQVACW/E/Q/PfJet4sog/bw9v7Lwfqu2Nbzv1OrydMWEtpAAQAVDvxyBaQApACJQAlAkVYFQACoBSFgAAAAAAAAShCAWw+P93w/kvX8aWElfp4+f7LwfqeuNdM79LrcnXjqooAlIUInPc/NzZ9PpbBQoIAAIACUBAKJBQAlAAEUAAAAAAEBKKSEoo+X9jy/lvW8qCzFxpr67xPo+uN9M79Lq8nXFgUCan5+XPLc5bzx3nlqCx9F5nYBQAAACIAIAASgsikUBBSFBQIAEKKEKSAqAEFRYSvC9Lp/P8Ao9LedamtSq/Z1+z3xyduPfp9Tl6S/n5Jy5M8tTnqctTUAZoll1Hv+dziKAKQFIEQASgAIKEsKQKgAoAECkKCUBCkAICVCWiV5fd4fH7fX3Nal1LZdKIu5cVqEVS2BVsDcuoh7fQ5RFAAFIEACQUABBQlgACoAABQAAAQAAgoQzaJWdTzO3xfg7HHrNssoWXSpRV3mwoUUAABPc8/mgUAAAEACQCgBBQgsAKJYAAAoBAAAQCoTT83NjhyTjvPHknHUxRIShqWy1bLqWwWqNS2KqJZmqgsuo9jo8oAAAAEKEQBQEAFCAAWCUAAAAAlhRnU/NzT83Lx8OTPHkcdZ3m7xqgGKzqctZzVLLqXtjdl3LvOhmpUSqilWwkVAez0eUAAAAAAiAKAgAFQACwQCgAgonPkn5ebPLc/PyZ5anPTeUUgsoKJZChSZrNSkVRuXpjVWywpqIUlZqwBT2ehygCFAAAAQAACoAEgoBQELBZx5Jw5MceSfn5M/m5cw6YtgsqILLRULFLKJUJZixbYzVXebAVbEoF1LY1FUBCoez0OSrAACgAAIBAUBABURQShw5s/n5MceTPDc4cksbySywACrcqozZLM0illoWgiys3IBZWbN51qWxVFgpM0NRVsCHtdHlKgAACkAKEAhQEKSUs/LzY57nPU4cmfz7mosZKUiUsooUZSWStRZdyolZsxpE1KLFUCUAWyxFFsal1LmtRVgQZsgtsnt9DmKgAAAAUBAARXHkn5+XHDkz+fkzy3NZWWiM2CmpYZsok0ozVgUhLIblssBQZrNmbBqWrYlFRV1GdIagupdQlpCgAESWex0eagAKgKQFBDU4cmePJOPJjjucdSkjNixFNSw1GpZZirGixnUylWxQCAAhK1LqICrYlnPUzqQsupdQUtIVYllpDSwsaNZtISoZufZ6PNQAFEBjefz8ueO5y5M89TlqazSZoWBC2ZCCm5cljcozZK1CFZslWLAsolgsShmty7zRBViVmrErnqCy6lFWIWliqigiKsaiy6l9TqcipCuW5+flx+fln5+TMM10yzRLKAiWZrRYAhm5pCmpbErUpM1LEblETNkKuoollhaWJUM2bl3KlzYWWCEFAVUCiKtlpqXUZsxqQESn6cXjuc9TluZBY1LZQBLLLSiJZmhYGozSyFBDUVcpqBLJWTUajGpKQNLrKqjRkVZZZmyFXpm6lxWbKCEoWWwqENFlsopmyxVBInDlxCy1RmyllsuozYqBdQLEqIIaECVLAKQJYlWNSiGdQmoxW5ZWE0WWrrNVYJKssrKShuWwWWRSCVK1m0ENSixqFsKIIPyc3GqxrOlRKFBc2CpZbLSVYAiCiJUsAAzYNRmwbzdTVTFma1FWxLMUssus2lXUtjFUJKzZihuXUWXNWCkVmrFgujJKqCy2BU/Ny8dlqiygApFqM2ClWJvNlEhKsUzZSAApiylliDpLc2VLOepqN51qKctZlShrN3LqXUQzZLLLDOmbCWa6SolAFshZZDUsFkIlLLU//EAEYQAAEDAQMJBgIIAwQLAAAAAAEAAhEDBBASBQYgITFBYXGxEzAyQFFyM1AiNENgc4GR0aGywRQlUoIVIyQ1NkRTYnDC4f/aAAgBAQABPwDyE3z5yfMzoToDRH3CHyAf+FR9wh87n5eO7HlXmKbiNoBQy/bR9u79AhnFbR9t+rAhnJbd72fmwIZz2r0on/L/APU3OivvpUf4oZzv30Kf5OKGc3rZ/wBHoZy0t9B/5OCsmV6drqhjKVQE7zEedHyp2tpCdVeHGHuQtFUbKj/1QtlcbKr/ANULfaBsqvQylaR9osn2h9ehiedcpgVCjKyewU6rBx7gXjy48gPLVRFRw4nRyMJsp9xVCmrOwKzaq7OaHejRn5oNoVoEWmpweeujkETZXe9UmqmMLVZzFZnMd6O7nzQ8qPEOatww2+uPSo7roBZvfVanvVBiaqGqqzmNIfcEbRzWUxGVLV+K7roBZtCaFX3BMTVS+I3mPIjTHy/eOayxqyzbPxn9To5r/Cr82piaqfjHPux8jHmstiMuW3hXf/MdHNbZaP8AKmpqZtCH3HzgEZw2/wDHf1OjmrttI9qampm0fKh507FnKIzkt347tHNXx2jkE1BNTdnyEdwPOnYs6RGc1u/FKGhmuYr1/YOqamoJh1D7jFZ2/wDE9t946DRzX+tVvZ/UJqagmbBy+VDup8kVngIzotfNv8o0c2PrtX8P+oTU1BU/A3kEPOjuRpDSGhHkM8hGc9p5M/lFwvzZ+vv/AAympqCp66beQ84Lgh3o70d9nsIzkq8WM6aObZjKJ9hTU1BUfhN5DTHywXTonvCs+RGcPOkzRzc/3oPYU1BBUfgs9o+QT5DfcdAXnvSs+9WXWfgN6nRzeMZWZyd0KaggqGugz2/Ix5AaRuPeZ/CMs0fwB1cpUqVKyAf73o/n0KaggrP9XZy+aToDv8/x/eNm40f/AGOjkPVlihzTE1BWb6uzl8xGhPks/wAf7VZD603ddHI2rK1n96Ympqs31dnLzQ0BfKlDRHn8/WS+xcnrAuzWBYVkvVlOz+8dUxBBWb6u3vKlpo0/HUaE/KlMGGU6j/ygd4O7HyPPVmNtj5v/AKLsF/ZyUbK7eEbM7cFY6ZZb6JO6oOqYmpqsuuzt0iYT8oWam4tNdmL0GvonZVpjwUqr+Yw9U7KdY+GmxvEnF+ydbLQ/bWI9gDU4l+suLj6uMoSgD5YaAuHns6mY6Nm4OchQCbZ0LIhYwdqGTqYeHAQQZTar27gUy0N3ghUqjX7HKymLOAnVGsEuIA4mE7KFnZtqtPt19E7KrB4KdR3P6KOVKp8LGM5yUbXXftrOHtgItDzL5cfVxnqg2FhWFFiwIMUfJh5TLzMVClweeiZSQpIUl2aDEGKPQI059AgaoYGio8Abg5dlJ1ieJQYVgQYVBCg3An0UkIOQUcFCHkR3Y83Ke9tNsvc1vMwsp16Vei1tOo15DpOHWgPQKD6KCsPC4IKY2hShKgELCsPFBkIcQsBO5YFhaN6DmhdodzVLigO9HyWUTCq5TsdHx2miOAfJ/gnZaofZsr1eLaUD+MJ+WK32dkjjUqfsnZRtrtr6dP2056p9avV8des7hMdEGRuB4kSiSu1K7Y7AV2j/APEhUcVjKmd0oNulCVJWtBpO9BoG9bEJRneVhHogAPQLkEGu9EGefHeypTnhgl5DRxMJ+VLIzUazXcGDF0VTLX/Qs1R/F8M/dOypbX7BZ6X6vRtFreIfa6vKmAzonWWnUM1A6ofWo4uTKQp6qQaz2iEHOG3Wsbd4QwnYUWLAU4FEIhNQCamQRJKAbuchTYd6FELsQFs3FTvlfqg70ClEJrD6LAoAWMLEdEd+PKSgVVtNKj8Wqyn7nAJ+WbINTKhqcKbC5OyyT8KzP51HhvSU/KlqfsNKnybi6o2mu/x2mseTsPRdmycRY0n1Os/xQUAXAraoQWpFih7dhQqPG0LtGngoa5GmFgXZoNcpcgJMlNJahXEawu2lB4O+4H1CDPUyvoNWMIvX0kJUXATpDy40ZUqrbrNQ1Va9JnN0lf6YspnB2j/awp+WH7KdCOL3/sn5Rtb9lRjB6MZ+6ealX41es/gahhMo0meFjP0U3QsCwFCRcAi24FTeeSDwi0ORoqXt3rtfVqLz6JrkCiFKgKPQosNweUHneFjahhcsC1jcpKxLGVJ87KmJJT8oWWkTjr0wfQOk/wAFUy1RHw6dapybHVOyxXfOCgxnvfPRPtlsqf8AMFnCm0DrKfT7XXVfUq+95KZTYzU1jW8hdChYVhuFwKkKJRYoLUSUCgbgpUoEHcsAUEKVqWAINgoyEHQdYQM70HFqkFQNoK1rVvCwgrAixAuGwoPcg4bxCDgiT5mYReBJJgKrlax0dTq7eTdfRHLNJwmlSrP5tw9U7Klod4KVNnFxLv2T7Zan7a7m+wBqc0Vfi4qnvcXdU1oYIYA3ldru/O8BQgVqULDeHEIOCD/zWoosRYti1oOQchdJulQ07kGoSEGbysAWBBqDUGLBdK13QFhCLFCghAnytS22elqfXYOTp6J+VaOvAypU5NjrCdlaqfBRYz3vnon261P21sAO6m0BFoqyapfU97pTabWD6DQ1SgZuwXNi7DcCgpui6b4uDm+kKLgpuwLs1hNweVKEOUKCgLpGwohqF30eKHBykrE1AArChIUoRfAUDvycIJJgJ+ULKwwa7OTTPROytSE4KdV/5R1T8q1nTgpU2cXuJ6J1stL9tcjhTaAnf6zXULqh9XuJQ1amgN5LaiLtaa5RiuBuIuBugFFim6VKCgKLhChQhI2IP/xBAYthUXa7ixGmiwgoSgUHkIPlqEbAsKwuC4EKFqQhQFJCxSFAQLgsfqEHBywqLoWDuZT69Kn8SoxnudCflayt2PL/AGNJTssbqdneeLnBv7o5StT9nZU+QLuqNe0VJx2mpybDeiNJpMubjPq4z1Q1CBA7g3hy2qEDdChAoOQKgKNKAi1C4i9tQ79abhdsMFEEKb9SwLCiAnMTZCDyEHzcBdrCEIC4BQVChSUKhQqjeEHNcsOhKqWuhSkPqsaRxTsrUB4cb+TVUyxVMilQA4ucv7da3iH1QPYIXaVH+J7jzchSY3Y0XygdAoJt8KERdCEhA7ii2FJQN0XByBUqAiFKnSEqAsKwolNqkIOY/wD7SixFAhawpUDcdGEJu5G4BQgYQIucEQo9QtVweRsKdluh9kyrV5NjqnZYtDtTLOxnvfPROtlseJNdrOFNic+o/wCJWqvn1cg0AGBBQCChBFNKcINwUII6GooXSVruF0IOhETsuBm+FsQcoTpG9NcHLWgSECgSgQhAuKFxChQQmvLdhTaodqeEGA62lOChABbL5CBF5lSsSn0KAWxYisSBlQRcGhYDwNxQMtuPhQF7UbiVKnUhowpi4acKYukoPuACIRTXrU4LCJQai24FAoEoISCoBRkXkKBdMGQhVO/WgWv2FFpQF8Suz9FrCD0IO9EINWBAkIOQAI2oNUBTeCgYEIlUxtlTfBulFyMoG4HQAUXQgh3BQ23FNJGxAhyBWpFqhNIUXFiNwKDljQTSsAdrCghAqVCLbgUKpCDwboIQIF5YCsJCBvBRUldoQu0O8Jjg66YTSgEB6BQgFqQIF8KAg0LVeJF0JutqIWrebxN0aUKEFF7DPAqFCLUQmOhCHISEWByLS1RcHoQCmv8AW4HVB1hFgOsIghA3FiLFhuDiEHnY5QCsCi6UEWKXBYgVBWtQCsFwKD1IK//EAC4RAAIBAQUHBQEAAgMAAAAAAAABEQIDBBAgMRIwMjNAQWAFEyFQURQiQmFxkP/aAAgBAgEBPwD/AMGKVLP5aPw/ks/w/ks/w/jsx3Kg/iX6O5f8n8T/AEru+wtfB7PiQqUbKNik9un8PZoLWhUsZVUWrleD0cSKdMt41KmVMq0fg9HEijhWW9alTGVaeD06os+BZb3qirCrTwenUsuBZb5qh4PTwenUseWst97Dwfg61LHlr/rLfew8H4PTqXflU5b7oh4Pwdal25VOW+6IfhKLpyKct94UPF+DIufIpy3zhHi/BkXHkU5b5wDxfg9w5FOW+cGSrwf0/kLLeuXkq18GR6dyFlvXLyV6+D+ncnLeeW8levg/pvJy3nlPJXr4P6XynlvHKY8a+LwZHpfA8tvy2PGvi8H9Lf8AjUSSTha8DHjXxbxWdTFYPu/uvTXCqNo2zbQq0VuaWPGvXNDYrGt9hWD7sVjSKihdvvbi4k2jbPcPcPecQNJjoHSytSxUNisaxWH6xWNKFTSuxJJJJJJP3d1cSbRJJJJOEnwbRJJPgMCpbLGh0a5J3Mk4zhBH2qpZTd7SrRCutXdiu9Hdis7NdhKlaIkRBskIjfTkn65Utiu9o+wrsv8AZisbJa/IlQtKT3KloOva1wjGRZmfJLNpm1kjJOEEfUwU2dVeiFdqxXZd6hWNmhU0rRG09zOEIh4SSSTk2TZIxk+SCPqIKbGurRCu1fcV3p7sVnZrsJpaIdbeSSd3GG0fBBBG5gjCcYII66GKxtHohXZ/7MVhQtWKizXYVUaDqb1xkknPO6nLOEZ5Jw+CCCOrSbFd7R6IV2fdisaFqKihaITa0G56OScYIzzjJOMk55JwjpIFY1vsK7vuxWFC1YrOhdiY0Np98k5J6OScYI3kEdRDYrGv8Fd33YrChasVFC7Exp0E72M0kk4wRhJO5hEEYTjO5hlNnVVoK71iu67sVjZoSpWiNp9HBHQRnknBPCCN7BBGWBWdT7Cu9RTd6Vqz27NaIhEvpo6XZIgnpFlgV1q7iu9C1ZsWa0R8dkTlXXIjdrGCMF0MZZyr6KMJwnfxnnCMk4RhO4eeOlW4TyzljGcs4wRmncQQNfUPcJ5IwjGRYyTkjCeg/8QALBEAAgECBAYCAgEFAAAAAAAAAAERAhIFEyBgAwQQMjNQMUAwURQhQUJhkP/aAAgBAwEBPwD/AIMMz/8AZns/kGexcYzjOM0pqnY9fayviVS/6mbX+zOr/Z/I4n7FzXE/ZyvEq4lMsRTSUqNj1fDK+56eR7ClFKFser4ZxO56cP7ClCFser4Zxe96cN7WU7Jfwzjd704Z2sWyavhnH8j04X8PohbHfwzmPK9OF/3EIWx2c15qtOFf5CELZHN+arThXzUIQtjv4Od89WnC+5iFsnnvPVpwzufRbJxDz1acM72LZWIeerThvk0LY+I+d6cO8ouiFsfEvO9OH+bQtj4n5tPIeZaFsfFfKSSSSch5loWx8W8i08j5loWx8W7kQR15PzIXVbHxSmWi0tLS05byoQhC/HJci/3XP0zBlGUZLHwmcGmK0L4EIWqS9GYXlzJfvOapksMsyjKFwEnInAmJlJKL0Xl7Ln0jRHvOMpLS0gggjpHWOkbClIraZGyJHXSZiMx/ouqJfWSSSdgSh1ozC+olssElqjShdIII0z7C5GYi9lzJeqPxRpkknVPqZL0XozGXVdEtMfnkkX4JJ9PejML2SyCFojXH3Z+7KL6TML2S/SR6S5F5ey59IRH2oI9TKLkXl5c/SwR1n7skl6MwuZL9ZBH0pJ13IvMxl7JI9ZP2pM1GYy6ol+zn7EaF9+fYr3Ek/nknUvRr1n//2Q=="; + +#if defined(ESP32) || defined(ESP8266) +#if defined(ESP32) + if (ESP_MAIL_DEFAULT_FLASH_FS.begin(true)) +#elif defined(ESP8266) + if (ESP_MAIL_DEFAULT_FLASH_FS.begin()) +#endif + { + + // ESP_MAIL_DEFAULT_FLASH_FS.format(); + + if (ESP_MAIL_DEFAULT_FLASH_FS.exists("/base64Img.jpg")) + ESP_MAIL_DEFAULT_FLASH_FS.remove("/base64Img.jpg"); + + Serial.println("Preparing flash file attachments..."); + +#if defined(ESP32) + File file = ESP_MAIL_DEFAULT_FLASH_FS.open("/base64Img.jpg", FILE_WRITE); +#elif defined(ESP8266) + File file = ESP_MAIL_DEFAULT_FLASH_FS.open("/base64Img.jpg", "w"); +#endif + file.print(base64Img); + file.close(); + +#if defined(ESP32) + file = ESP_MAIL_DEFAULT_FLASH_FS.open("/msg.html", FILE_WRITE); +#elif defined(ESP8266) + file = ESP_MAIL_DEFAULT_FLASH_FS.open("/msg.html", "w"); +#endif + file.print(html); + file.close(); + } + else + { + Serial.println("Flash filesystem monting Failed"); + } +#endif + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Enable the chunked data transfer with pipelining for large message if server supported */ + message.enable.chunking = true; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + message.subject = F("Test sending base64 inline image stored in flash memory"); + message.addRecipient(F("user1"), RECIPIENT_EMAIL); + + /* Two alternative content versions are sending in this example e.g. plain text and html */ + + /* Assign blob data (in flash or ram) as HTML message */ + message.html.blob.data = (const uint8_t *)html; + message.html.blob.size = strlen(html); + + // Or get the content from file + // message.html.file.name = "/msg.html"; + // message.html.file.type = esp_mail_file_storage_type_flash; + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) <- not supported for message from blob and file + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The HTML text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + message.text.content = F("This message contains inline image.\r\nThe inline image was not shown in the plain text message."); + message.text.charSet = F("utf-8"); + message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* The attachment data item */ + SMTP_Attachment att; + /** Set the inline image info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + att.descr.filename = F("base64Img.jpg"); + att.descr.mime = F("image/jpg"); + +#if defined(ESP32) || defined(ESP8266) + att.file.path = F("/base64Img.jpg"); + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + att.file.storage_type = esp_mail_file_storage_type_flash; +#elif defined(ARDUINO_ARCH_SAMD) + att.blob.data = (const uint8_t *)base64Img; + att.blob.size = sizeof(base64Img); +#endif + + att.descr.content_id = F("image-001"); // The content id (cid) of orange image in the src tag + + /* Need to be base64 transfer encoding for inline image */ + att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The attach image file is already base64 encoded file. + * Then set the content encoding to match the transfer encoding + * which no encoding was taken place prior to sending. + */ + att.descr.content_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending the Email and close the session */ + if (!MailClient.sendMail(&smtp, &message, true)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_HTML/Send_HTML.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_HTML/Send_HTML.ino new file mode 100644 index 000000000000..1a4af3860dd6 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_HTML/Send_HTML.ino @@ -0,0 +1,301 @@ + + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send html message. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* The full message sending logs can now save to file */ + /* Since v3.0.4, the sent logs stored in smtp.sendingResult will store only the latest message logs */ + // config.sentLogs.filename = "/path/to/log/file"; + // config.sentLogs.storage_type = esp_mail_file_storage_type_flash; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending html Email"); + message.addRecipient(F("Admin"), RECIPIENT_EMAIL); + + String htmlMsg = "

This is the html text message.

The message was sent via ESP device.

"; + message.html.content = htmlMsg; + + /** The html text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* Set the TCP response read timeout in seconds */ + // smtp.setTCPTimeout(10); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/Send_Parallel_Attachment.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/Send_Parallel_Attachment.ino new file mode 100644 index 000000000000..bb7221272440 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/Send_Parallel_Attachment.ino @@ -0,0 +1,334 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + * +*/ + + +/** + * This example shows how to send Email with media e.g. audio and images as parallen attachments, + * and play or display them simultaneously on the Email client (depends on the Mail client supports). + */ + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +/* This is for attachment data */ +#include "data.h" + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Enable the chunked data transfer with pipelining for large message if server supported */ + message.enable.chunking = true; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + message.subject = F("Test sending Email with parallel attachments"); + message.addRecipient(F("user1"), RECIPIENT_EMAIL); + + message.html.content = F("This message contains image and audio file which will play on the Mail client in parallel or simultaneously (depends on the client supports)."); + + /** The HTML text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; + + message.text.content = F("This message contains image and audio file which will play on the Mail client in parallel or simultaneously (depends on the client supports)."); + message.text.charSet = F("us-ascii"); + message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* The attachment data item */ + SMTP_Attachment att; + + /** Set the attachment info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + att.descr.filename = F("haun.png"); + att.descr.mime = F("image/png"); + att.blob.data = shaun_png; + att.blob.size = sizeof(shaun_png); + att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + message.addParallelAttachment(att); + + /** Set the attachment info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + message.resetAttachItem(att); // Clear the attach item data to reuse + att.descr.filename = F("mu_law.wav"); + att.descr.mime = F("audio/basic"); + att.blob.data = mu_law_wave; + att.blob.size = sizeof(mu_law_wave); + att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + message.addParallelAttachment(att); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending the Email and close the session */ + if (!MailClient.sendMail(&smtp, &message, true)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/data.h b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/data.h new file mode 100644 index 000000000000..c7a88aeab659 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/data.h @@ -0,0 +1,1957 @@ +#include + +static const uint8_t mu_law_wave[] PROGMEM = { +0x52, 0x49, 0x46, 0x46, 0x84, 0x5D, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20, +0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, +0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x66, 0x61, 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0x00, 0x5D, +0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x5D, 0x00, 0x00, 0xFB, 0xFD, 0xFF, 0xFE, 0xFF, 0x7F, +0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7C, 0x7D, +0x7C, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7E, 0xFF, 0x7F, +0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7C, 0x7C, 0x7B, +0x7B, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, +0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x79, 0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7C, 0x7E, 0xFF, 0xFE, 0xFE, +0xFF, 0x7E, 0x7C, 0x7D, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x79, 0x78, 0x79, +0x7A, 0x79, 0x78, 0x78, 0x78, 0x77, 0x78, 0x78, 0x79, 0x79, 0x78, 0x77, 0x77, 0x78, 0x78, 0x79, +0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, +0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF8, +0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFB, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, +0xFF, 0xFF, 0xFE, 0x7E, 0x7D, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7C, +0x7B, 0x7A, 0x79, 0x79, 0x79, 0x77, 0x77, 0x78, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, +0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x79, +0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, +0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7A, 0x79, +0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, 0xFB, 0xFC, +0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, +0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, +0x7C, 0x7B, 0x79, 0x7A, 0x7A, 0x7A, 0x7A, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7C, 0x79, 0x79, 0x7A, +0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7C, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFE, +0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, +0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, +0x78, 0x78, 0x77, 0x77, 0x77, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, 0x72, 0x73, 0x73, +0x74, 0x74, 0x74, 0x75, 0x77, 0x78, 0x78, 0x77, 0x76, 0x77, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, +0x78, 0x79, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, +0x7E, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFD, 0xFE, 0x7F, 0xFF, +0x7F, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7D, 0x7F, +0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7D, +0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFC, 0xFC, 0xFD, +0xFC, 0xFB, 0xFB, 0xFC, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFD, 0xFE, +0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x79, +0x78, 0x78, 0x78, 0x76, 0x74, 0x74, 0x73, 0x72, 0x75, 0x77, 0x77, 0x76, 0x75, 0x75, 0x76, 0x77, +0x77, 0x76, 0x74, 0x74, 0x74, 0x74, 0x76, 0x76, 0x76, 0x77, 0x75, 0x76, 0x78, 0x79, 0x77, 0x77, +0x79, 0x7B, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFE, +0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7F, 0x7F, 0x7D, 0x7E, 0xFF, 0x7F, +0x7F, 0xFF, 0x7F, 0x7E, 0x7D, 0x7E, 0xFF, 0x7E, 0x7F, 0x7F, 0x7C, 0x7D, 0x7F, 0x7D, 0x7E, 0x7E, +0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x7D, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, +0x7D, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFB, 0xFB, +0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, +0x78, 0x79, 0x78, 0x75, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x73, 0x74, 0x73, 0x72, 0x73, +0x75, 0x75, 0x74, 0x76, 0x74, 0x72, 0x73, 0x74, 0x75, 0x75, 0x76, 0x77, 0x77, 0x78, 0x77, 0x77, +0x77, 0x78, 0x78, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, +0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7C, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, +0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, +0xFE, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0xFF, 0x7E, 0x7E, 0x7E, 0x7D, +0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, +0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7B, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7D, 0x7C, 0x7C, +0x7D, 0x7C, 0x7C, 0x7E, 0x7E, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, +0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, +0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, +0x7E, 0x7E, 0x7E, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7F, +0x7D, 0x7B, 0x7C, 0x7C, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7E, +0x7F, 0x7E, 0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x74, 0x73, +0x72, 0x73, 0x74, 0x75, 0x77, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, +0x7C, 0x7D, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, +0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x79, 0x79, +0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, +0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7D, 0x7D, +0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, +0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, +0x7A, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, +0x7D, 0x7E, 0xFF, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, +0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7C, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x78, +0x78, 0x77, 0x77, 0x76, 0x75, 0x74, 0x74, 0x74, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x76, 0x75, +0x74, 0x75, 0x77, 0x78, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, +0xFC, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, +0xF8, 0xFA, 0xF8, 0xF6, 0xF7, 0xF7, 0xF8, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFB, +0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, +0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFD, 0xFE, 0xFF, +0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, +0x7D, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x78, 0x79, 0x78, 0x77, 0x76, +0x76, 0x75, 0x73, 0x74, 0x73, 0x71, 0x70, 0x70, 0x71, 0x72, 0x71, 0x71, 0x70, 0x6F, 0x6F, 0x6F, +0x70, 0x71, 0x71, 0x72, 0x73, 0x74, 0x74, 0x74, 0x76, 0x77, 0x76, 0x78, 0x79, 0x79, 0x79, 0x78, +0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, +0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7D, +0x7D, 0x7D, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7C, 0x7A, 0x78, 0x79, 0x78, 0x77, +0x76, 0x78, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, +0x7E, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, 0xFA, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, +0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF7, 0xF9, 0xF9, 0xF8, 0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFD, 0xFD, +0xFC, 0xFD, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0x7F, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, +0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x75, 0x76, 0x76, 0x75, 0x76, 0x77, +0x78, 0x79, 0x7B, 0x7B, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7A, 0x7B, 0x7B, 0x7A, +0x7B, 0x7D, 0x7E, 0x7B, 0x7C, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFE, 0xFF, +0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7D, 0x7F, 0x7F, 0x7C, 0x7B, +0x7A, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7C, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7C, 0x7C, +0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, +0x7D, 0xFE, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF9, 0xF8, 0xF5, 0xF4, 0xF7, 0xF8, +0xF8, 0xF8, 0xF9, 0xFB, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, +0x7A, 0x7B, 0x7B, 0x7A, 0x78, 0x78, 0x77, 0x76, 0x76, 0x75, 0x76, 0x76, 0x76, 0x77, 0x75, 0x75, +0x76, 0x75, 0x76, 0x76, 0x78, 0x78, 0x77, 0x78, 0x76, 0x74, 0x75, 0x77, 0x79, 0x7A, 0x7A, 0x7B, +0x7C, 0x7D, 0x7D, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, +0xFE, 0x7F, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0xFF, 0xFD, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, +0xFC, 0xFD, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, +0x7B, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7E, 0x7E, 0xFF, +0xFF, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, +0x7C, 0x7D, 0xFF, 0x7E, 0x7C, 0x7D, 0xFF, 0xFF, 0xFF, 0xFD, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, 0x7E, +0x7F, 0x7E, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x79, +0x77, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7C, 0x7D, 0x7D, 0x7E, 0xFD, 0xFD, 0xFE, 0xFC, 0xFC, 0xFB, +0xFB, 0xFC, 0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, +0xFF, 0xFF, 0xFD, 0xFC, 0xFD, 0xFD, 0xFC, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7C, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, +0x7B, 0x7C, 0x7D, 0x7B, 0x7B, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x75, 0x73, 0x72, +0x72, 0x72, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x74, +0x75, 0x76, 0x76, 0x76, 0x77, 0x78, 0x77, 0x78, 0x79, 0x77, 0x78, 0x78, 0x79, 0x7A, 0x7A, 0x7A, +0x7A, 0x79, 0x77, 0x76, 0x76, 0x78, 0x78, 0x77, 0x77, 0x77, 0x75, 0x74, 0x74, 0x75, 0x75, 0x76, +0x79, 0x79, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7D, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFE, 0xFC, +0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF4, 0xF6, 0xF8, 0xF7, 0xF7, 0xF9, 0xF9, +0xF9, 0xF8, 0xF8, 0xFB, 0xFA, 0xF9, 0xFA, 0xFB, 0xFC, 0xFE, 0xFC, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, +0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, +0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7F, 0xFE, 0xFE, 0xFD, 0xFD, +0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFB, 0xFC, +0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, +0x7C, 0x7B, 0x7B, 0x7C, 0x79, 0x79, 0x79, 0x78, 0x76, 0x75, 0x76, 0x78, 0x77, 0x76, 0x76, 0x77, +0x76, 0x74, 0x74, 0x75, 0x75, 0x75, 0x74, 0x74, 0x76, 0x77, 0x78, 0x7A, 0x7C, 0x7B, 0x7A, 0x7D, +0x7E, 0x7E, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, +0xFF, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFE, 0xFD, 0xFC, 0xFE, +0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7F, 0xFE, 0xFC, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0x7F, 0x7E, 0xFF, +0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7E, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, +0x7E, 0x7D, 0x7E, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7B, 0x7B, +0x7D, 0x7E, 0x7E, 0x7D, 0xFF, 0xFF, 0x7F, 0x7F, 0x7E, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x77, 0x77, +0x77, 0x78, 0x78, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x74, 0x74, 0x75, 0x74, 0x72, 0x74, +0x76, 0x74, 0x74, 0x76, 0x76, 0x74, 0x73, 0x73, 0x72, 0x73, 0x74, 0x76, 0x77, 0x75, 0x73, 0x75, +0x77, 0x78, 0x75, 0x75, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7B, +0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7C, 0x7F, +0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x79, 0x77, 0x77, +0x78, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7B, 0x7C, 0x7B, 0x7C, 0x7D, 0xFF, +0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, +0xFA, 0xF9, 0xF9, 0xF7, 0xF7, 0xF7, 0xF4, 0xF4, 0xF4, 0xF2, 0xEF, 0xEE, 0xEF, 0xF2, 0xF2, 0xF1, +0xF2, 0xF5, 0xF5, 0xF3, 0xF1, 0xF2, 0xF5, 0xF7, 0xF8, 0xFA, 0xFB, 0xFC, 0xFC, 0xFB, 0xFC, 0xFC, +0xFD, 0xFF, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, 0x78, 0x77, 0x76, 0x75, 0x75, 0x74, 0x71, 0x70, 0x71, +0x71, 0x71, 0x70, 0x6F, 0x71, 0x71, 0x71, 0x73, 0x75, 0x77, 0x77, 0x76, 0x79, 0x7A, 0x79, 0x79, +0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0x7E, 0x7D, 0x7E, 0x7E, 0x7D, 0x7D, +0x7E, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x78, +0x7A, 0x7C, 0x7C, 0x7A, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7D, 0x7C, +0x7C, 0x7E, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7E, +0x7D, 0x7D, 0xFF, 0xFF, 0x7F, 0xFF, 0xFC, 0xFC, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, +0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7F, 0x7F, 0x7E, 0x7D, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, +0x7B, 0x7C, 0x7C, 0x7A, 0x78, 0x78, 0x7B, 0x7A, 0x77, 0x75, 0x76, 0x75, 0x76, 0x76, 0x76, 0x76, +0x78, 0x79, 0x78, 0x75, 0x75, 0x76, 0x77, 0x7A, 0x7D, 0xFF, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFA, +0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0x7E, 0x78, 0x76, 0x72, 0x70, 0x71, 0x75, 0x77, 0x77, 0x79, 0x7A, +0x7A, 0x7A, 0x7B, 0xFF, 0xFB, 0xFA, 0xF9, 0xFB, 0xFD, 0xFE, 0x7E, 0x7F, 0xFF, 0xFC, 0xF6, 0xF3, +0xF7, 0xFC, 0xFF, 0x7A, 0x73, 0x6E, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6E, 0x6F, 0x74, 0x73, 0x72, +0x75, 0x7A, 0x7D, 0x7D, 0xFF, 0xFF, 0x7C, 0x7C, 0x7D, 0x7B, 0x7A, 0x79, 0x7B, 0xFF, 0xFF, 0x7D, +0x7C, 0xFF, 0xFE, 0x7D, 0xFC, 0xF3, 0xF6, 0xFC, 0xFE, 0xFE, 0xFF, 0x78, 0x75, 0x79, 0x7A, 0x7E, +0xF8, 0xF6, 0xF6, 0xF2, 0xEF, 0xEE, 0xF0, 0xF7, 0xFD, 0xFE, 0xFD, 0x7B, 0x77, 0x7C, 0xFF, 0xFB, +0xFD, 0x7D, 0xFF, 0x7C, 0x78, 0x7A, 0x7A, 0xFF, 0xF9, 0xF5, 0xF1, 0xF4, 0xFA, 0xFC, 0xFC, 0xFA, +0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFF, 0x7D, 0x7B, 0x7D, 0x7E, 0x7A, 0x76, 0x76, 0x75, +0x72, 0x75, 0x7B, 0x7D, 0x7A, 0x7A, 0x7D, 0xFF, 0x7C, 0x7C, 0xFF, 0x7D, 0x7A, 0x7B, 0x7C, 0x7E, +0xFC, 0xFC, 0x7F, 0xFE, 0xFD, 0xFE, 0xFC, 0xF8, 0xF9, 0xFA, 0xFB, 0xFE, 0x7E, 0x79, 0x72, 0x72, +0x74, 0x76, 0x78, 0x76, 0x78, 0x7A, 0x75, 0x76, 0x77, 0x75, 0x73, 0x73, 0x73, 0x73, 0x74, 0x73, +0x73, 0x77, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x73, 0x73, 0x7B, 0x7C, 0x7C, 0xFC, 0xFC, 0xFE, 0x7F, +0x76, 0x73, 0x76, 0x73, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0x7D, 0x7B, 0x7B, +0x7C, 0x7A, 0x78, 0x7B, 0x7B, 0x7D, 0x7F, 0x7A, 0x77, 0x73, 0x6F, 0x70, 0x72, 0x73, 0x72, 0x72, +0x73, 0x74, 0x74, 0x76, 0x7D, 0xFE, 0x7D, 0x7C, 0x7C, 0x78, 0x76, 0x77, 0x79, 0x7B, 0xFF, 0xFD, +0xFE, 0x7E, 0x7B, 0x7A, 0x78, 0x78, 0x7B, 0x7C, 0x7C, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x79, 0x7B, +0xFF, 0xFA, 0xF9, 0xFD, 0x7E, 0x7D, 0x7C, 0x7B, 0x7E, 0xFE, 0xFC, 0xFF, 0x7E, 0xFE, 0xFD, 0xFE, +0xFD, 0xFC, 0xFB, 0xFC, 0xFC, 0xFD, 0xF9, 0xF3, 0xF2, 0xF3, 0xF4, 0xF6, 0xF6, 0xF8, 0xFA, 0xFC, +0xFB, 0xF7, 0xF9, 0xFC, 0xFC, 0xFD, 0xFD, 0x7E, 0x7C, 0x7F, 0xFF, 0x7D, 0x7A, 0x7A, 0x7B, 0x78, +0x78, 0x78, 0x75, 0x75, 0x76, 0x79, 0x7A, 0x79, 0x7C, 0x7F, 0xFD, 0xFF, 0x7E, 0xFF, 0x7D, 0x79, +0x77, 0x78, 0x79, 0x78, 0x79, 0x7C, 0x7D, 0x7F, 0x7E, 0x7E, 0xFE, 0xFC, 0xF8, 0xF7, 0xFA, 0xFB, +0xFC, 0xFD, 0xFF, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, 0x7B, 0x7D, 0xFE, 0xF9, 0xF5, 0xF6, 0xF6, 0xF4, +0xF6, 0xFA, 0xFE, 0x7D, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFF, 0xFF, 0xFA, 0xFA, 0xFE, +0x7C, 0x75, 0x71, 0x72, 0x74, 0x75, 0x74, 0x75, 0x75, 0x77, 0x79, 0x79, 0x77, 0x74, 0x74, 0x74, +0x72, 0x71, 0x70, 0x71, 0x70, 0x6F, 0x72, 0x73, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7A, 0x78, +0x77, 0x77, 0x76, 0x74, 0x73, 0x72, 0x70, 0x71, 0x75, 0x78, 0x7B, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, +0x7E, 0xFF, 0xFD, 0x7F, 0x7C, 0x7B, 0x7F, 0xFD, 0xFF, 0xFE, 0xFC, 0xFE, 0xFD, 0xFC, 0xFA, 0xF7, +0xF7, 0xFB, 0xFD, 0xFE, 0x7E, 0x7C, 0x7B, 0x7A, 0x7B, 0x79, 0x75, 0x75, 0x76, 0x78, 0x7D, 0xFF, +0x7E, 0x7D, 0x7E, 0x7C, 0x77, 0x75, 0x76, 0x76, 0x78, 0x7E, 0xFD, 0xFB, 0xFC, 0xFD, 0xFE, 0x7C, +0x78, 0x78, 0x7A, 0x7B, 0x7E, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x78, 0x79, 0x7B, 0x7A, 0x7D, 0xFC, +0xFD, 0x7E, 0xFF, 0xFB, 0xF7, 0xF6, 0xF7, 0xF7, 0xF6, 0xFA, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0xFF, +0xFC, 0xFB, 0xF9, 0xFD, 0xFE, 0xFD, 0x7E, 0x79, 0x76, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x72, 0x76, +0x7A, 0x7E, 0xFF, 0xFF, 0x7C, 0x7B, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7E, 0xFF, 0xFF, 0x7E, 0x7D, +0x7D, 0x7E, 0x7C, 0x78, 0x79, 0x7A, 0x7B, 0xFF, 0xFF, 0x7F, 0x7E, 0x7B, 0x79, 0x79, 0x76, 0x72, +0x73, 0x7B, 0xFF, 0xFE, 0xFB, 0xFA, 0xFA, 0xFC, 0x7D, 0x78, 0x77, 0x78, 0x79, 0x79, 0x78, 0x79, +0x77, 0x73, 0x74, 0x76, 0x77, 0x79, 0x7A, 0x7B, 0x7F, 0xFD, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0x7C, +0x78, 0x78, 0x7B, 0x7B, 0x7A, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0x7E, 0xFF, 0xFD, 0xFC, 0xF9, 0xF5, +0xF2, 0xF0, 0xF2, 0xF3, 0xF0, 0xF1, 0xF2, 0xF1, 0xF4, 0xF7, 0xF8, 0xFC, 0xFC, 0xF6, 0xF3, 0xF4, +0xF5, 0xF5, 0xF6, 0xFB, 0xFF, 0xFF, 0xFF, 0x7D, 0x7D, 0x7E, 0x7D, 0x79, 0x75, 0x74, 0x75, 0x72, +0x72, 0x75, 0x75, 0x74, 0x77, 0x7A, 0x7A, 0x7A, 0x7A, 0x77, 0x74, 0x73, 0x72, 0x74, 0x75, 0x76, +0x77, 0x74, 0x74, 0x77, 0x79, 0x79, 0x79, 0x78, 0x77, 0x74, 0x70, 0x6F, 0x70, 0x6F, 0x6E, 0x6E, +0x6E, 0x6F, 0x6F, 0x72, 0x75, 0x72, 0x74, 0x79, 0x7B, 0x7B, 0x7B, 0x7D, 0xFF, 0x7E, 0x7F, 0xFE, +0xFE, 0x7F, 0x7D, 0x7D, 0xFF, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7E, 0x7C, 0x79, 0x77, 0x75, 0x76, +0x77, 0x78, 0x78, 0x74, 0x75, 0x7A, 0x7F, 0xFB, 0xF9, 0xF9, 0xF8, 0xFD, 0x7E, 0x7B, 0x76, 0x78, +0x7B, 0x7C, 0x7E, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7C, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x7D, 0x7B, +0x7B, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0x7F, 0x7F, 0xFF, 0xFD, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0x7D, +0x7C, 0x7F, 0xFB, 0xF7, 0xF6, 0xFC, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0x7C, +0x76, 0x74, 0x74, 0x79, 0x79, 0x76, 0x77, 0x79, 0x7C, 0x7D, 0x7B, 0x7B, 0x7B, 0x7E, 0xFD, 0xFB, +0xF9, 0xF9, 0xFE, 0x7C, 0x79, 0x79, 0x77, 0x76, 0x79, 0x7B, 0x7D, 0x7C, 0x7C, 0x7D, 0x7C, 0x78, +0x75, 0x74, 0x72, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0x7F, 0x7F, 0x7D, +0x7A, 0x78, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x7B, 0xFF, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, +0xF8, 0xF9, 0xFE, 0x7E, 0xFF, 0xFE, 0xFE, 0x7D, 0x7A, 0x78, 0x75, 0x75, 0x77, 0x7A, 0x7A, 0x79, +0x7B, 0x7D, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF7, +0xF8, 0xFA, 0xF8, 0xF9, 0xFC, 0xFD, 0xFD, 0xFC, 0xF9, 0xF7, 0xF8, 0xFC, 0x7E, 0x7B, 0x7A, 0x7A, +0x79, 0x79, 0x7A, 0x7A, 0x7A, 0x77, 0x72, 0x72, 0x74, 0x76, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, +0x7D, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, +0x7A, 0x7A, 0x77, 0x75, 0x75, 0x74, 0x73, 0x70, 0x6E, 0x6E, 0x6E, 0x6F, 0x72, 0x75, 0x77, 0x7A, +0x7D, 0x7D, 0x7D, 0x7E, 0xFF, 0x7D, 0x7A, 0x7A, 0x7A, 0x7B, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, +0x7D, 0x7B, 0x78, 0x75, 0x73, 0x74, 0x75, 0x75, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7D, 0xFE, 0xFC, +0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, 0xF6, 0xF8, 0xFB, 0xFC, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x7C, +0x7C, 0x7B, 0x7C, 0x7B, 0x79, 0x79, 0x7A, 0x79, 0x76, 0x74, 0x72, 0x72, 0x73, 0x74, 0x75, 0x77, +0x78, 0x78, 0x78, 0x77, 0x76, 0x75, 0x75, 0x78, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, +0xFE, 0xFC, 0xFC, 0xFC, 0xFA, 0xF8, 0xF7, 0xF7, 0xF8, 0xF7, 0xF5, 0xF5, 0xF5, 0xF4, 0xF5, 0xF6, +0xF7, 0xF8, 0xF9, 0xFB, 0xFE, 0x7F, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7D, 0x7A, 0x7A, 0x7A, +0x7A, 0x79, 0x79, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7A, 0x7A, 0x79, 0x77, 0x76, +0x77, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7B, +0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0xFE, +0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, +0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x76, 0x77, 0x78, 0x77, 0x79, +0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7D, 0x7B, 0x7B, 0x7D, 0x7C, 0x7D, 0xFF, 0x7E, +0xFF, 0xFD, 0xFB, 0xF9, 0xF8, 0xF9, 0xF9, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF3, 0xF5, 0xF6, 0xF6, +0xF7, 0xF9, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFC, 0xFB, 0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xF8, +0xF8, 0xF9, 0xFB, 0xFD, 0x7E, 0x7B, 0x78, 0x78, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x75, 0x75, +0x73, 0x71, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x6E, 0x6E, 0x6E, 0x6D, +0x6D, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x70, 0x72, 0x73, 0x74, 0x75, 0x79, 0x7C, 0x7D, 0x7E, 0xFF, +0xFF, 0xFF, 0xFD, 0xFC, 0xFA, 0xF9, 0xFB, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0x7E, 0x7B, 0x7A, +0x79, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7C, 0x7C, 0x7B, 0x79, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x7C, +0x7E, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0xFD, +0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFB, 0xFB, +0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFD, 0xFC, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF7, +0xF6, 0xF7, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7D, 0x7C, 0x7C, +0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, +0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x78, 0x77, 0x76, 0x75, 0x75, 0x75, 0x76, 0x76, 0x75, 0x76, +0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFE, +0xFD, 0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFF, 0x7F, 0x7E, 0x7C, 0x7C, 0x7B, +0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7B, +0x7A, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7B, 0x7F, 0xFD, 0x7D, 0x79, 0xFE, +0xFA, 0xFE, 0xFC, 0xF8, 0xFC, 0xFF, 0xFF, 0xFE, 0xFB, 0xFC, 0x7F, 0xFF, 0x7F, 0x7C, 0x7D, 0x7D, +0x7E, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, +0x7D, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, +0x7D, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x74, 0x73, +0x74, 0x75, 0x74, 0x74, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x77, 0x77, 0x79, 0x7B, 0x7C, 0x7D, +0x7D, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFB, 0xFC, 0xFD, +0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, +0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, +0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, +0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, +0x7D, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x77, 0x78, 0x76, 0x76, 0x78, 0x7A, 0x78, 0x78, 0x78, 0x77, +0x77, 0x76, 0x75, 0x76, 0x75, 0x75, 0x77, 0x77, 0x76, 0x74, 0x74, 0x75, 0x76, 0x75, 0x76, 0x76, +0x75, 0x76, 0x76, 0x75, 0x74, 0x73, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x78, 0x7A, 0x7A, 0x7B, +0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFD, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xFE, +0xFE, 0xFE, 0x7F, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFD, 0xFD, 0xFD, +0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0xFE, 0xFC, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF9, 0xFA, +0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0xFE, 0xFF, 0x7F, 0xFF, 0x7E, 0x7D, 0x7B, 0x79, 0x79, 0x7B, 0x7C, +0x7C, 0x7D, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x78, 0x75, 0x75, 0x76, 0x76, +0x78, 0x75, 0x76, 0x77, 0x73, 0x75, 0x73, 0x77, 0x76, 0x73, 0x78, 0x73, 0x78, 0x77, 0x75, 0x7B, +0x70, 0x7E, 0x68, 0x5B, 0xE4, 0xD9, 0x77, 0x66, 0x5F, 0x6B, 0xEB, 0x78, 0x6B, 0xEC, 0xE9, 0x67, +0x5A, 0x62, 0xF8, 0xE2, 0xF1, 0x6B, 0x6F, 0x72, 0x6E, 0x6D, 0x72, 0xEF, 0xE7, 0xF7, 0x6D, 0x6A, +0x70, 0x7B, 0xFC, 0xF5, 0xED, 0xEF, 0x7D, 0x71, 0x70, 0xFF, 0xEE, 0xEF, 0xF8, 0xFC, 0x7B, 0x73, +0x6F, 0x71, 0x7E, 0xF2, 0xF2, 0x76, 0x67, 0x68, 0x78, 0xF7, 0xF5, 0xFC, 0x7E, 0x7B, 0x73, 0x70, +0x79, 0xF4, 0xEB, 0xEC, 0xF8, 0x7C, 0x7B, 0xFF, 0xF6, 0xEF, 0xEF, 0xF4, 0xF8, 0xFE, 0x7D, 0xFE, +0xF8, 0xF4, 0xF4, 0xF9, 0xFE, 0x7E, 0x7C, 0x7C, 0xFD, 0xF8, 0xF8, 0xFD, 0x7D, 0x7A, 0x79, 0x7C, +0xFF, 0xFD, 0xFB, 0xFC, 0x7D, 0x7B, 0x7D, 0x7F, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7A, 0x79, 0x7C, +0x7E, 0x7D, 0x7D, 0x7B, 0x78, 0x79, 0x7B, 0x7A, 0x78, 0x79, 0x77, 0x76, 0x78, 0x71, 0x70, 0x78, +0x7E, 0xF6, 0xFE, 0x67, 0x68, 0xF4, 0xEF, 0x74, 0x69, 0x6A, 0xFF, 0x7E, 0x6E, 0xF2, 0xFB, 0x69, +0x66, 0x69, 0xDD, 0xD9, 0x71, 0x7B, 0x74, 0x5F, 0x69, 0x61, 0x6A, 0xE6, 0xEC, 0x66, 0x55, 0x50, +0x5C, 0xFB, 0xED, 0xF5, 0xFA, 0x6F, 0x6E, 0x7B, 0xE8, 0xCF, 0xC7, 0xC6, 0xCA, 0xCB, 0xDB, 0x3A, +0x2E, 0x49, 0xBD, 0xB7, 0xC6, 0x4D, 0x41, 0x4B, 0x49, 0x4D, 0xD9, 0xBF, 0xC2, 0xFD, 0x3F, 0x3D, +0x51, 0xDF, 0xCD, 0xCC, 0xD5, 0xF4, 0x50, 0x46, 0x4D, 0xF0, 0xCB, 0xCA, 0xDA, 0x61, 0x51, 0x52, +0x5B, 0xE6, 0xD0, 0xCE, 0xDC, 0x5D, 0x53, 0x51, 0x6A, 0xF9, 0x48, 0x67, 0xC2, 0xE0, 0x5F, 0x5B, +0x4C, 0x71, 0xFA, 0x6E, 0xCE, 0xCF, 0x7A, 0x64, 0x79, 0xD8, 0xCE, 0xD1, 0xCD, 0xC3, 0xC5, 0xCD, +0xC7, 0xDC, 0x42, 0x3E, 0x53, 0xD2, 0xC0, 0xDE, 0x44, 0x48, 0x58, 0x53, 0x59, 0xFA, 0xD9, 0xD6, +0x5E, 0x43, 0x47, 0x61, 0xE1, 0xD8, 0xEA, 0x64, 0x46, 0x3C, 0x51, 0x7F, 0x77, 0xD0, 0xF6, 0x4B, +0x4B, 0x4A, 0x6F, 0xCA, 0xC6, 0xC9, 0xC7, 0xC2, 0xC8, 0xBD, 0xB0, 0xAB, 0xBB, 0x1F, 0x19, 0x5F, +0xA3, 0xA5, 0xBA, 0x30, 0x30, 0x47, 0x31, 0x37, 0xBC, 0xAB, 0xB8, 0x3D, 0x2B, 0x30, 0x4E, 0xBD, +0xB4, 0xC4, 0x5D, 0x3F, 0x38, 0x41, 0x6E, 0xC8, 0xC1, 0xDC, 0x4B, 0x3B, 0x3F, 0xE5, 0xBF, 0xBC, +0xC8, 0xE5, 0xDE, 0xC0, 0xAE, 0xAD, 0xAF, 0xC1, 0x20, 0x1A, 0x63, 0xA8, 0xA7, 0xB5, 0x36, 0x2E, +0x3D, 0x32, 0x3F, 0xBD, 0xB1, 0xC1, 0x39, 0x2E, 0x42, 0xE8, 0xCA, 0xC3, 0xDB, 0x5F, 0x47, 0x39, +0x47, 0xD5, 0xCB, 0xD1, 0x70, 0x4B, 0x4D, 0xF0, 0xC1, 0xB3, 0xAE, 0xB4, 0xBE, 0xB8, 0xB8, 0x34, +0x1C, 0x27, 0xB6, 0xA3, 0xAC, 0x4F, 0x2C, 0x32, 0x3B, 0x3E, 0xEB, 0xB9, 0xBB, 0x45, 0x2E, 0x39, +0x60, 0xC3, 0xBB, 0xD8, 0x4D, 0x45, 0x41, 0x57, 0xD6, 0xDE, 0x79, 0x5D, 0x50, 0x5B, 0xDB, 0xBE, +0xB4, 0xB3, 0xBC, 0xC4, 0xB6, 0xAC, 0xC2, 0x26, 0x1A, 0x30, 0xAB, 0xA9, 0xBB, 0x61, 0x33, 0x30, +0x36, 0x39, 0xCF, 0xB9, 0x64, 0x41, 0x42, 0x3E, 0x5E, 0xD3, 0xCF, 0xC4, 0xEC, 0x47, 0x56, 0x5C, +0x50, 0x57, 0x62, 0xDF, 0xD2, 0xD3, 0xC4, 0xB6, 0xB3, 0xBA, 0xB8, 0xAD, 0xAF, 0x3C, 0x1C, 0x1E, +0xCB, 0xA1, 0xA9, 0xFE, 0x2D, 0x2C, 0x39, 0x3D, 0x64, 0xBE, 0xD5, 0x4B, 0x42, 0x3A, 0x40, 0xEC, +0xC4, 0xBE, 0xD1, 0x4A, 0x3E, 0x47, 0x62, 0xE4, 0xD7, 0xD6, 0xDC, 0xDE, 0xCD, 0xB6, 0xAD, 0xAE, +0xAC, 0xAD, 0xE6, 0x22, 0x19, 0x2E, 0xA6, 0x9E, 0xB2, 0x39, 0x28, 0x2D, 0x39, 0x4E, 0xC2, 0xBE, +0x5B, 0x3E, 0x3B, 0x3C, 0x58, 0xC6, 0xBD, 0xC7, 0x60, 0x3F, 0x3F, 0x51, 0xED, 0xCF, 0xC8, 0xD1, +0xE0, 0xD9, 0xBC, 0xAC, 0xAB, 0xAB, 0xA9, 0xC2, 0x25, 0x17, 0x22, 0xAE, 0x9D, 0xA9, 0x47, 0x26, +0x29, 0x34, 0x47, 0xC5, 0xBB, 0x77, 0x3F, 0x3A, 0x38, 0x4E, 0xC6, 0xBC, 0xBE, 0xE6, 0x3D, 0x39, +0x43, 0x67, 0xCE, 0xC7, 0xD6, 0xED, 0xD9, 0xBD, 0xAB, 0xAB, 0xAE, 0xA9, 0xB4, 0x30, 0x1A, 0x1B, +0xD5, 0x9D, 0xA3, 0xDA, 0x2A, 0x26, 0x31, 0x3C, 0x6C, 0xBF, 0xCE, 0x5E, 0x42, 0x32, 0x3C, 0xD6, +0xBC, 0xB8, 0xCC, 0x3F, 0x37, 0x3B, 0x51, 0xCC, 0xC1, 0xCC, 0xE2, 0xDE, 0xBD, 0xAC, 0xAA, 0xA9, +0xA7, 0xC5, 0x26, 0x18, 0x1F, 0xB7, 0x9D, 0xA6, 0xDF, 0x2B, 0x26, 0x2D, 0x37, 0xEB, 0xBA, 0xCB, +0x5E, 0x3C, 0x30, 0x44, 0xC9, 0xBB, 0xB8, 0xCF, 0x3D, 0x34, 0x3B, 0x5F, 0xC1, 0xBE, 0xCE, 0xD6, +0xCE, 0xB8, 0xAB, 0xAA, 0xA4, 0xA8, 0x42, 0x1C, 0x18, 0x31, 0xA4, 0x9F, 0xAF, 0x48, 0x29, 0x28, +0x2C, 0x37, 0xCC, 0xBA, 0xC7, 0x57, 0x30, 0x31, 0x5A, 0xC6, 0xB6, 0xB7, 0x5F, 0x38, 0x34, 0x3D, +0xE2, 0xBD, 0xBD, 0xC7, 0xD2, 0xCA, 0xB2, 0xAB, 0xA7, 0xA2, 0xB3, 0x29, 0x18, 0x1C, 0xD2, 0x9F, +0xA5, 0xBC, 0x3A, 0x2A, 0x29, 0x2A, 0x3E, 0xC3, 0xBB, 0xC1, 0x43, 0x2D, 0x3A, 0xF5, 0xC1, 0xB5, +0xBE, 0x4F, 0x36, 0x32, 0x3F, 0xD2, 0xBB, 0xBA, 0xBE, 0xC5, 0xBF, 0xB1, 0xAB, 0xA4, 0xA7, 0x75, +0x1F, 0x18, 0x27, 0xAE, 0xA2, 0xAD, 0xD6, 0x36, 0x2B, 0x28, 0x2C, 0x4E, 0xC2, 0xB8, 0xC9, 0x35, +0x2F, 0x42, 0x71, 0xBA, 0xB4, 0xD2, 0x44, 0x34, 0x34, 0x4C, 0xCD, 0xBE, 0xBB, 0xB9, 0xBC, 0xB3, +0xAE, 0xAB, 0xA3, 0xB0, 0x2C, 0x1A, 0x1C, 0x5F, 0xA4, 0xA9, 0xBA, 0x6F, 0x34, 0x28, 0x26, 0x32, +0x77, 0xB9, 0xB3, 0x5E, 0x32, 0x38, 0x40, 0xD8, 0xB6, 0xBE, 0xF4, 0x40, 0x34, 0x3A, 0x5B, 0xC7, +0xB7, 0xB4, 0xB7, 0xB4, 0xB2, 0xAE, 0xA5, 0xAB, 0x3B, 0x1D, 0x1B, 0x34, 0xAE, 0xAA, 0xB4, 0xC7, +0x42, 0x2C, 0x25, 0x2B, 0x43, 0xCF, 0xB5, 0xBE, 0x3F, 0x38, 0x3D, 0x4D, 0xC4, 0xBD, 0xCF, 0x5D, +0x3E, 0x38, 0x43, 0xE4, 0xBF, 0xB4, 0xAF, 0xB0, 0xAF, 0xAE, 0xA8, 0xA7, 0xF6, 0x21, 0x1A, 0x27, +0xBA, 0xAC, 0xB5, 0xB9, 0xE2, 0x36, 0x26, 0x25, 0x33, 0x4E, 0xBA, 0xB2, 0x64, 0x41, 0x3F, 0x3D, +0xE6, 0xC6, 0xCD, 0xD4, 0x50, 0x3D, 0x3C, 0x48, 0xD4, 0xB9, 0xAF, 0xAD, 0xAE, 0xAE, 0xAA, 0xA7, +0xC0, 0x2A, 0x1B, 0x1F, 0x65, 0xAF, 0xB5, 0xB5, 0xBF, 0x4C, 0x2C, 0x23, 0x2A, 0x37, 0xE6, 0xAF, +0xBC, 0x5B, 0x4B, 0x3B, 0x49, 0xCF, 0xCE, 0xD0, 0xDE, 0x4F, 0x40, 0x3F, 0x57, 0xC7, 0xB3, 0xAA, +0xA9, 0xAC, 0xAE, 0xA9, 0xAE, 0x3B, 0x1E, 0x1E, 0x37, 0xBA, 0xB7, 0xB7, 0xB5, 0xC9, 0x3A, 0x26, +0x27, 0x2E, 0x37, 0xC1, 0xB1, 0xCA, 0xE8, 0x49, 0x3E, 0x62, 0x78, 0xEF, 0xD7, 0x69, 0x4F, 0x44, +0x48, 0xFB, 0xC5, 0xAF, 0xA9, 0xA8, 0xAA, 0xAB, 0xAA, 0xCF, 0x26, 0x1C, 0x22, 0x4A, 0xBD, 0xBB, +0xAF, 0xB1, 0xD7, 0x31, 0x25, 0x27, 0x28, 0x38, 0xB9, 0xB6, 0xC3, 0xCB, 0x4B, 0x45, 0x4E, 0x47, +0x62, 0xE0, 0xF9, 0x5C, 0x4C, 0x5C, 0xE4, 0xBF, 0xAD, 0xA8, 0xA5, 0xA7, 0xA9, 0xB2, 0x36, 0x20, +0x1E, 0x29, 0x56, 0xCC, 0xB8, 0xAC, 0xB5, 0xFA, 0x2F, 0x28, 0x25, 0x25, 0x45, 0xBE, 0xBF, 0xB8, +0xC5, 0x5F, 0x54, 0x41, 0x43, 0x4F, 0x56, 0x75, 0x70, 0xFE, 0xE2, 0xD3, 0xB9, 0xAD, 0xA8, 0xA6, +0xA6, 0xA8, 0xCA, 0x2D, 0x22, 0x21, 0x2E, 0x47, 0x77, 0xB4, 0xAD, 0xB7, 0xDC, 0x39, 0x2D, 0x24, +0x28, 0x40, 0x5A, 0xC7, 0xB5, 0xBD, 0xC0, 0xDB, 0x4E, 0x4C, 0x40, 0x44, 0x4E, 0x56, 0xDA, 0xCC, +0xC0, 0xB1, 0xAC, 0xA7, 0xA5, 0xA6, 0xAD, 0x4F, 0x2A, 0x23, 0x25, 0x2F, 0x39, 0x6C, 0xB6, 0xB1, +0xB7, 0xD6, 0x43, 0x2F, 0x26, 0x2C, 0x35, 0x3A, 0xDF, 0xC7, 0xBE, 0xBA, 0xCB, 0xD4, 0x6E, 0x48, +0x44, 0x3E, 0x4A, 0x6C, 0xD6, 0xB9, 0xB0, 0xA8, 0xA4, 0xA5, 0xA4, 0xB5, 0x42, 0x2C, 0x23, 0x27, +0x2B, 0x2E, 0x55, 0xC2, 0xB9, 0xB6, 0xC5, 0xF4, 0x3C, 0x32, 0x34, 0x2F, 0x37, 0x4A, 0x5B, 0xCF, +0xC9, 0xC6, 0xC0, 0xCA, 0xCF, 0xF4, 0x52, 0x51, 0x4E, 0xF8, 0xC4, 0xB7, 0xAD, 0xA9, 0xA6, 0xA7, +0xB8, 0x5D, 0x38, 0x2F, 0x2E, 0x2B, 0x2C, 0x35, 0x42, 0x5D, 0x7D, 0xE3, 0xDF, 0x6F, 0x73, 0x5A, +0x4D, 0x55, 0x4F, 0x4F, 0x58, 0x5C, 0x6E, 0xFA, 0xE2, 0xD4, 0xD4, 0xD6, 0xD9, 0xD6, 0xCC, 0xC6, +0xBF, 0xBB, 0xB8, 0xB6, 0xBC, 0xC9, 0xDC, 0x60, 0x59, 0x53, 0x4A, 0x49, 0x46, 0x45, 0x46, 0x43, +0x45, 0x45, 0x49, 0x56, 0x5A, 0x5D, 0x6E, 0x72, 0x7C, 0x74, 0x6D, 0x7A, 0x7A, 0xFC, 0xED, 0xE8, +0xEB, 0xFF, 0xFD, 0xEC, 0xDE, 0xD2, 0xCC, 0xC7, 0xC5, 0xCA, 0xD2, 0xD9, 0xDB, 0xD4, 0xCF, 0xD1, +0xD9, 0xE7, 0xFC, 0x6E, 0x60, 0x57, 0x50, 0x4C, 0x49, 0x47, 0x46, 0x45, 0x47, 0x4A, 0x4D, 0x4F, +0x4F, 0x53, 0x5A, 0x5F, 0x62, 0x60, 0x62, 0x6B, 0x77, 0xEC, 0xD8, 0xCC, 0xC7, 0xC7, 0xCB, 0xCF, +0xD3, 0xD3, 0xCE, 0xCB, 0xCA, 0xCC, 0xCF, 0xD4, 0xD9, 0xDF, 0xEB, 0xFE, 0x6A, 0x58, 0x4D, 0x46, +0x43, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x52, 0x54, 0x55, 0x54, 0x57, 0x5C, 0x61, 0x72, 0xE5, +0xD4, 0xCC, 0xCB, 0xCD, 0xD0, 0xD4, 0xD3, 0xD1, 0xD0, 0xCF, 0xD1, 0xD2, 0xD4, 0xD6, 0xD9, 0xDB, +0xDB, 0xDD, 0xEC, 0x6B, 0x59, 0x53, 0x54, 0x57, 0x59, 0x58, 0x57, 0x5A, 0x5C, 0x5A, 0x55, 0x52, +0x52, 0x51, 0x51, 0x57, 0x61, 0xFC, 0xE3, 0xDF, 0xE0, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDD, 0xDE, +0xDD, 0xDF, 0xE0, 0xDF, 0xDC, 0xD9, 0xDC, 0xE7, 0x7E, 0x6B, 0x6D, 0x7C, 0xEE, 0xE6, 0xE7, 0xEA, +0xEC, 0xF5, 0x7A, 0x6A, 0x61, 0x5A, 0x51, 0x4F, 0x50, 0x55, 0x5D, 0x62, 0x63, 0x60, 0x5F, 0x61, +0x65, 0x68, 0x6D, 0x75, 0xFA, 0xF1, 0xF1, 0xEE, 0xE6, 0xDD, 0xDB, 0xDE, 0xEB, 0x79, 0x6B, 0x6F, +0xF7, 0xE2, 0xDC, 0xDB, 0xDA, 0xDA, 0xDC, 0xDD, 0xDE, 0xE0, 0xF1, 0x6B, 0x5F, 0x5F, 0x66, 0x6B, +0x6A, 0x65, 0x5E, 0x5B, 0x5A, 0x59, 0x5A, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x68, 0xFC, 0xE8, 0xE5, +0xEB, 0xFB, 0x71, 0x6D, 0x78, 0xEE, 0xE2, 0xDE, 0xDD, 0xDC, 0xDE, 0xDF, 0xDC, 0xD9, 0xD9, 0xE0, +0xED, 0xF0, 0xEC, 0xE4, 0xE2, 0xE6, 0xEE, 0x7C, 0x6D, 0x65, 0x5E, 0x5E, 0x62, 0x64, 0x61, 0x5C, +0x5B, 0x5F, 0x70, 0xF7, 0xF8, 0x78, 0x6B, 0x65, 0x61, 0x69, 0xFA, 0xE9, 0xE5, 0xE2, 0xE5, 0xEA, +0xED, 0xEB, 0xE5, 0xE5, 0xED, 0xF9, 0xFC, 0xEF, 0xE3, 0xDE, 0xDE, 0xE1, 0xE9, 0xF4, 0x74, 0x6A, +0x6B, 0x6F, 0x6F, 0x67, 0x5E, 0x5C, 0x5F, 0x6A, 0x6F, 0x6C, 0x66, 0x5F, 0x5D, 0x5E, 0x64, 0x6F, +0xFE, 0xEF, 0xEC, 0xF2, 0xFD, 0x7E, 0xFB, 0xF6, 0xFF, 0x6F, 0x6A, 0x6A, 0x74, 0xF4, 0xE9, 0xE4, +0xE7, 0xEE, 0x7D, 0x6A, 0x69, 0x6F, 0xFE, 0xF7, 0x7B, 0x6B, 0x68, 0x6E, 0x79, 0x78, 0x6F, 0x69, +0x62, 0x5F, 0x60, 0x66, 0x72, 0xF6, 0xEB, 0xEC, 0xF3, 0xFC, 0xFA, 0xF2, 0xF2, 0xFE, 0x70, 0x69, +0x69, 0x71, 0xF7, 0xE8, 0xE3, 0xE4, 0xED, 0x76, 0x69, 0x6A, 0x6F, 0x7E, 0xFB, 0x7D, 0x75, 0x73, +0x7C, 0xFB, 0xFC, 0x7D, 0x73, 0x6D, 0x6A, 0x69, 0x6F, 0xFD, 0xEC, 0xE8, 0xED, 0xF6, 0xF7, 0xF1, +0xED, 0xEF, 0xF6, 0x7E, 0x76, 0x78, 0xFB, 0xEC, 0xE2, 0xDE, 0xE0, 0xEB, 0xFE, 0x73, 0x73, 0x7E, +0xFA, 0xFC, 0xFF, 0x7B, 0x7D, 0xFC, 0xFE, 0x7B, 0x74, 0x6F, 0x6D, 0x6C, 0x6E, 0x77, 0xFA, 0xEE, +0xED, 0xF6, 0x7A, 0x73, 0x77, 0x7B, 0x7C, 0x78, 0x6E, 0x6B, 0x6F, 0x7C, 0xEF, 0xE7, 0xE2, 0xE6, +0xF2, 0x7A, 0x71, 0x75, 0x7D, 0xFE, 0xFD, 0xFD, 0xFB, 0xF5, 0xF7, 0xFE, 0x77, 0x6E, 0x6A, 0x67, +0x67, 0x6C, 0x76, 0xF7, 0xEE, 0xEF, 0xFA, 0x7B, 0x78, 0x7B, 0xFF, 0x7F, 0x78, 0x6F, 0x6C, 0x6C, +0x72, 0xFE, 0xEF, 0xEC, 0xEF, 0xFD, 0x76, 0x70, 0x71, 0x75, 0x7A, 0x7E, 0x7E, 0xFF, 0xFC, 0xFD, +0x7C, 0x73, 0x6D, 0x69, 0x65, 0x63, 0x65, 0x6B, 0x79, 0xFB, 0xFD, 0x78, 0x70, 0x70, 0x74, 0x79, +0x7C, 0x7B, 0x79, 0x77, 0x78, 0x7F, 0xF4, 0xED, 0xED, 0xF2, 0xFB, 0x7A, 0x74, 0x74, 0x76, 0x7A, +0x7F, 0xFB, 0xF5, 0xF4, 0xF6, 0xFA, 0x7D, 0x75, 0x6E, 0x6B, 0x6B, 0x6F, 0x7D, 0xF3, 0xEF, 0xF4, +0x7E, 0x78, 0x7A, 0xFF, 0xFA, 0xF7, 0xF5, 0xF4, 0xF4, 0xF1, 0xED, 0xE9, 0xE6, 0xE8, 0xEE, 0xF8, +0x7F, 0x7C, 0x7A, 0x7A, 0x7B, 0x7D, 0xFD, 0xF8, 0xF8, 0xF9, 0xFC, 0x7D, 0x74, 0x6C, 0x69, 0x69, +0x6C, 0x76, 0xFA, 0xF6, 0xFD, 0x78, 0x71, 0x6F, 0x6F, 0x6F, 0x71, 0x74, 0x77, 0x7C, 0xFD, 0xF5, +0xEC, 0xE9, 0xEA, 0xEF, 0xFB, 0x7A, 0x74, 0x73, 0x73, 0x73, 0x73, 0x78, 0x7E, 0xFE, 0xFD, 0xFE, +0x7B, 0x74, 0x6D, 0x68, 0x66, 0x69, 0x6F, 0x7B, 0x7F, 0x7C, 0x77, 0x73, 0x72, 0x6F, 0x6D, 0x6D, +0x6D, 0x6D, 0x6E, 0x72, 0x7A, 0xFA, 0xF1, 0xEE, 0xEF, 0xF6, 0xFD, 0x7D, 0x7B, 0x7A, 0x78, 0x78, +0x79, 0x79, 0x7A, 0x7C, 0x7D, 0x7E, 0x7D, 0x77, 0x70, 0x6E, 0x71, 0x79, 0x7E, 0x7E, 0x7E, 0x7D, +0x7E, 0x7D, 0x7C, 0x7A, 0x78, 0x76, 0x74, 0x73, 0x75, 0x7A, 0xFC, 0xF6, 0xF4, 0xF4, 0xF6, 0xF6, +0xF6, 0xF9, 0xF9, 0xF7, 0xF5, 0xF3, 0xF1, 0xF1, 0xF3, 0xF5, 0xF7, 0xFA, 0x7B, 0x6F, 0x6D, 0x6D, +0x6F, 0x6F, 0x6E, 0x6E, 0x70, 0x70, 0x71, 0x74, 0x78, 0x7C, 0x7D, 0x7E, 0x7D, 0xFF, 0xFB, 0xF7, +0xF4, 0xF4, 0xF6, 0xF8, 0xFB, 0xFD, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x7F, 0xFF, 0xFC, 0xF8, +0xF9, 0xFD, 0x7D, 0x7C, 0x7F, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x79, 0x76, +0x71, 0x6F, 0x6F, 0x71, 0x76, 0x78, 0x78, 0x78, 0x7B, 0x7D, 0x7A, 0x77, 0x76, 0x76, 0x78, 0x79, +0x78, 0x79, 0x7C, 0xFD, 0xF4, 0xF1, 0xF2, 0xF5, 0xF9, 0xFB, 0x7F, 0x79, 0x76, 0x76, 0x78, 0x77, +0x77, 0x7B, 0xFF, 0xFA, 0xF6, 0xF6, 0xF7, 0xF6, 0xF6, 0xF7, 0xF9, 0xFA, 0xF9, 0xF6, 0xF6, 0xF9, +0xFB, 0xFE, 0x7F, 0x7E, 0x7C, 0x79, 0x7A, 0xFE, 0xF5, 0xEF, 0xEE, 0xEF, 0xF1, 0xF3, 0xF4, 0xFB, +0x79, 0x73, 0x72, 0x6E, 0x6B, 0x68, 0x68, 0x6C, 0x73, 0x7A, 0x7C, 0x7B, 0x7B, 0x7D, 0x7D, 0xFD, +0xF6, 0xF0, 0xEE, 0xEF, 0xF6, 0xFB, 0xFF, 0x7D, 0x7F, 0x7D, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, 0x7B, +0x7A, 0xFF, 0xFD, 0xFF, 0x7E, 0x7A, 0x75, 0x74, 0x71, 0x6F, 0x6F, 0x70, 0x77, 0x7A, 0x78, 0x75, +0x72, 0x75, 0x73, 0x6F, 0x6F, 0x70, 0x75, 0x77, 0x76, 0x78, 0x75, 0x78, 0x7B, 0x7B, 0x7F, 0x7B, +0x7E, 0x7F, 0x7E, 0x7E, 0x77, 0x79, 0x73, 0x71, 0x71, 0x6B, 0x6F, 0x60, 0x5B, 0x6F, 0x72, 0x69, +0x71, 0x72, 0x7E, 0xFC, 0xF7, 0xEE, 0xF4, 0xFB, 0x7E, 0x7E, 0xFC, 0xF9, 0xFD, 0x7F, 0xFC, 0x72, +0x78, 0x64, 0x53, 0x71, 0xDF, 0xF0, 0xEB, 0xE9, 0xF0, 0x7C, 0x7B, 0xEA, 0xF6, 0x7E, 0x79, 0x6C, +0x79, 0x5F, 0x5B, 0xEC, 0xE2, 0xEF, 0xED, 0xF1, 0xF7, 0xFE, 0x7C, 0xFE, 0x75, 0x6E, 0x75, 0x79, +0x7A, 0x72, 0x6E, 0x75, 0x7A, 0x7B, 0x77, 0x77, 0xFE, 0xF8, 0xF6, 0xF5, 0xEB, 0xE9, 0xEC, 0xE8, +0xEE, 0xEC, 0xED, 0x77, 0xFD, 0x61, 0x51, 0x66, 0xE7, 0xDC, 0xD8, 0xD3, 0xD3, 0x6C, 0x52, 0x63, +0x6F, 0x73, 0x7F, 0xFB, 0xF4, 0x79, 0x7B, 0xF1, 0xED, 0xEC, 0xFA, 0x76, 0x7A, 0x74, 0x6B, 0x6B, +0x75, 0x7C, 0x7C, 0x79, 0xFE, 0xF6, 0xFE, 0x7A, 0x71, 0x75, 0xFF, 0x70, 0x6D, 0x6E, 0x69, 0x66, +0x5E, 0x62, 0xFA, 0xEA, 0xE5, 0xE0, 0xE1, 0xE5, 0xEE, 0xF1, 0xE5, 0xE4, 0xEA, 0xE8, 0xE7, 0xE7, +0xE3, 0xE7, 0xE8, 0xE8, 0xEF, 0xF7, 0x78, 0x6E, 0x6D, 0x60, 0x5A, 0x57, 0x54, 0x53, 0x51, 0x50, +0x52, 0x54, 0x57, 0x59, 0x5D, 0x67, 0x70, 0x7B, 0xF5, 0xE5, 0xDA, 0xD5, 0xD2, 0xCD, 0xC4, 0xBE, +0xBB, 0xB7, 0xB5, 0xBB, 0xCB, 0xDE, 0xE9, 0x56, 0x3F, 0x3A, 0x39, 0x3B, 0x3B, 0x3A, 0x3F, 0x4E, +0x5D, 0x69, 0xF2, 0xDD, 0xD9, 0xE2, 0xF3, 0xF4, 0x72, 0x5C, 0x53, 0x4E, 0x4D, 0x4E, 0x4E, 0x4F, +0x58, 0x7E, 0xDA, 0xCB, 0xBF, 0xBA, 0xB7, 0xB4, 0xB0, 0xAE, 0xB2, 0xBE, 0xD7, 0x70, 0x4E, 0x3B, +0x32, 0x30, 0x33, 0x35, 0x35, 0x3A, 0x49, 0x5F, 0x7E, 0xEF, 0xE1, 0xD2, 0xD1, 0xE6, 0xEF, 0xF7, +0x5F, 0x4F, 0x48, 0x48, 0x4B, 0x48, 0x4B, 0x55, 0x72, 0xE1, 0xD2, 0xC2, 0xBA, 0xB6, 0xB3, 0xB0, +0xAD, 0xAE, 0xBA, 0xD0, 0x64, 0x4C, 0x3C, 0x30, 0x2E, 0x2F, 0x33, 0x35, 0x3A, 0x47, 0x6C, 0xE6, +0xEB, 0xD0, 0xC6, 0xCC, 0xD6, 0xE3, 0xEF, 0x69, 0x4E, 0x4B, 0x4B, 0x47, 0x46, 0x48, 0x4F, 0x61, +0xFE, 0xD1, 0xBE, 0xB8, 0xB5, 0xB2, 0xAF, 0xAD, 0xAE, 0xBA, 0xCD, 0x5F, 0x47, 0x3B, 0x2F, 0x2D, +0x2E, 0x30, 0x35, 0x3B, 0x47, 0x6C, 0xF4, 0xE2, 0xCB, 0xC7, 0xCD, 0xD7, 0xDD, 0xE3, 0x6E, 0x4E, +0x4A, 0x4B, 0x48, 0x47, 0x4A, 0x5B, 0xE4, 0xD3, 0xC0, 0xB7, 0xB3, 0xB0, 0xAF, 0xAC, 0xAC, 0xB3, +0xC4, 0x7D, 0x4C, 0x3E, 0x30, 0x2C, 0x2E, 0x31, 0x35, 0x3A, 0x45, 0x62, 0xFA, 0xEB, 0xCE, 0xCA, +0xD2, 0xDA, 0xE7, 0xE9, 0x6D, 0x4C, 0x49, 0x49, 0x47, 0x48, 0x4C, 0x68, 0xD7, 0xCA, 0xBC, 0xB5, +0xB2, 0xB0, 0xAE, 0xAC, 0xAE, 0xB9, 0xCE, 0x5D, 0x45, 0x39, 0x2F, 0x2D, 0x2E, 0x31, 0x36, 0x3B, +0x47, 0x5C, 0x6E, 0xE4, 0xD3, 0xD3, 0xD4, 0xDA, 0xDE, 0xEB, 0x5B, 0x4D, 0x4A, 0x47, 0x48, 0x49, +0x54, 0xEB, 0xCE, 0xBE, 0xB8, 0xB7, 0xB3, 0xB3, 0xB5, 0xB3, 0xBB, 0xC9, 0xC8, 0xED, 0x47, 0x42, +0x3A, 0x36, 0x37, 0x34, 0x39, 0x3E, 0x3F, 0x47, 0x4E, 0x65, 0xDE, 0xEC, 0xDC, 0xCE, 0xD9, 0xEB, +0x5F, 0x54, 0x51, 0x47, 0x46, 0x4C, 0x58, 0xFC, 0xD8, 0xC4, 0xBB, 0xBA, 0xB8, 0xB5, 0xB2, 0xAF, +0xB0, 0xB6, 0xBD, 0xCC, 0x66, 0x47, 0x3B, 0x34, 0x32, 0x32, 0x34, 0x38, 0x3B, 0x3F, 0x4B, 0x58, +0x69, 0xE9, 0xD9, 0xD4, 0xDB, 0x77, 0x5C, 0x59, 0x4F, 0x4A, 0x4B, 0x51, 0x69, 0xE0, 0xCE, 0xC2, +0xBD, 0xBC, 0xBA, 0xB8, 0xB7, 0xB4, 0xB2, 0xB7, 0xC3, 0xCE, 0xD4, 0x67, 0x44, 0x3D, 0x3C, 0x3B, +0x38, 0x38, 0x3B, 0x3F, 0x42, 0x46, 0x4E, 0x5F, 0x6A, 0x6B, 0xFD, 0xF7, 0x70, 0x5C, 0x54, 0x58, +0x58, 0x53, 0x5B, 0x73, 0xE5, 0xD2, 0xCA, 0xC6, 0xC2, 0xBF, 0xBE, 0xBE, 0xBD, 0xBB, 0xBC, 0xC3, +0xCA, 0xD0, 0xE2, 0x5F, 0x4E, 0x4A, 0x44, 0x3E, 0x3D, 0x3D, 0x3F, 0x42, 0x44, 0x4B, 0x55, 0x57, +0x5F, 0x69, 0x68, 0x63, 0x58, 0x56, 0x5B, 0x56, 0x57, 0x66, 0x79, 0xE8, 0xD9, 0xCF, 0xCB, 0xCB, +0xC8, 0xC4, 0xC5, 0xC6, 0xC9, 0xC9, 0xC6, 0xCD, 0xD4, 0xD8, 0xE2, 0xF1, 0x66, 0x5C, 0x57, 0x4C, +0x49, 0x49, 0x48, 0x49, 0x49, 0x4B, 0x51, 0x51, 0x4F, 0x53, 0x56, 0x58, 0x58, 0x54, 0x58, 0x5F, +0x5E, 0x5B, 0x63, 0xF2, 0xE5, 0xE5, 0xD7, 0xCF, 0xD2, 0xD6, 0xD1, 0xCF, 0xD6, 0xD6, 0xD2, 0xCF, +0xCE, 0xD0, 0xD8, 0xDB, 0xDB, 0xE5, 0x6D, 0x67, 0x65, 0x5C, 0x58, 0x54, 0x59, 0x5D, 0x57, 0x57, +0x5B, 0x5B, 0x59, 0x56, 0x57, 0x5A, 0x56, 0x52, 0x5A, 0x5C, 0x5D, 0x7D, 0xF1, 0xF3, 0xE7, 0xE3, +0xDF, 0xDB, 0xDA, 0xE7, 0xEC, 0xDE, 0xE5, 0xE9, 0xE6, 0xE4, 0xD6, 0xDF, 0xF8, 0xDE, 0xE9, 0x7C, +0xEE, 0xFB, 0x7A, 0x6B, 0x65, 0xFF, 0x79, 0x69, 0x6B, 0x63, 0x65, 0x62, 0x56, 0x5A, 0x60, 0x55, +0x58, 0x62, 0x5E, 0x64, 0x79, 0x7C, 0x78, 0xED, 0xE1, 0xEC, 0xF0, 0xE4, 0xF0, 0x6E, 0x7C, 0xED, +0xDD, 0xDB, 0xFE, 0x73, 0xED, 0xF0, 0xFF, 0xF9, 0xDE, 0xDC, 0x76, 0x6E, 0xFB, 0x7B, 0xFB, 0x6F, +0x6F, 0xEF, 0x7B, 0x6E, 0xF8, 0xE9, 0x7E, 0x5B, 0x5F, 0xF3, 0xFD, 0x67, 0x74, 0xEA, 0xEF, 0x77, +0x6D, 0x7C, 0xE8, 0xE2, 0xEE, 0xFB, 0xE6, 0xED, 0x66, 0x6C, 0x7B, 0x7C, 0xF4, 0xEF, 0xE2, 0xE6, +0x72, 0x70, 0xF0, 0xEE, 0x6E, 0x6B, 0xFB, 0xF5, 0xF6, 0x71, 0x6A, 0x6C, 0x65, 0x67, 0x5F, 0x5D, +0x6B, 0x62, 0x65, 0xFD, 0xED, 0xE9, 0xF2, 0xED, 0xE3, 0xE7, 0xE4, 0xE8, 0xED, 0xEF, 0x66, 0x5E, +0x79, 0x7E, 0x78, 0xF5, 0xFA, 0x79, 0x7A, 0xF5, 0xE7, 0xE2, 0xE4, 0xF2, 0xFF, 0x73, 0x66, 0x6B, +0x70, 0xFD, 0xEF, 0x6F, 0x67, 0x5F, 0x5C, 0x6B, 0x6E, 0x78, 0x77, 0x6D, 0xF1, 0xF4, 0xF8, 0xE5, +0xE9, 0xEB, 0xEC, 0xEF, 0xEF, 0xF0, 0xE7, 0xED, 0x6B, 0x6F, 0xF0, 0xFF, 0x6A, 0x6F, 0x7E, 0x6F, +0x69, 0xED, 0xDF, 0xFF, 0x7C, 0xEB, 0xF3, 0xF8, 0x7E, 0x7A, 0xFB, 0x6E, 0x5E, 0x60, 0x70, 0x7A, +0xFC, 0xF4, 0xFF, 0xEF, 0xF5, 0x72, 0xF1, 0xEC, 0xEA, 0xE1, 0xE9, 0xED, 0xF2, 0xFC, 0xE7, 0xF0, +0x68, 0x76, 0xEF, 0xF4, 0xF9, 0x77, 0x79, 0xFB, 0xFC, 0xF6, 0xEE, 0xE9, 0xF2, 0x6D, 0x70, 0x6F, +0x6F, 0xFE, 0x6A, 0x69, 0x7F, 0x6F, 0x6F, 0x79, 0x78, 0x77, 0x6E, 0xFE, 0xEE, 0xF0, 0xEF, 0x7E, +0xF4, 0xE9, 0xF8, 0xFD, 0x7C, 0x77, 0x7D, 0x78, 0x7D, 0xFE, 0x79, 0x72, 0x6E, 0x72, 0x7B, 0x73, +0x6B, 0x74, 0x76, 0x6C, 0x72, 0x70, 0x75, 0x6D, 0x5A, 0x5C, 0x6A, 0x77, 0xFE, 0x71, 0x7A, 0xF2, +0xE9, 0xE7, 0xEA, 0xDE, 0xE6, 0xF5, 0xEB, 0xF5, 0xEE, 0xEA, 0xF3, 0xEE, 0xF4, 0xEE, 0xF5, 0x73, +0xF4, 0xF6, 0x73, 0x7C, 0xEC, 0xE9, 0x72, 0x67, 0x6C, 0x70, 0x6E, 0x69, 0x6F, 0x68, 0x5D, 0x64, +0x71, 0x75, 0x6B, 0x6D, 0xF9, 0x79, 0x6F, 0xF4, 0xEA, 0xF5, 0x79, 0x7B, 0x7D, 0xFA, 0xF3, 0xF7, +0xF4, 0xF4, 0xF9, 0x7F, 0x77, 0x7F, 0xF5, 0xFD, 0x71, 0x71, 0x7B, 0x78, 0x7A, 0x73, 0x68, 0x71, +0x7A, 0x6B, 0x6C, 0x6E, 0x69, 0x6E, 0x71, 0x6C, 0x69, 0x6C, 0x7A, 0x7D, 0xF6, 0xEB, 0xF4, 0xF2, +0xF4, 0x78, 0xF8, 0xF1, 0xF6, 0xFE, 0x71, 0x75, 0x7C, 0x7B, 0x7D, 0x7E, 0xFB, 0x7E, 0x77, 0x76, +0xFF, 0xF7, 0x79, 0x70, 0x6E, 0x6C, 0x71, 0x6F, 0x6C, 0x6A, 0x70, 0x6E, 0x5F, 0x65, 0x6C, 0x66, +0x6D, 0x7A, 0xF1, 0x78, 0x6B, 0xED, 0xFB, 0x6C, 0x7C, 0x74, 0xF1, 0xEC, 0x76, 0xF9, 0xF8, 0x75, +0x71, 0x7A, 0xEC, 0xFA, 0x6C, 0x76, 0x7C, 0x7F, 0x6E, 0x6A, 0x76, 0x6C, 0x76, 0xF2, 0x7C, 0x76, +0x66, 0x62, 0x7D, 0xF9, 0x78, 0x69, 0x6A, 0xF8, 0x78, 0x6D, 0xFC, 0xF8, 0xF3, 0xF7, 0x7D, 0xEF, +0xF1, 0x7C, 0xF1, 0xE9, 0xEB, 0xEE, 0xF3, 0xFD, 0x73, 0x7D, 0xFA, 0x74, 0x78, 0x7A, 0x6E, 0x70, +0x76, 0x73, 0x6F, 0x6D, 0x6C, 0x68, 0x6D, 0x7D, 0x6E, 0x64, 0x6D, 0xFC, 0xFA, 0x71, 0x6F, 0xFF, +0x70, 0x70, 0xF0, 0xEE, 0xEF, 0xEB, 0xEC, 0xEC, 0xED, 0xF0, 0xEE, 0xE9, 0xEB, 0xF8, 0xFB, 0xED, +0xE9, 0xF7, 0xFF, 0xED, 0xEE, 0xEF, 0xF3, 0x6E, 0x70, 0xF3, 0xFF, 0x6F, 0x6F, 0x6F, 0x79, 0x7C, +0x79, 0x7E, 0x77, 0x6E, 0x6E, 0x7B, 0x7C, 0x6B, 0x72, 0xF6, 0xFF, 0x7D, 0x7D, 0x72, 0x78, 0xFB, +0xFD, 0xFB, 0xFA, 0x7D, 0x7A, 0x6D, 0x68, 0x74, 0x75, 0xF1, 0xE7, 0x7B, 0x76, 0x6B, 0x66, 0xFD, +0x73, 0x68, 0x6B, 0x73, 0x7C, 0x62, 0x64, 0x70, 0x64, 0x6D, 0x79, 0x70, 0x70, 0x74, 0xF8, 0x7C, +0x7C, 0xF8, 0x6B, 0x70, 0xF9, 0x7D, 0xF1, 0xF0, 0xFF, 0x7F, 0xF8, 0xED, 0xF2, 0xFC, 0xFF, 0x76, +0x7B, 0x7C, 0xFE, 0xFE, 0x6C, 0x7C, 0xED, 0x79, 0x77, 0x71, 0x69, 0x76, 0x7A, 0x76, 0x7A, 0x6F, +0x6E, 0x6E, 0x73, 0xFF, 0x78, 0x76, 0x7F, 0x7A, 0x6F, 0x78, 0xFE, 0x77, 0xFB, 0xEE, 0xEE, 0xF1, +0x7A, 0xFB, 0xEE, 0x75, 0x70, 0xFE, 0x7D, 0x72, 0x6D, 0x6F, 0x7B, 0xFB, 0xF9, 0x7C, 0x7E, 0x7A, +0x70, 0x76, 0x7B, 0xF7, 0xF5, 0x70, 0x74, 0xFF, 0x78, 0xFA, 0xFC, 0x79, 0x78, 0x6D, 0x7A, 0xFA, +0x77, 0xFC, 0xF4, 0xF1, 0xF1, 0xF7, 0xEB, 0xED, 0xFB, 0xF7, 0xEF, 0xF2, 0x78, 0x79, 0xF0, 0xF3, +0xFC, 0xFC, 0x7E, 0x77, 0xFF, 0xFC, 0x78, 0xF6, 0xF9, 0x6F, 0x7A, 0x78, 0x6F, 0xFF, 0xF9, 0x7E, +0x76, 0x72, 0x76, 0x78, 0x79, 0xFD, 0xFA, 0x7A, 0x7E, 0xF1, 0xFB, 0x7A, 0xF2, 0xEF, 0xFF, 0x74, +0x75, 0x7E, 0xFF, 0xF6, 0xE9, 0xF4, 0x71, 0x74, 0x74, 0x7C, 0xF8, 0x79, 0x75, 0x74, 0x73, 0xF9, +0xFE, 0xFF, 0xFA, 0x6A, 0x6C, 0xFE, 0x70, 0x72, 0x7C, 0x7D, 0x70, 0x67, 0x6F, 0x76, 0x7B, 0xF0, +0x7E, 0x6E, 0x6E, 0x76, 0xF1, 0xF2, 0x7A, 0x72, 0x7B, 0xFD, 0x79, 0x77, 0x6E, 0x6A, 0x6D, 0x6E, +0x74, 0x72, 0x77, 0xF5, 0x7C, 0x6D, 0x6C, 0x6D, 0x70, 0x76, 0xFD, 0xFC, 0xFF, 0xFE, 0xFE, 0xFA, +0x7D, 0x77, 0x74, 0x6F, 0xFB, 0xFA, 0x71, 0xFC, 0xF8, 0xFE, 0xEB, 0xE5, 0xEE, 0x7F, 0xF6, 0xED, +0xFA, 0x78, 0xF6, 0xF1, 0xF8, 0xF6, 0x79, 0x70, 0x7C, 0x75, 0x78, 0xF6, 0xFA, 0xFC, 0xFB, 0x7B, +0x7D, 0xF9, 0xF7, 0xF7, 0x7E, 0x6B, 0x68, 0xFA, 0xE6, 0xEE, 0x7B, 0x7B, 0x79, 0x7E, 0xFB, 0xF2, +0xEA, 0xEE, 0xF1, 0xF6, 0x79, 0xFB, 0xF0, 0xFB, 0xFF, 0xF0, 0xEE, 0xF4, 0xEF, 0xFB, 0x6F, 0x6C, +0x72, 0xFF, 0x71, 0x6C, 0x6A, 0x6D, 0xF4, 0xFB, 0x7C, 0xF3, 0xFA, 0xFC, 0x6F, 0x73, 0xFB, 0x72, +0x7D, 0x78, 0x76, 0xEF, 0xF3, 0x7C, 0x71, 0xFA, 0xF2, 0xFB, 0xEF, 0xF0, 0xEA, 0xFD, 0x6B, 0xED, +0xF2, 0x77, 0x6E, 0x6D, 0xFD, 0x64, 0xF3, 0xDF, 0x5C, 0x61, 0xED, 0xF2, 0x7E, 0x66, 0x73, 0x6E, +0x66, 0xFF, 0x6F, 0x72, 0x70, 0x66, 0xF3, 0xF7, 0x6F, 0x72, 0x75, 0xED, 0xEF, 0xF4, 0xED, 0xEF, +0xEF, 0x6E, 0x6F, 0xF7, 0x72, 0x7E, 0x78, 0x6F, 0xF9, 0x77, 0xFC, 0xF4, 0x6C, 0x66, 0x6A, 0x76, +0x65, 0x5C, 0x6D, 0xFF, 0xF8, 0xEA, 0xE2, 0xEF, 0x65, 0x70, 0xEB, 0xE8, 0xE2, 0xDF, 0xDA, 0xD9, +0xE3, 0xF0, 0xFA, 0xE6, 0xDD, 0xDF, 0xDF, 0xE0, 0xE4, 0xFC, 0x63, 0x60, 0x64, 0x63, 0x66, 0x78, +0x65, 0x57, 0x60, 0x67, 0x64, 0x67, 0x5F, 0x6E, 0xF3, 0x7F, 0x75, 0xFE, 0xEA, 0xF4, 0xF8, 0xE0, +0xE0, 0xE4, 0xE3, 0xE7, 0xEA, 0xFB, 0x6F, 0x6E, 0x75, 0x72, 0x68, 0x6E, 0x77, 0x74, 0x6D, 0x73, +0xF9, 0x74, 0xF2, 0xE2, 0xEF, 0xDE, 0xDD, 0x79, 0xFD, 0xF4, 0x6F, 0x6A, 0x6E, 0xFE, 0x7A, 0x68, +0x60, 0x63, 0x6B, 0x66, 0x67, 0x76, 0xFE, 0x78, 0x65, 0x63, 0x7A, 0xFF, 0x72, 0x72, 0x74, 0x7D, +0x7C, 0x6B, 0x72, 0xEF, 0xF6, 0x73, 0x74, 0x7C, 0x74, 0x68, 0x68, 0x73, 0xFA, 0xF6, 0x6F, 0x67, +0x6F, 0x6D, 0x6A, 0x69, 0x68, 0x74, 0x6D, 0x64, 0x6F, 0x75, 0x77, 0xFA, 0x7F, 0xF5, 0xEF, 0x78, +0x77, 0x7D, 0x7A, 0xFE, 0x77, 0x73, 0xF8, 0xF4, 0xFE, 0x6F, 0x71, 0xF7, 0x74, 0x79, 0xEF, 0x7B, +0xF9, 0xFA, 0x68, 0x71, 0x7F, 0x76, 0x73, 0x71, 0x7D, 0x7D, 0x65, 0x5D, 0x69, 0x6E, 0x5F, 0x67, +0x6F, 0x6D, 0xFF, 0x7F, 0x6E, 0x6F, 0x73, 0x77, 0xF2, 0xDE, 0xD4, 0xD0, 0xD0, 0xCF, 0xCE, 0xD0, +0xD2, 0xD6, 0xDA, 0xDB, 0xE7, 0x6D, 0x5B, 0x52, 0x4C, 0x47, 0x44, 0x43, 0x44, 0x47, 0x49, 0x4B, +0x4E, 0x52, 0x56, 0x5A, 0x5D, 0x64, 0x75, 0xE6, 0xCF, 0xC5, 0xBF, 0xBD, 0xBB, 0xB7, 0xB5, 0xB1, +0xAF, 0xB5, 0xC1, 0xDF, 0x51, 0x44, 0x3A, 0x33, 0x33, 0x37, 0x3D, 0x44, 0x48, 0x4D, 0x51, 0x54, +0x53, 0x4D, 0x49, 0x44, 0x43, 0x45, 0x46, 0x4C, 0x54, 0x65, 0xE4, 0xCF, 0xC4, 0xBB, 0xB4, 0xAF, +0xAD, 0xAC, 0xAA, 0xAB, 0xB5, 0xD1, 0x49, 0x3B, 0x35, 0x2F, 0x2D, 0x32, 0x3D, 0x4E, 0x57, 0x51, +0x4F, 0x50, 0x4C, 0x42, 0x3D, 0x3F, 0x46, 0x4A, 0x4F, 0x5E, 0xEC, 0xD9, 0xDA, 0xD2, 0xC8, 0xBE, +0xB7, 0xB0, 0xAD, 0xAB, 0xA9, 0xA8, 0xAD, 0xC4, 0x48, 0x36, 0x31, 0x2E, 0x2D, 0x30, 0x3E, 0x67, +0xE2, 0x63, 0x47, 0x43, 0x42, 0x39, 0x36, 0x3B, 0x46, 0x6B, 0xE1, 0xDB, 0xCC, 0xC8, 0xCC, 0xD7, +0xDD, 0xC6, 0xBA, 0xB2, 0xAC, 0xAA, 0xA7, 0xA7, 0xB0, 0x69, 0x32, 0x2D, 0x2D, 0x2C, 0x2D, 0x39, +0xF1, 0xC2, 0xCA, 0x5E, 0x3D, 0x38, 0x34, 0x2E, 0x2F, 0x3E, 0x69, 0xCC, 0xC3, 0xBD, 0xBD, 0xC2, +0xCD, 0xEC, 0xF4, 0xCD, 0xC0, 0xB7, 0xAC, 0xA7, 0xA4, 0xA4, 0xB7, 0x3A, 0x2A, 0x29, 0x2A, 0x2B, +0x30, 0x56, 0xBA, 0xB6, 0xCD, 0x4A, 0x33, 0x2C, 0x2C, 0x2B, 0x34, 0x65, 0xC3, 0xBB, 0xBB, 0xBC, +0xC1, 0xDA, 0x7F, 0x6A, 0x75, 0xD1, 0xC2, 0xB8, 0xAC, 0xA6, 0xA5, 0xA4, 0xB0, 0x35, 0x23, 0x25, +0x29, 0x2F, 0x38, 0x73, 0xB3, 0xAF, 0xC8, 0x3E, 0x2E, 0x29, 0x26, 0x2C, 0x3D, 0xDF, 0xB8, 0xB5, +0xBB, 0xC5, 0xE7, 0x5A, 0x53, 0x68, 0xD9, 0xC8, 0xBA, 0xB3, 0xAD, 0xA8, 0xA7, 0xA6, 0xAF, 0x34, +0x1F, 0x24, 0x2E, 0x3B, 0x48, 0xDA, 0xB3, 0xB0, 0xD6, 0x33, 0x29, 0x29, 0x29, 0x2F, 0x5B, 0xC3, +0xB9, 0xB8, 0xC1, 0xDB, 0x53, 0x46, 0x4E, 0xEE, 0xCB, 0xC5, 0xBF, 0xBA, 0xB6, 0xAE, 0xAA, 0xA8, +0xAA, 0xDB, 0x26, 0x20, 0x2B, 0x3E, 0x5E, 0xEE, 0xC1, 0xB6, 0xC1, 0x3F, 0x2A, 0x29, 0x2A, 0x2F, +0x4F, 0xCA, 0xC0, 0xBE, 0xC5, 0xDC, 0x51, 0x44, 0x4B, 0x7D, 0xCB, 0xC5, 0xC5, 0xC2, 0xBF, 0xBD, +0xB1, 0xA9, 0xA8, 0xAA, 0xCB, 0x28, 0x20, 0x2C, 0x44, 0x7E, 0xDE, 0xC8, 0xBB, 0xC6, 0x3F, 0x2B, +0x29, 0x2E, 0x35, 0x4C, 0xCB, 0xBF, 0xC3, 0xCA, 0xE6, 0x4E, 0x43, 0x44, 0x6A, 0xC8, 0xC3, 0xC3, +0xC8, 0xC8, 0xBE, 0xB5, 0xAB, 0xA7, 0xA8, 0xBC, 0x2D, 0x1F, 0x29, 0x42, 0xD7, 0xD0, 0xCD, 0xBF, +0xC5, 0x4C, 0x2E, 0x2B, 0x2F, 0x36, 0x4A, 0xD7, 0xBE, 0xBD, 0xD5, 0x74, 0x50, 0x42, 0x45, 0x53, +0xD1, 0xBE, 0xBE, 0xC5, 0xD2, 0xCD, 0xBC, 0xAE, 0xA7, 0xA7, 0xB5, 0x36, 0x21, 0x28, 0x41, 0xD1, +0xC9, 0xD4, 0xCB, 0xCB, 0x51, 0x31, 0x2B, 0x2F, 0x39, 0x47, 0xE9, 0xC5, 0xC0, 0xCD, 0xED, 0x50, +0x3F, 0x3F, 0x52, 0xCD, 0xBB, 0xBC, 0xC6, 0xDE, 0xE7, 0xCB, 0xB5, 0xA8, 0xA4, 0xA9, 0xCC, 0x28, +0x20, 0x2E, 0x6F, 0xC2, 0xCF, 0xF7, 0xDA, 0xEB, 0x3F, 0x2E, 0x2D, 0x34, 0x3E, 0x5D, 0xCD, 0xBF, +0xC7, 0x73, 0x53, 0x43, 0x3C, 0x49, 0xDD, 0xBC, 0xB7, 0xC2, 0xE4, 0x62, 0xEC, 0xBD, 0xAA, 0xA3, +0xA4, 0xB3, 0x32, 0x1F, 0x26, 0x42, 0xC3, 0xC0, 0xF2, 0x68, 0x73, 0x4D, 0x37, 0x2D, 0x2F, 0x39, +0x47, 0xDD, 0xC2, 0xBE, 0xD2, 0x4A, 0x3E, 0x3B, 0x42, 0xEB, 0xBE, 0xB5, 0xB9, 0xD5, 0x54, 0x54, +0xCB, 0xAD, 0xA3, 0xA2, 0xAC, 0x4D, 0x23, 0x21, 0x34, 0xCF, 0xBA, 0xD0, 0x5E, 0x73, 0x5D, 0x43, +0x34, 0x30, 0x38, 0x3C, 0x46, 0xCE, 0xB9, 0xBE, 0x5F, 0x3E, 0x3B, 0x3E, 0x62, 0xC0, 0xB5, 0xB6, +0xC9, 0x54, 0x48, 0xE3, 0xB1, 0xA4, 0xA0, 0xA6, 0xC3, 0x2B, 0x1E, 0x29, 0x5D, 0xB9, 0xBD, 0x72, +0x50, 0x5B, 0x50, 0x3C, 0x30, 0x30, 0x36, 0x3F, 0x7C, 0xC0, 0xBA, 0xD0, 0x45, 0x3A, 0x38, 0x46, +0xCB, 0xB7, 0xB5, 0xC4, 0x5A, 0x48, 0x62, 0xBA, 0xA8, 0xA1, 0xA3, 0xB0, 0x3C, 0x20, 0x20, 0x39, +0xBD, 0xB1, 0xC7, 0x4F, 0x4A, 0x4E, 0x48, 0x35, 0x2E, 0x31, 0x39, 0x56, 0xC0, 0xB8, 0xC2, 0x4D, +0x39, 0x37, 0x3E, 0xE2, 0xBC, 0xB6, 0xBB, 0xDC, 0x4B, 0x4A, 0xD3, 0xAE, 0xA3, 0xA0, 0xA8, 0xD5, +0x29, 0x1F, 0x2B, 0xE3, 0xB3, 0xBA, 0x65, 0x47, 0x4C, 0x4F, 0x3D, 0x2F, 0x2D, 0x30, 0x41, 0xCB, +0xB7, 0xBA, 0x76, 0x3D, 0x38, 0x39, 0x51, 0xC5, 0xB6, 0xB6, 0xCC, 0x50, 0x46, 0x7E, 0xB4, 0xA6, +0xA1, 0xA4, 0xB8, 0x35, 0x20, 0x25, 0x48, 0xB8, 0xB5, 0xDB, 0x47, 0x47, 0x52, 0x4A, 0x34, 0x2D, +0x2E, 0x39, 0xEC, 0xBA, 0xB6, 0xCF, 0x3F, 0x38, 0x37, 0x41, 0xD0, 0xB8, 0xB4, 0xBF, 0x6A, 0x4A, +0x5B, 0xBC, 0xA8, 0xA1, 0xA2, 0xAF, 0x3E, 0x22, 0x24, 0x3E, 0xBA, 0xB3, 0xD4, 0x45, 0x41, 0x4F, +0x52, 0x37, 0x2D, 0x2D, 0x36, 0x65, 0xBB, 0xB6, 0xC9, 0x46, 0x38, 0x35, 0x3D, 0xDC, 0xB7, 0xB0, +0xBA, 0xF0, 0x48, 0x4E, 0xC1, 0xAA, 0xA2, 0xA1, 0xAB, 0x5E, 0x27, 0x21, 0x32, 0xC7, 0xB4, 0xC8, +0x48, 0x3E, 0x4B, 0x58, 0x3D, 0x2E, 0x2C, 0x2F, 0x48, 0xBF, 0xB5, 0xBF, 0x4C, 0x36, 0x34, 0x3A, +0x67, 0xBC, 0xB2, 0xB7, 0xD6, 0x4C, 0x4A, 0xCE, 0xAD, 0xA3, 0xA0, 0xA7, 0xD8, 0x29, 0x20, 0x2F, +0xD2, 0xB5, 0xC4, 0x4C, 0x40, 0x4B, 0x64, 0x44, 0x2F, 0x2C, 0x2D, 0x3F, 0xC4, 0xB4, 0xB9, 0x5F, +0x39, 0x36, 0x39, 0x5D, 0xBE, 0xB3, 0xB4, 0xC8, 0x59, 0x4B, 0xDC, 0xAF, 0xA3, 0x9F, 0xA5, 0xC5, +0x2C, 0x21, 0x2C, 0xFB, 0xB9, 0xC1, 0x53, 0x42, 0x4A, 0x5F, 0x49, 0x31, 0x2C, 0x2C, 0x3A, 0xCF, +0xB6, 0xBA, 0xF7, 0x3E, 0x39, 0x3A, 0x4C, 0xCA, 0xB7, 0xB4, 0xBF, 0x79, 0x4D, 0xE5, 0xB1, 0xA4, +0x9F, 0xA4, 0xC6, 0x2B, 0x20, 0x2C, 0xEC, 0xB7, 0xC1, 0x57, 0x43, 0x49, 0x5C, 0x47, 0x31, 0x2C, +0x2C, 0x39, 0xD3, 0xB7, 0xBA, 0xDC, 0x46, 0x3C, 0x39, 0x47, 0xCE, 0xB9, 0xB5, 0xBD, 0xDE, 0x5E, +0xD3, 0xB0, 0xA4, 0xA0, 0xA6, 0xCF, 0x2A, 0x21, 0x2D, 0xF6, 0xBB, 0xC8, 0x55, 0x44, 0x48, 0x51, +0x3F, 0x2F, 0x2C, 0x2D, 0x3B, 0xD8, 0xBC, 0xBF, 0xE7, 0x4E, 0x45, 0x3C, 0x44, 0xEB, 0xBE, 0xB5, +0xBA, 0xCA, 0xE3, 0xC9, 0xAF, 0xA5, 0xA0, 0xA7, 0xE6, 0x28, 0x22, 0x2E, 0xEA, 0xBD, 0xC8, 0x5D, +0x46, 0x4A, 0x4D, 0x3B, 0x2F, 0x2D, 0x2F, 0x3F, 0xD0, 0xBE, 0xC3, 0xE6, 0x56, 0x4B, 0x43, 0x4C, +0xFA, 0xC8, 0xBB, 0xBB, 0xC3, 0xC8, 0xBD, 0xAE, 0xA7, 0xA3, 0xAA, 0x6C, 0x2A, 0x25, 0x30, 0x5A, +0xCD, 0xD3, 0x5F, 0x4D, 0x50, 0x4C, 0x3B, 0x2F, 0x2D, 0x2F, 0x3D, 0xE6, 0xCC, 0xD3, 0xDA, 0xDB, +0x79, 0x55, 0x56, 0x68, 0xE0, 0xCA, 0xC2, 0xC0, 0xBC, 0xB1, 0xAB, 0xA6, 0xA5, 0xAE, 0x53, 0x2C, +0x29, 0x30, 0x41, 0x59, 0x62, 0x53, 0x57, 0x7F, 0x5D, 0x40, 0x35, 0x2E, 0x2F, 0x3D, 0x58, 0x78, +0xE5, 0xCD, 0xC8, 0xCF, 0xDA, 0xEC, 0x7B, 0xE4, 0xD1, 0xCA, 0xC4, 0xBA, 0xB0, 0xAC, 0xAA, 0xAB, +0xBA, 0x4F, 0x39, 0x39, 0x3D, 0x3F, 0x42, 0x3D, 0x3C, 0x45, 0x51, 0x52, 0x4C, 0x42, 0x3B, 0x3E, +0x4A, 0x4C, 0x4D, 0x57, 0x69, 0xEE, 0xDE, 0xE4, 0xFD, 0xED, 0xDC, 0xD3, 0xCD, 0xCA, 0xC3, 0xBD, +0xB9, 0xB6, 0xB8, 0xC3, 0xCE, 0xC8, 0xC1, 0xC5, 0xCE, 0xF9, 0x4A, 0x3F, 0x3F, 0x41, 0x3F, 0x3D, +0x39, 0x38, 0x3B, 0x3C, 0x3A, 0x3C, 0x43, 0x4C, 0x52, 0x58, 0x5B, 0x59, 0x65, 0xDC, 0xCB, 0xC3, +0xBD, 0xB8, 0xB6, 0xB2, 0xAF, 0xB2, 0xB6, 0xB2, 0xB0, 0xB6, 0xBF, 0xD7, 0x4F, 0x40, 0x3F, 0x3D, +0x3A, 0x35, 0x2F, 0x2D, 0x2F, 0x32, 0x33, 0x34, 0x39, 0x3E, 0x46, 0x51, 0x59, 0x5C, 0x6F, 0xD8, +0xC6, 0xBD, 0xB8, 0xB4, 0xB2, 0xAF, 0xAC, 0xAD, 0xAF, 0xAE, 0xAE, 0xB2, 0xBC, 0xCF, 0x55, 0x42, +0x3E, 0x3B, 0x36, 0x31, 0x2D, 0x2A, 0x2B, 0x2F, 0x32, 0x33, 0x36, 0x3B, 0x40, 0x4A, 0x57, 0x69, +0xEE, 0xD6, 0xC8, 0xBF, 0xB9, 0xB3, 0xB1, 0xAF, 0xAC, 0xAB, 0xAE, 0xAF, 0xAF, 0xB1, 0xB9, 0xC6, +0x75, 0x46, 0x3D, 0x3A, 0x36, 0x30, 0x2D, 0x2B, 0x2A, 0x2D, 0x31, 0x34, 0x36, 0x39, 0x3E, 0x46, +0x56, 0x77, 0xE3, 0xD4, 0xCA, 0xC3, 0xBD, 0xB6, 0xB1, 0xAF, 0xAC, 0xAB, 0xAC, 0xAF, 0xAF, 0xB0, +0xB5, 0xBE, 0xDA, 0x4E, 0x3E, 0x3A, 0x36, 0x31, 0x2D, 0x2C, 0x2B, 0x2C, 0x2F, 0x32, 0x34, 0x38, +0x3D, 0x43, 0x4D, 0x66, 0xE7, 0xD6, 0xCB, 0xC5, 0xC0, 0xBA, 0xB3, 0xAF, 0xAD, 0xAB, 0xAC, 0xAE, +0xAF, 0xAF, 0xB3, 0xBB, 0xCD, 0x5A, 0x40, 0x3A, 0x36, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2F, 0x31, +0x32, 0x38, 0x3D, 0x41, 0x4B, 0x5C, 0xF8, 0xD8, 0xCA, 0xC3, 0xBF, 0xBA, 0xB4, 0xB0, 0xAD, 0xAB, +0xAB, 0xAE, 0xAF, 0xB0, 0xB3, 0xBA, 0xC9, 0x68, 0x46, 0x3C, 0x37, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, +0x2F, 0x30, 0x31, 0x36, 0x3C, 0x3F, 0x49, 0x58, 0x70, 0xDD, 0xCA, 0xC2, 0xBE, 0xB9, 0xB3, 0xB0, +0xAD, 0xAA, 0xAB, 0xAE, 0xAF, 0xAF, 0xB4, 0xBC, 0xCB, 0x61, 0x46, 0x3D, 0x36, 0x30, 0x2E, 0x2C, +0x2B, 0x2D, 0x2F, 0x2F, 0x31, 0x37, 0x3B, 0x3F, 0x4B, 0x5C, 0xFF, 0xD8, 0xC8, 0xC1, 0xBC, 0xB6, +0xB2, 0xAF, 0xAC, 0xAA, 0xAB, 0xAD, 0xAE, 0xAF, 0xB5, 0xBD, 0xCF, 0x5C, 0x45, 0x3C, 0x35, 0x2F, +0x2D, 0x2C, 0x2C, 0x2D, 0x2F, 0x2F, 0x32, 0x37, 0x3B, 0x3F, 0x4B, 0x5F, 0xEE, 0xD4, 0xC8, 0xC1, +0xBC, 0xB5, 0xB0, 0xAE, 0xAB, 0xAA, 0xAB, 0xAD, 0xAF, 0xB1, 0xB7, 0xC0, 0xD9, 0x53, 0x42, 0x3B, +0x34, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x30, 0x33, 0x37, 0x3C, 0x43, 0x4D, 0x5E, 0xEC, 0xD0, +0xC7, 0xC0, 0xBB, 0xB6, 0xB0, 0xAE, 0xAB, 0xAA, 0xAC, 0xAE, 0xAF, 0xB3, 0xB9, 0xC5, 0xE2, 0x4E, +0x3F, 0x39, 0x32, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x2F, 0x33, 0x39, 0x3D, 0x44, 0x4F, 0x65, +0xE3, 0xCE, 0xC5, 0xBF, 0xBA, 0xB4, 0xAF, 0xAD, 0xAA, 0xAA, 0xAC, 0xAE, 0xB0, 0xB5, 0xBB, 0xC8, +0xF8, 0x4C, 0x3E, 0x38, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2E, 0x2F, 0x31, 0x35, 0x39, 0x3E, 0x4A, +0x5C, 0xF9, 0xD8, 0xCB, 0xC2, 0xBC, 0xB7, 0xB2, 0xAE, 0xAB, 0xA9, 0xAA, 0xAC, 0xAE, 0xB2, 0xB8, +0xBE, 0xCE, 0x72, 0x48, 0x3B, 0x34, 0x2F, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x36, 0x3A, +0x3E, 0x4A, 0x5F, 0xEA, 0xD0, 0xC9, 0xC1, 0xBB, 0xB5, 0xB0, 0xAE, 0xAB, 0xA9, 0xAB, 0xAC, 0xAE, +0xB4, 0xBB, 0xC4, 0xD6, 0x60, 0x45, 0x39, 0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x32, +0x35, 0x3A, 0x43, 0x51, 0x6A, 0xDF, 0xCB, 0xC3, 0xBD, 0xB8, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, +0xAC, 0xAF, 0xB7, 0xBD, 0xCC, 0xF1, 0x51, 0x3F, 0x36, 0x2F, 0x2D, 0x2B, 0x2A, 0x2C, 0x2D, 0x2E, +0x2F, 0x33, 0x37, 0x3B, 0x45, 0x58, 0x77, 0xD5, 0xC8, 0xC0, 0xBB, 0xB6, 0xB1, 0xAE, 0xAB, 0xA9, +0xAA, 0xAB, 0xAC, 0xB1, 0xB9, 0xC0, 0xD3, 0x6A, 0x4A, 0x3C, 0x33, 0x2E, 0x2D, 0x2B, 0x2B, 0x2C, +0x2D, 0x2E, 0x31, 0x34, 0x38, 0x3F, 0x4C, 0x5D, 0xEA, 0xCE, 0xC6, 0xBE, 0xB8, 0xB4, 0xAF, 0xAD, +0xAB, 0xAA, 0xAA, 0xAB, 0xAD, 0xB2, 0xB9, 0xC3, 0xD8, 0x61, 0x47, 0x3A, 0x32, 0x2E, 0x2C, 0x2B, +0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x38, 0x3F, 0x4D, 0x62, 0xDD, 0xCC, 0xC3, 0xBC, 0xB7, 0xB2, +0xAE, 0xAC, 0xAA, 0xAA, 0xAA, 0xAB, 0xAE, 0xB3, 0xBA, 0xC6, 0xE1, 0x55, 0x41, 0x37, 0x30, 0x2D, +0x2B, 0x2A, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x39, 0x40, 0x4D, 0x6A, 0xD8, 0xC9, 0xC1, 0xBC, +0xB7, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, 0xAC, 0xAF, 0xB7, 0xBB, 0xC6, 0x79, 0x55, 0x44, 0x37, +0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2D, 0x2F, 0x33, 0x35, 0x39, 0x42, 0x51, 0x6C, 0xDA, 0xCA, +0xC4, 0xBE, 0xBA, 0xB6, 0xB0, 0xAD, 0xAC, 0xAC, 0xAC, 0xAD, 0xAF, 0xB4, 0xB9, 0xC0, 0xD0, 0x65, +0x47, 0x3A, 0x32, 0x2F, 0x2C, 0x2B, 0x2B, 0x2C, 0x2D, 0x2E, 0x31, 0x36, 0x3A, 0x3F, 0x4A, 0x5E, +0xDC, 0xCC, 0xC4, 0xBE, 0xBA, 0xB6, 0xB2, 0xAF, 0xAE, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB8, 0xBE, +0xCA, 0xE6, 0x4F, 0x3F, 0x38, 0x31, 0x2E, 0x2C, 0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x35, 0x3A, 0x3F, +0x4B, 0x64, 0xDD, 0xCB, 0xC3, 0xBD, 0xBA, 0xB7, 0xB4, 0xB1, 0xAF, 0xAE, 0xAE, 0xB0, 0xB3, 0xB5, +0xB9, 0xBE, 0xC6, 0xD3, 0x74, 0x4E, 0x40, 0x3A, 0x35, 0x32, 0x30, 0x2F, 0x2F, 0x30, 0x33, 0x36, +0x3A, 0x3F, 0x48, 0x52, 0x6C, 0xDF, 0xCE, 0xC7, 0xC1, 0xBE, 0xBB, 0xB9, 0xB8, 0xB7, 0xB6, 0xB6, +0xB7, 0xB9, 0xBB, 0xBE, 0xC4, 0xCA, 0xD9, 0x6C, 0x50, 0x45, 0x3D, 0x3A, 0x37, 0x35, 0x35, 0x35, +0x36, 0x37, 0x39, 0x3C, 0x3F, 0x46, 0x4F, 0x5E, 0xF1, 0xD9, 0xCF, 0xCC, 0xC9, 0xC5, 0xC1, 0xBE, +0xBC, 0xBC, 0xBC, 0xBD, 0xBF, 0xC2, 0xC4, 0xC7, 0xCC, 0xD5, 0xE8, 0x64, 0x52, 0x4A, 0x45, 0x41, +0x3F, 0x3E, 0x3D, 0x3D, 0x3E, 0x41, 0x45, 0x49, 0x4D, 0x53, 0x5C, 0x71, 0xE9, 0xDD, 0xD6, 0xD1, +0xCE, 0xCB, 0xC9, 0xC8, 0xC8, 0xC7, 0xC7, 0xC8, 0xC9, 0xCC, 0xCF, 0xD4, 0xDA, 0xE4, 0xF7, 0x69, +0x5B, 0x53, 0x4F, 0x4E, 0x4D, 0x4D, 0x4D, 0x4E, 0x51, 0x58, 0x5F, 0x68, 0x6F, 0x77, 0xFC, 0xEE, +0xE8, 0xE5, 0xE1, 0xDD, 0xDE, 0xDE, 0xDE, 0xE2, 0xE6, 0xE6, 0xEB, 0xF0, 0xED, 0xEA, 0xEC, 0xEE, +0xF8, 0x6A, 0x5C, 0x57, 0x55, 0x56, 0x58, 0x59, 0x58, 0x58, 0x5B, 0x5E, 0x63, 0x71, 0xF7, 0xEE, +0xE9, 0xE3, 0xE4, 0xE8, 0xE7, 0xEA, 0xEE, 0xEE, 0xF2, 0xFB, 0xFF, 0x7B, 0x74, 0x6E, 0x6B, 0x65, +0x60, 0x65, 0x67, 0x61, 0x60, 0x61, 0x5E, 0x5E, 0x62, 0x69, 0x70, 0x7F, 0xF6, 0xF2, 0xEC, 0xE7, +0xE6, 0xE3, 0xDF, 0xDE, 0xDE, 0xDD, 0xDE, 0xE0, 0xE5, 0xEC, 0xF6, 0x7F, 0x78, 0x75, 0x70, 0x6B, +0x64, 0x5E, 0x5A, 0x58, 0x58, 0x59, 0x5A, 0x5C, 0x5D, 0x5E, 0x61, 0x67, 0x6C, 0x75, 0xF8, 0xEC, +0xE6, 0xE0, 0xDD, 0xDD, 0xDE, 0xDF, 0xE0, 0xE2, 0xE2, 0xE4, 0xE6, 0xE9, 0xEE, 0xF9, 0x7D, 0x75, +0x6E, 0x6A, 0x65, 0x61, 0x5E, 0x5C, 0x5B, 0x5C, 0x5D, 0x5E, 0x60, 0x63, 0x66, 0x6C, 0x76, 0xFA, +0xEE, 0xE9, 0xE4, 0xE1, 0xDF, 0xDD, 0xDE, 0xDF, 0xE2, 0xE6, 0xEA, 0xEE, 0xF4, 0xFA, 0x7E, 0x7A, +0x75, 0x72, 0x74, 0x74, 0x71, 0x70, 0x6D, 0x6A, 0x6A, 0x6B, 0x6D, 0x70, 0x74, 0x78, 0x7A, 0x7D, +0xFA, 0xF0, 0xEA, 0xE5, 0xE3, 0xE2, 0xE0, 0xDF, 0xE1, 0xE3, 0xE4, 0xE8, 0xEB, 0xEE, 0xF4, 0xFB, +0x7E, 0x75, 0x6D, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x65, 0x64, 0x63, 0x64, 0x66, 0x69, 0x6D, 0x72, +0x77, 0x7B, 0xFE, 0xF7, 0xF0, 0xEB, 0xE8, 0xE7, 0xE6, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xEA, 0xED, +0xF3, 0xFC, 0x79, 0x72, 0x6F, 0x6C, 0x6B, 0x6B, 0x69, 0x66, 0x64, 0x63, 0x62, 0x63, 0x67, 0x6C, +0x73, 0x7C, 0xFE, 0xFD, 0xFA, 0xF4, 0xEE, 0xEA, 0xE5, 0xE1, 0xE1, 0xE2, 0xE5, 0xE9, 0xED, 0xEF, +0xF1, 0xF2, 0xF4, 0xF8, 0xFF, 0x76, 0x6E, 0x6A, 0x68, 0x67, 0x66, 0x65, 0x64, 0x62, 0x61, 0x61, +0x63, 0x67, 0x6B, 0x72, 0x7E, 0xFA, 0xF5, 0xF1, 0xEE, 0xED, 0xEC, 0xE9, 0xE8, 0xE7, 0xE7, 0xE9, +0xEC, 0xF0, 0xF9, 0x7D, 0x77, 0x73, 0x70, 0x6F, 0x6E, 0x6C, 0x69, 0x67, 0x65, 0x66, 0x66, 0x68, +0x69, 0x69, 0x6A, 0x6C, 0x6E, 0x75, 0x7F, 0xF8, 0xF1, 0xED, 0xEB, 0xEA, 0xEA, 0xEB, 0xEB, 0xEB, +0xEA, 0xE9, 0xEA, 0xEC, 0xEF, 0xF4, 0xFB, 0x7D, 0x77, 0x73, 0x71, 0x6F, 0x6D, 0x6B, 0x69, 0x67, +0x66, 0x67, 0x68, 0x69, 0x6B, 0x6D, 0x6F, 0x74, 0x79, 0x7F, 0xF9, 0xF3, 0xEF, 0xEE, 0xEE, 0xEE, +0xEE, 0xED, 0xED, 0xED, 0xEE, 0xEC, 0xEC, 0xF1, 0xF3, 0xF6, 0xFD, 0xFF, 0x7D, 0x78, 0x78, 0x76, +0x70, 0x6F, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x71, 0x73, 0x77, 0x7B, 0x7D, 0xFF, 0xFB, 0xF8, 0xF8, +0xFA, 0xFB, 0xFE, 0x7E, 0x7D, 0x7A, 0x79, 0x7A, 0x76, 0x76, 0x76, 0x72, 0x70, 0x6F, 0x6D, 0x6E, +0x6D, 0x6B, 0x6E, 0x65, 0x66, 0x57, 0x41, 0x59, 0xC7, 0x62, 0x57, 0xCD, 0x64, 0x6B, 0xCC, 0x6D, +0xF6, 0xD1, 0x69, 0x6E, 0xDA, 0x7D, 0x61, 0xEE, 0xF1, 0xFD, 0xFF, 0x6E, 0xE7, 0x74, 0x66, 0xE9, +0x6A, 0xFC, 0xF2, 0x64, 0xEE, 0x6F, 0x6B, 0x7B, 0x69, 0xF2, 0x68, 0x74, 0xEC, 0x5F, 0xED, 0xFC, +0x5F, 0xDE, 0x72, 0x65, 0xDC, 0x51, 0x4C, 0xE8, 0x5F, 0xEF, 0xD7, 0x4E, 0xF3, 0xF9, 0x52, 0xC3, +0xE2, 0x56, 0xC9, 0x5B, 0x59, 0xE4, 0x50, 0x53, 0x47, 0x66, 0xF9, 0x47, 0xC9, 0xCB, 0x59, 0xD4, +0x55, 0x58, 0xD3, 0x5C, 0xF9, 0xCE, 0xD7, 0x6D, 0x61, 0xDB, 0xE4, 0xE8, 0x70, 0x79, 0xCD, 0x6B, +0x5D, 0xEC, 0x66, 0xDC, 0x6C, 0x5F, 0xD3, 0xF9, 0xFB, 0x66, 0x55, 0xDE, 0xFB, 0x64, 0xD7, 0xDA, +0xF1, 0xF1, 0xF1, 0xE5, 0xDB, 0xF4, 0x75, 0xDF, 0xE7, 0xFD, 0x79, 0xEC, 0xD9, 0xF0, 0x6E, 0xF5, +0xE4, 0xE5, 0x64, 0x74, 0xDF, 0x7D, 0x68, 0x75, 0xF0, 0xFD, 0x7B, 0xFC, 0x7B, 0xDE, 0xEF, 0x64, +0xDF, 0xE8, 0xFF, 0xE9, 0xFF, 0xE2, 0xE1, 0x76, 0xF6, 0xEF, 0xEC, 0xF9, 0x6D, 0x7C, 0x73, 0x6D, +0x69, 0x67, 0x76, 0x75, 0x73, 0x64, 0x66, 0xFD, 0x60, 0x5F, 0x77, 0x67, 0x70, 0x74, 0x60, 0x78, +0x7A, 0x5C, 0x67, 0x79, 0x6C, 0x77, 0x63, 0x63, 0xEF, 0x6C, 0x66, 0x73, 0x6D, 0xF8, 0x72, 0x74, +0xE6, 0xFB, 0x7B, 0xF3, 0xF6, 0xF1, 0xFE, 0x7B, 0xF5, 0xF1, 0x6D, 0x63, 0x75, 0x6E, 0x60, 0x64, +0x67, 0x67, 0x68, 0x67, 0x67, 0x6C, 0x64, 0x5B, 0x65, 0x6E, 0x69, 0x72, 0x76, 0x74, 0xFE, 0xFD, +0xFF, 0xF6, 0xF3, 0x7C, 0x7A, 0xFC, 0xFE, 0xFB, 0x7E, 0x75, 0xF5, 0xEE, 0xFC, 0xF7, 0xF3, 0xFF, +0xFE, 0x74, 0x6B, 0x6F, 0x6D, 0x6A, 0x6C, 0x6A, 0x7A, 0xF9, 0x71, 0x7C, 0xF5, 0x7C, 0x7B, 0x7F, +0xFE, 0x72, 0x6E, 0xFF, 0x6F, 0x66, 0x6B, 0x6A, 0x6E, 0x76, 0x71, 0x7C, 0x7A, 0x6E, 0x6C, 0x69, +0x6C, 0x6D, 0x63, 0x65, 0x6A, 0x66, 0x63, 0x65, 0x6C, 0x68, 0x64, 0x69, 0x6A, 0x6E, 0x79, 0x7B, +0x78, 0x6D, 0x6E, 0x79, 0x77, 0xFA, 0xED, 0xEF, 0xEF, 0xEC, 0xE8, 0xEF, 0xFB, 0xF6, 0xEF, 0xEE, +0xF7, 0xF9, 0xF3, 0xF7, 0xF1, 0xF3, 0xFD, 0xFD, 0x7A, 0x7B, 0xFE, 0x79, 0x7C, 0x7B, 0x6E, 0x72, +0x7A, 0x72, 0x71, 0x79, 0x79, 0x6F, 0x6F, 0x78, 0x74, 0x72, 0x7B, 0x72, 0x78, 0xF6, 0xF7, 0xF9, +0x78, 0x79, 0xEE, 0xF5, 0x74, 0x76, 0x7A, 0xFE, 0x7E, 0x75, 0x7A, 0x7E, 0x74, 0x70, 0x7D, 0xF8, +0xF8, 0x7D, 0x77, 0xF8, 0xF0, 0x7F, 0x7E, 0xF2, 0xED, 0xF0, 0xF4, 0xEB, 0xE9, 0xFE, 0x74, 0xEF, +0xE1, 0xE0, 0xDC, 0xD9, 0xD7, 0xD3, 0xD7, 0xDD, 0xD9, 0xD9, 0xDF, 0xE6, 0xEB, 0xF2, 0x78, 0x65, +0x61, 0x65, 0x5F, 0x5A, 0x5B, 0x5B, 0x5A, 0x5C, 0x5B, 0x5D, 0x5E, 0x5C, 0x5B, 0x5B, 0x5B, 0x5C, +0x5E, 0x6B, 0xEA, 0xD9, 0xD2, 0xD1, 0xCD, 0xC8, 0xC6, 0xC5, 0xC5, 0xC3, 0xC3, 0xC6, 0xCA, 0xD2, +0xE8, 0x67, 0x51, 0x49, 0x42, 0x3D, 0x3D, 0x3E, 0x3F, 0x41, 0x44, 0x49, 0x4E, 0x50, 0x55, 0x5A, +0x5F, 0x6F, 0xEF, 0xDA, 0xCD, 0xCA, 0xC8, 0xC4, 0xBF, 0xBD, 0xBB, 0xB9, 0xB7, 0xB6, 0xBA, 0xC2, +0xCC, 0xE2, 0x56, 0x43, 0x3B, 0x39, 0x37, 0x36, 0x37, 0x3B, 0x3E, 0x42, 0x47, 0x4B, 0x51, 0x5A, +0x5B, 0x5E, 0x67, 0x7A, 0xED, 0xE8, 0xDB, 0xCF, 0xCB, 0xC5, 0xBD, 0xB9, 0xB6, 0xB2, 0xB0, 0xB4, +0xB9, 0xBF, 0xCD, 0xFC, 0x49, 0x3B, 0x37, 0x33, 0x31, 0x32, 0x33, 0x38, 0x3E, 0x45, 0x4F, 0x5F, +0x74, 0xF0, 0xEF, 0xF1, 0xF4, 0xFF, 0x77, 0x72, 0xFB, 0xE4, 0xD9, 0xCE, 0xC3, 0xBA, 0xB6, 0xB2, +0xB0, 0xB2, 0xB6, 0xBB, 0xC8, 0xE4, 0x51, 0x3E, 0x38, 0x33, 0x2F, 0x2F, 0x31, 0x35, 0x3A, 0x3E, +0x49, 0x5D, 0xFE, 0xE4, 0xDD, 0xD9, 0xD9, 0xE1, 0xEB, 0xEE, 0xEE, 0xE7, 0xDD, 0xD2, 0xC7, 0xBD, +0xB9, 0xB5, 0xB2, 0xB5, 0xB8, 0xBB, 0xC6, 0xDA, 0x5F, 0x45, 0x3D, 0x37, 0x33, 0x31, 0x31, 0x35, +0x39, 0x3D, 0x45, 0x53, 0x6F, 0xE3, 0xD9, 0xD0, 0xCF, 0xD2, 0xD5, 0xD9, 0xD9, 0xD8, 0xD4, 0xCE, +0xC8, 0xC0, 0xBD, 0xB9, 0xB8, 0xBB, 0xBD, 0xC1, 0xCD, 0xDF, 0x5F, 0x4A, 0x41, 0x3B, 0x37, 0x36, +0x35, 0x36, 0x3A, 0x3D, 0x44, 0x4E, 0x5F, 0xEC, 0xDB, 0xD6, 0xD2, 0xD4, 0xD6, 0xDA, 0xDD, 0xDB, +0xD8, 0xD2, 0xCD, 0xC9, 0xC3, 0xBF, 0xBE, 0xBF, 0xC3, 0xC4, 0xCA, 0xD6, 0xED, 0x5E, 0x50, 0x48, +0x3F, 0x3C, 0x3B, 0x3A, 0x3A, 0x3D, 0x40, 0x4A, 0x55, 0x6A, 0xE6, 0xDC, 0xD8, 0xD6, 0xD8, 0xD8, +0xDB, 0xDE, 0xDF, 0xE2, 0xDE, 0xDC, 0xD9, 0xD0, 0xCB, 0xC8, 0xC8, 0xCC, 0xCD, 0xCD, 0xD1, 0xDB, +0xF2, 0x67, 0x5B, 0x51, 0x49, 0x44, 0x42, 0x41, 0x42, 0x44, 0x49, 0x4E, 0x55, 0x5C, 0x6A, 0x7E, +0xF3, 0xED, 0xED, 0xEF, 0xEC, 0xED, 0xF4, 0xF7, 0xF0, 0xEB, 0xE4, 0xDF, 0xDA, 0xD2, 0xCD, 0xCC, +0xCC, 0xCF, 0xCF, 0xCE, 0xD3, 0xDB, 0xE7, 0x7C, 0x69, 0x5E, 0x54, 0x4F, 0x4E, 0x4D, 0x4E, 0x4F, +0x52, 0x58, 0x5B, 0x5E, 0x63, 0x67, 0x6B, 0x6B, 0x6A, 0x6B, 0x6C, 0x6E, 0x6F, 0x73, 0x7D, 0xF3, +0xEA, 0xE1, 0xDC, 0xD8, 0xD3, 0xD1, 0xCF, 0xCE, 0xD1, 0xD2, 0xD2, 0xD6, 0xDB, 0xE2, 0xEF, 0xFD, +0x73, 0x66, 0x5F, 0x5C, 0x5A, 0x59, 0x58, 0x56, 0x56, 0x57, 0x57, 0x58, 0x58, 0x5A, 0x5C, 0x5D, +0x61, 0x65, 0x6A, 0x74, 0x7E, 0xF4, 0xEA, 0xE2, 0xDD, 0xDA, 0xD7, 0xD5, 0xD2, 0xD1, 0xD0, 0xD1, +0xD3, 0xD3, 0xD4, 0xD7, 0xDB, 0xE0, 0xE8, 0xEF, 0x7B, 0x69, 0x5F, 0x5B, 0x57, 0x53, 0x50, 0x4F, +0x4F, 0x4F, 0x4F, 0x50, 0x52, 0x56, 0x59, 0x5C, 0x60, 0x68, 0x6E, 0x7A, 0xFB, 0xF1, 0xEB, 0xE7, +0xE2, 0xDE, 0xDC, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD3, 0xD5, 0xD5, 0xD8, 0xDC, 0xE4, 0xF2, 0x78, +0x6A, 0x5E, 0x59, 0x55, 0x52, 0x50, 0x4F, 0x4F, 0x50, 0x52, 0x55, 0x58, 0x5A, 0x5D, 0x61, 0x64, +0x69, 0x6E, 0x74, 0xFF, 0xF6, 0xEE, 0xE9, 0xE4, 0xDF, 0xDC, 0xD8, 0xD5, 0xD2, 0xD0, 0xD1, 0xD1, +0xD2, 0xD6, 0xD7, 0xDA, 0xDF, 0xE8, 0xF8, 0x71, 0x69, 0x60, 0x5C, 0x58, 0x56, 0x54, 0x53, 0x53, +0x53, 0x55, 0x56, 0x58, 0x5A, 0x5C, 0x5F, 0x63, 0x69, 0x71, 0xFF, 0xEF, 0xEA, 0xE6, 0xE1, 0xDF, +0xDE, 0xDB, 0xDA, 0xDA, 0xD7, 0xD4, 0xD1, 0xD1, 0xD2, 0xD4, 0xD7, 0xD8, 0xDB, 0xE1, 0xED, 0x78, +0x69, 0x61, 0x5A, 0x53, 0x50, 0x4F, 0x4E, 0x4F, 0x4F, 0x51, 0x55, 0x59, 0x5D, 0x60, 0x65, 0x6C, +0x6F, 0x76, 0x7E, 0xFC, 0xF5, 0xF2, 0xF2, 0xED, 0xE7, 0xE1, 0xDD, 0xD9, 0xD4, 0xCE, 0xCB, 0xCA, +0xC8, 0xCA, 0xCF, 0xD0, 0xD7, 0xE6, 0x7C, 0x5E, 0x53, 0x4F, 0x4C, 0x4A, 0x4A, 0x4A, 0x4C, 0x4E, +0x4F, 0x51, 0x57, 0x5D, 0x62, 0x66, 0x69, 0x6D, 0x6D, 0x67, 0x63, 0x65, 0x6B, 0x70, 0x75, 0xFE, +0xEA, 0xDC, 0xD3, 0xCE, 0xC9, 0xC2, 0xBE, 0xBC, 0xBC, 0xC1, 0xC8, 0xCB, 0xDC, 0x69, 0x50, 0x46, +0x42, 0x3F, 0x3D, 0x3D, 0x3F, 0x43, 0x4B, 0x4F, 0x55, 0x61, 0x6F, 0xFC, 0xF0, 0xFA, 0xFD, 0x7B, +0x63, 0x5A, 0x54, 0x52, 0x54, 0x58, 0x62, 0x7D, 0xDE, 0xCC, 0xC4, 0xBC, 0xB6, 0xB1, 0xAE, 0xB2, +0xBA, 0xC1, 0xDA, 0x5A, 0x45, 0x38, 0x33, 0x32, 0x33, 0x36, 0x3A, 0x3E, 0x4B, 0x66, 0xEA, 0xD6, +0xCE, 0xCF, 0xD3, 0xE0, 0x6E, 0x5C, 0x51, 0x4D, 0x4B, 0x4A, 0x4F, 0x5B, 0x7A, 0xD6, 0xC6, 0xBA, +0xB1, 0xAE, 0xAA, 0xAA, 0xAF, 0xBA, 0xD1, 0x4E, 0x3D, 0x31, 0x2B, 0x2B, 0x2C, 0x30, 0x38, 0x3E, +0x4E, 0xEA, 0xCD, 0xC7, 0xC8, 0xCB, 0xCE, 0xDD, 0x64, 0x4F, 0x48, 0x48, 0x47, 0x46, 0x4D, 0x62, +0xDD, 0xCA, 0xBD, 0xB1, 0xAC, 0xA9, 0xA7, 0xAA, 0xB2, 0xC4, 0x51, 0x3A, 0x2F, 0x29, 0x28, 0x2A, +0x2E, 0x39, 0x45, 0x5A, 0xDB, 0xC8, 0xC2, 0xC5, 0xCD, 0xD5, 0xE8, 0x5B, 0x4C, 0x46, 0x47, 0x4C, +0x4E, 0x59, 0xF3, 0xD3, 0xC6, 0xBE, 0xB5, 0xAD, 0xAA, 0xA6, 0xA8, 0xB2, 0xC5, 0x54, 0x38, 0x2F, +0x28, 0x26, 0x2A, 0x2F, 0x3A, 0x4B, 0x73, 0xCF, 0xC5, 0xC4, 0xC9, 0xD9, 0xF8, 0x5F, 0x4C, 0x47, +0x47, 0x48, 0x4F, 0x5A, 0x74, 0xD9, 0xCE, 0xC7, 0xBF, 0xBA, 0xB0, 0xAC, 0xAA, 0xA9, 0xB0, 0xC5, +0x5C, 0x3B, 0x30, 0x2B, 0x27, 0x29, 0x2E, 0x39, 0x49, 0x6C, 0xD2, 0xC7, 0xC5, 0xCA, 0xDA, 0x7A, +0x5E, 0x4D, 0x48, 0x49, 0x4B, 0x52, 0x5E, 0x70, 0xDC, 0xCE, 0xC9, 0xC4, 0xBE, 0xB5, 0xAE, 0xAC, +0xAA, 0xAD, 0xBB, 0xE1, 0x43, 0x35, 0x2E, 0x29, 0x28, 0x2B, 0x32, 0x3D, 0x4E, 0x7E, 0xD2, 0xC9, +0xC7, 0xCC, 0xDF, 0xFE, 0x61, 0x4F, 0x4C, 0x4B, 0x4C, 0x54, 0x5D, 0x72, 0xDA, 0xCE, 0xC7, 0xC0, +0xB9, 0xB0, 0xAD, 0xAA, 0xAA, 0xB1, 0xC5, 0x5D, 0x3D, 0x33, 0x2C, 0x29, 0x29, 0x2D, 0x35, 0x3F, +0x4F, 0x78, 0xD7, 0xCA, 0xC7, 0xCD, 0xD9, 0xE3, 0x71, 0x5C, 0x54, 0x4D, 0x4E, 0x55, 0x5A, 0x6E, +0xE3, 0xD3, 0xC8, 0xBE, 0xB6, 0xAF, 0xAC, 0xAA, 0xAC, 0xB7, 0xCE, 0x53, 0x3D, 0x34, 0x2D, 0x2A, +0x2A, 0x2E, 0x35, 0x3E, 0x4A, 0x5C, 0xE5, 0xCD, 0xC8, 0xCB, 0xCE, 0xD5, 0xE2, 0xF7, 0x66, 0x57, +0x54, 0x56, 0x5B, 0x6E, 0xE7, 0xD5, 0xC9, 0xBE, 0xB6, 0xB1, 0xAE, 0xAE, 0xB4, 0xBE, 0xD3, 0x5C, +0x46, 0x3C, 0x34, 0x30, 0x2F, 0x32, 0x38, 0x3E, 0x45, 0x4E, 0x69, 0xDC, 0xCF, 0xCD, 0xCF, 0xD3, +0xD9, 0xDF, 0xEF, 0x6F, 0x68, 0x67, 0x6F, 0xF7, 0xE7, 0xDC, 0xD2, 0xC8, 0xC1, 0xBE, 0xBC, 0xBD, +0xC3, 0xCB, 0xD5, 0xEA, 0x6A, 0x58, 0x4D, 0x47, 0x43, 0x43, 0x44, 0x47, 0x4A, 0x4D, 0x52, 0x5D, +0x6D, 0x78, 0x77, 0x78, 0x76, 0x73, 0x75, 0x72, 0x72, 0x78, 0x7E, 0xF6, 0xEB, 0xE3, 0xDC, 0xD6, +0xD2, 0xCF, 0xCE, 0xCE, 0xCD, 0xCF, 0xD2, 0xD4, 0xD7, 0xDA, 0xDD, 0xE3, 0xEF, 0x7A, 0x6C, 0x65, +0x5F, 0x5B, 0x57, 0x53, 0x4F, 0x4E, 0x4D, 0x4C, 0x4A, 0x4A, 0x4A, 0x4B, 0x4D, 0x4F, 0x53, 0x59, +0x5F, 0x6C, 0xFE, 0xEC, 0xE3, 0xDE, 0xDC, 0xDA, 0xD9, 0xD8, 0xD7, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, +0xD8, 0xDA, 0xDC, 0xDE, 0xE3, 0xEC, 0xFB, 0x6F, 0x63, 0x5B, 0x55, 0x4F, 0x4D, 0x4C, 0x4B, 0x4C, +0x4C, 0x4D, 0x4F, 0x53, 0x58, 0x5E, 0x67, 0x73, 0xFB, 0xEE, 0xE8, 0xE3, 0xDF, 0xDC, 0xDA, 0xD9, +0xD8, 0xD8, 0xD8, 0xD9, 0xDB, 0xDD, 0xDF, 0xE1, 0xE5, 0xE9, 0xEE, 0xF6, 0x7C, 0x6E, 0x66, 0x5F, +0x5C, 0x5A, 0x58, 0x56, 0x56, 0x57, 0x58, 0x5A, 0x5D, 0x60, 0x66, 0x6D, 0x74, 0x7C, 0xFB, 0xF4, +0xEE, 0xEA, 0xE7, 0xE5, 0xE4, 0xE4, 0xE4, 0xE7, 0xEA, 0xEC, 0xED, 0xED, 0xEC, 0xED, 0xEC, 0xED, +0xEE, 0xF1, 0xF9, 0x7F, 0x79, 0x75, 0x70, 0x6D, 0x6C, 0x6C, 0x6E, 0x73, 0x79, 0xFE, 0xF9, 0xF3, +0xEE, 0xEB, 0xE9, 0xE8, 0xE6, 0xE5, 0xE6, 0xE8, 0xEA, 0xED, 0xF1, 0xF8, 0xFD, 0x7E, 0x7E, 0xFE, +0xFC, 0xF9, 0xF5, 0xF5, 0xF6, 0xFB, 0x7C, 0x77, 0x71, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6B, 0x6E, +0x70, 0x75, 0x7A, 0xFE, 0xF6, 0xF1, 0xEE, 0xEC, 0xEB, 0xEB, 0xEC, 0xEE, 0xF1, 0xF5, 0xFB, 0x7D, +0x7B, 0x7A, 0x7C, 0xFE, 0xFA, 0xF4, 0xF1, 0xF0, 0xF0, 0xF3, 0xF7, 0xFB, 0xFD, 0xFF, 0xFF, 0x7F, +0x7F, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0xFD, 0xFC, 0xFA, 0xF5, 0xF4, 0xF1, 0xEF, 0xEF, 0xEF, 0xF0, +0xF4, 0xF8, 0xFD, 0x7D, 0x78, 0x77, 0x78, 0x7A, 0x7C, 0x7C, 0x7E, 0x7C, 0x7A, 0x79, 0x76, 0x77, +0x78, 0x77, 0x7B, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0x7E, 0xFE, 0xFB, +0xFA, 0xF9, 0xFA, 0xFB, 0xFE, 0x7F, 0x7C, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7C, 0x7D, 0x7E, 0x7B, +0x77, 0x74, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x76, 0x76, 0x75, 0x76, +0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x77, 0x74, 0x72, 0x70, 0x6F, 0x6E, 0x6E, 0x6E, 0x70, 0x74, +0x78, 0x7B, 0x7D, 0x7D, 0x7C, 0x7C, 0x7A, 0x76, 0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x72, 0x72, +0x74, 0x76, 0x78, 0x7B, 0x7F, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF7, 0xFC, 0xFF, 0x7C, 0x79, 0x78, +0x77, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xFA, 0xFC, 0xFE, 0x7D, 0x7A, 0x76, +0x74, 0x74, 0x73, 0x75, 0x76, 0x76, 0x78, 0x7A, 0x7C, 0x7E, 0xFF, 0xFB, 0xF9, 0xF8, 0xF9, 0xFD, +0x7E, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x7C, 0x7F, 0xFB, 0xF6, 0xF5, 0xF2, 0xF2, 0xF3, +0xF4, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFA, +0xF7, 0xF6, 0xF8, 0xFC, 0x7F, 0x7C, 0x79, 0x72, 0x6F, 0x6E, 0x6E, 0x6E, 0x6F, 0x73, 0x77, 0x77, +0x7B, 0x7D, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x77, 0x75, 0x71, 0x6F, 0x6E, 0x6D, 0x6E, 0x6F, 0x70, +0x73, 0x74, 0x77, 0x79, 0x7C, 0x7D, 0x7D, 0x7D, 0x7B, 0x7A, 0x79, 0x76, 0x73, 0x70, 0x6F, 0x71, +0x73, 0x78, 0x7B, 0x7F, 0xFB, 0xF8, 0xF5, 0xF3, 0xF5, 0xF6, 0xF6, 0xF8, 0xF9, 0xFC, 0xFE, 0xFF, +0x7F, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xF7, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF6, 0xF7, 0xF9, +0xFA, 0xFC, 0xFF, 0xFF, 0x7F, 0x7F, 0xFE, 0xFD, 0xFE, 0xFD, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7C, +0x7A, 0x79, 0x77, 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7C, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, +0x7D, 0x7E, 0x7C, 0x7E, 0x7F, 0x7E, 0x7E, 0xFF, 0xFD, 0xFC, 0xFB, 0xF8, 0xF8, 0xFA, 0xFA, 0xFC, +0xFE, 0x7D, 0x78, 0x75, 0x72, 0x70, 0x70, 0x73, 0x75, 0x76, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x78, +0x77, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7D, 0x7F, 0xFC, 0xF8, 0xF6, +0xF4, 0xF2, 0xF3, 0xF7, 0xF9, 0xFB, 0x7E, 0x78, 0x75, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, +0x75, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x76, 0x79, 0x7B, +0x7C, 0x7E, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF6, 0xF7, 0xF9, 0xFC, 0xFE, 0x7C, 0x79, 0x77, 0x76, +0x75, 0x74, 0x74, 0x75, 0x74, 0x76, 0x77, 0x78, 0x79, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x78, 0x78, +0x77, 0x76, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7C, 0xFF, 0xFD, 0xFA, 0xF8, 0xF6, 0xF7, 0xF8, 0xF7, +0xF8, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, 0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFD, 0xFC, 0xFD, 0xFE, +0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, 0x7C, +0x7C, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x71, 0x70, 0x6F, 0x6F, 0x6E, +0x6D, 0x6C, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6F, 0x6E, 0x6F, 0x70, 0x70, 0x72, 0x75, 0x78, 0x7B, +0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFC, 0xFA, 0xFA, 0xF9, 0xF7, 0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF9, +0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFB, +0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0x7F, 0xFC, 0xFA, 0xFB, 0xFA, 0xFA, 0xF9, +0xFA, 0xFC, 0xFC, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFD, 0xFA, 0xFA, 0xF9, 0xF8, +0xFA, 0xF8, 0xFA, 0xFA, 0xFB, 0xFE, 0xFB, 0xFF, 0xFD, 0xFD, 0xFF, 0xFB, 0xFF, 0xFA, 0xFC, 0x7F, +0xFC, 0x70, 0x6A, 0x64, 0x61, 0x67, 0x6C, 0x73, 0x61, 0x60, 0x5A, 0x47, 0x53, 0xDF, 0x7D, 0x6F, +0x71, 0x69, 0x7F, 0x72, 0x70, 0x68, 0x5A, 0x5B, 0x59, 0x55, 0x5A, 0x5D, 0x4E, 0x46, 0x51, 0x77, +0xF6, 0xEC, 0xE8, 0xE6, 0xE5, 0xE4, 0xE1, 0xE5, 0xFD, 0x60, 0x65, 0xE6, 0xDB, 0xDD, 0xE1, 0xE4, +0xE2, 0xDC, 0xD4, 0xCF, 0xCF, 0xCF, 0xD1, 0xD2, 0xCF, 0xCD, 0xCC, 0xCD, 0xD0, 0xD4, 0xD7, 0xD5, +0xCE, 0xCD, 0xD3, 0xD9, 0xDB, 0xDA, 0xD9, 0xDC, 0xE2, 0xE5, 0xF1, 0xEE, 0xD7, 0xD2, 0xD9, 0xDC, +0xDD, 0xD9, 0xDC, 0xE7, 0xDF, 0xD9, 0xDD, 0x74, 0x62, 0xFC, 0xE9, 0xF2, 0x6C, 0x5D, 0x5D, 0x61, +0x6B, 0x6C, 0x5C, 0x5D, 0x70, 0x64, 0x5B, 0x6D, 0x78, 0x61, 0x57, 0x58, 0x65, 0x62, 0x53, 0x51, +0x69, 0xF5, 0x59, 0x53, 0x69, 0x68, 0x54, 0x4F, 0x67, 0xFA, 0x5B, 0x58, 0x5D, 0x60, 0x5D, 0x4E, +0x53, 0x61, 0x5A, 0x5F, 0x63, 0x61, 0x5E, 0x4C, 0x4C, 0x5A, 0x6B, 0xF7, 0x58, 0x47, 0x51, 0x6D, +0x68, 0x5A, 0x55, 0x53, 0x4A, 0x4E, 0xEE, 0xE1, 0x56, 0x46, 0x4D, 0x74, 0x70, 0x59, 0x53, 0x4C, +0x4E, 0x62, 0xF2, 0xF3, 0x5A, 0x4A, 0x4F, 0x6D, 0x6B, 0x57, 0x63, 0xED, 0x79, 0x69, 0x62, 0x5D, +0x6C, 0x67, 0x5E, 0xF5, 0xEA, 0x69, 0x63, 0x76, 0xFA, 0x6A, 0x59, 0x5D, 0xFB, 0xF6, 0x72, 0xFB, +0x71, 0x5D, 0x65, 0x7D, 0xFC, 0x79, 0xFB, 0xE9, 0xE2, 0xDD, 0xE3, 0xF9, 0xFA, 0xF3, 0xEA, 0xEC, +0x7D, 0xF1, 0xE5, 0xF2, 0x78, 0x6D, 0x6D, 0xED, 0xE4, 0xE5, 0xE4, 0xF6, 0x7A, 0xF8, 0xE5, 0xDC, +0xEA, 0xDF, 0xCF, 0xD3, 0xE7, 0x6C, 0x78, 0xCF, 0xC9, 0xD5, 0x7E, 0x64, 0x7E, 0xD7, 0xCF, 0xD7, +0xE0, 0xE8, 0xDC, 0xCB, 0xC5, 0xCC, 0xE6, 0x73, 0xE9, 0xD2, 0xC9, 0xCA, 0xD3, 0xED, 0x68, 0xF3, +0xD9, 0xDA, 0xDC, 0xDA, 0xD7, 0xDB, 0xE1, 0xE1, 0xEA, 0x69, 0x59, 0x60, 0xEE, 0xE0, 0xDC, 0xDF, +0xE5, 0xDD, 0xE1, 0xED, 0xED, 0xF4, 0xF6, 0xF2, 0xEE, 0xED, 0xFC, 0x6F, 0x64, 0x5C, 0x5C, 0x61, +0x76, 0xEA, 0xE1, 0xEB, 0x73, 0x66, 0x60, 0x69, 0xFB, 0x7E, 0x70, 0x76, 0xFF, 0x78, 0x73, 0xEB, +0xE2, 0x6F, 0x5C, 0x69, 0xE9, 0xDB, 0xDE, 0x73, 0x5E, 0x6D, 0xED, 0xEB, 0xF4, 0xFF, 0x77, 0xFD, +0xE7, 0xE2, 0xFB, 0x66, 0x69, 0xFE, 0xFA, 0x6B, 0x63, 0x69, 0x74, 0x74, 0x66, 0x63, 0x6F, 0xFB, +0xFD, 0x73, 0x71, 0x7B, 0xF4, 0xE8, 0xE2, 0xE8, 0xF2, 0xEB, 0xDE, 0xDC, 0xDE, 0xE2, 0xE7, 0xE5, +0xDF, 0xDF, 0xE8, 0xFC, 0x6D, 0x6A, 0x66, 0x5C, 0x53, 0x51, 0x56, 0x5B, 0x59, 0x56, 0x56, 0x5A, +0x5E, 0x5A, 0x53, 0x53, 0x59, 0x5D, 0x5F, 0x64, 0x74, 0xE9, 0xD6, 0xCB, 0xCB, 0xD3, 0xDC, 0xD4, +0xC8, 0xC1, 0xBF, 0xBE, 0xBE, 0xC5, 0xCE, 0xDC, 0xEA, 0x68, 0x4B, 0x3E, 0x3B, 0x3B, 0x3D, 0x3E, +0x41, 0x45, 0x47, 0x48, 0x4A, 0x4C, 0x4A, 0x47, 0x49, 0x4F, 0x5E, 0x6D, 0xF5, 0xDB, 0xCC, 0xC5, +0xC1, 0xBF, 0xBE, 0xBC, 0xBA, 0xB7, 0xB2, 0xAF, 0xAE, 0xB7, 0xDA, 0x43, 0x38, 0x35, 0x32, 0x31, +0x33, 0x3A, 0x46, 0x54, 0x5D, 0x56, 0x4A, 0x44, 0x43, 0x46, 0x44, 0x3F, 0x40, 0x4B, 0x61, 0x7B, +0xFD, 0xE7, 0xD4, 0xCA, 0xC5, 0xBF, 0xBB, 0xB6, 0xB1, 0xAF, 0xAD, 0xAC, 0xAC, 0xB4, 0xD8, 0x3C, +0x2D, 0x2B, 0x2D, 0x2F, 0x37, 0x41, 0x54, 0x76, 0xFF, 0x68, 0x54, 0x46, 0x40, 0x44, 0x49, 0x4A, +0x49, 0x4C, 0x5C, 0xFB, 0xE9, 0xE5, 0xDB, 0xCE, 0xC8, 0xC3, 0xBE, 0xBA, 0xB6, 0xB1, 0xAE, 0xAB, +0xA9, 0xAB, 0xBD, 0x3F, 0x2A, 0x26, 0x2A, 0x31, 0x3A, 0x43, 0x58, 0xE9, 0xDB, 0xE8, 0x5E, 0x46, +0x3C, 0x3D, 0x48, 0x55, 0x56, 0x55, 0x61, 0xF3, 0xE8, 0xE6, 0xDC, 0xCF, 0xC9, 0xC0, 0xB9, 0xB4, +0xB3, 0xB3, 0xAF, 0xAA, 0xA8, 0xAF, 0x75, 0x2C, 0x22, 0x24, 0x2D, 0x3F, 0x56, 0x72, 0xE0, 0xCF, +0xD4, 0x59, 0x3F, 0x38, 0x38, 0x3E, 0x4C, 0x68, 0xE8, 0xE3, 0xEA, 0x7E, 0x67, 0x64, 0x79, 0xDC, +0xCB, 0xBF, 0xB7, 0xB1, 0xAF, 0xAE, 0xAC, 0xAA, 0xB1, 0x56, 0x29, 0x1F, 0x20, 0x2B, 0x45, 0xD1, +0xC4, 0xC7, 0xCB, 0xD8, 0x4B, 0x33, 0x2E, 0x34, 0x42, 0x6D, 0xCD, 0xC5, 0xC8, 0xD1, 0xE0, 0x69, +0x52, 0x52, 0x6D, 0xD4, 0xC6, 0xBB, 0xB1, 0xAC, 0xAB, 0xAA, 0xA8, 0xAE, 0x68, 0x28, 0x1D, 0x1E, +0x2B, 0x53, 0xBC, 0xB6, 0xBD, 0xCA, 0xE1, 0x4E, 0x33, 0x2A, 0x2C, 0x3B, 0x7D, 0xBF, 0xBB, 0xC1, +0xD5, 0xED, 0x6A, 0x4F, 0x4C, 0x58, 0x7E, 0xD6, 0xC7, 0xBB, 0xB2, 0xAD, 0xA9, 0xA6, 0xA9, 0xC3, +0x2D, 0x1D, 0x1B, 0x23, 0x41, 0xBC, 0xAF, 0xB5, 0xC2, 0xDE, 0x4F, 0x3B, 0x2D, 0x27, 0x2D, 0x49, +0xC3, 0xB5, 0xB9, 0xCB, 0x64, 0x54, 0x56, 0x51, 0x58, 0x75, 0xE3, 0xD1, 0xCA, 0xC1, 0xB6, 0xAB, +0xA6, 0xA3, 0xA6, 0xC0, 0x2B, 0x1C, 0x1A, 0x24, 0x4D, 0xB0, 0xAA, 0xB0, 0xC3, 0xF0, 0x46, 0x38, +0x2D, 0x28, 0x2B, 0x4C, 0xBC, 0xB2, 0xB6, 0xD1, 0x4B, 0x46, 0x4F, 0x58, 0x61, 0xEE, 0xE1, 0xDB, +0xCF, 0xCB, 0xBD, 0xAE, 0xA7, 0xA3, 0xA2, 0xB6, 0x2C, 0x1B, 0x19, 0x21, 0x52, 0xAB, 0xA5, 0xAE, +0xC9, 0x4F, 0x3B, 0x37, 0x32, 0x2A, 0x2A, 0x3D, 0xC9, 0xB2, 0xB1, 0xCA, 0x44, 0x3D, 0x49, 0x5F, +0xDD, 0xD8, 0x77, 0x6E, 0xED, 0xDB, 0xC7, 0xB7, 0xAB, 0xA5, 0xA3, 0xA6, 0xC8, 0x26, 0x1A, 0x1A, +0x27, 0xC5, 0xA4, 0xA3, 0xAF, 0xE9, 0x3B, 0x33, 0x34, 0x31, 0x2D, 0x31, 0x57, 0xBF, 0xB3, 0xBA, +0x78, 0x41, 0x3E, 0x4E, 0xDC, 0xCE, 0xD4, 0x78, 0x5B, 0x67, 0xDC, 0xC4, 0xB7, 0xAC, 0xA6, 0xA5, +0xA5, 0xBA, 0x2C, 0x1B, 0x19, 0x23, 0xD8, 0xA3, 0x9F, 0xAB, 0xDA, 0x34, 0x2D, 0x30, 0x33, 0x33, +0x37, 0x54, 0xC1, 0xB7, 0xBD, 0x6E, 0x41, 0x3D, 0x4A, 0xD8, 0xCA, 0xD0, 0xEB, 0x56, 0x54, 0x74, +0xCE, 0xBD, 0xAF, 0xA8, 0xA6, 0xA5, 0xAE, 0x3B, 0x1E, 0x19, 0x1E, 0x43, 0xA8, 0x9E, 0xA6, 0xC8, +0x33, 0x29, 0x2C, 0x32, 0x39, 0x3D, 0x4E, 0xCD, 0xBE, 0xC2, 0xFF, 0x40, 0x3D, 0x48, 0xE0, 0xC4, +0xCB, 0xEA, 0x4F, 0x48, 0x59, 0xD7, 0xBE, 0xB5, 0xAD, 0xA9, 0xA9, 0xA7, 0xB3, 0x34, 0x1D, 0x19, +0x20, 0xEE, 0xA2, 0x9D, 0xA8, 0x60, 0x2A, 0x26, 0x2D, 0x3B, 0x4A, 0x4E, 0x64, 0xCE, 0xC6, 0xCF, +0x57, 0x42, 0x47, 0x67, 0xCB, 0xC3, 0xD4, 0x5C, 0x48, 0x47, 0x63, 0xCA, 0xBA, 0xB2, 0xAE, 0xAC, +0xAC, 0xAB, 0xB3, 0x3D, 0x1F, 0x1B, 0x20, 0x51, 0xA5, 0x9E, 0xA8, 0x6C, 0x2A, 0x24, 0x2B, 0x3E, +0x5E, 0x6C, 0x66, 0xFA, 0xE0, 0xE4, 0x60, 0x4B, 0x4E, 0x71, 0xD2, 0xC8, 0xD8, 0x5A, 0x4A, 0x49, +0x6E, 0xC6, 0xB9, 0xB3, 0xB1, 0xAF, 0xAE, 0xAC, 0xAF, 0x48, 0x21, 0x1B, 0x1F, 0x4C, 0xA5, 0x9D, +0xA7, 0x64, 0x28, 0x23, 0x2C, 0x4A, 0xD6, 0xD9, 0x61, 0x59, 0x6C, 0xEF, 0xF8, 0x5B, 0x5B, 0xEE, +0xD5, 0xCD, 0xDB, 0x5C, 0x4D, 0x4C, 0x6E, 0xC8, 0xBB, 0xB8, 0xB8, 0xB6, 0xB3, 0xAD, 0xA8, 0xBC, +0x2D, 0x1D, 0x1B, 0x2B, 0xB7, 0x9F, 0xA1, 0xB9, 0x33, 0x23, 0x28, 0x3A, 0xEB, 0xCF, 0x77, 0x50, +0x56, 0x6E, 0xE2, 0x73, 0x55, 0x5D, 0xE6, 0xCF, 0xD9, 0x5B, 0x4B, 0x47, 0x59, 0xD2, 0xC3, 0xBD, +0xBD, 0xBC, 0xB6, 0xAE, 0xA9, 0xAB, 0x68, 0x24, 0x1B, 0x1E, 0x3C, 0xAA, 0x9E, 0xA6, 0xDE, 0x2A, +0x23, 0x2C, 0x47, 0xD1, 0xCE, 0x72, 0x55, 0x58, 0x6A, 0x78, 0x5D, 0x5B, 0xF9, 0xDA, 0xD3, 0xDE, +0x5A, 0x49, 0x4A, 0x5F, 0xD1, 0xC0, 0xBD, 0xBC, 0xB9, 0xB3, 0xAD, 0xA9, 0xB1, 0x3C, 0x1F, 0x1C, +0x24, 0xE1, 0xA4, 0x9F, 0xAD, 0x44, 0x26, 0x25, 0x32, 0x6E, 0xC3, 0xCD, 0x64, 0x4F, 0x4F, 0x62, +0x70, 0x5C, 0x68, 0xE1, 0xD4, 0xD3, 0xF6, 0x4E, 0x45, 0x4B, 0x78, 0xCA, 0xBE, 0xBC, 0xBC, 0xB8, +0xB3, 0xAC, 0xA9, 0xBC, 0x2F, 0x1E, 0x1C, 0x2A, 0xBC, 0xA0, 0xA1, 0xB7, 0x35, 0x24, 0x28, 0x3B, +0xD8, 0xC4, 0xDC, 0x53, 0x4B, 0x4F, 0x67, 0x6D, 0x65, 0xEA, 0xDB, 0xD5, 0xDA, 0x5E, 0x4B, 0x48, +0x53, 0xDB, 0xC4, 0xBD, 0xBD, 0xBB, 0xB5, 0xAE, 0xA8, 0xAB, 0x75, 0x25, 0x1B, 0x1E, 0x3D, 0xAA, +0x9E, 0xA6, 0xDC, 0x2B, 0x25, 0x2E, 0x4E, 0xCC, 0xCC, 0x66, 0x4B, 0x4C, 0x5A, 0x74, 0x6C, 0x6D, +0xDF, 0xD6, 0xD6, 0xED, 0x4D, 0x43, 0x46, 0x59, 0xD0, 0xBF, 0xBC, 0xBB, 0xB8, 0xB3, 0xAD, 0xA9, +0xB3, 0x38, 0x1E, 0x1B, 0x24, 0xCF, 0xA2, 0x9F, 0xAF, 0x3E, 0x26, 0x27, 0x36, 0x6A, 0xCD, 0xE6, +0x4F, 0x4D, 0x55, 0x6E, 0xEF, 0x63, 0x7B, 0xDA, 0xDB, 0xDF, 0x5F, 0x49, 0x47, 0x4F, 0xE8, 0xC5, +0xBD, 0xBC, 0xBB, 0xB6, 0xAF, 0xAA, 0xAA, 0xCD, 0x29, 0x1C, 0x1D, 0x34, 0xAE, 0x9F, 0xA4, 0xC7, +0x2E, 0x25, 0x2C, 0x41, 0xDB, 0xD2, 0x75, 0x5B, 0x59, 0x60, 0x6E, 0x5B, 0x5C, 0xDF, 0xD0, 0xD8, +0x74, 0x4B, 0x43, 0x4B, 0x6E, 0xCC, 0xBF, 0xBD, 0xBE, 0xBC, 0xB5, 0xAD, 0xA8, 0xAD, 0x4B, 0x22, +0x1C, 0x22, 0x65, 0xA6, 0x9F, 0xAC, 0x4C, 0x2A, 0x28, 0x33, 0x50, 0xDE, 0xF2, 0x65, 0x7C, 0xF8, +0x79, 0x5A, 0x4B, 0x5E, 0xD7, 0xCF, 0xD6, 0x5F, 0x45, 0x43, 0x4C, 0xFB, 0xC9, 0xBF, 0xBD, 0xBC, +0xB8, 0xB2, 0xAD, 0xAA, 0xB7, 0x38, 0x20, 0x1D, 0x29, 0xC6, 0xA5, 0xA4, 0xB8, 0x3C, 0x2A, 0x2C, +0x39, 0x53, 0x7F, 0x6F, 0x79, 0xE8, 0xF9, 0x61, 0x4D, 0x4B, 0xFF, 0xD0, 0xD3, 0xEC, 0x4F, 0x45, +0x49, 0x58, 0xDF, 0xC7, 0xBF, 0xBD, 0xBB, 0xB5, 0xAF, 0xA9, 0xAA, 0xCA, 0x2C, 0x1D, 0x1E, 0x36, +0xB1, 0xA2, 0xA8, 0xCE, 0x33, 0x2B, 0x30, 0x3E, 0x4F, 0x5A, 0x6D, 0xD8, 0xD2, 0xF5, 0x4F, 0x46, +0x54, 0xD4, 0xCA, 0xD7, 0x65, 0x48, 0x43, 0x4C, 0x61, 0xD7, 0xC4, 0xBF, 0xBD, 0xB7, 0xB1, 0xAD, +0xAA, 0xB0, 0x48, 0x23, 0x1D, 0x24, 0x5D, 0xAA, 0xA4, 0xB0, 0x56, 0x30, 0x2E, 0x34, 0x3E, 0x47, +0x52, 0xE3, 0xC9, 0xCE, 0x65, 0x45, 0x43, 0x6A, 0xCE, 0xCD, 0xDE, 0x58, 0x49, 0x49, 0x4F, 0x6D, +0xD1, 0xC0, 0xBB, 0xB6, 0xAF, 0xAE, 0xAA, 0xAB, 0xCF, 0x2B, 0x1D, 0x1E, 0x36, 0xB2, 0xA4, 0xA9, +0xC7, 0x3B, 0x2F, 0x31, 0x37, 0x3D, 0x46, 0x6E, 0xC7, 0xC5, 0xE5, 0x4C, 0x41, 0x50, 0xD5, 0xCB, +0xDF, 0x58, 0x4C, 0x49, 0x4E, 0x62, 0xE4, 0xC8, 0xBD, 0xB9, 0xB4, 0xAF, 0xAD, 0xA9, 0xB2, 0x41, +0x22, 0x1D, 0x26, 0xEB, 0xAA, 0xA6, 0xB3, 0x5D, 0x38, 0x32, 0x32, 0x34, 0x39, 0x4D, 0xCC, 0xBD, +0xC7, 0x60, 0x44, 0x47, 0x6D, 0xDC, 0xE2, 0xEF, 0x63, 0x58, 0x50, 0x4D, 0x5A, 0xDB, 0xC3, 0xBA, +0xB3, 0xAF, 0xAD, 0xAC, 0xAE, 0xD3, 0x2D, 0x1F, 0x20, 0x38, 0xB9, 0xA9, 0xAD, 0xC4, 0x4C, 0x39, +0x33, 0x30, 0x32, 0x3C, 0xFA, 0xBE, 0xBE, 0xD5, 0x51, 0x46, 0x4F, 0x6F, 0x7B, 0x65, 0x68, 0x76, +0x60, 0x54, 0x52, 0x61, 0xCF, 0xBF, 0xB7, 0xAE, 0xAC, 0xAB, 0xAB, 0xBC, 0x39, 0x22, 0x1E, 0x2B, +0xE7, 0xAF, 0xAC, 0xB6, 0xD1, 0x4E, 0x3A, 0x2F, 0x2D, 0x31, 0x45, 0xCC, 0xBC, 0xC2, 0xDA, 0x58, +0x4D, 0x55, 0x52, 0x52, 0x68, 0xED, 0xF4, 0x66, 0x55, 0x59, 0xEF, 0xCE, 0xBF, 0xB5, 0xAD, 0xAB, +0xAB, 0xAE, 0xCC, 0x31, 0x22, 0x22, 0x2F, 0xE8, 0xB6, 0xB1, 0xB8, 0xC4, 0x73, 0x3D, 0x2F, 0x2B, +0x2F, 0x3F, 0xDD, 0xC0, 0xBF, 0xC7, 0xD8, 0x73, 0x55, 0x46, 0x44, 0x53, 0x7B, 0xEE, 0xED, 0xF2, +0xED, 0xDC, 0xCF, 0xC1, 0xB3, 0xAC, 0xA9, 0xA9, 0xB2, 0x58, 0x2C, 0x24, 0x28, 0x36, 0x5C, 0xC7, +0xBA, 0xB6, 0xB7, 0xCA, 0x49, 0x34, 0x2D, 0x2E, 0x37, 0x49, 0xE0, 0xC4, 0xBD, 0xBE, 0xC7, 0xEA, +0x4C, 0x42, 0x44, 0x49, 0x50, 0x69, 0xDD, 0xD0, 0xCB, 0xC6, 0xBD, 0xB3, 0xAD, 0xAB, 0xAB, 0xBA, +0x49, 0x2F, 0x2B, 0x2D, 0x32, 0x3A, 0x4B, 0xD6, 0xBC, 0xB6, 0xBD, 0xD7, 0x51, 0x3D, 0x36, 0x34, +0x37, 0x3E, 0x52, 0xDE, 0xC8, 0xC3, 0xC7, 0xCE, 0xDE, 0x72, 0x56, 0x4F, 0x53, 0x5D, 0xFF, 0xDA, +0xC9, 0xBD, 0xB7, 0xB4, 0xB2, 0xB6, 0xC6, 0x62, 0x47, 0x3F, 0x3D, 0x3B, 0x3B, 0x40, 0x4E, 0x6F, +0xEC, 0x7B, 0x67, 0x5E, 0x5B, 0x59, 0x55, 0x5A, 0x65, 0x5E, 0x5A, 0x5F, 0x61, 0x5E, 0x63, 0x65, +0x61, 0x6D, 0xF5, 0xFA, 0x7A, 0x77, 0x77, 0xFF, 0xEB, 0xDC, 0xD5, 0xCE, 0xCA, 0xC8, 0xC8, 0xCD, +0xD9, 0xEC, 0x76, 0x70, 0xFD, 0xED, 0xEA, 0xEE, 0x7D, 0x66, 0x59, 0x53, 0x50, 0x4F, 0x50, 0x54, +0x56, 0x58, 0x59, 0x5A, 0x5A, 0x5C, 0x5F, 0x6B, 0xF6, 0xE5, 0xE1, 0xE7, 0xEF, 0xF5, 0xF2, 0xEA, +0xDF, 0xD8, 0xCE, 0xC8, 0xC4, 0xC5, 0xCB, 0xD4, 0xDF, 0xE9, 0xE7, 0xE1, 0xDD, 0xDB, 0xDE, 0xEE, +0x68, 0x57, 0x4F, 0x4D, 0x4D, 0x4E, 0x4F, 0x4F, 0x52, 0x54, 0x53, 0x51, 0x53, 0x57, 0x5E, 0x6F, +0xFA, 0xEF, 0xEF, 0xF3, 0xF1, 0xF1, 0xEE, 0xE6, 0xDE, 0xD6, 0xCF, 0xCD, 0xCE, 0xD3, 0xDA, 0xDC, +0xDF, 0xDF, 0xD9, 0xD5, 0xD4, 0xD7, 0xE0, 0xFE, 0x6B, 0x5F, 0x5A, 0x58, 0x56, 0x54, 0x54, 0x53, +0x53, 0x50, 0x4E, 0x4F, 0x52, 0x56, 0x5C, 0x64, 0x67, 0x66, 0x69, 0x6C, 0x6D, 0x74, 0xFA, 0xEC, +0xDF, 0xD7, 0xD6, 0xDD, 0xE6, 0xF3, 0x7B, 0xF7, 0xE8, 0xDC, 0xD3, 0xD0, 0xD2, 0xD9, 0xE1, 0xE7, +0xEB, 0xF6, 0x7B, 0x74, 0x6F, 0x6B, 0x66, 0x5E, 0x59, 0x55, 0x53, 0x52, 0x56, 0x59, 0x5C, 0x61, +0x5F, 0x64, 0x65, 0x62, 0x6F, 0x7B, 0xFC, 0xE4, 0xDC, 0xD9, 0xE2, 0x7E, 0xFF, 0xFE, 0xFF, 0xEE, +0xDF, 0xD8, 0xD6, 0xD7, 0xDB, 0xDD, 0xDD, 0xE8, 0xE7, 0xE3, 0xEA, 0xE7, 0xF9, 0x72, 0x7C, 0x5F, +0x56, 0x58, 0x58, 0x56, 0x57, 0x57, 0x53, 0x54, 0x4A, 0x42, 0x4F, 0x67, 0x6A, 0xE0, 0xD4, 0xD8, +0xD7, 0xDD, 0xFD, 0xFE, 0xE4, 0x7B, 0xFF, 0xD9, 0xDF, 0xDE, 0xD7, 0xDA, 0xCF, 0xCF, 0xD3, 0xCD, +0xD3, 0xDF, 0xDD, 0xDE, 0xF3, 0x6D, 0x5F, 0x55, 0x54, 0x55, 0x51, 0x51, 0x50, 0x4F, 0x51, 0x53, +0x57, 0x59, 0x60, 0x73, 0xFB, 0xE7, 0xE1, 0xEA, 0xF4, 0x7D, 0x6D, 0x6F, 0x7F, 0x78, 0xF5, 0xE7, +0xEA, 0xE0, 0xDE, 0xD9, 0xCD, 0xCB, 0xC5, 0xC2, 0xC5, 0xCB, 0xDB, 0xDD, 0xEC, 0x53, 0x4C, 0x45, +0x42, 0x49, 0x48, 0x49, 0x4D, 0x51, 0x5A, 0x55, 0x55, 0x5D, 0x64, 0xF4, 0xED, 0xF5, 0xEB, 0xF2, +0x7A, 0x6D, 0x60, 0x5E, 0x6E, 0xF3, 0xF7, 0xE9, 0xDF, 0xDD, 0xD4, 0xCD, 0xC8, 0xC1, 0xBC, 0xB8, +0xB5, 0xB8, 0xC7, 0xF5, 0x52, 0x3E, 0x38, 0x37, 0x36, 0x3D, 0x4B, 0x59, 0xFD, 0xDF, 0xE3, 0xFE, +0x5C, 0x54, 0x52, 0x4E, 0x50, 0x55, 0x5D, 0xFF, 0xF2, 0xF1, 0xE9, 0xFB, 0xFD, 0x74, 0x5E, 0x62, +0x7A, 0xE3, 0xD2, 0xCA, 0xC0, 0xB9, 0xB1, 0xAD, 0xAE, 0xBC, 0x68, 0x3E, 0x31, 0x2D, 0x2E, 0x30, +0x3B, 0x5B, 0xD4, 0xC7, 0xC9, 0xD6, 0x65, 0x4A, 0x46, 0x3E, 0x3D, 0x47, 0x51, 0x7F, 0xD5, 0xD0, +0xCE, 0xD2, 0xE2, 0x6E, 0x57, 0x55, 0x61, 0xEA, 0xCD, 0xBE, 0xB7, 0xB2, 0xAD, 0xAB, 0xB0, 0xCE, +0x40, 0x2F, 0x2B, 0x2D, 0x2F, 0x38, 0x59, 0xCA, 0xBD, 0xBE, 0xCF, 0x70, 0x45, 0x39, 0x3A, 0x3B, +0x3F, 0x5D, 0xD9, 0xCB, 0xC4, 0xC5, 0xCF, 0xEA, 0x62, 0x52, 0x50, 0x5C, 0x7E, 0xD1, 0xBE, 0xB5, +0xAF, 0xAE, 0xAB, 0xAC, 0xC2, 0x44, 0x2F, 0x2A, 0x2D, 0x32, 0x38, 0x55, 0xC6, 0xBA, 0xBC, 0xCF, +0x5B, 0x40, 0x36, 0x34, 0x38, 0x40, 0x66, 0xCD, 0xC4, 0xC2, 0xC6, 0xD1, 0xFE, 0x52, 0x4C, 0x4F, +0x5C, 0xEF, 0xCF, 0xC1, 0xB7, 0xAF, 0xAD, 0xAB, 0xAD, 0xC9, 0x3C, 0x2D, 0x29, 0x2D, 0x35, 0x3D, +0xF1, 0xBD, 0xB8, 0xBF, 0xE1, 0x4C, 0x3C, 0x32, 0x31, 0x39, 0x47, 0xF7, 0xCB, 0xC4, 0xC2, 0xC7, +0xD9, 0x6F, 0x54, 0x4D, 0x4F, 0x5D, 0xEF, 0xCF, 0xC1, 0xB8, 0xAF, 0xAD, 0xAB, 0xAC, 0xC9, 0x3A, +0x2C, 0x29, 0x2D, 0x37, 0x44, 0xD8, 0xB9, 0xB7, 0xC4, 0x6C, 0x44, 0x38, 0x31, 0x30, 0x39, 0x4E, +0xDF, 0xCA, 0xC5, 0xC6, 0xCD, 0xEF, 0x5E, 0x5A, 0x53, 0x55, 0x64, 0xE8, 0xCD, 0xC4, 0xBB, 0xB0, +0xAC, 0xAA, 0xAC, 0xD0, 0x36, 0x2C, 0x2B, 0x2E, 0x39, 0x4A, 0xCB, 0xB6, 0xB7, 0xC8, 0x5D, 0x43, +0x39, 0x31, 0x32, 0x3D, 0x58, 0xD9, 0xCD, 0xCA, 0xC9, 0xD6, 0x73, 0x62, 0x63, 0x62, 0x68, 0x72, +0xE9, 0xCE, 0xC6, 0xBB, 0xAF, 0xAD, 0xAB, 0xAE, 0xD7, 0x38, 0x2D, 0x2C, 0x2F, 0x3B, 0x4F, 0xCA, +0xB6, 0xB8, 0xCB, 0x5D, 0x41, 0x39, 0x32, 0x33, 0x3E, 0x59, 0xDC, 0xCF, 0xCD, 0xCB, 0xD8, 0x63, +0x53, 0x5A, 0x5E, 0x61, 0x6F, 0xEA, 0xCF, 0xC6, 0xBC, 0xB0, 0xAD, 0xAB, 0xAE, 0xEE, 0x32, 0x2C, +0x2C, 0x30, 0x3B, 0x50, 0xC9, 0xB6, 0xB9, 0xCF, 0x5D, 0x47, 0x3A, 0x32, 0x33, 0x3F, 0x63, 0xDB, +0xD5, 0xCC, 0xC8, 0xD7, 0x66, 0x56, 0x58, 0x5C, 0x5A, 0x5B, 0x7E, 0xCE, 0xC4, 0xBB, 0xB0, 0xAD, +0xAB, 0xAF, 0x7B, 0x2F, 0x2C, 0x2E, 0x31, 0x39, 0x52, 0xC6, 0xB6, 0xBA, 0xD1, 0x5C, 0x4E, 0x3E, +0x32, 0x33, 0x3F, 0x64, 0xEA, 0xFD, 0xCE, 0xC2, 0xD0, 0x6C, 0x57, 0x5D, 0x64, 0x56, 0x53, 0x6C, +0xCE, 0xC4, 0xBD, 0xB1, 0xAD, 0xAA, 0xAE, 0x6F, 0x31, 0x2F, 0x31, 0x31, 0x37, 0x4F, 0xC5, 0xB6, +0xBA, 0xD2, 0xFC, 0x60, 0x45, 0x36, 0x35, 0x41, 0x56, 0xF8, 0xF2, 0xE4, 0xC6, 0xC8, 0x7C, 0x5A, +0x6A, 0x6A, 0x57, 0x52, 0x5B, 0xDA, 0xC6, 0xC0, 0xB6, 0xAE, 0xAA, 0xAC, 0xDD, 0x33, 0x30, 0x35, +0x31, 0x30, 0x42, 0xCE, 0xBA, 0xBA, 0xCC, 0xD9, 0xD9, 0x53, 0x3A, 0x35, 0x3E, 0x4D, 0x52, 0x60, +0xD6, 0xC5, 0xD2, 0x71, 0xE7, 0x7C, 0x55, 0x53, 0x51, 0x5B, 0xEE, 0xDC, 0xD3, 0xBE, 0xB2, 0xB0, +0xAD, 0xAE, 0x67, 0x31, 0x38, 0x39, 0x2F, 0x32, 0x49, 0xD5, 0xBE, 0xBF, 0xCF, 0xCD, 0xCA, 0x5C, +0x3D, 0x3C, 0x41, 0x41, 0x47, 0x5D, 0xE1, 0xC9, 0xC7, 0xD4, 0xDD, 0xFC, 0x51, 0x4C, 0x4C, 0x4C, +0x5F, 0xE2, 0xDC, 0xCA, 0xBF, 0xBD, 0xB9, 0xB5, 0xAF, 0xBA, 0x43, 0x35, 0x44, 0x3E, 0x2F, 0x36, +0x53, 0xD4, 0xC8, 0xCC, 0xD1, 0xC3, 0xC5, 0x5E, 0x41, 0x45, 0x49, 0x42, 0x44, 0x55, 0xE9, 0xD0, +0xD1, 0xDA, 0xD6, 0xD7, 0xFD, 0x5A, 0x58, 0x5B, 0x5A, 0x5B, 0x5F, 0x6C, 0x7A, 0xE1, 0xD3, 0xD2, +0xCC, 0xC8, 0xC4, 0xBF, 0xBD, 0xBA, 0xC2, 0x49, 0x3C, 0x4C, 0x41, 0x35, 0x3B, 0x52, 0xF3, 0xD6, +0xD1, 0xCE, 0xC3, 0xC6, 0x7A, 0x53, 0x57, 0x4E, 0x44, 0x46, 0x4F, 0x64, 0xE8, 0xDF, 0xDD, 0xD4, +0xD6, 0xEC, 0x56, 0x49, 0x54, 0x5E, 0x4F, 0x57, 0xFA, 0xE1, 0xDC, 0xE0, 0xE3, 0xD6, 0xD0, 0xDC, +0xD9, 0xC9, 0xC2, 0xBD, 0xC5, 0x58, 0x50, 0xE6, 0x4B, 0x37, 0x3F, 0x4F, 0x4D, 0x52, 0x6D, 0xDD, +0xC8, 0xC8, 0xDC, 0xDC, 0xD1, 0x72, 0x4A, 0x4A, 0x4E, 0x4B, 0x4E, 0x57, 0x6A, 0xDF, 0xD7, 0xDB, +0xD5, 0xCF, 0xDA, 0xF4, 0x74, 0x67, 0x5E, 0x5E, 0x5E, 0x66, 0xF9, 0xED, 0xEC, 0xE8, 0xE4, 0xE8, +0xF4, 0xF7, 0x60, 0x52, 0x6D, 0xF3, 0x5B, 0x66, 0xE7, 0xE1, 0xE0, 0xDF, 0xDF, 0xD8, 0xD1, 0xEA, +0x6B, 0xD9, 0xD1, 0xE5, 0xE6, 0xCC, 0xC4, 0xE7, 0x52, 0xEA, 0xE4, 0x4C, 0x48, 0x59, 0x5D, 0x59, +0x5D, 0x60, 0xF7, 0xDF, 0x79, 0x6A, 0xDF, 0xDC, 0xFE, 0xF8, 0xE2, 0xF0, 0x6F, 0x6B, 0x61, 0x5F, +0x62, 0x5D, 0x5E, 0x6C, 0x76, 0x70, 0xF7, 0xE5, 0xE6, 0xE7, 0xE5, 0xEA, 0xF4, 0x7D, 0x6C, 0x66, +0x68, 0x66, 0x66, 0x73, 0xF8, 0xF3, 0xF4, 0xF6, 0xFB, 0x7E, 0x7A, 0x7E, 0xF6, 0xEF, 0xED, 0xE9, +0xE9, 0xEF, 0xFB, 0x78, 0x6E, 0x69, 0x64, 0x63, 0x68, 0x6E, 0x74, 0x7B, 0xFA, 0xF6, 0xF3, 0xFF, +0x6B, 0x69, 0x69, 0x60, 0x5F, 0x65, 0x6C, 0x73, 0x7C, 0xF3, 0xEB, 0xE9, 0xEA, 0xE8, 0xE6, 0xE6, +0xE7, 0xE4, 0xDE, 0xDD, 0xE2, 0xE2, 0xE1, 0xE9, 0xF8, 0x77, 0x6B, 0x62, 0x5D, 0x5B, 0x5A, 0x59, +0x5A, 0x5B, 0x5D, 0x5E, 0x5E, 0x5E, 0x5F, 0x62, 0x67, 0x6D, 0x78, 0xFA, 0xF2, 0xEE, 0xEF, 0xF3, +0xF7, 0xF8, 0xFA, 0xFE, 0xFA, 0xF3, 0xF1, 0xEF, 0xEA, 0xE7, 0xE5, 0xE6, 0xE9, 0xEF, 0xFB, 0x79, +0x70, 0x6C, 0x6A, 0x6C, 0x6F, 0x77, 0x7C, 0xFD, 0xFB, 0x7F, 0x73, 0x6C, 0x69, 0x69, 0x6C, 0x73, +0xFA, 0xED, 0xE9, 0xE5, 0xE1, 0xE4, 0xE8, 0xE8, 0xE7, 0xE7, 0xE5, 0xE2, 0xE0, 0xDD, 0xDC, 0xE1, +0xE3, 0xE2, 0xEC, 0x7C, 0x6C, 0x63, 0x5D, 0x5B, 0x59, 0x58, 0x5A, 0x5B, 0x5B, 0x5C, 0x5F, 0x60, +0x5F, 0x60, 0x65, 0x6A, 0x75, 0xF8, 0xEC, 0xE7, 0xE6, 0xE7, 0xEA, 0xF0, 0xF8, 0xF9, 0xF4, 0xED, +0xE9, 0xE5, 0xE3, 0xE3, 0xE6, 0xEB, 0xF6, 0x76, 0x6C, 0x67, 0x62, 0x5F, 0x61, 0x64, 0x69, 0x6F, +0x73, 0x73, 0x75, 0x75, 0x70, 0x6E, 0x6F, 0x6E, 0x6E, 0x75, 0xFE, 0xF3, 0xEC, 0xE9, 0xE9, 0xE9, +0xED, 0xFA, 0x7A, 0x74, 0x71, 0x72, 0x73, 0x74, 0x7A, 0xFF, 0xFF, 0x7B, 0x72, 0x6E, 0x6D, 0x6C, +0x6C, 0x6E, 0x73, 0x7C, 0xFC, 0xF7, 0xF0, 0xEB, 0xE6, 0xE0, 0xDD, 0xDB, 0xDB, 0xDB, 0xDC, 0xDF, +0xE2, 0xE3, 0xE8, 0xF2, 0x7D, 0x6C, 0x61, 0x5D, 0x5A, 0x58, 0x59, 0x5C, 0x5E, 0x61, 0x66, 0x69, +0x6A, 0x6B, 0x6C, 0x6B, 0x6C, 0x75, 0xFE, 0xF7, 0xEE, 0xEA, 0xE8, 0xE6, 0xE9, 0xEC, 0xEB, 0xEB, +0xEE, 0xF0, 0xF2, 0xF6, 0xF9, 0xFD, 0x7F, 0xFF, 0x7C, 0x74, 0x6D, 0x69, 0x66, 0x64, 0x64, 0x68, +0x6B, 0x6D, 0x75, 0x7D, 0xFC, 0xF8, 0xFA, 0xFC, 0xFA, 0xF7, 0xF5, 0xF0, 0xEB, 0xE6, 0xE4, 0xE5, +0xE9, 0xED, 0xF2, 0xFC, 0x7A, 0x74, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x6E, +0x6D, 0x6E, 0x70, 0x71, 0x74, 0x79, 0x7B, 0x7E, 0xFB, 0xF6, 0xF8, 0xF9, 0xF6, 0xF5, 0xF8, 0xFA, +0xF7, 0xF0, 0xEE, 0xF0, 0xF7, 0xFC, 0x7D, 0x73, 0x6C, 0x6B, 0x6B, 0x6A, 0x6B, 0x6B, 0x6B, 0x6B, +0x6C, 0x6D, 0x6D, 0x6E, 0x71, 0x71, 0x71, 0x72, 0x77, 0x7D, 0xFC, 0xF7, 0xF3, 0xED, 0xEB, 0xEB, +0xEE, 0xF4, 0xF9, 0xFE, 0x79, 0x77, 0x7B, 0x7F, 0x7F, 0xFF, 0xFF, 0x7B, 0x77, 0x76, 0x77, 0x79, +0x79, 0x7A, 0x7C, 0xFF, 0xFC, 0xFC, 0xFA, 0xF8, 0xF9, 0xF9, 0xFA, 0xFD, 0xFE, 0xFD, 0xFA, 0xF8, +0xF5, 0xF2, 0xF1, 0xF2, 0xF4, 0xF8, 0xFE, 0x7C, 0x79, 0x77, 0x77, 0x7A, 0x7E, 0x7F, 0x7C, 0x79, +0x78, 0x75, 0x73, 0x72, 0x71, 0x73, 0x75, 0x76, 0x78, 0x7D, 0xFD, 0xFB, 0xFC, 0xFF, 0x7D, 0x79, +0x76, 0x76, 0x77, 0x7C, 0xFB, 0xF5, 0xF3, 0xF3, 0xF3, 0xF7, 0x7D, 0x74, 0x6F, 0x6D, 0x6B, 0x6C, +0x6E, 0x73, 0x77, 0x77, 0x77, 0x7A, 0x7A, 0x76, 0x73, 0x72, 0x6F, 0x6D, 0x6B, 0x6C, 0x6F, 0x76, +0x7A, 0x7D, 0xFE, 0xFC, 0x7E, 0x7A, 0x75, 0x71, 0x6E, 0x6D, 0x6E, 0x71, 0x77, 0x7D, 0xFE, 0xFC, +0xFC, 0xFE, 0xFF, 0x7D, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFC, 0xF9, 0xF7, 0xF6, 0xF8, 0xFA, 0xFC, +0xFF, 0x7E, 0x7F, 0xFF, 0xFD, 0xFB, 0xF7, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFD, 0x7D, 0x7A, 0x7A, +0x7D, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFD, 0xFD, +0xFB, 0xF8, 0xF7, 0xF9, 0xFD, 0x7C, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x75, 0x75, 0x75, 0x75, +0x75, 0x74, 0x76, 0x78, 0x79, 0x7B, 0x7D, 0x7F, 0xFD, 0xFB, 0xFF, 0x7A, 0x79, 0x7D, 0xFE, 0xFD, +0xFD, 0xFC, 0xFD, 0xFA, 0xF5, 0xF2, 0xF3, 0xF6, 0xF8, 0xF9, 0xFC, 0xFF, 0xFD, 0xF8, 0xF5, 0xF5, +0xF6, 0xFA, 0xFC, 0xFD, 0x7F, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x77, 0x7B, 0x7E, 0x7E, 0x7E, 0x7F, +0x7E, 0x7C, 0x79, 0x76, 0x76, 0x78, 0x79, 0x78, 0x7B, 0x7E, 0xFF, 0x7F, 0x7C, 0x7A, 0x78, 0x75, +0x73, 0x73, 0x74, 0x76, 0x77, 0x78, 0x7B, 0x7B, 0x79, 0x79, 0x78, 0x77, 0x78, 0x74, 0x71, 0x72, +0x73, 0x76, 0x77, 0x77, 0x79, 0x79, 0x77, 0x76, 0x75, 0x76, 0x78, 0x7B, 0x7F, 0xFC, 0xFB, 0xFB, +0xFA, 0xFB, 0xFE, 0x7C, 0x79, 0x79, 0x78, 0x78, 0x7B, 0xFF, 0xFD, 0xFD, 0xFC, 0xFC, 0xFE, 0x7E, +0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7B, 0x77, 0x78, 0x7A, +0x7A, 0x7A, 0x7C, 0x7E, 0xFF, 0x7F, 0x7F, 0xFF, 0xFF, 0x7F, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, +0x79, 0x79, 0x7B, 0x7E, 0x7E, 0x7F, 0xFD, 0xFC, 0xFD, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, +0xFF, 0x7E, 0x7D, 0x7F, 0xFF, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFE, 0x7E, 0x7F, 0x7E, 0x7B, +0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x77, 0x7A, +0x7C, 0x7D, 0x7E, 0x7E, 0x7C, 0x79, 0x76, 0x77, 0x79, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, +0x7D, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7B, 0x7C, +0x7C, 0x7C, 0x7D, 0xFF, 0xFC, 0xFB, 0xFB, 0xFC, 0xFF, 0x7C, 0x79, 0x77, 0x74, 0x75, 0x77, 0x7A, +0x7D, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7B, 0x7A, 0x7B, 0x7D, 0x7E, 0xFE, 0xFD, +0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x78, 0x76, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7C, +0x7A, 0x79, 0x78, 0x78, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7B, 0x7A, +0x7B, 0x7C, 0x7D, 0xFE, 0xFC, 0xFA, 0xF9, 0xFA, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFA, 0xF8, 0xF7, +0xF6, 0xF7, 0xF9, 0xFB, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x79, 0x7B, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, +0x7E, 0x7C, 0x7B, 0x79, 0x7A, 0x7C, 0x7C, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7E, 0x7C, 0x7B, 0x79, +0x77, 0x76, 0x76, 0x78, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7B, +0x7D, 0x79, 0x79, 0x7E, 0x79, 0x78, 0x79, 0x78, 0x7A, 0x78, 0x7D, 0x7D, 0x7C, 0xFF, 0x7D, 0x7F, +0x7E, 0x7B, 0x7A, 0x76, 0x79, 0x76, 0x78, 0x7B, 0x79, 0xFF, 0x7D, 0xFB, 0xFD, 0x7D, 0xF9, 0x7B, +0xFF, 0x79, 0x75, 0xFF, 0x6E, 0x7F, 0x71, 0x73, 0x79, 0x51, 0x60, 0xE2, 0x6F, 0x7D, 0xF7, 0xF5, +0x77, 0x72, 0xE4, 0x50, 0x4C, 0xDE, 0xFB, 0x66, 0xE5, 0xF6, 0x6F, 0x6C, 0xE7, 0xDC, 0x6E, 0xFD, +0xE6, 0x7E, 0xE9, 0x77, 0x62, 0xE3, 0xE9, 0x6C, 0x71, 0xEA, 0xDE, 0x75, 0x7E, 0xE8, 0x75, 0xF8, +0x7A, 0xFC, 0xF2, 0x65, 0xF8, 0xEE, 0xF9, 0xF4, 0x73, 0xE4, 0xF9, 0x6E, 0xE5, 0x75, 0x67, 0x5A, +0x50, 0x57, 0x5A, 0x7D, 0x6C, 0x64, 0xDA, 0xED, 0x64, 0xEA, 0xE9, 0xF5, 0x7E, 0x6F, 0xFC, 0xF2, +0x66, 0x63, 0xF7, 0x7D, 0x78, 0xF6, 0xF8, 0xE1, 0xE2, 0xF9, 0xEB, 0xE4, 0xED, 0xFE, 0xFA, 0xF6, +0xF1, 0xF2, 0x6F, 0xFE, 0xE8, 0xFF, 0x7F, 0xEA, 0xE8, 0xED, 0xEE, 0xEA, 0xEB, 0xED, 0xF8, 0xEF, +0xE8, 0x7F, 0xF5, 0xE6, 0xF7, 0xF2, 0xF3, 0xF2, 0xDF, 0xEB, 0xF5, 0xE3, 0xEC, 0xF2, 0xEF, 0xFC, +0xED, 0xEF, 0xFD, 0xED, 0xF0, 0x7C, 0x77, 0xFE, 0xF1, 0x77, 0x79, 0xEF, 0xF6, 0xF8, 0xFB, 0x72, +0x75, 0x79, 0x78, 0x70, 0x6E, 0x7C, 0x7D, 0x74, 0x79, 0x77, 0x6E, 0x71, 0x7D, 0x6F, 0x6B, 0x7D, +0xFE, 0x76, 0x7A, 0x7D, 0x7F, 0x75, 0x6C, 0x7B, 0xF7, 0x7A, 0x7B, 0x7E, 0x74, 0x79, 0x75, 0x70, +0x7C, 0x79, 0xFD, 0xF6, 0x6E, 0x6E, 0x7B, 0x6B, 0x67, 0x6D, 0x6E, 0x6A, 0x67, 0x6A, 0x6D, 0x6F, +0x6B, 0x67, 0x6D, 0x6C, 0x65, 0x63, 0x5E, 0x65, 0x6A, 0x5F, 0x68, 0x6C, 0x60, 0x6C, 0x7D, 0x6D, +0x6E, 0x7D, 0x7C, 0xFF, 0xEE, 0xEB, 0xEC, 0xE3, 0xDE, 0xE1, 0xE4, 0xE0, 0xE8, 0xF8, 0xEE, 0xFA, +0x6D, 0x69, 0x5C, 0x58, 0x59, 0x53, 0x50, 0x4E, 0x4D, 0x4E, 0x4F, 0x4F, 0x53, 0x51, 0x51, 0x54, +0x55, 0x56, 0x5A, 0x5E, 0x69, 0xF7, 0xE2, 0xD8, 0xCF, 0xCE, 0xCD, 0xCC, 0xCE, 0xCE, 0xCA, 0xC7, +0xC2, 0xBF, 0xBE, 0xBD, 0xC2, 0xD5, 0xF1, 0x62, 0x4B, 0x3F, 0x3D, 0x3D, 0x3E, 0x40, 0x42, 0x4A, +0x51, 0x51, 0x51, 0x55, 0x56, 0x4F, 0x4D, 0x4E, 0x50, 0x52, 0x55, 0x5C, 0x69, 0xFA, 0xE4, 0xD9, +0xCD, 0xC9, 0xC5, 0xC1, 0xBF, 0xBB, 0xBB, 0xBD, 0xB9, 0xB7, 0xB5, 0xB7, 0xC8, 0xDD, 0x61, 0x43, +0x3C, 0x38, 0x38, 0x3D, 0x40, 0x46, 0x4E, 0x5A, 0x60, 0x5D, 0x5B, 0x5B, 0x5A, 0x58, 0x56, 0x58, +0x5C, 0x5E, 0x5E, 0x64, 0x6B, 0x6D, 0xF9, 0xED, 0xE5, 0xDC, 0xD9, 0xD2, 0xCC, 0xC5, 0xBF, 0xBF, +0xBA, 0xB7, 0xB6, 0xB1, 0xB7, 0xCB, 0xFA, 0x49, 0x3A, 0x35, 0x31, 0x33, 0x3A, 0x42, 0x4C, 0x5C, +0xFD, 0xE1, 0xEE, 0x68, 0x66, 0x5C, 0x51, 0x4F, 0x4D, 0x55, 0x5F, 0x5D, 0x64, 0x71, 0xFA, 0xED, +0xEF, 0xEB, 0xDE, 0xD3, 0xCC, 0xC3, 0xBE, 0xBD, 0xB9, 0xB8, 0xB5, 0xAF, 0xB7, 0xCC, 0x60, 0x3F, +0x39, 0x34, 0x2F, 0x31, 0x3A, 0x47, 0x56, 0x6F, 0xE3, 0xDA, 0xD5, 0xEC, 0x56, 0x50, 0x4E, 0x4B, +0x4B, 0x4C, 0x57, 0x7B, 0xE7, 0xE0, 0xDC, 0xD5, 0xD6, 0xDE, 0xEC, 0xEF, 0xDE, 0xD7, 0xCC, 0xC1, +0xBD, 0xB8, 0xB5, 0xB4, 0xB0, 0xB6, 0xCB, 0x58, 0x3E, 0x38, 0x34, 0x2F, 0x2F, 0x38, 0x45, 0x59, +0x7D, 0xDD, 0xD1, 0xCE, 0xDD, 0x63, 0x53, 0x4E, 0x4C, 0x4A, 0x4B, 0x53, 0x69, 0xE7, 0xDB, 0xD5, +0xD0, 0xCE, 0xD3, 0xDC, 0xE4, 0xEA, 0xE8, 0xE2, 0xD5, 0xC8, 0xC0, 0xBB, 0xB8, 0xB5, 0xB2, 0xB9, +0xD1, 0x54, 0x40, 0x3A, 0x34, 0x2F, 0x2F, 0x36, 0x3F, 0x4C, 0x5B, 0x7E, 0xDE, 0xD4, 0xDB, 0xFF, +0x62, 0x58, 0x55, 0x53, 0x4F, 0x52, 0x5D, 0x6F, 0xF0, 0xE4, 0xDE, 0xDA, 0xD8, 0xDC, 0xE1, 0xE5, +0xDF, 0xDC, 0xD6, 0xCC, 0xC6, 0xC1, 0xBE, 0xBB, 0xB8, 0xBC, 0xCE, 0x67, 0x4B, 0x44, 0x3E, 0x38, +0x35, 0x37, 0x3D, 0x45, 0x4B, 0x53, 0x61, 0xFA, 0xE4, 0xEC, 0x7F, 0x79, 0x78, 0x79, 0x70, 0x68, +0x68, 0x70, 0x7B, 0x7D, 0x7D, 0xF9, 0xEE, 0xEA, 0xE8, 0xE6, 0xE1, 0xDB, 0xD6, 0xCF, 0xCB, 0xC8, +0xC5, 0xC1, 0xBE, 0xBF, 0xC7, 0xD5, 0xF9, 0x5F, 0x55, 0x4A, 0x42, 0x3E, 0x3E, 0x41, 0x45, 0x48, +0x4C, 0x56, 0x5F, 0x6F, 0xF8, 0xEF, 0xE7, 0xE4, 0xE6, 0xE2, 0xEA, 0xF5, 0xFD, 0x75, 0x75, 0x79, +0x75, 0x76, 0x7E, 0xFA, 0xF1, 0xE9, 0xE0, 0xDA, 0xD3, 0xCF, 0xCC, 0xCA, 0xC7, 0xC4, 0xC5, 0xCC, +0xD3, 0xDF, 0xFF, 0x69, 0x58, 0x4C, 0x47, 0x43, 0x42, 0x42, 0x43, 0x46, 0x4C, 0x55, 0x59, 0x62, +0x77, 0xFD, 0xEE, 0xEC, 0xF3, 0xEC, 0xF2, 0x76, 0x76, 0x6F, 0x6E, 0x79, 0x79, 0x7F, 0xF3, 0xED, +0xE4, 0xDD, 0xDB, 0xD7, 0xD3, 0xD0, 0xCE, 0xCC, 0xCB, 0xCA, 0xCC, 0xD1, 0xD6, 0xDD, 0xEA, 0x7E, +0x62, 0x56, 0x4F, 0x4C, 0x49, 0x48, 0x49, 0x4C, 0x50, 0x56, 0x58, 0x5C, 0x67, 0x6F, 0x6C, 0x6E, +0x6D, 0x6A, 0x6F, 0x6D, 0x6B, 0x6E, 0x6D, 0x76, 0xFA, 0xF9, 0xF1, 0xEB, 0xE7, 0xE1, 0xDE, 0xDD, +0xDB, 0xD8, 0xD7, 0xD4, 0xD2, 0xD0, 0xCF, 0xD4, 0xD8, 0xDA, 0xDF, 0xEA, 0xF8, 0x6D, 0x60, 0x5C, +0x58, 0x56, 0x56, 0x56, 0x57, 0x59, 0x5B, 0x5B, 0x5A, 0x5C, 0x5F, 0x5F, 0x5F, 0x63, 0x66, 0x6B, +0x72, 0x77, 0x7E, 0xF7, 0xF0, 0xEC, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xEA, 0xE7, 0xE6, 0xE5, +0xE3, 0xE1, 0xDD, 0xDA, 0xD9, 0xD8, 0xDD, 0xDF, 0xDD, 0xE0, 0xE7, 0xEE, 0xFE, 0x74, 0x6C, 0x62, +0x5C, 0x59, 0x56, 0x54, 0x52, 0x51, 0x51, 0x52, 0x55, 0x58, 0x59, 0x5D, 0x62, 0x68, 0x70, 0x75, +0x7D, 0xF9, 0xF8, 0xF4, 0xF5, 0xF9, 0xF5, 0xF3, 0xF3, 0xF2, 0xF2, 0xEF, 0xED, 0xEB, 0xEA, 0xE6, +0xE3, 0xE0, 0xDC, 0xDA, 0xD7, 0xD8, 0xDB, 0xDB, 0xDA, 0xDC, 0xDF, 0xE8, 0xF6, 0x7F, 0x6E, 0x60, +0x5B, 0x58, 0x56, 0x54, 0x53, 0x52, 0x53, 0x59, 0x5C, 0x5E, 0x63, 0x68, 0x6F, 0x7B, 0x7C, 0xFF, +0xFC, 0xFC, 0xFB, 0xFC, 0xFD, 0xF8, 0xF7, 0xF6, 0xF4, 0xF5, 0xF3, 0xF0, 0xEF, 0xED, 0xEB, 0xE8, +0xE4, 0xE0, 0xDD, 0xDA, 0xD9, 0xDA, 0xDC, 0xDC, 0xDC, 0xE0, 0xE9, 0xF8, 0x76, 0x6B, 0x61, 0x5C, +0x5A, 0x5A, 0x5A, 0x5B, 0x5C, 0x5E, 0x62, 0x67, 0x6B, 0x6D, 0x6F, 0x72, 0x75, 0x76, 0x76, 0x75, +0x74, 0x79, 0x7E, 0x7B, 0x78, 0x7D, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF5, 0xF2, 0xEF, 0xEC, 0xE9, +0xE4, 0xDF, 0xDE, 0xDE, 0xE0, 0xE7, 0xEA, 0xEC, 0xF2, 0xFE, 0x76, 0x6F, 0x6F, 0x6D, 0x6A, 0x6A, +0x6B, 0x6C, 0x6C, 0x69, 0x67, 0x67, 0x66, 0x65, 0x64, 0x64, 0x65, 0x66, 0x67, 0x69, 0x6B, 0x6E, +0x71, 0x76, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF4, 0xF0, 0xEE, 0xEC, 0xEA, 0xE9, 0xE8, 0xE9, +0xEB, 0xEB, 0xEC, 0xED, 0xEE, 0xED, 0xEB, 0xE9, 0xEA, 0xE9, 0xE9, 0xEA, 0xEC, 0xF0, 0xF6, 0xFD, +0x78, 0x71, 0x6D, 0x69, 0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x66, 0x66, 0x67, 0x67, 0x66, 0x66, +0x69, 0x6B, 0x6D, 0x73, 0x7A, 0xFE, 0xF7, 0xF3, 0xEF, 0xEE, 0xEE, 0xEC, 0xEB, 0xEA, 0xE8, 0xE7, +0xE5, 0xE3, 0xE1, 0xE1, 0xE1, 0xE3, 0xE6, 0xE8, 0xEB, 0xEF, 0xF8, 0x7E, 0x75, 0x6F, 0x6B, 0x69, +0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, +0x70, 0x6F, 0x6F, 0x6F, 0x72, 0x75, 0x79, 0xFF, 0xFB, 0xF6, 0xF2, 0xEF, 0xEE, 0xED, 0xEE, 0xF0, +0xF3, 0xF6, 0xF8, 0xFC, 0xFF, 0x7D, 0x79, 0x76, 0x72, 0x6E, 0x6D, 0x6B, 0x6B, 0x6C, 0x6C, 0x6D, +0x6E, 0x71, 0x76, 0x7B, 0xFF, 0xFE, 0xFD, 0xFC, 0xFD, 0x7F, 0x7B, 0x78, 0x75, 0x74, 0x75, 0x77, +0x7A, 0x7E, 0xFC, 0xF9, 0xF6, 0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xF8, 0xF7, 0xF6, 0xF5, 0xF5, +0xF6, 0xF8, 0xFA, 0xFC, 0x7F, 0x7B, 0x79, 0x78, 0x77, 0x77, 0x79, 0x7D, 0xFD, 0xF9, 0xF4, 0xF2, +0xF1, 0xF1, 0xF3, 0xF5, 0xFA, 0xFE, 0x7F, 0xFF, 0xFD, 0xFC, 0xFB, 0xF7, 0xF5, 0xF4, 0xF4, 0xF6, +0xF8, 0xFB, 0xFD, 0xFF, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7B, 0x79, 0x77, +0x76, 0x75, 0x74, 0x74, 0x75, 0x78, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0x7E, 0x7C, 0x7B, 0x79, +0x79, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xF9, 0xFB, 0xFD, 0x7F, 0x7B, 0x78, 0x76, 0x75, +0x74, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x7A, 0x7C, +0x7E, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x78, 0x77, 0x77, 0x76, 0x79, 0x7B, 0x7E, 0xFF, +0xFE, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7C, 0x7B, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x74, 0x74, +0x74, 0x74, 0x75, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFC, 0xF8, 0xF7, 0xF6, 0xF7, 0xF7, 0xF7, 0xF9, +0xFC, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7F, 0xFF, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, +0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xFA, 0xFD, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7D, 0x7E, 0xFE, +0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF9, 0xF9, 0xFA, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x79, 0x77, 0x75, +0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x71, 0x70, 0x71, 0x72, 0x71, 0x72, 0x71, 0x72, 0x73, 0x72, +0x72, 0x71, 0x71, 0x71, 0x72, 0x74, 0x74, 0x76, 0x77, 0x77, 0x77, 0x78, 0x77, 0x78, 0x78, 0x78, +0x7A, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, +0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7C, 0x7E, 0xFF, 0xFD, +0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7D, +0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, +0xFF, 0xFF, 0xFF, 0xFD, 0xFA, 0xF9, 0xF7, 0xF5, 0xF4, 0xF3, 0xF1, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, +0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFE, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, +0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7A, 0x7D, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, +0x77, 0x76, 0x75, 0x76, 0x75, 0x74, 0x74, 0x75, 0x74, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, 0x74, +0x72, 0x70, 0x70, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x70, 0x70, 0x70, 0x71, 0x72, 0x73, 0x73, 0x76, +0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7F, 0x7D, 0x7C, 0x7B, 0x7B, 0x7C, +0x7B, 0x7B, 0x7A, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0xFF, 0x7D, 0x7E, 0x7C, 0x7C, 0x7B, 0x78, +0x7C, 0x7A, 0x7C, 0x7D, 0x7B, 0x7E, 0x7C, 0x7F, 0x7D, 0x7A, 0x7E, 0x78, 0x7B, 0x6F, 0x68, 0x5C, +0x4C, 0x58, 0xDD, 0xE1, 0xEB, 0xE1, 0xE9, 0xEF, 0xF8, 0xE9, 0xE1, 0xED, 0xF9, 0xFC, 0xF2, 0xED, +0x7D, 0x76, 0xFB, 0xF9, 0x7C, 0x70, 0x6F, 0x78, 0x79, 0x6D, 0x6D, 0x76, 0x7D, 0xFE, 0x7A, 0x79, +0xFC, 0xFD, 0xFD, 0xFA, 0xFB, 0xFA, 0xFC, 0xFF, 0xFC, 0xFC, 0xFE, 0xFD, 0xFE, 0xFB, 0xFB, 0xFE, +0xFE, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x78, 0x7D, 0x7D, 0xFF, 0xFA, 0xFF, 0xF9, 0xF9, 0xFA, 0xF7, +0x7F, 0xF9, 0x7A, 0x7A, 0x6F, 0x51, 0x52, 0x6E, 0x71, 0xF1, 0xD8, 0xD3, 0xDB, 0xEF, 0xE2, 0xDB, +0xED, 0xF6, 0xF3, 0xEF, 0xF4, 0x6A, 0x74, 0x73, 0x57, 0x5E, 0x77, 0x6E, 0xFD, 0xF4, 0xFC, 0x7D, +0x73, 0xE9, 0xDE, 0xE2, 0xDE, 0xE3, 0xE5, 0xE8, 0xFA, 0xF7, 0xFA, 0x6F, 0x6C, 0x6A, 0x6B, 0x6A, +0x66, 0x6B, 0x75, 0x70, 0x74, 0xFA, 0xFB, 0xFD, 0xF8, 0xF3, 0xF2, 0xFB, 0xF5, 0xED, 0xEF, 0xEB, +0xE5, 0xDF, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD4, 0xD8, 0xE0, 0xEE, 0x76, 0x5D, 0x53, 0x4D, 0x49, +0x46, 0x43, 0x42, 0x43, 0x43, 0x45, 0x48, 0x4B, 0x4F, 0x57, 0x60, 0x6D, 0xF7, 0xE3, 0xDB, 0xD4, +0xCF, 0xCB, 0xC8, 0xC4, 0xBE, 0xBC, 0xB9, 0xB4, 0xB6, 0xBC, 0xC1, 0xC3, 0xD5, 0x4F, 0x4B, 0x43, +0x36, 0x33, 0x34, 0x32, 0x31, 0x36, 0x3B, 0x3F, 0x48, 0x60, 0xDF, 0xD2, 0xC9, 0xC1, 0xC3, 0xC6, +0xC7, 0xCF, 0xE3, 0x67, 0x56, 0x47, 0x3E, 0x3F, 0x3C, 0x3B, 0x43, 0x48, 0x4F, 0xFA, 0xD5, 0xC5, +0xBD, 0xB7, 0xB1, 0xAE, 0xAC, 0xAE, 0xB1, 0xB5, 0xC0, 0xD7, 0x5D, 0x40, 0x38, 0x31, 0x2E, 0x2D, +0x2C, 0x2E, 0x32, 0x37, 0x3F, 0x4F, 0xF8, 0xD0, 0xC4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBE, 0xC7, 0xD0, +0xF1, 0x56, 0x48, 0x40, 0x3D, 0x3B, 0x3D, 0x42, 0x49, 0x63, 0xDA, 0xCB, 0xBC, 0xB6, 0xB0, 0xAE, +0xAF, 0xAF, 0xB4, 0xBC, 0xC6, 0xFE, 0x4C, 0x3E, 0x34, 0x30, 0x2E, 0x2D, 0x2E, 0x30, 0x35, 0x3C, +0x46, 0x62, 0xDE, 0xCA, 0xBE, 0xBD, 0xBB, 0xBA, 0xBD, 0xC3, 0xCB, 0xDC, 0x6B, 0x59, 0x51, 0x52, +0x60, 0xFF, 0xD5, 0xC4, 0xBE, 0xBC, 0xBA, 0xB9, 0xBB, 0xC3, 0xC8, 0xD6, 0x5A, 0x4C, 0x42, 0x39, +0x36, 0x35, 0x32, 0x34, 0x36, 0x39, 0x41, 0x47, 0x58, 0xE0, 0xDA, 0xC9, 0xC1, 0xC4, 0xC0, 0xC0, +0xC6, 0xCA, 0xD1, 0xDC, 0xF3, 0x6E, 0xFC, 0xE8, 0xDB, 0xCB, 0xC2, 0xBE, 0xBD, 0xBE, 0xBD, 0xC0, +0xCD, 0xCE, 0xEC, 0x4E, 0x4C, 0x40, 0x38, 0x39, 0x37, 0x35, 0x38, 0x38, 0x3B, 0x43, 0x49, 0x54, +0xEA, 0xDB, 0xCE, 0xC5, 0xC5, 0xC3, 0xC1, 0xC7, 0xCA, 0xCF, 0xDB, 0xE9, 0xFD, 0xF7, 0xE9, 0xDD, +0xCE, 0xC6, 0xC1, 0xBF, 0xC0, 0xBF, 0xC3, 0xCF, 0xD0, 0xE6, 0x51, 0x4E, 0x43, 0x3A, 0x3B, 0x38, +0x35, 0x38, 0x38, 0x3A, 0x3F, 0x44, 0x4E, 0x5F, 0xEF, 0xD7, 0xCD, 0xC8, 0xC6, 0xC4, 0xC6, 0xC9, +0xCC, 0xD4, 0xDD, 0xE6, 0xE1, 0xDA, 0xD7, 0xCA, 0xC3, 0xC4, 0xC4, 0xC1, 0xC3, 0xCC, 0xCF, 0xD8, +0x60, 0x54, 0x4E, 0x3F, 0x3D, 0x3D, 0x39, 0x3A, 0x3C, 0x3B, 0x3D, 0x47, 0x48, 0x51, 0x79, 0xFA, +0xDD, 0xCD, 0xCF, 0xCC, 0xC8, 0xCD, 0xCE, 0xCE, 0xD7, 0xDC, 0xDC, 0xD7, 0xD4, 0xCC, 0xC3, 0xC1, +0xBF, 0xBF, 0xC2, 0xC1, 0xCE, 0xDB, 0xDD, 0x54, 0x4C, 0x49, 0x3C, 0x3B, 0x3B, 0x38, 0x3A, 0x3B, +0x3C, 0x3E, 0x48, 0x4C, 0x55, 0xF3, 0xEC, 0xDB, 0xCD, 0xD1, 0xCD, 0xCB, 0xD2, 0xD1, 0xD6, 0xDD, +0xE1, 0xE2, 0xD7, 0xD3, 0xCA, 0xC0, 0xBE, 0xBE, 0xBF, 0xBE, 0xC1, 0xCF, 0xD0, 0xED, 0x4E, 0x4D, +0x41, 0x3A, 0x3A, 0x37, 0x35, 0x38, 0x3A, 0x3A, 0x3F, 0x49, 0x4A, 0x62, 0xE7, 0xEA, 0xCE, 0xCB, +0xCF, 0xC8, 0xCB, 0xD1, 0xCF, 0xD7, 0xE2, 0xE5, 0xE5, 0xDF, 0xD5, 0xCC, 0xC5, 0xBE, 0xBE, 0xC0, +0xBC, 0xC0, 0xCD, 0xC8, 0xDC, 0x58, 0x5B, 0x47, 0x3C, 0x3D, 0x39, 0x36, 0x39, 0x3A, 0x39, 0x3E, +0x47, 0x49, 0x59, 0xEA, 0xEC, 0xD0, 0xC9, 0xCD, 0xC7, 0xC8, 0xCE, 0xCD, 0xD2, 0xDC, 0xDF, 0xDF, +0xDD, 0xD6, 0xCB, 0xC6, 0xBF, 0xBF, 0xC4, 0xBD, 0xC4, 0xD1, 0xC9, 0xEF, 0x55, 0x5D, 0x43, 0x3D, +0x3E, 0x38, 0x37, 0x3A, 0x3A, 0x3A, 0x3E, 0x45, 0x48, 0x56, 0x74, 0xF8, 0xD8, 0xCF, 0xD0, 0xCB, +0xCB, 0xCE, 0xCE, 0xD2, 0xD9, 0xDC, 0xDC, 0xD7, 0xD3, 0xCA, 0xC4, 0xC0, 0xBF, 0xC2, 0xBE, 0xC3, +0xCF, 0xCB, 0xE5, 0x58, 0x5C, 0x45, 0x3D, 0x3E, 0x39, 0x37, 0x39, 0x3A, 0x3A, 0x3D, 0x45, 0x46, +0x52, 0x79, 0x73, 0xD7, 0xCD, 0xD1, 0xC8, 0xC8, 0xCD, 0xCA, 0xCF, 0xD5, 0xD7, 0xDC, 0xDA, 0xD4, +0xCD, 0xC7, 0xC1, 0xC0, 0xC5, 0xBF, 0xC2, 0xD1, 0xCA, 0xDA, 0x5A, 0x68, 0x4C, 0x3E, 0x42, 0x3B, +0x38, 0x3B, 0x3A, 0x3A, 0x3D, 0x42, 0x44, 0x4B, 0x62, 0x66, 0xF1, 0xD0, 0xD6, 0xCD, 0xC8, 0xCE, +0xCA, 0xCB, 0xD1, 0xCF, 0xD2, 0xD2, 0xCE, 0xC9, 0xC5, 0xC1, 0xBF, 0xC5, 0xC1, 0xC0, 0xD3, 0xCE, +0xD6, 0x57, 0x5F, 0x4E, 0x3E, 0x41, 0x3D, 0x39, 0x3B, 0x3B, 0x3A, 0x3D, 0x42, 0x44, 0x4C, 0x5A, +0x5E, 0xEC, 0xDD, 0xDC, 0xCE, 0xD0, 0xD1, 0xCD, 0xD4, 0xD4, 0xD4, 0xDA, 0xD3, 0xCE, 0xCB, 0xC4, +0xBF, 0xBE, 0xC2, 0xBE, 0xBF, 0xCD, 0xCB, 0xD5, 0x5B, 0x5F, 0x4D, 0x3E, 0x3F, 0x3B, 0x37, 0x39, +0x3A, 0x39, 0x3C, 0x3F, 0x42, 0x4B, 0x59, 0x61, 0xEA, 0xDA, 0xD6, 0xCD, 0xCD, 0xCE, 0xCD, 0xCF, +0xD3, 0xD6, 0xDA, 0xD7, 0xD2, 0xCE, 0xC7, 0xC2, 0xBF, 0xC0, 0xC1, 0xBE, 0xC8, 0xCE, 0xCB, 0x79, +0x5A, 0x5C, 0x41, 0x3F, 0x3E, 0x38, 0x39, 0x3A, 0x39, 0x3A, 0x3E, 0x42, 0x45, 0x51, 0x62, 0x65, +0xDD, 0xD5, 0xD7, 0xCA, 0xCC, 0xCE, 0xCA, 0xCE, 0xD0, 0xCF, 0xCF, 0xCD, 0xC9, 0xC4, 0xBF, 0xBD, +0xBE, 0xBF, 0xBD, 0xC5, 0xCE, 0xCB, 0xF8, 0x58, 0x5B, 0x43, 0x3E, 0x3E, 0x39, 0x38, 0x3A, 0x39, +0x3A, 0x3E, 0x44, 0x45, 0x51, 0x6E, 0x69, 0xDC, 0xCF, 0xD7, 0xCA, 0xCB, 0xD0, 0xCC, 0xD1, 0xD5, +0xD5, 0xD5, 0xCF, 0xCB, 0xC5, 0xBF, 0xBC, 0xBD, 0xBF, 0xBB, 0xC3, 0xCC, 0xC8, 0xEF, 0x5B, 0x5D, +0x41, 0x3D, 0x3D, 0x37, 0x37, 0x38, 0x37, 0x38, 0x3B, 0x41, 0x43, 0x4E, 0x6B, 0x67, 0xDC, 0xCE, +0xD4, 0xC9, 0xC8, 0xCE, 0xCA, 0xCE, 0xD5, 0xD4, 0xD5, 0xD3, 0xCE, 0xC7, 0xC3, 0xBE, 0xBE, 0xC3, +0xBD, 0xC2, 0xD0, 0xC9, 0xDE, 0x57, 0x61, 0x47, 0x3D, 0x3F, 0x39, 0x36, 0x38, 0x38, 0x38, 0x3A, +0x41, 0x40, 0x48, 0x6A, 0x5C, 0xF7, 0xCD, 0xDB, 0xCD, 0xC6, 0xD1, 0xCC, 0xCC, 0xD6, 0xD5, 0xD3, +0xCF, 0xCE, 0xC6, 0xC0, 0xBF, 0xBE, 0xBF, 0xBE, 0xC0, 0xCC, 0xCB, 0xDB, 0x5D, 0x5B, 0x49, 0x3E, +0x3E, 0x39, 0x37, 0x38, 0x38, 0x38, 0x3B, 0x40, 0x42, 0x4A, 0x63, 0x66, 0xE5, 0xCE, 0xD0, 0xCA, +0xC7, 0xCA, 0xCA, 0xCC, 0xCE, 0xD1, 0xCF, 0xCC, 0xCC, 0xC4, 0xBF, 0xBF, 0xBE, 0xC0, 0xBE, 0xC2, +0xCE, 0xCC, 0xE2, 0x58, 0x59, 0x47, 0x3D, 0x3D, 0x39, 0x37, 0x39, 0x39, 0x39, 0x3C, 0x40, 0x44, +0x4D, 0x5D, 0x6F, 0xE0, 0xD4, 0xCF, 0xCC, 0xCB, 0xCB, 0xCD, 0xCF, 0xCF, 0xD4, 0xD1, 0xCC, 0xCA, +0xC4, 0xBF, 0xBD, 0xBF, 0xBF, 0xBE, 0xC7, 0xCF, 0xCE, 0x79, 0x52, 0x51, 0x41, 0x3C, 0x3B, 0x38, +0x36, 0x38, 0x39, 0x38, 0x3D, 0x44, 0x44, 0x55, 0x70, 0x76, 0xD5, 0xCF, 0xCF, 0xC9, 0xCB, 0xCB, +0xCD, 0xD1, 0xD1, 0xD9, 0xD2, 0xCD, 0xCD, 0xC4, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xC9, 0xCF, 0xD0, +0x6A, 0x53, 0x4F, 0x3F, 0x3C, 0x3B, 0x38, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x56, 0x75, +0xE7, 0xD7, 0xCD, 0xCB, 0xCA, 0xC9, 0xCA, 0xCD, 0xCE, 0xCF, 0xD3, 0xCE, 0xCA, 0xC7, 0xC0, 0xBE, +0xBE, 0xBF, 0xBF, 0xC1, 0xCD, 0xD2, 0xDB, 0x5C, 0x4F, 0x4A, 0x3E, 0x3C, 0x3B, 0x39, 0x38, 0x3A, +0x3A, 0x3C, 0x43, 0x46, 0x4E, 0x71, 0x7A, 0xDD, 0xCE, 0xD0, 0xCB, 0xCA, 0xCD, 0xCC, 0xD1, 0xD2, +0xD5, 0xD7, 0xCC, 0xCC, 0xC7, 0xBE, 0xBF, 0xBF, 0xBE, 0xC0, 0xC6, 0xCD, 0xD5, 0xEE, 0x54, 0x4D, +0x45, 0x3C, 0x3B, 0x39, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x59, 0x71, 0xE8, 0xD4, 0xCE, +0xCC, 0xC9, 0xCB, 0xCB, 0xCE, 0xD2, 0xD4, 0xD7, 0xD2, 0xCD, 0xCB, 0xC4, 0xBF, 0xBF, 0xC0, 0xC0, +0xC0, 0xC9, 0xD1, 0xD8, 0x73, 0x52, 0x4B, 0x42, 0x3C, 0x3A, 0x39, 0x38, 0x38, 0x39, 0x3C, 0x3F, +0x41, 0x4E, 0x5D, 0x63, 0xDF, 0xD3, 0xD1, 0xCD, 0xCB, 0xCC, 0xD1, 0xD1, 0xD3, 0xDE, 0xDA, 0xD1, +0xCF, 0xCC, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, 0xD2, 0xE3, 0x63, 0x4F, 0x4A, 0x42, 0x3C, +0x3B, 0x3A, 0x39, 0x3A, 0x3B, 0x3F, 0x42, 0x47, 0x5A, 0x62, 0x7C, 0xD5, 0xD2, 0xCF, 0xCC, 0xCD, +0xCE, 0xD5, 0xD6, 0xD9, 0xE0, 0xD9, 0xD2, 0xCE, 0xCB, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, +0xD4, 0xE2, 0x67, 0x4F, 0x4B, 0x43, 0x3D, 0x3C, 0x3B, 0x3B, 0x3B, 0x3C, 0x42, 0x43, 0x49, 0x60, +0x6B, 0xF5, 0xD4, 0xD2, 0xD0, 0xD2, 0xD2, 0xD4, 0xDF, 0xDD, 0xDF, 0xEA, 0xDC, 0xD5, 0xD0, 0xCB, +0xC4, 0xC0, 0xC2, 0xBF, 0xC0, 0xC7, 0xC9, 0xD0, 0xDD, 0x7A, 0x57, 0x52, 0x48, 0x3F, 0x3F, 0x3D, +0x3C, 0x3C, 0x3D, 0x42, 0x44, 0x49, 0x5B, 0x64, 0x7C, 0xDE, 0xDB, 0xDB, 0xDC, 0xDA, 0xDF, 0xEE, +0xE9, 0xE6, 0xE8, 0xE3, 0xDB, 0xD0, 0xCD, 0xCC, 0xC5, 0xC3, 0xC5, 0xC2, 0xC3, 0xC8, 0xCD, 0xD1, +0xDE, 0x6F, 0x5B, 0x50, 0x4A, 0x44, 0x40, 0x3F, 0x3E, 0x3E, 0x42, 0x43, 0x47, 0x4F, 0x58, 0x5F, +0x69, 0xF6, 0xED, 0xF7, 0xEB, 0xE8, 0xEA, 0xEC, 0xE8, 0xE0, 0xE0, 0xDD, 0xD7, 0xD0, 0xCE, 0xCC, +0xC8, 0xC7, 0xC6, 0xC4, 0xC8, 0xC9, 0xCB, 0xD2, 0xDA, 0xEF, 0x71, 0x5B, 0x4F, 0x4E, 0x49, 0x45, +0x46, 0x45, 0x47, 0x47, 0x4A, 0x4E, 0x4E, 0x54, 0x5A, 0x5D, 0x62, 0x65, 0x70, 0x6C, 0x69, 0xFA, +0x7A, 0x7A, 0xE6, 0xE2, 0xDF, 0xDA, 0xD5, 0xCF, 0xD1, 0xD1, 0xCB, 0xCE, 0xD4, 0xCE, 0xD1, 0xD9, +0xDB, 0xE0, 0xE1, 0xEE, 0x6A, 0x74, 0x6C, 0x5A, 0x5B, 0x5A, 0x56, 0x56, 0x53, 0x56, 0x57, 0x53, +0x57, 0x5B, 0x59, 0x59, 0x5D, 0x65, 0x60, 0x61, 0x6F, 0x73, 0xF7, 0xEF, 0xEA, 0xDD, 0xDF, 0xDC, +0xD5, 0xD8, 0xDC, 0xDC, 0xDA, 0xDF, 0xE5, 0xE1, 0xEB, 0xED, 0xED, 0xFC, 0xFF, 0x70, 0x6C, 0x6C, +0x66, 0x5F, 0x5F, 0x62, 0x5F, 0x60, 0x60, 0x5A, 0x5F, 0x64, 0x5C, 0x64, 0x6E, 0x5F, 0x5E, 0x69, +0x6B, 0x7B, 0xF0, 0xFA, 0xE9, 0xE4, 0xE8, 0xDF, 0xE6, 0xEB, 0xE1, 0xE2, 0xE6, 0xE3, 0xE8, 0xED, +0xE5, 0xFC, 0x71, 0xE9, 0xFE, 0x7A, 0xEC, 0x73, 0x7E, 0x77, 0x64, 0xFD, 0x74, 0x66, 0x7B, 0x6C, +0x6B, 0x72, 0x6A, 0x79, 0x73, 0x71, 0xF4, 0x79, 0xFC, 0xEF, 0xF9, 0xEB, 0xF1, 0xF0, 0xE2, 0xE3, +0xE0, 0xE2, 0xE3, 0xEB, 0xFC, 0xEA, 0xF8, 0x6F, 0x70, 0x69, 0x77, 0x6C, 0x6D, 0xEF, 0x6B, 0x67, +0x6D, 0x65, 0x76, 0x75, 0x6F, 0x7E, 0x69, 0x67, 0x6F, 0x68, 0x6F, 0x73, 0x68, 0x69, 0x68, 0x69, +0x75, 0xFA, 0xEE, 0xF2, 0xEA, 0xDE, 0xE2, 0xE7, 0xE5, 0xEB, 0xF3, 0xED, 0xE8, 0xF7, 0x7F, 0xFA, +0x74, 0x6A, 0x68, 0x65, 0x66, 0x68, 0x64, 0x65, 0x68, 0x64, 0x6D, 0x77, 0x72, 0x70, 0x69, 0x77, +0x78, 0x64, 0x6B, 0x68, 0x60, 0x66, 0x67, 0x67, 0x61, 0x6D, 0xEB, 0xE8, 0xEC, 0xEB, 0xEA, 0xF7, +0xF5, 0xE2, 0xE5, 0xF6, 0xF8, 0xF0, 0x7E, 0x77, 0xFA, 0x76, 0x77, 0x7D, 0x6E, 0x74, 0x74, 0x72, +0x72, 0x6D, 0x75, 0x74, 0x74, 0x75, 0x76, 0xEF, 0xEE, 0xEF, 0xEA, 0xFA, 0x7F, 0xF2, 0xF6, 0xF7, +0xEF, 0xEA, 0xE4, 0xE5, 0xE7, 0xE3, 0xE9, 0xEC, 0xE8, 0xEB, 0xF0, 0xF8, 0xFC, 0x7F, 0x73, 0x73, +0x70, 0x72, 0x75, 0x69, 0x67, 0x6A, 0x6C, 0x6D, 0x6C, 0x70, 0x6D, 0x6D, 0x78, 0x72, 0x6F, 0x6E, +0x6C, 0x6F, 0x77, 0xF7, 0xEF, 0xF1, 0xF6, 0xF4, 0xF1, 0xFC, 0xF8, 0xEE, 0xF0, 0xEE, 0xEF, 0xEF, +0xEC, 0xEE, 0xF3, 0xF4, 0x76, 0x69, 0x77, 0xFA, 0x70, 0x75, 0x7E, 0x6E, 0x6D, 0x6E, 0x6E, 0x6E, +0x6D, 0x70, 0x74, 0x79, 0xFE, 0x7D, 0x78, 0x7C, 0x7A, 0x75, 0x78, 0x75, 0x70, 0x7C, 0xFC, 0xFB, +0xF4, 0xF3, 0xED, 0xEC, 0xF6, 0xF1, 0xEF, 0xF6, 0xF0, 0xFB, 0x7A, 0x7C, 0x74, 0x79, 0x74, 0x6C, +0x6C, 0x63, 0x67, 0x6C, 0x62, 0x66, 0x67, 0x68, 0x6C, 0x6A, 0x7D, 0x78, 0x6B, 0x7B, 0x71, 0x75, +0xFB, 0x75, 0x76, 0x7E, 0xEE, 0xED, 0xFA, 0xE8, 0xEE, 0x7F, 0xE4, 0xE9, 0xED, 0xE1, 0xEC, 0xEE, +0xE6, 0xF6, 0xFE, 0xF7, 0xFF, 0x7B, 0x72, 0x7C, 0x7F, 0x6B, 0x6C, 0x66, 0x67, 0x71, 0x66, 0x72, +0xFF, 0x69, 0x7B, 0xF7, 0xFF, 0xF3, 0xF6, 0xF3, 0xF2, 0xEE, 0xED, 0xFF, 0xF6, 0xED, 0xFB, 0xF2, +0xE9, 0xF0, 0xEC, 0xE6, 0xF4, 0xF2, 0xF5, 0x7C, 0xED, 0x7E, 0x6B, 0x7B, 0x77, 0xFE, 0x7A, 0x69, +0x68, 0x60, 0x65, 0x66, 0x61, 0x71, 0x74, 0x74, 0xFC, 0x7E, 0xFA, 0xFF, 0x7E, 0xF9, 0xFB, 0xEE, +0xED, 0xEF, 0xEF, 0xF4, 0xEC, 0xEC, 0xF2, 0xF0, 0xEF, 0xED, 0xF4, 0xF6, 0xEF, 0xFD, 0xF8, 0xF1, +0x77, 0x74, 0x7A, 0x70, 0x6F, 0x79, 0x76, 0x6A, 0x68, 0x6C, 0x6C, 0x69, 0x65, 0x66, 0x6E, 0x73, +0x6C, 0x6D, 0x7A, 0x79, 0x7A, 0xFE, 0x73, 0x72, 0x7A, 0x7E, 0xF3, 0xEF, 0xEE, 0xF1, 0xF6, 0xEC, +0xEF, 0xFA, 0xEE, 0xF5, 0xFE, 0xF2, 0xF0, 0xF7, 0xFA, 0xF9, 0xFB, 0xFB, 0x7A, 0x6B, 0x6B, 0x72, +0x6C, 0x6A, 0x76, 0x74, 0x6E, 0x72, 0x6C, 0x6B, 0x6F, 0x6B, 0x6E, 0x71, 0x6D, 0x75, 0x76, 0x70, +0x78, 0x7C, 0xFA, 0xF2, 0xF7, 0xF1, 0xED, 0xF3, 0xF4, 0xF6, 0xFA, 0xF0, 0xEF, 0xFD, 0x7B, 0xFF, +0x78, 0x6C, 0x70, 0x72, 0x6E, 0x73, 0x6D, 0x6D, 0x6D, 0x65, 0x65, 0x69, 0x6F, 0x70, 0x6B, 0x6E, +0x71, 0x6E, 0x6E, 0x6F, 0x7A, 0x7D, 0x7E, 0xEF, 0xF4, 0x7D, 0xFB, 0xF3, 0xEC, 0xEB, 0xF0, 0xEF, +0xEE, 0xEE, 0xF3, 0xF0, 0xED, 0xFF, 0xFF, 0xF3, 0x7E, 0xFB, 0xFF, 0x73, 0x7E, 0x7A, 0x76, 0x6F, +0x6C, 0x7A, 0x74, 0x6F, 0xFF, 0x7B, 0x79, 0xF7, 0xF5, 0xFB, 0xF6, 0xF3, 0x7E, 0x7D, 0xFA, 0xFD, +0xF6, 0xF5, 0x7D, 0x7B, 0x7A, 0xFF, 0xFB, 0x7D, 0x75, 0x76, 0xF3, 0xF3, 0x78, 0xFE, 0x76, 0x6B, +0x7B, 0xFB, 0x75, 0x69, 0x6C, 0xF6, 0xF6, 0x7B, 0x6F, 0x69, 0x6E, 0x72, 0x70, 0x74, 0x78, 0xFF, +0x7F, 0xFD, 0xF5, 0xF8, 0xF5, 0xF9, 0x75, 0x74, 0x7D, 0xF7, 0xFB, 0x70, 0x7E, 0xE9, 0xEF, 0xF7, +0xE6, 0xED, 0x74, 0x7A, 0xF7, 0x7D, 0x71, 0x77, 0xFE, 0xF6, 0xFC, 0x6B, 0x6B, 0x72, 0x69, 0x6D, +0x7B, 0x7C, 0xFD, 0x6F, 0x6B, 0xFC, 0x7F, 0x73, 0xF9, 0xF5, 0x70, 0x6E, 0xFD, 0xFF, 0x7C, 0xFB, +0x70, 0x76, 0xEF, 0x7D, 0x75, 0xFB, 0xF6, 0xEF, 0xF6, 0x7C, 0x79, 0x76, 0xFE, 0x7D, 0x73, 0xFD, +0xFE, 0x76, 0x6E, 0x66, 0x6B, 0x75, 0x6D, 0x7D, 0xF2, 0x6D, 0x75, 0xED, 0x7A, 0x6D, 0x7E, 0xF9, +0xFE, 0x6E, 0x78, 0xF4, 0x6E, 0x73, 0xF8, 0x74, 0xFF, 0xFE, 0x77, 0xF6, 0x7C, 0x71, 0x7F, 0x7E, +0x7E, 0x79, 0x78, 0x7C, 0x6E, 0x6F, 0x70, 0x6D, 0xFD, 0xFA, 0x6C, 0x6B, 0x71, 0x70, 0x7B, 0x7A, +0x7C, 0xFD, 0x6D, 0x75, 0xED, 0xF8, 0xFC, 0xF7, 0xFB, 0xEE, 0xEF, 0x79, 0xFF, 0xED, 0xF8, 0x7A, +0xF1, 0xED, 0xF7, 0xFC, 0xF8, 0xF1, 0xF8, 0x79, 0x7D, 0xF6, 0x78, 0x6E, 0xFD, 0xFB, 0x72, 0x6E, +0x6C, 0x74, 0xFE, 0xFF, 0xF7, 0xFE, 0x6D, 0x75, 0x79, 0x6F, 0x7C, 0x7D, 0x76, 0x78, 0x7A, 0x7F, +0x75, 0x7D, 0xF7, 0xF8, 0xEF, 0x7B, 0x7A, 0xF3, 0xFF, 0xEF, 0xF8, 0xFE, 0xF6, 0x6E, 0xF4, 0xED, +0x6F, 0x7C, 0x74, 0x75, 0xF2, 0x7C, 0x75, 0xF9, 0xEE, 0xFF, 0x70, 0x7C, 0x7F, 0xFD, 0xFD, 0xFA, +0x79, 0x6C, 0x7C, 0x7F, 0xFD, 0xF3, 0x78, 0xFE, 0xF7, 0xFC, 0xED, 0xF1, 0xFD, 0xFE, 0x7D, 0xF4, +0xED, 0xF4, 0xFA, 0xFD, 0x70, 0x73, 0xF6, 0xFF, 0x7D, 0xF7, 0x79, 0x72, 0x78, 0x7D, 0x77, 0x6E, +0x71, 0x6C, 0x6A, 0x7D, 0x74, 0x71, 0x7D, 0x6E, 0x79, 0xF8, 0x70, 0x7C, 0xFE, 0x6D, 0x6F, 0x6E, +0x6D, 0x7D, 0xFD, 0xFB, 0xFA, 0x7C, 0xFD, 0xFA, 0xF7, 0xF4, 0xFD, 0x7B, 0x76, 0x7D, 0xF3, 0xF5, +0xFD, 0xF5, 0xED, 0x7A, 0x6D, 0xF5, 0x7C, 0x76, 0xEF, 0x77, 0x6E, 0xFF, 0x74, 0x79, 0xFD, 0x76, +0x7A, 0x7E, 0x7B, 0x7D, 0x78, 0x73, 0x7A, 0xFB, 0xFB, 0x7E, 0xFB, 0xF2, 0xF8, 0xF9, 0xFB, 0xFE, +0xF5, 0xF6, 0xF9, 0x7E, 0x73, 0xF7, 0xFA, 0x74, 0xFC, 0x7B, 0x70, 0xFF, 0xFC, 0x7E, 0x7C, 0xFE, +0xFF, 0x7C, 0xFC, 0x7E, 0x79, 0xFF, 0x7C, 0x79, 0x79, 0x79, 0x7A, 0x79, 0x7A, 0x7C, 0x7A, 0x75, +0x72, 0x7C, 0xFC, 0xFE, 0xFE, 0xFC, 0xF9, 0xFE, 0xFE, 0xFA, 0x7C, 0xFD, 0xFC, 0x77, 0x7B, 0x7A, +0x73, 0x78, 0x7A, 0x78, 0x7B, 0x77, 0x6E, 0x70, 0x7B, 0x7A, 0x72, 0x74, 0x76, 0x75, 0x77, 0x75, +0x70, 0x6F, 0x6F, 0x6F, 0x74, 0x77, 0x72, 0x6F, 0x70, 0x79, 0x79, 0x6F, 0x7E, 0xFA, 0x72, 0x79, +0x79, 0x78, 0xFE, 0x78, 0xFF, 0xFE, 0x76, 0xFF, 0xFF, 0x7D, 0xFF, 0x7E, 0x7B, 0x78, 0x7C, 0x75, +0x75, 0xFF, 0xFF, 0xF8, 0xF6, 0xFD, 0xF5, 0xF4, 0xF6, 0xFC, 0x7C, 0x7C, 0x7B, 0xFC, 0xFD, 0xFD, +0xFD, 0x77, 0x7A, 0x7F, 0x7E, 0xFC, 0xFA, 0xF7, 0xFF, 0xFE, 0xF1, 0xFD, 0xFD, 0xF0, 0xF9, 0xF8, +0xEE, 0xEF, 0xF8, 0x7E, 0x79, 0x77, 0x6C, 0x66, 0x6A, 0x68, 0x67, 0x71, 0x74, 0x77, 0x7E, 0x7B, +0xFD, 0xFD, 0x7F, 0xFF, 0x79, 0xFE, 0xFE, 0x75, 0x78, 0x7A, 0x74, 0x70, 0x76, 0x77, 0x75, 0x7C, +0x7C, 0x79, 0x78, 0x77, 0x78, 0x7C, 0x7E, 0x77, 0x74, 0x79, 0x77, 0x78, 0x78, 0x77, 0x7B, 0x78, +0x77, 0x77, 0x7A, 0xFE, 0x7D, 0xFE, 0xF6, 0xFB, 0xFC, 0xF8, 0xF6, 0xFA, 0xFD, 0xFB, 0xFC, 0x7D, +0x7B, 0xFB, 0xF5, 0xFC, 0xFF, 0xFD, 0xFE, 0xFF, 0x7F, 0xFC, 0xF8, 0xFF, 0x7F, 0xF7, 0xF9, 0xFA, +0xF9, 0xFB, 0xFA, 0xFA, 0xFA, 0xF8, 0xF8, 0xFD, 0x7E, 0xF8, 0xF7, 0xEF, 0xE0, 0xE1, 0xF7, 0x6E, +0x69, 0x65, 0x5C, 0x5B, 0x61, 0x69, 0x6E, 0x76, 0xF8, 0xEF, 0xF2, 0xEB, 0xE3, 0xDE, 0xE2, 0xFA, +0x66, 0x5B, 0x5F, 0x6E, 0x6E, 0xFB, 0xED, 0xED, 0xEC, 0xF8, 0x7E, 0x7B, 0x6E, 0x67, 0x60, 0x65, +0x6E, 0x6F, 0x78, 0xFB, 0x7E, 0x7D, 0xFA, 0xF9, 0xF7, 0xF5, 0xF7, 0xEE, 0xEB, 0xF3, 0xFA, 0x7A, +0x6D, 0x69, 0x6A, 0x69, 0x64, 0x69, 0x6E, 0x6F, 0x78, 0xFB, 0xFB, 0x7C, 0xF8, 0xF1, 0xFB, 0xF4, +0xF9, 0x7D, 0xF8, 0x7D, 0xFD, 0xF3, 0x7C, 0xFD, 0xF4, 0x7A, 0x6F, 0x79, 0xFF, 0x75, 0x78, 0xFA, +0xFB, 0xFE, 0xFB, 0xF9, 0xFE, 0xFF, 0xFF, 0xFC, 0xF5, 0xFD, 0x79, 0xFF, 0xF9, 0xFA, 0xFF, 0xFF, +0x7B, 0x74, 0x75, 0x6F, 0x71, 0x7D, 0x74, 0x75, 0x79, 0x71, 0x77, 0x7E, 0x7E, 0x7C, 0x74, 0x71, +0x77, 0x7A, 0x7F, 0xFB, 0x72, 0x69, 0x74, 0x74, 0x6A, 0x74, 0x7E, 0x79, 0x76, 0x74, 0x7F, 0x7C, +0x76, 0xF8, 0xF8, 0x7E, 0x7D, 0x7E, 0xFE, 0x77, 0x7B, 0xF8, 0x7B, 0xFF, 0xF3, 0xFC, 0xFF, 0xFE, +0xFD, 0xF5, 0xF6, 0xF3, 0xF2, 0xFA, 0xF8, 0xF3, 0xFB, 0x7E, 0xFA, 0xFA, 0x7E, 0xFE, 0xFC, 0x7C, +0x78, 0x7D, 0xFB, 0xF3, 0xFD, 0x74, 0xF7, 0xF5, 0x76, 0xF9, 0xF8, 0xFF, 0xF5, 0x76, 0x7B, 0xFA, +0x77, 0xFD, 0x7C, 0x77, 0x7D, 0x6F, 0x7D, 0xF7, 0xFC, 0xFD, 0x7B, 0xF5, 0xF8, 0x7A, 0xF4, 0xFB, +0x77, 0x7B, 0x76, 0x74, 0x7D, 0x7E, 0x72, 0x71, 0x70, 0x70, 0x77, 0x70, 0x7B, 0xFD, 0x6F, 0x72, +0x7D, 0x7A, 0x71, 0x79, 0xF8, 0x77, 0x6F, 0x74, 0x7A, 0x78, 0x7C, 0xF6, 0x7C, 0xFB, 0x7D, 0x6C, +0xEF, 0xFC, 0x6D, 0xF1, 0xF5, 0x7D, 0x79, 0xFA, 0xF5, 0x75, 0xF4, 0x7C, 0xFC, 0xE6, 0x68, 0x78, +0xE4, 0x6E, 0x77, 0xF2, 0x7E, 0x70, 0x69, 0xF9, 0xF7, 0x6C, 0x74, 0xF3, 0xEE, 0x79, 0x7E, 0xFB, +0x7A, 0xF6, 0x6C, 0x6B, 0xED, 0x77, 0x6A, 0x70, 0x6F, 0xFC, 0x7E, 0x79, 0xF2, 0xEE, 0xF8, 0x7D, +0xEF, 0xEB, 0x7E, 0x72, 0x7D, 0x74, 0x6B, 0xFA, 0xE5, 0xE7, 0xE4, 0xEB, 0xF8, 0xEC, 0xEA, 0xF3, +0xFB, 0xFA, 0xEF, 0xF6, 0x7C, 0xFF, 0x7B, 0x72, 0x78, 0x7C, 0x6F, 0x6E, 0xFF, 0xFF, 0x75, 0x74, +0x74, 0x76, 0x6C, 0x6A, 0x7F, 0x78, 0x6D, 0x74, 0x6E, 0x76, 0x7B, 0x69, 0x6B, 0x79, 0x72, 0x6A, +0x6D, 0x77, 0xFD, 0xFC, 0x6F, 0x7C, 0xEE, 0x76, 0x69, 0x74, 0xFB, 0x74, 0x6A, 0x7D, 0xF0, 0xFF, +0x6B, 0x71, 0xEF, 0x7D, 0x74, 0xF8, 0x75, 0x74, 0x77, 0x6C, 0x6E, 0x71, 0x73, 0x72, 0x70, 0xF4, +0xF0, 0x79, 0x7B, 0xFB, 0xF3, 0xF4, 0x78, 0x79, 0xF7, 0xFC, 0x6E, 0x70, 0xF8, 0xF8, 0x79, 0x6D, +0x70, 0xFB, 0x6E, 0x64, 0x6B, 0x72, 0x6F, 0x65, 0x71, 0xFC, 0x71, 0x76, 0x6E, 0x71, 0xF9, 0xFF, +0xFD, 0x73, 0x7A, 0xFF, 0x66, 0x70, 0xFE, 0x79, 0xFD, 0x7D, 0xF1, 0xF6, 0x76, 0x79, 0x6D, 0x79, +0xFF, 0x72, 0x7F, 0xF8, 0xF0, 0xFF, 0x71, 0xEC, 0xE9, 0x7C, 0x7C, 0xF1, 0xF7, 0xF7, 0xF5, 0xFA, +0xF1, 0x7C, 0x70, 0x7D, 0xFB, 0xF4, 0x7C, 0x7D, 0xF6, 0xFD, 0xEF, 0xF6, 0xEE, 0xE1, 0xEE, 0xF4, +0xF3, 0xEE, 0xF4, 0x78, 0xEC, 0xF7, 0x72, 0x74, 0x6E, 0xF5, 0x6A, 0x7B, 0xDF, 0x69, 0x7F, 0xE7, +0x6F, 0x7C, 0x68, 0xF4, 0xEE, 0x5C, 0x72, 0x6B, 0x6D, 0xEC, 0x60, 0x7E, 0xEB, 0x66, 0x6D, 0x6A, +0x7A, 0xFF, 0x6A, 0x6E, 0x74, 0xED, 0x79, 0x6B, 0xED, 0xFA, 0xFC, 0x70, 0x65, 0xF6, 0x75, 0x67, +0x78, 0x78, 0xF4, 0xFF, 0x5F, 0xF9, 0xE3, 0x6D, 0xF1, 0x7A, 0x70, 0xDB, 0x6A, 0xF9, 0xDC, 0x66, +0xDB, 0xF8, 0x65, 0xD6, 0x6A, 0xF2, 0xE6, 0x5E, 0xE1, 0x76, 0x6F, 0xF5, 0x65, 0xEF, 0x5F, 0x66, +0x6F, 0x5A, 0xFB, 0x5E, 0x65, 0x7E, 0x60, 0xF2, 0x5D, 0x72, 0xE8, 0x5A, 0xEA, 0x6E, 0x62, 0xE4, +0x5E, 0x6F, 0x74, 0x67, 0xEA, 0x64, 0x77, 0xF3, 0x69, 0xF1, 0x6B, 0x6E, 0xEB, 0x74, 0x74, 0x74, +0xF6, 0xF5, 0x66, 0xF5, 0xF7, 0x6C, 0xE9, 0x70, 0x6F, 0xE4, 0x6E, 0xF0, 0xF4, 0x63, 0xE1, 0xFE, +0x6D, 0xE4, 0x6D, 0xF2, 0xEF, 0x6C, 0xE8, 0x7B, 0xFC, 0xED, 0x74, 0xEB, 0xFE, 0xFC, 0xEF, 0x6D, +0xEC, 0xFB, 0x71, 0xEB, 0x77, 0xF3, 0xF8, 0x6F, 0xE9, 0xFE, 0xFC, 0xEE, 0x6F, 0xEB, 0xED, 0x7A, +0xEE, 0xF4, 0xF3, 0xF8, 0xF1, 0xEE, 0x79, 0xF4, 0xF3, 0xFC, 0xF1, 0x7C, 0xF4, 0xF9, 0x76, 0xE8, +0xF8, 0x75, 0xE3, 0x7B, 0x6E, 0xE0, 0x75, 0x72, 0xE3, 0x6C, 0xF8, 0xE7, 0x6D, 0xEA, 0xF4, 0x75, +0xEA, 0x71, 0xFA, 0xED, 0x6A, 0xF2, 0xFB, 0x70, 0xEB, 0x6F, 0x71, 0xEE, 0x6C, 0xF6, 0xF2, 0x68, +0xF3, 0xF8, 0x6D, 0x7A, 0xFC, 0x75, 0x6D, 0xF3, 0x6E, 0x6E, 0xEE, 0x61, 0x7C, 0xFE, 0x60, 0xF2, +0x6D, 0x78, 0x7C, 0x63, 0xEB, 0x64, 0x71, 0xED, 0x5C, 0xEB, 0x6F, 0x69, 0xEA, 0x5D, 0xE7, 0xF8, +0x5E, 0xE6, 0x6F, 0xFA, 0x79, 0x72, 0xE8, 0x5E, 0xE9, 0xFB, 0x5F, 0xDE, 0x61, 0xFA, 0xE3, 0x5A, +0xE3, 0x79, 0x62, 0xDF, 0x64, 0x76, 0xE4, 0x63, 0xFE, 0xE9, 0x64, 0xF8, 0xE6, 0x5F, 0xF2, 0xE8, +0x62, 0xE7, 0xFB, 0x6A, 0xF0, 0x77, 0xF9, 0x77, 0xE9, 0x78, 0x59, 0xE3, 0x71, 0x6C, 0xDF, 0x5F, +0xEF, 0xE9, 0x5F, 0xFA, 0x76, 0xF9, 0x7D, 0x67, 0xEE, 0x7B, 0x6F, 0x7E, 0x6B, 0x6D, 0xF7, 0x6E, +0x6B, 0xF0, 0x63, 0xF0, 0x75, 0x57, 0xD4, 0x59, 0x57, 0xCD, 0x4F, 0xEE, 0xDE, 0x4B, 0xCF, 0x68, +0x5B, 0xD4, 0x50, 0xE0, 0xEF, 0x54, 0xD5, 0x57, 0x6A, 0xD3, 0x54, 0x79, 0xDF, 0x5E, 0xFC, 0xE6, +0x5F, 0x71, 0xE0, 0x64, 0x76, 0xFC, 0x5D, 0xEA, 0xF8, 0x58, 0x79, 0xDB, 0x68, 0x59, 0xDF, 0x76, +0x64, 0xDA, 0x63, 0x5A, 0xD9, 0xE0, 0x51, 0xF3, 0xD3, 0x4D, 0xDE, 0xCF, 0x3F, 0xDA, 0xC2, 0x41, +0x6A, 0xC3, 0x50, 0x55, 0xC6, 0x5A, 0x4B, 0xC2, 0x7A, 0x46, 0xCA, 0xDF, 0x4C, 0xD8, 0xDE, 0x4F, +0xE2, 0xD2, 0x4D, 0x6B, 0xCD, 0x5C, 0x56, 0xD8, 0xEB, 0x54, 0xEF, 0xDE, 0x4F, 0x78, 0xD7, 0x54, +0x5B, 0xDA, 0xFA, 0x56, 0xF6, 0xE9, 0x58, 0xF1, 0xE5, 0x59, 0x6D, 0xE8, 0x7B, 0x64, 0x7E, 0xE2, +0x60, 0x6D, 0xDC, 0x63, 0x67, 0xDC, 0x6F, 0x62, 0xE2, 0x7B, 0x60, 0xEC, 0xF3, 0x67, 0x77, 0xF1, +0x7C, 0x75, 0xF0, 0x79, 0x6F, 0xED, 0x76, 0x6B, 0xF3, 0xFF, 0x74, 0xF4, 0xF8, 0x6B, 0x6C, 0xE6, +0xE7, 0x61, 0x79, 0xDD, 0x6F, 0x77, 0xDE, 0x6D, 0x6E, 0xE4, 0x7E, 0xF9, 0xE8, 0x6D, 0x6F, 0xDE, +0xEF, 0x5C, 0xEF, 0xDB, 0x64, 0x6B, 0xDF, 0xF9, 0x6C, 0xF4, 0xF5, 0x72, 0xF5, 0xF7, 0x66, 0x7D, +0xE9, 0x7D, 0x70, 0x79, 0xF6, 0x7B, 0x6C, 0xF3, 0xF2, 0x6A, 0x76, 0xED, 0x79, 0x6B, 0xF2, 0xF1, +0x6B, 0x78, 0xEF, 0x73, 0x74, 0xED, 0x73, 0x6A, 0xEB, 0xF2, 0x64, 0x6F, 0xE2, 0xF8, 0x5E, 0xF3, +0xE8, 0x64, 0x74, 0xEF, 0x7B, 0x77, 0x74, 0x78, 0x6D, 0xF8, 0xEA, 0x63, 0x68, 0xEC, 0xEF, 0x6E, +0x63, 0xEE, 0xFA, 0x5F, 0xE5, 0xEB, 0x58, 0x73, 0xD1, 0xF3, 0x4D, 0xF2, 0xCD, 0x5D, 0x54, 0xDF, +0xDD, 0x61, 0x5B, 0xD9, 0xDF, 0x50, 0xF0, 0xD3, 0x5F, 0x5D, 0xE4, 0xDF, 0x6E, 0x5B, 0xED, 0xD8, +0x68, 0x56, 0xEA, 0xD3, 0x70, 0x52, 0xF0, 0xD3, 0x74, 0x57, 0xF5, 0xD8, 0x6A, 0x58, 0xE4, 0xE2, +0x5C, 0x7A, 0xD8, 0x77, 0x5A, 0xE8, 0xD9, 0x73, 0x5F, 0x7D, 0xE3, 0xEC, 0x73, 0x72, 0x6E, 0xF6, +0xDF, 0xF7, 0x62, 0x6B, 0xE5, 0xDD, 0x6B, 0x58, 0xF7, 0xDB, 0x73, 0x5E, 0x75, 0x7E, 0xF6, 0xFE, +0x66, 0x71, 0x7B, 0x7E, 0xEE, 0x6C, 0x6B, 0xEB, 0x76, 0x6C, 0xEA, 0x7A, 0x67, 0xE5, 0xE8, 0x5F, +0x75, 0xDE, 0xEE, 0x6F, 0x7A, 0xED, 0xE8, 0xF8, 0xFB, 0xF4, 0x78, 0xF1, 0xE4, 0x6E, 0x62, 0xEB, +0xEC, 0x65, 0x6D, 0x7E, 0x6B, 0x69, 0x6E, 0x72, 0x78, 0x68, 0x5E, 0x74, 0xE9, 0x6F, 0x5E, 0x72, +0xEB, 0x7A, 0x6F, 0xF1, 0x78, 0x75, 0xE5, 0xE6, 0xE2, 0xDD, 0xE0, 0xD6, 0xD1, 0xD5, 0xD1, 0xD3, +0xDE, 0xE0, 0xDD, 0xE9, 0x68, 0x57, 0x52, 0x50, 0x4B, 0x48, 0x48, 0x48, 0x48, 0x4B, 0x51, 0x56, +0x56, 0x5D, 0x68, 0x6A, 0x69, 0x7C, 0xE8, 0xED, 0xED, 0xDC, 0xD5, 0xCD, 0xCB, 0xCD, 0xC5, 0xBE, +0xBE, 0xBC, 0xBC, 0xBF, 0xC5, 0xD2, 0x72, 0x52, 0x48, 0x40, 0x3C, 0x39, 0x39, 0x3B, 0x3D, 0x40, +0x4A, 0x5A, 0x6C, 0x7E, 0xDF, 0xCF, 0xCE, 0xDB, 0x6F, 0x63, 0x6E, 0x60, 0x4D, 0x47, 0x4D, 0x5E, +0x7C, 0xFA, 0xE4, 0xCD, 0xC1, 0xBD, 0xBC, 0xBA, 0xB7, 0xB4, 0xB5, 0xBE, 0xD7, 0xEB, 0xF2, 0x4E, +0x3B, 0x36, 0x37, 0x39, 0x38, 0x39, 0x3D, 0x48, 0x58, 0xFE, 0xDA, 0xD6, 0xD8, 0xCF, 0xC8, 0xCD, +0xF3, 0x5A, 0x59, 0x58, 0x4E, 0x47, 0x48, 0x4F, 0x5F, 0xF2, 0xD9, 0xCE, 0xC6, 0xBF, 0xBB, 0xBA, +0xB9, 0xB7, 0xB5, 0xB7, 0xC0, 0xD9, 0x68, 0x57, 0x49, 0x3B, 0x35, 0x35, 0x38, 0x3A, 0x3B, 0x3F, +0x4B, 0x60, 0xE7, 0xD8, 0xD5, 0xD4, 0xCE, 0xCA, 0xCF, 0xF9, 0x59, 0x51, 0x4E, 0x4C, 0x48, 0x46, +0x49, 0x56, 0xFB, 0xD9, 0xD1, 0xC9, 0xBE, 0xB8, 0xB6, 0xB5, 0xB3, 0xB2, 0xB6, 0xC3, 0xE5, 0x60, +0x4E, 0x3F, 0x37, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x41, 0x4E, 0x6F, 0xDA, 0xD2, 0xD4, 0xD1, 0xCA, +0xC9, 0xD7, 0x6F, 0x59, 0x4D, 0x47, 0x47, 0x48, 0x45, 0x46, 0x52, 0xEE, 0xD7, 0xD0, 0xC7, 0xBC, +0xB5, 0xB3, 0xB3, 0xB1, 0xB0, 0xB7, 0xCA, 0x68, 0x4F, 0x45, 0x3B, 0x32, 0x2E, 0x30, 0x35, 0x39, +0x3D, 0x44, 0x52, 0xEC, 0xD0, 0xCF, 0xD3, 0xD0, 0xCD, 0xCF, 0xE3, 0x63, 0x5B, 0x59, 0x52, 0x4D, +0x4C, 0x4F, 0x5A, 0x6D, 0xE5, 0xD2, 0xC8, 0xBE, 0xB9, 0xB5, 0xB3, 0xB1, 0xAF, 0xB1, 0xBD, 0xE3, +0x53, 0x4B, 0x40, 0x35, 0x2E, 0x2F, 0x34, 0x39, 0x3B, 0x3F, 0x4C, 0x75, 0xDA, 0xD6, 0xD2, 0xCE, +0xCE, 0xD0, 0xD9, 0xEF, 0x62, 0x56, 0x55, 0x55, 0x4F, 0x4E, 0x52, 0x61, 0xEF, 0xDB, 0xCC, 0xBF, +0xB9, 0xB5, 0xB3, 0xB0, 0xAE, 0xB4, 0xC8, 0x63, 0x4D, 0x45, 0x39, 0x2E, 0x2C, 0x2F, 0x35, 0x38, +0x3B, 0x43, 0x5A, 0xDD, 0xCE, 0xCD, 0xCC, 0xCB, 0xCD, 0xD2, 0xDE, 0x76, 0x5A, 0x52, 0x53, 0x51, +0x4E, 0x4F, 0x5C, 0x7C, 0xE2, 0xD2, 0xC5, 0xBB, 0xB5, 0xB2, 0xB0, 0xAE, 0xAE, 0xB6, 0xCF, 0x55, +0x48, 0x3F, 0x34, 0x2C, 0x2C, 0x2F, 0x36, 0x39, 0x3D, 0x4A, 0x7D, 0xCE, 0xCA, 0xCB, 0xCB, 0xCB, +0xCD, 0xD9, 0x76, 0x59, 0x4F, 0x4C, 0x4C, 0x4A, 0x4C, 0x54, 0x68, 0xEC, 0xD8, 0xCB, 0xBF, 0xB8, +0xB3, 0xB0, 0xAE, 0xAD, 0xAE, 0xBC, 0xF5, 0x4C, 0x43, 0x39, 0x2E, 0x2A, 0x2D, 0x32, 0x37, 0x3B, +0x44, 0x5F, 0xD5, 0xC8, 0xC7, 0xC9, 0xCB, 0xCE, 0xD3, 0xE9, 0x5A, 0x4D, 0x4D, 0x4D, 0x4B, 0x4B, +0x50, 0x63, 0xF6, 0xDE, 0xCE, 0xC5, 0xBD, 0xB7, 0xB2, 0xB0, 0xAF, 0xAD, 0xAF, 0xBF, 0x5E, 0x45, +0x40, 0x37, 0x2C, 0x29, 0x2D, 0x34, 0x38, 0x3C, 0x48, 0x77, 0xCD, 0xC6, 0xC7, 0xCB, 0xCB, 0xCF, +0xE9, 0x59, 0x4E, 0x4B, 0x47, 0x44, 0x47, 0x4D, 0x57, 0x69, 0xEB, 0xD7, 0xCA, 0xBF, 0xB9, 0xB3, +0xAF, 0xAE, 0xAD, 0xAC, 0xB5, 0xDE, 0x49, 0x43, 0x3B, 0x2D, 0x28, 0x2A, 0x30, 0x36, 0x3A, 0x44, +0x6A, 0xCD, 0xC2, 0xC2, 0xC6, 0xCA, 0xCC, 0xD8, 0x60, 0x4C, 0x48, 0x46, 0x44, 0x43, 0x49, 0x54, +0x68, 0xEC, 0xD8, 0xCB, 0xC2, 0xBC, 0xB8, 0xB2, 0xAF, 0xAE, 0xAE, 0xAE, 0xBA, 0x74, 0x45, 0x3F, +0x36, 0x2C, 0x29, 0x2C, 0x32, 0x37, 0x3E, 0x4E, 0xE3, 0xC7, 0xC2, 0xC5, 0xC6, 0xC8, 0xD2, 0x71, +0x52, 0x4D, 0x49, 0x42, 0x41, 0x47, 0x51, 0x60, 0x7B, 0xDE, 0xCE, 0xC6, 0xC0, 0xBE, 0xB9, 0xB2, +0xAF, 0xAF, 0xAE, 0xAE, 0xBC, 0x6B, 0x47, 0x3F, 0x34, 0x2C, 0x2A, 0x2D, 0x32, 0x39, 0x3F, 0x4F, +0xDF, 0xC5, 0xC4, 0xCD, 0xCA, 0xC7, 0xDB, 0x5A, 0x4E, 0x4D, 0x48, 0x42, 0x40, 0x45, 0x54, 0x6F, +0x74, 0xEC, 0xCD, 0xC4, 0xC4, 0xC1, 0xBB, 0xB3, 0xAF, 0xB0, 0xAE, 0xAE, 0xBC, 0x6F, 0x4A, 0x3F, +0x34, 0x2C, 0x2B, 0x2E, 0x34, 0x3B, 0x42, 0x56, 0xCF, 0xBF, 0xC2, 0xCB, 0xC6, 0xC6, 0xE6, 0x52, +0x4B, 0x47, 0x45, 0x3F, 0x3D, 0x45, 0x5E, 0x7A, 0x72, 0xDB, 0xC7, 0xC3, 0xC5, 0xC2, 0xBC, 0xB5, +0xB1, 0xB3, 0xB0, 0xAE, 0xB9, 0xF0, 0x4C, 0x43, 0x38, 0x2E, 0x2B, 0x2D, 0x34, 0x3A, 0x3E, 0x4F, +0xD3, 0xC1, 0xC4, 0xCD, 0xCC, 0xC8, 0xDE, 0x4D, 0x45, 0x47, 0x47, 0x41, 0x3D, 0x47, 0x6D, 0xF7, +0x79, 0xDA, 0xC9, 0xC6, 0xC8, 0xC9, 0xC0, 0xB8, 0xB4, 0xB5, 0xB0, 0xAC, 0xB1, 0xCF, 0x5A, 0x4E, +0x3E, 0x30, 0x2B, 0x2D, 0x33, 0x38, 0x3B, 0x48, 0xDC, 0xC4, 0xC5, 0xCA, 0xCB, 0xCB, 0xD9, 0x50, +0x46, 0x4B, 0x46, 0x3E, 0x3F, 0x48, 0x55, 0x76, 0x7E, 0xE3, 0xCA, 0xC9, 0xCE, 0xCB, 0xC6, 0xBE, +0xBA, 0xB8, 0xB4, 0xAE, 0xAE, 0xBD, 0xEA, 0x62, 0x48, 0x35, 0x2D, 0x2C, 0x30, 0x35, 0x37, 0x3F, +0x6F, 0xCB, 0xCA, 0xC9, 0xC7, 0xCE, 0xD9, 0x60, 0x46, 0x46, 0x48, 0x40, 0x40, 0x49, 0x52, 0x69, +0xED, 0xE1, 0xD1, 0xCC, 0xD0, 0xD2, 0xD0, 0xCD, 0xC2, 0xBD, 0xB9, 0xB2, 0xAE, 0xAF, 0xBA, 0xE0, +0x67, 0x4C, 0x34, 0x2D, 0x2E, 0x30, 0x34, 0x37, 0x41, 0xF4, 0xCD, 0xCC, 0xC7, 0xC5, 0xD0, 0xED, +0x64, 0x4D, 0x45, 0x47, 0x43, 0x44, 0x4F, 0x51, 0x69, 0xD9, 0xDD, 0xD1, 0xCB, 0xD1, 0xCF, 0xD2, +0xCD, 0xBF, 0xBC, 0xB8, 0xB0, 0xAD, 0xAE, 0xBC, 0xD9, 0x76, 0x48, 0x32, 0x2D, 0x2F, 0x30, 0x32, +0x38, 0x49, 0xE6, 0xD1, 0xCB, 0xC1, 0xC1, 0xD2, 0x7A, 0x6F, 0x51, 0x42, 0x43, 0x45, 0x4A, 0x4D, +0x4E, 0x72, 0xD7, 0xDB, 0xD8, 0xCE, 0xCF, 0xD7, 0xDD, 0xD3, 0xC6, 0xBF, 0xBB, 0xB3, 0xAD, 0xAE, +0xB8, 0xCD, 0xE2, 0x52, 0x35, 0x2E, 0x2F, 0x2F, 0x2F, 0x35, 0x43, 0x62, 0xE5, 0xCF, 0xC1, 0xC0, +0xD1, 0xE1, 0xDB, 0x5E, 0x46, 0x49, 0x4D, 0x4A, 0x49, 0x51, 0x6A, 0xEE, 0xEB, 0xDE, 0xD0, 0xD4, +0xDF, 0xDC, 0xD7, 0xCF, 0xC5, 0xBE, 0xB7, 0xB1, 0xAE, 0xAF, 0xBC, 0xD3, 0xE7, 0x48, 0x31, 0x2E, +0x2F, 0x2E, 0x2F, 0x36, 0x44, 0x5B, 0xF4, 0xCC, 0xBF, 0xC2, 0xD4, 0xD1, 0xCF, 0x59, 0x4B, 0x51, +0x4B, 0x46, 0x44, 0x4C, 0x56, 0x51, 0x66, 0xE5, 0xE6, 0xE0, 0xDF, 0xD6, 0xD1, 0xCD, 0xC0, 0xBB, +0xB7, 0xB0, 0xAD, 0xB0, 0xBD, 0xCE, 0xEF, 0x44, 0x31, 0x2F, 0x30, 0x2E, 0x2E, 0x39, 0x46, 0x56, +0xF0, 0xC7, 0xBD, 0xC2, 0xC9, 0xC8, 0xCC, 0x7A, 0x50, 0x57, 0x4F, 0x42, 0x42, 0x4A, 0x4C, 0x4C, +0x5D, 0xEF, 0xEE, 0xE3, 0xD6, 0xD1, 0xD2, 0xCC, 0xC0, 0xBC, 0xBA, 0xB3, 0xAE, 0xAF, 0xBA, 0xC9, +0xD6, 0x4F, 0x36, 0x30, 0x30, 0x2E, 0x2D, 0x34, 0x3E, 0x45, 0x5C, 0xCF, 0xC1, 0xC0, 0xC1, 0xC0, +0xC9, 0xD9, 0xF5, 0x54, 0x4A, 0x47, 0x40, 0x41, 0x42, 0x45, 0x4E, 0x53, 0x68, 0xE8, 0xE1, 0xD1, +0xCD, 0xCC, 0xC5, 0xBF, 0xBB, 0xB8, 0xB4, 0xAF, 0xB0, 0xBD, 0xCB, 0xD8, 0x4B, 0x36, 0x34, 0x33, +0x2E, 0x2E, 0x37, 0x3D, 0x44, 0x62, 0xCD, 0xC4, 0xC0, 0xBE, 0xBF, 0xC5, 0xCF, 0xEE, 0x66, 0x4F, +0x45, 0x43, 0x40, 0x41, 0x44, 0x47, 0x51, 0x5B, 0x71, 0xDD, 0xD8, 0xCE, 0xC8, 0xC6, 0xC1, 0xBD, +0xB9, 0xB7, 0xB2, 0xAF, 0xB9, 0xC3, 0xCC, 0x71, 0x40, 0x37, 0x36, 0x31, 0x2E, 0x33, 0x3A, 0x3D, +0x4A, 0xE6, 0xCF, 0xC7, 0xBE, 0xBF, 0xC2, 0xCA, 0xD3, 0xE6, 0x50, 0x4C, 0x4B, 0x3E, 0x3E, 0x43, +0x41, 0x47, 0x4D, 0x59, 0x75, 0xE4, 0xD0, 0xCC, 0xC9, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB3, 0xB3, +0xBB, 0xC3, 0xCD, 0x6A, 0x42, 0x3A, 0x38, 0x31, 0x30, 0x36, 0x39, 0x3C, 0x4B, 0x7A, 0xDB, 0xCB, +0xC1, 0xC3, 0xC5, 0xC5, 0xD5, 0xE5, 0x6B, 0x4E, 0x4C, 0x43, 0x40, 0x45, 0x42, 0x48, 0x50, 0x55, +0x6C, 0xE8, 0xD7, 0xCD, 0xCC, 0xC7, 0xC3, 0xC0, 0xBD, 0xBC, 0xB8, 0xB2, 0xB5, 0xBD, 0xC2, 0xD0, +0x5D, 0x45, 0x3C, 0x38, 0x32, 0x32, 0x37, 0x37, 0x3C, 0x4C, 0x5E, 0xEE, 0xCD, 0xC5, 0xC8, 0xC6, +0xC5, 0xD0, 0xE2, 0xF9, 0x5D, 0x4D, 0x47, 0x46, 0x42, 0x41, 0x47, 0x4B, 0x4E, 0x63, 0xEA, 0xE3, +0xD3, 0xC9, 0xCB, 0xC8, 0xC0, 0xBF, 0xBD, 0xBA, 0xB5, 0xB6, 0xBC, 0xC1, 0xCC, 0x7E, 0x4B, 0x3F, +0x3B, 0x35, 0x32, 0x37, 0x37, 0x3A, 0x45, 0x50, 0x6D, 0xD7, 0xC8, 0xC6, 0xC7, 0xC2, 0xCA, 0xD7, +0xDB, 0x6D, 0x59, 0x4F, 0x48, 0x48, 0x45, 0x46, 0x4D, 0x4F, 0x5E, 0xFF, 0xE6, 0xD7, 0xD4, 0xCF, +0xD1, 0xD5, 0xD0, 0xD3, 0xCD, 0xC6, 0xC1, 0xBA, 0xB8, 0xBB, 0xC2, 0xC4, 0xCD, 0x58, 0x4C, 0x48, +0x39, 0x36, 0x39, 0x36, 0x37, 0x3E, 0x44, 0x4B, 0x66, 0xDC, 0xD4, 0xCA, 0xC3, 0xC5, 0xC7, 0xCA, +0xCE, 0xDD, 0x6D, 0x5F, 0x4F, 0x46, 0x47, 0x46, 0x43, 0x49, 0x4E, 0x53, 0x65, 0xF1, 0xE4, 0xD9, +0xCF, 0xCE, 0xCD, 0xC6, 0xC3, 0xC0, 0xBA, 0xB7, 0xB7, 0xBD, 0xC4, 0xC5, 0xFD, 0x4A, 0x4C, 0x3B, +0x33, 0x37, 0x34, 0x32, 0x3A, 0x3F, 0x47, 0x5B, 0xDC, 0xCB, 0xC8, 0xBE, 0xBC, 0xC3, 0xC0, 0xC7, +0xDE, 0xEC, 0x5B, 0x49, 0x45, 0x3F, 0x3E, 0x3F, 0x40, 0x49, 0x4E, 0x5B, 0xEF, 0xDF, 0xD4, 0xCC, +0xCA, 0xC7, 0xC5, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB8, 0xC0, 0xCB, 0xCA, 0x68, 0x45, 0x4D, 0x3D, +0x35, 0x3C, 0x3A, 0x38, 0x41, 0x49, 0x4D, 0x69, 0xDB, 0xD3, 0xCD, 0xC5, 0xC6, 0xCC, 0xCB, 0xD0, +0xEB, 0x76, 0x5C, 0x4C, 0x48, 0x44, 0x41, 0x41, 0x44, 0x49, 0x4E, 0x5D, 0x7E, 0xE6, 0xD4, 0xCE, +0xCE, 0xCB, 0xCB, 0xCE, 0xCE, 0xCA, 0xC9, 0xC6, 0xBE, 0xBC, 0xC6, 0xCA, 0xC4, 0xE0, 0x58, 0x77, +0x4A, 0x3D, 0x45, 0x3D, 0x39, 0x3F, 0x41, 0x40, 0x4C, 0x61, 0x6D, 0xE7, 0xCE, 0xCC, 0xCC, 0xC9, +0xCA, 0xD1, 0xDB, 0xE2, 0x66, 0x54, 0x50, 0x48, 0x45, 0x47, 0x47, 0x4B, 0x51, 0x5A, 0x71, 0xEB, +0xDD, 0xD5, 0xD2, 0xCF, 0xCC, 0xCC, 0xCA, 0xC4, 0xC3, 0xBF, 0xB9, 0xBD, 0xCB, 0xC0, 0xC9, 0x56, +0x71, 0x5A, 0x3A, 0x3F, 0x3E, 0x34, 0x3A, 0x3E, 0x3C, 0x42, 0x54, 0x62, 0x73, 0xCF, 0xC8, 0xCC, +0xC3, 0xC3, 0xCD, 0xCF, 0xDD, 0x6D, 0x56, 0x4D, 0x48, 0x42, 0x42, 0x44, 0x45, 0x4D, 0x57, 0x61, +0xED, 0xDB, 0xD5, 0xCD, 0xCD, 0xCD, 0xCD, 0xD0, 0xCD, 0xD1, 0xCA, 0xC4, 0xC7, 0xBA, 0xC2, 0xD8, +0xBB, 0xD7, 0x53, 0xCC, 0x4E, 0x3E, 0x57, 0x3E, 0x3B, 0x43, 0x3F, 0x3E, 0x46, 0x52, 0x50, 0x60, +0xD6, 0xD9, 0xD4, 0xC6, 0xCA, 0xCF, 0xCB, 0xD5, 0xF4, 0xFB, 0x5D, 0x4E, 0x4C, 0x4B, 0x46, 0x45, +0x4F, 0x4E, 0x4D, 0x7E, 0x6F, 0x71, 0xD4, 0xE1, 0xDF, 0xCE, 0xD9, 0xD5, 0xCD, 0xCD, 0xC5, 0xBF, +0xB9, 0xBA, 0xC6, 0xBA, 0xBF, 0x6C, 0xCE, 0xFB, 0x3D, 0x4D, 0x40, 0x35, 0x3C, 0x3B, 0x38, 0x3E, +0x47, 0x4B, 0x52, 0xDF, 0xD8, 0xD6, 0xC3, 0xC6, 0xCB, 0xC5, 0xCD, 0xDD, 0xE4, 0x6B, 0x50, 0x4D, +0x49, 0x44, 0x45, 0x47, 0x48, 0x49, 0x50, 0x5D, 0x5C, 0xEE, 0xDD, 0xE7, 0xD1, 0xD5, 0xDC, 0xD0, +0xDA, 0xD8, 0xD1, 0xCD, 0xC6, 0xBF, 0xBA, 0xC1, 0xC4, 0xBA, 0xD3, 0xE1, 0xCC, 0x4D, 0x49, 0x4F, +0x3B, 0x3B, 0x3E, 0x3A, 0x3C, 0x42, 0x4A, 0x4C, 0x6D, 0xD9, 0xDC, 0xC9, 0xC4, 0xCA, 0xC6, 0xC8, +0xD0, 0xD8, 0xE5, 0x68, 0x58, 0x53, 0x4C, 0x4A, 0x4B, 0x4C, 0x4E, 0x56, 0x5F, 0x69, 0xEA, 0xE0, +0xE8, 0xD5, 0xDD, 0xE7, 0xD9, 0xFB, 0xF9, 0xF5, 0x64, 0x75, 0x6D, 0xF5, 0xE5, 0xD8, 0xC8, 0xC4, +0xBB, 0xBF, 0xC4, 0xB7, 0xCC, 0xD6, 0xC3, 0x56, 0x52, 0x5F, 0x3D, 0x3E, 0x3E, 0x39, 0x3A, 0x3D, +0x41, 0x41, 0x4F, 0x6B, 0x63, 0xD6, 0xCD, 0xD1, 0xC7, 0xC8, 0xCE, 0xCE, 0xD6, 0xE8, 0x71, 0x67, +0x55, 0x4F, 0x52, 0x4D, 0x4F, 0x56, 0x56, 0x5E, 0x6D, 0x7E, 0xF5, 0xDF, 0xE3, 0xEE, 0xDC, 0x7B, +0x73, 0xED, 0x5C, 0x6A, 0x69, 0x5B, 0x70, 0x6D, 0xEF, 0xE1, 0xCF, 0xC8, 0xC4, 0xB9, 0xC5, 0xC2, +0xB6, 0xDC, 0xCD, 0xC3, 0x49, 0x60, 0x57, 0x3A, 0x40, 0x3D, 0x38, 0x3A, 0x3E, 0x3F, 0x3E, 0x53, +0x58, 0x59, 0xD3, 0xD7, 0xD2, 0xC4, 0xC9, 0xCA, 0xC8, 0xCD, 0xD8, 0xDE, 0xEE, 0x5F, 0x5D, 0x59, +0x4F, 0x54, 0x56, 0x54, 0x5D, 0x69, 0x6D, 0xF2, 0xE1, 0xDF, 0xDB, 0xD8, 0xDD, 0xE8, 0xEB, 0x71, +0x5D, 0x66, 0x56, 0x52, 0x62, 0x52, 0x5C, 0x74, 0x63, 0xE2, 0xDD, 0xD4, 0xCA, 0xC9, 0xBF, 0xC0, +0xBB, 0xBB, 0xCC, 0xBB, 0xC8, 0x68, 0xC8, 0x58, 0x44, 0x5D, 0x3C, 0x3B, 0x40, 0x3A, 0x3B, 0x3F, +0x44, 0x43, 0x52, 0x7A, 0x62, 0xD4, 0xCB, 0xD1, 0xC3, 0xC4, 0xC8, 0xC5, 0xCA, 0xD0, 0xD9, 0xE1, +0x6C, 0x5C, 0x5B, 0x4E, 0x4D, 0x50, 0x4C, 0x50, 0x58, 0x58, 0x63, 0x79, 0xFE, 0xED, 0xE1, 0xE7, +0xEE, 0xE6, 0xFB, 0x6D, 0x7A, 0x61, 0x5D, 0x62, 0x59, 0x5B, 0x5E, 0x5C, 0x64, 0x69, 0x72, 0xFE, +0xF1, 0xE6, 0xE2, 0xDB, 0xD9, 0xD6, 0xD3, 0xD3, 0xD0, 0xD0, 0xCF, 0xCE, 0xCD, 0xCD, 0xDA, 0xDB, +0xDA, 0x64, 0x69, 0x63, 0x4C, 0x4F, 0x4D, 0x46, 0x4A, 0x4A, 0x48, 0x4D, 0x52, 0x52, 0x5C, 0x70, +0x71, 0xEB, 0xDC, 0xDE, 0xD7, 0xD4, 0xD8, 0xD5, 0xD7, 0xDD, 0xDF, 0xE7, 0xFD, 0x71, 0x69, 0x5D, +0x5A, 0x5A, 0x57, 0x56, 0x5B, 0x59, 0x5A, 0x69, 0x62, 0x6A, 0xF5, 0x73, 0xF1, 0xE7, 0xF4, 0xE6, +0xE6, 0xEE, 0xEA, 0xED, 0xF5, 0xF1, 0xED, 0xF0, 0xEA, 0xE4, 0xE7, 0xDF, 0xDE, 0xDF, 0xDC, 0xDE, +0xDF, 0xE1, 0xE8, 0xEE, 0xFD, 0x77, 0x6B, 0x64, 0x61, 0x5C, 0x5C, 0x5C, 0x5B, 0x5F, 0x61, 0x67, +0x6E, 0x78, 0xF8, 0xF1, 0xEA, 0xE5, 0xE4, 0xE2, 0xE1, 0xE5, 0xEA, 0xED, 0xFA, 0x77, 0x6E, 0x66, +0x62, 0x5D, 0x5C, 0x5A, 0x59, 0x59, 0x59, 0x5B, 0x5C, 0x5D, 0x64, 0x64, 0x6C, 0x77, 0x7C, 0xEE, +0xEB, 0xE0, 0xDB, 0xD7, 0xCF, 0xCF, 0xCA, 0xC8, 0xC5, 0xC4, 0xCD, 0xC7, 0xCB, 0xE8, 0xD3, 0xFD, +0x55, 0x67, 0x4B, 0x45, 0x48, 0x40, 0x3F, 0x42, 0x43, 0x43, 0x4A, 0x50, 0x50, 0x6C, 0xF5, 0xF2, +0xD4, 0xD2, 0xD1, 0xCB, 0xCC, 0xCE, 0xCE, 0xD0, 0xDA, 0xDC, 0xDF, 0xFD, 0x7D, 0x6F, 0x5E, 0x5F, +0x5D, 0x59, 0x5A, 0x5C, 0x5C, 0x5F, 0x68, 0x68, 0x6F, 0xFC, 0xFC, 0xEF, 0xE9, 0xEB, 0xE9, 0xE9, +0xED, 0xEF, 0xF2, 0xF8, 0xFE, 0xFE, 0x7C, 0x7C, 0x7E, 0x79, 0xFE, 0xFB, 0xFE, 0xF7, 0xF6, 0xF9, +0xF6, 0xF8, 0xFD, 0xFF, 0x7C, 0x73, 0x70, 0x6E, 0x6A, 0x6A, 0x69, 0x68, 0x6A, 0x6B, 0x6C, 0x6F, +0x74, 0x79, 0xFF, 0xFA, 0xF8, 0xF2, 0xF4, 0xF6, 0xF3, 0xFE, 0xFB, 0x74, 0x62, 0x69, 0x5F, 0x5A, +0x66, 0x5B, 0x5D, 0x70, 0x61, 0x78, 0xED, 0xF4, 0xDB, 0xD7, 0xD0, 0xCB, 0xC9, 0xC3, 0xCC, 0xC9, +0xC4, 0xDD, 0xD2, 0xD7, 0x59, 0x6E, 0x57, 0x45, 0x4B, 0x45, 0x3F, 0x43, 0x44, 0x43, 0x49, 0x51, +0x4F, 0x5E, 0xFB, 0x70, 0xDE, 0xD8, 0xDC, 0xD1, 0xD2, 0xD7, 0xD4, 0xD6, 0xDD, 0xDF, 0xDF, 0xF1, +0xF2, 0xF2, 0x6F, 0x73, 0x72, 0x69, 0x6D, 0x6F, 0x6D, 0x72, 0x7B, 0x79, 0x7E, 0xF8, 0xFD, 0xF9, +0xF6, 0xFD, 0xFA, 0xFA, 0xFD, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF8, 0xF3, 0xF2, 0xF4, 0xEF, 0xF1, +0xF4, 0xF2, 0xF6, 0xF9, 0xF8, 0xF9, 0xFD, 0xFD, 0xFC, 0x7F, 0x7E, 0x7D, 0x79, 0x76, 0x74, 0x71, +0x6F, 0x6E, 0x6C, 0x6C, 0x6D, 0x6B, 0x6C, 0x6D, 0x6C, 0x71, 0x71, 0x70, 0x7E, 0x79, 0x7C, 0xFA, +0x7B, 0xFD, 0xFC, 0x7A, 0xFE, 0x7C, 0x78, 0x7B, 0x76, 0x76, 0x78, 0x77, 0x77, 0x7C, 0x7E, 0xFF, +0xF2, 0xF3, 0xED, 0xE7, 0xE8, 0xE0, 0xDE, 0xDC, 0xD7, 0xD8, 0xD3, 0xD4, 0xDA, 0xD7, 0xDF, 0xEB, +0xED, 0x6A, 0x60, 0x5C, 0x52, 0x4F, 0x4D, 0x4B, 0x4A, 0x4B, 0x4B, 0x4D, 0x50, 0x54, 0x5B, 0x66, +0x6F, 0xF1, 0xE6, 0xDF, 0xDA, 0xD8, 0xD8, 0xD7, 0xD9, 0xDB, 0xDE, 0xE2, 0xEA, 0xF1, 0xFA, 0x78, +0x70, 0x6D, 0x69, 0x68, 0x66, 0x65, 0x65, 0x66, 0x66, 0x67, 0x6A, 0x6B, 0x6C, 0x70, 0x74, 0x79, +0xFB, 0xF5, 0xEF, 0xEB, 0xE9, 0xE6, 0xE3, 0xE2, 0xE1, 0xE0, 0xE0, 0xE0, 0xE1, 0xE3, 0xE3, 0xE6, +0xE9, 0xEB, 0xEF, 0xF7, 0x7F, 0x75, 0x6E, 0x6A, 0x66, 0x62, 0x61, 0x5F, 0x5F, 0x60, 0x5F, 0x62, +0x65, 0x66, 0x6C, 0x6E, 0x72, 0x7D, 0xFE, 0xF6, 0xEF, 0xED, 0xE9, 0xE7, 0xE4, 0xE3, 0xE0, 0xDF, +0xE1, 0xDF, 0xE1, 0xE3, 0xE3, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xF5, 0xF6, 0xF9, 0x75, +0x76, 0x6E, 0x66, 0x65, 0x5E, 0x5B, 0x5A, 0x56, 0x55, 0x54, 0x53, 0x54, 0x55, 0x57, 0x59, 0x5D, +0x60, 0x66, 0x70, 0x79, 0xFA, 0xF0, 0xEE, 0xEC, 0xED, 0xED, 0xF0, 0xF5, 0xF8, 0xFF, 0xFD, 0x7E, +0x7D, 0xFE, 0x7E, 0xFD, 0xF8, 0xF6, 0xEF, 0xED, 0xEB, 0xE8, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDC, +0xDD, 0xDC, 0xDD, 0xE1, 0xE2, 0xE9, 0xF3, 0x7A, 0x65, 0x61, 0x5B, 0x56, 0x56, 0x51, 0x50, 0x52, +0x50, 0x55, 0x58, 0x59, 0x5F, 0x68, 0x70, 0xFC, 0xEE, 0xE9, 0xE4, 0xE1, 0xE4, 0xE4, 0xE7, 0xED, +0xEE, 0xF8, 0xFF, 0x7D, 0x76, 0x76, 0x7A, 0x7B, 0xFF, 0xF9, 0xF7, 0xF1, 0xED, 0xED, 0xEB, 0xE9, +0xEA, 0xEA, 0xEC, 0xED, 0xEE, 0xF0, 0xF1, 0xF2, 0xF2, 0xF3, 0xF0, 0xF1, 0xF3, 0xEF, 0xF3, 0xF5, +0xF4, 0xFB, 0xFC, 0xFC, 0x7C, 0x7A, 0x76, 0x70, 0x6F, 0x6F, 0x6C, 0x6C, 0x6C, 0x68, 0x6B, 0x6B, +0x68, 0x6D, 0x6B, 0x6B, 0x6F, 0x6E, 0x70, 0x77, 0x76, 0x7A, 0x7F, 0xFF, 0xFD, 0xF6, 0xF7, 0xF5, +0xEF, 0xF4, 0xF1, 0xEF, 0xF2, 0xEE, 0xF0, 0xF1, 0xEE, 0xF0, 0xF1, 0xF1, 0xF2, 0xF6, 0xF9, 0xFA, +0x7F, 0x7E, 0x7A, 0x76, 0x7A, 0x73, 0x72, 0x74, 0x6F, 0x73, 0x75, 0x73, 0x75, 0x74, 0x76, 0x73, +0x77, 0x7A, 0x76, 0x7E, 0x78, 0x76, 0x7E, 0x76, 0x7A, 0x79, 0x74, 0x7D, 0x77, 0x77, 0x79, 0x74, +0x76, 0x77, 0x7A, 0x79, 0x7C, 0xFF, 0x79, 0xFC, 0xFA, 0x7E, 0xF4, 0xF9, 0xFC, 0xF6, 0x7E, 0xFF, +0xFF, 0x7B, 0x7C, 0x77, 0x75, 0x76, 0x78, 0x76, 0x74, 0x7B, 0x74, 0x75, 0x7E, 0x74, 0x7B, 0x7C, +0x72, 0x7A, 0x77, 0x74, 0x7A, 0x75, 0x72, 0x73, 0x72, 0x6E, 0x6E, 0x70, 0x6D, 0x70, 0x71, 0x6E, +0x75, 0x73, 0x72, 0x79, 0x78, 0x7B, 0xFF, 0xFF, 0xFD, 0xFA, 0xFC, 0xFB, 0xF7, 0xFD, 0xFE, 0xFA, +0x7D, 0x7D, 0xFE, 0x79, 0x7B, 0x7C, 0x7B, 0x7E, 0x7E, 0xFD, 0xFA, 0xFA, 0xF7, 0xF8, 0xF9, 0xF9, +0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x7D, 0x7B, 0x77, 0x78, 0x74, 0x71, 0x74, 0x6F, 0x6F, 0x71, 0x6D, +0x6F, 0x71, 0x6F, 0x73, 0x74, 0x77, 0x7B, 0x7D, 0x7F, 0xFF, 0xFC, 0xFE, 0xFB, 0xF8, 0xFB, 0xF7, +0xF9, 0xFE, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7E, 0x7B, 0x7B, 0x7E, 0x7C, 0xFF, 0xFE, +0xFE, 0xFB, 0xFE, 0xFF, 0xFD, 0xFE, 0x7E, 0x7F, 0x7A, 0x78, 0x79, 0x75, 0x74, 0x75, 0x73, 0x75, +0x77, 0x77, 0x79, 0x7B, 0x7D, 0xFF, 0xFA, 0xF8, 0xF4, 0xF2, 0xF5, 0xF1, 0xF2, 0xF6, 0xF3, 0xF6, +0xFA, 0xFB, 0xFC, 0x7D, 0x7A, 0x7A, 0x74, 0x77, 0x78, 0x74, 0x7A, 0x77, 0x7A, 0xFF, 0x7F, 0xF9, +0xFB, 0xFB, 0xF9, 0xFF, 0x7F, 0x7C, 0x7A, 0x77, 0x72, 0x73, 0x6E, 0x6E, 0x6E, 0x6D, 0x70, 0x70, +0x75, 0x7D, 0x7B, 0xFE, 0xFD, 0xFF, 0xFC, 0xFF, 0x7E, 0xFF, 0x7E, 0x7A, 0x79, 0x76, 0x6F, 0x72, +0x72, 0x6F, 0x73, 0x6F, 0x6E, 0x74, 0x72, 0x74, 0x7C, 0x7C, 0xFF, 0xF9, 0xFA, 0xF9, 0xF5, 0xF7, +0xF7, 0xF5, 0xFA, 0xFA, 0xF7, 0xFA, 0xF9, 0xF8, 0xFC, 0xF9, 0xF8, 0xFA, 0xF6, 0xF9, 0xFC, 0xFA, +0xFD, 0xFE, 0xFD, 0xFF, 0x7E, 0x7E, 0x7D, 0x7A, 0x7C, 0x7B, 0x79, 0x7C, 0x7B, 0x7B, 0xFF, 0x7E, +0xFF, 0xFC, 0xFE, 0xFE, 0xFB, 0xFD, 0x7C, 0x7F, 0x7F, 0x76, 0x78, 0x78, 0x74, 0x78, 0x78, 0x78, +0x7B, 0x7A, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x78, 0x7A, 0x7B, 0x7A, 0x7C, 0x7F, 0x7D, 0xFF, 0xFC, +0xFD, 0xFA, 0xFB, 0xFD, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x7B, 0x7D, 0x7D, 0x7E, 0x7E, 0x7D, +0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, +0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, 0xFD, 0xFF, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x77, 0x78, +0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFC, 0xFC, 0xFC, +0xFE, 0xFF, 0xFF, 0x7E, 0x7B, 0x78, 0x77, 0x76, 0x74, 0x73, 0x73, 0x71, 0x72, 0x73, 0x73, 0x74, +0x75, 0x76, 0x77, 0x77, 0x78, 0x78, 0x7A, 0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0x7F, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7A, +0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7A, 0x7A, 0x79, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, +0x74, 0x77, 0x79, 0x7A, 0x7D, 0x7F, 0xFE, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFF, +0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4C, 0x49, 0x53, 0x54, 0x4A, 0x00, +0x00, 0x00, 0x49, 0x4E, 0x46, 0x4F, 0x49, 0x53, 0x46, 0x54, 0x3E, 0x00, 0x00, 0x00, 0x46, 0x69, +0x6C, 0x65, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x6F, +0x6C, 0x64, 0x57, 0x61, 0x76, 0x65, 0x2E, 0x20, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x57, 0x61, 0x76, +0x65, 0x20, 0x63, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, +0x43, 0x68, 0x72, 0x69, 0x73, 0x20, 0x43, 0x72, 0x61, 0x69, 0x67, 0x00 + +}; + +static const uint8_t shaun_png[] PROGMEM = { + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x08, 0x06, 0x00, 0x00, 0x00, 0xF2, 0x0C, 0xE0, + 0x57, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4B, 0x47, 0x44, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xA0, + 0xBD, 0xA7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x42, 0x8A, 0x00, + 0x00, 0x42, 0x8A, 0x01, 0x34, 0xA8, 0x6C, 0x25, 0x00, 0x00, 0x00, 0x09, 0x76, 0x70, 0x41, 0x67, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x00, 0x73, 0x4D, 0x3B, 0xD6, 0x00, 0x00, 0x1B, + 0x47, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0xED, 0x9D, 0x79, 0x74, 0x14, 0x55, 0xBE, 0xC7, 0x3F, + 0x55, 0xDD, 0x49, 0x67, 0x5F, 0x3A, 0x7B, 0x42, 0x82, 0x61, 0x49, 0x02, 0x81, 0xB0, 0x29, 0x32, + 0x22, 0x3C, 0x16, 0x41, 0x45, 0x10, 0x15, 0x7D, 0x13, 0x65, 0xD0, 0x81, 0xE3, 0x7B, 0xCC, 0xD3, + 0x51, 0x04, 0xF5, 0xE1, 0xB8, 0xCE, 0xE6, 0x28, 0x22, 0x23, 0x33, 0x2C, 0x2A, 0x22, 0xEE, 0x02, + 0x22, 0x0C, 0x2A, 0x83, 0x28, 0x7B, 0x20, 0xC8, 0x92, 0x10, 0xD9, 0x97, 0x40, 0x08, 0x81, 0x90, + 0x3D, 0x64, 0x21, 0xE9, 0x4E, 0x3A, 0x5D, 0xF7, 0xFD, 0x71, 0xBB, 0x93, 0x0E, 0x10, 0xD2, 0x59, + 0x3A, 0x01, 0xCF, 0xFB, 0x9E, 0xD3, 0xE7, 0xA4, 0x6E, 0xA5, 0x6E, 0xDD, 0xFA, 0xFD, 0xEA, 0xFE, + 0xEE, 0xEF, 0xFE, 0xB6, 0x52, 0xB8, 0xFE, 0xA1, 0x03, 0x7A, 0x01, 0x43, 0x81, 0x9B, 0x80, 0x6A, + 0x60, 0x3F, 0xA0, 0x02, 0x8F, 0x00, 0xB7, 0x03, 0xA1, 0x80, 0x00, 0x72, 0x81, 0xAD, 0xC0, 0xC7, + 0xC0, 0x6E, 0xA0, 0xAE, 0xB3, 0x07, 0xFF, 0x4B, 0x43, 0x30, 0xF0, 0x67, 0x20, 0x1B, 0xB0, 0x20, + 0x89, 0xAE, 0x01, 0x95, 0x40, 0xB9, 0xED, 0xF8, 0x6A, 0xBF, 0x3C, 0xDB, 0x75, 0x81, 0xCD, 0xF4, + 0xAF, 0x03, 0x8C, 0x40, 0x2C, 0xD0, 0x13, 0x88, 0x00, 0x0C, 0x9D, 0xF9, 0xC0, 0x4A, 0x27, 0xDD, + 0xD7, 0x13, 0x88, 0x07, 0xFA, 0x03, 0x51, 0x36, 0x22, 0xE4, 0x03, 0x87, 0x80, 0x83, 0x48, 0x62, + 0x1B, 0x81, 0x85, 0x40, 0x72, 0x2B, 0xC7, 0xA9, 0x01, 0x5F, 0x00, 0x2F, 0x03, 0x35, 0xB6, 0xE3, + 0x0A, 0xDB, 0xDF, 0xDE, 0xC0, 0x48, 0x60, 0x22, 0x30, 0x08, 0xC9, 0x78, 0x3D, 0x92, 0xD1, 0x99, + 0xC0, 0x0F, 0xC0, 0x5A, 0xE0, 0x5C, 0x47, 0x13, 0xA6, 0xA3, 0x19, 0xA2, 0x07, 0x46, 0x00, 0x4F, + 0x22, 0x45, 0x4D, 0xD0, 0x65, 0x63, 0xB8, 0x84, 0x14, 0x47, 0xEF, 0x03, 0x09, 0xC0, 0x4B, 0x48, + 0xD1, 0x44, 0x40, 0x40, 0x00, 0x31, 0x31, 0x31, 0x54, 0x56, 0x56, 0x92, 0x93, 0x93, 0x83, 0xD5, + 0x6A, 0x25, 0x3A, 0x3A, 0x9A, 0x89, 0x13, 0x27, 0x32, 0x60, 0xC0, 0x00, 0xAC, 0x56, 0x2B, 0xBB, + 0x77, 0xEF, 0x66, 0xDD, 0xBA, 0x75, 0x14, 0x16, 0x16, 0xDA, 0xFB, 0xAB, 0x03, 0x4E, 0x23, 0x67, + 0x4D, 0x9D, 0x8D, 0xC0, 0xFB, 0x90, 0x22, 0xF0, 0x1E, 0xC0, 0xAB, 0x89, 0x71, 0x6A, 0xC0, 0x11, + 0xE0, 0x0D, 0xE0, 0x6B, 0xE4, 0xEC, 0xFC, 0xC5, 0xC1, 0x07, 0x78, 0x0D, 0x28, 0xA5, 0x69, 0x51, + 0x63, 0xFF, 0x99, 0x80, 0x2A, 0xFB, 0xF1, 0xC0, 0x81, 0x03, 0xC5, 0xA6, 0x4D, 0x9B, 0x44, 0x49, + 0x49, 0x89, 0xC8, 0xCA, 0xCA, 0x12, 0xAF, 0xBF, 0xFE, 0xBA, 0x78, 0xFC, 0xF1, 0xC7, 0x45, 0x5A, + 0x5A, 0x9A, 0xD0, 0x34, 0x4D, 0xD8, 0x51, 0x57, 0x57, 0x27, 0xB6, 0x6E, 0xDD, 0x2A, 0xFA, 0xF7, + 0xEF, 0xDF, 0x5C, 0xFF, 0x8D, 0x7E, 0x8A, 0xA2, 0x08, 0x55, 0x55, 0xAF, 0x76, 0xAE, 0x02, 0x78, + 0x0E, 0xF9, 0x22, 0x75, 0x08, 0x3A, 0x6A, 0x86, 0x78, 0x02, 0x7F, 0x05, 0x9E, 0x02, 0xDC, 0x00, + 0x14, 0x45, 0x21, 0x24, 0x24, 0x84, 0xE8, 0xE8, 0x68, 0xDC, 0xDD, 0xDD, 0xB9, 0x70, 0xE1, 0x02, + 0xB9, 0xB9, 0xB9, 0xD4, 0xD5, 0x35, 0x5E, 0x87, 0xBD, 0xBC, 0xBC, 0x58, 0xB1, 0x62, 0x05, 0x13, + 0x26, 0x4C, 0xA8, 0x6F, 0x13, 0x42, 0x20, 0x84, 0x40, 0x55, 0xD5, 0xAB, 0xDE, 0x6C, 0xD7, 0xAE, + 0x5D, 0x3C, 0xFC, 0xF0, 0xC3, 0xE4, 0xE4, 0xE4, 0x34, 0xFD, 0xE0, 0x8A, 0x42, 0x7C, 0x7C, 0x3C, + 0xF7, 0xDC, 0x73, 0x0F, 0xFD, 0xFA, 0xF5, 0xC3, 0xC3, 0xC3, 0x83, 0xEC, 0xEC, 0x6C, 0x36, 0x6C, + 0xD8, 0x40, 0x6A, 0x6A, 0x2A, 0x35, 0x35, 0x35, 0xF6, 0x7F, 0xAD, 0xB4, 0x8D, 0xFB, 0x73, 0xC0, + 0xDA, 0x41, 0xF4, 0x72, 0x39, 0x7E, 0x8F, 0x7C, 0xEB, 0x05, 0x20, 0xC2, 0xC2, 0xC2, 0xC4, 0x2B, + 0xAF, 0xBC, 0x22, 0x0E, 0x1E, 0x3C, 0x28, 0x2E, 0x5E, 0xBC, 0x28, 0x2A, 0x2A, 0x2A, 0x44, 0x56, + 0x56, 0x96, 0x58, 0xBC, 0x78, 0xB1, 0x48, 0x48, 0x48, 0x68, 0xF4, 0x96, 0xC6, 0xC4, 0xC4, 0x88, + 0x33, 0x67, 0xCE, 0x88, 0x96, 0xE2, 0xE3, 0x8F, 0x3F, 0x16, 0x77, 0xDE, 0x79, 0xA7, 0x78, 0xFE, + 0xF9, 0xE7, 0xC5, 0xBB, 0xEF, 0xBE, 0x2B, 0xDE, 0x7E, 0xFB, 0x6D, 0xF1, 0xE0, 0x83, 0x0F, 0x0A, + 0xA3, 0xD1, 0x28, 0xDC, 0xDC, 0xDC, 0xC4, 0xD4, 0xA9, 0x53, 0xC5, 0xE9, 0xD3, 0xA7, 0xAF, 0xB8, + 0xAE, 0xA2, 0xA2, 0x42, 0x2C, 0x58, 0xB0, 0x40, 0x04, 0x07, 0x07, 0x3B, 0x8E, 0xA3, 0x00, 0x58, + 0x0D, 0xFC, 0x0E, 0x08, 0xEF, 0x6C, 0x62, 0xB6, 0x15, 0x7D, 0x80, 0x33, 0xF6, 0x87, 0x8B, 0x8D, + 0x8D, 0x15, 0xEB, 0xD7, 0xAF, 0x6F, 0x24, 0x6A, 0x1C, 0x91, 0x91, 0x91, 0x21, 0x06, 0x0F, 0x1E, + 0x2C, 0x00, 0x61, 0x30, 0x18, 0xC4, 0xAF, 0x7F, 0xFD, 0x6B, 0x51, 0x51, 0x51, 0xD1, 0x62, 0x86, + 0x58, 0xAD, 0x56, 0x61, 0x36, 0x9B, 0x1B, 0xDD, 0xA7, 0xA6, 0xA6, 0x46, 0xEC, 0xD8, 0xB1, 0x43, + 0xAC, 0x5A, 0xB5, 0x4A, 0x94, 0x97, 0x97, 0x37, 0x79, 0xAD, 0xA6, 0x69, 0x62, 0xF1, 0xE2, 0xC5, + 0xC2, 0xC3, 0xC3, 0xE3, 0x72, 0x11, 0x66, 0x05, 0x76, 0x02, 0x43, 0x3A, 0x9B, 0xA8, 0x6D, 0xC1, + 0xDB, 0xF6, 0x07, 0xF2, 0xF5, 0xF5, 0x15, 0x2B, 0x56, 0xAC, 0x68, 0x96, 0x98, 0xC7, 0x8E, 0x1D, + 0x13, 0xF3, 0xE7, 0xCF, 0x17, 0x1B, 0x36, 0x6C, 0x10, 0xA5, 0xA5, 0xA5, 0x2D, 0x66, 0x46, 0x7B, + 0xA0, 0xB2, 0xB2, 0x52, 0x4C, 0x98, 0x30, 0xA1, 0xA9, 0x75, 0xE7, 0x00, 0x52, 0x31, 0x68, 0x77, + 0xB8, 0x7A, 0x0D, 0x89, 0x02, 0x36, 0xDA, 0x07, 0x3F, 0x79, 0xF2, 0x64, 0x3E, 0xFC, 0xF0, 0x43, + 0x0C, 0x86, 0x4E, 0x55, 0xF5, 0x9D, 0xC6, 0xC1, 0x83, 0x07, 0x59, 0xBB, 0x76, 0x2D, 0x16, 0x8B, + 0x85, 0x94, 0x94, 0x14, 0x52, 0x53, 0x53, 0xB1, 0x5A, 0xEB, 0x97, 0x91, 0xF7, 0x91, 0xDA, 0xE2, + 0x0D, 0xB5, 0xAE, 0x8C, 0x07, 0xCC, 0x80, 0xF0, 0xF4, 0xF4, 0x14, 0xEB, 0xD6, 0xAD, 0xEB, 0x94, + 0xB7, 0xBD, 0x3D, 0x50, 0x54, 0x54, 0x24, 0x92, 0x93, 0x93, 0x1D, 0x67, 0x49, 0x36, 0xD0, 0xBD, + 0xB3, 0x09, 0xDC, 0x12, 0x84, 0x00, 0xAB, 0xEC, 0x0F, 0x10, 0x1F, 0x1F, 0x2F, 0x72, 0x73, 0x73, + 0x3B, 0x9B, 0xAE, 0x6D, 0xC2, 0x96, 0x2D, 0x5B, 0x84, 0x8F, 0x8F, 0x8F, 0xA3, 0x6A, 0x7E, 0x47, + 0x7B, 0x13, 0x4D, 0x6D, 0x7B, 0x17, 0x57, 0x85, 0x37, 0x72, 0x53, 0x35, 0xC9, 0xDE, 0xD0, 0xAD, + 0x5B, 0x37, 0x8C, 0x46, 0xA3, 0x8B, 0x6E, 0xD7, 0x31, 0xF0, 0xF5, 0xF5, 0x45, 0xAF, 0xAF, 0xDF, + 0x92, 0xA8, 0x80, 0x47, 0x7B, 0xDF, 0xC3, 0x55, 0x0C, 0xF9, 0x4F, 0xE0, 0x37, 0xD8, 0xD6, 0xA8, + 0x84, 0x84, 0x04, 0x9E, 0x7E, 0xFA, 0x69, 0x3C, 0x3C, 0xDA, 0x7D, 0xFC, 0x1D, 0x8A, 0x5D, 0xBB, + 0x76, 0x51, 0x56, 0x56, 0x66, 0x3F, 0xAC, 0x42, 0xDA, 0xCC, 0xDA, 0x15, 0xAE, 0xD8, 0x81, 0x1A, + 0x81, 0xC7, 0xB1, 0x19, 0xE9, 0x12, 0x12, 0x12, 0xF8, 0xEC, 0xB3, 0xCF, 0xB8, 0xF9, 0xE6, 0x9B, + 0x5D, 0x44, 0xA6, 0x8E, 0x43, 0x5E, 0x5E, 0x23, 0xFA, 0x0B, 0x5C, 0xF7, 0x42, 0xB7, 0x2B, 0x46, + 0x21, 0x6D, 0x52, 0x42, 0xAF, 0xD7, 0x8B, 0x25, 0x4B, 0x96, 0x74, 0xB6, 0xE8, 0x6F, 0x37, 0xEC, + 0xDD, 0xBB, 0x57, 0x84, 0x86, 0x86, 0x3A, 0x2E, 0xEC, 0xB3, 0xDB, 0x9B, 0x78, 0xAE, 0xE0, 0x70, + 0x12, 0x72, 0x0D, 0xA1, 0x6B, 0xD7, 0xAE, 0x8C, 0x1D, 0x3B, 0xD6, 0x85, 0xBC, 0xEF, 0x58, 0x24, + 0x25, 0x25, 0x31, 0x64, 0x48, 0xA3, 0x3D, 0xE1, 0x2D, 0xB4, 0xB3, 0x94, 0x71, 0x05, 0x43, 0x22, + 0xED, 0x7F, 0x44, 0x47, 0x47, 0x13, 0x12, 0x12, 0xE2, 0x1A, 0xEA, 0x74, 0x02, 0x0C, 0x06, 0x03, + 0x89, 0x89, 0x89, 0x8E, 0x4D, 0x51, 0x48, 0x3B, 0x5D, 0xBB, 0xC1, 0x15, 0x0C, 0xA9, 0xEF, 0x53, + 0xA7, 0xD3, 0x35, 0x69, 0x00, 0xBC, 0x51, 0xE1, 0xEB, 0xEB, 0xEB, 0x78, 0x68, 0xE0, 0x06, 0x98, + 0x21, 0xF5, 0xCE, 0x88, 0xBC, 0xBC, 0x3C, 0x47, 0xAD, 0xE4, 0x17, 0x81, 0xD2, 0xD2, 0x52, 0xC7, + 0xC3, 0x6A, 0xDA, 0xD9, 0x57, 0xE2, 0x0A, 0x86, 0x1C, 0x46, 0xEE, 0xCE, 0xC9, 0xCA, 0xCA, 0x22, + 0x35, 0x35, 0xD5, 0x65, 0xC4, 0xE9, 0x68, 0x54, 0x55, 0x55, 0x91, 0x91, 0x91, 0xE1, 0xD8, 0x94, + 0x8D, 0x64, 0xCA, 0x75, 0x8D, 0x70, 0xE0, 0x67, 0x6C, 0x9A, 0xC8, 0xD0, 0xA1, 0x43, 0x45, 0x76, + 0x76, 0x76, 0x67, 0x2B, 0x48, 0xED, 0x82, 0x1F, 0x7E, 0xF8, 0x41, 0xF8, 0xF9, 0xF9, 0x39, 0x6A, + 0x59, 0x4F, 0x74, 0x36, 0xB1, 0x9D, 0xC5, 0x73, 0x48, 0xA3, 0x9B, 0x00, 0xC4, 0xC8, 0x91, 0x23, + 0xC5, 0x8F, 0x3F, 0xFE, 0x28, 0xCC, 0x66, 0xB3, 0xCB, 0x88, 0x65, 0xB5, 0x5A, 0x5D, 0xCA, 0x8C, + 0xAC, 0xAC, 0x2C, 0x31, 0x6C, 0xD8, 0x30, 0x47, 0x66, 0x64, 0x01, 0x71, 0x9D, 0x4D, 0x68, 0x67, + 0x61, 0x04, 0xD6, 0x39, 0x0C, 0x5E, 0xF8, 0xF8, 0xF8, 0x88, 0x05, 0x0B, 0x16, 0xB8, 0x84, 0x58, + 0x99, 0x99, 0x99, 0x62, 0xFA, 0xF4, 0xE9, 0x62, 0xD9, 0xB2, 0x65, 0xC2, 0x64, 0x32, 0x5D, 0x71, + 0x5E, 0xD3, 0x34, 0x71, 0xEE, 0xDC, 0x39, 0x91, 0x97, 0x97, 0xD7, 0xAA, 0xFE, 0x4F, 0x9E, 0x3C, + 0x29, 0x46, 0x8C, 0x18, 0x71, 0xB9, 0x09, 0xFE, 0xF5, 0xCE, 0x26, 0xB2, 0xB3, 0x08, 0x46, 0x5A, + 0x79, 0x1B, 0x31, 0x04, 0x10, 0x49, 0x49, 0x49, 0x22, 0x27, 0x27, 0xA7, 0x5D, 0x99, 0x61, 0xB5, + 0x5A, 0xC5, 0x8C, 0x19, 0x33, 0x04, 0x20, 0xBC, 0xBC, 0xBC, 0xC4, 0xA3, 0x8F, 0x3E, 0x2A, 0x36, + 0x6F, 0xDE, 0x2C, 0xCE, 0x9F, 0x3F, 0x2F, 0x0A, 0x0B, 0x0B, 0xC5, 0xE1, 0xC3, 0x87, 0xC5, 0xDC, + 0xB9, 0x73, 0x45, 0x42, 0x42, 0x82, 0x18, 0x33, 0x66, 0x8C, 0x28, 0x28, 0x28, 0x68, 0xF1, 0x3D, + 0x96, 0x2E, 0x5D, 0x7A, 0x39, 0x33, 0x34, 0x60, 0x3B, 0xF0, 0xDF, 0x40, 0x37, 0x64, 0x38, 0xD1, + 0x75, 0x87, 0x28, 0xA4, 0xEF, 0x79, 0x2F, 0x36, 0x93, 0x3B, 0x57, 0x09, 0x26, 0x98, 0x35, 0x6B, + 0x56, 0xBB, 0x8A, 0xAE, 0x6D, 0xDB, 0xB6, 0x89, 0xD0, 0xD0, 0x50, 0xE1, 0xED, 0x69, 0x10, 0xE1, + 0xC1, 0x01, 0x02, 0x10, 0x9E, 0x5E, 0x5E, 0xA2, 0x5B, 0xB7, 0xEE, 0xA2, 0x57, 0xAF, 0x5E, 0x22, + 0x38, 0x24, 0x44, 0x28, 0x8A, 0x22, 0x00, 0xE1, 0xE6, 0xE6, 0x26, 0x3E, 0xFA, 0xE8, 0xA3, 0x16, + 0xDF, 0x63, 0xCD, 0x9A, 0x35, 0x42, 0xAF, 0xD7, 0x5F, 0xCD, 0x51, 0x55, 0x87, 0x14, 0x5D, 0x0B, + 0x80, 0x5B, 0x01, 0xF7, 0xB6, 0x12, 0xB1, 0x3D, 0x38, 0x1B, 0x0A, 0x4C, 0x07, 0xE6, 0x21, 0x0D, + 0x8A, 0x5D, 0x70, 0xD0, 0xCD, 0x75, 0x3A, 0x1D, 0xE1, 0xE1, 0xE1, 0x24, 0x25, 0x25, 0x61, 0x36, + 0x9B, 0x49, 0x4D, 0x4D, 0xC5, 0x64, 0x32, 0xD1, 0xB7, 0x6F, 0x5F, 0x7C, 0x7C, 0x7C, 0x00, 0x19, + 0xB4, 0x50, 0x50, 0x50, 0x40, 0x59, 0x59, 0x19, 0xBE, 0xBE, 0xBE, 0x28, 0x8A, 0x73, 0x7E, 0xB3, + 0xEC, 0xEC, 0x6C, 0x9E, 0x7E, 0xFA, 0x69, 0x8E, 0x1D, 0x3B, 0xC6, 0x8C, 0x87, 0xC7, 0x31, 0x77, + 0xC6, 0x14, 0x02, 0xFD, 0x7C, 0xA8, 0xAA, 0x36, 0x51, 0x5A, 0x5A, 0x42, 0x65, 0x45, 0x39, 0x81, + 0x3E, 0x06, 0xEE, 0xFC, 0x55, 0x7F, 0x86, 0x0D, 0x48, 0x20, 0xFD, 0xE8, 0x69, 0xB2, 0xB3, 0xCF, + 0x72, 0xC7, 0x1D, 0x77, 0xB4, 0xC8, 0xF2, 0xBC, 0x7E, 0xFD, 0x7A, 0x36, 0x6C, 0xD8, 0x80, 0x9F, + 0x9F, 0x1F, 0x3A, 0x9D, 0x0E, 0x8B, 0xA5, 0x5E, 0xD3, 0x55, 0x91, 0xC1, 0x78, 0x83, 0x81, 0xFB, + 0x81, 0xDE, 0x40, 0x11, 0xD2, 0xE8, 0xA8, 0xB5, 0x03, 0x6D, 0x5B, 0x04, 0x37, 0xA4, 0x68, 0x4A, + 0x45, 0xBE, 0x29, 0x8D, 0x66, 0x42, 0x97, 0x2E, 0x5D, 0xC4, 0x23, 0x8F, 0x3C, 0x22, 0x3E, 0xF9, + 0xE4, 0x13, 0x71, 0xEC, 0xD8, 0x31, 0x51, 0x55, 0x55, 0x25, 0x5E, 0x7A, 0xE9, 0x25, 0x01, 0x08, + 0x9D, 0x4E, 0x27, 0x06, 0x0E, 0x1A, 0x24, 0x66, 0xCF, 0x9E, 0x2D, 0xE6, 0xCF, 0x9F, 0x2F, 0x66, + 0xCE, 0x9C, 0x29, 0xFA, 0xF4, 0xE9, 0x23, 0x7A, 0xF7, 0xEE, 0x2D, 0xD6, 0xAC, 0x59, 0xE3, 0xD4, + 0x02, 0x9D, 0x99, 0x99, 0x29, 0xC6, 0x8D, 0x1B, 0x27, 0x95, 0x86, 0x9B, 0x13, 0x45, 0xEE, 0x86, + 0x25, 0x42, 0x64, 0xAC, 0x16, 0x5A, 0xFA, 0x2A, 0x51, 0xB6, 0xED, 0x63, 0x71, 0xFA, 0x9B, 0x05, + 0xE2, 0xF8, 0xD7, 0xF3, 0xC5, 0x85, 0x0D, 0xEF, 0x0B, 0xCB, 0xDE, 0x15, 0xA2, 0x74, 0xFB, 0x27, + 0x62, 0xFC, 0xB0, 0x41, 0x02, 0x10, 0x77, 0xDF, 0x7D, 0xB7, 0x38, 0x7A, 0xF4, 0x68, 0xA3, 0xFE, + 0x34, 0x4D, 0x13, 0xFB, 0xF7, 0xEF, 0x17, 0x6F, 0xBD, 0xF5, 0x96, 0xD8, 0xBD, 0x7B, 0xB7, 0xB0, + 0x58, 0x2C, 0xC2, 0x62, 0xB1, 0x88, 0x6D, 0xDB, 0xB6, 0x89, 0xB8, 0xB8, 0x38, 0xE1, 0xEE, 0xEE, + 0x2E, 0xDE, 0x7B, 0xEF, 0x3D, 0xB1, 0x69, 0xD3, 0x26, 0xF1, 0xDC, 0x73, 0xCF, 0x89, 0x7E, 0xFD, + 0xFA, 0x09, 0x77, 0x77, 0xF7, 0xAB, 0xCD, 0x9A, 0x12, 0xE0, 0x03, 0x64, 0x10, 0x60, 0x87, 0xC5, + 0xBD, 0x45, 0x20, 0x67, 0x44, 0x99, 0xE3, 0x60, 0x74, 0x3A, 0x9D, 0x48, 0x4A, 0x4A, 0x12, 0x6F, + 0xBE, 0xF9, 0xA6, 0x38, 0x76, 0xEC, 0x98, 0xB0, 0x58, 0x2C, 0xF5, 0x0F, 0x6C, 0x32, 0x99, 0xC4, + 0xA4, 0x49, 0x93, 0x04, 0x20, 0xBA, 0x84, 0x1A, 0x85, 0xA7, 0xC1, 0xAD, 0xD1, 0x83, 0x78, 0xB8, + 0xBB, 0x09, 0x9D, 0xAA, 0x8A, 0xA0, 0xA0, 0x20, 0xF1, 0xDA, 0x6B, 0xAF, 0x89, 0xB3, 0x67, 0xCF, + 0x5E, 0x35, 0x10, 0xA2, 0xA2, 0xA2, 0x42, 0xAC, 0x5C, 0xB9, 0x52, 0x0C, 0x18, 0x30, 0x40, 0x00, + 0xE2, 0x96, 0xDE, 0xDD, 0xC5, 0xC1, 0x95, 0x6F, 0x0B, 0xB1, 0xFF, 0x6B, 0x21, 0xD2, 0xBE, 0x92, + 0xBF, 0xF4, 0x55, 0x42, 0xEC, 0x5F, 0x25, 0xDB, 0xD2, 0x57, 0xC9, 0xB6, 0xFD, 0x5F, 0x8B, 0xC3, + 0x5F, 0xFD, 0x5D, 0x0C, 0x4E, 0xEC, 0x21, 0x00, 0xD1, 0xA3, 0x47, 0x0F, 0xF1, 0x87, 0x3F, 0xFC, + 0x41, 0xAC, 0x5A, 0xB5, 0x4A, 0xAC, 0x5C, 0xB9, 0x52, 0xCC, 0x9A, 0x35, 0x4B, 0xC4, 0xC4, 0xC4, + 0x08, 0x40, 0x84, 0x87, 0x87, 0x8B, 0xFB, 0xEE, 0xBB, 0x4F, 0x4C, 0x9C, 0x38, 0xB1, 0xDE, 0x98, + 0x38, 0x79, 0xF2, 0xE4, 0xFA, 0x60, 0x0B, 0x4D, 0xD3, 0x44, 0x7E, 0x7E, 0xBE, 0x58, 0xBE, 0x7C, + 0xB9, 0x18, 0x3F, 0x7E, 0xBC, 0xF0, 0xF5, 0xF5, 0xBD, 0x1A, 0x63, 0xCE, 0x21, 0x8D, 0x8F, 0xC1, + 0x2D, 0x21, 0x6C, 0x4B, 0x39, 0xA8, 0x20, 0x83, 0x9E, 0x5F, 0x07, 0x86, 0x39, 0x5E, 0x1F, 0x17, + 0x17, 0xC7, 0xF4, 0xE9, 0xD3, 0x49, 0x4E, 0x4E, 0x26, 0x32, 0x32, 0xF2, 0x8A, 0x0B, 0x77, 0xEC, + 0xD8, 0xC1, 0x84, 0x09, 0x13, 0xF0, 0xD4, 0x2B, 0x2C, 0xFF, 0xDB, 0x33, 0x58, 0xEA, 0xEA, 0x48, + 0x3B, 0x7A, 0x9A, 0xD2, 0x8A, 0x4B, 0x04, 0x07, 0xF8, 0x31, 0xA8, 0x57, 0x37, 0x52, 0x7F, 0x3E, + 0xCE, 0x3F, 0x96, 0xAF, 0xA7, 0xEC, 0x52, 0x35, 0x71, 0xF1, 0xF1, 0xDC, 0x39, 0x76, 0x2C, 0x03, + 0x07, 0x0E, 0x24, 0x28, 0x28, 0x88, 0xAA, 0xAA, 0x2A, 0x4E, 0x9C, 0x38, 0xC1, 0x96, 0x2D, 0x5B, + 0xD8, 0xB3, 0x67, 0x0F, 0x96, 0xDA, 0x5A, 0xEE, 0xBA, 0xAD, 0x3F, 0x73, 0x9F, 0x99, 0x42, 0xAF, + 0x6E, 0xD1, 0xA0, 0x39, 0x21, 0x21, 0x54, 0x95, 0x13, 0x67, 0xCE, 0xF3, 0xA7, 0x25, 0xAB, 0xF8, + 0x76, 0x7B, 0x1A, 0x55, 0xE6, 0x1A, 0xDB, 0x23, 0x08, 0x00, 0x02, 0x7C, 0xBD, 0x49, 0xEA, 0x19, + 0xC3, 0xD1, 0xAC, 0xF3, 0x14, 0x97, 0x55, 0xA2, 0x28, 0x0A, 0xE1, 0xE1, 0xE1, 0x24, 0x27, 0x27, + 0x33, 0x7B, 0xF6, 0x6C, 0xC2, 0xC2, 0xC2, 0xAE, 0xE8, 0xB2, 0xBA, 0xBA, 0x9A, 0xD4, 0xD4, 0x54, + 0x96, 0x2E, 0x5D, 0xCA, 0xF7, 0xDF, 0x7F, 0x4F, 0x65, 0x65, 0xA5, 0xE3, 0x69, 0x2B, 0xB0, 0x03, + 0xF8, 0x13, 0x90, 0x82, 0x13, 0x62, 0xAC, 0x25, 0x0C, 0x71, 0x03, 0x26, 0x03, 0x7F, 0x41, 0xAE, + 0x13, 0x80, 0xB4, 0xED, 0x4C, 0x99, 0x32, 0x85, 0x99, 0x33, 0x67, 0xD2, 0xA3, 0x47, 0x8F, 0xAB, + 0x5E, 0x28, 0x84, 0x60, 0xC6, 0x8C, 0x19, 0x2C, 0x58, 0xB0, 0x80, 0xA9, 0xF7, 0x8E, 0x64, 0xC9, + 0x2B, 0xBF, 0xB3, 0x79, 0xDE, 0x84, 0xA4, 0x85, 0x22, 0x87, 0x52, 0x67, 0xA9, 0x63, 0xEB, 0xDE, + 0x43, 0xFC, 0x73, 0xE5, 0xF7, 0x6C, 0x4F, 0x3F, 0x42, 0x65, 0xB5, 0x59, 0x0E, 0x52, 0x51, 0x11, + 0x42, 0x3E, 0x8B, 0x5E, 0xA7, 0x92, 0xD8, 0x2D, 0x9A, 0x69, 0x13, 0x47, 0x32, 0xE5, 0x9E, 0xFF, + 0x20, 0xD0, 0xDF, 0xD7, 0x39, 0x66, 0x38, 0x30, 0xA5, 0xDA, 0x64, 0x66, 0xD7, 0x81, 0x13, 0x6C, + 0xD9, 0x77, 0x98, 0xAC, 0xDC, 0x02, 0x54, 0x45, 0xA1, 0x67, 0x4C, 0x04, 0x63, 0x6E, 0x4D, 0x62, + 0x50, 0xAF, 0x6E, 0x7C, 0xBA, 0x6E, 0x3B, 0x4F, 0xCE, 0x59, 0x4A, 0x78, 0x44, 0x24, 0x5F, 0x7E, + 0xF9, 0x25, 0x43, 0x87, 0x0E, 0x45, 0xA7, 0xBB, 0xF6, 0x72, 0x6B, 0x36, 0x9B, 0xD9, 0xB6, 0x6D, + 0x1B, 0x0B, 0x17, 0x2E, 0x64, 0xD3, 0xA6, 0x4D, 0x8E, 0x81, 0x76, 0x20, 0xE3, 0xBA, 0xDE, 0x04, + 0x96, 0xD0, 0xCC, 0xCE, 0xDE, 0x59, 0x86, 0xF8, 0x02, 0xFF, 0x0B, 0x3C, 0x83, 0x0C, 0x09, 0x05, + 0x20, 0x31, 0x31, 0x91, 0x3F, 0xFE, 0xF1, 0x8F, 0xDC, 0x7B, 0xEF, 0xBD, 0xB8, 0xBB, 0x37, 0xAD, + 0x60, 0x9C, 0x39, 0x73, 0x86, 0x31, 0x63, 0xC7, 0x92, 0x9B, 0x73, 0x96, 0x7F, 0xCD, 0x7B, 0x9E, + 0xBB, 0x6E, 0x1F, 0x08, 0xD6, 0x26, 0x88, 0xA8, 0x53, 0xA9, 0xAA, 0x32, 0xF1, 0xF3, 0xF1, 0x33, + 0xEC, 0x3C, 0x70, 0x82, 0xE3, 0xD9, 0xB9, 0x54, 0x5C, 0xAA, 0xC6, 0xD3, 0xC3, 0x40, 0x4C, 0x78, + 0x30, 0x83, 0x13, 0xBB, 0x33, 0xA4, 0x6F, 0x1C, 0xE1, 0x21, 0x81, 0x36, 0xE1, 0x20, 0x9C, 0x67, + 0x86, 0xE3, 0x53, 0xAB, 0x2A, 0x08, 0xD0, 0xEA, 0xAC, 0xA0, 0x80, 0xAA, 0xD3, 0xD5, 0x4F, 0x96, + 0xBC, 0xA2, 0x52, 0xEE, 0x7A, 0xF2, 0xAF, 0x1C, 0x3D, 0x9B, 0xC7, 0x8A, 0xE5, 0xCB, 0x99, 0x34, + 0x69, 0x92, 0xD3, 0x5D, 0x57, 0x56, 0x56, 0xB2, 0x62, 0xC5, 0x0A, 0xE6, 0xCD, 0x9B, 0xC7, 0x89, + 0x13, 0x27, 0x1C, 0x4F, 0xD5, 0x00, 0xCB, 0x80, 0x57, 0x81, 0xE2, 0xB6, 0x30, 0x24, 0x10, 0x29, + 0xA2, 0xFE, 0x0B, 0x9B, 0xF6, 0xA4, 0xD7, 0xEB, 0x79, 0xE0, 0x81, 0x07, 0xF8, 0xF3, 0x9F, 0xFF, + 0x4C, 0x7C, 0x7C, 0x7C, 0xB3, 0x1D, 0x2C, 0x59, 0xB2, 0x84, 0xE9, 0xD3, 0xA7, 0x33, 0x6C, 0x40, + 0x02, 0xDF, 0xBE, 0xF3, 0x02, 0x01, 0xBE, 0xDE, 0xD7, 0x26, 0xA4, 0x9D, 0x60, 0x80, 0xB0, 0x6A, + 0x68, 0x9A, 0x86, 0xAA, 0x28, 0x28, 0x3A, 0x1D, 0x28, 0x8A, 0x9C, 0x11, 0xAD, 0x61, 0x84, 0xB3, + 0x50, 0x14, 0x5E, 0x5A, 0xB4, 0x9C, 0xBF, 0x2D, 0x5B, 0x43, 0x72, 0x72, 0x32, 0x9F, 0x7E, 0xFA, + 0x29, 0x6E, 0x6E, 0x6E, 0x2D, 0xEA, 0x22, 0x33, 0x33, 0x93, 0xD7, 0x5F, 0x7F, 0x9D, 0x15, 0x2B, + 0x56, 0x38, 0xCE, 0x16, 0x0D, 0x19, 0x01, 0x39, 0x13, 0x99, 0xCB, 0x72, 0x05, 0x9A, 0x33, 0x2E, + 0x86, 0x00, 0xFF, 0x40, 0xAA, 0xB5, 0x7A, 0x90, 0x22, 0xEA, 0x85, 0x17, 0x5E, 0x60, 0xC9, 0x92, + 0x25, 0x4E, 0x31, 0xC3, 0x6C, 0x36, 0xB3, 0x6E, 0xDD, 0x3A, 0x00, 0x26, 0x0C, 0xBF, 0x99, 0x00, + 0x7F, 0x9F, 0xE6, 0x89, 0x29, 0x90, 0x33, 0xC8, 0xAA, 0xA1, 0x00, 0x3A, 0x55, 0x95, 0xAA, 0xB0, + 0xA6, 0x81, 0xD5, 0xEA, 0x5A, 0x66, 0x00, 0xA8, 0x0A, 0x13, 0x86, 0x0F, 0x22, 0xC0, 0xD7, 0x8B, + 0x94, 0x94, 0x14, 0x32, 0x33, 0x33, 0x5B, 0xDC, 0x45, 0xCF, 0x9E, 0x3D, 0x59, 0xBC, 0x78, 0x31, + 0x73, 0xE6, 0xCC, 0x71, 0xF4, 0x09, 0xA9, 0xC0, 0x43, 0xC8, 0x7D, 0x4B, 0xC4, 0x55, 0x6F, 0x7D, + 0x8D, 0x3E, 0x8D, 0x34, 0xEC, 0x2D, 0x54, 0x80, 0x90, 0x90, 0x10, 0xDE, 0x79, 0xE7, 0x1D, 0x5E, + 0x7D, 0xF5, 0x55, 0xFC, 0xFD, 0xFD, 0x9D, 0x1A, 0xD8, 0xF1, 0xE3, 0xC7, 0xF9, 0x69, 0xF7, 0x6E, + 0x42, 0x02, 0xFD, 0x18, 0x3B, 0xA4, 0x9F, 0x7D, 0xFD, 0xBC, 0xBE, 0xA1, 0x69, 0xF4, 0xED, 0x11, + 0xC3, 0x2D, 0x89, 0x3D, 0xB8, 0x70, 0xE1, 0x02, 0x5B, 0xB7, 0x6E, 0x6D, 0x55, 0x37, 0x5E, 0x5E, + 0x5E, 0x3C, 0xF5, 0xD4, 0x53, 0x7C, 0xF0, 0xC1, 0x07, 0xC4, 0xC6, 0xC6, 0x3A, 0x9E, 0xBA, 0x1F, + 0x98, 0x03, 0x5C, 0x41, 0xC4, 0xA6, 0x18, 0xE2, 0x89, 0x4C, 0x1D, 0x98, 0x8C, 0x4D, 0xAC, 0x45, + 0x45, 0x45, 0xB1, 0x68, 0xD1, 0x22, 0xA6, 0x4D, 0x9B, 0xD6, 0xA2, 0xE9, 0xBB, 0x7D, 0xFB, 0x76, + 0x8A, 0x8B, 0x8A, 0xB8, 0xB5, 0x4F, 0x4F, 0xE2, 0xBB, 0x46, 0xB6, 0x6C, 0x01, 0xEE, 0x2C, 0x08, + 0xF0, 0xF6, 0xF6, 0x64, 0xDC, 0xD0, 0x01, 0x00, 0x6C, 0xD8, 0xB0, 0x01, 0xB3, 0xD9, 0xDC, 0xAA, + 0xAE, 0x54, 0x55, 0x65, 0xE2, 0xC4, 0x89, 0x2C, 0x5D, 0xBA, 0xF4, 0x72, 0xA5, 0xE7, 0x11, 0xE4, + 0xBA, 0xDC, 0xC8, 0xC1, 0x75, 0x35, 0x86, 0x28, 0xC0, 0xFF, 0x20, 0xC5, 0x94, 0x0A, 0x92, 0x19, + 0xEF, 0xBE, 0xFB, 0x2E, 0x0F, 0x3D, 0xF4, 0x90, 0xD3, 0xBB, 0x68, 0x90, 0xE2, 0x6A, 0xD3, 0xA6, + 0x4D, 0x00, 0x8C, 0x19, 0x92, 0x84, 0x87, 0xE7, 0x8D, 0x11, 0x42, 0x0A, 0x80, 0x80, 0x11, 0x83, + 0x12, 0x09, 0xF2, 0xF7, 0x21, 0x2D, 0x2D, 0x9D, 0xAC, 0xAC, 0xAC, 0x36, 0x75, 0x37, 0x6A, 0xD4, + 0x28, 0x16, 0x2D, 0x5A, 0x44, 0x54, 0x54, 0x94, 0xBD, 0x49, 0x87, 0xCC, 0x0A, 0xB8, 0xDF, 0xF1, + 0xFF, 0xAE, 0xC6, 0x90, 0x31, 0xC8, 0x0D, 0x8D, 0x01, 0xC0, 0x68, 0x34, 0x32, 0x6F, 0xDE, 0xBC, + 0x46, 0xF9, 0x19, 0xCE, 0x22, 0x3B, 0x3B, 0x9B, 0xF4, 0xFD, 0xFB, 0x09, 0xF2, 0xF7, 0x61, 0xF8, + 0x80, 0x5E, 0x37, 0x86, 0xB8, 0xB2, 0x43, 0x68, 0xC4, 0xC5, 0x44, 0x30, 0x20, 0x3E, 0x96, 0xFC, + 0xFC, 0x3C, 0x76, 0xED, 0xDA, 0xD5, 0xE6, 0x2E, 0xC7, 0x8E, 0x1D, 0xCB, 0x1B, 0x6F, 0xBC, 0xE1, + 0xE8, 0x06, 0xF6, 0x43, 0x66, 0x89, 0xDD, 0x64, 0x6F, 0xB8, 0x9C, 0x21, 0x91, 0x48, 0x51, 0x15, + 0x0A, 0xD2, 0xA9, 0xFF, 0xF2, 0xCB, 0x2F, 0xF3, 0xD0, 0x43, 0x0F, 0xB5, 0x6A, 0x00, 0xE9, 0xE9, + 0xE9, 0xE4, 0x5D, 0xC8, 0xA3, 0x4F, 0xF7, 0x18, 0x7A, 0x44, 0x87, 0x3B, 0xBF, 0x18, 0xAB, 0x2A, + 0xA8, 0xAA, 0x4C, 0xCC, 0x01, 0xD0, 0xA9, 0x52, 0xBB, 0x6A, 0x2D, 0x54, 0x05, 0x54, 0x15, 0xAB, + 0xA6, 0x61, 0xD5, 0xB4, 0xFA, 0xFE, 0xAF, 0x09, 0x01, 0x5E, 0x5E, 0x9E, 0x0C, 0x1F, 0xD8, 0x1B, + 0x80, 0x9D, 0x3B, 0x77, 0xA2, 0xB5, 0x83, 0xB8, 0x4D, 0x4E, 0x4E, 0x66, 0xFA, 0xF4, 0xE9, 0x8E, + 0x4D, 0xFD, 0x90, 0x41, 0xDB, 0x2A, 0x34, 0x96, 0x5F, 0x0A, 0x32, 0x21, 0xE5, 0x36, 0x7B, 0xC3, + 0x23, 0x8F, 0x3C, 0xC2, 0xF4, 0xE9, 0xD3, 0x5B, 0x1D, 0xA8, 0x20, 0xDD, 0xB7, 0x82, 0xDB, 0xFA, + 0xC5, 0xE3, 0xE3, 0xED, 0x09, 0x5A, 0x33, 0x0C, 0x51, 0x14, 0xAC, 0x9A, 0x46, 0xFA, 0xA1, 0x93, + 0xFC, 0x7B, 0xE7, 0x7E, 0x4E, 0x9D, 0xCB, 0xC7, 0xDB, 0xD3, 0xC0, 0x6D, 0x49, 0xF1, 0x8C, 0xBB, + 0x7D, 0x20, 0xA1, 0x41, 0x01, 0x2D, 0x5F, 0x83, 0x14, 0x85, 0x53, 0x39, 0x79, 0xFC, 0x6B, 0xCB, + 0x5E, 0xD2, 0x8F, 0x67, 0x61, 0xB5, 0x6A, 0x24, 0x76, 0x8F, 0xE6, 0xFE, 0x11, 0xB7, 0xD0, 0x37, + 0xEE, 0xA6, 0x6B, 0xAB, 0x99, 0x8A, 0xC2, 0xAD, 0x7D, 0x7B, 0xE2, 0xAE, 0xD7, 0x91, 0x91, 0x91, + 0x41, 0x49, 0x49, 0x49, 0x9B, 0xA3, 0x68, 0xDC, 0xDC, 0xDC, 0x78, 0xE6, 0x99, 0x67, 0x48, 0x49, + 0x49, 0x61, 0xEF, 0xDE, 0xBD, 0xF6, 0xE6, 0xC9, 0xC0, 0x72, 0x60, 0xBF, 0x23, 0x43, 0xFA, 0x03, + 0x53, 0xED, 0x07, 0x7D, 0xFA, 0xF4, 0xE1, 0xC5, 0x17, 0x5F, 0xC4, 0xCB, 0xCB, 0xCB, 0xE9, 0x9B, + 0x39, 0xA2, 0xAC, 0xAC, 0x8C, 0xFD, 0xFB, 0xF7, 0xA3, 0x53, 0x15, 0x86, 0xF4, 0xED, 0x09, 0x8A, + 0x4A, 0x73, 0x91, 0xFB, 0xB5, 0x96, 0x3A, 0x16, 0xAE, 0xFC, 0x9E, 0x39, 0x1F, 0x7F, 0x43, 0xE1, + 0xC5, 0xF2, 0xFA, 0xF6, 0x65, 0xDF, 0x6C, 0x65, 0xD8, 0x80, 0x04, 0xDE, 0x79, 0x76, 0x2A, 0xFD, + 0x13, 0x62, 0x9D, 0x67, 0x8A, 0xA2, 0xF0, 0x7D, 0xEA, 0x7E, 0x9E, 0x7D, 0xE7, 0x53, 0x8E, 0x9D, + 0x69, 0x50, 0xFB, 0xBF, 0xDE, 0xBC, 0x9B, 0x0F, 0xD7, 0x6E, 0xE6, 0x2F, 0xFF, 0x93, 0xCC, 0xA3, + 0xE3, 0xFF, 0x03, 0xB5, 0xA9, 0xD9, 0xA7, 0x69, 0xF4, 0x8E, 0xED, 0x42, 0xD7, 0x88, 0x10, 0x4E, + 0x67, 0x65, 0x71, 0xF2, 0xE4, 0xC9, 0x76, 0x09, 0x6B, 0x8A, 0x8A, 0x8A, 0x62, 0xE6, 0xCC, 0x99, + 0x4C, 0x9D, 0x3A, 0xD5, 0xAE, 0x2C, 0x44, 0x00, 0x8F, 0x02, 0x19, 0xF6, 0x17, 0x44, 0x05, 0xA6, + 0x61, 0x33, 0x89, 0xB8, 0xBB, 0xBB, 0x33, 0x6B, 0xD6, 0xAC, 0x26, 0x4D, 0x21, 0xCE, 0xE0, 0xEC, + 0xD9, 0xB3, 0x64, 0x9E, 0x3A, 0x45, 0x44, 0x70, 0x20, 0xBD, 0xBB, 0x75, 0x01, 0xD1, 0x0C, 0x11, + 0x55, 0x95, 0x55, 0x9B, 0x7E, 0xE2, 0xD5, 0xF7, 0xBE, 0x6A, 0xC4, 0x0C, 0x2F, 0x2F, 0x2F, 0xFC, + 0xFC, 0xFD, 0xD9, 0x96, 0x7E, 0x94, 0x67, 0xDE, 0xFE, 0x88, 0x82, 0xE2, 0x8B, 0xCE, 0x89, 0x2F, + 0x55, 0xE5, 0xF0, 0xE9, 0x1C, 0x66, 0xBC, 0xFD, 0x71, 0x23, 0x66, 0x18, 0x0C, 0x06, 0xC2, 0xC2, + 0xC2, 0x28, 0x2C, 0xAB, 0xE2, 0xF9, 0x7F, 0x7C, 0xCE, 0x96, 0x7D, 0x87, 0x9B, 0x16, 0x5F, 0x42, + 0x10, 0x1E, 0xE4, 0x4F, 0xBF, 0xB8, 0x9B, 0xA8, 0xBA, 0x74, 0x89, 0xB4, 0xB4, 0xB4, 0x36, 0x33, + 0xC3, 0x8E, 0x71, 0xE3, 0xC6, 0x31, 0x7C, 0xF8, 0x70, 0xC7, 0xA6, 0x7B, 0x80, 0x04, 0xFB, 0x48, + 0x12, 0x80, 0xFB, 0xEC, 0x67, 0x46, 0x8C, 0x18, 0xC1, 0x03, 0x0F, 0x3C, 0xD0, 0xA6, 0x1B, 0x1E, + 0x3D, 0x7A, 0x94, 0xD2, 0x92, 0x12, 0xE2, 0xBB, 0x46, 0x12, 0x19, 0x62, 0xBC, 0xB6, 0xB8, 0x52, + 0x14, 0xCA, 0x2B, 0x2E, 0xF1, 0xFE, 0xEA, 0x8D, 0x54, 0x99, 0x1A, 0xD4, 0xCB, 0xBE, 0x7D, 0xFB, + 0xB2, 0x72, 0xE5, 0x4A, 0x36, 0x6F, 0xDE, 0xCC, 0x13, 0x4F, 0x3C, 0xC1, 0x4F, 0x87, 0x32, 0xF9, + 0x2E, 0x25, 0x4D, 0xAE, 0x09, 0xCD, 0x41, 0x08, 0xBE, 0x58, 0xBF, 0x83, 0xCC, 0x9C, 0x86, 0x78, + 0x5C, 0xA3, 0xD1, 0xC8, 0xFC, 0xF9, 0xF3, 0x49, 0x49, 0x49, 0xE1, 0xBD, 0xF7, 0xDE, 0x45, 0xE8, + 0xDD, 0xF9, 0x60, 0xCD, 0x26, 0x2C, 0xB5, 0x4D, 0x47, 0xF2, 0xE8, 0xDD, 0xDD, 0xE4, 0x0C, 0x07, + 0xF6, 0xEC, 0xD9, 0xE3, 0x98, 0xB0, 0xD3, 0x26, 0xF8, 0xF9, 0xF9, 0x31, 0x79, 0xF2, 0x64, 0xC7, + 0x68, 0xFA, 0x58, 0x60, 0xBC, 0x9D, 0x21, 0xE3, 0xB1, 0xCD, 0x0E, 0x83, 0xC1, 0xC0, 0xB4, 0x69, + 0xD3, 0x9C, 0xDE, 0xF8, 0x35, 0x85, 0x43, 0x87, 0x0E, 0x01, 0x90, 0xD8, 0x3D, 0x06, 0x2F, 0x8F, + 0x66, 0xD4, 0x5D, 0x45, 0xE1, 0x6C, 0x5E, 0x11, 0xC7, 0xCE, 0x9C, 0x6F, 0xD4, 0xFC, 0xE4, 0x93, + 0x4F, 0x32, 0x7E, 0xFC, 0x78, 0x06, 0x0C, 0x18, 0xC0, 0x8B, 0x2F, 0xBE, 0x48, 0x74, 0xD7, 0x9B, + 0x48, 0xFD, 0xF9, 0x78, 0xD3, 0x76, 0x30, 0x07, 0x98, 0xCC, 0x35, 0xEC, 0x3D, 0x72, 0xAA, 0x51, + 0xDB, 0x98, 0x31, 0x63, 0x78, 0xFC, 0xF1, 0xC7, 0x89, 0x8B, 0x8B, 0xE3, 0xB1, 0xC7, 0x1E, 0x63, + 0xC2, 0x84, 0x09, 0xA4, 0x1F, 0x3B, 0x4D, 0x71, 0x59, 0xE5, 0x35, 0x66, 0x9D, 0x42, 0xBF, 0xB8, + 0x9B, 0x70, 0xD7, 0xEB, 0x38, 0x7E, 0xFC, 0x38, 0xE5, 0xE5, 0xE5, 0xCD, 0xDE, 0xDB, 0x59, 0x8C, + 0x1A, 0x35, 0x8A, 0xEE, 0xDD, 0xEB, 0x73, 0x7E, 0x74, 0xC0, 0x44, 0x15, 0xB9, 0x5B, 0xBC, 0xDB, + 0xDE, 0xDA, 0xB7, 0x6F, 0x5F, 0x46, 0x8F, 0x1E, 0xDD, 0xA6, 0x1B, 0x59, 0x2C, 0x16, 0x8E, 0x1E, + 0x3D, 0x2A, 0xFB, 0xEB, 0x11, 0xD3, 0xBC, 0x46, 0xA3, 0x80, 0xB9, 0xD6, 0x42, 0xAD, 0xA5, 0xF1, + 0xDB, 0x27, 0x1C, 0xB4, 0x32, 0x21, 0x04, 0x08, 0x41, 0xB5, 0xB9, 0x06, 0xAD, 0x39, 0x6D, 0x4D, + 0x01, 0xAB, 0x55, 0xC3, 0x5C, 0xD3, 0xF8, 0xCD, 0xB7, 0x58, 0x2C, 0xF5, 0x9A, 0x92, 0xA6, 0x69, + 0xD4, 0xD6, 0xD6, 0x52, 0x6B, 0xA9, 0xA3, 0xCE, 0x6A, 0x6D, 0xDA, 0xAA, 0x27, 0x34, 0x62, 0x23, + 0x43, 0x09, 0x35, 0xFA, 0x93, 0x9D, 0x9D, 0x4D, 0x4A, 0x4A, 0x0A, 0x15, 0x15, 0x15, 0x8D, 0xC6, + 0xD6, 0x52, 0x54, 0x57, 0x57, 0x93, 0x9E, 0x9E, 0xCE, 0xFB, 0xEF, 0xBF, 0x7F, 0x79, 0xE0, 0x5D, + 0x92, 0x1E, 0x48, 0x44, 0x66, 0xCA, 0x02, 0x70, 0xF7, 0xDD, 0x77, 0x13, 0x1C, 0xDC, 0x22, 0x9F, + 0xCA, 0x15, 0xA8, 0xA8, 0xA8, 0xE0, 0xCC, 0x99, 0x33, 0x78, 0xB8, 0xEB, 0xE9, 0x19, 0x13, 0x4E, + 0xB3, 0x1B, 0x10, 0x21, 0x08, 0x0F, 0x0A, 0x20, 0xD4, 0xE8, 0x47, 0x45, 0x55, 0x83, 0x75, 0x7A, + 0xD1, 0xA2, 0x45, 0x44, 0x44, 0x44, 0x10, 0x15, 0x15, 0xC5, 0x87, 0x1F, 0x7E, 0xC8, 0xE9, 0xAC, + 0xD3, 0x3C, 0x3C, 0xA2, 0x9F, 0xB4, 0xCC, 0x5E, 0x6B, 0x61, 0x17, 0xE0, 0xE5, 0x61, 0xA0, 0x47, + 0x74, 0x38, 0xBB, 0x0E, 0x36, 0x58, 0x5C, 0x37, 0x6E, 0xDC, 0xC8, 0xDC, 0xB9, 0x73, 0x19, 0x33, + 0x66, 0x0C, 0x3B, 0x76, 0xEC, 0xE0, 0xBB, 0xEF, 0xD6, 0x31, 0xA0, 0x47, 0x24, 0x81, 0xBE, 0xDE, + 0x4D, 0x0F, 0x51, 0x40, 0xA8, 0xD1, 0x9F, 0xAE, 0x11, 0x21, 0xA4, 0x1E, 0x38, 0xC1, 0x6F, 0x7F, + 0xFB, 0x5B, 0x12, 0x12, 0x12, 0x18, 0x32, 0x64, 0x08, 0x83, 0x07, 0x0F, 0xA6, 0x7B, 0xF7, 0xEE, + 0x44, 0x45, 0x45, 0x11, 0x18, 0x18, 0x88, 0xC1, 0x60, 0x40, 0xA7, 0xD3, 0xD5, 0x6F, 0x9E, 0x35, + 0x4D, 0xC3, 0x62, 0xB1, 0x50, 0x5D, 0x5D, 0x4D, 0x71, 0x71, 0x31, 0xA7, 0x4F, 0x9F, 0x26, 0x2D, + 0x2D, 0x8D, 0x94, 0x94, 0x14, 0x32, 0x32, 0x32, 0x28, 0x2E, 0xBE, 0xC2, 0xE8, 0x9B, 0xAB, 0x47, + 0xAA, 0xB9, 0x46, 0x00, 0x6F, 0x6F, 0x6F, 0x46, 0x8C, 0x18, 0xD1, 0x26, 0x66, 0x00, 0x14, 0x14, + 0x14, 0x90, 0x97, 0x9F, 0x4F, 0x90, 0xBF, 0x2F, 0x51, 0xA1, 0xC6, 0xE6, 0x37, 0x84, 0x9A, 0xA0, + 0x4B, 0x58, 0x10, 0xE3, 0x6E, 0x1F, 0xC8, 0x3F, 0x97, 0xAF, 0xAF, 0x6F, 0x3E, 0x7C, 0xF8, 0x30, + 0x0F, 0x3F, 0xFC, 0x30, 0xEE, 0xEE, 0xEE, 0x94, 0x57, 0x54, 0x10, 0x66, 0xF4, 0x63, 0xC2, 0xF0, + 0x41, 0x4E, 0x8D, 0x41, 0x75, 0xD3, 0x31, 0x69, 0xF4, 0xAD, 0xAC, 0xD9, 0xBA, 0x87, 0x4B, 0x36, + 0xBF, 0x4A, 0x65, 0x65, 0x25, 0xAF, 0xBD, 0xF6, 0x1A, 0x73, 0xE6, 0xCC, 0xA1, 0xBA, 0xBA, 0x1A, + 0x10, 0x3C, 0x74, 0xC7, 0x6D, 0xF8, 0xF8, 0x78, 0x35, 0xCD, 0x60, 0x21, 0xF0, 0xF1, 0xF2, 0x20, + 0xBE, 0x6B, 0x24, 0xA9, 0x07, 0x4E, 0x50, 0x5E, 0x5E, 0xCE, 0x9E, 0x3D, 0x7B, 0xD8, 0xB3, 0x67, + 0x0F, 0x3A, 0x9D, 0x0E, 0x1F, 0x1F, 0x1F, 0x42, 0x42, 0x42, 0x88, 0x88, 0x88, 0x20, 0x28, 0x28, + 0x08, 0x5F, 0x5F, 0x5F, 0x0C, 0x06, 0x03, 0x9A, 0xA6, 0x51, 0x5D, 0x5D, 0x4D, 0x59, 0x59, 0x19, + 0x85, 0x85, 0x85, 0x14, 0x14, 0x14, 0x50, 0x52, 0x52, 0xD2, 0x94, 0x09, 0x46, 0x43, 0x66, 0xF6, + 0xBE, 0xAA, 0x47, 0x3A, 0xE8, 0x55, 0x80, 0x2E, 0x5D, 0xBA, 0x90, 0x90, 0x90, 0xD0, 0x6A, 0x46, + 0x98, 0xCD, 0x66, 0x32, 0x32, 0x32, 0x58, 0xB8, 0x70, 0x21, 0x45, 0x85, 0x45, 0x0C, 0x4C, 0x88, + 0x25, 0xC8, 0xDF, 0xD7, 0xA9, 0x0D, 0xA1, 0xAA, 0x53, 0x99, 0xF9, 0xC8, 0x3D, 0x1C, 0x3C, 0x79, + 0x96, 0x6D, 0xE9, 0x47, 0xEA, 0xDB, 0x4D, 0x26, 0x13, 0x26, 0x93, 0x09, 0x1F, 0x4F, 0x0F, 0x66, + 0x3F, 0x76, 0x1F, 0x37, 0xF7, 0xEE, 0xEE, 0x9C, 0xDA, 0x6B, 0xD5, 0xB8, 0xEB, 0xB6, 0xFE, 0x3C, + 0x9D, 0x7C, 0x37, 0xF3, 0x3E, 0x5F, 0x47, 0x8D, 0x6D, 0xE1, 0xB6, 0x5A, 0xAD, 0x54, 0x56, 0x56, + 0xA2, 0x53, 0x55, 0x7E, 0x33, 0x6E, 0x38, 0x53, 0xC6, 0x0D, 0x6B, 0x76, 0x7C, 0x8A, 0x4E, 0x27, + 0x35, 0xC5, 0xCB, 0x6F, 0x61, 0xB5, 0x52, 0x5E, 0x5E, 0x4E, 0x79, 0x79, 0x39, 0xA7, 0x4E, 0x9D, + 0xA2, 0x15, 0xA8, 0x46, 0x46, 0x79, 0xAE, 0x04, 0xD6, 0x00, 0xE7, 0xF5, 0xC8, 0x48, 0x09, 0x40, + 0x9A, 0x8C, 0x5B, 0x2A, 0xAE, 0xEA, 0xEA, 0xEA, 0x38, 0x7F, 0xFE, 0x3C, 0x5B, 0xB7, 0x6E, 0x65, + 0xCD, 0x9A, 0x35, 0xEC, 0xDA, 0xB5, 0xAB, 0x5E, 0x2E, 0x46, 0x04, 0x07, 0xE0, 0xED, 0x61, 0x70, + 0x6E, 0x87, 0xAE, 0x09, 0x6E, 0x8A, 0x0A, 0xE5, 0xE3, 0x3F, 0x3D, 0xC9, 0x3F, 0x97, 0xAF, 0x67, + 0xDD, 0xCE, 0x74, 0x8A, 0x4A, 0x2B, 0x70, 0x73, 0xD3, 0xD3, 0x3B, 0xB6, 0x0B, 0xBF, 0x7B, 0x70, + 0x0C, 0xF7, 0x8F, 0xBA, 0x15, 0x55, 0x55, 0x9C, 0x36, 0xC1, 0xB8, 0xBB, 0xB9, 0xF1, 0xF2, 0xE3, + 0x0F, 0xD2, 0xA3, 0x4B, 0x38, 0x1F, 0x7D, 0xB7, 0x8D, 0x53, 0xE7, 0xF2, 0xD1, 0x34, 0x8D, 0xE8, + 0xB0, 0x20, 0x92, 0xEF, 0x1C, 0xCA, 0xB4, 0x89, 0xA3, 0xF1, 0x6F, 0xCE, 0x37, 0x63, 0x43, 0xD7, + 0x88, 0x10, 0x74, 0x3A, 0x15, 0xAB, 0x54, 0x28, 0x34, 0xA4, 0x93, 0xC9, 0x1B, 0x59, 0xC0, 0xC6, + 0x59, 0x33, 0x42, 0x1D, 0x32, 0x0E, 0xE1, 0x14, 0x32, 0x38, 0xE4, 0x47, 0x64, 0xD8, 0x54, 0x99, + 0xFD, 0x1F, 0xF4, 0x38, 0xD8, 0xE5, 0x2D, 0x16, 0x0B, 0x07, 0x0F, 0x1E, 0x24, 0x2A, 0x2A, 0x0A, + 0x3F, 0x3F, 0x3F, 0x0C, 0x06, 0x03, 0xAA, 0xCD, 0x17, 0xA1, 0x69, 0x1A, 0x75, 0x75, 0x75, 0x98, + 0x4C, 0x26, 0x4A, 0x4B, 0x4B, 0xC9, 0xCE, 0xCE, 0xE6, 0xC0, 0x81, 0x03, 0xEC, 0xDE, 0xBD, 0x9B, + 0x7D, 0xFB, 0xF6, 0x71, 0xEE, 0xDC, 0xB9, 0x2B, 0xEA, 0x94, 0x44, 0x86, 0x04, 0xE2, 0xEE, 0xD6, + 0x82, 0x68, 0x7D, 0x4D, 0xD0, 0x35, 0x32, 0x84, 0xB7, 0x9E, 0x99, 0xC2, 0xAC, 0xC9, 0xE3, 0x29, + 0xBC, 0x58, 0x8E, 0xC1, 0xDD, 0x8D, 0xE8, 0xB0, 0x20, 0x7C, 0x7D, 0xBC, 0x6D, 0x8E, 0x29, 0xE7, + 0xBB, 0x43, 0x08, 0x3C, 0x0D, 0x6E, 0x4C, 0xBD, 0x6F, 0x34, 0x93, 0x46, 0x0F, 0x21, 0xBF, 0xF8, + 0x22, 0x56, 0x4D, 0x10, 0x16, 0xE4, 0x4F, 0xA0, 0xBF, 0xAF, 0xA4, 0xA2, 0x53, 0x8B, 0xB3, 0x5C, + 0xE3, 0x3C, 0xDD, 0xDD, 0xB9, 0x24, 0xD5, 0xF2, 0x3A, 0xE0, 0x0F, 0xC8, 0x52, 0x4E, 0x7D, 0x80, + 0x18, 0x64, 0x5C, 0x5A, 0x28, 0x32, 0x11, 0x54, 0x8F, 0xD4, 0x9A, 0xAA, 0x6D, 0xC4, 0x2E, 0x45, + 0xC6, 0x6F, 0x1D, 0x47, 0x56, 0x27, 0x3A, 0x8B, 0x2C, 0x6C, 0x73, 0xC5, 0xCD, 0xF5, 0x38, 0x64, + 0x92, 0x6E, 0xDC, 0xB8, 0x91, 0x3D, 0x7B, 0xF6, 0x10, 0x1A, 0x1A, 0x4A, 0x68, 0x68, 0x28, 0x46, + 0xA3, 0x11, 0x2F, 0x2F, 0x2F, 0x54, 0x55, 0xA5, 0xB6, 0xB6, 0x96, 0xCA, 0xCA, 0x4A, 0x8A, 0x8B, + 0x8B, 0x29, 0x2C, 0x2C, 0xA4, 0xA4, 0xA4, 0x04, 0x93, 0xC9, 0x74, 0x4D, 0x6D, 0x23, 0x24, 0xD0, + 0x5F, 0x6A, 0x58, 0x2D, 0x31, 0x77, 0x68, 0x02, 0x9D, 0xA2, 0x10, 0x15, 0x16, 0x44, 0x54, 0x78, + 0x70, 0x3D, 0x61, 0x5B, 0x6D, 0xB6, 0x17, 0x80, 0xD0, 0xF0, 0xF3, 0xF1, 0xC2, 0xCF, 0xD7, 0xBB, + 0xA1, 0xBF, 0x96, 0x68, 0x49, 0x02, 0x42, 0x02, 0xFD, 0xF0, 0xF5, 0xF6, 0xB0, 0x33, 0xC4, 0x1D, + 0x39, 0x4B, 0x76, 0xD8, 0x7E, 0x20, 0x67, 0x89, 0x3B, 0x52, 0xFC, 0xEB, 0x6C, 0xC7, 0x16, 0x1B, + 0xF3, 0x9C, 0xAE, 0x6C, 0xA7, 0x07, 0x7E, 0x02, 0x46, 0x83, 0xD4, 0x0A, 0xCA, 0xCA, 0xCA, 0x28, + 0x2B, 0x2B, 0xE3, 0xE4, 0xC9, 0x93, 0x2D, 0x7D, 0xF4, 0x3A, 0xE0, 0x02, 0xD2, 0xCB, 0xE8, 0x09, + 0x10, 0xE4, 0xEF, 0xD3, 0x7A, 0xA3, 0x60, 0x4B, 0x89, 0xE6, 0xCA, 0xFE, 0x84, 0x20, 0xD0, 0xD7, + 0x9B, 0x40, 0x3F, 0x1F, 0xF2, 0x8A, 0xCB, 0xEC, 0xAD, 0x51, 0x97, 0xFF, 0x17, 0xD2, 0x6F, 0xDE, + 0x26, 0xE8, 0x91, 0x36, 0xF9, 0x67, 0x80, 0xE1, 0xC8, 0xCD, 0xA1, 0x0F, 0xCE, 0xC9, 0xC4, 0x3A, + 0xE4, 0xB4, 0xCB, 0x46, 0xCA, 0xC1, 0x6D, 0xC0, 0x79, 0x64, 0x15, 0xB7, 0xAE, 0x00, 0x7E, 0xDE, + 0xED, 0x9A, 0xED, 0xD5, 0x89, 0x10, 0x78, 0x7B, 0x7A, 0x60, 0xF4, 0xF3, 0x71, 0x6C, 0x0C, 0x72, + 0xC5, 0x9D, 0xF4, 0x48, 0xB9, 0xF6, 0x7B, 0x64, 0x40, 0x57, 0x37, 0xE4, 0xBE, 0xA4, 0x2B, 0xD2, + 0x14, 0x1F, 0x8C, 0x9C, 0x86, 0x3A, 0xA4, 0x65, 0xB0, 0x0C, 0x29, 0x0F, 0xCF, 0x03, 0x27, 0x69, + 0x90, 0x87, 0x17, 0x91, 0x6F, 0x48, 0x4F, 0x1C, 0xEA, 0x61, 0x79, 0x7A, 0x18, 0x3A, 0xAF, 0x88, + 0x60, 0x7B, 0x42, 0x80, 0x9B, 0x5E, 0x87, 0xBF, 0x4F, 0x23, 0x43, 0x6B, 0xDB, 0x4C, 0x19, 0x4D, + 0xC0, 0xBE, 0xE2, 0xD6, 0x21, 0x6B, 0x1E, 0xE6, 0x03, 0x76, 0x4F, 0x8C, 0x62, 0x3B, 0xEF, 0xB8, + 0xCD, 0xAE, 0xE3, 0xDA, 0x26, 0x5B, 0x9D, 0xFD, 0xFF, 0x55, 0x45, 0xC1, 0x5D, 0xAF, 0xBB, 0xB1, + 0x9C, 0x52, 0xD7, 0x22, 0x94, 0x5E, 0x87, 0x6F, 0xE3, 0x19, 0xEF, 0x47, 0xC3, 0x8B, 0xDA, 0x7E, + 0xF7, 0xB9, 0xC6, 0x39, 0xC1, 0x2F, 0xB4, 0xD6, 0x60, 0x6B, 0xA0, 0x2A, 0x0A, 0x9E, 0x86, 0x46, + 0xB1, 0x67, 0x9E, 0xB8, 0x80, 0x21, 0xED, 0x9D, 0x63, 0x58, 0x3F, 0x1F, 0x84, 0x10, 0xD2, 0x3B, + 0xF7, 0x4B, 0x10, 0x59, 0x00, 0x8A, 0x82, 0xA1, 0xB1, 0x0A, 0x6F, 0xD7, 0xA4, 0xDA, 0x15, 0xED, + 0xCD, 0x90, 0x1A, 0xA0, 0x16, 0x40, 0x13, 0x82, 0x6A, 0x73, 0xED, 0x2F, 0x46, 0x64, 0x01, 0x97, + 0x07, 0x78, 0xDC, 0x30, 0x0C, 0x31, 0xD9, 0x0F, 0x2A, 0xAA, 0x4C, 0x6D, 0xE8, 0xEA, 0x3A, 0x83, + 0x10, 0xD2, 0x2A, 0xDC, 0x00, 0x0D, 0x17, 0xBC, 0x6E, 0xED, 0xCD, 0x10, 0x13, 0xB2, 0xCE, 0x09, + 0x00, 0x45, 0xA5, 0xE5, 0xAE, 0x8F, 0x32, 0xEC, 0x20, 0x08, 0x21, 0x30, 0x35, 0x36, 0xE7, 0x9B, + 0x70, 0x41, 0x35, 0x39, 0x57, 0x30, 0xA4, 0xBE, 0x70, 0xC0, 0x85, 0xE2, 0x8B, 0x88, 0x1B, 0x21, + 0x30, 0xCE, 0x09, 0x58, 0x35, 0x8D, 0x4B, 0xD5, 0x8D, 0x66, 0xFC, 0x0D, 0xC1, 0x90, 0x1A, 0x1C, + 0x82, 0x88, 0xCF, 0xE6, 0x15, 0x61, 0x32, 0xB7, 0x79, 0xF3, 0xDA, 0xF9, 0x50, 0xA0, 0xA6, 0xB6, + 0x8E, 0x92, 0xF2, 0x4B, 0x8E, 0xAD, 0xC5, 0xDC, 0x00, 0x22, 0x0B, 0xE4, 0x66, 0x11, 0x80, 0x9C, + 0xFC, 0x62, 0xF9, 0x10, 0x6D, 0x89, 0xA9, 0xBA, 0x2E, 0xA0, 0x70, 0xC9, 0x64, 0x96, 0xAE, 0xDE, + 0x06, 0xB4, 0x7B, 0xF1, 0x32, 0x70, 0x5D, 0x69, 0x8D, 0x5A, 0x80, 0xFC, 0x92, 0x32, 0x4E, 0x9D, + 0xCB, 0x77, 0x2E, 0x28, 0xE1, 0x7A, 0x86, 0xA2, 0x50, 0x50, 0x5A, 0x4E, 0x51, 0x43, 0x34, 0x8C, + 0x40, 0x5A, 0x2B, 0xDA, 0x1D, 0xAE, 0x60, 0xC8, 0x49, 0x64, 0x26, 0x2A, 0x55, 0xA6, 0x2B, 0x03, + 0x0D, 0x6E, 0x48, 0x28, 0x0A, 0xA7, 0xCE, 0xE5, 0x53, 0x7E, 0xA9, 0xDE, 0xBD, 0x5C, 0x89, 0xF4, + 0x69, 0xB4, 0x3B, 0x5C, 0xC1, 0x90, 0x73, 0xC8, 0xCF, 0x4E, 0x00, 0xB0, 0x65, 0xDF, 0x61, 0xAA, + 0xAB, 0xCD, 0x9D, 0xBF, 0x41, 0x54, 0x14, 0x19, 0x92, 0xDA, 0x9A, 0x28, 0x4C, 0x21, 0xD8, 0x77, + 0xE4, 0x14, 0x96, 0xBA, 0xFA, 0x35, 0x3C, 0x1F, 0x69, 0xC3, 0x6B, 0x77, 0xB8, 0x82, 0x21, 0x26, + 0xE4, 0x57, 0x6E, 0x00, 0x48, 0x3F, 0x96, 0xC5, 0xE1, 0x53, 0x39, 0xAD, 0x23, 0x84, 0x1D, 0x8A, + 0xD2, 0x40, 0xD0, 0x96, 0xAE, 0x47, 0x0A, 0xA0, 0xD3, 0x51, 0x71, 0xA9, 0x9A, 0x9D, 0xE9, 0x47, + 0x39, 0x9E, 0xD5, 0xC2, 0x4F, 0x82, 0x28, 0x0A, 0xE5, 0x95, 0x97, 0xD8, 0x91, 0x71, 0xDC, 0xB1, + 0xF5, 0x20, 0x36, 0x29, 0xD0, 0xDE, 0x70, 0xD5, 0x67, 0x18, 0x36, 0xDB, 0x06, 0x1C, 0x52, 0x52, + 0x5E, 0xC9, 0xAA, 0x4D, 0xBB, 0x19, 0xDC, 0xA7, 0xF5, 0x51, 0x90, 0xCB, 0x37, 0xEC, 0x64, 0xF7, + 0xA1, 0x4C, 0x46, 0xDF, 0xD2, 0x87, 0x61, 0x03, 0x7B, 0x39, 0x9F, 0xE8, 0xA9, 0x28, 0x54, 0x9B, + 0x6B, 0xF8, 0xF1, 0xA7, 0x03, 0x2C, 0x59, 0xB3, 0x91, 0xED, 0xFB, 0x8F, 0xD2, 0x3B, 0x36, 0x9A, + 0xB5, 0xF3, 0x9E, 0x27, 0x2A, 0x2C, 0xC8, 0xB9, 0x3D, 0x92, 0xAA, 0xB0, 0xF7, 0xC8, 0x69, 0x0E, + 0x64, 0x66, 0xDB, 0x5B, 0x84, 0xED, 0xF9, 0x5C, 0x62, 0xE7, 0x73, 0x55, 0x8D, 0x8E, 0x12, 0x64, + 0xAC, 0x70, 0x1F, 0x80, 0x0B, 0xC5, 0xA5, 0x8C, 0x1D, 0xD2, 0x8F, 0x90, 0xA0, 0x80, 0x96, 0x6D, + 0x14, 0x6D, 0x8B, 0xE9, 0xF4, 0xD7, 0xDF, 0xE7, 0xDB, 0x94, 0x34, 0xD6, 0x6E, 0xDF, 0xC7, 0xB6, + 0xB4, 0x23, 0x18, 0xFD, 0x7C, 0xE8, 0xD9, 0x35, 0xB2, 0xE9, 0x98, 0x5C, 0xDB, 0xB5, 0x85, 0x17, + 0xCB, 0xF9, 0xDF, 0x7F, 0x7C, 0xC6, 0x6B, 0xEF, 0x7F, 0xC5, 0xB1, 0xEC, 0x5C, 0x2C, 0x75, 0x56, + 0xAA, 0xCC, 0x35, 0xDC, 0x3F, 0x62, 0x30, 0x51, 0xE1, 0xCE, 0x31, 0xA4, 0xCE, 0x6A, 0xE5, 0x8D, + 0x65, 0xFF, 0x62, 0xEF, 0xE1, 0xFA, 0x25, 0xE3, 0x3C, 0x32, 0x13, 0xB9, 0xB8, 0xD9, 0x8B, 0x5B, + 0x01, 0x57, 0xD5, 0xDF, 0xAB, 0x45, 0x3A, 0xAA, 0xAA, 0x01, 0xB2, 0x2F, 0x14, 0xB1, 0x74, 0xED, + 0x16, 0xB4, 0x56, 0x84, 0x61, 0x6A, 0x9A, 0x46, 0x8D, 0x45, 0x7A, 0x40, 0xCD, 0x35, 0xB5, 0xA4, + 0x1E, 0x38, 0xC1, 0xB4, 0x3F, 0x2D, 0xE6, 0x93, 0xEF, 0xB6, 0x35, 0xBD, 0x2E, 0xD9, 0x66, 0xC6, + 0x4B, 0x0B, 0x97, 0xB3, 0x74, 0xED, 0x16, 0xCC, 0x0E, 0xA1, 0xA2, 0x31, 0xE1, 0xC1, 0x44, 0x85, + 0x19, 0x9B, 0x8F, 0xC4, 0x07, 0xD0, 0xA9, 0xEC, 0x3B, 0x72, 0x8A, 0x75, 0x3B, 0xD2, 0x1D, 0x5B, + 0xBF, 0x47, 0xFA, 0xD2, 0x5D, 0x02, 0x57, 0x16, 0x44, 0xDC, 0x82, 0x8C, 0xAA, 0x00, 0xE0, 0xCB, + 0xEF, 0x77, 0xB0, 0xEB, 0xE0, 0x49, 0xB9, 0x0E, 0x38, 0x0B, 0x21, 0x08, 0x33, 0x06, 0x70, 0xD7, + 0x6D, 0xFD, 0xEB, 0x9B, 0xBC, 0x3D, 0x0D, 0x18, 0xDC, 0xDD, 0x78, 0xE5, 0xDD, 0x15, 0xEC, 0xFC, + 0xF9, 0xC4, 0xD5, 0xD7, 0x26, 0x45, 0x61, 0xD5, 0xC6, 0x9F, 0xF8, 0xF4, 0xDF, 0xDB, 0x19, 0x79, + 0x73, 0x62, 0xFD, 0xF5, 0xC1, 0x01, 0xBE, 0x3C, 0x3F, 0xE5, 0x5E, 0x19, 0x6B, 0xEC, 0x44, 0xF4, + 0xA3, 0xD9, 0x5C, 0xC3, 0xA2, 0xAF, 0x7E, 0xA0, 0xE8, 0x62, 0x85, 0xBD, 0xB5, 0x14, 0x17, 0x7F, + 0xD8, 0xC5, 0x95, 0x65, 0x85, 0x2C, 0x48, 0xD1, 0x75, 0x2F, 0xE0, 0x51, 0x65, 0xAA, 0xA1, 0xE8, + 0x62, 0x05, 0xF7, 0x0C, 0x1D, 0x88, 0x87, 0xC1, 0xF9, 0xA2, 0x39, 0x8A, 0xAA, 0x92, 0xD4, 0xB3, + 0x2B, 0x25, 0x65, 0x95, 0x14, 0x94, 0x94, 0x73, 0xEF, 0xF0, 0x9B, 0x99, 0xFD, 0xD8, 0x44, 0xBE, + 0x4D, 0x49, 0x27, 0x33, 0x27, 0x8F, 0x7B, 0x87, 0x0D, 0xC2, 0xE0, 0xD8, 0x9F, 0xA2, 0x90, 0x5B, + 0x58, 0xC2, 0xEF, 0xDF, 0x5A, 0x86, 0x5E, 0xA7, 0x63, 0xD9, 0x1F, 0x9F, 0xE0, 0x81, 0x91, 0xB7, + 0x12, 0xDF, 0x35, 0x82, 0x19, 0x0F, 0x8F, 0x63, 0xDC, 0xED, 0x03, 0x9D, 0xDB, 0x16, 0xE9, 0x54, + 0x56, 0x6F, 0xDA, 0xCD, 0x9C, 0x8F, 0xBF, 0x71, 0xD4, 0xAE, 0xBE, 0x44, 0x7E, 0x15, 0xC1, 0x65, + 0xF6, 0x20, 0x57, 0xD7, 0x79, 0x3A, 0x87, 0x0C, 0x33, 0x1A, 0x0C, 0x70, 0xE6, 0x42, 0x21, 0x46, + 0x3F, 0x6F, 0x7E, 0x95, 0x14, 0xD7, 0x22, 0x2D, 0xD8, 0xD7, 0xDB, 0x8B, 0x3B, 0x6F, 0xEB, 0xCF, + 0x83, 0xA3, 0x87, 0x30, 0x69, 0xF4, 0x10, 0x92, 0xE2, 0x63, 0x11, 0x42, 0xE3, 0x93, 0x75, 0xDB, + 0xE9, 0xD3, 0x3D, 0x9A, 0xC4, 0x9E, 0x31, 0x0D, 0x6F, 0xBC, 0x4E, 0xE5, 0x8B, 0x7F, 0xA7, 0xF0, + 0xD9, 0xFA, 0x14, 0x5E, 0xFD, 0xAF, 0x87, 0xB8, 0x7F, 0xD4, 0xAD, 0x04, 0xFA, 0x7B, 0x73, 0x4B, + 0xDF, 0x38, 0x62, 0x22, 0x42, 0x9C, 0x13, 0x09, 0xAA, 0xCA, 0x89, 0xEC, 0x5C, 0x9E, 0x7A, 0x6B, + 0x19, 0xB9, 0x85, 0xF5, 0xB1, 0xB7, 0x39, 0xC0, 0xB3, 0x34, 0x91, 0x5F, 0xDE, 0x5E, 0x70, 0x35, + 0x43, 0x34, 0xE4, 0x46, 0x71, 0x14, 0x10, 0xAA, 0x69, 0x82, 0x03, 0x27, 0xCF, 0xD2, 0x3F, 0x3E, + 0x96, 0xEE, 0x31, 0x11, 0x2D, 0x5A, 0xE0, 0xDD, 0x74, 0x3A, 0x8C, 0x81, 0x7E, 0x78, 0xB8, 0xCB, + 0x0C, 0xE0, 0xB8, 0xAE, 0x91, 0x6C, 0xDE, 0x7B, 0x88, 0xFC, 0x92, 0x8B, 0xDC, 0x3F, 0xE2, 0x96, + 0xFA, 0x05, 0xBE, 0xB6, 0xD6, 0xC2, 0x5F, 0x96, 0x7E, 0x8D, 0x97, 0x87, 0x81, 0x37, 0x9F, 0xFE, + 0x0D, 0x3E, 0x9E, 0x86, 0x86, 0x88, 0x13, 0x67, 0xEE, 0xA7, 0x28, 0x94, 0x55, 0x56, 0xF1, 0xEC, + 0xDF, 0x3F, 0x61, 0x6B, 0x5A, 0x7D, 0x04, 0xA5, 0x15, 0xF9, 0x71, 0x81, 0xD5, 0x2E, 0xA6, 0x57, + 0x87, 0xD4, 0x2E, 0x3F, 0x8D, 0xAC, 0x04, 0x51, 0x09, 0x50, 0x50, 0x2A, 0x35, 0x9F, 0xA3, 0xA7, + 0x72, 0x5A, 0xB6, 0x9E, 0x40, 0x43, 0x05, 0x07, 0x21, 0x08, 0x31, 0xFA, 0xF3, 0xDB, 0x09, 0x23, + 0x38, 0x73, 0xA1, 0x88, 0xCA, 0x2A, 0x53, 0xFD, 0x5E, 0xA5, 0xFC, 0x52, 0x35, 0x39, 0xF9, 0xC5, + 0xFC, 0xE7, 0xD8, 0xDB, 0x08, 0x0B, 0x0E, 0x68, 0xB1, 0x56, 0x67, 0xAE, 0xAD, 0xE5, 0xAF, 0x4B, + 0x57, 0xB3, 0x7A, 0xF3, 0x1E, 0xC7, 0x33, 0xDF, 0x21, 0x4B, 0x2E, 0xB9, 0x1C, 0x1D, 0x55, 0xE5, + 0x78, 0x35, 0xF0, 0x1E, 0x36, 0xEB, 0xE8, 0xCF, 0x27, 0xB2, 0x99, 0x31, 0xF7, 0x23, 0x72, 0x72, + 0x0B, 0x5B, 0xBF, 0x61, 0x14, 0x82, 0x31, 0x43, 0xFA, 0xD1, 0x2D, 0x2A, 0x94, 0x3A, 0x87, 0x7C, + 0x91, 0x3A, 0xAB, 0x95, 0x40, 0x3F, 0x1F, 0xC6, 0xDE, 0x9A, 0xD4, 0x32, 0x5B, 0xAC, 0xA2, 0x60, + 0xAE, 0xB5, 0x30, 0xE7, 0xA3, 0xB5, 0x2C, 0xFC, 0x6A, 0x83, 0x74, 0x3F, 0x4B, 0x1C, 0x01, 0x5E, + 0xC1, 0x21, 0xDC, 0xD3, 0x95, 0xE8, 0xA8, 0x5A, 0x81, 0x1A, 0x90, 0x81, 0x0C, 0x13, 0xEA, 0x05, + 0x90, 0x95, 0x5B, 0xC8, 0xC9, 0xB3, 0x17, 0xB8, 0xBD, 0x7F, 0x82, 0x73, 0xE5, 0x36, 0x2E, 0x87, + 0x00, 0x7F, 0x1F, 0x4F, 0x06, 0x27, 0xF6, 0x20, 0xD4, 0xE8, 0x57, 0x2F, 0xB2, 0xF4, 0x3A, 0x1D, + 0x91, 0x21, 0x46, 0x6E, 0xE9, 0xDD, 0x1D, 0x37, 0x9D, 0x93, 0x8F, 0xA7, 0xAA, 0x54, 0x56, 0x9B, + 0xF9, 0xDB, 0xD2, 0xD5, 0xCC, 0xFD, 0xFC, 0xBB, 0xFA, 0xC0, 0x6C, 0x64, 0xE0, 0xDF, 0x13, 0xC8, + 0x60, 0xC2, 0x0E, 0x41, 0x47, 0x16, 0x6F, 0xAC, 0x46, 0x7E, 0x65, 0x73, 0x10, 0x32, 0x16, 0x96, + 0xCC, 0x73, 0xF9, 0x1C, 0x3A, 0x95, 0xC3, 0xA0, 0x84, 0x6E, 0x84, 0xB6, 0x54, 0xBC, 0x20, 0x23, + 0x41, 0x02, 0xFC, 0x7D, 0x1A, 0x6D, 0x10, 0xDD, 0xF4, 0x3A, 0xE2, 0x6E, 0x8A, 0x72, 0x9E, 0x19, + 0x3A, 0x95, 0xF3, 0xF9, 0xC5, 0xBC, 0xF0, 0xCF, 0xCF, 0x79, 0x77, 0xF5, 0x8F, 0xD4, 0x5A, 0xEA, + 0xA3, 0x3E, 0x8B, 0x90, 0x45, 0x62, 0xBE, 0xE9, 0x40, 0x1A, 0x75, 0x78, 0x35, 0xCD, 0x8B, 0x48, + 0xA6, 0x0C, 0xC4, 0x96, 0x42, 0x77, 0x26, 0xB7, 0x90, 0x9D, 0x3F, 0x1F, 0x27, 0x36, 0x3C, 0x84, + 0xD8, 0xE8, 0xF0, 0x6B, 0xEF, 0xBE, 0xAF, 0x86, 0xAB, 0xF1, 0xD0, 0x49, 0x93, 0x88, 0x26, 0x20, + 0x25, 0xED, 0x08, 0x4F, 0xCE, 0x59, 0xCA, 0xB7, 0xDB, 0xD3, 0xB0, 0x36, 0x6C, 0x16, 0x0B, 0x90, + 0xCC, 0x58, 0xD1, 0xC1, 0xF4, 0xE9, 0x94, 0xF2, 0xA6, 0x85, 0xC8, 0x4F, 0x6B, 0xF7, 0xC5, 0x16, + 0x72, 0x5A, 0x50, 0x5A, 0xCE, 0x86, 0x9F, 0x7E, 0xA6, 0xA6, 0xA6, 0x96, 0x5E, 0x37, 0x45, 0xC9, + 0x04, 0x1A, 0x57, 0xC1, 0x66, 0xA4, 0xCC, 0x2D, 0x28, 0xE1, 0xEF, 0x9F, 0x7F, 0xC7, 0xEC, 0x05, + 0x5F, 0x34, 0xCA, 0xD2, 0x45, 0x2A, 0x21, 0x4F, 0x22, 0xF3, 0x35, 0x3A, 0x3C, 0x20, 0xA0, 0xB3, + 0xEA, 0xCD, 0x16, 0x21, 0x2D, 0xC2, 0x5D, 0x90, 0x5F, 0x8D, 0x56, 0x4D, 0xE6, 0x5A, 0x76, 0x64, + 0x1C, 0x27, 0xF5, 0xE7, 0xE3, 0xF8, 0x79, 0x79, 0x10, 0x13, 0x1E, 0x8C, 0xA1, 0xB9, 0x64, 0xD1, + 0x96, 0x40, 0x95, 0x96, 0xE2, 0xC2, 0xD2, 0x32, 0xBE, 0xF8, 0xF7, 0x0E, 0x9E, 0x7D, 0xE7, 0x13, + 0x56, 0x6D, 0xFC, 0xC9, 0x1E, 0xCD, 0x0E, 0x92, 0xF8, 0xDB, 0x91, 0xC5, 0x13, 0x5A, 0x57, 0xFE, + 0xA7, 0x1D, 0xD0, 0xD9, 0x5E, 0x8A, 0x40, 0xA4, 0x68, 0xF8, 0x3D, 0x0E, 0xDF, 0x3E, 0xF7, 0x34, + 0xB8, 0x33, 0x6C, 0x40, 0x2F, 0xA6, 0x8C, 0x1B, 0xCE, 0xE8, 0xC1, 0x7D, 0x09, 0x0F, 0x09, 0x40, + 0x51, 0x75, 0x36, 0x95, 0xD7, 0xC9, 0x1C, 0x11, 0x45, 0xB1, 0x79, 0x2A, 0x15, 0x6A, 0x6B, 0x6A, + 0x38, 0x95, 0x93, 0xCF, 0xBA, 0x9D, 0xE9, 0x7C, 0xB5, 0xF1, 0x27, 0x0E, 0x9C, 0x3C, 0x7B, 0x79, + 0x48, 0x4F, 0x39, 0xF0, 0x21, 0xF2, 0x23, 0x98, 0x2E, 0x71, 0xCD, 0x3A, 0x8B, 0xCE, 0x66, 0x08, + 0x48, 0x17, 0xC0, 0x9D, 0xC0, 0x8B, 0xC8, 0x62, 0xC4, 0xF5, 0xB3, 0xD6, 0x4D, 0xAF, 0x23, 0xBE, + 0x6B, 0x24, 0x23, 0x6F, 0xEE, 0xC3, 0xA8, 0x5B, 0x12, 0xE9, 0xD3, 0x3D, 0x86, 0x88, 0xE0, 0x40, + 0xBC, 0x3C, 0xDC, 0x1B, 0xAA, 0xCB, 0x35, 0x82, 0x00, 0x4D, 0x50, 0x6B, 0xB1, 0x50, 0x56, 0x51, + 0xC5, 0x99, 0x0B, 0x85, 0xEC, 0x3B, 0x7A, 0x9A, 0x2D, 0xFB, 0x0E, 0xB3, 0xFB, 0x50, 0x26, 0xF9, + 0x25, 0x65, 0x97, 0xE7, 0xB3, 0xD4, 0x21, 0x3F, 0xA5, 0x3A, 0x17, 0xF9, 0x01, 0xCC, 0x4E, 0x0F, + 0x9D, 0xBD, 0x1E, 0x18, 0x62, 0x47, 0x28, 0xB2, 0xB4, 0xC7, 0x34, 0xA4, 0x7A, 0xDC, 0x68, 0x6C, + 0xEE, 0x6E, 0x7A, 0x42, 0x8D, 0xFE, 0x74, 0x8B, 0x0C, 0x25, 0x36, 0x2A, 0x8C, 0x2E, 0xA1, 0x46, + 0x82, 0xFC, 0x7D, 0xF0, 0xF2, 0x34, 0xA0, 0x2A, 0x2A, 0xE6, 0x5A, 0x0B, 0x15, 0x97, 0xAA, 0xB9, + 0x50, 0x7C, 0x91, 0x9C, 0xFC, 0x62, 0xCE, 0xE4, 0x16, 0x72, 0xBE, 0xB0, 0x84, 0x8A, 0xAA, 0xAB, + 0x26, 0x15, 0xD5, 0x21, 0x93, 0x2C, 0x97, 0x02, 0x5F, 0x21, 0x8D, 0x86, 0xFF, 0x8F, 0xAB, 0x40, + 0x41, 0xA6, 0x44, 0xBC, 0x88, 0xDC, 0xB7, 0xD4, 0xD0, 0x82, 0xEF, 0xA2, 0x3B, 0xF1, 0x2B, 0x03, + 0x7E, 0x40, 0x32, 0x3D, 0xB4, 0xB3, 0x1F, 0xB6, 0x29, 0x02, 0x5C, 0xAF, 0x08, 0x45, 0xD6, 0x06, + 0xBE, 0x0B, 0xF8, 0x15, 0x72, 0xEF, 0xE2, 0x6C, 0x32, 0x91, 0x1D, 0x16, 0xA4, 0x23, 0xE9, 0x38, + 0x32, 0xA1, 0x68, 0x13, 0x72, 0x66, 0x54, 0x75, 0xF6, 0xC3, 0x35, 0x85, 0xEB, 0x99, 0x21, 0x76, + 0xE8, 0x90, 0x16, 0xE3, 0x3E, 0x48, 0xAB, 0x71, 0x5F, 0xA0, 0x07, 0x92, 0x61, 0x01, 0x34, 0xE4, + 0xF5, 0xD5, 0x22, 0x09, 0x5D, 0x8C, 0xF4, 0xEA, 0x1D, 0x45, 0xA6, 0x1C, 0x67, 0x20, 0x23, 0x44, + 0x2A, 0x5B, 0x76, 0xDB, 0xCE, 0xC1, 0xFF, 0x01, 0xCE, 0x34, 0xF5, 0xEC, 0x2D, 0xA9, 0x9C, 0xA8, + 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, 0x31, + 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0xED, 0x4F, 0xCC, + 0x0D, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x6D, 0x6F, + 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, + 0x31, 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x9C, 0x12, + 0x74, 0xB1, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, + 0x72, 0x65, 0x00, 0x77, 0x77, 0x77, 0x2E, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2E, + 0x6F, 0x72, 0x67, 0x9B, 0xEE, 0x3C, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, + 0x42, 0x60, 0x82}; \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/Send_RFC822_Attachment.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/Send_RFC822_Attachment.ino new file mode 100644 index 000000000000..49a98ed09bc8 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/Send_RFC822_Attachment.ino @@ -0,0 +1,360 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email message with attachment + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +/* This is for attachment data */ +#include "image.h" + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending Email with rfc822 attachment"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + message.text.content = F("This is simple plain text message with rfc822 attachment"); + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + SMTP_Message rfc822; + rfc822.messageID = F("1234@local.machine.example"); + rfc822.from.name = F("rob"); + rfc822.from.email = F("rob@example.com"); + rfc822.sender.name = F("steve"); + rfc822.sender.email = F("steve@example.com"); + + // This date field will set by default if the device time was already set or set date field manually + rfc822.date = MailClient.Time.getDateTimeString(); + + rfc822.subject = F("Test rfc822 message"); + rfc822.comments = F("This is comment"); + rfc822.addRecipient(F("joe"), F("joe@example.com")); + rfc822.response.reply_to = F("rob@example.com"); + rfc822.text.charSet = F("utf-8"); + rfc822.text.content = F("This is rfc822 text message"); + rfc822.text.transfer_encoding = Content_Transfer_Encoding::enc_qp; + + rfc822.html.charSet = F("utf-8"); + rfc822.html.content = F("This is rfc822 html message"); + rfc822.html.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* The attachment data item */ + SMTP_Attachment att[2]; + int attIndex = 0; + + /** Set the attachment info e.g. + * file name, MIME type, BLOB data, BLOB data size, + * and transfer encoding + */ + att[attIndex].descr.filename = F("firebase_logo.png"); + att[attIndex].descr.mime = F("image/png"); + att[attIndex].blob.data = firebase_png; + att[attIndex].blob.size = sizeof(firebase_png); + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add the attachment to the rfc822 message */ +#if defined(ESP32) || defined(ESP8266) + rfc822.addAttachment(att[attIndex]); // Required more stack and may fail on SAMD +#endif + /* Prepare other attachment data */ + uint8_t *a = new uint8_t[512]; + int j = 0; + + for (int i = 0; i < 512; i++) + { + a[i] = j; + j++; + if (j > 255) + j = 0; + } + + /** Set the attachment info e.g. + * file name, MIME type, BLOB data, BLOB data size. + * The default transfer encoding is base64. + */ + attIndex++; + att[attIndex].descr.filename = F("test.dat"); + att[attIndex].descr.mime = F("application/octet-stream"); + att[attIndex].blob.data = a; + att[attIndex].blob.size = 512; + + /* Add this attachment to the message */ + message.addAttachment(att[attIndex]); + + /* Add rfc822 message in the message */ + message.addMessage(rfc822); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (!smtp.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/lib_mail/examples/Send_Attachment_Blob/image.h b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/image.h similarity index 99% rename from lib/libesp32/lib_mail/examples/Send_Attachment_Blob/image.h rename to lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/image.h index 80ce0a0e7cee..5ddd6829b2d9 100644 --- a/lib/libesp32/lib_mail/examples/Send_Attachment_Blob/image.h +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/image.h @@ -1,1851 +1,1851 @@ -#include - -static const uint8_t firebase_png[] PROGMEM = { - 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x02, 0x58, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9A, 0x76, 0x82, - 0x70, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, - 0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61, 0x05, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01, 0xC7, - 0x6F, 0xA8, 0x64, 0x00, 0x00, 0x55, 0x14, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5E, 0xED, 0xDD, 0x59, - 0x90, 0x1D, 0xF5, 0x81, 0xE7, 0x7B, 0x3F, 0xF4, 0xC3, 0x84, 0x91, 0x40, 0x6E, 0xEF, 0xC6, 0x8B, - 0x30, 0x92, 0x4A, 0x1B, 0x58, 0x98, 0xCD, 0xA0, 0xA5, 0x4A, 0x12, 0x20, 0x6C, 0x9A, 0xB6, 0xBA, - 0x01, 0x63, 0x4F, 0x3F, 0x8C, 0x1E, 0x26, 0xC2, 0xF7, 0xE5, 0xC6, 0x25, 0xE2, 0xDE, 0x97, 0x3B, - 0x7D, 0x67, 0xAC, 0x6E, 0x63, 0x63, 0x83, 0x8D, 0xBC, 0xB1, 0x99, 0xA5, 0x10, 0x08, 0xED, 0x52, - 0x69, 0xAD, 0x92, 0xA0, 0xBB, 0xAB, 0xA7, 0xED, 0x6E, 0x77, 0xB7, 0x81, 0x42, 0x9B, 0x99, 0x89, - 0x89, 0xDB, 0x9A, 0xB9, 0x0E, 0x2F, 0x2C, 0x76, 0x61, 0x16, 0x49, 0x85, 0xA4, 0xFC, 0xDF, 0xFF, - 0x3F, 0x4F, 0xE6, 0xA9, 0x3C, 0x79, 0x7E, 0xE7, 0x9C, 0xCC, 0x3C, 0x99, 0x75, 0xCE, 0xC9, 0xFA, - 0x7E, 0x22, 0x7E, 0xA1, 0x6E, 0x2F, 0x42, 0xC2, 0x94, 0xE2, 0xFF, 0x8D, 0x7F, 0x65, 0x9E, 0xF7, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x28, 0x82, 0x79, 0x6E, 0xCD, 0x80, 0xBF, 0xC3, 0x5F, 0x58, 0x12, 0xFC, - 0x4B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x1F, 0x73, 0x78, 0xCD, 0x3A, 0xEF, 0xB9, 0x35, 0x63, 0xE6, - 0xB9, 0x9B, 0x4D, 0x75, 0xCF, 0xAE, 0xF1, 0xE7, 0x3D, 0x7B, 0xD3, 0xA0, 0x0B, 0x92, 0xE0, 0x3F, - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x98, 0x91, 0x35, 0xB3, 0xEB, 0xC2, 0x23, 0x12, 0x1F, 0xD1, - 0x79, 0x87, 0xD7, 0x6C, 0x08, 0xFE, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x8E, 0xFB, 0x16, 0x2B, - 0xEF, 0xD9, 0x35, 0xE3, 0x95, 0xE0, 0xB8, 0xD1, 0x98, 0x03, 0x57, 0x19, 0xB3, 0x7B, 0xAE, 0x31, - 0x3B, 0x3E, 0x65, 0xCC, 0xB6, 0x8F, 0x1A, 0xB3, 0xF3, 0xD3, 0xC6, 0x0C, 0x2D, 0x34, 0x66, 0x78, - 0xD9, 0x64, 0x84, 0x3C, 0x7B, 0xD3, 0x60, 0xF0, 0x5F, 0x07, 0x00, 0x00, 0x00, 0x80, 0xE4, 0xAA, - 0x37, 0x1F, 0x2E, 0x3C, 0x76, 0x7C, 0xC2, 0x98, 0xED, 0x1F, 0xAB, 0x84, 0x87, 0xDA, 0x2E, 0x1B, - 0x26, 0x87, 0x6F, 0xA8, 0x84, 0xC8, 0xA1, 0x9B, 0xD6, 0x06, 0x3F, 0x05, 0x00, 0x00, 0x00, 0x00, - 0xB4, 0xE6, 0x9E, 0xF9, 0xF0, 0xE3, 0x63, 0xCF, 0xA2, 0x4A, 0x78, 0x34, 0x8B, 0x8F, 0x70, 0xDB, - 0x3F, 0x6E, 0xCC, 0xC8, 0x0A, 0xF7, 0xAD, 0x58, 0xE3, 0x66, 0xB4, 0x7F, 0x56, 0xF0, 0x53, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x73, 0xDE, 0x73, 0x37, 0x9F, 0x34, 0xFB, 0xAF, 0x48, 0x1E, 0x1F, 0xE1, - 0x76, 0x5E, 0x62, 0xCC, 0xE1, 0xD5, 0x76, 0x37, 0xAE, 0x0F, 0x7E, 0x2A, 0x00, 0x00, 0x00, 0x00, - 0x68, 0xCC, 0x3D, 0x78, 0x6E, 0x0E, 0xAF, 0x4A, 0x1F, 0x1F, 0xFE, 0x3E, 0x62, 0xCC, 0xBE, 0xCF, - 0x18, 0xEF, 0xF0, 0x4D, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x68, 0xCD, 0xFF, 0x8C, 0x8F, 0xBD, - 0x97, 0x67, 0x8B, 0x0F, 0xB7, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x20, 0x19, 0x1B, - 0x20, 0xEB, 0xCD, 0xAE, 0x4F, 0xC7, 0xE2, 0xA2, 0xD5, 0x82, 0xF8, 0x08, 0xB7, 0x67, 0xB1, 0x31, - 0xCF, 0xDE, 0x64, 0xDC, 0x6D, 0x4A, 0xF0, 0xD3, 0x02, 0x00, 0x00, 0x00, 0x40, 0x3D, 0xEF, 0xB9, - 0x9B, 0x07, 0x75, 0x64, 0x34, 0x5A, 0x2C, 0x3E, 0xC2, 0x1D, 0x1A, 0xE0, 0xB5, 0xBC, 0x00, 0x00, - 0x00, 0x00, 0x9A, 0xF3, 0x0E, 0x2E, 0x1B, 0xD5, 0xA1, 0xA1, 0x26, 0xC2, 0x23, 0xDC, 0xD0, 0x02, - 0x6E, 0x41, 0x00, 0x00, 0x00, 0x00, 0x34, 0xE7, 0x1D, 0xB8, 0x76, 0x5C, 0xC7, 0x46, 0x7C, 0x22, - 0x3A, 0xE2, 0x1B, 0x59, 0x6E, 0xBC, 0xC3, 0x37, 0x8E, 0x06, 0x3F, 0x35, 0x00, 0x00, 0x00, 0x00, - 0x4C, 0x72, 0x6F, 0xAE, 0x32, 0xFB, 0x96, 0xD8, 0x78, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x0D, 0xB5, - 0x5D, 0x73, 0x2A, 0xB7, 0x20, 0xCF, 0xAD, 0x19, 0x08, 0xFE, 0x12, 0x00, 0x00, 0x00, 0x00, 0x50, - 0xE1, 0xBF, 0x01, 0x6B, 0x77, 0x9F, 0x8D, 0x07, 0x15, 0x1D, 0xE1, 0x44, 0x68, 0x34, 0xDB, 0xF0, - 0xF5, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xE7, 0x7F, 0x02, 0xFA, 0xAE, 0xB9, 0x36, 0x1C, - 0x54, 0x78, 0xB8, 0x89, 0xC0, 0x68, 0xB5, 0x5D, 0x97, 0x1A, 0xF3, 0xEC, 0x8D, 0xC6, 0x3C, 0xB7, - 0x9A, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x93, 0x6C, 0x80, 0xAC, 0xD7, 0xE1, 0xE1, 0x26, 0xE2, - 0xA2, 0xE5, 0x3E, 0x5C, 0xD9, 0x81, 0xAB, 0x8C, 0xF7, 0xEC, 0x0D, 0x27, 0x83, 0xBF, 0x0C, 0x00, - 0x00, 0x00, 0x00, 0xBC, 0xE7, 0x3D, 0xDE, 0xF0, 0x8A, 0x06, 0x6F, 0xC0, 0x52, 0x71, 0xD1, 0x6A, - 0x41, 0x7C, 0xB8, 0xED, 0xF8, 0x44, 0xE5, 0x16, 0xE4, 0xF0, 0x8D, 0xEB, 0x82, 0xBF, 0x14, 0x00, - 0x00, 0x00, 0x80, 0xE9, 0xCE, 0x3B, 0x70, 0xFD, 0xC9, 0xDC, 0xE3, 0x23, 0x1C, 0xB7, 0x20, 0x00, - 0x00, 0x00, 0x00, 0xA2, 0xCC, 0xFE, 0x2B, 0x6D, 0x2C, 0x14, 0x10, 0x1F, 0x6E, 0xEE, 0x16, 0xE4, - 0xF0, 0x2A, 0x77, 0x0B, 0xB2, 0x3E, 0xF8, 0xCB, 0x01, 0x00, 0x00, 0x00, 0x98, 0xAE, 0x6C, 0x18, - 0x2C, 0x31, 0x7B, 0x2E, 0xB3, 0xB1, 0x50, 0x40, 0x7C, 0x84, 0xDB, 0x77, 0xB9, 0x7B, 0x23, 0xD6, - 0xB8, 0x7B, 0xDD, 0x6F, 0xF0, 0x97, 0x05, 0x00, 0x00, 0x00, 0x30, 0x1D, 0x99, 0x43, 0x37, 0xAD, - 0x9D, 0x7C, 0x03, 0x96, 0x8A, 0x8B, 0x56, 0x13, 0xC1, 0x11, 0xDF, 0xF6, 0x8F, 0x71, 0x0B, 0x02, - 0x00, 0x00, 0x00, 0x20, 0x78, 0x03, 0xD6, 0xF6, 0x8F, 0xDB, 0x50, 0x50, 0x71, 0xD1, 0x6A, 0x22, - 0x36, 0x1A, 0x8D, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xB3, 0x37, 0x0D, 0xEA, 0xB8, 0x68, - 0x35, 0x11, 0x19, 0xAD, 0x76, 0xA8, 0xDF, 0x3D, 0x90, 0x3E, 0x18, 0xFC, 0xA5, 0x01, 0x00, 0x00, - 0x00, 0x4C, 0x37, 0xDE, 0x81, 0x6B, 0x46, 0x75, 0x60, 0x34, 0x9B, 0x88, 0x8B, 0x56, 0xDB, 0xFA, - 0x21, 0x63, 0x86, 0xE6, 0x57, 0x5E, 0xCB, 0x3B, 0xB2, 0x66, 0x76, 0xF0, 0x97, 0x07, 0x00, 0x00, - 0x00, 0x30, 0x9D, 0x98, 0x03, 0x57, 0xDB, 0x40, 0x50, 0x91, 0xD1, 0x68, 0x22, 0x2E, 0x5A, 0xCD, - 0xC5, 0x47, 0x38, 0x6E, 0x41, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC9, 0xDD, 0x44, 0x98, 0x7D, 0x9F, - 0xB1, 0x91, 0xA0, 0x42, 0x43, 0x4D, 0xC4, 0x45, 0xAB, 0x45, 0xE3, 0xC3, 0x6D, 0xF7, 0xDC, 0xCA, - 0x2D, 0xC8, 0x73, 0xAB, 0x07, 0x82, 0x5F, 0x06, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC0, 0x3C, 0xB7, - 0x66, 0xC0, 0xEC, 0x9E, 0x67, 0x43, 0x41, 0xC5, 0x46, 0x7C, 0x22, 0x2E, 0x5A, 0x2D, 0x1E, 0x1F, - 0xE1, 0x86, 0xAF, 0x73, 0x0F, 0xA4, 0x8F, 0x06, 0xBF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x81, - 0xF7, 0xEC, 0x4D, 0x77, 0x99, 0x9D, 0x97, 0xD8, 0x58, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x8B, 0x56, - 0x53, 0xE1, 0x11, 0x6E, 0xD7, 0xA7, 0xB9, 0x05, 0x01, 0x00, 0x00, 0x00, 0xA6, 0x1B, 0xEF, 0xF0, - 0x8D, 0x1B, 0x74, 0x70, 0x44, 0x27, 0xE2, 0xA2, 0xD5, 0x54, 0x74, 0xC4, 0xC7, 0x2D, 0x08, 0x00, - 0x00, 0x00, 0x30, 0xBD, 0x78, 0x07, 0xAF, 0x6F, 0xF1, 0x06, 0x2C, 0x11, 0x17, 0xAD, 0xA6, 0x62, - 0x43, 0xCD, 0x7D, 0xF6, 0x88, 0xBB, 0x05, 0x39, 0x7C, 0xE3, 0xBA, 0xE0, 0x97, 0x03, 0x00, 0x00, - 0x00, 0xA0, 0xCC, 0xBC, 0x03, 0xD7, 0x9D, 0xD4, 0xE1, 0xE1, 0x26, 0xE2, 0xA2, 0xD5, 0x54, 0x68, - 0x34, 0xDB, 0xFE, 0x2B, 0xDD, 0x1B, 0xB1, 0x4E, 0x06, 0xBF, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xD6, 0xF8, 0x0D, 0x58, 0x22, 0x2E, 0x5A, 0x4D, 0x05, 0x46, 0xAB, 0xB9, 0x5B, 0x90, 0xC3, 0x37, - 0x70, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x94, 0x9D, 0xFF, 0x06, 0xAC, 0xA1, 0x05, 0x36, 0x1E, 0x3A, - 0x14, 0x1F, 0xFE, 0x3E, 0x68, 0x5C, 0x04, 0x79, 0x87, 0x6E, 0x18, 0x37, 0xA3, 0xFD, 0xB3, 0x82, - 0x5F, 0x1A, 0x00, 0x00, 0x00, 0x80, 0xB2, 0x71, 0xB7, 0x0E, 0x66, 0xD7, 0x1C, 0x1B, 0x10, 0x1D, - 0x8C, 0x0F, 0x37, 0xF7, 0xD7, 0x3D, 0xB4, 0xD2, 0x98, 0xC3, 0xAB, 0xD7, 0x07, 0xBF, 0x34, 0x00, - 0x00, 0x00, 0x00, 0x65, 0x63, 0x03, 0x64, 0xBD, 0xD9, 0x7E, 0x71, 0x25, 0x00, 0x3A, 0x15, 0x1F, - 0xE1, 0xF6, 0x5E, 0xC6, 0x2D, 0x08, 0x00, 0x00, 0x00, 0x50, 0x66, 0xDE, 0xC8, 0xCA, 0xA1, 0xAE, - 0x88, 0x0F, 0xB7, 0xE0, 0x16, 0xC4, 0x3B, 0xBC, 0x7A, 0x43, 0xF0, 0xCB, 0x03, 0x00, 0x00, 0x00, - 0x50, 0x26, 0xDE, 0xC1, 0x6B, 0xC7, 0xBA, 0x22, 0x3E, 0xC2, 0xED, 0xEE, 0xAB, 0x3C, 0x90, 0x3E, - 0xB2, 0x66, 0x76, 0xF0, 0x4B, 0x04, 0x00, 0x00, 0x00, 0x50, 0x16, 0x66, 0xFF, 0x67, 0x75, 0x5C, - 0xB4, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0xD1, 0x11, 0xDF, 0xC8, 0x0A, 0xE3, 0x1D, 0x5A, 0x3D, 0x18, - 0xFC, 0x12, 0x01, 0x00, 0x00, 0x00, 0x94, 0x81, 0xBB, 0x65, 0x30, 0xFB, 0x2E, 0xD7, 0x81, 0xD1, - 0x6C, 0x32, 0x2C, 0x92, 0x4C, 0xC4, 0x86, 0x1A, 0xB7, 0x20, 0x00, 0x00, 0x00, 0x40, 0xF9, 0x98, - 0xE7, 0x56, 0x0F, 0x98, 0x5D, 0x97, 0xEA, 0xC8, 0x68, 0x34, 0x19, 0x16, 0x49, 0x26, 0x42, 0xA3, - 0xD9, 0x0E, 0x7E, 0xCE, 0x78, 0x87, 0x6F, 0x18, 0x0D, 0x7E, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x7A, - 0x9D, 0xFF, 0x06, 0xAC, 0x1D, 0x9F, 0xD0, 0xA1, 0xA1, 0x26, 0xC3, 0x22, 0xC9, 0x44, 0x60, 0xB4, - 0xDA, 0xCE, 0x4B, 0x82, 0x5B, 0x90, 0xD5, 0x03, 0xC1, 0x2F, 0x17, 0x00, 0x00, 0x00, 0x40, 0x2F, - 0xF3, 0x9E, 0xBD, 0x61, 0x50, 0x86, 0x86, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0x71, 0x91, 0x74, 0x07, - 0xAF, 0x35, 0xDE, 0xE1, 0x55, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x65, 0xE0, 0x1D, 0xBC, 0x6E, - 0x54, 0xC6, 0x46, 0x7C, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, 0x6D, 0xF9, 0x80, 0x31, 0x3B, - 0x67, 0xBB, 0x0F, 0x26, 0x34, 0xE6, 0xD0, 0xAA, 0xB5, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, 0x40, - 0xAF, 0xF2, 0x0E, 0x5C, 0x33, 0x2E, 0x83, 0x23, 0x3A, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, - 0x5C, 0x7C, 0x84, 0xDB, 0x77, 0x85, 0xFB, 0x5C, 0x90, 0x93, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, - 0x40, 0x2F, 0x72, 0x9F, 0x36, 0xDE, 0xF2, 0x0D, 0x58, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, - 0x45, 0xE3, 0xC3, 0x6D, 0xDB, 0xC7, 0x2A, 0xB7, 0x20, 0x87, 0x57, 0xAD, 0x0B, 0x7E, 0xE9, 0x00, - 0x00, 0x00, 0x00, 0x7A, 0x8D, 0xFF, 0x06, 0xAC, 0xDD, 0x73, 0xEB, 0xA3, 0x23, 0x9C, 0x0C, 0x8B, - 0x24, 0x13, 0x51, 0x91, 0x74, 0xF1, 0xF8, 0x08, 0xC7, 0x2D, 0x08, 0x00, 0x00, 0x00, 0xD0, 0xDB, - 0xCC, 0xE1, 0x1B, 0xD7, 0x35, 0x7C, 0x05, 0xAF, 0x0C, 0x8B, 0x24, 0x13, 0x51, 0x91, 0x74, 0x2A, - 0x3C, 0xC2, 0x6D, 0xB5, 0xBF, 0xA6, 0x43, 0x03, 0xEE, 0x26, 0x64, 0x7D, 0xF0, 0xCB, 0x07, 0x00, - 0x00, 0x00, 0xD0, 0x4B, 0xFC, 0x57, 0xF0, 0xF6, 0x42, 0x7C, 0x84, 0xDB, 0xB3, 0xD8, 0x7D, 0x3A, - 0xFA, 0xB8, 0xFB, 0xD6, 0xB1, 0xE0, 0xB7, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x57, 0x78, 0xC3, 0xCB, - 0xEB, 0xDF, 0x80, 0x25, 0xC3, 0x22, 0xC9, 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x0D, 0x35, 0x6E, 0x41, - 0x00, 0x00, 0x00, 0x80, 0xDE, 0xE5, 0x1D, 0xBC, 0x76, 0xAC, 0x67, 0xE2, 0x23, 0xDC, 0x9E, 0x45, - 0xC6, 0x3B, 0xB4, 0x6A, 0xDC, 0x8C, 0xF4, 0xCF, 0x0E, 0x7E, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x7A, - 0x81, 0xD9, 0x7F, 0x45, 0x6F, 0xC5, 0x87, 0xBF, 0xF7, 0x1B, 0x33, 0xB2, 0xCC, 0x46, 0xC8, 0xCA, - 0xC1, 0xE0, 0xB7, 0x01, 0x00, 0x00, 0x00, 0xA0, 0xDB, 0x99, 0xC3, 0x37, 0x2E, 0x71, 0xB7, 0x09, - 0x3D, 0x17, 0x1F, 0x6E, 0xEE, 0xCD, 0x5D, 0x87, 0x57, 0xD9, 0x10, 0xE9, 0xCD, 0x5B, 0x10, 0xF7, - 0xEB, 0xB6, 0x1B, 0x08, 0xC6, 0x4D, 0x0E, 0x00, 0x00, 0x00, 0xCA, 0xCF, 0x1C, 0xBA, 0x69, 0xAD, - 0xFF, 0x06, 0x2C, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x5A, 0x10, 0x1F, - 0xE1, 0x7A, 0xEC, 0x16, 0xC4, 0xFF, 0xCC, 0x95, 0x91, 0xFE, 0xF5, 0xDE, 0xA1, 0x81, 0x93, 0xFE, - 0x73, 0x2C, 0x91, 0xF9, 0xFF, 0x9A, 0xFD, 0xF7, 0x78, 0xB8, 0x1E, 0x00, 0x00, 0x00, 0xA5, 0x55, - 0x79, 0x03, 0xD6, 0x47, 0x6D, 0x10, 0xA8, 0xB8, 0x68, 0x35, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, - 0xD5, 0x62, 0xF1, 0xE1, 0xB6, 0xF3, 0x53, 0xC1, 0x2D, 0xC8, 0xEA, 0x81, 0xE0, 0xB7, 0xD4, 0xB5, - 0xCC, 0xA1, 0xFE, 0xB5, 0xDE, 0xC8, 0xC0, 0x78, 0x3C, 0x3C, 0xE2, 0xAB, 0xFC, 0x67, 0xFA, 0xD7, - 0x06, 0xFF, 0x35, 0x00, 0x00, 0x00, 0xA0, 0x3C, 0xBC, 0x67, 0x6F, 0x18, 0xD4, 0x71, 0xD1, 0x6A, - 0x22, 0x2A, 0x92, 0x4E, 0xC6, 0x45, 0xAB, 0x89, 0xF8, 0x08, 0x77, 0xF0, 0x1A, 0xE3, 0x1D, 0x5E, - 0x39, 0x1A, 0xFC, 0x96, 0xBA, 0x92, 0x19, 0xE9, 0x5F, 0x57, 0x8D, 0x8C, 0x91, 0xE5, 0xFE, 0x43, - 0xF4, 0x66, 0xC7, 0xC7, 0x6B, 0xE7, 0xFE, 0x35, 0xF7, 0xEF, 0xF9, 0xFF, 0x99, 0x7E, 0x37, 0x3E, - 0xF1, 0x1D, 0x00, 0x00, 0x00, 0xE5, 0xE2, 0x1D, 0xB8, 0x7A, 0x54, 0x07, 0x46, 0xB3, 0x89, 0xA8, - 0x48, 0x3A, 0x19, 0x17, 0xAD, 0x26, 0xA2, 0x23, 0xBA, 0x2E, 0xBF, 0x05, 0xB1, 0x21, 0x31, 0xBB, - 0x7A, 0xF3, 0x31, 0x34, 0xBF, 0xF2, 0x6B, 0xDE, 0x3C, 0x4B, 0xCF, 0xFD, 0x7B, 0x43, 0x7D, 0x7E, - 0x80, 0x78, 0x23, 0x2B, 0x78, 0xCB, 0x17, 0x00, 0x00, 0x00, 0xCA, 0xC5, 0xEC, 0xBF, 0xD2, 0x86, - 0x81, 0x8A, 0x8C, 0x46, 0x13, 0x51, 0x91, 0x74, 0x32, 0x2E, 0x5A, 0x2D, 0x12, 0x1A, 0xCD, 0xE6, - 0x6E, 0x41, 0x0E, 0xAD, 0x1A, 0x0B, 0x7E, 0x5B, 0x5D, 0xC5, 0xC6, 0xC7, 0x90, 0x1F, 0x1F, 0xBB, - 0x3E, 0xAD, 0xA3, 0xA3, 0x66, 0x17, 0x55, 0xB6, 0xF3, 0x92, 0x4A, 0x84, 0x0C, 0xAF, 0xE8, 0xEA, - 0x9B, 0x1D, 0x00, 0x00, 0x00, 0x20, 0x31, 0xFF, 0x81, 0xE8, 0xBD, 0x97, 0xDB, 0x38, 0x50, 0xA1, - 0xA1, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x9A, 0x08, 0x8D, 0x46, 0x73, 0xCF, 0xB1, 0xB8, - 0x5B, 0x90, 0xC3, 0xAB, 0xBA, 0xEA, 0xDB, 0x96, 0x6C, 0x44, 0x0C, 0xF8, 0xF1, 0xE1, 0xDE, 0xD8, - 0x25, 0x83, 0x23, 0xBA, 0x20, 0x3E, 0x62, 0x11, 0xE2, 0x7E, 0x8E, 0xE0, 0xA7, 0x03, 0x00, 0x00, - 0x00, 0x7A, 0x97, 0x79, 0x6E, 0xF5, 0x80, 0x7F, 0x30, 0x96, 0xB1, 0x11, 0x9F, 0x88, 0x8A, 0xA4, - 0x93, 0x71, 0xD1, 0x6A, 0x22, 0x32, 0x5A, 0x6D, 0xDF, 0x12, 0xE3, 0x1D, 0x5E, 0x75, 0x32, 0xF8, - 0xED, 0x75, 0x05, 0xEF, 0xD0, 0xC0, 0xA8, 0x39, 0x70, 0x55, 0x10, 0x18, 0xCD, 0x16, 0x8B, 0x8F, - 0x70, 0xFB, 0xAF, 0xE4, 0x16, 0x04, 0x00, 0x00, 0x00, 0xE5, 0xE0, 0x3D, 0x7B, 0xC3, 0x5D, 0x66, - 0xC7, 0xA7, 0x6C, 0x24, 0xA8, 0xE0, 0x88, 0x4E, 0x44, 0x45, 0xD2, 0xC9, 0xB8, 0x68, 0x35, 0x11, - 0x17, 0x49, 0x16, 0xDC, 0x82, 0x78, 0x87, 0x56, 0xDD, 0x15, 0xFC, 0x16, 0x3B, 0xAA, 0x7A, 0xFB, - 0xE1, 0x1E, 0x30, 0x97, 0xD1, 0x11, 0x4E, 0x84, 0x47, 0xB8, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, - 0x00, 0x80, 0x72, 0xF0, 0x0E, 0xDF, 0xB8, 0x41, 0x07, 0x47, 0x74, 0x22, 0x2A, 0x92, 0x4E, 0xC6, - 0x45, 0xAB, 0x89, 0xB0, 0x48, 0xB3, 0x3D, 0x0B, 0x8D, 0x37, 0xB2, 0x72, 0xBC, 0x1B, 0x3E, 0x4B, - 0x23, 0xD9, 0xED, 0x87, 0x88, 0x8E, 0xF8, 0xB8, 0x05, 0x01, 0x00, 0x00, 0x40, 0x19, 0x78, 0x07, - 0xAF, 0x6B, 0xF1, 0x06, 0x2C, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, 0xD5, 0x44, 0x50, 0xA4, 0xDA, - 0x1F, 0x57, 0xFE, 0xDA, 0x23, 0x2B, 0xEC, 0x56, 0xAE, 0x0F, 0x7E, 0x9B, 0x1D, 0xE1, 0x3E, 0xC7, - 0xC3, 0xBF, 0xFD, 0x70, 0x7F, 0x1F, 0x65, 0x78, 0xB8, 0x89, 0xD8, 0x50, 0xF3, 0x7F, 0x4F, 0xFD, - 0xC6, 0x1C, 0xE4, 0xB3, 0x41, 0x00, 0x00, 0x00, 0xD0, 0xC3, 0xBC, 0x03, 0x9F, 0x3B, 0x59, 0x1F, - 0x1D, 0xE1, 0x22, 0x31, 0x91, 0x76, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xD9, 0xF8, 0x08, - 0xD7, 0x05, 0xB7, 0x20, 0xFE, 0xA7, 0x9A, 0xBB, 0x07, 0xFC, 0x65, 0x78, 0xB8, 0x89, 0xD0, 0x68, - 0xB6, 0xBD, 0x97, 0xB9, 0x5B, 0x90, 0xAE, 0x7A, 0xBE, 0x05, 0x00, 0x00, 0x00, 0x48, 0xA5, 0xF1, - 0x1B, 0xB0, 0x44, 0x54, 0x24, 0x9D, 0x8C, 0x8B, 0x56, 0x53, 0x41, 0x91, 0x66, 0x91, 0xF8, 0x70, - 0x73, 0xBF, 0x8E, 0xE1, 0xA5, 0xEE, 0x13, 0xC5, 0x37, 0x04, 0xBF, 0xD5, 0x29, 0x65, 0xC2, 0x0F, - 0x1D, 0x74, 0x7F, 0x2F, 0xF3, 0x88, 0x0F, 0x37, 0xF7, 0x7B, 0xF2, 0x9F, 0x05, 0x59, 0xCE, 0x87, - 0x13, 0x02, 0x00, 0x00, 0xA0, 0xF7, 0xF8, 0x6F, 0xC0, 0x72, 0x1F, 0x8A, 0x57, 0xB6, 0xF8, 0x08, - 0xB7, 0x6B, 0x8E, 0x31, 0x87, 0x56, 0xBA, 0x43, 0xFB, 0x94, 0x7F, 0x90, 0x5F, 0xF3, 0xDB, 0x0F, - 0x11, 0x17, 0x49, 0xB7, 0x67, 0xB1, 0xF1, 0x86, 0x97, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x80, 0xDE, - 0x63, 0x0E, 0xDD, 0xB4, 0xD6, 0xFF, 0x60, 0xBC, 0x32, 0xC6, 0x47, 0x38, 0x77, 0x0B, 0x72, 0x68, - 0xE5, 0x60, 0xF0, 0x5B, 0x9E, 0x12, 0xCD, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0xDD, 0x33, 0x17, 0xDA, - 0xDF, 0x93, 0xFD, 0x7B, 0x66, 0x7F, 0x4F, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0xE7, 0x98, 0xC3, - 0x37, 0xAE, 0xF7, 0x5F, 0x5B, 0x5B, 0xD6, 0xF8, 0x70, 0x0B, 0x6F, 0x41, 0x0E, 0xF7, 0x2F, 0x09, - 0x7E, 0xDB, 0x85, 0x72, 0xCF, 0x9C, 0xF8, 0xB7, 0x1F, 0xEE, 0x66, 0x29, 0xEF, 0xF8, 0x08, 0xB7, - 0x7B, 0x9E, 0xF1, 0x46, 0x96, 0x8F, 0x9B, 0xA1, 0xCE, 0xBF, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, - 0xCC, 0x1B, 0x59, 0x39, 0x54, 0xEA, 0xF8, 0x08, 0x77, 0xE0, 0x6A, 0x77, 0x0B, 0x32, 0x25, 0xAF, - 0xB0, 0x35, 0x23, 0xFD, 0xEB, 0xCD, 0xC8, 0x72, 0xFB, 0xD7, 0xB5, 0xBF, 0xC6, 0x22, 0xE2, 0xC3, - 0x6D, 0xF3, 0xFB, 0xC2, 0x5B, 0x90, 0x8E, 0xBE, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, 0xC5, 0xDB, - 0x7F, 0xED, 0x58, 0xE9, 0xE3, 0xC3, 0x6D, 0xC7, 0x27, 0xC3, 0x67, 0x41, 0x0A, 0xFD, 0x20, 0x3F, - 0xFF, 0xF6, 0x63, 0x64, 0x60, 0xBC, 0xFE, 0xF6, 0x43, 0x44, 0x45, 0xD2, 0xC5, 0xE3, 0x23, 0x1C, - 0xB7, 0x20, 0x00, 0x00, 0x00, 0xE8, 0x35, 0x66, 0xDF, 0x12, 0x1D, 0x15, 0x49, 0x27, 0xE3, 0xA2, - 0xD5, 0x54, 0x50, 0xA4, 0x99, 0x08, 0x8C, 0x56, 0x73, 0x37, 0x06, 0x53, 0x70, 0x0B, 0xA2, 0x6F, - 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8F, 0x70, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0x97, 0x98, - 0x91, 0x35, 0xB3, 0xDD, 0xE7, 0x4A, 0xC8, 0xB0, 0x48, 0x32, 0x19, 0x17, 0xAD, 0x16, 0x8F, 0x89, - 0xB4, 0x13, 0x71, 0xD1, 0x6A, 0xEE, 0xA0, 0xEE, 0xB6, 0xED, 0x63, 0x95, 0x5B, 0x90, 0x43, 0xC5, - 0x7C, 0x90, 0x9F, 0xBE, 0xFD, 0x10, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0xE2, 0xE3, 0x16, 0x04, 0x00, - 0x00, 0x00, 0xBD, 0xC2, 0x8C, 0xAC, 0x1E, 0x30, 0x3B, 0x2F, 0xD1, 0x71, 0xD1, 0x6A, 0x32, 0x2E, - 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0x30, 0x3E, 0xC2, 0xED, 0xFD, 0x8C, 0xBB, - 0x05, 0x29, 0xE4, 0x15, 0xB6, 0xEE, 0xF3, 0x46, 0xCC, 0xF0, 0xF5, 0xF6, 0xAF, 0x33, 0x45, 0xF1, - 0x11, 0xEE, 0xE0, 0xE7, 0x6C, 0x84, 0xAC, 0xE8, 0xC8, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x89, - 0x99, 0xC3, 0xAB, 0xD7, 0x9B, 0xED, 0x17, 0xEB, 0xC0, 0x68, 0x36, 0x19, 0x17, 0xAD, 0xA6, 0x82, - 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x5A, 0x3C, 0x3E, 0xDC, 0xB6, 0x7E, 0x38, 0x7C, 0x16, 0x24, 0xD7, - 0x57, 0xD8, 0xDA, 0x9F, 0x6F, 0xB6, 0xFF, 0xDA, 0x5D, 0xF7, 0x4A, 0xE3, 0xA9, 0x8C, 0x0F, 0xB7, - 0x9D, 0xB3, 0xED, 0xEF, 0x67, 0x85, 0xFB, 0x3D, 0x4D, 0xF9, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, - 0x89, 0x79, 0x87, 0x57, 0x6F, 0x90, 0x81, 0xD1, 0x6C, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, - 0x89, 0xB8, 0x68, 0x35, 0x15, 0x1F, 0xE1, 0x82, 0x5B, 0x10, 0xF7, 0x2D, 0x53, 0xC1, 0xDF, 0x8A, - 0xB6, 0x79, 0x87, 0x06, 0x06, 0x27, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8C, 0x24, 0x73, - 0xB7, 0x20, 0xC3, 0x2B, 0xA6, 0xF4, 0xB3, 0x4E, 0x00, 0x00, 0x00, 0x80, 0x54, 0xBC, 0x83, 0x9F, - 0x1B, 0x95, 0x91, 0xD1, 0x68, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0x35, - 0x15, 0x1D, 0xD1, 0xB9, 0x5F, 0x97, 0x7F, 0x63, 0xB0, 0x32, 0x97, 0x87, 0xB7, 0x6B, 0x6F, 0x3F, - 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8B, 0xA4, 0xE3, 0x16, 0x04, 0x00, 0x00, 0x00, 0xDD, 0xCE, 0xDB, - 0x7F, 0xD5, 0xB8, 0x0C, 0x0D, 0xB5, 0xBA, 0xB0, 0x48, 0x32, 0x15, 0x14, 0x69, 0x26, 0xE2, 0xA2, - 0xD5, 0x54, 0x70, 0xA8, 0x0D, 0x2D, 0x30, 0xDE, 0xC8, 0xCA, 0xF1, 0x3C, 0x6E, 0x41, 0xFC, 0xDB, - 0x8F, 0x03, 0xD7, 0xDA, 0x9F, 0x57, 0x44, 0x45, 0xD2, 0xA9, 0xA8, 0x48, 0x3B, 0xF7, 0x96, 0xAF, - 0xE1, 0x65, 0xDC, 0x82, 0x34, 0x60, 0xC6, 0xFE, 0xC3, 0x2C, 0xF3, 0xF2, 0xBF, 0x5F, 0x67, 0x4E, - 0x7C, 0x65, 0x7D, 0x64, 0x6B, 0xDD, 0xBF, 0x1E, 0xFC, 0x47, 0x00, 0x00, 0x00, 0x50, 0x14, 0x77, - 0xF0, 0x4E, 0xFC, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, - 0x0A, 0x8D, 0x46, 0x73, 0xBF, 0xC6, 0x1C, 0x6E, 0x41, 0xDC, 0xA7, 0xAB, 0xFB, 0xB7, 0x1F, 0xEE, - 0x59, 0x1A, 0x15, 0x16, 0x49, 0xA6, 0x62, 0x22, 0xCB, 0xB6, 0x7F, 0xD4, 0xFE, 0x7E, 0x96, 0xDB, - 0x2D, 0x2D, 0xF4, 0xB3, 0x4E, 0x7A, 0x8D, 0x0B, 0x0C, 0xEF, 0xC4, 0x97, 0x07, 0xCD, 0x2F, 0xBE, - 0x62, 0xE4, 0x4E, 0x7C, 0xC9, 0xF8, 0xFF, 0x3E, 0x21, 0x02, 0x00, 0x00, 0x50, 0x1C, 0xFF, 0x0D, - 0x58, 0xBB, 0xE6, 0xE8, 0xE0, 0x88, 0xAE, 0x2E, 0x2C, 0x92, 0x4C, 0x05, 0x45, 0x9A, 0x89, 0xB8, - 0x68, 0x35, 0x15, 0x19, 0xAD, 0xE6, 0xBF, 0xC2, 0x76, 0xE5, 0x78, 0x3B, 0xDF, 0xB6, 0xE4, 0x1D, - 0x1A, 0x18, 0x35, 0xFB, 0xAF, 0xB4, 0x3F, 0x9F, 0x08, 0x8B, 0x24, 0x53, 0x21, 0x91, 0x69, 0x33, - 0x2B, 0xDB, 0x7F, 0x85, 0xF1, 0x86, 0x97, 0x4F, 0xC9, 0x27, 0xBE, 0xF7, 0x02, 0x73, 0xFC, 0xDF, - 0x2F, 0xF1, 0x7E, 0xF1, 0xE5, 0xF1, 0xDA, 0xE0, 0xB8, 0xDD, 0x98, 0xE3, 0x5F, 0xF4, 0xC3, 0x23, - 0xFA, 0xAF, 0xFB, 0xFF, 0x39, 0xFB, 0x9F, 0x0F, 0xFE, 0xAB, 0x00, 0x00, 0x00, 0xC8, 0x93, 0x39, - 0x7C, 0xE3, 0xBA, 0x96, 0xAF, 0xE0, 0x95, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, - 0xAB, 0xA9, 0xB8, 0x48, 0xBA, 0xE1, 0xEB, 0x8D, 0xFB, 0x16, 0xAA, 0xE0, 0x6F, 0x4B, 0x2A, 0x36, - 0x5C, 0x06, 0xEC, 0xB2, 0xDF, 0x7E, 0xC8, 0x90, 0xC8, 0xB2, 0x20, 0x3E, 0xDC, 0xB8, 0x05, 0xA9, - 0xAA, 0x89, 0x0F, 0x17, 0x1D, 0x2F, 0xD9, 0xFF, 0xAD, 0x5E, 0xB0, 0xB1, 0xF8, 0xFC, 0x92, 0xC9, - 0xBD, 0x70, 0xB5, 0xFD, 0xD7, 0x57, 0x55, 0xFE, 0x7D, 0x22, 0x04, 0x00, 0x00, 0xA0, 0x38, 0xFE, - 0x2B, 0x78, 0x55, 0x74, 0x84, 0x93, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, - 0xA9, 0xA8, 0x48, 0xBC, 0x59, 0x95, 0x07, 0xC7, 0xDD, 0xB7, 0x50, 0x65, 0xB8, 0x05, 0xF1, 0x86, - 0x57, 0x64, 0xBF, 0xFD, 0x90, 0x21, 0x91, 0x65, 0x91, 0xF8, 0x08, 0xC7, 0x2D, 0x48, 0x6D, 0x7C, - 0x1C, 0xB9, 0xB1, 0x36, 0x3A, 0xD4, 0x5C, 0x98, 0x1C, 0xFD, 0x42, 0x25, 0x42, 0x4E, 0x7C, 0x85, - 0x1B, 0x24, 0x00, 0x00, 0x80, 0xBC, 0x79, 0x07, 0x97, 0x35, 0x7E, 0x03, 0x96, 0x8C, 0x8B, 0x56, - 0x53, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0x85, 0x1F, 0x16, 0x68, 0xE7, - 0x6E, 0x41, 0x46, 0x06, 0x86, 0x82, 0xBF, 0x35, 0x89, 0xB4, 0x75, 0xFB, 0x21, 0x43, 0x22, 0xCB, - 0x44, 0x7C, 0xB8, 0x6D, 0xFD, 0xD0, 0xB4, 0xBE, 0x05, 0xA9, 0x89, 0x0F, 0x77, 0xEB, 0xA1, 0x82, - 0xA3, 0xD1, 0x5C, 0xAC, 0xF8, 0x37, 0x26, 0x5F, 0x29, 0xE4, 0xD3, 0xF2, 0x01, 0x00, 0x00, 0xA6, - 0x2D, 0x6F, 0xFF, 0x35, 0x63, 0xC4, 0x47, 0xB0, 0xED, 0x1F, 0xB7, 0x87, 0x75, 0xFF, 0x16, 0x24, - 0xF1, 0x81, 0xDD, 0x1B, 0x59, 0x31, 0xE6, 0x3F, 0xC4, 0xAF, 0x02, 0xA3, 0xD9, 0x64, 0x48, 0x64, - 0x99, 0x08, 0x8F, 0xE8, 0xF6, 0x2C, 0xB2, 0x51, 0xB5, 0x7C, 0x2C, 0xF8, 0xE5, 0x4E, 0x1B, 0x6D, - 0xC5, 0x47, 0xB8, 0x63, 0x7F, 0xE2, 0x3F, 0x94, 0x1E, 0xFC, 0x94, 0x00, 0x00, 0x00, 0xC8, 0x83, - 0xD9, 0xF7, 0x19, 0xE2, 0xC3, 0xED, 0x99, 0x60, 0xFB, 0xAF, 0x32, 0xDE, 0xF0, 0x40, 0xA2, 0x6F, - 0xBD, 0xB1, 0xA1, 0xB2, 0xCE, 0xBF, 0xFD, 0x70, 0x7F, 0xCF, 0x54, 0x64, 0x34, 0x9A, 0x0C, 0x89, - 0x2C, 0x13, 0xC1, 0x11, 0x9F, 0xFB, 0x7B, 0xEB, 0xDF, 0x82, 0x2C, 0xCF, 0xF5, 0x13, 0xDF, 0xBB, - 0x59, 0x2E, 0xF1, 0xE1, 0xF6, 0xC2, 0xD5, 0xEE, 0xDB, 0xB0, 0x4E, 0x06, 0x3F, 0x2D, 0x00, 0x00, - 0x00, 0xDA, 0x65, 0x0E, 0xDF, 0xB8, 0xC4, 0x0C, 0x2D, 0x9C, 0xBE, 0xF1, 0x11, 0x46, 0x47, 0xF0, - 0x7F, 0x7B, 0x6E, 0xDB, 0x3F, 0xEE, 0xBE, 0x0D, 0x2B, 0xD1, 0x2D, 0x88, 0x37, 0xBC, 0xE2, 0x64, - 0xEA, 0xDB, 0x0F, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, 0xD1, 0xDC, 0x2D, 0xC8, 0xF0, 0xB2, 0x69, - 0x71, 0x90, 0xCE, 0x2D, 0x3E, 0xC2, 0x1D, 0xBB, 0xC5, 0x04, 0x3F, 0x35, 0x00, 0x00, 0x00, 0xDA, - 0x65, 0x0E, 0xAD, 0x5A, 0x5B, 0xF3, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, - 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0xAB, 0x8F, 0x0F, 0x3F, 0x3C, 0xC2, 0x6D, 0xB2, 0xDB, 0x7B, - 0x85, 0x39, 0x3F, 0x3C, 0xD0, 0xF4, 0xC0, 0x9E, 0xE9, 0xF6, 0x43, 0x86, 0x44, 0x96, 0x89, 0xC8, - 0x68, 0x36, 0xF7, 0xF7, 0x79, 0x1A, 0xDC, 0x82, 0xE4, 0x1E, 0x1F, 0xCF, 0x7F, 0xC6, 0x98, 0x23, - 0x37, 0x18, 0xF3, 0xF2, 0x9D, 0x7C, 0x9E, 0x0A, 0x00, 0x00, 0x40, 0x1E, 0xFC, 0x37, 0x60, 0x6D, - 0xFB, 0xC8, 0xF4, 0x8D, 0x8F, 0x68, 0x78, 0xB8, 0xB9, 0xF8, 0x70, 0xDB, 0xFC, 0x21, 0xF7, 0x6D, - 0x58, 0xEE, 0x16, 0xA4, 0xE1, 0x81, 0xDD, 0xBF, 0xFD, 0xD8, 0xB3, 0xD0, 0xFE, 0x7C, 0x22, 0x34, - 0xD4, 0x64, 0x48, 0x64, 0x99, 0x08, 0x8C, 0x24, 0x1B, 0x9A, 0x5F, 0xEA, 0x5B, 0x90, 0x42, 0xE2, - 0xC3, 0x6D, 0xEC, 0x3A, 0x17, 0x20, 0xD3, 0xE6, 0xDB, 0xD7, 0x00, 0x00, 0x00, 0x0A, 0xE5, 0x1D, - 0x5A, 0x3D, 0x38, 0xED, 0xE2, 0x23, 0x12, 0x20, 0xD5, 0xE8, 0x88, 0xC4, 0xC7, 0xF9, 0x70, 0x43, - 0x97, 0x9B, 0x73, 0x07, 0xF5, 0x2D, 0xC8, 0xF9, 0x91, 0xFE, 0xF5, 0x66, 0x78, 0x99, 0xFD, 0xB9, - 0xDC, 0xAF, 0x49, 0xC4, 0x46, 0x7C, 0x32, 0x24, 0xB2, 0x4C, 0x84, 0x45, 0xD2, 0xB9, 0xDF, 0xF7, - 0xF0, 0xF5, 0xEE, 0x16, 0xA4, 0xAD, 0x4F, 0x7C, 0xEF, 0x46, 0x85, 0xC5, 0x87, 0xDB, 0x0B, 0x57, - 0x19, 0x73, 0xE2, 0xCE, 0xD2, 0xFD, 0x3D, 0x03, 0x00, 0x00, 0xE8, 0x08, 0x6F, 0xDF, 0x55, 0xA3, - 0x3A, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xC5, 0xC2, 0x22, 0xC9, 0x64, 0x54, 0x24, 0x5D, 0x24, - 0x3E, 0x82, 0xD5, 0xDC, 0x78, 0x84, 0xD1, 0xF1, 0x74, 0x64, 0x9B, 0x3F, 0x64, 0xCE, 0x1F, 0x5C, - 0x6E, 0xCE, 0x0D, 0xF7, 0xDF, 0x15, 0xFC, 0xED, 0xF2, 0x99, 0xA1, 0xFE, 0x59, 0xE7, 0x47, 0x56, - 0x8C, 0x9B, 0xDD, 0x7D, 0xF6, 0x60, 0x2F, 0x62, 0x23, 0x3E, 0x19, 0x12, 0x59, 0x26, 0xA2, 0x22, - 0xED, 0x76, 0xCF, 0x35, 0xDE, 0xC8, 0xB2, 0x71, 0xF7, 0x7B, 0x08, 0x7E, 0x3B, 0x3D, 0xAF, 0xD0, - 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x9F, 0x07, 0x02, 0x00, 0x00, 0x90, 0x07, 0xB3, 0xEF, 0x0A, - 0x7B, 0xB8, 0x57, 0x81, 0xD1, 0x6C, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, 0x48, - 0xBA, 0x48, 0x78, 0x44, 0x6F, 0x3E, 0xE2, 0xB7, 0x1E, 0x7E, 0x78, 0xBC, 0xCF, 0x9C, 0x7B, 0x6A, - 0x72, 0xE7, 0x77, 0xCE, 0x77, 0xB7, 0x20, 0x35, 0x07, 0xF6, 0xF3, 0x07, 0xFB, 0xD7, 0x7B, 0xC3, - 0xCB, 0x8C, 0xE7, 0x6E, 0x3F, 0x5A, 0x05, 0x88, 0x0C, 0x89, 0x2C, 0x13, 0x31, 0x91, 0x76, 0x9B, - 0x66, 0xD8, 0x1F, 0xED, 0xAF, 0xA9, 0x44, 0xB7, 0x20, 0x53, 0x11, 0x1F, 0x6E, 0xDE, 0xD1, 0x5B, - 0xA6, 0xDD, 0x6B, 0x8C, 0x01, 0x00, 0x00, 0x72, 0x67, 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x8B, 0xED, - 0x01, 0x5F, 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x58, 0x24, 0x99, 0x8C, 0x8A, 0xA4, - 0x8B, 0xC4, 0x47, 0x83, 0x00, 0x09, 0xE3, 0xE3, 0x5C, 0x24, 0x3E, 0xCE, 0x6E, 0x0C, 0xF6, 0xD4, - 0xFB, 0xCD, 0xF9, 0x03, 0xCB, 0x8D, 0x8B, 0x0E, 0xFF, 0xEF, 0x99, 0x0D, 0x91, 0x73, 0xC3, 0x2B, - 0xC6, 0xBD, 0x5D, 0x7D, 0xF6, 0xBF, 0x7F, 0x91, 0x3F, 0xFF, 0x50, 0xAF, 0x42, 0x44, 0x86, 0x44, - 0x96, 0x89, 0x98, 0x48, 0x3B, 0x17, 0x1F, 0xE1, 0x4A, 0x72, 0x0B, 0x32, 0x55, 0xF1, 0xE1, 0xEF, - 0xE8, 0xE7, 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xBB, 0xCC, 0xC8, 0xEA, 0x01, 0xB3, 0xEB, 0x52, - 0x7B, 0xC8, 0x57, 0xA1, 0xA1, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, - 0x4B, 0x1F, 0x1F, 0xD5, 0xF0, 0x78, 0xD2, 0x6D, 0x96, 0xBF, 0x73, 0x3B, 0xE6, 0x9B, 0xB3, 0x07, - 0x2A, 0xB7, 0x20, 0x2E, 0x44, 0xCE, 0x1F, 0x5C, 0x66, 0xFF, 0xFB, 0x7F, 0xDC, 0x3C, 0x40, 0x64, - 0x48, 0x64, 0x99, 0x88, 0x89, 0xB4, 0x8B, 0xC6, 0x87, 0x9B, 0xFB, 0xB5, 0x1E, 0xBC, 0xB6, 0xA7, - 0x6F, 0x41, 0xA6, 0x34, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0xEC, 0x5F, 0x33, 0xF8, 0xCB, 0x03, 0x00, - 0x00, 0x20, 0x0B, 0xEF, 0xD0, 0xAA, 0xBB, 0xCC, 0xF6, 0x4F, 0xD8, 0x83, 0xBE, 0x8A, 0x8D, 0xF8, - 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, 0x74, 0xB1, 0xF8, 0x08, 0x02, 0x24, - 0x49, 0x7C, 0xBC, 0x6B, 0xE3, 0xE3, 0xDD, 0xC1, 0x59, 0x93, 0xDB, 0xF8, 0x7E, 0x73, 0x6E, 0xEF, - 0xF5, 0xE6, 0xDC, 0x81, 0x81, 0x51, 0xF7, 0xED, 0x58, 0xE7, 0xB7, 0x5F, 0x62, 0xFF, 0xBB, 0x36, - 0x3E, 0xDC, 0x54, 0x84, 0xC8, 0x90, 0xC8, 0x32, 0x11, 0x13, 0x69, 0x17, 0x8F, 0x8F, 0x70, 0x3B, - 0x3E, 0xE9, 0x02, 0xC4, 0xBD, 0xE5, 0x6B, 0x76, 0xF0, 0x8F, 0x43, 0xCF, 0x98, 0xF2, 0xF8, 0x70, - 0x1B, 0x5B, 0x66, 0xCC, 0x89, 0xAF, 0xAC, 0x0D, 0x7E, 0x09, 0x00, 0x00, 0x00, 0xC8, 0xC2, 0x3B, - 0xBC, 0x7A, 0x83, 0x8E, 0x8D, 0xF8, 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, - 0x74, 0x3A, 0x3E, 0xEA, 0x02, 0xC4, 0x86, 0x47, 0xF8, 0xCC, 0x47, 0x3C, 0x3E, 0x26, 0xDC, 0x9E, - 0xA8, 0xCC, 0xFD, 0xFF, 0x67, 0xB7, 0x7C, 0xDA, 0x4C, 0x3C, 0xD3, 0x6F, 0xCE, 0x0D, 0xD9, 0x10, - 0x79, 0xCA, 0xFD, 0x77, 0x2F, 0xD2, 0x11, 0xB2, 0x49, 0x85, 0x44, 0x96, 0x89, 0x98, 0x48, 0x3B, - 0x15, 0x1E, 0xD1, 0x1D, 0xBC, 0xD6, 0xBD, 0x96, 0x77, 0x30, 0xF8, 0xC7, 0xA1, 0x27, 0x74, 0x24, - 0x3E, 0xDC, 0x5E, 0xBC, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0xB4, 0xCB, 0x3B, 0x78, 0x4D, 0x82, - 0x37, 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0xE1, 0x11, - 0x2E, 0x1E, 0x1F, 0xE1, 0xED, 0x47, 0xE4, 0x99, 0x0F, 0x17, 0x1F, 0xD1, 0xF0, 0x98, 0x78, 0x3C, - 0x98, 0xFB, 0xBF, 0x1F, 0x9B, 0x65, 0x4E, 0x3F, 0x72, 0x9D, 0x39, 0xF3, 0xF0, 0x25, 0x7E, 0x80, - 0x9C, 0xF3, 0x1F, 0x58, 0x8F, 0x05, 0x88, 0x8B, 0x8F, 0x5C, 0x02, 0x44, 0xC4, 0x44, 0xDA, 0xA9, - 0xE0, 0x88, 0xAF, 0xC7, 0x6E, 0x41, 0x3A, 0x16, 0x1F, 0xC1, 0xBC, 0x5F, 0xDC, 0x39, 0x14, 0xFC, - 0x52, 0x00, 0x00, 0x00, 0x90, 0x85, 0xB7, 0xFF, 0xEA, 0x93, 0x3A, 0x3A, 0xC2, 0xA9, 0xA0, 0x48, - 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x78, 0xB8, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, - 0xDE, 0x7E, 0xD4, 0x7E, 0xEB, 0x55, 0x34, 0x3E, 0xCE, 0xD8, 0xE8, 0x38, 0xF3, 0xF8, 0xFB, 0x82, - 0x55, 0x22, 0xE4, 0xF4, 0xFD, 0x17, 0x99, 0x53, 0xF7, 0x5E, 0x6C, 0x4E, 0xDD, 0x7D, 0x91, 0x39, - 0x6B, 0xFF, 0x33, 0x75, 0xB7, 0x20, 0x36, 0x3C, 0xDC, 0xDA, 0x0F, 0x10, 0x11, 0x13, 0x69, 0xA7, - 0x62, 0xA3, 0xD1, 0x7A, 0xE4, 0x16, 0xA4, 0xD3, 0xF1, 0xE1, 0xE6, 0x1D, 0xFB, 0x53, 0xDE, 0x84, - 0x05, 0x00, 0x00, 0xD0, 0x8E, 0xE6, 0x6F, 0xC0, 0x52, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, - 0x46, 0x45, 0xD2, 0xC5, 0xA2, 0x23, 0xBA, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDC, 0x7E, 0xD4, 0x7C, - 0xDB, 0x55, 0x18, 0x1F, 0x8F, 0xD9, 0xF0, 0xB0, 0x3B, 0x1D, 0xFC, 0x78, 0xE6, 0x91, 0xF7, 0xF9, - 0xE1, 0x11, 0xEE, 0xF4, 0x7D, 0x36, 0x42, 0x36, 0x4E, 0x46, 0x88, 0xF7, 0x74, 0x25, 0x3E, 0xAA, - 0x01, 0x92, 0x39, 0x42, 0x44, 0x4C, 0xA4, 0x9D, 0x8A, 0x8C, 0x66, 0xDB, 0x7E, 0x71, 0xD7, 0xDF, - 0x82, 0x74, 0x43, 0x7C, 0xF8, 0x3B, 0x76, 0x0B, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xC8, 0xCA, 0x7F, - 0x03, 0xD6, 0xEE, 0x79, 0xF6, 0xE0, 0x5F, 0xFE, 0xF8, 0x70, 0x3F, 0x36, 0xBF, 0xFD, 0xB0, 0xF1, - 0xE1, 0x02, 0x24, 0x88, 0x0F, 0x17, 0x1E, 0xA7, 0x1F, 0x9D, 0xDC, 0xA9, 0x7B, 0x67, 0xD5, 0x04, - 0x88, 0xDB, 0xBB, 0x3F, 0x0E, 0x02, 0xE4, 0xA9, 0x0B, 0xED, 0xCF, 0x67, 0xE3, 0x23, 0x1E, 0x21, - 0x32, 0x30, 0x9A, 0x4D, 0xC4, 0x44, 0xDA, 0xA9, 0xC0, 0x48, 0xB2, 0x7D, 0x57, 0x18, 0x6F, 0x78, - 0x79, 0x57, 0x7E, 0xD0, 0x5E, 0xD7, 0xC4, 0x87, 0x9B, 0x7B, 0x13, 0xD6, 0xCB, 0x77, 0xF6, 0xDC, - 0x43, 0xFB, 0x00, 0x00, 0x00, 0x5D, 0xC1, 0x1C, 0x5A, 0xB5, 0xD6, 0xEC, 0x9C, 0x6D, 0x0F, 0xFF, - 0x25, 0x8E, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDD, 0x7E, 0xB8, 0xD7, 0xEC, 0x46, 0x6F, - 0x3F, 0xE2, 0xF1, 0x71, 0xFA, 0x81, 0xDA, 0xDB, 0x8F, 0x70, 0xEE, 0x16, 0xE4, 0xDC, 0x93, 0x76, - 0x1B, 0x2F, 0xF2, 0x23, 0xA4, 0x26, 0x40, 0x5C, 0x50, 0xA4, 0x8A, 0x10, 0x11, 0x13, 0x69, 0xA7, - 0xC2, 0x22, 0xE9, 0xB6, 0x7D, 0x24, 0xB8, 0x05, 0x59, 0x3A, 0x10, 0xFC, 0xE3, 0xD1, 0x15, 0xBA, - 0x2A, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0xB3, 0xAB, 0xFE, 0x1E, 0x01, 0x00, 0x00, 0xF4, - 0x0C, 0x73, 0x78, 0xF5, 0x7A, 0xB3, 0xF5, 0xC3, 0x36, 0x00, 0x4A, 0x1C, 0x1F, 0xC1, 0xD4, 0xED, - 0xC7, 0x59, 0x3F, 0x40, 0x6C, 0x7C, 0xB8, 0xDB, 0x8F, 0xC8, 0xB7, 0x5E, 0x55, 0xC3, 0xE3, 0xC7, - 0x95, 0xA9, 0xDB, 0x0F, 0x7F, 0x5F, 0xBF, 0xD0, 0xBC, 0xFB, 0x48, 0x25, 0x40, 0xCE, 0xB5, 0x75, - 0x0B, 0x22, 0x62, 0x22, 0xED, 0x54, 0x54, 0xA4, 0x9D, 0xBB, 0x05, 0x39, 0xB8, 0xAC, 0x6B, 0x6E, - 0x41, 0xBA, 0x2E, 0x3E, 0xDC, 0x78, 0x13, 0x16, 0x00, 0x00, 0x40, 0x76, 0xDE, 0xC8, 0x8A, 0xA1, - 0xD2, 0xC7, 0x47, 0xC3, 0xDB, 0x8F, 0x59, 0xD5, 0xF8, 0xA8, 0xDE, 0x7E, 0x84, 0xF1, 0x11, 0x84, - 0x87, 0x1F, 0x1F, 0x3F, 0xD2, 0xB7, 0x1F, 0x2E, 0x3E, 0xDC, 0x4E, 0x7F, 0xEB, 0x42, 0x73, 0xB6, - 0xAD, 0x5B, 0x10, 0x11, 0x13, 0x69, 0xA7, 0x62, 0x22, 0xCB, 0xB6, 0xD9, 0x18, 0x1D, 0x5E, 0xD6, - 0x15, 0xB7, 0x20, 0x5D, 0x19, 0x1F, 0xC1, 0xBC, 0x13, 0x5F, 0xEE, 0xA9, 0xD7, 0x16, 0x03, 0x00, - 0x00, 0x74, 0x0D, 0x6F, 0xDF, 0x55, 0x63, 0x65, 0xBF, 0xF9, 0x70, 0xAB, 0xBF, 0xFD, 0x88, 0x04, - 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x70, 0x44, 0x02, 0xE4, 0x94, 0x7B, 0xE8, 0xDC, 0xED, 0xDB, 0xE2, - 0xF6, 0x23, 0x88, 0x8F, 0x70, 0x13, 0x0F, 0x64, 0xBD, 0x05, 0x11, 0x31, 0x91, 0x76, 0x2A, 0x24, - 0x32, 0xED, 0x82, 0xCA, 0xF6, 0x5C, 0xD6, 0xF1, 0x5B, 0x90, 0x6E, 0x8E, 0x0F, 0x37, 0xEF, 0xF8, - 0x9F, 0x75, 0xE5, 0xB3, 0x32, 0x00, 0x00, 0x00, 0x5D, 0xCF, 0xEC, 0xBD, 0xDC, 0x86, 0x40, 0x89, - 0xE3, 0x23, 0xC1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xC1, 0xB7, 0x5E, 0x9D, 0x0A, 0x03, 0xE4, 0x07, - 0xAD, 0xE3, 0xC3, 0xED, 0xF4, 0x3D, 0x2D, 0x6E, 0x41, 0xE4, 0x44, 0x4C, 0xA4, 0x9D, 0x0C, 0x89, - 0x2C, 0x0B, 0xE2, 0xC3, 0xCD, 0xFD, 0xFD, 0xF5, 0x6F, 0x41, 0x96, 0xAF, 0x0B, 0xFE, 0x31, 0x99, - 0x52, 0xDD, 0x1E, 0x1F, 0xFE, 0x8E, 0xFF, 0x29, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x48, 0xCB, 0xBD, - 0x72, 0xD5, 0xEC, 0x59, 0x64, 0x63, 0x40, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0xBA, 0xA0, - 0x48, 0x33, 0x11, 0x1A, 0x8D, 0x16, 0x0F, 0x90, 0xE0, 0xF6, 0xE3, 0x6C, 0x92, 0xDB, 0x8F, 0x87, - 0xED, 0xEE, 0x69, 0x1D, 0x1F, 0xE1, 0xC2, 0x5B, 0x90, 0x64, 0x6F, 0xC4, 0x12, 0x31, 0x91, 0x76, - 0x32, 0x24, 0xB2, 0x2C, 0x12, 0x1F, 0xE1, 0x86, 0x16, 0x1A, 0xEF, 0xE0, 0xD2, 0x93, 0xC1, 0x3F, - 0x2A, 0x53, 0xA6, 0x27, 0xE2, 0xC3, 0xED, 0xC8, 0x6A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0x90, 0x96, - 0xFF, 0x0A, 0xDE, 0x9D, 0x9F, 0xB2, 0x41, 0xA0, 0xA2, 0x22, 0xE9, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, - 0x8A, 0xA4, 0x13, 0x91, 0xA1, 0x66, 0x83, 0xA3, 0x1A, 0x1F, 0x36, 0x3C, 0x12, 0xDF, 0x7E, 0x44, - 0xBF, 0xF5, 0xEA, 0xFB, 0xB1, 0xDB, 0x0F, 0x11, 0x1D, 0xD1, 0x25, 0xBF, 0x05, 0x11, 0x31, 0x91, - 0x76, 0x32, 0x24, 0xB2, 0x4C, 0xC4, 0x87, 0x9B, 0xFB, 0x7B, 0x3D, 0xC5, 0xB7, 0x20, 0x3D, 0x13, - 0x1F, 0x3F, 0xBF, 0xDC, 0x98, 0xB1, 0x15, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x20, 0x2D, 0x73, 0x78, - 0xE5, 0x7A, 0xB3, 0xED, 0xA3, 0x36, 0x0A, 0x54, 0x58, 0x24, 0x99, 0x88, 0x8B, 0x56, 0xAB, 0x0B, - 0x8A, 0x34, 0x8B, 0x45, 0x46, 0xB3, 0x45, 0x03, 0xC4, 0xAE, 0x12, 0x1F, 0x36, 0x0E, 0xC2, 0x00, - 0x69, 0xF4, 0xDA, 0xDD, 0x46, 0xB7, 0x1F, 0x22, 0x38, 0xD4, 0x26, 0x7E, 0x50, 0x09, 0x90, 0x9A, - 0x67, 0x41, 0x82, 0x10, 0xA9, 0xDC, 0x82, 0x88, 0x98, 0x48, 0x3B, 0x19, 0x12, 0x59, 0x26, 0xC2, - 0x23, 0xBA, 0x29, 0xBC, 0x05, 0xE9, 0xA9, 0xF8, 0x70, 0x7B, 0xF1, 0x3A, 0x63, 0x7F, 0xBD, 0x77, - 0x05, 0xBF, 0x7C, 0x00, 0x00, 0x00, 0x24, 0xE1, 0x1D, 0x5E, 0xB9, 0x41, 0x87, 0x45, 0x92, 0x89, - 0xB8, 0x68, 0x35, 0x19, 0x15, 0x49, 0x17, 0x0B, 0x8C, 0x66, 0x8B, 0xC5, 0x47, 0xE5, 0xF6, 0x23, - 0x12, 0x1F, 0xCD, 0x6E, 0x3F, 0xC2, 0x00, 0x89, 0xDE, 0x7E, 0x88, 0xD0, 0x68, 0xB8, 0x6F, 0x5C, - 0x68, 0xCE, 0x3E, 0xD1, 0xE0, 0x16, 0x64, 0x93, 0x88, 0x89, 0xB4, 0x93, 0x21, 0x91, 0x65, 0x22, - 0x38, 0xE2, 0x73, 0x7F, 0xDF, 0x0F, 0x5E, 0x57, 0xF8, 0x2D, 0x48, 0xCF, 0xC5, 0x47, 0x30, 0xEF, - 0xC4, 0x9D, 0x1B, 0x82, 0xDF, 0x02, 0x00, 0x00, 0x00, 0x92, 0xF0, 0x0E, 0x5E, 0x3D, 0xAA, 0xE3, - 0xA2, 0xD5, 0x44, 0x5C, 0xB4, 0x5A, 0x5D, 0x50, 0xA4, 0x59, 0x2C, 0x30, 0x9A, 0xAD, 0x41, 0x7C, - 0xF8, 0xB7, 0x1F, 0x2E, 0x3E, 0xD4, 0xED, 0x47, 0x10, 0x1F, 0xD5, 0xDB, 0x8F, 0x87, 0xEC, 0xBE, - 0x91, 0x21, 0x3E, 0x82, 0x85, 0xB7, 0x20, 0xE7, 0x9F, 0x72, 0x7F, 0xDD, 0x20, 0x42, 0x9E, 0x9E, - 0x69, 0x7F, 0x2D, 0x2E, 0x20, 0x82, 0xA9, 0xB8, 0x68, 0x35, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, - 0xD1, 0x76, 0xCD, 0x31, 0xDE, 0xF0, 0xD2, 0x71, 0x33, 0xD4, 0x3F, 0x2B, 0xF8, 0xC7, 0x26, 0x57, - 0xBD, 0x1A, 0x1F, 0x7E, 0x80, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x74, 0xBC, 0xFD, 0x9F, 0x1D, - 0xD7, 0x81, 0xD1, 0x6C, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xC5, 0x02, 0xA3, 0xD5, 0xEA, - 0x02, 0x24, 0x88, 0x8F, 0xF8, 0xED, 0x47, 0x10, 0x1F, 0xF2, 0xD9, 0x8F, 0xFB, 0x83, 0xDB, 0x0F, - 0x11, 0x17, 0x89, 0x16, 0xBB, 0x05, 0x39, 0x1F, 0xC4, 0x47, 0x5B, 0x01, 0x22, 0x43, 0x22, 0xCB, - 0x44, 0x64, 0x34, 0x9B, 0x7B, 0x66, 0xC5, 0xDD, 0x82, 0x1C, 0x5C, 0x9A, 0xFB, 0x07, 0xEF, 0xF5, - 0x72, 0x7C, 0xB8, 0x79, 0xC7, 0xFE, 0x64, 0x3C, 0xF8, 0xAD, 0x00, 0x00, 0x00, 0xA0, 0x15, 0x33, - 0xDA, 0x3F, 0x2B, 0xFD, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x8B, 0xC5, 0x45, - 0x92, 0xC5, 0xE3, 0x23, 0x7A, 0xFB, 0x11, 0xC4, 0x47, 0xCD, 0x9B, 0xAF, 0x1A, 0xDD, 0x7E, 0xA8, - 0xB0, 0x48, 0xB1, 0x33, 0xDF, 0xBB, 0x70, 0xF2, 0x59, 0x90, 0xA7, 0x6C, 0x7C, 0xB4, 0x13, 0x21, - 0x32, 0x24, 0xB2, 0x4C, 0x04, 0x46, 0x92, 0x15, 0x70, 0x0B, 0xD2, 0xEB, 0xF1, 0xE1, 0xEF, 0xC8, - 0x4D, 0xC6, 0x8C, 0xFD, 0x87, 0x42, 0x6E, 0x86, 0x00, 0x00, 0x00, 0x4A, 0xC7, 0x7F, 0x03, 0xD6, - 0xAE, 0x4F, 0xDB, 0x48, 0x50, 0xA1, 0xA1, 0x26, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, - 0x8B, 0x56, 0xB3, 0xD1, 0x31, 0x19, 0x20, 0x17, 0x55, 0x02, 0x24, 0xB8, 0xFD, 0xA8, 0xBE, 0x76, - 0xB7, 0x7A, 0xFB, 0xF1, 0xBE, 0xC6, 0xB7, 0x1F, 0x22, 0x28, 0xB2, 0xEC, 0xEC, 0x63, 0x2E, 0x42, - 0x2A, 0x01, 0xE2, 0xDF, 0x82, 0x64, 0x89, 0x10, 0x19, 0x12, 0x59, 0x26, 0xC2, 0x22, 0xE9, 0x72, - 0xBE, 0x05, 0x29, 0x45, 0x7C, 0xB8, 0xBD, 0x34, 0xC0, 0x9B, 0xB0, 0x00, 0x00, 0x00, 0x92, 0x32, - 0x87, 0x57, 0xAD, 0x4B, 0xFE, 0x0A, 0x5E, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x61, - 0x91, 0x74, 0xF1, 0xF8, 0xC8, 0x74, 0xFB, 0xA1, 0x63, 0x22, 0xFD, 0x66, 0x9A, 0x33, 0xF7, 0xCF, - 0x34, 0x67, 0x9F, 0x9C, 0x8C, 0x90, 0xD4, 0x01, 0x22, 0x43, 0x22, 0xCB, 0x44, 0x54, 0xA4, 0xDD, - 0xCE, 0xD9, 0xC6, 0x1B, 0xBE, 0xBE, 0xED, 0x5B, 0x90, 0xD2, 0xC4, 0x87, 0x1B, 0x6F, 0xC2, 0x02, - 0x00, 0x00, 0x48, 0xCE, 0xB8, 0x57, 0xF0, 0xCA, 0xD8, 0x88, 0x4F, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, - 0x48, 0x3A, 0x11, 0x16, 0x49, 0xE6, 0x6E, 0x3F, 0xEC, 0x8F, 0x7E, 0x7C, 0xC4, 0x6E, 0x3F, 0xEA, - 0x9F, 0xFD, 0x68, 0x70, 0xFB, 0x71, 0x5F, 0xFB, 0xDF, 0x7A, 0x55, 0xD9, 0xCC, 0xEA, 0xDE, 0x0D, - 0x6E, 0x41, 0xCE, 0x35, 0xBA, 0x05, 0x51, 0xE1, 0xE1, 0x26, 0x43, 0x22, 0xCB, 0x44, 0x4C, 0x64, - 0xDA, 0x7B, 0x8D, 0x39, 0x70, 0xB5, 0x7B, 0x2D, 0xEF, 0x60, 0xF0, 0x8F, 0x50, 0x6A, 0xA5, 0x8A, - 0x0F, 0xB7, 0xE7, 0xAF, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x49, 0x79, 0x07, 0xAF, 0x4B, 0xF0, - 0x06, 0x2C, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x51, 0x91, 0x66, 0xE1, 0xCD, 0x47, - 0x83, 0xDB, 0x8F, 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0x78, 0x30, 0xAF, 0x6F, 0xBD, 0x9A, 0x8C, 0x0F, - 0xB7, 0x4C, 0xB7, 0x20, 0x32, 0x24, 0xB2, 0x4C, 0x85, 0x44, 0x96, 0xD9, 0xF8, 0x70, 0xDB, 0xFE, - 0x71, 0xF7, 0x6D, 0x58, 0xC6, 0x8C, 0x5C, 0x9B, 0xFA, 0x13, 0xC0, 0x4B, 0x17, 0x1F, 0xC1, 0xBC, - 0x13, 0x77, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x24, 0xBC, 0x7D, 0x57, 0x8E, 0xE9, 0xE8, 0x08, - 0x27, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, 0x8A, 0xA4, 0xF3, 0x6F, 0x3F, 0x82, 0xF8, - 0x88, 0xDD, 0x7E, 0xA8, 0x67, 0x3F, 0xEA, 0x3F, 0x74, 0xD0, 0xC6, 0x47, 0x2E, 0xB7, 0x1F, 0xB5, - 0xF1, 0x11, 0xEE, 0xDD, 0x47, 0x5A, 0x3C, 0x0B, 0xD2, 0x0B, 0xF1, 0xF1, 0x74, 0xB0, 0xFD, 0xE9, - 0x6F, 0x41, 0xCA, 0x1A, 0x1F, 0x6E, 0xDE, 0xB1, 0x5B, 0xA6, 0xE4, 0x83, 0x1A, 0x01, 0x00, 0x00, - 0x7A, 0x9E, 0xD9, 0x7B, 0x99, 0x8D, 0x06, 0x15, 0x1E, 0x6E, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, - 0xD2, 0xC5, 0x82, 0x22, 0xED, 0xC2, 0xF0, 0x68, 0x70, 0xFB, 0x51, 0xF7, 0xEC, 0x47, 0x10, 0x20, - 0x95, 0xDB, 0x0F, 0x1B, 0x1F, 0xB9, 0xDC, 0x7E, 0xE8, 0xF8, 0x70, 0x3B, 0x7D, 0xEF, 0x4C, 0x73, - 0xAE, 0xD1, 0x2D, 0x88, 0x1F, 0x1D, 0x3D, 0x12, 0x1F, 0xF6, 0xFF, 0xF6, 0xB6, 0x7F, 0xDC, 0x05, - 0x48, 0xE2, 0x5B, 0x90, 0x32, 0xC7, 0x87, 0xBF, 0x23, 0x37, 0x99, 0xE0, 0xB7, 0x0A, 0x00, 0x00, - 0x80, 0x46, 0xCC, 0xE1, 0xFE, 0x25, 0x66, 0x68, 0xBE, 0x0D, 0x87, 0x72, 0xC4, 0x47, 0xCB, 0xDB, - 0x0F, 0x11, 0x1F, 0x95, 0xDB, 0x0F, 0x1B, 0x1E, 0xB9, 0xDC, 0x7E, 0xE8, 0xF0, 0x88, 0x2E, 0xBC, - 0x05, 0x69, 0xF8, 0x2C, 0x88, 0x0C, 0x89, 0x2C, 0x53, 0x21, 0x91, 0x65, 0x22, 0x3E, 0xEC, 0x8F, - 0xFE, 0xF6, 0x7C, 0xC6, 0x9C, 0x3F, 0x70, 0xFD, 0x50, 0xF0, 0x8F, 0x53, 0x43, 0xA5, 0x8F, 0x0F, - 0x37, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x9A, 0xFF, 0x0A, 0x5E, 0xF9, 0x06, 0x2C, 0x11, 0x17, - 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x50, 0xA4, 0x9A, 0x8D, 0x8F, 0x30, 0x3C, 0xC2, 0xF8, 0x48, - 0x7A, 0xFB, 0xF1, 0x63, 0x1B, 0x1E, 0x2E, 0x40, 0x7E, 0xD8, 0xEE, 0xED, 0x87, 0x0E, 0x8E, 0xF8, - 0xDC, 0x2D, 0x48, 0xE3, 0x67, 0x41, 0x54, 0x48, 0x64, 0x99, 0x0A, 0x89, 0x2C, 0x6B, 0x12, 0x1F, - 0x4F, 0xBD, 0xD7, 0x9C, 0xDF, 0xF2, 0x21, 0x73, 0x7E, 0xFF, 0x32, 0x73, 0x76, 0xFF, 0xD2, 0x86, - 0x07, 0xEF, 0x69, 0x11, 0x1F, 0x6E, 0x2F, 0x5E, 0xE7, 0x02, 0x64, 0x5D, 0xF0, 0xDB, 0x06, 0x00, - 0x00, 0x80, 0xE2, 0xBF, 0x01, 0x6B, 0xEB, 0x87, 0x6C, 0x40, 0xF4, 0x7E, 0x7C, 0x64, 0xB9, 0xFD, - 0xA8, 0xC6, 0x87, 0xBB, 0xFD, 0xF8, 0x56, 0x3B, 0xB7, 0x1F, 0x3A, 0x36, 0x1A, 0x6D, 0xE2, 0x21, - 0x75, 0x0B, 0x32, 0xC3, 0x9F, 0x0E, 0x8A, 0x34, 0x53, 0x21, 0x91, 0x65, 0x2D, 0xE2, 0xC3, 0x6D, - 0xE3, 0x05, 0xE6, 0xFC, 0xEE, 0x25, 0xE6, 0xDC, 0xDE, 0x65, 0xF2, 0x01, 0xEC, 0x69, 0x13, 0x1F, - 0x6E, 0xCF, 0x5F, 0x69, 0xCC, 0x89, 0x3B, 0x73, 0xFF, 0x94, 0x78, 0x00, 0x00, 0x80, 0x52, 0xF1, - 0x0E, 0xAD, 0x1C, 0xEC, 0xF9, 0xF8, 0xC8, 0x78, 0xFB, 0x71, 0xEA, 0x51, 0x1B, 0x1D, 0xB9, 0xDC, - 0x7E, 0xE8, 0xC8, 0x68, 0xB6, 0xD3, 0xF7, 0xC4, 0x6F, 0x41, 0x2A, 0xF1, 0xD1, 0x7E, 0x80, 0xA8, - 0x90, 0xC8, 0xB2, 0x64, 0xF1, 0x71, 0xEE, 0x49, 0xBB, 0x4D, 0x1F, 0x76, 0x01, 0x62, 0xCE, 0x0E, - 0xD5, 0xDE, 0x82, 0x4C, 0xAB, 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x6F, 0xC2, 0x02, 0x00, 0x00, - 0x68, 0xC6, 0xDB, 0x77, 0x45, 0xE4, 0x15, 0xBC, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xA9, - 0xA0, 0x48, 0xB3, 0x20, 0x3E, 0x82, 0xA5, 0xBB, 0xFD, 0x88, 0xC4, 0x47, 0x5B, 0xB7, 0x1F, 0x3A, - 0x30, 0x92, 0x6C, 0xE2, 0x81, 0xE8, 0x2D, 0x88, 0x8D, 0x8F, 0xB6, 0x23, 0x44, 0x85, 0x44, 0x96, - 0x25, 0x8F, 0x8F, 0xB3, 0x83, 0x76, 0x4F, 0x5C, 0x60, 0xDE, 0xDD, 0xB1, 0xC4, 0x4C, 0xEC, 0x5E, - 0x5E, 0x3D, 0x7C, 0x4F, 0xC7, 0xF8, 0x70, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x2D, 0x98, 0x7D, - 0xF6, 0x70, 0xD7, 0xEB, 0xF1, 0x91, 0xE6, 0xF6, 0x23, 0x8C, 0x8F, 0x5C, 0x6E, 0x3F, 0x74, 0x58, - 0x24, 0x5D, 0xE5, 0x16, 0x64, 0xA6, 0x8D, 0x10, 0x1B, 0x20, 0x4F, 0xB5, 0x1B, 0x20, 0x2A, 0x24, - 0xB2, 0x2C, 0x43, 0x7C, 0x3C, 0x7E, 0x81, 0x39, 0x33, 0xF8, 0x41, 0x17, 0x20, 0xE6, 0xF4, 0x8E, - 0xA5, 0x03, 0xD3, 0x35, 0x3E, 0xFC, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x00, 0x34, 0x62, - 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x0B, 0x75, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, - 0x66, 0x91, 0xF8, 0x08, 0xA6, 0x6E, 0x3F, 0xAA, 0x01, 0x52, 0x73, 0xFB, 0x31, 0xAB, 0xFE, 0xF6, - 0xE3, 0x9B, 0x2A, 0x2E, 0x5A, 0x4D, 0x47, 0x45, 0x9A, 0xBD, 0xF3, 0xD7, 0x33, 0xCC, 0x99, 0x1F, - 0x4E, 0x06, 0x48, 0xF6, 0x5B, 0x10, 0x15, 0x12, 0x59, 0x96, 0x31, 0x3E, 0x1E, 0x9D, 0x61, 0x4E, - 0xFF, 0xD8, 0xEE, 0x99, 0x45, 0x66, 0xE2, 0xC0, 0xAA, 0x93, 0xD3, 0x36, 0x3E, 0xDC, 0x8E, 0xAC, - 0x32, 0xE6, 0xF8, 0x1D, 0x4B, 0x82, 0x2F, 0x31, 0x00, 0x00, 0x00, 0x44, 0x99, 0x91, 0xFE, 0x01, - 0xB3, 0xF3, 0x12, 0x1D, 0x18, 0xCD, 0x26, 0xA3, 0x22, 0xE9, 0x54, 0x50, 0xA4, 0x59, 0x2C, 0x3E, - 0x12, 0xDC, 0x7E, 0x4C, 0xB8, 0x00, 0x79, 0xDC, 0xDD, 0x7E, 0xC4, 0xE2, 0xC3, 0xED, 0x7B, 0x59, - 0xBE, 0xF5, 0x4A, 0x07, 0x45, 0x9A, 0xB9, 0xF8, 0xF0, 0x77, 0xF7, 0x0C, 0x7B, 0x90, 0x6F, 0xE7, - 0x16, 0x44, 0x85, 0x44, 0x96, 0xB5, 0x17, 0x1F, 0xA7, 0x1E, 0x76, 0x01, 0x32, 0xDB, 0x98, 0x63, - 0x77, 0x9A, 0x69, 0x1B, 0x1F, 0x3F, 0xBF, 0xCC, 0x98, 0x17, 0x3F, 0x67, 0xCC, 0x89, 0x2F, 0xAD, - 0x0D, 0xBE, 0xC4, 0x00, 0x00, 0x00, 0x10, 0xE5, 0x1D, 0x5A, 0x75, 0x97, 0xD9, 0x7E, 0xB1, 0x8E, - 0x8C, 0x46, 0x93, 0x51, 0x91, 0x74, 0x2A, 0x28, 0xD2, 0x2C, 0x16, 0x1F, 0x2A, 0x40, 0x1A, 0x3E, - 0xFB, 0x61, 0xE3, 0x23, 0x97, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0x56, 0x8D, 0x8F, 0x60, 0x67, 0xBE, - 0x5F, 0x09, 0x90, 0x73, 0xD1, 0x5B, 0x90, 0x20, 0x44, 0x74, 0x74, 0x84, 0x53, 0x21, 0x91, 0x65, - 0x39, 0xC4, 0xC7, 0xD3, 0x1F, 0x33, 0xDE, 0xD1, 0xDB, 0xA7, 0x77, 0x7C, 0xB8, 0x3D, 0xFF, 0x59, - 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x88, 0x19, 0x59, 0xB9, 0x5E, 0x46, 0x46, 0xA3, 0xC9, 0xA8, - 0x48, 0x3A, 0x15, 0x14, 0x69, 0x56, 0x1F, 0x1E, 0xD5, 0xF8, 0xB0, 0xE1, 0x31, 0x79, 0xFB, 0x11, - 0xF9, 0xD6, 0xAB, 0xEA, 0xED, 0xC7, 0x45, 0x95, 0xDB, 0x0F, 0xBB, 0xF6, 0x6E, 0x3F, 0x74, 0x50, - 0xA4, 0x59, 0x3C, 0x3E, 0xFC, 0x65, 0xBA, 0x05, 0x51, 0x21, 0x91, 0x65, 0xC4, 0x47, 0xFB, 0x0B, - 0xE2, 0x23, 0x98, 0xF7, 0x8B, 0x3B, 0x5B, 0x7E, 0x30, 0x23, 0x00, 0x00, 0xC0, 0xB4, 0xE4, 0x1D, - 0xB8, 0x7A, 0x54, 0x86, 0x86, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, 0x66, 0xB1, 0xF8, 0x88, - 0x07, 0x88, 0x5D, 0xF5, 0x5B, 0xAF, 0xC2, 0x00, 0xA9, 0x3E, 0x78, 0x6E, 0xE3, 0xC3, 0x06, 0x48, - 0xFB, 0xB7, 0x1F, 0x3A, 0x28, 0xD2, 0x4C, 0xC6, 0x47, 0xB0, 0xF0, 0x16, 0xC4, 0xBD, 0x92, 0xB7, - 0xF5, 0x2D, 0x88, 0x0A, 0x89, 0x2C, 0x23, 0x3E, 0xDA, 0x5F, 0x6D, 0x7C, 0xF8, 0x01, 0x72, 0xF4, - 0xD6, 0xB1, 0xE0, 0x4B, 0x0C, 0x00, 0x00, 0x00, 0x51, 0xDE, 0xFE, 0x2B, 0x4F, 0xCA, 0xD8, 0x88, - 0x4F, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x78, 0x88, 0xF8, 0x08, 0x6F, 0x3F, 0x6A, - 0x1E, 0x3C, 0xF7, 0x6F, 0x3F, 0x2E, 0x9A, 0xBC, 0xFD, 0x08, 0xE3, 0x23, 0x0C, 0x90, 0xFB, 0xD3, - 0xDC, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x1D, 0x35, 0x73, 0xB7, 0x20, 0x8F, 0x4D, 0xDE, 0x82, - 0xF8, 0x11, 0x62, 0x63, 0xA3, 0x3E, 0x40, 0x54, 0x48, 0x64, 0x19, 0xF1, 0xD1, 0xFE, 0xEA, 0xE3, - 0xC3, 0xDF, 0xB1, 0x2F, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x00, 0x25, 0xD1, 0x1B, 0xB0, 0x64, 0x54, - 0x24, 0x9D, 0x0A, 0x8A, 0x34, 0x8B, 0x85, 0x47, 0x93, 0xF8, 0xA8, 0x3E, 0x78, 0x5E, 0xBD, 0xFD, - 0xB0, 0xF1, 0x11, 0xDE, 0x7E, 0xC4, 0xE3, 0xE3, 0x21, 0xBB, 0xBB, 0x55, 0x68, 0xA8, 0xE9, 0xA0, - 0x48, 0x33, 0x19, 0x1C, 0x62, 0xA7, 0xBF, 0x3B, 0x23, 0x78, 0x16, 0xA4, 0xC1, 0xB7, 0x62, 0x3D, - 0xAD, 0x42, 0x22, 0xCB, 0x88, 0x8F, 0xF6, 0x27, 0xC2, 0x23, 0x1C, 0x6F, 0xC2, 0x02, 0x00, 0x00, - 0xA8, 0xE7, 0xBF, 0x01, 0x6B, 0xD7, 0x1C, 0x1D, 0x1D, 0xE1, 0x64, 0x54, 0x24, 0x9D, 0x0A, 0x8A, - 0x34, 0x8B, 0x85, 0x47, 0x38, 0x15, 0x20, 0xF1, 0xD7, 0xEE, 0x3E, 0x39, 0x19, 0x1F, 0xF2, 0xCD, - 0x57, 0x89, 0x6F, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0A, 0x8D, 0x66, 0x7B, 0x37, 0x7E, 0x0B, 0x12, - 0x46, 0x88, 0x8B, 0x8F, 0x70, 0x32, 0x2A, 0x92, 0x8E, 0xF8, 0x68, 0x7F, 0x22, 0x3A, 0xA2, 0x7B, - 0xF1, 0x7A, 0x63, 0x5E, 0xBE, 0xB3, 0xE6, 0x53, 0xE1, 0x01, 0x00, 0x00, 0xA6, 0x3D, 0x73, 0xA8, - 0x7F, 0xAD, 0xD9, 0xF1, 0x49, 0x1D, 0x1E, 0x6E, 0x32, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, 0xC5, - 0xA2, 0x23, 0xBA, 0x78, 0x7C, 0x44, 0x6F, 0x3F, 0x82, 0xF8, 0x98, 0xBC, 0xFD, 0x10, 0xDF, 0x7A, - 0x95, 0xF8, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xA9, 0xC0, 0x68, 0x35, 0x77, 0x0B, 0x52, 0xF7, 0xE1, - 0x84, 0x36, 0x3A, 0xF2, 0x09, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xE0, 0x88, 0xEF, 0x85, 0xAB, 0x79, - 0x13, 0x16, 0x00, 0x00, 0x40, 0x9C, 0xFF, 0x06, 0xAC, 0xAD, 0x1F, 0xEC, 0xB9, 0xF8, 0x68, 0x74, - 0xFB, 0xE1, 0xE2, 0xE3, 0x6C, 0x2C, 0x3E, 0xB2, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x17, - 0x49, 0xF7, 0xEE, 0x8F, 0x2B, 0x01, 0xE2, 0xBF, 0x96, 0xF7, 0x29, 0x1B, 0x1F, 0x6E, 0xD1, 0x08, - 0x91, 0x71, 0xD1, 0x6A, 0xC4, 0x47, 0xFB, 0x13, 0xB1, 0xD1, 0x60, 0xDE, 0x89, 0x2F, 0x0D, 0x06, - 0x5F, 0x6A, 0x00, 0x00, 0x00, 0x70, 0xBC, 0xE1, 0xE5, 0x43, 0x3D, 0x15, 0x1F, 0x6E, 0xF1, 0xF8, - 0x88, 0xDE, 0x7E, 0xB8, 0xF8, 0x68, 0x75, 0xFB, 0xF1, 0xA0, 0x9D, 0x0C, 0x8E, 0xE8, 0x74, 0x50, - 0xA4, 0x99, 0x8A, 0x8A, 0x34, 0x3B, 0xFD, 0xED, 0xE0, 0x16, 0xE4, 0x49, 0x1B, 0x20, 0x36, 0x0A, - 0xEA, 0x02, 0x24, 0x75, 0x84, 0x10, 0x1F, 0xED, 0x4F, 0x87, 0x46, 0xA3, 0x79, 0x47, 0x6F, 0x1D, - 0x0D, 0xBE, 0xD4, 0x00, 0x00, 0x00, 0xE0, 0x78, 0x7B, 0xAF, 0xA8, 0x7F, 0x05, 0xAF, 0x8C, 0x8A, - 0xA4, 0x53, 0x41, 0x91, 0x66, 0x22, 0x38, 0xA2, 0xB3, 0xD1, 0xE1, 0x7E, 0xAC, 0xBB, 0xFD, 0xB0, - 0xF1, 0x71, 0x6E, 0xE3, 0x45, 0xC9, 0x6E, 0x3F, 0xEE, 0x6B, 0x75, 0xFB, 0xA1, 0x83, 0x22, 0xCD, - 0x54, 0x50, 0x64, 0xD9, 0xBB, 0xF6, 0xD0, 0x1F, 0x06, 0x48, 0x7B, 0xB7, 0x20, 0xC4, 0x47, 0xFB, - 0xD3, 0x91, 0xD1, 0x74, 0xC7, 0x6E, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x51, 0x66, 0xEF, 0xE2, - 0xDE, 0x89, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x08, 0x03, 0x24, 0x88, 0x8F, 0x78, 0x80, 0xD4, - 0xC5, 0x47, 0xCB, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0xA6, 0x42, 0x22, 0xDB, 0x2E, 0x30, 0xA7, 0xBF, - 0x6D, 0xA3, 0x60, 0x70, 0x32, 0x42, 0x6A, 0x02, 0xC4, 0x85, 0x45, 0xA2, 0x08, 0x21, 0x3E, 0xDA, - 0x9F, 0x88, 0x8B, 0x24, 0x73, 0x6F, 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x1B, 0x00, 0x00, - 0xC0, 0xF4, 0x66, 0x46, 0xFA, 0x67, 0xD7, 0xBC, 0x82, 0x57, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, - 0x33, 0x11, 0x1B, 0xF1, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, 0xDF, 0x7E, 0xD8, 0xF0, 0x10, 0xB7, 0x1F, - 0xF2, 0x43, 0x07, 0x9B, 0xDE, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x76, 0x41, 0x75, - 0xE1, 0x2D, 0xC8, 0xB9, 0x4C, 0xB7, 0x20, 0xC4, 0x47, 0xFB, 0x13, 0x61, 0x91, 0x74, 0x63, 0xCB, - 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xC8, 0x7F, 0x05, 0x6F, 0xF8, 0x06, 0x2C, 0x19, 0x15, 0x49, - 0xA7, 0x82, 0x22, 0xCD, 0x62, 0xA1, 0xD1, 0x68, 0x61, 0x78, 0x84, 0xF1, 0xE1, 0xF6, 0xD4, 0x85, - 0x35, 0xDF, 0x7A, 0x15, 0x0F, 0x90, 0x53, 0x2E, 0x40, 0xC2, 0xDB, 0x8F, 0x1F, 0xD9, 0xC9, 0xF0, - 0x70, 0xD3, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x6C, 0x32, 0x3E, 0xDC, 0x4E, 0x7D, 0xD3, 0xC5, - 0x41, 0x96, 0x5B, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xA8, 0x48, 0xB3, 0x17, 0x3F, 0xC7, 0x9B, 0xB0, - 0x00, 0x00, 0x00, 0x42, 0xFE, 0x1B, 0xB0, 0xB6, 0x7D, 0xC4, 0x1E, 0xEE, 0x55, 0x54, 0x24, 0x9D, - 0x0A, 0x8A, 0x34, 0x13, 0xA1, 0xA1, 0x66, 0xA3, 0xC3, 0xFD, 0x58, 0x7B, 0xFB, 0x61, 0xE3, 0x23, - 0xCD, 0xED, 0xC7, 0xB7, 0x1A, 0xDD, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x56, 0x1B, - 0x1F, 0xE1, 0x26, 0x7E, 0x94, 0xF6, 0x16, 0x84, 0xF8, 0x68, 0x7F, 0x22, 0x28, 0x32, 0x8C, 0x37, - 0x61, 0x01, 0x00, 0x00, 0x04, 0xBC, 0x91, 0x81, 0x0D, 0x3A, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, - 0xC5, 0x22, 0xA3, 0xD9, 0xC2, 0xF0, 0x88, 0xC4, 0x47, 0xA2, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x68, - 0xD7, 0xA3, 0xF1, 0xE1, 0xD6, 0xF2, 0x16, 0x84, 0xF8, 0xC8, 0x79, 0x3A, 0x26, 0xB2, 0xCC, 0x3B, - 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0x38, 0xDE, 0x81, 0xAB, 0x47, 0x75, 0x58, 0x24, 0x99, - 0x0A, 0x8A, 0x34, 0x13, 0x91, 0xD1, 0x62, 0xD5, 0x00, 0x09, 0xE3, 0xA3, 0xED, 0xDB, 0x0F, 0x1D, - 0x14, 0x69, 0xA6, 0x43, 0x22, 0xCB, 0x74, 0x78, 0x44, 0x17, 0xDE, 0x82, 0xB8, 0x78, 0x68, 0x7C, - 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x12, 0x59, 0xE7, 0x1D, 0xBB, 0x65, 0x3C, 0xF8, 0x92, 0x03, - 0x00, 0x00, 0x98, 0xDE, 0xBC, 0x7D, 0x57, 0x8C, 0xEB, 0xB8, 0x68, 0x35, 0x15, 0x14, 0x69, 0xA6, - 0x03, 0xA3, 0xE1, 0x6A, 0x6E, 0x3F, 0x6C, 0x7C, 0x34, 0xBB, 0xFD, 0x08, 0xE3, 0xA3, 0xE5, 0xED, - 0x87, 0x0E, 0x8A, 0x34, 0xD3, 0x21, 0x91, 0x65, 0x3A, 0x38, 0xE2, 0xF3, 0x6F, 0x41, 0x1E, 0x6F, - 0x76, 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x11, 0x6D, 0xCD, 0xBD, 0x09, 0x6B, 0xEC, 0x8B, 0xB3, - 0x82, 0x2F, 0x3B, 0x00, 0x00, 0x80, 0xE9, 0xCB, 0x0C, 0x2D, 0xB0, 0x07, 0x7C, 0x15, 0x18, 0xCD, - 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x60, 0x24, 0x58, 0x18, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xB9, 0x1F, - 0xC9, 0x6E, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0E, 0x89, 0x2C, 0xD3, 0xB1, 0xD1, 0x68, 0x67, 0xBE, - 0x2F, 0x9E, 0x05, 0xF1, 0x43, 0x24, 0x12, 0x1E, 0x6E, 0xC4, 0x47, 0x86, 0x89, 0x78, 0xC8, 0x63, - 0x63, 0xCB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x80, 0xFF, 0x06, 0xAC, 0x9D, 0xB3, 0xED, 0xE1, 0x5E, - 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0x33, 0x1D, 0x17, 0x4D, 0x17, 0xB9, 0xF9, 0xF0, 0xE3, 0x43, - 0xDC, 0x7E, 0x4C, 0xB8, 0x3D, 0x1E, 0xB9, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xE5, 0x89, 0x0F, - 0x7F, 0x77, 0xAB, 0x5B, 0x90, 0x4A, 0x68, 0x18, 0x1B, 0x19, 0xC4, 0x47, 0xD6, 0x89, 0x70, 0xC8, - 0x65, 0x8B, 0x8D, 0x79, 0xF1, 0x5A, 0xE3, 0xFD, 0xE2, 0x4B, 0x77, 0x05, 0x5F, 0x7A, 0x00, 0x00, - 0x00, 0xD3, 0x93, 0x0D, 0x90, 0x75, 0x66, 0xC7, 0x27, 0xEC, 0x21, 0x5F, 0x85, 0x86, 0x9A, 0x0A, - 0x8A, 0x34, 0x13, 0x71, 0x91, 0x64, 0x61, 0x7C, 0xC4, 0x6E, 0x3F, 0x12, 0x3F, 0xFB, 0xF1, 0xCD, - 0x12, 0xC5, 0x47, 0xB0, 0x33, 0xDF, 0x8B, 0x3E, 0x0B, 0x52, 0x89, 0x8C, 0x70, 0x2E, 0x40, 0xC2, - 0xF0, 0x20, 0x3E, 0x92, 0x4E, 0x85, 0x43, 0x1E, 0xB3, 0xF1, 0xE1, 0x66, 0x7F, 0xED, 0xDE, 0x89, - 0x3B, 0x36, 0x04, 0x5F, 0x7A, 0x00, 0x00, 0x00, 0xD3, 0x93, 0xFF, 0x0A, 0x5E, 0x19, 0x1A, 0x6A, - 0x2A, 0x28, 0xD2, 0x4C, 0x84, 0x45, 0xAB, 0xD9, 0xF0, 0xA8, 0xC6, 0x87, 0x0D, 0x8F, 0xC9, 0xDB, - 0x8F, 0xD8, 0xB7, 0x5E, 0x45, 0x6F, 0x3F, 0xEC, 0x1A, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, - 0x12, 0x59, 0xA6, 0xC3, 0x22, 0xF1, 0xAA, 0xB7, 0x20, 0x36, 0x40, 0x36, 0xBA, 0xC0, 0x08, 0x82, - 0x23, 0x12, 0x1E, 0xC4, 0x47, 0xD2, 0xA9, 0x70, 0xC8, 0x63, 0x41, 0x7C, 0x04, 0xF3, 0x4E, 0xFC, - 0x39, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x9B, 0x77, 0xF0, 0xBA, 0x84, 0x6F, 0xC0, 0x52, 0x41, - 0x91, 0x66, 0xB1, 0xB0, 0x48, 0x3A, 0x17, 0x20, 0xE1, 0xCD, 0x87, 0x5D, 0xF5, 0x5B, 0xAF, 0xE4, - 0xB3, 0x1F, 0x17, 0xB5, 0xB8, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x04, 0x45, - 0x86, 0x9D, 0xFE, 0xCE, 0x7B, 0xFD, 0xB0, 0x08, 0x23, 0xA4, 0x1A, 0x1C, 0x2E, 0x3E, 0x82, 0x28, - 0x21, 0x3E, 0x5A, 0x4D, 0x85, 0x43, 0x1E, 0xAB, 0x8D, 0x0F, 0x3F, 0x40, 0x8E, 0x7D, 0x81, 0x37, - 0x61, 0x01, 0x00, 0x80, 0xE9, 0xCD, 0xDB, 0xFB, 0xD9, 0x31, 0x1D, 0x1C, 0xD1, 0xA9, 0xA0, 0x48, - 0xB3, 0x58, 0x54, 0x24, 0x5D, 0x2C, 0x3E, 0xC2, 0xDB, 0x8F, 0xBA, 0xF8, 0x88, 0xDE, 0x7E, 0x84, - 0xF1, 0x11, 0x06, 0xC8, 0x86, 0xF0, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xE9, 0x90, 0xC8, 0x32, 0x1D, - 0x13, 0xA9, 0xF7, 0x57, 0xEF, 0xF5, 0xF7, 0xEE, 0xA3, 0x93, 0x01, 0x12, 0x9F, 0x1F, 0x27, 0x2E, - 0x3C, 0x88, 0x8F, 0x06, 0x53, 0xE1, 0x90, 0xC7, 0xEA, 0xE3, 0xC3, 0xDF, 0x91, 0x1B, 0x4C, 0xF0, - 0xA5, 0x07, 0x00, 0x00, 0x30, 0x3D, 0x99, 0x3D, 0xF6, 0x50, 0x24, 0xA3, 0x23, 0x9C, 0x0A, 0x8A, - 0x34, 0x8B, 0x45, 0x45, 0xD2, 0x35, 0x88, 0x8F, 0xEA, 0x83, 0xE7, 0xEA, 0xF6, 0x23, 0x1E, 0x1F, - 0x0F, 0xD9, 0xDD, 0x5D, 0xEE, 0xF8, 0x70, 0x73, 0xB7, 0x20, 0x7E, 0x60, 0xD8, 0x9D, 0x7B, 0xD2, - 0x86, 0x87, 0xDD, 0xB9, 0x68, 0x7C, 0xD8, 0xF0, 0x38, 0x6B, 0xC3, 0x83, 0xF8, 0x88, 0x4F, 0x85, - 0x43, 0x1E, 0x8B, 0x45, 0x47, 0x74, 0x2F, 0xAD, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xFA, 0x32, - 0x87, 0xFB, 0x97, 0x98, 0xDD, 0xF3, 0xEC, 0x81, 0x5F, 0x85, 0x87, 0x9B, 0x0A, 0x8A, 0x34, 0x8B, - 0x45, 0x45, 0x9A, 0xD9, 0xE8, 0xA8, 0x0B, 0x90, 0x26, 0xDF, 0x7A, 0x25, 0xDF, 0x7C, 0x75, 0xBF, - 0xBB, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x45, 0xE2, 0x23, - 0x9C, 0xBB, 0x05, 0xF1, 0x43, 0x63, 0xD0, 0xC6, 0x88, 0x0D, 0x90, 0xB3, 0xB1, 0x6F, 0xB9, 0x7A, - 0xF7, 0x31, 0xE2, 0xA3, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x88, 0x8E, 0xE8, 0x5E, 0xBC, 0xD6, 0x06, - 0xC8, 0x1D, 0xEB, 0x82, 0x2F, 0x41, 0x00, 0x00, 0x80, 0xE9, 0xC5, 0x7F, 0x05, 0x6F, 0xC3, 0x37, - 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x15, 0x49, 0xF7, 0x8C, 0x88, 0x8F, 0xE8, 0xED, 0x87, 0x8B, - 0x8F, 0x9A, 0x00, 0x11, 0xDF, 0x7A, 0xE5, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, - 0x26, 0x42, 0x22, 0xCB, 0x44, 0x7C, 0xBC, 0xBD, 0xFE, 0xBD, 0xE6, 0xD4, 0x3D, 0x36, 0x42, 0x5C, - 0x68, 0xB8, 0xE0, 0x70, 0x21, 0x12, 0xFC, 0xE8, 0xFE, 0xB5, 0x09, 0x17, 0x1F, 0x36, 0x3C, 0x4E, - 0x3F, 0x42, 0x7C, 0x54, 0xA6, 0xC2, 0x21, 0x8F, 0x89, 0xE0, 0x88, 0xCF, 0xFD, 0xBE, 0x4E, 0xDC, - 0xB1, 0x3E, 0xF8, 0x12, 0x04, 0x00, 0x00, 0x98, 0x5E, 0xFC, 0x37, 0x60, 0x6D, 0xF9, 0x80, 0x3D, - 0xF4, 0x77, 0x5F, 0x7C, 0x34, 0xBA, 0xFD, 0x50, 0xAF, 0xDD, 0xD5, 0xB7, 0x1F, 0xED, 0x7F, 0xEB, - 0x95, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0x0D, 0xE2, 0x23, 0xDC, 0x99, 0x07, 0x6D, 0x6C, - 0x3C, 0x3E, 0xA3, 0x12, 0x22, 0x41, 0x78, 0x4C, 0x3C, 0x7A, 0x81, 0x7F, 0xEB, 0x41, 0x7C, 0x84, - 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x6C, 0x34, 0x98, 0x77, 0xE2, 0x0E, 0xDE, 0x84, 0x05, 0x00, 0x00, - 0xA6, 0x27, 0xEF, 0xD0, 0xCA, 0xC1, 0xAE, 0x8B, 0x8F, 0x5C, 0x6E, 0x3F, 0x2E, 0x6A, 0xFB, 0xF6, - 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0xD6, 0xD7, 0xEC, 0xBF, 0xF6, - 0x4D, 0x17, 0x1D, 0x33, 0xFC, 0x9D, 0xB1, 0xE1, 0xE1, 0xE6, 0x7F, 0xCB, 0x55, 0x18, 0x1F, 0x4F, - 0x11, 0x1F, 0xC5, 0x4C, 0x87, 0x46, 0xA3, 0x79, 0xC7, 0xBE, 0x70, 0x32, 0xF8, 0x12, 0x04, 0x00, - 0x00, 0x98, 0x5E, 0xBC, 0xBD, 0x57, 0xC4, 0x5E, 0xC1, 0xAB, 0x82, 0x22, 0xCD, 0x44, 0x54, 0x24, - 0x5D, 0x24, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0xA3, 0xFE, 0xD9, 0x0F, 0x75, 0xFB, 0x61, 0xE3, 0xE3, - 0xBE, 0xF6, 0x6E, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x4B, 0x10, 0x1F, 0x6F, 0x7D, - 0xED, 0x02, 0xF3, 0xD6, 0x7F, 0xB9, 0xC0, 0x9C, 0xFA, 0xA1, 0x0D, 0x0D, 0x77, 0xE3, 0xF1, 0x63, - 0x1B, 0x1F, 0x41, 0x78, 0xBC, 0xF3, 0x90, 0xFD, 0x91, 0xF8, 0x28, 0x68, 0x3A, 0x32, 0x9A, 0xEE, - 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x4C, 0x4F, 0x66, 0xAF, 0x3D, 0xF0, 0x75, 0x53, 0x7C, - 0x04, 0x01, 0xD2, 0xEC, 0xF6, 0x23, 0x1E, 0x20, 0x75, 0xF1, 0xF1, 0x60, 0x7B, 0x0F, 0x9E, 0xEB, - 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x96, 0x22, 0x3E, 0xDE, 0xFC, 0xCF, 0xF6, 0xC7, 0xBB, 0x6D, - 0x84, 0x04, 0xD1, 0xE1, 0xEF, 0x41, 0xE2, 0x43, 0x87, 0x43, 0x1E, 0x13, 0x71, 0x91, 0x64, 0x47, - 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xFD, 0x98, 0xD1, 0xFE, 0x59, 0x66, 0x68, 0x81, 0x0D, - 0x80, 0xEE, 0x8A, 0x0F, 0xF7, 0xA3, 0xBA, 0xFD, 0x50, 0xCF, 0x7E, 0xD4, 0x7E, 0xE8, 0xA0, 0x0D, - 0x8F, 0x87, 0xDB, 0xBB, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x2C, 0x65, 0x7C, 0xB8, - 0xFD, 0xE1, 0xFF, 0xB1, 0xFF, 0xFF, 0x77, 0x66, 0x98, 0xB7, 0x1F, 0x98, 0x69, 0x67, 0xE3, 0x63, - 0x23, 0xF1, 0x51, 0xCC, 0x44, 0x58, 0x24, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x2F, 0xAD, 0x0D, 0xBE, - 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0xFF, 0x0D, 0x58, 0x3B, 0x67, 0xDB, 0x08, 0x50, 0x41, 0x91, - 0x66, 0x22, 0x2A, 0x92, 0x2E, 0x1A, 0x1F, 0x41, 0x80, 0x34, 0xBB, 0xFD, 0x70, 0xF1, 0x11, 0x0F, - 0x90, 0x6A, 0x7C, 0xB4, 0x79, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, 0x64, 0x59, 0xC6, 0xF8, - 0x78, 0xE3, 0x2F, 0x67, 0x98, 0xF1, 0xFF, 0x3C, 0xC3, 0xBC, 0xF5, 0x23, 0xFB, 0x7B, 0x7A, 0x92, - 0xF8, 0x28, 0x66, 0x22, 0x2A, 0xD2, 0xEC, 0xF9, 0x2B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x7E, - 0xBC, 0x43, 0xAB, 0xEE, 0x32, 0xDB, 0x3E, 0x6A, 0x43, 0x40, 0x45, 0x45, 0xD2, 0x89, 0xA8, 0x48, - 0x3A, 0x11, 0x1F, 0xEE, 0xC7, 0xD4, 0xB7, 0x1F, 0x61, 0x7C, 0xB8, 0xDB, 0x8F, 0x7B, 0xB3, 0xDD, - 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x4E, 0x7C, 0xFC, 0xA7, 0x19, 0xE6, 0xF7, - 0xFF, 0xF7, 0x0C, 0xF3, 0xE6, 0x03, 0xC4, 0x47, 0x31, 0x13, 0x41, 0x91, 0x61, 0xDE, 0x2F, 0xEE, - 0x18, 0x0A, 0xBE, 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0x33, 0xD2, 0xBF, 0x5E, 0x47, 0x45, 0xD2, - 0x89, 0xA8, 0x48, 0xBA, 0x78, 0x7C, 0xB8, 0x85, 0xE1, 0x11, 0xC6, 0x47, 0xAB, 0xDB, 0x0F, 0xFF, - 0x5B, 0xAF, 0x82, 0xF8, 0x70, 0xFB, 0xA1, 0x9D, 0x88, 0x8B, 0x56, 0xD3, 0x21, 0x91, 0x65, 0x22, - 0x24, 0xB2, 0x2C, 0x87, 0xF8, 0x78, 0xE3, 0xDB, 0x36, 0x3E, 0x5E, 0x22, 0x3E, 0xF2, 0x9F, 0x8E, - 0x89, 0x2C, 0xF3, 0x8E, 0xDE, 0x3C, 0x16, 0x7C, 0x29, 0x02, 0x00, 0x00, 0x4C, 0x0F, 0xDE, 0x81, - 0xAB, 0x46, 0x75, 0x58, 0x24, 0x99, 0x88, 0x8A, 0xA4, 0x6B, 0x10, 0x1F, 0xEE, 0xC7, 0x54, 0xB7, - 0x1F, 0xD1, 0xF8, 0x70, 0xB7, 0x1F, 0xDF, 0x4A, 0x7F, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, - 0x64, 0x19, 0xF1, 0x91, 0xC3, 0x54, 0x38, 0xE4, 0x31, 0x1D, 0x12, 0x99, 0xC7, 0x9B, 0xB0, 0x00, - 0x00, 0xC0, 0x74, 0xE3, 0xED, 0xFF, 0xEC, 0x49, 0x1D, 0x17, 0xAD, 0x26, 0xA2, 0x22, 0xE9, 0xE2, - 0xE1, 0x11, 0x2E, 0x0C, 0x8F, 0x30, 0x3E, 0x9A, 0xDD, 0x7E, 0x3C, 0x76, 0x91, 0x39, 0xFD, 0xA8, - 0x0D, 0x8E, 0x36, 0x6F, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, - 0x0A, 0x87, 0x3C, 0x26, 0x02, 0xA2, 0xDD, 0xB9, 0x37, 0x61, 0x1D, 0xBF, 0x63, 0x49, 0xF0, 0xE5, - 0x08, 0x00, 0x00, 0x50, 0x7E, 0x66, 0x68, 0xBE, 0x8D, 0x02, 0x15, 0x18, 0xCD, 0x26, 0xA2, 0x22, - 0xE9, 0x54, 0x78, 0x44, 0x96, 0xE8, 0xF6, 0x23, 0x88, 0x8F, 0x76, 0x6F, 0x3F, 0x74, 0x48, 0x64, - 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0x26, 0xE2, 0x21, 0x8F, 0xBD, - 0x78, 0x1D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x87, 0xFF, 0x06, 0xAC, 0x5D, 0x9F, 0xB6, 0x61, - 0xA0, 0x22, 0xA3, 0xD1, 0x44, 0x54, 0x24, 0x9D, 0x08, 0x8E, 0xEA, 0x92, 0xDE, 0x7E, 0x3C, 0x6E, - 0x03, 0x24, 0x8C, 0x8F, 0x68, 0x80, 0xFC, 0x80, 0xF8, 0x20, 0x3E, 0x54, 0x38, 0xE4, 0x31, 0x11, - 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x3E, 0xCC, 0xA1, 0xFE, 0xB5, - 0x66, 0xC7, 0xC7, 0x6D, 0x1C, 0xA8, 0xD0, 0x50, 0x13, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0x62, 0x53, - 0xB7, 0x1F, 0xD1, 0x00, 0xF1, 0xE3, 0xA3, 0xD1, 0xED, 0xC7, 0x37, 0x75, 0x68, 0xA8, 0xE9, 0x90, - 0xC8, 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x44, 0x43, 0xCE, - 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xDA, 0xF0, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0x36, 0x10, 0x54, - 0x6C, 0xC4, 0x27, 0xA2, 0x22, 0xE9, 0x44, 0x6C, 0xD4, 0x2C, 0xC1, 0xED, 0x87, 0xFB, 0xD6, 0xAB, - 0x89, 0xC7, 0x2E, 0x9C, 0xBC, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xC9, 0x6F, 0x3F, 0x74, 0x48, - 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0xA6, 0x83, 0x21, 0xEF, - 0x79, 0x47, 0xFF, 0x64, 0x34, 0xF8, 0x92, 0x04, 0x00, 0x00, 0x28, 0x37, 0x6F, 0x78, 0xE9, 0x90, - 0x8E, 0x8D, 0xF8, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8E, 0xF8, 0xE2, 0x01, 0xA2, 0x9E, 0xFD, 0x78, - 0xDC, 0xC6, 0x47, 0x9B, 0xB7, 0x1F, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x11, 0x1F, 0x39, - 0x4C, 0x85, 0x43, 0x1E, 0xD3, 0xB1, 0x50, 0xC8, 0x8E, 0x7D, 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, - 0xE9, 0xC1, 0xDB, 0xBB, 0x24, 0xC1, 0x2B, 0x78, 0x45, 0x54, 0x24, 0x9D, 0x8A, 0x8D, 0xE8, 0x6C, - 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, 0x47, 0xEC, 0x5B, 0xAF, 0x9E, 0xB8, 0x70, 0xF2, - 0xF6, 0xC3, 0x2E, 0xCB, 0xED, 0x87, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, - 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x24, 0x14, 0xB6, 0x45, 0x95, 0x37, 0x61, 0xBD, 0x7C, 0xE7, 0xEC, - 0xE0, 0xCB, 0x12, 0x00, 0x00, 0xA0, 0xBC, 0xCC, 0x1E, 0x7B, 0xF8, 0x91, 0xD1, 0x11, 0x4E, 0x44, - 0x45, 0xD2, 0xA9, 0xE0, 0x88, 0x2F, 0x1A, 0x20, 0x76, 0xD5, 0x6F, 0xBD, 0x8A, 0x06, 0x88, 0x8B, - 0x0F, 0xFF, 0xF6, 0xE3, 0xC2, 0xFA, 0xDB, 0x8F, 0x87, 0xEC, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, - 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xB3, - 0x5F, 0x7F, 0x6E, 0x2F, 0x7E, 0xCE, 0x05, 0xC8, 0x40, 0xF0, 0x65, 0x09, 0x00, 0x00, 0x50, 0x4E, - 0x66, 0xA4, 0x7F, 0x76, 0xF3, 0x57, 0xF0, 0x8A, 0xA8, 0x48, 0x3A, 0x15, 0x1B, 0xF1, 0xC5, 0xE2, - 0x23, 0xBC, 0xFD, 0xA8, 0x7D, 0xF0, 0xDC, 0xC6, 0x47, 0xF4, 0xF6, 0x23, 0xFE, 0xAD, 0x57, 0xF7, - 0xB7, 0xBE, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, - 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x16, 0xC4, 0x87, 0x1F, 0x20, 0xD7, 0xF0, 0x26, 0x2C, 0x00, 0x00, - 0x50, 0x7E, 0xFE, 0x2B, 0x78, 0x1B, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, 0xA9, 0xD8, 0x88, 0xAF, - 0x41, 0x7C, 0x54, 0x1F, 0x3C, 0x77, 0xB3, 0xF1, 0x51, 0x73, 0xFB, 0x11, 0x7F, 0xF0, 0xDC, 0xDD, - 0x7E, 0xDC, 0xAD, 0xA3, 0x23, 0x9C, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, - 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0xB5, 0x48, 0x7C, 0x04, 0xF3, 0x4E, 0x7C, 0x69, 0x30, - 0xF8, 0xD2, 0x04, 0x00, 0x00, 0x28, 0x27, 0xFF, 0x0D, 0x58, 0x5B, 0x3F, 0x64, 0xA3, 0x61, 0x8A, - 0xE3, 0xC3, 0x4D, 0x05, 0x48, 0xCD, 0xB7, 0x5E, 0xD9, 0xF8, 0x70, 0xB7, 0x1F, 0x41, 0x7C, 0x64, - 0xB9, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x56, 0x1F, 0x1F, 0x6E, 0xDE, 0xF1, 0x3F, 0xE5, 0x4D, 0x58, 0x00, 0x00, - 0xA0, 0xDC, 0xBC, 0x91, 0x81, 0x0D, 0x1D, 0x89, 0x0F, 0xB7, 0x78, 0x7C, 0x54, 0x6F, 0x3F, 0x2E, - 0xAC, 0xC6, 0xC7, 0xE4, 0xED, 0x47, 0x2C, 0x3E, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, - 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xF1, 0xE1, - 0xEF, 0xD8, 0x2D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x94, 0x9B, 0x77, 0xE0, 0xAA, 0xD8, 0x1B, 0xB0, - 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x8C, 0x46, 0xB3, 0xD1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0x44, 0x02, - 0x24, 0x8C, 0x0F, 0xF9, 0xB9, 0x1F, 0xDF, 0x69, 0x7C, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, - 0x64, 0x59, 0x34, 0x3A, 0x88, 0x8F, 0x8C, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x11, - 0x1D, 0xD1, 0xB9, 0x37, 0x61, 0x8D, 0x7D, 0x71, 0x56, 0xF0, 0xE5, 0x09, 0x00, 0x00, 0x50, 0x3E, - 0xDE, 0xBE, 0x25, 0xE3, 0x53, 0x1E, 0x1F, 0x6E, 0xF1, 0xF8, 0x48, 0x7B, 0xFB, 0xF1, 0xA0, 0x9D, - 0x08, 0x0F, 0x37, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x52, 0xC4, 0x47, 0x18, 0x20, 0x2E, - 0x3E, 0xFE, 0x40, 0x7C, 0x44, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x38, 0xE2, - 0x1B, 0x5B, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB9, 0x4D, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, - 0xA9, 0xC0, 0x68, 0x36, 0x1B, 0x1D, 0xEE, 0x47, 0x75, 0xFB, 0x11, 0x0D, 0x90, 0xA6, 0xB7, 0x1F, - 0xF7, 0xE9, 0xDB, 0x0F, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x22, 0xF1, 0x11, 0xAE, 0x3E, - 0x3E, 0xEC, 0x5C, 0x78, 0x84, 0xB7, 0x1F, 0xC4, 0x47, 0x6C, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, - 0xA2, 0x26, 0x62, 0x43, 0xED, 0xC5, 0x6B, 0x8C, 0xF7, 0x8B, 0x2F, 0xDD, 0x15, 0x7C, 0x79, 0x02, - 0x00, 0x00, 0x94, 0x8B, 0xFF, 0x06, 0xAC, 0x9D, 0x9F, 0xD2, 0x51, 0x91, 0x74, 0xF1, 0xB8, 0x48, - 0xB2, 0x30, 0x3C, 0xC2, 0xF8, 0xF0, 0x03, 0x64, 0x66, 0x35, 0x3E, 0x6A, 0xDF, 0x7C, 0x95, 0xFC, - 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0x76, 0x24, 0x3E, 0xE2, - 0x37, 0x1F, 0x6F, 0x04, 0xF1, 0xF1, 0x07, 0xE2, 0xA3, 0xA0, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x34, - 0x9A, 0xCC, 0x3B, 0x71, 0xC7, 0x86, 0xE0, 0x4B, 0x14, 0x00, 0x00, 0xA0, 0x5C, 0x6C, 0x80, 0xAC, - 0x33, 0xDB, 0x2F, 0xD6, 0x61, 0x91, 0x64, 0x2A, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0xF6, - 0xF6, 0xC3, 0xC6, 0x47, 0x83, 0x67, 0x3F, 0xEA, 0x3E, 0x74, 0xD0, 0xBD, 0xF9, 0x4A, 0xDC, 0x7E, - 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x22, 0x3E, 0xA2, 0x37, 0x1F, 0x61, 0x7C, 0x84, - 0x37, 0x1F, 0xC4, 0x47, 0x38, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x91, 0xD1, 0x6C, - 0xDE, 0x89, 0x3F, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x9C, 0xFC, 0x57, 0xF0, 0xAA, 0xB0, 0x48, - 0xB2, 0x78, 0x58, 0x24, 0x5D, 0x18, 0x1E, 0x61, 0x7C, 0x3C, 0x3D, 0xB3, 0xE6, 0xF6, 0xA3, 0xEE, - 0xD9, 0x0F, 0x1B, 0x20, 0xA7, 0xA2, 0x01, 0xF2, 0x23, 0xBB, 0x1E, 0x8C, 0x0F, 0xB7, 0xBA, 0x00, - 0x69, 0x10, 0x1F, 0xE3, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0xC0, - 0x68, 0x35, 0xEF, 0xD8, 0x17, 0xC6, 0x83, 0x2F, 0x51, 0x00, 0x00, 0x80, 0x72, 0xF1, 0x0E, 0x5C, - 0x33, 0x2A, 0xE3, 0xA2, 0xD5, 0x54, 0x58, 0x24, 0x99, 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, - 0xF1, 0x11, 0xBD, 0xFD, 0x88, 0xC5, 0x47, 0xDD, 0xED, 0xC7, 0xB7, 0x6A, 0x6F, 0x3F, 0x74, 0x48, - 0x64, 0x99, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x56, 0x17, 0x1F, 0xEA, 0x8D, 0x57, 0xC4, 0x47, - 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x71, 0x91, 0x68, 0x47, 0x56, 0xF3, 0x26, - 0x2C, 0x00, 0x00, 0x50, 0x4E, 0xDE, 0xDE, 0x25, 0x63, 0x32, 0x30, 0x9A, 0x2D, 0x1E, 0x15, 0x69, - 0x16, 0x86, 0x47, 0x18, 0x1F, 0x69, 0x6F, 0x3F, 0x7E, 0x68, 0x57, 0xB6, 0xF8, 0x70, 0x37, 0x1F, - 0x2E, 0x3E, 0xDC, 0x43, 0xE7, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, - 0xA8, 0x48, 0xB3, 0x97, 0x56, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x4E, 0x66, 0xCF, 0x42, 0x1D, - 0x19, 0x8D, 0xA6, 0xA2, 0x22, 0xE5, 0x2A, 0x01, 0x32, 0xB3, 0xED, 0xDB, 0x0F, 0x1D, 0x12, 0x59, - 0x26, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0xB5, 0x8C, 0x8F, 0xBF, 0x9C, 0xFC, 0xAC, 0x8F, 0x3F, - 0xDC, 0x4B, 0x7C, 0x14, 0x33, 0x15, 0x09, 0x45, 0x4D, 0x04, 0x45, 0xDA, 0xBD, 0x78, 0x8D, 0x0D, - 0x90, 0x3B, 0xD6, 0x05, 0x5F, 0xA6, 0x00, 0x00, 0x00, 0xE5, 0x60, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, - 0xE6, 0xE8, 0xD0, 0x50, 0x13, 0x31, 0x91, 0x6A, 0xD5, 0xDB, 0x8F, 0x20, 0x3E, 0x9A, 0xDD, 0x7E, - 0x84, 0xF1, 0xD1, 0xE0, 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, - 0x0D, 0xE3, 0x23, 0x08, 0x90, 0xE8, 0x07, 0x0D, 0x12, 0x1F, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, - 0xA2, 0x26, 0x62, 0x22, 0xCB, 0x9E, 0xB7, 0x7F, 0x3F, 0x4E, 0xDC, 0xB1, 0x3E, 0xF8, 0x52, 0x05, - 0x00, 0x00, 0x28, 0x07, 0xFF, 0x15, 0xBC, 0x49, 0xDF, 0x80, 0xA5, 0x82, 0x22, 0xC3, 0xFC, 0xF8, - 0x88, 0xDD, 0x7E, 0x54, 0x03, 0xA4, 0xD5, 0xED, 0xC7, 0x3D, 0xBD, 0x1B, 0x1F, 0x95, 0xD7, 0xED, - 0x12, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x24, 0xDA, 0x18, 0x6F, - 0xC2, 0x02, 0x00, 0x00, 0xA5, 0xE3, 0xBF, 0x01, 0x6B, 0xEB, 0x07, 0x75, 0x70, 0x44, 0x27, 0x42, - 0x22, 0xF5, 0xC2, 0x9B, 0x8F, 0x26, 0xB7, 0x1F, 0x13, 0x2E, 0x40, 0x1E, 0x8B, 0xDC, 0x7E, 0x84, - 0xF1, 0xE1, 0xF6, 0xBD, 0xCA, 0xB7, 0x5E, 0xE9, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x26, 0xC2, - 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x11, 0xD1, 0xCE, - 0xBC, 0x63, 0x5F, 0x38, 0x19, 0x7C, 0xA9, 0x02, 0x00, 0x00, 0x94, 0x83, 0x37, 0xBC, 0x62, 0x50, - 0x06, 0x47, 0x74, 0x2A, 0x26, 0xB2, 0x2C, 0x8C, 0x8F, 0xD8, 0xED, 0x47, 0xE2, 0x67, 0x3F, 0xBE, - 0xC9, 0xB7, 0x5D, 0x25, 0x9B, 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, - 0x2A, 0x12, 0x8A, 0x9A, 0x0E, 0x88, 0xB6, 0x77, 0x64, 0xB5, 0x09, 0xBE, 0x54, 0x01, 0x00, 0x00, - 0xCA, 0xC1, 0xDB, 0x7B, 0x79, 0xF3, 0x57, 0xF0, 0xAA, 0x90, 0x48, 0xBB, 0x4D, 0x6E, 0x93, 0xE1, - 0x31, 0x79, 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xFC, 0xF6, 0x43, 0x87, 0x44, - 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0x0D, 0xE3, 0xC3, 0x3D, 0x70, 0x1E, 0x8B, 0x8F, - 0xF1, 0xFF, 0x32, 0xCB, 0x9C, 0xFF, 0xD7, 0x5B, 0x83, 0xF8, 0x58, 0x65, 0x0F, 0xFA, 0x2A, 0x28, - 0xD2, 0x4C, 0x84, 0x43, 0x1E, 0x93, 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, - 0x4D, 0x84, 0x43, 0x5E, 0x3B, 0xB2, 0x92, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF1, 0xF6, 0x2C, - 0x1A, 0x97, 0xE1, 0xE1, 0xA6, 0x62, 0x22, 0xCB, 0x6C, 0x78, 0x44, 0x6F, 0x3F, 0xAA, 0xDF, 0x7A, - 0x15, 0x06, 0x48, 0xCD, 0x6B, 0x77, 0x2F, 0x94, 0xB7, 0x1F, 0xEF, 0x7C, 0x23, 0xAF, 0xDB, 0x0F, - 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x2D, 0x6D, 0x7C, 0x9C, 0xFB, 0xE9, 0x17, 0x2A, 0xF1, 0x71, - 0xD4, 0xFE, 0x28, 0x83, 0x22, 0xCD, 0x44, 0x38, 0xE4, 0x31, 0x19, 0x0E, 0x79, 0x4C, 0x85, 0x43, - 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x44, 0x34, 0xE4, 0x39, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xCA, 0xC4, - 0x0C, 0xF5, 0xCF, 0x32, 0x43, 0x7D, 0x53, 0x1A, 0x1F, 0xE1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xCD, - 0x9E, 0xFD, 0x70, 0xF1, 0x71, 0x7F, 0x5E, 0xB7, 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, - 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x82, 0x21, 0xEF, 0xB9, 0xFF, - 0x6D, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0x0B, 0xFF, 0x0D, 0x58, 0x3B, 0x3E, 0x39, 0xE5, 0xF1, - 0x51, 0x7D, 0xF0, 0x5C, 0xDD, 0x7E, 0xC4, 0x1E, 0x3C, 0x7F, 0xE7, 0x41, 0x1B, 0x1F, 0x5F, 0x57, - 0x31, 0x91, 0x76, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x62, 0xA1, 0xA0, 0x79, 0x27, 0xEE, 0xE0, 0x4D, 0x58, 0x00, 0x00, - 0xA0, 0x1C, 0xBC, 0xE1, 0xFE, 0xBB, 0xCC, 0xB6, 0x8F, 0x14, 0x13, 0x1F, 0xCF, 0x54, 0xE2, 0xA3, - 0x2E, 0x40, 0xE2, 0xAF, 0xDD, 0x75, 0xB7, 0x1F, 0x41, 0x7C, 0xC4, 0x6F, 0x3F, 0xDE, 0x79, 0xD8, - 0xC6, 0xC7, 0x77, 0xF3, 0xF8, 0xD6, 0x2B, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, - 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xA1, 0x50, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, - 0x82, 0x2F, 0x59, 0x00, 0x00, 0x80, 0xDE, 0xE6, 0xBF, 0x82, 0xB7, 0xA8, 0xF8, 0x08, 0x02, 0xA4, - 0xE1, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0x8A, 0xC7, 0x47, 0x2E, 0xB7, 0x1F, 0x22, 0x24, - 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0xA6, - 0x23, 0xA1, 0xD0, 0x1D, 0xB9, 0x91, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF0, 0x0E, 0x5C, 0x33, - 0xF9, 0x06, 0x2C, 0x19, 0x12, 0x59, 0x36, 0x19, 0x1F, 0x8D, 0x6E, 0x3F, 0xAA, 0xAF, 0xDD, 0xAD, - 0xDE, 0x7E, 0x5C, 0x14, 0xBB, 0xFD, 0xB0, 0xE1, 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, - 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x38, 0x98, - 0x8A, 0xBD, 0x34, 0x60, 0xCC, 0xF1, 0x3B, 0x96, 0x04, 0x5F, 0xB6, 0x00, 0x00, 0x00, 0xBD, 0xCB, - 0xDB, 0x77, 0xC5, 0xC9, 0x42, 0xE2, 0xA3, 0xAD, 0xDB, 0x8F, 0x20, 0x3E, 0x1E, 0x68, 0xF7, 0xF6, - 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, - 0x50, 0xD4, 0x44, 0x18, 0x4C, 0xD5, 0xDC, 0x9B, 0xB0, 0x4E, 0x7C, 0x69, 0x6D, 0xF0, 0x65, 0x0B, - 0x00, 0x00, 0xD0, 0xBB, 0xCC, 0xEE, 0xBE, 0x48, 0x3C, 0xB4, 0xBB, 0xDA, 0xF8, 0x70, 0x3F, 0xAA, - 0xDB, 0x8F, 0xFA, 0x67, 0x3F, 0xA2, 0xB7, 0x1F, 0x41, 0x7C, 0xB8, 0xDD, 0xDB, 0xCE, 0xED, 0x87, - 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, - 0xA8, 0x89, 0x28, 0x98, 0xCA, 0xBD, 0x70, 0x25, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xCF, 0x1C, - 0xE8, 0x5F, 0x62, 0x76, 0xCE, 0x0E, 0xE2, 0xA1, 0xDD, 0x45, 0xE2, 0x23, 0x08, 0x90, 0x66, 0xB7, - 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xE1, 0x6E, 0x3F, 0x64, 0x58, 0x24, 0x99, 0x08, 0x89, 0x2C, - 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x20, - 0xE8, 0xC0, 0xBC, 0xE3, 0xB7, 0x0F, 0x05, 0x5F, 0xBA, 0x00, 0x00, 0x00, 0xBD, 0xC9, 0x1C, 0x5C, - 0xB6, 0xD6, 0x6C, 0xFF, 0x58, 0x10, 0x10, 0xED, 0xAC, 0x3E, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0x43, - 0x3D, 0xFB, 0x51, 0xF9, 0xD0, 0xC1, 0x0B, 0x27, 0x03, 0xE4, 0x21, 0xBB, 0xCC, 0xB7, 0x1F, 0x22, - 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, - 0xA6, 0x63, 0xA0, 0x13, 0xF3, 0x8E, 0xDE, 0xC2, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x33, 0x23, - 0xCB, 0xD7, 0x9B, 0xCD, 0xEF, 0xB3, 0xB1, 0xA0, 0xA2, 0x22, 0xE9, 0x62, 0xF1, 0xE1, 0x16, 0x86, - 0x47, 0x18, 0x1F, 0xB1, 0xDB, 0x8F, 0xBA, 0x67, 0x3F, 0x1E, 0xB5, 0xF1, 0xE1, 0x02, 0xA4, 0xED, - 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, - 0x45, 0x42, 0x51, 0xD3, 0x21, 0xD0, 0xB1, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, - 0xE6, 0x1D, 0xB8, 0x7E, 0xA8, 0x36, 0x26, 0xD2, 0x4E, 0xC7, 0x87, 0xFB, 0xB1, 0xE9, 0xED, 0x47, - 0x2C, 0x3E, 0xEA, 0x6E, 0x3F, 0xEE, 0xC9, 0x72, 0xFB, 0x21, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, - 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x00, 0x3A, 0x3D, 0xF7, - 0x26, 0xAC, 0x97, 0xEF, 0x9C, 0x1D, 0x7C, 0xF9, 0x02, 0x00, 0x00, 0xF4, 0x1E, 0x6F, 0xEF, 0x65, - 0xA3, 0xF5, 0x51, 0x91, 0x74, 0xB1, 0xF0, 0x08, 0x17, 0x86, 0x47, 0x18, 0x1F, 0x4D, 0x6F, 0x3F, - 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x4E, 0x06, 0x46, 0xB3, 0x89, 0x90, 0xC8, - 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, - 0xFC, 0x77, 0xC3, 0x5E, 0xFC, 0x9C, 0x31, 0xC7, 0x6E, 0x1B, 0x08, 0xBE, 0x7C, 0x01, 0x00, 0x00, - 0x7A, 0x8F, 0xD9, 0x63, 0x0F, 0x5B, 0x32, 0x2E, 0x5A, 0x4D, 0x84, 0x47, 0x64, 0xC9, 0x6E, 0x3F, - 0x2A, 0xF1, 0xD1, 0xFE, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, - 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xFE, 0xDD, 0x32, 0xDE, 0x84, 0x05, 0x00, - 0x00, 0x7A, 0x99, 0x19, 0xE9, 0x9F, 0x6D, 0x76, 0xCF, 0xB3, 0xC1, 0xA0, 0x02, 0xA3, 0xD9, 0x74, - 0x74, 0xF8, 0x4B, 0x7C, 0xFB, 0x31, 0xD3, 0x9C, 0x09, 0xE3, 0xA3, 0xAD, 0xDB, 0x0F, 0x11, 0x12, - 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xFE, 0x2E, 0x9B, 0x77, 0xE2, 0xF6, 0xC1, 0xE0, 0x4B, 0x18, 0x00, 0x00, 0xA0, 0xB7, 0xD8, - 0x00, 0x19, 0x48, 0xFF, 0x06, 0x2C, 0x11, 0x1D, 0xB1, 0xA9, 0xDB, 0x8F, 0x6A, 0x80, 0x84, 0xF1, - 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, - 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7F, 0xB7, 0xCD, 0x3B, 0xFA, 0x85, 0xD1, 0xE0, 0x4B, - 0x18, 0x00, 0x00, 0xA0, 0xB7, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0x3E, 0x60, 0xA3, 0x41, 0x85, - 0x86, 0x9A, 0x0E, 0x8E, 0xEA, 0x12, 0xDC, 0x7E, 0x4C, 0x3C, 0x31, 0xD3, 0x4C, 0x3C, 0x16, 0xB9, - 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0xFB, 0xC4, 0x47, 0x65, 0x22, 0x1C, 0xF2, 0x98, 0x0C, 0x87, 0x3C, - 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0xB0, 0xDF, 0x95, 0x3B, 0x76, 0x0B, 0x6F, - 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xC9, 0x1B, 0x59, 0xB1, 0xA1, 0x3E, 0x32, 0x1A, 0x4D, 0x04, 0x47, - 0x7C, 0xF1, 0x00, 0xA9, 0x7B, 0xF6, 0xC3, 0xC6, 0x47, 0xB3, 0xDB, 0x8F, 0x6F, 0xA8, 0xD0, 0x50, - 0x13, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, - 0x14, 0x35, 0x71, 0xC8, 0xEF, 0xE6, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xAB, 0xBC, 0x7D, 0x57, - 0x24, 0x7C, 0x03, 0x96, 0x88, 0x8D, 0xE8, 0x6C, 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, - 0x47, 0xE4, 0x5B, 0xAF, 0x06, 0x6D, 0x7C, 0x44, 0x6F, 0x3F, 0xEC, 0x6A, 0x6E, 0x3F, 0x36, 0x24, - 0xBD, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, - 0x54, 0x24, 0x14, 0x35, 0x71, 0xC0, 0xEF, 0xF6, 0x8D, 0x2D, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0xA0, - 0x37, 0x79, 0x7B, 0x2F, 0x1B, 0xAF, 0x8F, 0x8D, 0xF8, 0x62, 0xB1, 0xA1, 0x16, 0x0D, 0x10, 0xBB, - 0xEA, 0xB7, 0x5E, 0x85, 0x01, 0x62, 0xE3, 0x63, 0xF2, 0xF6, 0x63, 0x66, 0x1B, 0xB7, 0x1F, 0x22, - 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, - 0x26, 0x0E, 0xF7, 0xBD, 0xB0, 0x17, 0xAF, 0x31, 0xDE, 0x2F, 0x6E, 0xBF, 0x2B, 0xF8, 0x32, 0x06, - 0x00, 0x00, 0xE8, 0x1D, 0xAD, 0xDF, 0x80, 0x15, 0x0B, 0x0D, 0xB5, 0x58, 0x7C, 0x84, 0xB7, 0x1F, - 0x93, 0x0F, 0x9E, 0xDB, 0xF8, 0x88, 0xDF, 0x7E, 0x84, 0xF1, 0x11, 0x06, 0x48, 0xA2, 0xDB, 0x0F, - 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, - 0x51, 0x13, 0x07, 0xFB, 0x1E, 0x9A, 0x77, 0xFC, 0x8E, 0x0D, 0xC1, 0x97, 0x31, 0x00, 0x00, 0x40, - 0x6F, 0xF0, 0xDF, 0x80, 0xB5, 0x73, 0xB6, 0x8D, 0x08, 0x15, 0x1E, 0x6E, 0xB1, 0xD0, 0x50, 0x6B, - 0x10, 0x1F, 0xD5, 0x07, 0xCF, 0x37, 0xCE, 0xAC, 0xBF, 0xFD, 0x08, 0xE2, 0xA3, 0x7A, 0xFB, 0xF1, - 0xA0, 0xDD, 0xD7, 0x55, 0x70, 0x44, 0x27, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, - 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0x50, 0xDF, 0x4B, 0xF3, 0x8E, 0xDE, 0xCA, - 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x31, 0x23, 0xCB, 0xD7, 0x35, 0x7E, 0x05, 0x6F, 0x2C, 0x34, - 0x1A, 0x4D, 0x05, 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x41, 0x7C, 0xC8, 0x37, - 0x5F, 0x7D, 0xB7, 0xD5, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, - 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7D, 0xAF, 0xCD, 0x3B, 0xFA, 0xF9, 0xF1, - 0xE0, 0x4B, 0x19, 0x00, 0x00, 0xA0, 0x37, 0xD8, 0x00, 0x59, 0x5F, 0x1F, 0x1E, 0x29, 0xE2, 0xC3, - 0x2D, 0x1E, 0x1F, 0xD5, 0xDB, 0x8F, 0xC9, 0xF8, 0xA8, 0x79, 0xF3, 0x55, 0xEA, 0xDB, 0x0F, 0x11, - 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, - 0xD3, 0x87, 0xF9, 0x9E, 0x9C, 0x7B, 0x13, 0xD6, 0xD8, 0x17, 0x67, 0x05, 0x5F, 0xCE, 0x00, 0x00, - 0x00, 0xDD, 0xCF, 0x3B, 0x70, 0xD5, 0x50, 0xBB, 0xF1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0xD4, 0xDD, - 0x7E, 0x5C, 0x98, 0xE1, 0xF6, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, - 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBE, 0x97, 0x37, 0xB6, 0x9C, 0x37, 0x61, - 0x01, 0x00, 0x80, 0xDE, 0xE2, 0xED, 0xBD, 0x7C, 0x2C, 0x73, 0x7C, 0xB8, 0xC5, 0xE3, 0xC3, 0x0F, - 0x90, 0x19, 0x39, 0xDD, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, - 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xC0, 0xF7, 0xFA, 0x78, 0x13, 0x16, 0x00, 0x00, - 0xE8, 0x35, 0x66, 0x68, 0x81, 0x0D, 0x89, 0xEC, 0xF1, 0xE1, 0x7E, 0xAC, 0xBD, 0xFD, 0xB0, 0xF1, - 0x11, 0xFB, 0xF6, 0xAB, 0xA6, 0xB7, 0x1F, 0xF7, 0x35, 0xBA, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, - 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x78, 0x2F, - 0xC3, 0x9E, 0xBF, 0x9C, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, 0x61, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, - 0x2E, 0xB5, 0x11, 0x91, 0x21, 0x3E, 0xDC, 0xC2, 0xF0, 0x08, 0xE3, 0xE3, 0xE9, 0x19, 0x35, 0xB7, - 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xF1, 0x80, 0x1D, 0xF1, 0x91, 0xCF, 0x64, 0x38, 0xE4, 0x31, - 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x07, 0xF7, 0x12, 0xCD, 0x3B, 0xFE, 0x67, 0xBC, - 0x09, 0x0B, 0x00, 0x00, 0xF4, 0x06, 0xFF, 0x15, 0xBC, 0xFE, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, - 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, 0xF1, 0xD1, 0xE0, 0xD9, 0x0F, 0xF9, 0xA1, 0x83, 0xF7, - 0xAA, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, - 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x87, 0xF6, 0x32, 0xCD, 0x3B, 0xFA, 0xF9, 0x93, 0xC1, 0x97, 0x34, - 0x00, 0x00, 0x40, 0x77, 0xF3, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0xF5, 0x71, 0x91, 0x64, 0x61, 0x78, - 0x84, 0xF1, 0x11, 0xBB, 0xFD, 0xA8, 0x7B, 0xF6, 0xC3, 0x06, 0xC8, 0x29, 0x17, 0x20, 0x4D, 0x6F, - 0x3F, 0x44, 0x48, 0x64, 0x99, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, - 0x09, 0x45, 0x4D, 0x1F, 0xD8, 0x4B, 0xB7, 0x23, 0xAB, 0x4C, 0xF0, 0x25, 0x0D, 0x00, 0x00, 0xD0, - 0xDD, 0xBC, 0xE1, 0x65, 0x83, 0x32, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0x12, 0x20, 0x33, - 0xF4, 0xED, 0x47, 0x2C, 0x3E, 0x5A, 0xDF, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, - 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA8, 0x97, 0x75, 0x63, 0xCB, - 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0D, 0xDE, 0xDE, 0xCB, 0x46, 0xEB, 0xE2, 0x22, 0xC9, 0xAA, - 0xB7, 0x1F, 0x41, 0x7C, 0x24, 0xBD, 0xFD, 0x08, 0x03, 0xE4, 0x07, 0x76, 0xC4, 0x47, 0x7B, 0x93, - 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0xBA, 0x7F, - 0x5D, 0x68, 0xCC, 0x0B, 0x57, 0x1B, 0x73, 0xFC, 0x8E, 0x75, 0xC1, 0x97, 0x35, 0x00, 0x00, 0x40, - 0xF7, 0xF2, 0xF6, 0x2C, 0x18, 0x97, 0x81, 0xD1, 0x6C, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0x59, 0x6F, - 0x3F, 0xEE, 0x89, 0xDE, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, - 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2E, 0x3E, 0xDC, 0x7E, 0x6E, - 0xFF, 0x99, 0x38, 0x71, 0xDB, 0xFA, 0xE0, 0xCB, 0x1A, 0x00, 0x00, 0xA0, 0x3B, 0x99, 0xA1, 0xFE, - 0x59, 0x66, 0xF7, 0xDC, 0xFA, 0xC0, 0x68, 0xB5, 0xF0, 0xE6, 0x23, 0x97, 0xDB, 0x0F, 0x11, 0x12, - 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xF4, 0xB2, 0x2E, 0x8C, 0x8F, 0x60, 0xDE, 0x89, 0xDB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, - 0x6E, 0x66, 0x64, 0xE9, 0x80, 0xD9, 0xF1, 0x71, 0x1D, 0x19, 0xCD, 0x16, 0xC6, 0x47, 0xDB, 0xB7, - 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, - 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x5D, 0x2C, 0x3E, 0xFC, 0x00, 0x39, 0x7A, 0x33, 0x6F, 0xC2, - 0x02, 0x00, 0x00, 0xDD, 0xCD, 0x1B, 0x5E, 0x7E, 0x97, 0xD9, 0xFA, 0x21, 0x1D, 0x19, 0x8D, 0x16, - 0x8F, 0x8F, 0x66, 0xB7, 0x1F, 0x61, 0x7C, 0xC8, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, - 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, - 0xC4, 0x87, 0xBF, 0x23, 0x37, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xDD, 0xFC, 0x57, 0xF0, 0xAA, - 0xC8, 0x68, 0x34, 0x1B, 0x1D, 0x8D, 0x6E, 0x3F, 0xAA, 0x01, 0xD2, 0xEA, 0xF6, 0xE3, 0x1B, 0xC4, - 0x47, 0xA6, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, - 0x65, 0x9D, 0x0A, 0x8F, 0x70, 0x2F, 0xF5, 0xBB, 0x07, 0xD1, 0x97, 0x04, 0x5F, 0xDE, 0x00, 0x00, - 0x00, 0xDD, 0xC7, 0x3B, 0x70, 0x75, 0xF2, 0x37, 0x60, 0x45, 0xE3, 0xC3, 0x86, 0x47, 0xA3, 0xDB, - 0x8F, 0x09, 0x17, 0x20, 0x8F, 0x45, 0x6E, 0x3F, 0xC2, 0xF8, 0x70, 0xDB, 0xE0, 0xBE, 0xF5, 0x4A, - 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, - 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xD1, 0x11, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x3F, 0x5F, 0x1B, - 0x7C, 0x79, 0x03, 0x00, 0x00, 0x74, 0x1F, 0x6F, 0xDF, 0xE5, 0x27, 0x65, 0x6C, 0xC4, 0x17, 0xC4, - 0x47, 0xA3, 0xDB, 0x8F, 0xC4, 0xCF, 0x7E, 0x7C, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, - 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xC1, - 0x11, 0x1F, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xDD, 0x2E, 0xD1, 0x1B, 0xB0, 0xE2, 0xF1, 0x51, 0x73, - 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xED, 0xED, 0x47, 0x4E, 0xDF, 0x7A, 0x25, - 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, - 0xB2, 0x4E, 0xC5, 0x46, 0x83, 0x79, 0xC7, 0x6F, 0x1F, 0x0A, 0xBE, 0xBC, 0x01, 0x00, 0x00, 0xBA, - 0x8B, 0x39, 0x70, 0xFD, 0x12, 0xB3, 0xF3, 0x53, 0x3A, 0x3A, 0xC2, 0x45, 0xE2, 0xA3, 0x1A, 0x20, - 0x76, 0xD5, 0x6F, 0xBD, 0x0A, 0x03, 0xA4, 0xE6, 0xB5, 0xBB, 0x33, 0xC5, 0xED, 0xC7, 0xCC, 0x7C, - 0x6E, 0x3F, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, - 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0xC8, 0x68, 0x36, 0xEF, 0xC8, 0x9A, 0xB1, 0xE0, 0x4B, 0x1C, 0x00, - 0x00, 0xA0, 0xBB, 0x98, 0x83, 0xCB, 0xD6, 0x9A, 0xED, 0x1F, 0xD5, 0xE1, 0xE1, 0x16, 0x09, 0x8F, - 0x68, 0x7C, 0x84, 0xB7, 0x1F, 0x35, 0x0F, 0x9E, 0x37, 0x7A, 0xF6, 0xC3, 0x0F, 0x10, 0x1B, 0x1F, - 0xDF, 0xCD, 0xE1, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, - 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x08, 0x8C, 0x96, 0x3B, 0xBA, 0x86, 0x37, 0x61, 0x01, - 0x00, 0x80, 0xEE, 0xE4, 0xBF, 0x01, 0x6B, 0xF3, 0xAC, 0x4C, 0xF1, 0x51, 0x7D, 0xF0, 0x5C, 0xDD, - 0x7E, 0x04, 0xF1, 0x51, 0xB9, 0xFD, 0xB0, 0xF1, 0xF1, 0xA0, 0xDD, 0xD7, 0x45, 0x50, 0xA4, 0x99, - 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, - 0xCB, 0x3A, 0x15, 0x17, 0x49, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB7, 0xF2, 0x0E, 0x7C, 0x6E, - 0x28, 0x49, 0x7C, 0xD4, 0x05, 0x48, 0xFC, 0xB5, 0xBB, 0xEE, 0xF6, 0x23, 0x88, 0x8F, 0xDA, 0x37, - 0x5F, 0xD9, 0xF0, 0xC8, 0xE3, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x0A, 0x8B, 0xA4, 0x7B, 0xE1, 0x5A, 0x63, - 0x8E, 0xDD, 0x36, 0x10, 0x7C, 0x99, 0x03, 0x00, 0x00, 0x74, 0x0F, 0x6F, 0xEF, 0x65, 0xF5, 0xAF, - 0xE0, 0x8D, 0x44, 0x87, 0x8C, 0x8F, 0xE8, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0xAA, 0xDE, - 0x7E, 0x04, 0xF1, 0xD1, 0xEE, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, - 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x15, 0x69, 0xF6, 0xFC, 0x67, 0x79, - 0x13, 0x16, 0x00, 0x00, 0xE8, 0x4E, 0x66, 0x8F, 0x3D, 0xEC, 0xB4, 0x88, 0x0F, 0x37, 0x75, 0xFB, - 0x51, 0x7D, 0xED, 0x6E, 0xF5, 0xF6, 0xE3, 0xC2, 0xC8, 0xED, 0x47, 0x10, 0x1F, 0xED, 0xDE, 0x7E, - 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x62, 0x07, - 0xF4, 0x32, 0x4F, 0x05, 0x45, 0x86, 0x79, 0x27, 0x6E, 0x1B, 0x0C, 0xBE, 0xCC, 0x01, 0x00, 0x00, - 0xBA, 0x83, 0x19, 0xE9, 0x9F, 0x5D, 0xF3, 0x0A, 0xDE, 0x48, 0x70, 0x44, 0x97, 0xFE, 0xF6, 0x63, - 0xE6, 0x64, 0x80, 0x3C, 0x60, 0xA7, 0xC2, 0x22, 0xC9, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, - 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0x90, 0xC8, 0x3A, 0xEF, - 0xC8, 0xE7, 0x47, 0x83, 0x2F, 0x75, 0x00, 0x00, 0x80, 0xEE, 0x60, 0x46, 0x96, 0x0E, 0x54, 0xDF, - 0x80, 0x15, 0x09, 0x8E, 0xF8, 0xD4, 0xED, 0x47, 0xFD, 0xB3, 0x1F, 0xE1, 0xED, 0x47, 0x24, 0x3E, - 0xDC, 0xEE, 0xCD, 0x78, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, - 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x44, 0x44, 0x5B, 0xE3, 0x4D, 0x58, 0x00, 0x00, - 0xA0, 0xDB, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0xDE, 0x2F, 0xA3, 0x23, 0x5C, 0xB3, 0xDB, 0x8F, - 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0xC8, 0x7A, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, - 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x05, 0x44, 0xBB, 0x73, 0x6F, - 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x3B, 0x00, 0x00, 0x40, 0xE7, 0x79, 0x23, 0xCB, 0x36, - 0xA8, 0xE8, 0x88, 0x4E, 0xDD, 0x7E, 0xD4, 0x3F, 0xFB, 0xE1, 0x3E, 0x74, 0xD0, 0xBD, 0x7A, 0x37, - 0x12, 0x20, 0xEE, 0x43, 0x07, 0xB3, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, - 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xF1, 0x90, 0xC7, 0x5E, 0xBC, - 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, 0xEE, 0xE2, 0xED, 0xBD, 0x62, 0x54, 0x45, 0x47, 0xB8, 0x66, - 0xB7, 0x1F, 0xD5, 0x67, 0x3F, 0xFC, 0xD7, 0xEE, 0x06, 0xF1, 0xE1, 0xD6, 0xCE, 0xED, 0x87, 0x08, - 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, - 0x3A, 0x15, 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x2E, 0xDE, 0xDE, - 0xC5, 0xE3, 0x2A, 0x3C, 0xC2, 0x35, 0xBD, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC5, 0x87, 0xBA, 0xFD, - 0xB8, 0x27, 0xE5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, - 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x0D, 0x39, 0xCF, 0x3B, 0xB6, 0x96, 0x37, 0x61, - 0x01, 0x00, 0x80, 0xEE, 0xE1, 0xBF, 0x01, 0x2B, 0x12, 0x1C, 0xD1, 0xB5, 0xBC, 0xFD, 0xB0, 0xF1, - 0x31, 0xF1, 0xD8, 0x8C, 0xDA, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x60, 0xA7, 0x22, 0xA3, 0xD1, 0x44, - 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, - 0xD6, 0x89, 0x58, 0x28, 0x62, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0E, 0xFE, - 0x1B, 0xB0, 0x76, 0x7C, 0x52, 0xC6, 0x87, 0x5B, 0xCB, 0xDB, 0x8F, 0x30, 0x3E, 0xDA, 0xBD, 0xFD, - 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, - 0x7A, 0x59, 0x27, 0x42, 0xA1, 0xA8, 0x79, 0x47, 0x6F, 0x1E, 0x0F, 0xBE, 0xE4, 0x01, 0x00, 0x00, - 0x3A, 0xCB, 0x8C, 0x2C, 0x5F, 0x67, 0xB6, 0x7D, 0xA4, 0x75, 0x7C, 0xC8, 0xDB, 0x8F, 0x19, 0xF9, - 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, - 0xC4, 0x21, 0xBD, 0xAC, 0x13, 0x91, 0x50, 0xE8, 0xDC, 0x9B, 0xB0, 0xC6, 0xBE, 0x38, 0x2B, 0xF8, - 0xB2, 0x07, 0x00, 0x00, 0xE8, 0x1C, 0x1B, 0x20, 0xEB, 0x55, 0x7C, 0xB8, 0xA9, 0xDB, 0x0F, 0x3F, - 0x40, 0x44, 0x7C, 0x64, 0xBE, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, - 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA1, 0xE8, 0xF1, 0x26, 0x2C, 0x00, - 0x00, 0xD0, 0x2D, 0xBC, 0x03, 0x57, 0x0D, 0x35, 0x8C, 0x0F, 0x1B, 0x1E, 0xF2, 0xF6, 0xE3, 0x09, - 0x1B, 0x1F, 0x2E, 0x40, 0x1E, 0x8D, 0xDC, 0x7E, 0x84, 0xF1, 0xE1, 0xB6, 0x81, 0xF8, 0xA8, 0x9B, - 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xA9, - 0x38, 0x98, 0x8A, 0xBD, 0x70, 0xB5, 0xF1, 0x7E, 0x71, 0xFB, 0x5D, 0xC1, 0x97, 0x3D, 0x00, 0x00, - 0x40, 0xE7, 0x78, 0x7B, 0x2F, 0x1B, 0x6B, 0x18, 0x20, 0x6E, 0x91, 0xDB, 0x0F, 0x17, 0x1F, 0x67, - 0x07, 0x67, 0xD4, 0xDE, 0x7E, 0xA8, 0x67, 0x3F, 0xBE, 0x21, 0x62, 0x23, 0x3E, 0x11, 0x1E, 0x6E, - 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2A, - 0x0C, 0xA6, 0x70, 0xDE, 0xF1, 0xDB, 0x36, 0x04, 0x5F, 0xF6, 0x00, 0x00, 0x00, 0x9D, 0x63, 0x86, - 0xE6, 0xEB, 0xF8, 0xA8, 0xB9, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC6, 0x47, 0x1E, 0xB7, 0x1F, 0x22, - 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, - 0xEB, 0x44, 0x10, 0x4C, 0xF5, 0xBC, 0xE3, 0x7F, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x67, 0x99, - 0x91, 0xFE, 0xD9, 0x66, 0xE7, 0x25, 0x3A, 0x40, 0xEC, 0xA2, 0xDF, 0x7A, 0x75, 0xEE, 0xC9, 0x19, - 0xE6, 0xAC, 0x8D, 0x8F, 0xC9, 0xDB, 0x8F, 0x19, 0xFA, 0xD9, 0x8F, 0x56, 0xB7, 0x1F, 0x22, 0x3C, - 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, - 0x44, 0x0C, 0x74, 0x62, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x74, 0x9C, 0xFF, 0x0A, 0xDE, 0xD8, 0x1B, - 0xB0, 0x6A, 0xBE, 0xF5, 0xCA, 0xEE, 0x9C, 0x0B, 0x10, 0x17, 0x1F, 0xF1, 0xDB, 0x8F, 0x68, 0x7C, - 0x84, 0x01, 0x72, 0x7F, 0x8B, 0xDB, 0x0F, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, - 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x22, 0x04, 0x3A, 0xB6, 0x97, 0x56, 0x99, - 0xE0, 0x4B, 0x1F, 0x00, 0x00, 0xA0, 0x33, 0xFC, 0x37, 0x60, 0x6D, 0xFE, 0xE3, 0x86, 0xF1, 0x51, - 0xB9, 0xFD, 0xB0, 0xF1, 0xD1, 0xE0, 0xF6, 0xC3, 0xC5, 0x47, 0xF5, 0xF6, 0xE3, 0x41, 0xBB, 0xAF, - 0x8B, 0xE8, 0x08, 0x27, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, - 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x45, 0x40, 0x27, 0x37, 0xB6, 0x8C, 0x37, 0x61, 0x01, 0x00, - 0x80, 0xCE, 0xF2, 0x86, 0x97, 0x0D, 0x36, 0xBC, 0xFD, 0x08, 0xE2, 0xA3, 0xE6, 0xF6, 0x23, 0x88, - 0x8F, 0x9A, 0xDB, 0x8F, 0xF0, 0xD9, 0x8F, 0xEF, 0x36, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, - 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA0, - 0xD3, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0xF2, 0x07, 0x00, 0x00, 0x98, 0x7A, - 0xDE, 0xDE, 0xCB, 0x46, 0x1B, 0xDE, 0x7E, 0x6C, 0xBC, 0xA0, 0x26, 0x3E, 0xEA, 0x3E, 0x74, 0x30, - 0xE9, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, - 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x75, 0xF8, 0xEF, 0xF8, 0x16, 0xD8, 0x5F, 0x9B, 0xFD, 0xDF, 0xE1, - 0xC4, 0x6D, 0xEB, 0x83, 0x2F, 0x7F, 0x00, 0x00, 0x80, 0xA9, 0xE7, 0xED, 0x9E, 0x3F, 0xAE, 0x6F, - 0x3F, 0x6C, 0x7C, 0x84, 0xDF, 0x7A, 0x55, 0x73, 0xFB, 0x31, 0x33, 0xDD, 0xED, 0x87, 0x08, 0x0F, - 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0xB1, 0x78, 0x20, 0x14, 0x39, 0x71, 0x48, 0x2F, 0xEB, - 0xE4, 0xE1, 0xBF, 0xD3, 0xB3, 0xF1, 0x11, 0xCC, 0x3B, 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x80, - 0xCE, 0x30, 0x43, 0xFD, 0xB3, 0xCC, 0xEE, 0xB9, 0x32, 0x3E, 0x72, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, - 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, - 0x0F, 0xFF, 0x9D, 0xDE, 0x64, 0x7C, 0xF8, 0x01, 0x72, 0xF4, 0xE6, 0x93, 0xC1, 0x1F, 0x01, 0x00, - 0x00, 0x00, 0x53, 0xCB, 0x7F, 0x03, 0xD6, 0xF6, 0x8B, 0x6B, 0x03, 0x24, 0x8C, 0x0F, 0xF9, 0xEC, - 0x47, 0x83, 0xDB, 0x8F, 0x7B, 0xC5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, - 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x6A, 0xE3, - 0xC3, 0xDF, 0x91, 0x1B, 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0C, 0x33, 0xB2, 0x7C, 0x9D, 0xD9, - 0xFA, 0xC1, 0xC8, 0xED, 0x87, 0x8D, 0x8F, 0xD8, 0xED, 0x47, 0xED, 0x9B, 0xAF, 0x44, 0x7C, 0x3C, - 0x60, 0x47, 0x7C, 0x14, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, - 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x11, 0x1F, 0x6E, 0x2F, 0xF5, 0xF3, 0x26, 0x2C, 0x00, 0x00, 0xD0, - 0x19, 0xE6, 0xE0, 0xF2, 0xF5, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xEC, 0xC7, - 0xE9, 0x78, 0x80, 0xB8, 0x0F, 0x1D, 0x8C, 0xDF, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, - 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, - 0x84, 0x47, 0x38, 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x00, 0x00, 0x00, 0x60, - 0xEA, 0x78, 0xFB, 0xAE, 0x1E, 0xAD, 0x89, 0x8F, 0x24, 0xCF, 0x7E, 0xB8, 0x35, 0xBA, 0xFD, 0x10, - 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, - 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x88, 0x8E, 0xE8, 0xDC, 0x3F, 0x67, 0xBC, 0x09, 0x0B, 0x00, - 0x00, 0x74, 0x82, 0xB7, 0xF7, 0xF2, 0x93, 0x7E, 0x7C, 0x34, 0xBA, 0xFD, 0x88, 0xC6, 0x87, 0xBA, - 0xFD, 0xF8, 0x76, 0xE4, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, - 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x38, 0xC4, 0xBC, - 0xE3, 0xB7, 0x0F, 0x05, 0x7F, 0x0C, 0x00, 0x00, 0x00, 0x4C, 0x1D, 0x6F, 0xE7, 0x9C, 0xF4, 0xB7, - 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x8E, 0xF8, 0xC8, 0x71, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, - 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x36, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, - 0x82, 0x3F, 0x06, 0x00, 0x00, 0x00, 0xA6, 0x86, 0x39, 0x70, 0xFD, 0x12, 0x6F, 0xFB, 0x27, 0xB2, - 0xDF, 0x7E, 0xDC, 0x13, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, - 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x87, 0x46, 0xC3, - 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xD5, 0xCC, 0xC1, 0x65, 0x6B, 0xBD, 0xAD, 0x1F, 0x6E, 0xEF, - 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, - 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x30, 0x5A, 0xCD, 0xBD, 0x09, 0xEB, 0xF8, - 0x1D, 0x4B, 0x82, 0x3F, 0x0E, 0x00, 0x00, 0x00, 0x8A, 0x77, 0xFE, 0xE0, 0xD2, 0xF5, 0xDE, 0xA6, - 0x0B, 0x33, 0xDE, 0x7E, 0x10, 0x1F, 0xF9, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, - 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC4, 0x45, 0x92, 0xBD, 0x70, 0x0D, 0x6F, 0xC2, - 0x02, 0x00, 0x00, 0x53, 0xEB, 0xFC, 0xFE, 0x6B, 0x06, 0xB3, 0xDD, 0x7E, 0xCC, 0x90, 0xE1, 0xE1, - 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, - 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x8B, 0xA4, 0x7B, 0xFE, 0x0A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xA6, - 0xD6, 0xF9, 0xDD, 0x8B, 0x47, 0xA3, 0xB7, 0x1F, 0xD5, 0x00, 0x89, 0xC5, 0x47, 0xDD, 0xED, 0xC7, - 0xDD, 0xC4, 0x47, 0xFB, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, - 0xE4, 0xE1, 0xBF, 0xD3, 0x13, 0x51, 0x91, 0x72, 0xDE, 0xB1, 0xB5, 0xBC, 0x09, 0x0B, 0x00, 0x00, - 0x4C, 0x1D, 0x6F, 0xF7, 0x42, 0x79, 0xFB, 0x31, 0xE1, 0x02, 0xE4, 0xD1, 0xC8, 0xED, 0x47, 0x18, - 0x1F, 0x6E, 0xF7, 0xEB, 0x6F, 0xBD, 0x22, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, - 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x07, 0x45, 0xDA, 0x79, 0x47, 0x3E, - 0x3F, 0x1A, 0xFC, 0x71, 0x00, 0x00, 0x00, 0x50, 0x2C, 0x33, 0xD2, 0x3F, 0xDB, 0xDB, 0x31, 0x27, - 0xDD, 0xB3, 0x1F, 0x0F, 0xCE, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, - 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x98, 0xC8, 0xB4, 0xA3, - 0x6B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x1A, 0x66, 0xFF, 0xD2, 0x81, 0xF3, 0x5B, 0x3E, 0x6C, - 0x03, 0x24, 0xF2, 0xAD, 0x57, 0xCD, 0x6E, 0x3F, 0x1E, 0xB2, 0xF1, 0x21, 0x6E, 0x3F, 0x88, 0x8F, - 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, - 0xD3, 0x13, 0x11, 0xD1, 0xCE, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0x73, 0x76, 0xF0, 0xC7, 0x02, 0x00, - 0x00, 0x40, 0x71, 0xCE, 0xED, 0x5F, 0x7A, 0xD7, 0xF9, 0x4D, 0xEF, 0x9B, 0x7C, 0xF6, 0xA3, 0xE6, - 0xC1, 0xF3, 0x19, 0xB5, 0xCF, 0x7E, 0xB8, 0xF8, 0x78, 0xA0, 0xFE, 0xF6, 0x83, 0xF8, 0x48, 0x33, - 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, - 0x11, 0x10, 0xED, 0xCE, 0xBD, 0x09, 0xEB, 0xD8, 0x6D, 0x03, 0xC1, 0x1F, 0x0B, 0x00, 0x00, 0x00, - 0xC5, 0x39, 0x7F, 0x60, 0xD9, 0x86, 0x9A, 0x07, 0xCF, 0xA3, 0xB7, 0x1F, 0xD1, 0xF8, 0x78, 0xD8, - 0x86, 0x87, 0x0B, 0x90, 0xEF, 0xD4, 0xDE, 0x7E, 0x10, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x21, 0x8F, 0xF1, - 0x26, 0x2C, 0x00, 0x00, 0x30, 0x55, 0xCE, 0xEF, 0x5E, 0x32, 0xEA, 0xC7, 0x47, 0x83, 0xDB, 0x0F, - 0x17, 0x1F, 0xA7, 0xC2, 0xF8, 0x70, 0xB7, 0x1F, 0x7F, 0x4D, 0x7C, 0x64, 0x9B, 0x0A, 0x87, 0x3C, - 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x87, 0x1C, - 0xE7, 0x9D, 0xB8, 0x6D, 0x30, 0xF8, 0x63, 0x01, 0x00, 0x00, 0xA0, 0x38, 0xE7, 0x76, 0x2E, 0x3A, - 0x59, 0x73, 0xFB, 0x11, 0xC4, 0x47, 0xF5, 0xD9, 0x8F, 0x30, 0x3E, 0x62, 0xB7, 0x1F, 0xC4, 0x47, - 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, - 0xE9, 0xE9, 0x68, 0xC8, 0x73, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0xDE, 0xF9, - 0xED, 0x73, 0xAA, 0xF1, 0x51, 0xF7, 0xA1, 0x83, 0x8F, 0xCC, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, - 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, - 0xE9, 0x60, 0xC8, 0x7D, 0x47, 0x3F, 0xCF, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB1, 0xCE, 0xEE, 0x5F, - 0x3A, 0x70, 0x6E, 0xCB, 0x27, 0x63, 0xB7, 0x1F, 0x33, 0x2B, 0xCF, 0x7E, 0x44, 0xE3, 0xC3, 0xED, - 0xDE, 0xCA, 0xED, 0x07, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, - 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x14, 0x8A, 0x9A, 0x7B, 0x13, 0xD6, 0xD8, 0x17, - 0x67, 0x05, 0x7F, 0x3C, 0x00, 0x00, 0x00, 0xE4, 0xEF, 0xDC, 0xDE, 0xE5, 0xEB, 0xCE, 0x6D, 0xFA, - 0x48, 0xEC, 0xF6, 0x63, 0x46, 0x35, 0x3E, 0xAA, 0x01, 0xF2, 0x23, 0x3B, 0xE2, 0x23, 0xE5, 0x54, - 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x44, - 0x24, 0x14, 0xB9, 0x17, 0xAF, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x58, 0xE7, 0xF7, 0x2E, 0x5F, - 0x5F, 0xF7, 0xEC, 0xC7, 0x8F, 0x27, 0x03, 0xA4, 0x7A, 0xFB, 0xF1, 0xED, 0x0B, 0x88, 0x8F, 0x54, - 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, - 0x13, 0x81, 0x50, 0xF4, 0x5E, 0xB8, 0xCA, 0x78, 0xBF, 0xB8, 0xFD, 0xAE, 0xE0, 0x8F, 0x07, 0x00, - 0x00, 0x80, 0xFC, 0x9D, 0xDB, 0x7D, 0xD5, 0x50, 0xCD, 0x9B, 0xAF, 0xC2, 0xF8, 0x88, 0x06, 0xC8, - 0x8F, 0x66, 0x10, 0x1F, 0xA9, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, - 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x60, 0x8A, 0xE6, 0x1D, 0xBF, 0x6D, 0x43, 0xF0, 0xC7, - 0x03, 0x00, 0x00, 0x40, 0xFE, 0xCE, 0xED, 0xB8, 0x6C, 0x6C, 0xF2, 0xF6, 0xE3, 0x02, 0x79, 0xFB, - 0xF1, 0x76, 0xE4, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x06, 0x53, 0x35, 0xDE, 0x84, 0x05, 0x00, - 0x00, 0x0A, 0x75, 0x76, 0xDB, 0xFC, 0xE0, 0xF6, 0xC3, 0xC6, 0x87, 0x78, 0xF6, 0xE3, 0xED, 0x1F, - 0x4C, 0xDE, 0x7E, 0x10, 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, - 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0xA3, 0x60, 0x2A, 0xE7, 0x1D, 0xBD, 0x79, 0x3C, 0xF8, - 0xE3, 0x01, 0x00, 0x00, 0x20, 0x5F, 0x66, 0xA8, 0x7F, 0xF6, 0xD9, 0xCD, 0x97, 0x04, 0xF1, 0x51, - 0x7B, 0xFB, 0x71, 0x2A, 0xBC, 0xFD, 0xF8, 0x66, 0xE5, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, - 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x04, - 0x53, 0xBE, 0x97, 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x8C, 0xB3, 0x43, 0x4B, 0x07, 0xDE, - 0xDD, 0xF8, 0xE1, 0x6A, 0x80, 0x9C, 0xB6, 0x01, 0x52, 0xF3, 0xEC, 0xC7, 0xF7, 0x2B, 0xB7, 0x1F, - 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, - 0xF0, 0xDF, 0xE9, 0x89, 0x10, 0xE8, 0xD4, 0xC6, 0x96, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x0C, - 0x1B, 0x20, 0xEB, 0x27, 0x06, 0xDF, 0x57, 0x73, 0xFB, 0x11, 0x7D, 0xFE, 0xC3, 0xDD, 0x7E, 0x10, - 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, - 0x7F, 0xA7, 0x27, 0x22, 0xA0, 0x93, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0x63, - 0x02, 0x00, 0x00, 0x20, 0x3F, 0xEF, 0xEE, 0x59, 0x3A, 0xE8, 0xDF, 0x7E, 0x88, 0xF8, 0x70, 0xB7, - 0x1F, 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, - 0xF2, 0xF0, 0xDF, 0xE9, 0x89, 0x00, 0xE8, 0xF4, 0xDC, 0x3F, 0x17, 0x27, 0x6E, 0x5B, 0x1F, 0xFC, - 0x31, 0x01, 0x00, 0x00, 0x90, 0x9F, 0x89, 0x6D, 0x8B, 0x47, 0xEB, 0xDE, 0x7C, 0x15, 0xDE, 0x7E, - 0xDC, 0x4D, 0x7C, 0x34, 0x9F, 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xE9, 0x65, - 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xE2, 0xF0, 0xDF, 0x25, 0xF3, 0x8E, 0xAF, 0xE5, 0x4D, 0x58, 0x00, - 0x00, 0x20, 0x7F, 0x13, 0x5B, 0xFA, 0xC6, 0xE5, 0xC3, 0xE7, 0xF7, 0xBB, 0x6F, 0xBD, 0x22, 0x3E, - 0x1A, 0x4F, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, - 0x4E, 0x4F, 0x1F, 0xFC, 0xBB, 0x65, 0xDE, 0xD1, 0x9B, 0x4F, 0x06, 0x7F, 0x4C, 0x00, 0x00, 0x00, - 0xE4, 0xC3, 0x0C, 0xF5, 0xCF, 0x7A, 0xF7, 0x99, 0x39, 0x95, 0xF8, 0xB0, 0x8B, 0x3E, 0x7C, 0xFE, - 0xD6, 0x5F, 0x11, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, - 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFD, 0x5D, 0xB5, 0x97, 0x56, 0x9A, 0xE0, 0x8F, 0x0A, - 0x00, 0x00, 0x80, 0x7C, 0xB8, 0x37, 0x60, 0x4D, 0x6C, 0xFC, 0x98, 0x0D, 0x90, 0x0B, 0xCC, 0xE9, - 0x47, 0xEC, 0xDC, 0xED, 0x87, 0x0B, 0x90, 0xFB, 0x6D, 0x80, 0x10, 0x1F, 0x0D, 0xA6, 0xC2, 0x21, - 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xFB, - 0xDD, 0x38, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x7C, 0xDD, 0xC4, 0x13, 0x1F, - 0x30, 0xA7, 0xFD, 0x00, 0x09, 0xBE, 0xFD, 0xEA, 0xE1, 0x99, 0xFE, 0xED, 0x07, 0xF1, 0xA1, 0xA6, - 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, - 0x0E, 0xFA, 0xDD, 0x3A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x74, 0x7D, 0x78, - 0xFB, 0x71, 0xCA, 0xCD, 0xDD, 0x7E, 0x7C, 0x67, 0x06, 0xF1, 0x21, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF9, 0xDD, 0x3C, - 0xF7, 0xCF, 0x3D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x79, 0x9A, 0xD8, 0x79, 0xD5, 0x68, 0xF5, 0xDB, - 0xAF, 0xDC, 0x0D, 0x88, 0x7B, 0xF6, 0xE3, 0x6B, 0xC4, 0x47, 0xFD, 0x54, 0x38, 0xE4, 0x31, 0x15, - 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, 0x01, 0xBF, 0x07, 0xC6, - 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xAE, 0x26, 0xB6, 0x5D, 0x76, 0xB2, 0x7A, 0x03, 0xF2, 0xF0, 0x0C, - 0xF3, 0xF6, 0x7D, 0xC1, 0xED, 0x87, 0x8D, 0x8F, 0x3F, 0x10, 0x1F, 0xC1, 0x54, 0x38, 0xE4, 0x31, - 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0xE1, 0xBE, 0x17, - 0xE6, 0x1D, 0x59, 0x33, 0x16, 0xFC, 0x71, 0x01, 0x00, 0x00, 0xD0, 0xBE, 0x09, 0xFF, 0x0D, 0x58, - 0x93, 0xB7, 0x1F, 0x6F, 0x7E, 0x6D, 0xF2, 0xE6, 0xE3, 0x0D, 0xE2, 0xC3, 0x4E, 0x85, 0x43, 0x1E, - 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xEC, 0x7B, - 0x66, 0x47, 0x6E, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x20, 0x1F, 0x13, 0x43, 0xD7, 0x2F, 0x99, 0x78, - 0xFA, 0x13, 0xE6, 0xCC, 0xA3, 0x95, 0xCF, 0xFF, 0x70, 0xB7, 0x1F, 0x95, 0xF8, 0xB8, 0xC0, 0xBF, - 0xF9, 0x78, 0x83, 0xF8, 0x28, 0x68, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, - 0xDF, 0xE9, 0x89, 0x03, 0x7D, 0xAF, 0xED, 0xA5, 0x7E, 0xF7, 0x20, 0xFA, 0x92, 0xE0, 0x8F, 0x0D, - 0x00, 0x00, 0x80, 0xEC, 0xCE, 0x0C, 0x2D, 0x5B, 0x3B, 0xF1, 0xE4, 0x87, 0x2B, 0x9F, 0x01, 0xF2, - 0x60, 0xE5, 0xB5, 0xBB, 0xD5, 0xDB, 0x8F, 0xAF, 0xD9, 0xF8, 0xF8, 0x47, 0xE2, 0x23, 0xFF, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF3, 0xBD, 0x38, - 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x03, 0x00, 0x00, 0x20, 0x3B, 0xF7, 0x06, - 0xAC, 0x89, 0xC7, 0x2F, 0xF2, 0x03, 0xE4, 0xED, 0x6F, 0x55, 0x9E, 0xFB, 0x20, 0x3E, 0xDC, 0x54, - 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, - 0x41, 0xBE, 0x57, 0xE7, 0xBE, 0x26, 0x78, 0x13, 0x16, 0x00, 0x00, 0xC8, 0xC3, 0xD9, 0x5D, 0xD7, - 0x0C, 0x4E, 0x3C, 0x36, 0xC3, 0x9C, 0x71, 0xCF, 0x7E, 0x04, 0x6F, 0xBD, 0xFA, 0xC3, 0x7A, 0xE2, - 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, - 0xF1, 0x3D, 0xBB, 0xF9, 0xFE, 0xBC, 0xE3, 0xB7, 0x0D, 0x05, 0x7F, 0x6C, 0x00, 0x00, 0x00, 0x64, - 0xF7, 0xEE, 0xB6, 0xC5, 0xA3, 0x13, 0x8F, 0xCF, 0x30, 0xEF, 0x7C, 0xBB, 0x72, 0xFB, 0xF1, 0xE6, - 0x5F, 0x5D, 0x44, 0x7C, 0x14, 0x32, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, - 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x57, 0x89, 0x0F, 0x3F, 0x40, 0x8E, 0xDC, 0xCC, 0x9B, 0xB0, - 0x00, 0x00, 0x40, 0xFB, 0xCE, 0x6D, 0x5F, 0x60, 0x26, 0x1E, 0xB9, 0xC0, 0xBC, 0xE5, 0x5E, 0xBB, - 0xFB, 0xD7, 0xC4, 0x47, 0x31, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, - 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0xE1, 0xEF, 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, - 0x00, 0xB4, 0xC7, 0x0C, 0x5D, 0x3B, 0xFB, 0xDC, 0xB6, 0x4B, 0xCD, 0x3B, 0xDF, 0xB4, 0x01, 0xF2, - 0x75, 0xE2, 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, - 0xA7, 0x0E, 0xF1, 0xBD, 0xBA, 0x58, 0x7C, 0xB8, 0xBD, 0xB4, 0xC2, 0x98, 0x97, 0xBF, 0x38, 0x3B, - 0xF8, 0xE3, 0x03, 0x00, 0x00, 0x20, 0xBD, 0xB3, 0xFB, 0x97, 0x0E, 0xBC, 0xFB, 0xD8, 0x87, 0xCC, - 0xDB, 0x77, 0x5F, 0x64, 0xCE, 0x13, 0x1F, 0x05, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, - 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x89, 0xF8, 0x70, 0x7B, 0xE1, 0x6A, 0x63, - 0x8E, 0xDD, 0x36, 0x10, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDE, 0x99, 0x5D, 0x9F, 0xBB, 0xEB, - 0xD4, 0x86, 0x0F, 0x98, 0xF3, 0xFF, 0x44, 0x7C, 0xE4, 0x3F, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, - 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x27, 0xC2, 0x23, 0x98, 0xF7, 0xAF, - 0x4B, 0xCC, 0xE9, 0x9F, 0xDD, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x76, 0xAF, 0x3D, 0x70, 0xED, - 0x86, 0xF1, 0xDD, 0xAB, 0xCD, 0xD9, 0x17, 0xBF, 0x44, 0x7C, 0xE4, 0x3A, 0x15, 0x09, 0x45, 0x4D, - 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0xA7, 0xC3, 0xC3, 0xED, - 0xD4, 0xB3, 0xF3, 0xCC, 0xEF, 0x77, 0xCC, 0x31, 0xBF, 0xDB, 0x77, 0xD3, 0x60, 0xF0, 0xC7, 0x07, - 0x00, 0x00, 0x40, 0x7A, 0xAF, 0xEF, 0xB9, 0x75, 0xF8, 0xF7, 0x07, 0x6F, 0x35, 0xBF, 0xDF, 0xB7, - 0xD2, 0xBC, 0x79, 0xE0, 0x32, 0x73, 0xFE, 0x9F, 0x55, 0x54, 0x24, 0x9D, 0x08, 0x87, 0x3C, 0x26, - 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, - 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0x4E, 0x87, 0xC7, 0x99, 0xBF, 0xEB, 0x33, 0xE3, 0xBB, - 0xE6, 0x9A, 0xDF, 0x6D, 0xB3, 0xF1, 0xE1, 0xB6, 0x67, 0x39, 0xAF, 0xE2, 0x05, 0x00, 0x00, 0xD9, - 0xFD, 0xF3, 0xFF, 0xFE, 0x17, 0x17, 0xFE, 0x76, 0xFB, 0xEA, 0xFB, 0x7E, 0xB7, 0x6D, 0xF1, 0x5B, - 0xBF, 0xDF, 0xB9, 0xD8, 0xB8, 0xBD, 0x7D, 0xE8, 0x72, 0xFF, 0x5B, 0x2D, 0x74, 0x64, 0x34, 0x9A, - 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, - 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0xAE, 0x3E, 0x3C, 0xCE, 0xFE, - 0x43, 0x9F, 0x79, 0x73, 0xEF, 0x64, 0x78, 0xBC, 0xBE, 0x75, 0xCE, 0xF8, 0xEF, 0xB6, 0x5D, 0xBA, - 0x7E, 0xB4, 0xFF, 0x3D, 0x7F, 0x14, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDD, 0x7F, 0xBF, 0xFB, - 0x33, 0x17, 0xBF, 0xB6, 0x79, 0xF1, 0x96, 0x30, 0x42, 0xC6, 0x77, 0x2F, 0x36, 0xA7, 0xFF, 0xC6, - 0x1E, 0xD4, 0x65, 0x6C, 0xC4, 0x27, 0xC2, 0x21, 0x8F, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, 0xDF, - 0xAB, 0xAB, 0x0D, 0x8F, 0xF3, 0xFF, 0x34, 0xDF, 0xBC, 0xB5, 0x3F, 0x72, 0xE3, 0x61, 0xF7, 0xEA, - 0x33, 0x73, 0x7E, 0x34, 0x3E, 0xF4, 0xA9, 0x59, 0xC1, 0x1F, 0x17, 0x00, 0x00, 0x00, 0xF9, 0xF9, - 0xEF, 0xDF, 0x5D, 0xF2, 0x99, 0xD7, 0xB6, 0x2C, 0xFA, 0x59, 0x18, 0x22, 0x6F, 0xEC, 0xB9, 0xCC, - 0x4C, 0xFC, 0xBD, 0x0B, 0x02, 0x15, 0x1E, 0x6E, 0xB1, 0x68, 0xC8, 0x6B, 0x32, 0x1C, 0xF2, 0x98, - 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, - 0x3A, 0xC4, 0xF7, 0xEA, 0x26, 0xC3, 0xC3, 0xFB, 0xE7, 0xF9, 0xE6, 0x9D, 0x91, 0x79, 0x35, 0xE1, - 0xF1, 0xDA, 0xE6, 0x4B, 0xF7, 0x8F, 0x6F, 0xE9, 0xE3, 0xB5, 0xBB, 0x00, 0x00, 0xA0, 0x78, 0xFF, - 0xEB, 0xA1, 0xCB, 0xBE, 0xF8, 0xBB, 0x6D, 0x8B, 0x7E, 0x19, 0x86, 0x88, 0x7B, 0x3E, 0xE4, 0xEC, - 0x4F, 0x5D, 0x1C, 0x10, 0x1F, 0xF5, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, - 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0x51, 0x7D, 0xC0, 0x3C, 0x08, 0x8F, 0xD7, - 0xB7, 0x5E, 0x3A, 0xF6, 0xDA, 0x96, 0x4B, 0x79, 0xDD, 0x2E, 0x00, 0x00, 0x98, 0x5A, 0xA3, 0xFD, - 0xFD, 0x7F, 0xF4, 0xAB, 0x27, 0x2E, 0xFB, 0x3F, 0xA2, 0xCF, 0x87, 0xBC, 0x35, 0xEC, 0x1E, 0x54, - 0x17, 0xD1, 0x90, 0xD7, 0x64, 0x38, 0xE4, 0x31, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x55, 0xC2, 0x23, 0xFE, - 0x80, 0xB9, 0x8D, 0x8E, 0x5F, 0xBE, 0xBE, 0x7D, 0xEE, 0xBA, 0xE0, 0x8F, 0x00, 0x00, 0x00, 0x80, - 0xCE, 0xF8, 0xD5, 0x23, 0x57, 0x7E, 0xE0, 0x37, 0x4F, 0x2E, 0xDE, 0x30, 0x19, 0x22, 0x8B, 0xCC, - 0xE9, 0xBF, 0xB9, 0xCC, 0x78, 0xFF, 0x2A, 0x02, 0xA2, 0x9D, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, - 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, - 0xDF, 0xAB, 0x6B, 0xFC, 0x80, 0x39, 0xCF, 0x79, 0x00, 0x00, 0x80, 0xAE, 0x72, 0xF2, 0x91, 0xC5, - 0xF3, 0x5F, 0x7D, 0x66, 0xF1, 0x0E, 0x17, 0x20, 0x6E, 0xE3, 0xBB, 0x17, 0x99, 0x33, 0x7F, 0x67, - 0x0F, 0xE2, 0x2A, 0x26, 0xD2, 0x4E, 0x86, 0x43, 0x1E, 0x8B, 0x47, 0x43, 0x5E, 0x53, 0x91, 0x50, - 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x73, 0xEA, 0x01, - 0xF3, 0xDF, 0x6D, 0xBD, 0x74, 0xF0, 0xBF, 0x7D, 0x67, 0xDE, 0x07, 0x82, 0x2F, 0x73, 0x00, 0x00, - 0x80, 0xEE, 0xF3, 0xAB, 0x8D, 0x8B, 0xD6, 0xBC, 0xFA, 0xCC, 0xC2, 0x9F, 0x87, 0x21, 0xF2, 0xC6, - 0x9E, 0xC5, 0xE6, 0xDD, 0x7F, 0xB0, 0x87, 0x7D, 0x15, 0x16, 0x49, 0x26, 0xC3, 0x21, 0x8F, 0xA9, - 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, - 0x83, 0x7C, 0xAF, 0xCD, 0xFB, 0xE7, 0x05, 0x75, 0x0F, 0x98, 0xDB, 0x8D, 0xFE, 0x7F, 0x8F, 0x5E, - 0x3A, 0x27, 0xF8, 0xB2, 0x06, 0x00, 0x00, 0xE8, 0x6E, 0xFE, 0xF3, 0x21, 0x83, 0x8B, 0xFF, 0xE2, - 0x77, 0xDB, 0x16, 0xFE, 0x32, 0x0C, 0x91, 0x37, 0x0F, 0x2C, 0x36, 0x67, 0x7F, 0x6A, 0x0F, 0xFE, - 0x2A, 0x32, 0x1A, 0x4D, 0x86, 0x43, 0x1E, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, - 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x87, 0xF9, 0x5E, 0xDB, 0xE9, 0xBF, 0xE9, 0xAB, - 0x79, 0xC0, 0xFC, 0xB5, 0x67, 0xE6, 0x1C, 0xE3, 0x01, 0x73, 0x00, 0x00, 0xD0, 0xB3, 0x6C, 0x88, - 0xFC, 0xBB, 0x57, 0x37, 0x2F, 0xBA, 0xE7, 0x77, 0xDB, 0x16, 0xBD, 0x15, 0x86, 0xC8, 0xDB, 0x87, - 0x12, 0x3E, 0xA8, 0x2E, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, - 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xC3, 0x7C, 0x2F, 0x6D, 0xE2, 0xEF, 0xE7, 0xF3, - 0x80, 0x39, 0x00, 0x00, 0x28, 0xAF, 0x93, 0xF7, 0x2E, 0xFC, 0xC8, 0x2B, 0x9B, 0x16, 0x3F, 0x1A, - 0x46, 0x88, 0x7B, 0x3E, 0xA4, 0xE9, 0x83, 0xEA, 0x32, 0x1C, 0xF2, 0x98, 0x0A, 0x87, 0x3C, 0xA6, - 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x3E, 0xD0, 0xF7, 0xCA, - 0xCE, 0xFE, 0xC3, 0x7C, 0xF3, 0xE6, 0x5E, 0xF7, 0xED, 0x56, 0x95, 0xF8, 0xE0, 0x01, 0x73, 0x00, - 0x00, 0x50, 0x6A, 0xFF, 0xE3, 0xFE, 0xCF, 0x2C, 0x7A, 0x75, 0xF3, 0xA2, 0xE7, 0xA2, 0x21, 0x32, - 0xF1, 0xF7, 0x36, 0x0C, 0x88, 0x8F, 0x84, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, - 0x7D, 0xA8, 0xEF, 0x85, 0x9D, 0xFF, 0xA7, 0x05, 0xE6, 0xED, 0x83, 0x7D, 0x41, 0x78, 0x04, 0x37, - 0x1F, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0xA6, 0x8B, 0x5F, 0x3E, 0xB6, 0xF8, 0x96, 0xD7, 0xB7, 0x2E, - 0x7C, 0x39, 0x0C, 0x11, 0xF7, 0xA0, 0xBA, 0xFF, 0x7C, 0x88, 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, - 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xF6, - 0xDD, 0x3E, 0xF7, 0x80, 0xF9, 0xA9, 0x67, 0xA3, 0xE1, 0xE1, 0xC7, 0x07, 0x0F, 0x98, 0x03, 0x00, - 0x80, 0xE9, 0xC7, 0x3D, 0xA8, 0xFE, 0xDB, 0xA7, 0x17, 0x7F, 0xF5, 0xF5, 0xAD, 0x8B, 0x7E, 0xE3, - 0x22, 0xE4, 0x77, 0x3B, 0x16, 0x9A, 0x37, 0xF7, 0x2F, 0x32, 0xE7, 0xFE, 0xD1, 0x1D, 0xEC, 0x55, - 0x44, 0x64, 0x5D, 0x3C, 0x1A, 0xF2, 0x9A, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, - 0xFC, 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xED, 0xAB, 0x3C, 0x60, 0x3E, 0x19, 0x1E, 0xAF, 0x3D, 0x33, - 0x97, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x7E, 0xF5, 0xC8, 0xBC, 0x0F, 0xFC, 0xE6, 0xE9, 0x85, 0xF7, - 0xBD, 0xBE, 0x75, 0xC1, 0x5B, 0x2E, 0x42, 0xDC, 0xDE, 0x1E, 0x59, 0x6C, 0xBC, 0x7F, 0x51, 0x31, - 0x91, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, - 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xCD, 0xAB, 0x3C, 0x60, 0x1E, 0x3E, 0xE7, 0x61, 0xC3, 0x63, 0xCB, - 0x5C, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x88, 0x1B, 0xFB, 0x4F, 0x9F, 0xB9, 0xF8, 0x95, 0xCD, 0x0B, - 0xB7, 0x84, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCD, 0xA9, 0xE7, 0xDA, 0x09, 0x11, 0x15, 0x0E, 0x79, - 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC0, 0xEF, - 0xD6, 0xD5, 0x3E, 0x60, 0x3E, 0xD7, 0xBC, 0xBE, 0x75, 0xEE, 0xB8, 0xFD, 0x91, 0x07, 0xCC, 0x01, - 0x00, 0x00, 0x9A, 0xF9, 0x9F, 0x0F, 0x2D, 0x5A, 0xFA, 0xEA, 0xE6, 0x85, 0x3F, 0x0B, 0x43, 0x64, - 0x7C, 0x68, 0x91, 0x39, 0x33, 0xEA, 0x0E, 0xFE, 0x2A, 0x32, 0x1A, 0x2D, 0x1E, 0x0D, 0x79, 0x4D, - 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC8, 0xEF, 0xC6, - 0xD5, 0x3F, 0x60, 0x6E, 0xB7, 0x75, 0x0E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA4, 0xF1, 0xBF, 0x1E, - 0x5A, 0xF0, 0xC5, 0xD7, 0xB6, 0x2E, 0xF8, 0x65, 0x18, 0x22, 0x6F, 0xEC, 0x5D, 0x64, 0xCE, 0xFE, - 0xC4, 0x45, 0x80, 0x0A, 0x8E, 0xE8, 0xE2, 0xD1, 0x90, 0xD7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, - 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x07, 0xFD, 0x6E, 0x9B, 0x7E, 0xC0, 0x7C, 0x2E, 0x0F, - 0x98, 0x03, 0x00, 0x00, 0x64, 0xE5, 0x1E, 0x54, 0xFF, 0xF5, 0xC6, 0x45, 0x7F, 0x19, 0x7D, 0x3E, - 0xC4, 0x3D, 0xA8, 0x7E, 0xFE, 0x67, 0x2A, 0x3C, 0xDC, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, - 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0x61, 0xBF, 0xDB, 0xC6, 0x03, 0xE6, - 0x00, 0x00, 0x00, 0x05, 0x72, 0x0F, 0xAA, 0xFF, 0xFA, 0xC9, 0x85, 0x1B, 0xC2, 0x08, 0x71, 0x7B, - 0xE7, 0x70, 0xFC, 0xF9, 0x10, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, - 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xD8, 0xEF, 0xA6, 0xF1, 0x80, 0x39, 0x00, 0x00, 0xC0, 0x14, - 0x3A, 0xF9, 0xC8, 0xE2, 0xF9, 0xBF, 0xDD, 0xB4, 0x60, 0x47, 0x18, 0x21, 0xE1, 0x83, 0xEA, 0x3A, - 0x1C, 0xF2, 0x58, 0x3C, 0x10, 0x8A, 0x9C, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, - 0x03, 0x7F, 0xB7, 0x8C, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x3A, 0xE8, 0x57, 0x1B, 0x17, 0xAD, 0x79, - 0x65, 0xD3, 0x82, 0x9F, 0x57, 0x42, 0x64, 0x81, 0x19, 0x1F, 0x5A, 0x68, 0xCE, 0x8C, 0xBA, 0x43, - 0xBC, 0x8A, 0x88, 0xAC, 0x8B, 0x07, 0x42, 0x91, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, - 0x3D, 0x7D, 0xE8, 0xEF, 0x86, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x40, 0x97, 0xA8, 0x7C, 0x90, 0xE1, - 0xC2, 0xAF, 0xBE, 0xB6, 0x75, 0xFE, 0x2F, 0x5D, 0x84, 0xB8, 0xBD, 0xB9, 0x7F, 0xA1, 0x39, 0xFB, - 0x13, 0x77, 0xA0, 0x57, 0x41, 0x91, 0x66, 0xF1, 0x40, 0x28, 0x72, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, - 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFE, 0x9D, 0x5E, 0xA3, 0x07, 0xCC, 0x4F, 0x7E, 0xE7, 0x53, 0xF3, - 0x83, 0x2F, 0x01, 0x00, 0x00, 0x00, 0x74, 0xC2, 0x60, 0xFF, 0xA7, 0xFE, 0xDD, 0xAB, 0x9B, 0x16, - 0xDC, 0xF3, 0xFA, 0xD6, 0xF9, 0x6F, 0x85, 0x21, 0xF2, 0xF6, 0x88, 0x7B, 0x50, 0x5D, 0x85, 0x45, - 0x92, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFF, - 0x9D, 0x9E, 0x7A, 0xC0, 0xFC, 0xB7, 0x1B, 0xE7, 0xDE, 0x10, 0xFC, 0x23, 0x0F, 0x00, 0x00, 0x80, - 0x6E, 0xF0, 0xFF, 0x7E, 0x63, 0xF1, 0x87, 0x7F, 0xF3, 0xD4, 0x82, 0x47, 0xC3, 0x08, 0x71, 0x3B, - 0xF5, 0xDC, 0x22, 0xE3, 0xFD, 0x8B, 0x8A, 0x8C, 0x46, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, - 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xFE, 0x3B, 0xB9, 0xF8, 0x03, 0xE6, 0xEE, 0x39, 0x8F, - 0x57, 0x9F, 0xBE, 0xF4, 0x3F, 0x06, 0xFF, 0x88, 0x03, 0x00, 0x00, 0xA0, 0x1B, 0xFD, 0x8F, 0xFB, - 0x17, 0x2C, 0x7A, 0x75, 0xF3, 0x82, 0x9F, 0x85, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCC, 0xE9, 0xBF, - 0x75, 0x07, 0x61, 0x15, 0x1C, 0xD1, 0xA9, 0x48, 0x28, 0x6A, 0xB1, 0x03, 0x7A, 0x99, 0x27, 0x0F, - 0xFF, 0x9D, 0x9E, 0x0E, 0x80, 0x4E, 0xAD, 0xEE, 0x01, 0xF3, 0xCD, 0x73, 0xDE, 0xB2, 0x3F, 0xF2, - 0x80, 0x39, 0x00, 0x00, 0x40, 0x2F, 0xF9, 0xE5, 0xC3, 0xF3, 0x6F, 0x79, 0x75, 0xCB, 0x82, 0x97, - 0xC3, 0x10, 0x71, 0x0F, 0xAA, 0x4F, 0xFC, 0x57, 0x77, 0xF8, 0x27, 0x3E, 0xA6, 0x6C, 0xF2, 0xF0, - 0xDF, 0xE9, 0xE9, 0x08, 0xE8, 0xC4, 0x1A, 0x3D, 0x60, 0x3E, 0xBE, 0xA5, 0x6F, 0x76, 0xF0, 0x8F, - 0x31, 0x00, 0x00, 0x00, 0x7A, 0x49, 0xF8, 0xA0, 0x7A, 0xF4, 0xF9, 0x10, 0xF7, 0xA0, 0xFA, 0xB9, - 0x7F, 0x74, 0x21, 0x40, 0x7C, 0x14, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x74, 0x08, 0x4C, 0xF5, 0x1A, - 0x3D, 0x60, 0xFE, 0xEB, 0xC7, 0x3E, 0x7D, 0x55, 0xF0, 0x8F, 0x2E, 0x00, 0x00, 0x00, 0x7A, 0x99, - 0xFB, 0x20, 0xC3, 0xDF, 0x6C, 0x9C, 0x7F, 0x5F, 0xED, 0x83, 0xEA, 0x0B, 0xCD, 0xF9, 0x9F, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x63, 0x60, 0xAA, 0x17, - 0x7F, 0xC0, 0xFC, 0xF5, 0x6D, 0x73, 0x4E, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x40, 0x49, 0xFD, 0xDB, - 0x83, 0x7D, 0x7D, 0xAF, 0x6C, 0x5E, 0xB0, 0xA5, 0x12, 0x21, 0xF3, 0xCD, 0xEF, 0x77, 0xCD, 0x37, - 0xA7, 0x9E, 0x5B, 0x68, 0xBC, 0x7F, 0x51, 0xC1, 0x90, 0xE7, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, - 0xFF, 0x4E, 0x4F, 0xC7, 0xC0, 0x54, 0x8E, 0x07, 0xCC, 0x01, 0x00, 0x00, 0xA6, 0xB1, 0xFF, 0xF9, - 0xD0, 0xBC, 0xA5, 0xAF, 0x6E, 0xEE, 0xFB, 0x99, 0x8B, 0x90, 0x30, 0x44, 0xCE, 0x8C, 0xBA, 0x03, - 0xB4, 0x8A, 0x87, 0x76, 0x17, 0x3B, 0xA0, 0x97, 0x79, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x20, 0x98, - 0xAA, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xAA, 0x7E, 0xF5, 0x58, 0xDF, 0x5F, 0x54, 0x3E, 0xC8, - 0xB0, 0x12, 0x22, 0xE3, 0x43, 0xF6, 0xC0, 0xF8, 0x13, 0x77, 0x98, 0x56, 0x21, 0x91, 0x65, 0xB1, - 0x03, 0x7A, 0x99, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x82, 0xA9, 0x18, 0x0F, 0x98, 0x03, 0x00, - 0x00, 0x40, 0x72, 0x0F, 0xAA, 0xFF, 0x7A, 0x63, 0xDF, 0x5F, 0xBE, 0xBE, 0xB5, 0xEF, 0xAD, 0x30, - 0x44, 0xDE, 0xDC, 0x6F, 0x0F, 0x90, 0x6D, 0x3F, 0x1F, 0x22, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, - 0x77, 0x7A, 0x3A, 0x0C, 0x8A, 0x1E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x20, 0x11, 0xFF, 0x41, 0xF5, - 0xA7, 0xFA, 0x1E, 0x0D, 0x23, 0xC4, 0xCD, 0x3D, 0xA8, 0x9E, 0xED, 0xF9, 0x10, 0x71, 0x48, 0x2F, - 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x71, 0x50, 0xF4, 0xCE, 0xFC, 0xDD, 0x7C, 0x1E, 0x30, 0x07, - 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x41, 0xF5, 0x57, 0x9F, 0x99, 0x3F, 0x12, 0x46, 0x48, 0xFA, 0x07, - 0xD5, 0xC5, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x41, 0x91, 0x73, 0xCF, 0x79, - 0xF0, 0x80, 0x39, 0x00, 0x00, 0x00, 0xDA, 0xF2, 0xAB, 0x27, 0xFA, 0xD6, 0x44, 0x1F, 0x54, 0x77, - 0xCF, 0x87, 0xB4, 0x7E, 0x50, 0x3D, 0x76, 0x40, 0x2F, 0xF3, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x81, - 0x50, 0xD4, 0xCE, 0xFD, 0x94, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x90, 0xA3, 0xCA, 0x07, 0x19, 0xF6, - 0x7D, 0x35, 0xFA, 0xA0, 0xBA, 0x7B, 0x3E, 0x44, 0x3F, 0xA8, 0x1E, 0x3B, 0xA0, 0x97, 0x79, 0xF2, - 0xF0, 0xDF, 0xE9, 0xE9, 0x48, 0x28, 0x62, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x42, 0xB9, 0xE7, - 0x43, 0x5E, 0xDD, 0xD4, 0x77, 0x4F, 0xF4, 0x41, 0xF5, 0xB7, 0x0E, 0x46, 0x1F, 0x54, 0x17, 0x87, - 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0A, 0x79, 0x2F, 0x7C, 0xC0, 0x3C, 0xFA, 0x9C, - 0x87, 0x1D, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA0, 0x18, 0x47, 0xBF, 0xB1, 0xF8, 0xC3, 0xAF, 0x6C, - 0xEE, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0x3B, 0x87, 0xEC, 0xC1, 0xF4, 0x5F, 0xC4, 0x41, 0xBD, 0x8C, - 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x42, 0xDE, 0x53, 0x0F, 0x98, 0xFF, 0xFA, 0xE1, 0x4B, 0x6F, - 0x0E, 0xFE, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xE3, 0x3F, 0xA8, 0xEE, 0x9E, 0x0F, 0xD9, 0xDE, - 0x67, 0xDC, 0x7E, 0xBF, 0xB3, 0xCF, 0x9C, 0x7A, 0xCE, 0x1E, 0x54, 0xD5, 0xA1, 0xBD, 0x2C, 0x93, - 0x87, 0xFF, 0x4E, 0xAF, 0x3E, 0x14, 0xF2, 0x9E, 0x7A, 0xC0, 0xFC, 0xD7, 0x83, 0x73, 0xFE, 0xB7, - 0xE0, 0x1F, 0x05, 0x00, 0x00, 0x00, 0x60, 0xEA, 0xFC, 0xF2, 0xE1, 0xB9, 0xB7, 0xBC, 0xB6, 0xB5, - 0xEF, 0x97, 0x61, 0x88, 0x8C, 0xEF, 0x9E, 0x6F, 0x26, 0xFE, 0xAB, 0x3D, 0x18, 0xAB, 0x03, 0x7C, - 0x2F, 0x4F, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0C, 0x79, 0x4D, 0x3D, 0x60, 0xFE, 0xDA, 0xA6, 0x39, - 0x77, 0xF3, 0x80, 0x39, 0x00, 0x00, 0x00, 0x3A, 0xCA, 0x7F, 0x50, 0xFD, 0xC9, 0xBE, 0xAF, 0xBE, - 0xBE, 0x65, 0xDE, 0x5B, 0x61, 0x88, 0xBC, 0xB9, 0x6F, 0xBE, 0x39, 0xFB, 0x13, 0x7B, 0x48, 0x56, - 0x87, 0xF9, 0x5E, 0x9B, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x1A, 0xF2, 0x98, 0x7A, 0xC0, 0xFC, 0xD5, - 0xCD, 0x73, 0x37, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xBA, 0x8A, 0x7B, 0x50, 0xFD, 0xB7, 0x9B, - 0xFA, 0xEE, 0x09, 0x23, 0xC4, 0xED, 0xED, 0x61, 0xF7, 0xA0, 0xBA, 0x38, 0xD4, 0xF7, 0xCA, 0xE4, - 0xE1, 0xBF, 0xD3, 0xD3, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0x3D, 0xC9, 0x3D, - 0x1F, 0xF2, 0xCA, 0xA6, 0xBE, 0x2D, 0xD1, 0x10, 0x71, 0xCF, 0x87, 0xF4, 0xDC, 0x83, 0xEA, 0xF2, - 0xF0, 0xDF, 0xE9, 0xE9, 0x78, 0x68, 0x77, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x9E, 0x57, 0xF9, - 0x20, 0xC3, 0x79, 0x35, 0x0F, 0xAA, 0x9F, 0xFE, 0x5B, 0x7B, 0xE0, 0x55, 0x87, 0xFD, 0x6E, 0x9B, - 0x3C, 0xFC, 0x77, 0x7A, 0xF5, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xA5, 0xF3, - 0xAB, 0xC7, 0xFA, 0xFE, 0x22, 0xFE, 0xA0, 0x7A, 0x57, 0x3F, 0x1F, 0x22, 0x0F, 0xFF, 0x9D, 0x9E, - 0x0E, 0x88, 0xAC, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0x94, 0x9A, 0x7B, 0x50, 0xFD, 0xB5, 0x2D, - 0xF3, 0xBE, 0x1E, 0x7F, 0x50, 0xFD, 0xDC, 0x3F, 0xDA, 0xC3, 0xB5, 0x8A, 0x80, 0x4E, 0x4D, 0x1E, - 0xFE, 0x3B, 0x3D, 0x1D, 0x11, 0x59, 0xC6, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x98, 0x56, 0xDC, 0x83, - 0xEA, 0xBF, 0x79, 0xAA, 0xEF, 0xC7, 0x61, 0x84, 0xB8, 0x75, 0xCD, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, - 0xE9, 0xE9, 0x90, 0x48, 0xBB, 0x46, 0x0F, 0x98, 0xBF, 0xB6, 0xE5, 0xD2, 0x81, 0xE0, 0x7F, 0x1A, - 0x00, 0x00, 0x00, 0xA0, 0xBC, 0xFC, 0x0F, 0x32, 0xDC, 0xD4, 0x37, 0x12, 0x46, 0x48, 0xF8, 0x41, - 0x86, 0x1D, 0x7B, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x13, 0x69, 0xA7, 0x1E, 0x30, 0x7F, - 0xE5, 0xC9, 0x39, 0xB7, 0x07, 0xFF, 0x53, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x87, 0x7B, 0x50, 0xFD, - 0xB5, 0x2D, 0xF3, 0x8E, 0x85, 0x21, 0xE2, 0x9E, 0x0F, 0x39, 0x33, 0x6A, 0x0F, 0xDF, 0x2A, 0x12, - 0x8A, 0x9A, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x26, 0xD2, 0x4C, 0x3D, 0x60, 0xFE, 0xCA, 0xA6, 0xB9, - 0xFF, 0x57, 0xF0, 0xB7, 0x1E, 0x00, 0x00, 0x00, 0x98, 0x9E, 0xC2, 0x0F, 0x32, 0x8C, 0x3E, 0xA8, - 0xFE, 0xC6, 0x9E, 0x29, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x14, 0x49, 0x17, 0x7F, - 0xC0, 0xDC, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x98, 0xF0, 0x83, 0x0C, 0xE3, 0x0F, 0xAA, - 0x17, 0xF6, 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2A, 0x92, 0x8C, 0x07, 0xCC, 0x01, 0x00, - 0x00, 0x80, 0x0C, 0x5E, 0x79, 0x72, 0xCE, 0xA5, 0xF1, 0x0F, 0x32, 0x74, 0x0F, 0xAA, 0xE7, 0xFA, - 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2C, 0x5A, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, - 0x1C, 0xFC, 0x7A, 0x63, 0xDF, 0x55, 0xAF, 0x6E, 0x9E, 0xF7, 0x4F, 0x61, 0x84, 0x84, 0x0F, 0xAA, - 0xCB, 0xA0, 0x48, 0x33, 0x79, 0xF8, 0xEF, 0xF4, 0xEA, 0xC3, 0x22, 0xC9, 0x78, 0xC0, 0x1C, 0x00, - 0x00, 0x00, 0xC8, 0xD9, 0x2F, 0x1F, 0x9E, 0x7B, 0x4B, 0xFC, 0x83, 0x0C, 0x33, 0x3F, 0xA8, 0x2E, - 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x8B, 0x66, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, 0x40, 0xFE, - 0x07, 0x19, 0x6E, 0xEE, 0xFB, 0x3F, 0xE3, 0xCF, 0x87, 0xA4, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, - 0x3D, 0x1D, 0x18, 0x8D, 0xA6, 0x1E, 0x30, 0xFF, 0xED, 0xC6, 0x4B, 0xBF, 0xC5, 0x03, 0xE6, 0x00, - 0x00, 0x00, 0x40, 0x01, 0xC2, 0x07, 0xD5, 0xC3, 0x08, 0x71, 0x7B, 0xEB, 0x40, 0x82, 0x07, 0xD5, - 0xE5, 0xE1, 0xBF, 0xD3, 0xD3, 0x91, 0xA1, 0xE6, 0x9E, 0xF3, 0x88, 0x3F, 0x60, 0xFE, 0xCA, 0x53, - 0x73, 0xB6, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x00, 0x30, 0x05, 0xDC, 0x07, 0x19, 0xBE, 0xBE, 0x75, - 0xDE, 0xFE, 0x68, 0x88, 0xBC, 0x73, 0xA8, 0xC1, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xD0, - 0x88, 0x4F, 0x3D, 0x60, 0xFE, 0xDA, 0xE6, 0x39, 0x3F, 0xE1, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, - 0x03, 0xDC, 0x07, 0x19, 0xC6, 0x1F, 0x54, 0x3F, 0xFD, 0xB7, 0xF6, 0xF0, 0x5E, 0x82, 0xF8, 0x70, - 0x0F, 0x98, 0xD7, 0x3C, 0xE7, 0xC1, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x40, 0x77, 0x88, 0x7F, 0x90, - 0xE1, 0xF8, 0xEE, 0x3E, 0x33, 0xF1, 0xF7, 0xEE, 0x20, 0xAF, 0x02, 0xA0, 0x93, 0xAB, 0x0F, 0x8D, - 0xF8, 0xDC, 0x03, 0xE6, 0x6F, 0x0C, 0xD5, 0x3F, 0x60, 0x3E, 0xDA, 0xFF, 0x9E, 0x3F, 0x0A, 0x7E, - 0xBB, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xCD, 0x7F, 0x50, 0x7D, 0xCB, 0xBC, 0xAF, 0x57, 0x1E, 0x54, - 0xB7, 0x07, 0x78, 0xBB, 0x37, 0xF7, 0xF5, 0xD9, 0x03, 0xBD, 0x3B, 0xD8, 0xAB, 0x18, 0x98, 0xEA, - 0xD5, 0xC7, 0x46, 0x74, 0xEE, 0x83, 0x04, 0x79, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xE8, 0x31, 0xEE, - 0x41, 0xF5, 0x57, 0x36, 0xCD, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0xDB, 0xC3, 0xF3, 0xED, 0x01, 0x5F, - 0x45, 0xC1, 0x54, 0x4D, 0x47, 0x87, 0x1B, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x6F, - 0x1B, 0xFA, 0xFA, 0x5E, 0xDB, 0x32, 0xF7, 0x27, 0x61, 0x84, 0xFC, 0x7E, 0xE7, 0x3C, 0x73, 0xEA, - 0xD9, 0xF9, 0xF6, 0xC0, 0xAF, 0x02, 0xA1, 0xC8, 0x35, 0x0E, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, - 0x00, 0x4A, 0xE6, 0x57, 0x4F, 0x5C, 0xBA, 0xC6, 0x86, 0xC8, 0xB1, 0x68, 0x88, 0x9C, 0xF9, 0x3B, - 0x17, 0x01, 0x2A, 0x16, 0xF2, 0x5E, 0x7D, 0x78, 0xB8, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0x50, - 0x62, 0xEE, 0x01, 0xEE, 0xDF, 0x3E, 0x39, 0xF7, 0xAB, 0xAF, 0x6F, 0x9B, 0x37, 0x1E, 0x86, 0x88, - 0x7B, 0x50, 0xBD, 0xD8, 0xE7, 0x43, 0xEA, 0xC3, 0x83, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x69, - 0xA4, 0xF2, 0x41, 0x86, 0x73, 0xEF, 0x79, 0x7D, 0xCB, 0xDC, 0x9A, 0x07, 0xD5, 0xCF, 0xFD, 0x34, - 0xEF, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, 0xA6, 0xB1, 0x57, 0x9E, 0x9C, - 0x73, 0xA9, 0x7A, 0x50, 0x3D, 0x9F, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, - 0xE0, 0x7B, 0x6D, 0x47, 0xDF, 0x40, 0xE5, 0x83, 0x0C, 0x27, 0x43, 0xE4, 0x8D, 0x3D, 0x7D, 0xFE, - 0x33, 0x22, 0xD9, 0xDE, 0x9A, 0x55, 0x79, 0xB8, 0xDC, 0x3D, 0xE3, 0x11, 0xBF, 0xF1, 0xE0, 0x01, - 0x73, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x57, 0x9E, 0x99, 0x73, 0xDB, 0xEB, 0xDB, 0xE7, 0x9E, 0x8C, - 0x86, 0x48, 0x18, 0x23, 0xEF, 0x1C, 0x9A, 0x6F, 0x4E, 0xFF, 0xCD, 0x7C, 0xFF, 0x79, 0x91, 0xF8, - 0x0D, 0x89, 0xFB, 0xFF, 0xDD, 0xBF, 0xEE, 0xFE, 0xFD, 0x77, 0x0E, 0xF5, 0xD5, 0x3C, 0xDF, 0x11, - 0xCE, 0x3D, 0x60, 0x6E, 0x7F, 0xEE, 0x75, 0xC1, 0x5F, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xDC, - 0x1B, 0xB3, 0x5E, 0x79, 0x66, 0xEE, 0x70, 0x3C, 0x44, 0x5A, 0x2E, 0x16, 0x1D, 0x95, 0xCD, 0x19, - 0xFA, 0xF5, 0xA3, 0x97, 0xDE, 0x1C, 0xFC, 0xD4, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xB9, 0x87, 0xD5, - 0x7F, 0xB3, 0x71, 0xDE, 0x9D, 0xAF, 0x3E, 0x3D, 0xEF, 0xA1, 0x57, 0x37, 0xCF, 0x7D, 0x59, 0x46, - 0x47, 0xB8, 0x20, 0x38, 0x5E, 0xDB, 0x3C, 0xF7, 0xD8, 0xAB, 0xCF, 0xCC, 0x7D, 0xDA, 0xDD, 0x76, - 0xFC, 0xB7, 0xEF, 0xCC, 0xFB, 0x40, 0xF0, 0x53, 0x01, 0x00, 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x35, - 0xB9, 0xFE, 0x07, 0x1B, 0xEE, 0xE8, 0x1B, 0x88, 0xEF, 0xDF, 0x36, 0xCC, 0xEE, 0x0B, 0xFE, 0x63, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xD0, 0x15, 0xDE, 0xF3, 0x9E, 0xFF, 0x1F, 0x5B, 0xE2, 0x94, 0x1D, 0x86, - 0x86, 0x23, 0x09, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82}; - -static const uint8_t tree_gif[] PROGMEM = { - - 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x28, 0x00, 0x3C, 0x00, 0x83, 0x0B, 0x00, 0x00, 0xFF, 0xFF, - 0x00, 0x21, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x94, 0x00, 0x00, 0xB5, 0x00, 0x00, - 0xDE, 0x00, 0x00, 0xFF, 0x00, 0x6B, 0x00, 0x00, 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, - 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x00, 0xCC, 0x00, 0x00, 0x21, 0xFF, 0x0B, - 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0xA0, 0x0F, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, - 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, - 0x8C, 0xCA, 0xE8, 0x85, 0xE8, 0xA5, 0xAC, 0x67, 0xEA, 0x8A, 0xE5, 0x2B, 0x2F, 0xE3, 0x31, 0xCE, - 0xAF, 0x41, 0x1C, 0xB8, 0x1B, 0x24, 0x80, 0x04, 0xAF, 0x87, 0x02, 0x26, 0x88, 0xA1, 0x07, 0x60, - 0xB9, 0x44, 0x82, 0x04, 0x02, 0x80, 0x61, 0x30, 0x70, 0x6E, 0x0C, 0x86, 0x03, 0x60, 0x20, 0xB0, - 0x6A, 0xA8, 0xD3, 0x03, 0x21, 0xEC, 0xAD, 0x18, 0x12, 0xE8, 0xF4, 0xB1, 0x4C, 0x51, 0xA0, 0x07, - 0xEA, 0x07, 0x5B, 0xF2, 0x70, 0x13, 0x76, 0xD4, 0xA8, 0xBC, 0xBC, 0xEA, 0x1F, 0x06, 0x77, 0x51, - 0x73, 0x50, 0x0A, 0x80, 0x7F, 0x04, 0x4C, 0x4D, 0x65, 0x06, 0x0A, 0x3B, 0x3B, 0x62, 0x5A, 0x53, - 0x65, 0x05, 0x02, 0x04, 0x68, 0x0C, 0x6A, 0x00, 0x5D, 0x5E, 0x0F, 0x0F, 0x6A, 0x98, 0x6A, 0x09, - 0x7B, 0x56, 0x9D, 0x09, 0x0C, 0xA7, 0xA7, 0x7F, 0x06, 0x9D, 0xA3, 0x44, 0x02, 0x01, 0x03, 0x90, - 0x0C, 0x87, 0x03, 0x06, 0x02, 0x05, 0x56, 0x06, 0x01, 0x02, 0x53, 0xB1, 0xB3, 0x04, 0x79, 0xAF, - 0x55, 0x48, 0x51, 0xB0, 0x87, 0xC0, 0x7F, 0x07, 0x95, 0x05, 0x85, 0x44, 0xB6, 0x00, 0x05, 0x53, - 0x96, 0x6A, 0x60, 0x02, 0x0A, 0x48, 0x89, 0x00, 0x07, 0xA1, 0x69, 0x7D, 0x2B, 0x3D, 0x9D, 0x41, - 0xA1, 0x04, 0xA0, 0xDD, 0x9D, 0x38, 0x02, 0xE1, 0x6A, 0x07, 0x62, 0x0C, 0x77, 0xE6, 0xAD, 0x2F, - 0x05, 0x01, 0xB6, 0x90, 0x07, 0xA8, 0xA7, 0x54, 0xB5, 0xBC, 0x06, 0x33, 0x50, 0x53, 0x3A, 0x00, - 0x39, 0x62, 0x10, 0x6B, 0xDF, 0xBE, 0x19, 0x03, 0x18, 0x40, 0xA9, 0x15, 0x4B, 0xCC, 0x0E, 0x77, - 0x3B, 0x04, 0xC4, 0x02, 0x38, 0x43, 0x21, 0x96, 0x2C, 0xD3, 0xD6, 0x81, 0x01, 0x26, 0x2A, 0xFB, - 0xDE, 0x07, 0x7C, 0x0A, 0xB7, 0x71, 0x1B, 0x79, 0xEE, 0xC5, 0x83, 0x72, 0xDD, 0x84, 0xBC, 0x4B, - 0x13, 0xA4, 0x13, 0x15, 0x17, 0xAB, 0x18, 0x78, 0x4A, 0x43, 0x40, 0x81, 0x43, 0x76, 0x8E, 0xB6, - 0x04, 0x7C, 0x19, 0x02, 0x98, 0xC4, 0x86, 0x35, 0xBD, 0xE1, 0x1C, 0x90, 0x4D, 0x62, 0xBF, 0x14, - 0xFC, 0x7E, 0x02, 0x1A, 0x60, 0xD3, 0xD1, 0x9D, 0x3B, 0x3A, 0x09, 0xFC, 0x44, 0xB1, 0xD0, 0x96, - 0x8E, 0x43, 0x8D, 0x9E, 0xDA, 0xDB, 0x22, 0x11, 0x8A, 0x42, 0x10, 0x5C, 0x00, 0x1A, 0x2D, 0x38, - 0xF2, 0x0E, 0xA0, 0x4A, 0x03, 0x4E, 0xA2, 0xF0, 0xF4, 0x80, 0x17, 0x95, 0x8C, 0x23, 0xD1, 0xD8, - 0x12, 0x00, 0x92, 0x03, 0xAB, 0x99, 0x23, 0x71, 0x3E, 0x8D, 0xEB, 0x6E, 0x18, 0x07, 0x66, 0x23, - 0x05, 0x3E, 0x72, 0xE4, 0x06, 0x0D, 0x81, 0x02, 0xE4, 0x36, 0x5D, 0xD9, 0xA5, 0xC0, 0xAD, 0x59, - 0xA2, 0x86, 0x6E, 0xD6, 0xC4, 0x73, 0xEB, 0x15, 0xA5, 0xC5, 0xDE, 0x14, 0xF4, 0x62, 0x07, 0xC0, - 0xE9, 0x9D, 0xCC, 0x58, 0x02, 0x14, 0xA0, 0x84, 0x45, 0x83, 0x68, 0x7A, 0x8D, 0x81, 0x66, 0xC3, - 0xE9, 0xD0, 0xA6, 0x3E, 0x03, 0xF3, 0x80, 0x7D, 0x90, 0xD8, 0x58, 0xA2, 0x59, 0x2D, 0x90, 0x68, - 0xD6, 0x64, 0x17, 0x76, 0x5A, 0x23, 0xBF, 0x13, 0x58, 0x89, 0x7A, 0xC3, 0xF0, 0x8F, 0xB6, 0xB8, - 0x4B, 0xD3, 0x74, 0x52, 0x50, 0x92, 0xC2, 0x03, 0xD1, 0x78, 0xD7, 0x89, 0x4C, 0x23, 0x26, 0x6E, - 0x82, 0xCC, 0x15, 0x5E, 0x05, 0x08, 0x30, 0x06, 0x8A, 0x75, 0x64, 0xFA, 0x42, 0xF1, 0x12, 0xAD, - 0x60, 0xDE, 0x51, 0x0A, 0x94, 0xBA, 0x5E, 0x2C, 0x8C, 0x86, 0xDD, 0x3D, 0xDE, 0x8F, 0x0A, 0x70, - 0x51, 0x5F, 0xFE, 0xF2, 0x84, 0xD1, 0xD0, 0xA6, 0x68, 0xB7, 0x96, 0x62, 0x14, 0x0C, 0xC1, 0xB7, - 0x90, 0x68, 0x72, 0xD1, 0x7C, 0xD9, 0x3D, 0xA3, 0x94, 0x35, 0xDE, 0x54, 0x06, 0x92, 0x51, 0x50, - 0x68, 0xC2, 0xC5, 0x44, 0xB7, 0x30, 0x70, 0xDE, 0x6A, 0x49, 0x69, 0x86, 0xC5, 0x2D, 0xA3, 0x29, - 0x04, 0x05, 0x2F, 0xD9, 0xC4, 0x02, 0x0C, 0x6C, 0x0C, 0x48, 0xB0, 0x94, 0x01, 0xDA, 0x3C, 0xF2, - 0x56, 0x21, 0xFA, 0xE8, 0xA3, 0xA1, 0x55, 0x12, 0xE9, 0xF4, 0x56, 0x42, 0xF8, 0x50, 0x00, 0x40, - 0x08, 0x08, 0xD4, 0x88, 0x80, 0x05, 0x33, 0x66, 0x10, 0xA2, 0x0C, 0xDC, 0xA0, 0xB0, 0xA3, 0x0B, - 0x71, 0xCD, 0xB1, 0x80, 0x75, 0x69, 0x20, 0x41, 0xE4, 0x91, 0x6B, 0x64, 0x10, 0x01, 0x00, 0x21, - 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, 0x00, - 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, 0x8C, - 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0x31, 0x1C, 0x34, - 0x1B, 0x24, 0x4C, 0x82, 0xE7, 0x28, 0x5E, 0x02, 0x78, 0x7A, 0x30, 0x8E, 0x47, 0x62, 0x48, 0x20, - 0x60, 0xD8, 0x06, 0x4A, 0x8E, 0xC1, 0x70, 0x60, 0x0C, 0x04, 0xD1, 0xCD, 0x60, 0x60, 0x3B, 0x10, - 0xBA, 0x59, 0x8B, 0x21, 0x41, 0x2E, 0x0F, 0xC3, 0x16, 0xF2, 0xC0, 0xAC, 0x40, 0x4F, 0x1E, 0x80, - 0x04, 0x81, 0x70, 0xD8, 0x0A, 0x14, 0x0F, 0xF7, 0x42, 0x00, 0xA0, 0xD6, 0x09, 0x0A, 0x81, 0x81, - 0x68, 0x00, 0x85, 0x85, 0x7F, 0x07, 0x07, 0x0A, 0x06, 0x7A, 0x06, 0x00, 0x74, 0x74, 0x5E, 0x8A, - 0x36, 0x68, 0x05, 0x7C, 0x66, 0x3D, 0x64, 0x58, 0x61, 0x0F, 0x0F, 0x66, 0x64, 0x99, 0x64, 0x79, - 0x9C, 0x9E, 0xA0, 0x48, 0x4E, 0x9D, 0xA3, 0x4A, 0x02, 0x01, 0x37, 0x90, 0x55, 0x04, 0x5C, 0x02, - 0x05, 0x59, 0x06, 0x01, 0x02, 0x4F, 0x89, 0x55, 0x76, 0xAC, 0x50, 0xAB, 0x0A, 0xAD, 0x7F, 0xB1, - 0x75, 0x07, 0x02, 0x04, 0x05, 0x00, 0xBE, 0x39, 0x06, 0x77, 0x05, 0x36, 0x04, 0x9F, 0x5B, 0xCC, - 0x00, 0x4A, 0x82, 0x81, 0x07, 0x9F, 0x65, 0x86, 0x85, 0x40, 0x9D, 0x0A, 0x9F, 0x0C, 0xD0, 0x9F, - 0x00, 0x9D, 0x39, 0x02, 0xDE, 0x66, 0xB0, 0x73, 0xE2, 0x09, 0xE4, 0xAA, 0x2F, 0x05, 0x01, 0xCC, - 0x5E, 0xA7, 0x56, 0x75, 0xD2, 0xB8, 0x8C, 0x2F, 0x4C, 0x36, 0x06, 0xB1, 0x73, 0xE1, 0x88, 0xC9, - 0x92, 0x45, 0x43, 0x96, 0x00, 0x2E, 0x37, 0xE8, 0x79, 0x99, 0x53, 0xEC, 0x86, 0x0D, 0x06, 0x05, - 0xF3, 0x51, 0x61, 0x57, 0xE6, 0x9E, 0xBF, 0x35, 0x0C, 0xDE, 0x81, 0xE8, 0x64, 0x10, 0xFB, 0x5B, - 0xB6, 0x6C, 0xF5, 0x56, 0x94, 0x22, 0x13, 0xA7, 0xE2, 0x9C, 0x04, 0xDF, 0xCA, 0x74, 0xB2, 0xB2, - 0xC2, 0x40, 0x2A, 0x92, 0x72, 0x20, 0x45, 0x52, 0xE0, 0x45, 0x1A, 0x01, 0x2B, 0xCA, 0x3E, 0xC4, - 0x3A, 0x38, 0x60, 0xDB, 0x23, 0x86, 0xD6, 0x14, 0x0C, 0x20, 0xC0, 0x84, 0xCB, 0x8A, 0x7C, 0x3C, - 0x1F, 0x25, 0x94, 0xA9, 0x80, 0x21, 0x17, 0xA2, 0x5B, 0x4E, 0x34, 0x91, 0xE5, 0x2F, 0x99, 0x4C, - 0xA0, 0x89, 0xEC, 0x5C, 0xC1, 0xB5, 0x89, 0xC3, 0x15, 0x2B, 0xCC, 0x10, 0xD6, 0xF9, 0x38, 0x67, - 0xA8, 0xB1, 0x01, 0xE5, 0x40, 0xD4, 0x7B, 0x42, 0xF1, 0x63, 0x02, 0x66, 0x02, 0x12, 0xA4, 0xFA, - 0x90, 0x2A, 0x54, 0xB6, 0x44, 0xEB, 0xDA, 0x96, 0x19, 0x9A, 0x53, 0x43, 0x01, 0xBB, 0x64, 0x84, - 0xAE, 0xC3, 0xBB, 0xB0, 0xCC, 0x31, 0x40, 0x5D, 0x35, 0xD8, 0x62, 0x82, 0x6B, 0x68, 0xAC, 0xA6, - 0x43, 0xF1, 0xD2, 0x01, 0x20, 0xE9, 0x8A, 0x25, 0x05, 0x96, 0x36, 0xD8, 0x8A, 0xD7, 0xD8, 0x46, - 0xD0, 0x85, 0xEB, 0x7E, 0x72, 0x31, 0x10, 0x54, 0x9F, 0x85, 0x00, 0xF1, 0xA6, 0x1C, 0x94, 0x2C, - 0x34, 0xB2, 0x17, 0x9F, 0x5B, 0xB8, 0x14, 0x80, 0xFC, 0x41, 0x28, 0x63, 0xC7, 0x03, 0x9A, 0x4A, - 0x32, 0x9C, 0x2C, 0x2B, 0x2E, 0x40, 0x72, 0x63, 0x59, 0x48, 0x85, 0x47, 0x8D, 0xD8, 0xC8, 0xD9, - 0xE2, 0xF0, 0x55, 0x99, 0x4A, 0xE3, 0x82, 0x07, 0x41, 0x3F, 0x25, 0x92, 0xAE, 0xD7, 0x4C, 0x3C, - 0xE7, 0xAC, 0x02, 0x04, 0x58, 0xC4, 0xC4, 0xAD, 0x9C, 0x1B, 0xB1, 0x3F, 0xE1, 0x42, 0x3D, 0x4B, - 0x9E, 0x85, 0xCB, 0x57, 0xA6, 0x30, 0x4B, 0x97, 0x88, 0x26, 0xA2, 0x03, 0x7F, 0x8B, 0x72, 0x2D, - 0x90, 0x79, 0x02, 0xFD, 0x59, 0x36, 0xB2, 0xF3, 0x41, 0x2A, 0x65, 0xAD, 0x75, 0x64, 0x3A, 0x0C, - 0x48, 0xB4, 0x15, 0x35, 0x13, 0xE0, 0xC2, 0xC0, 0x2D, 0xB1, 0x15, 0x95, 0x0C, 0x13, 0x97, 0x59, - 0x73, 0x90, 0x01, 0xF5, 0xAC, 0x36, 0x8D, 0x79, 0x12, 0x40, 0xB8, 0x45, 0x22, 0xB8, 0xF8, 0xC4, - 0x0C, 0x7D, 0xB3, 0x31, 0x96, 0xCF, 0x00, 0x01, 0x76, 0x41, 0x80, 0x4F, 0x0B, 0x80, 0x78, 0x4A, - 0x24, 0x5B, 0x8C, 0x18, 0xDB, 0x8A, 0x0A, 0xF0, 0xC3, 0x15, 0x88, 0x08, 0xF1, 0xC5, 0xC7, 0x3C, - 0x13, 0x40, 0x94, 0x01, 0x81, 0x13, 0x20, 0xA0, 0x23, 0x02, 0x27, 0xE0, 0x58, 0x63, 0x08, 0xD9, - 0xE8, 0x41, 0x81, 0x5B, 0x42, 0x7A, 0x57, 0x86, 0x12, 0x46, 0x26, 0x79, 0x46, 0x06, 0x11, 0x00, - 0x00, 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, - 0x3C, 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, - 0xE4, 0x8C, 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0xA1, - 0x1C, 0x34, 0x1B, 0x24, 0x4A, 0x82, 0xE7, 0x27, 0x85, 0x50, 0x08, 0x0C, 0x3D, 0x12, 0xBC, 0xC4, - 0xA3, 0x18, 0x12, 0x08, 0x14, 0x86, 0xC1, 0x80, 0xC9, 0x31, 0x18, 0x0E, 0x84, 0x81, 0x80, 0xBA, - 0x91, 0x46, 0xB1, 0x51, 0x06, 0xD7, 0x62, 0x40, 0x9A, 0x91, 0xE2, 0x71, 0xA5, 0x37, 0x40, 0x33, - 0xDE, 0xE9, 0xF1, 0xE3, 0xA1, 0x20, 0x10, 0x0E, 0x52, 0x01, 0x63, 0xA9, 0x5E, 0x0C, 0x85, 0x03, - 0x76, 0x7A, 0x7D, 0x0B, 0x4E, 0x03, 0x75, 0x78, 0x77, 0x78, 0x06, 0x84, 0x51, 0x37, 0x8A, 0x77, - 0x02, 0x51, 0x6A, 0x05, 0x02, 0x04, 0x67, 0x67, 0x5B, 0x72, 0x47, 0x98, 0x98, 0x7C, 0x5C, 0x73, - 0x66, 0x58, 0x07, 0x8B, 0x0F, 0x00, 0x9F, 0x45, 0x02, 0x01, 0x03, 0xA3, 0x0C, 0x89, 0x03, 0x06, - 0x02, 0x00, 0x5C, 0x06, 0x01, 0x92, 0x52, 0x07, 0xAE, 0x59, 0x03, 0x00, 0xBD, 0xBD, 0x4C, 0x02, - 0x05, 0xAB, 0xB9, 0x70, 0x0C, 0xAC, 0x96, 0x00, 0x52, 0x45, 0x36, 0xC1, 0x51, 0x97, 0x0C, 0x66, - 0x5E, 0x00, 0x8C, 0x4C, 0x0A, 0x05, 0x5F, 0x68, 0x98, 0x4E, 0x56, 0x40, 0x7F, 0x3D, 0x67, 0x97, - 0x9D, 0x73, 0x39, 0x02, 0x74, 0x9C, 0x48, 0xA4, 0x76, 0x76, 0x66, 0x73, 0xA8, 0x2C, 0x05, 0x50, - 0x02, 0xA3, 0xA3, 0x59, 0x78, 0x5E, 0x92, 0xD4, 0x2C, 0xDB, 0xB0, 0x59, 0x76, 0x07, 0x00, 0x78, - 0x16, 0x09, 0x80, 0xF5, 0xE4, 0x05, 0xC1, 0x81, 0x5F, 0xB0, 0x10, 0x00, 0xA0, 0xEE, 0xC0, 0xC0, - 0x03, 0x8E, 0x68, 0x68, 0xB1, 0x72, 0xE5, 0x92, 0xAF, 0x5E, 0xF6, 0x0C, 0x10, 0xF0, 0x86, 0x62, - 0xFB, 0xCE, 0xC1, 0x03, 0x98, 0x00, 0x74, 0x42, 0x42, 0xE7, 0xC5, 0xB9, 0x4E, 0xFF, 0xC2, 0x9D, - 0x99, 0xA3, 0x60, 0x0A, 0x0A, 0x03, 0xED, 0xC0, 0xDD, 0xF1, 0x47, 0xCF, 0xCB, 0x2E, 0x97, 0x20, - 0x92, 0x0D, 0x64, 0x85, 0xA5, 0x65, 0x43, 0x2C, 0x3C, 0x19, 0x10, 0x30, 0x94, 0x2F, 0x27, 0xBE, - 0x9D, 0x87, 0x78, 0xCE, 0x54, 0x47, 0xC0, 0x98, 0xC6, 0x9D, 0x39, 0x2F, 0xC6, 0xB2, 0xF1, 0x87, - 0x29, 0x96, 0x62, 0xC6, 0xB6, 0x69, 0xE2, 0xC0, 0x2B, 0x4A, 0x2C, 0x58, 0x49, 0x47, 0xDA, 0x11, - 0x6A, 0x69, 0xC0, 0xB8, 0x10, 0x22, 0x1F, 0xDC, 0x0A, 0xF4, 0x6D, 0x64, 0x02, 0x06, 0xB1, 0x04, - 0x28, 0x39, 0xBB, 0xA1, 0xDD, 0x49, 0x4C, 0xE9, 0xD4, 0xB9, 0x4D, 0x0A, 0xA2, 0x40, 0x81, 0x91, - 0x81, 0x68, 0x2E, 0x35, 0x43, 0xA0, 0xC0, 0x50, 0x05, 0x1F, 0x6A, 0x39, 0xB9, 0x65, 0x47, 0x4A, - 0xBF, 0xBC, 0xF4, 0xF0, 0x04, 0xE3, 0x98, 0xA1, 0x96, 0x02, 0x5B, 0x5E, 0x71, 0xA5, 0x53, 0xA8, - 0x4E, 0x68, 0x16, 0x2B, 0x01, 0xFC, 0x42, 0x29, 0x4A, 0x21, 0xF4, 0xE8, 0x87, 0x0A, 0xA5, 0x04, - 0xDA, 0xDC, 0x94, 0x95, 0x6A, 0x03, 0xC2, 0x5A, 0x6E, 0xF0, 0x66, 0xC8, 0x0E, 0xC0, 0x99, 0x20, - 0xDF, 0x16, 0x93, 0xAC, 0x91, 0x64, 0x16, 0x0B, 0xED, 0x14, 0x70, 0xF2, 0xC2, 0x6B, 0x75, 0x27, - 0x68, 0x81, 0xDA, 0x90, 0xB4, 0x0B, 0xDC, 0x74, 0xC8, 0x8B, 0x67, 0xB0, 0xBC, 0x75, 0x2B, 0xCC, - 0x5D, 0xA1, 0x00, 0xD8, 0x09, 0xC4, 0x3D, 0x23, 0x92, 0xB0, 0x6B, 0x29, 0xDA, 0x6A, 0x55, 0x12, - 0x46, 0x7A, 0x41, 0xA5, 0x81, 0xF8, 0x62, 0x25, 0xE8, 0x4E, 0x2A, 0x60, 0x22, 0x52, 0x05, 0xB4, - 0xB4, 0x94, 0x14, 0xAC, 0x12, 0x05, 0xBF, 0xCD, 0xB4, 0x60, 0xA7, 0x6F, 0x66, 0x65, 0xE7, 0x57, - 0xC7, 0xA3, 0xC8, 0x67, 0x85, 0x16, 0x5B, 0x49, 0xF0, 0x84, 0x2A, 0x48, 0x19, 0x92, 0x47, 0x30, - 0x4E, 0x00, 0x60, 0xC9, 0x57, 0x71, 0x79, 0x03, 0x51, 0x30, 0xD3, 0x4C, 0xA0, 0xC0, 0x4E, 0xA4, - 0x1C, 0x45, 0x51, 0x2C, 0x7E, 0x39, 0xB8, 0x18, 0x3E, 0x04, 0xB5, 0x04, 0x14, 0x6C, 0xB3, 0xF8, - 0xF1, 0xC7, 0x3C, 0x00, 0xAA, 0xC6, 0xCB, 0x45, 0xFC, 0x21, 0xD5, 0x52, 0x72, 0x17, 0x95, 0x88, - 0xD8, 0x09, 0x08, 0x00, 0x80, 0x00, 0x02, 0x28, 0x94, 0x28, 0xC1, 0x8C, 0x20, 0x20, 0xD1, 0x5D, - 0x02, 0x27, 0xE8, 0x88, 0x82, 0x5B, 0x84, 0x2C, 0xE0, 0xD6, 0x19, 0x4C, 0x1C, 0xA9, 0xA4, 0x19, - 0x1B, 0x44, 0x00, 0x00, 0x21, 0xFE, 0x19, 0x42, 0x6F, 0x79, 0x27, 0x73, 0x20, 0x48, 0x61, 0x70, - 0x70, 0x79, 0x20, 0x48, 0x6F, 0x6C, 0x69, 0x64, 0x61, 0x79, 0x73, 0x20, 0x50, 0x61, 0x67, 0x65, - 0x00, 0x3B - -}; - -static const uint8_t bird_gif[] PROGMEM = { - 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x74, 0x00, 0x4E, 0x00, 0xCC, 0x13, 0x00, 0xFF, 0xFF, 0xFF, - 0xEF, 0xFF, 0xFF, 0xBD, 0xE7, 0xE7, 0xD6, 0xEF, 0xEF, 0x63, 0x63, 0x63, 0xAD, 0xAD, 0xAD, 0xCE, - 0xCE, 0xCE, 0xD6, 0xDE, 0xDE, 0x4A, 0x4A, 0x4A, 0x7B, 0x84, 0x84, 0x94, 0x9C, 0x9C, 0xE7, 0xE7, - 0xE7, 0x84, 0x94, 0x94, 0xB5, 0xC6, 0xC6, 0x73, 0x7B, 0x7B, 0x31, 0x31, 0x31, 0xF7, 0xF7, 0xF7, - 0x18, 0x10, 0x10, 0xCE, 0x63, 0x39, 0x6B, 0x39, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xFF, 0x0B, - 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x4B, - 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0xAE, 0xEC, 0x68, 0x2C, - 0x6D, 0x2C, 0xCF, 0x74, 0x6D, 0x03, 0x46, 0x84, 0x40, 0x77, 0xEF, 0xFF, 0x40, 0x51, 0x42, 0x41, - 0x0C, 0x1A, 0x8F, 0x48, 0x13, 0xC1, 0xD0, 0x20, 0x00, 0x0E, 0x8E, 0x42, 0x72, 0x4A, 0xAD, 0x21, - 0x0E, 0xCD, 0x05, 0xE1, 0x80, 0xA8, 0x7A, 0xBF, 0x29, 0xC2, 0xA0, 0x91, 0x28, 0x34, 0x02, 0x5D, - 0xB0, 0x5A, 0xFD, 0x08, 0x34, 0x14, 0x84, 0x00, 0x7A, 0x4D, 0xF7, 0x22, 0xDC, 0x89, 0xB8, 0xC1, - 0xB9, 0x80, 0xD5, 0xFF, 0x40, 0x0B, 0x77, 0x0C, 0x0F, 0x05, 0x01, 0x0C, 0x0A, 0x0B, 0x0F, 0x08, - 0x06, 0x80, 0x8E, 0x37, 0x7B, 0x01, 0x09, 0x11, 0x03, 0x68, 0x5C, 0x4C, 0x0A, 0x8F, 0x9A, 0x33, - 0x06, 0x09, 0x01, 0x0E, 0x71, 0x68, 0x88, 0x92, 0x07, 0x9B, 0xA6, 0x2C, 0x0A, 0x86, 0x07, 0x95, - 0x05, 0x04, 0xA1, 0x5D, 0x8D, 0xA7, 0xB2, 0x26, 0x09, 0x06, 0x72, 0x72, 0x0E, 0x94, 0x01, 0xA9, - 0x04, 0x08, 0x52, 0xB3, 0xC0, 0x00, 0x09, 0x95, 0xB7, 0x0D, 0x86, 0x01, 0x04, 0x0A, 0xC3, 0x09, - 0x34, 0x43, 0xC1, 0x54, 0x0E, 0xB7, 0xD2, 0x87, 0xAE, 0xBB, 0x99, 0x32, 0x7B, 0x0E, 0xCF, 0x49, - 0x0B, 0xD1, 0xD3, 0x72, 0x0C, 0xDE, 0x57, 0x33, 0xBE, 0xCC, 0xDB, 0x47, 0x05, 0x0C, 0xDF, 0xD3, - 0x05, 0xD7, 0x31, 0x0C, 0xE1, 0xA5, 0xE7, 0x46, 0xBE, 0xEB, 0xD2, 0x04, 0x05, 0xBF, 0x2C, 0x5C, - 0x4D, 0xF3, 0x46, 0x0B, 0x11, 0x56, 0xD9, 0x3B, 0x14, 0x01, 0x14, 0x0F, 0x16, 0x04, 0x1A, 0x30, - 0x28, 0x00, 0x81, 0xA1, 0x3F, 0x1F, 0xAD, 0x02, 0x10, 0x5B, 0x87, 0x6F, 0x0E, 0x8B, 0x02, 0x0E, - 0x04, 0x5C, 0x41, 0x10, 0xF0, 0x61, 0x8F, 0x25, 0x03, 0x26, 0xDA, 0x43, 0xC4, 0x42, 0x8B, 0x00, - 0x05, 0x0E, 0x7C, 0xFF, 0xED, 0xF0, 0x68, 0x83, 0x8B, 0x44, 0x91, 0xDF, 0x06, 0xAC, 0x54, 0x01, - 0x21, 0xA1, 0x80, 0x07, 0x0F, 0x1A, 0x38, 0x70, 0xC7, 0x72, 0x46, 0xC2, 0x97, 0x03, 0x3F, 0xC5, - 0x52, 0xE1, 0x80, 0x81, 0x00, 0x01, 0x19, 0x1B, 0x3C, 0x38, 0xD8, 0x53, 0xC6, 0x81, 0x38, 0x21, - 0x61, 0x4A, 0xEB, 0xB7, 0x42, 0x01, 0x82, 0xA3, 0x58, 0x7D, 0xC9, 0x6B, 0x1A, 0x63, 0x0B, 0xD0, - 0x81, 0x11, 0x08, 0x74, 0x44, 0x61, 0xE0, 0x01, 0xD6, 0xA3, 0x05, 0x16, 0x2D, 0xE5, 0xDA, 0xC2, - 0x80, 0xB7, 0x90, 0x41, 0xCB, 0xA4, 0x39, 0xC1, 0xEF, 0x2C, 0x56, 0xAA, 0x6C, 0x57, 0x38, 0xA8, - 0x14, 0x35, 0xA8, 0x35, 0x14, 0x10, 0x10, 0x34, 0xB0, 0x9B, 0xD5, 0x4F, 0xDE, 0x14, 0x06, 0x8E, - 0xF5, 0x1D, 0xC8, 0x25, 0x85, 0x83, 0xC1, 0x84, 0x05, 0x20, 0x32, 0x30, 0xF4, 0x30, 0x2D, 0x39, - 0x8B, 0x07, 0x32, 0x42, 0xA1, 0x00, 0x72, 0xE4, 0x45, 0x08, 0x7C, 0x59, 0x36, 0x91, 0x18, 0x73, - 0xE6, 0x6F, 0x79, 0x38, 0x2B, 0x88, 0x7C, 0x54, 0xE7, 0xE0, 0x2D, 0xA3, 0x4B, 0x78, 0x7A, 0x79, - 0x7A, 0x1A, 0xCE, 0x04, 0x4C, 0x85, 0xAC, 0x66, 0x7D, 0x96, 0x80, 0xB9, 0xD8, 0x22, 0x4A, 0x4B, - 0x14, 0x00, 0x97, 0xF1, 0xD3, 0x12, 0x3B, 0x79, 0x9F, 0x45, 0xC0, 0x13, 0xB8, 0xB7, 0xE1, 0xC5, - 0x19, 0x33, 0xEB, 0x53, 0xD3, 0xA8, 0x72, 0x01, 0x0D, 0x44, 0x97, 0x5C, 0x90, 0x7B, 0x9B, 0x01, - 0x05, 0xA6, 0x89, 0xFB, 0x3D, 0x54, 0x20, 0x81, 0xDA, 0x8C, 0xD7, 0x91, 0x16, 0x22, 0x91, 0xF8, - 0x80, 0x9F, 0x86, 0x08, 0x1E, 0xF4, 0xF2, 0xD5, 0x7D, 0x96, 0x18, 0xCC, 0x47, 0xA3, 0xDB, 0x7B, - 0xCA, 0x60, 0x40, 0xCA, 0xF4, 0x58, 0x81, 0xE2, 0x42, 0x04, 0x11, 0x4C, 0x80, 0x53, 0x7C, 0x3F, - 0xC9, 0xB1, 0xC7, 0xFF, 0x7A, 0xC1, 0x18, 0xA0, 0x0E, 0x7E, 0xC4, 0x49, 0xA5, 0x99, 0x67, 0xD7, - 0xA5, 0xB4, 0x15, 0x04, 0x93, 0x48, 0xA0, 0xA1, 0x81, 0x7C, 0x49, 0xB3, 0xC7, 0x38, 0xF6, 0x11, - 0x13, 0x52, 0x7E, 0x12, 0xAE, 0x63, 0xC0, 0x55, 0x00, 0x82, 0x62, 0xD8, 0x08, 0x0B, 0x24, 0xA0, - 0xA1, 0x86, 0x57, 0x3C, 0xF0, 0xE0, 0x2D, 0x05, 0x68, 0x67, 0x4A, 0x27, 0xB7, 0x0C, 0x80, 0x95, - 0x7E, 0x41, 0x11, 0x80, 0x5E, 0x85, 0xBF, 0x9D, 0xD0, 0xC0, 0x04, 0x2F, 0x2E, 0x62, 0xCB, 0x34, - 0x03, 0xE4, 0xB1, 0xA2, 0x23, 0x5E, 0x41, 0xC8, 0x63, 0x50, 0x0E, 0x9A, 0x75, 0x5D, 0x68, 0x5B, - 0x9D, 0xA0, 0x45, 0x04, 0x38, 0x2D, 0x72, 0xCC, 0x34, 0x7B, 0x24, 0xF2, 0x88, 0x5B, 0x39, 0xEA, - 0x18, 0xE1, 0x78, 0xD2, 0x58, 0x05, 0x20, 0x6C, 0x2B, 0xD4, 0x78, 0x64, 0x89, 0x6E, 0xB8, 0xF2, - 0xC2, 0x1F, 0x4D, 0xBE, 0x44, 0x22, 0x99, 0x72, 0xE4, 0x01, 0x60, 0x19, 0x31, 0x68, 0xB1, 0xC4, - 0x78, 0x50, 0xF4, 0xE2, 0x9B, 0x43, 0x5E, 0x80, 0x99, 0xE3, 0x8E, 0x6C, 0x4E, 0xE3, 0x63, 0x7A, - 0xD9, 0x55, 0xD6, 0x82, 0x4E, 0x04, 0x30, 0xD0, 0xC0, 0x01, 0x7C, 0x2A, 0xE4, 0xA3, 0xA2, 0x47, - 0xDC, 0x37, 0xE8, 0x9C, 0xE3, 0xC9, 0x64, 0x9D, 0x72, 0x70, 0x54, 0x29, 0x03, 0x04, 0xDF, 0xE5, - 0xE1, 0x4A, 0x19, 0x06, 0xB0, 0xD9, 0xC4, 0x66, 0x48, 0x7C, 0x27, 0xCD, 0x88, 0x98, 0x92, 0x89, - 0xE2, 0x75, 0x69, 0x2D, 0x69, 0xC3, 0x02, 0x07, 0xA4, 0x03, 0x8A, 0x2B, 0x8E, 0xC2, 0x04, 0x05, - 0x03, 0x48, 0x3C, 0x17, 0x5E, 0xAB, 0x7E, 0x61, 0x04, 0x20, 0x03, 0x33, 0x21, 0x01, 0xC1, 0x02, - 0xDF, 0x81, 0x52, 0x8B, 0x34, 0xAD, 0xC8, 0x6A, 0x43, 0x3E, 0x48, 0x9E, 0xF5, 0x24, 0x45, 0xAF, - 0xF2, 0x96, 0x9D, 0xFF, 0x03, 0xF5, 0x51, 0xD1, 0xA2, 0x03, 0x90, 0xCA, 0xF1, 0x94, 0x3E, 0x37, - 0x68, 0x81, 0xA4, 0x98, 0xC0, 0x9A, 0xF8, 0xC0, 0x8F, 0xCA, 0x39, 0xA0, 0xCD, 0x1F, 0x0B, 0x10, - 0x21, 0x0D, 0x03, 0xB8, 0x7D, 0x74, 0x64, 0x98, 0xD2, 0x16, 0x8A, 0x0C, 0xBA, 0xCA, 0x29, 0xF5, - 0x48, 0x8B, 0x53, 0xA1, 0x19, 0x03, 0xA8, 0x18, 0x85, 0xB2, 0x2A, 0xB9, 0x63, 0x06, 0x45, 0x06, - 0x80, 0x48, 0x05, 0xC9, 0x6E, 0x9C, 0x4F, 0xE1, 0xA3, 0xC2, 0x77, 0xF0, 0x16, 0x95, 0x4B, 0xB7, - 0xF4, 0x12, 0xEA, 0x57, 0x59, 0x14, 0xB2, 0x46, 0x08, 0xB8, 0x8E, 0x08, 0x72, 0x06, 0xB3, 0x3E, - 0xA6, 0xF2, 0x28, 0x46, 0x8B, 0x2C, 0xEB, 0xED, 0x03, 0xF3, 0x56, 0x5C, 0xF0, 0x40, 0xE6, 0xED, - 0xA6, 0x9C, 0x7C, 0xD9, 0x02, 0xA2, 0x48, 0xCA, 0x98, 0x25, 0xD6, 0xCE, 0x4E, 0x14, 0x2B, 0x18, - 0xE7, 0xC0, 0xE5, 0xAE, 0x93, 0x00, 0xC2, 0x45, 0x01, 0xB3, 0xC0, 0x8C, 0x74, 0xFA, 0xF7, 0x80, - 0x84, 0xAC, 0xAE, 0x6C, 0xCF, 0x00, 0x04, 0xA4, 0x47, 0x2C, 0x02, 0xCE, 0x6A, 0xF2, 0x06, 0x9D, - 0x98, 0xE5, 0x3C, 0xB0, 0x98, 0xB5, 0x4D, 0xD3, 0x40, 0x04, 0x05, 0x28, 0x57, 0x40, 0x04, 0x0A, - 0x50, 0x2A, 0x4B, 0x02, 0x1F, 0x53, 0xBD, 0x74, 0x54, 0x59, 0xBF, 0x1B, 0x5A, 0x41, 0xAC, 0x65, - 0xA7, 0xF0, 0x33, 0x0C, 0x58, 0x6D, 0xB6, 0x69, 0x68, 0x4F, 0x2B, 0x87, 0x55, 0xB7, 0x38, 0x50, - 0xC8, 0x5D, 0x7E, 0x8A, 0x1D, 0x0C, 0x04, 0x8F, 0xCD, 0x1D, 0x94, 0xDD, 0x4F, 0xA1, 0xEC, 0xA1, - 0x7C, 0xAD, 0x8D, 0xC5, 0x52, 0x4D, 0xBE, 0x0A, 0x3E, 0x9E, 0x55, 0x32, 0xDA, 0xA3, 0x37, 0x03, - 0xBD, 0x44, 0x3D, 0x8F, 0x55, 0x34, 0x3B, 0x6E, 0x4F, 0x03, 0x99, 0x73, 0x89, 0x93, 0xE5, 0xFE, - 0x74, 0x13, 0xB7, 0xCB, 0xE6, 0xA4, 0x4B, 0x63, 0x90, 0x65, 0xED, 0x16, 0x25, 0x77, 0xE9, 0x54, - 0x67, 0x11, 0xDB, 0x89, 0x44, 0xB3, 0x6E, 0xF6, 0x89, 0x7E, 0x37, 0x05, 0x47, 0xE7, 0xB2, 0xFB, - 0xF5, 0x2D, 0x70, 0xDD, 0x80, 0x37, 0xDE, 0x0A, 0x8E, 0xFB, 0x06, 0x1C, 0x00, 0x4D, 0xE0, 0x1E, - 0x80, 0x0C, 0x73, 0xFB, 0x47, 0x00, 0xE8, 0x2C, 0x89, 0x6E, 0xCF, 0x0C, 0x66, 0x87, 0x64, 0x55, - 0x73, 0x87, 0xB5, 0xD2, 0x39, 0xF2, 0x54, 0xA3, 0xAD, 0x24, 0xEF, 0x09, 0xC4, 0x2E, 0x47, 0x0C, - 0x83, 0x4F, 0x44, 0x6E, 0x25, 0xA9, 0x0C, 0x8F, 0x43, 0xE0, 0xD3, 0xB4, 0x30, 0x50, 0x54, 0xF9, - 0x41, 0x57, 0xC9, 0x63, 0xE6, 0x03, 0x00, 0xC1, 0xED, 0xE9, 0xAB, 0x60, 0x4F, 0x62, 0x94, 0x41, - 0x2A, 0xFE, 0x01, 0x56, 0x11, 0x10, 0xB3, 0x65, 0x4F, 0x11, 0xCC, 0x37, 0x4A, 0x10, 0x2C, 0x8E, - 0x3C, 0x80, 0x40, 0x3A, 0x30, 0x20, 0x02, 0x96, 0x10, 0x3F, 0x13, 0x64, 0xA7, 0x1E, 0x17, 0x53, - 0x90, 0x02, 0x28, 0x87, 0x00, 0xB2, 0xC1, 0xE0, 0x29, 0x08, 0x24, 0x50, 0xC9, 0xFE, 0x37, 0x3C, - 0x28, 0x30, 0x67, 0x75, 0x01, 0x9C, 0x20, 0x4E, 0x0A, 0xE0, 0xAC, 0xAF, 0x21, 0x90, 0x3E, 0x0D, - 0x4C, 0x41, 0xBB, 0x42, 0x13, 0x05, 0x63, 0xA4, 0x64, 0x81, 0x43, 0x28, 0x40, 0xED, 0x44, 0x00, - 0x01, 0x2C, 0x78, 0x29, 0x85, 0x2C, 0x38, 0x56, 0x62, 0x1A, 0xC0, 0x1D, 0x35, 0x84, 0x00, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, - 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, - 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, - 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, - 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, - 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, - 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, - 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, - 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, - 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, - 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, - 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, - 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, - 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, - 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, - 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, - 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, - 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, - 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, - 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, - 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, - 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, - 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, - 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, - 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, - 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, - 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, - 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, - 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, - 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, - 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, - 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, - 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, - 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, - 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, - 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, - 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, - 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, - 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, - 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, - 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, - 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, - 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, - 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, - 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, - 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, - 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, - 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, - 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, - 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, - 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, - 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, - 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, - 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, - 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, - 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, - 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, - 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, - 0x0D, 0x21, 0x00, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, - 0x00, 0x6A, 0x00, 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, - 0xAE, 0x6C, 0xEB, 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, - 0x0A, 0xC7, 0x03, 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, - 0xA4, 0x10, 0xA8, 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, - 0x9E, 0x18, 0x02, 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, - 0xD4, 0x81, 0x01, 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, - 0x0D, 0x08, 0x05, 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, - 0x04, 0x06, 0x10, 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, - 0x93, 0x09, 0x0C, 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, - 0x0C, 0x39, 0x9A, 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, - 0xAB, 0x5B, 0x4A, 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, - 0x0D, 0x0D, 0x07, 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, - 0x0E, 0x7B, 0x04, 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, - 0x92, 0x0C, 0x0E, 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, - 0x5B, 0x03, 0x0E, 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, - 0x98, 0xBE, 0x73, 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, - 0xB0, 0x6A, 0xA3, 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, - 0xBC, 0xA5, 0x0C, 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, - 0x04, 0x32, 0x53, 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, - 0x67, 0x8E, 0xA2, 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, - 0x33, 0xA0, 0x2B, 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, - 0x0E, 0x10, 0xC0, 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, - 0x0A, 0x08, 0xF8, 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, - 0x1D, 0x8A, 0x47, 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, - 0x22, 0x22, 0x82, 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, - 0x6B, 0x50, 0xE0, 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, - 0xA3, 0x2D, 0x60, 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, - 0x94, 0x14, 0x7F, 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, - 0x05, 0x30, 0x4A, 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, - 0x53, 0x20, 0xC1, 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, - 0x10, 0x03, 0x80, 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, - 0x26, 0x0F, 0x28, 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, - 0xC6, 0x0A, 0x02, 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, - 0xA0, 0xC0, 0x28, 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, - 0x42, 0x01, 0x5A, 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, - 0x88, 0x33, 0x14, 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, - 0x6A, 0xC4, 0x80, 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, - 0x28, 0xC2, 0xE2, 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, - 0x21, 0xA4, 0x0C, 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, - 0x4A, 0x93, 0x29, 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, - 0x94, 0x0C, 0x38, 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, - 0x56, 0x74, 0x54, 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, - 0x99, 0x83, 0x8A, 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, - 0x10, 0x02, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, - 0x6A, 0x00, 0x2E, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x00, 0x40, 0x62, 0xB9, 0x28, 0x08, 0x41, 0x28, - 0x4B, 0xE9, 0xBE, 0x70, 0x2C, 0xCF, 0x74, 0x6D, 0xDF, 0xE5, 0xF1, 0x3C, 0x69, 0x52, 0x24, 0x0F, - 0x82, 0xE1, 0x60, 0x00, 0x26, 0x5A, 0xB8, 0xA4, 0x72, 0xC9, 0x94, 0xE9, 0x22, 0x12, 0xC9, 0x64, - 0xF2, 0x18, 0x04, 0xAE, 0xD7, 0x01, 0xB0, 0xD0, 0xEC, 0x7A, 0xBF, 0x31, 0x48, 0x61, 0x12, 0x95, - 0x32, 0x02, 0x8E, 0x06, 0x36, 0x70, 0x50, 0x21, 0xC1, 0xF0, 0x78, 0x72, 0x91, 0x20, 0x4B, 0x55, - 0x85, 0xF5, 0xB5, 0x81, 0xE0, 0xCA, 0xFF, 0x80, 0x32, 0x0D, 0x0F, 0x53, 0x11, 0x11, 0x04, 0x07, - 0x7A, 0x57, 0x0E, 0x04, 0x6F, 0x81, 0x8F, 0x7F, 0x0B, 0x2A, 0x06, 0x94, 0x6A, 0x8A, 0x01, 0x06, - 0x04, 0x05, 0x07, 0x0B, 0x0B, 0x44, 0x94, 0xA0, 0x43, 0x24, 0x90, 0xA4, 0x37, 0x05, 0x04, 0x96, - 0x97, 0x58, 0x45, 0x09, 0x0A, 0x0C, 0x0C, 0x0A, 0x05, 0x0D, 0xB3, 0x05, 0x0A, 0x09, 0x0C, 0x05, - 0x06, 0xA3, 0x4D, 0x9F, 0xA0, 0x0B, 0xBB, 0xA5, 0x33, 0x6D, 0x08, 0x0C, 0x89, 0xAA, 0xC7, 0x8A, - 0x07, 0xAE, 0x3E, 0xC0, 0x32, 0x10, 0x07, 0x3F, 0x2A, 0x0E, 0x8C, 0x2A, 0x08, 0xD6, 0x29, 0x0E, - 0xB9, 0xCD, 0xC1, 0x22, 0x10, 0x45, 0xD2, 0xB8, 0x07, 0x56, 0x97, 0x22, 0xC8, 0x01, 0x0D, 0x0C, - 0x3E, 0x9C, 0x25, 0xCF, 0xA7, 0x04, 0xD9, 0xE2, 0xC8, 0x03, 0xD0, 0x09, 0x04, 0xD6, 0x09, 0xBA, - 0xDC, 0x30, 0x10, 0x0B, 0x06, 0xB6, 0x2A, 0x04, 0x12, 0xDC, 0x52, 0x40, 0x90, 0x60, 0x81, 0x5C, - 0x07, 0x20, 0xA8, 0x1A, 0xD0, 0x20, 0x01, 0x35, 0x07, 0x3C, 0x1C, 0x18, 0x30, 0x87, 0xCC, 0x00, - 0x03, 0x02, 0x0F, 0x12, 0x34, 0xD8, 0xA6, 0xCF, 0x44, 0xA7, 0x8F, 0x9D, 0x0E, 0x88, 0xAC, 0x75, - 0x6B, 0x22, 0xC5, 0x4B, 0x44, 0x4E, 0xFF, 0x26, 0x63, 0x80, 0x20, 0xE3, 0x81, 0x8E, 0x5D, 0x0E, - 0xA4, 0x33, 0xA6, 0x92, 0x8D, 0x03, 0x04, 0x35, 0x2F, 0x35, 0xC0, 0x98, 0xE0, 0x25, 0x4C, 0x26, - 0x07, 0x7C, 0xE4, 0xBC, 0x82, 0x40, 0xE1, 0x50, 0x3D, 0xCA, 0x52, 0x38, 0xFA, 0x89, 0xE3, 0x47, - 0xCE, 0x1F, 0x00, 0x8E, 0xAA, 0x02, 0xC2, 0x80, 0xE9, 0x92, 0x86, 0x2A, 0x0D, 0x3C, 0xA0, 0x29, - 0x55, 0xD1, 0x00, 0x8C, 0x06, 0xAC, 0x26, 0x31, 0x80, 0xC0, 0x24, 0x32, 0x04, 0x09, 0xBA, 0x9A, - 0x1B, 0x94, 0x80, 0xA3, 0x58, 0x18, 0x5A, 0xCF, 0x1C, 0x13, 0x78, 0x69, 0x9C, 0xDA, 0x2C, 0x04, - 0x22, 0x34, 0x78, 0x6B, 0x03, 0x82, 0x02, 0x44, 0x97, 0x5E, 0xD5, 0x1D, 0x60, 0xF7, 0xEE, 0xB9, - 0x07, 0x61, 0xF9, 0xD6, 0x58, 0xC0, 0x20, 0xDB, 0x1A, 0x82, 0x0B, 0x09, 0x17, 0xBE, 0xFB, 0x55, - 0x81, 0xE2, 0x1B, 0x99, 0x10, 0x39, 0xF6, 0x2A, 0x99, 0xB0, 0x61, 0x3D, 0x0E, 0x2F, 0xDF, 0x18, - 0x94, 0x87, 0xF3, 0x00, 0x01, 0x02, 0x24, 0x7F, 0x7E, 0x8C, 0x60, 0xA9, 0x68, 0x17, 0x6D, 0xCC, - 0x62, 0x91, 0x8C, 0x1A, 0x75, 0xE7, 0x2B, 0x30, 0xBA, 0xF2, 0xF1, 0xF9, 0xDA, 0x45, 0x26, 0xAE, - 0x59, 0x4E, 0xD7, 0x4E, 0xED, 0x19, 0xF7, 0x8C, 0xA3, 0x5A, 0xF7, 0xF6, 0x16, 0xF1, 0xC3, 0x68, - 0x70, 0xE1, 0xC3, 0x8B, 0xAF, 0xA1, 0x31, 0xF4, 0xB4, 0xD2, 0xD7, 0x10, 0x60, 0xE9, 0x21, 0x3C, - 0x3C, 0xFA, 0x64, 0xE3, 0x32, 0x6A, 0xD2, 0x56, 0xF0, 0xC0, 0x0F, 0x5F, 0x3A, 0xA9, 0x02, 0x70, - 0xEF, 0x4E, 0x5C, 0x3A, 0x68, 0xD7, 0xE5, 0x54, 0x72, 0xB7, 0xF2, 0xD5, 0xBC, 0xD5, 0xA0, 0x34, - 0xD7, 0xDB, 0x6E, 0xAF, 0x5A, 0x95, 0x03, 0xDE, 0x2F, 0x98, 0x73, 0xDB, 0x70, 0x01, 0xC4, 0xF2, - 0x96, 0x45, 0xB3, 0x41, 0x67, 0x5B, 0xFF, 0x7F, 0xE6, 0x00, 0x20, 0x51, 0x0C, 0xF2, 0xD0, 0x47, - 0x9C, 0x7A, 0xEA, 0x91, 0x07, 0x20, 0x4C, 0x05, 0xC8, 0xA5, 0x9E, 0x70, 0xA7, 0x31, 0x78, 0x92, - 0x24, 0x89, 0xB9, 0x70, 0x4C, 0x26, 0x41, 0x04, 0xA4, 0x40, 0x03, 0x19, 0x32, 0x72, 0xC8, 0x85, - 0x1D, 0xB9, 0x92, 0x20, 0x7F, 0xEE, 0x9D, 0x94, 0xE1, 0x49, 0x0C, 0xDD, 0x84, 0x16, 0x79, 0x11, - 0xF4, 0x11, 0x0B, 0x42, 0x62, 0x41, 0x70, 0xCB, 0x73, 0x1E, 0x0E, 0xE5, 0x20, 0x70, 0x7B, 0x10, - 0x40, 0x58, 0x5E, 0xC4, 0xE4, 0x23, 0x42, 0x02, 0x86, 0x34, 0xA2, 0x98, 0x24, 0x0A, 0x00, 0x19, - 0x63, 0x4E, 0xFD, 0x10, 0x43, 0x93, 0x32, 0x79, 0xF1, 0x90, 0x42, 0x88, 0x2E, 0x2C, 0xF0, 0x80, - 0x21, 0x0F, 0x30, 0x00, 0x5F, 0x30, 0x62, 0xF4, 0xB1, 0x61, 0x90, 0x47, 0x39, 0x18, 0xCB, 0x3F, - 0xEF, 0xF8, 0x60, 0xC0, 0x2F, 0x36, 0x3C, 0xB1, 0x22, 0x53, 0x99, 0x20, 0x90, 0x08, 0x9A, 0x5D, - 0x79, 0xD9, 0x80, 0x00, 0x29, 0xB4, 0xD6, 0x04, 0x59, 0x2C, 0xFC, 0x24, 0x13, 0x2A, 0x78, 0x76, - 0xF5, 0x95, 0x03, 0x0C, 0xA0, 0xA6, 0xA3, 0x17, 0x6E, 0x3D, 0xB2, 0xC0, 0x0F, 0x0A, 0x10, 0xB9, - 0xDA, 0x39, 0x08, 0x08, 0x90, 0x86, 0x00, 0x4E, 0x2E, 0x17, 0x86, 0x3B, 0xA5, 0x4D, 0xAA, 0x87, - 0x42, 0xAF, 0x0C, 0xE2, 0x00, 0xA6, 0x63, 0x8A, 0xF6, 0xA8, 0x0A, 0x91, 0x06, 0xF0, 0x4B, 0x9E, - 0xCE, 0x29, 0xF2, 0x17, 0x4B, 0x96, 0x16, 0x50, 0xA9, 0x9F, 0x9A, 0x02, 0x50, 0x00, 0x23, 0x81, - 0x9E, 0x1A, 0x41, 0x94, 0x47, 0x31, 0x10, 0xE6, 0x01, 0xD3, 0x98, 0xA5, 0x10, 0x2A, 0x2D, 0xF1, - 0x21, 0x46, 0x40, 0xB5, 0xDA, 0x8A, 0xD8, 0x02, 0x0D, 0x21, 0x9A, 0x80, 0x99, 0x98, 0xE0, 0x63, - 0xCE, 0x10, 0x01, 0xC8, 0x7A, 0xC2, 0x79, 0x11, 0x50, 0x65, 0x26, 0x2B, 0x9F, 0x64, 0xF9, 0xD1, - 0xE8, 0x93, 0x29, 0x32, 0x30, 0x84, 0x03, 0x0A, 0x28, 0x04, 0x2C, 0x46, 0x0B, 0x5C, 0x91, 0xAE, - 0x22, 0x64, 0x21, 0xB0, 0x13, 0x30, 0x99, 0xDC, 0xB4, 0xD3, 0xB3, 0xE9, 0x00, 0x50, 0x6A, 0xB2, - 0x00, 0xB4, 0xD1, 0x42, 0x50, 0x42, 0x00, 0xF6, 0x55, 0x51, 0xAA, 0x6A, 0x82, 0x09, 0x22, 0x08, - 0x38, 0xB0, 0x4D, 0xB7, 0x88, 0x2C, 0x60, 0x0D, 0x8B, 0xF8, 0xBE, 0x90, 0x89, 0x02, 0x0E, 0xE0, - 0x03, 0x81, 0xC0, 0x99, 0xDC, 0xAA, 0x2A, 0x44, 0xB3, 0xF8, 0xE9, 0x16, 0x04, 0x08, 0xD8, 0xC2, - 0x1C, 0x97, 0x0D, 0xCB, 0xE0, 0xC9, 0x28, 0x3A, 0x28, 0xF3, 0x5F, 0x6B, 0xBF, 0xD9, 0x72, 0xC4, - 0x62, 0x1D, 0x7F, 0x1B, 0x72, 0x0D, 0xCA, 0xBC, 0xD4, 0x86, 0x2D, 0x3E, 0xB9, 0xBC, 0x5C, 0x08, - 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, 0x6A, 0x00, - 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, 0xAE, 0x6C, 0xEB, - 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, 0x0A, 0xC7, 0x03, - 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, 0xA4, 0x10, 0xA8, - 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, 0x9E, 0x18, 0x02, - 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, 0xD4, 0x81, 0x01, - 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, 0x0D, 0x08, 0x05, - 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, 0x04, 0x06, 0x10, - 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, 0x93, 0x09, 0x0C, - 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, 0x0C, 0x39, 0x9A, - 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, 0xAB, 0x5B, 0x4A, - 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, 0x0D, 0x0D, 0x07, - 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, 0x0E, 0x7B, 0x04, - 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, 0x92, 0x0C, 0x0E, - 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, 0x5B, 0x03, 0x0E, - 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, 0x98, 0xBE, 0x73, - 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, 0xB0, 0x6A, 0xA3, - 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, 0xBC, 0xA5, 0x0C, - 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, 0x04, 0x32, 0x53, - 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, 0x67, 0x8E, 0xA2, - 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, 0x33, 0xA0, 0x2B, - 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, 0x0E, 0x10, 0xC0, - 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, 0x0A, 0x08, 0xF8, - 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, 0x1D, 0x8A, 0x47, - 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, 0x22, 0x22, 0x82, - 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, 0x6B, 0x50, 0xE0, - 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, 0xA3, 0x2D, 0x60, - 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, 0x94, 0x14, 0x7F, - 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, 0x05, 0x30, 0x4A, - 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, 0x53, 0x20, 0xC1, - 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, 0x10, 0x03, 0x80, - 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, 0x26, 0x0F, 0x28, - 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, 0xC6, 0x0A, 0x02, - 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, 0xA0, 0xC0, 0x28, - 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, 0x42, 0x01, 0x5A, - 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, 0x88, 0x33, 0x14, - 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, 0x6A, 0xC4, 0x80, - 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, 0x28, 0xC2, 0xE2, - 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, 0x21, 0xA4, 0x0C, - 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, 0x4A, 0x93, 0x29, - 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, 0x94, 0x0C, 0x38, - 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, 0x56, 0x74, 0x54, - 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, 0x99, 0x83, 0x8A, - 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, 0x10, 0x02, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, - 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, - 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, - 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, - 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, - 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, - 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, - 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, - 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, - 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, - 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, - 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, - 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, - 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, - 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, - 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, - 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, - 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, - 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, - 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, - 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, - 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, - 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, - 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, - 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, - 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, - 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, - 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, - 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, - 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, - 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, - 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, - 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, - 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, - 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, - 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, - 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, - 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, - 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, - 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, - 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, - 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, - 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, - 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, - 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, - 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, - 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, - 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, - 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, - 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, - 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, - 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, - 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, - 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, - 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, - 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, - 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, - 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, - 0x0D, 0x21, 0x00, 0x00, 0x3B}; +#include + +static const uint8_t firebase_png[] PROGMEM = { + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x02, 0x58, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9A, 0x76, 0x82, + 0x70, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, + 0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61, 0x05, 0x00, 0x00, + 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01, 0xC7, + 0x6F, 0xA8, 0x64, 0x00, 0x00, 0x55, 0x14, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5E, 0xED, 0xDD, 0x59, + 0x90, 0x1D, 0xF5, 0x81, 0xE7, 0x7B, 0x3F, 0xF4, 0xC3, 0x84, 0x91, 0x40, 0x6E, 0xEF, 0xC6, 0x8B, + 0x30, 0x92, 0x4A, 0x1B, 0x58, 0x98, 0xCD, 0xA0, 0xA5, 0x4A, 0x12, 0x20, 0x6C, 0x9A, 0xB6, 0xBA, + 0x01, 0x63, 0x4F, 0x3F, 0x8C, 0x1E, 0x26, 0xC2, 0xF7, 0xE5, 0xC6, 0x25, 0xE2, 0xDE, 0x97, 0x3B, + 0x7D, 0x67, 0xAC, 0x6E, 0x63, 0x63, 0x83, 0x8D, 0xBC, 0xB1, 0x99, 0xA5, 0x10, 0x08, 0xED, 0x52, + 0x69, 0xAD, 0x92, 0xA0, 0xBB, 0xAB, 0xA7, 0xED, 0x6E, 0x77, 0xB7, 0x81, 0x42, 0x9B, 0x99, 0x89, + 0x89, 0xDB, 0x9A, 0xB9, 0x0E, 0x2F, 0x2C, 0x76, 0x61, 0x16, 0x49, 0x85, 0xA4, 0xFC, 0xDF, 0xFF, + 0x3F, 0x4F, 0xE6, 0xA9, 0x3C, 0x79, 0x7E, 0xE7, 0x9C, 0xCC, 0x3C, 0x99, 0x75, 0xCE, 0xC9, 0xFA, + 0x7E, 0x22, 0x7E, 0xA1, 0x6E, 0x2F, 0x42, 0xC2, 0x94, 0xE2, 0xFF, 0x8D, 0x7F, 0x65, 0x9E, 0xF7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x82, 0x79, 0x6E, 0xCD, 0x80, 0xBF, 0xC3, 0x5F, 0x58, 0x12, 0xFC, + 0x4B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x1F, 0x73, 0x78, 0xCD, 0x3A, 0xEF, 0xB9, 0x35, 0x63, 0xE6, + 0xB9, 0x9B, 0x4D, 0x75, 0xCF, 0xAE, 0xF1, 0xE7, 0x3D, 0x7B, 0xD3, 0xA0, 0x0B, 0x92, 0xE0, 0x3F, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x98, 0x91, 0x35, 0xB3, 0xEB, 0xC2, 0x23, 0x12, 0x1F, 0xD1, + 0x79, 0x87, 0xD7, 0x6C, 0x08, 0xFE, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x8E, 0xFB, 0x16, 0x2B, + 0xEF, 0xD9, 0x35, 0xE3, 0x95, 0xE0, 0xB8, 0xD1, 0x98, 0x03, 0x57, 0x19, 0xB3, 0x7B, 0xAE, 0x31, + 0x3B, 0x3E, 0x65, 0xCC, 0xB6, 0x8F, 0x1A, 0xB3, 0xF3, 0xD3, 0xC6, 0x0C, 0x2D, 0x34, 0x66, 0x78, + 0xD9, 0x64, 0x84, 0x3C, 0x7B, 0xD3, 0x60, 0xF0, 0x5F, 0x07, 0x00, 0x00, 0x00, 0x80, 0xE4, 0xAA, + 0x37, 0x1F, 0x2E, 0x3C, 0x76, 0x7C, 0xC2, 0x98, 0xED, 0x1F, 0xAB, 0x84, 0x87, 0xDA, 0x2E, 0x1B, + 0x26, 0x87, 0x6F, 0xA8, 0x84, 0xC8, 0xA1, 0x9B, 0xD6, 0x06, 0x3F, 0x05, 0x00, 0x00, 0x00, 0x00, + 0xB4, 0xE6, 0x9E, 0xF9, 0xF0, 0xE3, 0x63, 0xCF, 0xA2, 0x4A, 0x78, 0x34, 0x8B, 0x8F, 0x70, 0xDB, + 0x3F, 0x6E, 0xCC, 0xC8, 0x0A, 0xF7, 0xAD, 0x58, 0xE3, 0x66, 0xB4, 0x7F, 0x56, 0xF0, 0x53, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x73, 0xDE, 0x73, 0x37, 0x9F, 0x34, 0xFB, 0xAF, 0x48, 0x1E, 0x1F, 0xE1, + 0x76, 0x5E, 0x62, 0xCC, 0xE1, 0xD5, 0x76, 0x37, 0xAE, 0x0F, 0x7E, 0x2A, 0x00, 0x00, 0x00, 0x00, + 0x68, 0xCC, 0x3D, 0x78, 0x6E, 0x0E, 0xAF, 0x4A, 0x1F, 0x1F, 0xFE, 0x3E, 0x62, 0xCC, 0xBE, 0xCF, + 0x18, 0xEF, 0xF0, 0x4D, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x68, 0xCD, 0xFF, 0x8C, 0x8F, 0xBD, + 0x97, 0x67, 0x8B, 0x0F, 0xB7, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x20, 0x19, 0x1B, + 0x20, 0xEB, 0xCD, 0xAE, 0x4F, 0xC7, 0xE2, 0xA2, 0xD5, 0x82, 0xF8, 0x08, 0xB7, 0x67, 0xB1, 0x31, + 0xCF, 0xDE, 0x64, 0xDC, 0x6D, 0x4A, 0xF0, 0xD3, 0x02, 0x00, 0x00, 0x00, 0x40, 0x3D, 0xEF, 0xB9, + 0x9B, 0x07, 0x75, 0x64, 0x34, 0x5A, 0x2C, 0x3E, 0xC2, 0x1D, 0x1A, 0xE0, 0xB5, 0xBC, 0x00, 0x00, + 0x00, 0x00, 0x9A, 0xF3, 0x0E, 0x2E, 0x1B, 0xD5, 0xA1, 0xA1, 0x26, 0xC2, 0x23, 0xDC, 0xD0, 0x02, + 0x6E, 0x41, 0x00, 0x00, 0x00, 0x00, 0x34, 0xE7, 0x1D, 0xB8, 0x76, 0x5C, 0xC7, 0x46, 0x7C, 0x22, + 0x3A, 0xE2, 0x1B, 0x59, 0x6E, 0xBC, 0xC3, 0x37, 0x8E, 0x06, 0x3F, 0x35, 0x00, 0x00, 0x00, 0x00, + 0x4C, 0x72, 0x6F, 0xAE, 0x32, 0xFB, 0x96, 0xD8, 0x78, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x0D, 0xB5, + 0x5D, 0x73, 0x2A, 0xB7, 0x20, 0xCF, 0xAD, 0x19, 0x08, 0xFE, 0x12, 0x00, 0x00, 0x00, 0x00, 0x50, + 0xE1, 0xBF, 0x01, 0x6B, 0x77, 0x9F, 0x8D, 0x07, 0x15, 0x1D, 0xE1, 0x44, 0x68, 0x34, 0xDB, 0xF0, + 0xF5, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xE7, 0x7F, 0x02, 0xFA, 0xAE, 0xB9, 0x36, 0x1C, + 0x54, 0x78, 0xB8, 0x89, 0xC0, 0x68, 0xB5, 0x5D, 0x97, 0x1A, 0xF3, 0xEC, 0x8D, 0xC6, 0x3C, 0xB7, + 0x9A, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x93, 0x6C, 0x80, 0xAC, 0xD7, 0xE1, 0xE1, 0x26, 0xE2, + 0xA2, 0xE5, 0x3E, 0x5C, 0xD9, 0x81, 0xAB, 0x8C, 0xF7, 0xEC, 0x0D, 0x27, 0x83, 0xBF, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0xBC, 0xE7, 0x3D, 0xDE, 0xF0, 0x8A, 0x06, 0x6F, 0xC0, 0x52, 0x71, 0xD1, 0x6A, + 0x41, 0x7C, 0xB8, 0xED, 0xF8, 0x44, 0xE5, 0x16, 0xE4, 0xF0, 0x8D, 0xEB, 0x82, 0xBF, 0x14, 0x00, + 0x00, 0x00, 0x80, 0xE9, 0xCE, 0x3B, 0x70, 0xFD, 0xC9, 0xDC, 0xE3, 0x23, 0x1C, 0xB7, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xA2, 0xCC, 0xFE, 0x2B, 0x6D, 0x2C, 0x14, 0x10, 0x1F, 0x6E, 0xEE, 0x16, 0xE4, + 0xF0, 0x2A, 0x77, 0x0B, 0xB2, 0x3E, 0xF8, 0xCB, 0x01, 0x00, 0x00, 0x00, 0x98, 0xAE, 0x6C, 0x18, + 0x2C, 0x31, 0x7B, 0x2E, 0xB3, 0xB1, 0x50, 0x40, 0x7C, 0x84, 0xDB, 0x77, 0xB9, 0x7B, 0x23, 0xD6, + 0xB8, 0x7B, 0xDD, 0x6F, 0xF0, 0x97, 0x05, 0x00, 0x00, 0x00, 0x30, 0x1D, 0x99, 0x43, 0x37, 0xAD, + 0x9D, 0x7C, 0x03, 0x96, 0x8A, 0x8B, 0x56, 0x13, 0xC1, 0x11, 0xDF, 0xF6, 0x8F, 0x71, 0x0B, 0x02, + 0x00, 0x00, 0x00, 0x20, 0x78, 0x03, 0xD6, 0xF6, 0x8F, 0xDB, 0x50, 0x50, 0x71, 0xD1, 0x6A, 0x22, + 0x36, 0x1A, 0x8D, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xB3, 0x37, 0x0D, 0xEA, 0xB8, 0x68, + 0x35, 0x11, 0x19, 0xAD, 0x76, 0xA8, 0xDF, 0x3D, 0x90, 0x3E, 0x18, 0xFC, 0xA5, 0x01, 0x00, 0x00, + 0x00, 0x4C, 0x37, 0xDE, 0x81, 0x6B, 0x46, 0x75, 0x60, 0x34, 0x9B, 0x88, 0x8B, 0x56, 0xDB, 0xFA, + 0x21, 0x63, 0x86, 0xE6, 0x57, 0x5E, 0xCB, 0x3B, 0xB2, 0x66, 0x76, 0xF0, 0x97, 0x07, 0x00, 0x00, + 0x00, 0x30, 0x9D, 0x98, 0x03, 0x57, 0xDB, 0x40, 0x50, 0x91, 0xD1, 0x68, 0x22, 0x2E, 0x5A, 0xCD, + 0xC5, 0x47, 0x38, 0x6E, 0x41, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC9, 0xDD, 0x44, 0x98, 0x7D, 0x9F, + 0xB1, 0x91, 0xA0, 0x42, 0x43, 0x4D, 0xC4, 0x45, 0xAB, 0x45, 0xE3, 0xC3, 0x6D, 0xF7, 0xDC, 0xCA, + 0x2D, 0xC8, 0x73, 0xAB, 0x07, 0x82, 0x5F, 0x06, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC0, 0x3C, 0xB7, + 0x66, 0xC0, 0xEC, 0x9E, 0x67, 0x43, 0x41, 0xC5, 0x46, 0x7C, 0x22, 0x2E, 0x5A, 0x2D, 0x1E, 0x1F, + 0xE1, 0x86, 0xAF, 0x73, 0x0F, 0xA4, 0x8F, 0x06, 0xBF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x81, + 0xF7, 0xEC, 0x4D, 0x77, 0x99, 0x9D, 0x97, 0xD8, 0x58, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x8B, 0x56, + 0x53, 0xE1, 0x11, 0x6E, 0xD7, 0xA7, 0xB9, 0x05, 0x01, 0x00, 0x00, 0x00, 0xA6, 0x1B, 0xEF, 0xF0, + 0x8D, 0x1B, 0x74, 0x70, 0x44, 0x27, 0xE2, 0xA2, 0xD5, 0x54, 0x74, 0xC4, 0xC7, 0x2D, 0x08, 0x00, + 0x00, 0x00, 0x30, 0xBD, 0x78, 0x07, 0xAF, 0x6F, 0xF1, 0x06, 0x2C, 0x11, 0x17, 0xAD, 0xA6, 0x62, + 0x43, 0xCD, 0x7D, 0xF6, 0x88, 0xBB, 0x05, 0x39, 0x7C, 0xE3, 0xBA, 0xE0, 0x97, 0x03, 0x00, 0x00, + 0x00, 0xA0, 0xCC, 0xBC, 0x03, 0xD7, 0x9D, 0xD4, 0xE1, 0xE1, 0x26, 0xE2, 0xA2, 0xD5, 0x54, 0x68, + 0x34, 0xDB, 0xFE, 0x2B, 0xDD, 0x1B, 0xB1, 0x4E, 0x06, 0xBF, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x65, + 0xD6, 0xF8, 0x0D, 0x58, 0x22, 0x2E, 0x5A, 0x4D, 0x05, 0x46, 0xAB, 0xB9, 0x5B, 0x90, 0xC3, 0x37, + 0x70, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x94, 0x9D, 0xFF, 0x06, 0xAC, 0xA1, 0x05, 0x36, 0x1E, 0x3A, + 0x14, 0x1F, 0xFE, 0x3E, 0x68, 0x5C, 0x04, 0x79, 0x87, 0x6E, 0x18, 0x37, 0xA3, 0xFD, 0xB3, 0x82, + 0x5F, 0x1A, 0x00, 0x00, 0x00, 0x80, 0xB2, 0x71, 0xB7, 0x0E, 0x66, 0xD7, 0x1C, 0x1B, 0x10, 0x1D, + 0x8C, 0x0F, 0x37, 0xF7, 0xD7, 0x3D, 0xB4, 0xD2, 0x98, 0xC3, 0xAB, 0xD7, 0x07, 0xBF, 0x34, 0x00, + 0x00, 0x00, 0x00, 0x65, 0x63, 0x03, 0x64, 0xBD, 0xD9, 0x7E, 0x71, 0x25, 0x00, 0x3A, 0x15, 0x1F, + 0xE1, 0xF6, 0x5E, 0xC6, 0x2D, 0x08, 0x00, 0x00, 0x00, 0x50, 0x66, 0xDE, 0xC8, 0xCA, 0xA1, 0xAE, + 0x88, 0x0F, 0xB7, 0xE0, 0x16, 0xC4, 0x3B, 0xBC, 0x7A, 0x43, 0xF0, 0xCB, 0x03, 0x00, 0x00, 0x00, + 0x50, 0x26, 0xDE, 0xC1, 0x6B, 0xC7, 0xBA, 0x22, 0x3E, 0xC2, 0xED, 0xEE, 0xAB, 0x3C, 0x90, 0x3E, + 0xB2, 0x66, 0x76, 0xF0, 0x4B, 0x04, 0x00, 0x00, 0x00, 0x50, 0x16, 0x66, 0xFF, 0x67, 0x75, 0x5C, + 0xB4, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0xD1, 0x11, 0xDF, 0xC8, 0x0A, 0xE3, 0x1D, 0x5A, 0x3D, 0x18, + 0xFC, 0x12, 0x01, 0x00, 0x00, 0x00, 0x94, 0x81, 0xBB, 0x65, 0x30, 0xFB, 0x2E, 0xD7, 0x81, 0xD1, + 0x6C, 0x32, 0x2C, 0x92, 0x4C, 0xC4, 0x86, 0x1A, 0xB7, 0x20, 0x00, 0x00, 0x00, 0x40, 0xF9, 0x98, + 0xE7, 0x56, 0x0F, 0x98, 0x5D, 0x97, 0xEA, 0xC8, 0x68, 0x34, 0x19, 0x16, 0x49, 0x26, 0x42, 0xA3, + 0xD9, 0x0E, 0x7E, 0xCE, 0x78, 0x87, 0x6F, 0x18, 0x0D, 0x7E, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x7A, + 0x9D, 0xFF, 0x06, 0xAC, 0x1D, 0x9F, 0xD0, 0xA1, 0xA1, 0x26, 0xC3, 0x22, 0xC9, 0x44, 0x60, 0xB4, + 0xDA, 0xCE, 0x4B, 0x82, 0x5B, 0x90, 0xD5, 0x03, 0xC1, 0x2F, 0x17, 0x00, 0x00, 0x00, 0x40, 0x2F, + 0xF3, 0x9E, 0xBD, 0x61, 0x50, 0x86, 0x86, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0x71, 0x91, 0x74, 0x07, + 0xAF, 0x35, 0xDE, 0xE1, 0x55, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x65, 0xE0, 0x1D, 0xBC, 0x6E, + 0x54, 0xC6, 0x46, 0x7C, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, 0x6D, 0xF9, 0x80, 0x31, 0x3B, + 0x67, 0xBB, 0x0F, 0x26, 0x34, 0xE6, 0xD0, 0xAA, 0xB5, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, 0x40, + 0xAF, 0xF2, 0x0E, 0x5C, 0x33, 0x2E, 0x83, 0x23, 0x3A, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, + 0x5C, 0x7C, 0x84, 0xDB, 0x77, 0x85, 0xFB, 0x5C, 0x90, 0x93, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, + 0x40, 0x2F, 0x72, 0x9F, 0x36, 0xDE, 0xF2, 0x0D, 0x58, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, + 0x45, 0xE3, 0xC3, 0x6D, 0xDB, 0xC7, 0x2A, 0xB7, 0x20, 0x87, 0x57, 0xAD, 0x0B, 0x7E, 0xE9, 0x00, + 0x00, 0x00, 0x00, 0x7A, 0x8D, 0xFF, 0x06, 0xAC, 0xDD, 0x73, 0xEB, 0xA3, 0x23, 0x9C, 0x0C, 0x8B, + 0x24, 0x13, 0x51, 0x91, 0x74, 0xF1, 0xF8, 0x08, 0xC7, 0x2D, 0x08, 0x00, 0x00, 0x00, 0xD0, 0xDB, + 0xCC, 0xE1, 0x1B, 0xD7, 0x35, 0x7C, 0x05, 0xAF, 0x0C, 0x8B, 0x24, 0x13, 0x51, 0x91, 0x74, 0x2A, + 0x3C, 0xC2, 0x6D, 0xB5, 0xBF, 0xA6, 0x43, 0x03, 0xEE, 0x26, 0x64, 0x7D, 0xF0, 0xCB, 0x07, 0x00, + 0x00, 0x00, 0xD0, 0x4B, 0xFC, 0x57, 0xF0, 0xF6, 0x42, 0x7C, 0x84, 0xDB, 0xB3, 0xD8, 0x7D, 0x3A, + 0xFA, 0xB8, 0xFB, 0xD6, 0xB1, 0xE0, 0xB7, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x57, 0x78, 0xC3, 0xCB, + 0xEB, 0xDF, 0x80, 0x25, 0xC3, 0x22, 0xC9, 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x0D, 0x35, 0x6E, 0x41, + 0x00, 0x00, 0x00, 0x80, 0xDE, 0xE5, 0x1D, 0xBC, 0x76, 0xAC, 0x67, 0xE2, 0x23, 0xDC, 0x9E, 0x45, + 0xC6, 0x3B, 0xB4, 0x6A, 0xDC, 0x8C, 0xF4, 0xCF, 0x0E, 0x7E, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x7A, + 0x81, 0xD9, 0x7F, 0x45, 0x6F, 0xC5, 0x87, 0xBF, 0xF7, 0x1B, 0x33, 0xB2, 0xCC, 0x46, 0xC8, 0xCA, + 0xC1, 0xE0, 0xB7, 0x01, 0x00, 0x00, 0x00, 0xA0, 0xDB, 0x99, 0xC3, 0x37, 0x2E, 0x71, 0xB7, 0x09, + 0x3D, 0x17, 0x1F, 0x6E, 0xEE, 0xCD, 0x5D, 0x87, 0x57, 0xD9, 0x10, 0xE9, 0xCD, 0x5B, 0x10, 0xF7, + 0xEB, 0xB6, 0x1B, 0x08, 0xC6, 0x4D, 0x0E, 0x00, 0x00, 0x00, 0xCA, 0xCF, 0x1C, 0xBA, 0x69, 0xAD, + 0xFF, 0x06, 0x2C, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x5A, 0x10, 0x1F, + 0xE1, 0x7A, 0xEC, 0x16, 0xC4, 0xFF, 0xCC, 0x95, 0x91, 0xFE, 0xF5, 0xDE, 0xA1, 0x81, 0x93, 0xFE, + 0x73, 0x2C, 0x91, 0xF9, 0xFF, 0x9A, 0xFD, 0xF7, 0x78, 0xB8, 0x1E, 0x00, 0x00, 0x00, 0xA5, 0x55, + 0x79, 0x03, 0xD6, 0x47, 0x6D, 0x10, 0xA8, 0xB8, 0x68, 0x35, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, + 0xD5, 0x62, 0xF1, 0xE1, 0xB6, 0xF3, 0x53, 0xC1, 0x2D, 0xC8, 0xEA, 0x81, 0xE0, 0xB7, 0xD4, 0xB5, + 0xCC, 0xA1, 0xFE, 0xB5, 0xDE, 0xC8, 0xC0, 0x78, 0x3C, 0x3C, 0xE2, 0xAB, 0xFC, 0x67, 0xFA, 0xD7, + 0x06, 0xFF, 0x35, 0x00, 0x00, 0x00, 0xA0, 0x3C, 0xBC, 0x67, 0x6F, 0x18, 0xD4, 0x71, 0xD1, 0x6A, + 0x22, 0x2A, 0x92, 0x4E, 0xC6, 0x45, 0xAB, 0x89, 0xF8, 0x08, 0x77, 0xF0, 0x1A, 0xE3, 0x1D, 0x5E, + 0x39, 0x1A, 0xFC, 0x96, 0xBA, 0x92, 0x19, 0xE9, 0x5F, 0x57, 0x8D, 0x8C, 0x91, 0xE5, 0xFE, 0x43, + 0xF4, 0x66, 0xC7, 0xC7, 0x6B, 0xE7, 0xFE, 0x35, 0xF7, 0xEF, 0xF9, 0xFF, 0x99, 0x7E, 0x37, 0x3E, + 0xF1, 0x1D, 0x00, 0x00, 0x00, 0xE5, 0xE2, 0x1D, 0xB8, 0x7A, 0x54, 0x07, 0x46, 0xB3, 0x89, 0xA8, + 0x48, 0x3A, 0x19, 0x17, 0xAD, 0x26, 0xA2, 0x23, 0xBA, 0x2E, 0xBF, 0x05, 0xB1, 0x21, 0x31, 0xBB, + 0x7A, 0xF3, 0x31, 0x34, 0xBF, 0xF2, 0x6B, 0xDE, 0x3C, 0x4B, 0xCF, 0xFD, 0x7B, 0x43, 0x7D, 0x7E, + 0x80, 0x78, 0x23, 0x2B, 0x78, 0xCB, 0x17, 0x00, 0x00, 0x00, 0xCA, 0xC5, 0xEC, 0xBF, 0xD2, 0x86, + 0x81, 0x8A, 0x8C, 0x46, 0x13, 0x51, 0x91, 0x74, 0x32, 0x2E, 0x5A, 0x2D, 0x12, 0x1A, 0xCD, 0xE6, + 0x6E, 0x41, 0x0E, 0xAD, 0x1A, 0x0B, 0x7E, 0x5B, 0x5D, 0xC5, 0xC6, 0xC7, 0x90, 0x1F, 0x1F, 0xBB, + 0x3E, 0xAD, 0xA3, 0xA3, 0x66, 0x17, 0x55, 0xB6, 0xF3, 0x92, 0x4A, 0x84, 0x0C, 0xAF, 0xE8, 0xEA, + 0x9B, 0x1D, 0x00, 0x00, 0x00, 0x20, 0x31, 0xFF, 0x81, 0xE8, 0xBD, 0x97, 0xDB, 0x38, 0x50, 0xA1, + 0xA1, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x9A, 0x08, 0x8D, 0x46, 0x73, 0xCF, 0xB1, 0xB8, + 0x5B, 0x90, 0xC3, 0xAB, 0xBA, 0xEA, 0xDB, 0x96, 0x6C, 0x44, 0x0C, 0xF8, 0xF1, 0xE1, 0xDE, 0xD8, + 0x25, 0x83, 0x23, 0xBA, 0x20, 0x3E, 0x62, 0x11, 0xE2, 0x7E, 0x8E, 0xE0, 0xA7, 0x03, 0x00, 0x00, + 0x00, 0x7A, 0x97, 0x79, 0x6E, 0xF5, 0x80, 0x7F, 0x30, 0x96, 0xB1, 0x11, 0x9F, 0x88, 0x8A, 0xA4, + 0x93, 0x71, 0xD1, 0x6A, 0x22, 0x32, 0x5A, 0x6D, 0xDF, 0x12, 0xE3, 0x1D, 0x5E, 0x75, 0x32, 0xF8, + 0xED, 0x75, 0x05, 0xEF, 0xD0, 0xC0, 0xA8, 0x39, 0x70, 0x55, 0x10, 0x18, 0xCD, 0x16, 0x8B, 0x8F, + 0x70, 0xFB, 0xAF, 0xE4, 0x16, 0x04, 0x00, 0x00, 0x00, 0xE5, 0xE0, 0x3D, 0x7B, 0xC3, 0x5D, 0x66, + 0xC7, 0xA7, 0x6C, 0x24, 0xA8, 0xE0, 0x88, 0x4E, 0x44, 0x45, 0xD2, 0xC9, 0xB8, 0x68, 0x35, 0x11, + 0x17, 0x49, 0x16, 0xDC, 0x82, 0x78, 0x87, 0x56, 0xDD, 0x15, 0xFC, 0x16, 0x3B, 0xAA, 0x7A, 0xFB, + 0xE1, 0x1E, 0x30, 0x97, 0xD1, 0x11, 0x4E, 0x84, 0x47, 0xB8, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, + 0x00, 0x80, 0x72, 0xF0, 0x0E, 0xDF, 0xB8, 0x41, 0x07, 0x47, 0x74, 0x22, 0x2A, 0x92, 0x4E, 0xC6, + 0x45, 0xAB, 0x89, 0xB0, 0x48, 0xB3, 0x3D, 0x0B, 0x8D, 0x37, 0xB2, 0x72, 0xBC, 0x1B, 0x3E, 0x4B, + 0x23, 0xD9, 0xED, 0x87, 0x88, 0x8E, 0xF8, 0xB8, 0x05, 0x01, 0x00, 0x00, 0x40, 0x19, 0x78, 0x07, + 0xAF, 0x6B, 0xF1, 0x06, 0x2C, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, 0xD5, 0x44, 0x50, 0xA4, 0xDA, + 0x1F, 0x57, 0xFE, 0xDA, 0x23, 0x2B, 0xEC, 0x56, 0xAE, 0x0F, 0x7E, 0x9B, 0x1D, 0xE1, 0x3E, 0xC7, + 0xC3, 0xBF, 0xFD, 0x70, 0x7F, 0x1F, 0x65, 0x78, 0xB8, 0x89, 0xD8, 0x50, 0xF3, 0x7F, 0x4F, 0xFD, + 0xC6, 0x1C, 0xE4, 0xB3, 0x41, 0x00, 0x00, 0x00, 0xD0, 0xC3, 0xBC, 0x03, 0x9F, 0x3B, 0x59, 0x1F, + 0x1D, 0xE1, 0x22, 0x31, 0x91, 0x76, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xD9, 0xF8, 0x08, + 0xD7, 0x05, 0xB7, 0x20, 0xFE, 0xA7, 0x9A, 0xBB, 0x07, 0xFC, 0x65, 0x78, 0xB8, 0x89, 0xD0, 0x68, + 0xB6, 0xBD, 0x97, 0xB9, 0x5B, 0x90, 0xAE, 0x7A, 0xBE, 0x05, 0x00, 0x00, 0x00, 0x48, 0xA5, 0xF1, + 0x1B, 0xB0, 0x44, 0x54, 0x24, 0x9D, 0x8C, 0x8B, 0x56, 0x53, 0x41, 0x91, 0x66, 0x91, 0xF8, 0x70, + 0x73, 0xBF, 0x8E, 0xE1, 0xA5, 0xEE, 0x13, 0xC5, 0x37, 0x04, 0xBF, 0xD5, 0x29, 0x65, 0xC2, 0x0F, + 0x1D, 0x74, 0x7F, 0x2F, 0xF3, 0x88, 0x0F, 0x37, 0xF7, 0x7B, 0xF2, 0x9F, 0x05, 0x59, 0xCE, 0x87, + 0x13, 0x02, 0x00, 0x00, 0xA0, 0xF7, 0xF8, 0x6F, 0xC0, 0x72, 0x1F, 0x8A, 0x57, 0xB6, 0xF8, 0x08, + 0xB7, 0x6B, 0x8E, 0x31, 0x87, 0x56, 0xBA, 0x43, 0xFB, 0x94, 0x7F, 0x90, 0x5F, 0xF3, 0xDB, 0x0F, + 0x11, 0x17, 0x49, 0xB7, 0x67, 0xB1, 0xF1, 0x86, 0x97, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x80, 0xDE, + 0x63, 0x0E, 0xDD, 0xB4, 0xD6, 0xFF, 0x60, 0xBC, 0x32, 0xC6, 0x47, 0x38, 0x77, 0x0B, 0x72, 0x68, + 0xE5, 0x60, 0xF0, 0x5B, 0x9E, 0x12, 0xCD, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0xDD, 0x33, 0x17, 0xDA, + 0xDF, 0x93, 0xFD, 0x7B, 0x66, 0x7F, 0x4F, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0xE7, 0x98, 0xC3, + 0x37, 0xAE, 0xF7, 0x5F, 0x5B, 0x5B, 0xD6, 0xF8, 0x70, 0x0B, 0x6F, 0x41, 0x0E, 0xF7, 0x2F, 0x09, + 0x7E, 0xDB, 0x85, 0x72, 0xCF, 0x9C, 0xF8, 0xB7, 0x1F, 0xEE, 0x66, 0x29, 0xEF, 0xF8, 0x08, 0xB7, + 0x7B, 0x9E, 0xF1, 0x46, 0x96, 0x8F, 0x9B, 0xA1, 0xCE, 0xBF, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, + 0xCC, 0x1B, 0x59, 0x39, 0x54, 0xEA, 0xF8, 0x08, 0x77, 0xE0, 0x6A, 0x77, 0x0B, 0x32, 0x25, 0xAF, + 0xB0, 0x35, 0x23, 0xFD, 0xEB, 0xCD, 0xC8, 0x72, 0xFB, 0xD7, 0xB5, 0xBF, 0xC6, 0x22, 0xE2, 0xC3, + 0x6D, 0xF3, 0xFB, 0xC2, 0x5B, 0x90, 0x8E, 0xBE, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, 0xC5, 0xDB, + 0x7F, 0xED, 0x58, 0xE9, 0xE3, 0xC3, 0x6D, 0xC7, 0x27, 0xC3, 0x67, 0x41, 0x0A, 0xFD, 0x20, 0x3F, + 0xFF, 0xF6, 0x63, 0x64, 0x60, 0xBC, 0xFE, 0xF6, 0x43, 0x44, 0x45, 0xD2, 0xC5, 0xE3, 0x23, 0x1C, + 0xB7, 0x20, 0x00, 0x00, 0x00, 0xE8, 0x35, 0x66, 0xDF, 0x12, 0x1D, 0x15, 0x49, 0x27, 0xE3, 0xA2, + 0xD5, 0x54, 0x50, 0xA4, 0x99, 0x08, 0x8C, 0x56, 0x73, 0x37, 0x06, 0x53, 0x70, 0x0B, 0xA2, 0x6F, + 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8F, 0x70, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0x97, 0x98, + 0x91, 0x35, 0xB3, 0xDD, 0xE7, 0x4A, 0xC8, 0xB0, 0x48, 0x32, 0x19, 0x17, 0xAD, 0x16, 0x8F, 0x89, + 0xB4, 0x13, 0x71, 0xD1, 0x6A, 0xEE, 0xA0, 0xEE, 0xB6, 0xED, 0x63, 0x95, 0x5B, 0x90, 0x43, 0xC5, + 0x7C, 0x90, 0x9F, 0xBE, 0xFD, 0x10, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0xE2, 0xE3, 0x16, 0x04, 0x00, + 0x00, 0x00, 0xBD, 0xC2, 0x8C, 0xAC, 0x1E, 0x30, 0x3B, 0x2F, 0xD1, 0x71, 0xD1, 0x6A, 0x32, 0x2E, + 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0x30, 0x3E, 0xC2, 0xED, 0xFD, 0x8C, 0xBB, + 0x05, 0x29, 0xE4, 0x15, 0xB6, 0xEE, 0xF3, 0x46, 0xCC, 0xF0, 0xF5, 0xF6, 0xAF, 0x33, 0x45, 0xF1, + 0x11, 0xEE, 0xE0, 0xE7, 0x6C, 0x84, 0xAC, 0xE8, 0xC8, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x89, + 0x99, 0xC3, 0xAB, 0xD7, 0x9B, 0xED, 0x17, 0xEB, 0xC0, 0x68, 0x36, 0x19, 0x17, 0xAD, 0xA6, 0x82, + 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x5A, 0x3C, 0x3E, 0xDC, 0xB6, 0x7E, 0x38, 0x7C, 0x16, 0x24, 0xD7, + 0x57, 0xD8, 0xDA, 0x9F, 0x6F, 0xB6, 0xFF, 0xDA, 0x5D, 0xF7, 0x4A, 0xE3, 0xA9, 0x8C, 0x0F, 0xB7, + 0x9D, 0xB3, 0xED, 0xEF, 0x67, 0x85, 0xFB, 0x3D, 0x4D, 0xF9, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x79, 0x87, 0x57, 0x6F, 0x90, 0x81, 0xD1, 0x6C, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, + 0x89, 0xB8, 0x68, 0x35, 0x15, 0x1F, 0xE1, 0x82, 0x5B, 0x10, 0xF7, 0x2D, 0x53, 0xC1, 0xDF, 0x8A, + 0xB6, 0x79, 0x87, 0x06, 0x06, 0x27, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8C, 0x24, 0x73, + 0xB7, 0x20, 0xC3, 0x2B, 0xA6, 0xF4, 0xB3, 0x4E, 0x00, 0x00, 0x00, 0x80, 0x54, 0xBC, 0x83, 0x9F, + 0x1B, 0x95, 0x91, 0xD1, 0x68, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0x35, + 0x15, 0x1D, 0xD1, 0xB9, 0x5F, 0x97, 0x7F, 0x63, 0xB0, 0x32, 0x97, 0x87, 0xB7, 0x6B, 0x6F, 0x3F, + 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8B, 0xA4, 0xE3, 0x16, 0x04, 0x00, 0x00, 0x00, 0xDD, 0xCE, 0xDB, + 0x7F, 0xD5, 0xB8, 0x0C, 0x0D, 0xB5, 0xBA, 0xB0, 0x48, 0x32, 0x15, 0x14, 0x69, 0x26, 0xE2, 0xA2, + 0xD5, 0x54, 0x70, 0xA8, 0x0D, 0x2D, 0x30, 0xDE, 0xC8, 0xCA, 0xF1, 0x3C, 0x6E, 0x41, 0xFC, 0xDB, + 0x8F, 0x03, 0xD7, 0xDA, 0x9F, 0x57, 0x44, 0x45, 0xD2, 0xA9, 0xA8, 0x48, 0x3B, 0xF7, 0x96, 0xAF, + 0xE1, 0x65, 0xDC, 0x82, 0x34, 0x60, 0xC6, 0xFE, 0xC3, 0x2C, 0xF3, 0xF2, 0xBF, 0x5F, 0x67, 0x4E, + 0x7C, 0x65, 0x7D, 0x64, 0x6B, 0xDD, 0xBF, 0x1E, 0xFC, 0x47, 0x00, 0x00, 0x00, 0x50, 0x14, 0x77, + 0xF0, 0x4E, 0xFC, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, + 0x0A, 0x8D, 0x46, 0x73, 0xBF, 0xC6, 0x1C, 0x6E, 0x41, 0xDC, 0xA7, 0xAB, 0xFB, 0xB7, 0x1F, 0xEE, + 0x59, 0x1A, 0x15, 0x16, 0x49, 0xA6, 0x62, 0x22, 0xCB, 0xB6, 0x7F, 0xD4, 0xFE, 0x7E, 0x96, 0xDB, + 0x2D, 0x2D, 0xF4, 0xB3, 0x4E, 0x7A, 0x8D, 0x0B, 0x0C, 0xEF, 0xC4, 0x97, 0x07, 0xCD, 0x2F, 0xBE, + 0x62, 0xE4, 0x4E, 0x7C, 0xC9, 0xF8, 0xFF, 0x3E, 0x21, 0x02, 0x00, 0x00, 0x50, 0x1C, 0xFF, 0x0D, + 0x58, 0xBB, 0xE6, 0xE8, 0xE0, 0x88, 0xAE, 0x2E, 0x2C, 0x92, 0x4C, 0x05, 0x45, 0x9A, 0x89, 0xB8, + 0x68, 0x35, 0x15, 0x19, 0xAD, 0xE6, 0xBF, 0xC2, 0x76, 0xE5, 0x78, 0x3B, 0xDF, 0xB6, 0xE4, 0x1D, + 0x1A, 0x18, 0x35, 0xFB, 0xAF, 0xB4, 0x3F, 0x9F, 0x08, 0x8B, 0x24, 0x53, 0x21, 0x91, 0x69, 0x33, + 0x2B, 0xDB, 0x7F, 0x85, 0xF1, 0x86, 0x97, 0x4F, 0xC9, 0x27, 0xBE, 0xF7, 0x02, 0x73, 0xFC, 0xDF, + 0x2F, 0xF1, 0x7E, 0xF1, 0xE5, 0xF1, 0xDA, 0xE0, 0xB8, 0xDD, 0x98, 0xE3, 0x5F, 0xF4, 0xC3, 0x23, + 0xFA, 0xAF, 0xFB, 0xFF, 0x39, 0xFB, 0x9F, 0x0F, 0xFE, 0xAB, 0x00, 0x00, 0x00, 0xC8, 0x93, 0x39, + 0x7C, 0xE3, 0xBA, 0x96, 0xAF, 0xE0, 0x95, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, + 0xAB, 0xA9, 0xB8, 0x48, 0xBA, 0xE1, 0xEB, 0x8D, 0xFB, 0x16, 0xAA, 0xE0, 0x6F, 0x4B, 0x2A, 0x36, + 0x5C, 0x06, 0xEC, 0xB2, 0xDF, 0x7E, 0xC8, 0x90, 0xC8, 0xB2, 0x20, 0x3E, 0xDC, 0xB8, 0x05, 0xA9, + 0xAA, 0x89, 0x0F, 0x17, 0x1D, 0x2F, 0xD9, 0xFF, 0xAD, 0x5E, 0xB0, 0xB1, 0xF8, 0xFC, 0x92, 0xC9, + 0xBD, 0x70, 0xB5, 0xFD, 0xD7, 0x57, 0x55, 0xFE, 0x7D, 0x22, 0x04, 0x00, 0x00, 0xA0, 0x38, 0xFE, + 0x2B, 0x78, 0x55, 0x74, 0x84, 0x93, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, + 0xA9, 0xA8, 0x48, 0xBC, 0x59, 0x95, 0x07, 0xC7, 0xDD, 0xB7, 0x50, 0x65, 0xB8, 0x05, 0xF1, 0x86, + 0x57, 0x64, 0xBF, 0xFD, 0x90, 0x21, 0x91, 0x65, 0x91, 0xF8, 0x08, 0xC7, 0x2D, 0x48, 0x6D, 0x7C, + 0x1C, 0xB9, 0xB1, 0x36, 0x3A, 0xD4, 0x5C, 0x98, 0x1C, 0xFD, 0x42, 0x25, 0x42, 0x4E, 0x7C, 0x85, + 0x1B, 0x24, 0x00, 0x00, 0x80, 0xBC, 0x79, 0x07, 0x97, 0x35, 0x7E, 0x03, 0x96, 0x8C, 0x8B, 0x56, + 0x53, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0x85, 0x1F, 0x16, 0x68, 0xE7, + 0x6E, 0x41, 0x46, 0x06, 0x86, 0x82, 0xBF, 0x35, 0x89, 0xB4, 0x75, 0xFB, 0x21, 0x43, 0x22, 0xCB, + 0x44, 0x7C, 0xB8, 0x6D, 0xFD, 0xD0, 0xB4, 0xBE, 0x05, 0xA9, 0x89, 0x0F, 0x77, 0xEB, 0xA1, 0x82, + 0xA3, 0xD1, 0x5C, 0xAC, 0xF8, 0x37, 0x26, 0x5F, 0x29, 0xE4, 0xD3, 0xF2, 0x01, 0x00, 0x00, 0xA6, + 0x2D, 0x6F, 0xFF, 0x35, 0x63, 0xC4, 0x47, 0xB0, 0xED, 0x1F, 0xB7, 0x87, 0x75, 0xFF, 0x16, 0x24, + 0xF1, 0x81, 0xDD, 0x1B, 0x59, 0x31, 0xE6, 0x3F, 0xC4, 0xAF, 0x02, 0xA3, 0xD9, 0x64, 0x48, 0x64, + 0x99, 0x08, 0x8F, 0xE8, 0xF6, 0x2C, 0xB2, 0x51, 0xB5, 0x7C, 0x2C, 0xF8, 0xE5, 0x4E, 0x1B, 0x6D, + 0xC5, 0x47, 0xB8, 0x63, 0x7F, 0xE2, 0x3F, 0x94, 0x1E, 0xFC, 0x94, 0x00, 0x00, 0x00, 0xC8, 0x83, + 0xD9, 0xF7, 0x19, 0xE2, 0xC3, 0xED, 0x99, 0x60, 0xFB, 0xAF, 0x32, 0xDE, 0xF0, 0x40, 0xA2, 0x6F, + 0xBD, 0xB1, 0xA1, 0xB2, 0xCE, 0xBF, 0xFD, 0x70, 0x7F, 0xCF, 0x54, 0x64, 0x34, 0x9A, 0x0C, 0x89, + 0x2C, 0x13, 0xC1, 0x11, 0x9F, 0xFB, 0x7B, 0xEB, 0xDF, 0x82, 0x2C, 0xCF, 0xF5, 0x13, 0xDF, 0xBB, + 0x59, 0x2E, 0xF1, 0xE1, 0xF6, 0xC2, 0xD5, 0xEE, 0xDB, 0xB0, 0x4E, 0x06, 0x3F, 0x2D, 0x00, 0x00, + 0x00, 0xDA, 0x65, 0x0E, 0xDF, 0xB8, 0xC4, 0x0C, 0x2D, 0x9C, 0xBE, 0xF1, 0x11, 0x46, 0x47, 0xF0, + 0x7F, 0x7B, 0x6E, 0xDB, 0x3F, 0xEE, 0xBE, 0x0D, 0x2B, 0xD1, 0x2D, 0x88, 0x37, 0xBC, 0xE2, 0x64, + 0xEA, 0xDB, 0x0F, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, 0xD1, 0xDC, 0x2D, 0xC8, 0xF0, 0xB2, 0x69, + 0x71, 0x90, 0xCE, 0x2D, 0x3E, 0xC2, 0x1D, 0xBB, 0xC5, 0x04, 0x3F, 0x35, 0x00, 0x00, 0x00, 0xDA, + 0x65, 0x0E, 0xAD, 0x5A, 0x5B, 0xF3, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, + 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0xAB, 0x8F, 0x0F, 0x3F, 0x3C, 0xC2, 0x6D, 0xB2, 0xDB, 0x7B, + 0x85, 0x39, 0x3F, 0x3C, 0xD0, 0xF4, 0xC0, 0x9E, 0xE9, 0xF6, 0x43, 0x86, 0x44, 0x96, 0x89, 0xC8, + 0x68, 0x36, 0xF7, 0xF7, 0x79, 0x1A, 0xDC, 0x82, 0xE4, 0x1E, 0x1F, 0xCF, 0x7F, 0xC6, 0x98, 0x23, + 0x37, 0x18, 0xF3, 0xF2, 0x9D, 0x7C, 0x9E, 0x0A, 0x00, 0x00, 0x40, 0x1E, 0xFC, 0x37, 0x60, 0x6D, + 0xFB, 0xC8, 0xF4, 0x8D, 0x8F, 0x68, 0x78, 0xB8, 0xB9, 0xF8, 0x70, 0xDB, 0xFC, 0x21, 0xF7, 0x6D, + 0x58, 0xEE, 0x16, 0xA4, 0xE1, 0x81, 0xDD, 0xBF, 0xFD, 0xD8, 0xB3, 0xD0, 0xFE, 0x7C, 0x22, 0x34, + 0xD4, 0x64, 0x48, 0x64, 0x99, 0x08, 0x8C, 0x24, 0x1B, 0x9A, 0x5F, 0xEA, 0x5B, 0x90, 0x42, 0xE2, + 0xC3, 0x6D, 0xEC, 0x3A, 0x17, 0x20, 0xD3, 0xE6, 0xDB, 0xD7, 0x00, 0x00, 0x00, 0x0A, 0xE5, 0x1D, + 0x5A, 0x3D, 0x38, 0xED, 0xE2, 0x23, 0x12, 0x20, 0xD5, 0xE8, 0x88, 0xC4, 0xC7, 0xF9, 0x70, 0x43, + 0x97, 0x9B, 0x73, 0x07, 0xF5, 0x2D, 0xC8, 0xF9, 0x91, 0xFE, 0xF5, 0x66, 0x78, 0x99, 0xFD, 0xB9, + 0xDC, 0xAF, 0x49, 0xC4, 0x46, 0x7C, 0x32, 0x24, 0xB2, 0x4C, 0x84, 0x45, 0xD2, 0xB9, 0xDF, 0xF7, + 0xF0, 0xF5, 0xEE, 0x16, 0xA4, 0xAD, 0x4F, 0x7C, 0xEF, 0x46, 0x85, 0xC5, 0x87, 0xDB, 0x0B, 0x57, + 0x19, 0x73, 0xE2, 0xCE, 0xD2, 0xFD, 0x3D, 0x03, 0x00, 0x00, 0xE8, 0x08, 0x6F, 0xDF, 0x55, 0xA3, + 0x3A, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xC5, 0xC2, 0x22, 0xC9, 0x64, 0x54, 0x24, 0x5D, 0x24, + 0x3E, 0x82, 0xD5, 0xDC, 0x78, 0x84, 0xD1, 0xF1, 0x74, 0x64, 0x9B, 0x3F, 0x64, 0xCE, 0x1F, 0x5C, + 0x6E, 0xCE, 0x0D, 0xF7, 0xDF, 0x15, 0xFC, 0xED, 0xF2, 0x99, 0xA1, 0xFE, 0x59, 0xE7, 0x47, 0x56, + 0x8C, 0x9B, 0xDD, 0x7D, 0xF6, 0x60, 0x2F, 0x62, 0x23, 0x3E, 0x19, 0x12, 0x59, 0x26, 0xA2, 0x22, + 0xED, 0x76, 0xCF, 0x35, 0xDE, 0xC8, 0xB2, 0x71, 0xF7, 0x7B, 0x08, 0x7E, 0x3B, 0x3D, 0xAF, 0xD0, + 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x9F, 0x07, 0x02, 0x00, 0x00, 0x90, 0x07, 0xB3, 0xEF, 0x0A, + 0x7B, 0xB8, 0x57, 0x81, 0xD1, 0x6C, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, 0x48, + 0xBA, 0x48, 0x78, 0x44, 0x6F, 0x3E, 0xE2, 0xB7, 0x1E, 0x7E, 0x78, 0xBC, 0xCF, 0x9C, 0x7B, 0x6A, + 0x72, 0xE7, 0x77, 0xCE, 0x77, 0xB7, 0x20, 0x35, 0x07, 0xF6, 0xF3, 0x07, 0xFB, 0xD7, 0x7B, 0xC3, + 0xCB, 0x8C, 0xE7, 0x6E, 0x3F, 0x5A, 0x05, 0x88, 0x0C, 0x89, 0x2C, 0x13, 0x31, 0x91, 0x76, 0x9B, + 0x66, 0xD8, 0x1F, 0xED, 0xAF, 0xA9, 0x44, 0xB7, 0x20, 0x53, 0x11, 0x1F, 0x6E, 0xDE, 0xD1, 0x5B, + 0xA6, 0xDD, 0x6B, 0x8C, 0x01, 0x00, 0x00, 0x72, 0x67, 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x8B, 0xED, + 0x01, 0x5F, 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x58, 0x24, 0x99, 0x8C, 0x8A, 0xA4, + 0x8B, 0xC4, 0x47, 0x83, 0x00, 0x09, 0xE3, 0xE3, 0x5C, 0x24, 0x3E, 0xCE, 0x6E, 0x0C, 0xF6, 0xD4, + 0xFB, 0xCD, 0xF9, 0x03, 0xCB, 0x8D, 0x8B, 0x0E, 0xFF, 0xEF, 0x99, 0x0D, 0x91, 0x73, 0xC3, 0x2B, + 0xC6, 0xBD, 0x5D, 0x7D, 0xF6, 0xBF, 0x7F, 0x91, 0x3F, 0xFF, 0x50, 0xAF, 0x42, 0x44, 0x86, 0x44, + 0x96, 0x89, 0x98, 0x48, 0x3B, 0x17, 0x1F, 0xE1, 0x4A, 0x72, 0x0B, 0x32, 0x55, 0xF1, 0xE1, 0xEF, + 0xE8, 0xE7, 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xBB, 0xCC, 0xC8, 0xEA, 0x01, 0xB3, 0xEB, 0x52, + 0x7B, 0xC8, 0x57, 0xA1, 0xA1, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, + 0x4B, 0x1F, 0x1F, 0xD5, 0xF0, 0x78, 0xD2, 0x6D, 0x96, 0xBF, 0x73, 0x3B, 0xE6, 0x9B, 0xB3, 0x07, + 0x2A, 0xB7, 0x20, 0x2E, 0x44, 0xCE, 0x1F, 0x5C, 0x66, 0xFF, 0xFB, 0x7F, 0xDC, 0x3C, 0x40, 0x64, + 0x48, 0x64, 0x99, 0x88, 0x89, 0xB4, 0x8B, 0xC6, 0x87, 0x9B, 0xFB, 0xB5, 0x1E, 0xBC, 0xB6, 0xA7, + 0x6F, 0x41, 0xA6, 0x34, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0xEC, 0x5F, 0x33, 0xF8, 0xCB, 0x03, 0x00, + 0x00, 0x20, 0x0B, 0xEF, 0xD0, 0xAA, 0xBB, 0xCC, 0xF6, 0x4F, 0xD8, 0x83, 0xBE, 0x8A, 0x8D, 0xF8, + 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, 0x74, 0xB1, 0xF8, 0x08, 0x02, 0x24, + 0x49, 0x7C, 0xBC, 0x6B, 0xE3, 0xE3, 0xDD, 0xC1, 0x59, 0x93, 0xDB, 0xF8, 0x7E, 0x73, 0x6E, 0xEF, + 0xF5, 0xE6, 0xDC, 0x81, 0x81, 0x51, 0xF7, 0xED, 0x58, 0xE7, 0xB7, 0x5F, 0x62, 0xFF, 0xBB, 0x36, + 0x3E, 0xDC, 0x54, 0x84, 0xC8, 0x90, 0xC8, 0x32, 0x11, 0x13, 0x69, 0x17, 0x8F, 0x8F, 0x70, 0x3B, + 0x3E, 0xE9, 0x02, 0xC4, 0xBD, 0xE5, 0x6B, 0x76, 0xF0, 0x8F, 0x43, 0xCF, 0x98, 0xF2, 0xF8, 0x70, + 0x1B, 0x5B, 0x66, 0xCC, 0x89, 0xAF, 0xAC, 0x0D, 0x7E, 0x09, 0x00, 0x00, 0x00, 0xC8, 0xC2, 0x3B, + 0xBC, 0x7A, 0x83, 0x8E, 0x8D, 0xF8, 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, + 0x74, 0x3A, 0x3E, 0xEA, 0x02, 0xC4, 0x86, 0x47, 0xF8, 0xCC, 0x47, 0x3C, 0x3E, 0x26, 0xDC, 0x9E, + 0xA8, 0xCC, 0xFD, 0xFF, 0x67, 0xB7, 0x7C, 0xDA, 0x4C, 0x3C, 0xD3, 0x6F, 0xCE, 0x0D, 0xD9, 0x10, + 0x79, 0xCA, 0xFD, 0x77, 0x2F, 0xD2, 0x11, 0xB2, 0x49, 0x85, 0x44, 0x96, 0x89, 0x98, 0x48, 0x3B, + 0x15, 0x1E, 0xD1, 0x1D, 0xBC, 0xD6, 0xBD, 0x96, 0x77, 0x30, 0xF8, 0xC7, 0xA1, 0x27, 0x74, 0x24, + 0x3E, 0xDC, 0x5E, 0xBC, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0xB4, 0xCB, 0x3B, 0x78, 0x4D, 0x82, + 0x37, 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0xE1, 0x11, + 0x2E, 0x1E, 0x1F, 0xE1, 0xED, 0x47, 0xE4, 0x99, 0x0F, 0x17, 0x1F, 0xD1, 0xF0, 0x98, 0x78, 0x3C, + 0x98, 0xFB, 0xBF, 0x1F, 0x9B, 0x65, 0x4E, 0x3F, 0x72, 0x9D, 0x39, 0xF3, 0xF0, 0x25, 0x7E, 0x80, + 0x9C, 0xF3, 0x1F, 0x58, 0x8F, 0x05, 0x88, 0x8B, 0x8F, 0x5C, 0x02, 0x44, 0xC4, 0x44, 0xDA, 0xA9, + 0xE0, 0x88, 0xAF, 0xC7, 0x6E, 0x41, 0x3A, 0x16, 0x1F, 0xC1, 0xBC, 0x5F, 0xDC, 0x39, 0x14, 0xFC, + 0x52, 0x00, 0x00, 0x00, 0x90, 0x85, 0xB7, 0xFF, 0xEA, 0x93, 0x3A, 0x3A, 0xC2, 0xA9, 0xA0, 0x48, + 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x78, 0xB8, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, + 0xDE, 0x7E, 0xD4, 0x7E, 0xEB, 0x55, 0x34, 0x3E, 0xCE, 0xD8, 0xE8, 0x38, 0xF3, 0xF8, 0xFB, 0x82, + 0x55, 0x22, 0xE4, 0xF4, 0xFD, 0x17, 0x99, 0x53, 0xF7, 0x5E, 0x6C, 0x4E, 0xDD, 0x7D, 0x91, 0x39, + 0x6B, 0xFF, 0x33, 0x75, 0xB7, 0x20, 0x36, 0x3C, 0xDC, 0xDA, 0x0F, 0x10, 0x11, 0x13, 0x69, 0xA7, + 0x62, 0xA3, 0xD1, 0x7A, 0xE4, 0x16, 0xA4, 0xD3, 0xF1, 0xE1, 0xE6, 0x1D, 0xFB, 0x53, 0xDE, 0x84, + 0x05, 0x00, 0x00, 0xD0, 0x8E, 0xE6, 0x6F, 0xC0, 0x52, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, + 0x46, 0x45, 0xD2, 0xC5, 0xA2, 0x23, 0xBA, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDC, 0x7E, 0xD4, 0x7C, + 0xDB, 0x55, 0x18, 0x1F, 0x8F, 0xD9, 0xF0, 0xB0, 0x3B, 0x1D, 0xFC, 0x78, 0xE6, 0x91, 0xF7, 0xF9, + 0xE1, 0x11, 0xEE, 0xF4, 0x7D, 0x36, 0x42, 0x36, 0x4E, 0x46, 0x88, 0xF7, 0x74, 0x25, 0x3E, 0xAA, + 0x01, 0x92, 0x39, 0x42, 0x44, 0x4C, 0xA4, 0x9D, 0x8A, 0x8C, 0x66, 0xDB, 0x7E, 0x71, 0xD7, 0xDF, + 0x82, 0x74, 0x43, 0x7C, 0xF8, 0x3B, 0x76, 0x0B, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xC8, 0xCA, 0x7F, + 0x03, 0xD6, 0xEE, 0x79, 0xF6, 0xE0, 0x5F, 0xFE, 0xF8, 0x70, 0x3F, 0x36, 0xBF, 0xFD, 0xB0, 0xF1, + 0xE1, 0x02, 0x24, 0x88, 0x0F, 0x17, 0x1E, 0xA7, 0x1F, 0x9D, 0xDC, 0xA9, 0x7B, 0x67, 0xD5, 0x04, + 0x88, 0xDB, 0xBB, 0x3F, 0x0E, 0x02, 0xE4, 0xA9, 0x0B, 0xED, 0xCF, 0x67, 0xE3, 0x23, 0x1E, 0x21, + 0x32, 0x30, 0x9A, 0x4D, 0xC4, 0x44, 0xDA, 0xA9, 0xC0, 0x48, 0xB2, 0x7D, 0x57, 0x18, 0x6F, 0x78, + 0x79, 0x57, 0x7E, 0xD0, 0x5E, 0xD7, 0xC4, 0x87, 0x9B, 0x7B, 0x13, 0xD6, 0xCB, 0x77, 0xF6, 0xDC, + 0x43, 0xFB, 0x00, 0x00, 0x00, 0x5D, 0xC1, 0x1C, 0x5A, 0xB5, 0xD6, 0xEC, 0x9C, 0x6D, 0x0F, 0xFF, + 0x25, 0x8E, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDD, 0x7E, 0xB8, 0xD7, 0xEC, 0x46, 0x6F, + 0x3F, 0xE2, 0xF1, 0x71, 0xFA, 0x81, 0xDA, 0xDB, 0x8F, 0x70, 0xEE, 0x16, 0xE4, 0xDC, 0x93, 0x76, + 0x1B, 0x2F, 0xF2, 0x23, 0xA4, 0x26, 0x40, 0x5C, 0x50, 0xA4, 0x8A, 0x10, 0x11, 0x13, 0x69, 0xA7, + 0xC2, 0x22, 0xE9, 0xB6, 0x7D, 0x24, 0xB8, 0x05, 0x59, 0x3A, 0x10, 0xFC, 0xE3, 0xD1, 0x15, 0xBA, + 0x2A, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0xB3, 0xAB, 0xFE, 0x1E, 0x01, 0x00, 0x00, 0xF4, + 0x0C, 0x73, 0x78, 0xF5, 0x7A, 0xB3, 0xF5, 0xC3, 0x36, 0x00, 0x4A, 0x1C, 0x1F, 0xC1, 0xD4, 0xED, + 0xC7, 0x59, 0x3F, 0x40, 0x6C, 0x7C, 0xB8, 0xDB, 0x8F, 0xC8, 0xB7, 0x5E, 0x55, 0xC3, 0xE3, 0xC7, + 0x95, 0xA9, 0xDB, 0x0F, 0x7F, 0x5F, 0xBF, 0xD0, 0xBC, 0xFB, 0x48, 0x25, 0x40, 0xCE, 0xB5, 0x75, + 0x0B, 0x22, 0x62, 0x22, 0xED, 0x54, 0x54, 0xA4, 0x9D, 0xBB, 0x05, 0x39, 0xB8, 0xAC, 0x6B, 0x6E, + 0x41, 0xBA, 0x2E, 0x3E, 0xDC, 0x78, 0x13, 0x16, 0x00, 0x00, 0x40, 0x76, 0xDE, 0xC8, 0x8A, 0xA1, + 0xD2, 0xC7, 0x47, 0xC3, 0xDB, 0x8F, 0x59, 0xD5, 0xF8, 0xA8, 0xDE, 0x7E, 0x84, 0xF1, 0x11, 0x84, + 0x87, 0x1F, 0x1F, 0x3F, 0xD2, 0xB7, 0x1F, 0x2E, 0x3E, 0xDC, 0x4E, 0x7F, 0xEB, 0x42, 0x73, 0xB6, + 0xAD, 0x5B, 0x10, 0x11, 0x13, 0x69, 0xA7, 0x62, 0x22, 0xCB, 0xB6, 0xD9, 0x18, 0x1D, 0x5E, 0xD6, + 0x15, 0xB7, 0x20, 0x5D, 0x19, 0x1F, 0xC1, 0xBC, 0x13, 0x5F, 0xEE, 0xA9, 0xD7, 0x16, 0x03, 0x00, + 0x00, 0x74, 0x0D, 0x6F, 0xDF, 0x55, 0x63, 0x65, 0xBF, 0xF9, 0x70, 0xAB, 0xBF, 0xFD, 0x88, 0x04, + 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x70, 0x44, 0x02, 0xE4, 0x94, 0x7B, 0xE8, 0xDC, 0xED, 0xDB, 0xE2, + 0xF6, 0x23, 0x88, 0x8F, 0x70, 0x13, 0x0F, 0x64, 0xBD, 0x05, 0x11, 0x31, 0x91, 0x76, 0x2A, 0x24, + 0x32, 0xED, 0x82, 0xCA, 0xF6, 0x5C, 0xD6, 0xF1, 0x5B, 0x90, 0x6E, 0x8E, 0x0F, 0x37, 0xEF, 0xF8, + 0x9F, 0x75, 0xE5, 0xB3, 0x32, 0x00, 0x00, 0x00, 0x5D, 0xCF, 0xEC, 0xBD, 0xDC, 0x86, 0x40, 0x89, + 0xE3, 0x23, 0xC1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xC1, 0xB7, 0x5E, 0x9D, 0x0A, 0x03, 0xE4, 0x07, + 0xAD, 0xE3, 0xC3, 0xED, 0xF4, 0x3D, 0x2D, 0x6E, 0x41, 0xE4, 0x44, 0x4C, 0xA4, 0x9D, 0x0C, 0x89, + 0x2C, 0x0B, 0xE2, 0xC3, 0xCD, 0xFD, 0xFD, 0xF5, 0x6F, 0x41, 0x96, 0xAF, 0x0B, 0xFE, 0x31, 0x99, + 0x52, 0xDD, 0x1E, 0x1F, 0xFE, 0x8E, 0xFF, 0x29, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x48, 0xCB, 0xBD, + 0x72, 0xD5, 0xEC, 0x59, 0x64, 0x63, 0x40, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0xBA, 0xA0, + 0x48, 0x33, 0x11, 0x1A, 0x8D, 0x16, 0x0F, 0x90, 0xE0, 0xF6, 0xE3, 0x6C, 0x92, 0xDB, 0x8F, 0x87, + 0xED, 0xEE, 0x69, 0x1D, 0x1F, 0xE1, 0xC2, 0x5B, 0x90, 0x64, 0x6F, 0xC4, 0x12, 0x31, 0x91, 0x76, + 0x32, 0x24, 0xB2, 0x2C, 0x12, 0x1F, 0xE1, 0x86, 0x16, 0x1A, 0xEF, 0xE0, 0xD2, 0x93, 0xC1, 0x3F, + 0x2A, 0x53, 0xA6, 0x27, 0xE2, 0xC3, 0xED, 0xC8, 0x6A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0x90, 0x96, + 0xFF, 0x0A, 0xDE, 0x9D, 0x9F, 0xB2, 0x41, 0xA0, 0xA2, 0x22, 0xE9, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, + 0x8A, 0xA4, 0x13, 0x91, 0xA1, 0x66, 0x83, 0xA3, 0x1A, 0x1F, 0x36, 0x3C, 0x12, 0xDF, 0x7E, 0x44, + 0xBF, 0xF5, 0xEA, 0xFB, 0xB1, 0xDB, 0x0F, 0x11, 0x1D, 0xD1, 0x25, 0xBF, 0x05, 0x11, 0x31, 0x91, + 0x76, 0x32, 0x24, 0xB2, 0x4C, 0xC4, 0x87, 0x9B, 0xFB, 0x7B, 0x3D, 0xC5, 0xB7, 0x20, 0x3D, 0x13, + 0x1F, 0x3F, 0xBF, 0xDC, 0x98, 0xB1, 0x15, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x20, 0x2D, 0x73, 0x78, + 0xE5, 0x7A, 0xB3, 0xED, 0xA3, 0x36, 0x0A, 0x54, 0x58, 0x24, 0x99, 0x88, 0x8B, 0x56, 0xAB, 0x0B, + 0x8A, 0x34, 0x8B, 0x45, 0x46, 0xB3, 0x45, 0x03, 0xC4, 0xAE, 0x12, 0x1F, 0x36, 0x0E, 0xC2, 0x00, + 0x69, 0xF4, 0xDA, 0xDD, 0x46, 0xB7, 0x1F, 0x22, 0x38, 0xD4, 0x26, 0x7E, 0x50, 0x09, 0x90, 0x9A, + 0x67, 0x41, 0x82, 0x10, 0xA9, 0xDC, 0x82, 0x88, 0x98, 0x48, 0x3B, 0x19, 0x12, 0x59, 0x26, 0xC2, + 0x23, 0xBA, 0x29, 0xBC, 0x05, 0xE9, 0xA9, 0xF8, 0x70, 0x7B, 0xF1, 0x3A, 0x63, 0x7F, 0xBD, 0x77, + 0x05, 0xBF, 0x7C, 0x00, 0x00, 0x00, 0x24, 0xE1, 0x1D, 0x5E, 0xB9, 0x41, 0x87, 0x45, 0x92, 0x89, + 0xB8, 0x68, 0x35, 0x19, 0x15, 0x49, 0x17, 0x0B, 0x8C, 0x66, 0x8B, 0xC5, 0x47, 0xE5, 0xF6, 0x23, + 0x12, 0x1F, 0xCD, 0x6E, 0x3F, 0xC2, 0x00, 0x89, 0xDE, 0x7E, 0x88, 0xD0, 0x68, 0xB8, 0x6F, 0x5C, + 0x68, 0xCE, 0x3E, 0xD1, 0xE0, 0x16, 0x64, 0x93, 0x88, 0x89, 0xB4, 0x93, 0x21, 0x91, 0x65, 0x22, + 0x38, 0xE2, 0x73, 0x7F, 0xDF, 0x0F, 0x5E, 0x57, 0xF8, 0x2D, 0x48, 0xCF, 0xC5, 0x47, 0x30, 0xEF, + 0xC4, 0x9D, 0x1B, 0x82, 0xDF, 0x02, 0x00, 0x00, 0x00, 0x92, 0xF0, 0x0E, 0x5E, 0x3D, 0xAA, 0xE3, + 0xA2, 0xD5, 0x44, 0x5C, 0xB4, 0x5A, 0x5D, 0x50, 0xA4, 0x59, 0x2C, 0x30, 0x9A, 0xAD, 0x41, 0x7C, + 0xF8, 0xB7, 0x1F, 0x2E, 0x3E, 0xD4, 0xED, 0x47, 0x10, 0x1F, 0xD5, 0xDB, 0x8F, 0x87, 0xEC, 0xBE, + 0x91, 0x21, 0x3E, 0x82, 0x85, 0xB7, 0x20, 0xE7, 0x9F, 0x72, 0x7F, 0xDD, 0x20, 0x42, 0x9E, 0x9E, + 0x69, 0x7F, 0x2D, 0x2E, 0x20, 0x82, 0xA9, 0xB8, 0x68, 0x35, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, + 0xD1, 0x76, 0xCD, 0x31, 0xDE, 0xF0, 0xD2, 0x71, 0x33, 0xD4, 0x3F, 0x2B, 0xF8, 0xC7, 0x26, 0x57, + 0xBD, 0x1A, 0x1F, 0x7E, 0x80, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x74, 0xBC, 0xFD, 0x9F, 0x1D, + 0xD7, 0x81, 0xD1, 0x6C, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xC5, 0x02, 0xA3, 0xD5, 0xEA, + 0x02, 0x24, 0x88, 0x8F, 0xF8, 0xED, 0x47, 0x10, 0x1F, 0xF2, 0xD9, 0x8F, 0xFB, 0x83, 0xDB, 0x0F, + 0x11, 0x17, 0x89, 0x16, 0xBB, 0x05, 0x39, 0x1F, 0xC4, 0x47, 0x5B, 0x01, 0x22, 0x43, 0x22, 0xCB, + 0x44, 0x64, 0x34, 0x9B, 0x7B, 0x66, 0xC5, 0xDD, 0x82, 0x1C, 0x5C, 0x9A, 0xFB, 0x07, 0xEF, 0xF5, + 0x72, 0x7C, 0xB8, 0x79, 0xC7, 0xFE, 0x64, 0x3C, 0xF8, 0xAD, 0x00, 0x00, 0x00, 0xA0, 0x15, 0x33, + 0xDA, 0x3F, 0x2B, 0xFD, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x8B, 0xC5, 0x45, + 0x92, 0xC5, 0xE3, 0x23, 0x7A, 0xFB, 0x11, 0xC4, 0x47, 0xCD, 0x9B, 0xAF, 0x1A, 0xDD, 0x7E, 0xA8, + 0xB0, 0x48, 0xB1, 0x33, 0xDF, 0xBB, 0x70, 0xF2, 0x59, 0x90, 0xA7, 0x6C, 0x7C, 0xB4, 0x13, 0x21, + 0x32, 0x24, 0xB2, 0x4C, 0x04, 0x46, 0x92, 0x15, 0x70, 0x0B, 0xD2, 0xEB, 0xF1, 0xE1, 0xEF, 0xC8, + 0x4D, 0xC6, 0x8C, 0xFD, 0x87, 0x42, 0x6E, 0x86, 0x00, 0x00, 0x00, 0x4A, 0xC7, 0x7F, 0x03, 0xD6, + 0xAE, 0x4F, 0xDB, 0x48, 0x50, 0xA1, 0xA1, 0x26, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, + 0x8B, 0x56, 0xB3, 0xD1, 0x31, 0x19, 0x20, 0x17, 0x55, 0x02, 0x24, 0xB8, 0xFD, 0xA8, 0xBE, 0x76, + 0xB7, 0x7A, 0xFB, 0xF1, 0xBE, 0xC6, 0xB7, 0x1F, 0x22, 0x28, 0xB2, 0xEC, 0xEC, 0x63, 0x2E, 0x42, + 0x2A, 0x01, 0xE2, 0xDF, 0x82, 0x64, 0x89, 0x10, 0x19, 0x12, 0x59, 0x26, 0xC2, 0x22, 0xE9, 0x72, + 0xBE, 0x05, 0x29, 0x45, 0x7C, 0xB8, 0xBD, 0x34, 0xC0, 0x9B, 0xB0, 0x00, 0x00, 0x00, 0x92, 0x32, + 0x87, 0x57, 0xAD, 0x4B, 0xFE, 0x0A, 0x5E, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x61, + 0x91, 0x74, 0xF1, 0xF8, 0xC8, 0x74, 0xFB, 0xA1, 0x63, 0x22, 0xFD, 0x66, 0x9A, 0x33, 0xF7, 0xCF, + 0x34, 0x67, 0x9F, 0x9C, 0x8C, 0x90, 0xD4, 0x01, 0x22, 0x43, 0x22, 0xCB, 0x44, 0x54, 0xA4, 0xDD, + 0xCE, 0xD9, 0xC6, 0x1B, 0xBE, 0xBE, 0xED, 0x5B, 0x90, 0xD2, 0xC4, 0x87, 0x1B, 0x6F, 0xC2, 0x02, + 0x00, 0x00, 0x48, 0xCE, 0xB8, 0x57, 0xF0, 0xCA, 0xD8, 0x88, 0x4F, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, + 0x48, 0x3A, 0x11, 0x16, 0x49, 0xE6, 0x6E, 0x3F, 0xEC, 0x8F, 0x7E, 0x7C, 0xC4, 0x6E, 0x3F, 0xEA, + 0x9F, 0xFD, 0x68, 0x70, 0xFB, 0x71, 0x5F, 0xFB, 0xDF, 0x7A, 0x55, 0xD9, 0xCC, 0xEA, 0xDE, 0x0D, + 0x6E, 0x41, 0xCE, 0x35, 0xBA, 0x05, 0x51, 0xE1, 0xE1, 0x26, 0x43, 0x22, 0xCB, 0x44, 0x4C, 0x64, + 0xDA, 0x7B, 0x8D, 0x39, 0x70, 0xB5, 0x7B, 0x2D, 0xEF, 0x60, 0xF0, 0x8F, 0x50, 0x6A, 0xA5, 0x8A, + 0x0F, 0xB7, 0xE7, 0xAF, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x49, 0x79, 0x07, 0xAF, 0x4B, 0xF0, + 0x06, 0x2C, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x51, 0x91, 0x66, 0xE1, 0xCD, 0x47, + 0x83, 0xDB, 0x8F, 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0x78, 0x30, 0xAF, 0x6F, 0xBD, 0x9A, 0x8C, 0x0F, + 0xB7, 0x4C, 0xB7, 0x20, 0x32, 0x24, 0xB2, 0x4C, 0x85, 0x44, 0x96, 0xD9, 0xF8, 0x70, 0xDB, 0xFE, + 0x71, 0xF7, 0x6D, 0x58, 0xC6, 0x8C, 0x5C, 0x9B, 0xFA, 0x13, 0xC0, 0x4B, 0x17, 0x1F, 0xC1, 0xBC, + 0x13, 0x77, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x24, 0xBC, 0x7D, 0x57, 0x8E, 0xE9, 0xE8, 0x08, + 0x27, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, 0x8A, 0xA4, 0xF3, 0x6F, 0x3F, 0x82, 0xF8, + 0x88, 0xDD, 0x7E, 0xA8, 0x67, 0x3F, 0xEA, 0x3F, 0x74, 0xD0, 0xC6, 0x47, 0x2E, 0xB7, 0x1F, 0xB5, + 0xF1, 0x11, 0xEE, 0xDD, 0x47, 0x5A, 0x3C, 0x0B, 0xD2, 0x0B, 0xF1, 0xF1, 0x74, 0xB0, 0xFD, 0xE9, + 0x6F, 0x41, 0xCA, 0x1A, 0x1F, 0x6E, 0xDE, 0xB1, 0x5B, 0xA6, 0xE4, 0x83, 0x1A, 0x01, 0x00, 0x00, + 0x7A, 0x9E, 0xD9, 0x7B, 0x99, 0x8D, 0x06, 0x15, 0x1E, 0x6E, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, + 0xD2, 0xC5, 0x82, 0x22, 0xED, 0xC2, 0xF0, 0x68, 0x70, 0xFB, 0x51, 0xF7, 0xEC, 0x47, 0x10, 0x20, + 0x95, 0xDB, 0x0F, 0x1B, 0x1F, 0xB9, 0xDC, 0x7E, 0xE8, 0xF8, 0x70, 0x3B, 0x7D, 0xEF, 0x4C, 0x73, + 0xAE, 0xD1, 0x2D, 0x88, 0x1F, 0x1D, 0x3D, 0x12, 0x1F, 0xF6, 0xFF, 0xF6, 0xB6, 0x7F, 0xDC, 0x05, + 0x48, 0xE2, 0x5B, 0x90, 0x32, 0xC7, 0x87, 0xBF, 0x23, 0x37, 0x99, 0xE0, 0xB7, 0x0A, 0x00, 0x00, + 0x80, 0x46, 0xCC, 0xE1, 0xFE, 0x25, 0x66, 0x68, 0xBE, 0x0D, 0x87, 0x72, 0xC4, 0x47, 0xCB, 0xDB, + 0x0F, 0x11, 0x1F, 0x95, 0xDB, 0x0F, 0x1B, 0x1E, 0xB9, 0xDC, 0x7E, 0xE8, 0xF0, 0x88, 0x2E, 0xBC, + 0x05, 0x69, 0xF8, 0x2C, 0x88, 0x0C, 0x89, 0x2C, 0x53, 0x21, 0x91, 0x65, 0x22, 0x3E, 0xEC, 0x8F, + 0xFE, 0xF6, 0x7C, 0xC6, 0x9C, 0x3F, 0x70, 0xFD, 0x50, 0xF0, 0x8F, 0x53, 0x43, 0xA5, 0x8F, 0x0F, + 0x37, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x9A, 0xFF, 0x0A, 0x5E, 0xF9, 0x06, 0x2C, 0x11, 0x17, + 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x50, 0xA4, 0x9A, 0x8D, 0x8F, 0x30, 0x3C, 0xC2, 0xF8, 0x48, + 0x7A, 0xFB, 0xF1, 0x63, 0x1B, 0x1E, 0x2E, 0x40, 0x7E, 0xD8, 0xEE, 0xED, 0x87, 0x0E, 0x8E, 0xF8, + 0xDC, 0x2D, 0x48, 0xE3, 0x67, 0x41, 0x54, 0x48, 0x64, 0x99, 0x0A, 0x89, 0x2C, 0x6B, 0x12, 0x1F, + 0x4F, 0xBD, 0xD7, 0x9C, 0xDF, 0xF2, 0x21, 0x73, 0x7E, 0xFF, 0x32, 0x73, 0x76, 0xFF, 0xD2, 0x86, + 0x07, 0xEF, 0x69, 0x11, 0x1F, 0x6E, 0x2F, 0x5E, 0xE7, 0x02, 0x64, 0x5D, 0xF0, 0xDB, 0x06, 0x00, + 0x00, 0x80, 0xE2, 0xBF, 0x01, 0x6B, 0xEB, 0x87, 0x6C, 0x40, 0xF4, 0x7E, 0x7C, 0x64, 0xB9, 0xFD, + 0xA8, 0xC6, 0x87, 0xBB, 0xFD, 0xF8, 0x56, 0x3B, 0xB7, 0x1F, 0x3A, 0x36, 0x1A, 0x6D, 0xE2, 0x21, + 0x75, 0x0B, 0x32, 0xC3, 0x9F, 0x0E, 0x8A, 0x34, 0x53, 0x21, 0x91, 0x65, 0x2D, 0xE2, 0xC3, 0x6D, + 0xE3, 0x05, 0xE6, 0xFC, 0xEE, 0x25, 0xE6, 0xDC, 0xDE, 0x65, 0xF2, 0x01, 0xEC, 0x69, 0x13, 0x1F, + 0x6E, 0xCF, 0x5F, 0x69, 0xCC, 0x89, 0x3B, 0x73, 0xFF, 0x94, 0x78, 0x00, 0x00, 0x80, 0x52, 0xF1, + 0x0E, 0xAD, 0x1C, 0xEC, 0xF9, 0xF8, 0xC8, 0x78, 0xFB, 0x71, 0xEA, 0x51, 0x1B, 0x1D, 0xB9, 0xDC, + 0x7E, 0xE8, 0xC8, 0x68, 0xB6, 0xD3, 0xF7, 0xC4, 0x6F, 0x41, 0x2A, 0xF1, 0xD1, 0x7E, 0x80, 0xA8, + 0x90, 0xC8, 0xB2, 0x64, 0xF1, 0x71, 0xEE, 0x49, 0xBB, 0x4D, 0x1F, 0x76, 0x01, 0x62, 0xCE, 0x0E, + 0xD5, 0xDE, 0x82, 0x4C, 0xAB, 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x6F, 0xC2, 0x02, 0x00, 0x00, + 0x68, 0xC6, 0xDB, 0x77, 0x45, 0xE4, 0x15, 0xBC, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xA9, + 0xA0, 0x48, 0xB3, 0x20, 0x3E, 0x82, 0xA5, 0xBB, 0xFD, 0x88, 0xC4, 0x47, 0x5B, 0xB7, 0x1F, 0x3A, + 0x30, 0x92, 0x6C, 0xE2, 0x81, 0xE8, 0x2D, 0x88, 0x8D, 0x8F, 0xB6, 0x23, 0x44, 0x85, 0x44, 0x96, + 0x25, 0x8F, 0x8F, 0xB3, 0x83, 0x76, 0x4F, 0x5C, 0x60, 0xDE, 0xDD, 0xB1, 0xC4, 0x4C, 0xEC, 0x5E, + 0x5E, 0x3D, 0x7C, 0x4F, 0xC7, 0xF8, 0x70, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x2D, 0x98, 0x7D, + 0xF6, 0x70, 0xD7, 0xEB, 0xF1, 0x91, 0xE6, 0xF6, 0x23, 0x8C, 0x8F, 0x5C, 0x6E, 0x3F, 0x74, 0x58, + 0x24, 0x5D, 0xE5, 0x16, 0x64, 0xA6, 0x8D, 0x10, 0x1B, 0x20, 0x4F, 0xB5, 0x1B, 0x20, 0x2A, 0x24, + 0xB2, 0x2C, 0x43, 0x7C, 0x3C, 0x7E, 0x81, 0x39, 0x33, 0xF8, 0x41, 0x17, 0x20, 0xE6, 0xF4, 0x8E, + 0xA5, 0x03, 0xD3, 0x35, 0x3E, 0xFC, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x00, 0x34, 0x62, + 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x0B, 0x75, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, + 0x66, 0x91, 0xF8, 0x08, 0xA6, 0x6E, 0x3F, 0xAA, 0x01, 0x52, 0x73, 0xFB, 0x31, 0xAB, 0xFE, 0xF6, + 0xE3, 0x9B, 0x2A, 0x2E, 0x5A, 0x4D, 0x47, 0x45, 0x9A, 0xBD, 0xF3, 0xD7, 0x33, 0xCC, 0x99, 0x1F, + 0x4E, 0x06, 0x48, 0xF6, 0x5B, 0x10, 0x15, 0x12, 0x59, 0x96, 0x31, 0x3E, 0x1E, 0x9D, 0x61, 0x4E, + 0xFF, 0xD8, 0xEE, 0x99, 0x45, 0x66, 0xE2, 0xC0, 0xAA, 0x93, 0xD3, 0x36, 0x3E, 0xDC, 0x8E, 0xAC, + 0x32, 0xE6, 0xF8, 0x1D, 0x4B, 0x82, 0x2F, 0x31, 0x00, 0x00, 0x00, 0x44, 0x99, 0x91, 0xFE, 0x01, + 0xB3, 0xF3, 0x12, 0x1D, 0x18, 0xCD, 0x26, 0xA3, 0x22, 0xE9, 0x54, 0x50, 0xA4, 0x59, 0x2C, 0x3E, + 0x12, 0xDC, 0x7E, 0x4C, 0xB8, 0x00, 0x79, 0xDC, 0xDD, 0x7E, 0xC4, 0xE2, 0xC3, 0xED, 0x7B, 0x59, + 0xBE, 0xF5, 0x4A, 0x07, 0x45, 0x9A, 0xB9, 0xF8, 0xF0, 0x77, 0xF7, 0x0C, 0x7B, 0x90, 0x6F, 0xE7, + 0x16, 0x44, 0x85, 0x44, 0x96, 0xB5, 0x17, 0x1F, 0xA7, 0x1E, 0x76, 0x01, 0x32, 0xDB, 0x98, 0x63, + 0x77, 0x9A, 0x69, 0x1B, 0x1F, 0x3F, 0xBF, 0xCC, 0x98, 0x17, 0x3F, 0x67, 0xCC, 0x89, 0x2F, 0xAD, + 0x0D, 0xBE, 0xC4, 0x00, 0x00, 0x00, 0x10, 0xE5, 0x1D, 0x5A, 0x75, 0x97, 0xD9, 0x7E, 0xB1, 0x8E, + 0x8C, 0x46, 0x93, 0x51, 0x91, 0x74, 0x2A, 0x28, 0xD2, 0x2C, 0x16, 0x1F, 0x2A, 0x40, 0x1A, 0x3E, + 0xFB, 0x61, 0xE3, 0x23, 0x97, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0x56, 0x8D, 0x8F, 0x60, 0x67, 0xBE, + 0x5F, 0x09, 0x90, 0x73, 0xD1, 0x5B, 0x90, 0x20, 0x44, 0x74, 0x74, 0x84, 0x53, 0x21, 0x91, 0x65, + 0x39, 0xC4, 0xC7, 0xD3, 0x1F, 0x33, 0xDE, 0xD1, 0xDB, 0xA7, 0x77, 0x7C, 0xB8, 0x3D, 0xFF, 0x59, + 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x88, 0x19, 0x59, 0xB9, 0x5E, 0x46, 0x46, 0xA3, 0xC9, 0xA8, + 0x48, 0x3A, 0x15, 0x14, 0x69, 0x56, 0x1F, 0x1E, 0xD5, 0xF8, 0xB0, 0xE1, 0x31, 0x79, 0xFB, 0x11, + 0xF9, 0xD6, 0xAB, 0xEA, 0xED, 0xC7, 0x45, 0x95, 0xDB, 0x0F, 0xBB, 0xF6, 0x6E, 0x3F, 0x74, 0x50, + 0xA4, 0x59, 0x3C, 0x3E, 0xFC, 0x65, 0xBA, 0x05, 0x51, 0x21, 0x91, 0x65, 0xC4, 0x47, 0xFB, 0x0B, + 0xE2, 0x23, 0x98, 0xF7, 0x8B, 0x3B, 0x5B, 0x7E, 0x30, 0x23, 0x00, 0x00, 0xC0, 0xB4, 0xE4, 0x1D, + 0xB8, 0x7A, 0x54, 0x86, 0x86, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, 0x66, 0xB1, 0xF8, 0x88, + 0x07, 0x88, 0x5D, 0xF5, 0x5B, 0xAF, 0xC2, 0x00, 0xA9, 0x3E, 0x78, 0x6E, 0xE3, 0xC3, 0x06, 0x48, + 0xFB, 0xB7, 0x1F, 0x3A, 0x28, 0xD2, 0x4C, 0xC6, 0x47, 0xB0, 0xF0, 0x16, 0xC4, 0xBD, 0x92, 0xB7, + 0xF5, 0x2D, 0x88, 0x0A, 0x89, 0x2C, 0x23, 0x3E, 0xDA, 0x5F, 0x6D, 0x7C, 0xF8, 0x01, 0x72, 0xF4, + 0xD6, 0xB1, 0xE0, 0x4B, 0x0C, 0x00, 0x00, 0x00, 0x51, 0xDE, 0xFE, 0x2B, 0x4F, 0xCA, 0xD8, 0x88, + 0x4F, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x78, 0x88, 0xF8, 0x08, 0x6F, 0x3F, 0x6A, + 0x1E, 0x3C, 0xF7, 0x6F, 0x3F, 0x2E, 0x9A, 0xBC, 0xFD, 0x08, 0xE3, 0x23, 0x0C, 0x90, 0xFB, 0xD3, + 0xDC, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x1D, 0x35, 0x73, 0xB7, 0x20, 0x8F, 0x4D, 0xDE, 0x82, + 0xF8, 0x11, 0x62, 0x63, 0xA3, 0x3E, 0x40, 0x54, 0x48, 0x64, 0x19, 0xF1, 0xD1, 0xFE, 0xEA, 0xE3, + 0xC3, 0xDF, 0xB1, 0x2F, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x00, 0x25, 0xD1, 0x1B, 0xB0, 0x64, 0x54, + 0x24, 0x9D, 0x0A, 0x8A, 0x34, 0x8B, 0x85, 0x47, 0x93, 0xF8, 0xA8, 0x3E, 0x78, 0x5E, 0xBD, 0xFD, + 0xB0, 0xF1, 0x11, 0xDE, 0x7E, 0xC4, 0xE3, 0xE3, 0x21, 0xBB, 0xBB, 0x55, 0x68, 0xA8, 0xE9, 0xA0, + 0x48, 0x33, 0x19, 0x1C, 0x62, 0xA7, 0xBF, 0x3B, 0x23, 0x78, 0x16, 0xA4, 0xC1, 0xB7, 0x62, 0x3D, + 0xAD, 0x42, 0x22, 0xCB, 0x88, 0x8F, 0xF6, 0x27, 0xC2, 0x23, 0x1C, 0x6F, 0xC2, 0x02, 0x00, 0x00, + 0xA8, 0xE7, 0xBF, 0x01, 0x6B, 0xD7, 0x1C, 0x1D, 0x1D, 0xE1, 0x64, 0x54, 0x24, 0x9D, 0x0A, 0x8A, + 0x34, 0x8B, 0x85, 0x47, 0x38, 0x15, 0x20, 0xF1, 0xD7, 0xEE, 0x3E, 0x39, 0x19, 0x1F, 0xF2, 0xCD, + 0x57, 0x89, 0x6F, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0A, 0x8D, 0x66, 0x7B, 0x37, 0x7E, 0x0B, 0x12, + 0x46, 0x88, 0x8B, 0x8F, 0x70, 0x32, 0x2A, 0x92, 0x8E, 0xF8, 0x68, 0x7F, 0x22, 0x3A, 0xA2, 0x7B, + 0xF1, 0x7A, 0x63, 0x5E, 0xBE, 0xB3, 0xE6, 0x53, 0xE1, 0x01, 0x00, 0x00, 0xA6, 0x3D, 0x73, 0xA8, + 0x7F, 0xAD, 0xD9, 0xF1, 0x49, 0x1D, 0x1E, 0x6E, 0x32, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, 0xC5, + 0xA2, 0x23, 0xBA, 0x78, 0x7C, 0x44, 0x6F, 0x3F, 0x82, 0xF8, 0x98, 0xBC, 0xFD, 0x10, 0xDF, 0x7A, + 0x95, 0xF8, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xA9, 0xC0, 0x68, 0x35, 0x77, 0x0B, 0x52, 0xF7, 0xE1, + 0x84, 0x36, 0x3A, 0xF2, 0x09, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xE0, 0x88, 0xEF, 0x85, 0xAB, 0x79, + 0x13, 0x16, 0x00, 0x00, 0x40, 0x9C, 0xFF, 0x06, 0xAC, 0xAD, 0x1F, 0xEC, 0xB9, 0xF8, 0x68, 0x74, + 0xFB, 0xE1, 0xE2, 0xE3, 0x6C, 0x2C, 0x3E, 0xB2, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x17, + 0x49, 0xF7, 0xEE, 0x8F, 0x2B, 0x01, 0xE2, 0xBF, 0x96, 0xF7, 0x29, 0x1B, 0x1F, 0x6E, 0xD1, 0x08, + 0x91, 0x71, 0xD1, 0x6A, 0xC4, 0x47, 0xFB, 0x13, 0xB1, 0xD1, 0x60, 0xDE, 0x89, 0x2F, 0x0D, 0x06, + 0x5F, 0x6A, 0x00, 0x00, 0x00, 0x70, 0xBC, 0xE1, 0xE5, 0x43, 0x3D, 0x15, 0x1F, 0x6E, 0xF1, 0xF8, + 0x88, 0xDE, 0x7E, 0xB8, 0xF8, 0x68, 0x75, 0xFB, 0xF1, 0xA0, 0x9D, 0x0C, 0x8E, 0xE8, 0x74, 0x50, + 0xA4, 0x99, 0x8A, 0x8A, 0x34, 0x3B, 0xFD, 0xED, 0xE0, 0x16, 0xE4, 0x49, 0x1B, 0x20, 0x36, 0x0A, + 0xEA, 0x02, 0x24, 0x75, 0x84, 0x10, 0x1F, 0xED, 0x4F, 0x87, 0x46, 0xA3, 0x79, 0x47, 0x6F, 0x1D, + 0x0D, 0xBE, 0xD4, 0x00, 0x00, 0x00, 0xE0, 0x78, 0x7B, 0xAF, 0xA8, 0x7F, 0x05, 0xAF, 0x8C, 0x8A, + 0xA4, 0x53, 0x41, 0x91, 0x66, 0x22, 0x38, 0xA2, 0xB3, 0xD1, 0xE1, 0x7E, 0xAC, 0xBB, 0xFD, 0xB0, + 0xF1, 0x71, 0x6E, 0xE3, 0x45, 0xC9, 0x6E, 0x3F, 0xEE, 0x6B, 0x75, 0xFB, 0xA1, 0x83, 0x22, 0xCD, + 0x54, 0x50, 0x64, 0xD9, 0xBB, 0xF6, 0xD0, 0x1F, 0x06, 0x48, 0x7B, 0xB7, 0x20, 0xC4, 0x47, 0xFB, + 0xD3, 0x91, 0xD1, 0x74, 0xC7, 0x6E, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x51, 0x66, 0xEF, 0xE2, + 0xDE, 0x89, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x08, 0x03, 0x24, 0x88, 0x8F, 0x78, 0x80, 0xD4, + 0xC5, 0x47, 0xCB, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0xA6, 0x42, 0x22, 0xDB, 0x2E, 0x30, 0xA7, 0xBF, + 0x6D, 0xA3, 0x60, 0x70, 0x32, 0x42, 0x6A, 0x02, 0xC4, 0x85, 0x45, 0xA2, 0x08, 0x21, 0x3E, 0xDA, + 0x9F, 0x88, 0x8B, 0x24, 0x73, 0x6F, 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x1B, 0x00, 0x00, + 0xC0, 0xF4, 0x66, 0x46, 0xFA, 0x67, 0xD7, 0xBC, 0x82, 0x57, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, + 0x33, 0x11, 0x1B, 0xF1, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, 0xDF, 0x7E, 0xD8, 0xF0, 0x10, 0xB7, 0x1F, + 0xF2, 0x43, 0x07, 0x9B, 0xDE, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x76, 0x41, 0x75, + 0xE1, 0x2D, 0xC8, 0xB9, 0x4C, 0xB7, 0x20, 0xC4, 0x47, 0xFB, 0x13, 0x61, 0x91, 0x74, 0x63, 0xCB, + 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xC8, 0x7F, 0x05, 0x6F, 0xF8, 0x06, 0x2C, 0x19, 0x15, 0x49, + 0xA7, 0x82, 0x22, 0xCD, 0x62, 0xA1, 0xD1, 0x68, 0x61, 0x78, 0x84, 0xF1, 0xE1, 0xF6, 0xD4, 0x85, + 0x35, 0xDF, 0x7A, 0x15, 0x0F, 0x90, 0x53, 0x2E, 0x40, 0xC2, 0xDB, 0x8F, 0x1F, 0xD9, 0xC9, 0xF0, + 0x70, 0xD3, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x6C, 0x32, 0x3E, 0xDC, 0x4E, 0x7D, 0xD3, 0xC5, + 0x41, 0x96, 0x5B, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xA8, 0x48, 0xB3, 0x17, 0x3F, 0xC7, 0x9B, 0xB0, + 0x00, 0x00, 0x00, 0x42, 0xFE, 0x1B, 0xB0, 0xB6, 0x7D, 0xC4, 0x1E, 0xEE, 0x55, 0x54, 0x24, 0x9D, + 0x0A, 0x8A, 0x34, 0x13, 0xA1, 0xA1, 0x66, 0xA3, 0xC3, 0xFD, 0x58, 0x7B, 0xFB, 0x61, 0xE3, 0x23, + 0xCD, 0xED, 0xC7, 0xB7, 0x1A, 0xDD, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x56, 0x1B, + 0x1F, 0xE1, 0x26, 0x7E, 0x94, 0xF6, 0x16, 0x84, 0xF8, 0x68, 0x7F, 0x22, 0x28, 0x32, 0x8C, 0x37, + 0x61, 0x01, 0x00, 0x00, 0x04, 0xBC, 0x91, 0x81, 0x0D, 0x3A, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, + 0xC5, 0x22, 0xA3, 0xD9, 0xC2, 0xF0, 0x88, 0xC4, 0x47, 0xA2, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x68, + 0xD7, 0xA3, 0xF1, 0xE1, 0xD6, 0xF2, 0x16, 0x84, 0xF8, 0xC8, 0x79, 0x3A, 0x26, 0xB2, 0xCC, 0x3B, + 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0x38, 0xDE, 0x81, 0xAB, 0x47, 0x75, 0x58, 0x24, 0x99, + 0x0A, 0x8A, 0x34, 0x13, 0x91, 0xD1, 0x62, 0xD5, 0x00, 0x09, 0xE3, 0xA3, 0xED, 0xDB, 0x0F, 0x1D, + 0x14, 0x69, 0xA6, 0x43, 0x22, 0xCB, 0x74, 0x78, 0x44, 0x17, 0xDE, 0x82, 0xB8, 0x78, 0x68, 0x7C, + 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x12, 0x59, 0xE7, 0x1D, 0xBB, 0x65, 0x3C, 0xF8, 0x92, 0x03, + 0x00, 0x00, 0x98, 0xDE, 0xBC, 0x7D, 0x57, 0x8C, 0xEB, 0xB8, 0x68, 0x35, 0x15, 0x14, 0x69, 0xA6, + 0x03, 0xA3, 0xE1, 0x6A, 0x6E, 0x3F, 0x6C, 0x7C, 0x34, 0xBB, 0xFD, 0x08, 0xE3, 0xA3, 0xE5, 0xED, + 0x87, 0x0E, 0x8A, 0x34, 0xD3, 0x21, 0x91, 0x65, 0x3A, 0x38, 0xE2, 0xF3, 0x6F, 0x41, 0x1E, 0x6F, + 0x76, 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x11, 0x6D, 0xCD, 0xBD, 0x09, 0x6B, 0xEC, 0x8B, 0xB3, + 0x82, 0x2F, 0x3B, 0x00, 0x00, 0x80, 0xE9, 0xCB, 0x0C, 0x2D, 0xB0, 0x07, 0x7C, 0x15, 0x18, 0xCD, + 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x60, 0x24, 0x58, 0x18, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xB9, 0x1F, + 0xC9, 0x6E, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0E, 0x89, 0x2C, 0xD3, 0xB1, 0xD1, 0x68, 0x67, 0xBE, + 0x2F, 0x9E, 0x05, 0xF1, 0x43, 0x24, 0x12, 0x1E, 0x6E, 0xC4, 0x47, 0x86, 0x89, 0x78, 0xC8, 0x63, + 0x63, 0xCB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x80, 0xFF, 0x06, 0xAC, 0x9D, 0xB3, 0xED, 0xE1, 0x5E, + 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0x33, 0x1D, 0x17, 0x4D, 0x17, 0xB9, 0xF9, 0xF0, 0xE3, 0x43, + 0xDC, 0x7E, 0x4C, 0xB8, 0x3D, 0x1E, 0xB9, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xE5, 0x89, 0x0F, + 0x7F, 0x77, 0xAB, 0x5B, 0x90, 0x4A, 0x68, 0x18, 0x1B, 0x19, 0xC4, 0x47, 0xD6, 0x89, 0x70, 0xC8, + 0x65, 0x8B, 0x8D, 0x79, 0xF1, 0x5A, 0xE3, 0xFD, 0xE2, 0x4B, 0x77, 0x05, 0x5F, 0x7A, 0x00, 0x00, + 0x00, 0xD3, 0x93, 0x0D, 0x90, 0x75, 0x66, 0xC7, 0x27, 0xEC, 0x21, 0x5F, 0x85, 0x86, 0x9A, 0x0A, + 0x8A, 0x34, 0x13, 0x71, 0x91, 0x64, 0x61, 0x7C, 0xC4, 0x6E, 0x3F, 0x12, 0x3F, 0xFB, 0xF1, 0xCD, + 0x12, 0xC5, 0x47, 0xB0, 0x33, 0xDF, 0x8B, 0x3E, 0x0B, 0x52, 0x89, 0x8C, 0x70, 0x2E, 0x40, 0xC2, + 0xF0, 0x20, 0x3E, 0x92, 0x4E, 0x85, 0x43, 0x1E, 0xB3, 0xF1, 0xE1, 0x66, 0x7F, 0xED, 0xDE, 0x89, + 0x3B, 0x36, 0x04, 0x5F, 0x7A, 0x00, 0x00, 0x00, 0xD3, 0x93, 0xFF, 0x0A, 0x5E, 0x19, 0x1A, 0x6A, + 0x2A, 0x28, 0xD2, 0x4C, 0x84, 0x45, 0xAB, 0xD9, 0xF0, 0xA8, 0xC6, 0x87, 0x0D, 0x8F, 0xC9, 0xDB, + 0x8F, 0xD8, 0xB7, 0x5E, 0x45, 0x6F, 0x3F, 0xEC, 0x1A, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, + 0x12, 0x59, 0xA6, 0xC3, 0x22, 0xF1, 0xAA, 0xB7, 0x20, 0x36, 0x40, 0x36, 0xBA, 0xC0, 0x08, 0x82, + 0x23, 0x12, 0x1E, 0xC4, 0x47, 0xD2, 0xA9, 0x70, 0xC8, 0x63, 0x41, 0x7C, 0x04, 0xF3, 0x4E, 0xFC, + 0x39, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x9B, 0x77, 0xF0, 0xBA, 0x84, 0x6F, 0xC0, 0x52, 0x41, + 0x91, 0x66, 0xB1, 0xB0, 0x48, 0x3A, 0x17, 0x20, 0xE1, 0xCD, 0x87, 0x5D, 0xF5, 0x5B, 0xAF, 0xE4, + 0xB3, 0x1F, 0x17, 0xB5, 0xB8, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x04, 0x45, + 0x86, 0x9D, 0xFE, 0xCE, 0x7B, 0xFD, 0xB0, 0x08, 0x23, 0xA4, 0x1A, 0x1C, 0x2E, 0x3E, 0x82, 0x28, + 0x21, 0x3E, 0x5A, 0x4D, 0x85, 0x43, 0x1E, 0xAB, 0x8D, 0x0F, 0x3F, 0x40, 0x8E, 0x7D, 0x81, 0x37, + 0x61, 0x01, 0x00, 0x80, 0xE9, 0xCD, 0xDB, 0xFB, 0xD9, 0x31, 0x1D, 0x1C, 0xD1, 0xA9, 0xA0, 0x48, + 0xB3, 0x58, 0x54, 0x24, 0x5D, 0x2C, 0x3E, 0xC2, 0xDB, 0x8F, 0xBA, 0xF8, 0x88, 0xDE, 0x7E, 0x84, + 0xF1, 0x11, 0x06, 0xC8, 0x86, 0xF0, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xE9, 0x90, 0xC8, 0x32, 0x1D, + 0x13, 0xA9, 0xF7, 0x57, 0xEF, 0xF5, 0xF7, 0xEE, 0xA3, 0x93, 0x01, 0x12, 0x9F, 0x1F, 0x27, 0x2E, + 0x3C, 0x88, 0x8F, 0x06, 0x53, 0xE1, 0x90, 0xC7, 0xEA, 0xE3, 0xC3, 0xDF, 0x91, 0x1B, 0x4C, 0xF0, + 0xA5, 0x07, 0x00, 0x00, 0x30, 0x3D, 0x99, 0x3D, 0xF6, 0x50, 0x24, 0xA3, 0x23, 0x9C, 0x0A, 0x8A, + 0x34, 0x8B, 0x45, 0x45, 0xD2, 0x35, 0x88, 0x8F, 0xEA, 0x83, 0xE7, 0xEA, 0xF6, 0x23, 0x1E, 0x1F, + 0x0F, 0xD9, 0xDD, 0x5D, 0xEE, 0xF8, 0x70, 0x73, 0xB7, 0x20, 0x7E, 0x60, 0xD8, 0x9D, 0x7B, 0xD2, + 0x86, 0x87, 0xDD, 0xB9, 0x68, 0x7C, 0xD8, 0xF0, 0x38, 0x6B, 0xC3, 0x83, 0xF8, 0x88, 0x4F, 0x85, + 0x43, 0x1E, 0x8B, 0x45, 0x47, 0x74, 0x2F, 0xAD, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xFA, 0x32, + 0x87, 0xFB, 0x97, 0x98, 0xDD, 0xF3, 0xEC, 0x81, 0x5F, 0x85, 0x87, 0x9B, 0x0A, 0x8A, 0x34, 0x8B, + 0x45, 0x45, 0x9A, 0xD9, 0xE8, 0xA8, 0x0B, 0x90, 0x26, 0xDF, 0x7A, 0x25, 0xDF, 0x7C, 0x75, 0xBF, + 0xBB, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x45, 0xE2, 0x23, + 0x9C, 0xBB, 0x05, 0xF1, 0x43, 0x63, 0xD0, 0xC6, 0x88, 0x0D, 0x90, 0xB3, 0xB1, 0x6F, 0xB9, 0x7A, + 0xF7, 0x31, 0xE2, 0xA3, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x88, 0x8E, 0xE8, 0x5E, 0xBC, 0xD6, 0x06, + 0xC8, 0x1D, 0xEB, 0x82, 0x2F, 0x41, 0x00, 0x00, 0x80, 0xE9, 0xC5, 0x7F, 0x05, 0x6F, 0xC3, 0x37, + 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x15, 0x49, 0xF7, 0x8C, 0x88, 0x8F, 0xE8, 0xED, 0x87, 0x8B, + 0x8F, 0x9A, 0x00, 0x11, 0xDF, 0x7A, 0xE5, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, + 0x26, 0x42, 0x22, 0xCB, 0x44, 0x7C, 0xBC, 0xBD, 0xFE, 0xBD, 0xE6, 0xD4, 0x3D, 0x36, 0x42, 0x5C, + 0x68, 0xB8, 0xE0, 0x70, 0x21, 0x12, 0xFC, 0xE8, 0xFE, 0xB5, 0x09, 0x17, 0x1F, 0x36, 0x3C, 0x4E, + 0x3F, 0x42, 0x7C, 0x54, 0xA6, 0xC2, 0x21, 0x8F, 0x89, 0xE0, 0x88, 0xCF, 0xFD, 0xBE, 0x4E, 0xDC, + 0xB1, 0x3E, 0xF8, 0x12, 0x04, 0x00, 0x00, 0x98, 0x5E, 0xFC, 0x37, 0x60, 0x6D, 0xF9, 0x80, 0x3D, + 0xF4, 0x77, 0x5F, 0x7C, 0x34, 0xBA, 0xFD, 0x50, 0xAF, 0xDD, 0xD5, 0xB7, 0x1F, 0xED, 0x7F, 0xEB, + 0x95, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0x0D, 0xE2, 0x23, 0xDC, 0x99, 0x07, 0x6D, 0x6C, + 0x3C, 0x3E, 0xA3, 0x12, 0x22, 0x41, 0x78, 0x4C, 0x3C, 0x7A, 0x81, 0x7F, 0xEB, 0x41, 0x7C, 0x84, + 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x6C, 0x34, 0x98, 0x77, 0xE2, 0x0E, 0xDE, 0x84, 0x05, 0x00, 0x00, + 0xA6, 0x27, 0xEF, 0xD0, 0xCA, 0xC1, 0xAE, 0x8B, 0x8F, 0x5C, 0x6E, 0x3F, 0x2E, 0x6A, 0xFB, 0xF6, + 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0xD6, 0xD7, 0xEC, 0xBF, 0xF6, + 0x4D, 0x17, 0x1D, 0x33, 0xFC, 0x9D, 0xB1, 0xE1, 0xE1, 0xE6, 0x7F, 0xCB, 0x55, 0x18, 0x1F, 0x4F, + 0x11, 0x1F, 0xC5, 0x4C, 0x87, 0x46, 0xA3, 0x79, 0xC7, 0xBE, 0x70, 0x32, 0xF8, 0x12, 0x04, 0x00, + 0x00, 0x98, 0x5E, 0xBC, 0xBD, 0x57, 0xC4, 0x5E, 0xC1, 0xAB, 0x82, 0x22, 0xCD, 0x44, 0x54, 0x24, + 0x5D, 0x24, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0xA3, 0xFE, 0xD9, 0x0F, 0x75, 0xFB, 0x61, 0xE3, 0xE3, + 0xBE, 0xF6, 0x6E, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x4B, 0x10, 0x1F, 0x6F, 0x7D, + 0xED, 0x02, 0xF3, 0xD6, 0x7F, 0xB9, 0xC0, 0x9C, 0xFA, 0xA1, 0x0D, 0x0D, 0x77, 0xE3, 0xF1, 0x63, + 0x1B, 0x1F, 0x41, 0x78, 0xBC, 0xF3, 0x90, 0xFD, 0x91, 0xF8, 0x28, 0x68, 0x3A, 0x32, 0x9A, 0xEE, + 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x4C, 0x4F, 0x66, 0xAF, 0x3D, 0xF0, 0x75, 0x53, 0x7C, + 0x04, 0x01, 0xD2, 0xEC, 0xF6, 0x23, 0x1E, 0x20, 0x75, 0xF1, 0xF1, 0x60, 0x7B, 0x0F, 0x9E, 0xEB, + 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x96, 0x22, 0x3E, 0xDE, 0xFC, 0xCF, 0xF6, 0xC7, 0xBB, 0x6D, + 0x84, 0x04, 0xD1, 0xE1, 0xEF, 0x41, 0xE2, 0x43, 0x87, 0x43, 0x1E, 0x13, 0x71, 0x91, 0x64, 0x47, + 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xFD, 0x98, 0xD1, 0xFE, 0x59, 0x66, 0x68, 0x81, 0x0D, + 0x80, 0xEE, 0x8A, 0x0F, 0xF7, 0xA3, 0xBA, 0xFD, 0x50, 0xCF, 0x7E, 0xD4, 0x7E, 0xE8, 0xA0, 0x0D, + 0x8F, 0x87, 0xDB, 0xBB, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x2C, 0x65, 0x7C, 0xB8, + 0xFD, 0xE1, 0xFF, 0xB1, 0xFF, 0xFF, 0x77, 0x66, 0x98, 0xB7, 0x1F, 0x98, 0x69, 0x67, 0xE3, 0x63, + 0x23, 0xF1, 0x51, 0xCC, 0x44, 0x58, 0x24, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x2F, 0xAD, 0x0D, 0xBE, + 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0xFF, 0x0D, 0x58, 0x3B, 0x67, 0xDB, 0x08, 0x50, 0x41, 0x91, + 0x66, 0x22, 0x2A, 0x92, 0x2E, 0x1A, 0x1F, 0x41, 0x80, 0x34, 0xBB, 0xFD, 0x70, 0xF1, 0x11, 0x0F, + 0x90, 0x6A, 0x7C, 0xB4, 0x79, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, 0x64, 0x59, 0xC6, 0xF8, + 0x78, 0xE3, 0x2F, 0x67, 0x98, 0xF1, 0xFF, 0x3C, 0xC3, 0xBC, 0xF5, 0x23, 0xFB, 0x7B, 0x7A, 0x92, + 0xF8, 0x28, 0x66, 0x22, 0x2A, 0xD2, 0xEC, 0xF9, 0x2B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x7E, + 0xBC, 0x43, 0xAB, 0xEE, 0x32, 0xDB, 0x3E, 0x6A, 0x43, 0x40, 0x45, 0x45, 0xD2, 0x89, 0xA8, 0x48, + 0x3A, 0x11, 0x1F, 0xEE, 0xC7, 0xD4, 0xB7, 0x1F, 0x61, 0x7C, 0xB8, 0xDB, 0x8F, 0x7B, 0xB3, 0xDD, + 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x4E, 0x7C, 0xFC, 0xA7, 0x19, 0xE6, 0xF7, + 0xFF, 0xF7, 0x0C, 0xF3, 0xE6, 0x03, 0xC4, 0x47, 0x31, 0x13, 0x41, 0x91, 0x61, 0xDE, 0x2F, 0xEE, + 0x18, 0x0A, 0xBE, 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0x33, 0xD2, 0xBF, 0x5E, 0x47, 0x45, 0xD2, + 0x89, 0xA8, 0x48, 0xBA, 0x78, 0x7C, 0xB8, 0x85, 0xE1, 0x11, 0xC6, 0x47, 0xAB, 0xDB, 0x0F, 0xFF, + 0x5B, 0xAF, 0x82, 0xF8, 0x70, 0xFB, 0xA1, 0x9D, 0x88, 0x8B, 0x56, 0xD3, 0x21, 0x91, 0x65, 0x22, + 0x24, 0xB2, 0x2C, 0x87, 0xF8, 0x78, 0xE3, 0xDB, 0x36, 0x3E, 0x5E, 0x22, 0x3E, 0xF2, 0x9F, 0x8E, + 0x89, 0x2C, 0xF3, 0x8E, 0xDE, 0x3C, 0x16, 0x7C, 0x29, 0x02, 0x00, 0x00, 0x4C, 0x0F, 0xDE, 0x81, + 0xAB, 0x46, 0x75, 0x58, 0x24, 0x99, 0x88, 0x8A, 0xA4, 0x6B, 0x10, 0x1F, 0xEE, 0xC7, 0x54, 0xB7, + 0x1F, 0xD1, 0xF8, 0x70, 0xB7, 0x1F, 0xDF, 0x4A, 0x7F, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, + 0x64, 0x19, 0xF1, 0x91, 0xC3, 0x54, 0x38, 0xE4, 0x31, 0x1D, 0x12, 0x99, 0xC7, 0x9B, 0xB0, 0x00, + 0x00, 0xC0, 0x74, 0xE3, 0xED, 0xFF, 0xEC, 0x49, 0x1D, 0x17, 0xAD, 0x26, 0xA2, 0x22, 0xE9, 0xE2, + 0xE1, 0x11, 0x2E, 0x0C, 0x8F, 0x30, 0x3E, 0x9A, 0xDD, 0x7E, 0x3C, 0x76, 0x91, 0x39, 0xFD, 0xA8, + 0x0D, 0x8E, 0x36, 0x6F, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, + 0x0A, 0x87, 0x3C, 0x26, 0x02, 0xA2, 0xDD, 0xB9, 0x37, 0x61, 0x1D, 0xBF, 0x63, 0x49, 0xF0, 0xE5, + 0x08, 0x00, 0x00, 0x50, 0x7E, 0x66, 0x68, 0xBE, 0x8D, 0x02, 0x15, 0x18, 0xCD, 0x26, 0xA2, 0x22, + 0xE9, 0x54, 0x78, 0x44, 0x96, 0xE8, 0xF6, 0x23, 0x88, 0x8F, 0x76, 0x6F, 0x3F, 0x74, 0x48, 0x64, + 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0x26, 0xE2, 0x21, 0x8F, 0xBD, + 0x78, 0x1D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x87, 0xFF, 0x06, 0xAC, 0x5D, 0x9F, 0xB6, 0x61, + 0xA0, 0x22, 0xA3, 0xD1, 0x44, 0x54, 0x24, 0x9D, 0x08, 0x8E, 0xEA, 0x92, 0xDE, 0x7E, 0x3C, 0x6E, + 0x03, 0x24, 0x8C, 0x8F, 0x68, 0x80, 0xFC, 0x80, 0xF8, 0x20, 0x3E, 0x54, 0x38, 0xE4, 0x31, 0x11, + 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x3E, 0xCC, 0xA1, 0xFE, 0xB5, + 0x66, 0xC7, 0xC7, 0x6D, 0x1C, 0xA8, 0xD0, 0x50, 0x13, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0x62, 0x53, + 0xB7, 0x1F, 0xD1, 0x00, 0xF1, 0xE3, 0xA3, 0xD1, 0xED, 0xC7, 0x37, 0x75, 0x68, 0xA8, 0xE9, 0x90, + 0xC8, 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x44, 0x43, 0xCE, + 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xDA, 0xF0, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0x36, 0x10, 0x54, + 0x6C, 0xC4, 0x27, 0xA2, 0x22, 0xE9, 0x44, 0x6C, 0xD4, 0x2C, 0xC1, 0xED, 0x87, 0xFB, 0xD6, 0xAB, + 0x89, 0xC7, 0x2E, 0x9C, 0xBC, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xC9, 0x6F, 0x3F, 0x74, 0x48, + 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0xA6, 0x83, 0x21, 0xEF, + 0x79, 0x47, 0xFF, 0x64, 0x34, 0xF8, 0x92, 0x04, 0x00, 0x00, 0x28, 0x37, 0x6F, 0x78, 0xE9, 0x90, + 0x8E, 0x8D, 0xF8, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8E, 0xF8, 0xE2, 0x01, 0xA2, 0x9E, 0xFD, 0x78, + 0xDC, 0xC6, 0x47, 0x9B, 0xB7, 0x1F, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x11, 0x1F, 0x39, + 0x4C, 0x85, 0x43, 0x1E, 0xD3, 0xB1, 0x50, 0xC8, 0x8E, 0x7D, 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, + 0xE9, 0xC1, 0xDB, 0xBB, 0x24, 0xC1, 0x2B, 0x78, 0x45, 0x54, 0x24, 0x9D, 0x8A, 0x8D, 0xE8, 0x6C, + 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, 0x47, 0xEC, 0x5B, 0xAF, 0x9E, 0xB8, 0x70, 0xF2, + 0xF6, 0xC3, 0x2E, 0xCB, 0xED, 0x87, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, + 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x24, 0x14, 0xB6, 0x45, 0x95, 0x37, 0x61, 0xBD, 0x7C, 0xE7, 0xEC, + 0xE0, 0xCB, 0x12, 0x00, 0x00, 0xA0, 0xBC, 0xCC, 0x1E, 0x7B, 0xF8, 0x91, 0xD1, 0x11, 0x4E, 0x44, + 0x45, 0xD2, 0xA9, 0xE0, 0x88, 0x2F, 0x1A, 0x20, 0x76, 0xD5, 0x6F, 0xBD, 0x8A, 0x06, 0x88, 0x8B, + 0x0F, 0xFF, 0xF6, 0xE3, 0xC2, 0xFA, 0xDB, 0x8F, 0x87, 0xEC, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, + 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xB3, + 0x5F, 0x7F, 0x6E, 0x2F, 0x7E, 0xCE, 0x05, 0xC8, 0x40, 0xF0, 0x65, 0x09, 0x00, 0x00, 0x50, 0x4E, + 0x66, 0xA4, 0x7F, 0x76, 0xF3, 0x57, 0xF0, 0x8A, 0xA8, 0x48, 0x3A, 0x15, 0x1B, 0xF1, 0xC5, 0xE2, + 0x23, 0xBC, 0xFD, 0xA8, 0x7D, 0xF0, 0xDC, 0xC6, 0x47, 0xF4, 0xF6, 0x23, 0xFE, 0xAD, 0x57, 0xF7, + 0xB7, 0xBE, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, + 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x16, 0xC4, 0x87, 0x1F, 0x20, 0xD7, 0xF0, 0x26, 0x2C, 0x00, 0x00, + 0x50, 0x7E, 0xFE, 0x2B, 0x78, 0x1B, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, 0xA9, 0xD8, 0x88, 0xAF, + 0x41, 0x7C, 0x54, 0x1F, 0x3C, 0x77, 0xB3, 0xF1, 0x51, 0x73, 0xFB, 0x11, 0x7F, 0xF0, 0xDC, 0xDD, + 0x7E, 0xDC, 0xAD, 0xA3, 0x23, 0x9C, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, + 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0xB5, 0x48, 0x7C, 0x04, 0xF3, 0x4E, 0x7C, 0x69, 0x30, + 0xF8, 0xD2, 0x04, 0x00, 0x00, 0x28, 0x27, 0xFF, 0x0D, 0x58, 0x5B, 0x3F, 0x64, 0xA3, 0x61, 0x8A, + 0xE3, 0xC3, 0x4D, 0x05, 0x48, 0xCD, 0xB7, 0x5E, 0xD9, 0xF8, 0x70, 0xB7, 0x1F, 0x41, 0x7C, 0x64, + 0xB9, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x56, 0x1F, 0x1F, 0x6E, 0xDE, 0xF1, 0x3F, 0xE5, 0x4D, 0x58, 0x00, 0x00, + 0xA0, 0xDC, 0xBC, 0x91, 0x81, 0x0D, 0x1D, 0x89, 0x0F, 0xB7, 0x78, 0x7C, 0x54, 0x6F, 0x3F, 0x2E, + 0xAC, 0xC6, 0xC7, 0xE4, 0xED, 0x47, 0x2C, 0x3E, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, + 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xF1, 0xE1, + 0xEF, 0xD8, 0x2D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x94, 0x9B, 0x77, 0xE0, 0xAA, 0xD8, 0x1B, 0xB0, + 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x8C, 0x46, 0xB3, 0xD1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0x44, 0x02, + 0x24, 0x8C, 0x0F, 0xF9, 0xB9, 0x1F, 0xDF, 0x69, 0x7C, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, + 0x64, 0x59, 0x34, 0x3A, 0x88, 0x8F, 0x8C, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x11, + 0x1D, 0xD1, 0xB9, 0x37, 0x61, 0x8D, 0x7D, 0x71, 0x56, 0xF0, 0xE5, 0x09, 0x00, 0x00, 0x50, 0x3E, + 0xDE, 0xBE, 0x25, 0xE3, 0x53, 0x1E, 0x1F, 0x6E, 0xF1, 0xF8, 0x48, 0x7B, 0xFB, 0xF1, 0xA0, 0x9D, + 0x08, 0x0F, 0x37, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x52, 0xC4, 0x47, 0x18, 0x20, 0x2E, + 0x3E, 0xFE, 0x40, 0x7C, 0x44, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x38, 0xE2, + 0x1B, 0x5B, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB9, 0x4D, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, + 0xA9, 0xC0, 0x68, 0x36, 0x1B, 0x1D, 0xEE, 0x47, 0x75, 0xFB, 0x11, 0x0D, 0x90, 0xA6, 0xB7, 0x1F, + 0xF7, 0xE9, 0xDB, 0x0F, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x22, 0xF1, 0x11, 0xAE, 0x3E, + 0x3E, 0xEC, 0x5C, 0x78, 0x84, 0xB7, 0x1F, 0xC4, 0x47, 0x6C, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, + 0xA2, 0x26, 0x62, 0x43, 0xED, 0xC5, 0x6B, 0x8C, 0xF7, 0x8B, 0x2F, 0xDD, 0x15, 0x7C, 0x79, 0x02, + 0x00, 0x00, 0x94, 0x8B, 0xFF, 0x06, 0xAC, 0x9D, 0x9F, 0xD2, 0x51, 0x91, 0x74, 0xF1, 0xB8, 0x48, + 0xB2, 0x30, 0x3C, 0xC2, 0xF8, 0xF0, 0x03, 0x64, 0x66, 0x35, 0x3E, 0x6A, 0xDF, 0x7C, 0x95, 0xFC, + 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0x76, 0x24, 0x3E, 0xE2, + 0x37, 0x1F, 0x6F, 0x04, 0xF1, 0xF1, 0x07, 0xE2, 0xA3, 0xA0, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x34, + 0x9A, 0xCC, 0x3B, 0x71, 0xC7, 0x86, 0xE0, 0x4B, 0x14, 0x00, 0x00, 0xA0, 0x5C, 0x6C, 0x80, 0xAC, + 0x33, 0xDB, 0x2F, 0xD6, 0x61, 0x91, 0x64, 0x2A, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0xF6, + 0xF6, 0xC3, 0xC6, 0x47, 0x83, 0x67, 0x3F, 0xEA, 0x3E, 0x74, 0xD0, 0xBD, 0xF9, 0x4A, 0xDC, 0x7E, + 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x22, 0x3E, 0xA2, 0x37, 0x1F, 0x61, 0x7C, 0x84, + 0x37, 0x1F, 0xC4, 0x47, 0x38, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x91, 0xD1, 0x6C, + 0xDE, 0x89, 0x3F, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x9C, 0xFC, 0x57, 0xF0, 0xAA, 0xB0, 0x48, + 0xB2, 0x78, 0x58, 0x24, 0x5D, 0x18, 0x1E, 0x61, 0x7C, 0x3C, 0x3D, 0xB3, 0xE6, 0xF6, 0xA3, 0xEE, + 0xD9, 0x0F, 0x1B, 0x20, 0xA7, 0xA2, 0x01, 0xF2, 0x23, 0xBB, 0x1E, 0x8C, 0x0F, 0xB7, 0xBA, 0x00, + 0x69, 0x10, 0x1F, 0xE3, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0xC0, + 0x68, 0x35, 0xEF, 0xD8, 0x17, 0xC6, 0x83, 0x2F, 0x51, 0x00, 0x00, 0x80, 0x72, 0xF1, 0x0E, 0x5C, + 0x33, 0x2A, 0xE3, 0xA2, 0xD5, 0x54, 0x58, 0x24, 0x99, 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, + 0xF1, 0x11, 0xBD, 0xFD, 0x88, 0xC5, 0x47, 0xDD, 0xED, 0xC7, 0xB7, 0x6A, 0x6F, 0x3F, 0x74, 0x48, + 0x64, 0x99, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x56, 0x17, 0x1F, 0xEA, 0x8D, 0x57, 0xC4, 0x47, + 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x71, 0x91, 0x68, 0x47, 0x56, 0xF3, 0x26, + 0x2C, 0x00, 0x00, 0x50, 0x4E, 0xDE, 0xDE, 0x25, 0x63, 0x32, 0x30, 0x9A, 0x2D, 0x1E, 0x15, 0x69, + 0x16, 0x86, 0x47, 0x18, 0x1F, 0x69, 0x6F, 0x3F, 0x7E, 0x68, 0x57, 0xB6, 0xF8, 0x70, 0x37, 0x1F, + 0x2E, 0x3E, 0xDC, 0x43, 0xE7, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, + 0xA8, 0x48, 0xB3, 0x97, 0x56, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x4E, 0x66, 0xCF, 0x42, 0x1D, + 0x19, 0x8D, 0xA6, 0xA2, 0x22, 0xE5, 0x2A, 0x01, 0x32, 0xB3, 0xED, 0xDB, 0x0F, 0x1D, 0x12, 0x59, + 0x26, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0xB5, 0x8C, 0x8F, 0xBF, 0x9C, 0xFC, 0xAC, 0x8F, 0x3F, + 0xDC, 0x4B, 0x7C, 0x14, 0x33, 0x15, 0x09, 0x45, 0x4D, 0x04, 0x45, 0xDA, 0xBD, 0x78, 0x8D, 0x0D, + 0x90, 0x3B, 0xD6, 0x05, 0x5F, 0xA6, 0x00, 0x00, 0x00, 0xE5, 0x60, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, + 0xE6, 0xE8, 0xD0, 0x50, 0x13, 0x31, 0x91, 0x6A, 0xD5, 0xDB, 0x8F, 0x20, 0x3E, 0x9A, 0xDD, 0x7E, + 0x84, 0xF1, 0xD1, 0xE0, 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, + 0x0D, 0xE3, 0x23, 0x08, 0x90, 0xE8, 0x07, 0x0D, 0x12, 0x1F, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, + 0xA2, 0x26, 0x62, 0x22, 0xCB, 0x9E, 0xB7, 0x7F, 0x3F, 0x4E, 0xDC, 0xB1, 0x3E, 0xF8, 0x52, 0x05, + 0x00, 0x00, 0x28, 0x07, 0xFF, 0x15, 0xBC, 0x49, 0xDF, 0x80, 0xA5, 0x82, 0x22, 0xC3, 0xFC, 0xF8, + 0x88, 0xDD, 0x7E, 0x54, 0x03, 0xA4, 0xD5, 0xED, 0xC7, 0x3D, 0xBD, 0x1B, 0x1F, 0x95, 0xD7, 0xED, + 0x12, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x24, 0xDA, 0x18, 0x6F, + 0xC2, 0x02, 0x00, 0x00, 0xA5, 0xE3, 0xBF, 0x01, 0x6B, 0xEB, 0x07, 0x75, 0x70, 0x44, 0x27, 0x42, + 0x22, 0xF5, 0xC2, 0x9B, 0x8F, 0x26, 0xB7, 0x1F, 0x13, 0x2E, 0x40, 0x1E, 0x8B, 0xDC, 0x7E, 0x84, + 0xF1, 0xE1, 0xF6, 0xBD, 0xCA, 0xB7, 0x5E, 0xE9, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x26, 0xC2, + 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x11, 0xD1, 0xCE, + 0xBC, 0x63, 0x5F, 0x38, 0x19, 0x7C, 0xA9, 0x02, 0x00, 0x00, 0x94, 0x83, 0x37, 0xBC, 0x62, 0x50, + 0x06, 0x47, 0x74, 0x2A, 0x26, 0xB2, 0x2C, 0x8C, 0x8F, 0xD8, 0xED, 0x47, 0xE2, 0x67, 0x3F, 0xBE, + 0xC9, 0xB7, 0x5D, 0x25, 0x9B, 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, + 0x2A, 0x12, 0x8A, 0x9A, 0x0E, 0x88, 0xB6, 0x77, 0x64, 0xB5, 0x09, 0xBE, 0x54, 0x01, 0x00, 0x00, + 0xCA, 0xC1, 0xDB, 0x7B, 0x79, 0xF3, 0x57, 0xF0, 0xAA, 0x90, 0x48, 0xBB, 0x4D, 0x6E, 0x93, 0xE1, + 0x31, 0x79, 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xFC, 0xF6, 0x43, 0x87, 0x44, + 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0x0D, 0xE3, 0xC3, 0x3D, 0x70, 0x1E, 0x8B, 0x8F, + 0xF1, 0xFF, 0x32, 0xCB, 0x9C, 0xFF, 0xD7, 0x5B, 0x83, 0xF8, 0x58, 0x65, 0x0F, 0xFA, 0x2A, 0x28, + 0xD2, 0x4C, 0x84, 0x43, 0x1E, 0x93, 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, + 0x4D, 0x84, 0x43, 0x5E, 0x3B, 0xB2, 0x92, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF1, 0xF6, 0x2C, + 0x1A, 0x97, 0xE1, 0xE1, 0xA6, 0x62, 0x22, 0xCB, 0x6C, 0x78, 0x44, 0x6F, 0x3F, 0xAA, 0xDF, 0x7A, + 0x15, 0x06, 0x48, 0xCD, 0x6B, 0x77, 0x2F, 0x94, 0xB7, 0x1F, 0xEF, 0x7C, 0x23, 0xAF, 0xDB, 0x0F, + 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x2D, 0x6D, 0x7C, 0x9C, 0xFB, 0xE9, 0x17, 0x2A, 0xF1, 0x71, + 0xD4, 0xFE, 0x28, 0x83, 0x22, 0xCD, 0x44, 0x38, 0xE4, 0x31, 0x19, 0x0E, 0x79, 0x4C, 0x85, 0x43, + 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x44, 0x34, 0xE4, 0x39, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xCA, 0xC4, + 0x0C, 0xF5, 0xCF, 0x32, 0x43, 0x7D, 0x53, 0x1A, 0x1F, 0xE1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xCD, + 0x9E, 0xFD, 0x70, 0xF1, 0x71, 0x7F, 0x5E, 0xB7, 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, + 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x82, 0x21, 0xEF, 0xB9, 0xFF, + 0x6D, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0x0B, 0xFF, 0x0D, 0x58, 0x3B, 0x3E, 0x39, 0xE5, 0xF1, + 0x51, 0x7D, 0xF0, 0x5C, 0xDD, 0x7E, 0xC4, 0x1E, 0x3C, 0x7F, 0xE7, 0x41, 0x1B, 0x1F, 0x5F, 0x57, + 0x31, 0x91, 0x76, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x62, 0xA1, 0xA0, 0x79, 0x27, 0xEE, 0xE0, 0x4D, 0x58, 0x00, 0x00, + 0xA0, 0x1C, 0xBC, 0xE1, 0xFE, 0xBB, 0xCC, 0xB6, 0x8F, 0x14, 0x13, 0x1F, 0xCF, 0x54, 0xE2, 0xA3, + 0x2E, 0x40, 0xE2, 0xAF, 0xDD, 0x75, 0xB7, 0x1F, 0x41, 0x7C, 0xC4, 0x6F, 0x3F, 0xDE, 0x79, 0xD8, + 0xC6, 0xC7, 0x77, 0xF3, 0xF8, 0xD6, 0x2B, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, + 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xA1, 0x50, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, + 0x82, 0x2F, 0x59, 0x00, 0x00, 0x80, 0xDE, 0xE6, 0xBF, 0x82, 0xB7, 0xA8, 0xF8, 0x08, 0x02, 0xA4, + 0xE1, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0x8A, 0xC7, 0x47, 0x2E, 0xB7, 0x1F, 0x22, 0x24, + 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0xA6, + 0x23, 0xA1, 0xD0, 0x1D, 0xB9, 0x91, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF0, 0x0E, 0x5C, 0x33, + 0xF9, 0x06, 0x2C, 0x19, 0x12, 0x59, 0x36, 0x19, 0x1F, 0x8D, 0x6E, 0x3F, 0xAA, 0xAF, 0xDD, 0xAD, + 0xDE, 0x7E, 0x5C, 0x14, 0xBB, 0xFD, 0xB0, 0xE1, 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, + 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x38, 0x98, + 0x8A, 0xBD, 0x34, 0x60, 0xCC, 0xF1, 0x3B, 0x96, 0x04, 0x5F, 0xB6, 0x00, 0x00, 0x00, 0xBD, 0xCB, + 0xDB, 0x77, 0xC5, 0xC9, 0x42, 0xE2, 0xA3, 0xAD, 0xDB, 0x8F, 0x20, 0x3E, 0x1E, 0x68, 0xF7, 0xF6, + 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, + 0x50, 0xD4, 0x44, 0x18, 0x4C, 0xD5, 0xDC, 0x9B, 0xB0, 0x4E, 0x7C, 0x69, 0x6D, 0xF0, 0x65, 0x0B, + 0x00, 0x00, 0xD0, 0xBB, 0xCC, 0xEE, 0xBE, 0x48, 0x3C, 0xB4, 0xBB, 0xDA, 0xF8, 0x70, 0x3F, 0xAA, + 0xDB, 0x8F, 0xFA, 0x67, 0x3F, 0xA2, 0xB7, 0x1F, 0x41, 0x7C, 0xB8, 0xDD, 0xDB, 0xCE, 0xED, 0x87, + 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, + 0xA8, 0x89, 0x28, 0x98, 0xCA, 0xBD, 0x70, 0x25, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xCF, 0x1C, + 0xE8, 0x5F, 0x62, 0x76, 0xCE, 0x0E, 0xE2, 0xA1, 0xDD, 0x45, 0xE2, 0x23, 0x08, 0x90, 0x66, 0xB7, + 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xE1, 0x6E, 0x3F, 0x64, 0x58, 0x24, 0x99, 0x08, 0x89, 0x2C, + 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x20, + 0xE8, 0xC0, 0xBC, 0xE3, 0xB7, 0x0F, 0x05, 0x5F, 0xBA, 0x00, 0x00, 0x00, 0xBD, 0xC9, 0x1C, 0x5C, + 0xB6, 0xD6, 0x6C, 0xFF, 0x58, 0x10, 0x10, 0xED, 0xAC, 0x3E, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0x43, + 0x3D, 0xFB, 0x51, 0xF9, 0xD0, 0xC1, 0x0B, 0x27, 0x03, 0xE4, 0x21, 0xBB, 0xCC, 0xB7, 0x1F, 0x22, + 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, + 0xA6, 0x63, 0xA0, 0x13, 0xF3, 0x8E, 0xDE, 0xC2, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x33, 0x23, + 0xCB, 0xD7, 0x9B, 0xCD, 0xEF, 0xB3, 0xB1, 0xA0, 0xA2, 0x22, 0xE9, 0x62, 0xF1, 0xE1, 0x16, 0x86, + 0x47, 0x18, 0x1F, 0xB1, 0xDB, 0x8F, 0xBA, 0x67, 0x3F, 0x1E, 0xB5, 0xF1, 0xE1, 0x02, 0xA4, 0xED, + 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, + 0x45, 0x42, 0x51, 0xD3, 0x21, 0xD0, 0xB1, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, + 0xE6, 0x1D, 0xB8, 0x7E, 0xA8, 0x36, 0x26, 0xD2, 0x4E, 0xC7, 0x87, 0xFB, 0xB1, 0xE9, 0xED, 0x47, + 0x2C, 0x3E, 0xEA, 0x6E, 0x3F, 0xEE, 0xC9, 0x72, 0xFB, 0x21, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, + 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x00, 0x3A, 0x3D, 0xF7, + 0x26, 0xAC, 0x97, 0xEF, 0x9C, 0x1D, 0x7C, 0xF9, 0x02, 0x00, 0x00, 0xF4, 0x1E, 0x6F, 0xEF, 0x65, + 0xA3, 0xF5, 0x51, 0x91, 0x74, 0xB1, 0xF0, 0x08, 0x17, 0x86, 0x47, 0x18, 0x1F, 0x4D, 0x6F, 0x3F, + 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x4E, 0x06, 0x46, 0xB3, 0x89, 0x90, 0xC8, + 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, + 0xFC, 0x77, 0xC3, 0x5E, 0xFC, 0x9C, 0x31, 0xC7, 0x6E, 0x1B, 0x08, 0xBE, 0x7C, 0x01, 0x00, 0x00, + 0x7A, 0x8F, 0xD9, 0x63, 0x0F, 0x5B, 0x32, 0x2E, 0x5A, 0x4D, 0x84, 0x47, 0x64, 0xC9, 0x6E, 0x3F, + 0x2A, 0xF1, 0xD1, 0xFE, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, + 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xFE, 0xDD, 0x32, 0xDE, 0x84, 0x05, 0x00, + 0x00, 0x7A, 0x99, 0x19, 0xE9, 0x9F, 0x6D, 0x76, 0xCF, 0xB3, 0xC1, 0xA0, 0x02, 0xA3, 0xD9, 0x74, + 0x74, 0xF8, 0x4B, 0x7C, 0xFB, 0x31, 0xD3, 0x9C, 0x09, 0xE3, 0xA3, 0xAD, 0xDB, 0x0F, 0x11, 0x12, + 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xFE, 0x2E, 0x9B, 0x77, 0xE2, 0xF6, 0xC1, 0xE0, 0x4B, 0x18, 0x00, 0x00, 0xA0, 0xB7, 0xD8, + 0x00, 0x19, 0x48, 0xFF, 0x06, 0x2C, 0x11, 0x1D, 0xB1, 0xA9, 0xDB, 0x8F, 0x6A, 0x80, 0x84, 0xF1, + 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, + 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7F, 0xB7, 0xCD, 0x3B, 0xFA, 0x85, 0xD1, 0xE0, 0x4B, + 0x18, 0x00, 0x00, 0xA0, 0xB7, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0x3E, 0x60, 0xA3, 0x41, 0x85, + 0x86, 0x9A, 0x0E, 0x8E, 0xEA, 0x12, 0xDC, 0x7E, 0x4C, 0x3C, 0x31, 0xD3, 0x4C, 0x3C, 0x16, 0xB9, + 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0xFB, 0xC4, 0x47, 0x65, 0x22, 0x1C, 0xF2, 0x98, 0x0C, 0x87, 0x3C, + 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0xB0, 0xDF, 0x95, 0x3B, 0x76, 0x0B, 0x6F, + 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xC9, 0x1B, 0x59, 0xB1, 0xA1, 0x3E, 0x32, 0x1A, 0x4D, 0x04, 0x47, + 0x7C, 0xF1, 0x00, 0xA9, 0x7B, 0xF6, 0xC3, 0xC6, 0x47, 0xB3, 0xDB, 0x8F, 0x6F, 0xA8, 0xD0, 0x50, + 0x13, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, + 0x14, 0x35, 0x71, 0xC8, 0xEF, 0xE6, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xAB, 0xBC, 0x7D, 0x57, + 0x24, 0x7C, 0x03, 0x96, 0x88, 0x8D, 0xE8, 0x6C, 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, + 0x47, 0xE4, 0x5B, 0xAF, 0x06, 0x6D, 0x7C, 0x44, 0x6F, 0x3F, 0xEC, 0x6A, 0x6E, 0x3F, 0x36, 0x24, + 0xBD, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, + 0x54, 0x24, 0x14, 0x35, 0x71, 0xC0, 0xEF, 0xF6, 0x8D, 0x2D, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0xA0, + 0x37, 0x79, 0x7B, 0x2F, 0x1B, 0xAF, 0x8F, 0x8D, 0xF8, 0x62, 0xB1, 0xA1, 0x16, 0x0D, 0x10, 0xBB, + 0xEA, 0xB7, 0x5E, 0x85, 0x01, 0x62, 0xE3, 0x63, 0xF2, 0xF6, 0x63, 0x66, 0x1B, 0xB7, 0x1F, 0x22, + 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, + 0x26, 0x0E, 0xF7, 0xBD, 0xB0, 0x17, 0xAF, 0x31, 0xDE, 0x2F, 0x6E, 0xBF, 0x2B, 0xF8, 0x32, 0x06, + 0x00, 0x00, 0xE8, 0x1D, 0xAD, 0xDF, 0x80, 0x15, 0x0B, 0x0D, 0xB5, 0x58, 0x7C, 0x84, 0xB7, 0x1F, + 0x93, 0x0F, 0x9E, 0xDB, 0xF8, 0x88, 0xDF, 0x7E, 0x84, 0xF1, 0x11, 0x06, 0x48, 0xA2, 0xDB, 0x0F, + 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, + 0x51, 0x13, 0x07, 0xFB, 0x1E, 0x9A, 0x77, 0xFC, 0x8E, 0x0D, 0xC1, 0x97, 0x31, 0x00, 0x00, 0x40, + 0x6F, 0xF0, 0xDF, 0x80, 0xB5, 0x73, 0xB6, 0x8D, 0x08, 0x15, 0x1E, 0x6E, 0xB1, 0xD0, 0x50, 0x6B, + 0x10, 0x1F, 0xD5, 0x07, 0xCF, 0x37, 0xCE, 0xAC, 0xBF, 0xFD, 0x08, 0xE2, 0xA3, 0x7A, 0xFB, 0xF1, + 0xA0, 0xDD, 0xD7, 0x55, 0x70, 0x44, 0x27, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, + 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0x50, 0xDF, 0x4B, 0xF3, 0x8E, 0xDE, 0xCA, + 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x31, 0x23, 0xCB, 0xD7, 0x35, 0x7E, 0x05, 0x6F, 0x2C, 0x34, + 0x1A, 0x4D, 0x05, 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x41, 0x7C, 0xC8, 0x37, + 0x5F, 0x7D, 0xB7, 0xD5, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, + 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7D, 0xAF, 0xCD, 0x3B, 0xFA, 0xF9, 0xF1, + 0xE0, 0x4B, 0x19, 0x00, 0x00, 0xA0, 0x37, 0xD8, 0x00, 0x59, 0x5F, 0x1F, 0x1E, 0x29, 0xE2, 0xC3, + 0x2D, 0x1E, 0x1F, 0xD5, 0xDB, 0x8F, 0xC9, 0xF8, 0xA8, 0x79, 0xF3, 0x55, 0xEA, 0xDB, 0x0F, 0x11, + 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, + 0xD3, 0x87, 0xF9, 0x9E, 0x9C, 0x7B, 0x13, 0xD6, 0xD8, 0x17, 0x67, 0x05, 0x5F, 0xCE, 0x00, 0x00, + 0x00, 0xDD, 0xCF, 0x3B, 0x70, 0xD5, 0x50, 0xBB, 0xF1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0xD4, 0xDD, + 0x7E, 0x5C, 0x98, 0xE1, 0xF6, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, + 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBE, 0x97, 0x37, 0xB6, 0x9C, 0x37, 0x61, + 0x01, 0x00, 0x80, 0xDE, 0xE2, 0xED, 0xBD, 0x7C, 0x2C, 0x73, 0x7C, 0xB8, 0xC5, 0xE3, 0xC3, 0x0F, + 0x90, 0x19, 0x39, 0xDD, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, + 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xC0, 0xF7, 0xFA, 0x78, 0x13, 0x16, 0x00, 0x00, + 0xE8, 0x35, 0x66, 0x68, 0x81, 0x0D, 0x89, 0xEC, 0xF1, 0xE1, 0x7E, 0xAC, 0xBD, 0xFD, 0xB0, 0xF1, + 0x11, 0xFB, 0xF6, 0xAB, 0xA6, 0xB7, 0x1F, 0xF7, 0x35, 0xBA, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, + 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x78, 0x2F, + 0xC3, 0x9E, 0xBF, 0x9C, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, 0x61, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, + 0x2E, 0xB5, 0x11, 0x91, 0x21, 0x3E, 0xDC, 0xC2, 0xF0, 0x08, 0xE3, 0xE3, 0xE9, 0x19, 0x35, 0xB7, + 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xF1, 0x80, 0x1D, 0xF1, 0x91, 0xCF, 0x64, 0x38, 0xE4, 0x31, + 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x07, 0xF7, 0x12, 0xCD, 0x3B, 0xFE, 0x67, 0xBC, + 0x09, 0x0B, 0x00, 0x00, 0xF4, 0x06, 0xFF, 0x15, 0xBC, 0xFE, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, + 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, 0xF1, 0xD1, 0xE0, 0xD9, 0x0F, 0xF9, 0xA1, 0x83, 0xF7, + 0xAA, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, + 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x87, 0xF6, 0x32, 0xCD, 0x3B, 0xFA, 0xF9, 0x93, 0xC1, 0x97, 0x34, + 0x00, 0x00, 0x40, 0x77, 0xF3, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0xF5, 0x71, 0x91, 0x64, 0x61, 0x78, + 0x84, 0xF1, 0x11, 0xBB, 0xFD, 0xA8, 0x7B, 0xF6, 0xC3, 0x06, 0xC8, 0x29, 0x17, 0x20, 0x4D, 0x6F, + 0x3F, 0x44, 0x48, 0x64, 0x99, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, + 0x09, 0x45, 0x4D, 0x1F, 0xD8, 0x4B, 0xB7, 0x23, 0xAB, 0x4C, 0xF0, 0x25, 0x0D, 0x00, 0x00, 0xD0, + 0xDD, 0xBC, 0xE1, 0x65, 0x83, 0x32, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0x12, 0x20, 0x33, + 0xF4, 0xED, 0x47, 0x2C, 0x3E, 0x5A, 0xDF, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, + 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA8, 0x97, 0x75, 0x63, 0xCB, + 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0D, 0xDE, 0xDE, 0xCB, 0x46, 0xEB, 0xE2, 0x22, 0xC9, 0xAA, + 0xB7, 0x1F, 0x41, 0x7C, 0x24, 0xBD, 0xFD, 0x08, 0x03, 0xE4, 0x07, 0x76, 0xC4, 0x47, 0x7B, 0x93, + 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0xBA, 0x7F, + 0x5D, 0x68, 0xCC, 0x0B, 0x57, 0x1B, 0x73, 0xFC, 0x8E, 0x75, 0xC1, 0x97, 0x35, 0x00, 0x00, 0x40, + 0xF7, 0xF2, 0xF6, 0x2C, 0x18, 0x97, 0x81, 0xD1, 0x6C, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0x59, 0x6F, + 0x3F, 0xEE, 0x89, 0xDE, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, + 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2E, 0x3E, 0xDC, 0x7E, 0x6E, + 0xFF, 0x99, 0x38, 0x71, 0xDB, 0xFA, 0xE0, 0xCB, 0x1A, 0x00, 0x00, 0xA0, 0x3B, 0x99, 0xA1, 0xFE, + 0x59, 0x66, 0xF7, 0xDC, 0xFA, 0xC0, 0x68, 0xB5, 0xF0, 0xE6, 0x23, 0x97, 0xDB, 0x0F, 0x11, 0x12, + 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xF4, 0xB2, 0x2E, 0x8C, 0x8F, 0x60, 0xDE, 0x89, 0xDB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, + 0x6E, 0x66, 0x64, 0xE9, 0x80, 0xD9, 0xF1, 0x71, 0x1D, 0x19, 0xCD, 0x16, 0xC6, 0x47, 0xDB, 0xB7, + 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, + 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x5D, 0x2C, 0x3E, 0xFC, 0x00, 0x39, 0x7A, 0x33, 0x6F, 0xC2, + 0x02, 0x00, 0x00, 0xDD, 0xCD, 0x1B, 0x5E, 0x7E, 0x97, 0xD9, 0xFA, 0x21, 0x1D, 0x19, 0x8D, 0x16, + 0x8F, 0x8F, 0x66, 0xB7, 0x1F, 0x61, 0x7C, 0xC8, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, + 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, + 0xC4, 0x87, 0xBF, 0x23, 0x37, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xDD, 0xFC, 0x57, 0xF0, 0xAA, + 0xC8, 0x68, 0x34, 0x1B, 0x1D, 0x8D, 0x6E, 0x3F, 0xAA, 0x01, 0xD2, 0xEA, 0xF6, 0xE3, 0x1B, 0xC4, + 0x47, 0xA6, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, + 0x65, 0x9D, 0x0A, 0x8F, 0x70, 0x2F, 0xF5, 0xBB, 0x07, 0xD1, 0x97, 0x04, 0x5F, 0xDE, 0x00, 0x00, + 0x00, 0xDD, 0xC7, 0x3B, 0x70, 0x75, 0xF2, 0x37, 0x60, 0x45, 0xE3, 0xC3, 0x86, 0x47, 0xA3, 0xDB, + 0x8F, 0x09, 0x17, 0x20, 0x8F, 0x45, 0x6E, 0x3F, 0xC2, 0xF8, 0x70, 0xDB, 0xE0, 0xBE, 0xF5, 0x4A, + 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, + 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xD1, 0x11, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x3F, 0x5F, 0x1B, + 0x7C, 0x79, 0x03, 0x00, 0x00, 0x74, 0x1F, 0x6F, 0xDF, 0xE5, 0x27, 0x65, 0x6C, 0xC4, 0x17, 0xC4, + 0x47, 0xA3, 0xDB, 0x8F, 0xC4, 0xCF, 0x7E, 0x7C, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, + 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xC1, + 0x11, 0x1F, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xDD, 0x2E, 0xD1, 0x1B, 0xB0, 0xE2, 0xF1, 0x51, 0x73, + 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xED, 0xED, 0x47, 0x4E, 0xDF, 0x7A, 0x25, + 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, + 0xB2, 0x4E, 0xC5, 0x46, 0x83, 0x79, 0xC7, 0x6F, 0x1F, 0x0A, 0xBE, 0xBC, 0x01, 0x00, 0x00, 0xBA, + 0x8B, 0x39, 0x70, 0xFD, 0x12, 0xB3, 0xF3, 0x53, 0x3A, 0x3A, 0xC2, 0x45, 0xE2, 0xA3, 0x1A, 0x20, + 0x76, 0xD5, 0x6F, 0xBD, 0x0A, 0x03, 0xA4, 0xE6, 0xB5, 0xBB, 0x33, 0xC5, 0xED, 0xC7, 0xCC, 0x7C, + 0x6E, 0x3F, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, + 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0xC8, 0x68, 0x36, 0xEF, 0xC8, 0x9A, 0xB1, 0xE0, 0x4B, 0x1C, 0x00, + 0x00, 0xA0, 0xBB, 0x98, 0x83, 0xCB, 0xD6, 0x9A, 0xED, 0x1F, 0xD5, 0xE1, 0xE1, 0x16, 0x09, 0x8F, + 0x68, 0x7C, 0x84, 0xB7, 0x1F, 0x35, 0x0F, 0x9E, 0x37, 0x7A, 0xF6, 0xC3, 0x0F, 0x10, 0x1B, 0x1F, + 0xDF, 0xCD, 0xE1, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, + 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x08, 0x8C, 0x96, 0x3B, 0xBA, 0x86, 0x37, 0x61, 0x01, + 0x00, 0x80, 0xEE, 0xE4, 0xBF, 0x01, 0x6B, 0xF3, 0xAC, 0x4C, 0xF1, 0x51, 0x7D, 0xF0, 0x5C, 0xDD, + 0x7E, 0x04, 0xF1, 0x51, 0xB9, 0xFD, 0xB0, 0xF1, 0xF1, 0xA0, 0xDD, 0xD7, 0x45, 0x50, 0xA4, 0x99, + 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, + 0xCB, 0x3A, 0x15, 0x17, 0x49, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB7, 0xF2, 0x0E, 0x7C, 0x6E, + 0x28, 0x49, 0x7C, 0xD4, 0x05, 0x48, 0xFC, 0xB5, 0xBB, 0xEE, 0xF6, 0x23, 0x88, 0x8F, 0xDA, 0x37, + 0x5F, 0xD9, 0xF0, 0xC8, 0xE3, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x0A, 0x8B, 0xA4, 0x7B, 0xE1, 0x5A, 0x63, + 0x8E, 0xDD, 0x36, 0x10, 0x7C, 0x99, 0x03, 0x00, 0x00, 0x74, 0x0F, 0x6F, 0xEF, 0x65, 0xF5, 0xAF, + 0xE0, 0x8D, 0x44, 0x87, 0x8C, 0x8F, 0xE8, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0xAA, 0xDE, + 0x7E, 0x04, 0xF1, 0xD1, 0xEE, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, + 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x15, 0x69, 0xF6, 0xFC, 0x67, 0x79, + 0x13, 0x16, 0x00, 0x00, 0xE8, 0x4E, 0x66, 0x8F, 0x3D, 0xEC, 0xB4, 0x88, 0x0F, 0x37, 0x75, 0xFB, + 0x51, 0x7D, 0xED, 0x6E, 0xF5, 0xF6, 0xE3, 0xC2, 0xC8, 0xED, 0x47, 0x10, 0x1F, 0xED, 0xDE, 0x7E, + 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x62, 0x07, + 0xF4, 0x32, 0x4F, 0x05, 0x45, 0x86, 0x79, 0x27, 0x6E, 0x1B, 0x0C, 0xBE, 0xCC, 0x01, 0x00, 0x00, + 0xBA, 0x83, 0x19, 0xE9, 0x9F, 0x5D, 0xF3, 0x0A, 0xDE, 0x48, 0x70, 0x44, 0x97, 0xFE, 0xF6, 0x63, + 0xE6, 0x64, 0x80, 0x3C, 0x60, 0xA7, 0xC2, 0x22, 0xC9, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, + 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0x90, 0xC8, 0x3A, 0xEF, + 0xC8, 0xE7, 0x47, 0x83, 0x2F, 0x75, 0x00, 0x00, 0x80, 0xEE, 0x60, 0x46, 0x96, 0x0E, 0x54, 0xDF, + 0x80, 0x15, 0x09, 0x8E, 0xF8, 0xD4, 0xED, 0x47, 0xFD, 0xB3, 0x1F, 0xE1, 0xED, 0x47, 0x24, 0x3E, + 0xDC, 0xEE, 0xCD, 0x78, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, + 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x44, 0x44, 0x5B, 0xE3, 0x4D, 0x58, 0x00, 0x00, + 0xA0, 0xDB, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0xDE, 0x2F, 0xA3, 0x23, 0x5C, 0xB3, 0xDB, 0x8F, + 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0xC8, 0x7A, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, + 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x05, 0x44, 0xBB, 0x73, 0x6F, + 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x3B, 0x00, 0x00, 0x40, 0xE7, 0x79, 0x23, 0xCB, 0x36, + 0xA8, 0xE8, 0x88, 0x4E, 0xDD, 0x7E, 0xD4, 0x3F, 0xFB, 0xE1, 0x3E, 0x74, 0xD0, 0xBD, 0x7A, 0x37, + 0x12, 0x20, 0xEE, 0x43, 0x07, 0xB3, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, + 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xF1, 0x90, 0xC7, 0x5E, 0xBC, + 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, 0xEE, 0xE2, 0xED, 0xBD, 0x62, 0x54, 0x45, 0x47, 0xB8, 0x66, + 0xB7, 0x1F, 0xD5, 0x67, 0x3F, 0xFC, 0xD7, 0xEE, 0x06, 0xF1, 0xE1, 0xD6, 0xCE, 0xED, 0x87, 0x08, + 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, + 0x3A, 0x15, 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x2E, 0xDE, 0xDE, + 0xC5, 0xE3, 0x2A, 0x3C, 0xC2, 0x35, 0xBD, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC5, 0x87, 0xBA, 0xFD, + 0xB8, 0x27, 0xE5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, + 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x0D, 0x39, 0xCF, 0x3B, 0xB6, 0x96, 0x37, 0x61, + 0x01, 0x00, 0x80, 0xEE, 0xE1, 0xBF, 0x01, 0x2B, 0x12, 0x1C, 0xD1, 0xB5, 0xBC, 0xFD, 0xB0, 0xF1, + 0x31, 0xF1, 0xD8, 0x8C, 0xDA, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x60, 0xA7, 0x22, 0xA3, 0xD1, 0x44, + 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, + 0xD6, 0x89, 0x58, 0x28, 0x62, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0E, 0xFE, + 0x1B, 0xB0, 0x76, 0x7C, 0x52, 0xC6, 0x87, 0x5B, 0xCB, 0xDB, 0x8F, 0x30, 0x3E, 0xDA, 0xBD, 0xFD, + 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, + 0x7A, 0x59, 0x27, 0x42, 0xA1, 0xA8, 0x79, 0x47, 0x6F, 0x1E, 0x0F, 0xBE, 0xE4, 0x01, 0x00, 0x00, + 0x3A, 0xCB, 0x8C, 0x2C, 0x5F, 0x67, 0xB6, 0x7D, 0xA4, 0x75, 0x7C, 0xC8, 0xDB, 0x8F, 0x19, 0xF9, + 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, + 0xC4, 0x21, 0xBD, 0xAC, 0x13, 0x91, 0x50, 0xE8, 0xDC, 0x9B, 0xB0, 0xC6, 0xBE, 0x38, 0x2B, 0xF8, + 0xB2, 0x07, 0x00, 0x00, 0xE8, 0x1C, 0x1B, 0x20, 0xEB, 0x55, 0x7C, 0xB8, 0xA9, 0xDB, 0x0F, 0x3F, + 0x40, 0x44, 0x7C, 0x64, 0xBE, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, + 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA1, 0xE8, 0xF1, 0x26, 0x2C, 0x00, + 0x00, 0xD0, 0x2D, 0xBC, 0x03, 0x57, 0x0D, 0x35, 0x8C, 0x0F, 0x1B, 0x1E, 0xF2, 0xF6, 0xE3, 0x09, + 0x1B, 0x1F, 0x2E, 0x40, 0x1E, 0x8D, 0xDC, 0x7E, 0x84, 0xF1, 0xE1, 0xB6, 0x81, 0xF8, 0xA8, 0x9B, + 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xA9, + 0x38, 0x98, 0x8A, 0xBD, 0x70, 0xB5, 0xF1, 0x7E, 0x71, 0xFB, 0x5D, 0xC1, 0x97, 0x3D, 0x00, 0x00, + 0x40, 0xE7, 0x78, 0x7B, 0x2F, 0x1B, 0x6B, 0x18, 0x20, 0x6E, 0x91, 0xDB, 0x0F, 0x17, 0x1F, 0x67, + 0x07, 0x67, 0xD4, 0xDE, 0x7E, 0xA8, 0x67, 0x3F, 0xBE, 0x21, 0x62, 0x23, 0x3E, 0x11, 0x1E, 0x6E, + 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2A, + 0x0C, 0xA6, 0x70, 0xDE, 0xF1, 0xDB, 0x36, 0x04, 0x5F, 0xF6, 0x00, 0x00, 0x00, 0x9D, 0x63, 0x86, + 0xE6, 0xEB, 0xF8, 0xA8, 0xB9, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC6, 0x47, 0x1E, 0xB7, 0x1F, 0x22, + 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, + 0xEB, 0x44, 0x10, 0x4C, 0xF5, 0xBC, 0xE3, 0x7F, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x67, 0x99, + 0x91, 0xFE, 0xD9, 0x66, 0xE7, 0x25, 0x3A, 0x40, 0xEC, 0xA2, 0xDF, 0x7A, 0x75, 0xEE, 0xC9, 0x19, + 0xE6, 0xAC, 0x8D, 0x8F, 0xC9, 0xDB, 0x8F, 0x19, 0xFA, 0xD9, 0x8F, 0x56, 0xB7, 0x1F, 0x22, 0x3C, + 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, + 0x44, 0x0C, 0x74, 0x62, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x74, 0x9C, 0xFF, 0x0A, 0xDE, 0xD8, 0x1B, + 0xB0, 0x6A, 0xBE, 0xF5, 0xCA, 0xEE, 0x9C, 0x0B, 0x10, 0x17, 0x1F, 0xF1, 0xDB, 0x8F, 0x68, 0x7C, + 0x84, 0x01, 0x72, 0x7F, 0x8B, 0xDB, 0x0F, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, + 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x22, 0x04, 0x3A, 0xB6, 0x97, 0x56, 0x99, + 0xE0, 0x4B, 0x1F, 0x00, 0x00, 0xA0, 0x33, 0xFC, 0x37, 0x60, 0x6D, 0xFE, 0xE3, 0x86, 0xF1, 0x51, + 0xB9, 0xFD, 0xB0, 0xF1, 0xD1, 0xE0, 0xF6, 0xC3, 0xC5, 0x47, 0xF5, 0xF6, 0xE3, 0x41, 0xBB, 0xAF, + 0x8B, 0xE8, 0x08, 0x27, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, + 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x45, 0x40, 0x27, 0x37, 0xB6, 0x8C, 0x37, 0x61, 0x01, 0x00, + 0x80, 0xCE, 0xF2, 0x86, 0x97, 0x0D, 0x36, 0xBC, 0xFD, 0x08, 0xE2, 0xA3, 0xE6, 0xF6, 0x23, 0x88, + 0x8F, 0x9A, 0xDB, 0x8F, 0xF0, 0xD9, 0x8F, 0xEF, 0x36, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, + 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA0, + 0xD3, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0xF2, 0x07, 0x00, 0x00, 0x98, 0x7A, + 0xDE, 0xDE, 0xCB, 0x46, 0x1B, 0xDE, 0x7E, 0x6C, 0xBC, 0xA0, 0x26, 0x3E, 0xEA, 0x3E, 0x74, 0x30, + 0xE9, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, + 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x75, 0xF8, 0xEF, 0xF8, 0x16, 0xD8, 0x5F, 0x9B, 0xFD, 0xDF, 0xE1, + 0xC4, 0x6D, 0xEB, 0x83, 0x2F, 0x7F, 0x00, 0x00, 0x80, 0xA9, 0xE7, 0xED, 0x9E, 0x3F, 0xAE, 0x6F, + 0x3F, 0x6C, 0x7C, 0x84, 0xDF, 0x7A, 0x55, 0x73, 0xFB, 0x31, 0x33, 0xDD, 0xED, 0x87, 0x08, 0x0F, + 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0xB1, 0x78, 0x20, 0x14, 0x39, 0x71, 0x48, 0x2F, 0xEB, + 0xE4, 0xE1, 0xBF, 0xD3, 0xB3, 0xF1, 0x11, 0xCC, 0x3B, 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x80, + 0xCE, 0x30, 0x43, 0xFD, 0xB3, 0xCC, 0xEE, 0xB9, 0x32, 0x3E, 0x72, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, + 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, + 0x0F, 0xFF, 0x9D, 0xDE, 0x64, 0x7C, 0xF8, 0x01, 0x72, 0xF4, 0xE6, 0x93, 0xC1, 0x1F, 0x01, 0x00, + 0x00, 0x00, 0x53, 0xCB, 0x7F, 0x03, 0xD6, 0xF6, 0x8B, 0x6B, 0x03, 0x24, 0x8C, 0x0F, 0xF9, 0xEC, + 0x47, 0x83, 0xDB, 0x8F, 0x7B, 0xC5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, + 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x6A, 0xE3, + 0xC3, 0xDF, 0x91, 0x1B, 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0C, 0x33, 0xB2, 0x7C, 0x9D, 0xD9, + 0xFA, 0xC1, 0xC8, 0xED, 0x87, 0x8D, 0x8F, 0xD8, 0xED, 0x47, 0xED, 0x9B, 0xAF, 0x44, 0x7C, 0x3C, + 0x60, 0x47, 0x7C, 0x14, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, + 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x11, 0x1F, 0x6E, 0x2F, 0xF5, 0xF3, 0x26, 0x2C, 0x00, 0x00, 0xD0, + 0x19, 0xE6, 0xE0, 0xF2, 0xF5, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xEC, 0xC7, + 0xE9, 0x78, 0x80, 0xB8, 0x0F, 0x1D, 0x8C, 0xDF, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, + 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, + 0x84, 0x47, 0x38, 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x00, 0x00, 0x00, 0x60, + 0xEA, 0x78, 0xFB, 0xAE, 0x1E, 0xAD, 0x89, 0x8F, 0x24, 0xCF, 0x7E, 0xB8, 0x35, 0xBA, 0xFD, 0x10, + 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, + 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x88, 0x8E, 0xE8, 0xDC, 0x3F, 0x67, 0xBC, 0x09, 0x0B, 0x00, + 0x00, 0x74, 0x82, 0xB7, 0xF7, 0xF2, 0x93, 0x7E, 0x7C, 0x34, 0xBA, 0xFD, 0x88, 0xC6, 0x87, 0xBA, + 0xFD, 0xF8, 0x76, 0xE4, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, + 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x38, 0xC4, 0xBC, + 0xE3, 0xB7, 0x0F, 0x05, 0x7F, 0x0C, 0x00, 0x00, 0x00, 0x4C, 0x1D, 0x6F, 0xE7, 0x9C, 0xF4, 0xB7, + 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x8E, 0xF8, 0xC8, 0x71, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, + 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x36, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, + 0x82, 0x3F, 0x06, 0x00, 0x00, 0x00, 0xA6, 0x86, 0x39, 0x70, 0xFD, 0x12, 0x6F, 0xFB, 0x27, 0xB2, + 0xDF, 0x7E, 0xDC, 0x13, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, + 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x87, 0x46, 0xC3, + 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xD5, 0xCC, 0xC1, 0x65, 0x6B, 0xBD, 0xAD, 0x1F, 0x6E, 0xEF, + 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, + 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x30, 0x5A, 0xCD, 0xBD, 0x09, 0xEB, 0xF8, + 0x1D, 0x4B, 0x82, 0x3F, 0x0E, 0x00, 0x00, 0x00, 0x8A, 0x77, 0xFE, 0xE0, 0xD2, 0xF5, 0xDE, 0xA6, + 0x0B, 0x33, 0xDE, 0x7E, 0x10, 0x1F, 0xF9, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, + 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC4, 0x45, 0x92, 0xBD, 0x70, 0x0D, 0x6F, 0xC2, + 0x02, 0x00, 0x00, 0x53, 0xEB, 0xFC, 0xFE, 0x6B, 0x06, 0xB3, 0xDD, 0x7E, 0xCC, 0x90, 0xE1, 0xE1, + 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, + 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x8B, 0xA4, 0x7B, 0xFE, 0x0A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xA6, + 0xD6, 0xF9, 0xDD, 0x8B, 0x47, 0xA3, 0xB7, 0x1F, 0xD5, 0x00, 0x89, 0xC5, 0x47, 0xDD, 0xED, 0xC7, + 0xDD, 0xC4, 0x47, 0xFB, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, + 0xE4, 0xE1, 0xBF, 0xD3, 0x13, 0x51, 0x91, 0x72, 0xDE, 0xB1, 0xB5, 0xBC, 0x09, 0x0B, 0x00, 0x00, + 0x4C, 0x1D, 0x6F, 0xF7, 0x42, 0x79, 0xFB, 0x31, 0xE1, 0x02, 0xE4, 0xD1, 0xC8, 0xED, 0x47, 0x18, + 0x1F, 0x6E, 0xF7, 0xEB, 0x6F, 0xBD, 0x22, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, + 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x07, 0x45, 0xDA, 0x79, 0x47, 0x3E, + 0x3F, 0x1A, 0xFC, 0x71, 0x00, 0x00, 0x00, 0x50, 0x2C, 0x33, 0xD2, 0x3F, 0xDB, 0xDB, 0x31, 0x27, + 0xDD, 0xB3, 0x1F, 0x0F, 0xCE, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, + 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x98, 0xC8, 0xB4, 0xA3, + 0x6B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x1A, 0x66, 0xFF, 0xD2, 0x81, 0xF3, 0x5B, 0x3E, 0x6C, + 0x03, 0x24, 0xF2, 0xAD, 0x57, 0xCD, 0x6E, 0x3F, 0x1E, 0xB2, 0xF1, 0x21, 0x6E, 0x3F, 0x88, 0x8F, + 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, + 0xD3, 0x13, 0x11, 0xD1, 0xCE, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0x73, 0x76, 0xF0, 0xC7, 0x02, 0x00, + 0x00, 0x40, 0x71, 0xCE, 0xED, 0x5F, 0x7A, 0xD7, 0xF9, 0x4D, 0xEF, 0x9B, 0x7C, 0xF6, 0xA3, 0xE6, + 0xC1, 0xF3, 0x19, 0xB5, 0xCF, 0x7E, 0xB8, 0xF8, 0x78, 0xA0, 0xFE, 0xF6, 0x83, 0xF8, 0x48, 0x33, + 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, + 0x11, 0x10, 0xED, 0xCE, 0xBD, 0x09, 0xEB, 0xD8, 0x6D, 0x03, 0xC1, 0x1F, 0x0B, 0x00, 0x00, 0x00, + 0xC5, 0x39, 0x7F, 0x60, 0xD9, 0x86, 0x9A, 0x07, 0xCF, 0xA3, 0xB7, 0x1F, 0xD1, 0xF8, 0x78, 0xD8, + 0x86, 0x87, 0x0B, 0x90, 0xEF, 0xD4, 0xDE, 0x7E, 0x10, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x21, 0x8F, 0xF1, + 0x26, 0x2C, 0x00, 0x00, 0x30, 0x55, 0xCE, 0xEF, 0x5E, 0x32, 0xEA, 0xC7, 0x47, 0x83, 0xDB, 0x0F, + 0x17, 0x1F, 0xA7, 0xC2, 0xF8, 0x70, 0xB7, 0x1F, 0x7F, 0x4D, 0x7C, 0x64, 0x9B, 0x0A, 0x87, 0x3C, + 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x87, 0x1C, + 0xE7, 0x9D, 0xB8, 0x6D, 0x30, 0xF8, 0x63, 0x01, 0x00, 0x00, 0xA0, 0x38, 0xE7, 0x76, 0x2E, 0x3A, + 0x59, 0x73, 0xFB, 0x11, 0xC4, 0x47, 0xF5, 0xD9, 0x8F, 0x30, 0x3E, 0x62, 0xB7, 0x1F, 0xC4, 0x47, + 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, + 0xE9, 0xE9, 0x68, 0xC8, 0x73, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0xDE, 0xF9, + 0xED, 0x73, 0xAA, 0xF1, 0x51, 0xF7, 0xA1, 0x83, 0x8F, 0xCC, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, + 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, + 0xE9, 0x60, 0xC8, 0x7D, 0x47, 0x3F, 0xCF, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB1, 0xCE, 0xEE, 0x5F, + 0x3A, 0x70, 0x6E, 0xCB, 0x27, 0x63, 0xB7, 0x1F, 0x33, 0x2B, 0xCF, 0x7E, 0x44, 0xE3, 0xC3, 0xED, + 0xDE, 0xCA, 0xED, 0x07, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, + 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x14, 0x8A, 0x9A, 0x7B, 0x13, 0xD6, 0xD8, 0x17, + 0x67, 0x05, 0x7F, 0x3C, 0x00, 0x00, 0x00, 0xE4, 0xEF, 0xDC, 0xDE, 0xE5, 0xEB, 0xCE, 0x6D, 0xFA, + 0x48, 0xEC, 0xF6, 0x63, 0x46, 0x35, 0x3E, 0xAA, 0x01, 0xF2, 0x23, 0x3B, 0xE2, 0x23, 0xE5, 0x54, + 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x44, + 0x24, 0x14, 0xB9, 0x17, 0xAF, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x58, 0xE7, 0xF7, 0x2E, 0x5F, + 0x5F, 0xF7, 0xEC, 0xC7, 0x8F, 0x27, 0x03, 0xA4, 0x7A, 0xFB, 0xF1, 0xED, 0x0B, 0x88, 0x8F, 0x54, + 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, + 0x13, 0x81, 0x50, 0xF4, 0x5E, 0xB8, 0xCA, 0x78, 0xBF, 0xB8, 0xFD, 0xAE, 0xE0, 0x8F, 0x07, 0x00, + 0x00, 0x80, 0xFC, 0x9D, 0xDB, 0x7D, 0xD5, 0x50, 0xCD, 0x9B, 0xAF, 0xC2, 0xF8, 0x88, 0x06, 0xC8, + 0x8F, 0x66, 0x10, 0x1F, 0xA9, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, + 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x60, 0x8A, 0xE6, 0x1D, 0xBF, 0x6D, 0x43, 0xF0, 0xC7, + 0x03, 0x00, 0x00, 0x40, 0xFE, 0xCE, 0xED, 0xB8, 0x6C, 0x6C, 0xF2, 0xF6, 0xE3, 0x02, 0x79, 0xFB, + 0xF1, 0x76, 0xE4, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x06, 0x53, 0x35, 0xDE, 0x84, 0x05, 0x00, + 0x00, 0x0A, 0x75, 0x76, 0xDB, 0xFC, 0xE0, 0xF6, 0xC3, 0xC6, 0x87, 0x78, 0xF6, 0xE3, 0xED, 0x1F, + 0x4C, 0xDE, 0x7E, 0x10, 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, + 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0xA3, 0x60, 0x2A, 0xE7, 0x1D, 0xBD, 0x79, 0x3C, 0xF8, + 0xE3, 0x01, 0x00, 0x00, 0x20, 0x5F, 0x66, 0xA8, 0x7F, 0xF6, 0xD9, 0xCD, 0x97, 0x04, 0xF1, 0x51, + 0x7B, 0xFB, 0x71, 0x2A, 0xBC, 0xFD, 0xF8, 0x66, 0xE5, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, + 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x04, + 0x53, 0xBE, 0x97, 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x8C, 0xB3, 0x43, 0x4B, 0x07, 0xDE, + 0xDD, 0xF8, 0xE1, 0x6A, 0x80, 0x9C, 0xB6, 0x01, 0x52, 0xF3, 0xEC, 0xC7, 0xF7, 0x2B, 0xB7, 0x1F, + 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, + 0xF0, 0xDF, 0xE9, 0x89, 0x10, 0xE8, 0xD4, 0xC6, 0x96, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x0C, + 0x1B, 0x20, 0xEB, 0x27, 0x06, 0xDF, 0x57, 0x73, 0xFB, 0x11, 0x7D, 0xFE, 0xC3, 0xDD, 0x7E, 0x10, + 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, + 0x7F, 0xA7, 0x27, 0x22, 0xA0, 0x93, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0x63, + 0x02, 0x00, 0x00, 0x20, 0x3F, 0xEF, 0xEE, 0x59, 0x3A, 0xE8, 0xDF, 0x7E, 0x88, 0xF8, 0x70, 0xB7, + 0x1F, 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, + 0xF2, 0xF0, 0xDF, 0xE9, 0x89, 0x00, 0xE8, 0xF4, 0xDC, 0x3F, 0x17, 0x27, 0x6E, 0x5B, 0x1F, 0xFC, + 0x31, 0x01, 0x00, 0x00, 0x90, 0x9F, 0x89, 0x6D, 0x8B, 0x47, 0xEB, 0xDE, 0x7C, 0x15, 0xDE, 0x7E, + 0xDC, 0x4D, 0x7C, 0x34, 0x9F, 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xE9, 0x65, + 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xE2, 0xF0, 0xDF, 0x25, 0xF3, 0x8E, 0xAF, 0xE5, 0x4D, 0x58, 0x00, + 0x00, 0x20, 0x7F, 0x13, 0x5B, 0xFA, 0xC6, 0xE5, 0xC3, 0xE7, 0xF7, 0xBB, 0x6F, 0xBD, 0x22, 0x3E, + 0x1A, 0x4F, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, + 0x4E, 0x4F, 0x1F, 0xFC, 0xBB, 0x65, 0xDE, 0xD1, 0x9B, 0x4F, 0x06, 0x7F, 0x4C, 0x00, 0x00, 0x00, + 0xE4, 0xC3, 0x0C, 0xF5, 0xCF, 0x7A, 0xF7, 0x99, 0x39, 0x95, 0xF8, 0xB0, 0x8B, 0x3E, 0x7C, 0xFE, + 0xD6, 0x5F, 0x11, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, + 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFD, 0x5D, 0xB5, 0x97, 0x56, 0x9A, 0xE0, 0x8F, 0x0A, + 0x00, 0x00, 0x80, 0x7C, 0xB8, 0x37, 0x60, 0x4D, 0x6C, 0xFC, 0x98, 0x0D, 0x90, 0x0B, 0xCC, 0xE9, + 0x47, 0xEC, 0xDC, 0xED, 0x87, 0x0B, 0x90, 0xFB, 0x6D, 0x80, 0x10, 0x1F, 0x0D, 0xA6, 0xC2, 0x21, + 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xFB, + 0xDD, 0x38, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x7C, 0xDD, 0xC4, 0x13, 0x1F, + 0x30, 0xA7, 0xFD, 0x00, 0x09, 0xBE, 0xFD, 0xEA, 0xE1, 0x99, 0xFE, 0xED, 0x07, 0xF1, 0xA1, 0xA6, + 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, + 0x0E, 0xFA, 0xDD, 0x3A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x74, 0x7D, 0x78, + 0xFB, 0x71, 0xCA, 0xCD, 0xDD, 0x7E, 0x7C, 0x67, 0x06, 0xF1, 0x21, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF9, 0xDD, 0x3C, + 0xF7, 0xCF, 0x3D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x79, 0x9A, 0xD8, 0x79, 0xD5, 0x68, 0xF5, 0xDB, + 0xAF, 0xDC, 0x0D, 0x88, 0x7B, 0xF6, 0xE3, 0x6B, 0xC4, 0x47, 0xFD, 0x54, 0x38, 0xE4, 0x31, 0x15, + 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, 0x01, 0xBF, 0x07, 0xC6, + 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xAE, 0x26, 0xB6, 0x5D, 0x76, 0xB2, 0x7A, 0x03, 0xF2, 0xF0, 0x0C, + 0xF3, 0xF6, 0x7D, 0xC1, 0xED, 0x87, 0x8D, 0x8F, 0x3F, 0x10, 0x1F, 0xC1, 0x54, 0x38, 0xE4, 0x31, + 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0xE1, 0xBE, 0x17, + 0xE6, 0x1D, 0x59, 0x33, 0x16, 0xFC, 0x71, 0x01, 0x00, 0x00, 0xD0, 0xBE, 0x09, 0xFF, 0x0D, 0x58, + 0x93, 0xB7, 0x1F, 0x6F, 0x7E, 0x6D, 0xF2, 0xE6, 0xE3, 0x0D, 0xE2, 0xC3, 0x4E, 0x85, 0x43, 0x1E, + 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xEC, 0x7B, + 0x66, 0x47, 0x6E, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x20, 0x1F, 0x13, 0x43, 0xD7, 0x2F, 0x99, 0x78, + 0xFA, 0x13, 0xE6, 0xCC, 0xA3, 0x95, 0xCF, 0xFF, 0x70, 0xB7, 0x1F, 0x95, 0xF8, 0xB8, 0xC0, 0xBF, + 0xF9, 0x78, 0x83, 0xF8, 0x28, 0x68, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, + 0xDF, 0xE9, 0x89, 0x03, 0x7D, 0xAF, 0xED, 0xA5, 0x7E, 0xF7, 0x20, 0xFA, 0x92, 0xE0, 0x8F, 0x0D, + 0x00, 0x00, 0x80, 0xEC, 0xCE, 0x0C, 0x2D, 0x5B, 0x3B, 0xF1, 0xE4, 0x87, 0x2B, 0x9F, 0x01, 0xF2, + 0x60, 0xE5, 0xB5, 0xBB, 0xD5, 0xDB, 0x8F, 0xAF, 0xD9, 0xF8, 0xF8, 0x47, 0xE2, 0x23, 0xFF, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF3, 0xBD, 0x38, + 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x03, 0x00, 0x00, 0x20, 0x3B, 0xF7, 0x06, + 0xAC, 0x89, 0xC7, 0x2F, 0xF2, 0x03, 0xE4, 0xED, 0x6F, 0x55, 0x9E, 0xFB, 0x20, 0x3E, 0xDC, 0x54, + 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, + 0x41, 0xBE, 0x57, 0xE7, 0xBE, 0x26, 0x78, 0x13, 0x16, 0x00, 0x00, 0xC8, 0xC3, 0xD9, 0x5D, 0xD7, + 0x0C, 0x4E, 0x3C, 0x36, 0xC3, 0x9C, 0x71, 0xCF, 0x7E, 0x04, 0x6F, 0xBD, 0xFA, 0xC3, 0x7A, 0xE2, + 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, + 0xF1, 0x3D, 0xBB, 0xF9, 0xFE, 0xBC, 0xE3, 0xB7, 0x0D, 0x05, 0x7F, 0x6C, 0x00, 0x00, 0x00, 0x64, + 0xF7, 0xEE, 0xB6, 0xC5, 0xA3, 0x13, 0x8F, 0xCF, 0x30, 0xEF, 0x7C, 0xBB, 0x72, 0xFB, 0xF1, 0xE6, + 0x5F, 0x5D, 0x44, 0x7C, 0x14, 0x32, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, + 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x57, 0x89, 0x0F, 0x3F, 0x40, 0x8E, 0xDC, 0xCC, 0x9B, 0xB0, + 0x00, 0x00, 0x40, 0xFB, 0xCE, 0x6D, 0x5F, 0x60, 0x26, 0x1E, 0xB9, 0xC0, 0xBC, 0xE5, 0x5E, 0xBB, + 0xFB, 0xD7, 0xC4, 0x47, 0x31, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, + 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0xE1, 0xEF, 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, + 0x00, 0xB4, 0xC7, 0x0C, 0x5D, 0x3B, 0xFB, 0xDC, 0xB6, 0x4B, 0xCD, 0x3B, 0xDF, 0xB4, 0x01, 0xF2, + 0x75, 0xE2, 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, + 0xA7, 0x0E, 0xF1, 0xBD, 0xBA, 0x58, 0x7C, 0xB8, 0xBD, 0xB4, 0xC2, 0x98, 0x97, 0xBF, 0x38, 0x3B, + 0xF8, 0xE3, 0x03, 0x00, 0x00, 0x20, 0xBD, 0xB3, 0xFB, 0x97, 0x0E, 0xBC, 0xFB, 0xD8, 0x87, 0xCC, + 0xDB, 0x77, 0x5F, 0x64, 0xCE, 0x13, 0x1F, 0x05, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, + 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x89, 0xF8, 0x70, 0x7B, 0xE1, 0x6A, 0x63, + 0x8E, 0xDD, 0x36, 0x10, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDE, 0x99, 0x5D, 0x9F, 0xBB, 0xEB, + 0xD4, 0x86, 0x0F, 0x98, 0xF3, 0xFF, 0x44, 0x7C, 0xE4, 0x3F, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, + 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x27, 0xC2, 0x23, 0x98, 0xF7, 0xAF, + 0x4B, 0xCC, 0xE9, 0x9F, 0xDD, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x76, 0xAF, 0x3D, 0x70, 0xED, + 0x86, 0xF1, 0xDD, 0xAB, 0xCD, 0xD9, 0x17, 0xBF, 0x44, 0x7C, 0xE4, 0x3A, 0x15, 0x09, 0x45, 0x4D, + 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0xA7, 0xC3, 0xC3, 0xED, + 0xD4, 0xB3, 0xF3, 0xCC, 0xEF, 0x77, 0xCC, 0x31, 0xBF, 0xDB, 0x77, 0xD3, 0x60, 0xF0, 0xC7, 0x07, + 0x00, 0x00, 0x40, 0x7A, 0xAF, 0xEF, 0xB9, 0x75, 0xF8, 0xF7, 0x07, 0x6F, 0x35, 0xBF, 0xDF, 0xB7, + 0xD2, 0xBC, 0x79, 0xE0, 0x32, 0x73, 0xFE, 0x9F, 0x55, 0x54, 0x24, 0x9D, 0x08, 0x87, 0x3C, 0x26, + 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, + 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0x4E, 0x87, 0xC7, 0x99, 0xBF, 0xEB, 0x33, 0xE3, 0xBB, + 0xE6, 0x9A, 0xDF, 0x6D, 0xB3, 0xF1, 0xE1, 0xB6, 0x67, 0x39, 0xAF, 0xE2, 0x05, 0x00, 0x00, 0xD9, + 0xFD, 0xF3, 0xFF, 0xFE, 0x17, 0x17, 0xFE, 0x76, 0xFB, 0xEA, 0xFB, 0x7E, 0xB7, 0x6D, 0xF1, 0x5B, + 0xBF, 0xDF, 0xB9, 0xD8, 0xB8, 0xBD, 0x7D, 0xE8, 0x72, 0xFF, 0x5B, 0x2D, 0x74, 0x64, 0x34, 0x9A, + 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, + 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0xAE, 0x3E, 0x3C, 0xCE, 0xFE, + 0x43, 0x9F, 0x79, 0x73, 0xEF, 0x64, 0x78, 0xBC, 0xBE, 0x75, 0xCE, 0xF8, 0xEF, 0xB6, 0x5D, 0xBA, + 0x7E, 0xB4, 0xFF, 0x3D, 0x7F, 0x14, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDD, 0x7F, 0xBF, 0xFB, + 0x33, 0x17, 0xBF, 0xB6, 0x79, 0xF1, 0x96, 0x30, 0x42, 0xC6, 0x77, 0x2F, 0x36, 0xA7, 0xFF, 0xC6, + 0x1E, 0xD4, 0x65, 0x6C, 0xC4, 0x27, 0xC2, 0x21, 0x8F, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, 0xDF, + 0xAB, 0xAB, 0x0D, 0x8F, 0xF3, 0xFF, 0x34, 0xDF, 0xBC, 0xB5, 0x3F, 0x72, 0xE3, 0x61, 0xF7, 0xEA, + 0x33, 0x73, 0x7E, 0x34, 0x3E, 0xF4, 0xA9, 0x59, 0xC1, 0x1F, 0x17, 0x00, 0x00, 0x00, 0xF9, 0xF9, + 0xEF, 0xDF, 0x5D, 0xF2, 0x99, 0xD7, 0xB6, 0x2C, 0xFA, 0x59, 0x18, 0x22, 0x6F, 0xEC, 0xB9, 0xCC, + 0x4C, 0xFC, 0xBD, 0x0B, 0x02, 0x15, 0x1E, 0x6E, 0xB1, 0x68, 0xC8, 0x6B, 0x32, 0x1C, 0xF2, 0x98, + 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, + 0x3A, 0xC4, 0xF7, 0xEA, 0x26, 0xC3, 0xC3, 0xFB, 0xE7, 0xF9, 0xE6, 0x9D, 0x91, 0x79, 0x35, 0xE1, + 0xF1, 0xDA, 0xE6, 0x4B, 0xF7, 0x8F, 0x6F, 0xE9, 0xE3, 0xB5, 0xBB, 0x00, 0x00, 0xA0, 0x78, 0xFF, + 0xEB, 0xA1, 0xCB, 0xBE, 0xF8, 0xBB, 0x6D, 0x8B, 0x7E, 0x19, 0x86, 0x88, 0x7B, 0x3E, 0xE4, 0xEC, + 0x4F, 0x5D, 0x1C, 0x10, 0x1F, 0xF5, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, + 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0x51, 0x7D, 0xC0, 0x3C, 0x08, 0x8F, 0xD7, + 0xB7, 0x5E, 0x3A, 0xF6, 0xDA, 0x96, 0x4B, 0x79, 0xDD, 0x2E, 0x00, 0x00, 0x98, 0x5A, 0xA3, 0xFD, + 0xFD, 0x7F, 0xF4, 0xAB, 0x27, 0x2E, 0xFB, 0x3F, 0xA2, 0xCF, 0x87, 0xBC, 0x35, 0xEC, 0x1E, 0x54, + 0x17, 0xD1, 0x90, 0xD7, 0x64, 0x38, 0xE4, 0x31, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x55, 0xC2, 0x23, 0xFE, + 0x80, 0xB9, 0x8D, 0x8E, 0x5F, 0xBE, 0xBE, 0x7D, 0xEE, 0xBA, 0xE0, 0x8F, 0x00, 0x00, 0x00, 0x80, + 0xCE, 0xF8, 0xD5, 0x23, 0x57, 0x7E, 0xE0, 0x37, 0x4F, 0x2E, 0xDE, 0x30, 0x19, 0x22, 0x8B, 0xCC, + 0xE9, 0xBF, 0xB9, 0xCC, 0x78, 0xFF, 0x2A, 0x02, 0xA2, 0x9D, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, + 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, + 0xDF, 0xAB, 0x6B, 0xFC, 0x80, 0x39, 0xCF, 0x79, 0x00, 0x00, 0x80, 0xAE, 0x72, 0xF2, 0x91, 0xC5, + 0xF3, 0x5F, 0x7D, 0x66, 0xF1, 0x0E, 0x17, 0x20, 0x6E, 0xE3, 0xBB, 0x17, 0x99, 0x33, 0x7F, 0x67, + 0x0F, 0xE2, 0x2A, 0x26, 0xD2, 0x4E, 0x86, 0x43, 0x1E, 0x8B, 0x47, 0x43, 0x5E, 0x53, 0x91, 0x50, + 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x73, 0xEA, 0x01, + 0xF3, 0xDF, 0x6D, 0xBD, 0x74, 0xF0, 0xBF, 0x7D, 0x67, 0xDE, 0x07, 0x82, 0x2F, 0x73, 0x00, 0x00, + 0x80, 0xEE, 0xF3, 0xAB, 0x8D, 0x8B, 0xD6, 0xBC, 0xFA, 0xCC, 0xC2, 0x9F, 0x87, 0x21, 0xF2, 0xC6, + 0x9E, 0xC5, 0xE6, 0xDD, 0x7F, 0xB0, 0x87, 0x7D, 0x15, 0x16, 0x49, 0x26, 0xC3, 0x21, 0x8F, 0xA9, + 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, + 0x83, 0x7C, 0xAF, 0xCD, 0xFB, 0xE7, 0x05, 0x75, 0x0F, 0x98, 0xDB, 0x8D, 0xFE, 0x7F, 0x8F, 0x5E, + 0x3A, 0x27, 0xF8, 0xB2, 0x06, 0x00, 0x00, 0xE8, 0x6E, 0xFE, 0xF3, 0x21, 0x83, 0x8B, 0xFF, 0xE2, + 0x77, 0xDB, 0x16, 0xFE, 0x32, 0x0C, 0x91, 0x37, 0x0F, 0x2C, 0x36, 0x67, 0x7F, 0x6A, 0x0F, 0xFE, + 0x2A, 0x32, 0x1A, 0x4D, 0x86, 0x43, 0x1E, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, + 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x87, 0xF9, 0x5E, 0xDB, 0xE9, 0xBF, 0xE9, 0xAB, + 0x79, 0xC0, 0xFC, 0xB5, 0x67, 0xE6, 0x1C, 0xE3, 0x01, 0x73, 0x00, 0x00, 0xD0, 0xB3, 0x6C, 0x88, + 0xFC, 0xBB, 0x57, 0x37, 0x2F, 0xBA, 0xE7, 0x77, 0xDB, 0x16, 0xBD, 0x15, 0x86, 0xC8, 0xDB, 0x87, + 0x12, 0x3E, 0xA8, 0x2E, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, + 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xC3, 0x7C, 0x2F, 0x6D, 0xE2, 0xEF, 0xE7, 0xF3, + 0x80, 0x39, 0x00, 0x00, 0x28, 0xAF, 0x93, 0xF7, 0x2E, 0xFC, 0xC8, 0x2B, 0x9B, 0x16, 0x3F, 0x1A, + 0x46, 0x88, 0x7B, 0x3E, 0xA4, 0xE9, 0x83, 0xEA, 0x32, 0x1C, 0xF2, 0x98, 0x0A, 0x87, 0x3C, 0xA6, + 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x3E, 0xD0, 0xF7, 0xCA, + 0xCE, 0xFE, 0xC3, 0x7C, 0xF3, 0xE6, 0x5E, 0xF7, 0xED, 0x56, 0x95, 0xF8, 0xE0, 0x01, 0x73, 0x00, + 0x00, 0x50, 0x6A, 0xFF, 0xE3, 0xFE, 0xCF, 0x2C, 0x7A, 0x75, 0xF3, 0xA2, 0xE7, 0xA2, 0x21, 0x32, + 0xF1, 0xF7, 0x36, 0x0C, 0x88, 0x8F, 0x84, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, + 0x7D, 0xA8, 0xEF, 0x85, 0x9D, 0xFF, 0xA7, 0x05, 0xE6, 0xED, 0x83, 0x7D, 0x41, 0x78, 0x04, 0x37, + 0x1F, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0xA6, 0x8B, 0x5F, 0x3E, 0xB6, 0xF8, 0x96, 0xD7, 0xB7, 0x2E, + 0x7C, 0x39, 0x0C, 0x11, 0xF7, 0xA0, 0xBA, 0xFF, 0x7C, 0x88, 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, + 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xF6, + 0xDD, 0x3E, 0xF7, 0x80, 0xF9, 0xA9, 0x67, 0xA3, 0xE1, 0xE1, 0xC7, 0x07, 0x0F, 0x98, 0x03, 0x00, + 0x80, 0xE9, 0xC7, 0x3D, 0xA8, 0xFE, 0xDB, 0xA7, 0x17, 0x7F, 0xF5, 0xF5, 0xAD, 0x8B, 0x7E, 0xE3, + 0x22, 0xE4, 0x77, 0x3B, 0x16, 0x9A, 0x37, 0xF7, 0x2F, 0x32, 0xE7, 0xFE, 0xD1, 0x1D, 0xEC, 0x55, + 0x44, 0x64, 0x5D, 0x3C, 0x1A, 0xF2, 0x9A, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, + 0xFC, 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xED, 0xAB, 0x3C, 0x60, 0x3E, 0x19, 0x1E, 0xAF, 0x3D, 0x33, + 0x97, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x7E, 0xF5, 0xC8, 0xBC, 0x0F, 0xFC, 0xE6, 0xE9, 0x85, 0xF7, + 0xBD, 0xBE, 0x75, 0xC1, 0x5B, 0x2E, 0x42, 0xDC, 0xDE, 0x1E, 0x59, 0x6C, 0xBC, 0x7F, 0x51, 0x31, + 0x91, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, + 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xCD, 0xAB, 0x3C, 0x60, 0x1E, 0x3E, 0xE7, 0x61, 0xC3, 0x63, 0xCB, + 0x5C, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x88, 0x1B, 0xFB, 0x4F, 0x9F, 0xB9, 0xF8, 0x95, 0xCD, 0x0B, + 0xB7, 0x84, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCD, 0xA9, 0xE7, 0xDA, 0x09, 0x11, 0x15, 0x0E, 0x79, + 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC0, 0xEF, + 0xD6, 0xD5, 0x3E, 0x60, 0x3E, 0xD7, 0xBC, 0xBE, 0x75, 0xEE, 0xB8, 0xFD, 0x91, 0x07, 0xCC, 0x01, + 0x00, 0x00, 0x9A, 0xF9, 0x9F, 0x0F, 0x2D, 0x5A, 0xFA, 0xEA, 0xE6, 0x85, 0x3F, 0x0B, 0x43, 0x64, + 0x7C, 0x68, 0x91, 0x39, 0x33, 0xEA, 0x0E, 0xFE, 0x2A, 0x32, 0x1A, 0x2D, 0x1E, 0x0D, 0x79, 0x4D, + 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC8, 0xEF, 0xC6, + 0xD5, 0x3F, 0x60, 0x6E, 0xB7, 0x75, 0x0E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA4, 0xF1, 0xBF, 0x1E, + 0x5A, 0xF0, 0xC5, 0xD7, 0xB6, 0x2E, 0xF8, 0x65, 0x18, 0x22, 0x6F, 0xEC, 0x5D, 0x64, 0xCE, 0xFE, + 0xC4, 0x45, 0x80, 0x0A, 0x8E, 0xE8, 0xE2, 0xD1, 0x90, 0xD7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, + 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x07, 0xFD, 0x6E, 0x9B, 0x7E, 0xC0, 0x7C, 0x2E, 0x0F, + 0x98, 0x03, 0x00, 0x00, 0x64, 0xE5, 0x1E, 0x54, 0xFF, 0xF5, 0xC6, 0x45, 0x7F, 0x19, 0x7D, 0x3E, + 0xC4, 0x3D, 0xA8, 0x7E, 0xFE, 0x67, 0x2A, 0x3C, 0xDC, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, + 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0x61, 0xBF, 0xDB, 0xC6, 0x03, 0xE6, + 0x00, 0x00, 0x00, 0x05, 0x72, 0x0F, 0xAA, 0xFF, 0xFA, 0xC9, 0x85, 0x1B, 0xC2, 0x08, 0x71, 0x7B, + 0xE7, 0x70, 0xFC, 0xF9, 0x10, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, + 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xD8, 0xEF, 0xA6, 0xF1, 0x80, 0x39, 0x00, 0x00, 0xC0, 0x14, + 0x3A, 0xF9, 0xC8, 0xE2, 0xF9, 0xBF, 0xDD, 0xB4, 0x60, 0x47, 0x18, 0x21, 0xE1, 0x83, 0xEA, 0x3A, + 0x1C, 0xF2, 0x58, 0x3C, 0x10, 0x8A, 0x9C, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, + 0x03, 0x7F, 0xB7, 0x8C, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x3A, 0xE8, 0x57, 0x1B, 0x17, 0xAD, 0x79, + 0x65, 0xD3, 0x82, 0x9F, 0x57, 0x42, 0x64, 0x81, 0x19, 0x1F, 0x5A, 0x68, 0xCE, 0x8C, 0xBA, 0x43, + 0xBC, 0x8A, 0x88, 0xAC, 0x8B, 0x07, 0x42, 0x91, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, + 0x3D, 0x7D, 0xE8, 0xEF, 0x86, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x40, 0x97, 0xA8, 0x7C, 0x90, 0xE1, + 0xC2, 0xAF, 0xBE, 0xB6, 0x75, 0xFE, 0x2F, 0x5D, 0x84, 0xB8, 0xBD, 0xB9, 0x7F, 0xA1, 0x39, 0xFB, + 0x13, 0x77, 0xA0, 0x57, 0x41, 0x91, 0x66, 0xF1, 0x40, 0x28, 0x72, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, + 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFE, 0x9D, 0x5E, 0xA3, 0x07, 0xCC, 0x4F, 0x7E, 0xE7, 0x53, 0xF3, + 0x83, 0x2F, 0x01, 0x00, 0x00, 0x00, 0x74, 0xC2, 0x60, 0xFF, 0xA7, 0xFE, 0xDD, 0xAB, 0x9B, 0x16, + 0xDC, 0xF3, 0xFA, 0xD6, 0xF9, 0x6F, 0x85, 0x21, 0xF2, 0xF6, 0x88, 0x7B, 0x50, 0x5D, 0x85, 0x45, + 0x92, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFF, + 0x9D, 0x9E, 0x7A, 0xC0, 0xFC, 0xB7, 0x1B, 0xE7, 0xDE, 0x10, 0xFC, 0x23, 0x0F, 0x00, 0x00, 0x80, + 0x6E, 0xF0, 0xFF, 0x7E, 0x63, 0xF1, 0x87, 0x7F, 0xF3, 0xD4, 0x82, 0x47, 0xC3, 0x08, 0x71, 0x3B, + 0xF5, 0xDC, 0x22, 0xE3, 0xFD, 0x8B, 0x8A, 0x8C, 0x46, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, + 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xFE, 0x3B, 0xB9, 0xF8, 0x03, 0xE6, 0xEE, 0x39, 0x8F, + 0x57, 0x9F, 0xBE, 0xF4, 0x3F, 0x06, 0xFF, 0x88, 0x03, 0x00, 0x00, 0xA0, 0x1B, 0xFD, 0x8F, 0xFB, + 0x17, 0x2C, 0x7A, 0x75, 0xF3, 0x82, 0x9F, 0x85, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCC, 0xE9, 0xBF, + 0x75, 0x07, 0x61, 0x15, 0x1C, 0xD1, 0xA9, 0x48, 0x28, 0x6A, 0xB1, 0x03, 0x7A, 0x99, 0x27, 0x0F, + 0xFF, 0x9D, 0x9E, 0x0E, 0x80, 0x4E, 0xAD, 0xEE, 0x01, 0xF3, 0xCD, 0x73, 0xDE, 0xB2, 0x3F, 0xF2, + 0x80, 0x39, 0x00, 0x00, 0x40, 0x2F, 0xF9, 0xE5, 0xC3, 0xF3, 0x6F, 0x79, 0x75, 0xCB, 0x82, 0x97, + 0xC3, 0x10, 0x71, 0x0F, 0xAA, 0x4F, 0xFC, 0x57, 0x77, 0xF8, 0x27, 0x3E, 0xA6, 0x6C, 0xF2, 0xF0, + 0xDF, 0xE9, 0xE9, 0x08, 0xE8, 0xC4, 0x1A, 0x3D, 0x60, 0x3E, 0xBE, 0xA5, 0x6F, 0x76, 0xF0, 0x8F, + 0x31, 0x00, 0x00, 0x00, 0x7A, 0x49, 0xF8, 0xA0, 0x7A, 0xF4, 0xF9, 0x10, 0xF7, 0xA0, 0xFA, 0xB9, + 0x7F, 0x74, 0x21, 0x40, 0x7C, 0x14, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x74, 0x08, 0x4C, 0xF5, 0x1A, + 0x3D, 0x60, 0xFE, 0xEB, 0xC7, 0x3E, 0x7D, 0x55, 0xF0, 0x8F, 0x2E, 0x00, 0x00, 0x00, 0x7A, 0x99, + 0xFB, 0x20, 0xC3, 0xDF, 0x6C, 0x9C, 0x7F, 0x5F, 0xED, 0x83, 0xEA, 0x0B, 0xCD, 0xF9, 0x9F, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x63, 0x60, 0xAA, 0x17, + 0x7F, 0xC0, 0xFC, 0xF5, 0x6D, 0x73, 0x4E, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x40, 0x49, 0xFD, 0xDB, + 0x83, 0x7D, 0x7D, 0xAF, 0x6C, 0x5E, 0xB0, 0xA5, 0x12, 0x21, 0xF3, 0xCD, 0xEF, 0x77, 0xCD, 0x37, + 0xA7, 0x9E, 0x5B, 0x68, 0xBC, 0x7F, 0x51, 0xC1, 0x90, 0xE7, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, + 0xFF, 0x4E, 0x4F, 0xC7, 0xC0, 0x54, 0x8E, 0x07, 0xCC, 0x01, 0x00, 0x00, 0xA6, 0xB1, 0xFF, 0xF9, + 0xD0, 0xBC, 0xA5, 0xAF, 0x6E, 0xEE, 0xFB, 0x99, 0x8B, 0x90, 0x30, 0x44, 0xCE, 0x8C, 0xBA, 0x03, + 0xB4, 0x8A, 0x87, 0x76, 0x17, 0x3B, 0xA0, 0x97, 0x79, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x20, 0x98, + 0xAA, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xAA, 0x7E, 0xF5, 0x58, 0xDF, 0x5F, 0x54, 0x3E, 0xC8, + 0xB0, 0x12, 0x22, 0xE3, 0x43, 0xF6, 0xC0, 0xF8, 0x13, 0x77, 0x98, 0x56, 0x21, 0x91, 0x65, 0xB1, + 0x03, 0x7A, 0x99, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x82, 0xA9, 0x18, 0x0F, 0x98, 0x03, 0x00, + 0x00, 0x40, 0x72, 0x0F, 0xAA, 0xFF, 0x7A, 0x63, 0xDF, 0x5F, 0xBE, 0xBE, 0xB5, 0xEF, 0xAD, 0x30, + 0x44, 0xDE, 0xDC, 0x6F, 0x0F, 0x90, 0x6D, 0x3F, 0x1F, 0x22, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, + 0x77, 0x7A, 0x3A, 0x0C, 0x8A, 0x1E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x20, 0x11, 0xFF, 0x41, 0xF5, + 0xA7, 0xFA, 0x1E, 0x0D, 0x23, 0xC4, 0xCD, 0x3D, 0xA8, 0x9E, 0xED, 0xF9, 0x10, 0x71, 0x48, 0x2F, + 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x71, 0x50, 0xF4, 0xCE, 0xFC, 0xDD, 0x7C, 0x1E, 0x30, 0x07, + 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x41, 0xF5, 0x57, 0x9F, 0x99, 0x3F, 0x12, 0x46, 0x48, 0xFA, 0x07, + 0xD5, 0xC5, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x41, 0x91, 0x73, 0xCF, 0x79, + 0xF0, 0x80, 0x39, 0x00, 0x00, 0x00, 0xDA, 0xF2, 0xAB, 0x27, 0xFA, 0xD6, 0x44, 0x1F, 0x54, 0x77, + 0xCF, 0x87, 0xB4, 0x7E, 0x50, 0x3D, 0x76, 0x40, 0x2F, 0xF3, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x81, + 0x50, 0xD4, 0xCE, 0xFD, 0x94, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x90, 0xA3, 0xCA, 0x07, 0x19, 0xF6, + 0x7D, 0x35, 0xFA, 0xA0, 0xBA, 0x7B, 0x3E, 0x44, 0x3F, 0xA8, 0x1E, 0x3B, 0xA0, 0x97, 0x79, 0xF2, + 0xF0, 0xDF, 0xE9, 0xE9, 0x48, 0x28, 0x62, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x42, 0xB9, 0xE7, + 0x43, 0x5E, 0xDD, 0xD4, 0x77, 0x4F, 0xF4, 0x41, 0xF5, 0xB7, 0x0E, 0x46, 0x1F, 0x54, 0x17, 0x87, + 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0A, 0x79, 0x2F, 0x7C, 0xC0, 0x3C, 0xFA, 0x9C, + 0x87, 0x1D, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA0, 0x18, 0x47, 0xBF, 0xB1, 0xF8, 0xC3, 0xAF, 0x6C, + 0xEE, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0x3B, 0x87, 0xEC, 0xC1, 0xF4, 0x5F, 0xC4, 0x41, 0xBD, 0x8C, + 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x42, 0xDE, 0x53, 0x0F, 0x98, 0xFF, 0xFA, 0xE1, 0x4B, 0x6F, + 0x0E, 0xFE, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xE3, 0x3F, 0xA8, 0xEE, 0x9E, 0x0F, 0xD9, 0xDE, + 0x67, 0xDC, 0x7E, 0xBF, 0xB3, 0xCF, 0x9C, 0x7A, 0xCE, 0x1E, 0x54, 0xD5, 0xA1, 0xBD, 0x2C, 0x93, + 0x87, 0xFF, 0x4E, 0xAF, 0x3E, 0x14, 0xF2, 0x9E, 0x7A, 0xC0, 0xFC, 0xD7, 0x83, 0x73, 0xFE, 0xB7, + 0xE0, 0x1F, 0x05, 0x00, 0x00, 0x00, 0x60, 0xEA, 0xFC, 0xF2, 0xE1, 0xB9, 0xB7, 0xBC, 0xB6, 0xB5, + 0xEF, 0x97, 0x61, 0x88, 0x8C, 0xEF, 0x9E, 0x6F, 0x26, 0xFE, 0xAB, 0x3D, 0x18, 0xAB, 0x03, 0x7C, + 0x2F, 0x4F, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0C, 0x79, 0x4D, 0x3D, 0x60, 0xFE, 0xDA, 0xA6, 0x39, + 0x77, 0xF3, 0x80, 0x39, 0x00, 0x00, 0x00, 0x3A, 0xCA, 0x7F, 0x50, 0xFD, 0xC9, 0xBE, 0xAF, 0xBE, + 0xBE, 0x65, 0xDE, 0x5B, 0x61, 0x88, 0xBC, 0xB9, 0x6F, 0xBE, 0x39, 0xFB, 0x13, 0x7B, 0x48, 0x56, + 0x87, 0xF9, 0x5E, 0x9B, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x1A, 0xF2, 0x98, 0x7A, 0xC0, 0xFC, 0xD5, + 0xCD, 0x73, 0x37, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xBA, 0x8A, 0x7B, 0x50, 0xFD, 0xB7, 0x9B, + 0xFA, 0xEE, 0x09, 0x23, 0xC4, 0xED, 0xED, 0x61, 0xF7, 0xA0, 0xBA, 0x38, 0xD4, 0xF7, 0xCA, 0xE4, + 0xE1, 0xBF, 0xD3, 0xD3, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0x3D, 0xC9, 0x3D, + 0x1F, 0xF2, 0xCA, 0xA6, 0xBE, 0x2D, 0xD1, 0x10, 0x71, 0xCF, 0x87, 0xF4, 0xDC, 0x83, 0xEA, 0xF2, + 0xF0, 0xDF, 0xE9, 0xE9, 0x78, 0x68, 0x77, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x9E, 0x57, 0xF9, + 0x20, 0xC3, 0x79, 0x35, 0x0F, 0xAA, 0x9F, 0xFE, 0x5B, 0x7B, 0xE0, 0x55, 0x87, 0xFD, 0x6E, 0x9B, + 0x3C, 0xFC, 0x77, 0x7A, 0xF5, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xA5, 0xF3, + 0xAB, 0xC7, 0xFA, 0xFE, 0x22, 0xFE, 0xA0, 0x7A, 0x57, 0x3F, 0x1F, 0x22, 0x0F, 0xFF, 0x9D, 0x9E, + 0x0E, 0x88, 0xAC, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0x94, 0x9A, 0x7B, 0x50, 0xFD, 0xB5, 0x2D, + 0xF3, 0xBE, 0x1E, 0x7F, 0x50, 0xFD, 0xDC, 0x3F, 0xDA, 0xC3, 0xB5, 0x8A, 0x80, 0x4E, 0x4D, 0x1E, + 0xFE, 0x3B, 0x3D, 0x1D, 0x11, 0x59, 0xC6, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x98, 0x56, 0xDC, 0x83, + 0xEA, 0xBF, 0x79, 0xAA, 0xEF, 0xC7, 0x61, 0x84, 0xB8, 0x75, 0xCD, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, + 0xE9, 0xE9, 0x90, 0x48, 0xBB, 0x46, 0x0F, 0x98, 0xBF, 0xB6, 0xE5, 0xD2, 0x81, 0xE0, 0x7F, 0x1A, + 0x00, 0x00, 0x00, 0xA0, 0xBC, 0xFC, 0x0F, 0x32, 0xDC, 0xD4, 0x37, 0x12, 0x46, 0x48, 0xF8, 0x41, + 0x86, 0x1D, 0x7B, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x13, 0x69, 0xA7, 0x1E, 0x30, 0x7F, + 0xE5, 0xC9, 0x39, 0xB7, 0x07, 0xFF, 0x53, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x87, 0x7B, 0x50, 0xFD, + 0xB5, 0x2D, 0xF3, 0x8E, 0x85, 0x21, 0xE2, 0x9E, 0x0F, 0x39, 0x33, 0x6A, 0x0F, 0xDF, 0x2A, 0x12, + 0x8A, 0x9A, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x26, 0xD2, 0x4C, 0x3D, 0x60, 0xFE, 0xCA, 0xA6, 0xB9, + 0xFF, 0x57, 0xF0, 0xB7, 0x1E, 0x00, 0x00, 0x00, 0x98, 0x9E, 0xC2, 0x0F, 0x32, 0x8C, 0x3E, 0xA8, + 0xFE, 0xC6, 0x9E, 0x29, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x14, 0x49, 0x17, 0x7F, + 0xC0, 0xDC, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x98, 0xF0, 0x83, 0x0C, 0xE3, 0x0F, 0xAA, + 0x17, 0xF6, 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2A, 0x92, 0x8C, 0x07, 0xCC, 0x01, 0x00, + 0x00, 0x80, 0x0C, 0x5E, 0x79, 0x72, 0xCE, 0xA5, 0xF1, 0x0F, 0x32, 0x74, 0x0F, 0xAA, 0xE7, 0xFA, + 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2C, 0x5A, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, + 0x1C, 0xFC, 0x7A, 0x63, 0xDF, 0x55, 0xAF, 0x6E, 0x9E, 0xF7, 0x4F, 0x61, 0x84, 0x84, 0x0F, 0xAA, + 0xCB, 0xA0, 0x48, 0x33, 0x79, 0xF8, 0xEF, 0xF4, 0xEA, 0xC3, 0x22, 0xC9, 0x78, 0xC0, 0x1C, 0x00, + 0x00, 0x00, 0xC8, 0xD9, 0x2F, 0x1F, 0x9E, 0x7B, 0x4B, 0xFC, 0x83, 0x0C, 0x33, 0x3F, 0xA8, 0x2E, + 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x8B, 0x66, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, 0x40, 0xFE, + 0x07, 0x19, 0x6E, 0xEE, 0xFB, 0x3F, 0xE3, 0xCF, 0x87, 0xA4, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, + 0x3D, 0x1D, 0x18, 0x8D, 0xA6, 0x1E, 0x30, 0xFF, 0xED, 0xC6, 0x4B, 0xBF, 0xC5, 0x03, 0xE6, 0x00, + 0x00, 0x00, 0x40, 0x01, 0xC2, 0x07, 0xD5, 0xC3, 0x08, 0x71, 0x7B, 0xEB, 0x40, 0x82, 0x07, 0xD5, + 0xE5, 0xE1, 0xBF, 0xD3, 0xD3, 0x91, 0xA1, 0xE6, 0x9E, 0xF3, 0x88, 0x3F, 0x60, 0xFE, 0xCA, 0x53, + 0x73, 0xB6, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x00, 0x30, 0x05, 0xDC, 0x07, 0x19, 0xBE, 0xBE, 0x75, + 0xDE, 0xFE, 0x68, 0x88, 0xBC, 0x73, 0xA8, 0xC1, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xD0, + 0x88, 0x4F, 0x3D, 0x60, 0xFE, 0xDA, 0xE6, 0x39, 0x3F, 0xE1, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, + 0x03, 0xDC, 0x07, 0x19, 0xC6, 0x1F, 0x54, 0x3F, 0xFD, 0xB7, 0xF6, 0xF0, 0x5E, 0x82, 0xF8, 0x70, + 0x0F, 0x98, 0xD7, 0x3C, 0xE7, 0xC1, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x40, 0x77, 0x88, 0x7F, 0x90, + 0xE1, 0xF8, 0xEE, 0x3E, 0x33, 0xF1, 0xF7, 0xEE, 0x20, 0xAF, 0x02, 0xA0, 0x93, 0xAB, 0x0F, 0x8D, + 0xF8, 0xDC, 0x03, 0xE6, 0x6F, 0x0C, 0xD5, 0x3F, 0x60, 0x3E, 0xDA, 0xFF, 0x9E, 0x3F, 0x0A, 0x7E, + 0xBB, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xCD, 0x7F, 0x50, 0x7D, 0xCB, 0xBC, 0xAF, 0x57, 0x1E, 0x54, + 0xB7, 0x07, 0x78, 0xBB, 0x37, 0xF7, 0xF5, 0xD9, 0x03, 0xBD, 0x3B, 0xD8, 0xAB, 0x18, 0x98, 0xEA, + 0xD5, 0xC7, 0x46, 0x74, 0xEE, 0x83, 0x04, 0x79, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xE8, 0x31, 0xEE, + 0x41, 0xF5, 0x57, 0x36, 0xCD, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0xDB, 0xC3, 0xF3, 0xED, 0x01, 0x5F, + 0x45, 0xC1, 0x54, 0x4D, 0x47, 0x87, 0x1B, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x6F, + 0x1B, 0xFA, 0xFA, 0x5E, 0xDB, 0x32, 0xF7, 0x27, 0x61, 0x84, 0xFC, 0x7E, 0xE7, 0x3C, 0x73, 0xEA, + 0xD9, 0xF9, 0xF6, 0xC0, 0xAF, 0x02, 0xA1, 0xC8, 0x35, 0x0E, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, + 0x00, 0x4A, 0xE6, 0x57, 0x4F, 0x5C, 0xBA, 0xC6, 0x86, 0xC8, 0xB1, 0x68, 0x88, 0x9C, 0xF9, 0x3B, + 0x17, 0x01, 0x2A, 0x16, 0xF2, 0x5E, 0x7D, 0x78, 0xB8, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0x50, + 0x62, 0xEE, 0x01, 0xEE, 0xDF, 0x3E, 0x39, 0xF7, 0xAB, 0xAF, 0x6F, 0x9B, 0x37, 0x1E, 0x86, 0x88, + 0x7B, 0x50, 0xBD, 0xD8, 0xE7, 0x43, 0xEA, 0xC3, 0x83, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x69, + 0xA4, 0xF2, 0x41, 0x86, 0x73, 0xEF, 0x79, 0x7D, 0xCB, 0xDC, 0x9A, 0x07, 0xD5, 0xCF, 0xFD, 0x34, + 0xEF, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, 0xA6, 0xB1, 0x57, 0x9E, 0x9C, + 0x73, 0xA9, 0x7A, 0x50, 0x3D, 0x9F, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, + 0xE0, 0x7B, 0x6D, 0x47, 0xDF, 0x40, 0xE5, 0x83, 0x0C, 0x27, 0x43, 0xE4, 0x8D, 0x3D, 0x7D, 0xFE, + 0x33, 0x22, 0xD9, 0xDE, 0x9A, 0x55, 0x79, 0xB8, 0xDC, 0x3D, 0xE3, 0x11, 0xBF, 0xF1, 0xE0, 0x01, + 0x73, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x57, 0x9E, 0x99, 0x73, 0xDB, 0xEB, 0xDB, 0xE7, 0x9E, 0x8C, + 0x86, 0x48, 0x18, 0x23, 0xEF, 0x1C, 0x9A, 0x6F, 0x4E, 0xFF, 0xCD, 0x7C, 0xFF, 0x79, 0x91, 0xF8, + 0x0D, 0x89, 0xFB, 0xFF, 0xDD, 0xBF, 0xEE, 0xFE, 0xFD, 0x77, 0x0E, 0xF5, 0xD5, 0x3C, 0xDF, 0x11, + 0xCE, 0x3D, 0x60, 0x6E, 0x7F, 0xEE, 0x75, 0xC1, 0x5F, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xDC, + 0x1B, 0xB3, 0x5E, 0x79, 0x66, 0xEE, 0x70, 0x3C, 0x44, 0x5A, 0x2E, 0x16, 0x1D, 0x95, 0xCD, 0x19, + 0xFA, 0xF5, 0xA3, 0x97, 0xDE, 0x1C, 0xFC, 0xD4, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xB9, 0x87, 0xD5, + 0x7F, 0xB3, 0x71, 0xDE, 0x9D, 0xAF, 0x3E, 0x3D, 0xEF, 0xA1, 0x57, 0x37, 0xCF, 0x7D, 0x59, 0x46, + 0x47, 0xB8, 0x20, 0x38, 0x5E, 0xDB, 0x3C, 0xF7, 0xD8, 0xAB, 0xCF, 0xCC, 0x7D, 0xDA, 0xDD, 0x76, + 0xFC, 0xB7, 0xEF, 0xCC, 0xFB, 0x40, 0xF0, 0x53, 0x01, 0x00, 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x35, + 0xB9, 0xFE, 0x07, 0x1B, 0xEE, 0xE8, 0x1B, 0x88, 0xEF, 0xDF, 0x36, 0xCC, 0xEE, 0x0B, 0xFE, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD0, 0x15, 0xDE, 0xF3, 0x9E, 0xFF, 0x1F, 0x5B, 0xE2, 0x94, 0x1D, 0x86, + 0x86, 0x23, 0x09, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82}; + +static const uint8_t tree_gif[] PROGMEM = { + + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x28, 0x00, 0x3C, 0x00, 0x83, 0x0B, 0x00, 0x00, 0xFF, 0xFF, + 0x00, 0x21, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x94, 0x00, 0x00, 0xB5, 0x00, 0x00, + 0xDE, 0x00, 0x00, 0xFF, 0x00, 0x6B, 0x00, 0x00, 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x00, 0xCC, 0x00, 0x00, 0x21, 0xFF, 0x0B, + 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0xA0, 0x0F, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, + 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, + 0x8C, 0xCA, 0xE8, 0x85, 0xE8, 0xA5, 0xAC, 0x67, 0xEA, 0x8A, 0xE5, 0x2B, 0x2F, 0xE3, 0x31, 0xCE, + 0xAF, 0x41, 0x1C, 0xB8, 0x1B, 0x24, 0x80, 0x04, 0xAF, 0x87, 0x02, 0x26, 0x88, 0xA1, 0x07, 0x60, + 0xB9, 0x44, 0x82, 0x04, 0x02, 0x80, 0x61, 0x30, 0x70, 0x6E, 0x0C, 0x86, 0x03, 0x60, 0x20, 0xB0, + 0x6A, 0xA8, 0xD3, 0x03, 0x21, 0xEC, 0xAD, 0x18, 0x12, 0xE8, 0xF4, 0xB1, 0x4C, 0x51, 0xA0, 0x07, + 0xEA, 0x07, 0x5B, 0xF2, 0x70, 0x13, 0x76, 0xD4, 0xA8, 0xBC, 0xBC, 0xEA, 0x1F, 0x06, 0x77, 0x51, + 0x73, 0x50, 0x0A, 0x80, 0x7F, 0x04, 0x4C, 0x4D, 0x65, 0x06, 0x0A, 0x3B, 0x3B, 0x62, 0x5A, 0x53, + 0x65, 0x05, 0x02, 0x04, 0x68, 0x0C, 0x6A, 0x00, 0x5D, 0x5E, 0x0F, 0x0F, 0x6A, 0x98, 0x6A, 0x09, + 0x7B, 0x56, 0x9D, 0x09, 0x0C, 0xA7, 0xA7, 0x7F, 0x06, 0x9D, 0xA3, 0x44, 0x02, 0x01, 0x03, 0x90, + 0x0C, 0x87, 0x03, 0x06, 0x02, 0x05, 0x56, 0x06, 0x01, 0x02, 0x53, 0xB1, 0xB3, 0x04, 0x79, 0xAF, + 0x55, 0x48, 0x51, 0xB0, 0x87, 0xC0, 0x7F, 0x07, 0x95, 0x05, 0x85, 0x44, 0xB6, 0x00, 0x05, 0x53, + 0x96, 0x6A, 0x60, 0x02, 0x0A, 0x48, 0x89, 0x00, 0x07, 0xA1, 0x69, 0x7D, 0x2B, 0x3D, 0x9D, 0x41, + 0xA1, 0x04, 0xA0, 0xDD, 0x9D, 0x38, 0x02, 0xE1, 0x6A, 0x07, 0x62, 0x0C, 0x77, 0xE6, 0xAD, 0x2F, + 0x05, 0x01, 0xB6, 0x90, 0x07, 0xA8, 0xA7, 0x54, 0xB5, 0xBC, 0x06, 0x33, 0x50, 0x53, 0x3A, 0x00, + 0x39, 0x62, 0x10, 0x6B, 0xDF, 0xBE, 0x19, 0x03, 0x18, 0x40, 0xA9, 0x15, 0x4B, 0xCC, 0x0E, 0x77, + 0x3B, 0x04, 0xC4, 0x02, 0x38, 0x43, 0x21, 0x96, 0x2C, 0xD3, 0xD6, 0x81, 0x01, 0x26, 0x2A, 0xFB, + 0xDE, 0x07, 0x7C, 0x0A, 0xB7, 0x71, 0x1B, 0x79, 0xEE, 0xC5, 0x83, 0x72, 0xDD, 0x84, 0xBC, 0x4B, + 0x13, 0xA4, 0x13, 0x15, 0x17, 0xAB, 0x18, 0x78, 0x4A, 0x43, 0x40, 0x81, 0x43, 0x76, 0x8E, 0xB6, + 0x04, 0x7C, 0x19, 0x02, 0x98, 0xC4, 0x86, 0x35, 0xBD, 0xE1, 0x1C, 0x90, 0x4D, 0x62, 0xBF, 0x14, + 0xFC, 0x7E, 0x02, 0x1A, 0x60, 0xD3, 0xD1, 0x9D, 0x3B, 0x3A, 0x09, 0xFC, 0x44, 0xB1, 0xD0, 0x96, + 0x8E, 0x43, 0x8D, 0x9E, 0xDA, 0xDB, 0x22, 0x11, 0x8A, 0x42, 0x10, 0x5C, 0x00, 0x1A, 0x2D, 0x38, + 0xF2, 0x0E, 0xA0, 0x4A, 0x03, 0x4E, 0xA2, 0xF0, 0xF4, 0x80, 0x17, 0x95, 0x8C, 0x23, 0xD1, 0xD8, + 0x12, 0x00, 0x92, 0x03, 0xAB, 0x99, 0x23, 0x71, 0x3E, 0x8D, 0xEB, 0x6E, 0x18, 0x07, 0x66, 0x23, + 0x05, 0x3E, 0x72, 0xE4, 0x06, 0x0D, 0x81, 0x02, 0xE4, 0x36, 0x5D, 0xD9, 0xA5, 0xC0, 0xAD, 0x59, + 0xA2, 0x86, 0x6E, 0xD6, 0xC4, 0x73, 0xEB, 0x15, 0xA5, 0xC5, 0xDE, 0x14, 0xF4, 0x62, 0x07, 0xC0, + 0xE9, 0x9D, 0xCC, 0x58, 0x02, 0x14, 0xA0, 0x84, 0x45, 0x83, 0x68, 0x7A, 0x8D, 0x81, 0x66, 0xC3, + 0xE9, 0xD0, 0xA6, 0x3E, 0x03, 0xF3, 0x80, 0x7D, 0x90, 0xD8, 0x58, 0xA2, 0x59, 0x2D, 0x90, 0x68, + 0xD6, 0x64, 0x17, 0x76, 0x5A, 0x23, 0xBF, 0x13, 0x58, 0x89, 0x7A, 0xC3, 0xF0, 0x8F, 0xB6, 0xB8, + 0x4B, 0xD3, 0x74, 0x52, 0x50, 0x92, 0xC2, 0x03, 0xD1, 0x78, 0xD7, 0x89, 0x4C, 0x23, 0x26, 0x6E, + 0x82, 0xCC, 0x15, 0x5E, 0x05, 0x08, 0x30, 0x06, 0x8A, 0x75, 0x64, 0xFA, 0x42, 0xF1, 0x12, 0xAD, + 0x60, 0xDE, 0x51, 0x0A, 0x94, 0xBA, 0x5E, 0x2C, 0x8C, 0x86, 0xDD, 0x3D, 0xDE, 0x8F, 0x0A, 0x70, + 0x51, 0x5F, 0xFE, 0xF2, 0x84, 0xD1, 0xD0, 0xA6, 0x68, 0xB7, 0x96, 0x62, 0x14, 0x0C, 0xC1, 0xB7, + 0x90, 0x68, 0x72, 0xD1, 0x7C, 0xD9, 0x3D, 0xA3, 0x94, 0x35, 0xDE, 0x54, 0x06, 0x92, 0x51, 0x50, + 0x68, 0xC2, 0xC5, 0x44, 0xB7, 0x30, 0x70, 0xDE, 0x6A, 0x49, 0x69, 0x86, 0xC5, 0x2D, 0xA3, 0x29, + 0x04, 0x05, 0x2F, 0xD9, 0xC4, 0x02, 0x0C, 0x6C, 0x0C, 0x48, 0xB0, 0x94, 0x01, 0xDA, 0x3C, 0xF2, + 0x56, 0x21, 0xFA, 0xE8, 0xA3, 0xA1, 0x55, 0x12, 0xE9, 0xF4, 0x56, 0x42, 0xF8, 0x50, 0x00, 0x40, + 0x08, 0x08, 0xD4, 0x88, 0x80, 0x05, 0x33, 0x66, 0x10, 0xA2, 0x0C, 0xDC, 0xA0, 0xB0, 0xA3, 0x0B, + 0x71, 0xCD, 0xB1, 0x80, 0x75, 0x69, 0x20, 0x41, 0xE4, 0x91, 0x6B, 0x64, 0x10, 0x01, 0x00, 0x21, + 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, 0x00, + 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, 0x8C, + 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0x31, 0x1C, 0x34, + 0x1B, 0x24, 0x4C, 0x82, 0xE7, 0x28, 0x5E, 0x02, 0x78, 0x7A, 0x30, 0x8E, 0x47, 0x62, 0x48, 0x20, + 0x60, 0xD8, 0x06, 0x4A, 0x8E, 0xC1, 0x70, 0x60, 0x0C, 0x04, 0xD1, 0xCD, 0x60, 0x60, 0x3B, 0x10, + 0xBA, 0x59, 0x8B, 0x21, 0x41, 0x2E, 0x0F, 0xC3, 0x16, 0xF2, 0xC0, 0xAC, 0x40, 0x4F, 0x1E, 0x80, + 0x04, 0x81, 0x70, 0xD8, 0x0A, 0x14, 0x0F, 0xF7, 0x42, 0x00, 0xA0, 0xD6, 0x09, 0x0A, 0x81, 0x81, + 0x68, 0x00, 0x85, 0x85, 0x7F, 0x07, 0x07, 0x0A, 0x06, 0x7A, 0x06, 0x00, 0x74, 0x74, 0x5E, 0x8A, + 0x36, 0x68, 0x05, 0x7C, 0x66, 0x3D, 0x64, 0x58, 0x61, 0x0F, 0x0F, 0x66, 0x64, 0x99, 0x64, 0x79, + 0x9C, 0x9E, 0xA0, 0x48, 0x4E, 0x9D, 0xA3, 0x4A, 0x02, 0x01, 0x37, 0x90, 0x55, 0x04, 0x5C, 0x02, + 0x05, 0x59, 0x06, 0x01, 0x02, 0x4F, 0x89, 0x55, 0x76, 0xAC, 0x50, 0xAB, 0x0A, 0xAD, 0x7F, 0xB1, + 0x75, 0x07, 0x02, 0x04, 0x05, 0x00, 0xBE, 0x39, 0x06, 0x77, 0x05, 0x36, 0x04, 0x9F, 0x5B, 0xCC, + 0x00, 0x4A, 0x82, 0x81, 0x07, 0x9F, 0x65, 0x86, 0x85, 0x40, 0x9D, 0x0A, 0x9F, 0x0C, 0xD0, 0x9F, + 0x00, 0x9D, 0x39, 0x02, 0xDE, 0x66, 0xB0, 0x73, 0xE2, 0x09, 0xE4, 0xAA, 0x2F, 0x05, 0x01, 0xCC, + 0x5E, 0xA7, 0x56, 0x75, 0xD2, 0xB8, 0x8C, 0x2F, 0x4C, 0x36, 0x06, 0xB1, 0x73, 0xE1, 0x88, 0xC9, + 0x92, 0x45, 0x43, 0x96, 0x00, 0x2E, 0x37, 0xE8, 0x79, 0x99, 0x53, 0xEC, 0x86, 0x0D, 0x06, 0x05, + 0xF3, 0x51, 0x61, 0x57, 0xE6, 0x9E, 0xBF, 0x35, 0x0C, 0xDE, 0x81, 0xE8, 0x64, 0x10, 0xFB, 0x5B, + 0xB6, 0x6C, 0xF5, 0x56, 0x94, 0x22, 0x13, 0xA7, 0xE2, 0x9C, 0x04, 0xDF, 0xCA, 0x74, 0xB2, 0xB2, + 0xC2, 0x40, 0x2A, 0x92, 0x72, 0x20, 0x45, 0x52, 0xE0, 0x45, 0x1A, 0x01, 0x2B, 0xCA, 0x3E, 0xC4, + 0x3A, 0x38, 0x60, 0xDB, 0x23, 0x86, 0xD6, 0x14, 0x0C, 0x20, 0xC0, 0x84, 0xCB, 0x8A, 0x7C, 0x3C, + 0x1F, 0x25, 0x94, 0xA9, 0x80, 0x21, 0x17, 0xA2, 0x5B, 0x4E, 0x34, 0x91, 0xE5, 0x2F, 0x99, 0x4C, + 0xA0, 0x89, 0xEC, 0x5C, 0xC1, 0xB5, 0x89, 0xC3, 0x15, 0x2B, 0xCC, 0x10, 0xD6, 0xF9, 0x38, 0x67, + 0xA8, 0xB1, 0x01, 0xE5, 0x40, 0xD4, 0x7B, 0x42, 0xF1, 0x63, 0x02, 0x66, 0x02, 0x12, 0xA4, 0xFA, + 0x90, 0x2A, 0x54, 0xB6, 0x44, 0xEB, 0xDA, 0x96, 0x19, 0x9A, 0x53, 0x43, 0x01, 0xBB, 0x64, 0x84, + 0xAE, 0xC3, 0xBB, 0xB0, 0xCC, 0x31, 0x40, 0x5D, 0x35, 0xD8, 0x62, 0x82, 0x6B, 0x68, 0xAC, 0xA6, + 0x43, 0xF1, 0xD2, 0x01, 0x20, 0xE9, 0x8A, 0x25, 0x05, 0x96, 0x36, 0xD8, 0x8A, 0xD7, 0xD8, 0x46, + 0xD0, 0x85, 0xEB, 0x7E, 0x72, 0x31, 0x10, 0x54, 0x9F, 0x85, 0x00, 0xF1, 0xA6, 0x1C, 0x94, 0x2C, + 0x34, 0xB2, 0x17, 0x9F, 0x5B, 0xB8, 0x14, 0x80, 0xFC, 0x41, 0x28, 0x63, 0xC7, 0x03, 0x9A, 0x4A, + 0x32, 0x9C, 0x2C, 0x2B, 0x2E, 0x40, 0x72, 0x63, 0x59, 0x48, 0x85, 0x47, 0x8D, 0xD8, 0xC8, 0xD9, + 0xE2, 0xF0, 0x55, 0x99, 0x4A, 0xE3, 0x82, 0x07, 0x41, 0x3F, 0x25, 0x92, 0xAE, 0xD7, 0x4C, 0x3C, + 0xE7, 0xAC, 0x02, 0x04, 0x58, 0xC4, 0xC4, 0xAD, 0x9C, 0x1B, 0xB1, 0x3F, 0xE1, 0x42, 0x3D, 0x4B, + 0x9E, 0x85, 0xCB, 0x57, 0xA6, 0x30, 0x4B, 0x97, 0x88, 0x26, 0xA2, 0x03, 0x7F, 0x8B, 0x72, 0x2D, + 0x90, 0x79, 0x02, 0xFD, 0x59, 0x36, 0xB2, 0xF3, 0x41, 0x2A, 0x65, 0xAD, 0x75, 0x64, 0x3A, 0x0C, + 0x48, 0xB4, 0x15, 0x35, 0x13, 0xE0, 0xC2, 0xC0, 0x2D, 0xB1, 0x15, 0x95, 0x0C, 0x13, 0x97, 0x59, + 0x73, 0x90, 0x01, 0xF5, 0xAC, 0x36, 0x8D, 0x79, 0x12, 0x40, 0xB8, 0x45, 0x22, 0xB8, 0xF8, 0xC4, + 0x0C, 0x7D, 0xB3, 0x31, 0x96, 0xCF, 0x00, 0x01, 0x76, 0x41, 0x80, 0x4F, 0x0B, 0x80, 0x78, 0x4A, + 0x24, 0x5B, 0x8C, 0x18, 0xDB, 0x8A, 0x0A, 0xF0, 0xC3, 0x15, 0x88, 0x08, 0xF1, 0xC5, 0xC7, 0x3C, + 0x13, 0x40, 0x94, 0x01, 0x81, 0x13, 0x20, 0xA0, 0x23, 0x02, 0x27, 0xE0, 0x58, 0x63, 0x08, 0xD9, + 0xE8, 0x41, 0x81, 0x5B, 0x42, 0x7A, 0x57, 0x86, 0x12, 0x46, 0x26, 0x79, 0x46, 0x06, 0x11, 0x00, + 0x00, 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x3C, 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, + 0xE4, 0x8C, 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0xA1, + 0x1C, 0x34, 0x1B, 0x24, 0x4A, 0x82, 0xE7, 0x27, 0x85, 0x50, 0x08, 0x0C, 0x3D, 0x12, 0xBC, 0xC4, + 0xA3, 0x18, 0x12, 0x08, 0x14, 0x86, 0xC1, 0x80, 0xC9, 0x31, 0x18, 0x0E, 0x84, 0x81, 0x80, 0xBA, + 0x91, 0x46, 0xB1, 0x51, 0x06, 0xD7, 0x62, 0x40, 0x9A, 0x91, 0xE2, 0x71, 0xA5, 0x37, 0x40, 0x33, + 0xDE, 0xE9, 0xF1, 0xE3, 0xA1, 0x20, 0x10, 0x0E, 0x52, 0x01, 0x63, 0xA9, 0x5E, 0x0C, 0x85, 0x03, + 0x76, 0x7A, 0x7D, 0x0B, 0x4E, 0x03, 0x75, 0x78, 0x77, 0x78, 0x06, 0x84, 0x51, 0x37, 0x8A, 0x77, + 0x02, 0x51, 0x6A, 0x05, 0x02, 0x04, 0x67, 0x67, 0x5B, 0x72, 0x47, 0x98, 0x98, 0x7C, 0x5C, 0x73, + 0x66, 0x58, 0x07, 0x8B, 0x0F, 0x00, 0x9F, 0x45, 0x02, 0x01, 0x03, 0xA3, 0x0C, 0x89, 0x03, 0x06, + 0x02, 0x00, 0x5C, 0x06, 0x01, 0x92, 0x52, 0x07, 0xAE, 0x59, 0x03, 0x00, 0xBD, 0xBD, 0x4C, 0x02, + 0x05, 0xAB, 0xB9, 0x70, 0x0C, 0xAC, 0x96, 0x00, 0x52, 0x45, 0x36, 0xC1, 0x51, 0x97, 0x0C, 0x66, + 0x5E, 0x00, 0x8C, 0x4C, 0x0A, 0x05, 0x5F, 0x68, 0x98, 0x4E, 0x56, 0x40, 0x7F, 0x3D, 0x67, 0x97, + 0x9D, 0x73, 0x39, 0x02, 0x74, 0x9C, 0x48, 0xA4, 0x76, 0x76, 0x66, 0x73, 0xA8, 0x2C, 0x05, 0x50, + 0x02, 0xA3, 0xA3, 0x59, 0x78, 0x5E, 0x92, 0xD4, 0x2C, 0xDB, 0xB0, 0x59, 0x76, 0x07, 0x00, 0x78, + 0x16, 0x09, 0x80, 0xF5, 0xE4, 0x05, 0xC1, 0x81, 0x5F, 0xB0, 0x10, 0x00, 0xA0, 0xEE, 0xC0, 0xC0, + 0x03, 0x8E, 0x68, 0x68, 0xB1, 0x72, 0xE5, 0x92, 0xAF, 0x5E, 0xF6, 0x0C, 0x10, 0xF0, 0x86, 0x62, + 0xFB, 0xCE, 0xC1, 0x03, 0x98, 0x00, 0x74, 0x42, 0x42, 0xE7, 0xC5, 0xB9, 0x4E, 0xFF, 0xC2, 0x9D, + 0x99, 0xA3, 0x60, 0x0A, 0x0A, 0x03, 0xED, 0xC0, 0xDD, 0xF1, 0x47, 0xCF, 0xCB, 0x2E, 0x97, 0x20, + 0x92, 0x0D, 0x64, 0x85, 0xA5, 0x65, 0x43, 0x2C, 0x3C, 0x19, 0x10, 0x30, 0x94, 0x2F, 0x27, 0xBE, + 0x9D, 0x87, 0x78, 0xCE, 0x54, 0x47, 0xC0, 0x98, 0xC6, 0x9D, 0x39, 0x2F, 0xC6, 0xB2, 0xF1, 0x87, + 0x29, 0x96, 0x62, 0xC6, 0xB6, 0x69, 0xE2, 0xC0, 0x2B, 0x4A, 0x2C, 0x58, 0x49, 0x47, 0xDA, 0x11, + 0x6A, 0x69, 0xC0, 0xB8, 0x10, 0x22, 0x1F, 0xDC, 0x0A, 0xF4, 0x6D, 0x64, 0x02, 0x06, 0xB1, 0x04, + 0x28, 0x39, 0xBB, 0xA1, 0xDD, 0x49, 0x4C, 0xE9, 0xD4, 0xB9, 0x4D, 0x0A, 0xA2, 0x40, 0x81, 0x91, + 0x81, 0x68, 0x2E, 0x35, 0x43, 0xA0, 0xC0, 0x50, 0x05, 0x1F, 0x6A, 0x39, 0xB9, 0x65, 0x47, 0x4A, + 0xBF, 0xBC, 0xF4, 0xF0, 0x04, 0xE3, 0x98, 0xA1, 0x96, 0x02, 0x5B, 0x5E, 0x71, 0xA5, 0x53, 0xA8, + 0x4E, 0x68, 0x16, 0x2B, 0x01, 0xFC, 0x42, 0x29, 0x4A, 0x21, 0xF4, 0xE8, 0x87, 0x0A, 0xA5, 0x04, + 0xDA, 0xDC, 0x94, 0x95, 0x6A, 0x03, 0xC2, 0x5A, 0x6E, 0xF0, 0x66, 0xC8, 0x0E, 0xC0, 0x99, 0x20, + 0xDF, 0x16, 0x93, 0xAC, 0x91, 0x64, 0x16, 0x0B, 0xED, 0x14, 0x70, 0xF2, 0xC2, 0x6B, 0x75, 0x27, + 0x68, 0x81, 0xDA, 0x90, 0xB4, 0x0B, 0xDC, 0x74, 0xC8, 0x8B, 0x67, 0xB0, 0xBC, 0x75, 0x2B, 0xCC, + 0x5D, 0xA1, 0x00, 0xD8, 0x09, 0xC4, 0x3D, 0x23, 0x92, 0xB0, 0x6B, 0x29, 0xDA, 0x6A, 0x55, 0x12, + 0x46, 0x7A, 0x41, 0xA5, 0x81, 0xF8, 0x62, 0x25, 0xE8, 0x4E, 0x2A, 0x60, 0x22, 0x52, 0x05, 0xB4, + 0xB4, 0x94, 0x14, 0xAC, 0x12, 0x05, 0xBF, 0xCD, 0xB4, 0x60, 0xA7, 0x6F, 0x66, 0x65, 0xE7, 0x57, + 0xC7, 0xA3, 0xC8, 0x67, 0x85, 0x16, 0x5B, 0x49, 0xF0, 0x84, 0x2A, 0x48, 0x19, 0x92, 0x47, 0x30, + 0x4E, 0x00, 0x60, 0xC9, 0x57, 0x71, 0x79, 0x03, 0x51, 0x30, 0xD3, 0x4C, 0xA0, 0xC0, 0x4E, 0xA4, + 0x1C, 0x45, 0x51, 0x2C, 0x7E, 0x39, 0xB8, 0x18, 0x3E, 0x04, 0xB5, 0x04, 0x14, 0x6C, 0xB3, 0xF8, + 0xF1, 0xC7, 0x3C, 0x00, 0xAA, 0xC6, 0xCB, 0x45, 0xFC, 0x21, 0xD5, 0x52, 0x72, 0x17, 0x95, 0x88, + 0xD8, 0x09, 0x08, 0x00, 0x80, 0x00, 0x02, 0x28, 0x94, 0x28, 0xC1, 0x8C, 0x20, 0x20, 0xD1, 0x5D, + 0x02, 0x27, 0xE8, 0x88, 0x82, 0x5B, 0x84, 0x2C, 0xE0, 0xD6, 0x19, 0x4C, 0x1C, 0xA9, 0xA4, 0x19, + 0x1B, 0x44, 0x00, 0x00, 0x21, 0xFE, 0x19, 0x42, 0x6F, 0x79, 0x27, 0x73, 0x20, 0x48, 0x61, 0x70, + 0x70, 0x79, 0x20, 0x48, 0x6F, 0x6C, 0x69, 0x64, 0x61, 0x79, 0x73, 0x20, 0x50, 0x61, 0x67, 0x65, + 0x00, 0x3B + +}; + +static const uint8_t bird_gif[] PROGMEM = { + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x74, 0x00, 0x4E, 0x00, 0xCC, 0x13, 0x00, 0xFF, 0xFF, 0xFF, + 0xEF, 0xFF, 0xFF, 0xBD, 0xE7, 0xE7, 0xD6, 0xEF, 0xEF, 0x63, 0x63, 0x63, 0xAD, 0xAD, 0xAD, 0xCE, + 0xCE, 0xCE, 0xD6, 0xDE, 0xDE, 0x4A, 0x4A, 0x4A, 0x7B, 0x84, 0x84, 0x94, 0x9C, 0x9C, 0xE7, 0xE7, + 0xE7, 0x84, 0x94, 0x94, 0xB5, 0xC6, 0xC6, 0x73, 0x7B, 0x7B, 0x31, 0x31, 0x31, 0xF7, 0xF7, 0xF7, + 0x18, 0x10, 0x10, 0xCE, 0x63, 0x39, 0x6B, 0x39, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xFF, 0x0B, + 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x4B, + 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0xAE, 0xEC, 0x68, 0x2C, + 0x6D, 0x2C, 0xCF, 0x74, 0x6D, 0x03, 0x46, 0x84, 0x40, 0x77, 0xEF, 0xFF, 0x40, 0x51, 0x42, 0x41, + 0x0C, 0x1A, 0x8F, 0x48, 0x13, 0xC1, 0xD0, 0x20, 0x00, 0x0E, 0x8E, 0x42, 0x72, 0x4A, 0xAD, 0x21, + 0x0E, 0xCD, 0x05, 0xE1, 0x80, 0xA8, 0x7A, 0xBF, 0x29, 0xC2, 0xA0, 0x91, 0x28, 0x34, 0x02, 0x5D, + 0xB0, 0x5A, 0xFD, 0x08, 0x34, 0x14, 0x84, 0x00, 0x7A, 0x4D, 0xF7, 0x22, 0xDC, 0x89, 0xB8, 0xC1, + 0xB9, 0x80, 0xD5, 0xFF, 0x40, 0x0B, 0x77, 0x0C, 0x0F, 0x05, 0x01, 0x0C, 0x0A, 0x0B, 0x0F, 0x08, + 0x06, 0x80, 0x8E, 0x37, 0x7B, 0x01, 0x09, 0x11, 0x03, 0x68, 0x5C, 0x4C, 0x0A, 0x8F, 0x9A, 0x33, + 0x06, 0x09, 0x01, 0x0E, 0x71, 0x68, 0x88, 0x92, 0x07, 0x9B, 0xA6, 0x2C, 0x0A, 0x86, 0x07, 0x95, + 0x05, 0x04, 0xA1, 0x5D, 0x8D, 0xA7, 0xB2, 0x26, 0x09, 0x06, 0x72, 0x72, 0x0E, 0x94, 0x01, 0xA9, + 0x04, 0x08, 0x52, 0xB3, 0xC0, 0x00, 0x09, 0x95, 0xB7, 0x0D, 0x86, 0x01, 0x04, 0x0A, 0xC3, 0x09, + 0x34, 0x43, 0xC1, 0x54, 0x0E, 0xB7, 0xD2, 0x87, 0xAE, 0xBB, 0x99, 0x32, 0x7B, 0x0E, 0xCF, 0x49, + 0x0B, 0xD1, 0xD3, 0x72, 0x0C, 0xDE, 0x57, 0x33, 0xBE, 0xCC, 0xDB, 0x47, 0x05, 0x0C, 0xDF, 0xD3, + 0x05, 0xD7, 0x31, 0x0C, 0xE1, 0xA5, 0xE7, 0x46, 0xBE, 0xEB, 0xD2, 0x04, 0x05, 0xBF, 0x2C, 0x5C, + 0x4D, 0xF3, 0x46, 0x0B, 0x11, 0x56, 0xD9, 0x3B, 0x14, 0x01, 0x14, 0x0F, 0x16, 0x04, 0x1A, 0x30, + 0x28, 0x00, 0x81, 0xA1, 0x3F, 0x1F, 0xAD, 0x02, 0x10, 0x5B, 0x87, 0x6F, 0x0E, 0x8B, 0x02, 0x0E, + 0x04, 0x5C, 0x41, 0x10, 0xF0, 0x61, 0x8F, 0x25, 0x03, 0x26, 0xDA, 0x43, 0xC4, 0x42, 0x8B, 0x00, + 0x05, 0x0E, 0x7C, 0xFF, 0xED, 0xF0, 0x68, 0x83, 0x8B, 0x44, 0x91, 0xDF, 0x06, 0xAC, 0x54, 0x01, + 0x21, 0xA1, 0x80, 0x07, 0x0F, 0x1A, 0x38, 0x70, 0xC7, 0x72, 0x46, 0xC2, 0x97, 0x03, 0x3F, 0xC5, + 0x52, 0xE1, 0x80, 0x81, 0x00, 0x01, 0x19, 0x1B, 0x3C, 0x38, 0xD8, 0x53, 0xC6, 0x81, 0x38, 0x21, + 0x61, 0x4A, 0xEB, 0xB7, 0x42, 0x01, 0x82, 0xA3, 0x58, 0x7D, 0xC9, 0x6B, 0x1A, 0x63, 0x0B, 0xD0, + 0x81, 0x11, 0x08, 0x74, 0x44, 0x61, 0xE0, 0x01, 0xD6, 0xA3, 0x05, 0x16, 0x2D, 0xE5, 0xDA, 0xC2, + 0x80, 0xB7, 0x90, 0x41, 0xCB, 0xA4, 0x39, 0xC1, 0xEF, 0x2C, 0x56, 0xAA, 0x6C, 0x57, 0x38, 0xA8, + 0x14, 0x35, 0xA8, 0x35, 0x14, 0x10, 0x10, 0x34, 0xB0, 0x9B, 0xD5, 0x4F, 0xDE, 0x14, 0x06, 0x8E, + 0xF5, 0x1D, 0xC8, 0x25, 0x85, 0x83, 0xC1, 0x84, 0x05, 0x20, 0x32, 0x30, 0xF4, 0x30, 0x2D, 0x39, + 0x8B, 0x07, 0x32, 0x42, 0xA1, 0x00, 0x72, 0xE4, 0x45, 0x08, 0x7C, 0x59, 0x36, 0x91, 0x18, 0x73, + 0xE6, 0x6F, 0x79, 0x38, 0x2B, 0x88, 0x7C, 0x54, 0xE7, 0xE0, 0x2D, 0xA3, 0x4B, 0x78, 0x7A, 0x79, + 0x7A, 0x1A, 0xCE, 0x04, 0x4C, 0x85, 0xAC, 0x66, 0x7D, 0x96, 0x80, 0xB9, 0xD8, 0x22, 0x4A, 0x4B, + 0x14, 0x00, 0x97, 0xF1, 0xD3, 0x12, 0x3B, 0x79, 0x9F, 0x45, 0xC0, 0x13, 0xB8, 0xB7, 0xE1, 0xC5, + 0x19, 0x33, 0xEB, 0x53, 0xD3, 0xA8, 0x72, 0x01, 0x0D, 0x44, 0x97, 0x5C, 0x90, 0x7B, 0x9B, 0x01, + 0x05, 0xA6, 0x89, 0xFB, 0x3D, 0x54, 0x20, 0x81, 0xDA, 0x8C, 0xD7, 0x91, 0x16, 0x22, 0x91, 0xF8, + 0x80, 0x9F, 0x86, 0x08, 0x1E, 0xF4, 0xF2, 0xD5, 0x7D, 0x96, 0x18, 0xCC, 0x47, 0xA3, 0xDB, 0x7B, + 0xCA, 0x60, 0x40, 0xCA, 0xF4, 0x58, 0x81, 0xE2, 0x42, 0x04, 0x11, 0x4C, 0x80, 0x53, 0x7C, 0x3F, + 0xC9, 0xB1, 0xC7, 0xFF, 0x7A, 0xC1, 0x18, 0xA0, 0x0E, 0x7E, 0xC4, 0x49, 0xA5, 0x99, 0x67, 0xD7, + 0xA5, 0xB4, 0x15, 0x04, 0x93, 0x48, 0xA0, 0xA1, 0x81, 0x7C, 0x49, 0xB3, 0xC7, 0x38, 0xF6, 0x11, + 0x13, 0x52, 0x7E, 0x12, 0xAE, 0x63, 0xC0, 0x55, 0x00, 0x82, 0x62, 0xD8, 0x08, 0x0B, 0x24, 0xA0, + 0xA1, 0x86, 0x57, 0x3C, 0xF0, 0xE0, 0x2D, 0x05, 0x68, 0x67, 0x4A, 0x27, 0xB7, 0x0C, 0x80, 0x95, + 0x7E, 0x41, 0x11, 0x80, 0x5E, 0x85, 0xBF, 0x9D, 0xD0, 0xC0, 0x04, 0x2F, 0x2E, 0x62, 0xCB, 0x34, + 0x03, 0xE4, 0xB1, 0xA2, 0x23, 0x5E, 0x41, 0xC8, 0x63, 0x50, 0x0E, 0x9A, 0x75, 0x5D, 0x68, 0x5B, + 0x9D, 0xA0, 0x45, 0x04, 0x38, 0x2D, 0x72, 0xCC, 0x34, 0x7B, 0x24, 0xF2, 0x88, 0x5B, 0x39, 0xEA, + 0x18, 0xE1, 0x78, 0xD2, 0x58, 0x05, 0x20, 0x6C, 0x2B, 0xD4, 0x78, 0x64, 0x89, 0x6E, 0xB8, 0xF2, + 0xC2, 0x1F, 0x4D, 0xBE, 0x44, 0x22, 0x99, 0x72, 0xE4, 0x01, 0x60, 0x19, 0x31, 0x68, 0xB1, 0xC4, + 0x78, 0x50, 0xF4, 0xE2, 0x9B, 0x43, 0x5E, 0x80, 0x99, 0xE3, 0x8E, 0x6C, 0x4E, 0xE3, 0x63, 0x7A, + 0xD9, 0x55, 0xD6, 0x82, 0x4E, 0x04, 0x30, 0xD0, 0xC0, 0x01, 0x7C, 0x2A, 0xE4, 0xA3, 0xA2, 0x47, + 0xDC, 0x37, 0xE8, 0x9C, 0xE3, 0xC9, 0x64, 0x9D, 0x72, 0x70, 0x54, 0x29, 0x03, 0x04, 0xDF, 0xE5, + 0xE1, 0x4A, 0x19, 0x06, 0xB0, 0xD9, 0xC4, 0x66, 0x48, 0x7C, 0x27, 0xCD, 0x88, 0x98, 0x92, 0x89, + 0xE2, 0x75, 0x69, 0x2D, 0x69, 0xC3, 0x02, 0x07, 0xA4, 0x03, 0x8A, 0x2B, 0x8E, 0xC2, 0x04, 0x05, + 0x03, 0x48, 0x3C, 0x17, 0x5E, 0xAB, 0x7E, 0x61, 0x04, 0x20, 0x03, 0x33, 0x21, 0x01, 0xC1, 0x02, + 0xDF, 0x81, 0x52, 0x8B, 0x34, 0xAD, 0xC8, 0x6A, 0x43, 0x3E, 0x48, 0x9E, 0xF5, 0x24, 0x45, 0xAF, + 0xF2, 0x96, 0x9D, 0xFF, 0x03, 0xF5, 0x51, 0xD1, 0xA2, 0x03, 0x90, 0xCA, 0xF1, 0x94, 0x3E, 0x37, + 0x68, 0x81, 0xA4, 0x98, 0xC0, 0x9A, 0xF8, 0xC0, 0x8F, 0xCA, 0x39, 0xA0, 0xCD, 0x1F, 0x0B, 0x10, + 0x21, 0x0D, 0x03, 0xB8, 0x7D, 0x74, 0x64, 0x98, 0xD2, 0x16, 0x8A, 0x0C, 0xBA, 0xCA, 0x29, 0xF5, + 0x48, 0x8B, 0x53, 0xA1, 0x19, 0x03, 0xA8, 0x18, 0x85, 0xB2, 0x2A, 0xB9, 0x63, 0x06, 0x45, 0x06, + 0x80, 0x48, 0x05, 0xC9, 0x6E, 0x9C, 0x4F, 0xE1, 0xA3, 0xC2, 0x77, 0xF0, 0x16, 0x95, 0x4B, 0xB7, + 0xF4, 0x12, 0xEA, 0x57, 0x59, 0x14, 0xB2, 0x46, 0x08, 0xB8, 0x8E, 0x08, 0x72, 0x06, 0xB3, 0x3E, + 0xA6, 0xF2, 0x28, 0x46, 0x8B, 0x2C, 0xEB, 0xED, 0x03, 0xF3, 0x56, 0x5C, 0xF0, 0x40, 0xE6, 0xED, + 0xA6, 0x9C, 0x7C, 0xD9, 0x02, 0xA2, 0x48, 0xCA, 0x98, 0x25, 0xD6, 0xCE, 0x4E, 0x14, 0x2B, 0x18, + 0xE7, 0xC0, 0xE5, 0xAE, 0x93, 0x00, 0xC2, 0x45, 0x01, 0xB3, 0xC0, 0x8C, 0x74, 0xFA, 0xF7, 0x80, + 0x84, 0xAC, 0xAE, 0x6C, 0xCF, 0x00, 0x04, 0xA4, 0x47, 0x2C, 0x02, 0xCE, 0x6A, 0xF2, 0x06, 0x9D, + 0x98, 0xE5, 0x3C, 0xB0, 0x98, 0xB5, 0x4D, 0xD3, 0x40, 0x04, 0x05, 0x28, 0x57, 0x40, 0x04, 0x0A, + 0x50, 0x2A, 0x4B, 0x02, 0x1F, 0x53, 0xBD, 0x74, 0x54, 0x59, 0xBF, 0x1B, 0x5A, 0x41, 0xAC, 0x65, + 0xA7, 0xF0, 0x33, 0x0C, 0x58, 0x6D, 0xB6, 0x69, 0x68, 0x4F, 0x2B, 0x87, 0x55, 0xB7, 0x38, 0x50, + 0xC8, 0x5D, 0x7E, 0x8A, 0x1D, 0x0C, 0x04, 0x8F, 0xCD, 0x1D, 0x94, 0xDD, 0x4F, 0xA1, 0xEC, 0xA1, + 0x7C, 0xAD, 0x8D, 0xC5, 0x52, 0x4D, 0xBE, 0x0A, 0x3E, 0x9E, 0x55, 0x32, 0xDA, 0xA3, 0x37, 0x03, + 0xBD, 0x44, 0x3D, 0x8F, 0x55, 0x34, 0x3B, 0x6E, 0x4F, 0x03, 0x99, 0x73, 0x89, 0x93, 0xE5, 0xFE, + 0x74, 0x13, 0xB7, 0xCB, 0xE6, 0xA4, 0x4B, 0x63, 0x90, 0x65, 0xED, 0x16, 0x25, 0x77, 0xE9, 0x54, + 0x67, 0x11, 0xDB, 0x89, 0x44, 0xB3, 0x6E, 0xF6, 0x89, 0x7E, 0x37, 0x05, 0x47, 0xE7, 0xB2, 0xFB, + 0xF5, 0x2D, 0x70, 0xDD, 0x80, 0x37, 0xDE, 0x0A, 0x8E, 0xFB, 0x06, 0x1C, 0x00, 0x4D, 0xE0, 0x1E, + 0x80, 0x0C, 0x73, 0xFB, 0x47, 0x00, 0xE8, 0x2C, 0x89, 0x6E, 0xCF, 0x0C, 0x66, 0x87, 0x64, 0x55, + 0x73, 0x87, 0xB5, 0xD2, 0x39, 0xF2, 0x54, 0xA3, 0xAD, 0x24, 0xEF, 0x09, 0xC4, 0x2E, 0x47, 0x0C, + 0x83, 0x4F, 0x44, 0x6E, 0x25, 0xA9, 0x0C, 0x8F, 0x43, 0xE0, 0xD3, 0xB4, 0x30, 0x50, 0x54, 0xF9, + 0x41, 0x57, 0xC9, 0x63, 0xE6, 0x03, 0x00, 0xC1, 0xED, 0xE9, 0xAB, 0x60, 0x4F, 0x62, 0x94, 0x41, + 0x2A, 0xFE, 0x01, 0x56, 0x11, 0x10, 0xB3, 0x65, 0x4F, 0x11, 0xCC, 0x37, 0x4A, 0x10, 0x2C, 0x8E, + 0x3C, 0x80, 0x40, 0x3A, 0x30, 0x20, 0x02, 0x96, 0x10, 0x3F, 0x13, 0x64, 0xA7, 0x1E, 0x17, 0x53, + 0x90, 0x02, 0x28, 0x87, 0x00, 0xB2, 0xC1, 0xE0, 0x29, 0x08, 0x24, 0x50, 0xC9, 0xFE, 0x37, 0x3C, + 0x28, 0x30, 0x67, 0x75, 0x01, 0x9C, 0x20, 0x4E, 0x0A, 0xE0, 0xAC, 0xAF, 0x21, 0x90, 0x3E, 0x0D, + 0x4C, 0x41, 0xBB, 0x42, 0x13, 0x05, 0x63, 0xA4, 0x64, 0x81, 0x43, 0x28, 0x40, 0xED, 0x44, 0x00, + 0x01, 0x2C, 0x78, 0x29, 0x85, 0x2C, 0x38, 0x56, 0x62, 0x1A, 0xC0, 0x1D, 0x35, 0x84, 0x00, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, + 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, + 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, + 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, + 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, + 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, + 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, + 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, + 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, + 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, + 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, + 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, + 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, + 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, + 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, + 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, + 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, + 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, + 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, + 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, + 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, + 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, + 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, + 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, + 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, + 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, + 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, + 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, + 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, + 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, + 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, + 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, + 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, + 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, + 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, + 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, + 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, + 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, + 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, + 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, + 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, + 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, + 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, + 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, + 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, + 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, + 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, + 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, + 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, + 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, + 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, + 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, + 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, + 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, + 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, + 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, + 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, + 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, + 0x0D, 0x21, 0x00, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, + 0x00, 0x6A, 0x00, 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, + 0xAE, 0x6C, 0xEB, 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, + 0x0A, 0xC7, 0x03, 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, + 0xA4, 0x10, 0xA8, 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, + 0x9E, 0x18, 0x02, 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, + 0xD4, 0x81, 0x01, 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, + 0x0D, 0x08, 0x05, 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, + 0x04, 0x06, 0x10, 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, + 0x93, 0x09, 0x0C, 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, + 0x0C, 0x39, 0x9A, 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, + 0xAB, 0x5B, 0x4A, 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, + 0x0D, 0x0D, 0x07, 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, + 0x0E, 0x7B, 0x04, 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, + 0x92, 0x0C, 0x0E, 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, + 0x5B, 0x03, 0x0E, 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, + 0x98, 0xBE, 0x73, 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, + 0xB0, 0x6A, 0xA3, 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, + 0xBC, 0xA5, 0x0C, 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, + 0x04, 0x32, 0x53, 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, + 0x67, 0x8E, 0xA2, 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, + 0x33, 0xA0, 0x2B, 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, + 0x0E, 0x10, 0xC0, 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, + 0x0A, 0x08, 0xF8, 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, + 0x1D, 0x8A, 0x47, 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, + 0x22, 0x22, 0x82, 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, + 0x6B, 0x50, 0xE0, 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, + 0xA3, 0x2D, 0x60, 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, + 0x94, 0x14, 0x7F, 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, + 0x05, 0x30, 0x4A, 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, + 0x53, 0x20, 0xC1, 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, + 0x10, 0x03, 0x80, 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, + 0x26, 0x0F, 0x28, 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, + 0xC6, 0x0A, 0x02, 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, + 0xA0, 0xC0, 0x28, 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, + 0x42, 0x01, 0x5A, 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, + 0x88, 0x33, 0x14, 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, + 0x6A, 0xC4, 0x80, 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, + 0x28, 0xC2, 0xE2, 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, + 0x21, 0xA4, 0x0C, 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, + 0x4A, 0x93, 0x29, 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, + 0x94, 0x0C, 0x38, 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, + 0x56, 0x74, 0x54, 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, + 0x99, 0x83, 0x8A, 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, + 0x10, 0x02, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, + 0x6A, 0x00, 0x2E, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x00, 0x40, 0x62, 0xB9, 0x28, 0x08, 0x41, 0x28, + 0x4B, 0xE9, 0xBE, 0x70, 0x2C, 0xCF, 0x74, 0x6D, 0xDF, 0xE5, 0xF1, 0x3C, 0x69, 0x52, 0x24, 0x0F, + 0x82, 0xE1, 0x60, 0x00, 0x26, 0x5A, 0xB8, 0xA4, 0x72, 0xC9, 0x94, 0xE9, 0x22, 0x12, 0xC9, 0x64, + 0xF2, 0x18, 0x04, 0xAE, 0xD7, 0x01, 0xB0, 0xD0, 0xEC, 0x7A, 0xBF, 0x31, 0x48, 0x61, 0x12, 0x95, + 0x32, 0x02, 0x8E, 0x06, 0x36, 0x70, 0x50, 0x21, 0xC1, 0xF0, 0x78, 0x72, 0x91, 0x20, 0x4B, 0x55, + 0x85, 0xF5, 0xB5, 0x81, 0xE0, 0xCA, 0xFF, 0x80, 0x32, 0x0D, 0x0F, 0x53, 0x11, 0x11, 0x04, 0x07, + 0x7A, 0x57, 0x0E, 0x04, 0x6F, 0x81, 0x8F, 0x7F, 0x0B, 0x2A, 0x06, 0x94, 0x6A, 0x8A, 0x01, 0x06, + 0x04, 0x05, 0x07, 0x0B, 0x0B, 0x44, 0x94, 0xA0, 0x43, 0x24, 0x90, 0xA4, 0x37, 0x05, 0x04, 0x96, + 0x97, 0x58, 0x45, 0x09, 0x0A, 0x0C, 0x0C, 0x0A, 0x05, 0x0D, 0xB3, 0x05, 0x0A, 0x09, 0x0C, 0x05, + 0x06, 0xA3, 0x4D, 0x9F, 0xA0, 0x0B, 0xBB, 0xA5, 0x33, 0x6D, 0x08, 0x0C, 0x89, 0xAA, 0xC7, 0x8A, + 0x07, 0xAE, 0x3E, 0xC0, 0x32, 0x10, 0x07, 0x3F, 0x2A, 0x0E, 0x8C, 0x2A, 0x08, 0xD6, 0x29, 0x0E, + 0xB9, 0xCD, 0xC1, 0x22, 0x10, 0x45, 0xD2, 0xB8, 0x07, 0x56, 0x97, 0x22, 0xC8, 0x01, 0x0D, 0x0C, + 0x3E, 0x9C, 0x25, 0xCF, 0xA7, 0x04, 0xD9, 0xE2, 0xC8, 0x03, 0xD0, 0x09, 0x04, 0xD6, 0x09, 0xBA, + 0xDC, 0x30, 0x10, 0x0B, 0x06, 0xB6, 0x2A, 0x04, 0x12, 0xDC, 0x52, 0x40, 0x90, 0x60, 0x81, 0x5C, + 0x07, 0x20, 0xA8, 0x1A, 0xD0, 0x20, 0x01, 0x35, 0x07, 0x3C, 0x1C, 0x18, 0x30, 0x87, 0xCC, 0x00, + 0x03, 0x02, 0x0F, 0x12, 0x34, 0xD8, 0xA6, 0xCF, 0x44, 0xA7, 0x8F, 0x9D, 0x0E, 0x88, 0xAC, 0x75, + 0x6B, 0x22, 0xC5, 0x4B, 0x44, 0x4E, 0xFF, 0x26, 0x63, 0x80, 0x20, 0xE3, 0x81, 0x8E, 0x5D, 0x0E, + 0xA4, 0x33, 0xA6, 0x92, 0x8D, 0x03, 0x04, 0x35, 0x2F, 0x35, 0xC0, 0x98, 0xE0, 0x25, 0x4C, 0x26, + 0x07, 0x7C, 0xE4, 0xBC, 0x82, 0x40, 0xE1, 0x50, 0x3D, 0xCA, 0x52, 0x38, 0xFA, 0x89, 0xE3, 0x47, + 0xCE, 0x1F, 0x00, 0x8E, 0xAA, 0x02, 0xC2, 0x80, 0xE9, 0x92, 0x86, 0x2A, 0x0D, 0x3C, 0xA0, 0x29, + 0x55, 0xD1, 0x00, 0x8C, 0x06, 0xAC, 0x26, 0x31, 0x80, 0xC0, 0x24, 0x32, 0x04, 0x09, 0xBA, 0x9A, + 0x1B, 0x94, 0x80, 0xA3, 0x58, 0x18, 0x5A, 0xCF, 0x1C, 0x13, 0x78, 0x69, 0x9C, 0xDA, 0x2C, 0x04, + 0x22, 0x34, 0x78, 0x6B, 0x03, 0x82, 0x02, 0x44, 0x97, 0x5E, 0xD5, 0x1D, 0x60, 0xF7, 0xEE, 0xB9, + 0x07, 0x61, 0xF9, 0xD6, 0x58, 0xC0, 0x20, 0xDB, 0x1A, 0x82, 0x0B, 0x09, 0x17, 0xBE, 0xFB, 0x55, + 0x81, 0xE2, 0x1B, 0x99, 0x10, 0x39, 0xF6, 0x2A, 0x99, 0xB0, 0x61, 0x3D, 0x0E, 0x2F, 0xDF, 0x18, + 0x94, 0x87, 0xF3, 0x00, 0x01, 0x02, 0x24, 0x7F, 0x7E, 0x8C, 0x60, 0xA9, 0x68, 0x17, 0x6D, 0xCC, + 0x62, 0x91, 0x8C, 0x1A, 0x75, 0xE7, 0x2B, 0x30, 0xBA, 0xF2, 0xF1, 0xF9, 0xDA, 0x45, 0x26, 0xAE, + 0x59, 0x4E, 0xD7, 0x4E, 0xED, 0x19, 0xF7, 0x8C, 0xA3, 0x5A, 0xF7, 0xF6, 0x16, 0xF1, 0xC3, 0x68, + 0x70, 0xE1, 0xC3, 0x8B, 0xAF, 0xA1, 0x31, 0xF4, 0xB4, 0xD2, 0xD7, 0x10, 0x60, 0xE9, 0x21, 0x3C, + 0x3C, 0xFA, 0x64, 0xE3, 0x32, 0x6A, 0xD2, 0x56, 0xF0, 0xC0, 0x0F, 0x5F, 0x3A, 0xA9, 0x02, 0x70, + 0xEF, 0x4E, 0x5C, 0x3A, 0x68, 0xD7, 0xE5, 0x54, 0x72, 0xB7, 0xF2, 0xD5, 0xBC, 0xD5, 0xA0, 0x34, + 0xD7, 0xDB, 0x6E, 0xAF, 0x5A, 0x95, 0x03, 0xDE, 0x2F, 0x98, 0x73, 0xDB, 0x70, 0x01, 0xC4, 0xF2, + 0x96, 0x45, 0xB3, 0x41, 0x67, 0x5B, 0xFF, 0x7F, 0xE6, 0x00, 0x20, 0x51, 0x0C, 0xF2, 0xD0, 0x47, + 0x9C, 0x7A, 0xEA, 0x91, 0x07, 0x20, 0x4C, 0x05, 0xC8, 0xA5, 0x9E, 0x70, 0xA7, 0x31, 0x78, 0x92, + 0x24, 0x89, 0xB9, 0x70, 0x4C, 0x26, 0x41, 0x04, 0xA4, 0x40, 0x03, 0x19, 0x32, 0x72, 0xC8, 0x85, + 0x1D, 0xB9, 0x92, 0x20, 0x7F, 0xEE, 0x9D, 0x94, 0xE1, 0x49, 0x0C, 0xDD, 0x84, 0x16, 0x79, 0x11, + 0xF4, 0x11, 0x0B, 0x42, 0x62, 0x41, 0x70, 0xCB, 0x73, 0x1E, 0x0E, 0xE5, 0x20, 0x70, 0x7B, 0x10, + 0x40, 0x58, 0x5E, 0xC4, 0xE4, 0x23, 0x42, 0x02, 0x86, 0x34, 0xA2, 0x98, 0x24, 0x0A, 0x00, 0x19, + 0x63, 0x4E, 0xFD, 0x10, 0x43, 0x93, 0x32, 0x79, 0xF1, 0x90, 0x42, 0x88, 0x2E, 0x2C, 0xF0, 0x80, + 0x21, 0x0F, 0x30, 0x00, 0x5F, 0x30, 0x62, 0xF4, 0xB1, 0x61, 0x90, 0x47, 0x39, 0x18, 0xCB, 0x3F, + 0xEF, 0xF8, 0x60, 0xC0, 0x2F, 0x36, 0x3C, 0xB1, 0x22, 0x53, 0x99, 0x20, 0x90, 0x08, 0x9A, 0x5D, + 0x79, 0xD9, 0x80, 0x00, 0x29, 0xB4, 0xD6, 0x04, 0x59, 0x2C, 0xFC, 0x24, 0x13, 0x2A, 0x78, 0x76, + 0xF5, 0x95, 0x03, 0x0C, 0xA0, 0xA6, 0xA3, 0x17, 0x6E, 0x3D, 0xB2, 0xC0, 0x0F, 0x0A, 0x10, 0xB9, + 0xDA, 0x39, 0x08, 0x08, 0x90, 0x86, 0x00, 0x4E, 0x2E, 0x17, 0x86, 0x3B, 0xA5, 0x4D, 0xAA, 0x87, + 0x42, 0xAF, 0x0C, 0xE2, 0x00, 0xA6, 0x63, 0x8A, 0xF6, 0xA8, 0x0A, 0x91, 0x06, 0xF0, 0x4B, 0x9E, + 0xCE, 0x29, 0xF2, 0x17, 0x4B, 0x96, 0x16, 0x50, 0xA9, 0x9F, 0x9A, 0x02, 0x50, 0x00, 0x23, 0x81, + 0x9E, 0x1A, 0x41, 0x94, 0x47, 0x31, 0x10, 0xE6, 0x01, 0xD3, 0x98, 0xA5, 0x10, 0x2A, 0x2D, 0xF1, + 0x21, 0x46, 0x40, 0xB5, 0xDA, 0x8A, 0xD8, 0x02, 0x0D, 0x21, 0x9A, 0x80, 0x99, 0x98, 0xE0, 0x63, + 0xCE, 0x10, 0x01, 0xC8, 0x7A, 0xC2, 0x79, 0x11, 0x50, 0x65, 0x26, 0x2B, 0x9F, 0x64, 0xF9, 0xD1, + 0xE8, 0x93, 0x29, 0x32, 0x30, 0x84, 0x03, 0x0A, 0x28, 0x04, 0x2C, 0x46, 0x0B, 0x5C, 0x91, 0xAE, + 0x22, 0x64, 0x21, 0xB0, 0x13, 0x30, 0x99, 0xDC, 0xB4, 0xD3, 0xB3, 0xE9, 0x00, 0x50, 0x6A, 0xB2, + 0x00, 0xB4, 0xD1, 0x42, 0x50, 0x42, 0x00, 0xF6, 0x55, 0x51, 0xAA, 0x6A, 0x82, 0x09, 0x22, 0x08, + 0x38, 0xB0, 0x4D, 0xB7, 0x88, 0x2C, 0x60, 0x0D, 0x8B, 0xF8, 0xBE, 0x90, 0x89, 0x02, 0x0E, 0xE0, + 0x03, 0x81, 0xC0, 0x99, 0xDC, 0xAA, 0x2A, 0x44, 0xB3, 0xF8, 0xE9, 0x16, 0x04, 0x08, 0xD8, 0xC2, + 0x1C, 0x97, 0x0D, 0xCB, 0xE0, 0xC9, 0x28, 0x3A, 0x28, 0xF3, 0x5F, 0x6B, 0xBF, 0xD9, 0x72, 0xC4, + 0x62, 0x1D, 0x7F, 0x1B, 0x72, 0x0D, 0xCA, 0xBC, 0xD4, 0x86, 0x2D, 0x3E, 0xB9, 0xBC, 0x5C, 0x08, + 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, 0x6A, 0x00, + 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, 0xAE, 0x6C, 0xEB, + 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, 0x0A, 0xC7, 0x03, + 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, 0xA4, 0x10, 0xA8, + 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, 0x9E, 0x18, 0x02, + 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, 0xD4, 0x81, 0x01, + 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, 0x0D, 0x08, 0x05, + 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, 0x04, 0x06, 0x10, + 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, 0x93, 0x09, 0x0C, + 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, 0x0C, 0x39, 0x9A, + 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, 0xAB, 0x5B, 0x4A, + 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, 0x0D, 0x0D, 0x07, + 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, 0x0E, 0x7B, 0x04, + 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, 0x92, 0x0C, 0x0E, + 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, 0x5B, 0x03, 0x0E, + 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, 0x98, 0xBE, 0x73, + 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, 0xB0, 0x6A, 0xA3, + 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, 0xBC, 0xA5, 0x0C, + 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, 0x04, 0x32, 0x53, + 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, 0x67, 0x8E, 0xA2, + 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, 0x33, 0xA0, 0x2B, + 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, 0x0E, 0x10, 0xC0, + 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, 0x0A, 0x08, 0xF8, + 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, 0x1D, 0x8A, 0x47, + 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, 0x22, 0x22, 0x82, + 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, 0x6B, 0x50, 0xE0, + 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, 0xA3, 0x2D, 0x60, + 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, 0x94, 0x14, 0x7F, + 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, 0x05, 0x30, 0x4A, + 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, 0x53, 0x20, 0xC1, + 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, 0x10, 0x03, 0x80, + 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, 0x26, 0x0F, 0x28, + 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, 0xC6, 0x0A, 0x02, + 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, 0xA0, 0xC0, 0x28, + 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, 0x42, 0x01, 0x5A, + 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, 0x88, 0x33, 0x14, + 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, 0x6A, 0xC4, 0x80, + 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, 0x28, 0xC2, 0xE2, + 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, 0x21, 0xA4, 0x0C, + 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, 0x4A, 0x93, 0x29, + 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, 0x94, 0x0C, 0x38, + 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, 0x56, 0x74, 0x54, + 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, 0x99, 0x83, 0x8A, + 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, 0x10, 0x02, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, + 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, + 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, + 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, + 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, + 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, + 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, + 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, + 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, + 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, + 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, + 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, + 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, + 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, + 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, + 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, + 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, + 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, + 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, + 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, + 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, + 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, + 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, + 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, + 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, + 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, + 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, + 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, + 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, + 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, + 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, + 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, + 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, + 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, + 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, + 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, + 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, + 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, + 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, + 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, + 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, + 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, + 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, + 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, + 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, + 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, + 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, + 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, + 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, + 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, + 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, + 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, + 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, + 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, + 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, + 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, + 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, + 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, + 0x0D, 0x21, 0x00, 0x00, 0x3B}; diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Reuse_Session/Send_Reuse_Session.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Reuse_Session/Send_Reuse_Session.ino new file mode 100644 index 000000000000..ed7d61396305 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Reuse_Session/Send_Reuse_Session.ino @@ -0,0 +1,242 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example show how to login once for sending multiple messages. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +Session_Config config; + +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +#include "HeapStat.h" +HeapStat heapInfo; + +unsigned long sentMillis = 0; + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + smtp.debug(1); + + smtp.callback(smtpCallback); + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; +} + +void loop() +{ + if (millis() - sentMillis > 3 * 60 * 1000 || sentMillis == 0) + { + sentMillis = millis(); + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Send Email with session reusage"); + message.addRecipient(F("user"), RECIPIENT_EMAIL); + + message.html.content = F("

This is the HTML message.

"); + message.text.content = F("This is the text message"); + + Serial.println(); + Serial.println("Sending Email..."); + + if (!smtp.isLoggedIn()) + { + /* Set the TCP response read timeout in seconds */ + // smtp.setTCPTimeout(10); + + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + goto exit; + } + + if (!smtp.isLoggedIn()) + { + Serial.println("\nError, Not yet logged in."); + goto exit; + } + else + { + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + } + + if (!MailClient.sendMail(&smtp, &message, false)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + exit: + + heapInfo.collect(); + heapInfo.print(); + } +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + + Serial.println(status.info()); + + if (status.success()) + { + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + smtp.sendingResult.clear(); + } +} \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text _Silent_Mode/Send_Text_Silent_Mode.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text _Silent_Mode/Send_Text_Silent_Mode.ino new file mode 100644 index 000000000000..2fa30a75301f --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text _Silent_Mode/Send_Text_Silent_Mode.ino @@ -0,0 +1,197 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example showes how to send text message without callback and debug. + +/** + * To use library in silent mode (no debug printing and callback), please define this macro in src/ESP_Mail_FS.h. + * #define SILENT_MODE + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define SMTP_HOST "" + +#define SMTP_PORT esp_mail_smtp_port_587 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +void printSmtpData(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + String textMsg = "This is simple plain text message"; + message.text.content = textMsg; + + message.text.charSet = F("us-ascii"); + + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + message.addHeader(F("Message-ID: ")); + + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (!smtp.isLoggedIn()) + { + Serial.println("Not yet logged in."); + } + else + { + if (smtp.isAuthenticated()) + Serial.println("Successfully logged in."); + else + Serial.println("Connected with no Auth."); + } + + if (MailClient.sendMail(&smtp, &message)) + { + printSmtpData(smtp.status()); + } + else + { + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + } + + smtp.sendingResult.clear(); +} + +void loop() +{ +} + +void printSmtpData(SMTP_Status status) +{ + + if (status.success()) + { + + Serial.println("\n----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text/Send_Text.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text/Send_Text.ino new file mode 100644 index 000000000000..ea9beee086c3 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text/Send_Text.ino @@ -0,0 +1,396 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example showes how to send text message. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 // port 465 is not available for Outlook.com + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +// const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" +// "-----END CERTIFICATE-----\n"; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /** If non-secure port is prefered (not allow SSL and TLS connection), use + * config.secure.mode = esp_mail_secure_mode_nonsecure; + * + * If SSL and TLS are always required, use + * config.secure.mode = esp_mail_secure_mode_ssl_tls; + * + * To disable SSL permanently (use less program space), define ESP_MAIL_DISABLE_SSL in ESP_Mail_FS.h + * or Custom_ESP_Mail_FS.h + */ + // config.secure.mode = esp_mail_secure_mode_nonsecure; + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* The full message sending logs can now save to file */ + /* Since v3.0.4, the sent logs stored in smtp.sendingResult will store only the latest message logs */ + // config.sentLogs.filename = "/path/to/log/file"; + // config.sentLogs.storage_type = esp_mail_file_storage_type_flash; + + /** In ESP32, timezone environment will not keep after wake up boot from sleep. + * The local time will equal to GMT time. + * + * To sync or set time with NTP server with the valid local time after wake up boot, + * set both gmt and day light offsets to 0 and assign the timezone environment string e.g. + + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 0; + config.time.day_light_offset = 0; + config.time.timezone_env_string = "JST-9"; // for Tokyo + + * The library will get (sync) the time from NTP server without GMT time offset adjustment + * and set the timezone environment variable later. + * + * This timezone environment string will be stored to flash or SD file named "/tze.txt" + * which set via config.time.timezone_file. + * + * See the timezone environment string list from + * https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv + * + */ + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + /** If author and sender are not identical + message.sender.name = F("Sender"); + message.sender.email = "sender@mail.com"; + message.author.name = F("ESP Mail"); + message.author.email = AUTHOR_EMAIL; // should be the same email as config.login.email + */ + + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + String textMsg = "This is simple plain text message"; + message.text.content = textMsg; + + /** If the message to send is a large string, to reduce the memory used from internal copying while sending, + * you can assign string to message.text.blob by cast your string to uint8_t array like this + * + * String myBigString = "..... ......"; + * message.text.blob.data = (uint8_t *)myBigString.c_str(); + * message.text.blob.size = myBigString.length(); + * + * or assign string to message.text.nonCopyContent, like this + * + * message.text.nonCopyContent = myBigString.c_str(); + * + * Only base64 encoding is supported for content transfer encoding in this case. + */ + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + // If this is a reply message + // message.in_reply_to = ""; + // message.references = " "; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + // message.response.reply_to = "someone@somemail.com"; + // message.response.return_path = "someone@somemail.com"; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + // For Root CA certificate verification (ESP8266 and ESP32 only) + // config.certificate.cert_data = rootCACert; + // or + // config.certificate.cert_file = "/path/to/der/file"; + // config.certificate.cert_file_storage_type = esp_mail_file_storage_type_flash; // esp_mail_file_storage_type_sd + // config.certificate.verify = true; + + // The WiFiNINA firmware the Root CA certification can be added via the option in Firmware update tool in Arduino IDE + + /* Connect to server with the session config */ + + // Library will be trying to sync the time with NTP server if time is never sync or set. + // This is 10 seconds blocking process. + // If time reading was timed out, the error "NTP server time reading timed out" will show via debug and callback function. + // You can manually sync time by yourself with NTP library or calling configTime in ESP32 and ESP8266. + // Time can be set manually with provided timestamp to function smtp.setSystemTime. + + /* Set the TCP response read timeout in seconds */ + // smtp.setTCPTimeout(10); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + /** Or connect without log in and log in later + + if (!smtp.connect(&config, false)) + return; + + if (!smtp.loginWithPassword(AUTHOR_EMAIL, AUTHOR_PASSWORD)) + return; + */ + + if (!smtp.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text_Flowed/Send_Text_Flowed.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text_Flowed/Send_Text_Flowed.ino new file mode 100644 index 000000000000..badb2b5a6223 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text_Flowed/Send_Text_Flowed.ino @@ -0,0 +1,308 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send text message with text wrapping. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + /** The option to add soft line break to to the message for + * the long text message > 78 characters (rfc 3676) + * Some Servers may not compliant with this standard. + */ + message.text.flowed = true; + + /** if the option message.text.flowed is true, + * the following plain text message will be wrapped. + */ + message.text.content = F("The text below is the long quoted text which breaks into several lines.\r\n\r\n>> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\r\n\r\nThis is the normal short text.\r\n\r\nAnother long text, abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz."); + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (!smtp.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Set_Time/Set_Time.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Set_Time/Set_Time.ino new file mode 100644 index 000000000000..fcf96414f4c7 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Set_Time/Set_Time.ino @@ -0,0 +1,253 @@ + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example showes how to set the library and/or device time manually. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#include "RTC.h" +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define SMTP_HOST "" +#define SMTP_PORT esp_mail_smtp_port_587 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + Serial.print("Waiting for NTP server time reading"); + +#if defined(ESP8266) || defined(ESP32) && !defined(ARDUINO_NANO_RP2040_CONNECT) + + configTime(0, 0, "pool.ntp.org", "time.nist.gov"); + while (time(nullptr) < ESP_MAIL_CLIENT_VALID_TS) + { + delay(100); + } + +#elif defined(ARDUINO_RASPBERRY_PI_PICO_W) + + configTime(10000, 0, "pool.ntp.org", "time.nist.gov"); + while (time(nullptr) < ESP_MAIL_CLIENT_VALID_TS) + { + delay(100); + } + +#elif __has_include() || __has_include() + time_t ts = 0; + do + { + ts = WiFi.getTime(); + delay(100); + } while (ts < ESP_MAIL_CLIENT_VALID_TS); + + float gmtOffset = 3.0; // GMT offset in hour + + smtp.setSystemTime(ts, gmtOffset); + +#elif __has_include() + + // see https://docs.arduino.cc/tutorials/uno-r4-wifi/rtc + + RTC.begin(); + + // RTCTime startTime(30, Month::JUNE, 2023, 13, 37, 00, DayOfWeek::WEDNESDAY, SaveLight::SAVING_TIME_ACTIVE); + // RTC.setTime(startTime); + + RTCTime currentTime; + + // Get current time from RTC + RTC.getTime(currentTime); + + float gmtOffset = 3.0; // GMT offset in hour + smtp.setSystemTime(currentTime.getUnixTime(), gmtOffset); + +#endif + + // To disable library internal NTP time reading, please comment or remove the following macro defined in src/ESP_Mail_FS.h + // #define ENABLE_NTP_TIME + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + smtp.debug(1); + + smtp.callback(smtpCallback); + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + config.login.user_domain = F("127.0.0.1"); + + /** + * Once the system time (using smtp.setSystemTime) or device time was set before calling smtp.connect, the following config will + * not take effect when NTP time is enabled. + * + * config.time.ntp_server + * config.time.gmt_offset + * config.time.day_light_offset + * + * To reset the reference time and use config.time instead, call smtp.setSystemTime(0) whenever you want. + */ + + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + /* The time format of timestamp to inject into subject or content as using in strftime C++ function */ + message.timestamp.tag = "#esp_mail_current_time"; + + /* The tag that will be replaced with current timestamp */ + message.timestamp.format = "%B %d, %Y %H:%M:%S"; + + message.subject = F("Test sending plain text Email (#esp_mail_current_time)"); + + message.text.content = "This is simple plain text message\n\nSent #esp_mail_current_time"; + + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (!smtp.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); +} + +void loop() +{ +} + +void smtpCallback(SMTP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Sleep/Sleep.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Sleep/Sleep.ino new file mode 100644 index 000000000000..2902423aaa6d --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Sleep/Sleep.ino @@ -0,0 +1,310 @@ +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example showes how the device time was resume after device woke up from sleep. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) +#include +#else + +// Other Client defined here +// To use custom Client, define ENABLE_CUSTOM_CLIENT in src/ESP_Mail_FS.h. +// See the example Custom_Client.ino for how to use. + +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, to send Email via port 465 (SSL), less secure app option + * should be enabled in the account settings. https://myaccount.google.com/lesssecureapps?pli=1 + * + * Some Gmail user still not able to sign in using account password even above option was set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 // port 465 is not available for Outlook.com + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "-----END CERTIFICATE-----\n"; + +void sendEmail() +{ + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 0; + config.time.day_light_offset = 0; + config.time.timezone_env_string = "JST-9"; // for Tokyo + + // See the timezone environment string list from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); // This witll be used with 'MAIL FROM' command and 'From' header field. + message.sender.email = AUTHOR_EMAIL; // This witll be used with 'From' header field. + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); // This will be used with RCPT TO command and 'To' header field. + + String textMsg = "This is simple plain text message"; + message.text.content = textMsg; + + /** If the message to send is a large string, to reduce the memory used from internal copying while sending, + * you can assign string to message.text.blob by cast your string to uint8_t array like this + * + * String myBigString = "..... ......"; + * message.text.blob.data = (uint8_t *)myBigString.c_str(); + * message.text.blob.size = myBigString.length(); + * + * or assign string to message.text.nonCopyContent, like this + * + * message.text.nonCopyContent = myBigString.c_str(); + * + * Only base64 encoding is supported for content transfer encoding in this case. + */ + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + // If this is a reply message + // message.in_reply_to = ""; + // message.references = " "; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + // message.response.reply_to = "someone@somemail.com"; + // message.response.return_path = "someone@somemail.com"; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + // For Root CA certificate verification (ESP8266 and ESP32 only) + // config.certificate.cert_data = rootCACert; + // or + // config.certificate.cert_file = "/path/to/der/file"; + // config.certificate.cert_file_storage_type = esp_mail_file_storage_type_flash; // esp_mail_file_storage_type_sd + // config.certificate.verify = true; + + // The WiFiNINA firmware the Root CA certification can be added via the option in Firmware update tool in Arduino IDE + + /* Connect to server with the session config */ + + // Library will be trying to sync the time with NTP server if time is never sync or set. + // This is 10 seconds blocking process. + // If time reading was timed out, the error "NTP server time reading timed out" will show via debug and callback function. + // You can manually sync time by yourself with NTP library or calling configTime in ESP32 and ESP8266. + // Time can be set manually with provided timestamp to function smtp.setSystemTime. + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + + Serial.print("Connecting to AP"); + + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(200); + } + + Serial.println(""); + Serial.println("WiFi connected."); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + sendEmail(); + + // Sleep for 60 seconds + + Serial.println("Going to sleep for 60 seconds..."); + +#if defined(ESP32) + + esp_sleep_enable_timer_wakeup(60 * 1000000); + + esp_deep_sleep_start(); + +#endif +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. AVR, SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + struct tm dt; + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/lib_mail/keywords.txt b/lib/libesp32/ESP-Mail-Client/keywords.txt similarity index 62% rename from lib/libesp32/lib_mail/keywords.txt rename to lib/libesp32/ESP-Mail-Client/keywords.txt index 8e669d92c3eb..86c058045274 100644 --- a/lib/libesp32/lib_mail/keywords.txt +++ b/lib/libesp32/ESP-Mail-Client/keywords.txt @@ -1,127 +1,194 @@ -###################################### -# Syntax Coloring Map ESP Mail Client -###################################### - -####################################### -# Classes and Structured Type (KEYWORD1) -####################################### - -MailClient KEYWORD1 -IMAPSession KEYWORD1 -SMTPSession KEYWORD1 -SMTP_Message KEYWORD1 -IMAP_Config KEYWORD1 -FoldersCollection KEYWORD1 -imapStatusCallback KEYWORD1 -IMAP_MSG_List KEYWORD1 -SelectedFolderInfo KEYWORD1 -ESP_Mail_Session KEYWORD1 -smtpStatusCallback KEYWORD1 -SMTP_Attachment KEYWORD1 -SMTP_Result KEYWORD1 -IMAP_MSG_Item KEYWORD1 -Content_Transfer_Encoding KEYWORD1 -MessageList KEYWORD1 - -############################################### -# Methods and Functions (KEYWORD2) -############################################### - -sendMail KEYWORD2 -readMail KEYWORD2 -setFlag KEYWORD2 -addFlag KEYWORD2 -removeFlag KEYWORD2 -sdBegin KEYWORD2 -sdMMCBegin KEYWORD2 -connect KEYWORD2 -closeSession KEYWORD2 -debug KEYWORD2 -getFolders KEYWORD2 -selectFolder KEYWORD2 -openFolder KEYWORD2 -closeFolder KEYWORD2 -callback KEYWORD2 -headerOnly KEYWORD2 -data KEYWORD2 -selectedFolder KEYWORD2 -errorReason KEYWORD2 -empty KEYWORD2 -resetAttachItem KEYWORD2 -clear KEYWORD2 -clearInlineimages KEYWORD2 -clearAttachments KEYWORD2 -clearRFC822Messages KEYWORD2 -clearRecipients KEYWORD2 -clearCc KEYWORD2 -clearBcc KEYWORD2 -clearHeader KEYWORD2 -addAttachment KEYWORD2 -addParallelAttachment KEYWORD2 -addInlineImage KEYWORD2 -addMessage KEYWORD2 -addRecipient KEYWORD2 -addCc KEYWORD2 -addBcc KEYWORD2 -addHeader KEYWORD2 -info KEYWORD2 -successs KEYWORD2 -completedCount KEYWORD2 -failedCount KEYWORD2 -getItem KEYWORD2 -size KEYWORD2 -flagCount KEYWORD2 -msgCount KEYWORD2 -nextUID KEYWORD2 -searchCount KEYWORD2 -availableMessages KEYWORD2 -flag KEYWORD2 -setClock KEYWORD2 -getUnixTime KEYWORD2 -getTimestamp KEYWORD2 -getYear KEYWORD2 -getMonth KEYWORD2 -getDay KEYWORD2 -getDayOfWeek KEYWORD2 -getDayOfWeekString KEYWORD2 -getHour KEYWORD2 -getMin KEYWORD2 -getSecond KEYWORD2 -getNumberOfDayThisYear KEYWORD2 -getTotalDays KEYWORD2 -dayofWeek KEYWORD2 -getCurrentSecond KEYWORD2 -getCurrentTimestamp KEYWORD2 -getTimeFromSec KEYWORD2 -getDateTimeString KEYWORD2 -copyMessages KEYWORD2 -deleteMessages KEYWORD2 -createFolder KEYWORD2 -deleteFolder KEYWORD2 - - -####################################### -# Struct (KEYWORD3) -####################################### - -esp_mail_email_info_t KEYWORD3 -esp_mail_plain_body_t KEYWORD3 -esp_mail_html_body_t KEYWORD3 -esp_mail_smtp_msg_response_t KEYWORD3 -esp_mail_smtp_enable_option_t KEYWORD3 -esp_mail_email_info_t KEYWORD3 -esp_mail_folder_info_item_t KEYWORD3 -esp_mail_sesson_sever_config_t KEYWORD3 -esp_mail_sesson_login_config_t KEYWORD3 -esp_mail_sesson_secure_config_t KEYWORD3 -esp_mail_sesson_cert_config_t KEYWORD3 -esp_mail_imap_fetch_config_t KEYWORD3 -esp_mail_imap_search_config_t KEYWORD3 -esp_mail_imap_limit_config_t KEYWORD3 -esp_mail_imap_enable_config_t KEYWORD3 -esp_mail_imap_download_config_t KEYWORD3 -esp_mail_imap_storage_config_t KEYWORD3 - -esp_mail_file_storage_type_none KEYWORD3 -esp_mail_file_storage_type_flash KEYWORD3 -esp_mail_file_storage_type_sd KEYWORD3 \ No newline at end of file +###################################### +# Syntax Coloring Map ESP Mail Client +###################################### + +####################################### +# Classes and Structured Type (KEYWORD1) +####################################### + +MailClient KEYWORD1 +IMAPSession KEYWORD1 +SMTPSession KEYWORD1 +SMTP_Message KEYWORD1 +IMAP_Config KEYWORD1 +IMAP_Data KEYWORD2 +FoldersCollection KEYWORD1 +imapStatusCallback KEYWORD1 +IMAP_MSG_List KEYWORD1 +SelectedFolderInfo KEYWORD1 +ESP_Mail_Session KEYWORD1 +Session_Config KEYWORD1 +smtpStatusCallback KEYWORD1 +imapResponseCallback KEYWORD1 +SMTP_Attachment KEYWORD1 +SMTP_Result KEYWORD1 +IMAP_MSG_Item KEYWORD1 +Content_Transfer_Encoding KEYWORD1 +MessageList KEYWORD1 + +############################################### +# Methods and Functions (KEYWORD2) +############################################### + +sendMail KEYWORD2 +appendMessage KEYWORD2 +readMail KEYWORD2 +setFlag KEYWORD2 +addFlag KEYWORD2 +removeFlag KEYWORD2 +networkReconnect KEYWORD2 +sdBegin KEYWORD2 +sdMMCBegin KEYWORD2 +getFreeHeap KEYWORD2 +connect KEYWORD2 +loginWithPassword KEYWORD2 +loginWithAccessToken KEYWORD2 +isAuthenticated KEYWORD2 +isLoggedIn KEYWORD2 +connected KEYWORD2 +keepAlive KEYWORD2 +isKeepAlive KEYWORD2 +customConnect KEYWORD2 +closeSession KEYWORD2 +debug KEYWORD2 +getFolders KEYWORD2 +selectFolder KEYWORD2 +openFolder KEYWORD2 +closeFolder KEYWORD2 +callback KEYWORD2 +headerOnly KEYWORD2 +data KEYWORD2 +selectedFolder KEYWORD2 +errorReason KEYWORD2 +statusCode KEYWORD2 +statusMessage KEYWORD2 +errorCode KEYWORD2 +empty KEYWORD2 +resetAttachItem KEYWORD2 +clear KEYWORD2 +clearInlineimages KEYWORD2 +clearAttachments KEYWORD2 +clearRFC822Messages KEYWORD2 +clearRecipients KEYWORD2 +clearCc KEYWORD2 +clearBcc KEYWORD2 +clearHeader KEYWORD2 +addAttachment KEYWORD2 +addParallelAttachment KEYWORD2 +addInlineImage KEYWORD2 +addMessage KEYWORD2 +addRecipient KEYWORD2 +addCc KEYWORD2 +addBcc KEYWORD2 +addHeader KEYWORD2 +info KEYWORD2 +successs KEYWORD2 +completedCount KEYWORD2 +failedCount KEYWORD2 +getItem KEYWORD2 +size KEYWORD2 +flagCount KEYWORD2 +msgCount KEYWORD2 +recentCount KEYWORD2 +nextUID KEYWORD2 +pollingStatus KEYWORD2 +searchCount KEYWORD2 +availableMessages KEYWORD2 +flag KEYWORD2 +setClock KEYWORD2 +getUnixTime KEYWORD2 +getTimestamp KEYWORD2 +getYear KEYWORD2 +getMonth KEYWORD2 +getDay KEYWORD2 +getDayOfWeek KEYWORD2 +getDayOfWeekString KEYWORD2 +getHour KEYWORD2 +getMin KEYWORD2 +getSecond KEYWORD2 +getNumberOfDayThisYear KEYWORD2 +getTotalDays KEYWORD2 +dayofWeek KEYWORD2 +getCurrentSecond KEYWORD2 +getCurrentTimestamp KEYWORD2 +getTimeFromSec KEYWORD2 +getDateTimeString KEYWORD2 +copyMessages KEYWORD2 +moveMessages KEYWORD2 +deleteMessages KEYWORD2 +getQuota KEYWORD2 +setQuota KEYWORD2 +getQuotaRoot KEYWORD2 +getACL KEYWORD2 +setACL KEYWORD2 +deleteACL KEYWORD2 +myRights KEYWORD2 +enable KEYWORD2 +getNamespace KEYWORD2 +createFolder KEYWORD2 +renameFolder KEYWORD2 +getSubscribesMailboxes KEYWORD2 +subscribe KEYWORD2 +unSubscribe KEYWORD2 +deleteFolder KEYWORD2 +listen KEYWORD2 +stopListen KEYWORD2 +folderChanged KEYWORD2 +sendCustomCommand KEYWORD2 +sendCustomData KEYWORD2 +toBase64 KEYWORD2 +getFlags KEYWORD2 +getUID KEYWORD2 +setTCPTimeout KEYWORD2 +setClient KEYWORD2 +setGSMClient KEYWORD2 +connectionRequestCallback KEYWORD2 +connectionUpgradeRequestCallback KEYWORD2 +networkConnectionRequestCallback KEYWORD2 +networkDisconnectionRequestCallback KEYWORD2 +networkStatusRequestCallback KEYWORD2 +setSystemTime KEYWORD2 +mimeDataStreamCallback KEYWORD2 +characterDecodingCallback KEYWORD2 +clearAP KEYWORD2 +addAP KEYWORD2 +isFirmwareUpdated KEYWORD2 +id KEYWORD2 +serverID KEYWORD2 +fileList KEYWORD2 +status KEYWORD2 + +####################################### +# Struct (KEYWORD3) +####################################### + +esp_mail_email_info_t KEYWORD3 +esp_mail_plain_body_t KEYWORD3 +esp_mail_html_body_t KEYWORD3 +esp_mail_smtp_msg_response_t KEYWORD3 +esp_mail_smtp_enable_option_t KEYWORD3 +esp_mail_email_info_t KEYWORD3 +esp_mail_folder_info_item_t KEYWORD3 +esp_mail_sesson_sever_config_t KEYWORD3 +esp_mail_sesson_login_config_t KEYWORD3 +esp_mail_sesson_secure_config_t KEYWORD3 +esp_mail_sesson_cert_config_t KEYWORD3 +esp_mail_imap_fetch_config_t KEYWORD3 +esp_mail_imap_search_config_t KEYWORD3 +esp_mail_imap_limit_config_t KEYWORD3 +esp_mail_imap_enable_config_t KEYWORD3 +esp_mail_imap_download_config_t KEYWORD3 +esp_mail_imap_storage_config_t KEYWORD3 +esp_mail_imap_polling_status_t KEYWORD3 +IMAP_Polling_Status KEYWORD3 +IMAP_Identification KEYWORD3 + +esp_mail_file_storage_type_none KEYWORD3 +esp_mail_file_storage_type_flash KEYWORD3 +esp_mail_file_storage_type_sd KEYWORD3 + +###################################### +# Constants (LITERAL1) +####################################### + +ESP_MAIL_PRINTF LITERAL1 \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/library.json b/lib/libesp32/ESP-Mail-Client/library.json new file mode 100644 index 000000000000..6f1953984dfd --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/library.json @@ -0,0 +1,16 @@ +{ + "name": "ESP Mail Client", + "version": "3.4.9", + "keywords": "communication, email, imap, smtp, esp32, esp8266, samd, arduino", + "description": "Arduino E-Mail Client Library to send, read and get incoming email notification for ESP32, ESP8266 and SAMD21 devices. The library also supported other Arduino Devices using Clients interfaces e.g. WiFiClient, EthernetClient, and GSMClient.", + "repository": { + "type": "git", + "url": "https://github.com/mobizt/ESP-Mail-Client.git" + }, + "authors": [{ + "name": "Mobizt", + "email": "suwatchai@outlook.com" + }], + "frameworks": "arduino", + "platforms": "espressif32, espressif8266, atmelsam, atmelavr, atmelmegaavr, ststm32, teensy, rp2040" +} diff --git a/lib/libesp32/ESP-Mail-Client/library.properties b/lib/libesp32/ESP-Mail-Client/library.properties new file mode 100644 index 000000000000..80b2d2c7ee36 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/library.properties @@ -0,0 +1,17 @@ +name=ESP Mail Client + +version=3.4.9 + +author=Mobizt + +maintainer=Mobizt + +sentence=Arduino E-Mail Client Library to send, read and get incoming email notification for ESP32, ESP8266 and SAMD21 devices. + +paragraph=The library also supported other Arduino devices using Clients interfaces e.g. WiFiClient, EthernetClient, and GSMClient. + +category=Communication + +url=https://github.com/mobizt/ESP-Mail-Client + +architectures=esp8266,esp32,sam,samd,stm32,STM32F1,STM32F4,teensy,avr,megaavr,mbed_nano,mbed_rp2040,rp2040 diff --git a/lib/libesp32/lib_mail/media/images/ArduinoIDE.png b/lib/libesp32/ESP-Mail-Client/media/images/ArduinoIDE.png similarity index 100% rename from lib/libesp32/lib_mail/media/images/ArduinoIDE.png rename to lib/libesp32/ESP-Mail-Client/media/images/ArduinoIDE.png diff --git a/lib/libesp32/ESP-Mail-Client/media/images/ESP32-PSRAM.png b/lib/libesp32/ESP-Mail-Client/media/images/ESP32-PSRAM.png new file mode 100644 index 000000000000..4e5ece8f1aa6 Binary files /dev/null and b/lib/libesp32/ESP-Mail-Client/media/images/ESP32-PSRAM.png differ diff --git a/lib/libesp32/ESP-Mail-Client/media/images/ESP8266_VM.png b/lib/libesp32/ESP-Mail-Client/media/images/ESP8266_VM.png new file mode 100644 index 000000000000..abf0090ee073 Binary files /dev/null and b/lib/libesp32/ESP-Mail-Client/media/images/ESP8266_VM.png differ diff --git a/lib/libesp32/ESP-Mail-Client/media/images/SerialNINAPassthrough.png b/lib/libesp32/ESP-Mail-Client/media/images/SerialNINAPassthrough.png new file mode 100644 index 000000000000..130e78fce856 Binary files /dev/null and b/lib/libesp32/ESP-Mail-Client/media/images/SerialNINAPassthrough.png differ diff --git a/lib/libesp32/lib_mail/media/images/esp-mail-client.png b/lib/libesp32/ESP-Mail-Client/media/images/esp-mail-client.png similarity index 100% rename from lib/libesp32/lib_mail/media/images/esp-mail-client.png rename to lib/libesp32/ESP-Mail-Client/media/images/esp-mail-client.png diff --git a/lib/libesp32/lib_mail/media/images/esp-mail-client.svg b/lib/libesp32/ESP-Mail-Client/media/images/esp-mail-client.svg similarity index 100% rename from lib/libesp32/lib_mail/media/images/esp-mail-client.svg rename to lib/libesp32/ESP-Mail-Client/media/images/esp-mail-client.svg diff --git a/lib/libesp32/ESP-Mail-Client/media/images/esptool.png b/lib/libesp32/ESP-Mail-Client/media/images/esptool.png new file mode 100644 index 000000000000..17c9c143d684 Binary files /dev/null and b/lib/libesp32/ESP-Mail-Client/media/images/esptool.png differ diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.cpp b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.cpp new file mode 100644 index 000000000000..4c58543a2a88 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.cpp @@ -0,0 +1,1933 @@ +#ifndef ESP_MAIL_CLIENT_CPP +#define ESP_MAIL_CLIENT_CPP + +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +/** + * Mail Client Arduino Library for Arduino devices. + * + * Created August 28, 2023 + * + * This library allows Espressif's ESP32, ESP8266, SAMD and RP2040 Pico devices to send and read Email through the SMTP and IMAP servers. + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "ESP_Mail_Client.h" +#include "ESP_Mail_Client_Version.h" + +#include "ESP_Mail_IMAP.h" +#include "ESP_Mail_SMTP.h" + +void ESP_Mail_Client::networkReconnect(bool reconnect) +{ +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) && (defined(ESP32) || defined(ESP8266)) + WiFi.setAutoReconnect(reconnect); +#endif + networkAutoReconnect = reconnect; +} + +void ESP_Mail_Client::printf(const char *format, ...) +{ + int size = 2048; + char s[size]; + va_list va; + va_start(va, format); + vsnprintf(s, size, format, va); + va_end(va); + ESP_MAIL_DEFAULT_DEBUG_PORT.print(s); +} + +void ESP_Mail_Client::addAP(const String &ssid, const String &password) +{ + wifi.addAP(ssid, password); +} + +void ESP_Mail_Client::clearAP() +{ + wifi.clearAP(); +} + +#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) + +bool ESP_Mail_Client::sdBegin(int8_t ss, int8_t sck, int8_t miso, int8_t mosi, uint32_t frequency) +{ + return mbfs->sdBegin(ss, sck, miso, mosi, frequency); +} + +#if defined(ESP8266) || defined(MB_ARDUINO_PICO) +bool ESP_Mail_Client::sdBegin(SDFSConfig *sdFSConfig) +{ + return mbfs->sdFatBegin(sdFSConfig); +} +#endif + +#if defined(ESP32) +bool ESP_Mail_Client::sdBegin(int8_t ss, SPIClass *spiConfig, uint32_t frequency) +{ + return mbfs->sdSPIBegin(ss, spiConfig, frequency); +} +#endif + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) +bool ESP_Mail_Client::sdBegin(SdSpiConfig *sdFatSPIConfig, int8_t ss, int8_t sck, int8_t miso, int8_t mosi) +{ + return mbfs->sdFatBegin(sdFatSPIConfig, ss, sck, miso, mosi); +} + +bool ESP_Mail_Client::sdBegin(SdioConfig *sdFatSDIOConfig) +{ + return mbfs->sdFatBegin(sdFatSDIOConfig); +} +#endif + +#endif + +#if defined(ESP32) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD_MMC) + +bool ESP_Mail_Client::sdMMCBegin(const char *mountpoint, bool mode1bit, bool format_if_mount_failed) +{ + return mbfs->sdMMCBegin(mountpoint, mode1bit, format_if_mount_failed); +} + +#endif + +int ESP_Mail_Client::getFreeHeap() +{ +#if defined(MB_ARDUINO_ESP) + return ESP.getFreeHeap(); +#elif defined(MB_ARDUINO_PICO) + return rp2040.getFreeHeap(); +#else + return 0; +#endif +} + +// All following functions are for IMAP or SMTP only +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + +void ESP_Mail_Client::resumeNetwork(ESP_Mail_TCPClient *client) +{ + client->networkReconnect(); +} + +template +bool ESP_Mail_Client::sessionExisted(T sessionPtr) +{ + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + + Session_Config *config = sessionPtr->_session_cfg; + _vectorImpl *configPtrList = &(sessionPtr->_configPtrList); + + if (config) + { + int ptr = toAddr(*config); + for (size_t i = 0; i < configPtrList->size(); i++) + { + if ((*configPtrList)[i] == ptr) + return true; + } + + sessionPtr->closeSession(); + sessionPtr->_responseStatus.errorCode = MAIL_CLIENT_ERROR_SESSION_CONFIG_WAS_NOT_ASSIGNED; + sessionPtr->_responseStatus.text.clear(); + } + +#endif + return false; +} + +void ESP_Mail_Client::debugPrintNewLine() +{ +#if !defined(SILENT_MODE) + esp_mail_debug_print("", true); +#endif +} + +template +void ESP_Mail_Client::callBackSendNewLine(T sessionPtr, bool success) +{ +#if defined(SESSION_DEBUG_ENABLED) + sendCallback(sessionPtr, "", false, success); +#endif +} + +void ESP_Mail_Client::appendTagSpace(MB_String &buf, PGM_P tag) +{ + buf += (tag == NULL) ? esp_mail_imap_tag_str : tag; + appendSpace(buf); +} + +template +void ESP_Mail_Client::appendList(MB_String &buf, _vectorImpl &list) +{ + for (size_t i = 0; i < list.size(); i++) + { + if (i > 0) + buf += esp_mail_str_8; /* "," */ + buf += list[i]; + } +} + +void ESP_Mail_Client::appendSpace(MB_String &buf) +{ + buf += esp_mail_str_2 /* " " */; +} + +void ESP_Mail_Client::appendSpace(MB_String &buf, bool withTag, PGM_P value) +{ + if (withTag) + appendTagSpace(buf); + buf += value; + appendSpace(buf); +} + +void ESP_Mail_Client::appendSpace(MB_String &buf, bool withTag, int nunArgs, ...) +{ + if (withTag) + appendTagSpace(buf); + + va_list ap; + va_start(ap, nunArgs); + PGM_P p = va_arg(ap, PGM_P); + if (p) + buf += p; + for (int i = 2; i <= nunArgs; i++) + { + appendSpace(buf); + p = va_arg(ap, PGM_P); + if (p) + buf += p; + } + va_end(ap); + appendSpace(buf); +} + +void ESP_Mail_Client::prependSpace(MB_String &buf, PGM_P value) +{ + appendSpace(buf); + buf += value; +} + +void ESP_Mail_Client::appendDot(MB_String &buf) +{ + buf += esp_mail_str_27; /* "." */ +} + +void ESP_Mail_Client::prependDot(MB_String &buf, PGM_P value) +{ + buf += esp_mail_str_27; /* "." */ + buf += value; +} + +void ESP_Mail_Client::joinStringSpace(MB_String &buf, bool withTag, int nunArgs, ...) +{ + if (withTag) + appendTagSpace(buf); + + va_list ap; + va_start(ap, nunArgs); + PGM_P p = va_arg(ap, PGM_P); + if (p) + buf += p; + for (int i = 2; i <= nunArgs; i++) + { + appendSpace(buf); + p = va_arg(ap, PGM_P); + if (p) + buf += p; + } + va_end(ap); +} + +void ESP_Mail_Client::appendImap4KeyValue(MB_String &buf, PGM_P key, PGM_P value) +{ + buf += esp_mail_str_11; /* "\"" */ + buf += key; + buf += esp_mail_str_11; /* "\"" */ + appendSpace(buf); + buf += esp_mail_str_11; /* "\"" */ + buf += value; + buf += esp_mail_str_11; /* "\"" */ +} + +void ESP_Mail_Client::joinStringDot(MB_String &buf, int nunArgs, ...) +{ + va_list ap; + va_start(ap, nunArgs); + PGM_P p = va_arg(ap, PGM_P); + if (p) + buf += p; + for (int i = 2; i <= nunArgs; i++) + { + buf += esp_mail_str_27; /* "." */ + p = va_arg(ap, PGM_P); + if (p) + buf += p; + } + va_end(ap); +} + +template +void ESP_Mail_Client::sendCallback(T sessionPtr, PGM_P info, bool prependCRLF, bool success) +{ + +#if defined(SESSION_DEBUG_ENABLED) + + sessionPtr->_cbData._info.clear(); + + if (prependCRLF) + appendNewline(sessionPtr->_cbData._info); + if (strlen_P(info) > 0) + { + sessionPtr->_cbData._info += esp_mail_str_33; /* "#### " */ + sessionPtr->_cbData._info += info; + } + sessionPtr->_cbData._success = success; + if (sessionPtr->_statusCallback && !sessionPtr->_customCmdResCallback) + sessionPtr->_statusCallback(sessionPtr->_cbData); + +#endif +} + +template +void ESP_Mail_Client::printDebug(T sessionPtr, PGM_P cbMsg, PGM_P dbMsg, esp_mail_debug_tag_type type, bool prependCRLF, bool success) +{ +#if defined(SESSION_DEBUG_ENABLED) + + if (sessionPtr->_statusCallback != NULL && !isResponseCB(sessionPtr)) + sendCallback(sessionPtr, cbMsg, prependCRLF, success); + else if (sessionPtr->_debug) + debugPrintNewLine(); + + if (sessionPtr->_debug) + esp_mail_debug_print_tag(dbMsg, type, true); + +#endif +} + +void ESP_Mail_Client::printProgress(int progress, int &lastProgress) +{ +#if !defined(SILENT_MODE) + if (progress > 100) + progress = 100; + + if (lastProgress != progress && (progress == 0 || progress == 100 || lastProgress + ESP_MAIL_PROGRESS_REPORT_STEP <= progress)) + { + int len = 16; + int curTick = progress * len / 100; + int lastTick = lastProgress * len / 100; + + if (curTick > lastTick || progress == 0 || progress == 100) + { + MB_String s; + for (int i = 0; i < len; i++) + { + if (i == 0) + s = '['; + s += i < progress * len / 100 ? '#' : ' '; + if (i == len - 1) + s += ']'; + } + appendSpace(s); + s += progress; + appendSpace(s); + s += esp_mail_str_24; /* "%" */ + esp_mail_debug_print_tag(s.c_str(), esp_mail_debug_tag_type_client, true); + } + + lastProgress = progress; + } +#endif +} + +void ESP_Mail_Client::setTimezone(const char *TZ_Var, const char *TZ_file) +{ + + if (!TZ_Var) + return; + +#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) + if (strlen(TZ_Var) > 0) + { + +#if defined(ESP32) + + mb_fs_mem_storage_type type = mb_fs_mem_storage_type_undefined; + +#if defined(MBFS_FLASH_FS) + type = mb_fs_mem_storage_type_flash; +#elif defined(MBFS_SD_FS) + type = mb_fs_mem_storage_type_sd; +#endif + + if (type != mb_fs_mem_storage_type_undefined) + { + MB_String filename = TZ_file; + if (mbfs->open(filename, type, mb_fs_open_mode_write) > -1) + { + mbfs->print(type, TZ_Var); + mbfs->close(type); + } + } + +#endif + + setenv("TZ", TZ_Var, 1); + tzset(); + timezoneEnvSet = true; + } +#endif +} + +void ESP_Mail_Client::preparePortFunction(Session_Config *session_config, bool isSMTP, bool &secure, bool &secureMode, bool &ssl) +{ + + if (session_config->ports_functions.list) + { + if (session_config->ports_functions.use_internal_list) + { + session_config->ports_functions.use_internal_list = false; + delete[] session_config->ports_functions.list; + session_config->ports_functions.list = nullptr; + } + } + + if (!session_config->ports_functions.list) + { + if (isSMTP) + { +#if defined(ENABLE_SMTP) + session_config->ports_functions.use_internal_list = true; + session_config->ports_functions.list = new port_function[3]; + session_config->ports_functions.size = 3; + + for (int i = 0; i < 3; i++) + session_config->ports_functions.list[i] = smtp_ports[i]; +#endif + } + else + { +#if defined(ENABLE_IMAP) + session_config->ports_functions.use_internal_list = true; + session_config->ports_functions.list = new port_function[2]; + session_config->ports_functions.size = 2; + + for (int i = 0; i < 2; i++) + session_config->ports_functions.list[i] = imap_ports[i]; +#endif + } + } + + getPortFunction(session_config->server.port, session_config->ports_functions, secure, secureMode, ssl, session_config->secure.startTLS); +} + +void ESP_Mail_Client::getPortFunction(uint16_t port, struct esp_mail_ports_functions &ports_functions, bool &secure, bool &secureMode, bool &ssl, bool &starttls) +{ + for (size_t i = 0; i < ports_functions.size; i++) + { + if (ports_functions.list[i].port == port) + { + if (ports_functions.list[i].protocol == esp_mail_protocol_plain_text) + { + secure = false; + secureMode = false; + } + else + { + if (ports_functions.list[i].protocol == esp_mail_protocol_tls) + starttls = true; + + secureMode = !starttls; + + if (ports_functions.list[i].protocol == esp_mail_protocol_ssl) + ssl = true; + } + return; + } + } +} + +void ESP_Mail_Client::getTimezone(const char *TZ_file, MB_String &out) +{ + +#if defined(ESP32) + + mb_fs_mem_storage_type type = mb_fs_mem_storage_type_undefined; + +#if defined(MBFS_FLASH_FS) + type = mb_fs_mem_storage_type_flash; +#elif defined(MBFS_SD_FS) + type = mb_fs_mem_storage_type_sd; +#endif + + if (type != mb_fs_mem_storage_type_undefined) + { + MB_String filename = TZ_file; + + if (mbfs->open(filename, type, mb_fs_open_mode_read) > 0) + { + out.clear(); + while (mbfs->available(type)) + { + out += (char)mbfs->read(type); + } + mbfs->close(type); + } + } +#endif +} + +void ESP_Mail_Client::setTime(const char *TZ_Var, const char *TZ_file, bool wait, bool debugProgress) +{ + + timeStatus = Time.timeReady(); + + if (!timeStatus) + { + +#if defined(ENABLE_IMAP) || defined(ENABLE_SMTP) + +#if defined(ENABLE_NTP_TIME) + + if (WiFI_CONNECTED) + { + Time.readNTPTime(wait ? 10000 : 0, debugProgress); + } + else + { +#if !defined(SILENT_MODE) + esp_mail_debug_print_tag(esp_mail_error_client_str_4 /* "NTP server time reading cannot begin when valid time is required because of no WiFi capability/activity detected." */, esp_mail_debug_tag_type_warning, true); + esp_mail_debug_print_tag(esp_mail_error_client_str_5 /* "Please set the library reference time manually using smtp.setSystemTime or imap.setSystemTime." */, esp_mail_debug_tag_type_warning, true); +#endif + } + + getSetTimezoneEnv(TZ_file, TZ_Var); + +#elif !defined(SILENT_MODE) + esp_mail_debug_print_tag(esp_mail_error_client_str_5 /* "Please set the library reference time manually using smtp.setSystemTime or imap.setSystemTime." */, esp_mail_debug_tag_type_warning, true); +#endif + +#endif + } + + timeStatus = Time.timeReady(); +} + +void ESP_Mail_Client::getSetTimezoneEnv(const char *TZ_file, const char *TZ_Var) +{ + // set and get TZ environment variable + + MB_String timezone; + + // only ESP32 only + getTimezone(TZ_file, timezone); + + if (timezone.length() == 0) + timezone = TZ_Var; + + // if timezone string assign + setTimezone(timezone.c_str(), TZ_file); +} + +bool ESP_Mail_Client::validEmail(const char *s) +{ + MB_String str(s); + size_t at = str.find('@'); + size_t dot = str.find('.', at); + return (at != MB_String::npos) && (dot != MB_String::npos); +} + +#if defined(ENABLE_SMTP) && defined(ENABLE_IMAP) + +bool ESP_Mail_Client::mAppendMessage(IMAPSession *imap, SMTP_Message *msg, bool lastAppend, MB_StringPtr flags, MB_StringPtr dateTime) +{ + this->imap = imap; + calDataLen = true; + dataLen = 0; + imap_ts = 0; + + if (!sessionExisted(imap)) + return false; + + MB_String _flags = flags; + _flags.trim(); + + MB_String _dt = dateTime; + _dt.trim(); + + bool rfc822MSG = false; + + sendContent(nullptr, msg, false, rfc822MSG); + + MB_String cmd; + + if (!imap->_feature_capability[esp_mail_imap_read_capability_multiappend]) + { + lastAppend = true; + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + } + + if (imap->_prev_imap_cmd != esp_mail_imap_cmd_append) + joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_append].text, imap->_currentFolder.c_str()); + + appendSpace(cmd); + + if (_flags.length() > 0) + { + appendString(cmd, _flags.c_str(), false, false, esp_mail_string_mark_type_round_bracket); + appendSpace(cmd); + } + + if (_dt.length() > 0) + { + appendString(cmd, _dt.c_str(), false, false, esp_mail_string_mark_type_double_quote); + appendSpace(cmd); + } + + appendString(cmd, MB_String((int)dataLen).c_str(), false, false, esp_mail_string_mark_type_curly_bracket); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + { + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + return false; + } + + imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_append; + + if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) + { + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + return false; + } + + calDataLen = false; + + rfc822MSG = false; + + if (!sendContent(nullptr, msg, false, rfc822MSG)) + { + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + return false; + } + + if (lastAppend) + { + if (imapSend(imap, esp_mail_str_18 /* "\r\n" */, false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + { + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + return false; + } + + imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_append_last; + + if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) + { + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + return false; + } + + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + } + + if (!lastAppend) + imap->_prev_imap_cmd = esp_mail_imap_cmd_append; + else + { +#if !defined(SILENT_MODE) + altSendCallback(nullptr, esp_mail_cb_str_45 /* "Message append successfully" */, esp_mail_dbg_str_73 /* "message append successfully" */, esp_mail_debug_tag_type_client, true, false); +#endif + } + return true; +} + +#endif + +char *ESP_Mail_Client::getRandomUID() +{ + char *tmp = allocMem(36); + sprintf(tmp, "%d", (int)random(2000, 4000)); + return tmp; +} + +void ESP_Mail_Client::splitToken(const char *str, _vectorImpl &tk, const char *delim) +{ + char *p = allocMem(strlen(str)); + strcpy(p, str); + char *pp = p; + char *end = p; + MB_String tmp; + while (pp != NULL) + { + // See RFC2047.h + ESP_MAIL_STRSEP(&end, delim); + if (strlen(pp) > 0) + { + tmp = pp; + tk.push_back(tmp); + } + pp = end; + } + // release memory + freeMem(&p); +} + +int ESP_Mail_Client::strpos(const char *haystack, const char *needle, int offset, bool caseSensitive) +{ + if (!haystack || !needle) + return -1; + + int hlen = strlen(haystack); + int nlen = strlen(needle); + + if (hlen == 0 || nlen == 0) + return -1; + + int hidx = offset, nidx = 0; + while ((*(haystack + hidx) != '\0') && (*(needle + nidx) != '\0') && hidx < hlen) + { + + bool nm = caseSensitive ? *(needle + nidx) != *(haystack + hidx) : tolower(*(needle + nidx)) != tolower(*(haystack + hidx)); + + if (nm) + { + hidx++; + nidx = 0; + } + else + { + nidx++; + hidx++; + if (nidx == nlen) + return hidx - nidx; + } + } + + return -1; +} + +char *ESP_Mail_Client::subStr(const char *buf, PGM_P beginToken, PGM_P endToken, int beginPos, int endPos, bool caseSensitive) +{ + char *tmp = nullptr; + if (beginToken) + { + int p1 = strposP(buf, beginToken, beginPos, caseSensitive); + if (p1 != -1) + { + while (buf[p1 + strlen_P(beginToken)] == ' ' || buf[p1 + strlen_P(beginToken)] == '\r' || buf[p1 + strlen_P(beginToken)] == '\n') + { + p1++; + if (strlen(buf) <= p1 + strlen_P(beginToken)) + { + p1--; + break; + } + } + + int p2 = -1; + if (endPos == 0) + p2 = strposP(buf, endToken, p1 + strlen_P(beginToken), caseSensitive); + + if (p2 == -1) + p2 = strlen(buf); + + int len = p2 - p1 - strlen_P(beginToken); + int ofs = endToken ? strlen_P(endToken) : 1; + tmp = allocMem(len + ofs); + memcpy(tmp, &buf[p1 + strlen_P(beginToken)], len); + } + } + else + { + int p1 = strposP(buf, endToken, beginPos); + if (p1 != -1) + { + tmp = allocMem(p1); + memcpy(tmp, &buf[2], p1 - 1); + } + } + + return tmp; +} + +bool ESP_Mail_Client::getHeader(const char *buf, PGM_P beginToken, MB_String &out, bool caseSensitive) +{ + if (strcmpP(buf, 0, beginToken, caseSensitive)) + { + char *tmp = subStr(buf, beginToken, NULL, 0, -1, caseSensitive); + if (tmp) + { + out = tmp; + // release memory + freeMem(&tmp); + return true; + } + } + + return false; +} + +void ESP_Mail_Client::appendHeaderField(MB_String &buf, const char *name, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type) +{ + appendHeaderName(buf, name); + appendString(buf, value, comma, newLine, type); +} + +void ESP_Mail_Client::appendAddressHeaderField(MB_String &buf, esp_mail_address_info_t &source, esp_mail_rfc822_header_field_types type, bool header, bool comma, bool newLine) +{ + // Construct header field. + if (header) + appendHeaderName(buf, rfc822_headers[type].text); + + if (type != esp_mail_rfc822_header_field_cc && type != esp_mail_rfc822_header_field_bcc && + source.name.length() > 0) + { + appendString(buf, source.name.c_str(), false, false, esp_mail_string_mark_type_double_quote); + // Add white space after name for SMTP to fix iCloud Mail Service IMAP search compatibility issue #278 + // This is not restricted by rfc2822. + appendSpace(buf); + } + + appendString(buf, source.email.c_str(), comma, newLine, esp_mail_string_mark_type_angle_bracket); +} + +void ESP_Mail_Client::appendHeaderName(MB_String &buf, const char *name, bool clear, bool lowercase, bool space) +{ + if (clear) + buf.clear(); + + if (lowercase) + appendLowerCaseString(buf, name); + else + buf += name; + buf += esp_mail_str_34; /* ":" */ + if (space) + appendSpace(buf); +} + +void ESP_Mail_Client::appendLowerCaseString(MB_String &buf, PGM_P value, bool clear) +{ + if (clear) + buf.clear(); + char *tmp = strP2Lower(value); + buf += tmp; + freeMem(&tmp); +} + +void ESP_Mail_Client::appendHeaderProp(MB_String &buf, PGM_P prop, const char *value, bool &firstProp, bool lowerCase, bool isString, bool newLine) +{ + if (firstProp) + buf += esp_mail_str_35; /* ";" */ + appendSpace(buf); + if (lowerCase) + appendLowerCaseString(buf, prop); + else + buf += prop; + buf += esp_mail_str_7; /* "=" */ + if (isString) + buf += esp_mail_str_11; /* "\"" */ + buf += value; + if (isString) + buf += esp_mail_str_11; /* "\"" */ + buf += esp_mail_str_35; /* ";" */ + if (newLine) + appendNewline(buf); + + firstProp = false; +} + +void ESP_Mail_Client::appendString(MB_String &buf, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type) +{ + if (comma) + buf += esp_mail_str_8; /* "," */ + + switch (type) + { + case esp_mail_string_mark_type_double_quote: + buf += esp_mail_str_11; /* "\"" */ + break; + case esp_mail_string_mark_type_angle_bracket: + buf += esp_mail_str_19; /* "<" */ + break; + case esp_mail_string_mark_type_round_bracket: + buf += esp_mail_str_38; /* "(" */ + break; + case esp_mail_string_mark_type_curly_bracket: + buf += esp_mail_str_36; /* "{" */ + break; + case esp_mail_string_mark_type_square_bracket: + buf += esp_mail_str_40; /* "[" */ + break; + default: + break; + } + + if (value) + buf += value; + + switch (type) + { + case esp_mail_string_mark_type_double_quote: + buf += esp_mail_str_11; /* "\"" */ + break; + case esp_mail_string_mark_type_angle_bracket: + buf += esp_mail_str_20; /* ">" */ + break; + case esp_mail_string_mark_type_round_bracket: + buf += esp_mail_str_39; /* ")" */ + break; + case esp_mail_string_mark_type_curly_bracket: + buf += esp_mail_str_37; /* "}" */ + break; + case esp_mail_string_mark_type_square_bracket: + buf += esp_mail_str_41; /* "]" */ + break; + default: + break; + } + + if (newLine) + appendNewline(buf); +} + +void ESP_Mail_Client::maskString(MB_String &buf, int len) +{ + for (int i = 0; i < len; i++) + buf += esp_mail_str_3; /* "*" */ +} + +void ESP_Mail_Client::appendDomain(MB_String &buf, const char *domain) +{ + buf += strlen(domain) > 0 ? domain : pgm2Str(esp_mail_str_1 /* "127.0.0.1" */); +} + +void ESP_Mail_Client::appendEmbedMessage(MB_String &buf, esp_mail_message_body_t &body, bool isHtml) +{ + appendHeaderName(buf, message_headers[esp_mail_message_header_field_content_disposition].text); + appendString(buf, body.embed.type == esp_mail_smtp_embed_message_type_inline ? esp_mail_content_disposition_type_t::inline_ : esp_mail_content_disposition_type_t::attachment, false, false); + + PGM_P pgm = isHtml ? esp_mail_str_14 /* "msg.html" */ : esp_mail_str_13; /* "msg.txt" */ + MB_String filename; + if (body.embed.filename.length() > 0) + filename = body.embed.filename; + else + filename = pgm; + + bool firstProp = true; + appendHeaderProp(buf, message_headers[esp_mail_message_header_field_filename].text, filename.c_str(), firstProp, true, true, true); + + if (body.embed.type == esp_mail_smtp_embed_message_type_inline) + { + appendHeaderName(buf, message_headers[esp_mail_message_header_field_content_location].text); + body.embed.filename.length() > 0 ? appendString(buf, body.embed.filename.c_str(), false, true) : appendString(buf, pgm, false, true); + appendHeaderField(buf, message_headers[esp_mail_message_header_field_content_id].text, body._int.cid.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + } +} + +void ESP_Mail_Client::appendNewline(MB_String &buf) +{ + buf += esp_mail_str_18; /* "\r\n" */ +} + +void ESP_Mail_Client::getExtfromMIME(const char *mime, MB_String &ext) +{ + ext.clear(); + for (int i = 0; i < esp_mail_file_extension_maxType; i++) + { + if (strcmp_P(mime, mimeinfo[i].mimeType) == 0) + { + ext = mimeinfo[i].endsWith; + break; + } + } + + if (ext.length() == 0) + ext = esp_mail_str_42; /* ".dat" */ +} + +MB_String ESP_Mail_Client::mGetBase64(MB_StringPtr str) +{ + MB_String data = str; + return encodeBase64Str((uint8_t *)(data.c_str()), data.length()); +} + +int ESP_Mail_Client::readLine(ESP_Mail_TCPClient *client, char *buf, int bufLen, bool withLineBreak, int &count, bool &ovf, unsigned long timeoutSec, bool &isTimeout) +{ + int ret = -1; + char c = 0; + char _c = 0; + int idx = 0; + ovf = idx >= bufLen; + bool lineBreak = false; + isTimeout = false; + + unsigned long ms = millis(); + + // Instead of relying on data available, we looks for line break until timed out or disconnected or overflown occurred. + while (idx < bufLen && client->connected() && (!lineBreak || client->available() /* data may not available sometimes */)) + { + if (millis() - ms >= timeoutSec * 1000) + { + isTimeout = true; + break; + } + + yield_impl(); + + ret = client->read(); + if (ret > -1) + { + c = (char)ret; + buf[idx++] = c; + count++; + if (_c == '\r' && c == '\n') + { + lineBreak = true; + if (!withLineBreak) + { + buf[idx - 2] = 0; + idx -= 2; + } + return idx; + } + _c = c; + + if (idx >= bufLen - 1) + { + ovf = true; + return idx; + } + } + } + return idx; +} + +template +bool ESP_Mail_Client::readResponse(T sessionPtr, char *buf, int bufLen, int &readLen, bool withLineBreak, int &count, MB_String &ovfBuf) +{ + bool ovf = false, isTimeout = false; + unsigned long timeoutSec = TCP_CLIENT_DEFAULT_TCP_TIMEOUT_SEC; + + do + { + timeoutSec = sessionPtr->client.tcpTimeout(); + int len = readLine(&(sessionPtr->client), buf, bufLen, withLineBreak, count, ovf, timeoutSec, isTimeout); + readLen += len; + if (len > 0 && (ovf || ovfBuf.length() > 0)) + ovfBuf += buf; + + } while (ovf); + + if (isTimeout) + return false; + + if (ovfBuf.length() > 0) + { + +#if defined(SESSION_DEBUG_ENABLED) + sessionPtr->_responseStatus.errorCode = MAIL_CLIENT_ERROR_BUFFER_OVERFLOW; + sessionPtr->_responseStatus.text.clear(); + if (sessionPtr->_debug) + esp_mail_debug_print_tag(sessionPtr->errorReason().c_str(), esp_mail_debug_tag_type_warning, true); +#endif + } + + return true; +} + +template +bool ESP_Mail_Client::reconnect(T sessionPtr, unsigned long dataTime, bool downloadRequest) +{ + if (!sessionPtr) + return false; + + sessionPtr->client.setSession(sessionPtr->_session_cfg); + networkStatus = sessionPtr->client.networkReady(); + + if (dataTime > 0) + { + if (millis() - dataTime > (unsigned long)sessionPtr->client.tcpTimeout()) + { + closeTCPSession(sessionPtr); + + if (sessionPtr->_sessionType == esp_mail_session_type_imap) + { +#if defined(ENABLE_IMAP) + IMAPSession *ss = (IMAPSession *)sessionPtr; + if (ss->_headers.size() > 0) + { + if (downloadRequest) + { + errorStatusCB(ss, nullptr, IMAP_STATUS_ERROR_DOWNLAD_TIMEOUT, true); + if (cPart(ss) && cHeader(ss)->part_headers.size() > 0) + cPart(ss)->download_error = ss->errorReason().c_str(); + } + else + { + errorStatusCB(ss, nullptr, MAIL_CLIENT_ERROR_READ_TIMEOUT, true); + if (cHeader(ss)) + cHeader(ss)->error_msg = ss->errorReason().c_str(); + } + } + else + { +#if !defined(SILENT_MODE) + if (sessionPtr->_debug) + esp_mail_debug_print_tag(esp_mail_error_network_str_9 /* "response read timed out" */, esp_mail_debug_tag_type_error, true); +#endif + } +#endif + } + else + { +#if defined(ENABLE_SMTP) + SMTPSession *ss = (SMTPSession *)sessionPtr; + errorStatusCB(ss, this->imap, MAIL_CLIENT_ERROR_READ_TIMEOUT, false); +#endif + } + return false; + } + } + + if (!networkStatus) + { + closeTCPSession(sessionPtr); + + if (sessionPtr->_sessionType == esp_mail_session_type_imap) + { +#if defined(ENABLE_IMAP) + IMAPSession *ss = (IMAPSession *)sessionPtr; + if (ss->_mbif._idleTimeMs > 0 || ss->_imap_cmd == esp_mail_imap_cmd_idle || ss->_imap_cmd == esp_mail_imap_cmd_done) + { + // defer the polling error report + if (millis() - ss->_last_polling_error_ms > 10000 && !sessionPtr->connected()) + { + ss->_last_polling_error_ms = millis(); + errorStatusCB(ss, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, true); + } + } + else if (millis() - ss->_last_network_error_ms > 1000) + { + ss->_last_network_error_ms = millis(); + errorStatusCB(ss, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, true); + } + + if (ss->_headers.size() > 0) + { + if (cPart(ss) && downloadRequest) + cPart(ss)->download_error = ss->errorReason().c_str(); + else if (cHeader(ss)) + cHeader(ss)->error_msg = ss->errorReason().c_str(); + } + +#endif + } + else + { +#if defined(ENABLE_SMTP) + SMTPSession *ss = (SMTPSession *)sessionPtr; + errorStatusCB(ss, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, false); +#endif + } + + if (millis() - _lastReconnectMillis > _reconnectTimeout && !sessionPtr->connected()) + { + if (sessionPtr->_session_cfg->network_connection_handler) + { + // dummy + sessionPtr->client.disconnect(); + sessionPtr->_session_cfg->network_connection_handler(); + } + else + { + if (MailClient.networkAutoReconnect) + MailClient.resumeNetwork(&(sessionPtr->client)); + } + + _lastReconnectMillis = millis(); + } + + networkStatus = sessionPtr->client.networkReady(); + } + + return networkStatus; +} + +template +void ESP_Mail_Client::sendCB(T sessionPtr, PGM_P info, bool prependCRLF, bool success) +{ + if (sessionPtr) + { + sessionPtr->_cbData._info.clear(); + + if (prependCRLF) + appendNewline(sessionPtr->_cbData._info); + if (strlen_P(info) > 0) + { + sessionPtr->_cbData._info += esp_mail_str_33; /* "#### " */ + sessionPtr->_cbData._info += info; + } + sessionPtr->_cbData._success = success; + if (sessionPtr->_statusCallback) + sessionPtr->_statusCallback(sessionPtr->_cbData); + } +} + +template +void ESP_Mail_Client::sendErrorCB(T sessionPtr, PGM_P info, bool prependCRLF, bool success) +{ +#if !defined(SILENT_MODE) + MB_String e = esp_mail_str_12; /* "Error, " */ + e += info; + sendCB(sessionPtr, e.c_str(), prependCRLF, success); +#endif +} + +template +void ESP_Mail_Client::errorStatusCB(T1 sessionPtr, T2 sessionPtr2, int error, bool clearLastStatus) +{ + + if (sessionPtr) + { + sessionPtr->_responseStatus.errorCode = error; + + if (clearLastStatus) + sessionPtr->_responseStatus.text.clear(); + +#if !defined(SILENT_MODE) + if (sessionPtr->_statusCallback && !sessionPtr->_customCmdResCallback) + sendErrorCB(sessionPtr, sessionPtr->errorReason().c_str(), false, false); + + if (sessionPtr->_debug && !sessionPtr->_customCmdResCallback) + esp_mail_debug_print_tag(sessionPtr->errorReason().c_str(), esp_mail_debug_tag_type_error, true); +#endif + } + else if (sessionPtr2 && !calDataLen) + errorStatusCB(sessionPtr2, nullptr, error, clearLastStatus); +} + +template +bool ESP_Mail_Client::isResponseCB(T sessionPtr) +{ +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + return sessionPtr->_customCmdResCallback != NULL; +#endif + return false; +} + +template +void ESP_Mail_Client::printLibInfo(T sessionPtr) +{ +#if defined(SESSION_DEBUG_ENABLED) + + if (sessionPtr->_statusCallback != NULL && !isResponseCB(sessionPtr)) + sendCallback(sessionPtr, + sessionPtr->_sessionType == esp_mail_session_type_smtp ? esp_mail_cb_str_1 /* "Connecting to SMTP server..." */ + : esp_mail_cb_str_15 /* "Connecting to IMAP server..." */, + false, false); + + if (sessionPtr->_debug && !isResponseCB(sessionPtr)) + { + MB_String dbMsg = esp_mail_version_str; /* "ESP Mail Client v" */ + dbMsg += ESP_MAIL_VERSION; + esp_mail_debug_print_tag(dbMsg.c_str(), esp_mail_debug_tag_type_client, true); + +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) + if (ESP.getPsramSize() == 0 && !isResponseCB(sessionPtr)) + esp_mail_debug_print_tag(esp_mail_error_mem_str_4 /* "PSRAM was enabled but not detected." */, esp_mail_debug_tag_type_warning, true); +#endif + } + +#endif +} + +template +bool ESP_Mail_Client::beginConnection(Session_Config *session_config, T sessionPtr, bool secureMode) +{ + + sessionPtr->client.setWiFi(&wifi); + sessionPtr->client.setSession(session_config); + + if (!reconnect(sessionPtr)) + return false; + +#if defined(SESSION_DEBUG_ENABLED) + if (sessionPtr->_debug && !isResponseCB(sessionPtr)) + { + esp_mail_debug_print_tag(sessionPtr->_sessionType == esp_mail_session_type_smtp + ? esp_mail_dbg_str_2 /* "connecting to SMTP server" */ + : esp_mail_dbg_str_18 /* "connecting to IMAP server" */, + esp_mail_debug_tag_type_client, true); + + MB_String dbMsg = esp_mail_dbg_str_19; /* "Host > " */ + dbMsg += session_config->server.host_name; + esp_mail_debug_print_tag(dbMsg.c_str(), esp_mail_debug_tag_type_client, true); + + dbMsg = esp_mail_dbg_str_20; /* "Port > " */ + dbMsg += session_config->server.port; + esp_mail_debug_print_tag(dbMsg.c_str(), esp_mail_debug_tag_type_client, true); + } +#endif + + sessionPtr->client.begin(session_config->server.host_name.c_str(), session_config->server.port); + + sessionPtr->client.ethDNSWorkAround(); + + if (!sessionPtr->client.connect(secureMode, session_config->certificate.verify)) + { + if (sessionPtr->_sessionType == esp_mail_session_type_smtp) + { +#if defined(ENABLE_SMTP) + return handleSMTPError((SMTPSession *)sessionPtr, SMTP_STATUS_SERVER_CONNECT_FAILED, false); +#endif + } + else + { +#if defined(ENABLE_IMAP) + return handleIMAPError((IMAPSession *)sessionPtr, IMAP_STATUS_SERVER_CONNECT_FAILED, false); +#endif + } + } + + return true; +} + +template +bool ESP_Mail_Client::prepareTime(Session_Config *session_config, T sessionPtr) +{ + bool timeShouldBeValid = false; + + if (sessionPtr->_sessionType == esp_mail_session_type_smtp) + timeShouldBeValid = true; +#if !defined(ESP_MAIL_DISABLE_SSL) + else + timeShouldBeValid = session_config->certificate.cert_file.length() > 0 || session_config->cert_ptr != 0; +#endif + +#if defined(ENABLE_NTP_TIME) && defined(ESP_MAIL_WIFI_IS_AVAILABLE) + bool ntpEnabled = true; +#else + bool ntpEnabled = false; +#endif + +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + + if (session_config->time.ntp_server.length() > 0 || timeShouldBeValid) + { + + Time.begin(session_config->time.gmt_offset, session_config->time.day_light_offset, session_config->time.ntp_server.c_str()); + + if (!Time.timeReady()) + { + if (sessionPtr->client.type() == esp_mail_client_type_external_gsm_client) + { + int year = 0; + int month = 0; + int day = 0; + int hour = 0; + int min = 0; + int sec = 0; + float timezone = 0; + if (sessionPtr->client.gprsGetTime(year, month, day, hour, min, sec, timezone)) + Time.setTimestamp(Time.getTimestamp(year, month, day, hour, min, sec), timezone); + } + else if (session_config->time.ntp_server.length()) + { +#if defined(ENABLE_NTP_TIME) +#if !defined(SILENT_MODE) + if (sessionPtr->_debug && !isResponseCB(sessionPtr)) + esp_mail_debug_print_tag(esp_mail_dbg_str_21 /* "Reading time from NTP server" */, esp_mail_debug_tag_type_client, false); +#endif + + setTime(session_config->time.timezone_env_string.c_str(), session_config->time.timezone_file.c_str(), true, sessionPtr->_debug && !isResponseCB(sessionPtr)); +#endif + } + } + } + +#endif + +#if defined(ESP32) + if (Time.timeReady() && !timezoneEnvSet) + getSetTimezoneEnv(session_config->time.timezone_file.c_str(), session_config->time.timezone_env_string.c_str()); +#endif + + if (Time.timeReady()) + return true; + else if (WiFI_CONNECTED && timeShouldBeValid) + { + errorStatusCB(sessionPtr, nullptr, ntpEnabled && session_config->time.ntp_server.length() ? MAIL_CLIENT_ERROR_NTP_TIME_SYNC_TIMED_OUT : MAIL_CLIENT_ERROR_TIME_WAS_NOT_SET, false); + return false; + } + + return true; +} + +template +bool ESP_Mail_Client::sessionReady(T sessionPtr) +{ + // If network connection failure or tcp session closed, close session to clear resources. + if (!reconnect(sessionPtr) || !connected(sessionPtr)) + { + closeTCPSession(sessionPtr); + +#if defined(ENABLE_IMAP) + if (sessionPtr->_sessionType == esp_mail_session_type_imap && !connected(sessionPtr)) + errorStatusCB(sessionPtr, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, false); +#endif + + return false; + } + + return true; +} + +void ESP_Mail_Client::setCert(Session_Config *session_config, const char *ca) +{ + int ptr = reinterpret_cast(ca); + if (ptr != session_config->cert_ptr) + { + session_config->cert_updated = true; + session_config->cert_ptr = ptr; + } +} + +void ESP_Mail_Client::setSecure(ESP_Mail_TCPClient &client, Session_Config *session_config) +{ + + client.setMBFS(mbfs); + + client.setSession(session_config); + +#if !defined(ESP_MAIL_DISABLE_SSL) + + if (client.getCertType() == esp_mail_cert_type_undefined || session_config->cert_updated) + { + if (session_config->certificate.cert_file.length() > 0 || session_config->certificate.cert_data != NULL || session_config->cert_ptr > 0) + { + client.setClockReady(timeStatus); + } + + if (session_config->certificate.cert_file.length() == 0) + { + if (session_config->cert_ptr > 0) + client.setCACert(reinterpret_cast(session_config->cert_ptr)); + else if (session_config->certificate.cert_data != NULL) + client.setCACert(session_config->certificate.cert_data); + else + client.setCACert(NULL); + } + else + { + if (!client.setCertFile(session_config->certificate.cert_file.c_str(), mbfs_type session_config->certificate.cert_file_storage_type)) + client.setCACert(NULL); + } + session_config->cert_updated = false; + } +#endif +} + +void ESP_Mail_Client::appendMultipartContentType(MB_String &buf, esp_mail_multipart_types type, const char *boundary) +{ + bool firstProp = true; + appendHeaderField(buf, message_headers[esp_mail_message_header_field_content_type].text, multipart_types[type].text, false, false); + appendHeaderProp(buf, esp_mail_str_90 /* "boundary" */, boundary, firstProp, false, true, true); + appendNewline(buf); +} + +String ESP_Mail_Client::errorReason(bool isSMTP, int errorCode, const char *msg) +{ + MB_String ret; + +#if defined(ENABLE_ERROR_STRING) && !defined(SILENT_MODE) + + // If there is server meanningful response (msg) is available, return it instead + if (strlen(msg) > 0) + return msg; + + // The error code enums were defined in ESP_Mail_Error.h and MB_FS.h. + switch (errorCode) + { + + case TCP_CLIENT_ERROR_CONNECTION_REFUSED: + ret = esp_mail_error_network_str_7; /* "connection refused" */ + break; + case TCP_CLIENT_ERROR_SEND_DATA_FAILED: + ret = esp_mail_error_network_str_8; /* "data sending failed" */ + break; + case TCP_CLIENT_ERROR_NOT_INITIALIZED: + ret = esp_mail_error_client_str_1; /* "client and/or necessary callback functions are not yet assigned" */ + break; + case TCP_CLIENT_ERROR_NOT_CONNECTED: + ret = esp_mail_error_network_str_4; /* "not connected" */ + break; + + case MAIL_CLIENT_ERROR_CONNECTION_CLOSED: + ret = esp_mail_error_network_str_6; /* "connection closed" */ + break; + case MAIL_CLIENT_ERROR_READ_TIMEOUT: + ret = esp_mail_error_network_str_3; /* "response read timed out" */ + break; + case MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP: + ret = esp_mail_error_ssl_str_1; /* "fail to set up the SSL/TLS structure" */ + break; + case MAIL_CLIENT_ERROR_OUT_OF_MEMORY: + ret = esp_mail_error_mem_str_8; /* "out of memory" */ + break; + case MAIL_CLIENT_ERROR_NTP_TIME_SYNC_TIMED_OUT: + ret = esp_mail_error_network_str_2; /* "NTP server time reading timed out" */ + break; + case MAIL_CLIENT_ERROR_SESSION_CONFIG_WAS_NOT_ASSIGNED: + ret = esp_mail_error_session_str_1; /* "the Session_Config object was not assigned" */ + break; + case MAIL_CLIENT_ERROR_TIME_WAS_NOT_SET: + ret = esp_mail_error_time_str_1; /* "library or device time was not set" */ + break; + case MAIL_CLIENT_ERROR_NOT_YET_LOGIN: + ret = esp_mail_error_auth_str_3; /* "not yet log in" */ + break; + case MAIL_CLIENT_ERROR_BUFFER_OVERFLOW: + ret = esp_mail_error_mem_str_9; /* "buffer overflow" */ + break; + +#if defined(ENABLE_SMTP) + case SMTP_STATUS_SERVER_CONNECT_FAILED: + ret = esp_mail_error_network_str_1; /* "unable to connect to server" */ + break; + case SMTP_STATUS_SMTP_GREETING_GET_RESPONSE_FAILED: + ret = esp_mail_error_smtp_str_1; /* "SMTP server greeting failed" */ + break; + case SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED: + ret = esp_mail_error_smtp_str_1; /* "SMTP server greeting failed" */ + break; + case SMTP_STATUS_AUTHEN_NOT_SUPPORT: + ret = esp_mail_error_auth_str_1; /* "the provided SASL authentication mechanism is not support" */ + break; + case SMTP_STATUS_AUTHEN_FAILED: + ret = esp_mail_error_smtp_str_2; /* "authentication failed" */ + break; + case SMTP_STATUS_USER_LOGIN_FAILED: + ret = esp_mail_error_smtp_str_2; /* "authentication failed" */ + break; + case SMTP_STATUS_PASSWORD_LOGIN_FAILED: + ret = esp_mail_error_smtp_str_3; /* "login password is not valid" */ + break; + case SMTP_STATUS_SEND_HEADER_SENDER_FAILED: + ret = esp_mail_error_smtp_str_4; /* "send header failed" */ + break; + case SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED: + ret = esp_mail_error_smtp_str_9; /* "set recipient failed" */ + break; + case SMTP_STATUS_SEND_BODY_FAILED: + ret = esp_mail_error_smtp_str_5; /* "send body failed" */ + break; + case SMTP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED: + ret = esp_mail_error_auth_str_2; /* "OAuth2.0 log in was disabled for this server" */ + break; + case SMTP_STATUS_NO_VALID_RECIPIENTS_EXISTED: + ret = esp_mail_error_smtp_str_8; /* "some of the recipient Email address is not valid" */ + break; + case SMTP_STATUS_NO_VALID_SENDER_EXISTED: + ret = esp_mail_error_smtp_str_7; /* "sender Email address is not valid" */ + break; + case SMTP_STATUS_NO_SUPPORTED_AUTH: + ret = esp_mail_error_auth_str_1; /* "the provided SASL authentication mechanism is not support" */ + break; + case SMTP_STATUS_SEND_CUSTOM_COMMAND_FAILED: + ret = esp_mail_error_smtp_str_10; /* "send custom command failed" */ + break; + case SMTP_STATUS_XOAUTH2_AUTH_FAILED: + ret = esp_mail_error_smtp_str_11; /* "XOAuth2 authenticate failed" */ + break; + case SMTP_STATUS_UNDEFINED: + ret = esp_mail_error_smtp_str_12; /* "undefined error" */ + break; +#endif + +#if defined(ENABLE_IMAP) + case IMAP_STATUS_SERVER_CONNECT_FAILED: + ret = esp_mail_error_network_str_1; /* "unable to connect to server" */ + break; + case IMAP_STATUS_IMAP_RESPONSE_FAILED: + ret = esp_mail_error_imap_str_18; /* "server replied NO or BAD response" */ + break; + case IMAP_STATUS_AUTHENTICATE_FAILED: + ret = esp_mail_error_imap_str_19; /* "authenticate failed" */ + break; + case IMAP_STATUS_BAD_COMMAND: + ret = esp_mail_error_imap_str_17; /* "could not parse command" */ + break; + case IMAP_STATUS_STORE_FAILED: + ret = esp_mail_error_imap_str_20; /* "flags or keywords store failed" */ + break; + case IMAP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED: + ret = esp_mail_error_imap_str_21; /* "server is not support OAuth2 login" */ + break; + case IMAP_STATUS_NO_MESSAGE: + ret = esp_mail_error_imap_str_5; /* "some of the requested messages no longer exist" */ + break; + case IMAP_STATUS_ERROR_DOWNLAD_TIMEOUT: + ret = esp_mail_error_network_str_5; /* "connection timeout" */ + break; + case IMAP_STATUS_CLOSE_MAILBOX_FAILED: + ret = esp_mail_error_imap_str_3; /* "fail to close the mailbox" */ + break; + case IMAP_STATUS_OPEN_MAILBOX_FAILED: + ret = esp_mail_error_imap_str_4; /* "fail to open the mailbox" */ + break; + case IMAP_STATUS_LIST_MAILBOXS_FAILED: + ret = esp_mail_error_imap_str_1; /* "fail to list the mailboxes" */ + break; + case IMAP_STATUS_CHECK_CAPABILITIES_FAILED: + ret = esp_mail_error_imap_str_2; /* "fail to check the capabilities" */ + break; + case IMAP_STATUS_NO_SUPPORTED_AUTH: + ret = esp_mail_error_auth_str_1; /* "the provided SASL authentication mechanism is not support" */ + break; + case IMAP_STATUS_NO_MAILBOX_FOLDER_OPENED: + ret = esp_mail_error_imap_str_5; /* "no mailbox opened" */ + break; + case IMAP_STATUS_FIRMWARE_UPDATE_INIT_FAILED: + ret = esp_mail_error_imap_str_6; /* "firmware update initialization failed" */ + break; + case IMAP_STATUS_FIRMWARE_UPDATE_WRITE_FAILED: + ret = esp_mail_error_imap_str_7; /* "firmware update write failed" */ + break; + case IMAP_STATUS_FIRMWARE_UPDATE_END_FAILED: + ret = esp_mail_error_imap_str_8; /* "firmware update finalize failed" */ + break; + case IMAP_STATUS_CHANGEDSINC_MODSEQ_TEST_FAILED: + ret = esp_mail_error_imap_str_14; /* "no message changed since (assigned) modsec" */ + break; + case IMAP_STATUS_MODSEQ_WAS_NOT_SUPPORTED: + ret = esp_mail_error_imap_str_15; /* "CONDSTORE was not supported or modsec was not supported for selected mailbox" */ + break; + +#endif + +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) + + case MB_FS_ERROR_FILE_IO_ERROR: + ret = esp_mail_error_mem_str_7; /* "file I/O error" */ + break; + case MB_FS_ERROR_FILE_NOT_FOUND: + ret = esp_mail_error_mem_str_6; /* "file not found." */ + break; + case MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY: + ret = esp_mail_error_mem_str_1; /* "flash Storage is not ready." */ + break; + case MB_FS_ERROR_SD_STORAGE_IS_NOT_READY: + ret = esp_mail_error_mem_str_2; /* "SD Storage is not ready." */ + break; + case MB_FS_ERROR_FILE_STILL_OPENED: + ret = esp_mail_error_mem_str_5; /* "file is still opened." */ + break; + +#endif + default: + break; + } + +#endif + + return ret.c_str(); +} + +template +void ESP_Mail_Client::closeTCPSession(T sessionPtr) +{ + if (!sessionPtr) + return; + + sessionPtr->client.stop(); + + _lastReconnectMillis = millis(); + + memset(sessionPtr->_auth_capability, 0, esp_mail_auth_capability_maxType); + memset(sessionPtr->_feature_capability, 0, + sessionPtr->_sessionType == esp_mail_session_type_smtp +#if defined(ENABLE_SMTP) + ? (int)esp_mail_smtp_send_capability_maxType +#else + ? 0 +#endif + : (int)esp_mail_imap_read_capability_maxType); + + sessionPtr->_authenticated = false; + sessionPtr->_loginStatus = false; +} + +template +bool ESP_Mail_Client::connected(T sessionPtr) +{ + return sessionPtr->client.connected(); +} + +size_t ESP_Mail_Client::getReservedLen(size_t len) +{ + return mbfs->getReservedLen(len); +} + +template +T ESP_Mail_Client::allocMem(size_t size, bool clear) +{ + return reinterpret_cast(mbfs->newP(size, clear)); +} + +void ESP_Mail_Client::freeMem(void *ptr) +{ + mbfs->delP(ptr); +} + +bool ESP_Mail_Client::strcmpP(const char *buf, int ofs, PGM_P beginToken, bool caseSensitive) +{ + if (ofs < 0) + { + int p = strposP(buf, beginToken, 0, caseSensitive); + if (p == -1) + return false; + ofs = p; + } + + char *tmp2 = allocMem(strlen_P(beginToken) + 1); + memcpy(tmp2, &buf[ofs], strlen_P(beginToken)); + tmp2[strlen_P(beginToken)] = 0; + MB_String s = beginToken; + bool ret = (strcasecmp(s.c_str(), tmp2) == 0); + // release memory + freeMem(&tmp2); + return ret; +} + +int ESP_Mail_Client::strposP(const char *buf, PGM_P beginToken, int ofs, bool caseSensitive) +{ + MB_String s = beginToken; + return strpos(buf, s.c_str(), ofs, caseSensitive); +} + +char *ESP_Mail_Client::strP(PGM_P pgm) +{ + size_t len = strlen_P(pgm) + 1; + char *buf = allocMem(len); + strcpy_P(buf, pgm); + buf[len - 1] = 0; + return buf; +} + +char *ESP_Mail_Client::strP2Lower(PGM_P pgm) +{ + size_t len = strlen_P(pgm) + 1; + char *buf = allocMem(len); + strcpy_P(buf, pgm); + + for (char *p = buf; *p; p++) + { + *p = tolower(*p); + } + + buf[len - 1] = 0; + return buf; +} + +void ESP_Mail_Client::strReplaceP(MB_String &buf, PGM_P name, PGM_P value) +{ + char *n = strP(name); + char *v = strP(value); + + buf.replaceAll(n, v); + + freeMem(&n); + freeMem(&v); +} + +bool ESP_Mail_Client::isOAuthError(char *buf, int bufLen, int &chunkIdx, int ofs) +{ + bool ret = false; + if (chunkIdx == 0) + { + size_t olen; + unsigned char *decoded = decodeBase64((const unsigned char *)(buf + ofs), bufLen - ofs, &olen); + if (decoded) + { + ret = strposP((char *)decoded, esp_mail_str_44 /* "{\"status\":" */, 0) > -1; + freeMem(&decoded); + } + chunkIdx++; + } + return ret; +} + +MB_String ESP_Mail_Client::getXOAUTH2String(const MB_String &email, const MB_String &accessToken) +{ + MB_String raw = esp_mail_str_45; /* "user=" */ + raw += email; + raw += esp_mail_str_46; /* "\1auth=Bearer " */ + raw += accessToken; + raw += esp_mail_str_43; /* "\1\1" */ + return encodeBase64Str((const unsigned char *)raw.c_str(), raw.length()); +} + +unsigned char *ESP_Mail_Client::decodeBase64(const unsigned char *src, size_t len, size_t *out_len) +{ + unsigned char *out, *pos, block[4], tmp; + size_t i, count, olen; + int pad = 0; + size_t extra_pad; + + unsigned char *dtable = allocMem(256); + + memset(dtable, 0x80, 256); + + for (i = 0; i < sizeof(b64_index_table) - 1; i++) + dtable[b64_index_table[i]] = (unsigned char)i; + dtable['='] = 0; + + count = 0; + for (i = 0; i < len; i++) + { + if (dtable[src[i]] != 0x80) + count++; + } + + if (count == 0) + goto exit; + + extra_pad = (4 - count % 4) % 4; + + olen = (count + extra_pad) / 4 * 3; + + pos = out = allocMem(olen); + + if (out == NULL) + goto exit; + + count = 0; + + for (i = 0; i < len + extra_pad; i++) + { + unsigned char val; + + if (i >= len) + val = '='; + else + val = src[i]; + tmp = dtable[val]; + if (tmp == 0x80) + continue; + + if (val == '=') + pad++; + block[count] = tmp; + count++; + if (count == 4) + { + *pos++ = (block[0] << 2) | (block[1] >> 4); + *pos++ = (block[1] << 4) | (block[2] >> 2); + *pos++ = (block[2] << 6) | block[3]; + count = 0; + if (pad) + { + if (pad == 1) + pos--; + else if (pad == 2) + pos -= 2; + else + { + // release memory + free(out); + goto exit; + } + break; + } + } + } + + *out_len = pos - out; + // release memory + freeMem(&dtable); + return out; +exit: + // release memory + freeMem(&dtable); + return nullptr; +} + +MB_String ESP_Mail_Client::encodeBase64Str(const unsigned char *src, size_t len) +{ + return encodeBase64Str((uint8_t *)src, len); +} + +MB_String ESP_Mail_Client::encodeBase64Str(uint8_t *src, size_t len) +{ + MB_String outStr; + unsigned char *out, *pos; + const unsigned char *end, *in; + size_t olen = 4 * ((len + 2) / 3); + if (olen < len) + return outStr; + + outStr.resize(olen); + out = (unsigned char *)&outStr[0]; + + end = src + len; + in = src; + pos = out; + + while (end - in >= 3) + { + *pos++ = b64_index_table[in[0] >> 2]; + *pos++ = b64_index_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = b64_index_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; + *pos++ = b64_index_table[in[2] & 0x3f]; + in += 3; + } + + if (end - in) + { + *pos++ = b64_index_table[in[0] >> 2]; + if (end - in == 1) + { + *pos++ = b64_index_table[(in[0] & 0x03) << 4]; + *pos++ = '='; + } + else + { + *pos++ = b64_index_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = b64_index_table[(in[1] & 0x0f) << 2]; + } + *pos++ = '='; + } + + return outStr; +} + +#endif + +ESP_Mail_Client MailClient = ESP_Mail_Client(); + +#endif /* ESP_MAIL_CLIENT_CPP */ diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.h new file mode 100644 index 000000000000..69099a497229 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.h @@ -0,0 +1,2862 @@ +#ifndef ESP_MAIL_CLIENT_H +#define ESP_MAIL_CLIENT_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +/** + * Mail Client Arduino Library for Arduino devices. + * + * Created August 28, 2023 + * + * This library allows Espressif's ESP32, ESP8266, SAMD and RP2040 Pico devices to send and read Email through the SMTP and IMAP servers. + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "extras/RFC2047.h" +#include +#include + +#include +#include +#include + +#if __has_include() +#include +#endif + +#if __has_include() +#include +#endif + +#include "ESP_Mail_FS.h" +#include "ESP_Mail_Const.h" +#include "extras/MB_Time.h" + +#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) +#define ESP_MAIL_PRINTF ESP_MAIL_DEFAULT_DEBUG_PORT.printf +#else +#define ESP_MAIL_PRINTF MailClient.printf +#endif + +#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) + +#define UPLOAD_CHUNKS_NUM 12 + +#if defined(ESP32) + +#define ESP_MAIL_MIN_MEM 70000 + +#elif defined(ESP8266) + +#define SD_CS_PIN 15 +#define ESP_MAIL_MIN_MEM 8000 + +#elif defined(MB_ARDUINO_PICO) + +#define ESP_MAIL_MIN_MEM 70000 +#define SD_CS_PIN PIN_SPI1_SS + +#endif + +#else + +#undef min +#undef max +#define ESP_MAIL_MIN_MEM 3000 +#define UPLOAD_CHUNKS_NUM 5 + +#ifdef __arm__ +// should use uinstd.h to define sbrk but Due causes a conflict +extern "C" char *sbrk(int incr); +#else // __ARM__ +extern char *__brkval; +#endif // __arm__ + +#endif + +#include "ESP_Mail_TCPClient.h" + +using namespace mb_string; + +class IMAPSession; +class SMTPSession; +class SMTP_Status; +class DownloadProgress; +class MessageData; + +#if defined(ENABLE_IMAP) + +class MessageList +{ +public: + friend class IMAPSession; + MessageList(){}; + ~MessageList() { clear(); }; + void add(int uid) + { + if (uid > 0) + _list.push_back(uid); + } + + void clear() { _list.clear(); } + +private: + _vectorImpl _list; +}; + +/* The class that provides the info of selected or opened mailbox folder */ +class SelectedFolderInfo +{ +public: + friend class ESP_Mail_Client; + friend class IMAPSession; + SelectedFolderInfo(){}; + ~SelectedFolderInfo() { clear(); }; + + /* Get the flags count for this mailbox */ + size_t flagCount(bool permanent = false) { return permanent ? _permanent_flags.size() : _flags.size(); }; + + /* Get the numbers of messages in this mailbox */ + size_t msgCount() { return _msgCount; }; + + /* Get the numbers of messages in this mailbox that recent flag was set */ + size_t recentCount() { return _recentCount; }; + + /* Get the order of message in number of message in this mailbox that reoved */ + /** + * The IMAP_Polling_Status has the properties e.g. type, messageNum, and argument. + * + * The type property is the type of status e.g.imap_polling_status_type_undefined, imap_polling_status_type_new_message, + * imap_polling_status_type_remove_message, and imap_polling_status_type_fetch_message. + * + * The messageNum property is message number or order from the total number of message that added, fetched or deleted. + * + * The argument property is the argument of commands e.g. FETCH + */ + IMAP_Polling_Status pollingStatus() { return _polling_status; }; + + /* Get the The unique identifier (UID) validity value */ + size_t uidValidity() { return _uidValidity; }; + + /* Get the predict next message UID */ + size_t nextUID() { return _nextUID; }; + + /* Get the index of first unseen message */ + size_t unseenIndex() { return _unseenMsgIndex; }; + + /* Get the highest modification sequence */ + uint64_t highestModSeq() { return strtoull(_highestModSeq.c_str(), NULL, 10); }; + + /* Check for the modification sequence supports */ + bool modSeqSupported() { return _highestModSeq.length() > 0 && !_nomodsec; }; + + /* Get the numbers of messages from search result based on the search criteria + */ + size_t searchCount() { return _searchCount; }; + + /* Get the numbers of messages to be stored in the ressult */ + size_t availableMessages() { return _availableItems; }; + + /* Get the flag argument at the specified index */ + String flag(size_t index, bool permanent = false) + { + size_t size = permanent ? _permanent_flags.size() : _flags.size(); + if (index < size) + return permanent ? _permanent_flags[index].c_str() : _flags[index].c_str(); + return ""; + } + +private: + void addFlag(const char *flag, bool permanent) + { + MB_String s = flag; + if (permanent) + _permanent_flags.push_back(s); + else + _flags.push_back(s); + }; + void clear() + { + for (size_t i = 0; i < _flags.size(); i++) + _flags[i].clear(); + _flags.clear(); + + for (size_t i = 0; i < _permanent_flags.size(); i++) + _permanent_flags[i].clear(); + _permanent_flags.clear(); + + _msgCount = 0; + _polling_status.argument.clear(); + _polling_status.messageNum = 0; + _polling_status.type = imap_polling_status_type_undefined; + _idleTimeMs = 0; + _searchCount = 0; + } + + size_t _msgCount = 0; + size_t _recentCount = 0; + size_t _uidValidity = 0; + size_t _nextUID = 0; + size_t _unseenMsgIndex = 0; + MB_String _highestModSeq; + size_t _searchCount = 0; + size_t _availableItems = 0; + unsigned long _idleTimeMs = 0; + bool _folderChanged = false; + bool _floderChangedState = false; + bool _nomodsec = false; + IMAP_Polling_Status _polling_status; + _vectorImpl _flags; + _vectorImpl _permanent_flags; +}; + +/* The class that provides the list of FolderInfo e.g. name, attributes and + * delimiter */ +class FoldersCollection +{ +public: + friend class ESP_Mail_Client; + friend class IMAPSession; + FoldersCollection(){}; + ~FoldersCollection() { clear(); }; + size_t size() { return _folders.size(); }; + + struct esp_mail_folder_info_item_t info(size_t index) + { + struct esp_mail_folder_info_item_t fd; + if (index < _folders.size()) + { + fd.name = _folders[index].name.c_str(); + fd.attributes = _folders[index].attributes.c_str(); + fd.delimiter = _folders[index].delimiter.c_str(); + } + return fd; + } + + esp_mail_folder_info_t operator[](size_t index) + { + if (index < _folders.size()) + return _folders[index]; + + return esp_mail_folder_info_t(); + } + +private: + void add(struct esp_mail_folder_info_t fd) { _folders.push_back(fd); }; + void clear() + { + for (size_t i = 0; i < _folders.size(); i++) + { + _folders[i].name.clear(); + _folders[i].attributes.clear(); + _folders[i].delimiter.clear(); + } + _folders.clear(); + } + _vectorImpl _folders; +}; + +/* The class that provides the list of IMAP_Quota_Root_Info e.g. resource name, used and limit */ +class IMAP_Quota_Roots_List +{ + friend class IMAPSession; + +public: + IMAP_Quota_Roots_List(){}; + ~IMAP_Quota_Roots_List() { clear(); }; + + size_t size() { return _quota_roots.size(); }; + + IMAP_Quota_Root_Info operator[](size_t index) + { + if (index < _quota_roots.size()) + return _quota_roots[index]; + + return IMAP_Quota_Root_Info(); + } + +private: + _vectorImpl _quota_roots; + + void add(IMAP_Quota_Root_Info v) + { + _quota_roots.push_back(v); + } + void clear() + { + _quota_roots.clear(); + } +}; + +/* The class that provides the list of IMAP_Namespaces */ +class IMAP_Namespaces +{ + friend class IMAPSession; + +public: + IMAP_Namespaces(){}; + ~IMAP_Namespaces() { clear(); }; + + size_t size() { return _ns_list.size(); }; + + IMAP_Namespace_Info operator[](size_t index) + { + if (index < _ns_list.size()) + return _ns_list[index]; + + return IMAP_Namespace_Info(); + } + +private: + _vectorImpl _ns_list; + + void add(IMAP_Namespace_Info v) + { + _ns_list.push_back(v); + } + void clear() + { + _ns_list.clear(); + } +}; + +/* The class that provides the list of IMAP_Namespaces */ +class IMAP_Rights_List +{ + friend class IMAPSession; + +public: + IMAP_Rights_List(){}; + ~IMAP_Rights_List() { clear(); }; + + size_t size() { return _rights_list.size(); }; + + IMAP_Rights_Info operator[](size_t index) + { + if (index < _rights_list.size()) + return _rights_list[index]; + + return IMAP_Rights_Info(); + } + +private: + _vectorImpl _rights_list; + + void add(IMAP_Rights_Info v) + { + _rights_list.push_back(v); + } + void clear() + { + _rights_list.clear(); + } +}; + +typedef struct esp_mail_imap_nanespace_list_t +{ + IMAP_Namespaces personal_namespaces; + IMAP_Namespaces other_users_namespaces; + IMAP_Namespaces shared_namespaces; +} IMAP_Namespaces_List; + +/* The class that provides the status of message feching and searching */ +class IMAP_Status +{ +public: + IMAP_Status(); + ~IMAP_Status(); + const char *info(); + bool success(); + void empty(); + friend class IMAPSession; + + MB_String _info; + bool _success = false; +}; + +typedef void (*imapStatusCallback)(IMAP_Status); +typedef void (*imapResponseCallback)(IMAP_Response); +typedef void (*MIMEDataStreamCallback)(MIME_Data_Stream_Info); +typedef void (*imapCharacterDecodingCallback)(IMAP_Decoding_Info *); + +#else + +enum esp_mail_imap_read_capability_types +{ + esp_mail_imap_read_capability_maxType +}; + +// Dummy class used in template functions (errorStatusCB). +class IMAPSession +{ +public: + struct IMAP_Status + { + public: + const char *info() { return ""; }; + bool success() { return false; }; + void empty(); + MB_String _info; + bool _success = false; + }; + + typedef void (*imapStatusCallback)(IMAP_Status); + MB_String errorReason() { return ""; } + bool _debug; + imapStatusCallback _statusCallback = nullptr; + void *_customCmdResCallback = nullptr; + esp_mail_session_type _sessionType = esp_mail_session_type_imap; + + struct esp_mail_imap_response_status_t + { + int errorCode = 0; + MB_String tag; + MB_String text; + MB_String status; + bool completed = false; + }; + + esp_mail_imap_response_status_t _responseStatus; + IMAP_Status _cbData; +}; +#endif + +#if defined(ENABLE_SMTP) + +/* The SMTP message class */ +class SMTP_Message +{ +public: + SMTP_Message() + { + text.content_type = "text/plain"; + html.content_type = "text/html"; + }; + + ~SMTP_Message() { clear(); }; + + void resetAttachItem(SMTP_Attachment &att) + { + att.blob.size = 0; + att.blob.data = nullptr; + att.file.path.clear(); + att.file.storage_type = esp_mail_file_storage_type_none; + att.descr.name.clear(); + att.descr.filename.clear(); + att.descr.transfer_encoding.clear(); + att.descr.content_encoding.clear(); + att.descr.mime.clear(); + att.descr.content_id.clear(); + att._int.att_type = esp_mail_att_type_none; + att._int.index = 0; + att._int.msg_uid = 0; + att._int.flash_blob = false; + att._int.xencoding = esp_mail_msg_xencoding_none; + att._int.parallel = false; + att._int.cid.clear(); + } + + void clear() + { + sender.name.clear(); + sender.email.clear(); + subject.clear(); + text.charSet.clear(); + text.content.clear(); + text.content_type.clear(); + text.embed.enable = false; + html.charSet.clear(); + html.content.clear(); + html.content_type.clear(); + html.embed.enable = false; + response.reply_to.clear(); + response.notify = esp_mail_smtp_notify::esp_mail_smtp_notify_never; + priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; + + for (size_t i = 0; i < _rcp.size(); i++) + { + _rcp[i].name.clear(); + _rcp[i].email.clear(); + } + + for (size_t i = 0; i < _cc.size(); i++) + _cc[i].email.clear(); + + for (size_t i = 0; i < _bcc.size(); i++) + _bcc[i].email.clear(); + + for (size_t i = 0; i < _hdr.size(); i++) + _hdr[i].clear(); + + for (size_t i = 0; i < _att.size(); i++) + { + _att[i].descr.filename.clear(); + _att[i].blob.data = nullptr; + _att[i].descr.mime.clear(); + _att[i].descr.name.clear(); + _att[i].blob.size = 0; + _att[i].descr.transfer_encoding.clear(); + _att[i].file.path.clear(); + _att[i].file.storage_type = esp_mail_file_storage_type_none; + } + + for (size_t i = 0; i < _parallel.size(); i++) + { + _parallel[i].descr.filename.clear(); + _parallel[i].blob.data = nullptr; + _parallel[i].descr.mime.clear(); + _parallel[i].descr.name.clear(); + _parallel[i].blob.size = 0; + _parallel[i].descr.transfer_encoding.clear(); + _parallel[i].file.path.clear(); + _parallel[i].file.storage_type = esp_mail_file_storage_type_none; + } + + _rcp.clear(); + _cc.clear(); + _bcc.clear(); + _hdr.clear(); + _att.clear(); + _parallel.clear(); + } + + /** Clear all the inline images + */ + void clearInlineimages() + { + for (int i = (int)_att.size() - 1; i >= 0; i--) + { + if (_att[i]._int.att_type == esp_mail_att_type_inline) + _att.erase(_att.begin() + i); + } + }; + + /* Clear all the attachments */ + void clearAttachments() + { + for (int i = (int)_att.size() - 1; i >= 0; i--) + { + if (_att[i]._int.att_type == esp_mail_att_type_attachment) + _att.erase(_att.begin() + i); + } + + for (int i = (int)_parallel.size() - 1; i >= 0; i--) + _parallel.erase(_parallel.begin() + i); + }; + + /** Clear all rfc822 message attachment + */ + void clearRFC822Messages() + { + for (int i = (int)_rfc822.size() - 1; i >= 0; i--) + { + _rfc822[i].clear(); + _rfc822.erase(_rfc822.begin() + i); + } + }; + + /** Clear the primary recipient mailboxes + */ + void clearRecipients() { _rcp.clear(); }; + + /** Clear the Carbon-copy recipient mailboxes + */ + void clearCc() { _cc.clear(); }; + + /** Clear the Blind-carbon-copy recipient mailboxes + */ + void clearBcc() { _bcc.clear(); }; + + /** Clear the custom message headers + */ + void clearHeader() { _hdr.clear(); }; + + /** Add attachment to the message + * + * @param att The SMTP_Attachment data item + */ + void addAttachment(SMTP_Attachment &att) + { + att._int.att_type = esp_mail_att_type_attachment; + att._int.parallel = false; + att._int.flash_blob = true; + _att.push_back(att); + }; + + /** Add parallel attachment to the message + * + * @param att The SMTP_Attachment data item + */ + void addParallelAttachment(SMTP_Attachment &att) + { + att._int.att_type = esp_mail_att_type_attachment; + att._int.parallel = true; + att._int.flash_blob = true; + _parallel.push_back(att); + }; + + /** Add inline image to the message + * + * @param att The SMTP_Attachment data item + */ + void addInlineImage(SMTP_Attachment &att) + { + att._int.flash_blob = true; + att._int.parallel = false; + att._int.att_type = esp_mail_att_type_inline; + att._int.cid = random(2000, 4000); + _att.push_back(att); + }; + + /** Add rfc822 message to the message + * + * @param msg The RFC822_Message class object + */ + void addMessage(SMTP_Message &msg) { _rfc822.push_back(msg); } + + /** Add the primary recipient mailbox to the message + * + * @param name The name of primary recipient + * @param email The Email address of primary recipient + */ + template + void addRecipient(T1 name, T2 email) + { + struct esp_mail_address_info_t rcp; + rcp.name = toStringPtr(name); + rcp.email = toStringPtr(email); + _rcp.push_back(rcp); + }; + + /** Add Carbon-copy recipient mailbox + * + * @param email The Email address of the secondary recipient + */ + template + void addCc(T email) + { + struct esp_mail_address_info_t cc; + cc.email = toStringPtr(email); + _cc.push_back(cc); + }; + + /** Add Blind-carbon-copy recipient mailbox + * + * @param email The Email address of the tertiary recipient + */ + template + void addBcc(T email) + { + struct esp_mail_address_info_t bcc; + bcc.email = toStringPtr(email); + _bcc.push_back(bcc); + }; + + /** Add the custom header to the message + * + * @param hdr The header name and value + */ + template + void addHeader(T hdr) + { + _hdr.push_back(MB_String().setPtr(toStringPtr(hdr))); + }; + + /* The message author config */ + struct esp_mail_address_info_t author; + + /* The message sender (agent or teansmitter) config */ + struct esp_mail_address_info_t sender; + + /* The topic of message */ + MB_String subject; + + /* The message type */ + byte type = esp_mail_msg_type_none; + + /* The PLAIN text message */ + esp_mail_plain_body_t text; + + /* The HTML text message */ + esp_mail_html_body_t html; + + /* The response config */ + struct esp_mail_smtp_msg_response_t response; + + /* The priority of the message */ + esp_mail_smtp_priority priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; + + /* The enable options */ + struct esp_mail_smtp_enable_option_t enable; + + /* The message from config */ + struct esp_mail_address_info_t from; + + /* The message identifier */ + MB_String messageID; + + /* The keywords or phrases, separated by commas */ + MB_String keywords; + + /* The comments about message */ + MB_String comments; + + /* The date of message */ + MB_String date; + + /* The field that contains the parent's message ID of the message to which this one is a reply */ + MB_String in_reply_to; + + /* The field that contains the parent's references (if any) and followed by the parent's message ID (if any) of the message to which this one is a reply */ + MB_String references; + + /* The timestamp value to replace in text */ + esp_mail_timestamp_value_t timestamp; + +private: + friend class ESP_Mail_Client; + _vectorImpl _rcp; + _vectorImpl _cc; + _vectorImpl _bcc; + _vectorImpl _hdr; + _vectorImpl _att; + _vectorImpl _parallel; + _vectorImpl _rfc822; +}; + +class SMTP_Status +{ +public: + friend class SMTPSession; + friend class ESP_Mail_Client; + + SMTP_Status(); + ~SMTP_Status(); + const char *info(); + bool success(); + void empty(); + size_t completedCount(); + size_t failedCount(); + +private: + MB_String _info; + bool _success = false; + size_t _sentSuccess = 0; + size_t _sentFailed = 0; +}; + +typedef void (*smtpStatusCallback)(SMTP_Status); +typedef void (*smtpResponseCallback)(SMTP_Response); + +#endif + +class ESP_Mail_Client +{ + +public: + ESP_Mail_Client() + { + mbfs = new MB_FS(); + }; + + ~ESP_Mail_Client() + { + if (mbfs) + delete mbfs; + mbfs = nullptr; + + wifi.clearAP(); + }; + +#if defined(ENABLE_SMTP) + /** Sending Email through the SMTP server + * + * @param smtp The pointer to SMTP session object which holds the data and the + * TCP client. + * @param msg The pointer to SMTP_Message class which contains the header, + * body, and attachments. + * @param closeSession The option to Close the SMTP session after sent. + * @return The boolean value indicates the success of operation. + */ + bool sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession = true); +#endif + +#if defined(ENABLE_SMTP) && defined(ENABLE_IMAP) + /** Append message to the mailbox + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param msg The pointer to SMTP_Message class which contains the header, + * body, and attachments. + * @param lastAppend The last message to append (optional). In case of MULTIAPPEND extension + * is supported, set this to false will append messages in single APPEND command. + * @param flags The flags to set to this message (optional). + * @param dateTime The date/time to set to this message (optional). + * @return The boolean value indicates the success of operation. + */ + template + bool appendMessage(IMAPSession *imap, SMTP_Message *msg, bool lastAppend = true, T1 flags = "", T2 dateTime = "") { return mAppendMessage(imap, msg, lastAppend, toStringPtr(flags), toStringPtr(dateTime)); } +#endif + +#if defined(ENABLE_IMAP) + /** Reading Email through IMAP server. + * + * @param imap The pointer to IMAP session object which holds the data and + the TCP client. + + * @param closeSession The option to close the IMAP session after fetching or + searching the Email. + * @return The boolean value indicates the success of operation. + */ + bool readMail(IMAPSession *imap, bool closeSession = true); + + /** Set the argument to the Flags for the specified message. + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param msgUID The UID of the message. + * @param flags The flag list to set. + * @param closeSession The option to close the IMAP session after set flag. + * @param silent The option to ignore the response. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool setFlag(IMAPSession *imap, int msgUID, T flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(msgUID), toStringPtr(flags), esp_mail_imap_store_flag_type_set, closeSession, silent, true, modsequence); } + + /** Set the argument to the Flags for the specified message. + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. + * @param UID The option for sequenceSet whether it is UID or message sequence number. + * @param flags The flag list to set. + * @param closeSession The option to close the IMAP session after set flag. + * @param silent The option to ignore the response. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool setFlag(IMAPSession *imap, T1 sequenceSet, bool UID, T2 flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(sequenceSet), toStringPtr(flags), esp_mail_imap_store_flag_type_set, closeSession, silent, UID, modsequence); } + + /** Add the argument to the Flags for the specified message. + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param msgUID The UID of the message. + * @param flags The flag list to add. + * @param closeSession The option to close the IMAP session after add flag. + * @param silent The option to ignore the response. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool addFlag(IMAPSession *imap, int msgUID, T flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(msgUID), toStringPtr(flags), esp_mail_imap_store_flag_type_add, closeSession, silent, true, modsequence); } + + /** Add the argument to the Flags for the specified message. + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. + * @param UID The option for sequenceSet whether it is UID or message sequence number. + * @param flags The flag list to add. + * @param closeSession The option to close the IMAP session after set flag. + * @param silent The option to ignore the response. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool addFlag(IMAPSession *imap, T1 sequenceSet, bool UID, T2 flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(sequenceSet), toStringPtr(flags), esp_mail_imap_store_flag_type_add, closeSession, silent, UID, modsequence); } + + /** Remove the argument from the Flags for the specified message. + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param msgUID The UID of the message that flags to be removed. + * @param flags The flag list to remove. + * @param closeSession The option to close the IMAP session after remove flag. + * @param silent The option to ignore the response. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool removeFlag(IMAPSession *imap, int msgUID, T flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(msgUID), toStringPtr(flags), esp_mail_imap_store_flag_type_remove, closeSession, silent, true, modsequence); } + + /** Remove the argument from the Flags for the specified message. + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. + * @param UID The option for sequenceSet whether it is UID or message sequence number. + * @param flags The flag list to remove. + * @param closeSession The option to close the IMAP session after set flag. + * @param silent The option to ignore the response. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool removeFlag(IMAPSession *imap, T1 sequenceSet, bool UID, T2 flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(sequenceSet), toStringPtr(flags), esp_mail_imap_store_flag_type_remove, closeSession, silent, UID, modsequence); } + +#endif + + /** Reconnect WiFi or network if lost connection. + * + * @param reconnect The boolean to set/unset WiFi AP reconnection. + */ + void networkReconnect(bool reconnect); + + /* Obsoleted */ + void setUDPClient(void *client, float gmtOffset) {} + + /** Clear all WiFi access points assigned. + * + */ + void clearAP(); + + /** Add WiFi access point for non-ESP device to resume WiFi connection. + * + * @param ssid The WiFi SSID. + * @param password The WiFi password. + */ + void addAP(const String &ssid, const String &password); + + /** + * Formatted printing on debug port. + * + */ + void printf(const char *format, ...); + +#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) + + /** Initiate SD card with SPI port configuration. + * + * @param ss SPI Chip/Slave Select pin. + * @param sck SPI Clock pin. + * @param miso SPI MISO pin. + * @param mosi SPI MOSI pin. + * @param frequency The SPI frequency + * @return Boolean type status indicates the success of the operation. + */ + bool sdBegin(int8_t ss = -1, int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1, uint32_t frequency = 4000000); + +#if defined(ESP8266) || defined(MB_ARDUINO_PICO) + + /** Initiate SD card with SD FS configurations (ESP8266 only). + * + * @param ss SPI Chip/Slave Select pin. + * @param sdFSConfig The pointer to SDFSConfig object (ESP8266 only). + * @return Boolean type status indicates the success of the operation. + */ + bool sdBegin(SDFSConfig *sdFSConfig); + +#endif + +#if defined(ESP32) + /** Initiate SD card with chip select and SPI configuration (ESP32 only). + * + * @param ss SPI Chip/Slave Select pin. + * @param spiConfig The pointer to SPIClass object for SPI configuartion. + * @param frequency The SPI frequency. + * @return Boolean type status indicates the success of the operation. + */ + bool sdBegin(int8_t ss, SPIClass *spiConfig = nullptr, uint32_t frequency = 4000000); +#endif + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + /** Initiate SD card with SdFat SPI and pins configurations (with SdFat included only). + * + * @param sdFatSPIConfig The pointer to SdSpiConfig object for SdFat SPI configuration. + * @param ss SPI Chip/Slave Select pin. + * @param sck SPI Clock pin. + * @param miso SPI MISO pin. + * @param mosi SPI MOSI pin. + * @return Boolean type status indicates the success of the operation. + */ + bool sdBegin(SdSpiConfig *sdFatSPIConfig, int8_t ss = -1, int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1); + + /** Initiate SD card with SdFat SDIO configuration (with SdFat included only). + * + * @param sdFatSDIOConfig The pointer to SdioConfig object for SdFat SDIO configuration. + * @return Boolean type status indicates the success of the operation. + */ + bool sdBegin(SdioConfig *sdFatSDIOConfig); + +#endif + +#endif + +#if defined(ESP32) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD_MMC) + /** Initialize the SD_MMC card (ESP32 only). + * + * @param mountpoint The mounting point. + * @param mode1bit Allow 1 bit data line (SPI mode). + * @param format_if_mount_failed Format SD_MMC card if mount failed. + * @return The boolean value indicates the success of operation. + */ + bool sdMMCBegin(const char *mountpoint = "/sdcard", bool mode1bit = false, bool format_if_mount_failed = false); +#endif + + /** Get free Heap memory. + * + * @return Free memory amount in byte. + */ + int getFreeHeap(); + + /** Get base64 encode string. + * + * @return String of base64 encoded string. + */ + template + String toBase64(T str) { return mGetBase64(toStringPtr(str)).c_str(); } + + MB_Time Time; + +#if defined(ENABLE_IMAP) + + // Get encoding type from character set string + esp_mail_char_decoding_scheme getEncodingFromCharset(const char *enc); + + // Decode Latin1 to UTF-8 + int decodeLatin1_UTF8(unsigned char *out, int *outlen, const unsigned char *in, int *inlen); + + // Decode TIS620 to UTF-8 + void decodeTIS620_UTF8(char *out, const char *in, size_t len); + + // handle rfc2047 Q (quoted printable) and B (base64) decodings + RFC2047_Decoder RFC2047Decoder; + +#endif + +private: + friend class SMTPSession; + friend class IMAPSession; + + MB_FS *mbfs = nullptr; + bool timeStatus = false; + time_t ts = 0; + bool networkAutoReconnect = true; + volatile bool networkStatus = false; + esp_mail_wifi_credentials_t wifi; + bool timezoneEnvSet = false; + + IMAPSession *imap = nullptr; + bool calDataLen = false; + uint32_t dataLen = 0; + uint32_t imap_ts = 0; + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + + unsigned long _lastReconnectMillis = 0; + uint16_t _reconnectTimeout = ESP_MAIL_NETWORK_RECONNECT_TIMEOUT; + + // Resume network connection + void resumeNetwork(ESP_Mail_TCPClient *client); + + // Get the CRLF ending string w/wo CRLF included. Return the size of string read and the current octet read. + int readLine(ESP_Mail_TCPClient *client, char *buf, int bufLen, bool withLineBreak, int &count, bool &ovf, unsigned long timeoutSec, bool &isTimeout); + + // readLine with overflow handling. + template + bool readResponse(T sessionPtr, char *buf, int bufLen, int &readLen, bool withLineBreak, int &count, MB_String &ovfBuf); + + // Network reconnection and return the connection status + template + bool reconnect(T sessionPtr, unsigned long dataTime = 0, bool downloadRequest = false); + + // Send callback + template + void sendCB(T sessionPtr, PGM_P info = "", bool prependCRLF = false, bool success = false); + + // PGM string replacement + void strReplaceP(MB_String &buf, PGM_P key, PGM_P value); + + // Check for OAuth log in error response + bool isOAuthError(char *buf, int bufLen, int &chunkIdx, int ofs); + + // Get SASL XOAUTH2 string + MB_String getXOAUTH2String(const MB_String &email, const MB_String &accessToken); + + // Send error callback + template + void sendErrorCB(T sessionPtr, PGM_P info, bool prependCRLF = false, bool success = false); + + // Send the error status callback + template + void errorStatusCB(T1 sessionPtr, T2 sessionPtr2, int error, bool clearLastStatus); + + // Check response callback was assigned? + template + bool isResponseCB(T sessionPtr); + + // Print library info + template + void printLibInfo(T sessionPtr); + + // Begin server connection + template + bool beginConnection(Session_Config *session_config, T sessionPtr, bool secureMode); + + // Prepare system time + template + bool prepareTime(Session_Config *session_config, T sessionPtr); + + // Check for session. Close session If not ready. + template + bool sessionReady(T sessionPtr); + + // Set cert data + void setCert(Session_Config *session_cfg, const char *ca); + // Set secure data + void setSecure(ESP_Mail_TCPClient &client, Session_Config *session_config); + + void appendMultipartContentType(MB_String &buf, esp_mail_multipart_types type, const char *boundary); + + String errorReason(bool isSMTP, int errorCode, const char *msg); + + // Close TCP session and clear auth_capability, read/send_capability, connected and authenticate statuses + template + void closeTCPSession(T sessionPtr); + + // Get and set timezone + void getSetTimezoneEnv(const char *TZ_file, const char *TZ_Var); + + // Get TCP connected status + template + bool connected(T sessionPtr); + + // Get the memory allocation block size of multiple of 4 + size_t getReservedLen(size_t len); + + // Check Email for valid format + bool validEmail(const char *s); + + // Get random UID for SMTP content ID and IMAP attachment default file name + char *getRandomUID(); + + // Spit the string into token strings + void splitToken(const char *str, _vectorImpl &tk, const char *delim); + + // Decode base64 encoded string + unsigned char *decodeBase64(const unsigned char *src, size_t len, size_t *out_len); + + // Decode base64 encoded string + MB_String encodeBase64Str(const unsigned char *src, size_t len); + + // Decode base64 encoded string + MB_String encodeBase64Str(uint8_t *src, size_t len); + + // Decode base64 encoded string + MB_String mGetBase64(MB_StringPtr str); + + // Sub string + char *subStr(const char *buf, PGM_P beginToken, PGM_P endToken, int beginPos, int endPos = 0, bool caseSensitive = true); + + // Find string + int strpos(const char *haystack, const char *needle, int offset, bool caseSensitive = true); + + // Memory allocation + template + T allocMem(size_t size, bool clear = true); + + // Memory deallocation + void freeMem(void *ptr); + + // PGM string compare + bool strcmpP(const char *buf, int ofs, PGM_P beginToken, bool caseSensitive = true); + + // Find PGM string + int strposP(const char *buf, PGM_P beginToken, int ofs, bool caseSensitive = true); + + // Memory allocation for PGM string + char *strP(PGM_P pgm); + + // Memory allocation for PGM lower case string + char *strP2Lower(PGM_P pgm); + + // Set or sync device system time with NTP server + // Do not modify or remove + void setTime(const char *TZ_Var, const char *TZ_file, bool wait, bool debugProgress); + + // Set the device time zone via TZ environment variable + void setTimezone(const char *TZ_Var, const char *TZ_file); + + // Get TZ environment variable from file + // Do not modify or remove + void getTimezone(const char *TZ_file, MB_String &out); + + // Check the session existent + template + bool sessionExisted(T sessionPtr); + + // Send SMTP/IMAP callback + template + void sendCallback(T sessionPtr, PGM_P info, bool prependCRLF, bool success); + + // Send IMAP/SMTP response callback and print debug message + template + void printDebug(T sessionPtr, PGM_P cbMsg, PGM_P dbMsg, esp_mail_debug_tag_type type, bool prependCRLF, bool success); + + // Get header content from response based on the field name + bool getHeader(const char *buf, PGM_P beginToken, MB_String &out, bool caseSensitive); + + // Append header field to buffer + void appendHeaderField(MB_String &buf, const char *name, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type = esp_mail_string_mark_type_none); + + // Append SMTP address header field + void appendAddressHeaderField(MB_String &buf, esp_mail_address_info_t &source, esp_mail_rfc822_header_field_types type, bool header, bool comma, bool newLine); + + // Append header field name to buffer + void appendHeaderName(MB_String &buf, const char *name, bool clear = false, bool lowercase = false, bool space = true); + + // Append lowercase string to buffer + void appendLowerCaseString(MB_String &buf, PGM_P value, bool clear = false); + + // Append header field property to buffer + void appendHeaderProp(MB_String &buf, PGM_P prop, const char *value, bool &firstProp, bool lowerCase, bool isString, bool newLine); + + // Append quote string to buffer + void appendString(MB_String &buf, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type = esp_mail_string_mark_type_none); + + // Append list to buffer + template + void appendList(MB_String &buf, _vectorImpl &list); + + // Append space to buffer + void appendSpace(MB_String &buf); + + // Append space to buffer after value + void appendSpace(MB_String &buf, bool withTag, PGM_P value); + + // Append space to buffer after values + void appendSpace(MB_String &buf, bool withTag, int nunArgs, ...); + + // Append space to buffer before value + void prependSpace(MB_String &buf, PGM_P value); + + // Append dot to buffer + void appendDot(MB_String &buf); + + // Append IMAP string key value list + void appendImap4KeyValue(MB_String &buf, PGM_P key, PGM_P value); + + // Append dot to buffer before value + void prependDot(MB_String &buf, PGM_P value); + + // Join 2 strings to buffer with space + void joinStringSpace(MB_String &buf, bool withTag, int nunArgs, ...); + + // Join 2 strings to buffer with dot + void joinStringDot(MB_String &buf, int nunArgs, ...); + + // Append mask(*) string to buffer + void maskString(MB_String &buf, int len); + + // Append domain to buffer + void appendDomain(MB_String &buf, const char *domain); + + // Append embedded message header to buffer + void appendEmbedMessage(MB_String &buf, esp_mail_message_body_t &body, bool isHtml); + + // Append crlf to buffer + void appendNewline(MB_String &buf); + + // Append tag to the buffer + void appendTagSpace(MB_String &buf, PGM_P tag = NULL); + + // Print newline + void debugPrintNewLine(); + + // Send newline to callback + template + void callBackSendNewLine(T sessionPtr, bool success); + + // Print progress bar + void printProgress(int progress, int &lastProgress); + + // Get file extension with dot from MIME string + void getExtfromMIME(const char *mime, MB_String &ext); + + // Prepare ports + void preparePortFunction(Session_Config *session_config, bool isSMTP, bool &secure, bool &secureMode, bool &ssl); + + // Get operation config based on port and its protocol + void getPortFunction(uint16_t port, struct esp_mail_ports_functions &ports_functions, bool &secure, bool &secureMode, bool &ssl, bool &starttls); + +#endif + +#if defined(ENABLE_SMTP) + + // Encode Quoted Printable string + void encodeQP(const char *buf, char *out); + + // Add the soft line break to the long text line rfc 3676 + void formatFlowedText(MB_String &content); + + // Insert soft break + void softBreak(MB_String &content, const char *quoteMarks); + + // Get content type (MIME) from file extension + void getMIME(const char *ext, MB_String &mime); + + // Get content type (MIME) from file name + void mimeFromFile(const char *name, MB_String &mime); + + // Get MIME boundary string + MB_String getMIMEBoundary(size_t len); + + // Send Email function + bool mSendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession = true); + + // SMTP send data + size_t smtpSend(SMTPSession *smtp, PGM_P data, bool newline = false); + + // SMTP send data + size_t smtpSend(SMTPSession *smtp, int data, bool newline = false); + + // SMTP send data + size_t smtpSend(SMTPSession *smtp, uint8_t *data, size_t size); + + // Handle the error by sending callback and close session + bool handleSMTPError(SMTPSession *smtp, int err, bool ret = false); + + // Send parallel attachment RFC1521 + bool sendParallelAttachments(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary); + + // Send attachment + bool sendAttachments(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, bool parallel = false); + + // Send message content + bool sendContent(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG); + + // Send imap or smtp callback + void altSendCallback(SMTPSession *smtp, PGM_P cbMsg, PGM_P dbMsg, esp_mail_debug_tag_type type, bool prependCRLF, bool success); + + // Send message data + bool sendMSGData(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG); + + // Send RFC 822 message + bool sendRFC822Msg(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, bool closeSession, bool rfc822MSG); + + // Get RFC 822 message envelope + void getRFC822MsgEnvelope(SMTPSession *smtp, SMTP_Message *msg, MB_String &buf); + + // Append boundary string to buffer + void appendBoundaryString(MB_String &buf, const char *value, bool endMark, bool newLine); + + // Send BDAT command RFC 3030 + bool sendBDAT(SMTPSession *smtp, SMTP_Message *msg, int len, bool last); + + // Get transfer encoding + void getXEncoding(esp_mail_msg_xencoding &xencoding, const char *enc); + + // Set the unencoded xencoding enum for html, text and attachment from its xencoding string + void checkUnencodedData(SMTPSession *smtp, SMTP_Message *msg); + + // Check imap or smtp has callback set + bool altIsCB(SMTPSession *smtp); + + // Check imap or smtp has debug set + bool altIsDebug(SMTPSession *smtp); + + // Send BLOB attachment + bool sendBlobAttachment(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att); + + // Send file content + bool sendFile(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att); + + // Send imap or smtp storage error callback + void altSendStorageErrorCB(SMTPSession *smtp, int err); + + // Open file to send an attachment + bool openFileRead(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att, MB_String &buf, const MB_String &boundary, bool inlined); + + // Open text file or html file for to send message + bool openFileRead2(SMTPSession *smtp, SMTP_Message *msg, const char *path, esp_mail_file_storage_type storageType); + + // Send inline attachments + bool sendInline(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, byte type); + + // Send storage error callback + void sendStorageNotReadyError(SMTPSession *smtp, esp_mail_file_storage_type storageType); + + // Append message + bool mAppendMessage(IMAPSession *imap, SMTP_Message *msg, bool lastAppend, MB_StringPtr flags, MB_StringPtr dateTime); + + // Get numbers of attachment based on type + size_t numAtt(SMTPSession *smtp, esp_mail_attach_type type, SMTP_Message *msg); + + // Check for valid recipient Email + bool checkEmail(SMTPSession *smtp, SMTP_Message *msg); + + // Send text parts MIME message + bool sendPartText(SMTPSession *smtp, SMTP_Message *msg, byte type, const char *boundary); + + // Alternative string data sending to send imap APPEND data or smtp data + bool altSendData(MB_String &s, bool newLine, SMTPSession *smtp, SMTP_Message *msg, bool addSendResult, bool getResponse, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode); + + // Alternative bytes data sending to send imap APPEND data or smtp data + bool altSendData(uint8_t *data, size_t size, SMTPSession *smtp, SMTP_Message *msg, bool addSendResult, bool getResponse, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode); + + // Send MIME message + bool sendMSG(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary); + + // Get an attachment part header string + void getAttachHeader(MB_String &header, const MB_String &boundary, SMTP_Attachment *attach, size_t size, bool isInline); + + // Get RFC 8222 part header string + void getRFC822PartHeader(SMTPSession *smtp, MB_String &header, const MB_String &boundary); + + // Send BLOB type text part or html part MIME message + bool sendBlobBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type); + + // Send file type text part or html part MIME message + bool sendFileBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type); + + // Base64 and QP encodings for text and html messages and replace embeded attachment file name with content ID + void encodingText(SMTPSession *smtp, SMTP_Message *msg, uint8_t type, MB_String &content); + + // Blob or Stream available + int chunkAvailable(SMTPSession *smtp, esp_mail_smtp_send_base64_data_info_t &data_info); + + // Read chunk data of blob or file + int getChunk(SMTPSession *smtp, esp_mail_smtp_send_base64_data_info_t &data_info, unsigned char *rawChunk, bool base64); + + // Terminate chunk reading + void closeChunk(esp_mail_smtp_send_base64_data_info_t &data_info); + + // Get base64 encoded buffer or raw buffer + void getBuffer(bool base64, uint8_t *out, uint8_t *in, int &encodedCount, int &bufIndex, bool &dataReady, int &size, size_t chunkSize); + + // Send blob or file as base64 encoded chunk + bool sendBase64(SMTPSession *smtp, SMTP_Message *msg, esp_mail_smtp_send_base64_data_info_t &data_info, bool base64, bool report); + + // Save sending logs to file + void saveSendingLogs(SMTPSession *smtp, SMTP_Message *msg, bool result); + + // Get imap or smtp report progress var pointer + uint32_t altProgressPtr(SMTPSession *smtp); + + // Get SMTP response status (statusCode and text) + void getResponseStatus(const char *buf, esp_mail_smtp_status_code statusCode, int beginPos, struct esp_mail_smtp_response_status_t &status); + + // Parse SMTP authentication capability + void parseAuthCapability(SMTPSession *smtp, char *buf); + + // Add the sending result + bool addSendingResult(SMTPSession *smtp, SMTP_Message *msg, bool result, bool showResult); + + // Handle SMTP server authentication + bool smtpAuth(SMTPSession *smtp, bool &ssl); + + // Handle SMTP response + bool handleSMTPResponse(SMTPSession *smtp, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode); + + // Print the upload status to the debug port + void uploadReport(const char *filename, uint32_t pgAddr, int progress); + + // Get MB_FS object pointer + MB_FS *getMBFS(); + + // Set device system time + int setTimestamp(time_t ts); +#endif + +#if defined(ENABLE_IMAP) + + // Check if child part (part number string) is a member of the parent part (part number string) + // part number string format: .. + bool multipartMember(const MB_String &parent, const MB_String &child); + + // Decode string + int decodeChar(const char *s); + + // Decode Quoted Printable string + void decodeQP_UTF8(const char *buf, char *out); + + // Actually not decode because 7bit string is enencode string unless prepare valid 7bit string and do qp decoding + char *decode7Bit_UTF8(char *buf); + + // Actually not decode because 8bit string is enencode string unless prepare valid 8bit string + char *decode8Bit_UTF8(char *buf); + + // Decode string base on encoding + void decodeString(IMAPSession *imap, MB_String &string, const char *enc = ""); + + /** + * Encode a code point using UTF-8 + * + * @author Ondřej Hruška + * https://gist.github.com/MightyPork/52eda3e5677b4b03524e40c9f0ab1da5 + * + * @license MIT + * + * @param out - output buffer (min 5 characters), will be 0-terminated + * @param utf - code point 0-0x10FFFF + * @return number of bytes on success, 0 on failure (also produces U+FFFD, which uses 3 bytes) + */ + int encodeUnicode_UTF8(char *out, uint32_t utf); + + // Append headers fetch command + void appendHeadersFetchCommand(IMAPSession *imap, MB_String &cmd, int index, bool debug); + + // Append rfc822 headers fetch command + void appendRFC822HeadersFetchCommand(MB_String &cmd); + + // Get multipart MIME fetch command + bool getMultipartFechCmd(IMAPSession *imap, int msgIdx, MB_String &partText); + + // Fetch multipart MIME body header + bool fetchMultipartBodyHeader(IMAPSession *imap, int msgIdx); + + // Print body part fetching debug + void printBodyPartFechingDubug(IMAPSession *imap, const char *partNum, bool multiLevel); + + // Handle IMAP server authentication + bool imapAuth(IMAPSession *imap, bool &ssl); + + // Send IMAP command + bool sendFetchCommand(IMAPSession *imap, int msgIndex, esp_mail_imap_command cmdCase); + + // Send data + size_t imapSend(IMAPSession *imap, PGM_P data, bool newline = false); + + // Send data + size_t imapSend(IMAPSession *imap, int data, bool newline = false); + + // Send data + size_t imapSend(IMAPSession *imap, uint8_t *data, size_t size); + + // Log out + bool imapLogout(IMAPSession *imap); + + // Send storage error callback + void sendStorageNotReadyError(IMAPSession *imap, esp_mail_file_storage_type storageType); + + // Parse search response + int parseSearchResponse(IMAPSession *imap, esp_mail_imap_response_data &res, PGM_P tag, const char *key); + + // Parse header state + bool parseHeaderField(IMAPSession *imap, const char *buf, PGM_P beginToken, bool caseSensitive, struct esp_mail_message_header_t &header, int &headerState, int state); + + // Parse header response + void parseHeaderResponse(IMAPSession *imap, esp_mail_imap_response_data &res, bool caseSensitive = true); + + // Set the header based on state parsed + void collectHeaderField(IMAPSession *imap, char *buf, struct esp_mail_message_header_t &header, int state); + + // Get decoded header + bool getDecodedHeader(IMAPSession *imap, const char *buf, PGM_P beginToken, MB_String &out, bool caseSensitive); + + // Check attachment for firmware file + void checkFirmwareFile(IMAPSession *imap, const char *filename, struct esp_mail_message_part_info_t &part, bool defaultSize = false); + + // Parse part header response + void parsePartHeaderResponse(IMAPSession *imap, esp_mail_imap_response_data &res, bool caseSensitive = true); + + // Count char in string + int countChar(const char *buf, char find); + + // Store the value to string via its the pointer + bool storeStringPtr(IMAPSession *imap, uint32_t addr, MB_String &value, const char *buf); + + // Get part header properties + bool getPartHeaderProperties(IMAPSession *imap, const char *buf, PGM_P p, PGM_P e, bool num, MB_String &value, MB_String &old_value, esp_mail_char_decoding_scheme &scheme, bool caseSensitive); + + // Url decode for UTF-8 encoded header text + char *urlDecode(const char *str); + + // Reset the pointer to multiline response keeping string + void resetStringPtr(struct esp_mail_message_part_info_t &part); + + // Get current part + struct esp_mail_message_part_info_t *cPart(IMAPSession *imap); + + // Get current header + struct esp_mail_message_header_t *cHeader(IMAPSession *imap); + +#if !defined(MB_USE_STD_VECTOR) + // Decending sort + void numDecSort(_vectorImpl &arr); +#endif + + // Handle IMAP response + bool handleIMAPResponse(IMAPSession *imap, int errCode, bool closeSession); + + // Print the file download status via debug port + void downloadReport(IMAPSession *imap, int progress); + + // Print the message fetch status via debug port + void fetchReport(IMAPSession *imap, int progress, bool html); + + // Print the message search status via debug port + void searchReport(IMAPSession *imap, int progress); + + // Get current message num item + struct esp_mail_imap_msg_num_t cMSG(IMAPSession *imap); + + // Get current message Index + int cIdx(IMAPSession *imap); + + // Get IMAP response status e.g. OK, NO and Bad status enum value + esp_mail_imap_response_status imapResponseStatus(IMAPSession *imap, char *response, PGM_P tag); + + // Add header item to string buffer + void addHeaderItem(MB_String &str, esp_mail_message_header_t *header, bool json); + + // Get RFC822 header string pointer by index + int getRFC822HeaderPtr(int index, esp_mail_imap_rfc822_msg_header_item_t *header); + + // Add RFC822 headers to string buffer + void addRFC822Headers(MB_String &s, esp_mail_imap_rfc822_msg_header_item_t *header, bool json); + + // Add RFC822 header item to string buffer + void addRFC822HeaderItem(MB_String &s, esp_mail_imap_rfc822_msg_header_item_t *header, int index, bool json); + + // Add header string by name and value to string buffer + void addHeader(MB_String &s, const char *name, const char *s_value, int num_value, bool trim, bool isJson); + + // Save header string buffer to file + void saveHeader(IMAPSession *imap, bool json); + + // Send MIME stream to callback + void sendStreamCB(IMAPSession *imap, void *buf, size_t len, int chunkIndex, bool hrdBrk); + + // Prepare file path for saving + void prepareFilePath(IMAPSession *imap, MB_String &filePath, bool header); + + // Decode text and store it to buffer or file + void decodeText(IMAPSession *imap, esp_mail_imap_response_data &res); + + // Handle atachment parsing and download + bool parseAttachmentResponse(IMAPSession *imap, char *buf, esp_mail_imap_response_data &res); + + // Get List + char *getList(char *buf, bool &isList); + + // Parse mailbox folder open response + void parseFoldersResponse(IMAPSession *imap, char *buf, bool list); + + // Prepare alias (short name) file list for unsupported long file name filesystem + void prepareFileList(IMAPSession *imap, MB_String &filePath); + + // Parse capability response + bool parseCapabilityResponse(IMAPSession *imap, const char *buf, int &chunkIdx); + + // Parse Idle response + bool parseIdleResponse(IMAPSession *imap); + + // Append Fetch UID/Flags string to buffer + void appendFetchString(MB_String &buf, bool uid); + + // Parse command response + void parseCmdResponse(IMAPSession *imap, char *buf, PGM_P find); + + // Get flags + bool getFlags(IMAPSession *imap, char *buf, esp_mail_imap_response_types type); + + // Parse examine response + void parseExamineResponse(IMAPSession *imap, char *buf); + + // Handle the error by sending callback and close session + bool handleIMAPError(IMAPSession *imap, int err, bool ret); + + // Set Flag + bool mSetFlag(IMAPSession *imap, MB_StringPtr sequenceSet, MB_StringPtr flags, esp_mail_imap_store_flag_type type, bool closeSession, bool silent = false, bool UID = true, int32_t modsequence = -1); + +#endif +}; + +#if defined(ENABLE_IMAP) + +class IMAPSession +{ +public: + IMAPSession(Client *client); + IMAPSession(); + ~IMAPSession(); + + /** Set the tcp timeout. + * + * @param timeoutSec The tcp timeout in seconds. + */ + void setTCPTimeout(unsigned long timeoutSec); + + /** Assign custom Client from Arduino Clients. + * + * @param client The pointer to Arduino Client derived class e.g. WiFiClient, EthernetClient or GSMClient. + */ + void setClient(Client *client); + + /** Assign TinyGsm Clients. + * + * @param client The pointer to TinyGsmClient. + * @param modem The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data. + * @param pin The SIM pin. + * @param apn The GPRS APN (Access Point Name). + * @param user The GPRS user. + * @param password The GPRS password. + */ + void setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password); + + /** Assign the callback function to handle the network connection for custom Client. + * + * @param networkConnectionCB The function that handles the network connection. + */ + void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB); + + /** Assign the callback function to handle the network connection status acknowledgement. + * + * @param networkStatusCB The function that handle the network connection status acknowledgement. + */ + void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB); + + /** Set the network status acknowledgement. + * + * @param status The network status. + */ + void setNetworkStatus(bool status); + + /** Set the BearSSL IO buffer size. + * + * @param rx The BearSSL receive buffer size in bytes. + * @param tx The BearSSL trasmit buffer size in bytes. + */ + void setSSLBufferSize(int rx = -1, int tx = -1); + + /** Begin the IMAP server connection. + * + * @param session_config The pointer to Session_Config structured data that keeps + * the server and log in details. + * @param imap_data The pointer to IMAP_Data structured data that keeps the + * operation options. + * @param login The bool option for login after server connection. + * @return The boolean value which indicates the success of operation. + */ + bool connect(Session_Config *session_config, IMAP_Data *imap_data, bool login = true); + + /** Log in to IMAP server using Email and password. + * + * @param email The IMAP server account email. + * @param password The IMAP server account password. + * @return The boolean value which indicates the success of operation. + */ + template + bool loginWithPassword(T1 email, T2 password) { return mLogin(toStringPtr(email), toStringPtr(password), false); }; + + /** Log in to IMAP server using Email and access token. + * + * @param email The IMAP server account email. + * @param token The Access token to log in. + * @return The boolean value which indicates the success of operation. + */ + template + bool loginWithAccessToken(T1 email, T2 token) { return mLogin(toStringPtr(email), toStringPtr(token), true); }; + + /** Send the client identification to the server + * + * @param identification The pointer to IMAP_Identification structured data that keeps + * the key properties e.g., name, version, os, os_version, vendor, support_url, address, + * date, command, arguments, and environment. + */ + bool id(IMAP_Identification *identification); + + /** Return the server ID returns from ID command. + * @return The server ID string. + */ + String serverID(); + + /** Return the SASL authentication status. + * @return The boolean value indicates SASL authentication status. + */ + bool isAuthenticated(); + + /** Return the log status. + * @return The boolean value log in status. + */ + bool isLoggedIn(); + + /** Return firmware update result when attachment filename matches. + * @return The boolean value indicates the firmware update status. + */ + bool isFirmwareUpdateSuccess(); + + /** Begin the IMAP server connection without authentication. + * + * @param session_config The pointer to Session_Config structured data that keeps + * the server and log in details. + * @param callback The callback function that accepts IMAP_Response as parameter. + * @param tag The tag that pass to the callback function. + * @return The boolean value indicates the success of operation. + */ + template + bool customConnect(Session_Config *session_config, imapResponseCallback callback, T tag = "") { return mCustomConnect(session_config, callback, toStringPtr(tag)); }; + + /** Close the IMAP session. + * + * @return The boolean value which indicates the success of operation. + */ + bool closeSession(); + + /** Get TCP connection status. + * + * @return The boolean value indicates the connection status. + */ + bool connected(); + + /** Set to enable the debug. + * + * @param level The level to enable the debug message + * level = 0, no debugging + * level = 1, basic level debugging + */ + void debug(int level); + + /** Get the list of all the mailbox folders since the TCP session was opened + * and user was authenticated. + * + * @param folders The FoldersCollection class that contains the collection of + * the + * FolderInfo structured data. + * @return The boolean value which indicates the success of operation. + */ + bool getFolders(FoldersCollection &folders); + + /** Select or open the mailbox folder to search or fetch the message inside. + * + * @param folderName The known mailbox folder name. The default name is INBOX. + * @param readOnly The option to open the mailbox for read only. Set this + * option to false when you wish + * to modify the Flags using the setFlag, addFlag and removeFlag functions. + * @return The boolean value which indicates the success of operation. + * + * @note: the function will exit immediately and return true if the time since previous success folder selection (open) + * with the same readOnly mode, is less than 5 seconds. + */ + template + bool selectFolder(T folderName, bool readOnly = true) { return mSelectFolder(toStringPtr(folderName), readOnly); } + + /** Open the mailbox folder to read or search the mesages. + * + * @param folderName The name of known mailbox folder to be opened. + * @param readOnly The option to open the mailbox for reading only. Set this + * option to false when you wish + * to modify the flags using the setFlag, addFlag and removeFlag functions. + * @return The boolean value which indicates the success of operation. + * + * @note: the function will exit immediately and return true if the time since previous success folder selection (open) + * with the same readOnly mode, is less than 5 seconds. + */ + template + bool openFolder(T folderName, bool readOnly = true) { return mOpenFolder(toStringPtr(folderName), readOnly); } + + /** Close the mailbox folder that was opened. + * + * @param expunge The option to allow emty the deleted flag set messages in case folder was open with editable mode. + * @return The boolean value which indicates the success of operation. + */ + bool closeFolder(bool expunge = false) { return mCloseFolder(expunge); } + + /** Create folder. + * + * @param folderName The name of folder to create. + * @return The boolean value which indicates the success of operation. + */ + template + bool createFolder(T folderName) { return mCreateFolder(toStringPtr(folderName)); } + + /** Rename folder. + * + * @param currentFolderName The name of folder to rename. + * @param newFolderName The new name of folder to rename. + * @return The boolean value which indicates the success of operation. + */ + template + bool renameFolder(T1 currentFolderName, T2 newFolderName) { return mRenameFolder(toStringPtr(currentFolderName), toStringPtr(newFolderName)); } + + /** Delete folder. + * + * @param folderName The name of folder to delete. + * @return The boolean value which indicates the success of operation. + */ + template + bool deleteFolder(T folderName) { return mDeleteFolder(toStringPtr(folderName)); } + + /** Get subscribes mailboxes. + * + * @param reference The reference name. + * @param mailbox The mailbox name with possible wildcards. + * @param folders The return FoldersCollection that contains the folder info e.g., name, attribute and delimiter. + * @return The boolean value which indicates the success of operation. + */ + template + bool getSubscribesMailboxes(T1 reference, T2 mailbox, FoldersCollection &folders) { return mGetSubscribesMailboxes(toStringPtr(reference), toStringPtr(mailbox), folders); } + + /** Subscribe mailbox. + * + * @param folderName The name of folder to subscribe. + * @return The boolean value which indicates the success of operation. + */ + template + bool subscribe(T folderName) { return mSubscribe(toStringPtr(folderName)); } + + /** Unsubscribe mailbox. + * + * @param folderName The name of folder to unsubscribe. + * @return The boolean value which indicates the success of operation. + */ + template + bool unSubscribe(T folderName) { return mUnSubscribe(toStringPtr(folderName)); } + + /** Get UID number in selected or opened mailbox. + * + * @param msgNum The message number or order in the total message numbers. + * @return UID number in selected or opened mailbox. + * + * @note Returns 0 when fail to get UID. + */ + int getUID(int msgNum); + + /** Get message flags in selected or opened mailbox. + * + * @param msgNum The message number or order in the total message numbers. + * @return Message flags in selected or opened mailbox. + * + * @note Returns empty string when fail to get flags. + */ + const char *getFlags(int msgNum); + + /** Send the custom IMAP command and get the result via callback. + * + * @param cmd The command string. + * @param callback The callback function that accepts IMAP_Response as parameter. + * @param tag The tag string to pass to the callback function. + * @return The boolean value which indicates the success of operation. + * + * @note imap.connect and imap.selectFolder or imap.openFolder are needed to call once prior to call this function. + */ + template + bool sendCustomCommand(T1 cmd, imapResponseCallback callback, T2 tag = "") { return mSendCustomCommand(toStringPtr(cmd), callback, toStringPtr(tag)); } + + /** Send the custom IMAP command data string. + * + * @param data The string data. + * @param last The flag represents the last data to send (optional). + * @return The boolean value which indicates the success of operation. + * + * @note Should be used after calling sendCustomCommand("APPEND xxxxxx"); + */ + template + bool sendCustomData(T data, bool lastData = false) { return mSendData(toStringPtr(data), lastData, esp_mail_imap_cmd_custom); } + + /** Send the custom IMAP command data. + * + * @param data The byte data. + * @param size The data size. + * @param lastData The flag represents the last data to send (optional). + * @return The boolean value which indicates the success of operation. + * + * @note Should be used after calling ssendCustomCommand("APPEND xxxxxx"); + */ + bool sendCustomData(uint8_t *data, size_t size, bool lastData = false) { return mSendData(data, size, lastData, esp_mail_imap_cmd_custom); } + + /** Copy the messages to the defined mailbox folder. + * + * @param toCopy The pointer to the MessageList class that contains the + * list of messages to copy. + * @param dest The destination folder that the messages to copy to. + * @return The boolean value which indicates the success of operation. + */ + template + bool copyMessages(MessageList *toCopy, T dest) { return mCopyMessages(toCopy, toStringPtr(dest)); } + + /** Copy the messages to the defined mailbox folder. + * + * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. + * @param UID The option for sequenceSet whether it is UID or message sequence number. + * @param dest The destination folder that the messages to copy to. + * @return The boolean value indicates the success of operation. + */ + template + bool copyMessages(T1 sequenceSet, bool UID, T2 dest) { return mCopyMessagesSet(toStringPtr(sequenceSet), UID, toStringPtr(dest)); } + + /** Move the messages to the defined mailbox folder. + * + * @param toMove The pointer to the MessageList class that contains the + * list of messages to move. + * @param dest The destination folder that the messages to move to. + * @return The boolean value which indicates the success of operation. + */ + template + bool moveMessages(MessageList *toCopy, T dest) { return mMoveMessages(toCopy, toStringPtr(dest)); } + + /** Move the messages to the defined mailbox folder. + * + * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. + * @param UID The option for sequenceSet whether it is UID or message sequence number. + * @param dest The destination folder that the messages to move to. + * @return The boolean value indicates the success of operation. + */ + template + bool moveMessages(T1 sequenceSet, bool UID, T2 dest) { return mMoveMessagesSet(toStringPtr(sequenceSet), UID, toStringPtr(dest)); } + + /** Delete the messages in the opened mailbox folder. + * + * @param toDelete The pointer to the MessageList class that contains the + * list of messages to delete. + * @param expunge The boolean option to expunge all messages. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value which indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + bool deleteMessages(MessageList *toDelete, bool expunge = false, int32_t modsequence = -1) { return mDeleteMessages(toDelete, expunge, modsequence); } + + /** Delete the messages in the opened mailbox folder. + * + * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. + * @param UID The option for sequenceSet whether it is UID or message sequence number. + * @param expunge The boolean option to expunge all messages. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value which indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool deleteMessages(T sequenceSet, bool UID, bool expunge = false, int32_t modsequence = -1) { return mDeleteMessagesSet(toStringPtr(sequenceSet), UID, expunge, modsequence); } + + /** Get the quota root's resource usage and limits. + * + * @param quotaRoot The quota root to get. + * @param info The pointer to IMAP_Quota_Root_Info that contains quota root's resource name, usage and limit. + * @return The boolean value which indicates the success of operation. + */ + template + bool getQuota(T quotaRoot, IMAP_Quota_Root_Info *info) { return mGetSetQuota(toStringPtr(quotaRoot), info, true); } + + /** Set the quota root's resource usage and limits. + * + * @param quotaRoot The quota root to set. + * @param data The pointer to IMAP_Quota_Root_Info that contains quota root's resource name, usage and limit. + * @return The boolean value which indicates the success of operation. + */ + template + bool setQuota(T quotaRoot, IMAP_Quota_Root_Info *data) { return mGetSetQuota(toStringPtr(quotaRoot), data, false); } + + /** Get the list of quota roots for the named mailbox. + * + * @param mailbox The mailbox name. + * @param quotaRootsList The pointer to IMAP_Quota_Roots_List that contains the list of IMAP_Quota_Root_Info. + * @return The boolean value which indicates the success of operation. + */ + template + bool getQuotaRoot(T mailbox, IMAP_Quota_Roots_List *quotaRootsList) { return mGetQuotaRoots(toStringPtr(mailbox), quotaRootsList); } + + /** Get the ACLs for a mailbox. + * + * @param mailbox The mailbox name. + * @param aclList The pointer to the returning IMAP_Rights_List object. + * @return The boolean value which indicates the success of operation. + */ + template + bool getACL(T mailbox, IMAP_Rights_List *aclList) { return mManageACL(toStringPtr(mailbox), aclList, nullptr, toStringPtr(""), esp_mail_imap_cmd_get_acl); }; + + /** Get the ACLs for a mailbox. + * + * @param mailbox The mailbox name. + * @param acl The pointer to the acl IMAP_Rights_Info to set. + * @return The boolean value which indicates the success of operation. + */ + template + bool setACL(T mailbox, IMAP_Rights_Info *acl) { return mManageACL(toStringPtr(mailbox), nullptr, acl, toStringPtr(""), esp_mail_imap_cmd_set_acl); }; + + /** Delete the ACLs set for identifier on mailbox. + * + * @param mailbox The mailbox name. + * @param identifier The identifier (user) to remove the rights. + * @return The boolean value which indicates the success of operation. + */ + template + bool deleteACL(T1 mailbox, T2 identifier) { return mManageACL(toStringPtr(mailbox), nullptr, nullptr, toStringPtr(identifier), esp_mail_imap_cmd_delete_acl); }; + + /** Show my ACLs for a mailbox. + * + * @param mailbox The mailbox name. + * @param acl The pointer to the returning IMAP_Rights_Info object. + * @return The boolean value which indicates the success of operation. + */ + template + bool myRights(T mailbox, IMAP_Rights_Info *acl) { return mManageACL(toStringPtr(mailbox), nullptr, acl, toStringPtr(""), esp_mail_imap_cmd_my_rights); }; + + /** Returns IMAP namespaces. + * + * @param mailbox The mailbox name. + * @param ns The pointer to the returning IMAP_Namespaces_List object. + * @return The boolean value which indicates the success of operation. + */ + bool getNamespace(IMAP_Namespaces_List *ns) { return mNamespace(ns); }; + + /** Enable IMAP capability. + * + * @param capability The mailbox name. + * @return The boolean value which indicates the success of operation. + */ + template + bool enable(T capability) { return mEnable(toStringPtr(capability)); }; + + /** Listen for the selected or open mailbox for updates. + * @return The boolean value which indicates the success of operation. + */ + bool listen() { return mListen(false); }; + + /** Stop listen for the mailbox for updates. + * @return The boolean value which indicates the success of operation. + */ + bool stopListen() { return mStopListen(false); }; + + /** Check for the selected or open mailbox updates. + * @return The boolean value which indicates the changes status of mailbox. + */ + bool folderChanged(); + + /** Send NOOP command to IMAP server. + * @return The boolean value which indicates the success of operation. + */ + bool noop(); + + /** Assign the callback function that returns the operating status when + * fetching or reading the Email. + * + * @param imapCallback The function that accepts the imapStatusCallback as + * parameter. + */ + void callback(imapStatusCallback imapCallback); + + /** Assign the callback function to decode the string based on the character set. + * + * @param callback The function that accepts the pointer to IMAP_Decoding_Info as parameter. + */ + void characterDecodingCallback(imapCharacterDecodingCallback callback); + + /** Assign the callback function that returns the MIME data stream from + * fetching or reading the Email. + * + * @param mimeDataStreamCallback The function that accepts the MIME_Stream_Info as + * parameter. + */ + void mimeDataStreamCallback(MIMEDataStreamCallback mimeDataStreamCallback); + + /** Determine if no message body contained in the search result and only the + * message header is available. + */ + bool headerOnly(); + + /** Get the message list from search or fetch the Emails + * + * @return The IMAP_MSG_List structured data which contains text and html + * contents, + * attachments, inline images, embedded rfc822 messages details for each + * message. + */ + IMAP_MSG_List data(); + + /** Get the details of the selected or opned mailbox folder + * + * @return The SelectedFolderInfo class which contains the info about flags, + * total messages, next UID, + * search count and the available messages count. + */ + SelectedFolderInfo selectedFolder(); + + /** Get the error details when readingg the Emails + * + * @return The string of error details. + */ + String errorReason(); + + /** Get the operating status error code. + * + * @return The int value of operating status error code. + * + * The negative value indicated error. + * See src/ESP_Mail_Error.h and extras/MB_FS.h + */ + int errorCode(); + + /** Clear all the cache data stored in the IMAP session object. + */ + void empty(); + + /** Get the status of message fetching and searching. + * + * @return The IMAP_Status object contains the fetching and searching statuses. + */ + IMAP_Status status(); + + /** Get the JSON string of file name list of files that stored in SD card. + * + * @return The JSON string of filenames. + * @note This will available only when standard SD library was used and file storage is SD. + */ + String fileList(); + + /** Set the current timestamp. + * + * @param ts The current timestamp. + * @param gmtOffset The GMT offset. + */ + void setSystemTime(time_t ts, float gmtOffset = 0); + + /** Setup TCP KeepAlive for internal TCP client. + * + * @param tcpKeepIdleSeconds lwIP TCP Keepalive idle in seconds. + * @param tcpKeepIntervalSeconds lwIP TCP Keepalive interval in seconds. + * @param tcpKeepCount lwIP TCP Keepalive count. + * + * For the TCP (KeepAlive) options, see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options. + * + * If value of one of these parameters is zero, the TCP KeepAlive will be disabled. + * + * You can check the server connecting status, by exexuting .connected() which will return true when connection to the server is still alive. + */ + void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount); + + /** Get TCP KeepAlive status. + * + * @return Boolean status of TCP KeepAlive. + */ + bool isKeepAlive(); + + friend class ESP_Mail_Client; + friend class foldderList; + +private: + // Log in to IMAP server + bool mLogin(MB_StringPtr email, MB_StringPtr password, bool isToken); + + // Clear message data + void clearMessageData(); + + // Check for valid UID or set wildcard * as UID + void checkUID(); + + // Check for valid saving file path or prepend / + void checkPath(); + + // Get message item by index + void getMessages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg); + + // Get RFC822 message item by index + void getRFC822Messages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg); + + // Close mailbox + bool closeMailbox(bool expunge = false); + + // Open mailbox + bool openMailbox(MB_StringPtr folder, esp_mail_imap_auth_mode mode, bool waitResponse, bool unselect); + + // Get folders list + bool getMailboxes(FoldersCollection &folders); + + // Get subscribes mailboxes + bool mGetSubscribesMailboxes(MB_StringPtr reference, MB_StringPtr mailbox, FoldersCollection &folders); + + // Subscribe the mailbox + bool mSubscribe(MB_StringPtr folder); + + // Unsubscribe the mailbox + bool mUnSubscribe(MB_StringPtr folder); + + // Get UID + int mGetUID(int msgNum); + + // Fetch by sequence set + bool mFetchSequenceSet(); + + // Return string from TAG prepended command + MB_String prependTag(PGM_P cmd, PGM_P tag = NULL); + + // Check capabilities + bool checkCapabilities(); + + // Listen mailbox changes + bool mListen(bool recon); + + // Stop listen mailbox + bool mStopListen(bool recon); + + // Send custom command + bool mSendCustomCommand(MB_StringPtr cmd, imapResponseCallback callback, MB_StringPtr tag); + + // Send data after sending APPEND command + bool mSendData(MB_StringPtr data, bool lastData, esp_mail_imap_command cmd); + + // Send data after sending APPEND command + bool mSendData(uint8_t *data, size_t size, bool lastData, esp_mail_imap_command cmd); + + // Delete folder + bool mDeleteFolder(MB_StringPtr folderName); + + // Create folder + bool mCreateFolder(MB_StringPtr folderName); + + // Rename folder + bool mRenameFolder(MB_StringPtr currentFolderName, MB_StringPtr newFolderName); + + // Copy message + bool copyMsg(MessageList *toCopy, const char *sequenceSet, bool UID, MB_StringPtr dest); + + // Copy message + bool mCopyMessages(MessageList *toCopy, MB_StringPtr dest); + + // Copy message using sequence set + bool mCopyMessagesSet(MB_StringPtr sequenceSet, bool UID, MB_StringPtr dest); + + // Move message + bool moveMsg(MessageList *toMove, const char *sequenceSet, bool UID, MB_StringPtr dest); + + // Move message + bool mMoveMessages(MessageList *toMove, MB_StringPtr dest); + + // Move message using sequence set + bool mMoveMessagesSet(MB_StringPtr sequenceSet, bool UID, MB_StringPtr dest); + + // Check for conditional STORE extention support + bool isCondStoreSupported(); + + // Check for mailbox mod-sequence support + bool isModseqSupported(); + + // add UNCHANGEDSINCE STORE modifier and CHANGEDSINCE FETCH modifier to command + void addModifier(MB_String &cmd, esp_mail_imap_command_types type, int32_t modsequence); + + // Delete message + bool deleteMsg(MessageList *toDelete, const char *sequenceSet, bool UID, bool expunge, int32_t modsequence = -1); + + // Delete messages + bool mDeleteMessages(MessageList *toDelete, bool expunge = false, int32_t modsequence = -1); + + // Delete messages + bool mDeleteMessagesSet(MB_StringPtr sequenceSet, bool UID, bool expunge = false, int32_t modsequence = -1); + + // Get or set the quota root's resource usage and limits. + bool mGetSetQuota(MB_StringPtr quotaRoot, IMAP_Quota_Root_Info *data, bool getMode); + + // Parse the IMAP_Quota_Root_info + void mParseQuota(const char *quota, IMAP_Quota_Root_Info *data); + + // Get the list of quota roots for the named mailbox. + bool mGetQuotaRoots(MB_StringPtr mailbox, IMAP_Quota_Roots_List *quotaRootsList); + + // Get or set ACL. + bool mManageACL(MB_StringPtr mailbox, IMAP_Rights_List *acl_list, IMAP_Rights_Info *acl, MB_StringPtr identifier, esp_mail_imap_command type); + + // Parse ACL + void parseACL(MB_String &acl_str, IMAP_Rights_List *right_list); + + // parse Rights + void parseRights(MB_String &righs_str, IMAP_Rights_Info *info); + + // Get Rights from IMAP_Rights_Info + void getRights(MB_String &righs_str, IMAP_Rights_Info *info); + + // Get namespace + bool mNamespace(IMAP_Namespaces_List *ns); + + // Enable the IMAP capability + bool mEnable(MB_StringPtr capability); + + // Parse namespaces + void parseNamespaces(MB_String &ns_str, IMAP_Namespaces *ns); + + // Close folder + bool mCloseFolder(bool expunge = false); + + // Open folder + bool mOpenFolder(MB_StringPtr folderName, bool readOnly); + + // Select folder + bool mSelectFolder(MB_StringPtr folderName, bool readOnly); + + // Custom TCP connection + bool mCustomConnect(Session_Config *session_config, imapResponseCallback callback, MB_StringPtr tag); + + // Append ID list to buffer + void appendIdList(MB_String &list, IMAP_Identification *identification); + + // Handle connection + bool handleConnection(Session_Config *session_config, IMAP_Data *imap_data, bool &ssl); + + // Start TCP connection + bool connect(bool &ssl); + + // Print features not supported debug error message + void printDebugNotSupported(); + + bool _sessionSSL = false; + bool _sessionLogin = false; + bool _loginStatus = false; + unsigned long _last_polling_error_ms = 0; + unsigned long _last_host_check_ms = 0; + unsigned long _last_server_connect_ms = 0; + unsigned long _last_network_error_ms = 0; + unsigned long tcpTimeout = TCP_CLIENT_DEFAULT_TCP_TIMEOUT_SEC; + struct esp_mail_imap_response_status_t _responseStatus; + int _cMsgIdx = 0; + int _cPartIdx = 0; + int _totalRead = 0; + _vectorImpl _headers; + + esp_mail_imap_command _imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_sasl_login; + esp_mail_imap_command _prev_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_sasl_login; + esp_mail_imap_command _imap_custom_cmd = esp_mail_imap_cmd_custom; + esp_mail_imap_command _prev_imap_custom_cmd = esp_mail_imap_cmd_custom; + bool _idle = false; + MB_String _cmd; + _vectorImpl _multipart_levels; + int _rfc822_part_count = 0; + bool _unseen = false; + bool _readOnlyMode = true; + bool _msgDownload = false; + bool _attDownload = false; + bool _storageReady = false; + bool _storageChecked = false; + + bool _auth_capability[esp_mail_auth_capability_maxType]; + bool _feature_capability[esp_mail_imap_read_capability_maxType]; + Session_Config *_session_cfg; + _vectorImpl _configPtrList; + MB_String _currentFolder; + bool _mailboxOpened = false; + unsigned long _lastSameFolderOpenMillis = 0; + MB_String _nextUID; + MB_String _unseenMsgIndex; + MB_String _flags_tmp; + MB_String _quota_tmp; + MB_String _quota_root_tmp; + MB_String _acl_tmp; + MB_String _ns_tmp; + MB_String _server_id_tmp; + MB_String _sdFileList; + + struct esp_mail_imap_data_config_t *_imap_data = nullptr; + + int _userHeaderOnly = -1; + bool _headerOnly = true; + bool _uidSearch = false; + bool _headerSaved = false; + bool _debug = false; + int _debugLevel = 0; + bool _secure = false; + bool _authenticated = false; + bool _isFirmwareUpdated = false; + imapStatusCallback _statusCallback = NULL; + imapResponseCallback _customCmdResCallback = NULL; + MIMEDataStreamCallback _mimeDataStreamCallback = NULL; + imapCharacterDecodingCallback _charDecCallback = NULL; + + _vectorImpl _imap_msg_num; + esp_mail_session_type _sessionType = esp_mail_session_type_imap; + + FoldersCollection _folders; + SelectedFolderInfo _mbif; + int _uid_tmp = 0; + int _lastProgress = -1; + + ESP_Mail_TCPClient client; + + IMAP_Status _cbData; +}; + +#endif + +#if defined(ENABLE_SMTP) + +class SendingResult +{ +private: + _vectorImpl _result; + + void add(SMTP_Result *r) + { + _result.push_back(*r); + } + +public: + friend class SMTPSession; + friend class ESP_Mail_Client; + SendingResult(){}; + ~SendingResult() { clear(); }; + + void clear() + { + for (size_t i = 0; i < _result.size(); i++) + { + _result[i].recipients.clear(); + _result[i].subject.clear(); + _result[i].timestamp = 0; + _result[i].completed = false; + } + _result.clear(); + } + + SMTP_Result getItem(size_t index) + { + SMTP_Result r; + if (index < _result.size()) + return _result[index]; + return r; + } + size_t size() { return _result.size(); }; +}; + +class SMTPSession +{ +public: + SMTPSession(Client *client); + SMTPSession(); + ~SMTPSession(); + + /** Set the tcp timeout. + * + * @param timeoutSec The tcp timeout in seconds. + */ + void setTCPTimeout(unsigned long timeoutSec); + + /** Assign custom Client from Arduino Clients. + * + * @param client The pointer to Arduino Client derived class e.g. WiFiClient, EthernetClient or GSMClient. + */ + void setClient(Client *client); + + /** Assign TinyGsm Clients. + * + * @param client The pointer to TinyGsmClient. + * @param modem The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data. + * @param pin The SIM pin. + * @param apn The GPRS APN (Access Point Name). + * @param user The GPRS user. + * @param password The GPRS password. + */ + void setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password); + + /** Assign the callback function to handle the network connection for custom Client. + * + * @param networkConnectionCB The function that handles the network connection. + */ + void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB); + + /** Assign the callback function to handle the network connection status acknowledgement. + * + * @param networkStatusCB The function that handle the network connection status acknowledgement. + */ + void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB); + + /** Set the network status acknowledgement. + * + * @param status The network status. + */ + void setNetworkStatus(bool status); + + /** Set the BearSSL IO buffer size. + * + * @param rx The BearSSL receive buffer size in bytes. + * @param tx The BearSSL trasmit buffer size in bytes. + */ + void setSSLBufferSize(int rx = -1, int tx = -1); + + /** Begin the SMTP server connection. + * + * @param session_config The pointer to Session_Config structured data that keeps + * the server and log in details. + * @param login The bool option for login after server connection. + * @return The boolean value indicates the success of operation. + */ + bool connect(Session_Config *session_config, bool login = true); + + /** Log in to SMTP server using Email and password. + * + * @param email The SMTP server account email. + * @param password The SMTP server account password. + * @return The boolean value which indicates the success of operation. + */ + template + bool loginWithPassword(T1 email, T2 password) { return mLogin(toStringPtr(email), toStringPtr(password), false); }; + + /** Log in to SMTP server using Email and access token. + * + * @param email The SMTP server account email. + * @param token The Access token to log in. + * @return The boolean value which indicates the success of operation. + */ + template + bool loginWithAccessToken(T1 email, T2 token) { return mLogin(toStringPtr(email), toStringPtr(token), true); }; + + /** Return the SASL authentication status. + * @return The boolean value indicates SASL authentication status. + */ + bool isAuthenticated(); + + /** Return the log status. + * @return The boolean value indicates log in status. + */ + bool isLoggedIn(); + + /** Begin the SMTP server connection without authentication. + * + * @param session_config The pointer to Session_Config structured data that keeps + * the server and log in details. + * @param callback The callback function that accepts the SMTP_Response as parameter. + * @param commandID The command identifier number that will pass to the callback. + * @return The int value of status code. + * + * @note If commandID was not set or set to -1, the command identifier will be auto increased started from zero. + */ + int customConnect(Session_Config *session_config, smtpResponseCallback callback, int commandID = -1); + + /** Close the SMTP session. + * + */ + bool closeSession(); + + /** Get TCP connection status. + * + * @return The boolean value indicates the connection status. + */ + bool connected(); + + /** Send the custom SMTP command and get the result via callback. + * + * @param cmd The command string. + * @param callback The function that accepts the SMTP_Response as parameter. + * @param commandID The command identifier number that will pass to the callback. + * @return The integer value of response code. + * + * @note smtp.connect or smtp.customConnect is needed to call once prior to call this function. + * + * If commandID was not set or set to -1, the command identifier will be auto increased started from zero. + */ + template + int sendCustomCommand(T cmd, smtpResponseCallback callback, int commandID = -1) { return mSendCustomCommand(toStringPtr(cmd), callback, commandID); } + + /** Send the custom SMTP command data string. + * + * @param data The string data. + * @return The boolean value which indicates the success of operation. + * + * @note Should be used after calling sendCustomCommand("DATA"); + */ + template + bool sendCustomData(T data) { return mSendData(toStringPtr(data)); } + + /** Send the custom SMTP command data. + * + * @param data The byte data. + * @param size The data size. + * @return The boolean value which indicates the success of operation. + * + * @note Should be used after calling sendCustomCommand("DATA"); + */ + bool sendCustomData(uint8_t *data, size_t size) { return mSendData(data, size); } + + /** Set to enable the debug. + * + * @param level The level to enable the debug message + * level = 0, no debugging + * level = 1, basic level debugging + */ + void debug(int level); + + /** Get the error details when sending the Email + * + * @return The string of error details. + */ + String errorReason(); + + /** Get the SMTP server response status code. + * + * @return The int value of SMTP server response status code. + * + * See RFC 5321 standard's documentation. + */ + int statusCode(); + + /** Get the SMTP server response status message. + * + * @return The int value of SMTP server response status message. + * + */ + String statusMessage(); + + /** Get the operating status error code. + * + * @return The int value of operating status error code. + * + * The negative value indicated error. + * See src/ESP_Mail_Error.h and extras/MB_FS.h + */ + int errorCode(); + + /** Set the Email sending status callback function. + * + * @param smtpCallback The callback function that accept the + * smtpStatusCallback param. + */ + void callback(smtpStatusCallback smtpCallback); + + /** Get the status of message fetching and searching. + * + * @return The SMTP_Status object contains the sending status. + */ + SMTP_Status status(); + + /** Set the current timestamp. + * + * @param ts The current timestamp. + * @param gmtOffset The GMT offset. + */ + void setSystemTime(time_t ts, float gmtOffset = 0); + + /** Setup TCP KeepAlive for internal TCP client. + * + * @param tcpKeepIdleSeconds lwIP TCP Keepalive idle in seconds. + * @param tcpKeepIntervalSeconds lwIP TCP Keepalive interval in seconds. + * @param tcpKeepCount lwIP TCP Keepalive count. + * + * For the TCP (KeepAlive) options, see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options. + * + * If value of one of these parameters is zero, the TCP KeepAlive will be disabled. + * + * You can check the server connecting status, by exexuting .connected() which will return true when connection to the server is still alive. + */ + void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount); + + /** Get TCP KeepAlive status. + * + * @return Boolean status of TCP KeepAlive. + */ + bool isKeepAlive(); + + SendingResult sendingResult; + + friend class ESP_Mail_Client; + +private: + bool _sessionSSL = false; + bool _sessionLogin = false; + struct esp_mail_smtp_response_status_t _responseStatus; + int _sentSuccessCount = 0; + int _sentFailedCount = 0; + bool _chunkedEnable = false; + int _chunkCount = 0; + uint32_t ts = 0; + unsigned long tcpTimeout = TCP_CLIENT_DEFAULT_TCP_TIMEOUT_SEC; + + esp_mail_smtp_command _smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_greeting; + + bool _auth_capability[esp_mail_auth_capability_maxType]; + bool _feature_capability[esp_mail_smtp_send_capability_maxType]; + + Session_Config *_session_cfg = NULL; + _vectorImpl _configPtrList; + + bool _debug = false; + int _debugLevel = 0; + bool _secure = false; + bool _authenticated = false; + bool _loginStatus = false; + bool _waitForAuthenticate = false; + bool _canForward = false; + smtpStatusCallback _statusCallback = NULL; + smtpResponseCallback _customCmdResCallback = NULL; + int _commandID = -1; + bool _sdStorageReady = false; + bool _flashStorageReady = false; + bool _sdStorageChecked = false; + bool _flashStorageChecked = false; + + esp_mail_session_type _sessionType = esp_mail_session_type_smtp; + SMTP_Status _cbData; + struct esp_mail_smtp_msg_type_t _msgType; + int _lastProgress = -1; + + ESP_Mail_TCPClient client; + + // Start TCP connection + bool connect(bool &ssl); + + // Log in to SMTP server + bool mLogin(MB_StringPtr email, MB_StringPtr password, bool isToken); + + // Handle TCP connection + bool handleConnection(Session_Config *session_config, bool &ssl); + + // Send custom command + int mSendCustomCommand(MB_StringPtr cmd, smtpResponseCallback callback, int commandID = -1); + + // Send data after sending DATA command + bool mSendData(MB_StringPtr data); + + // Send data after sending DATA command + bool mSendData(uint8_t *data, size_t size); +}; + +#endif + +#if defined(ENABLE_SMTP) && defined(ENABLE_IMAP) + +class ESP_Mail_Message : public SMTP_Message +{ +public: + ESP_Mail_Message(){}; + ~ESP_Mail_Message(){}; +}; + +#endif + +extern ESP_Mail_Client MailClient; + +#endif /* ESP_MAIL_CLIENT_H */ diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client_Version.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client_Version.h new file mode 100644 index 000000000000..21cd038f604b --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client_Version.h @@ -0,0 +1,12 @@ + +#pragma once + +#ifndef ESP_MAIL_VERSION + +#define ESP_MAIL_VERSION "3.4.9" +#define ESP_MAIL_VERSION_NUM 30409 + +/* The inconsistent file version checking to prevent mixed versions compilation. */ +#define VALID_VERSION_CHECK(ver) (ver == ESP_MAIL_VERSION_NUM) + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Const.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Const.h new file mode 100644 index 000000000000..195ab0b1129b --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Const.h @@ -0,0 +1,3492 @@ +// Created August 20, 2023 + +#pragma once + +#ifndef ESP_MAIL_CONST_H +#define ESP_MAIL_CONST_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +#include +#include "ESP_Mail_FS.h" +#include "ESP_Mail_Error.h" +#include "extras/MB_FS.h" +#include "extras/RFC2047.h" +#include +#include + +#if defined(ESP_MAIL_DEBUG_PORT) +#define ESP_MAIL_DEFAULT_DEBUG_PORT ESP_MAIL_DEBUG_PORT +#else +#define ESP_MAIL_DEFAULT_DEBUG_PORT Serial +#endif + +#include +#include + +#define _vectorImpl std::vector +#define MB_VECTOR std::vector + +#if !defined(FPSTR) +#define FPSTR +#endif + +#include "extras/Networks_Provider.h" +#include "extras/ESP8266_Supports.h" + +#if defined(ESP8266) +#if __has_include() +#include +#endif +#endif + +#if defined(ENABLE_IMAP) && (defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO)) +#if defined(ESP32) +#include +#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) +#include +#endif +#define ESP_MAIL_OTA_UPDATE_ENABLED +#endif + +#if !defined(SILENT_MODE) && (defined(ENABLE_SMTP) || defined(ENABLE_IMAP)) +#define SESSION_DEBUG_ENABLED +#endif + +#define TCP_CLIENT_DEFAULT_TCP_TIMEOUT_SEC 30 + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + +#define MAX_EMAIL_SEARCH_LIMIT 1000 +#define BASE64_CHUNKED_LEN 76 +#define FLOWED_TEXT_LEN 78 +#define QP_ENC_MSG_LEN 76 +#define ESP_MAIL_NETWORK_RECONNECT_TIMEOUT 10000 +#define ESP_MAIL_PROGRESS_REPORT_STEP 5 +#define ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED 0 +#define ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE 256 +#define ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE 1024 // should be 1 k or more to prevent buffer overflow +#define ESP_MAIL_CLIENT_VALID_TS 1577836800 + +#endif + +typedef enum +{ + esp_mail_cert_type_undefined = -1, + esp_mail_cert_type_none = 0, + esp_mail_cert_type_data, + esp_mail_cert_type_file, + esp_mail_cert_type_bundle + +} esp_mail_cert_type; + +typedef enum +{ + esp_mail_client_type_undefined, + esp_mail_client_type_internal_basic_client, + esp_mail_client_type_external_basic_client, + esp_mail_client_type_external_gsm_client + +} esp_mail_client_type; + +/* The filesystem types enum */ +enum esp_mail_file_storage_type +{ + esp_mail_file_storage_type_none, + esp_mail_file_storage_type_flash, + esp_mail_file_storage_type_sd +}; + +/* The session types enum */ +enum esp_mail_session_type +{ + esp_mail_session_type_smtp, + esp_mail_session_type_imap +}; + +/* The secure connection mode preference */ +typedef enum +{ + // No preferences + esp_mail_secure_mode_undefined = 0, + // Always use SSL and TLS via STARTTLS rfc2595 section 3 and rfc3207 + esp_mail_secure_mode_ssl_tls, + // Plain text mode only (non SSL/TLS) + // To disable SSL/TLS permanently, define ESP_MAIL_DISABLE_SSL in ESP_Mail_FS.h + esp_mail_secure_mode_nonsecure + +} esp_mail_secure_mode; + +using namespace mb_string; + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + +typedef void (*NetworkConnectionHandler)(void); + +/* The file types enum */ +enum esp_mail_file_extension +{ + /** The arrangement is related to mimeinfo struct. + * Do not modify or remove. + */ + esp_mail_file_extension_html, + esp_mail_file_extension_htm, + esp_mail_file_extension_css, + esp_mail_file_extension_txt, + esp_mail_file_extension_js, + esp_mail_file_extension_json, + esp_mail_file_extension_png, + esp_mail_file_extension_gif, + esp_mail_file_extension_jpg, + esp_mail_file_extension_ico, + esp_mail_file_extension_svg, + esp_mail_file_extension_ttf, + esp_mail_file_extension_otf, + esp_mail_file_extension_woff, + esp_mail_file_extension_woff2, + esp_mail_file_extension_eot, + esp_mail_file_extension_sfnt, + esp_mail_file_extension_xml, + esp_mail_file_extension_pdf, + esp_mail_file_extension_zip, + esp_mail_file_extension_gz, + esp_mail_file_extension_appcache, + esp_mail_file_extension_dat, + esp_mail_file_extension_binary, + esp_mail_file_extension_maxType +}; + +struct esp_mail_mime_prop_t +{ + char endsWith[10]; + char mimeType[30]; +}; + +const struct esp_mail_mime_prop_t mimeinfo[esp_mail_file_extension_maxType] PROGMEM = { + /** The arrangement is related to esp_mail_file_extension enum. + * Do not modify or remove. + */ + {".html", "text/html"}, + {".htm", "text/html"}, + {".css", "text/css"}, + {".txt", "text/plain"}, + {".js", "application/javascript"}, + {".json", "application/json"}, + {".png", "image/png"}, + {".gif", "image/gif"}, + {".jpg", "image/jpeg"}, + {".ico", "image/x-icon"}, + {".svg", "image/svg+xml"}, + {".ttf", "application/x-font-ttf"}, + {".otf", "application/x-font-opentype"}, + {".woff", "application/font-woff"}, + {".woff2", "application/font-woff2"}, + {".eot", "application/vnd.ms-fontobject"}, + {".sfnt", "application/font-sfnt"}, + {".xml", "text/xml"}, + {".pdf", "application/pdf"}, + {".zip", "application/zip"}, + {".gz", "application/x-gzip"}, + {".appcache", "text/cache-manifest"}, + {".dat", "application/dat"}, + {"", "application/octet-stream"}}; + +#if defined(ENABLE_SMTP) + +/* The SMTP commands types enum */ +enum esp_mail_smtp_command_types +{ + /** The SMTP commands per stansards. + * The arrangement is related to smtp_commands struct. + * Do not modify or remove. + */ + esp_mail_smtp_command_auth, + esp_mail_smtp_command_login, + esp_mail_smtp_command_helo, + esp_mail_smtp_command_ehlo, + esp_mail_smtp_command_quit, + esp_mail_smtp_command_mail, + esp_mail_smtp_command_rcpt, + esp_mail_smtp_command_data, + esp_mail_smtp_command_bdat, + esp_mail_smtp_command_last, + esp_mail_smtp_command_plain, + esp_mail_smtp_command_from, + esp_mail_smtp_command_to, + esp_mail_smtp_command_notify, + esp_mail_smtp_command_success, + esp_mail_smtp_command_failure, + esp_mail_smtp_command_delay, + esp_mail_smtp_command_body, + esp_mail_smtp_command_terminate, + esp_mail_smtp_command_starttls, + esp_mail_smtp_command_maxType +}; + +/* The SMTP server capability types enum (except for SASL) */ +enum esp_mail_smtp_send_capability_types +{ + /** The server capability keywords per standard. + * The arrangement is related to smtp_send_capabilities struct. + * Do not modify or remove. + */ + esp_mail_smtp_send_capability_binary_mime, + esp_mail_smtp_send_capability_8bit_mime, + esp_mail_smtp_send_capability_chunking, + esp_mail_smtp_send_capability_utf8, + esp_mail_smtp_send_capability_pipelining, + esp_mail_smtp_send_capability_dsn, + esp_mail_smtp_send_capability_esmtp, + esp_mail_smtp_send_capability_maxType +}; + +#endif + +#if defined(ENABLE_IMAP) + +/* The IMAP server response types enum */ +enum esp_mail_imap_response_types +{ + /** The IMAP response. + * The arrangement is related to imap_responses struct. + * Do not modify or remove. + */ + esp_mail_imap_response_ok, + esp_mail_imap_response_no, + esp_mail_imap_response_bad, + esp_mail_imap_response_list, + esp_mail_imap_response_flags, + esp_mail_imap_response_search, + esp_mail_imap_response_fetch, + esp_mail_imap_response_nil, + esp_mail_imap_response_uid, + esp_mail_imap_response_capability_untagged, + esp_mail_imap_response_capability, + esp_mail_imap_response_lsub, + esp_mail_imap_response_quota, + esp_mail_imap_response_quotaroot, + esp_mail_imap_response_acl, + esp_mail_imap_response_myrights, + esp_mail_imap_response_namespace, + esp_mail_imap_response_untagged, + esp_mail_imap_response_exists, + esp_mail_imap_response_expunge, + esp_mail_imap_response_recent, + esp_mail_imap_response_uidnext, + esp_mail_imap_response_unseen, + esp_mail_imap_response_id, + esp_mail_imap_response_highest_modsec, + esp_mail_imap_response_nomodsec, + esp_mail_imap_response_permanent_flags, + esp_mail_imap_response_uidvalidity, + esp_mail_imap_response_maxType +}; + +/* The IMAP commands types enum */ +enum esp_mail_imap_command_types +{ + /** The IMAP commands per standards. + * The arrangement is related to imap_commands struct. + * Do not modify or remove. + */ + esp_mail_imap_command_starttls, + esp_mail_imap_command_append, + esp_mail_imap_command_capability, + esp_mail_imap_command_authenticate, + esp_mail_imap_command_plain, + esp_mail_imap_command_uid, + esp_mail_imap_command_fetch, + esp_mail_imap_command_flags, + esp_mail_imap_command_login, + esp_mail_imap_command_list, + esp_mail_imap_command_examine, + esp_mail_imap_command_search, + esp_mail_imap_command_logout, + esp_mail_imap_command_body, + esp_mail_imap_command_mime, + esp_mail_imap_command_close, + esp_mail_imap_command_exists, + esp_mail_imap_command_peek, + esp_mail_imap_command_text, + esp_mail_imap_command_fields, + esp_mail_imap_command_header, + esp_mail_imap_command_new, + esp_mail_imap_command_all, + esp_mail_imap_command_select, + esp_mail_imap_command_expunge, + esp_mail_imap_command_create, + esp_mail_imap_command_delete, + esp_mail_imap_command_idle, + esp_mail_imap_command_done, + esp_mail_imap_command_recent, + esp_mail_imap_command_unseen, + esp_mail_imap_command_rename, + esp_mail_imap_command_lsub, + esp_mail_imap_command_subscribe, + esp_mail_imap_command_unsubscribe, + esp_mail_imap_command_silent, + esp_mail_imap_command_move, + esp_mail_imap_command_getquota, + esp_mail_imap_command_setquota, + esp_mail_imap_command_root, + esp_mail_imap_command_get_acl, + esp_mail_imap_command_set_acl, + esp_mail_imap_command_delete_acl, + esp_mail_imap_command_myrights, + esp_mail_imap_command_namespace, + esp_mail_imap_command_enable, + esp_mail_imap_command_xoauth2, + esp_mail_imap_command_store, + esp_mail_imap_command_plus_flags, + esp_mail_imap_command_minus_flags, + esp_mail_imap_command_copy, + esp_mail_imap_command_id, + esp_mail_imap_command_unselect, + esp_mail_imap_command_condstore, + esp_mail_imap_command_noop, + esp_mail_imap_command_unchangedsince, + esp_mail_imap_command_changedsince, + esp_mail_imap_command_modsec, + esp_mail_imap_command_maxType +}; + +/* The IMAP server capability types enum (except for SASL) */ +enum esp_mail_imap_read_capability_types +{ + /** The server capability keywords per standard. + * The arrangement is related imap_read_capabilities struct. + * Do not modify or remove. + */ + + esp_mail_imap_read_capability_imap4, + esp_mail_imap_read_capability_imap4rev1, + // rfc2177 + esp_mail_imap_read_capability_idle, + esp_mail_imap_read_capability_literal_plus, + esp_mail_imap_read_capability_literal_minus, + esp_mail_imap_read_capability_multiappend, + esp_mail_imap_read_capability_uidplus, + // rfc4314 + esp_mail_imap_read_capability_acl, + esp_mail_imap_read_capability_binary, + esp_mail_imap_read_capability_logindisable, + // rfc6851 + esp_mail_imap_read_capability_move, + // rfc2087 + esp_mail_imap_read_capability_quota, + // rfc2342 + esp_mail_imap_read_capability_namespace, + // rfc5161 + esp_mail_imap_read_capability_enable, + // rfc2971 + esp_mail_imap_read_capability_id, + esp_mail_imap_read_capability_unselect, + esp_mail_imap_read_capability_children, + // rfc7162 (rfc4551 obsoleted) + esp_mail_imap_read_capability_condstore, + esp_mail_imap_read_capability_auto_caps, + esp_mail_imap_read_capability_maxType +}; + +/* The Identification keys enum used for IMAP ID command */ +enum esp_mail_imap_identification_keys +{ + /** The identification keys per standard. + * The arrangement is related imap_identification_keys struct. + * Do not modify or remove. + */ + + esp_mail_imap_identification_key_name, + esp_mail_imap_identification_key_version, + esp_mail_imap_identification_key_os, + esp_mail_imap_identification_key_os_version, + esp_mail_imap_identification_key_vendor, + esp_mail_imap_identification_key_support_url, + esp_mail_imap_identification_key_address, + esp_mail_imap_identification_key_date, + esp_mail_imap_identification_key_command, + esp_mail_imap_identification_key_arguments, + esp_mail_imap_identification_key_environment, + esp_mail_imap_identification_key_maxType +}; + +#endif + +/* The character encoding types enum used for decoding */ +enum esp_mail_char_decoding_types +{ + /** Supported charactor encodings. + * The arrangement is related to char_decodings struct. + * Do not modify or remove. + */ + esp_mail_char_decoding_utf8, + esp_mail_char_decoding_iso_8859_1, + esp_mail_char_decoding_iso_8859_11, + esp_mail_char_decoding_tis_620, + esp_mail_char_decoding_windows_874, + esp_mail_char_decoding_maxType +}; + +/* The MIME multipart message types */ +enum esp_mail_multipart_types +{ + /** MultiPart MIME. + * The arrangement is related to multipart_types struct. + * Do not modify or remove. + */ + esp_mail_multipart_type_mixed, + esp_mail_multipart_type_related, + esp_mail_multipart_type_parallel, + esp_mail_multipart_type_alternative, + esp_mail_multipart_maxType +}; + +/* The rfc822 message header fileds types enum */ +enum esp_mail_rfc822_header_field_types +{ + /** The rfc822 message header fields. + * The arrangement is related to rfc822_headers struct. + * Do not modify or remove. + */ + esp_mail_rfc822_header_field_from, + esp_mail_rfc822_header_field_sender, + esp_mail_rfc822_header_field_to, + esp_mail_rfc822_header_field_cc, + esp_mail_rfc822_header_field_subject, + esp_mail_rfc822_header_field_date, + esp_mail_rfc822_header_field_msg_id, + esp_mail_rfc822_header_field_return_path, + esp_mail_rfc822_header_field_reply_to, + esp_mail_rfc822_header_field_in_reply_to, + esp_mail_rfc822_header_field_references, + esp_mail_rfc822_header_field_comments, + esp_mail_rfc822_header_field_keywords, + esp_mail_rfc822_header_field_bcc, + esp_mail_rfc822_header_field_flags, + esp_mail_rfc822_header_field_maxType +}; + +/* The message header fileds types enum and its subproperties enum */ +enum esp_mail_message_header_field_types +{ + /** Additional fields and props. + * Some are used for the library information data field name. + * The arrangement is related to message_headers struct. + * Do not modify or remove. + */ + esp_mail_message_header_field_number, + esp_mail_message_header_field_uid, + esp_mail_message_header_field_accept_language, + esp_mail_message_header_field_content_language, + esp_mail_message_header_field_filename, + esp_mail_message_header_field_name, + esp_mail_message_header_field_size, + esp_mail_message_header_field_mime, + esp_mail_message_header_field_type, + esp_mail_message_header_field_description, + esp_mail_message_header_field_creation_date, + esp_mail_message_header_field_x_priority, + esp_mail_message_header_field_x_msmail_priority, + esp_mail_message_header_field_importance, + esp_mail_message_header_field_content_type, + esp_mail_message_header_field_content_transfer_encoding, + esp_mail_message_header_field_content_disposition, + esp_mail_message_header_field_content_location, + esp_mail_message_header_field_content_id, + esp_mail_message_header_field_content_description, + esp_mail_message_header_field_mime_version, + esp_mail_message_header_field_charset, + esp_mail_message_header_field_format, + esp_mail_message_header_field_delsp, + esp_mail_message_header_field_modification_date, + esp_mail_message_header_field_maxType +}; + +/* The auth capability types enum which shared usage between SMTP and IMAP */ +enum esp_mail_auth_capability_types +{ + /** The server capability keywords per standard. + * The arrangement is related to smtp_auth_capabilities and imap_auth_capabilities structs. + * Do not modify or remove. + */ + + esp_mail_auth_capability_plain, + esp_mail_auth_capability_xoauth2, + esp_mail_auth_capability_cram_md5, + esp_mail_auth_capability_digest_md5, + esp_mail_auth_capability_login, + esp_mail_auth_capability_starttls, + // imap rfc4959 + esp_mail_auth_capability_sasl_ir, + + esp_mail_auth_capability_maxType, +}; + +/* The smessage types enum */ +enum esp_mail_message_type +{ + esp_mail_msg_type_none = 0, + esp_mail_msg_type_plain = 1, + esp_mail_msg_type_html = 2, + esp_mail_msg_type_enriched = 1 +}; + +/* The string mark types enum used in joinStringx functions */ +enum esp_mail_string_mark_type +{ + esp_mail_string_mark_type_none, + esp_mail_string_mark_type_double_quote, + esp_mail_string_mark_type_angle_bracket, + esp_mail_string_mark_type_round_bracket, + esp_mail_string_mark_type_curly_bracket, + esp_mail_string_mark_type_square_bracket +}; + +/* The debug TAG types enum */ +enum esp_mail_debug_tag_type +{ + esp_mail_debug_tag_type_client, + esp_mail_debug_tag_type_server, + esp_mail_debug_tag_type_error, + esp_mail_debug_tag_type_info, + esp_mail_debug_tag_type_warning +}; + +/* The embed attachment types enum */ +enum esp_mail_smtp_embed_message_type +{ + esp_mail_smtp_embed_message_type_attachment = 0, + esp_mail_smtp_embed_message_type_inline +}; + +/* The attachment types enum */ +enum esp_mail_attach_type +{ + esp_mail_att_type_none, + esp_mail_att_type_attachment, + esp_mail_att_type_inline +}; + +/* The debug levels for printing the debug information via Serial port */ +enum esp_mail_debug_level +{ + esp_mail_debug_level_none = 0, + esp_mail_debug_level_basic, + esp_mail_debug_level_maintainer = 0xfff, + esp_mail_debug_level_developer = esp_mail_debug_level_maintainer + 1 +}; + +/* The content transfer encoding enum */ +enum esp_mail_msg_xencoding +{ + esp_mail_msg_xencoding_none, + /* rfc2045 section 2.7 */ + esp_mail_msg_xencoding_7bit, + esp_mail_msg_xencoding_qp, + esp_mail_msg_xencoding_base64, + /* rfc2045 section 2.8 */ + esp_mail_msg_xencoding_8bit, + /* rfc2045 section 2.9 */ + esp_mail_msg_xencoding_binary +}; + +/* The port protocols enum */ +enum esp_mail_protocol +{ + esp_mail_protocol_plain_text, + esp_mail_protocol_ssl, + esp_mail_protocol_tls +}; + +/* The internal use strct */ +struct esp_mail_internal_use_t +{ + esp_mail_msg_xencoding xencoding = esp_mail_msg_xencoding_none; + MB_String cid; +}; + +/* The struct contains port number and its protocol */ +struct port_function +{ + uint16_t port; + esp_mail_protocol protocol; +}; + +/* The struct that contains the list of port_function and its size */ +struct esp_mail_ports_functions +{ + friend class IMAPSession; + friend class SMTPSession; + friend class esp_mail_session_config_t; + + uint16_t size = 0; + port_function *list = nullptr; + bool use_internal_list = false; +}; + +/* The content transfer encoding type struct */ +struct esp_mail_transfer_encoding_t +{ + /* The default 7-bit transfer encoding for US-ACII characters*/ + static constexpr const char *enc_7bit = "7bit"; + + /* The quoted printable transfer encoding for non-US-ASCII characters*/ + static constexpr const char *enc_qp = "quoted-printable"; + + /* The base64 encoded transfer encoding */ + static constexpr const char *enc_base64 = "base64"; + + /* The 8-bit transfer encoding for extended-US-ASCII characters*/ + static constexpr const char *enc_8bit = "8bit"; + + /* The binary transfer encoding for extended-US-ASCII characters with no line + * length limit*/ + static constexpr const char *enc_binary = "binary"; +}; + +/* The content disposition types strucr (rfc 2183) */ +struct esp_mail_content_disposition_type_t +{ + /** if it is intended to be displayed automatically + * upon display of the message. + */ + static constexpr const char *inline_ = "inline"; + + /** to indicate that they are separate from the main body + * of the mail message, and that their display should not + * be automatic, but contingent upon some further action of the user. + */ + static constexpr const char *attachment = "attachment"; +}; + +/* The file (SD/flash) message content struct used for providing SMTP message content from file */ +struct esp_mail_file_message_content_t +{ + /* The file path include its name */ + MB_String name; + + /** The type of file storages e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + esp_mail_file_storage_type type = esp_mail_file_storage_type_flash; +}; + +/* The blob or flash string message content struct used for providing SMTP message content from blob or flash string */ +struct esp_mail_blob_message_content_t +{ + /* The array of content in flash memory */ + const uint8_t *data = nullptr; + + /* The array size in bytes */ + size_t size = 0; +}; + +/* The option to embed this message content as a file */ +struct esp_mail_smtp_embed_message_body_t +{ + /* Enable to send this message body as file */ + bool enable = false; + + /* The name of embedded file */ + MB_String filename; + + /** The embedded type + * esp_mail_smtp_embed_message_type_attachment or 0 + * esp_mail_smtp_embed_message_type_inline or 1 + */ + esp_mail_smtp_embed_message_type type = esp_mail_smtp_embed_message_type_attachment; +}; + +/** This is the base struct for SMTP message. + * This is for input and later used as esp_mail_plain_body_t + * and esp_mail_html_body_t. + * Its members are similar to esp_mail_imap_plain_body_t + * and esp_mail_imap_html_body_t unless it contains + * MB_String object to hold the string. + */ +struct esp_mail_message_body_t +{ + /* The option to embed this message content as a file */ + struct esp_mail_smtp_embed_message_body_t embed; + + /* The PLAIN/HTML content of the message */ + MB_String content; + + const char *nonCopyContent = ""; + + /* The blob that contins PLAIN/HTML content of the message */ + struct esp_mail_blob_message_content_t blob; + + /* The file that contins PLAIN/HTML content of the message */ + struct esp_mail_file_message_content_t file; + + /* The charset of the PLAIN/HTML content of the message */ + MB_String charSet = "UTF-8"; + + /* The content type of message */ + MB_String content_type = mimeinfo[esp_mail_file_extension_txt].mimeType; + + /* The option to encode the content for data transfer */ + MB_String transfer_encoding = "7bit"; + + /* The option to send the PLAIN text with wrapping */ + bool flowed = false; + + /* The internal usage data */ + struct esp_mail_internal_use_t _int; +}; + +/** The PLAIN text body details of the fetching message. + * This is for output and its members are similar to + * esp_mail_message_body_t unless there is no string object + * to hold string data unless the pointer to the const strings + * in IMAPSession object. + */ +struct esp_mail_imap_plain_body_t +{ + /* The option to embed this message content as a file */ + struct esp_mail_smtp_embed_message_body_t embed; + + /* The PLAIN text content of the message */ + const char *content = ""; + + /* The blob that contins PLAIN text content of the message */ + struct esp_mail_blob_message_content_t blob; + + /* The file that contins PLAIN text content of the message */ + struct esp_mail_file_message_content_t file; + + /* The charset of the PLAIN text content of the message */ + const char *charSet = "UTF-8"; + + /* The content type of message */ + const char *content_type = mimeinfo[esp_mail_file_extension_txt].mimeType; + + /* The option to encode the content for data transfer */ + const char *transfer_encoding = "7bit"; + + /* The option to send the PLAIN text with wrapping */ + bool flowed = false; + + /* The internal usage data */ + struct esp_mail_internal_use_t _int; +}; + +/** The HTML body details of the fetching message. + * This is for output and its members are similar to + * esp_mail_message_body_t unless there is no string object + * to hold string data unless the pointer to the const strings + * in IMAPSession object. + */ +struct esp_mail_imap_html_body_t +{ + /* The option to embedded the content as a file */ + struct esp_mail_smtp_embed_message_body_t embed; + + /* The HTML content of the message */ + const char *content = ""; + + /* The blob that contins HTML content of the message */ + struct esp_mail_blob_message_content_t blob; + + /* The file that contins HTML content of the message */ + struct esp_mail_file_message_content_t file; + + /* The charset of the HTML content of the message */ + const char *charSet = "UTF-8"; + + /* The content type of message */ + const char *content_type = mimeinfo[esp_mail_file_extension_html].mimeType; + + /* The option to encode the content for data transfer */ + const char *transfer_encoding = "7bit"; + + /* The internal usage data */ + struct esp_mail_internal_use_t _int; +}; + +/* The PLAIN text body details of the message */ +typedef struct esp_mail_message_body_t esp_mail_plain_body_t; + +/* The HTML text body details of the message */ +typedef struct esp_mail_message_body_t esp_mail_html_body_t; + +/* The attachment info struct used for output */ +struct esp_mail_attachment_info_t +{ + const char *filename = ""; + const char *name = ""; + const char *creationDate = ""; + const char *mime = ""; + const char *description = ""; + esp_mail_attach_type type = esp_mail_att_type_none; + size_t size; +}; + +#if defined(ENABLE_SMTP) + +struct esp_mail_smtp_command_t +{ + char text[9]; +}; + +struct esp_mail_timestamp_value_t +{ + /* The time format of timestamp to inject into subject or content as using in strftime C++ function */ + MB_String format; + /* The tag that will be replaced with current timestamp */ + MB_String tag; +}; + +/** The SMTP commands per stansards. + * The arrangement is related to esp_mail_smtp_command_types enum. + * Do not modify or remove. + */ +const struct esp_mail_smtp_command_t smtp_commands[esp_mail_smtp_command_maxType] PROGMEM = { + "AUTH", + "LOGIN", + "HELO", + "EHLO", + "QUIT", + "MAIL", + "RCPT", + "DATA", + "BDAT", + "LAST", + "PLAIN", + "FROM:", + "TO:", + "NOTIFY", + "SUCCESS", + "FAILURE", + "DELAY", + "BODY", + "\r\n.\r\n", + "STARTTLS"}; + +struct esp_mail_smtp_commands_tokens +{ +public: + esp_mail_smtp_commands_tokens(bool pre) + { + preToken = pre; + } + MB_String operator[](size_t index) + { + MB_String s = preToken ? " " : smtp_commands[index].text; + s += !preToken ? " " : smtp_commands[index].text; + return s; + } + +private: + bool preToken = false; +}; + +// The smtp commands with leading space. +static esp_mail_smtp_commands_tokens smtp_cmd_pre_tokens(true); + +// The smtp commands with trailing space. +static esp_mail_smtp_commands_tokens smtp_cmd_post_tokens(false); + +#endif + +#if defined(ENABLE_IMAP) + +struct esp_mail_imap_command_t +{ + char text[15]; +}; + +/** The IMAP commands per standards. + * The arrangement is related to esp_mail_imap_command_types enum. + * Do not modify or remove. + */ +const struct esp_mail_imap_command_t imap_commands[esp_mail_imap_command_maxType] PROGMEM = { + "STARTTLS", + "APPEND", + "CAPABILITY", + "AUTHENTICATE", + "PLAIN", + "UID", + "FETCH", + "FLAGS", + "LOGIN", + "LIST", + "EXAMINE", + "SEARCH", + "LOGOUT", + "BODY", + "MIME", + "CLOSE", + "EXISTS", + "PEEK", + "TEXT", + "FIELDS", + "HEADER", + "NEW", + "ALL", + "SELECT", + "EXPUNGE", + "CREATE", + "DELETE", + "IDLE", + "DONE", + "RECENT", + "UNSEEN", + "RENAME", + "LSUB", + "SUBSCRIBE", + "UNSUBSCRIBE", + "SILENT", + "MOVE", + "GETQUOTA", + "SETQUOTA", + "ROOT", + "GETACL", + "SETACL", + "DELETEACL", + "MYRIGHTS", + "NAMESPACE", + "ENABLE", + "XOAUTH2", + "STORE", + "+FLAGS", + "-FLAGS", + "COPY", + "ID", + "UNSELECT", + "CONDSTORE", + "NOOP", + "UNCHANGEDSINCE", + "CHANGEDSINCE", + "MODSEC"}; + +struct esp_mail_imap_commands_tokens +{ +public: + esp_mail_imap_commands_tokens(bool pre) + { + preToken = pre; + } + MB_String operator[](size_t index) + { + MB_String s = preToken ? " " : imap_commands[index].text; + s += !preToken ? " " : imap_commands[index].text; + return s; + } + +private: + bool preToken = false; +}; + +// The imap commands with leading space. +static esp_mail_imap_commands_tokens imap_cmd_pre_tokens(true); + +// The imap commands with trailing space. +static esp_mail_imap_commands_tokens imap_cmd_post_tokens(false); + +struct esp_mail_imap_response_t +{ + char text[18]; +}; + +/** The IMAP response. + * The arrangement is related to esp_mail_imap_response_types enum. + * Do not modify or remove. + */ +const struct esp_mail_imap_response_t imap_responses[esp_mail_imap_response_maxType] PROGMEM = { + // Tagged + "OK ", + "NO ", + "BAD ", + // Untagged + "* LIST ", + "* FLAGS ", + "* SEARCH ", + " FETCH ", + " NIL ", + " UID ", + "* CAPABILITY ", + "CAPABILITY ", + "* LSUB ", + "* QUOTA ", + "* QUOTAROOT ", + "* ACL ", + "* MYRIGHTS ", + "* NAMESPACE ", + "* ", + " EXISTS", + " EXPUNGE", + " RECENT", + " [UIDNEXT ", + " [UNSEEN ", + "* ID ", + " [HIGHESTMODSEQ ", + " [NOMODSEQ]", + " [PERMANENTFLAGS ", + " [UIDVALIDITY "}; + +#endif + +struct esp_mail_char_decoding_t +{ + char text[12]; +}; + +/** Supported charactor encodings. + * The arrangement is related to esp_mail_char_decoding_types enum. + * Do not modify or remove. + */ +const struct esp_mail_char_decoding_t char_decodings[esp_mail_char_decoding_maxType] PROGMEM = { + "utf-8", + "iso-8859-1", + "iso-8859-11", + "tis-620", + "windows-874"}; + +struct esp_mail_multipart_t +{ + char text[22]; +}; + +/** MultiPart MIME. + * The arrangement is related to esp_mail_multipart_types enum. + * Do not modify or remove. + */ +const struct esp_mail_multipart_t multipart_types[esp_mail_multipart_maxType] PROGMEM = { + "multipart/mixed", + "multipart/related", + "multipart/parallel", + "multipart/alternative"}; + +struct esp_mail_rfc822_header_field_t +{ + char text[20]; + bool isNum; + bool trim; +}; + +/** The rfc822 message header fields. + * The arrangement is related to esp_mail_rfc822_header_field_types enum. + * Do not modify or remove. + */ +const struct esp_mail_rfc822_header_field_t rfc822_headers[esp_mail_rfc822_header_field_maxType] PROGMEM = { + {"From", false, true}, + {"Sender", false, true}, + {"To", false, true}, + {"Cc", false, true}, + {"Subject", false, false}, + {"Date", false, false}, + {"Message-ID", false, false}, + {"Return-Path", false, true}, + {"Reply-To", false, true}, + {"In-Reply-To", false, true}, + {"References", false, true}, + {"Comments", false, false}, + {"Keywords", false, false}, + {"Bcc", false, true}, + {"Flags", false, false}}; + +struct esp_mail_message_header_field_t +{ + char text[26]; +}; + +/** Additional fields and props. + * The arrangement is related to esp_mail_message_header_field_types enum. + * Do not modify or remove. + */ +const struct esp_mail_message_header_field_t message_headers[esp_mail_message_header_field_maxType] PROGMEM = { + "Number", + "UID", + "Accept-Language", + "Content-Language", + "Filename", + "Name", + "Size", + "MIME", + "Type", + "Description", + "Creation-Date", + "X-Priority", + "X-MSMail-Priority", + "Importance", + "Content-Type", + "Content-transfer-encoding", + "Content-Disposition", + "Content-Location", + "Content-ID", + "Content-Description", + "Mime-Version", + "Charset", + "format", + "delsp", + "Modification-Date"}; + +struct esp_mail_auth_capability_t +{ + char text[20]; +}; + +#if defined(ENABLE_SMTP) + +/** The server capability keywords per standard. + * The arrangement is related to esp_mail_auth_capability_types enum. + * Do not modify or remove. + */ +const struct esp_mail_auth_capability_t smtp_auth_capabilities[esp_mail_auth_capability_maxType] PROGMEM = { + "PLAIN", + "XOAUTH2", + "CRAM-MD5", + "DIGEST-MD5", + "LOGIN", + "STARTTLS", + "DUMMY_AUTH" /* SASL-IR */}; + +struct esp_mail_smtp_auth_tokens +{ +public: + esp_mail_smtp_auth_tokens(bool pre) + { + preToken = pre; + } + MB_String operator[](size_t index) + { + MB_String s = preToken ? " " : smtp_auth_capabilities[index].text; + s += !preToken ? " " : smtp_auth_capabilities[index].text; + return s; + } + +private: + bool preToken = false; +}; + +// The smtp auth capability with leading space. +static esp_mail_smtp_auth_tokens smtp_auth_cap_pre_tokens(true); +// The smtp auth capability with trailing space. +static esp_mail_smtp_auth_tokens smtp_auth_cap_post_tokens(false); + +struct esp_mail_smtp_send_capability_t +{ + char text[15]; +}; + +/** The server capability keywords per standard. + * The arrangement is related esp_mail_smtp_send_capability_types enum. + * Do not modify or remove. + */ +const struct esp_mail_smtp_send_capability_t smtp_send_capabilities[esp_mail_smtp_send_capability_maxType] PROGMEM = { + "BINARYMIME", + "8BITMIME", + "CHUNKING", + "SMTPUTF8", + "PIPELINING", + "DSN", + "" /* ESMTP */}; + +struct esp_mail_smtp_send_tokens +{ +public: + esp_mail_smtp_send_tokens(bool pre) + { + preToken = pre; + } + MB_String operator[](size_t index) + { + MB_String s = preToken ? " " : smtp_send_capabilities[index].text; + s += !preToken ? " " : smtp_send_capabilities[index].text; + return s; + } + +private: + bool preToken = false; +}; + +static esp_mail_smtp_send_tokens smtp_send_cap_pre_tokens(true); + +#endif + +#if defined(ENABLE_IMAP) + +/** The server capability keywords per standard. + * The arrangement is related esp_mail_auth_capability_types enum. + * Do not modify or remove. + */ +const struct esp_mail_auth_capability_t imap_auth_capabilities[esp_mail_auth_capability_maxType] PROGMEM = { + "AUTH=PLAIN", + "AUTH=XOAUTH2", + "CRAM-MD5", + "DIGEST-MD5", + "DUMMY_AUTH", /* Log in */ + "STARTTLS", + "SASL-IR"}; + +struct esp_mail_imap_auth_tokens +{ +public: + esp_mail_imap_auth_tokens(bool pre) + { + preToken = pre; + } + MB_String operator[](size_t index) + { + MB_String s = preToken ? " " : imap_auth_capabilities[index].text; + s += !preToken ? " " : imap_auth_capabilities[index].text; + return s; + } + +private: + bool preToken = false; +}; + +// The imap auth capability with leading space. +static esp_mail_imap_auth_tokens imap_auth_cap_pre_tokens(true); + +struct esp_mail_imap_read_capability_t +{ + char text[15]; +}; + +/** The server capability keywords per standard. + * The arrangement is related esp_mail_imap_read_capability_types enum. + * Do not modify or remove. + */ +const struct esp_mail_imap_read_capability_t imap_read_capabilities[esp_mail_imap_read_capability_maxType] PROGMEM = { + "IMAP4", + "IMAP4rev1", + "IDLE", + "LITERAL+", + "LITERAL-", + "MULTIAPPEND", + "UIDPLUS", + "ACL", + "BINARY", + "LOGINDISABLED", + "MOVE", + "QUOTA", + "NAMESPACE", + "ENABLE", + "ID", + "UNSELECT", + "CHILDREN", + "CONDSTORE" + "" /* Auto cap */}; + +struct esp_mail_imap_read_tokens +{ +public: + esp_mail_imap_read_tokens(bool pre) + { + preToken = pre; + } + MB_String operator[](size_t index) + { + MB_String s = preToken ? " " : imap_read_capabilities[index].text; + s += !preToken ? " " : imap_read_capabilities[index].text; + return s; + } + +private: + bool preToken = false; +}; + +// The imap auth capability with leading space. +static esp_mail_imap_read_tokens imap_read_cap_pre_tokens(true); + +// The imap auth capability with trailing space. +static esp_mail_imap_read_tokens imap_read_cap_post_tokens(false); + +struct esp_mail_imap_identification_key_t +{ + char text[15]; +}; + +/** The identification keys per standard. + * The arrangement is related esp_mail_imap_identification_key_types enum. + * Do not modify or remove. + */ +const struct esp_mail_imap_identification_key_t imap_identification_keys[esp_mail_imap_identification_key_maxType] PROGMEM = { + "name", + "version", + "os", + "os-version", + "vendor", + "support-url", + "address", + "date", + "command", + "arguments", + "environment"}; + +/* The IMAP ID data struct */ +typedef struct esp_mail_imap_identity_t +{ + MB_String name; + MB_String version; + MB_String os; + MB_String os_version; + MB_String vendor; + MB_String support_url; + MB_String address; + MB_String date; + MB_String command; + MB_String arguments; + MB_String environment; + +} IMAP_Identification; + +#endif + +#endif + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) +/* The email address info [SMTP_Message]*/ +struct esp_mail_address_info_t +{ + /* The name of Email author/sender */ + MB_String name; + + /* The Email address */ + MB_String email; +}; +#endif + +#if defined(ENABLE_SMTP) + +/* The SMTP message notification types enum */ +enum esp_mail_smtp_notify +{ + esp_mail_smtp_notify_never = 0, + esp_mail_smtp_notify_success = 1, + esp_mail_smtp_notify_failure = 2, + esp_mail_smtp_notify_delay = 4 +}; + +/* The SMTP status codes enum */ +enum esp_mail_smtp_status_code +{ + esp_mail_smtp_status_code_0, // default + + /* Positive Completion */ + esp_mail_smtp_status_code_211 = 221, // System status, or system help reply + esp_mail_smtp_status_code_214 = 214, // Help message(A response to the HELP command) + esp_mail_smtp_status_code_220 = 220, // Service ready + esp_mail_smtp_status_code_221 = 221, // Service closing transmission channel [RFC 2034] + esp_mail_smtp_status_code_235 = 235, // 2.7.0 Authentication succeeded[RFC 4954] + esp_mail_smtp_status_code_250 = 250, // Requested mail action okay, completed + esp_mail_smtp_status_code_251 = 251, // User not local; will forward + esp_mail_smtp_status_code_252 = 252, // Cannot verify the user, but it will + // try to deliver the message anyway + + /* Positive Intermediate */ + esp_mail_smtp_status_code_334 = 334, //(Server challenge - the text part + // contains the Base64 - encoded + // challenge)[RFC 4954] + esp_mail_smtp_status_code_354 = 354, // Start mail input + + /* Transient Negative Completion */ + /* "Transient Negative" means the error condition is temporary, and the action + may be requested again.*/ + esp_mail_smtp_status_code_421 = 421, // Service is unavailable because the server is shutting down. + esp_mail_smtp_status_code_432 = 432, // 4.7.12 A password transition is needed [RFC 4954] + esp_mail_smtp_status_code_450 = 450, // Requested mail action not taken: mailbox unavailable (e.g., + // mailbox busy or temporarily blocked for policy reasons) + esp_mail_smtp_status_code_451 = 451, // Requested action aborted : local error in processing + // e.g.IMAP server unavailable[RFC 4468] + esp_mail_smtp_status_code_452 = 452, // Requested action not taken : insufficient system storage + esp_mail_smtp_status_code_454 = 454, // 4.7.0 Temporary authentication failure[RFC 4954] + esp_mail_smtp_status_code_455 = 455, // Server unable to accommodate parameters + + /* Permanent Negative Completion */ + esp_mail_smtp_status_code_500 = 500, // Syntax error, command unrecognized + // (This may include errors such as + // command line too long) + // e.g. Authentication Exchange line is too long [RFC 4954] + esp_mail_smtp_status_code_501 = 501, // Syntax error in parameters or arguments + // e.g. 5.5.2 Cannot Base64-decode Client responses [RFC 4954] + // 5.7.0 Client initiated Authentication Exchange (only when the SASL + // mechanism specified that client does not begin the authentication exchange) + // [RFC 4954] + esp_mail_smtp_status_code_502 = 502, // Command not implemented + esp_mail_smtp_status_code_503 = 503, // Bad sequence of commands + esp_mail_smtp_status_code_504 = 504, // Command parameter is not implemented + // e.g. 5.5.4 Unrecognized authentication type [RFC 4954] + esp_mail_smtp_status_code_521 = 521, // Server does not accept mail [RFC 7504] + esp_mail_smtp_status_code_523 = 523, // Encryption Needed [RFC 5248] + esp_mail_smtp_status_code_530 = 530, // 5.7.0 Authentication required [RFC 4954] + esp_mail_smtp_status_code_534 = 534, // 5.7.9 Authentication mechanism is too weak [RFC 4954] + esp_mail_smtp_status_code_535 = 535, // 5.7.8 Authentication credentials invalid [RFC 4954] + esp_mail_smtp_status_code_538 = 538, // 5.7.11 Encryption required for + // requested authentication mechanism[RFC + // 4954] + esp_mail_smtp_status_code_550 = 550, // Requested action not taken: mailbox unavailable (e.g., mailbox not + // found, no access, or command rejected for policy reasons) + esp_mail_smtp_status_code_551 = 551, // User not local; please try + esp_mail_smtp_status_code_552 = 552, // Requested mail action aborted: exceeded storage allocation + esp_mail_smtp_status_code_553 = 553, // Requested action not taken: mailbox name not allowed + esp_mail_smtp_status_code_554 = 554, // Transaction has failed (Or, in the + // case of a connection-opening response, + // "No SMTP service here") + // e.g. 5.3.4 Message too big for system [RFC 4468] + esp_mail_smtp_status_code_556 = 556, // Domain does not accept mail[RFC 7504] +}; + +/* The SMTP ports enum */ +enum esp_mail_smtp_port +{ + esp_mail_smtp_port_25 = 25, // PLAIN/TLS with STARTTLS + esp_mail_smtp_port_465 = 465, // SSL + esp_mail_smtp_port_587 = 587, // TLS with STARTTLS +}; + +const struct port_function smtp_ports[3] = { + {esp_mail_smtp_port_25, esp_mail_protocol_plain_text}, + {esp_mail_smtp_port_465, esp_mail_protocol_ssl}, + {esp_mail_smtp_port_587, esp_mail_protocol_tls}}; + +/* The SMTP message response [SMTP_Message] */ +struct esp_mail_smtp_msg_response_t +{ + /* The author Email address to reply */ + MB_String reply_to; + + /* The sender Email address to return the message */ + MB_String return_path; + + /** The Delivery Status Notifications e.g. esp_mail_smtp_notify_never, + * esp_mail_smtp_notify_success, + * esp_mail_smtp_notify_failure, and + * esp_mail_smtp_notify_delay + */ + int notify = esp_mail_smtp_notify::esp_mail_smtp_notify_never; +}; + +/* The SMTP enable option [SMTP_Message] */ +struct esp_mail_smtp_enable_option_t +{ + /* Enable chunk data sending for large message */ + bool chunking = false; +}; + +/* The SMTP blob data attachment data [Session_Config] */ +struct esp_mail_attach_blob_t +{ + /* BLOB data (flash or ram) */ + const uint8_t *data = nullptr; + + /* BLOB data size in byte */ + size_t size = 0; +}; + +/* The SMTP file attachment data [Session_Config] */ +struct esp_mail_attach_file_t +{ + MB_String path; + /** The file storage type e.g. esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + esp_mail_file_storage_type storage_type = esp_mail_file_storage_type_none; +}; + +/* The SMTP attachment decription [Session_Config] */ +struct esp_mail_attach_descr_t +{ + /* The name of attachment */ + MB_String name; + + /* The attachment file name */ + MB_String filename; + + /* The MIME type of attachment */ + MB_String mime; + + /* The transfer encoding of attachment e.g. base64 */ + MB_String transfer_encoding = "base64"; + + /* The content encoding of attachment e.g. base64 */ + MB_String content_encoding; + + /* The content id of attachment file */ + MB_String content_id; + + /* The description of attachment file */ + MB_String description; +}; + +/* Used internally in esp_mail_attachment_t */ +struct esp_mail_attach_internal_t +{ + esp_mail_attach_type att_type = esp_mail_att_type_attachment; + int index = 0; + int msg_uid = 0; + bool flash_blob = false; + esp_mail_msg_xencoding xencoding = esp_mail_msg_xencoding_none; + bool parallel = false; + MB_String cid; +}; + +/* The struct used as SMTP_Attachment for SMTP and ESP_Mail_Attachment for IMAP */ +struct esp_mail_attachment_t +{ + /* The attachment description */ + struct esp_mail_attach_descr_t descr; + + /* The BLOB data config */ + struct esp_mail_attach_blob_t blob; + + /* The file data config */ + struct esp_mail_attach_file_t file; + + /* reserved for internal usage */ + struct esp_mail_attach_internal_t _int; +}; + +/* The struct used as SMTP_Result */ +struct esp_mail_smtp_send_status_t +{ + /* The status of the message */ + bool completed = false; + + /* The primary recipient mailbox of the message */ + MB_String recipients; + + /* The topic of the message */ + MB_String subject; + + /* The timestamp of the message */ + uint32_t timestamp = 0; +}; + +/* Used internally for SMTPSession */ +struct esp_mail_smtp_msg_type_t +{ + bool rfc822 = false; + int rfc822Idx = 0; +}; + +/* Used internally for holding base64 data sources */ +struct esp_mail_smtp_send_base64_data_info_t +{ + esp_mail_file_storage_type storageType = esp_mail_file_storage_type_none; + const char *filename = ""; + const uint8_t *rawPtr = nullptr; + bool flashMem = false; + size_t size = 0; + size_t dataIndex = 0; +}; + +/* SMTP commands types enum */ +enum esp_mail_smtp_command +{ + esp_mail_smtp_cmd_undefined, + esp_mail_smtp_cmd_initial_state, + esp_mail_smtp_cmd_greeting, + esp_mail_smtp_cmd_start_tls, + esp_mail_smtp_cmd_login_user, + esp_mail_smtp_cmd_auth_plain, + esp_mail_smtp_cmd_auth_login, + esp_mail_smtp_cmd_auth_xoauth2, + esp_mail_smtp_cmd_login_psw, + esp_mail_smtp_cmd_send_header_sender, + esp_mail_smtp_cmd_send_header_recipient, + esp_mail_smtp_cmd_send_body, + esp_mail_smtp_cmd_chunk_termination, + esp_mail_smtp_cmd_logout, + esp_mail_smtp_cmd_custom +}; + +/* SMTP message priority level enum */ +enum esp_mail_smtp_priority +{ + esp_mail_smtp_priority_high = 1, + esp_mail_smtp_priority_normal = 3, + esp_mail_smtp_priority_low = 5, +}; + +/* SMTP response data */ +typedef struct esp_mail_smtp_response_status_t +{ + /* The SMTP server response status code */ + int statusCode = 0; + + /* error code */ + int errorCode = 0; + int id = -1; + MB_String text; +} SMTP_Response; + +#endif + +#if defined(ENABLE_IMAP) + +enum esp_mail_imap_msg_num_type +{ + esp_mail_imap_msg_num_type_undefined, + esp_mail_imap_msg_num_type_uid, + esp_mail_imap_msg_num_type_number +}; + +enum esp_mail_imap_store_flag_type +{ + esp_mail_imap_store_flag_type_set, + esp_mail_imap_store_flag_type_add, + esp_mail_imap_store_flag_type_remove +}; + +enum esp_mail_char_decoding_scheme +{ + esp_mail_char_decoding_scheme_default = -1, + esp_mail_char_decoding_scheme_utf_8, + esp_mail_char_decoding_scheme_iso8859_1, + esp_mail_char_decoding_scheme_iso8859_11, + esp_mail_char_decoding_scheme_tis_620, + esp_mail_char_decoding_scheme_windows_874 +}; + +enum esp_mail_imap_rights_type_t +{ + /* a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS) */ + esp_mail_imap_rights_administer = 'a' - 'a', + /* c - RFC2086 (obsoleted) create (CREATE new sub-mailboxes in any implementation-defined hierarchy) */ + esp_mail_imap_rights_create_c = 'c' - 'a', + /* d - RFC2086 (obsoleted) delete (STORE DELETED flag, perform EXPUNGE) */ + esp_mail_imap_rights_delete_d = 'd' - 'a', + /* e - perform EXPUNGE and expunge as a part of CLOSE */ + esp_mail_imap_rights_expunge = 'e' - 'a', + /* i - insert (perform APPEND, COPY into mailbox) */ + esp_mail_imap_rights_insert = 'i' - 'a', + /* k - RFC4314 create mailboxes (CREATE new sub-mailboxes in any implementation-defined hierarchy, parent mailbox for the new mailbox name in RENAME)*/ + esp_mail_imap_rights_create = 'k' - 'a', + /* l - lookup (mailbox is visible to LIST/LSUB commands, SUBSCRIBE mailbox) */ + esp_mail_imap_rights_lookup = 'l' - 'a', + /* p - post (send mail to submission address for mailbox, not enforced by IMAP4 itself) */ + esp_mail_imap_rights_post = 'p' - 'a', + /* r - read (SELECT the mailbox, perform STATUS) */ + esp_mail_imap_rights_read = 'r' - 'a', + /* s - keep seen/unseen information across sessions (set or clear \SEEN flag via STORE, also set \SEEN during APPEND/COPY/ FETCH BODY[...]) */ + esp_mail_imap_rights_seen = 's' - 'a', + /* t - RFC4314 delete messages (set or clear \DELETED flag via STORE, set \DELETED flag during APPEND/COPY) */ + esp_mail_imap_rights_delete_message = 't' - 'a', + /* w - write (set or clear flags other than \SEEN and \DELETED via STORE, also set them during APPEND/COPY) */ + esp_mail_imap_rights_write = 'w' - 'a', + /* x - RFC4314 delete mailbox (DELETE mailbox, old mailbox name in RENAME) */ + esp_mail_imap_rights_delete_mailbox = 'x' - 'a', + + esp_mail_imap_rights_maxType = esp_mail_imap_rights_delete_mailbox + 1 +}; + +enum esp_mail_imap_port +{ + esp_mail_imap_port_143 = 143, // PLAIN/TLS with STARTTLS + esp_mail_imap_port_993 = 993, // SSL +}; + +const struct port_function imap_ports[2] = { + {esp_mail_imap_port_143, esp_mail_protocol_plain_text}, + {esp_mail_imap_port_993, esp_mail_protocol_ssl}}; + +enum esp_mail_imap_auth_mode +{ + esp_mail_imap_mode_examine, + esp_mail_imap_mode_select +}; + +enum esp_mail_imap_response_status +{ + esp_mail_imap_resp_unknown, + esp_mail_imap_resp_ok, + esp_mail_imap_resp_no, + esp_mail_imap_resp_bad +}; + +enum esp_mail_imap_polling_status_type +{ + imap_polling_status_type_undefined, + imap_polling_status_type_new_message, + imap_polling_status_type_remove_message, + imap_polling_status_type_fetch_message +}; + +enum esp_mail_imap_header_state +{ + esp_mail_imap_state_content_type = esp_mail_rfc822_header_field_maxType, + esp_mail_imap_state_content_transfer_encoding, + esp_mail_imap_state_accept_language, + esp_mail_imap_state_content_language, + esp_mail_imap_state_char_set, + esp_mail_imap_state_boundary +}; + +enum esp_mail_imap_command +{ + esp_mail_imap_cmd_capability, + esp_mail_imap_cmd_starttls, + esp_mail_imap_cmd_sasl_login, + esp_mail_imap_cmd_sasl_auth_plain, + esp_mail_imap_cmd_sasl_auth_oauth, + esp_mail_imap_cmd_list, + esp_mail_imap_cmd_lsub, + esp_mail_imap_cmd_subscribe, + esp_mail_imap_cmd_unsubscribe, + esp_mail_imap_cmd_select, + esp_mail_imap_cmd_examine, + esp_mail_imap_cmd_close, + esp_mail_imap_cmd_status, + esp_mail_imap_cmd_search, + esp_mail_imap_cmd_fetch_body_header, + esp_mail_imap_cmd_fetch_body_mime, + esp_mail_imap_cmd_fetch_body_text, + esp_mail_imap_cmd_fetch_body_attachment, + esp_mail_imap_cmd_fetch_body_inline, + esp_mail_imap_cmd_fetch_sequence_set, + esp_mail_imap_cmd_logout, + esp_mail_imap_cmd_store, + esp_mail_imap_cmd_move, + esp_mail_imap_cmd_get_quota, + esp_mail_imap_cmd_set_quota, + esp_mail_imap_cmd_get_quota_root, + esp_mail_imap_cmd_get_acl, + esp_mail_imap_cmd_set_acl, + esp_mail_imap_cmd_delete_acl, + esp_mail_imap_cmd_my_rights, + esp_mail_imap_cmd_namespace, + esp_mail_imap_cmd_expunge, + esp_mail_imap_cmd_create, + esp_mail_imap_cmd_rename, + esp_mail_imap_cmd_delete, + esp_mail_imap_cmd_idle, + esp_mail_imap_cmd_done, + esp_mail_imap_cmd_get_uid, + esp_mail_imap_cmd_get_flags, + esp_mail_imap_cmd_append, + esp_mail_imap_cmd_append_last, + esp_mail_imap_cmd_enable, + esp_mail_imap_cmd_id, + esp_mail_imap_cmd_unselect, + esp_mail_imap_cmd_noop, + esp_mail_imap_cmd_copy, + esp_mail_imap_cmd_custom +}; + +enum esp_mail_imap_mime_fetch_type +{ + esp_mail_imap_mime_fetch_type_part, + esp_mail_imap_mime_fetch_type_sub_part1, + esp_mail_imap_mime_fetch_type_sub_part2 +}; + +enum esp_mail_imap_header_type +{ + esp_mail_imap_header_from, + esp_mail_imap_header_to, + esp_mail_imap_header_cc, + esp_mail_imap_header_subject, + esp_mail_imap_header_date, + esp_mail_imap_header_msg_id, + esp_mail_imap_header_cont_lang, + esp_mail_imap_header_accept_lang +}; + +enum esp_mail_imap_multipart_sub_type +{ + esp_mail_imap_multipart_sub_type_none = 0, + esp_mail_imap_multipart_sub_type_mixed, + esp_mail_imap_multipart_sub_type_alternative, + esp_mail_imap_multipart_sub_type_parallel, + esp_mail_imap_multipart_sub_type_digest, + esp_mail_imap_multipart_sub_type_related, + esp_mail_imap_multipart_sub_type_report, +}; + +enum esp_mail_imap_message_sub_type +{ + esp_mail_imap_message_sub_type_none = 0, + esp_mail_imap_message_sub_type_rfc822, + esp_mail_imap_message_sub_type_delivery_status, + esp_mail_imap_message_sub_type_partial, + esp_mail_imap_message_sub_type_external_body, +}; + +typedef struct esp_mail_imap_response_status_t +{ + // No IMAP server response status code (statusCode), server returns OK, NO and BAD response instead + + /* error code */ + int errorCode = 0; + MB_String tag; + MB_String text; + MB_String status; + bool completed = false; + +public: + void clear(bool clearTag = true) + { + if (clearTag) + tag.clear(); + status.clear(); + text.clear(); + completed = false; + } +} IMAP_Response; + +struct esp_mail_imap_msg_num_t +{ + esp_mail_imap_msg_num_type type = esp_mail_imap_msg_num_type_undefined; + uint32_t value = 0; +}; + +__attribute__((used)) struct +{ + bool operator()(struct esp_mail_imap_msg_num_t a, struct esp_mail_imap_msg_num_t b) const { return a.value > b.value; } +} compareMore; + +struct esp_mail_imap_rfc822_msg_header_item_t +{ + MB_String header_items[esp_mail_rfc822_header_field_maxType]; +}; + +/* IMAP quota root info */ +typedef struct esp_mail_imap_quota_root_info_t +{ + /* The quota root */ + MB_String quota_root; + + /* The resource name e.g. STORAGE and MESSAGE */ + MB_String name; + + /* The resource usage in kilo octets */ + size_t usage = 0; + + /* The resource limit in kilo octets */ + size_t limit = 0; + +} IMAP_Quota_Root_Info; + +/* IMAP namespace info */ +typedef struct esp_mail_imap_namespace_info_t +{ + /* The leading prefix */ + MB_String prefix; + + /* The hierarchy delimiter */ + MB_String delimiter; + +} IMAP_Namespace_Info; + +typedef struct esp_mail_imap_rights_info_t +{ + MB_String identifier; + bool rights[esp_mail_imap_rights_maxType]; + +} IMAP_Rights_Info; + +/* descrete media types (rfc 2046) */ +struct esp_mail_imap_descrete_media_type_t +{ + /** textual information with subtypes + * "plain" + * "enriched" (rfc 1896 revised from richtext in rfc 1341) + * + * unrecognized subtypes and charset should be interpreted as + * application/octet-stream + * + * parameters: + * "charset" (rfc 2045) default is us-ascii + * for character set includes 8-bit characters + * and such characters are used in the body, Content-Transfer-Encoding + * header field and a corresponding encoding on the data are required + * + * ISO-8859-X where "X" is to be replaced, as + * necessary, for the parts of ISO-8859 [ISO-8859]. + */ + static constexpr const char *text = "text"; + + /** image data with subtypes (rfc 2048) + * "jpeg" + * "gif" + * + * unrecognized subtypes should be interpreted as application/octet-stream + */ + static constexpr const char *image = "image"; + + /** audio data with initial subtype + * "baic" -- for single channel audio encoded using 8bit ISDN mu-law [PCM] + * at a sample rate of 8000 Hz. + * + * Unrecognized subtypes of "audio" should at a miniumum be treated as + * "application/octet-stream" + */ + static constexpr const char *audio = "audio"; + + /** video data with initial subtype + * "mpeg" + * + * Unrecognized subtypes of "video" should at a minumum be treated as + * "application/octet-stream" + */ + static constexpr const char *video = "video"; + + /** some other kind of data, typically either + * uninterpreted binary data or information to be + * processed by an application with subtypes + * + * "octet-stream" -- uninterpreted binary data + * "PostScript" -- for the transport of PostScript material + * + * Other expected uses include spreadsheets, data for mail-based + * scheduling systems, and languages for "active" (computational) + * messaging, and word processing formats that are not directly readable. + * + * The octet-stream subtype parameters: + * TYPE, PADDING, NAME + */ + static constexpr const char *application = "application"; +}; + +/** composite media types (rfc 2046) + * + * As stated in the definition of the Content-Transfer-Encoding field + * [RFC 2045], no encoding other than "7bit", "8bit", or "binary" is + * permitted for entities of type "multipart". The "multipart" boundary + * delimiters and header fields are always represented as 7bit US-ASCII + * in any case (though the header fields may encode non-US-ASCII header + * text as per RFC 2047) and data within the body parts can be encoded + * on a part-by-part basis, with Content-Transfer-Encoding fields for + * each appropriate body part. + */ +struct esp_mail_imap_composite_media_type_t +{ + /** data consisting of multiple entities of independent data types + * The Content-Type field for multipart entities requires one parameter, + * "boundary". + * The boundary delimiter line is then defined as a line + * consisting entirely of two hyphen characters ("-", decimal value 45) + * followed by the boundary parameter value from the Content-Type header + * field, optional linear whitespace, and a terminating CRLF. + * + * NOTE: The CRLF preceding the boundary delimiter line is conceptually + * attached to the boundary so that it is possible to have a part that + * does not end with a CRLF (line break). Body parts that must be + * considered to end with line breaks, therefore, must have two CRLFs + * preceding the boundary delimiter line, the first of which is part of + * the preceding body part, and the second of which is part of the + * encapsulation boundary. + * + * Boundary delimiters must not appear within the encapsulated material, + * and must be no longer than 70 characters, not counting the two + * leading hyphens. + * + * The boundary delimiter line following the last body part is a + * distinguished delimiter that indicates that no further body parts + * will follow. Such a delimiter line is identical to the previous + * delimiter lines, with the addition of two more hyphens after the + * boundary parameter value. + * + * See rfc2049 Appendix A for a Complex Multipart Example + */ + static constexpr const char *multipart = "multipart"; + + /* an encapsulated message */ + static constexpr const char *message = "message"; +}; + +typedef struct esp_mail_imap_mime_data_stream_info_t +{ + /* message UID */ + uint32_t uid = 0; + + /* content type */ + const char *type = ""; + + /* disposition */ + const char *disposition = ""; + + /* content character set */ + const char *charSet = ""; + + /* text content flowed format parameter */ + bool flowed = false; + + /* text content format DelSp parameter */ + bool delsp = false; + + /* content transfer encoding */ + const char *transfer_encoding = ""; + + /* content ID */ + const char *cid = ""; + + /* content description */ + const char *description = ""; + + /* content file name */ + const char *filename = ""; + + /* content name */ + const char *name = ""; + + /* creation date */ + const char *date = ""; + + /* content size */ + size_t size = 0; + + /* octet size */ + size_t octet_size = 0; + + /* current octet count */ + int octet_count = 0; + + /* data size */ + size_t data_size = 0; + + /* data buffer */ + void *data = NULL; + + bool isFirstData = false; + + bool isLastData = false; + +} MIME_Data_Stream_Info; + +typedef struct esp_mail_imap_decoding_info +{ + enum message_part_type + { + message_part_type_header, + message_part_type_text + }; + + /* The character set of the string to decode */ + const char *charset = ""; + + /* The string to decode */ + const char *data = ""; + + /* The decoded string to be processed */ + MB_String decodedString; + + /** The type of data that currently processed + * 0 or IMAP_Decoding_Info::message_part_type_header + * 1 or IMAP_Decoding_Info::message_part_type_text + */ + message_part_type type = message_part_type_header; + +} IMAP_Decoding_Info; + +struct esp_mail_imap_media_text_sub_type_t +{ + static constexpr const char *plain = "plain"; + static constexpr const char *enriched = "enriched"; + static constexpr const char *html = "html"; +}; + +/* multipart sub types */ +struct esp_mail_imap_multipart_sub_type_t +{ + /* a generic mixed set of parts */ + static constexpr const char *mixed = "mixed"; + + /* the same data in multiple formats */ + static constexpr const char *alternative = "alternative"; + + /* parts intended to be viewed simultaneously */ + static constexpr const char *parallel = "parallel"; + + /* multipart entities in which each part has a default type of + * "message/rfc822" */ + static constexpr const char *digest = "digest"; + + /* for compound objects consisting of several inter-related body parts (rfc + * 2387) */ + static constexpr const char *related = "related"; + + /* rfc 3462 */ + static constexpr const char *report = "report"; +}; + +/* message body sub types */ +struct esp_mail_imap_message_sub_type_t +{ + /* body contains an encapsulated message, with the syntax of an RFC 822 + * message. */ + static constexpr const char *rfc822 = "rfc822"; + + /* to allow large objects to be delivered as several separate pieces of mail + */ + static constexpr const char *Partial = "Partial"; + + /* the actual body data are not included, but merely referenced */ + static constexpr const char *External_Body = "External-Body"; + + static constexpr const char *delivery_status = "delivery-status"; +}; + +/* IMAP polling status */ +typedef struct esp_mail_imap_polling_status_t +{ + /** The type of status e.g. imap_polling_status_type_undefined, imap_polling_status_type_new_message, + * imap_polling_status_type_fetch_message and imap_polling_status_type_remove_message. + */ + esp_mail_imap_polling_status_type type = imap_polling_status_type_undefined; + + /** Message number or order from the total number of message that added, fetched or deleted. + */ + size_t messageNum = 0; + + /** Argument of commands e.g. FETCH + */ + MB_String argument; +} IMAP_Polling_Status; + +struct esp_mail_message_part_info_t +{ + enum content_header_field + { + content_header_field_none, + content_header_field_type, + content_header_field_description, + content_header_field_id, + content_header_field_disposition, + content_header_field_transfer_enc, + content_header_field_ext + + }; + + int octetLen = 0; + int octetCount = 0; + int attach_data_size = 0; + int textLen = 0; + bool sizeProp = false; + int nestedLevel = 0; + + // pointer to the MB_String for storing multi-line header field content. + uint32_t stringPtr = 0; + esp_mail_char_decoding_scheme stringEnc = esp_mail_char_decoding_scheme_default; + + content_header_field cur_content_hdr = content_header_field_none; + + MB_String partNumStr; + MB_String partNumFetchStr; + MB_String text; + MB_String filename; + MB_String CID; + MB_String type; + MB_String save_path; + MB_String name; + MB_String content_disposition; + MB_String content_description; + MB_String content_type; + MB_String descr; + MB_String content_transfer_encoding; + MB_String creation_date; + MB_String modification_date; + MB_String charset; + MB_String download_error; + esp_mail_attach_type attach_type = esp_mail_att_type_none; + esp_mail_message_type msg_type = esp_mail_msg_type_none; + bool file_open_write = false; + bool multipart = false; + bool is_firmware_file = false; + bool save_to_file = true; + size_t firmware_downloaded_byte = 0; + esp_mail_imap_multipart_sub_type multipart_sub_type = esp_mail_imap_multipart_sub_type_none; + esp_mail_imap_message_sub_type message_sub_type = esp_mail_imap_message_sub_type_none; + bool rfc822_part = false; + int rfc822_msg_Idx = 0; + struct esp_mail_imap_rfc822_msg_header_item_t rfc822_header; + bool error = false; + bool plain_flowed = false; + bool plain_delsp = false; + esp_mail_msg_xencoding xencoding = esp_mail_msg_xencoding_none; +}; + +struct esp_mail_message_header_t +{ + int header_data_len = 0; + + struct esp_mail_imap_rfc822_msg_header_item_t header_fields; + + MB_String content_type; + MB_String content_transfer_encoding; + uint32_t message_uid = 0; + uint32_t message_no = 0; + MB_String boundary; + MB_String accept_language; + MB_String content_language; + MB_String char_set; + bool multipart = false; + bool rfc822_part = false; + bool hasAttachment = false; + int rfc822Idx = 0; + MB_String partNumStr; + + esp_mail_imap_multipart_sub_type multipart_sub_type = esp_mail_imap_multipart_sub_type_none; + esp_mail_imap_message_sub_type message_sub_type = esp_mail_imap_message_sub_type_none; + MB_String msgID; + MB_String flags; + MB_String error_msg; + bool error = false; + _vectorImpl part_headers; + int attachment_count = 0; + int sd_alias_file_count = 0; + int total_download_size = 0; + int downloaded_size = 0; + int total_attach_data_size = 0; + int downloaded_bytes = 0; + int message_data_count = 0; +}; + +/* Internal use */ +struct esp_mail_folder_info_t +{ + MB_String name; + MB_String attributes; + MB_String delimiter; +}; + +struct esp_mail_folder_info_item_t +{ + /* The name of folder */ + const char *name = ""; + + /* The attributes of folder */ + const char *attributes = ""; + + /* The delimeter of folder */ + const char *delimiter = ""; +}; + +struct esp_mail_imap_download_config_t +{ + /* To download the PLAIN text content of the message */ + bool text = false; + + /* To download the HTML content of the message */ + bool html = false; + + /* To download the attachments of the message */ + bool attachment = false; + + /* To download the inline image of the message */ + bool inlineImg = false; + + /* To download the rfc822 mesages in the message */ + bool rfc822 = false; + + /* To download the message header */ + bool header = false; +}; + +struct esp_mail_imap_enable_config_t +{ + /* To store the PLAIN text of the message in the IMAPSession */ + bool text = false; + + /* To store the HTML of the message in the IMAPSession */ + bool html = false; + + /* To store the rfc822 messages in the IMAPSession */ + bool rfc822 = false; + + /* To enable the download status via the serial port */ + bool download_status = false; + + /* To sort the message UID of the search result in descending order */ + bool recent_sort = false; + + /* To allow case sesitive in header parsing */ + bool header_case_sensitive = false; +}; + +struct esp_mail_imap_limit_config_t +{ + /* The maximum messages from the search result */ + size_t search = 10; + + /* The maximum messages from the sequence set fetching result */ + size_t fetch = 30; + + /** The maximum size of the memory buffer to store the message content. + * This is only limit for data to be stored in the IMAPSession. + */ + size_t msg_size = 1024; + + /* The maximum size of each attachment to download */ + size_t attachment_size = 1024 * 1024 * 5; + + /* The IMAP idle timeout in ms (1 min to 29 min). Default is 8 min */ + size_t imap_idle_timeout = 8 * 60 * 1000; + + /** The IMAP idle host check interval in ms (30 sec to imap_idle_timeout) + * for internet availability checking to ensure the connection is active. + * Default is 1 min. + */ + size_t imap_idle_host_check_interval = 60 * 1000; +}; + +struct esp_mail_imap_storage_config_t +{ + /* The path to save the downloaded file */ + MB_String saved_path; + + /** The type of file storages e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + esp_mail_file_storage_type type = esp_mail_file_storage_type_flash; +}; + +struct esp_mail_imap_search_config_t +{ + /* The search criteria */ + MB_String criteria; + + /* The option to search the unseen message */ + bool unseen_msg = false; +}; + +struct esp_mail_imap_sequence_set_t +{ + /* The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number */ + MB_String string; + + /* The option for sequenceSet whether it is UID or message sequence number */ + bool UID = false; + + /* The option for header only fetching */ + bool headerOnly = false; +}; + +struct esp_mail_imap_fetch_config_t +{ + /* The UID of message to fetch */ + MB_String uid; + + /* The message sequence number to fetch */ + MB_String number; + + /* The sequence set options */ + esp_mail_imap_sequence_set_t sequence_set; + + /* Set the message flag as seen */ + bool set_seen = false; + + /* The int32_t option for CHANGESINCE conditional test. */ + int32_t modsequence = 0; + + /* The config to fetch only the header */ + bool headerOnly = false; +}; + +struct esp_mail_imap_firmware_config_t +{ + /* Update firmware using message attachments if one of its filename matches. */ + MB_String attach_filename; + + /* Save firmware file */ + bool save_to_file = false; +}; + +struct esp_mail_imap_data_config_t +{ + /* The config for fetching */ + struct esp_mail_imap_fetch_config_t fetch; + + /* The config for search */ + struct esp_mail_imap_search_config_t search; + + /* The config about the limits */ + struct esp_mail_imap_limit_config_t limit; + + /* The config to enable the features */ + struct esp_mail_imap_enable_config_t enable; + + /* The config about downloads */ + struct esp_mail_imap_download_config_t download; + + /* The config about the storage and path to save the downloaded file */ + struct esp_mail_imap_storage_config_t storage; + + /* The config about firmware updates and downloads for ESP32, ESP8266 and Raspberry Pi Pico */ + struct esp_mail_imap_firmware_config_t firmware_update; + + IMAP_Identification identification; +}; + +/* Mail and MIME Header Fields */ +struct esp_mail_imap_msg_item_t +{ + friend class IMAPSession; + +public: + esp_mail_imap_msg_item_t() + { + text.content_type = mimeinfo[esp_mail_file_extension_txt].mimeType; + html.content_type = mimeinfo[esp_mail_file_extension_html].mimeType; + }; + + /* The message number */ + int msgNo = 0; + + /* The message UID */ + int UID = 0; + + /* The message identifier (RFC 4021) */ + const char *ID = ""; + + /* The language(s) for auto-responses (RFC 4021) */ + const char *acceptLang = ""; + + /* The language of message content (RFC 4021) */ + const char *contentLang = ""; + + /* The mailbox of message author (RFC 4021) */ + const char *from = ""; + + /* The charset of the mailbox of message author */ + // deprecated + const char *fromCharset = ""; + + /* The primary recipient mailbox (RFC 4021) */ + const char *to = ""; + + /* The charset of the primary recipient mailbox */ + // deprecated + const char *toCharset = ""; + + /* The Carbon-copy recipient mailboxes (RFC 4021) */ + const char *cc = ""; + + /* The charset of the Carbon-copy recipient mailbox header */ + // deprecated + const char *ccCharset = ""; + + /* The Blind-carbon-copy recipient mailboxes (RFC 4021) */ + const char *bcc = ""; + + /* The charset of the Blind-carbon-copy recipient mailbox header */ + // deprecated + const char *bccCharset = ""; + + /* The message date and time (RFC 4021) */ + const char *date = ""; + + /* The topic of message (RFC 4021) */ + const char *subject = ""; + + /* The topic of message charset */ + // deprecated + const char *subjectCharset = ""; + + /* The message flags */ + const char *flags = ""; + + /* The PLAIN text content of the message */ + esp_mail_imap_plain_body_t text; + + /* The HTML content of the message */ + esp_mail_imap_html_body_t html; + + /* rfc822 related */ + + /* The sender Email */ + const char *sender; + + /* The charset of the sender Email */ + // deprecated + const char *senderCharset = ""; + + /* The keywords or phrases, separated by commas */ + const char *keywords = ""; + + /* The comments about message */ + const char *comments = ""; + + /* The field that contains the parent's message ID of the message to which this one is a reply */ + const char *in_reply_to = ""; + + /* The field that contains the parent's references (if any) and followed by the parent's message ID (if any) of the message to which this one is a reply */ + const char *references = ""; + + /* The return recipient of the message */ + const char *return_path = ""; + + /* The Email address to reply */ + const char *reply_to; + + /* The error description from fetching the message */ + const char *fetchError = ""; + + /* The info about the attachments in the message */ + _vectorImpl attachments; + + /* The info about the rfc822 messages included in the message */ + _vectorImpl rfc822; + + /* The status for message that contains attachment */ + bool hasAttachment = false; + +private: + void setRFC822Headers(struct esp_mail_imap_rfc822_msg_header_item_t *rfc822_header) + { + from = rfc822_header->header_items[esp_mail_rfc822_header_field_from].c_str(); + sender = rfc822_header->header_items[esp_mail_rfc822_header_field_sender].c_str(); + to = rfc822_header->header_items[esp_mail_rfc822_header_field_to].c_str(); + cc = rfc822_header->header_items[esp_mail_rfc822_header_field_cc].c_str(); + subject = rfc822_header->header_items[esp_mail_rfc822_header_field_subject].c_str(); + date = rfc822_header->header_items[esp_mail_rfc822_header_field_date].c_str(); + ID = rfc822_header->header_items[esp_mail_rfc822_header_field_msg_id].c_str(); + return_path = rfc822_header->header_items[esp_mail_rfc822_header_field_return_path].c_str(); + reply_to = rfc822_header->header_items[esp_mail_rfc822_header_field_reply_to].c_str(); + in_reply_to = rfc822_header->header_items[esp_mail_rfc822_header_field_in_reply_to].c_str(); + references = rfc822_header->header_items[esp_mail_rfc822_header_field_references].c_str(); + comments = rfc822_header->header_items[esp_mail_rfc822_header_field_comments].c_str(); + keywords = rfc822_header->header_items[esp_mail_rfc822_header_field_keywords].c_str(); + bcc = rfc822_header->header_items[esp_mail_rfc822_header_field_bcc].c_str(); + flags = rfc822_header->header_items[esp_mail_rfc822_header_field_flags].c_str(); + text.charSet = ""; + text.content_type = ""; + text.transfer_encoding = ""; + html.charSet = ""; + html.content_type = ""; + html.transfer_encoding = ""; + } +}; + +struct esp_mail_imap_msg_list_t +{ + /* The info of a message */ + _vectorImpl msgItems; +}; + +struct esp_mail_imap_multipart_level_t +{ + uint8_t level = 0; + bool fetch_rfc822_header = false; + bool append_body_text = false; +}; + +struct esp_mail_imap_response_data +{ +public: + esp_mail_imap_response_status imapResp = esp_mail_imap_resp_unknown; + char *response = nullptr; + int readLen = 0; + long dataTime = millis(); + int chunkBufSize = 512; + int chunkIdx = 0; + bool isUntaggedResponse = false; + bool untaggedRespCompleted = false; + bool completedResponse = false; + bool endSearch = false; + struct esp_mail_message_header_t header; + struct esp_mail_message_part_info_t part; + MB_String filePath; + bool downloadRequest = false; + int octetCount = 0; + int octetLength = 0; + bool tmo = false; + int headerState = 0; + int searchCount = 0; + char *lastBuf = nullptr; + char *buf = nullptr; + + esp_mail_imap_response_data(int bufLen) { chunkBufSize = bufLen; }; + ~esp_mail_imap_response_data() { clear(); } + void clear() + { + if (response) + free(response); + if (lastBuf) + free(lastBuf); + if (buf) + free(buf); + + response = nullptr; + lastBuf = nullptr; + buf = nullptr; + } +}; + +#endif + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + +struct esp_mail_link_internal_t +{ + MB_String cid; +}; + +struct esp_mail_sesson_cert_config_t +{ + /* The certificate data (base64 data) */ + const char *cert_data = NULL; + + /* The certificate file (DER format) */ + MB_String cert_file; + + /* The storage type */ + esp_mail_file_storage_type cert_file_storage_type; + + /* The cerificate verification option */ + bool verify = false; +}; + +struct esp_mail_smtp_logs_config_t +{ + + /* The log file path */ + MB_String filename; + + /* The storage type */ + esp_mail_file_storage_type storage_type; +}; + +struct esp_mail_sesson_sever_config_t +{ + /* The hostName of the server */ + MB_String host_name; + /* The port on the server to connect to */ + uint16_t port = 0; +}; + +/* The log in credentials */ +struct esp_mail_sesson_login_config_t +{ + /* The user Email address to log in */ + MB_String email; + + /* The user password to log in */ + MB_String password; + + /* The OAuth2.0 access token to log in */ + MB_String accessToken; + + /* The host name or public IP of client system */ + MB_String user_domain; +}; + +/* The device time config */ +struct esp_mail_sesson_time_config_t +{ + /* set the NTP servers (use comma to separate the servers) to let the library to set the time from NTP server */ + MB_String ntp_server; + + /* the GMT offset or time zone */ + float gmt_offset = 0; + + /* the day light saving offset */ + float day_light_offset = 0; + + /** TZ environment variable for local time setting + * See https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv + */ + MB_String timezone_env_string; + + /* the file path to store TZ environment variable */ + MB_String timezone_file = "/tze.txt"; +}; + +struct esp_mail_sesson_secure_config_t +{ + /** The option (obsoleted) to send the SMTP and IMAP commands to start the TLS connection rfc2595 section 3 and rfc3207 */ + bool startTLS = false; + + /* The secure connection mode preference */ + esp_mail_secure_mode mode = esp_mail_secure_mode_undefined; +}; + +struct esp_mail_spi_ethernet_module_t +{ +#if defined(ESP8266) && defined(ESP8266_CORE_SDK_V3_X_X) +#ifdef INC_ENC28J60_LWIP + ENC28J60lwIP *enc28j60 = nullptr; +#endif +#ifdef INC_W5100_LWIP + Wiznet5100lwIP *w5100 = nullptr; +#endif +#ifdef INC_W5500_LWIP + Wiznet5500lwIP *w5500 = nullptr; +#endif +#elif defined(MB_ARDUINO_PICO) + +#endif +}; + +struct esp_mail_session_config_t +{ + friend class IMAPSession; + friend class SMTPSession; + friend class ESP_Mail_Client; + + /* The server config */ + struct esp_mail_sesson_sever_config_t server; + + /* The log in config */ + struct esp_mail_sesson_login_config_t login; + + /* The device time config */ + struct esp_mail_sesson_time_config_t time; + + /* The secure config */ + struct esp_mail_sesson_secure_config_t secure; + + /* The certificate config */ + struct esp_mail_sesson_cert_config_t certificate; + + /* SPI Ethernet Module config for ESP8266 */ + struct esp_mail_spi_ethernet_module_t spi_ethernet_module; + + /* The callback function for WiFi connection */ + NetworkConnectionHandler network_connection_handler = NULL; + + /* specific ports and its protocols */ + struct esp_mail_ports_functions ports_functions; + + /* The mail sending logs config */ + struct esp_mail_smtp_logs_config_t sentLogs; + +public: + esp_mail_session_config_t(){}; + + ~esp_mail_session_config_t() + { + clear(); + aremovePtr(); + } + + void addPtr(_vectorImpl *listPtr, int ptr) + { + if (listPtr) + { + this->listPtr = listPtr; + bool existed = false; + + for (size_t i = 0; i < this->listPtr->size(); i++) + { + if ((*this->listPtr)[i] == ptr) + existed = true; + } + + if (!existed) + this->listPtr->push_back(ptr); + } + } + + void aremovePtr() + { + if (listPtr) + { + int ptr = toAddr(*this); + for (size_t i = 0; i < listPtr->size(); i++) + { + if ((*listPtr)[i] == ptr) + { + listPtr->erase(listPtr->begin() + i, listPtr->begin() + i + 1); + break; + } + } + } + } + + void clear() + { + server.host_name.clear(); + server.port = 0; + + secure.startTLS = false; + secure.mode = esp_mail_secure_mode_undefined; + + login.email.clear(); + login.password.clear(); + login.user_domain.clear(); + login.accessToken.clear(); + + time.day_light_offset = 0; + time.gmt_offset = 0; + time.ntp_server.clear(); + time.timezone_env_string.clear(); + + certificate.cert_data = ""; + certificate.cert_file = ""; + certificate.cert_file_storage_type = esp_mail_file_storage_type_none; + certificate.verify = false; + + clearPorts(); + } + +private: + int cert_ptr = 0; + bool cert_updated = false; + _vectorImpl *listPtr = nullptr; + + // Internal flags use to keep user sercure.startTLS and secure.mode. + bool int_start_tls = false; + esp_mail_secure_mode int_mode = esp_mail_secure_mode_undefined; + + void clearPorts() + { + if (ports_functions.list) + { + if (ports_functions.use_internal_list) + { + ports_functions.size = 0; + ports_functions.use_internal_list = false; + delete[] ports_functions.list; + ports_functions.list = nullptr; + } + } + } +}; + +/** The content transfer encoding + * enc_7bit or "7bit" + * enc_qp or "quoted-printable" + * enc_base64 or "base64" + * enc_binary or "binary" + * enc_8bit or "8bit" + */ +typedef struct esp_mail_transfer_encoding_t Content_Transfer_Encoding; + +/* The session configuations */ +typedef struct esp_mail_session_config_t ESP_Mail_Session; // obsoleted +typedef struct esp_mail_session_config_t Session_Config; + +#endif + +#if defined(ENABLE_SMTP) +/* The result from sending the Email */ +typedef struct esp_mail_smtp_send_status_t SMTP_Result; + +/* The attachment details for sending the Email */ +typedef struct esp_mail_attachment_t SMTP_Attachment; +#endif + +#if defined(ENABLE_SMTP) && defined(ENABLE_IMAP) + +typedef struct esp_mail_attachment_t ESP_Mail_Attachment; + +#endif + +#if defined(ENABLE_IMAP) +/* The info of the selected or open mailbox folder e.g. name, attributes and + * delimiter */ +typedef struct esp_mail_folder_info_item_t FolderInfo; +/* The attachment item details for a message which returned from fetching the + * Email */ +typedef struct esp_mail_attachment_info_t IMAP_Attach_Item; + +/** The IMAP operation configuations */ +typedef struct esp_mail_imap_data_config_t IMAP_Config; // obsoleted + +typedef struct esp_mail_imap_data_config_t IMAP_Data; + +/* The message item data of the IMAP_MSG_List which contains header, body and + * attachments info for eacch message*/ +typedef struct esp_mail_imap_msg_item_t IMAP_MSG_Item; + +/* The list that contains the message items from searching or fetching the Email + */ +typedef struct esp_mail_imap_msg_list_t IMAP_MSG_List; + +#endif + +struct esp_mail_wifi_credential_t +{ + MB_String ssid; + MB_String password; +}; + +struct esp_mail_wifi_credentials_t +{ + friend class ESP_Mail_Client; + friend class ESP_Mail_TCPClient; + +public: + esp_mail_wifi_credentials_t(){}; + ~esp_mail_wifi_credentials_t() + { + clearAP(); + clearMulti(); + }; + void addAP(const String &ssid, const String &password) + { + esp_mail_wifi_credential_t cred; + cred.ssid = ssid; + cred.password = password; + credentials.push_back(cred); + } + void clearAP() + { + credentials.clear(); + } + +private: + _vectorImpl credentials; +#if defined(ESP_MAIL_HAS_WIFIMULTI) + WiFiMulti *multi = nullptr; +#endif + + void reconnect() + { + if (credentials.size()) + { + disconnect(); + connect(); + } + } + + void connect() + { +#if defined(ESP_MAIL_HAS_WIFIMULTI) + + clearMulti(); + multi = new WiFiMulti(); + for (size_t i = 0; i < credentials.size(); i++) + multi->addAP(credentials[i].ssid.c_str(), credentials[i].password.c_str()); + + if (credentials.size() > 0) + multi->run(); + +#elif defined(ESP_MAIL_WIFI_IS_AVAILABLE) + WiFi.begin((CONST_STRING_CAST)credentials[0].ssid.c_str(), credentials[0].password.c_str()); +#endif + } + + void disconnect() + { +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + WiFi.disconnect(); +#endif + } + + void clearMulti() + { +#if defined(ESP_MAIL_HAS_WIFIMULTI) + if (multi) + delete multi; + multi = nullptr; +#endif + } +}; + +static const char esp_mail_imap_tag_str[] PROGMEM = "xmail"; + +#if !defined(SILENT_MODE) +static const char esp_mail_version_str[] PROGMEM = "ESP Mail Client v"; + +///////////////////////// +// SMTP debug string + +static const char esp_mail_dbg_str_1[] PROGMEM = "send command, STARTTLS"; +static const char esp_mail_dbg_str_2[] PROGMEM = "connecting to SMTP server"; + +#if defined(ENABLE_SMTP) +static const char esp_mail_dbg_str_3[] PROGMEM = "send Email"; +static const char esp_mail_dbg_str_4[] PROGMEM = "SMTP server connected"; +static const char esp_mail_dbg_str_5[] PROGMEM = "send SMTP command, EHLO"; +static const char esp_mail_dbg_str_6[] PROGMEM = "send SMTP command, AUTH LOGIN"; +static const char esp_mail_dbg_str_7[] PROGMEM = "send SMTP command, AUTH PLAIN"; +static const char esp_mail_dbg_str_8[] PROGMEM = "send message header"; +static const char esp_mail_dbg_str_9[] PROGMEM = "send message body"; +static const char esp_mail_dbg_str_10[] PROGMEM = "send attachments"; +static const char esp_mail_dbg_str_11[] PROGMEM = "terminate the SMTP session"; +static const char esp_mail_dbg_str_12[] PROGMEM = "message sent successfully"; +static const char esp_mail_dbg_str_13[] PROGMEM = "send next Email"; +static const char esp_mail_dbg_str_14[] PROGMEM = "send inline data"; +static const char esp_mail_dbg_str_15[] PROGMEM = "send smtp command, AUTH XOAUTH2"; +static const char esp_mail_dbg_str_16[] PROGMEM = "finishing the message sending"; +static const char esp_mail_dbg_str_17[] PROGMEM = "No ESMTP supported, send SMTP command, HELO"; +#endif + +///////////////////////// +// IMAP debug string +static const char esp_mail_dbg_str_18[] PROGMEM = "connecting to IMAP server"; +static const char esp_mail_dbg_str_19[] PROGMEM = "Host > "; +static const char esp_mail_dbg_str_20[] PROGMEM = "Port > "; +static const char esp_mail_dbg_str_21[] PROGMEM = "Reading time from NTP server"; +static const char esp_mail_dbg_str_22[] PROGMEM = "perform SSL/TLS handshake"; + +#if defined(ENABLE_IMAP) +static const char esp_mail_dbg_str_23[] PROGMEM = "get my ACL"; +static const char esp_mail_dbg_str_24[] PROGMEM = "checking the capability"; +static const char esp_mail_dbg_str_25[] PROGMEM = "fetching message "; +static const char esp_mail_dbg_str_26[] PROGMEM = "fetch message header"; +static const char esp_mail_dbg_str_27[] PROGMEM = "fetch body part header, "; +static const char esp_mail_dbg_str_28[] PROGMEM = "fetch body sub part header, "; +static const char esp_mail_dbg_str_29[] PROGMEM = "finished reading Email"; +static const char esp_mail_dbg_str_30[] PROGMEM = "UID is "; +static const char esp_mail_dbg_str_31[] PROGMEM = "log out completed"; +static const char esp_mail_dbg_str_32[] PROGMEM = "closing the "; +static const char esp_mail_dbg_str_33[] PROGMEM = "IMAP server connected"; +static const char esp_mail_dbg_str_34[] PROGMEM = "send IMAP command, LOGIN"; +static const char esp_mail_dbg_str_35[] PROGMEM = "send IMAP command, LIST"; +static const char esp_mail_dbg_str_36[] PROGMEM = "searching messages"; +static const char esp_mail_dbg_str_37[] PROGMEM = "send IMAP command, FETCH"; +static const char esp_mail_dbg_str_38[] PROGMEM = "send IMAP command, LOGOUT"; +static const char esp_mail_dbg_str_39[] PROGMEM = "message fetching completed"; +static const char esp_mail_dbg_str_40[] PROGMEM = "opening the mailbox folder"; +static const char esp_mail_dbg_str_41[] PROGMEM = "setting FLAG"; +static const char esp_mail_dbg_str_42[] PROGMEM = "adding FLAG"; +static const char esp_mail_dbg_str_43[] PROGMEM = "removing FLAG"; +static const char esp_mail_dbg_str_44[] PROGMEM = "send IMAP command, AUTHENTICATE PLAIN"; +static const char esp_mail_dbg_str_45[] PROGMEM = "send IMAP command, AUTH XOAUTH2"; +static const char esp_mail_dbg_str_46[] PROGMEM = "reading plain TEXT message"; +static const char esp_mail_dbg_str_47[] PROGMEM = "reading HTML message"; +static const char esp_mail_dbg_str_48[] PROGMEM = "copying message(s) to "; +static const char esp_mail_dbg_str_49[] PROGMEM = "creating folder"; +static const char esp_mail_dbg_str_50[] PROGMEM = "deleting folder"; +static const char esp_mail_dbg_str_51[] PROGMEM = "listening to "; +static const char esp_mail_dbg_str_52[] PROGMEM = " folder changes"; +static const char esp_mail_dbg_str_53[] PROGMEM = "polling established"; +static const char esp_mail_dbg_str_54[] PROGMEM = "Mailbox listening stopped"; +static const char esp_mail_dbg_str_55[] PROGMEM = "renaming folder"; +static const char esp_mail_dbg_str_56[] PROGMEM = "send IMAP command, LSUB"; +static const char esp_mail_dbg_str_57[] PROGMEM = "send IMAP command, SUBSCRIBE"; +static const char esp_mail_dbg_str_58[] PROGMEM = "send IMAP command, UNSUBSCRIBE"; +static const char esp_mail_dbg_str_59[] PROGMEM = "moving message(s) to "; +static const char esp_mail_dbg_str_60[] PROGMEM = "send IMAP command, GETQUOTA"; +static const char esp_mail_dbg_str_61[] PROGMEM = "send IMAP command, SETQUOTA"; +static const char esp_mail_dbg_str_62[] PROGMEM = "send IMAP command, GETQUOTAROOT"; +static const char esp_mail_dbg_str_63[] PROGMEM = "send IMAP command, GETACL"; +static const char esp_mail_dbg_str_64[] PROGMEM = "send IMAP command, SETACL"; +static const char esp_mail_dbg_str_65[] PROGMEM = "send IMAP command, DELETEACL"; +static const char esp_mail_dbg_str_66[] PROGMEM = "send IMAP command, MYRIGHTS"; +static const char esp_mail_dbg_str_67[] PROGMEM = "send IMAP command, NAMESPACE"; +static const char esp_mail_dbg_str_68[] PROGMEM = "selecting the "; +static const char esp_mail_dbg_str_69[] PROGMEM = "appending message"; +static const char esp_mail_dbg_str_70[] PROGMEM = "download attachment %d of %d"; +static const char esp_mail_dbg_str_71[] PROGMEM = "download HTML message"; +static const char esp_mail_dbg_str_72[] PROGMEM = "deleting the ACL"; +static const char esp_mail_dbg_str_73[] PROGMEM = "message append successfully"; +static const char esp_mail_dbg_str_74[] PROGMEM = "download plain TEXT message"; +static const char esp_mail_dbg_str_75[] PROGMEM = "deleting message(s)"; +static const char esp_mail_dbg_str_76[] PROGMEM = "check the capability"; +static const char esp_mail_dbg_str_77[] PROGMEM = "get the ACL"; +static const char esp_mail_dbg_str_78[] PROGMEM = "set the ACL"; +static const char esp_mail_dbg_str_79[] PROGMEM = "get UID"; +static const char esp_mail_dbg_str_80[] PROGMEM = "get Flags"; +static const char esp_mail_dbg_str_81[] PROGMEM = "delete folder"; +static const char esp_mail_dbg_str_82[] PROGMEM = "send IMAP command, ID"; +static const char esp_mail_dbg_str_83[] PROGMEM = "send IMAP command, NOOP"; +#endif + +///////////////////////// +// SMTP callback string + +static const char esp_mail_cb_str_1[] PROGMEM = "Connecting to SMTP server..."; +static const char esp_mail_cb_str_2[] PROGMEM = "Sending STARTTLS command..."; + +#if defined(ENABLE_SMTP) +static const char esp_mail_cb_str_3[] PROGMEM = "Sending greeting response..."; +static const char esp_mail_cb_str_4[] PROGMEM = "Sending message header..."; +static const char esp_mail_cb_str_5[] PROGMEM = "Sending message body..."; +static const char esp_mail_cb_str_6[] PROGMEM = "Sending attachments..."; +static const char esp_mail_cb_str_7[] PROGMEM = "Closing the session..."; +static const char esp_mail_cb_str_8[] PROGMEM = "Sending inline data..."; +static const char esp_mail_cb_str_9[] PROGMEM = "Sending Email..."; +static const char esp_mail_cb_str_10[] PROGMEM = "Sending next Email..."; +static const char esp_mail_cb_str_11[] PROGMEM = "Finishing the message sending..."; +static const char esp_mail_cb_str_12[] PROGMEM = "SMTP server connected, wait for greeting..."; +static const char esp_mail_cb_str_13[] PROGMEM = "Message sent successfully"; +#endif + +///////////////////////// +// IMAP callback string + +static const char esp_mail_cb_str_14[] PROGMEM = "Logging in..."; // shared with SMTP +static const char esp_mail_cb_str_15[] PROGMEM = "Connecting to IMAP server..."; + +#if defined(ENABLE_IMAP) + +static const char esp_mail_cb_str_16[] PROGMEM = "Reading the list of mailboxes..."; +static const char esp_mail_cb_str_17[] PROGMEM = "Checking the capability..."; +static const char esp_mail_cb_str_18[] PROGMEM = "Searching messages..."; +static const char esp_mail_cb_str_19[] PROGMEM = "Downloading attachments..."; +static const char esp_mail_cb_str_20[] PROGMEM = "Logging out..."; +static const char esp_mail_cb_str_21[] PROGMEM = "Saving message header to file..."; +static const char esp_mail_cb_str_22[] PROGMEM = "Get FLAG..."; +static const char esp_mail_cb_str_23[] PROGMEM = "Removing FLAG..."; +static const char esp_mail_cb_str_24[] PROGMEM = "Adding FLAG..."; +static const char esp_mail_cb_str_25[] PROGMEM = "Get UID..."; +static const char esp_mail_cb_str_26[] PROGMEM = "Setting FLAG..."; +static const char esp_mail_cb_str_27[] PROGMEM = "Closing the mailbox folder..."; +static const char esp_mail_cb_str_28[] PROGMEM = "Reading messages..."; +static const char esp_mail_cb_str_29[] PROGMEM = "Listening to mailbox changes..."; +static const char esp_mail_cb_str_30[] PROGMEM = "Listing the subscribed mailboxes..."; +static const char esp_mail_cb_str_31[] PROGMEM = "Subscribe mailbox..."; +static const char esp_mail_cb_str_32[] PROGMEM = "Unsubscribe mailbox..."; +static const char esp_mail_cb_str_33[] PROGMEM = "Get quota root resource usage and limit..."; +static const char esp_mail_cb_str_34[] PROGMEM = "Set quota root resource usage and limit..."; +static const char esp_mail_cb_str_35[] PROGMEM = "Get the list of quota roots..."; +static const char esp_mail_cb_str_36[] PROGMEM = "Get the ACL..."; +static const char esp_mail_cb_str_37[] PROGMEM = "Setting the ACL..."; +static const char esp_mail_cb_str_38[] PROGMEM = "Deleting the ACL..."; +static const char esp_mail_cb_str_39[] PROGMEM = "Get my ACL..."; +static const char esp_mail_cb_str_40[] PROGMEM = "Get namespace..."; +static const char esp_mail_cb_str_41[] PROGMEM = "Enable capability..."; +static const char esp_mail_cb_str_42[] PROGMEM = "Updating firmware..."; +static const char esp_mail_cb_str_43[] PROGMEM = "Downloading messages..."; +static const char esp_mail_cb_str_44[] PROGMEM = "Appending message..."; +static const char esp_mail_cb_str_45[] PROGMEM = "Message append successfully"; +static const char esp_mail_cb_str_46[] PROGMEM = "Finished reading Email"; +static const char esp_mail_cb_str_47[] PROGMEM = "Log out completed"; +static const char esp_mail_cb_str_48[] PROGMEM = "IMAP server connected"; +static const char esp_mail_cb_str_49[] PROGMEM = "Polling established"; +static const char esp_mail_cb_str_50[] PROGMEM = "Mailbox listening stopped"; +static const char esp_mail_cb_str_51[] PROGMEM = "Open the mailbox folder..."; +static const char esp_mail_cb_str_52[] PROGMEM = "Checking the capability..."; +static const char esp_mail_cb_str_53[] PROGMEM = "Renaming folder..."; +static const char esp_mail_cb_str_54[] PROGMEM = "UID is "; +static const char esp_mail_cb_str_55[] PROGMEM = "Get Flags..."; +static const char esp_mail_cb_str_56[] PROGMEM = "Deleting folder..."; +static const char esp_mail_cb_str_57[] PROGMEM = "Deleting message(s)..."; +static const char esp_mail_cb_str_58[] PROGMEM = "Copying message(s)..."; +static const char esp_mail_cb_str_59[] PROGMEM = "Creating folder..."; +static const char esp_mail_cb_str_60[] PROGMEM = "Moving message(s)..."; +static const char esp_mail_cb_str_61[] PROGMEM = "Send client identification..."; +static const char esp_mail_cb_str_62[] PROGMEM = "Send noop..."; +#endif + +#endif + +///////////////////////// +// Mem error string + +#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) +static const char esp_mail_error_mem_str_1[] PROGMEM = "flash Storage is not ready."; +static const char esp_mail_error_mem_str_2[] PROGMEM = "SD Storage is not ready."; +static const char esp_mail_error_mem_str_3[] PROGMEM = "file does not exist or can't access"; +#endif +static const char esp_mail_error_mem_str_4[] PROGMEM = "PSRAM was enabled but not detected."; +#endif + +#if defined(ENABLE_ERROR_STRING) + +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) +static const char esp_mail_error_mem_str_5[] PROGMEM = "file is still opened."; +static const char esp_mail_error_mem_str_6[] PROGMEM = "file not found."; +static const char esp_mail_error_mem_str_7[] PROGMEM = "file I/O error"; +#endif + +static const char esp_mail_error_mem_str_8[] PROGMEM = "out of memory"; +static const char esp_mail_error_mem_str_9[] PROGMEM = "buffer overflow"; + +#endif + +#if defined(MB_ARDUINO_PICO) +#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) +static const char esp_mail_error_mem_str_10[] PROGMEM = "please make sure that the size of flash filesystem is not 0 in Pico."; +#endif +#endif + +///////////////////////// +// Client error string + +#if !defined(SILENT_MODE) +static const char esp_mail_error_client_str_1[] PROGMEM = "client and/or necessary callback functions are not yet assigned"; +static const char esp_mail_error_client_str_2[] PROGMEM = "network connection callback is required"; +static const char esp_mail_error_client_str_3[] PROGMEM = "network connection status callback is required"; +static const char esp_mail_error_client_str_4[] PROGMEM = "NTP server time reading cannot begin when valid time is required because of no WiFi capability/activity detected."; +static const char esp_mail_error_client_str_5[] PROGMEM = "Please set the library reference time manually using smtp.setSystemTime or imap.setSystemTime."; +#endif + +///////////////////////// +// Network error string + +#if !defined(SILENT_MODE) +static const char esp_mail_error_network_str_1[] PROGMEM = "unable to connect to server"; +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_network_str_2[] PROGMEM = "NTP server time reading timed out"; +static const char esp_mail_error_network_str_3[] PROGMEM = "response read timed out"; +static const char esp_mail_error_network_str_4[] PROGMEM = "not connected"; +static const char esp_mail_error_network_str_5[] PROGMEM = "connection timeout"; +static const char esp_mail_error_network_str_6[] PROGMEM = "connection closed"; +static const char esp_mail_error_network_str_7[] PROGMEM = "connection refused"; +static const char esp_mail_error_network_str_8[] PROGMEM = "data sending failed"; +#endif +#endif + +#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) +static const char esp_mail_error_network_str_9[] PROGMEM = "response read timed out"; +#endif + +///////////////////////// +// SSL error string + +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_ssl_str_1[] PROGMEM = "fail to set up the SSL/TLS structure"; +#endif +#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) +static const char esp_mail_error_ssl_str_2[] PROGMEM = "the alert SSL record received"; +static const char esp_mail_error_ssl_str_3[] PROGMEM = "make sure the SSL/TLS handshake was done before sending the data"; +#endif + +///////////////////////// +// Auth error string + +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_auth_str_1[] PROGMEM = "the provided SASL authentication mechanism is not support"; +static const char esp_mail_error_auth_str_2[] PROGMEM = "OAuth2.0 log in was disabled for this server"; +static const char esp_mail_error_auth_str_3[] PROGMEM = "not yet log in"; +#endif + +///////////////////////// +// Session error string + +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_session_str_1[] PROGMEM = "the Session_Config object was not assigned"; +#endif + +///////////////////////// +// Time error string +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_time_str_1[] PROGMEM = "library or device time was not set, see examples/SMTP/Set_Time.ino for manually time setting"; +#endif + +///////////////////////// +// SMTP error string +#if defined(ENABLE_SMTP) +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_smtp_str_1[] PROGMEM = "SMTP server greeting failed"; +static const char esp_mail_error_smtp_str_2[] PROGMEM = "authentication failed"; +static const char esp_mail_error_smtp_str_3[] PROGMEM = "login password is not valid"; +static const char esp_mail_error_smtp_str_4[] PROGMEM = "send header failed"; +static const char esp_mail_error_smtp_str_5[] PROGMEM = "send body failed"; +static const char esp_mail_error_smtp_str_7[] PROGMEM = "sender Email address is not valid"; +static const char esp_mail_error_smtp_str_8[] PROGMEM = "some of the recipient Email address is not valid"; +static const char esp_mail_error_smtp_str_9[] PROGMEM = "set recipient failed"; +static const char esp_mail_error_smtp_str_10[] PROGMEM = "send custom command failed"; +static const char esp_mail_error_smtp_str_11[] PROGMEM = "XOAuth2 authenticate failed"; +static const char esp_mail_error_smtp_str_12[] PROGMEM = "undefined error"; +#endif +#endif + +///////////////////////// +// IMAP error string +#if defined(ENABLE_IMAP) +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_imap_str_1[] PROGMEM = "fail to list the mailboxes"; +static const char esp_mail_error_imap_str_2[] PROGMEM = "fail to check the capabilities"; + +static const char esp_mail_error_imap_str_3[] PROGMEM = "fail to close the mailbox"; + +static const char esp_mail_error_imap_str_4[] PROGMEM = "fail to open the mailbox"; +static const char esp_mail_error_imap_str_5[] PROGMEM = "some of the requested messages no longer exist"; +static const char esp_mail_error_imap_str_6[] PROGMEM = "firmware update initialization failed"; +static const char esp_mail_error_imap_str_7[] PROGMEM = "firmware update write failed"; +static const char esp_mail_error_imap_str_8[] PROGMEM = "firmware update finalize failed"; + +#endif +#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) +static const char esp_mail_error_imap_str_9[] PROGMEM = "no messages found for the specified search criteria"; +static const char esp_mail_error_imap_str_10[] PROGMEM = "no search criteria provided, then fetching the latest message"; +static const char esp_mail_error_imap_str_11[] PROGMEM = "no mailbox opened"; +static const char esp_mail_error_imap_str_12[] PROGMEM = "no content"; +static const char esp_mail_error_imap_str_13[] PROGMEM = "this feature was not supported"; +static const char esp_mail_error_imap_str_14[] PROGMEM = "no message changed since (assigned) modsec"; +static const char esp_mail_error_imap_str_15[] PROGMEM = "CONDSTORE was not supported or modsec was not supported for selected mailbox"; +static const char esp_mail_error_imap_str_17[] PROGMEM = "could not parse command"; +static const char esp_mail_error_imap_str_18[] PROGMEM = "server disconnected or returned error"; +static const char esp_mail_error_imap_str_19[] PROGMEM = "authenticate failed"; +static const char esp_mail_error_imap_str_20[] PROGMEM = "flags or keywords store failed"; +static const char esp_mail_error_imap_str_21[] PROGMEM = "server is not support OAuth2 login"; +#endif +#endif + +///////////////////////// +// General use string +static const char esp_mail_str_1[] PROGMEM = "127.0.0.1"; +static const char esp_mail_str_2[] PROGMEM = " "; +static const char esp_mail_str_3[] PROGMEM = "*"; +static const char esp_mail_str_4[] PROGMEM = "High"; +static const char esp_mail_str_5[] PROGMEM = "Normal"; +static const char esp_mail_str_6[] PROGMEM = "Low"; +static const char esp_mail_str_7[] PROGMEM = "="; +static const char esp_mail_str_8[] PROGMEM = ","; +static const char esp_mail_str_9[] PROGMEM = "--"; +static const char esp_mail_str_10[] PROGMEM = "/"; +static const char esp_mail_str_11[] PROGMEM = "\""; +static const char esp_mail_str_12[] PROGMEM = "Error, "; +static const char esp_mail_str_13[] PROGMEM = "msg.txt"; +static const char esp_mail_str_14[] PROGMEM = "msg.html"; +static const char esp_mail_str_15[] PROGMEM = "flash content message"; +static const char esp_mail_str_16[] PROGMEM = "file content message"; +static const char esp_mail_str_17[] PROGMEM = "cid:"; +static const char esp_mail_str_18[] PROGMEM = "\r\n"; +static const char esp_mail_str_19[] PROGMEM = "<"; +static const char esp_mail_str_20[] PROGMEM = ">"; +static const char esp_mail_str_21[] PROGMEM = "(\"name\" \"ESP Mail Client\" \"version\" \"%s\")"; +static const char esp_mail_str_22[] PROGMEM = "message/rfc822"; +static const char esp_mail_str_23[] PROGMEM = "upload"; +static const char esp_mail_str_24[] PROGMEM = "%"; +static const char esp_mail_str_25[] PROGMEM = "status code: "; +static const char esp_mail_str_26[] PROGMEM = ", text: "; +static const char esp_mail_str_27[] PROGMEM = "."; +static const char esp_mail_str_28[] PROGMEM = "> C: "; +static const char esp_mail_str_29[] PROGMEM = "< S: "; +static const char esp_mail_str_30[] PROGMEM = "! E: "; +static const char esp_mail_str_31[] PROGMEM = "! I: "; +static const char esp_mail_str_32[] PROGMEM = "! W: "; +static const char esp_mail_str_33[] PROGMEM = "#### "; +static const char esp_mail_str_34[] PROGMEM = ":"; +static const char esp_mail_str_35[] PROGMEM = ";"; +static const char esp_mail_str_36[] PROGMEM = "{"; +static const char esp_mail_str_37[] PROGMEM = "}"; +static const char esp_mail_str_38[] PROGMEM = "("; +static const char esp_mail_str_39[] PROGMEM = ")"; +static const char esp_mail_str_40[] PROGMEM = "["; +static const char esp_mail_str_41[] PROGMEM = "]"; +static const char esp_mail_str_42[] PROGMEM = "\r\n"; +static const char esp_mail_str_43[] PROGMEM = "\1\1"; +static const char esp_mail_str_44[] PROGMEM = "{\"status\":"; +static const char esp_mail_str_45[] PROGMEM = "user="; +static const char esp_mail_str_46[] PROGMEM = "\1auth=Bearer "; +static const char esp_mail_str_47[] PROGMEM = "0123456789ABCDEF"; +static const char esp_mail_str_48[] PROGMEM = "<0.0>"; +static const char esp_mail_str_49[] PROGMEM = "<0."; +static const char esp_mail_str_50[] PROGMEM = "Search limit: %d\nFound %d messages\nShow %d messages"; +static const char esp_mail_str_51[] PROGMEM = "1.0"; +static const char esp_mail_str_52[] PROGMEM = "Fetch message %d, UID: %d"; +static const char esp_mail_str_53[] PROGMEM = "Fetch message %d, Number: %d"; +static const char esp_mail_str_54[] PROGMEM = "Attachments (%d)"; +static const char esp_mail_str_55[] PROGMEM = "Free Heap: "; +static const char esp_mail_str_56[] PROGMEM = "content-"; +static const char esp_mail_str_58[] PROGMEM = "format=\"flowed\""; +static const char esp_mail_str_59[] PROGMEM = "format=flowed"; +static const char esp_mail_str_60[] PROGMEM = "delsp=\"yes\""; +static const char esp_mail_str_61[] PROGMEM = "delsp=yes"; +static const char esp_mail_str_62[] PROGMEM = "name"; +static const char esp_mail_str_63[] PROGMEM = "+ "; +static const char esp_mail_str_64[] PROGMEM = "boundary=\""; +static const char esp_mail_str_65[] PROGMEM = "/header.json"; +static const char esp_mail_str_66[] PROGMEM = "/header.txt"; +static const char esp_mail_str_67[] PROGMEM = "{\"Filename\":\""; +static const char esp_mail_str_68[] PROGMEM = "Index: "; +static const char esp_mail_str_69[] PROGMEM = ",\"RFC822\":"; +static const char esp_mail_str_70[] PROGMEM = "\r\n\r\nRFC822:\r\n"; +static const char esp_mail_str_71[] PROGMEM = ",\"Attachments\":{\"Count\":"; +static const char esp_mail_str_72[] PROGMEM = ",\"Files\":["; +static const char esp_mail_str_73[] PROGMEM = "\r\n\r\nAttachments ("; +static const char esp_mail_str_74[] PROGMEM = ")\r\n"; +static const char esp_mail_str_75[] PROGMEM = "]}"; +static const char esp_mail_str_76[] PROGMEM = "{\"Messages\":["; +static const char esp_mail_str_77[] PROGMEM = ",\""; +static const char esp_mail_str_78[] PROGMEM = "{\""; +static const char esp_mail_str_79[] PROGMEM = "\":\""; +static const char esp_mail_str_80[] PROGMEM = "{\"Renamed\":\""; +static const char esp_mail_str_81[] PROGMEM = "\",\"Original\":\""; +static const char esp_mail_str_82[] PROGMEM = "\"}]"; +static const char esp_mail_str_83[] PROGMEM = "_"; +static const char esp_mail_str_84[] PROGMEM = "message"; +static const char esp_mail_str_85[] PROGMEM = "rfc822"; +static const char esp_mail_str_86[] PROGMEM = "/msg"; +static const char esp_mail_str_87[] PROGMEM = "/rfc822_msg"; +static const char esp_mail_str_88[] PROGMEM = "polling established on "; +static const char esp_mail_str_89[] PROGMEM = " folder..."; +static const char esp_mail_str_90[] PROGMEM = "boundary"; +static const char esp_mail_str_91[] PROGMEM = "\\Deleted"; +static const char esp_mail_str_92[] PROGMEM = "Subject: %s"; +static const char esp_mail_str_93[] PROGMEM = "Message sent success: %d"; +static const char esp_mail_str_94[] PROGMEM = "Message sent failed: %d"; +static const char esp_mail_str_95[] PROGMEM = "Status: %s"; +static const char esp_mail_str_96[] PROGMEM = "Date/Time: %s"; +static const char esp_mail_str_97[] PROGMEM = "Recipient: %s"; +static const char esp_mail_str_98[] PROGMEM = "success"; +static const char esp_mail_str_99[] PROGMEM = "failed"; + +#if defined(ENABLE_SMTP) +static const char boundary_table[] PROGMEM = "=_abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +#endif + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + +static const unsigned char b64_index_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static void __attribute__((used)) +appendDebugTag(MB_String &buf, esp_mail_debug_tag_type type, bool clear, PGM_P text = NULL) +{ + if (clear) + buf.clear(); + + switch (type) + { + case esp_mail_debug_tag_type_client: + buf += esp_mail_str_28; /* "> C: "*/ + break; + case esp_mail_debug_tag_type_server: + buf += esp_mail_str_29; /* "< S: " */ + break; + case esp_mail_debug_tag_type_error: + buf += esp_mail_str_30; /* "! E: "*/ + break; + case esp_mail_debug_tag_type_info: + buf += esp_mail_str_31; /* "! I: "*/ + break; + case esp_mail_debug_tag_type_warning: + buf += esp_mail_str_32; /* "! W: "*/ + break; + default: + break; + } + + if (text != NULL) + buf += text; +} + +static void __attribute__((used)) +yield_impl() +{ +#if defined(ARDUINO_ESP8266_MAJOR) && defined(ARDUINO_ESP8266_MINOR) && defined(ARDUINO_ESP8266_REVISION) && ((ARDUINO_ESP8266_MAJOR == 3 && ARDUINO_ESP8266_MINOR >= 1) || ARDUINO_ESP8266_MAJOR > 3) + esp_yield(); +#else + delay(0); +#endif +} + +// Print debug message w/wo new line to debug port +static void __attribute__((used)) +esp_mail_debug_print(PGM_P msg = "", bool newLine = true) +{ + yield_impl(); + if (newLine) + ESP_MAIL_DEFAULT_DEBUG_PORT.println(msg); + else + ESP_MAIL_DEFAULT_DEBUG_PORT.print(msg); +} + +static void __attribute__((used)) +esp_mail_debug_print_tag(PGM_P msg, esp_mail_debug_tag_type type, bool newLine = true, bool showTag = true) +{ + yield_impl(); + + MB_String s; + if (showTag) + appendDebugTag(s, type, false, msg); + else + s = msg; + + if (newLine) + ESP_MAIL_DEFAULT_DEBUG_PORT.println(s.c_str()); + else + ESP_MAIL_DEFAULT_DEBUG_PORT.print(s.c_str()); +} + +#endif + +typedef void (*ConnectionUpgradeRequestCallback)(void); +typedef void (*NetworkConnectionRequestCallback)(void); +typedef void (*NetworkDisconnectionRequestCallback)(void); +typedef void (*NetworkStatusRequestCallback)(void); +// Optional +typedef void (*ConnectionRequestCallback)(const char *, int); +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Error.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Error.h new file mode 100644 index 000000000000..172e7f8d4a95 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Error.h @@ -0,0 +1,86 @@ +/** + * Created August 6, 2023 + */ +#pragma once + +#ifndef ESP_MAIL_ERROR_H +#define ESP_MAIL_ERROR_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +#define TCP_CLIENT_ERROR_CONNECTION_REFUSED -1 +#define TCP_CLIENT_ERROR_SEND_DATA_FAILED -2 +#define TCP_CLIENT_ERROR_NOT_INITIALIZED -3 +#define TCP_CLIENT_ERROR_NOT_CONNECTED -4 + +#if defined(ENABLE_SMTP) + +#define SMTP_STATUS_SERVER_CONNECT_FAILED -100 +#define SMTP_STATUS_SMTP_GREETING_GET_RESPONSE_FAILED -101 +#define SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED -102 +#define SMTP_STATUS_AUTHEN_NOT_SUPPORT -103 +#define SMTP_STATUS_AUTHEN_FAILED -104 +#define SMTP_STATUS_USER_LOGIN_FAILED -105 +#define SMTP_STATUS_PASSWORD_LOGIN_FAILED -106 +#define SMTP_STATUS_SEND_HEADER_SENDER_FAILED -107 +#define SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED -108 +#define SMTP_STATUS_SEND_BODY_FAILED -109 +#define SMTP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED -110 +#define SMTP_STATUS_NO_VALID_RECIPIENTS_EXISTED -111 +#define SMTP_STATUS_NO_VALID_SENDER_EXISTED -112 +#define SMTP_STATUS_NO_SUPPORTED_AUTH -113 +#define SMTP_STATUS_SEND_CUSTOM_COMMAND_FAILED -114 +#define SMTP_STATUS_XOAUTH2_AUTH_FAILED -115 +#define SMTP_STATUS_UNDEFINED -116 +#endif + +#if defined(ENABLE_IMAP) + +#define IMAP_STATUS_SERVER_CONNECT_FAILED -200 +#define IMAP_STATUS_IMAP_RESPONSE_FAILED -201 +#define IMAP_STATUS_AUTHENTICATE_FAILED -202 +#define IMAP_STATUS_BAD_COMMAND -203 +#define IMAP_STATUS_STORE_FAILED -204 +#define IMAP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED -205 +#define IMAP_STATUS_NO_MESSAGE -206 +#define IMAP_STATUS_ERROR_DOWNLAD_TIMEOUT -207 +#define IMAP_STATUS_CLOSE_MAILBOX_FAILED -208 +#define IMAP_STATUS_OPEN_MAILBOX_FAILED -209 +#define IMAP_STATUS_LIST_MAILBOXS_FAILED -210 +#define IMAP_STATUS_CHECK_CAPABILITIES_FAILED -211 +#define IMAP_STATUS_NO_SUPPORTED_AUTH -212 +#define IMAP_STATUS_NO_MAILBOX_FOLDER_OPENED -213 +#define IMAP_STATUS_FIRMWARE_UPDATE_INIT_FAILED -214 +#define IMAP_STATUS_FIRMWARE_UPDATE_WRITE_FAILED -215 +#define IMAP_STATUS_FIRMWARE_UPDATE_END_FAILED -216 +#define IMAP_STATUS_CHANGEDSINC_MODSEQ_TEST_FAILED -217 +#define IMAP_STATUS_MODSEQ_WAS_NOT_SUPPORTED -218 +#endif + +/** + * MB_FS.h + #define MB_FS_ERROR_FILE_IO_ERROR -300 + #define MB_FS_ERROR_FILE_NOT_FOUND -301 + #define MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY -302 + #define MB_FS_ERROR_SD_STORAGE_IS_NOT_READY -303 + #define MB_FS_ERROR_FILE_STILL_OPENED -304 +*/ + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + +#define MAIL_CLIENT_ERROR_CONNECTION_CLOSED -400 +#define MAIL_CLIENT_ERROR_READ_TIMEOUT -401 +#define MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP -402 +#define MAIL_CLIENT_ERROR_OUT_OF_MEMORY -403 +#define MAIL_CLIENT_ERROR_NTP_TIME_SYNC_TIMED_OUT -404 +#define MAIL_CLIENT_ERROR_SESSION_CONFIG_WAS_NOT_ASSIGNED -405 +#define MAIL_CLIENT_ERROR_TIME_WAS_NOT_SET -406 +#define MAIL_CLIENT_ERROR_NOT_YET_LOGIN -407 +#define MAIL_CLIENT_ERROR_BUFFER_OVERFLOW -408 + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_FS.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_FS.h new file mode 100644 index 000000000000..b9c9755d5a2f --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_FS.h @@ -0,0 +1,170 @@ + + +#pragma once + +#ifndef ESP_MAIL_CONFIG_H +#define ESP_MAIL_CONFIG_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +#include +#include "extras/MB_MCU.h" + +/** 📌 Predefined Build Options + * ⛔ Use following build flag to disable all predefined options. + * -D DISABLE_ALL_OPTIONS + */ + +/**📍 For enabling the device or library time setup from NTP server + * ⛔ Use following build flag to disable. + * -D DISABLE_NTP_TIME + */ +#define ENABLE_NTP_TIME + +/**📍 For enabling the error string from error reason + * ⛔ Use following build flag to disable. + * -D DISABLE_ERROR_STRING + */ +#define ENABLE_ERROR_STRING + +/**📍 For IMAP class compilation + * ⛔ Use following build flag to disable. + * -D DISABLE_IMAP + */ +#define ENABLE_IMAP + +/**📍 For SMTP class compilation + * ⛔ Use following build flag to disable. + * -D DISABLE_SMTP + */ +#define ENABLE_SMTP + +/**📍 For enabling PSRAM support + * ⛔ Use following build flag to disable. + * -D DISABLE_PSRAM + */ +#define ESP_MAIL_USE_PSRAM + +/**📌 For enabling flash filesystem support + * + * 📍 For SPIFFS + * #define ESP_MAIL_DEFAULT_FLASH_FS SPIFFS + * + * + * 📍 For LittleFS Filesystem + * #include + * #define ESP_MAIL_DEFAULT_FLASH_FS LittleFS + * + * + * 📍 For SPIFFS Filesystem + * #if defined(ESP32) + * #include + * #endif + * #define ESP_MAIL_DEFAULT_FLASH_FS SPIFFS + * + * + * 📍 For FAT Filesystem + * #include + * #define ESP_MAIL_DEFAULT_FLASH_FS FFat //For ESP32 FAT + * + * 🚫 Use following build flags to disable. + * -D DISABLE_FLASH or -DDISABLE_FLASH in PlatformIO + */ + +#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) + +#if defined(ESP8266) || defined(MB_ARDUINO_PICO) + +#include +#define ESP_MAIL_DEFAULT_FLASH_FS LittleFS + +#elif defined(ESP_ARDUINO_VERSION) /* ESP32 core >= v2.0.x */ /* ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) */ + +#include +#define ESP_MAIL_DEFAULT_FLASH_FS LittleFS + +#else + +#include +#define ESP_MAIL_DEFAULT_FLASH_FS SPIFFS + +#endif + +#endif + +// For ESP32, format SPIFFS or FFat if mounting failed +#define ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED 1 + +/**📌 For enabling SD filesystem support + * + * 📍 For SD + * #include + * #define ESP_MAIL_DEFAULT_SD_FS SD + * #define ESP_MAIL_CARD_TYPE_SD 1 + * + * 📍 For SD MMC (ESP32) + * #include + * #define ESP_MAIL_DEFAULT_SD_FS SD_MMC //For ESP32 SDMMC + * #define ESP_MAIL_CARD_TYPE_SD_MMC 1 + * + * 📍 For SdFat on ESP32 and other devices except for ESP8266 + * #include //https://github.com/greiman/SdFat + * static SdFat sd_fat_fs; //should declare as static here + * #define ESP_MAIL_DEFAULT_SD_FS sd_fat_fs + * #define ESP_MAIL_CARD_TYPE_SD 1 + * #define ESP_MAIL_SD_FS_FILE SdFile + * + * + * ⛔ Use following build flags to disable. + * -D DISABLE_SD or -DDISABLE_SD in PlatformIO + */ +#if defined(ESP32) || defined(ESP8266) +#include +#define ESP_MAIL_DEFAULT_SD_FS SD +#define ESP_MAIL_CARD_TYPE_SD 1 +#elif defined(MB_ARDUINO_PICO) +// Use SDFS (ESP8266SdFat) instead of SD +#include +#define ESP_MAIL_DEFAULT_SD_FS SDFS +#define ESP_MAIL_CARD_TYPE_SD 1 +#endif + +/** 🔖 Optional Build Options + * + * 🏷️ For silent operation (no debug printing and callback) + * #define SILENT_MODE + * + * 🏷️ For ENC28J60 Ethernet module support in ESP8266 + * #define ENABLE_ESP8266_ENC28J60_ETH + * + * 🏷️ For W5500 Ethernet module support in ESP8266 + * #define ENABLE_ESP8266_W5500_ETH + * + * 🏷️ For W5100 Ethernet module support in ESP8266 + * #define ENABLE_ESP8266_W5100_ETH + * + * 🏷️ For disabling on-board WiFI functionality in case external Client usage + * #define ESP_MAIL_DISABLE_ONBOARD_WIFI + * + * 🏷️ For disabling native (sdk) Ethernet functionality in case external Client usage + * #define ESP_MAIL_DISABLE_NATIVE_ETHERNET + * + * 🏷️ For disabling SSL connection (also disabling TLS using STARTTLS) in MAP and SMTP application + * #define ESP_MAIL_DISABLE_SSL + * + * 🏷️ For debug port assignment if SILENT_MODE option was not set + * #define ESP_MAIL_DEBUG_PORT Serial + */ + +#define ENABLE_ESP8266_ENC28J60_ETH + +#if __has_include("Custom_ESP_Mail_FS.h") +#include "Custom_ESP_Mail_FS.h" +#endif + +#include "extras/Build_Options.h" + +#endif diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_IMAP.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_IMAP.h new file mode 100644 index 000000000000..ddfdbed080b0 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_IMAP.h @@ -0,0 +1,6783 @@ + +#ifndef ESP_MAIL_IMAP_H +#define ESP_MAIL_IMAP_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +/** + * Mail Client Arduino Library for Espressif's ESP32 and ESP8266, Raspberry Pi RP2040 Pico, and SAMD21 with u-blox NINA-W102 WiFi/Bluetooth module + * + * Created August 28, 2023 + * + * This library allows Espressif's ESP32, ESP8266, SAMD and RP2040 Pico devices to send and read Email through the SMTP and IMAP servers. + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "ESP_Mail_Client_Version.h" +#include "ESP_Mail_Client.h" + +#if defined(ENABLE_IMAP) + +#if defined(MB_ARDUINO_PICO) +extern uint8_t _FS_start; +extern uint8_t _FS_end; +#endif + +int ESP_Mail_Client::decodeChar(const char *s) +{ + return 16 * hexval(*(s + 1)) + hexval(*(s + 2)); +} + +void ESP_Mail_Client::decodeQP_UTF8(const char *buf, char *out) +{ + char *tmp = strP(esp_mail_str_47 /* "0123456789ABCDEF" */); + int idx = 0; + while (*buf) + { + if (*buf != '=') + out[idx++] = *buf++; + else if (*(buf + 1) == '\r' && *(buf + 2) == '\n') + buf += 3; + else if (*(buf + 1) == '\n') + buf += 2; + else if (!strchr(tmp, *(buf + 1))) + out[idx++] = *buf++; + else if (!strchr(tmp, *(buf + 2))) + out[idx++] = *buf++; + else + { + out[idx++] = decodeChar(buf); + buf += 3; + } + } + + // release memory + freeMem(&tmp); +} + +char *ESP_Mail_Client::decode7Bit_UTF8(char *buf) +{ + MB_String s; + + // only non NULL and 7-bit ASCII are allowed + + // rfc2045 section 2.7 + + size_t len = buf ? strlen(buf) : 0; + + for (size_t i = 0; i < len; i++) + { + if (buf[i] > 0 && buf[i] < 128 && i < 998) + s.append(1, buf[i]); + } + + // some special chars can't send in 7bit unless encoded as queoted printable string + char *decoded = allocMem(s.length() + 10); + decodeQP_UTF8(s.c_str(), decoded); + s.clear(); + return decoded; +} + +char *ESP_Mail_Client::decode8Bit_UTF8(char *buf) +{ + MB_String s; + + // only non NULL and less than 998 octet length are allowed + + // rfc2045 section 2.8 + + size_t len = buf ? strlen(buf) : 0; + + for (size_t i = 0; i < len; i++) + { + if (buf[i] > 0 && i < 998) + s.append(1, buf[i]); + } + + char *decoded = allocMem(s.length() + 1); + strcpy(decoded, s.c_str()); + s.clear(); + return decoded; +} + +void ESP_Mail_Client::decodeString(IMAPSession *imap, MB_String &str, const char *enc) +{ + + size_t p1 = 0, p2 = 0; + MB_String headerEnc; + + if (strlen(enc) == 0) + { + while (str[p1] == ' ' && p1 < str.length() - 1) + p1++; + + if (str[p1] == '=' && str[p1 + 1] == '?') + { + p2 = str.find('?', p1 + 2); + if (p2 != MB_String::npos) + headerEnc = str.substr(p1 + 2, p2 - p1 - 2); + } + } + else + headerEnc = enc; + + int bufSize = str.length() + 10; + char *buf = allocMem(bufSize); + + // Content Q and B decodings + RFC2047Decoder.decode(mbfs, buf, str.c_str(), bufSize); + + // Char set decoding + esp_mail_char_decoding_scheme scheme = getEncodingFromCharset(headerEnc.c_str()); + if (imap->_charDecCallback) + { + IMAP_Decoding_Info decoding; + decoding.charset = headerEnc.c_str(); + decoding.data = buf; + decoding.type = IMAP_Decoding_Info::message_part_type_header; + + imap->_charDecCallback(&decoding); + + if (decoding.decodedString.length() > 0) + { + char *buf2 = allocMem(decoding.decodedString.length() + 1); + strcpy(buf2, decoding.decodedString.c_str()); + // release memory and point to new buffer + freeMem(&buf); + buf = buf2; + } + } + else if (scheme == esp_mail_char_decoding_scheme_iso8859_1) + { + int len = strlen(buf); + int olen = (len + 1) * 2; + unsigned char *out = allocMem(olen); + decodeLatin1_UTF8(out, &olen, (unsigned char *)buf, &len); + // release memory and point to new buffer + freeMem(&buf); + buf = (char *)out; + } + else if (scheme == esp_mail_char_decoding_scheme_tis_620 || scheme == esp_mail_char_decoding_scheme_iso8859_11 || scheme == esp_mail_char_decoding_scheme_windows_874) + { + size_t len2 = strlen(buf); + char *tmp = allocMem((len2 + 1) * 3); + decodeTIS620_UTF8(tmp, buf, len2); + // release memory and point to new buffer + freeMem(&buf); + buf = tmp; + } + + str = buf; + // release memory + freeMem(&buf); +} + +esp_mail_char_decoding_scheme ESP_Mail_Client::getEncodingFromCharset(const char *enc) +{ + esp_mail_char_decoding_scheme scheme = esp_mail_char_decoding_scheme_default; + + for (int i = esp_mail_char_decoding_utf8; i < esp_mail_char_decoding_maxType; i++) + { + if (strpos(enc, char_decodings[i].text, 0, false) > -1) + scheme = (esp_mail_char_decoding_scheme)i; + } + + return scheme; +} + +int ESP_Mail_Client::encodeUnicode_UTF8(char *out, uint32_t utf) +{ + if (utf <= 0x7F) + { + // Plain ASCII + out[0] = (char)utf; + out[1] = 0; + return 1; + } + else if (utf <= 0x07FF) + { + // 2-byte unicode + out[0] = (char)(((utf >> 6) & 0x1F) | 0xC0); + out[1] = (char)(((utf >> 0) & 0x3F) | 0x80); + out[2] = 0; + return 2; + } + else if (utf <= 0xFFFF) + { + // 3-byte unicode + out[0] = (char)(((utf >> 12) & 0x0F) | 0xE0); + out[1] = (char)(((utf >> 6) & 0x3F) | 0x80); + out[2] = (char)(((utf >> 0) & 0x3F) | 0x80); + out[3] = 0; + return 3; + } + else if (utf <= 0x10FFFF) + { + // 4-byte unicode + out[0] = (char)(((utf >> 18) & 0x07) | 0xF0); + out[1] = (char)(((utf >> 12) & 0x3F) | 0x80); + out[2] = (char)(((utf >> 6) & 0x3F) | 0x80); + out[3] = (char)(((utf >> 0) & 0x3F) | 0x80); + out[4] = 0; + return 4; + } + else + { + // error - use replacement character + out[0] = (char)0xEF; + out[1] = (char)0xBF; + out[2] = (char)0xBD; + out[3] = 0; + return 0; + } +} + +void ESP_Mail_Client::decodeTIS620_UTF8(char *out, const char *in, size_t len) +{ + // output is the 3-byte value UTF-8 + int j = 0; + for (size_t i = 0; i < len; i++) + { + if (in[i] < 0x80) + out[j++] = in[i]; + else if ((in[i] >= 0xa0 && in[i] < 0xdb) || (in[i] > 0xde && in[i] < 0xfc)) + { + int unicode = 0x0e00 + in[i] - 0xa0; + char o[5]; + memset(o, 0, 5); + int r = encodeUnicode_UTF8(o, unicode); + for (int x = 0; x < r; x++) + out[j++] = o[x]; + } + } +} + +int ESP_Mail_Client::decodeLatin1_UTF8(unsigned char *out, int *outlen, const unsigned char *in, int *inlen) +{ + unsigned char *outstart = out; + const unsigned char *base = in; + const unsigned char *processed = in; + unsigned char *outend = out + *outlen; + const unsigned char *inend; + unsigned int c; + int bits; + + inend = in + (*inlen); + while ((in < inend) && (out - outstart + 5 < *outlen)) + { + c = *in++; + + /* assertion: c is a single UTF-4 value */ + if (out >= outend) + break; + if (c < 0x80) + { + *out++ = c; + bits = -6; + } + else + { + *out++ = ((c >> 6) & 0x1F) | 0xC0; + bits = 0; + } + + for (; bits >= 0; bits -= 6) + { + if (out >= outend) + break; + *out++ = ((c >> bits) & 0x3F) | 0x80; + } + processed = (const unsigned char *)in; + } + *outlen = out - outstart; + *inlen = processed - base; + return (0); +} + +bool ESP_Mail_Client::sendFetchCommand(IMAPSession *imap, int msgIndex, esp_mail_imap_command cmdCase) +{ + + MB_String cmd, cmd2, cmd3; + appendHeadersFetchCommand(imap, cmd, msgIndex, false); + + if (cmdCase == esp_mail_imap_cmd_fetch_body_mime) + { + joinStringDot(cmd2, 2, imap_commands[esp_mail_imap_command_header].text, imap_commands[esp_mail_imap_command_fields].text); + appendSpace(cmd2); + joinStringSpace(cmd3, false, 2, message_headers[esp_mail_message_header_field_content_type].text, message_headers[esp_mail_message_header_field_content_transfer_encoding].text); + appendString(cmd2, cmd3.c_str(), false, false, esp_mail_string_mark_type_round_bracket); + } + else if (cmdCase == esp_mail_imap_cmd_fetch_body_text) + cmd2 = cPart(imap)->partNumFetchStr.length() > 0 ? cPart(imap)->partNumFetchStr.c_str() : imap_commands[esp_mail_imap_command_text].text; + else if (cmdCase == esp_mail_imap_cmd_fetch_body_attachment) + cmd2 = cPart(imap)->partNumFetchStr; + + if (cmd2.length() > 0) + appendString(cmd, cmd2.c_str(), false, false, esp_mail_string_mark_type_square_bracket); + + bool allowPartialFetch = (cmdCase == esp_mail_imap_cmd_fetch_body_attachment && cPart(imap)->is_firmware_file) ? false : true; + + if (imap->_mimeDataStreamCallback) + allowPartialFetch = false; + + if (allowPartialFetch) + { + // Apply partial fetch in case download was disabled. + if (!imap->_storageReady && imap->_attDownload && cmdCase == esp_mail_imap_cmd_fetch_body_attachment) + cmd += esp_mail_str_48; /* "<0.0>" */ // This case should not happen because the memory storage was previousely checked. + else if ((!imap->_msgDownload && cmdCase == esp_mail_imap_cmd_fetch_body_text) || (imap->_msgDownload && !imap->_storageReady)) + { + cmd += esp_mail_str_49; /* "<0." */ + cmd += imap->_imap_data->limit.msg_size; + cmd += esp_mail_str_20; /* ">" */ + } + } + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + return true; +} + +bool ESP_Mail_Client::readMail(IMAPSession *imap, bool closeSession) +{ + if (!imap || !sessionExisted(imap)) + return false; + + imap->checkUID(); + imap->checkPath(); + imap->_cbData._success = false; + + if (!imap->connected()) + imap->_mailboxOpened = false; + + imap->_isFirmwareUpdated = false; + + MB_String buf, command, _uid; + + size_t readCount = 0; + imap->_multipart_levels.clear(); + + if (!reconnect(imap)) + return false; + + imap->_msgDownload = imap->_imap_data->download.text || imap->_imap_data->download.html; + imap->_attDownload = imap->_imap_data->download.attachment || imap->_imap_data->download.inlineImg; + + if (!imap->_storageChecked) + { + imap->_storageChecked = true; + imap->_storageReady = imap->_imap_data->download.header || (!imap->_imap_data->fetch.headerOnly && (imap->_msgDownload || imap->_attDownload)) ? mbfs->checkStorageReady(mbfs_type imap->_imap_data->storage.type) : true; + } + + bool readyToDownload = (imap->_msgDownload || imap->_attDownload) && imap->_storageReady; + + if (!imap->_storageReady) + sendStorageNotReadyError(imap, imap->_imap_data->storage.type); + +#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) + + int cmem = MailClient.getFreeHeap(); + + if (cmem < ESP_MAIL_MIN_MEM) + { +#if !defined(SILENT_MODE) + if (imap->_debug && imap->_statusCallback && !imap->_customCmdResCallback) + { + esp_mail_debug_print(); + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_OUT_OF_MEMORY, true); + } +#endif + + goto out; + } +#endif + + if (!imap->connected() && !imap->_loginStatus) + { +#if !defined(SILENT_MODE) + if (imap->_debug && imap->_statusCallback && !imap->_customCmdResCallback) + { + esp_mail_debug_print(); + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_NOT_YET_LOGIN, true); + } +#endif + return false; + } + + // new session + if (!imap->connected()) + { + // authenticate new + + bool ssl = false; + + if (!imap->connect(ssl)) + { + closeTCPSession(imap); + return false; + } + + if (!imapAuth(imap, ssl)) + { + closeTCPSession(imap); + return false; + } + } + else + { + // If time config changed, we will update time + MailClient.prepareTime(imap->_session_cfg, imap); + + // reuse session + for (size_t i = 0; i < imap->_headers.size(); i++) + imap->_headers[i].part_headers.clear(); + imap->_headers.clear(); + + if (imap->_imap_data->fetch.sequence_set.string.length() > 0 || imap->_imap_data->fetch.uid.length() > 0 || imap->_imap_data->fetch.number.length() > 0) + imap->_headerOnly = false; + else + imap->_headerOnly = true; + } + + imap->_rfc822_part_count = 0; + imap->_mbif._availableItems = 0; + imap->_imap_msg_num.clear(); + imap->_uidSearch = false; + imap->_mbif._searchCount = 0; + + if (imap->_currentFolder.length() == 0) + return handleIMAPError(imap, IMAP_STATUS_NO_MAILBOX_FOLDER_OPENED, false); + + if (!imap->_mailboxOpened || (imap->_imap_data->fetch.set_seen && !imap->_headerOnly && imap->_readOnlyMode)) + { + if (!imap->openFolder(imap->_currentFolder.c_str(), imap->_readOnlyMode && !imap->_imap_data->fetch.set_seen)) + return handleIMAPError(imap, IMAP_STATUS_OPEN_MAILBOX_FAILED, false); + } + + if (imap->_headerOnly) + { + if (imap->_imap_data->search.criteria.length() > 0) + { + command = esp_mail_imap_tag_str; + +#if !defined(SILENT_MODE) + printDebug(imap, + esp_mail_cb_str_18 /* "Searching messages..." */, + esp_mail_dbg_str_36 /* "searching messages" */, + esp_mail_debug_tag_type_client, + true, + false); + +#endif + + if (strposP(imap->_imap_data->search.criteria.c_str(), imap_cmd_post_tokens[esp_mail_imap_command_uid].c_str(), 0) != -1) + { + imap->_uidSearch = true; + command += imap_cmd_pre_tokens[esp_mail_imap_command_uid]; + } + + command += imap_cmd_pre_tokens[esp_mail_imap_command_search]; + + imap->_imap_data->search.criteria.trim(); + + MB_String tag; + appendTagSpace(tag); + + // Remove internal used reserved tag + if (strpos(imap->_imap_data->search.criteria.c_str(), tag.c_str(), 0, true) == 0) + imap->_imap_data->search.criteria.erase(0, tag.length()); + + for (size_t i = 0; i < imap->_imap_data->search.criteria.length(); i++) + { + if (imap->_imap_data->search.criteria[i] != ' ' && imap->_imap_data->search.criteria[i] != '\r' && imap->_imap_data->search.criteria[i] != '\n') + buf.append(1, imap->_imap_data->search.criteria[i]); + + if (imap->_imap_data->search.criteria[i] == ' ') + { + + if ((imap->_uidSearch && strcmp(buf.c_str(), imap_commands[esp_mail_imap_command_uid].text) == 0) || (imap->_unseen && buf.find(imap_commands[esp_mail_imap_command_all].text) != MB_String::npos)) + buf.clear(); + + if (strcmp(buf.c_str(), imap_commands[esp_mail_imap_command_search].text) != 0 && buf.length() > 0) + prependSpace(command, buf.c_str()); + + buf.clear(); + } + } + + if (imap->_unseen && strpos(imap->_imap_data->search.criteria.c_str(), imap_cmd_pre_tokens[esp_mail_imap_command_new].c_str(), 0) == -1) + command += imap_cmd_pre_tokens[esp_mail_imap_command_new]; + + if (buf.length() > 0) + prependSpace(command, buf.c_str()); + + if (!imap->isModseqSupported() && strpos(imap->_imap_data->search.criteria.c_str(), imap_cmd_pre_tokens[esp_mail_imap_command_modsec].c_str(), 0, false) != -1) + { + imap->_responseStatus.errorCode = IMAP_STATUS_MODSEQ_WAS_NOT_SUPPORTED; +#if !defined(SILENT_MODE) + + if (imap->_statusCallback) + sendErrorCB(imap, imap->errorReason().c_str(), false, false); + + if (imap->_debug) + esp_mail_debug_print_tag(imap->errorReason().c_str(), esp_mail_debug_tag_type_error, true); + +#endif + return false; + } + + if (imapSend(imap, command.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + command.clear(); + + imap->_imap_cmd = esp_mail_imap_cmd_search; + + if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, closeSession)) + return false; + +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + { + callBackSendNewLine(imap, false); + if (imap->_imap_msg_num.size() > 0) + { + int bufLen = 100; + char *buf = allocMem(bufLen); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_50 /* "Search limit: %d\nFound %d messages\nShow %d messages\n" */), (int)imap->_imap_data->limit.search, imap->_mbif._searchCount, (int)imap->_imap_msg_num.size()); + sendCallback(imap, buf, false, false); + // release memory + freeMem(&buf); + } + else + sendCallback(imap, esp_mail_error_imap_str_9 /* "no messages found for the specified search criteria" */, false, false); + } +#endif + } + else + { +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + sendCallback(imap, esp_mail_error_imap_str_10 /* "no search criteria provided, then fetching the latest message" */, false, false); +#endif + imap->_mbif._availableItems++; + + esp_mail_imap_msg_num_t msg_num; + msg_num.type = esp_mail_imap_msg_num_type_number; + msg_num.value = (uint32_t)imap->_mbif._msgCount; + + imap->_imap_msg_num.push_back(msg_num); + imap->_headerOnly = false; + imap->_imap_data->fetch.number = imap->_mbif._msgCount; + } + } + else + { + + if (imap->_imap_data->fetch.sequence_set.string.length() > 0) + { + imap->_headerOnly = imap->_imap_data->fetch.sequence_set.headerOnly; + imap->mFetchSequenceSet(); + + imap->_mbif._availableItems = imap->_imap_msg_num.size(); + } + else + { + if (imap->_imap_data->fetch.uid.length() > 0) + { + imap->_mbif._availableItems++; + + esp_mail_imap_msg_num_t msg_num; + msg_num.type = esp_mail_imap_msg_num_type_uid; + msg_num.value = (uint32_t)atoi(imap->_imap_data->fetch.uid.c_str()); + + imap->_imap_msg_num.push_back(msg_num); + } + + if (imap->_imap_data->fetch.number.length() > 0) + { + imap->_mbif._availableItems++; + + esp_mail_imap_msg_num_t msg_num; + msg_num.type = esp_mail_imap_msg_num_type_number; + msg_num.value = (uint32_t)atoi(imap->_imap_data->fetch.number.c_str()); + + imap->_imap_msg_num.push_back(msg_num); + } + } + } + + if (imap->_imap_data->fetch.headerOnly) + imap->_headerOnly = true; + + for (size_t i = 0; i < imap->_imap_msg_num.size(); i++) + { + imap->_cMsgIdx = i; + imap->_totalRead++; + +#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) + if (MailClient.getFreeHeap() - (imap->_imap_data->limit.msg_size * (i + 1)) < ESP_MAIL_MIN_MEM) + { + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_OUT_OF_MEMORY, true); + goto out; + } +#endif + +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + { + readCount++; + int bufLen = 100; + PGM_P p = imap->_uidSearch || imap->_imap_msg_num[i].type == esp_mail_imap_msg_num_type_uid ? esp_mail_str_52 /* "Fetch message %d, UID: %d" */ : esp_mail_str_53 /* "Fetch message %d, Number: %d" */; + char *buf = allocMem(bufLen); + snprintf(buf, bufLen, pgm2Str(p), imap->_totalRead, (int)imap->_imap_msg_num[i].value); + sendCallback(imap, buf, true, false); + // release memory + freeMem(&buf); + } + + if (imap->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_37 /* "send IMAP command, FETCH" */, esp_mail_debug_tag_type_client, true); +#endif + MB_String cmd; + appendHeadersFetchCommand(imap, cmd, i, true); + + // We fetch only known RFC822 headers because + // using Fetch RFC822.HEADER reurns all included unused headers + // which required more memory and network bandwidth. + MB_String cmd2; + appendRFC822HeadersFetchCommand(cmd2); + + appendString(cmd, cmd2.c_str(), false, false, esp_mail_string_mark_type_square_bracket); + + imap->addModifier(cmd, esp_mail_imap_command_changedsince, imap->_imap_data->fetch.modsequence); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + { + if (i < imap->_imap_msg_num.size() - 1) + continue; + return false; + } + + imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_header; + + int err = imap->_headerOnly ? IMAP_STATUS_IMAP_RESPONSE_FAILED : IMAP_STATUS_BAD_COMMAND; + + if (!handleIMAPResponse(imap, err, closeSession)) + { + if (i < imap->_imap_msg_num.size() - 1) + continue; + return false; + } + + if (!cHeader(imap)) + continue; + + if (imap->_imap_msg_num[i].type == esp_mail_imap_msg_num_type_number) + cHeader(imap)->message_uid = imap->mGetUID(cHeader(imap)->message_no); + + cHeader(imap)->flags = imap->getFlags(cHeader(imap)->message_no); + + if (!imap->_headerOnly) + { + imap->_cPartIdx = 0; + + // Reset attachment state if it was set by "multipart/mixed" content type header + cHeader(imap)->hasAttachment = false; + +#if !defined(SILENT_MODE) + if (imap->_debug) + debugPrintNewLine(); +#endif + + // multipart + if (cHeader(imap)->multipart) + { + struct esp_mail_imap_multipart_level_t mlevel; + mlevel.level = 1; + mlevel.fetch_rfc822_header = false; + mlevel.append_body_text = false; + imap->_multipart_levels.push_back(mlevel); + + if (!fetchMultipartBodyHeader(imap, i)) + return false; + } + else + { + // single part + if (imap->_debug) + printBodyPartFechingDubug(imap, "1", false); + + cHeader(imap)->partNumStr.clear(); + if (!sendFetchCommand(imap, i, esp_mail_imap_cmd_fetch_body_mime)) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_mime; + if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, closeSession)) + return false; + } + + if (readyToDownload && imap->_imap_data->storage.saved_path.length() == 0) + imap->_imap_data->storage.saved_path = esp_mail_str_10; /* "/" */ + + if (cHeader(imap)->part_headers.size() > 0) + { + + cHeader(imap)->sd_alias_file_count = 0; + + imap->_sdFileList.clear(); + if (!mbfs->longNameSupported()) + imap->_sdFileList = esp_mail_str_40; /* "[" */ + +#if !defined(SILENT_MODE) + + if (cHeader(imap)->attachment_count > 0 && imap->_statusCallback) + { + int bufLen = 100; + char *buf = allocMem(bufLen); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_54 /* "Attachments (%d)" */), cHeader(imap)->attachment_count); + callBackSendNewLine(imap, false); + sendCallback(imap, buf, false, false); + // release memory + freeMem(&buf); + + int count = 0; + + for (size_t j = 0; j < cHeader(imap)->part_headers.size(); j++) + { + imap->_cPartIdx = j; + if (!cPart(imap)->rfc822_part && cPart(imap)->attach_type != esp_mail_att_type_none) + { + count++; + MB_String str = count; + appendDot(str); + prependSpace(str, cPart(imap)->filename.c_str()); + sendCallback(imap, str.c_str(), false, false); + } + } + } + +#endif + + MB_String s1, s2; + int _idx1 = 0; + for (size_t j = 0; j < cHeader(imap)->part_headers.size(); j++) + { + imap->_cPartIdx = j; + if (cPart(imap)->rfc822_part) + { + s1 = cPart(imap)->partNumStr; + _idx1 = cPart(imap)->rfc822_msg_Idx; + } + else if (s1.length() > 0) + { + if (multipartMember(s1, cPart(imap)->partNumStr)) + { + cPart(imap)->message_sub_type = esp_mail_imap_message_sub_type_rfc822; + cPart(imap)->rfc822_msg_Idx = _idx1; + } + } + + if (cPart(imap)->multipart_sub_type == esp_mail_imap_multipart_sub_type_parallel) + s2 = cPart(imap)->partNumStr; + else if (s2.length() > 0) + { + if (multipartMember(s2, cPart(imap)->partNumStr)) + { + cPart(imap)->attach_type = esp_mail_att_type_attachment; + if (cPart(imap)->filename.length() == 0) + { + if (cPart(imap)->name.length() > 0) + cPart(imap)->filename = cPart(imap)->name; + else + { + char *uid = getRandomUID(); + cPart(imap)->filename = uid; + cPart(imap)->filename += mimeinfo[esp_mail_file_extension_dat].endsWith; + freeMem(&uid); + } + } + } + } + + checkFirmwareFile(imap, cPart(imap)->filename.c_str(), *cPart(imap), true); + } + + int attach_count = 0; + int ccnt = 0; + + for (size_t j = 0; j < cHeader(imap)->part_headers.size(); j++) + { + imap->_cPartIdx = j; + + if (cPart(imap)->rfc822_part || cPart(imap)->multipart_sub_type != esp_mail_imap_multipart_sub_type_none) + continue; + + bool rfc822_body_subtype = cPart(imap)->message_sub_type == esp_mail_imap_message_sub_type_rfc822 && cPart(imap)->attach_type != esp_mail_att_type_attachment; + + if (cPart(imap)->attach_type == esp_mail_att_type_none && (cPart(imap)->msg_type == esp_mail_msg_type_html || cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched)) + { + + bool ret = ((imap->_imap_data->enable.rfc822 || imap->_imap_data->download.rfc822) && rfc822_body_subtype) || (!rfc822_body_subtype && ((imap->_imap_data->enable.text && (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched)) || (imap->_imap_data->enable.html && cPart(imap)->msg_type == esp_mail_msg_type_html) || (cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->download.text))); + if (!ret) + continue; + +#if !defined(SILENT_MODE) + + if ((imap->_imap_data->download.rfc822 && rfc822_body_subtype) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->download.text)))) + { + + if (ccnt == 0 && imap->_statusCallback) + sendCallback(imap, esp_mail_cb_str_43 /* "Downloading messages..." */, true, false); + + if (imap->_debug) + { + debugPrintNewLine(); + if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) + esp_mail_debug_print_tag(esp_mail_dbg_str_74 /* "download plain TEXT message" */, esp_mail_debug_tag_type_client, true); + else if (cPart(imap)->msg_type == esp_mail_msg_type_html) + esp_mail_debug_print_tag(esp_mail_dbg_str_71 /* "download HTML message" */, esp_mail_debug_tag_type_client, true); + } + } + else + { + if (ccnt == 0) + sendCallback(imap, esp_mail_cb_str_28 /* "Reading messages..." */, true, false); + + if (imap->_debug) + { + debugPrintNewLine(); + if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) + esp_mail_debug_print_tag(esp_mail_dbg_str_46 /* "reading plain TEXT message" */, esp_mail_debug_tag_type_client, true); + else if (cPart(imap)->msg_type == esp_mail_msg_type_html) + esp_mail_debug_print_tag(esp_mail_dbg_str_47 /* "reading HTML message" */, esp_mail_debug_tag_type_client, true); + } + } + +#endif + + ccnt++; + + if (!sendFetchCommand(imap, i, esp_mail_imap_cmd_fetch_body_text)) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_text; + if (!handleIMAPResponse(imap, IMAP_STATUS_IMAP_RESPONSE_FAILED, closeSession)) + return false; + } + else if (cPart(imap)->attach_type != esp_mail_att_type_none && (imap->_storageReady || cPart(imap)->is_firmware_file)) + { + + if (cPart(imap)->is_firmware_file || (imap->_imap_data->download.attachment && cPart(imap)->attach_type == esp_mail_att_type_attachment) || (imap->_imap_data->download.inlineImg && cPart(imap)->attach_type == esp_mail_att_type_inline)) + { +#if !defined(SILENT_MODE) + if (cPart(imap)->save_to_file) + { + + if (attach_count == 0 && imap->_statusCallback) + sendCallback(imap, esp_mail_cb_str_19 /* "Downloading attachments..." */, true, false); + + if (imap->_debug) + { + debugPrintNewLine(); + int bufLen = 100; + char *buf = allocMem(bufLen); + snprintf(buf, bufLen, pgm2Str(esp_mail_dbg_str_70 /* "download attachment %d of %d" */), attach_count + 1, (int)cHeader(imap)->attachment_count); + esp_mail_debug_print_tag(buf, esp_mail_debug_tag_type_client, true); + // release memory + freeMem(&buf); + + MB_String filePath = imap->_imap_data->storage.saved_path; + filePath += esp_mail_str_10; /* "/" */ + filePath += cHeader(imap)->message_uid; + filePath += esp_mail_str_10; /* "/" */ + filePath += cPart(imap)->filename; + + esp_mail_debug_print_tag(filePath.c_str(), esp_mail_debug_tag_type_client, true); + } + } +#endif + + attach_count++; + + if (cPart(imap)->octetLen <= (int)imap->_imap_data->limit.attachment_size) + { + + if (imap->_storageReady || cPart(imap)->is_firmware_file) + { + + if ((int)j < (int)cHeader(imap)->part_headers.size() - 1) + if (cHeader(imap)->part_headers[j + 1].octetLen > (int)imap->_imap_data->limit.attachment_size) + cHeader(imap)->downloaded_bytes += cHeader(imap)->part_headers[j + 1].octetLen; + + if (!sendFetchCommand(imap, i, esp_mail_imap_cmd_fetch_body_attachment)) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_attachment; + if (!handleIMAPResponse(imap, IMAP_STATUS_IMAP_RESPONSE_FAILED, closeSession)) + return false; + + yield_impl(); + } + } + else + { + if ((int)j == (int)cHeader(imap)->part_headers.size() - 1) + cHeader(imap)->downloaded_bytes += cPart(imap)->octetLen; + } + } + } + } + } + + if (imap->_storageReady && imap->_imap_data->download.header && !imap->_headerSaved) + { +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + sendCallback(imap, esp_mail_cb_str_21 /* "Saving message header to file..." */, true, false); + else if (imap->_debug) + debugPrintNewLine(); +#endif + + saveHeader(imap, false); + saveHeader(imap, true); + } + + // save files list to file + if (imap->_storageReady && imap->_sdFileList.length() > 0) + { + MB_String filepath = cHeader(imap)->message_uid; + filepath += mimeinfo[esp_mail_file_extension_txt].endsWith; + if (mbfs->open(filepath, mbfs_type imap->_imap_data->storage.type, mb_fs_open_mode_write) > -1) + { + mbfs->print(mbfs_type imap->_imap_data->storage.type, imap->_sdFileList.c_str()); + mbfs->close(mbfs_type imap->_imap_data->storage.type); + } + } + + imap->_cMsgIdx++; + } +#if !defined(SILENT_MODE) + if (imap->_debug) + { + MB_String str = esp_mail_str_55; /* "Free Heap: " */ + str += MailClient.getFreeHeap(); + esp_mail_debug_print_tag(str.c_str(), esp_mail_debug_tag_type_client, true); + } +#endif + } +#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) +out: +#endif + if (readCount < imap->_imap_msg_num.size()) + { + imap->_mbif._availableItems = readCount; + imap->_imap_msg_num.erase(imap->_imap_msg_num.begin() + readCount, imap->_imap_msg_num.end()); + } + + if (closeSession) + { + if (!imap->closeSession()) + return false; + } + else + { +#if !defined(SILENT_MODE) + printDebug(imap, + esp_mail_cb_str_46 /* "Finished reading Email" */, + esp_mail_dbg_str_29 /* "finished reading Email" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + } + + imap->_cbData._success = true; + +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + callBackSendNewLine(imap, true); +#endif + + return true; +} + +void ESP_Mail_Client::appendHeadersFetchCommand(IMAPSession *imap, MB_String &cmd, int index, bool debug) +{ + if (imap->_uidSearch || imap->_imap_msg_num[index].type == esp_mail_imap_msg_num_type_uid) + appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_fetch].text); + else + appendSpace(cmd, true, imap_commands[esp_mail_imap_command_fetch].text); +#if !defined(SILENT_MODE) + if (debug && imap->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_26 /* "fetch message header" */, esp_mail_debug_tag_type_client, true); +#endif + joinStringSpace(cmd, false, 2, MB_String((int)imap->_imap_msg_num[index].value).c_str(), imap_commands[esp_mail_imap_command_body].text); + + if (!imap->_imap_data->fetch.set_seen) + prependDot(cmd, imap_commands[esp_mail_imap_command_peek].text); +} + +void ESP_Mail_Client::appendRFC822HeadersFetchCommand(MB_String &cmd) +{ + joinStringDot(cmd, 2, imap_commands[esp_mail_imap_command_header].text, imap_commands[esp_mail_imap_command_fields].text); + appendSpace(cmd); + + MB_String cmd2; + + for (int i = 0; i < esp_mail_rfc822_header_field_maxType; i++) + appendSpace(cmd2, false, rfc822_headers[i].text); + + joinStringSpace(cmd2, false, 4, message_headers[esp_mail_message_header_field_content_type].text, + message_headers[esp_mail_message_header_field_content_transfer_encoding].text, + message_headers[esp_mail_message_header_field_content_language].text, + message_headers[esp_mail_message_header_field_accept_language].text); + + appendString(cmd, cmd2.c_str(), false, false, esp_mail_string_mark_type_round_bracket); +} + +bool ESP_Mail_Client::getMultipartFechCmd(IMAPSession *imap, int msgIdx, MB_String &partText) +{ + if (imap->_multipart_levels.size() == 0) + return false; + + int cLevel = imap->_multipart_levels.size() - 1; + + cHeader(imap)->partNumStr.clear(); + + appendHeadersFetchCommand(imap, partText, msgIdx, false); + + MB_String cmd1; + for (size_t i = 0; i < imap->_multipart_levels.size(); i++) + { + if (i > 0) + { + cmd1 += esp_mail_str_27; /* "." */ + cHeader(imap)->partNumStr += esp_mail_str_27; /* "." */ + } + + cmd1 += imap->_multipart_levels[i].level; + cHeader(imap)->partNumStr += imap->_multipart_levels[i].level; + } + + if (imap->_multipart_levels[cLevel].fetch_rfc822_header) + { + MB_String cmd2; + appendRFC822HeadersFetchCommand(cmd2); + prependDot(cmd1, cmd2.c_str()); + imap->_multipart_levels[cLevel].append_body_text = true; + } + else + prependDot(cmd1, imap_commands[esp_mail_imap_command_mime].text); + + appendString(partText, cmd1.c_str(), false, false, esp_mail_string_mark_type_square_bracket); + + imap->_multipart_levels[cLevel].fetch_rfc822_header = false; + + return true; +} + +bool ESP_Mail_Client::multipartMember(const MB_String &parent, const MB_String &child) +{ + if (parent.length() > child.length()) + return false; + + for (size_t i = 0; i < parent.length(); i++) + if (parent[i] != child[i]) + return false; + + return true; +} + +bool ESP_Mail_Client::fetchMultipartBodyHeader(IMAPSession *imap, int msgIdx) +{ + bool ret = true; + + if (!connected(imap)) + { + closeTCPSession(imap); + return false; + } + int cLevel = 0; + + // slower than BODYSTRUCTURE parsing but sure + do + { + +#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) + // Prevent stack overflow + if (MailClient.getFreeHeap() < ESP_MAIL_MIN_MEM) + { + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_OUT_OF_MEMORY, true); + break; + } +#endif + + struct esp_mail_message_part_info_t *_cpart = &cHeader(imap)->part_headers[cHeader(imap)->message_data_count - 1]; + bool rfc822_body_subtype = _cpart->message_sub_type == esp_mail_imap_message_sub_type_rfc822 && _cpart->attach_type != esp_mail_att_type_attachment; + + MB_String cmd; + if (!getMultipartFechCmd(imap, msgIdx, cmd)) + return true; + + if (imap->_debug) + printBodyPartFechingDubug(imap, cHeader(imap)->partNumStr.c_str(), imap->_multipart_levels.size() > 1); + + // Try fetching the part and its sub parts hierarchically + // Some sub part may not exist at the current multipart level + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_mime; + ret = handleIMAPResponse(imap, IMAP_STATUS_IMAP_RESPONSE_FAILED, false); + + _cpart = &cHeader(imap)->part_headers[cHeader(imap)->message_data_count - 1]; + rfc822_body_subtype = _cpart->message_sub_type == esp_mail_imap_message_sub_type_rfc822 && _cpart->attach_type != esp_mail_att_type_attachment; + cLevel = imap->_multipart_levels.size() - 1; + + if (ret) + { + if (_cpart->multipart) + { + if (_cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_parallel || _cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_alternative || _cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_related || _cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_mixed) + { + struct esp_mail_imap_multipart_level_t mlevel; + mlevel.level = 1; + mlevel.fetch_rfc822_header = false; + mlevel.append_body_text = false; + imap->_multipart_levels.push_back(mlevel); + fetchMultipartBodyHeader(imap, msgIdx); + } + else + imap->_multipart_levels[cLevel].level++; + } + else + { + if (rfc822_body_subtype) + { + // Get additional rfc822 message header + imap->_multipart_levels[cLevel].fetch_rfc822_header = true; + fetchMultipartBodyHeader(imap, msgIdx); + } + else + { + if (imap->_multipart_levels[cLevel].append_body_text) + { + // single part rfc822 message body, append TEXT to the body fetch command + prependDot(_cpart->partNumFetchStr, imap_commands[esp_mail_imap_command_text].text); + imap->_multipart_levels[cLevel].append_body_text = false; + } + imap->_multipart_levels[cLevel].level++; + } + } + } + + } while (ret); + + imap->_multipart_levels.pop_back(); + + if (imap->_multipart_levels.size() > 0) + { + cLevel = imap->_multipart_levels.size() - 1; + imap->_multipart_levels[cLevel].level++; + } + + return true; +} + +void ESP_Mail_Client::printBodyPartFechingDubug(IMAPSession *imap, const char *partNum, bool multiLevel) +{ +#if !defined(SILENT_MODE) + MB_String str = multiLevel ? esp_mail_dbg_str_28 /* "fetch body sub part header, " */ : esp_mail_dbg_str_27; /* "fetch body part header, " */ + str += partNum; + esp_mail_debug_print_tag(str.c_str(), esp_mail_debug_tag_type_client, true); +#endif +} + +bool ESP_Mail_Client::imapAuth(IMAPSession *imap, bool &ssl) +{ + + if (!sessionExisted(imap)) + return false; + + imap->_auth_capability[esp_mail_auth_capability_login] = false; + + imap->_session_cfg->int_start_tls = imap->_session_cfg->secure.startTLS; + imap->_session_cfg->int_mode = imap->_session_cfg->secure.mode; + +#if !defined(ESP_MAIL_DISABLE_SSL) +unauthenticate: +#endif + + // capabilities may change after TLS negotiation + if (!imap->checkCapabilities()) + return false; + +#if !defined(ESP_MAIL_DISABLE_SSL) + + if (imap->_session_cfg->int_mode != esp_mail_secure_mode_nonsecure) + { + // start TLS when needed or the server issues + if ((imap->_auth_capability[esp_mail_auth_capability_starttls] || imap->_session_cfg->int_start_tls || imap->_session_cfg->int_mode == esp_mail_secure_mode_ssl_tls) && !ssl) + { +#if !defined(SILENT_MODE) + printDebug(imap, + esp_mail_cb_str_2 /* "Sending STARTTLS command..." */, + esp_mail_dbg_str_1 /* "send command, STARTTLS" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + imapSend(imap, imap->prependTag(imap_commands[esp_mail_imap_command_starttls].text).c_str(), true); + + // rfc2595 section 3.1 + imap->_imap_cmd = esp_mail_imap_cmd_starttls; + if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) + return false; + +#if !defined(SILENT_MODE) + if (imap->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_22 /* "perform SSL/TLS handshake" */, esp_mail_debug_tag_type_client, true); +#endif + + // connect in secure mode + // do TLS handshake + + if (!imap->client.connectSSL(imap->_session_cfg->certificate.verify)) + return handleIMAPError(imap, MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP, false); + + // set the secure mode + imap->_session_cfg->int_start_tls = false; + imap->_session_cfg->int_mode = esp_mail_secure_mode_undefined; + ssl = true; + imap->_secure = true; + + // check the capabilitiy again to prevent the man in the middle attack + goto unauthenticate; + } + } + +#endif + + imap->clearMessageData(); + imap->_mailboxOpened = false; + + bool creds = imap->_session_cfg->login.email.length() > 0 && imap->_session_cfg->login.password.length() > 0; + bool sasl_auth_oauth = imap->_session_cfg->login.accessToken.length() > 0 && imap->_auth_capability[esp_mail_auth_capability_xoauth2]; + bool sasl_login = creds; + bool sasl_auth_plain = imap->_auth_capability[esp_mail_auth_capability_plain] && creds; + + bool supported_sasl = sasl_auth_oauth || sasl_login || sasl_auth_plain; + + if (!supported_sasl) + return handleIMAPError(imap, IMAP_STATUS_NO_SUPPORTED_AUTH, false); + + // rfc4959 + if (supported_sasl) + { +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + sendCallback(imap, esp_mail_cb_str_14 /* "Logging in..." */, true, false); + else if (imap->_debug) + debugPrintNewLine(); +#endif + } + + if (sasl_auth_oauth) + { + + if (!imap->_auth_capability[esp_mail_auth_capability_xoauth2]) + { + handleIMAPError(imap, IMAP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED, false); + return false; + } + +#if !defined(SILENT_MODE) + if (imap->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_45 /* "send IMAP command, AUTH XOAUTH2" */, esp_mail_debug_tag_type_client, true); +#endif + + MB_String cmd; + joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_authenticate].text, imap_commands[esp_mail_imap_command_xoauth2].text); + + if (imap->_auth_capability[esp_mail_auth_capability_sasl_ir]) + { + prependSpace(cmd, getXOAUTH2String(imap->_session_cfg->login.email, imap->_session_cfg->login.accessToken).c_str()); + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + } + else + { + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_sasl_auth_oauth; + if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, true)) + return false; + + cmd = getXOAUTH2String(imap->_session_cfg->login.email, imap->_session_cfg->login.accessToken); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + } + + imap->_imap_cmd = esp_mail_imap_cmd_sasl_auth_oauth; + if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, false)) + return false; + } + else if (sasl_auth_plain) + { + +#if !defined(SILENT_MODE) + if (imap->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_44 /* "send IMAP command, AUTHENTICATE PLAIN" */, esp_mail_debug_tag_type_client, true); +#endif + + int len = imap->_session_cfg->login.email.length() + imap->_session_cfg->login.password.length() + 2; + uint8_t *tmp = allocMem(len); + memset(tmp, 0, len); + int p = 1; + memcpy(tmp + p, imap->_session_cfg->login.email.c_str(), imap->_session_cfg->login.email.length()); + p += imap->_session_cfg->login.email.length() + 1; + memcpy(tmp + p, imap->_session_cfg->login.password.c_str(), imap->_session_cfg->login.password.length()); + p += imap->_session_cfg->login.password.length(); + + MB_String cmd; + joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_authenticate].text, imap_commands[esp_mail_imap_command_plain].text); + + if (imap->_auth_capability[esp_mail_auth_capability_sasl_ir]) + { + prependSpace(cmd, encodeBase64Str(tmp, p).c_str()); + // release memory + freeMem(&tmp); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + } + else + { + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_sasl_auth_plain; + + if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, true)) + return false; + + cmd = encodeBase64Str(tmp, p); + // release memory + freeMem(&tmp); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + } + + imap->_imap_cmd = esp_mail_imap_cmd_sasl_auth_plain; + if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, true)) + return false; + } + else if (sasl_login) + { + +#if !defined(SILENT_MODE) + if (imap->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_34 /* "send IMAP command, LOGIN" */, esp_mail_debug_tag_type_client, true); +#endif + MB_String cmd; + joinStringSpace(cmd, true, 3, imap_commands[esp_mail_imap_command_login].text, imap->_session_cfg->login.email.c_str(), imap->_session_cfg->login.password.c_str()); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_sasl_login; + if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, true)) + return false; + } + + // auto capabilities after login? + if (!imap->_feature_capability[esp_mail_imap_read_capability_auto_caps]) + { + if (!imap->checkCapabilities()) + return false; + } + + if (imap->_feature_capability[esp_mail_imap_read_capability_id]) + { + if (!imap->id(&imap->_imap_data->identification)) + return false; + } + + if (supported_sasl) + imap->_authenticated = true; + + return true; +} + +bool ESP_Mail_Client::imapLogout(IMAPSession *imap) +{ + +#if defined(ESP8266) + return false; +#endif + + if (!sessionExisted(imap)) + return false; + +#if !defined(SILENT_MODE) + printDebug(imap, + esp_mail_cb_str_20 /* "Logging out..." */, + esp_mail_dbg_str_38 /* "send IMAP command, LOGOUT" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (imapSend(imap, imap->prependTag(imap_commands[esp_mail_imap_command_logout].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_logout; + if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + imap->_authenticated = false; + +#if !defined(SILENT_MODE) + printDebug(imap, + esp_mail_cb_str_47 /* "Log out completed" */, + esp_mail_dbg_str_31 /* "log out completed" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + return true; +} + +size_t ESP_Mail_Client::imapSend(IMAPSession *imap, PGM_P data, bool newline) +{ + if (!imap || !sessionReady(imap)) + return 0; + + int sent = 0; + + MB_String s = data; + + int toSend = newline ? s.length() + 2 : s.length(); + + if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_maintainer && !imap->_customCmdResCallback) + esp_mail_debug_print(s.c_str(), newline); + + sent = newline ? imap->client.println(s.c_str()) : imap->client.print(s.c_str()); + + if (sent != toSend) + { + errorStatusCB(imap, nullptr, sent, true); + sent = 0; + } + + return sent; +} + +size_t ESP_Mail_Client::imapSend(IMAPSession *imap, int data, bool newline) +{ + MB_String s = data; + return imapSend(imap, s.c_str(), newline); +} + +size_t ESP_Mail_Client::imapSend(IMAPSession *imap, uint8_t *data, size_t size) +{ + if (!imap || !sessionReady(imap)) + return 0; + + int sent = 0; + + sent = imap->client.write(data, size); + + if (sent != (int)size) + { + errorStatusCB(imap, nullptr, sent, true); + sent = 0; + } + + return sent; +} + +bool ESP_Mail_Client::mSetFlag(IMAPSession *imap, MB_StringPtr sequenceSet, MB_StringPtr flag, esp_mail_imap_store_flag_type type, bool closeSession, bool silent, bool UID, int32_t modsequence) +{ + if (!reconnect(imap)) + return false; + + if (!imap->connected()) + { + imap->_mailboxOpened = false; + return false; + } + + if (imap->_currentFolder.length() == 0) + { +#if !defined(SILENT_MODE) + printDebug(imap, + esp_mail_error_imap_str_11 /* "no mailbox opened" */, + esp_mail_error_imap_str_11 /* "no mailbox opened" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + } + else + { + if (imap->_readOnlyMode || !imap->_mailboxOpened) + { + if (!imap->selectFolder(imap->_currentFolder.c_str(), false)) + return false; + } + } + +#if !defined(SILENT_MODE) + PGM_P p1 = NULL; + PGM_P p2 = NULL; + if (type == esp_mail_imap_store_flag_type_set) + { + p1 = esp_mail_cb_str_26; /* "Setting FLAG..." */ + p2 = esp_mail_dbg_str_41; /* "setting FLAG" */ + } + else if (type == esp_mail_imap_store_flag_type_add) + { + p1 = esp_mail_cb_str_24; /* "Adding FLAG..." */ + p2 = esp_mail_dbg_str_42; /* "adding FLAG" */ + } + else + { + p1 = esp_mail_cb_str_23; /* "Removing FLAG..." */ + p2 = esp_mail_dbg_str_43; /* "removing FLAG" */ + } + + printDebug(imap, + p1, + p2, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!sessionExisted(imap)) + return false; + + MB_String cmd; + if (UID) + appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_store].text); + else + appendSpace(cmd, true, imap_commands[esp_mail_imap_command_store].text); + + cmd += sequenceSet; + + imap->addModifier(cmd, esp_mail_imap_command_unchangedsince, modsequence); + + if (type == esp_mail_imap_store_flag_type_set) + cmd += imap_cmd_pre_tokens[esp_mail_imap_command_flags]; + else if (type == esp_mail_imap_store_flag_type_add) + cmd += imap_cmd_pre_tokens[esp_mail_imap_command_plus_flags]; + else + cmd += imap_cmd_pre_tokens[esp_mail_imap_command_minus_flags]; + + if (silent) + prependDot(cmd, imap_commands[esp_mail_imap_command_silent].text); + + appendSpace(cmd); + appendString(cmd, MB_String(flag).c_str(), false, false, esp_mail_string_mark_type_round_bracket); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_store; + + if (!handleIMAPResponse(imap, IMAP_STATUS_STORE_FAILED, false)) + return false; + + if (closeSession) + imap->closeSession(); + + return true; +} + +int ESP_Mail_Client::parseSearchResponse(IMAPSession *imap, esp_mail_imap_response_data &res, PGM_P tag, const char *key) +{ + int bufLen = res.chunkBufSize; + int ret = -1; + char c = 0; + int idx = 0; + int num = 0; + + size_t tagLen = strlen_P(tag); + MB_String _tag = tag; + + while (imap->client.available() > 0 && idx < bufLen) + { + yield_impl(); + + ret = imap->client.read(); + + if (ret > -1) + { + + if (idx >= bufLen - 1) + return idx; + + c = (char)ret; + + if (c == '\n') + c = ' '; + + res.response[idx++] = c; + + if (res.chunkIdx == 0) + { + // Search response parsing + if (strcmp(res.response, key) == 0) + { + res.chunkIdx++; + return 0; + } + else + { + // Status response parsing + res.imapResp = imapResponseStatus(imap, res.response, esp_mail_imap_tag_str); + + // Exit if error or complete (no messages found) + if (res.imapResp != esp_mail_imap_resp_unknown) + goto end_search; + } + } + else + { + if (c == ' ') + { + imap->_mbif._searchCount++; + if (imap->_imap_data->enable.recent_sort) + { + esp_mail_imap_msg_num_t msg_num; + msg_num.type = imap->_uidSearch ? esp_mail_imap_msg_num_type_uid : esp_mail_imap_msg_num_type_number; + msg_num.value = (uint32_t)atoi(res.response); + + imap->_imap_msg_num.push_back(msg_num); + + if (imap->_imap_msg_num.size() > imap->_imap_data->limit.search) + imap->_imap_msg_num.erase(imap->_imap_msg_num.begin()); + } + else + { + if (imap->_imap_msg_num.size() < imap->_imap_data->limit.search) + { + esp_mail_imap_msg_num_t msg_num; + msg_num.type = imap->_uidSearch ? esp_mail_imap_msg_num_type_uid : esp_mail_imap_msg_num_type_number; + msg_num.value = (uint32_t)atoi(res.response); + + imap->_imap_msg_num.push_back(msg_num); + } + } + + if (imap->_debug) + { + num = (float)(100.0f * imap->_mbif._searchCount / imap->_mbif._msgCount); + if (res.searchCount != num) + { + res.searchCount = num; + searchReport(imap, num); + } + } + + res.chunkIdx++; + return idx; + } + else if (idx >= (int)tagLen) + { + if (strpos(res.response, _tag.c_str(), 0, false) > -1) + { +#if defined(MB_USE_STD_VECTOR) + if (imap->_imap_data->enable.recent_sort) + std::sort(imap->_imap_msg_num.begin(), imap->_imap_msg_num.end(), compareMore); +#else + if (imap->_imap_data->enable.recent_sort) + numDecSort(imap->_imap_msg_num); +#endif + goto end_search; + } + } + } + } + } + + return idx; + +end_search: + + res.endSearch = true; + int read = imap->client.available(); + read = imap->client.readBytes(res.response + idx, read); + return idx + read; +} + +#if !defined(MB_USE_STD_VECTOR) +void ESP_Mail_Client::numDecSort(_vectorImpl &arr) +{ + + struct esp_mail_imap_msg_num_t tmp; + + for (size_t i = 0; i < arr.size(); ++i) + { + for (size_t j = i + 1; j < arr.size(); ++j) + { + if (arr[i].value < arr[j].value) + { + tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } + } + } +} +#endif + +struct esp_mail_message_part_info_t *ESP_Mail_Client::cPart(IMAPSession *imap) +{ + if (cHeader(imap) && imap->_cPartIdx < (int)cHeader(imap)->part_headers.size()) + return &cHeader(imap)->part_headers[imap->_cPartIdx]; + return nullptr; +} + +struct esp_mail_message_header_t *ESP_Mail_Client::cHeader(IMAPSession *imap) +{ + if (cIdx(imap) < (int)imap->_headers.size()) + return &imap->_headers[cIdx(imap)]; + return nullptr; +} + +bool ESP_Mail_Client::parseHeaderField(IMAPSession *imap, const char *buf, PGM_P beginToken, bool caseSensitive, struct esp_mail_message_header_t &header, int &headerState, int state) +{ + if (strcmpP(buf, 0, beginToken, caseSensitive)) + { + headerState = state; + char *tmp = subStr(buf, beginToken, NULL, 0, -1, caseSensitive); + if (tmp) + { + collectHeaderField(imap, tmp, header, headerState); + // release memory + freeMem(&tmp); + return true; + } + } + + return false; +} + +void ESP_Mail_Client::parseHeaderResponse(IMAPSession *imap, esp_mail_imap_response_data &res, bool caseSensitive) +{ + char *tmp = nullptr; + if (res.chunkIdx == 0) + { + MB_String str; + joinStringDot(str, 2, imap_commands[esp_mail_imap_command_header].text, imap_commands[esp_mail_imap_command_fields].text); + + if (!res.isUntaggedResponse && strposP(res.response, str.c_str(), 0, caseSensitive) != -1 && res.response[0] == '*') + res.isUntaggedResponse = true; + + if (res.isUntaggedResponse && res.response[strlen(res.response) - 1] == '}') + res.untaggedRespCompleted = true; + + if (res.isUntaggedResponse && res.header.message_no == 0) + { + tmp = subStr(res.response, imap_responses[esp_mail_imap_response_untagged].text, imap_responses[esp_mail_imap_response_fetch].text, 0); + if (tmp) + { + res.header.message_no = atoi(tmp); + // release memory + freeMem(&tmp); + } + } + + if (res.isUntaggedResponse && res.untaggedRespCompleted) + { + tmp = subStr(res.response, esp_mail_str_36 /* "{" */, esp_mail_str_37 /* "}" */, 0, 0, caseSensitive); + if (tmp) + { + res.octetCount = 2; + res.header.header_data_len = atoi(tmp); + // release memory + freeMem(&tmp); + res.chunkIdx++; + } + } + } + else + { + if (res.octetCount > res.header.header_data_len + 2) + return; + + res.chunkIdx++; + + MB_String field; + + for (int i = esp_mail_rfc822_header_field_from; i < esp_mail_rfc822_header_field_maxType; i++) + { + appendHeaderName(field, rfc822_headers[i].text, true, false, false); + if (parseHeaderField(imap, res.response, field.c_str(), caseSensitive, res.header, res.headerState, i)) + return; + } + + appendHeaderName(field, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, true, true, false); + + if (parseHeaderField(imap, res.response, field.c_str(), caseSensitive, res.header, res.headerState, esp_mail_imap_state_content_transfer_encoding)) + return; + + appendHeaderName(field, message_headers[esp_mail_message_header_field_accept_language].text, true, true, false); + + if (parseHeaderField(imap, res.response, field.c_str(), caseSensitive, res.header, res.headerState, esp_mail_imap_state_accept_language)) + return; + + appendHeaderName(field, message_headers[esp_mail_message_header_field_content_language].text, true, true, false); + + if (parseHeaderField(imap, res.response, field.c_str(), caseSensitive, res.header, res.headerState, esp_mail_imap_state_content_language)) + return; + + MB_String contentTypeName; + appendHeaderName(contentTypeName, message_headers[esp_mail_message_header_field_content_type].text, false, false, false); + if (strcmpP(res.response, 0, contentTypeName.c_str(), caseSensitive)) + { + res.headerState = esp_mail_imap_state_content_type; + tmp = subStr(res.response, contentTypeName.c_str(), esp_mail_str_35 /* ";" */, 0, 0, caseSensitive); + if (tmp) + { + // We set attachment status here as attachment should be included in multipart/mixed message, + // unless no real attachments included which we don't know until fetching the sub part. + if (strpos(tmp, esp_mail_imap_multipart_sub_type_t::mixed, 0, caseSensitive) != -1) + res.header.hasAttachment = true; + + collectHeaderField(imap, res.response, res.header, res.headerState); + // release memory + freeMem(&tmp); + } + } + } +} + +void ESP_Mail_Client::collectHeaderField(IMAPSession *imap, char *buf, struct esp_mail_message_header_t &header, int state) +{ + size_t i = 0; + while (buf[i] == ' ') + { + i++; + if (strlen(buf) <= i) + return; + } + + if (state < esp_mail_rfc822_header_field_maxType) + { + int ptr = getRFC822HeaderPtr(state, &header.header_fields); + if (ptr > 0) + { + *(addrTo(ptr)) += &buf[i]; + } + return; + } + + switch (state) + { + case esp_mail_imap_state_content_type: + header.content_type += &buf[i]; + break; + case esp_mail_imap_state_content_transfer_encoding: + header.content_transfer_encoding += &buf[i]; + break; + case esp_mail_imap_state_accept_language: + header.accept_language += &buf[i]; + break; + case esp_mail_imap_state_content_language: + header.content_language += &buf[i]; + break; + case esp_mail_imap_state_char_set: + header.char_set += &buf[i]; + break; + case esp_mail_imap_state_boundary: + header.boundary += &buf[i]; + break; + default: + break; + } +} + +bool ESP_Mail_Client::getDecodedHeader(IMAPSession *imap, const char *buf, PGM_P beginToken, MB_String &out, bool caseSensitive) +{ + if (getHeader(buf, beginToken, out, caseSensitive)) + { + // decode header text + decodeString(imap, out); + return true; + } + return false; +} + +void ESP_Mail_Client::checkFirmwareFile(IMAPSession *imap, const char *filename, struct esp_mail_message_part_info_t &part, bool defaultSize) +{ + if (strcmp(filename, imap->_imap_data->firmware_update.attach_filename.c_str()) == 0 && part.attach_type == esp_mail_att_type_attachment) + { + part.is_firmware_file = true; + // If no file size prop from Content-Disposition header + if (part.attach_data_size == 0 && defaultSize) + { +#if defined(ESP32) || defined(ESP8266) + int sketchFreeSpace = ESP.getFreeSketchSpace(); + part.attach_data_size = sketchFreeSpace ? sketchFreeSpace : 1024000; +#elif defined(MB_ARDUINO_PICO) + size_t spiffsSize = ((size_t)&_FS_end - (size_t)&_FS_start); + part.attach_data_size = spiffsSize ? spiffsSize / 2 : 1024000; +#endif + } + + if (!imap->_imap_data->firmware_update.save_to_file) + part.save_to_file = false; + } +} + +void ESP_Mail_Client::parsePartHeaderResponse(IMAPSession *imap, esp_mail_imap_response_data &res, bool caseSensitive) +{ + char *tmp = nullptr; + if (res.chunkIdx == 0) + { + tmp = subStr(res.response, imap_responses[esp_mail_imap_response_fetch].text, NULL, 0, -1); + if (tmp) + { + // release memory + freeMem(&tmp); + tmp = subStr(res.response, esp_mail_str_36 /* "{" */, esp_mail_str_37 /* "}" */, 0); + if (tmp) + { + res.chunkIdx++; + res.part.octetLen = atoi(tmp); + res.octetCount = 2; + // release memory + freeMem(&tmp); + } + } + } + else + { + MB_String value, old_value; + bool valueStored = false; + res.chunkIdx++; + + // if all octets read + + if (res.octetCount > res.part.octetLen) + { + + // Is inline attachment without content id or name or filename? + // It is supposed to be the inline message txt content, reset attach type to none + + if (res.part.attach_type == esp_mail_att_type_inline && res.part.CID.length() == 0) + res.part.attach_type = esp_mail_att_type_none; + + // Is attachment file extension missing? + // append extension + + if (res.part.attach_type == esp_mail_att_type_inline || res.part.attach_type == esp_mail_att_type_attachment) + { + if (res.part.filename.length() > 0 && res.part.filename.find('.') == MB_String::npos) + { + MB_String ext; + getExtfromMIME(res.part.content_type.c_str(), ext); + res.part.filename += ext; + } + + checkFirmwareFile(imap, res.part.filename.c_str(), res.part); + } + + return; + } + + // Content header field parse + if (strcmpP(res.response, 0, esp_mail_str_56 /* "content-" */, caseSensitive)) + { + // Content-Type + MB_String contentTypeName; + appendHeaderName(contentTypeName, message_headers[esp_mail_message_header_field_content_type].text, false, false, false); + if (strcmpP(res.response, 0, contentTypeName.c_str(), caseSensitive)) + { + + res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_type; + resetStringPtr(res.part); + + tmp = subStr(res.response, contentTypeName.c_str(), esp_mail_str_35 /* ";" */, 0, 0, caseSensitive); + if (tmp) + { + res.part.content_type = tmp; + // release memory + freeMem(&tmp); + int p1 = strposP(res.part.content_type.c_str(), esp_mail_imap_composite_media_type_t::multipart, 0, caseSensitive); + if (p1 != -1) + { + p1 += strlen(esp_mail_imap_composite_media_type_t::multipart) + 1; + res.part.multipart = true; + // inline or embedded images + if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::related, p1, caseSensitive) != -1) + res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_related; + // multiple text formats e.g. plain, html, enriched + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::alternative, p1, caseSensitive) != -1) + res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_alternative; + // medias + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::parallel, p1, caseSensitive) != -1) + res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_parallel; + // rfc822 encapsulated + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::digest, p1, caseSensitive) != -1) + res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_digest; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::report, p1, caseSensitive) != -1) + res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_report; + // others can be attachments + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::mixed, p1, caseSensitive) != -1) + res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_mixed; + } + + p1 = strposP(res.part.content_type.c_str(), esp_mail_imap_composite_media_type_t::message, 0, caseSensitive); + if (p1 != -1) + { + p1 += strlen(esp_mail_imap_composite_media_type_t::message) + 1; + if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::rfc822, p1, caseSensitive) != -1) + res.part.message_sub_type = esp_mail_imap_message_sub_type_rfc822; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::Partial, p1, caseSensitive) != -1) + res.part.message_sub_type = esp_mail_imap_message_sub_type_partial; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::External_Body, p1, caseSensitive) != -1) + res.part.message_sub_type = esp_mail_imap_message_sub_type_external_body; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::delivery_status, p1, caseSensitive) != -1) + res.part.message_sub_type = esp_mail_imap_message_sub_type_delivery_status; + } + + p1 = strpos(res.part.content_type.c_str(), esp_mail_imap_descrete_media_type_t::text, 0, caseSensitive); + if (p1 != -1) + { + p1 += strlen(esp_mail_imap_descrete_media_type_t::text) + 1; + if (strpos(res.part.content_type.c_str(), esp_mail_imap_media_text_sub_type_t::plain, p1, caseSensitive) != -1) + res.part.msg_type = esp_mail_msg_type_plain; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_media_text_sub_type_t::enriched, p1, caseSensitive) != -1) + res.part.msg_type = esp_mail_msg_type_enriched; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_media_text_sub_type_t::html, p1, caseSensitive) != -1) + res.part.msg_type = esp_mail_msg_type_html; + else + res.part.msg_type = esp_mail_msg_type_plain; + } + } + } + + // Content-Description + MB_String contentDescrName; + appendHeaderName(contentDescrName, message_headers[esp_mail_message_header_field_content_description].text, false, true, false); + if (getDecodedHeader(imap, res.response, contentDescrName.c_str(), res.part.descr, caseSensitive)) + { + res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_description; + + tmp = subStr(res.response, contentDescrName.c_str(), NULL, 0, -1, caseSensitive); + if (tmp) + { + value = tmp; + // release memory + freeMem(&tmp); + + res.part.stringPtr = toAddr(res.part.content_description); + value.trim(); + if (value.length() == 0) + return; + } + } + + // Content-ID + MB_String contentIdName; + appendHeaderName(contentIdName, message_headers[esp_mail_message_header_field_content_id].text, false, true, false); + if (strcmpP(res.response, 0, contentIdName.c_str(), caseSensitive)) + { + tmp = subStr(res.response, contentIdName.c_str(), NULL, 0, -1, caseSensitive); + if (tmp) + { + res.part.CID = tmp; + // release memory + freeMem(&tmp); + res.part.CID.trim(); + + if (res.part.CID[0] == '<') + res.part.CID.erase(0, 1); + + if (res.part.CID[res.part.CID.length() - 1] == '>') + res.part.CID.erase(res.part.CID.length() - 1, 1); + + // if inline attachment file name was not assigned + if (res.part.attach_type == esp_mail_att_type_inline && res.part.filename.length() == 0) + { + // set filename from content id and append extension later + res.part.filename = res.part.CID; + res.part.name = res.part.filename; + } + } + + res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_id; + resetStringPtr(res.part); + } + + // Content-Disposition + MB_String contentDispositionName; + appendHeaderName(contentDispositionName, message_headers[esp_mail_message_header_field_content_disposition].text, false, true, false); + if (strcmpP(res.response, 0, contentDispositionName.c_str(), caseSensitive)) + { + + res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_disposition; + resetStringPtr(res.part); + + tmp = subStr(res.response, contentDispositionName.c_str(), esp_mail_str_35 /* ";" */, 0, 0, caseSensitive); + if (tmp) + { + // don't count altenative part text and html as embedded contents + if (cHeader(imap)->multipart_sub_type != esp_mail_imap_multipart_sub_type_alternative) + { + res.part.content_disposition = tmp; + if (caseSensitive) + { + if (strcmp(tmp, esp_mail_content_disposition_type_t::attachment) == 0) + res.part.attach_type = esp_mail_att_type_attachment; + else if (strcmp(tmp, esp_mail_content_disposition_type_t::inline_) == 0) + res.part.attach_type = esp_mail_att_type_inline; + } + else + { + if (strcasecmp(tmp, esp_mail_content_disposition_type_t::attachment) == 0) + res.part.attach_type = esp_mail_att_type_attachment; + else if (strcasecmp(tmp, esp_mail_content_disposition_type_t::inline_) == 0) + res.part.attach_type = esp_mail_att_type_inline; + } + } + // release memory + freeMem(&tmp); + } + } + + // Content-Transfer-Encoding + MB_String contentTEName; + appendHeaderName(contentTEName, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, false, true, false); + if (strcmpP(res.response, 0, contentTEName.c_str(), caseSensitive)) + { + // store last text field + + res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_transfer_enc; + resetStringPtr(res.part); + + tmp = subStr(res.response, contentTEName.c_str(), NULL, 0, -1, caseSensitive); + if (tmp) + { + res.part.content_transfer_encoding = tmp; + + if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_base64)) + res.part.xencoding = esp_mail_msg_xencoding_base64; + else if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_qp)) + res.part.xencoding = esp_mail_msg_xencoding_qp; + else if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_7bit)) + res.part.xencoding = esp_mail_msg_xencoding_7bit; + else if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_8bit)) + res.part.xencoding = esp_mail_msg_xencoding_8bit; + else if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_binary)) + res.part.xencoding = esp_mail_msg_xencoding_binary; + // release memory + freeMem(&tmp); + } + } + } + else + { + + if (res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_none) + { + + resetStringPtr(res.part); + + MB_String field; + for (int i = esp_mail_rfc822_header_field_from; i < esp_mail_rfc822_header_field_maxType; i++) + { + field = rfc822_headers[i].text; + field += esp_mail_str_34; /* ":" */ + ; + + int ptr = getRFC822HeaderPtr(i, &res.part.rfc822_header); + if (ptr > 0) + { + if (getDecodedHeader(imap, res.response, field.c_str(), *(addrTo(ptr)), caseSensitive)) + return; + } + } + } + } + + // parse content type header sub type properties + if (res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_type) + { + + if (res.part.msg_type == esp_mail_msg_type_plain || res.part.msg_type == esp_mail_msg_type_enriched) + { + MB_String charset; + appendLowerCaseString(charset, message_headers[esp_mail_message_header_field_charset].text, false); + // We have to check for both quotes string or non quote string + if (getPartHeaderProperties(imap, res.response, charset.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.charset = value; + resetStringPtr(res.part); + } + else if (getPartHeaderProperties(imap, res.response, charset.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.charset = value; + resetStringPtr(res.part); + } + + if (strposP(res.response, esp_mail_str_59 /* "format=flowed" */, 0, caseSensitive) > -1 || strposP(res.response, esp_mail_str_58 /* "format=\"flowed\"" */, 0, caseSensitive) > -1) + { + res.part.plain_flowed = true; + resetStringPtr(res.part); + } + + if (strposP(res.response, esp_mail_str_61 /* "delsp=yes" */, 0, caseSensitive) > -1 || strposP(res.response, esp_mail_str_60 /* "delsp=\"yes\"" */, 0, caseSensitive) > -1) + { + res.part.plain_delsp = true; + resetStringPtr(res.part); + } + } + + if (res.part.charset.length() == 0) + { + MB_String charset; + appendLowerCaseString(charset, message_headers[esp_mail_message_header_field_charset].text, false); + // We have to check for both quotes string or non quote string + if (getPartHeaderProperties(imap, res.response, charset.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.charset = value; + resetStringPtr(res.part); + } + else if (getPartHeaderProperties(imap, res.response, charset.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.charset = value; + resetStringPtr(res.part); + } + } + + MB_String name; + appendLowerCaseString(name, message_headers[esp_mail_message_header_field_name].text, false); + // We have to check for both quotes string or non quote string + if (getPartHeaderProperties(imap, res.response, name.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.stringPtr = toAddr(res.part.name); + value.trim(); + if (value.length() == 0) + return; + } + else if (getPartHeaderProperties(imap, res.response, name.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.stringPtr = toAddr(res.part.name); + value.trim(); + if (value.length() == 0) + return; + } + } + + // parse content disposition header sub type properties + if (res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_disposition && res.part.content_disposition.length() > 0) + { + // filename prop + MB_String filename; + appendLowerCaseString(filename, message_headers[esp_mail_message_header_field_filename].text, false); + // We have to check for both quotes string or non quote string + if (getPartHeaderProperties(imap, res.response, filename.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.stringPtr = toAddr(res.part.filename); + value.trim(); + if (value.length() == 0) + return; + } + else if (getPartHeaderProperties(imap, res.response, filename.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.stringPtr = toAddr(res.part.filename); + value.trim(); + if (value.length() == 0) + return; + } + + // size prop + MB_String size; + appendLowerCaseString(size, message_headers[esp_mail_message_header_field_size].text, false); + + if (getPartHeaderProperties(imap, res.response, size.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.attach_data_size = atoi(value.c_str()); + cHeader(imap)->total_attach_data_size += res.part.attach_data_size; + res.part.sizeProp = true; + + if (!valueStored && old_value.length() > 0) + valueStored = storeStringPtr(imap, res.part.stringPtr, old_value, res.response); + resetStringPtr(res.part); + } + + // creation date prop + MB_String creationDate; + appendLowerCaseString(creationDate, message_headers[esp_mail_message_header_field_creation_date].text, false); + + if (getPartHeaderProperties(imap, res.response, creationDate.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.creation_date = value; + if (!valueStored && old_value.length() > 0) + valueStored = storeStringPtr(imap, res.part.stringPtr, old_value, res.response); + resetStringPtr(res.part); + } + + // mod date prop + MB_String modDate; + appendLowerCaseString(modDate, message_headers[esp_mail_message_header_field_modification_date].text, false); + + if (getPartHeaderProperties(imap, res.response, modDate.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.modification_date = value; + if (!valueStored && old_value.length() > 0) + valueStored = storeStringPtr(imap, res.part.stringPtr, old_value, res.response); + resetStringPtr(res.part); + } + } + + if (!valueStored && (res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_description || res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_type || res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_disposition)) + storeStringPtr(imap, res.part.stringPtr, value, res.response); + } +} + +void ESP_Mail_Client::resetStringPtr(struct esp_mail_message_part_info_t &part) +{ + part.stringPtr = 0; + part.stringEnc = esp_mail_char_decoding_scheme_default; +} + +int ESP_Mail_Client::countChar(const char *buf, char find) +{ + if (!buf) + return 0; + + int count = 0; + + for (size_t i = 0; i < strlen(buf); i++) + { + if (buf[i] == find) + count++; + } + + return count; +} + +bool ESP_Mail_Client::storeStringPtr(IMAPSession *imap, uint32_t addr, MB_String &value, const char *buf) +{ + if (addr) + { + MB_String *a = addrTo(addr); + MB_String s = value.length() > 0 ? value : buf; + + // is value string contains double quotes? + // trim it + if (countChar(s.c_str(), '"') == 2) + s.trim(); + + if (s[0] == '"') + s.erase(0, 1); + + if (s[s.length() - 1] == '"') + s.erase(s.length() - 1, 1); + + decodeString(imap, s); + + *a += s; + + return true; + } + + return false; +} + +bool ESP_Mail_Client::getPartHeaderProperties(IMAPSession *imap, const char *buf, PGM_P p, PGM_P e, bool num, MB_String &value, MB_String &old_value, esp_mail_char_decoding_scheme &scheme, bool caseSensitive) +{ + + MB_String str = p; + str += esp_mail_str_7; /* "=" */ + if (!num) + str += esp_mail_str_11; /* "\"" */ + + char *tmp = subStr(buf, str.c_str(), e, 0, 0, caseSensitive); + if (!tmp) + { + str = p; + str += esp_mail_str_7; /* "=" */ + tmp = subStr(buf, str.c_str(), e, 0, 0, caseSensitive); + if (tmp) + { + // other sub headers found? + int p2 = strposP(tmp, esp_mail_str_35 /* ";" */, 0, caseSensitive); + if (p2 > -1) + { + // release memory + freeMem(&tmp); + tmp = subStr(buf, str.c_str(), esp_mail_str_35 /* ";" */, 0, 0, caseSensitive); + } + // release memory in case above condition does not match + freeMem(&tmp); + } + else + { + // Extended notation rfc5987 + str = p; + str += esp_mail_str_3; /* "*" */ + int p2 = strpos(buf, str.c_str(), 0, caseSensitive); + if (p2 > -1) + { + int p3 = strposP(buf, esp_mail_str_3 /* "*" */, p2 + str.length() + 1, caseSensitive); + if (p3 > -1 && p3 < (int)strlen(buf)) + { + MB_String charset; + + p3 += 2; + + int p4 = strpos(buf, "'", p3, caseSensitive); + if (p4 > -1) + { + + scheme = getEncodingFromCharset(buf); + int c1 = p4 + 1; + p4 = strpos(buf, "'", p4 + 1, caseSensitive); + int c2 = p4; + if (c2 > -1) + { + charset.append(buf + c1, c2 - c1); + } + p3 = p4 + 1; + } + + int len = strlen(buf) - p3; + tmp = allocMem(len + 1); + + if (buf[strlen(buf) - 1] == ';') + len--; + + memcpy(tmp, &buf[p3], len); + + if (scheme == esp_mail_char_decoding_scheme_utf_8) + { + char *buf2 = urlDecode(tmp); + // release memory and point to new buffer + freeMem(&tmp); + tmp = buf2; + } + else if (imap->_charDecCallback) + { + IMAP_Decoding_Info decoding; + decoding.charset = charset.c_str(); + decoding.data = tmp; + decoding.type = IMAP_Decoding_Info::message_part_type_header; + + imap->_charDecCallback(&decoding); + + if (decoding.decodedString.length() > 0) + { + char *buf2 = allocMem(decoding.decodedString.length() + 1); + strcpy(buf2, decoding.decodedString.c_str()); + // release memory and point to new buffer + freeMem(&tmp); + tmp = buf2; + } + } + else if (scheme == esp_mail_char_decoding_scheme_iso8859_1) + { + int ilen = strlen(tmp); + int olen = (ilen + 1) * 2; + char *buf2 = allocMem(olen); + decodeLatin1_UTF8((unsigned char *)buf2, &olen, (unsigned char *)tmp, &ilen); + // release memory and point to new buffer + freeMem(&tmp); + tmp = buf2; + } + else if (scheme == esp_mail_char_decoding_scheme_tis_620 || scheme == esp_mail_char_decoding_scheme_iso8859_11 || scheme == esp_mail_char_decoding_scheme_windows_874) + { + int ilen = strlen(tmp); + char *buf2 = allocMem((ilen + 1) * 3); + decodeTIS620_UTF8(buf2, tmp, ilen); + // release memory and point to new buffer + freeMem(&tmp); + tmp = buf2; + } + } + } + } + } + + if (tmp) + { + old_value = value; + value = tmp; + // release memory + freeMem(&tmp); + return true; + } + + return false; +} + +char *ESP_Mail_Client::urlDecode(const char *str) +{ + int d = 0; /* whether or not the string is decoded */ + char *dStr = allocMem(strlen(str) + 1); + char eStr[] = "00"; /* for a hex code */ + + strcpy(dStr, str); + + while (!d) + { + d = 1; + size_t i; /* the counter for the string */ + + for (i = 0; i < strlen(dStr); ++i) + { + + if (dStr[i] == '%') + { + if (dStr[i + 1] == 0) + return dStr; + + if (isxdigit(dStr[i + 1]) && isxdigit(dStr[i + 2])) + { + d = 0; + + /* combine the next to numbers into one */ + eStr[0] = dStr[i + 1]; + eStr[1] = dStr[i + 2]; + + /* convert it to decimal */ + long int x = strtol(eStr, NULL, 16); + + /* remove the hex */ + memmove(&dStr[i + 1], &dStr[i + 3], strlen(&dStr[i + 3]) + 1); + + dStr[i] = x; + } + } + } + } + + return dStr; +} + +bool ESP_Mail_Client::handleIMAPResponse(IMAPSession *imap, int errCode, bool closeSession) +{ + + if (!reconnect(imap)) + return false; + + esp_mail_imap_response_data res(imap->client.available()); + imap->_lastProgress = -1; + + // Flag used for CRLF inclusion in response reading in case 8bit/binary attachment and base64 encoded and binary messages + bool withLineBreak = imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text && (cPart(imap)->xencoding == esp_mail_msg_xencoding_base64 || cPart(imap)->xencoding == esp_mail_msg_xencoding_binary); + withLineBreak |= imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment && cPart(imap)->xencoding != esp_mail_msg_xencoding_base64; + + // custom cmd IDLE?, waiting incoming server response + if (res.chunkBufSize == 0 && imap->_prev_imap_custom_cmd == imap->_imap_custom_cmd && imap->_imap_custom_cmd == esp_mail_imap_cmd_idle) + { + if (!reconnect(imap)) + return false; + + return true; + } + + while (imap->connected() && res.chunkBufSize <= 0) + { + + if (!reconnect(imap, res.dataTime)) + return false; + + if (!connected(imap)) + { +#if defined(ESP32) + if (imap->_imap_cmd == esp_mail_imap_cmd_logout) // suppress the error due to server closes the connection immediately in ESP32 core v2.0.4 + return true; +#endif + if (millis() - imap->_last_network_error_ms > 1000) + { + imap->_last_network_error_ms = millis(); + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, true); + } + + return false; + } + res.chunkBufSize = imap->client.available(); + yield_impl(); + } + + res.dataTime = millis(); + + if (res.chunkBufSize > 0) + { + if (imap->_imap_cmd == esp_mail_imap_cmd_examine) + { + imap->_mbif.clear(); + imap->_nextUID.clear(); + imap->_unseenMsgIndex.clear(); + } + + if (imap->_imap_cmd == esp_mail_imap_cmd_search) + { + imap->_mbif._searchCount = 0; + imap->_imap_msg_num.clear(); + } + + // response buffer + res.chunkBufSize = ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE; + res.response = allocMem(res.chunkBufSize + 1); + + if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) + res.lastBuf = allocMem(BASE64_CHUNKED_LEN + 1); + + while (!res.completedResponse) // looking for operation finishing + { + yield_impl(); + + if (imap->_imap_cmd == esp_mail_imap_cmd_append || (imap->_imap_custom_cmd == esp_mail_imap_cmd_append && imap->_imap_cmd == esp_mail_imap_cmd_custom && imap->_customCmdResCallback)) + { + // No waiting time out for APPEND + res.dataTime = millis(); + } + + if (!reconnect(imap, res.dataTime) || !connected(imap)) + { + + if (!connected(imap)) + { + + if (cPart(imap) && cPart(imap)->file_open_write) + mbfs->close(mbfs_type imap->_imap_data->storage.type); + +#if defined(ESP32) + if (imap->_imap_cmd == esp_mail_imap_cmd_logout) // suppress the error due to server closes the connection immediately in ESP32 core v2.0.4 + return true; +#endif + + if (millis() - imap->_last_network_error_ms > 1000) + { + imap->_last_network_error_ms = millis(); + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, true); + } + + return false; + } + return false; + } + + res.chunkBufSize = imap->client.available(); + + if (res.chunkBufSize > 0) + { + res.chunkBufSize = ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE; + + if (imap->_imap_cmd == esp_mail_imap_cmd_search) + { + + res.readLen = parseSearchResponse(imap, res, esp_mail_imap_tag_str, imap_responses[esp_mail_imap_response_search].text); + imap->_mbif._availableItems = imap->_imap_msg_num.size(); + + if (imap->_mbif._availableItems == 0) + { + res.imapResp = imapResponseStatus(imap, res.response, esp_mail_imap_tag_str); + + if (res.imapResp != esp_mail_imap_resp_unknown) + res.endSearch = true; + + if (res.imapResp == esp_mail_imap_resp_bad) + { + errorStatusCB(imap, nullptr, IMAP_STATUS_BAD_COMMAND, false); + return false; + } + } + } + else + { + // response read as chunk ended with CRLF or complete buffer size + int o = res.octetCount; + res.readLen = 0; + MB_String ovfBuf; + if (!readResponse(imap, res.response, res.chunkBufSize, res.readLen, withLineBreak, res.octetCount, ovfBuf)) + { + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_READ_TIMEOUT, true); + return false; + } + + // If buffer overflown, copy from overflow buffer + if (ovfBuf.length() > 0) + { + // release memory + freeMem(&res.response); + res.response = allocMem(ovfBuf.length() + 1); + strcpy(res.response, ovfBuf.c_str()); + ovfBuf.clear(); + } + + if (res.readLen == 0 && o != res.octetCount && res.octetCount <= res.octetLength && cPart(imap)->xencoding != esp_mail_msg_xencoding_base64 && cPart(imap)->xencoding != esp_mail_msg_xencoding_binary && cPart(imap)->xencoding != esp_mail_msg_xencoding_qp) + { + strcpy_P(res.response, esp_mail_str_42 /* "\r\n" */); + res.readLen = 2; + } + } + + if (res.readLen) + { + if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_basic && !imap->_customCmdResCallback) + { + if (imap->_imap_cmd != esp_mail_imap_cmd_search && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_text && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_attachment && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_inline) + esp_mail_debug_print((const char *)res.response, true); + } + + if (imap->_imap_cmd != esp_mail_imap_cmd_search || (imap->_imap_cmd == esp_mail_imap_cmd_search && res.endSearch)) + res.imapResp = imapResponseStatus(imap, res.response, esp_mail_imap_tag_str); + + if (res.imapResp != esp_mail_imap_resp_unknown) + { + + // We've got the right response, + // prepare to exit + + res.completedResponse = true; + + if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_basic && !imap->_customCmdResCallback) + { + if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) + esp_mail_debug_print((const char *)res.response, true); + } + + MB_String ovfBuf; + + while (imap->client.available()) + { + + if (!readResponse(imap, res.response, res.chunkBufSize, res.readLen, true, res.octetCount, ovfBuf)) + { + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_READ_TIMEOUT, true); + return false; + } + // If buffer overflown, copy from overflow buffer + if (ovfBuf.length() > 0) + { + // release memory + freeMem(&res.response); + res.response = allocMem(ovfBuf.length() + 1); + strcpy(res.response, ovfBuf.c_str()); + ovfBuf.clear(); + } + + if (res.readLen) + { + if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_basic && !imap->_customCmdResCallback) + { + if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) + esp_mail_debug_print((const char *)res.response, true); + } + } + } + } + else + { + + // No response ever parsed + + if (imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_plain || imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_oauth) + { + if (imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_oauth) + { + if (isOAuthError(res.response, res.readLen, res.chunkIdx, 2)) + res.completedResponse = true; + } + + // In case SASL-IR extension does not support, check for initial zero-length server challenge first "+ " + if (!imap->_auth_capability[esp_mail_auth_capability_sasl_ir] && strcmp(res.response, pgm2Str(esp_mail_str_63 /* "+ " */)) == 0) + { + res.imapResp = esp_mail_imap_resp_ok; + res.completedResponse = true; + } + } + + if (imap->_imap_cmd == esp_mail_imap_cmd_sasl_login || imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_oauth || imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_plain) + { + int i = 0; + if (parseCapabilityResponse(imap, res.response, i)) + imap->_feature_capability[esp_mail_imap_read_capability_auto_caps] = true; + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_custom && imap->_customCmdResCallback) + { + + res.imapResp = imapResponseStatus(imap, res.response, imap->_responseStatus.tag.c_str()); + + // get response or custom cmd APPEND or custom cmd IDLE? + if (res.imapResp > esp_mail_imap_resp_unknown || strposP(imap->_cmd.c_str(), imap_commands[esp_mail_imap_command_append].text, 0, false) > -1 || imap->_imap_custom_cmd == esp_mail_imap_cmd_idle) + res.completedResponse = true; + + imap->_responseStatus.text = res.response; + + imap->_customCmdResCallback(imap->_responseStatus); + + if (res.completedResponse) + return true; + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_append) + { + res.imapResp = esp_mail_imap_resp_ok; + res.completedResponse = true; + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_capability) + parseCapabilityResponse(imap, res.response, res.chunkIdx); + else if (imap->_imap_cmd == esp_mail_imap_cmd_list) + parseFoldersResponse(imap, res.response, true); + else if (imap->_imap_cmd == esp_mail_imap_cmd_lsub) + parseFoldersResponse(imap, res.response, false); + else if (imap->_imap_cmd == esp_mail_imap_cmd_select || imap->_imap_cmd == esp_mail_imap_cmd_examine) + parseExamineResponse(imap, res.response); + else if (imap->_imap_cmd == esp_mail_imap_cmd_get_uid) + { + MB_String str; + appendFetchString(str, true); + parseCmdResponse(imap, res.response, str.c_str()); + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_get_flags) + { + MB_String str; + appendFetchString(str, false); + parseCmdResponse(imap, res.response, str.c_str()); + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_get_quota) + parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_quota].text); + else if (imap->_imap_cmd == esp_mail_imap_cmd_id) + parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_id].text); + else if (imap->_imap_cmd == esp_mail_imap_cmd_get_quota_root) + { + parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_quotaroot].text); + imap->_quota_tmp.clear(); + parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_quota].text); + if (imap->_quota_tmp.length() > 0) + { + imap->_quota_root_tmp += (char)':'; + imap->_quota_root_tmp += imap->_quota_tmp; + } + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_get_acl || imap->_imap_cmd == esp_mail_imap_cmd_my_rights) + parseCmdResponse(imap, res.response, imap->_imap_cmd == esp_mail_imap_cmd_get_acl ? imap_responses[esp_mail_imap_response_acl].text : imap_responses[esp_mail_imap_response_myrights].text); + else if (imap->_imap_cmd == esp_mail_imap_cmd_namespace) + parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_namespace].text); + else if (imap->_imap_cmd == esp_mail_imap_cmd_idle) + { + res.completedResponse = res.response[0] == '+'; + res.imapResp = esp_mail_imap_resp_ok; + + imap->_last_host_check_ms = millis(); + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_sequence_set) + { + MB_String str; + appendFetchString(str, true); + parseCmdResponse(imap, res.response, str.c_str()); + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_header) + { + + if (res.headerState == 0 && cMSG(imap).type == esp_mail_imap_msg_num_type_uid) + res.header.message_uid = cMSG(imap).value; + + int _st = res.headerState; + parseHeaderResponse(imap, res, imap->_imap_data->enable.header_case_sensitive); + if (_st == res.headerState && res.headerState > 0 && res.octetCount <= res.header.header_data_len) + collectHeaderField(imap, res.response, res.header, res.headerState); + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_mime) + parsePartHeaderResponse(imap, res, imap->_imap_data->enable.header_case_sensitive); + else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text) + decodeText(imap, res); + else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) + { + + if (cPart(imap)->xencoding == esp_mail_msg_xencoding_base64) + { + // Multi-line chunked base64 string attachment handle + if (res.octetCount < res.octetLength && res.readLen < BASE64_CHUNKED_LEN) + { + if (strlen(res.lastBuf) > 0) + { + res.buf = allocMem(res.readLen + strlen(res.lastBuf) + 2); + strcpy(res.buf, res.lastBuf); + strcat(res.buf, res.response); + res.readLen = strlen(res.buf); + res.tmo = parseAttachmentResponse(imap, res.buf, res); + // release memory + freeMem(&res.buf); + memset(res.lastBuf, 0, BASE64_CHUNKED_LEN + 1); + if (!res.tmo) + break; + } + else if (res.readLen < BASE64_CHUNKED_LEN + 1) + strcpy(res.lastBuf, res.response); + } + else + { + res.tmo = parseAttachmentResponse(imap, res.response, res); + if (!res.tmo) + break; + } + } + else + res.tmo = parseAttachmentResponse(imap, res.response, res); + } + + res.dataTime = millis(); + } + } + memset(res.response, 0, res.chunkBufSize); + } + } + + if (imap->_imap_cmd == esp_mail_imap_cmd_search) + { + if (imap->_debug && res.searchCount > 0 && res.searchCount < 100) + { + searchReport(imap, 100); + } + } + } + + if ((res.imapResp != esp_mail_imap_resp_ok && imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_header && res.header.header_data_len == 0) || res.imapResp == esp_mail_imap_resp_no) + { + // We don't get any response + + if (res.imapResp == esp_mail_imap_resp_no) + imap->_responseStatus.errorCode = IMAP_STATUS_IMAP_RESPONSE_FAILED; + else if (imap->_imap_data->fetch.modsequence > -1 && imap->isModseqSupported() && res.imapResp == esp_mail_imap_resp_ok && res.header.header_data_len == 0) + imap->_responseStatus.errorCode = IMAP_STATUS_CHANGEDSINC_MODSEQ_TEST_FAILED; + else + imap->_responseStatus.errorCode = IMAP_STATUS_NO_MESSAGE; + +#if !defined(SILENT_MODE) + + if (imap->_statusCallback && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_mime) + sendErrorCB(imap, imap->errorReason().c_str(), false, false); + + if (imap->_debug && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_mime) + esp_mail_debug_print_tag(imap->errorReason().c_str(), esp_mail_debug_tag_type_error, true); + +#endif + + return false; + } + + // We've got OK or NO responses + + if (res.imapResp == esp_mail_imap_resp_ok) + { + // Response OK + + if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_header) + { + // Headers management + + char *buf = allocMem(res.header.content_type.length() + 1); + strcpy(buf, res.header.content_type.c_str()); + res.header.content_type.clear(); + + MB_String contentTypeName; + appendHeaderName(contentTypeName, message_headers[esp_mail_message_header_field_content_type].text, false, false, false); + + res.buf = subStr(buf, contentTypeName.c_str(), esp_mail_str_35 /* ";" */, 0, 0, false); + if (res.buf) + { + res.headerState = esp_mail_imap_state_content_type; + collectHeaderField(imap, res.buf, res.header, res.headerState); + // release memory + freeMem(&res.buf); + + if (res.header.content_type.length() > 0) + { + int p1 = strposP(res.header.content_type.c_str(), esp_mail_imap_composite_media_type_t::multipart, 0); + if (p1 != -1) + { + p1 += strlen(esp_mail_imap_composite_media_type_t::multipart) + 1; + res.header.multipart = true; + // inline or embedded images + if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::related, p1) != -1) + res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_related; + // multiple text formats e.g. plain, html, enriched + else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::alternative, p1) != -1) + res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_alternative; + // medias + else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::parallel, p1) != -1) + res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_parallel; + // rfc822 encapsulated + else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::digest, p1) != -1) + res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_digest; + else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::report, p1) != -1) + res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_report; + // others can be attachments + else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::mixed, p1) != -1) + res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_mixed; + } + + p1 = strposP(res.header.content_type.c_str(), esp_mail_imap_composite_media_type_t::message, 0); + if (p1 != -1) + { + p1 += strlen(esp_mail_imap_composite_media_type_t::message) + 1; + if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::rfc822, p1) != -1) + { + res.header.rfc822_part = true; + res.header.message_sub_type = esp_mail_imap_message_sub_type_rfc822; + } + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::Partial, p1) != -1) + res.header.message_sub_type = esp_mail_imap_message_sub_type_partial; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::External_Body, p1) != -1) + res.header.message_sub_type = esp_mail_imap_message_sub_type_external_body; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::delivery_status, p1) != -1) + res.header.message_sub_type = esp_mail_imap_message_sub_type_delivery_status; + } + } + + MB_String charset; + appendLowerCaseString(charset, message_headers[esp_mail_message_header_field_charset].text, false); + charset += esp_mail_str_7; /* "=" */ + + res.buf = subStr(buf, charset.c_str(), NULL, 0, -1, false); + if (res.buf) + { + res.headerState = esp_mail_imap_state_char_set; + collectHeaderField(imap, res.buf, res.header, res.headerState); + // release memory + freeMem(&res.buf); + } + + if (res.header.multipart) + { + if (strcmpP(buf, 0, esp_mail_str_64 /* "boundary=\"" */)) + { + res.buf = subStr(buf, esp_mail_str_64 /* "boundary=\"" */, esp_mail_str_11 /* "\"" */, 0, 0, false); + if (res.buf) + { + res.headerState = esp_mail_imap_state_boundary; + collectHeaderField(imap, res.buf, res.header, res.headerState); + // release memory + freeMem(&res.buf); + } + } + } + } + + // release memory + freeMem(&buf); + + // Decode the headers fields + + for (int i = esp_mail_rfc822_header_field_from; i < esp_mail_rfc822_header_field_maxType; i++) + { + if (i != esp_mail_rfc822_header_field_msg_id && i != esp_mail_rfc822_header_field_flags) + decodeString(imap, res.header.header_fields.header_items[i]); + } + + imap->_headers.push_back(res.header); + } + + if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_mime) + { + // Expect the octet length in the response for the existent part + if (res.part.octetLen > 0) + { + + res.part.partNumStr = cHeader(imap)->partNumStr; + res.part.partNumFetchStr = cHeader(imap)->partNumStr; + if (cHeader(imap)->part_headers.size() > 0) + { + + struct esp_mail_message_part_info_t *_part = &cHeader(imap)->part_headers[cHeader(imap)->part_headers.size() - 1]; + bool rfc822_body_subtype = _part->message_sub_type == esp_mail_imap_message_sub_type_rfc822; + + if (rfc822_body_subtype) + { + if (!_part->rfc822_part) + { + // additional rfc822 message header, store it to the rfc822 part header + _part->rfc822_part = true; + _part->rfc822_header = res.part.rfc822_header; + imap->_rfc822_part_count++; + _part->rfc822_msg_Idx = imap->_rfc822_part_count; + } + } + } + + cHeader(imap)->part_headers.push_back(res.part); + cHeader(imap)->message_data_count = cHeader(imap)->part_headers.size(); + + if (res.part.msg_type != esp_mail_msg_type_none || + res.part.attach_type != esp_mail_att_type_none) + { + if (res.part.attach_type == esp_mail_att_type_attachment || + res.part.message_sub_type != esp_mail_imap_message_sub_type_rfc822) + { + if (res.part.attach_type != esp_mail_att_type_none && + cHeader(imap)->multipart_sub_type != esp_mail_imap_multipart_sub_type_alternative) + { + cHeader(imap)->hasAttachment = true; + cHeader(imap)->attachment_count++; + } + } + } + } + else + { + // nonexistent part + // return false to exit the loop without closing the connection + if (closeSession) + imap->closeSession(); + return false; + } + } + + if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) + { + if (cPart(imap) && cPart(imap)->file_open_write) + mbfs->close(mbfs_type imap->_imap_data->storage.type); + } + + if (cPart(imap) && imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text) + cPart(imap)->text[cPart(imap)->textLen] = 0; + } + else + { + + // Response NO + + // Some server responses NO and should exit (false) from MIME feching loop without + // closing the session + if (imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_mime) + return handleIMAPError(imap, errCode, false); + + if (closeSession) + imap->closeSession(); + return false; + } + + return true; +} + +void ESP_Mail_Client::addHeader(MB_String &s, PGM_P name, const char *s_value, int num_value, bool trim, bool isJson) +{ + if (isJson) + { + s += (s.length() > 0) ? esp_mail_str_77 /* ",\"" */ : esp_mail_str_78 /* "{\"" */; + s += name; + + if (strlen(s_value) > 0) + { + s += esp_mail_str_79; /* "\":\"" */ + ; + if (trim) + { + MB_String t = s_value; + t.replaceAll("\"", ""); + s += t; + } + else + s += s_value; + s += esp_mail_str_11; /* "\"" */ + } + else + { + s += esp_mail_str_34 /* ":" */; + appendSpace(s); + s += num_value; + } + } + else + { + if (s.length() > 0) + appendNewline(s); + s += name; + s += esp_mail_str_34 /* ":" */; + appendSpace(s); + if (strlen(s_value) > 0) + s += s_value; + else + s += num_value; + } +} + +void ESP_Mail_Client::saveHeader(IMAPSession *imap, bool json) +{ + if (!imap->_storageReady) + return; + + MB_String headerFilePath; + + prepareFilePath(imap, headerFilePath, true); + + headerFilePath += json ? esp_mail_str_65 /* "/header.json" */ : esp_mail_str_66 /* "/header.txt" */; + + prepareFileList(imap, headerFilePath); + + int sz = mbfs->open(headerFilePath, mbfs_type imap->_imap_data->storage.type, mb_fs_open_mode_write); + if (sz < 0) + { + imap->_responseStatus.errorCode = sz; + imap->_responseStatus.text.clear(); +#if !defined(SILENT_MODE) + if (imap->_debug) + { + esp_mail_debug_print_tag(imap->errorReason().c_str(), esp_mail_debug_tag_type_error, true); + } +#endif + return; + } + + MB_String s; + for (size_t i = 0; i < imap->_headers.size(); i++) + addHeaderItem(s, &imap->_headers[i], json); + + if (json) + s += esp_mail_str_75; /* "]}" */ + + mbfs->print(mbfs_type imap->_imap_data->storage.type, s.c_str()); + + mbfs->close(mbfs_type imap->_imap_data->storage.type); + + imap->_headerSaved = true; +} + +void ESP_Mail_Client::addHeaderItem(MB_String &str, esp_mail_message_header_t *header, bool json) +{ + MB_String s; + if (json) + { + if (str.length() > 0) + str += esp_mail_str_8; /* "," */ + else + str = esp_mail_str_76; /* "{\"Messages\":[" */ + } + + addHeader(s, message_headers[esp_mail_message_header_field_number].text, "", header->message_no, false, json); + addHeader(s, message_headers[esp_mail_message_header_field_uid].text, "", header->message_uid, false, json); + + if (header->accept_language.length() > 0) + addHeader(s, message_headers[esp_mail_message_header_field_accept_language].text, header->accept_language.c_str(), 0, false, json); + + if (header->content_language.length() > 0) + addHeader(s, message_headers[esp_mail_message_header_field_content_language].text, header->content_language.c_str(), 0, false, json); + + addRFC822Headers(s, &header->header_fields, json); + + for (size_t j = 0; j < header->part_headers.size(); j++) + { + if (header->part_headers[j].rfc822_part) + { + MB_String s1; + addRFC822Headers(s1, &header->part_headers[j].rfc822_header, json); + + if (json) + { + s += esp_mail_str_69; /* ",\"RFC822\":" */ + s += s1; + s += esp_mail_str_36; /* "}" */ + } + else + { + s += esp_mail_str_70; /* "\r\n\r\nRFC822:\r\n" */ + s += s1; + } + } + } + + if (header->attachment_count > 0) + { + if (json) + { + s += esp_mail_str_71 /* ",\"Attachments\":{\"Count\":" */; + s += header->attachment_count; + s += esp_mail_str_72; /* ",\"Files\":[" */ + } + else + { + s += esp_mail_str_73; /* "\r\n\r\nAttachments (" */ + s += header->attachment_count; + s += esp_mail_str_74; /* ")\r\n" */ + } + + int index = 0; + for (size_t j = 0; j < header->part_headers.size(); j++) + { + + if (header->part_headers[j].attach_type == esp_mail_att_type_none || header->part_headers[j].rfc822_part) + continue; + + if (json) + { + if (index > 0) + s += esp_mail_str_8; /* "," */ + s += esp_mail_str_67; /* /"{\"Filename\":\"" */ + s += header->part_headers[j].filename; + s += esp_mail_str_11; /* "\"" */ + } + else + { + if (index > 0) + appendNewline(s); + appendNewline(s); + s += esp_mail_str_68; /* /"Index: " */ + s += index + 1; + addHeader(s, message_headers[esp_mail_message_header_field_filename].text, header->part_headers[j].filename.c_str(), 0, false, json); + } + + addHeader(s, message_headers[esp_mail_message_header_field_name].text, header->part_headers[j].name.c_str(), 0, false, json); + addHeader(s, message_headers[esp_mail_message_header_field_size].text, "", header->part_headers[j].attach_data_size, false, json); + addHeader(s, message_headers[esp_mail_message_header_field_mime].text, header->part_headers[j].content_type.c_str(), 0, false, json); + addHeader(s, message_headers[esp_mail_message_header_field_type].text, header->part_headers[j].attach_type == esp_mail_att_type_attachment ? esp_mail_content_disposition_type_t::attachment : esp_mail_content_disposition_type_t::inline_, 0, false, json); + addHeader(s, message_headers[esp_mail_message_header_field_description].text, header->part_headers[j].content_description.c_str(), 0, false, json); + addHeader(s, message_headers[esp_mail_message_header_field_creation_date].text, header->part_headers[j].creation_date.c_str(), 0, false, json); + + if (json) + s += esp_mail_str_36; /* "}" */ + + index++; + } + + if (json) + s += esp_mail_str_75; /* "]}" */ + } + + if (json) + { + s += esp_mail_str_36; /* "}" */ + } + + str += s; +} + +int ESP_Mail_Client::getRFC822HeaderPtr(int index, esp_mail_imap_rfc822_msg_header_item_t *header) +{ + if (index > esp_mail_rfc822_header_field_from && index < esp_mail_rfc822_header_field_maxType) + return toAddr(header->header_items[index]); + return 0; +} + +void ESP_Mail_Client::addRFC822Headers(MB_String &s, esp_mail_imap_rfc822_msg_header_item_t *header, bool json) +{ + for (int i = esp_mail_rfc822_header_field_from; i < esp_mail_rfc822_header_field_maxType; i++) + addRFC822HeaderItem(s, header, i, json); +} + +void ESP_Mail_Client::addRFC822HeaderItem(MB_String &s, esp_mail_imap_rfc822_msg_header_item_t *header, int index, bool json) +{ + int ptr = getRFC822HeaderPtr(index, header); + if (ptr > 0) + addHeader(s, rfc822_headers[index].text, addrTo(ptr)->c_str(), 0, rfc822_headers[index].trim, json); +} + +esp_mail_imap_response_status ESP_Mail_Client::imapResponseStatus(IMAPSession *imap, char *response, PGM_P tag) +{ + imap->_responseStatus.clear(false); + MB_String test; + esp_mail_imap_response_status status = esp_mail_imap_resp_unknown; + esp_mail_imap_response_types type = esp_mail_imap_response_maxType; + + if (strpos(response, imap->prependTag(imap_responses[esp_mail_imap_response_ok].text, tag).c_str(), 0) > -1) + { + status = esp_mail_imap_resp_ok; + type = esp_mail_imap_response_ok; + } + else if (strpos(response, imap->prependTag(imap_responses[esp_mail_imap_response_no].text, tag).c_str(), 0) > -1) + { + status = esp_mail_imap_resp_no; + type = esp_mail_imap_response_no; + } + else if (strpos(response, imap->prependTag(imap_responses[esp_mail_imap_response_bad].text, tag).c_str(), 0) > -1) + { + status = esp_mail_imap_resp_bad; + type = esp_mail_imap_response_bad; + } + + if (status != esp_mail_imap_resp_unknown) + { + test = imap->prependTag(imap_responses[type].text, tag); + + imap->_responseStatus.text = &response[test.length()]; + if (imap->_responseStatus.text[imap->_responseStatus.text.length() - 2] == '\r') + imap->_responseStatus.text[imap->_responseStatus.text.length() - 2] = 0; + + test = imap_responses[type].text; + test.trim(); + imap->_responseStatus.status = test; + imap->_responseStatus.completed = true; + } + return status; +} + +bool ESP_Mail_Client::parseCapabilityResponse(IMAPSession *imap, const char *buf, int &chunkIdx) +{ + if (chunkIdx == 0) + { + MB_String res; + // We add white space to make post token checking to work in all capabilities. + // This will allow us to check "IDLE " and "ID " correctly. + appendSpace(res, false, buf); + + if (strposP(res.c_str(), imap_responses[esp_mail_imap_response_capability_untagged].text, 0) > -1 || strposP(res.c_str(), imap_responses[esp_mail_imap_response_capability].text, 0) > -1) + { + for (int i = esp_mail_auth_capability_plain; i < esp_mail_auth_capability_maxType; i++) + { + if (strposP(res.c_str(), imap_auth_cap_pre_tokens[i].c_str(), 0) > -1) + imap->_auth_capability[i] = true; + } + + for (int i = esp_mail_imap_read_capability_imap4; i < esp_mail_imap_read_capability_maxType; i++) + { + if (strposP(res.c_str(), imap_read_cap_post_tokens[i].c_str(), 0) > -1) + { + imap->_feature_capability[i] = true; + if (i == esp_mail_imap_read_capability_logindisable) + imap->_auth_capability[esp_mail_auth_capability_login] = false; + } + } + + return true; + } + } + + return false; +} + +char *ESP_Mail_Client::getList(char *buf, bool &isList) +{ + if (buf[0] == '(' && buf[1] != ')') + { + if (buf[strlen(buf) - 1] == ')') + buf[strlen(buf) - 1] = 0; + else + isList = true; + + return &buf[1]; + } + else if (isList) + { + if (buf[strlen(buf) - 1] == ')') + { + buf[strlen(buf) - 1] = 0; + isList = false; + } + } + + return buf; +} + +void ESP_Mail_Client::parseFoldersResponse(IMAPSession *imap, char *buf, bool list) +{ + struct esp_mail_folder_info_t fd; + int pos = list ? strposP(buf, imap_responses[esp_mail_imap_response_list].text, 0) : strposP(buf, imap_responses[esp_mail_imap_response_lsub].text, 0); + bool isList = false, delimOk = false; + if (pos != -1) + { + char *p = allocMem(strlen(buf)); + strcpy(p, buf); + char *pp = p; + char *end = p; + int count = 0; + int tkPos = 3; + + while (pp != NULL) + { + // See RFC2047.h + ESP_MAIL_STRSEP(&end, " "); + count++; + + if (count >= tkPos && strlen(pp) > 0) + { + if (count == tkPos && pp[0] == '(' && pp[1] != ')') + fd.attributes = getList(pp, isList); + else if (isList) + { + fd.attributes += ' '; + fd.attributes += getList(pp, isList); + } + else + { + if (pp[strlen(pp) - 1] == '"') + pp[strlen(pp) - 1] = 0; + + const char *ptr = pp[0] == '"' ? &pp[1] : &pp[0]; + + if (!delimOk) + { + delimOk = true; + fd.delimiter = ptr; + } + else + { + if (fd.name.length() > 0) + fd.name += ' '; + fd.name += ptr; + } + } + } + pp = end; + } + + // release memory + freeMem(&p); + + imap->_folders.add(fd); + } +} + +bool ESP_Mail_Client::parseIdleResponse(IMAPSession *imap) +{ + + int chunkBufSize = 0; + + if (!reconnect(imap)) + return false; + + if (imap->client.connected()) + chunkBufSize = imap->client.available(); + else + return false; + + if (chunkBufSize > 0) + { + chunkBufSize = ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE; + + char *buf = allocMem(chunkBufSize + 1); + + int octetCount = 0; + + int readLen = 0; + + MB_String ovfBuf; + readResponse(imap, buf, chunkBufSize, readLen, false, octetCount, ovfBuf); + + // If buffer overflown, copy from overflow buffer + if (ovfBuf.length() > 0) + { + // release memory + freeMem(&buf); + buf = allocMem(ovfBuf.length() + 1); + strcpy(buf, ovfBuf.c_str()); + ovfBuf.clear(); + } + + if (readLen > 0) + { + + if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_basic) + esp_mail_debug_print((const char *)buf, true); + + char *tmp = nullptr; + int p1 = -1; + bool exists = false; + + tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_exists].text, 0); + if (tmp) + { + int numMsg = imap->_mbif._msgCount; + imap->_mbif._msgCount = atoi(tmp); + // release memory + freeMem(&tmp); + exists = true; + imap->_mbif._folderChanged |= (int)imap->_mbif._msgCount != numMsg; + if ((int)imap->_mbif._msgCount > numMsg) + { + imap->_mbif._polling_status.type = imap_polling_status_type_new_message; + imap->_mbif._polling_status.messageNum = imap->_mbif._msgCount; + } + goto ex; + } + + tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_expunge].text, 0); + if (tmp) + { + imap->_mbif._polling_status.type = imap_polling_status_type_remove_message; + imap->_mbif._polling_status.messageNum = atoi(tmp); + + if (imap->_mbif._polling_status.messageNum == imap->_mbif._msgCount && imap->_mbif._nextUID > 0) + imap->_mbif._nextUID--; + + // release memory + freeMem(&tmp); + imap->_mbif._folderChanged = true; + goto ex; + } + + tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_recent].text, 0); + if (tmp) + { + imap->_mbif._recentCount = atoi(tmp); + // release memory + freeMem(&tmp); + goto ex; + } + + tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_fetch].text, 0); + if (tmp) + { + imap->_mbif._polling_status.messageNum = atoi(tmp); + // release memory + freeMem(&tmp); + + imap->_mbif._polling_status.argument = buf; + imap->_mbif._polling_status.argument.erase(0, p1 + 8); + imap->_mbif._polling_status.argument.pop_back(); + imap->_mbif._folderChanged = true; + imap->_mbif._polling_status.type = imap_polling_status_type_fetch_message; + goto ex; + } + + ex: + + imap->_mbif._floderChangedState = (imap->_mbif._folderChanged && exists) || imap->_mbif._polling_status.type == imap_polling_status_type_fetch_message; + } + + // release memory + freeMem(&buf); + } + + size_t imap_idle_tmo = imap->_imap_data->limit.imap_idle_timeout; + + if (imap_idle_tmo < 60 * 1000 || imap_idle_tmo > 29 * 60 * 1000) + imap_idle_tmo = 10 * 60 * 1000; + + if (millis() - imap->_mbif._idleTimeMs > imap_idle_tmo) + { + if (imap->mStopListen(true)) + return imap->mListen(true); + return false; + } + + return true; +} + +void ESP_Mail_Client::appendFetchString(MB_String &buf, bool uid) +{ + if (uid) + buf += imap_cmd_post_tokens[esp_mail_imap_command_uid]; + else + joinStringSpace(buf, false, 2, imap_commands[esp_mail_imap_command_flags].text, esp_mail_str_38 /* "(" */); +} + +void ESP_Mail_Client::parseCmdResponse(IMAPSession *imap, char *buf, PGM_P find) +{ + if (imap->_imap_cmd == esp_mail_imap_cmd_get_uid) + imap->_uid_tmp = 0; + + char *tmp = nullptr; + int p1 = strposP(buf, find, 0); + if (p1 != -1) + { + if (imap->_imap_cmd == esp_mail_imap_cmd_get_quota_root || + imap->_imap_cmd == esp_mail_imap_cmd_get_acl || + imap->_imap_cmd == esp_mail_imap_cmd_my_rights) + { + int ofs = imap->_imap_cmd == esp_mail_imap_cmd_get_quota_root ? 0 : 1; + int p2 = strposP(buf, esp_mail_str_2 /* " " */, p1 + strlen_P(find) + ofs); + if (p2 != -1) + { + int len = strlen(buf) - p2 - 1; + tmp = allocMem(len); + strncpy(tmp, buf + p2 + 1, strlen(buf) - p2 - 1); + if (imap->_imap_cmd == esp_mail_imap_cmd_get_quota_root) + { + if (imap->_quota_root_tmp.length() > 0) + imap->_quota_root_tmp += esp_mail_str_8; /* ";" */ + imap->_quota_root_tmp += tmp; + } + else + { + imap->_acl_tmp = tmp; + } + + // release memory + freeMem(&tmp); + } + } + else + { + int len = imap->_imap_cmd == esp_mail_imap_cmd_get_uid ? 20 : strlen(buf) - p1 - strlen_P(find); + int ofs = imap->_imap_cmd == esp_mail_imap_cmd_get_uid || + imap->_imap_cmd == esp_mail_imap_cmd_fetch_sequence_set + ? 1 + : imap->_imap_cmd == esp_mail_imap_cmd_namespace || imap->_imap_cmd == esp_mail_imap_cmd_id ? 0 + : 2; + tmp = allocMem(len); + + strncpy(tmp, buf + p1 + strlen_P(find), strlen(buf) - p1 - strlen_P(find) - ofs); + + esp_mail_imap_msg_num_t msg_num; + + switch ((int)imap->_imap_cmd) + { + case esp_mail_imap_cmd_get_uid: + imap->_uid_tmp = atoi(tmp); + break; + case esp_mail_imap_cmd_get_flags: + imap->_flags_tmp = tmp; + break; + case esp_mail_imap_cmd_get_quota: + imap->_quota_tmp = tmp; + break; + case esp_mail_imap_cmd_id: + imap->_server_id_tmp = tmp; + break; + case esp_mail_imap_cmd_namespace: + imap->_ns_tmp += tmp; + break; + case esp_mail_imap_cmd_fetch_sequence_set: + + msg_num.type = esp_mail_imap_msg_num_type_uid; + msg_num.value = (uint32_t)atoi(tmp); + imap->_imap_msg_num.push_back(msg_num); + + if (imap->_imap_msg_num.size() > imap->_imap_data->limit.fetch) + imap->_imap_msg_num.erase(imap->_imap_msg_num.begin()); + + break; + default: + break; + } + } + + // release memory + freeMem(&tmp); + } +} + +bool ESP_Mail_Client::getFlags(IMAPSession *imap, char *buf, esp_mail_imap_response_types type) +{ + if (strposP(buf, imap_responses[type].text, 0) != -1) + { + char *p = allocMem(strlen(buf)); + strcpy(p, buf); + char *pp = p; + char *end = p; + int count = 0; + bool isList = false; + int tkPos = (type == esp_mail_imap_response_permanent_flags) ? 4 : 3; + + while (pp != NULL) + { + // See RFC2047.h + ESP_MAIL_STRSEP(&end, " "); + count++; + if (count >= tkPos && strlen(pp) > 0) + { + if (type == esp_mail_imap_response_permanent_flags && pp[strlen(pp) - 1] == ']') + pp[strlen(pp) - 1] = 0; + + if (count == tkPos && pp[0] == '(' && pp[1] != ')') + imap->_mbif.addFlag(getList(pp, isList), type == esp_mail_imap_response_permanent_flags); + else if (isList) + imap->_mbif.addFlag(getList(pp, isList), type == esp_mail_imap_response_permanent_flags); + } + pp = end; + } + + // release memory + freeMem(&p); + + return true; + } + + return false; +} + +void ESP_Mail_Client::parseExamineResponse(IMAPSession *imap, char *buf) +{ + char *tmp = NULL; + + tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_exists].text, 0); + if (tmp) + { + imap->_mbif._msgCount = atoi(tmp); + // release memory + freeMem(&tmp); + return; + } + + tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_recent].text, 0); + if (tmp) + { + imap->_mbif._recentCount = atoi(tmp); + // release memory + freeMem(&tmp); + return; + } + + if (imap->_mbif._flags.size() == 0 && getFlags(imap, buf, esp_mail_imap_response_flags)) + return; + + if (imap->_mbif._permanent_flags.size() == 0 && getFlags(imap, buf, esp_mail_imap_response_permanent_flags)) + return; + + if (imap->_mbif._uidValidity == 0) + { + tmp = subStr(buf, imap_responses[esp_mail_imap_response_uidvalidity].text, esp_mail_str_41 /* "]" */, 0, 0); + if (tmp) + { + imap->_mbif._uidValidity = atoi(tmp); + // release memory + freeMem(&tmp); + return; + } + } + + if (imap->_nextUID.length() == 0) + { + tmp = subStr(buf, imap_responses[esp_mail_imap_response_uidnext].text, esp_mail_str_41 /* "]" */, 0, 0); + if (tmp) + { + imap->_nextUID = tmp; + imap->_mbif._nextUID = atoi(tmp); + // release memory + freeMem(&tmp); + return; + } + } + + if (imap->_unseenMsgIndex.length() == 0) + { + tmp = subStr(buf, imap_responses[esp_mail_imap_response_unseen].text, esp_mail_str_41 /* "]" */, 0, 0); + if (tmp) + { + imap->_unseenMsgIndex = tmp; + imap->_mbif._unseenMsgIndex = atoi(tmp); + // release memory + freeMem(&tmp); + return; + } + } + + if (imap->isCondStoreSupported()) + { + tmp = subStr(buf, imap_responses[esp_mail_imap_response_highest_modsec].text, esp_mail_str_41 /* "]" */, 0, 0); + if (tmp) + { + imap->_mbif._highestModSeq = tmp; + // release memory + freeMem(&tmp); + return; + } + + tmp = subStr(buf, imap_responses[esp_mail_imap_response_nomodsec].text, nullptr, 0, 0); + if (tmp) + { + imap->_mbif._nomodsec = true; + // release memory + freeMem(&tmp); + return; + } + } +} + +bool ESP_Mail_Client::handleIMAPError(IMAPSession *imap, int err, bool ret) +{ + if (err < 0) + { + errorStatusCB(imap, nullptr, err, true); + + if (imap->_headers.size() > 0 && cHeader(imap)) + { + if ((imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) && (imap->_imap_data->download.attachment || imap->_imap_data->download.inlineImg)) + { + if (cPart(imap) && cHeader(imap)->part_headers.size() > 0) + cPart(imap)->download_error = imap->errorReason().c_str(); + } + else if (cHeader(imap)) + cHeader(imap)->error_msg = imap->errorReason().c_str(); + + cHeader(imap)->error = true; + } + } + + closeTCPSession(imap); + + imap->_cbData.empty(); + + return ret; +} + +void ESP_Mail_Client::prepareFileList(IMAPSession *imap, MB_String &filePath) +{ +#if defined(MBFS_SD_FS) + if (!mbfs->longNameSupported()) + { + cHeader(imap)->sd_alias_file_count++; + MB_String alias = cHeader(imap)->message_uid; + alias += esp_mail_str_83; /* "_" */ + alias += cHeader(imap)->sd_alias_file_count; + + if (imap->_sdFileList.length() > 0) + { + if (imap->_sdFileList[imap->_sdFileList.length() - 1] == ']') + { + imap->_sdFileList[imap->_sdFileList.length() - 1] = 0; + imap->_sdFileList += esp_mail_str_8; /* "," */ + } + } + imap->_sdFileList += esp_mail_str_80; /* "{\"Renamed\":\"" */ + imap->_sdFileList += alias; + imap->_sdFileList += esp_mail_str_81; /* "\",\"Original\":\"" */ + imap->_sdFileList += filePath; + imap->_sdFileList += esp_mail_str_82; /* "\"}]" */ + // rename the original file + filePath = alias; + } +#endif +} + +bool ESP_Mail_Client::parseAttachmentResponse(IMAPSession *imap, char *buf, esp_mail_imap_response_data &res) +{ + int bufLen = res.readLen; + + if (res.chunkIdx == 0) + { + char *tmp = subStr(buf, esp_mail_str_36 /* "{" */, esp_mail_str_37 /* "}" */, 0); + if (tmp) + { + res.chunkIdx++; + res.octetCount = 0; // CRLF counted from first line + res.octetLength = atoi(tmp); + // release memory + freeMem(&tmp); + cPart(imap)->octetLen = res.octetLength; + cPart(imap)->octetCount = 0; + cHeader(imap)->total_download_size += res.octetLength; + imap->_lastProgress = -1; + +#if defined(ESP_MAIL_OTA_UPDATE_ENABLED) + if (cPart(imap)->is_firmware_file) + { + cPart(imap)->is_firmware_file = Update.begin(cPart(imap)->attach_data_size); + + if (!cPart(imap)->is_firmware_file) + { + imap->_responseStatus.errorCode = IMAP_STATUS_FIRMWARE_UPDATE_INIT_FAILED; + imap->_responseStatus.text.clear(); + } + +#if !defined(SILENT_MODE) + + sendCallback(imap, esp_mail_cb_str_42 /* "Updating firmware..." */, true, false); + + if (!cPart(imap)->is_firmware_file) + { + printDebug(imap, + imap->errorReason().c_str(), + imap->errorReason().c_str(), + esp_mail_debug_tag_type_error, + true, + false); + } + +#endif + } +#endif + + if (!cPart(imap)->file_open_write) + { + + if (imap->_storageReady && cPart(imap)->save_to_file) + { + res.downloadRequest = true; + + res.filePath.clear(); + + res.filePath += imap->_imap_data->storage.saved_path; + res.filePath += esp_mail_str_10; /* "/" */ + res.filePath += cHeader(imap)->message_uid; + res.filePath += esp_mail_str_10; /* "/" */ + res.filePath += cPart(imap)->filename; + + prepareFileList(imap, res.filePath); + + int sz = mbfs->open(res.filePath, mbfs_type imap->_imap_data->storage.type, mb_fs_open_mode_write); + + if (sz < 0) + { + imap->_responseStatus.errorCode = sz; + imap->_responseStatus.text.clear(); +#if !defined(SILENT_MODE) + printDebug(imap, + imap->errorReason().c_str(), + imap->errorReason().c_str(), + esp_mail_debug_tag_type_error, + true, + false); +#endif + } + + cPart(imap)->file_open_write = true; + } + } + } + return true; + } + + yield_impl(); + + if (res.octetLength == 0) + return true; + + if (cPart(imap)->octetCount <= res.octetLength) + { + if (cPart(imap)->octetCount + bufLen > res.octetLength) + { + bufLen = res.octetLength - cPart(imap)->octetCount; + buf[bufLen] = 0; + cPart(imap)->octetCount += bufLen; + } + else + cPart(imap)->octetCount = res.octetCount; + + if (imap->_imap_data->enable.download_status) + { + if (imap->_debug) + downloadReport(imap, 100 * cPart(imap)->octetCount / res.octetLength); + } + + if (cPart(imap)->octetCount > res.octetLength) + return true; + + bool write_error = false, fw_write_error = false; + + if (cPart(imap)->xencoding == esp_mail_msg_xencoding_base64) + { + + size_t olen = 0; + unsigned char *decoded = decodeBase64((const unsigned char *)buf, bufLen, &olen); + + if (decoded) + { + + if (!cPart(imap)->sizeProp) + { + cPart(imap)->attach_data_size += olen; + cHeader(imap)->total_attach_data_size += cPart(imap)->attach_data_size; + } + + sendStreamCB(imap, (void *)decoded, olen, res.chunkIdx, false); + + size_t write = olen; + + if (cPart(imap)->is_firmware_file) + { +#if defined(ESP_MAIL_OTA_UPDATE_ENABLED) + size_t fw_write = Update.write((uint8_t *)decoded, olen); + cPart(imap)->firmware_downloaded_byte += fw_write == olen ? olen : 0; + fw_write_error = fw_write != olen; +#endif + } + + if (cPart(imap)->save_to_file) + { + if (mbfs->ready(mbfs_type imap->_imap_data->storage.type)) + write = mbfs->write(mbfs_type imap->_imap_data->storage.type, (uint8_t *)decoded, olen); + } + + yield_impl(); + // release memory + freeMem(&decoded); + + write_error = write != olen; + } + + if (!reconnect(imap)) + return false; + } + else + { + // binary content + if (!cPart(imap)->sizeProp) + { + cPart(imap)->attach_data_size += bufLen; + cHeader(imap)->total_attach_data_size += cPart(imap)->attach_data_size; + } + + sendStreamCB(imap, (void *)buf, bufLen, res.chunkIdx, false); + + int write = bufLen; + + if (cPart(imap)->is_firmware_file) + { +#if defined(ESP_MAIL_OTA_UPDATE_ENABLED) + int fw_write = Update.write((uint8_t *)buf, bufLen); + cPart(imap)->firmware_downloaded_byte += fw_write == bufLen ? (size_t)bufLen : 0; + fw_write_error = fw_write != bufLen; +#endif + } + + if (cPart(imap)->save_to_file) + { + if (mbfs->ready(mbfs_type imap->_imap_data->storage.type)) + write = mbfs->write(mbfs_type imap->_imap_data->storage.type, (uint8_t *)buf, bufLen); + } + + yield_impl(); + + write_error = write != bufLen; + + if (!reconnect(imap)) + return false; + } + +#if defined(ESP_MAIL_OTA_UPDATE_ENABLED) + if (cPart(imap)->is_firmware_file) + { + bool update_result_ok = !fw_write_error; + + if (!imap->_isFirmwareUpdated && update_result_ok && + (cPart(imap)->firmware_downloaded_byte == (size_t)cPart(imap)->attach_data_size || cPart(imap)->octetCount >= res.octetLength)) + { + update_result_ok = Update.end(cPart(imap)->octetCount >= res.octetLength); + if (update_result_ok) + imap->_isFirmwareUpdated = true; + } + + if (!update_result_ok) + { + cPart(imap)->is_firmware_file = false; + + imap->_responseStatus.errorCode = fw_write_error ? IMAP_STATUS_FIRMWARE_UPDATE_WRITE_FAILED : IMAP_STATUS_FIRMWARE_UPDATE_END_FAILED; + imap->_responseStatus.text.clear(); + +#if !defined(SILENT_MODE) + printDebug(imap, + imap->_responseStatus.text.c_str(), + imap->errorReason().c_str(), + esp_mail_debug_tag_type_error, + !imap->_debug, + false); +#endif + } + } +#endif + + if (write_error || fw_write_error) + return false; + } + + res.chunkIdx++; + return true; +} + +void ESP_Mail_Client::downloadReport(IMAPSession *imap, int progress) +{ + printProgress(progress, imap->_lastProgress); +} + +void ESP_Mail_Client::fetchReport(IMAPSession *imap, int progress, bool download) +{ +#if !defined(SILENT_MODE) + if (imap->_debug && imap->_lastProgress == -1 && strcmp_P(cPart(imap)->filename.c_str(), esp_mail_str_84 /* "message" */) != 0) + esp_mail_debug_print_tag(cPart(imap)->filename.c_str(), esp_mail_debug_tag_type_client, true); + printProgress(progress, imap->_lastProgress); +#endif +} + +void ESP_Mail_Client::searchReport(IMAPSession *imap, int progress) +{ + printProgress(progress, imap->_lastProgress); +} + +struct esp_mail_imap_msg_num_t ESP_Mail_Client::cMSG(IMAPSession *imap) +{ + return imap->_imap_msg_num[cIdx(imap)]; +} + +int ESP_Mail_Client::cIdx(IMAPSession *imap) +{ + return imap->_cMsgIdx; +} + +void ESP_Mail_Client::decodeText(IMAPSession *imap, esp_mail_imap_response_data &res) +{ + int bufLen = res.readLen; + bool rfc822_body_subtype = cPart(imap)->message_sub_type == esp_mail_imap_message_sub_type_rfc822; + if (res.chunkIdx == 0) + { + + imap->_lastProgress = -1; + char *tmp = subStr(res.response, esp_mail_str_36 /* "{" */, esp_mail_str_37 /* "}" */, 0); + if (tmp) + { + res.chunkIdx++; + res.octetCount = 0; + res.octetLength = atoi(tmp); + // release memory + freeMem(&tmp); + cPart(imap)->octetLen = res.octetLength; + cPart(imap)->octetCount = 0; + + bool dlMsg = (rfc822_body_subtype && imap->_imap_data->download.rfc822) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->download.text))); + if (dlMsg) + prepareFilePath(imap, res.filePath, false); + + if (res.filePath.length() == 0) + { + if (!rfc822_body_subtype) + res.filePath += esp_mail_str_84; /* "message" */ + else + joinStringSpace(res.filePath, false, 2, esp_mail_str_85 /* "rfc822" */, esp_mail_str_84 /* "message" */); + } + cPart(imap)->filename = res.filePath; + + if (imap->_storageReady && !cPart(imap)->file_open_write && dlMsg) + { + + prepareFileList(imap, res.filePath); + + int sz = mbfs->open(res.filePath, mbfs_type imap->_imap_data->storage.type, mb_fs_open_mode_write); + if (sz > -1) + { + res.downloadRequest = true; + cPart(imap)->file_open_write = true; + } + else + { + imap->_responseStatus.errorCode = sz; + imap->_responseStatus.text.clear(); +#if !defined(SILENT_MODE) + if (imap->_debug) + esp_mail_debug_print_tag(imap->errorReason().c_str(), esp_mail_debug_tag_type_error, true); +#endif + } + } + + return; + } + else + { +#if !defined(SILENT_MODE) + if (imap->_debug) + esp_mail_debug_print_tag(esp_mail_error_imap_str_12 /* "no centent" */, esp_mail_debug_tag_type_client, false); +#endif + } + } + + yield_impl(); + + if (res.octetLength == 0) + return; + + bool enableDownloads = (imap->_imap_data->download.rfc822 && rfc822_body_subtype) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->download.text))); + + if (imap->_imap_data->download.rfc822 || imap->_imap_data->download.html || imap->_imap_data->download.text || (rfc822_body_subtype && imap->_imap_data->enable.rfc822) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->enable.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->enable.text)))) + { + + if (cPart(imap)->octetCount + bufLen >= res.octetLength) + { + bufLen = res.octetLength - cPart(imap)->octetCount; + cPart(imap)->octetCount += bufLen; + + if (res.octetLength <= res.octetCount && cPart(imap)->xencoding != esp_mail_msg_xencoding_base64 && cPart(imap)->xencoding != esp_mail_msg_xencoding_qp) + bufLen = 0; + + res.response[bufLen] = 0; + } + else + cPart(imap)->octetCount = res.octetCount; + + if (imap->_debug) + fetchReport(imap, 100 * cPart(imap)->octetCount / res.octetLength, enableDownloads); + + if (cPart(imap)->octetCount <= res.octetLength) + { + bool hrdBrk = cPart(imap)->xencoding == esp_mail_msg_xencoding_qp; + hrdBrk &= cPart(imap)->octetCount < res.octetLength; + hrdBrk &= bufLen == 2 && res.response[bufLen - 2] != '\r' && res.response[bufLen - 1] != '\n'; + + // remove soft break for QP + if (bufLen <= QP_ENC_MSG_LEN && res.response[bufLen - 1] == '=' && cPart(imap)->xencoding == esp_mail_msg_xencoding_qp) + { + hrdBrk = false; + res.response[bufLen - 1] = 0; + bufLen--; + } + + size_t olen = 0; + char *decoded = nullptr; + MB_String str; + bool dontDeleteOrModify = false; + + // decode the content based on the transfer decoding + if (cPart(imap)->xencoding == esp_mail_msg_xencoding_base64) + { + decoded = (char *)decodeBase64((const unsigned char *)res.response, bufLen, &olen); + } + else if (cPart(imap)->xencoding == esp_mail_msg_xencoding_qp) + { + decoded = allocMem(bufLen + 10); + decodeQP_UTF8(res.response, decoded); + olen = strlen(decoded); + } + else if (cPart(imap)->xencoding == esp_mail_msg_xencoding_7bit) + { + decoded = decode7Bit_UTF8(res.response); + olen = strlen(decoded); + } + else if (cPart(imap)->xencoding == esp_mail_msg_xencoding_8bit) + { + decoded = decode8Bit_UTF8(res.response); + olen = strlen(decoded); + } + else + { + // binary + dontDeleteOrModify = true; + decoded = res.response; + olen = bufLen; + } + + if (decoded) + { + // charset? apply character decoding to the decoded or nonencoded content + if ((rfc822_body_subtype && imap->_imap_data->enable.rfc822) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->enable.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->enable.text)))) + { + if (imap->_charDecCallback) + { + IMAP_Decoding_Info decoding; + decoding.charset = cPart(imap)->charset.c_str(); + decoding.data = decoded; + decoding.type = IMAP_Decoding_Info::message_part_type_text; + + imap->_charDecCallback(&decoding); + + if (decoding.decodedString.length() > 0) + { + char *buf2 = allocMem(decoding.decodedString.length() + 1); + strcpy(buf2, decoding.decodedString.c_str()); + + if (decoded && !dontDeleteOrModify) + // release memory + freeMem(&decoded); + + decoded = buf2; + olen = strlen(buf2); + } + } + else + { + esp_mail_char_decoding_scheme scheme = getEncodingFromCharset(cPart(imap)->charset.c_str()); + + if (scheme == esp_mail_char_decoding_scheme_iso8859_1) + { + int ilen = olen; + int olen2 = (ilen + 1) * 2; + unsigned char *tmp = allocMem(olen2); + decodeLatin1_UTF8(tmp, &olen2, (unsigned char *)decoded, &ilen); + + if (decoded && !dontDeleteOrModify) + // release memory + freeMem(&decoded); + + olen = olen2; + decoded = (char *)tmp; + } + else if (scheme == esp_mail_char_decoding_scheme_tis_620 || scheme == esp_mail_char_decoding_scheme_iso8859_11 || scheme == esp_mail_char_decoding_scheme_windows_874) + { + char *out = allocMem((olen + 1) * 3); + decodeTIS620_UTF8(out, decoded, olen); + olen = strlen(out); + if (decoded && !dontDeleteOrModify) + // release memory + freeMem(&decoded); + decoded = out; + } + } + + if (cPart(imap)->text.length() < imap->_imap_data->limit.msg_size) + { + + if (cPart(imap)->text.length() + olen < imap->_imap_data->limit.msg_size) + { + cPart(imap)->textLen += olen; + cPart(imap)->text.append(decoded, olen); + if (hrdBrk) + { + appendNewline(cPart(imap)->text); + cPart(imap)->textLen += 2; + } + } + else + { + int d = imap->_imap_data->limit.msg_size - cPart(imap)->text.length(); + cPart(imap)->textLen += d; + if (d > 0) + cPart(imap)->text.append(decoded, d); + + if (hrdBrk) + { + appendNewline(cPart(imap)->text); + cPart(imap)->textLen += 2; + } + } + } + } + + if (res.filePath.length() > 0 && res.downloadRequest) + { + if (mbfs->ready(mbfs_type imap->_imap_data->storage.type)) + { + if (olen > 0) + mbfs->write(mbfs_type imap->_imap_data->storage.type, (uint8_t *)decoded, olen); + if (hrdBrk) + mbfs->write(mbfs_type imap->_imap_data->storage.type, (uint8_t *)"\r\n", 2); + } + } + + sendStreamCB(imap, (void *)decoded, olen, res.chunkIdx, hrdBrk); + + if (decoded && !dontDeleteOrModify) + // release memory + freeMem(&decoded); + } + } + } + + res.chunkIdx++; +} + +void ESP_Mail_Client::sendStreamCB(IMAPSession *imap, void *buf, size_t len, int chunkIndex, bool hrdBrk) +{ + if (imap->_mimeDataStreamCallback && len > 0) + { + MIME_Data_Stream_Info streaminfo; + streaminfo.uid = cHeader(imap)->message_uid; + streaminfo.disposition = cPart(imap)->content_disposition.c_str(); + streaminfo.type = cPart(imap)->content_type.c_str(); + streaminfo.charSet = cPart(imap)->charset.c_str(); + streaminfo.transfer_encoding = cPart(imap)->content_transfer_encoding.c_str(); + streaminfo.cid = cPart(imap)->CID.c_str(); + streaminfo.description = cPart(imap)->content_description.c_str(); + streaminfo.date = cPart(imap)->creation_date.c_str(); + streaminfo.filename = cPart(imap)->filename.c_str(); + streaminfo.size = (cPart(imap)->sizeProp) ? cPart(imap)->attach_data_size : cPart(imap)->octetLen; + streaminfo.name = cPart(imap)->name.c_str(); + streaminfo.octet_size = cPart(imap)->octetLen; + streaminfo.octet_count = cPart(imap)->octetCount; + streaminfo.isFirstData = chunkIndex == 1; + streaminfo.isLastData = !hrdBrk ? cPart(imap)->octetLen == cPart(imap)->octetCount : false; + streaminfo.data_size = len; + streaminfo.data = buf; + streaminfo.flowed = cPart(imap)->plain_flowed; + streaminfo.delsp = cPart(imap)->plain_delsp; + + imap->_mimeDataStreamCallback(streaminfo); + + if (hrdBrk) + { + streaminfo.isFirstData = false; + streaminfo.isLastData = cPart(imap)->octetLen == cPart(imap)->octetCount; + streaminfo.data_size = 2; + streaminfo.data = (void *)"\r\n"; + imap->_mimeDataStreamCallback(streaminfo); + } + } +} + +void ESP_Mail_Client::prepareFilePath(IMAPSession *imap, MB_String &filePath, bool header) +{ + bool rfc822_body_subtype = cPart(imap)->message_sub_type == esp_mail_imap_message_sub_type_rfc822; + MB_String fpath = imap->_imap_data->storage.saved_path; + fpath += esp_mail_str_10; /* "/" */ + fpath += cHeader(imap)->message_uid; + + if (!header) + { + if (!rfc822_body_subtype) + { + fpath += esp_mail_str_86; /* "/msg" */ + if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) + fpath += mimeinfo[esp_mail_file_extension_txt].endsWith; + else if (cPart(imap)->msg_type == esp_mail_msg_type_html) + fpath += mimeinfo[esp_mail_file_extension_htm].endsWith; + } + else + { + fpath += esp_mail_str_87; /* "/rfc822_msg" */ + + if (cPart(imap)->rfc822_msg_Idx > 0) + fpath += cPart(imap)->rfc822_msg_Idx; + + if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) + fpath += mimeinfo[esp_mail_file_extension_txt].endsWith; + else if (cPart(imap)->msg_type == esp_mail_msg_type_html) + fpath += mimeinfo[esp_mail_file_extension_htm].endsWith; + else + // possible rfc822 encapsulated message which cannot fetch its header + fpath += mimeinfo[esp_mail_file_extension_dat].endsWith; + } + } + + filePath = fpath; +} + +void ESP_Mail_Client::sendStorageNotReadyError(IMAPSession *imap, esp_mail_file_storage_type storageType) +{ + +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) +#if !defined(SILENT_MODE) + if (imap->_debug && (storageType == esp_mail_file_storage_type_flash || storageType == esp_mail_file_storage_type_sd)) + { + if (storageType == esp_mail_file_storage_type_flash) + { + esp_mail_debug_print_tag(esp_mail_error_mem_str_1 /* "flash Storage is not ready." */, esp_mail_debug_tag_type_error, true); +#if defined(MB_ARDUINO_PICO) + esp_mail_debug_print_tag(esp_mail_error_mem_str_10 /* "please make sure that the size of flash filesystem is not 0 in Pico." */, esp_mail_debug_tag_type_error, true); +#endif + } + else if (storageType == esp_mail_file_storage_type_sd) + esp_mail_debug_print_tag(esp_mail_error_mem_str_2 /* "SD Storage is not ready." */, esp_mail_debug_tag_type_error, true); + } +#endif +#endif +} + +IMAPSession::IMAPSession(Client *client) +{ + setClient(client); +} + +IMAPSession::IMAPSession() +{ +} + +IMAPSession::~IMAPSession() +{ + empty(); +} + +bool IMAPSession::closeSession() +{ + _prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + _prev_imap_custom_cmd = esp_mail_imap_cmd_custom; + + if (!connected()) + return false; + + if (_mbif._idleTimeMs > 0) + mStopListen(false); + + if (_loginStatus) + { +#if !defined(ESP8266) + /** + * The strange behavior in ESP8266 SSL client, BearSSLWiFiClientSecure + * The client disposed without memory released after the server close + * the connection due to LOGOUT command, which caused the memory leaks. + */ + if (!MailClient.imapLogout(this)) + return false; +#endif + } + + return MailClient.handleIMAPError(this, 0, true); +} + +bool IMAPSession::connected() +{ + return client.connected(); +} + +bool IMAPSession::connect(Session_Config *session_config, IMAP_Data *imap_data, bool login) +{ + _sessionSSL = false; + _sessionLogin = login; + + if (session_config) + session_config->clearPorts(); + + this->_customCmdResCallback = NULL; + + int ptr = toAddr(*session_config); + session_config->addPtr(&_configPtrList, ptr); + + if (!handleConnection(session_config, imap_data, _sessionSSL)) + return false; + + if (!_sessionLogin) + return true; + + _loginStatus = MailClient.imapAuth(this, _sessionSSL); + + return _loginStatus; +} + +bool IMAPSession::mLogin(MB_StringPtr email, MB_StringPtr password, bool isToken) +{ + if (_loginStatus) + return true; + + if (!MailClient.sessionExisted(this)) + return false; + + _session_cfg->login.email = email; + + _session_cfg->login.accessToken.clear(); + _session_cfg->login.password.clear(); + + if (isToken) + _session_cfg->login.accessToken = password; + else + _session_cfg->login.password = password; + + _loginStatus = MailClient.imapAuth(this, _sessionSSL); + + return _loginStatus; +} + +void IMAPSession::appendIdList(MB_String &list, IMAP_Identification *identification) +{ + + if (identification->name.length() > 0 && identification->name.length() <= 1024) + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_name].text, identification->name.c_str()); + + if (identification->version.length() > 0 && identification->version.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_version].text, identification->version.c_str()); + } + + if (identification->os.length() > 0 && identification->os.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_os].text, identification->os.c_str()); + } + + if (identification->vendor.length() > 0 && identification->vendor.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_vendor].text, identification->vendor.c_str()); + } + + if (identification->support_url.length() > 0 && identification->support_url.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_support_url].text, identification->support_url.c_str()); + } + + if (identification->address.length() > 0 && identification->address.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_address].text, identification->address.c_str()); + } + + if (identification->date.length() > 0 && identification->date.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_date].text, identification->date.c_str()); + } + + if (identification->command.length() > 0 && identification->command.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_command].text, identification->command.c_str()); + } + + if (identification->arguments.length() > 0 && identification->arguments.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_arguments].text, identification->arguments.c_str()); + } + + if (identification->environment.length() > 0 && identification->environment.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_environment].text, identification->environment.c_str()); + } +} + +bool IMAPSession::id(IMAP_Identification *identification) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_61 /* "Send client identification..." */, + esp_mail_dbg_str_82 /* "send IMAP command, ID" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + if (!_feature_capability[esp_mail_imap_read_capability_id]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + return false; + } + + if (!MailClient.reconnect(this)) + return false; + + MB_String cmd, idList; + + appendIdList(idList, identification); + + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_id].text); + + if (idList.length() > 0) + MailClient.appendString(cmd, idList.c_str(), false, false, esp_mail_string_mark_type_round_bracket); + else + { + int bufLen = 50; + char *buf = MailClient.allocMem(bufLen); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_21 /* "(\"name\" \"ESP Mail Client\" \"version\" \"%s\")" */), ESP_MAIL_VERSION); + cmd += buf; + // release memory + MailClient.freeMem(&buf); + } + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_id; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +String IMAPSession::serverID() +{ + return _server_id_tmp.c_str(); +} + +bool IMAPSession::isAuthenticated() +{ + return _authenticated; +} + +bool IMAPSession::isLoggedIn() +{ + return _loginStatus; +} + +bool IMAPSession::isFirmwareUpdateSuccess() +{ + return _isFirmwareUpdated; +} + +bool IMAPSession::mCustomConnect(Session_Config *session_config, imapResponseCallback callback, MB_StringPtr tag) +{ + this->_customCmdResCallback = callback; + this->_responseStatus.tag = tag; + + bool ssl = false; + if (!handleConnection(session_config, NULL, ssl)) + return false; + + return true; +} + +bool IMAPSession::handleConnection(Session_Config *session_config, IMAP_Data *imap_data, bool &ssl) +{ + + _session_cfg = session_config; + + if (!client.isInitialized()) + return MailClient.handleIMAPError(this, TCP_CLIENT_ERROR_NOT_INITIALIZED, false); + + // Resources are also released if network disconnected. + if (!MailClient.reconnect(this)) + return false; + + // Need to close previous connection first to free resources. + MailClient.closeTCPSession(this); + + _session_cfg = session_config; + _imap_data = imap_data; + + MailClient.setCert(_session_cfg, _session_cfg->certificate.cert_data); + + ssl = false; + if (!connect(ssl)) + { + MailClient.closeTCPSession(this); + return false; + } + + return true; +} + +bool IMAPSession::connect(bool &ssl) +{ + ssl = false; + MB_String buf; + + if (_imap_data) + { + if (_imap_data->fetch.sequence_set.string.length() > 0 || _imap_data->fetch.uid.length() > 0 || _imap_data->fetch.number.length() > 0) + _headerOnly = false; + else + _headerOnly = true; + } + + _totalRead = 0; + _secure = true; + bool secureMode = true; + + client.txBufDivider = 16; // minimum, tx buffer size for ssl data and request command data + client.rxBufDivider = 1; + if (_imap_data) + { + if (!_headerOnly && !_imap_data->firmware_update.attach_filename.length() == 0 && !_imap_data->enable.html && !_imap_data->enable.text && !_imap_data->download.attachment && !_imap_data->download.inlineImg && !_imap_data->download.html && !_imap_data->download.text) + client.rxBufDivider = 16; // minimum rx buffer size for only message header + } + + MailClient.preparePortFunction(_session_cfg, false, _secure, secureMode, ssl); + +#if !defined(SILENT_MODE) + MailClient.printLibInfo(this); +#endif + + MailClient.prepareTime(_session_cfg, this); + + MailClient.setSecure(client, _session_cfg); + + if (!MailClient.beginConnection(_session_cfg, this, secureMode)) + return false; + + // server connected + + client.setTimeout(tcpTimeout); + + // wait for greeting + unsigned long dataMs = millis(); + while (client.connected() && client.available() == 0 && millis() - dataMs < 2000) + { + yield_impl(); + } + + int chunkBufSize = client.available(); + + if (chunkBufSize > 0) + { + char *buf = MailClient.allocMem(chunkBufSize + 1); + client.readBytes(buf, chunkBufSize); + if (_debug && _debugLevel > esp_mail_debug_level_basic && !_customCmdResCallback) + esp_mail_debug_print((const char *)buf, true); + + if (_customCmdResCallback) + { + MailClient.imapResponseStatus(this, buf, esp_mail_str_3 /* "*" */); + _responseStatus.text = buf; + + if (_responseStatus.text[_responseStatus.text.length() - 2] == '\r' && _responseStatus.text[_responseStatus.text.length() - 1] == '\n') + _responseStatus.text[_responseStatus.text.length() - 2] = 0; + + if (_responseStatus.tag.length() == 0) + this->_responseStatus.tag = esp_mail_imap_tag_str; + + _customCmdResCallback(_responseStatus); + } + + // release memory + MailClient.freeMem(&buf); + } + + if (!_customCmdResCallback) + { +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_48 /* "IMAP server connected" */, + esp_mail_dbg_str_33 /* "IMAP server connected" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + } + + return true; +} + +void IMAPSession::debug(int level) +{ + if (level > esp_mail_debug_level_none) + { + if (level > esp_mail_debug_level_basic && level < esp_mail_debug_level_maintainer) + level = esp_mail_debug_level_basic; + _debugLevel = level; + _debug = true; + client.setDebugLevel(level); + } + else + { + _debugLevel = esp_mail_debug_level_none; + _debug = false; + client.setDebugLevel(0); + } +} + +String IMAPSession::errorReason() +{ + return MailClient.errorReason(false, _responseStatus.errorCode, _responseStatus.text.c_str()); +} + +int IMAPSession::errorCode() +{ + return _responseStatus.errorCode; +} + +bool IMAPSession::mSelectFolder(MB_StringPtr folderName, bool readOnly) +{ + if (connected()) + { + if (!openFolder(folderName, readOnly)) + return false; + } + else + { + _currentFolder = folderName; + } + + if (!connected()) + { + _responseStatus.errorCode = IMAP_STATUS_OPEN_MAILBOX_FAILED; + _responseStatus.clear(); + } + + return connected(); +} + +void IMAPSession::setTCPTimeout(unsigned long timeoutSec) +{ + tcpTimeout = timeoutSec; +} + +void IMAPSession::setClient(Client *client) +{ + this->client.setClient(client); +} + +void IMAPSession::setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password) +{ + this->client.setGSMClient(client, modem, pin, apn, user, password); +} + +void IMAPSession::networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB) +{ + this->client.networkConnectionRequestCallback(networkConnectionCB); +} + +void IMAPSession::networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB) +{ + this->client.networkStatusRequestCallback(networkStatusCB); +} + +void IMAPSession::setNetworkStatus(bool status) +{ + this->client.setNetworkStatus(status); + MailClient.networkStatus = status; +} + +void IMAPSession::setSSLBufferSize(int rx, int tx) +{ + this->client.setIOBufferSize(rx, tx); +} + +bool IMAPSession::mOpenFolder(MB_StringPtr folderName, bool readOnly) +{ + if (!connected()) + { + _responseStatus.errorCode = IMAP_STATUS_OPEN_MAILBOX_FAILED; + _responseStatus.clear(); + return false; + } + + if (readOnly) + return openMailbox(folderName, esp_mail_imap_auth_mode::esp_mail_imap_mode_examine, true, false); + else + return openMailbox(folderName, esp_mail_imap_auth_mode::esp_mail_imap_mode_select, true, false); +} + +bool IMAPSession::getFolders(FoldersCollection &folders) +{ + if (!connected()) + return false; + return getMailboxes(folders); +} + +bool IMAPSession::mCloseFolder(bool expunge) +{ + + // no folder opened + if (_currentFolder.length() == 0) + { +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_error_imap_str_11 /* "no mailbox opened" */, + esp_mail_error_imap_str_11 /* "no mailbox opened" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + return false; + } + + return closeMailbox(expunge); +} + +bool IMAPSession::mListen(bool recon) +{ + if (!MailClient.sessionExisted(this)) + return false; + + if (_currentFolder.length() == 0) + { + _mbif._floderChangedState = false; + _mbif._folderChanged = false; + return false; + } + + if (!MailClient.reconnect(this)) + return false; + + if (!connected()) + { + if (!_imap_data || (millis() - _last_server_connect_ms < 2000 && _last_server_connect_ms > 0)) + return false; + + _last_server_connect_ms = millis(); + + bool ssl = false; + + if (!connect(ssl)) + { + MailClient.closeTCPSession(this); + return false; + } + + // re-authenticate after session closed + if (!MailClient.imapAuth(this, ssl)) + { + MailClient.closeTCPSession(this); + return false; + } + + // re-open folder + if (!selectFolder(_currentFolder.c_str())) + return false; + } + + // no IDLE was not supported (should be checked after imapAuth) + if (!_feature_capability[esp_mail_imap_read_capability_idle]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + } + + if (_mbif._idleTimeMs == 0) + { + _mbif._polling_status.messageNum = 0; + _mbif._polling_status.type = imap_polling_status_type_undefined; + _mbif._polling_status.argument.clear(); + _mbif._recentCount = 0; + _mbif._folderChanged = false; + +#if !defined(SILENT_MODE) + MB_String dbMsg; + + if (!recon) + { + + dbMsg = esp_mail_dbg_str_51; /* "listening to " */ + dbMsg += _currentFolder; + dbMsg += esp_mail_dbg_str_52; /* " folder changes" */ + MailClient.printDebug(this, + esp_mail_cb_str_29 /* "Listening to mailbox changes..." */, + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); + } + +#endif + + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_idle].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_idle; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + +#if !defined(SILENT_MODE) + if (!recon) + { + + dbMsg = esp_mail_str_88 /* "polling established on " */; + dbMsg += MailClient.Time.getDateTimeString(MailClient.Time.getCurrentTimestamp(), "%B %d, %Y %H:%M:%S"); + MailClient.printDebug(this, + esp_mail_cb_str_49 /* "Polling established" */, + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); + } + +#endif + + _mbif._idleTimeMs = millis(); + } + else + { + if (_mbif._floderChangedState) + { + _mbif._floderChangedState = false; + _mbif._folderChanged = false; + _mbif._polling_status.messageNum = 0; + _mbif._polling_status.type = imap_polling_status_type_undefined; + _mbif._polling_status.argument.clear(); + _mbif._recentCount = 0; + } + + size_t imap_idle_tmo = _imap_data->limit.imap_idle_timeout; + + if (imap_idle_tmo < 60 * 1000 || imap_idle_tmo > 29 * 60 * 1000) + imap_idle_tmo = 10 * 60 * 1000; + + size_t host_check_interval = _imap_data->limit.imap_idle_host_check_interval; + + if (host_check_interval < 30 * 1000 || host_check_interval > imap_idle_tmo) + host_check_interval = 60 * 1000; + + if (millis() - _last_host_check_ms > host_check_interval && connected()) + { + _last_host_check_ms = millis(); + + IPAddress ip; + + if (client.hostByName(_session_cfg->server.host_name.c_str(), ip) != 1) + { + closeSession(); + _mbif._idleTimeMs = millis(); + return false; + } + } + + return MailClient.parseIdleResponse(this); + } + + return true; +} + +bool IMAPSession::mStopListen(bool recon) +{ + _mbif._idleTimeMs = 0; + _mbif._floderChangedState = false; + _mbif._folderChanged = false; + _mbif._polling_status.messageNum = 0; + _mbif._polling_status.type = imap_polling_status_type_undefined; + _mbif._polling_status.argument.clear(); + _mbif._recentCount = 0; + + if (!connected() || _currentFolder.length() == 0 || !_feature_capability[esp_mail_imap_read_capability_idle]) + return false; + + if (MailClient.imapSend(this, imap_commands[esp_mail_imap_command_done].text, true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_done; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + +#if !defined(SILENT_MODE) + if (!recon) + { + MailClient.printDebug(this, + esp_mail_cb_str_50 /* "Mailbox listening stopped" */, + esp_mail_dbg_str_54 /* "Mailbox listening stopped" */, + esp_mail_debug_tag_type_client, + true, + false); + } +#endif + + return true; +} + +bool IMAPSession::folderChanged() +{ + return _mbif._floderChangedState; +} + +bool IMAPSession::noop() +{ + +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_62 /* "Sending noop..." */, + esp_mail_dbg_str_83 /* "send IMAP command, NOOP" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_noop].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_noop; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +void IMAPSession::checkUID() +{ + if (MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_uid].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_flags].text) || + MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_body].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_peek].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_text].text) || + MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_header].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_fields].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, esp_mail_str_40 /* "[" */) || + MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, esp_mail_str_41 /* "]" */) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_mime].text)) + _imap_data->fetch.uid = esp_mail_str_3; /* "*" */ +} + +void IMAPSession::checkPath() +{ + MB_String path = _imap_data->storage.saved_path; + if (path[0] != '/') + { + path = '/'; + path += _imap_data->storage.saved_path; + path = path.c_str(); + } +} + +bool IMAPSession::headerOnly() +{ + return _headerOnly; +} + +struct esp_mail_imap_msg_list_t IMAPSession::data() +{ + struct esp_mail_imap_msg_list_t ret; + + for (size_t i = 0; i < _headers.size(); i++) + { + +#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) + if (MailClient.getFreeHeap() < ESP_MAIL_MIN_MEM) + continue; +#endif + struct esp_mail_imap_msg_item_t itm; + itm.setRFC822Headers(&_headers[i].header_fields); + itm.UID = _headers[i].message_uid; + itm.msgNo = _headers[i].message_no; + itm.flags = _headers[i].flags.c_str(); + itm.acceptLang = _headers[i].accept_language.c_str(); + itm.contentLang = _headers[i].content_language.c_str(); + itm.hasAttachment = _headers[i].hasAttachment; + itm.fetchError = _headers[i].error_msg.c_str(); + + getMessages(i, itm); + + getRFC822Messages(i, itm); + + ret.msgItems.push_back(itm); + } + + return ret; +} + +SelectedFolderInfo IMAPSession::selectedFolder() +{ + return _mbif; +} + +void IMAPSession::callback(imapStatusCallback imapCallback) +{ + _statusCallback = imapCallback; +} + +void IMAPSession::characterDecodingCallback(imapCharacterDecodingCallback callback) +{ + _charDecCallback = callback; +} + +void IMAPSession::mimeDataStreamCallback(MIMEDataStreamCallback mimeDataStreamCallback) +{ + _mimeDataStreamCallback = mimeDataStreamCallback; +} + +void IMAPSession::setSystemTime(time_t ts, float gmtOffset) +{ + MailClient.Time.setTimestamp(ts, gmtOffset); +} + +void IMAPSession::keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount) +{ + this->client.keepAlive(tcpKeepIdleSeconds, tcpKeepIntervalSeconds, tcpKeepCount); +} + +bool IMAPSession::isKeepAlive() +{ + return this->client.isKeepAlive(); +} + +void IMAPSession::getMessages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg) +{ + msg.text.content = ""; + msg.text.charSet = ""; + msg.text.content_type = ""; + msg.text.transfer_encoding = ""; + msg.html.content = ""; + msg.html.charSet = ""; + msg.html.content_type = ""; + msg.html.transfer_encoding = ""; + + if (messageIndex < _headers.size()) + { + int sz = _headers[messageIndex].part_headers.size(); + if (sz > 0) + { + for (int i = 0; i < sz; i++) + { + if (_headers[messageIndex].part_headers[i].attach_type == esp_mail_att_type_attachment || (!_headers[messageIndex].part_headers[i].rfc822_part && _headers[messageIndex].part_headers[i].message_sub_type != esp_mail_imap_message_sub_type_rfc822)) + { + if (_headers[messageIndex].part_headers[i].attach_type == esp_mail_att_type_none) + { + if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_plain || _headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_enriched) + { + msg.text.content = _headers[messageIndex].part_headers[i].text.c_str(); + msg.text.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); + msg.text.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); + msg.text.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); + } + + if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_html) + { + msg.html.content = _headers[messageIndex].part_headers[i].text.c_str(); + msg.html.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); + msg.html.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); + msg.html.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); + } + } + else + { + struct esp_mail_attachment_info_t att; + att.filename = _headers[messageIndex].part_headers[i].filename.c_str(); + att.mime = _headers[messageIndex].part_headers[i].content_type.c_str(); + att.name = _headers[messageIndex].part_headers[i].name.c_str(); + att.size = _headers[messageIndex].part_headers[i].attach_data_size; + att.description = _headers[messageIndex].part_headers[i].content_description.c_str(); + att.creationDate = _headers[messageIndex].part_headers[i].creation_date.c_str(); + att.type = _headers[messageIndex].part_headers[i].attach_type; + msg.attachments.push_back(att); + } + } + } + } + } +} + +void IMAPSession::getRFC822Messages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg) +{ + if (messageIndex < _headers.size()) + { + int size = _headers[messageIndex].part_headers.size(); + int partIdx = 0; + int cIdx = 0; + IMAP_MSG_Item *_rfc822 = nullptr; + if (size > 0) + { + for (int i = 0; i < size; i++) + { + if (_headers[messageIndex].part_headers[i].message_sub_type == esp_mail_imap_message_sub_type_rfc822 && _headers[messageIndex].part_headers[i].attach_type != esp_mail_att_type_attachment) + { + if (_headers[messageIndex].part_headers[i].rfc822_part) + { + if (partIdx > 0) + msg.rfc822.push_back(*_rfc822); + cIdx = i; + partIdx++; + _rfc822 = new IMAP_MSG_Item(); + _rfc822->setRFC822Headers(&_headers[messageIndex].part_headers[i].rfc822_header); + } + else + { + if (MailClient.multipartMember(_headers[messageIndex].part_headers[cIdx].partNumStr, _headers[messageIndex].part_headers[i].partNumStr)) + { + if (_headers[messageIndex].part_headers[i].attach_type == esp_mail_att_type_none) + { + if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_plain || _headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_enriched) + { + _rfc822->text.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); + _rfc822->text.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); + _rfc822->text.content = _headers[messageIndex].part_headers[i].text.c_str(); + _rfc822->text.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); + } + if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_html) + { + _rfc822->html.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); + _rfc822->html.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); + _rfc822->html.content = _headers[messageIndex].part_headers[i].text.c_str(); + _rfc822->html.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); + } + } + else + { + struct esp_mail_attachment_info_t att; + att.filename = _headers[messageIndex].part_headers[i].filename.c_str(); + att.mime = _headers[messageIndex].part_headers[i].content_type.c_str(); + att.name = _headers[messageIndex].part_headers[i].name.c_str(); + att.size = _headers[messageIndex].part_headers[i].attach_data_size; + att.description = _headers[messageIndex].part_headers[i].content_description.c_str(); + att.creationDate = _headers[messageIndex].part_headers[i].creation_date.c_str(); + att.type = _headers[messageIndex].part_headers[i].attach_type; + _rfc822->attachments.push_back(att); + } + } + } + } + } + + if ((int)msg.rfc822.size() < partIdx && _rfc822 != nullptr) + msg.rfc822.push_back(*_rfc822); + } + } +} + +bool IMAPSession::closeMailbox(bool expunge) +{ +#if !defined(SILENT_MODE) + MB_String dbMsg = esp_mail_dbg_str_32; /* "closing the " */ + dbMsg += _currentFolder; + dbMsg += esp_mail_str_89; /* " folder..." */ + + MailClient.printDebug(this, + esp_mail_cb_str_27 /* "Closing the mailbox folder..." */, + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); +#endif + if (!MailClient.reconnect(this)) + return false; + + // If folder was opened in readonly mode, use CLOSE command will not expunge the deleted messages + // Or user intent to expunge the deleted message after close the folder. + if (expunge || _readOnlyMode) + { + + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_close].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_close; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_CLOSE_MAILBOX_FAILED, false)) + return false; + } + else + { + // Close folder without expunge + if (_feature_capability[esp_mail_imap_read_capability_unselect]) + { + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_unselect].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_unselect; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_CLOSE_MAILBOX_FAILED, false)) + return false; + } + else + { + // Open non-existing folder + MB_String folder = esp_mail_str_84 /* "message" */; + folder += MailClient.Time.getCurrentTimestamp(); + MB_StringPtr folderPtr; + folderPtr = toStringPtr(folder); + openMailbox(folderPtr, esp_mail_imap_auth_mode::esp_mail_imap_mode_examine, true, true); + } + } + + _currentFolder.clear(); + _mailboxOpened = false; + + return true; +} + +bool IMAPSession::openMailbox(MB_StringPtr folder, esp_mail_imap_auth_mode mode, bool waitResponse, bool unselect) +{ + + if (!MailClient.sessionExisted(this)) + return false; + + MB_String _folder = folder; + + if (!MailClient.reconnect(this)) + return false; + + if (_folder.length() == 0) + return false; + + bool _dbg = _debug; + imapStatusCallback _cb = _statusCallback; + + // The SELECT/EXAMINE command automatically deselects any currently selected mailbox + // before attempting the new selection (RFC3501 p.33) + + // folder should not close for re-selection otherwise the server returned * BAD Command Argument Error. 12 + + if (!unselect) + { + + bool sameFolder = strcmp(_currentFolder.c_str(), _folder.c_str()) == 0; + + // guards 3 seconds to prevent accidently frequently select the same folder with the same mode + if (!_mailboxOpened && sameFolder && millis() - _lastSameFolderOpenMillis < 3000) + { + if ((_readOnlyMode && mode == esp_mail_imap_mode_examine) || (!_readOnlyMode && mode == esp_mail_imap_mode_select)) + return true; + } + + if (!sameFolder) + _currentFolder = folder; + +#if !defined(SILENT_MODE) + MB_String dbMsg = esp_mail_dbg_str_68; /* "selecting the " */ + dbMsg += _currentFolder; + dbMsg += esp_mail_str_89; /* " folder..." */ + + MailClient.printDebug(this, + esp_mail_cb_str_51 /* "Open the mailbox folder..." */, + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); +#endif + } + else + { + // Hide the callback and debug info + _debug = false; + _statusCallback = NULL; + _currentFolder = folder; + } + + MB_String cmd; + MailClient.appendSpace(cmd, true, mode == esp_mail_imap_mode_examine ? imap_commands[esp_mail_imap_command_examine].text : imap_commands[esp_mail_imap_command_select].text); + MailClient.appendString(cmd, _currentFolder.c_str(), false, false, esp_mail_string_mark_type_double_quote); + + if (isCondStoreSupported()) + { + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, imap_commands[esp_mail_imap_command_condstore].text, false, false, esp_mail_string_mark_type_round_bracket); + } + + _imap_cmd = mode == esp_mail_imap_mode_examine ? esp_mail_imap_cmd_examine : esp_mail_imap_cmd_select; + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (!unselect) + _lastSameFolderOpenMillis = millis(); + + if (waitResponse && !MailClient.handleIMAPResponse(this, IMAP_STATUS_OPEN_MAILBOX_FAILED, false)) + { + if (!unselect) + return false; + } + + if (unselect) + { + _statusCallback = _cb; + _debug = _dbg; + } + + if (mode == esp_mail_imap_mode_examine) + _readOnlyMode = true; + else if (mode == esp_mail_imap_mode_select) + _readOnlyMode = false; + + _mailboxOpened = !unselect; + + return true; +} + +bool IMAPSession::getMailboxes(FoldersCollection &folders) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_16 /* "Reading the list of mailboxes..." */, + esp_mail_dbg_str_35 /* "send IMAP command, LIST" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + _folders.clear(); + + MB_String cmd; + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_list].text); + MailClient.appendString(cmd, NULL, false, false, esp_mail_string_mark_type_double_quote); + MailClient.prependSpace(cmd, esp_mail_str_3 /* "*" */); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_list; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) + return false; + + folders = _folders; + return true; +} + +bool IMAPSession::mGetSubscribesMailboxes(MB_StringPtr reference, MB_StringPtr mailbox, FoldersCollection &folders) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_30 /* "Listing the subscribed mailboxes..." */, + esp_mail_dbg_str_56 /* "send IMAP command, LSUB" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + folders.clear(); + + MB_String cmd; + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_lsub].text); + MailClient.appendString(cmd, MB_String(reference).c_str(), false, false, esp_mail_string_mark_type_double_quote); + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, MB_String(mailbox).c_str(), false, false, esp_mail_string_mark_type_double_quote); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + FoldersCollection tmp; + + for (size_t i = 0; i < this->_folders.size(); i++) + tmp.add(this->_folders[i]); + + this->_folders.clear(); + + _imap_cmd = esp_mail_imap_cmd_lsub; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) + return false; + + for (size_t i = 0; i < this->_folders.size(); i++) + folders.add(this->_folders[i]); + + this->_folders.clear(); + + for (size_t i = 0; i < tmp.size(); i++) + this->_folders.add(tmp[i]); + + tmp.clear(); + + return true; +} + +bool IMAPSession::mSubscribe(MB_StringPtr folder) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_31 /* "Subscribe mailbox..." */, + esp_mail_dbg_str_57 /* "send IMAP command, SUBSCRIBE" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + MB_String cmd; + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_subscribe].text); + MailClient.appendString(cmd, MB_String(folder).c_str(), false, false, esp_mail_string_mark_type_double_quote); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_subscribe; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) + return false; + + return true; +} + +bool IMAPSession::mUnSubscribe(MB_StringPtr folder) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_32 /* "Unsubscribe mailbox..." */, + esp_mail_dbg_str_58 /* "send IMAP command, UNSUBSCRIBE" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + MB_String cmd; + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_unsubscribe].text); + MailClient.appendString(cmd, MB_String(folder).c_str(), false, false, esp_mail_string_mark_type_double_quote); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_unsubscribe; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) + return false; + + return true; +} + +bool IMAPSession::mFetchSequenceSet() +{ + + MB_String cmd; + if (_imap_data->fetch.sequence_set.UID) + MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_fetch].text); + else + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_fetch].text); + + MailClient.appendSpace(cmd, false, _imap_data->fetch.sequence_set.string.c_str()); + MailClient.appendString(cmd, imap_commands[esp_mail_imap_command_uid].text, false, false, esp_mail_string_mark_type_round_bracket); + + addModifier(cmd, esp_mail_imap_command_changedsince, _imap_data->fetch.modsequence); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_msg_num.clear(); + + _imap_cmd = esp_mail_imap_cmd_fetch_sequence_set; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) + return false; + + return true; +} + +MB_String IMAPSession::prependTag(PGM_P cmd, PGM_P tag) +{ + MB_String s = (tag == NULL) ? esp_mail_imap_tag_str : tag; + MailClient.appendSpace(s); + s += cmd; + return s; +} + +bool IMAPSession::checkCapabilities() +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_52 /* "Checking the capability..." */, + esp_mail_dbg_str_76 /* "check the capability" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_capability].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_capability; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_CHECK_CAPABILITIES_FAILED, false)) + return false; + + return true; +} + +bool IMAPSession::mCreateFolder(MB_StringPtr folderName) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_59 /* "Creating folder..." */, + esp_mail_dbg_str_49 /* "creating folder" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + MB_String cmd; + MailClient.joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_create].text, folderName); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_create; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +bool IMAPSession::mRenameFolder(MB_StringPtr currentFolderName, MB_StringPtr newFolderName) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_53 /* "Renaming folder..." */, + esp_mail_dbg_str_55 /* "renaming folder" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + MB_String o = currentFolderName; + MB_String n = newFolderName; + + o.trim(); + n.trim(); + + if (o == n) + return true; + + if (o.length() == 0 || n.length() == 0) + return false; + + MB_String cmd; + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_rename].text); + MailClient.appendString(cmd, o.c_str(), false, false, esp_mail_string_mark_type_double_quote); + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, n.c_str(), false, false, esp_mail_string_mark_type_double_quote); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_rename; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + if (_currentFolder == o) + selectFolder(n.c_str(), false); + + return true; +} + +int IMAPSession::getUID(int msgNum) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_25 /* "Get UID..." */, + esp_mail_dbg_str_79 /* "get UID" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + int uid = mGetUID(msgNum); + + if (!MailClient.sessionExisted(this)) + return false; + +#if !defined(SILENT_MODE) + MB_String dbMsg = esp_mail_cb_str_54; /* "UID is " */ + dbMsg += uid; + + MailClient.printDebug(this, + dbMsg.c_str(), + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); +#endif + return uid; +} + +int IMAPSession::mGetUID(int msgNum) +{ + + if (_currentFolder.length() == 0) + return 0; + + MB_String cmd; + MailClient.joinStringSpace(cmd, true, 3, imap_commands[esp_mail_imap_command_fetch].text, MB_String(msgNum).c_str(), imap_commands[esp_mail_imap_command_uid].text); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return 0; + + _imap_cmd = esp_mail_imap_cmd_get_uid; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return 0; + + return _uid_tmp; +} + +const char *IMAPSession::getFlags(int msgNum) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_55 /* "Get Flags..." */, + esp_mail_dbg_str_80 /* "get flags" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + _flags_tmp.clear(); + if (_currentFolder.length() == 0) + return _flags_tmp.c_str(); + + MB_String cmd, cmd2; + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_fetch].text); + MailClient.appendString(cmd2, imap_commands[esp_mail_imap_command_flags].text, false, false, esp_mail_string_mark_type_round_bracket); + MailClient.joinStringSpace(cmd, false, 2, MB_String(msgNum).c_str(), cmd2.c_str()); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return _flags_tmp.c_str(); + + _imap_cmd = esp_mail_imap_cmd_get_flags; + MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false); + + return _flags_tmp.c_str(); +} + +bool IMAPSession::mSendCustomCommand(MB_StringPtr cmd, imapResponseCallback callback, MB_StringPtr tag) +{ + + _customCmdResCallback = callback; + _cmd = cmd; + _cmd.trim(); + + MB_String _tag = cmd; + _tag.trim(); + + MB_String _tag2 = tag; + _tag2.trim(); + + if (_tag2.length() == 0) + { + int p = MailClient.strpos(_tag.c_str(), " ", 0); + if (p > -1) + { + _tag.erase(p, _tag.length() - p); + _tag.trim(); + _responseStatus.tag = _tag; + } + } + else + { + _responseStatus.tag = tag; + _responseStatus.tag.trim(); + if (MailClient.strpos(_cmd.c_str(), _responseStatus.tag.c_str(), 0, false) == -1) + _cmd = prependTag(_cmd.c_str(), _responseStatus.tag.c_str()); + } + + // filter for specific command + if (_cmd.find(imap_cmd_pre_tokens[esp_mail_imap_command_idle].c_str()) != MB_String::npos) + _imap_custom_cmd = esp_mail_imap_cmd_idle; + else if (_cmd.find(imap_cmd_pre_tokens[esp_mail_imap_command_append].c_str()) != MB_String::npos) + _imap_custom_cmd = esp_mail_imap_cmd_append; + else if (_cmd.find(imap_cmd_pre_tokens[esp_mail_imap_command_login].c_str()) != MB_String::npos) + _imap_custom_cmd = esp_mail_imap_cmd_sasl_login; + else if (_cmd.find(imap_cmd_pre_tokens[esp_mail_imap_command_logout].c_str()) != MB_String::npos) + _imap_custom_cmd = esp_mail_imap_cmd_logout; + else + _imap_custom_cmd = esp_mail_imap_cmd_custom; + + if (_prev_imap_custom_cmd != _imap_custom_cmd || _imap_custom_cmd != esp_mail_imap_cmd_idle) + { + if (MailClient.imapSend(this, _cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + { + _prev_imap_custom_cmd = esp_mail_imap_cmd_custom; + return false; + } + } + + _imap_cmd = esp_mail_imap_cmd_custom; + + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + { + _prev_imap_custom_cmd = esp_mail_imap_cmd_custom; + return false; + } + + if (_imap_custom_cmd == esp_mail_imap_cmd_sasl_login) + { + _authenticated = true; + _loginStatus = true; + } + else if (_imap_custom_cmd == esp_mail_imap_cmd_logout) + { + _authenticated = false; + _loginStatus = false; + } + + _prev_imap_custom_cmd = _imap_custom_cmd; + + if (MailClient.strposP(_cmd.c_str(), imap_auth_capabilities[esp_mail_auth_capability_starttls].text, 0, false) == 0) + { + bool verify = false; + + if (_session_cfg) + verify = _session_cfg->certificate.verify; + + if (!client.connectSSL(verify)) + return false; + + // set the secure mode + if (_session_cfg) + { + // We reset the prefer connection mode in case user set it. + _session_cfg->secure.startTLS = false; + _session_cfg->secure.mode = esp_mail_secure_mode_undefined; + } + + _secure = true; + } + + return true; +} + +bool IMAPSession::mSendData(MB_StringPtr data, bool lastData, esp_mail_imap_command cmd) +{ + MB_String _data = data; + if (MailClient.imapSend(this, _data.c_str(), lastData) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (lastData) + { + _imap_cmd = cmd; + _cmd.clear(); + + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + } + + return true; +} + +bool IMAPSession::mSendData(uint8_t *data, size_t size, bool lastData, esp_mail_imap_command cmd) +{ + + if (MailClient.imapSend(this, data, size) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (lastData) + { + if (MailClient.imapSend(this, pgm2Str(esp_mail_str_42 /* "\r\n" */), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = cmd; + _cmd.clear(); + + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + } + + return true; +} + +bool IMAPSession::mDeleteFolder(MB_StringPtr folderName) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_56 /* "Deleting folder..." */, + esp_mail_dbg_str_81 /* "delete folder" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + MB_String cmd; + MailClient.joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_delete].text, MB_String(folderName).c_str()); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_delete; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +bool IMAPSession::isCondStoreSupported() +{ + return _feature_capability[esp_mail_imap_read_capability_condstore]; +} + +bool IMAPSession::isModseqSupported() +{ + return isCondStoreSupported() && !_mbif._nomodsec; +} + +void IMAPSession::addModifier(MB_String &cmd, esp_mail_imap_command_types type, int32_t modsequence) +{ + if (modsequence > -1 && isModseqSupported()) + { + MB_String modifier; + MailClient.joinStringSpace(modifier, false, 2, imap_commands[type].text, MB_String(modsequence).c_str()); + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, modifier.c_str(), false, false, esp_mail_string_mark_type_round_bracket); + } +} + +bool IMAPSession::deleteMsg(MessageList *toDelete, const char *sequenceSet, bool UID, bool expunge, int32_t modsequence) +{ + if ((toDelete && toDelete->_list.size() == 0) || (!toDelete && strlen(sequenceSet) == 0)) + return false; + + if (!selectFolder(_currentFolder.c_str(), false)) + return false; + +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_57 /* "Deleting message(s)..." */, + esp_mail_dbg_str_75 /* "delete message(s)" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!MailClient.sessionExisted(this)) + return false; + + MB_String cmd; + if (UID || toDelete) + { + MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_store].text); + + if (toDelete && toDelete->_list.size() > 0) + MailClient.appendList(cmd, toDelete->_list); + } + else if (!toDelete && strlen(sequenceSet) > 0) + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_store].text); + + if (!toDelete && strlen(sequenceSet) > 0) + cmd += sequenceSet; + + addModifier(cmd, esp_mail_imap_command_unchangedsince, modsequence); + + cmd += imap_cmd_pre_tokens[esp_mail_imap_command_plus_flags]; + MailClient.prependDot(cmd, imap_commands[esp_mail_imap_command_silent].text); + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, esp_mail_str_91 /* "\\Deleted" */, false, false, esp_mail_string_mark_type_round_bracket); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_store; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + if (expunge) + { + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_expunge].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_expunge; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + } + + return true; +} + +bool IMAPSession::mDeleteMessages(MessageList *toDelete, bool expunge, int32_t modsequence) +{ + if (toDelete->_list.size() > 0) + return deleteMsg(toDelete, "", false, expunge); + return true; +} + +bool IMAPSession::mDeleteMessagesSet(MB_StringPtr sequenceSet, bool UID, bool expunge, int32_t modsequence) +{ + return deleteMsg(nullptr, MB_String(sequenceSet).c_str(), UID, expunge); +} + +bool IMAPSession::copyMsg(MessageList *toCopy, const char *sequenceSet, bool UID, MB_StringPtr dest) +{ +#if !defined(SILENT_MODE) + MB_String dbMsg = esp_mail_dbg_str_48; /* "copying message(s) to " */ + dbMsg += dest; + + MailClient.printDebug(this, + esp_mail_cb_str_58 /* "Copying message(s)..." */, + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!MailClient.sessionExisted(this)) + return false; + + if ((toCopy && toCopy->_list.size() == 0) || (!toCopy && strlen(sequenceSet) == 0)) + return false; + + if (!selectFolder(_currentFolder.c_str(), false)) + return false; + + MB_String cmd; + if (UID || toCopy) + { + MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_copy].text); + + if (toCopy && toCopy->_list.size() > 0) + MailClient.appendList(cmd, toCopy->_list); + } + else if (!toCopy && strlen(sequenceSet) > 0) + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_copy].text); + + if (!toCopy && strlen(sequenceSet) > 0) + cmd += sequenceSet; + + MailClient.prependSpace(cmd, MB_String(dest).c_str()); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_copy; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +bool IMAPSession::mCopyMessages(MessageList *toCopy, MB_StringPtr dest) +{ + return copyMsg(toCopy, "", false, dest); +} + +bool IMAPSession::mCopyMessagesSet(MB_StringPtr sequenceSet, bool UID, MB_StringPtr dest) +{ + return copyMsg(nullptr, MB_String(sequenceSet).c_str(), UID, dest); +} + +bool IMAPSession::moveMsg(MessageList *toMove, const char *sequenceSet, bool UID, MB_StringPtr dest) +{ +#if !defined(SILENT_MODE) + MB_String dbMsg = esp_mail_dbg_str_59; /* "moving message(s) to " */ + dbMsg += dest; + + MailClient.printDebug(this, + esp_mail_cb_str_60 /* "Moving message(s)..." */, + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!MailClient.sessionExisted(this)) + return false; + + if ((toMove && toMove->_list.size() == 0) || (!toMove && strlen(sequenceSet) == 0)) + return false; + + if (!_feature_capability[esp_mail_imap_read_capability_move]) + { + + bool ret = mCopyMessages(toMove, dest); + + if (ret) + ret = mDeleteMessages(toMove, true); + + return ret; + } + + if (!selectFolder(_currentFolder.c_str(), false)) + return false; + + MB_String cmd; + if (UID || toMove) + { + MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_move].text); + if (toMove && toMove->_list.size() > 0) + MailClient.appendList(cmd, toMove->_list); + } + else if (!toMove && strlen(sequenceSet) > 0) + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_move].text); + + if (!toMove && strlen(sequenceSet) > 0) + cmd += sequenceSet; + + MailClient.prependSpace(cmd, MB_String(dest).c_str()); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_move; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +bool IMAPSession::mMoveMessages(MessageList *toMove, MB_StringPtr dest) +{ + return moveMsg(toMove, "", false, dest); +} + +bool IMAPSession::mMoveMessagesSet(MB_StringPtr sequenceSet, bool UID, MB_StringPtr dest) +{ + return moveMsg(nullptr, MB_String(sequenceSet).c_str(), UID, dest); +} + +bool IMAPSession::mGetSetQuota(MB_StringPtr quotaRoot, IMAP_Quota_Root_Info *data, bool getMode) +{ + +#if !defined(SILENT_MODE) + PGM_P p1 = getMode ? esp_mail_cb_str_33 /* "Get quota root resource usage and limit..." */ : esp_mail_cb_str_34 /* "Set quota root resource usage and limit..." */; + PGM_P p2 = getMode ? esp_mail_dbg_str_60 /* "send IMAP command, GETQUOTA" */ : esp_mail_dbg_str_61 /* "send IMAP command, SETQUOTA" */; + MailClient.printDebug(this, p1, p2, esp_mail_debug_tag_type_client, true, false); +#endif + + if (!_feature_capability[esp_mail_imap_read_capability_quota]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + return false; + } + + MB_String _quotaRoot = quotaRoot; + + MB_String cmd; + if (getMode) + { + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_getquota].text); + MailClient.appendString(cmd, _quotaRoot.c_str(), false, false, esp_mail_string_mark_type_double_quote); + } + else + { + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_setquota].text); + MailClient.appendString(cmd, _quotaRoot.c_str(), false, false, esp_mail_string_mark_type_double_quote); + MailClient.appendSpace(cmd); + + MB_String cmd2; + MailClient.joinStringSpace(cmd2, false, 2, data->name.c_str(), MB_String((int)data->limit).c_str()); + MailClient.appendString(cmd, cmd2.c_str(), false, false, esp_mail_string_mark_type_round_bracket); + } + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _quota_tmp.clear(); + + _imap_cmd = (getMode) ? esp_mail_imap_cmd_get_quota : esp_mail_imap_cmd_set_quota; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + if (getMode) + { + mParseQuota(_quota_tmp.c_str(), data); + } + + _quota_tmp.clear(); + + return true; +} + +void IMAPSession::mParseQuota(const char *quota, IMAP_Quota_Root_Info *data) +{ + _vectorImpl tokens; + MailClient.splitToken(quota, tokens, " "); + data->quota_root = tokens[0]; + tokens[1].erase(0, 1); + data->name = tokens[1]; + data->usage = atoi(tokens[2].c_str()); + data->limit = atoi(tokens[3].c_str()); +} + +bool IMAPSession::mGetQuotaRoots(MB_StringPtr mailbox, IMAP_Quota_Roots_List *quotaRootsList) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_35 /* "Get the list of quota roots..." */, + esp_mail_dbg_str_62 /* "send IMAP command, GETQUOTAROOT" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!MailClient.sessionExisted(this)) + return false; + + if (!_feature_capability[esp_mail_imap_read_capability_quota]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + return false; + } + + MB_String _mailbox = mailbox; + + MB_String cmd; + MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_getquota].text, imap_commands[esp_mail_imap_command_root].text); + MailClient.appendString(cmd, _mailbox.c_str(), false, false, esp_mail_string_mark_type_double_quote); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _quota_root_tmp.clear(); + _quota_tmp.clear(); + + _imap_cmd = esp_mail_imap_cmd_get_quota_root; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + _vectorImpl tokens; + MailClient.splitToken(_quota_root_tmp.c_str(), tokens, ","); + + for (size_t i = 0; i < tokens.size(); i++) + { + _vectorImpl tk; + MailClient.splitToken(tokens[i].c_str(), tk, ":"); + IMAP_Quota_Root_Info data; + if (tk.size() > 1) + mParseQuota(tk[1].c_str(), &data); + else + data.quota_root = tk[0]; + + quotaRootsList->add(data); + } + + _quota_root_tmp.clear(); + _quota_tmp.clear(); + + return true; +} + +bool IMAPSession::mManageACL(MB_StringPtr mailbox, IMAP_Rights_List *acl_list, IMAP_Rights_Info *acl, MB_StringPtr identifier, esp_mail_imap_command type) +{ + +#if !defined(SILENT_MODE) + + PGM_P p1 = NULL; + PGM_P p2 = NULL; + if (type == esp_mail_imap_cmd_get_acl) + { + p1 = esp_mail_cb_str_36; /* "Get the ACL..." */ + p2 = esp_mail_dbg_str_77; /* "get the ACL" */ + } + else if (type == esp_mail_imap_cmd_set_acl) + { + p1 = esp_mail_cb_str_37; /* "Setting the ACL..." */ + p2 = esp_mail_dbg_str_78; /* "set the ACL" */ + } + else if (type == esp_mail_imap_cmd_delete_acl) + { + p1 = esp_mail_cb_str_38; /* "Deleting the ACL..." */ + p2 = esp_mail_dbg_str_72; /* "delete the ACL" */ + } + else if (type == esp_mail_imap_cmd_my_rights) + { + p1 = esp_mail_cb_str_39; /* "Get my ACL..." */ + p2 = esp_mail_dbg_str_23; /* "get my ACL" */ + } + + MailClient.printDebug(this, p1, p2, esp_mail_debug_tag_type_client, true, false); + +#endif + + if (!MailClient.sessionExisted(this)) + return false; + + if (!_feature_capability[esp_mail_imap_read_capability_acl]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + return false; + } + + MB_String _mailbox = mailbox; + MB_String _identifier = identifier; + + MB_String cmd; + if (type == esp_mail_imap_cmd_get_acl) + { + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_get_acl].text); + MailClient.appendString(cmd, _mailbox.c_str(), false, false, esp_mail_string_mark_type_double_quote); + } + else if (type == esp_mail_imap_cmd_set_acl) + { + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_set_acl].text); + MailClient.appendString(cmd, MB_String(mailbox).c_str(), false, false, esp_mail_string_mark_type_double_quote); + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, acl->identifier.c_str(), false, false, esp_mail_string_mark_type_double_quote); + MailClient.appendSpace(cmd); + MB_String rights; + getRights(rights, acl); + MailClient.appendString(cmd, rights.c_str(), false, false, esp_mail_string_mark_type_double_quote); + } + else if (type == esp_mail_imap_cmd_delete_acl) + { + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_delete_acl].text); + MailClient.appendString(cmd, _mailbox.c_str(), false, false, esp_mail_string_mark_type_double_quote); + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, _identifier.c_str(), false, false, esp_mail_string_mark_type_double_quote); + } + else if (type == esp_mail_imap_cmd_my_rights) + { + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_myrights].text); + MailClient.appendString(cmd, _mailbox.c_str(), false, false, esp_mail_string_mark_type_double_quote); + } + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _acl_tmp.clear(); + + _imap_cmd = type; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + if (type == esp_mail_imap_cmd_get_acl) + parseACL(_acl_tmp, acl_list); + else if (type == esp_mail_imap_cmd_my_rights) + parseRights(_acl_tmp, acl); + + _acl_tmp.clear(); + + return true; +} + +void IMAPSession::parseACL(MB_String &acl_str, IMAP_Rights_List *right_list) +{ + _vectorImpl tokens; + MailClient.splitToken(acl_str.c_str(), tokens, " "); + + for (size_t i = 0; i < tokens.size(); i += 2) + { + IMAP_Rights_Info info; + info.identifier = tokens[i]; + parseRights(tokens[i + 1], &info); + right_list->add(info); + } +} + +void IMAPSession::parseRights(MB_String &righs_str, IMAP_Rights_Info *info) +{ + for (size_t i = 0; i < righs_str.length(); i++) + { + uint8_t c = righs_str[i] - 97; + if (c >= esp_mail_imap_rights_administer && c < esp_mail_imap_rights_maxType) + info->rights[c] = true; + } +} + +void IMAPSession::getRights(MB_String &righs_str, IMAP_Rights_Info *info) +{ + for (size_t i = esp_mail_imap_rights_administer; i < esp_mail_imap_rights_maxType; i++) + { + if (info->rights[i]) + righs_str += (char)(i + 97); + } +} + +bool IMAPSession::mNamespace(IMAP_Namespaces_List *ns) +{ + +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_40 /* "Get namespace..." */, + esp_mail_dbg_str_67 /* "send IMAP command, NAMESPACE" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!MailClient.sessionExisted(this)) + return false; + + if (!_feature_capability[esp_mail_imap_read_capability_namespace]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + return false; + } + + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_namespace].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _ns_tmp.clear(); + + _imap_cmd = esp_mail_imap_cmd_namespace; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + int cnt = 0; + MB_String personal, other, shared; + + for (size_t i = 0; i < _ns_tmp.length(); i++) + { + if (i > 0 && i < _ns_tmp.length() - 1 && _ns_tmp[i] == ' ' && _ns_tmp[i - 1] != '"' && _ns_tmp[i + 1] != '"') + { + if (cnt == 0) + personal = _ns_tmp.substr(0, i); + else if (cnt == 1) + { + other = _ns_tmp.substr(personal.length() + 1, i - personal.length() - 1); + shared = _ns_tmp.substr(i + 1, _ns_tmp.length() - i - 1); + } + cnt++; + } + } + + if (personal.length() > 4) + parseNamespaces(personal, &(ns->personal_namespaces)); + + if (other.length() > 4) + parseNamespaces(other, &(ns->other_users_namespaces)); + + if (shared.length() > 4) + parseNamespaces(shared, &(ns->shared_namespaces)); + + return true; +} + +bool IMAPSession::mEnable(MB_StringPtr capability) +{ + +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_41 /* "Enable capability..." */, + esp_mail_dbg_str_68 /* "send IMAP command, ENABLE" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!_feature_capability[esp_mail_imap_read_capability_enable]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + return false; + } + + MB_String _cap = capability; + + MB_String cmd; + MailClient.joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_enable].text, _cap.c_str()); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_enable; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +void IMAPSession::parseNamespaces(MB_String &ns_str, IMAP_Namespaces *ns) +{ + MB_String tmp = ns_str.substr(2, ns_str.length() - 4); + tmp.replaceAll(")(", " "); + _vectorImpl tokens; + MailClient.splitToken(tmp.c_str(), tokens, " "); + + for (size_t i = 0; i < tokens.size(); i += 2) + { + IMAP_Namespace_Info info; + info.prefix = tokens[i]; + info.delimiter = tokens[i + 1]; + ns->add(info); + } +} + +void IMAPSession::empty() +{ + _nextUID.clear(); + _unseenMsgIndex.clear(); + _flags_tmp.clear(); + _quota_tmp.clear(); + _quota_root_tmp.clear(); + _acl_tmp.clear(); + _ns_tmp.clear(); + _server_id_tmp.clear(); + _sdFileList.clear(); + clearMessageData(); +} + +IMAP_Status IMAPSession::status() +{ + return _cbData; +} + +String IMAPSession::fileList() +{ + return _sdFileList.c_str(); +} + +void IMAPSession::clearMessageData() +{ + for (size_t i = 0; i < _headers.size(); i++) + { + _headers[i].part_headers.clear(); + } + + _headers.clear(); + _imap_msg_num.clear(); + _mbif._searchCount = 0; + _flags_tmp.clear(); + +#if defined(MB_USE_STD_VECTOR) + _folders.clear(); + _mbif._flags.clear(); +#endif +} + +void IMAPSession::printDebugNotSupported() +{ + +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_error_imap_str_13 /* "not supported by IMAP server" */, + esp_mail_error_imap_str_13 /* "not supported by IMAP server" */, + esp_mail_debug_tag_type_error, + true, + false); +#endif +} + +IMAP_Status::IMAP_Status() +{ +} + +IMAP_Status::~IMAP_Status() +{ + empty(); +} + +const char *IMAP_Status::info() +{ + return _info.c_str(); +} + +bool IMAP_Status::success() +{ + return _success; +} + +void IMAP_Status::empty() +{ + _info.clear(); +} + +#endif + +#endif /* ESP_MAIL_IMAP_H */ \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_SMTP.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_SMTP.h new file mode 100644 index 000000000000..8371e95cad67 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_SMTP.h @@ -0,0 +1,3631 @@ + +#ifndef ESP_MAIL_SMTP_H +#define ESP_MAIL_SMTP_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +/** + * Mail Client Arduino Library for Espressif's ESP32 and ESP8266, Raspberry Pi RP2040 Pico, and SAMD21 with u-blox NINA-W102 WiFi/Bluetooth module + * + * Created August 28, 2023 + * + * This library allows Espressif's ESP32, ESP8266, SAMD and RP2040 Pico devices to send and read Email through the SMTP and IMAP servers. + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "ESP_Mail_Client_Version.h" +#include "ESP_Mail_Client.h" + +#if defined(ENABLE_SMTP) + +void ESP_Mail_Client::mimeFromFile(const char *name, MB_String &mime) +{ + MB_String ext = name; + size_t p = ext.find_last_of("."); + if (p != MB_String::npos) + { + ext = ext.substr(p, ext.length() - p); + if (ext.length() > 0) + getMIME(ext.c_str(), mime); + } +} + +void ESP_Mail_Client::getMIME(const char *ext, MB_String &mime) +{ + mime.clear(); + for (int i = 0; i < esp_mail_file_extension_maxType; i++) + { + if (strcmp_P(ext, mimeinfo[i].endsWith) == 0) + { + mime = mimeinfo[i].mimeType; + break; + } + } +} + +bool ESP_Mail_Client::smtpAuth(SMTPSession *smtp, bool &ssl) +{ + if (!smtp) + return false; + + smtp->_auth_capability[esp_mail_auth_capability_login] = false; + + smtp->_session_cfg->int_start_tls = smtp->_session_cfg->secure.startTLS; + smtp->_session_cfg->int_mode = smtp->_session_cfg->secure.mode; + +#if !defined(ESP_MAIL_DISABLE_SSL) +initial_stage: +#endif + +// Sending greeting helo response +#if !defined(SILENT_MODE) + printDebug(smtp, + esp_mail_cb_str_3 /* "Sending greeting response..." */, + esp_mail_dbg_str_5 /* "send SMTP command, EHLO" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + // The Extended HELLO (EHLO) and HELLO (HELO) commands are used to identify Client (ourself) + + // Since we support ESMTP (rfc5321), let server knows by sending EHLO first + + // If server was not support ESMTP (rfc5321) the failure 501, 500, 502, or 550 would be replied. + + // To prevent connection rejection, EHLO/HELO command parameter should be primary host name (domain name) of client system. + // Otherwise client public IP address string (IPv4 or IPv6) can be assign when no host name is available + + MB_String s = smtp_cmd_post_tokens[esp_mail_smtp_command_ehlo]; + appendDomain(s, smtp->_session_cfg->login.user_domain.c_str()); + + if (smtpSend(smtp, s.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + // expected success status code 250 + // expected error status code 500, 501, 504, 421 + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_greeting, esp_mail_smtp_status_code_250, 0)) + { + +#if !defined(SILENT_MODE) + if (smtp->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_17 /* "No ESMTP supported, send SMTP command, HELO" */, esp_mail_debug_tag_type_client, true); +#endif + // In case EHLO (rfc5321) is not acceptable, + // send HELO command (rfc821) instead. + s = smtp_cmd_post_tokens[esp_mail_smtp_command_helo]; + appendDomain(s, smtp->_session_cfg->login.user_domain.c_str()); + + if (!smtpSend(smtp, s.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + // expected success status code 250 + // expected error status code 500, 501, 504, 421 + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_greeting, esp_mail_smtp_status_code_250, SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED)) + return false; + + smtp->_feature_capability[esp_mail_smtp_send_capability_esmtp] = false; + smtp->_auth_capability[esp_mail_auth_capability_login] = true; + } + else + smtp->_feature_capability[esp_mail_smtp_send_capability_esmtp] = true; + +#if !defined(ESP_MAIL_DISABLE_SSL) + + if (smtp->_session_cfg->int_mode != esp_mail_secure_mode_nonsecure) + { + // start TLS when needed + // rfc3207 + if ((smtp->_auth_capability[esp_mail_auth_capability_starttls] || smtp->_session_cfg->int_start_tls || smtp->_session_cfg->int_mode == esp_mail_secure_mode_ssl_tls) && !ssl) + { +// send starttls command +#if !defined(SILENT_MODE) + printDebug(smtp, + esp_mail_cb_str_2 /* "Sending STARTTLS command..." */, + esp_mail_dbg_str_1 /* "send command, STARTTLS" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + // expected success status code 250 for complete the request + // some server returns 220 to restart to initial state + + // expected error status code 500, 501, 504, 421 + smtpSend(smtp, smtp_commands[esp_mail_smtp_command_starttls].text, true); + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_start_tls, esp_mail_smtp_status_code_250, SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED)) + return false; + +#if !defined(SILENT_MODE) + if (smtp->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_22 /* "perform SSL/TLS handshake" */, esp_mail_debug_tag_type_client, true); +#endif + + // connect in secure mode + // do TLS handshake + if (!smtp->client.connectSSL(smtp->_session_cfg->certificate.verify)) + return handleSMTPError(smtp, MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP); + + // set the secure mode + smtp->_session_cfg->int_start_tls = false; + smtp->_session_cfg->int_mode = esp_mail_secure_mode_undefined; + ssl = true; + smtp->_secure = true; + + // return to initial stage if the response status is 220. + if (smtp->_responseStatus.statusCode == esp_mail_smtp_status_code_220) + goto initial_stage; + } + } + +#endif + + bool creds = smtp->_session_cfg->login.email.length() > 0 && smtp->_session_cfg->login.password.length() > 0; + bool sasl_auth_oauth = smtp->_session_cfg->login.accessToken.length() > 0 && smtp->_auth_capability[esp_mail_auth_capability_xoauth2]; + bool sasl_login = smtp->_auth_capability[esp_mail_auth_capability_login] && creds; + bool sasl_auth_plain = smtp->_auth_capability[esp_mail_auth_capability_plain] && creds; + + if (sasl_auth_oauth || sasl_login || sasl_auth_plain) + { +#if !defined(SILENT_MODE) + if (smtp->_statusCallback) + sendCB(smtp, esp_mail_cb_str_14 /* "Logging in..." */, true, false); +#endif + + // log in + if (sasl_auth_oauth) + { +#if !defined(SILENT_MODE) + if (smtp->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_15 /* "send smtp command, AUTH XOAUTH2" */, esp_mail_debug_tag_type_client, true); +#endif + if (!smtp->_auth_capability[esp_mail_auth_capability_xoauth2]) + return handleSMTPError(smtp, SMTP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED, false); + + MB_String cmd = smtp_cmd_post_tokens[esp_mail_smtp_command_auth]; + cmd += smtp_auth_cap_post_tokens[esp_mail_auth_capability_xoauth2]; + + if (smtpSend(smtp, cmd.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (smtpSend(smtp, getXOAUTH2String(smtp->_session_cfg->login.email, smtp->_session_cfg->login.accessToken).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_auth_xoauth2, esp_mail_smtp_status_code_235, SMTP_STATUS_AUTHEN_FAILED)) + return false; + } + else if (sasl_auth_plain) + { +#if !defined(SILENT_MODE) + if (smtp->_debug) + { + esp_mail_debug_print_tag(esp_mail_dbg_str_7 /* "send SMTP command, AUTH PLAIN" */, esp_mail_debug_tag_type_client, true); + esp_mail_debug_print_tag(smtp->_session_cfg->login.email.c_str(), esp_mail_debug_tag_type_client, true); + MB_String mask; + maskString(mask, smtp->_session_cfg->login.password.length()); + esp_mail_debug_print_tag(mask.c_str(), esp_mail_debug_tag_type_client, true); + } +#endif + // rfc4616 + int len = smtp->_session_cfg->login.email.length() + smtp->_session_cfg->login.password.length() + 2; + uint8_t *tmp = allocMem(len); + memset(tmp, 0, len); + int p = 1; + memcpy(tmp + p, smtp->_session_cfg->login.email.c_str(), smtp->_session_cfg->login.email.length()); + p += smtp->_session_cfg->login.email.length() + 1; + memcpy(tmp + p, smtp->_session_cfg->login.password.c_str(), smtp->_session_cfg->login.password.length()); + p += smtp->_session_cfg->login.password.length(); + + MB_String cmd = smtp_cmd_post_tokens[esp_mail_smtp_command_auth]; + cmd += smtp_cmd_post_tokens[esp_mail_smtp_command_plain]; + cmd += encodeBase64Str(tmp, p); + // release memory + freeMem(&tmp); + + if (smtpSend(smtp, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_auth_plain, esp_mail_smtp_status_code_235, SMTP_STATUS_USER_LOGIN_FAILED)) + return false; + } + else if (sasl_login) + { +#if !defined(SILENT_MODE) + if (smtp->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_6 /* "send SMTP command, AUTH LOGIN" */, esp_mail_debug_tag_type_client, true); +#endif + MB_String cmd = smtp_cmd_post_tokens[esp_mail_smtp_command_auth]; + cmd += smtp_commands[esp_mail_smtp_command_login].text; + + if (smtpSend(smtp, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + // expected server challenge response + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_auth_login, esp_mail_smtp_status_code_334, SMTP_STATUS_AUTHEN_FAILED)) + return false; + +#if !defined(SILENT_MODE) + if (smtp->_debug) + esp_mail_debug_print_tag(smtp->_session_cfg->login.email.c_str(), esp_mail_debug_tag_type_client, true); +#endif + if (smtpSend(smtp, encodeBase64Str((const unsigned char *)smtp->_session_cfg->login.email.c_str(), smtp->_session_cfg->login.email.length()).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + // expected server challenge response + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_login_user, esp_mail_smtp_status_code_334, SMTP_STATUS_USER_LOGIN_FAILED)) + return false; + +#if !defined(SILENT_MODE) + if (smtp->_debug) + { + MB_String mask; + maskString(mask, smtp->_session_cfg->login.password.length()); + esp_mail_debug_print_tag(mask.c_str(), esp_mail_debug_tag_type_client, true); + } +#endif + if (smtpSend(smtp, encodeBase64Str((const unsigned char *)smtp->_session_cfg->login.password.c_str(), smtp->_session_cfg->login.password.length()).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_login_psw, esp_mail_smtp_status_code_235, SMTP_STATUS_PASSWORD_LOGIN_FAILED)) + return false; + } + + smtp->_authenticated = true; + } + + return true; +} + +bool ESP_Mail_Client::addSendingResult(SMTPSession *smtp, SMTP_Message *msg, bool result, bool showResult) +{ + if (!smtp) + return false; + + if (result) + smtp->_sentSuccessCount++; + else + smtp->_sentFailedCount++; + + if (smtp->_session_cfg->sentLogs.filename.length() > 0 && smtp->_session_cfg->sentLogs.storage_type != esp_mail_file_storage_type_none) + saveSendingLogs(smtp, msg, result); + + // Store only tatest result + smtp->sendingResult.clear(); + + SMTP_Result status; + status.completed = result; + status.timestamp = smtp->ts; + status.subject = msg->subject.c_str(); + + if (msg->timestamp.tag.length() && msg->timestamp.format.length()) + status.subject.replaceAll(msg->timestamp.tag, Time.getDateTimeString(Time.getCurrentTimestamp(), msg->timestamp.format.c_str())); + + status.recipients = msg->_rcp[0].email.c_str(); + smtp->sendingResult.add(&status); + + smtp->_cbData._sentSuccess = smtp->_sentSuccessCount; + smtp->_cbData._sentFailed = smtp->_sentFailedCount; + +#if !defined(SILENT_MODE) + if (smtp->_statusCallback) + { + if (showResult) + { + int bufLen = 512; + char *buf = allocMem(bufLen); + time_t ts = (time_t)smtp->ts; + MB_String sep; + for (int i = 0; i < 25; i++) + sep += '-'; + + sendCallback(smtp, sep.c_str(), true, false); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_93 /* "Message sent success: %d" */), smtp->_sentSuccessCount); + sendCallback(smtp, buf, false, false); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_94 /* "Message sent failed: %d" */), smtp->_sentFailedCount); + sendCallback(smtp, buf, false, false); + sendCallback(smtp, sep.c_str(), false, false); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_95 /* "Status: %s" */), result ? pgm2Str(esp_mail_str_98 /* "success" */) : pgm2Str(esp_mail_str_99 /* "failed" */)); + sendCallback(smtp, buf, false, false); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_96 /* "Date/Time: %s" */), Time.getDateTimeString(ts, "%B %d, %Y %H:%M:%S").c_str()); + sendCallback(smtp, buf, false, false); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_97 /* "Recipient: %s" */), msg->_rcp[0].email.c_str()); + sendCallback(smtp, buf, false, false); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_92 /* "Subject: %s" */), msg->subject.c_str()); + sendCallback(smtp, buf, false, false); + freeMem(&buf); + } + } +#endif + + return result; +} + +void ESP_Mail_Client::saveSendingLogs(SMTPSession *smtp, SMTP_Message *msg, bool result) +{ + if (!smtp->_session_cfg || smtp->_session_cfg->sentLogs.filename.length() == 0 || smtp->_session_cfg->sentLogs.storage_type == esp_mail_file_storage_type_none) + return; + + int sz = mbfs->open(smtp->_session_cfg->sentLogs.filename.c_str(), mbfs_type smtp->_session_cfg->sentLogs.storage_type, mb_fs_open_mode_append); + if (sz < 0) + return; + + MB_String cm = esp_mail_str_8; /* "," */ + mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, (int)result); + mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, cm.c_str()); + mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, (int)smtp->ts); + mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, cm.c_str()); + mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, msg->_rcp[0].email.c_str()); + mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, cm.c_str()); + mbfs->println(mbfs_type smtp->_session_cfg->sentLogs.storage_type, msg->subject.c_str()); + mbfs->close(mbfs_type smtp->_session_cfg->sentLogs.storage_type); +} + +bool ESP_Mail_Client::sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession) +{ + if (!smtp || !sessionExisted(smtp)) + return false; + + smtp->_customCmdResCallback = NULL; + + return mSendMail(smtp, msg, closeSession); +} + +size_t ESP_Mail_Client::numAtt(SMTPSession *smtp, esp_mail_attach_type type, SMTP_Message *msg) +{ + size_t count = 0; + for (size_t i = 0; i < msg->_att.size(); i++) + { + if (msg->_att[i]._int.att_type == type) + count++; + } + return count; +} + +bool ESP_Mail_Client::checkEmail(SMTPSession *smtp, SMTP_Message *msg) +{ + bool validRecipient = false; + + if (!validEmail(msg->sender.email.c_str())) + { + errorStatusCB(smtp, this->imap, SMTP_STATUS_NO_VALID_SENDER_EXISTED, false); + return addSendingResult(smtp, msg, false, true); + } + + for (uint8_t i = 0; i < msg->_rcp.size(); i++) + { + if (validEmail(msg->_rcp[i].email.c_str())) + validRecipient = true; + } + + if (!validRecipient) + { + errorStatusCB(smtp, this->imap, SMTP_STATUS_NO_VALID_RECIPIENTS_EXISTED, false); + return addSendingResult(smtp, msg, false, true); + } + + return true; +} + +bool ESP_Mail_Client::mSendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession) +{ + if (!smtp) + return false; + + smtp->_responseStatus.errorCode = 0; + smtp->_responseStatus.statusCode = 0; + smtp->_responseStatus.text.clear(); + smtp->_cbData._success = false; + bool rfc822MSG = false; + + if (!checkEmail(smtp, msg)) + return false; + + smtp->_chunkedEnable = false; + smtp->_chunkCount = 0; + + if (!smtp->connected() && !smtp->_loginStatus) + { +#if !defined(SILENT_MODE) + if (smtp->_debug && smtp->_statusCallback && !smtp->_customCmdResCallback) + { + esp_mail_debug_print(); + errorStatusCB(smtp, this->imap, MAIL_CLIENT_ERROR_NOT_YET_LOGIN, false); + } +#endif + return false; + } + + // new session + if (!smtp->connected()) + { + bool ssl = false; + + if (!smtp->connect(ssl)) + { + closeTCPSession(smtp); + return addSendingResult(smtp, msg, false, true); + } + + if (!smtpAuth(smtp, ssl)) + { + closeTCPSession(smtp); + return addSendingResult(smtp, msg, false, true); + } + smtp->_sentSuccessCount = 0; + smtp->_sentFailedCount = 0; + smtp->sendingResult.clear(); + } + else + { + // If time config changed, we will update time + MailClient.prepareTime(smtp->_session_cfg, smtp); + // reuse session +#if !defined(SILENT_MODE) + PGM_P p1 = smtp->_sentSuccessCount || smtp->_sentFailedCount ? esp_mail_cb_str_10 /* "Sending next Email..." */ : esp_mail_cb_str_9 /* "Sending Email..." */; + PGM_P p2 = smtp->_sentSuccessCount || smtp->_sentFailedCount ? esp_mail_dbg_str_13 /* "send next Email" */ : esp_mail_dbg_str_3 /* "send Email" */; + + printDebug(smtp, + p1, + p2, + esp_mail_debug_tag_type_client, + true, + false); +#endif + } + +#if !defined(SILENT_MODE) + printDebug(smtp, + esp_mail_cb_str_4 /* "Sending message header..." */, + esp_mail_dbg_str_8 /* "send message header" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + imap = nullptr; + calDataLen = false; + dataLen = 0; + + return sendContent(smtp, msg, closeSession, rfc822MSG); +} + +bool ESP_Mail_Client::sendContent(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG) +{ + + if (msg->html.content.length() > 0 || strlen(msg->html.nonCopyContent) > 0 || msg->html.blob.size > 0 || msg->html.file.name.length() > 0) + msg->type |= esp_mail_msg_type_html; + + if (msg->text.content.length() > 0 || strlen(msg->text.nonCopyContent) > 0 || msg->text.blob.size > 0 || msg->text.file.name.length() > 0) + msg->type |= esp_mail_msg_type_plain; + + for (size_t i = 0; i < msg->_rfc822.size(); i++) + { + if (msg->_rfc822[i].html.content.length() > 0) + msg->_rfc822[i].type |= esp_mail_msg_type_html; + + if (msg->_rfc822[i].text.content.length() > 0) + msg->_rfc822[i].type |= esp_mail_msg_type_plain; + } + + MB_String buf; + MB_String buf2; + checkUnencodedData(smtp, msg); + + if (msg->priority >= esp_mail_smtp_priority_high && msg->priority <= esp_mail_smtp_priority_low) + { + appendHeaderField(buf2, message_headers[esp_mail_message_header_field_x_priority].text, MB_String(msg->priority).c_str(), false, true); + + PGM_P p = nullptr; + if (msg->priority == esp_mail_smtp_priority_high) + p = esp_mail_str_4; /* "High" */ + else if (msg->priority == esp_mail_smtp_priority_normal) + p = esp_mail_str_5; /* "Normal" */ + else if (msg->priority == esp_mail_smtp_priority_low) + p = esp_mail_str_6; /* "Low" */ + + if (p) + { + appendHeaderField(buf2, message_headers[esp_mail_message_header_field_x_msmail_priority].text, p, false, true); + appendHeaderField(buf2, message_headers[esp_mail_message_header_field_importance].text, p, false, true); + } + } + + // If author and transmitter (sender or agent) are not identical, send both 'From' and 'Sender' headers + if (msg->sender.email.length() > 0 && msg->author.email.length() > 0 && + strcmp(msg->sender.email.c_str(), msg->author.email.c_str()) != 0) + { + appendAddressHeaderField(buf2, msg->author, esp_mail_rfc822_header_field_from, true, false, true); + appendAddressHeaderField(buf2, msg->sender, esp_mail_rfc822_header_field_sender, true, false, true); + } + // If author and transmitter (agent) are identical, send only 'From' header + else if (msg->sender.email.length() > 0) + appendAddressHeaderField(buf2, msg->sender, esp_mail_rfc822_header_field_from, true, false, true); + + if (!imap && smtp) + { + + buf = smtp_cmd_post_tokens[esp_mail_smtp_command_mail]; + buf += smtp_commands[esp_mail_smtp_command_from].text; + + appendString(buf, msg->author.email.length() ? msg->author.email.c_str() : msg->sender.email.c_str(), false, false, esp_mail_string_mark_type_angle_bracket); + + if (msg->text._int.xencoding == esp_mail_msg_xencoding_binary || msg->html._int.xencoding == esp_mail_msg_xencoding_binary) + { + if (smtp->_feature_capability[esp_mail_smtp_send_capability_binary_mime] || (smtp->_feature_capability[esp_mail_smtp_send_capability_chunking] && msg->enable.chunking)) + { + buf += smtp_cmd_pre_tokens[esp_mail_smtp_command_body]; + buf += esp_mail_str_7; /* "=" */ + buf += smtp_send_capabilities[esp_mail_smtp_send_capability_binary_mime].text; + } + } + else if (msg->text._int.xencoding == esp_mail_msg_xencoding_8bit || msg->html._int.xencoding == esp_mail_msg_xencoding_8bit) + { + if (smtp->_feature_capability[esp_mail_smtp_send_capability_8bit_mime]) + { + buf += smtp_cmd_pre_tokens[esp_mail_smtp_command_body]; + buf += esp_mail_str_7; /* "=" */ + buf += smtp_send_capabilities[esp_mail_smtp_send_capability_8bit_mime].text; + } + } + + // expected success status code 250 + // expected failure status code 552, 451, 452 + // expected error status code 500, 501, 421 + if (!altSendData(buf, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_header_sender, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_SENDER_FAILED)) + return false; + } + + // Construct 'To' header fields. + + for (uint8_t i = 0; i < msg->_rcp.size(); i++) + { + appendAddressHeaderField(buf2, msg->_rcp[i], esp_mail_rfc822_header_field_to, i == 0, i > 0, i == msg->_rcp.size() - 1); + if (!imap && smtp) + { + // only address + buf = smtp_cmd_post_tokens[esp_mail_smtp_command_rcpt]; + buf += smtp_commands[esp_mail_smtp_command_to].text; + appendString(buf, msg->_rcp[i].email.c_str(), false, false, esp_mail_string_mark_type_angle_bracket); + + // rfc3461, rfc3464 + if (smtp->_feature_capability[esp_mail_smtp_send_capability_dsn]) + { + if (msg->response.notify != esp_mail_smtp_notify_never) + { + buf += smtp_cmd_pre_tokens[esp_mail_smtp_command_notify]; + buf += esp_mail_str_7; /* "=" */ + + MB_String notify; + + if ((msg->response.notify & esp_mail_smtp_notify_success) == esp_mail_smtp_notify_success) + notify = smtp_commands[esp_mail_smtp_command_success].text; + + if (notify.length()) + notify += esp_mail_str_8; /* "," */ + + if ((msg->response.notify & esp_mail_smtp_notify_failure) == esp_mail_smtp_notify_failure) + notify += smtp_commands[esp_mail_smtp_command_failure].text; + + if (notify.length()) + notify += esp_mail_str_8; /* "," */ + + if ((msg->response.notify & esp_mail_smtp_notify_delay) == esp_mail_smtp_notify_delay) + notify += smtp_commands[esp_mail_smtp_command_delay].text; + + buf += notify; + } + } + + smtp->_canForward = true; + + // expected success status code 250, 251 + // expected failure status code 550, 551, 552, 553, 450, 451, 452 + // expected error status code 500, 501, 503, 421 + if (!altSendData(buf, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_header_recipient, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED)) + return false; + } + } + + // Construct 'Cc' header field. + for (uint8_t i = 0; i < msg->_cc.size(); i++) + { + appendAddressHeaderField(buf2, msg->_cc[i], esp_mail_rfc822_header_field_cc, i == 0, i > 0, i == msg->_cc.size() - 1); + if (!imap) + { + // only address + buf = smtp_cmd_post_tokens[esp_mail_smtp_command_rcpt]; + buf += smtp_commands[esp_mail_smtp_command_to].text; + appendString(buf, msg->_cc[i].email.c_str(), false, false, esp_mail_string_mark_type_angle_bracket); + + smtp->_canForward = true; + + // expected success status code 250, 251 + // expected failure status code 550, 551, 552, 553, 450, 451, 452 + // expected error status code 500, 501, 503, 421 + if (!altSendData(buf, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_header_recipient, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED)) + return false; + } + } + + if (!imap && smtp) + { + for (uint8_t i = 0; i < msg->_bcc.size(); i++) + { + // only address + buf = smtp_cmd_post_tokens[esp_mail_smtp_command_rcpt]; + buf += smtp_commands[esp_mail_smtp_command_to].text; + appendString(buf, msg->_bcc[i].email.c_str(), false, false, esp_mail_string_mark_type_angle_bracket); + + smtp->_canForward = true; + + // expected success status code 250, 251 + // expected failure status code 550, 551, 552, 553, 450, 451, 452 + // expected error status code 500, 501, 503, 421 + if (!altSendData(buf, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_header_recipient, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED)) + return false; + } + +#if !defined(SILENT_MODE) + altSendCallback(smtp, esp_mail_cb_str_5 /* "Sending message body..." */, esp_mail_dbg_str_9 /* "send message body" */, esp_mail_debug_tag_type_client, true, false); +#endif + if (smtp->_feature_capability[esp_mail_smtp_send_capability_chunking] && msg->enable.chunking) + { + smtp->_chunkedEnable = true; + if (!sendBDAT(smtp, msg, buf2.length(), false)) + return false; + } + else + { + // expected success status code 354 + // expected failure status code 451, 554 + // expected error status code 500, 501, 503, 421 + MB_String sdata = smtp_commands[esp_mail_smtp_command_data].text; + if (!altSendData(sdata, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_body, esp_mail_smtp_status_code_354, SMTP_STATUS_SEND_BODY_FAILED)) + return false; + } + } + +#if defined(ENABLE_IMAP) && !defined(SILENT_MODE) + if (imap) + altSendCallback(smtp, esp_mail_cb_str_14 /* "Appending message..." */, esp_mail_dbg_str_69 /* "appending message" */, esp_mail_debug_tag_type_client, true, false); + +#endif + + if (!altSendData(buf2, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + MB_String s; + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_subject].text, msg->subject.c_str(), false, true); + + if (msg->timestamp.tag.length() && msg->timestamp.format.length()) + s.replaceAll(msg->timestamp.tag, Time.getDateTimeString(Time.getCurrentTimestamp(), msg->timestamp.format.c_str())); + + // Construct the 'Date' header field. + // The 'Date' header field should be valid and should be included in the message headers to + // prevent the 'spam' or 'junk' message considered by mail server. + + bool dateHdr = false; + MB_String dt; + + uint32_t ts = 0; + + if (smtp) + smtp->ts = ts; + + // Check if valid 'Date' field assigned from custom headers. + if (msg->_hdr.size() > 0) + { + for (uint8_t k = 0; k < msg->_hdr.size(); k++) + { + appendString(s, msg->_hdr[k].c_str(), false, true); + + if (getHeader(msg->_hdr[k].c_str(), rfc822_headers[esp_mail_rfc822_header_field_date].text, dt, false)) + { + ts = Time.getTimestamp(dt.c_str(), true); + dateHdr = ts > ESP_MAIL_CLIENT_VALID_TS; + if (smtp) + smtp->ts = ts; + } + } + } + + // Check if valid 'Date' field assigned from SMTP_Message's date property. + if (!dateHdr && msg->date.length() > 0) + { + dt = msg->date; + ts = Time.getTimestamp(msg->date.c_str(), true); + dateHdr = ts > ESP_MAIL_CLIENT_VALID_TS; + if (smtp) + smtp->ts = ts; + } + + if (dateHdr) + { + // 'Date' header field assigned. + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_date].text, dt.c_str(), false, true); + } + else + { + // If there is no 'Date' field assigned, get time from system and construct 'Date' header field. + if (smtp) + { + ts = MailClient.Time.getCurrentTimestamp(); + smtp->ts = ts; + } + else if (imap) + { +#if defined(ENABLE_IMAP) + if (calDataLen) + { + ts = MailClient.Time.getCurrentTimestamp(); + imap_ts = ts; + } + else + ts = imap_ts; +#endif + } + + if (ts > ESP_MAIL_CLIENT_VALID_TS) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_date].text, Time.getDateTimeString().c_str(), false, true); + } + + if (msg->response.reply_to.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_reply_to].text, msg->response.reply_to.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + + if (msg->response.return_path.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_return_path].text, msg->response.return_path.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + + if (msg->in_reply_to.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_in_reply_to].text, msg->in_reply_to.c_str(), false, true); + + if (msg->references.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_references].text, msg->references.c_str(), false, true); + + if (msg->comments.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_comments].text, msg->comments.c_str(), false, true); + + if (msg->keywords.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_keywords].text, msg->keywords.c_str(), false, true); + + if (msg->messageID.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_msg_id].text, msg->messageID.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + + appendHeaderField(s, message_headers[esp_mail_message_header_field_mime_version].text, esp_mail_str_51 /* "1.0" */, false, true); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + return sendMSGData(smtp, msg, closeSession, rfc822MSG); +} + +void ESP_Mail_Client::altSendCallback(SMTPSession *smtp, PGM_P cbMsg, PGM_P dbMsg, esp_mail_debug_tag_type type, bool prependCRLF, bool success) +{ +#if !defined(SILENT_MODE) + if (smtp) + printDebug(smtp, cbMsg, dbMsg, type, prependCRLF, success); + else if (imap && !calDataLen) + { +#if defined(ENABLE_IMAP) + printDebug(imap, cbMsg, dbMsg, type, prependCRLF, success); +#endif + } +#endif +} + +bool ESP_Mail_Client::sendMSGData(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG) +{ + MB_String s; + MB_String mixed = getMIMEBoundary(15); + MB_String alt = getMIMEBoundary(15); + + if (numAtt(smtp, esp_mail_att_type_attachment, msg) == 0 && msg->_parallel.size() == 0 && msg->_rfc822.size() == 0) + { + if (msg->type == (esp_mail_msg_type_plain | esp_mail_msg_type_html | esp_mail_msg_type_enriched) || numAtt(smtp, esp_mail_att_type_inline, msg) > 0) + { + if (!sendMSG(smtp, msg, alt)) + return addSendingResult(smtp, msg, false, true); + } + else if (msg->type != esp_mail_msg_type_none) + { + if (!sendPartText(smtp, msg, msg->type, "")) + return addSendingResult(smtp, msg, false, true); + } + } + else + { + s.clear(); + appendMultipartContentType(s, esp_mail_multipart_type_mixed, mixed.c_str()); + appendBoundaryString(s, mixed.c_str(), false, true); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendMSG(smtp, msg, alt)) + return addSendingResult(smtp, msg, false, true); + + if (!sendBDAT(smtp, msg, 2, false)) + return false; + + MB_String str; + appendNewline(str); + + if (!altSendData(str, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + +#if !defined(SILENT_MODE) + altSendCallback(smtp, esp_mail_cb_str_6 /* "Sending attachments..." */, esp_mail_dbg_str_10 /* "send attachments" */, esp_mail_debug_tag_type_client, true, false); +#endif + if (!sendAttachments(smtp, msg, mixed)) + return addSendingResult(smtp, msg, false, true); + + if (!sendParallelAttachments(smtp, msg, mixed)) + return addSendingResult(smtp, msg, false, true); + + if (!sendRFC822Msg(smtp, msg, mixed, closeSession, msg->_rfc822.size() > 0)) + return addSendingResult(smtp, msg, false, true); + + s.clear(); + appendBoundaryString(s, mixed.c_str(), true, false); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + + if (!rfc822MSG && !imap && smtp) + { +#if !defined(SILENT_MODE) + altSendCallback(smtp, esp_mail_cb_str_11 /* "Finishing the message sending..." */, esp_mail_dbg_str_16 /* "finishing the message sending" */, esp_mail_debug_tag_type_client, true, false); +#endif + if (smtp->_chunkedEnable) + { + + if (!sendBDAT(smtp, msg, 0, true)) + return false; + + // expected success status code 250 + // expected failure status code 451, 554 + // expected error status code 500, 501, 503, 421 + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_chunk_termination, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_BODY_FAILED)) + return false; + } + else + { + // expected success status code 250 + // expected failure status code 451, 554 + // expected error status code 500, 501, 503, 421 + MB_String str = smtp_commands[esp_mail_smtp_command_terminate].text; + if (!altSendData(str, false, smtp, msg, true, true, esp_mail_smtp_cmd_send_body, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_BODY_FAILED)) + return false; + } + + addSendingResult(smtp, msg, true, !closeSession); + + if (closeSession && smtp) + { + if (!smtp->closeSession()) + return false; + } + } + if (smtp) + smtp->_cbData._success = true; + return true; +} + +bool ESP_Mail_Client::sendRFC822Msg(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, bool closeSession, bool rfc822MSG) +{ + if (msg->_rfc822.size() == 0) + return true; + + MB_String buf; + + for (uint8_t i = 0; i < msg->_rfc822.size(); i++) + { + buf.clear(); + getRFC822PartHeader(smtp, buf, boundary); + + getRFC822MsgEnvelope(smtp, &msg->_rfc822[i], buf); + + if (!sendBDAT(smtp, msg, buf.length(), false)) + return false; + + if (!altSendData(buf, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendMSGData(smtp, &msg->_rfc822[i], closeSession, rfc822MSG)) + return false; + } + + return true; +} + +void ESP_Mail_Client::getRFC822MsgEnvelope(SMTPSession *smtp, SMTP_Message *msg, MB_String &buf) +{ + if (msg->date.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_date].text, msg->date.c_str(), false, true); + else + { + time_t now = 0; + if (smtp) + now = MailClient.Time.getCurrentTimestamp(); + else if (imap) + { +#if defined(ENABLE_IMAP) + if (calDataLen) + { + now = MailClient.Time.getCurrentTimestamp(); + imap_ts = now; + } + else + now = imap_ts; +#endif + } + + if (now > ESP_MAIL_CLIENT_VALID_TS) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_date].text, Time.getDateTimeString().c_str(), false, true); + } + + // Construct 'From' header field. + if (msg->from.email.length() > 0) + appendAddressHeaderField(buf, msg->from, esp_mail_rfc822_header_field_from, true, false, true); + + // Construct 'Sender' header field. + if (msg->sender.email.length() > 0) + appendAddressHeaderField(buf, msg->sender, esp_mail_rfc822_header_field_sender, true, false, true); + + if (msg->response.reply_to.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_reply_to].text, msg->response.reply_to.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + + if (msg->response.return_path.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_return_path].text, msg->response.return_path.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + + // Construct 'To' header field. + for (uint8_t i = 0; i < msg->_rcp.size(); i++) + appendAddressHeaderField(buf, msg->_rcp[i], esp_mail_rfc822_header_field_to, i == 0, i > 0, i == msg->_rcp.size() - 1); + + for (uint8_t i = 0; i < msg->_cc.size(); i++) + appendAddressHeaderField(buf, msg->_cc[i], esp_mail_rfc822_header_field_cc, i == 0, i > 0, i == msg->_cc.size() - 1); + + for (uint8_t i = 0; i < msg->_bcc.size(); i++) + appendAddressHeaderField(buf, msg->_bcc[i], esp_mail_rfc822_header_field_bcc, i == 0, i > 0, i == msg->_bcc.size() - 1); + + if (msg->subject.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_subject].text, msg->subject.c_str(), false, true); + + if (msg->keywords.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_keywords].text, msg->keywords.c_str(), false, true); + + if (msg->comments.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_comments].text, msg->comments.c_str(), false, true); + + if (msg->in_reply_to.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_in_reply_to].text, msg->in_reply_to.c_str(), false, true); + + if (msg->references.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_references].text, msg->references.c_str(), false, true); + + if (msg->messageID.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_msg_id].text, msg->messageID.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); +} + +void ESP_Mail_Client::appendBoundaryString(MB_String &buf, const char *value, bool endMark, bool newLine) +{ + buf += esp_mail_str_9; /* "--" */ + buf += value; + if (endMark) + buf += esp_mail_str_9; /* "--" */ + if (newLine) + appendNewline(buf); +} + +bool ESP_Mail_Client::sendBDAT(SMTPSession *smtp, SMTP_Message *msg, int len, bool last) +{ + if (!smtp) + return true; + + if (!smtp->_chunkedEnable || !msg->enable.chunking) + return true; + + smtp->_chunkCount++; + + MB_String bdat = smtp_cmd_post_tokens[esp_mail_smtp_command_bdat]; + bdat += len; + if (last) + bdat += smtp_cmd_pre_tokens[esp_mail_smtp_command_last]; + + if (smtpSend(smtp, bdat.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return addSendingResult(smtp, msg, false, true); + + if (!smtp->_feature_capability[esp_mail_smtp_send_capability_pipelining]) + { + // expected success status code 250 + // expected failure status code 451, 554 + // expected error status code 500, 501, 503, 421 + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_send_body, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_BODY_FAILED)) + return addSendingResult(smtp, msg, false, true); + smtp->_chunkCount = 0; + } + return true; +} + +void ESP_Mail_Client::getXEncoding(esp_mail_msg_xencoding &xencoding, const char *enc) +{ + if (strcmp(enc, Content_Transfer_Encoding::enc_binary) == 0) + xencoding = esp_mail_msg_xencoding_binary; + else if (strcmp(enc, Content_Transfer_Encoding::enc_8bit) == 0) + xencoding = esp_mail_msg_xencoding_8bit; + else if (strcmp(enc, Content_Transfer_Encoding::enc_7bit) == 0) + xencoding = esp_mail_msg_xencoding_7bit; +} + +void ESP_Mail_Client::checkUnencodedData(SMTPSession *smtp, SMTP_Message *msg) +{ + if (msg->type & esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched || msg->type & esp_mail_msg_type_html) + { + if ((msg->type & esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched) > 0 && msg->text.transfer_encoding.length() > 0) + getXEncoding(msg->text._int.xencoding, msg->text.transfer_encoding.c_str()); + + if ((msg->type & esp_mail_msg_type_html) > 0 && msg->html.transfer_encoding.length() > 0) + getXEncoding(msg->html._int.xencoding, msg->html.transfer_encoding.c_str()); + } + + for (size_t i = 0; i < msg->_att.size(); i++) + getXEncoding(msg->_att[i]._int.xencoding, msg->_att[i].descr.transfer_encoding.c_str()); +} + +bool ESP_Mail_Client::altIsCB(SMTPSession *smtp) +{ + bool cb = false; + if (smtp) + cb = smtp->_statusCallback != NULL; + else if (imap && !calDataLen) + { +#if defined(ENABLE_IMAP) + cb = imap->_statusCallback != NULL; +#endif + } + + return cb; +} + +bool ESP_Mail_Client::altIsDebug(SMTPSession *smtp) +{ + bool dbg = false; + if (smtp) + dbg = smtp->_debug; + else if (imap && !calDataLen) + { +#if defined(ENABLE_IMAP) + dbg = imap->_debug; +#endif + } + + return dbg; +} + +bool ESP_Mail_Client::sendBlobAttachment(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att) +{ + bool cb = altIsCB(smtp); + uint32_t addr = altProgressPtr(smtp); + + if (strcmp(att->descr.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0 && strcmp(att->descr.transfer_encoding.c_str(), att->descr.content_encoding.c_str()) != 0) + { + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.rawPtr = att->blob.data; + data_info.size = att->blob.size; + data_info.flashMem = att->_int.flash_blob; + data_info.filename = att->descr.filename.c_str(); + + if (!sendBase64(smtp, msg, data_info, true, cb)) + return false; + + return true; + } + else + { + if (att->blob.size > 0) + { + if (strcmp(att->descr.content_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) + { + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.rawPtr = att->blob.data; + data_info.size = att->blob.size; + data_info.flashMem = att->_int.flash_blob; + data_info.filename = att->descr.filename.c_str(); + + if (!sendBase64(smtp, msg, data_info, false, cb)) + return false; + + return true; + } + else + { + + size_t chunkSize = ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE; + size_t writeLen = 0; + uint8_t *buf = allocMem(chunkSize); + while (writeLen < att->blob.size) + { + if (writeLen > att->blob.size - chunkSize) + chunkSize = att->blob.size - writeLen; + + if (!sendBDAT(smtp, msg, chunkSize, false)) + break; + memcpy_P(buf, att->blob.data, chunkSize); + + if (!altSendData(buf, chunkSize, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + break; + + if (smtp->_debug) + uploadReport(att->descr.filename.c_str(), addr, 100 * writeLen / att->blob.size); + + writeLen += chunkSize; + } + + // release memory + freeMem(&buf); + + if (smtp->_debug) + uploadReport(att->descr.filename.c_str(), addr, 100); + + return writeLen >= att->blob.size; + } + } + } + return false; +} + +bool ESP_Mail_Client::sendFile(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att) +{ + bool cb = altIsCB(smtp); + uint32_t addr = altProgressPtr(smtp); + + if (strcmp(att->descr.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0 && strcmp(att->descr.transfer_encoding.c_str(), att->descr.content_encoding.c_str()) != 0) + { + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.filename = att->descr.filename.c_str(); + data_info.storageType = att->file.storage_type; + + if (!sendBase64(smtp, msg, data_info, true, cb)) + return false; + + return true; + } + else + { + if (mbfs->size(mbfs_type att->file.storage_type) > 0) + { + if (strcmp(att->descr.content_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) + { + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.filename = att->descr.filename.c_str(); + data_info.storageType = att->file.storage_type; + + if (!sendBase64(smtp, msg, data_info, false, cb)) + return false; + + return true; + } + else + { + int chunkSize = ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE; + int writeLen = 0; + + int fileSize = mbfs->size(mbfs_type att->file.storage_type); + + if (fileSize < chunkSize) + chunkSize = fileSize; + + uint8_t *buf = allocMem(chunkSize); + + while (writeLen < fileSize && mbfs->available(mbfs_type att->file.storage_type)) + { + if (writeLen > fileSize - chunkSize) + chunkSize = fileSize - writeLen; + int readLen = mbfs->read(mbfs_type att->file.storage_type, buf, chunkSize); + if (readLen != chunkSize) + { + errorStatusCB(smtp, this->imap, MB_FS_ERROR_FILE_IO_ERROR, false); + break; + } + + if (!sendBDAT(smtp, msg, chunkSize, false)) + break; + + if (!altSendData(buf, chunkSize, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + break; + + if (smtp->_debug) + uploadReport(att->descr.filename.c_str(), addr, 100 * writeLen / fileSize); + + writeLen += chunkSize; + } + + // release memory + freeMem(&buf); + + if (smtp->_debug) + uploadReport(att->descr.filename.c_str(), addr, 100); + + return writeLen == fileSize; + } + } + return false; + } + return false; +} + +bool ESP_Mail_Client::sendParallelAttachments(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary) +{ + if (msg->_parallel.size() == 0) + return true; + + MB_String parallel = getMIMEBoundary(15); + MB_String buf; + + appendBoundaryString(buf, boundary.c_str(), false, true); + + appendMultipartContentType(buf, esp_mail_multipart_type_parallel, parallel.c_str()); + + if (!sendBDAT(smtp, msg, buf.length(), false)) + return false; + + if (!altSendData(buf, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendAttachments(smtp, msg, parallel, true)) + return addSendingResult(smtp, msg, false, true); + + buf.clear(); + appendBoundaryString(buf, parallel.c_str(), true, false); + + if (!sendBDAT(smtp, msg, buf.length(), false)) + return false; + + if (!altSendData(buf, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + return true; +} + +bool ESP_Mail_Client::sendAttachments(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, bool parallel) +{ + MB_String s; + MB_String buf; + int cnt = 0; + + SMTP_Attachment *att = nullptr; + + size_t sz = msg->_att.size(); + if (parallel) + sz = msg->_parallel.size(); + + for (size_t i = 0; i < sz; i++) + { + if (parallel) + att = &msg->_parallel[i]; + else + att = &msg->_att[i]; + + if (att->_int.att_type == esp_mail_att_type_attachment) + { +#if !defined(SILENT_MODE) + altSendCallback(smtp, att->descr.filename.c_str(), att->descr.filename.c_str(), esp_mail_debug_tag_type_client, true, false); +#endif + cnt++; + + if (att->file.storage_type == esp_mail_file_storage_type_none) + { + if (!att->blob.data) + continue; + + if (att->blob.size == 0) + continue; + + buf.clear(); + getAttachHeader(buf, boundary, att, att->blob.size, false); + + if (!sendBDAT(smtp, msg, buf.length(), false)) + return false; + + if (!altSendData(buf, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendBlobAttachment(smtp, msg, att)) + return false; + + if (!sendBDAT(smtp, msg, 2, false)) + return false; + + MB_String str; + appendNewline(str); + + if (!altSendData(str, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + else + { + if (att->file.storage_type == esp_mail_file_storage_type_sd && !smtp->_sdStorageChecked && !smtp->_sdStorageReady) + { + smtp->_sdStorageChecked = true; + smtp->_sdStorageReady = mbfs->sdReady(); + } + else if (att->file.storage_type == esp_mail_file_storage_type_flash && !smtp->_flashStorageChecked && !smtp->_flashStorageReady) + { + smtp->_flashStorageChecked = true; + smtp->_flashStorageReady = mbfs->flashReady(); + } + + if (!smtp->_flashStorageReady && !smtp->_sdStorageReady) + { + sendStorageNotReadyError(smtp, att->file.storage_type); + continue; + } + + if (openFileRead(smtp, msg, att, buf, boundary, false)) + { + + if (!sendFile(smtp, msg, att)) + return false; + + if (!sendBDAT(smtp, msg, 2, false)) + return false; + + MB_String str; + appendNewline(str); + + if (!altSendData(str, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + } + } + } + return true; +} + +void ESP_Mail_Client::altSendStorageErrorCB(SMTPSession *smtp, int err) +{ +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) + + if (smtp) + { + smtp->_responseStatus.errorCode = err; + smtp->_responseStatus.text.clear(); + +#if !defined(SILENT_MODE) + if (smtp->_statusCallback) + esp_mail_debug_print_tag(esp_mail_error_mem_str_3 /* "file does not exist or can't access" */, esp_mail_debug_tag_type_client, true); + + if (smtp->_debug) + esp_mail_debug_print_tag(smtp->errorReason().c_str(), esp_mail_debug_tag_type_error, true); +#endif + } + else if (imap && !calDataLen) + { +#if defined(ENABLE_IMAP) + + imap->_responseStatus.errorCode = err; + imap->_responseStatus.text.clear(); + +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + esp_mail_debug_print_tag(esp_mail_error_mem_str_3 /* "file does not exist or can't access" */, esp_mail_debug_tag_type_client, true); + + if (imap->_debug) + { + esp_mail_debug_print_tag(smtp->errorReason().c_str(), esp_mail_debug_tag_type_error, true); + } +#endif +#endif + } + +#endif +} + +bool ESP_Mail_Client::openFileRead(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att, MB_String &buf, const MB_String &boundary, bool inlined) +{ + int sz = -1; + MB_String filepath; + + if (att->file.path.length() > 0) + { + if (att->file.path[0] != '/') + filepath = esp_mail_str_10; /* "/" */ + filepath += att->file.path; + } + + sz = mbfs->open(filepath, mbfs_type att->file.storage_type, mb_fs_open_mode_read); + if (sz < 0) + { + + if (strlen(att->descr.filename.c_str()) > 0) + { + filepath.clear(); + if (att->descr.filename[0] != '/') + filepath = esp_mail_str_10; /* "/" */ + filepath += att->descr.filename; + } + + sz = mbfs->open(filepath, mbfs_type att->file.storage_type, mb_fs_open_mode_read); + } + + if (sz < 0) + { + altSendStorageErrorCB(smtp, sz); + } + else + { + + buf.clear(); + + getAttachHeader(buf, boundary, att, sz, inlined); + + if (!sendBDAT(smtp, msg, buf.length(), false)) + return false; + + if (!altSendData(buf, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + return true; + } + + return false; +} + +bool ESP_Mail_Client::openFileRead2(SMTPSession *smtp, SMTP_Message *msg, const char *path, esp_mail_file_storage_type storageType) +{ + + MB_String filepath; + + if (strlen(path) > 0) + { + if (path[0] != '/') + filepath = esp_mail_str_10; /* "/" */ + filepath += path; + } + + int sz = mbfs->open(filepath, mbfs_type storageType, mb_fs_open_mode_read); + if (sz < 0) + { + altSendStorageErrorCB(smtp, sz); + return false; + } + + return true; +} + +void ESP_Mail_Client::sendStorageNotReadyError(SMTPSession *smtp, esp_mail_file_storage_type storageType) +{ + +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) + +#if !defined(SILENT_MODE) + if (altIsCB(smtp)) + { + if (storageType == esp_mail_file_storage_type_flash) + { + esp_mail_debug_print_tag(esp_mail_error_mem_str_1 /* "flash Storage is not ready." */, esp_mail_debug_tag_type_error, true); +#if defined(MB_ARDUINO_PICO) + esp_mail_debug_print_tag(esp_mail_error_mem_str_10 /* "please make sure that the size of flash filesystem is not 0 in Pico." */, esp_mail_debug_tag_type_error, true); +#endif + } + else if (storageType == esp_mail_file_storage_type_sd) + esp_mail_debug_print_tag(esp_mail_error_mem_str_2 /* "SD Storage is not ready." */, esp_mail_debug_tag_type_error, true); + } + + if (altIsDebug(smtp)) + { + if (storageType == esp_mail_file_storage_type_flash) + { + esp_mail_debug_print_tag(esp_mail_error_mem_str_1 /* "flash Storage is not ready." */, esp_mail_debug_tag_type_error, true); +#if defined(MB_ARDUINO_PICO) + esp_mail_debug_print_tag(esp_mail_error_mem_str_10 /* "please make sure that the size of flash filesystem is not 0 in Pico." */, esp_mail_debug_tag_type_error, true); +#endif + } + else if (storageType == esp_mail_file_storage_type_sd) + esp_mail_debug_print_tag(esp_mail_error_mem_str_2 /* "SD Storage is not ready." */, esp_mail_debug_tag_type_error, true); + } +#endif + +#endif +} + +bool ESP_Mail_Client::sendInline(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, byte type) +{ + size_t num = numAtt(smtp, esp_mail_att_type_inline, msg) > 0; + +#if !defined(SILENT_MODE) + if (num > 0) + altSendCallback(smtp, esp_mail_cb_str_8 /* "Sending inline data..." */, esp_mail_dbg_str_14 /* "send inline data" */, esp_mail_debug_tag_type_client, true, false); +#endif + MB_String buf; + MB_String related = getMIMEBoundary(15); + int cnt = 0; + SMTP_Attachment *att = nullptr; + + MB_String s; + + appendBoundaryString(s, boundary.c_str(), false, true); + + appendMultipartContentType(s, esp_mail_multipart_type_related, related.c_str()); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendPartText(smtp, msg, type, related.c_str())) + return false; + +#if !defined(SILENT_MODE) + bool cb = altIsCB(smtp); + + if (cb && numAtt(smtp, esp_mail_att_type_inline, msg) > 0) + esp_mail_debug_print(); +#endif + + if (num > 0) + { + for (uint8_t i = 0; i < msg->_att.size(); i++) + { + att = &msg->_att[i]; + if (att->_int.att_type == esp_mail_att_type_inline) + { +#if !defined(SILENT_MODE) + altSendCallback(smtp, att->descr.filename.c_str(), att->descr.filename.c_str(), esp_mail_debug_tag_type_client, true, false); +#endif + cnt++; + + if (att->file.storage_type == esp_mail_file_storage_type_none) + { + if (!att->blob.data) + continue; + + if (att->blob.size == 0) + continue; +#if !defined(SILENT_MODE) + altSendCallback(smtp, att->descr.filename.c_str(), att->descr.filename.c_str(), esp_mail_debug_tag_type_client, true, false); +#endif + buf.clear(); + getAttachHeader(buf, related, att, att->blob.size, true); + + if (!sendBDAT(smtp, msg, buf.length(), false)) + return false; + + if (!altSendData(buf, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendBlobAttachment(smtp, msg, att)) + return false; + + if (!sendBDAT(smtp, msg, 2, false)) + return false; + + MB_String str; + appendNewline(str); + + if (!altSendData(str, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + else + { + + if (att->file.storage_type == esp_mail_file_storage_type_sd && !smtp->_sdStorageChecked && !smtp->_sdStorageReady) + { + smtp->_sdStorageChecked = true; + smtp->_sdStorageReady = mbfs->sdReady(); + } + else if (att->file.storage_type == esp_mail_file_storage_type_flash && !smtp->_flashStorageChecked && !smtp->_flashStorageReady) + { + smtp->_flashStorageChecked = true; + smtp->_flashStorageReady = mbfs->flashReady(); + } + + if (!smtp->_flashStorageReady && !smtp->_sdStorageReady) + { + sendStorageNotReadyError(smtp, att->file.storage_type); + continue; + } + + if (openFileRead(smtp, msg, att, buf, related, true)) + { + if (!sendFile(smtp, msg, att)) + return false; + + if (!sendBDAT(smtp, msg, 2, false)) + return false; + + MB_String str; + appendNewline(str); + + if (!altSendData(str, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + } + } + } + } + + appendNewline(s); + + appendBoundaryString(s, related.c_str(), true, true); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + return true; +} + +size_t ESP_Mail_Client::smtpSend(SMTPSession *smtp, PGM_P data, bool newline) +{ + if (!smtp || !sessionReady(smtp)) + return 0; + + int sent = 0; + + MB_String s = data; + + int toSend = newline ? s.length() + 2 : s.length(); + +#if !defined(SILENT_MODE) + if (!smtp->_customCmdResCallback && smtp->_debugLevel > esp_mail_debug_level_maintainer) + esp_mail_debug_print(s.c_str(), newline); +#endif + + sent = newline ? smtp->client.println(s.c_str()) : smtp->client.print(s.c_str()); + + if (sent != toSend) + { + errorStatusCB(smtp, this->imap, sent, false); + sent = 0; + } + + return sent; +} + +size_t ESP_Mail_Client::smtpSend(SMTPSession *smtp, int data, bool newline) +{ + MB_String s = data; + return smtpSend(smtp, s.c_str(), newline); +} + +size_t ESP_Mail_Client::smtpSend(SMTPSession *smtp, uint8_t *data, size_t size) +{ + if (!smtp || !sessionReady(smtp)) + return 0; + + size_t sent = smtp->client.write(data, size); + + if (sent != size) + { + errorStatusCB(smtp, this->imap, sent, false); + sent = 0; + } + + return sent; +} + +bool ESP_Mail_Client::handleSMTPError(SMTPSession *smtp, int err, bool ret) +{ + + if (err < 0) + errorStatusCB(smtp, this->imap, err, false); + + if (smtp) + { + closeTCPSession(smtp); + } + else if (imap && !calDataLen) + { +#if defined(ENABLE_IMAP) + if (imap->connected()) + closeTCPSession(imap); +#endif + } + + return ret; +} + +bool ESP_Mail_Client::sendPartText(SMTPSession *smtp, SMTP_Message *msg, uint8_t type, const char *boundary) +{ + MB_String header; + + if (strlen(boundary) > 0) + appendBoundaryString(header, boundary, false, true); + + if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) + { + if (msg->text.content_type.length() > 0) + { + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_type].text, msg->text.content_type.c_str(), false, false); + + bool firstProp = true; + + if (msg->text.charSet.length() > 0) + appendHeaderProp(header, message_headers[esp_mail_message_header_field_charset].text, msg->text.charSet.c_str(), firstProp, true, true, false); + + if (msg->text.flowed) + { + appendHeaderProp(header, message_headers[esp_mail_message_header_field_format].text, "flowed", firstProp, true, true, false); + appendHeaderProp(header, message_headers[esp_mail_message_header_field_delsp].text, "no", firstProp, true, true, false); + } + + if (msg->text.embed.enable) + { + appendHeaderProp(header, message_headers[esp_mail_message_header_field_name].text, esp_mail_str_13 /* "msg.txt" */, firstProp, false, true, false); + char *uid = getRandomUID(); + msg->text._int.cid = uid; + // release memory + freeMem(&uid); + } + + appendNewline(header); + } + + if (msg->text.transfer_encoding.length() > 0) + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, msg->text.transfer_encoding.c_str(), false, true); + } + else if (type == esp_mail_msg_type_html) + { + if (msg->text.content_type.length() > 0) + { + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_type].text, msg->html.content_type.c_str(), false, false); + bool firstProp = true; + + if (msg->html.charSet.length() > 0) + appendHeaderProp(header, message_headers[esp_mail_message_header_field_charset].text, msg->html.charSet.c_str(), firstProp, true, true, false); + + if (msg->html.embed.enable) + { + appendHeaderProp(header, message_headers[esp_mail_message_header_field_name].text, esp_mail_str_14 /* "msg.html" */, firstProp, true, true, false); + char *uid = getRandomUID(); + msg->html._int.cid = uid; + // release memory + freeMem(&uid); + } + + appendNewline(header); + } + + if (msg->html.transfer_encoding.length() > 0) + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, msg->html.transfer_encoding.c_str(), false, true); + } + + if ((type == esp_mail_msg_type_html && msg->html.embed.enable) || ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && msg->text.embed.enable)) + { + + if ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && msg->text.embed.enable) + appendEmbedMessage(header, msg->text, false); + else if (type == esp_mail_msg_type_html && msg->html.embed.enable) + appendEmbedMessage(header, msg->html, true); + } + + appendNewline(header); + + bool rawBlob = (msg->text.blob.size > 0 && (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched)) || (msg->html.blob.size > 0 && type == esp_mail_msg_type_html); + bool rawFile = (msg->text.file.name.length() > 0 && (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched)) || (msg->html.file.name.length() > 0 && type == esp_mail_msg_type_html); + bool rawContent = ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && msg->text.content.length() > 0) || (type == esp_mail_msg_type_html && msg->html.content.length() > 0); + bool nonCopyContent = ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && strlen(msg->text.nonCopyContent) > 0) || (type == esp_mail_msg_type_html && strlen(msg->html.nonCopyContent) > 0); + + if (rawBlob || rawFile || nonCopyContent) + { + if (!sendBDAT(smtp, msg, header.length(), false)) + return false; + + if (!altSendData(header, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + header.clear(); + + if (rawBlob || nonCopyContent) + { + if (!sendBlobBody(smtp, msg, type)) + return false; + } + else if (rawFile) + { + if (!sendFileBody(smtp, msg, type)) + return false; + } + } + else if (rawContent) + encodingText(smtp, msg, type, header); + + appendNewline(header); + + if (strlen(boundary) > 0) + appendNewline(header); + + if (!sendBDAT(smtp, msg, header.length(), false)) + return false; + + if (!altSendData(header, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + return true; +} + +bool ESP_Mail_Client::sendBlobBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type) +{ + + bool cb = altIsCB(smtp); + uint32_t addr = altProgressPtr(smtp); + + if (msg->text.blob.size == 0 && msg->html.blob.size == 0 && strlen(msg->text.nonCopyContent) == 0 && strlen(msg->html.nonCopyContent) == 0) + return true; + + bool ret = true; + int bufLen = 512; + size_t pos = 0; + + const uint8_t *raw = NULL; + int len = 0; + bool base64 = false; + + if ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched)) + { + if (strlen(msg->text.nonCopyContent) > 0) + { + raw = (const uint8_t *)msg->text.nonCopyContent; + len = strlen(msg->text.nonCopyContent); + } + else + { + raw = msg->text.blob.data; + len = msg->text.blob.size; + } + base64 = msg->text.transfer_encoding.length() > 0 && strcmp(msg->text.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0; + } + else if (type == esp_mail_msg_type_html) + { + if (strlen(msg->html.nonCopyContent) > 0) + { + raw = (const uint8_t *)msg->html.nonCopyContent; + len = strlen(msg->html.nonCopyContent); + } + else + { + raw = msg->html.blob.data; + len = msg->html.blob.size; + } + base64 = msg->html.transfer_encoding.length() > 0 && strcmp(msg->html.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0; + } + + if (base64) + { + MB_String s1 = esp_mail_str_15; /* "flash content message" */ + + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.flashMem = true; + data_info.filename = s1.c_str(); + data_info.rawPtr = raw; + data_info.size = len; + + return sendBase64(smtp, msg, data_info, true, cb); + } + + int available = len; + int sz = len; + uint8_t *buf = allocMem(bufLen + 1); + while (available) + { + if (available > bufLen) + available = bufLen; + + memcpy_P(buf, raw + pos, available); + + if (!sendBDAT(smtp, msg, available, false)) + { + ret = false; + break; + } + + if (!altSendData(buf, available, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + { + ret = false; + break; + } + + pos += available; + len -= available; + available = len; + + if (smtp->_debug) + { + MB_String s1 = esp_mail_str_15; /* "flash content message" */ + uploadReport(s1.c_str(), addr, 100 * pos / sz); + } + } + + // release memory + freeMem(&buf); + + return ret; +} + +bool ESP_Mail_Client::sendFileBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type) +{ + bool cb = altIsCB(smtp); + uint32_t addr = altProgressPtr(smtp); + + if (msg->text.file.name.length() == 0 && msg->html.file.name.length() == 0) + return true; + + bool ret = true; + int chunkSize = ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE; + int writeLen = 0; + + if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) + { + + if (!openFileRead2(smtp, msg, msg->text.file.name.c_str(), msg->text.file.type)) + return false; + + if (msg->text.transfer_encoding.length() > 0) + { + if (strcmp(msg->text.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) + { + MB_String s1 = esp_mail_str_16; /* "file content message" */ + + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.filename = s1.c_str(); + data_info.storageType = msg->text.file.type; + + return sendBase64(smtp, msg, data_info, true, cb); + } + } + + int fileSize = mbfs->size(mbfs_type msg->text.file.type); + + if (fileSize > 0) + { + + if (fileSize < chunkSize) + chunkSize = fileSize; + + uint8_t *buf = allocMem(chunkSize); + + while (writeLen < fileSize && mbfs->available(mbfs_type msg->text.file.type)) + { + if (writeLen > fileSize - chunkSize) + chunkSize = fileSize - writeLen; + int readLen = mbfs->read(mbfs_type msg->text.file.type, buf, chunkSize); + + if (readLen != chunkSize) + { + errorStatusCB(smtp, this->imap, MB_FS_ERROR_FILE_IO_ERROR, false); + break; + } + + if (!sendBDAT(smtp, msg, chunkSize, false)) + { + ret = false; + break; + } + + if (!altSendData(buf, chunkSize, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + { + ret = false; + break; + } + + if (smtp->_debug) + uploadReport(pgm2Str(esp_mail_str_16 /* "file content message" */), addr, 100 * writeLen / fileSize); + + writeLen += chunkSize; + } + + // release memory + freeMem(&buf); + + if (smtp->_debug) + uploadReport(pgm2Str(esp_mail_str_16 /* "file content message" */), addr, 100); + + return ret && writeLen == fileSize; + } + } + else if (type == esp_mail_message_type::esp_mail_msg_type_html) + { + + if (!openFileRead2(smtp, msg, msg->html.file.name.c_str(), msg->html.file.type)) + return false; + + if (msg->html.transfer_encoding.length() > 0) + { + if (strcmp(msg->html.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) + { + MB_String s1 = esp_mail_str_16; /* "file content message" */ + + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.filename = s1.c_str(); + data_info.storageType = msg->html.file.type; + + return sendBase64(smtp, msg, data_info, true, cb); + } + } + + int fileSize = mbfs->size(mbfs_type msg->html.file.type); + + if (fileSize > 0) + { + + if (fileSize < chunkSize) + chunkSize = fileSize; + + uint8_t *buf = allocMem(chunkSize); + + while (writeLen < fileSize && mbfs->available(mbfs_type msg->html.file.type)) + { + if (writeLen > fileSize - chunkSize) + chunkSize = fileSize - writeLen; + int readLen = mbfs->read(mbfs_type msg->html.file.type, buf, chunkSize); + + if (readLen != chunkSize) + { + errorStatusCB(smtp, this->imap, MB_FS_ERROR_FILE_IO_ERROR, false); + break; + } + + if (!sendBDAT(smtp, msg, chunkSize, false)) + { + ret = false; + break; + } + + if (!altSendData(buf, chunkSize, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + { + ret = false; + break; + } + + if (cb) + uploadReport(pgm2Str(esp_mail_str_16 /* "file content message" */), addr, 100 * writeLen / fileSize); + + writeLen += chunkSize; + } + + // release memory + freeMem(&buf); + + if (cb) + uploadReport(pgm2Str(esp_mail_str_16 /* "file content message" */), addr, 100); + + return ret && writeLen == fileSize; + } + } + + return false; +} + +void ESP_Mail_Client::encodingText(SMTPSession *smtp, SMTP_Message *msg, uint8_t type, MB_String &content) +{ + if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) + { + MB_String s = msg->text.content; + + if (msg->text.flowed) + formatFlowedText(s); + + if (msg->text.transfer_encoding.length() > 0) + { + if (strcmp(msg->text.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) + content += encodeBase64Str((const unsigned char *)s.c_str(), s.length()); + else if (strcmp(msg->text.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_qp) == 0) + { + char *out = allocMem(s.length() * 3 + 1); + encodeQP(s.c_str(), out); + content += out; + + // release memory + freeMem(&out); + } + else + content += s; + } + else + content += s; + } + else if (type == esp_mail_message_type::esp_mail_msg_type_html) + { + MB_String s = msg->html.content; + MB_String fnd, rep; + SMTP_Attachment *att = nullptr; + for (uint8_t i = 0; i < msg->_att.size(); i++) + { + att = &msg->_att[i]; + if (att->_int.att_type == esp_mail_att_type_inline) + { + MB_String filename(att->descr.filename); + + size_t found = filename.find_last_of("/\\"); + if (found != MB_String::npos) + filename = filename.substr(found + 1); + + appendString(fnd, filename.c_str(), false, false, esp_mail_string_mark_type_double_quote); + + MB_String cid = esp_mail_str_17; /* "cid:" */ + cid += att->descr.content_id.length() > 0 ? att->descr.content_id : att->_int.cid; + + appendString(rep, cid.c_str(), false, false, esp_mail_string_mark_type_double_quote); + + s.replaceAll(fnd, rep); + } + } + + if (msg->html.transfer_encoding.length() > 0) + { + if (strcmp(msg->html.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) + content += encodeBase64Str((const unsigned char *)s.c_str(), s.length()); + else if (strcmp(msg->html.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_qp) == 0) + { + char *out = allocMem(msg->html.content.length() * 3 + 1); + encodeQP(msg->html.content.c_str(), out); + content += out; + + // release memory + freeMem(&out); + } + else + content += s; + } + else + content += s; + s.clear(); + } + + if (msg->timestamp.tag.length() && msg->timestamp.format.length()) + content.replaceAll(msg->timestamp.tag, Time.getDateTimeString(Time.getCurrentTimestamp(), msg->timestamp.format.c_str())); +} + +void ESP_Mail_Client::encodeQP(const char *buf, char *out) +{ + int n = 0, p = 0, pos = 0; + for (n = 0; *buf; buf++) + { + if (n >= 73 && *buf != 10 && *buf != 13) + { + p = sprintf(out + pos, "=\r\n"); + pos += p; + n = 0; + } + + if (*buf == 10 || *buf == 13) + { + out[pos++] = *buf; + n = 0; + } + else if (*buf < 32 || *buf == 61 || *buf > 126) + { + p = sprintf(out + pos, "=%02X", (unsigned char)*buf); + n += p; + pos += p; + } + else if (*buf != 32 || (*(buf + 1) != 10 && *(buf + 1) != 13)) + { + out[pos++] = *buf; + n++; + } + else + { + p = sprintf(out + pos, "=20"); + n += p; + pos += p; + } + } +} + +/** Add the soft line break to the long text line (rfc 3676) + * and add Format=flowed parameter in the plain text content-type header. + * We use the existing white space as a part of this soft line break + * and set delSp="no" parameter to the header. + * + * Some servers are not rfc 3676 compliant. + * This causes the text lines are wrapped instead of joined. + * + * Some mail clients trim the space before the line break + * which makes the soft line break cannot be seen. + */ +void ESP_Mail_Client::formatFlowedText(MB_String &content) +{ + int count = 0; + MB_String qms; + int j = 0; + _vectorImpl tokens; + char *stk = strP(esp_mail_str_18); /* "\r\n" */ + char *qm = strP(esp_mail_str_20); /* ">" */ + splitToken(content.c_str(), tokens, stk); + content.clear(); + for (size_t i = 0; i < tokens.size(); i++) + { + if (tokens[i].length() > 0) + { + j = 0; + qms.clear(); + while (tokens[i][j] == qm[0]) + { + qms += qm; + j++; + } + softBreak(tokens[i], qms.c_str()); + if (count > 0) + content += stk; + content += tokens[i]; + } + else if (count > 0) + content += stk; + count++; + } + + // release memory + freeMem(&stk); + freeMem(&qm); + tokens.clear(); +} + +void ESP_Mail_Client::softBreak(MB_String &content, const char *quoteMarks) +{ + size_t len = 0; + char *stk = strP(esp_mail_str_2); /* " " */ + _vectorImpl tokens; + splitToken(content.c_str(), tokens, stk); + content.clear(); + for (size_t i = 0; i < tokens.size(); i++) + { + if (tokens[i].length() > 0) + { + if (len + tokens[i].length() + 3 > FLOWED_TEXT_LEN) + { + /* insert soft crlf */ + content += stk; + appendNewline(content); + + /* insert quote marks */ + if (strlen(quoteMarks) > 0) + content += quoteMarks; + content += tokens[i]; + len = tokens[i].length(); + } + else + { + if (len > 0) + { + content += stk; + len += strlen(stk); + } + content += tokens[i]; + len += tokens[i].length(); + } + } + } + + // release memory + freeMem(&stk); + tokens.clear(); +} + +bool ESP_Mail_Client::altSendData(MB_String &s, bool newLine, SMTPSession *smtp, SMTP_Message *msg, bool addSendResult, bool getResponse, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode) +{ + if (!imap && smtp) + { + if (smtpSend(smtp, s.c_str(), newLine) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + { + if (addSendResult) + return addSendingResult(smtp, msg, false, true); + else + return false; + } + + if (getResponse) + { + if (!handleSMTPResponse(smtp, cmd, statusCode, errCode)) + { + if (addSendResult) + return addSendingResult(smtp, msg, false, true); + else + return false; + } + } + } + else if (imap) + { +#if defined(ENABLE_IMAP) + if (newLine) + appendNewline(s); + MB_StringPtr data = toStringPtr(s); + + if (calDataLen) + dataLen += s.length(); + else + return imap->mSendData(data, false, esp_mail_imap_cmd_append); +#endif + } + + return true; +} + +bool ESP_Mail_Client::altSendData(uint8_t *data, size_t size, SMTPSession *smtp, SMTP_Message *msg, bool addSendResult, bool getResponse, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode) +{ + if (!imap && smtp) + { + if (smtpSend(smtp, data, size) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + { + if (addSendResult) + return addSendingResult(smtp, msg, false, true); + else + return false; + } + + if (getResponse) + { + if (!handleSMTPResponse(smtp, cmd, statusCode, errCode)) + { + if (addSendResult) + return addSendingResult(smtp, msg, false, true); + else + return false; + } + } + } + else if (imap) + { +#if defined(ENABLE_IMAP) + + if (calDataLen) + dataLen += size; + else + return imap->mSendData(data, size, false, esp_mail_imap_cmd_append); +#endif + } + + return true; +} + +bool ESP_Mail_Client::sendMSG(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary) +{ + MB_String s; + + if (numAtt(smtp, esp_mail_att_type_inline, msg) > 0) + { + appendMultipartContentType(s, esp_mail_multipart_type_alternative, boundary.c_str()); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (msg->type == esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched || msg->type == esp_mail_msg_type_html) + { + if (!sendInline(smtp, msg, boundary, msg->type)) + return false; + } + else if (msg->type == (esp_mail_msg_type_html | esp_mail_msg_type_enriched | esp_mail_msg_type_plain)) + { + if (!sendPartText(smtp, msg, esp_mail_msg_type_plain, boundary.c_str())) + return false; + if (!sendInline(smtp, msg, boundary, esp_mail_msg_type_html)) + return false; + } + + appendBoundaryString(s, boundary.c_str(), true, true); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + else + { + if (msg->type == esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched || msg->type == esp_mail_msg_type_html) + { + if (!sendPartText(smtp, msg, msg->type, "")) + return false; + } + else if (msg->type == (esp_mail_msg_type_html | esp_mail_msg_type_enriched | esp_mail_msg_type_plain)) + { + appendMultipartContentType(s, esp_mail_multipart_type_alternative, boundary.c_str()); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendPartText(smtp, msg, esp_mail_msg_type_plain, boundary.c_str())) + return false; + + if (!sendPartText(smtp, msg, esp_mail_msg_type_html, boundary.c_str())) + return false; + + s.clear(); + appendBoundaryString(s, boundary.c_str(), true, false); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + } + return true; +} + +void ESP_Mail_Client::getAttachHeader(MB_String &header, const MB_String &boundary, SMTP_Attachment *attach, size_t size, bool isInline) +{ + appendBoundaryString(header, boundary.c_str(), false, true); + + appendHeaderName(header, message_headers[esp_mail_message_header_field_content_type].text); + + if (attach->descr.mime.length() == 0) + { + MB_String mime; + mimeFromFile(attach->descr.filename.c_str(), mime); + if (mime.length() > 0) + appendString(header, mime.c_str(), false, false); + else + appendString(header, mimeinfo[esp_mail_file_extension_binary].mimeType, false, false); + } + else + appendString(header, attach->descr.mime.c_str(), false, false); + + MB_String filename = attach->descr.filename; + + size_t found = filename.find_last_of("/\\"); + if (found != MB_String::npos) + filename = filename.substr(found + 1); + + bool firstProp = true; + + appendHeaderProp(header, message_headers[esp_mail_message_header_field_name].text, filename.c_str(), firstProp, false, true, true); + + if (isInline || (!isInline && !attach->_int.parallel)) + { + appendHeaderName(header, message_headers[esp_mail_message_header_field_content_disposition].text); + appendString(header, isInline ? esp_mail_content_disposition_type_t::inline_ : esp_mail_content_disposition_type_t::attachment, false, false); + + firstProp = true; + appendHeaderProp(header, message_headers[esp_mail_message_header_field_filename].text, filename.c_str(), firstProp, true, true, false); + appendHeaderProp(header, message_headers[esp_mail_message_header_field_size].text, MB_String((int)size).c_str(), firstProp, true, false, true); + } + + if (isInline) + { + + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_location].text, filename.c_str(), false, true); + + appendHeaderName(header, message_headers[esp_mail_message_header_field_content_id].text); + if (attach->descr.content_id.length() > 0) + appendString(header, attach->descr.content_id.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + else + appendString(header, attach->_int.cid.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + } + + if (attach->descr.transfer_encoding.length() > 0) + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, attach->descr.transfer_encoding.c_str(), false, true); + + if (attach->descr.description.length() > 0) + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_description].text, attach->descr.description.c_str(), false, true); + + appendNewline(header); +} + +void ESP_Mail_Client::getRFC822PartHeader(SMTPSession *smtp, MB_String &header, const MB_String &boundary) +{ + appendBoundaryString(header, boundary.c_str(), false, true); + + appendHeaderName(header, message_headers[esp_mail_message_header_field_content_type].text); + appendString(header, esp_mail_str_22 /* "message/rfc822" */, false, true); + + appendHeaderName(header, message_headers[esp_mail_message_header_field_content_disposition].text); + appendString(header, esp_mail_content_disposition_type_t::attachment, false, true); + appendNewline(header); +} + +uint32_t ESP_Mail_Client::altProgressPtr(SMTPSession *smtp) +{ + uint32_t addr = 0; + if (smtp) + { + smtp->_lastProgress = -1; + addr = toAddr(smtp->_lastProgress); + } + else if (imap && !calDataLen) + { +#if defined(ENABLE_IMAP) + imap->_lastProgress = -1; + addr = toAddr(imap->_lastProgress); +#endif + } + + return addr; +} + +void ESP_Mail_Client::parseAuthCapability(SMTPSession *smtp, char *buf) +{ + if (!smtp) + return; + + if (strposP(buf, smtp_cmd_post_tokens[esp_mail_smtp_command_auth].c_str(), 0) > -1) + { + for (int i = esp_mail_auth_capability_plain; i < esp_mail_auth_capability_maxType; i++) + { + if (strposP(buf, smtp_auth_cap_pre_tokens[i].c_str(), 0) > -1) + { + smtp->_auth_capability[i] = true; + // Don't exit the loop + // and continue checking for all auth types + } + } + } + else if (strposP(buf, smtp_auth_capabilities[esp_mail_auth_capability_starttls].text, 0) > -1) + { + smtp->_auth_capability[esp_mail_auth_capability_starttls] = true; + return; + } + + for (int i = esp_mail_smtp_send_capability_binary_mime; i < esp_mail_smtp_send_capability_maxType; i++) + { + if (strposP(buf, smtp_send_cap_pre_tokens[i].c_str(), 0) > -1) + { + smtp->_feature_capability[i] = true; + return; + } + } +} + +bool ESP_Mail_Client::handleSMTPResponse(SMTPSession *smtp, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode) +{ + if (!smtp) + return false; + + smtp->_smtp_cmd = cmd; + + if (!reconnect(smtp)) + return false; + + bool ret = false; + char *response = nullptr; + int readLen = 0; + long dataTime = millis(); + int chunkBufSize = 0; + MB_String s, r, err; + int chunkIndex = 0; + int count = 0; + bool completedResponse = false; + smtp->_responseStatus.errorCode = 0; + smtp->_responseStatus.statusCode = 0; + smtp->_responseStatus.text.clear(); + uint8_t minResLen = 5; + struct esp_mail_smtp_response_status_t status; + + bool canForward = smtp->_canForward; + smtp->_canForward = false; + + status.id = smtp->_commandID; + + chunkBufSize = smtp->client.available(); + + while (smtp->connected() && chunkBufSize <= 0) + { + if (!reconnect(smtp, dataTime)) + return false; + if (!connected(smtp)) + { + if (cmd != esp_mail_smtp_cmd_logout) + errorStatusCB(smtp, this->imap, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, false); + + return false; + } + chunkBufSize = smtp->client.available(); + yield_impl(); + } + + dataTime = millis(); + + if (chunkBufSize > 1) + { + while (!completedResponse) + { + yield_impl(); + + if (!reconnect(smtp, dataTime)) + return false; + + if (!connected(smtp)) + { + if (cmd != esp_mail_smtp_cmd_logout) + errorStatusCB(smtp, this->imap, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, false); + return false; + } + + chunkBufSize = smtp->client.available(); + + if (chunkBufSize <= 0) + break; + + if (chunkBufSize > 0) + { + + chunkBufSize = ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE; + response = allocMem(chunkBufSize + 1); + + read_line: + + MB_String ovfBuf; + if (!readResponse(smtp, response, chunkBufSize, readLen, false, count, ovfBuf)) + { + closeTCPSession(smtp); + errorStatusCB(smtp, this->imap, MAIL_CLIENT_ERROR_READ_TIMEOUT, false); + return false; + } + + // If buffer overflown, copy from overflow buffer + if (ovfBuf.length() > 0) + { + // release memory + freeMem(&response); + response = allocMem(ovfBuf.length() + 1); + strcpy(response, ovfBuf.c_str()); + ovfBuf.clear(); + } + + if (readLen) + { + if (smtp->_smtp_cmd != esp_mail_smtp_command::esp_mail_smtp_cmd_initial_state) + { + // sometimes server sent multiple lines response + // sometimes rx buffer is not ready for a while + + if (strlen(response) < minResLen) + { + r += response; + chunkBufSize = 0; + while (chunkBufSize == 0) + { + yield_impl(); + if (!reconnect(smtp, dataTime)) + return false; + chunkBufSize = smtp->client.available(); + } + } + else + { + if (r.length() > 0) + { + r += response; + memset(response, 0, chunkBufSize); + strcpy(response, r.c_str()); + } +#if !defined(SILENT_MODE) + if (!smtp->_customCmdResCallback && smtp->_debugLevel > esp_mail_debug_level_basic) + esp_mail_debug_print((const char *)response, true); +#endif + } + + if (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_greeting) + parseAuthCapability(smtp, response); + } + + getResponseStatus(response, statusCode, 0, status); + + // No response code from greeting? + // Assumed multi-line greeting responses. + + if (status.statusCode == 0 && smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_initial_state) + { + +#if !defined(SILENT_MODE) + if (smtp->_debug && !smtp->_customCmdResCallback) + esp_mail_debug_print_tag(response, esp_mail_debug_tag_type_server, true); +#endif + + memset(response, 0, chunkBufSize + 1); + + // read again until we get the response code + goto read_line; + } + + // get the status code again for unexpected return code + if (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_start_tls || status.statusCode == 0) + getResponseStatus(response, esp_mail_smtp_status_code_0, 0, status); + + smtp->_responseStatus = status; + + if ((status.statusCode > 0 && status.statusCode == statusCode) || + (smtp->_smtp_cmd == esp_mail_smtp_cmd_start_tls && status.statusCode == esp_mail_smtp_status_code_220) || + (canForward && statusCode == esp_mail_smtp_status_code_250 && status.statusCode == esp_mail_smtp_status_code_251) + + ) + { + ret = true; + } + + if (strlen(response) >= minResLen) + { +#if !defined(SILENT_MODE) + if (smtp->_debug) + { + if (!smtp->_customCmdResCallback) + { + appendDebugTag(s, esp_mail_debug_tag_type_server, true); + if (smtp->_responseStatus.statusCode != esp_mail_smtp_status_code_334) + s += response; + else + { + // base64 encoded server challenge message + size_t olen = 0; + char *decoded = (char *)decodeBase64((const unsigned char *)status.text.c_str(), status.text.length(), &olen); + if (decoded && olen > 0) + { + s.append(decoded, olen); + err = decoded; + } + + // release memory + freeMem(&decoded); + } + esp_mail_debug_print(s.c_str(), true); + } + } + +#endif + r.clear(); + } + + if (smtp->_customCmdResCallback && (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_initial_state || smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_custom)) + { + struct esp_mail_smtp_response_status_t res = status; + res.text = response; + smtp->_customCmdResCallback(res); + } + + completedResponse = smtp->_responseStatus.statusCode > 0 && status.text.length() > minResLen; + + if (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_auth_xoauth2 && smtp->_responseStatus.statusCode == esp_mail_smtp_status_code_334) + { + if (isOAuthError(response, readLen, chunkIndex, 4)) + { + smtp->_responseStatus.text = err; + smtp->_responseStatus.errorCode = SMTP_STATUS_XOAUTH2_AUTH_FAILED; + ret = false; + } + } + + chunkIndex++; + + if (smtp->_chunkedEnable && smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_chunk_termination) + completedResponse = smtp->_chunkCount == chunkIndex; + } + + // release memory + freeMem(&response); + } + } + + if (!ret && !smtp->_customCmdResCallback) + handleSMTPError(smtp, errCode, false); + } + + return ret; +} + +void ESP_Mail_Client::getResponseStatus(const char *buf, esp_mail_smtp_status_code statusCode, int beginPos, struct esp_mail_smtp_response_status_t &status) +{ + if (statusCode > esp_mail_smtp_status_code_0) + { + int codeLength = 3; + int textLength = strlen(buf) - codeLength - 1; + + if ((int)strlen(buf) > codeLength && (buf[codeLength] == ' ' || buf[codeLength] == '-') && textLength > 0) + { + char *tmp = nullptr; + tmp = allocMem(codeLength + 1); + memcpy(tmp, &buf[0], codeLength); + + int code = atoi(tmp); + + // release memory + freeMem(&tmp); + + if (buf[codeLength] == ' ') + status.statusCode = code; + + int i = codeLength + 1; + + // We will collect the status text starting from status code 334 and 4xx + // The status text of 334 will be used for debugging display of the base64 server challenge + if (code == esp_mail_smtp_status_code_334 || code >= esp_mail_smtp_status_code_421) + { + // find the next sp + while (i < (int)strlen(buf) && buf[i] != ' ') + i++; + + // if sp found, set index to the next pos, otherwise set index to num length + 1 + i = (i < (int)strlen(buf) - 1) ? i + 1 : codeLength + 1; + + tmp = allocMem(textLength + 1); + memcpy(tmp, &buf[i], strlen(buf) - i - 1); + status.text += tmp; + // release memory + freeMem(&tmp); + } + } + } +} + +void ESP_Mail_Client::uploadReport(const char *filename, uint32_t pgAddr, int progress) +{ + if (pgAddr == 0) + return; + + int *lastProgress = addrTo(pgAddr); + + printProgress(progress, *lastProgress); +} + +MB_String ESP_Mail_Client::getMIMEBoundary(size_t len) +{ + MB_String tmp = boundary_table; + char *buf = allocMem(len); + if (len) + { + --len; + buf[0] = tmp[0]; + buf[1] = tmp[1]; + for (size_t n = 2; n < len; n++) + { + int key = rand() % (int)(tmp.length() - 1); + buf[n] = tmp[key]; + } + buf[len] = '\0'; + } + MB_String s = buf; + // release memory + freeMem(&buf); + return s; +} + +int ESP_Mail_Client::chunkAvailable(SMTPSession *smtp, esp_mail_smtp_send_base64_data_info_t &data_info) +{ + if (!data_info.rawPtr) + { + int fileSize = mbfs->size(mbfs_type data_info.storageType); + if (!fileSize) + { + errorStatusCB(smtp, this->imap, MB_FS_ERROR_FILE_IO_ERROR, false); + return -1; + } + + return mbfs->available(mbfs_type data_info.storageType); + } + + return data_info.size - data_info.dataIndex; +} + +int ESP_Mail_Client::getChunk(SMTPSession *smtp, esp_mail_smtp_send_base64_data_info_t &data_info, unsigned char *rawChunk, bool base64) +{ + int available = chunkAvailable(smtp, data_info); + + if (available <= 0) + return available; + + size_t size = base64 ? 3 : 4; + + if (data_info.dataIndex + size > data_info.size) + size = data_info.size - data_info.dataIndex; + + if (!data_info.rawPtr) + { + + int readLen = mbfs->read(mbfs_type data_info.storageType, rawChunk, size); + + if (readLen >= 0) + data_info.dataIndex += readLen; + + return readLen; + } + + if (data_info.flashMem) + memcpy_P(rawChunk, data_info.rawPtr + data_info.dataIndex, size); + else + memcpy(rawChunk, data_info.rawPtr + data_info.dataIndex, size); + + data_info.dataIndex += size; + + return size; +} + +void ESP_Mail_Client::closeChunk(esp_mail_smtp_send_base64_data_info_t &data_info) +{ + if (!data_info.rawPtr) + { + mbfs->close(mbfs_type data_info.storageType); + } +} + +bool ESP_Mail_Client::sendBase64(SMTPSession *smtp, SMTP_Message *msg, esp_mail_smtp_send_base64_data_info_t &data_info, bool base64, bool report) +{ + int size = chunkAvailable(smtp, data_info); + + if (size <= 0) + return false; + + data_info.size = size; + + bool ret = false; + + uint32_t addr = altProgressPtr(smtp); + + size_t chunkSize = (BASE64_CHUNKED_LEN * UPLOAD_CHUNKS_NUM) + (2 * UPLOAD_CHUNKS_NUM); + int bufIndex = 0; + bool dataReady = false; + int encodedCount = 0; + int read = 0; + + if (!base64) + { + if (data_info.size < chunkSize) + chunkSize = data_info.size; + } + + uint8_t *buf = allocMem(chunkSize); + memset(buf, 0, chunkSize); + + uint8_t *rawChunk = allocMem(base64 ? 3 : 4); + + if (report) + uploadReport(data_info.filename, addr, data_info.dataIndex / data_info.size); + + int min = base64 ? 3 : 1; + + while (chunkAvailable(smtp, data_info)) + { + + if (chunkAvailable(smtp, data_info) >= min) + { + + read = getChunk(smtp, data_info, rawChunk, base64); + + if (!read) + goto ex; + + getBuffer(base64, buf, rawChunk, encodedCount, bufIndex, dataReady, read, chunkSize); + + if (dataReady) + { + + if (!sendBDAT(smtp, msg, base64 ? bufIndex : bufIndex + 1, false)) + goto ex; + + if (!altSendData(buf, base64 ? bufIndex : bufIndex + 1, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + goto ex; + + memset(buf, 0, chunkSize); + bufIndex = 0; + } + + if (report) + uploadReport(data_info.filename, addr, 100 * data_info.dataIndex / data_info.size); + } + else if (base64) + { + read = getChunk(smtp, data_info, rawChunk, base64); + if (!read) + goto ex; + } + } + + closeChunk(data_info); + + if (base64) + { + if (bufIndex > 0) + { + if (!sendBDAT(smtp, msg, bufIndex, false)) + goto ex; + + if (!altSendData(buf, bufIndex, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + goto ex; + } + + if (read) + { + memset(buf, 0, chunkSize); + bufIndex = 0; + buf[bufIndex++] = b64_index_table[rawChunk[0] >> 2]; + if (read == 1) + { + buf[bufIndex++] = b64_index_table[(rawChunk[0] & 0x03) << 4]; + buf[bufIndex++] = '='; + } + else + { + buf[bufIndex++] = b64_index_table[((rawChunk[0] & 0x03) << 4) | (rawChunk[1] >> 4)]; + buf[bufIndex++] = b64_index_table[(rawChunk[1] & 0x0f) << 2]; + } + buf[bufIndex++] = '='; + + if (!sendBDAT(smtp, msg, bufIndex, false)) + goto ex; + + if (!altSendData(buf, bufIndex, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + goto ex; + } + } + + ret = true; + + if (report) + uploadReport(data_info.filename, addr, 100); + +ex: + // release memory + freeMem(&buf); + freeMem(&rawChunk); + + if (!ret) + closeChunk(data_info); + + return ret; +} + +void ESP_Mail_Client::getBuffer(bool base64, uint8_t *out, uint8_t *in, int &encodedCount, int &bufIndex, bool &dataReady, int &size, size_t chunkSize) +{ + if (base64) + { + size = 0; + out[bufIndex++] = b64_index_table[in[0] >> 2]; + out[bufIndex++] = b64_index_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + out[bufIndex++] = b64_index_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; + out[bufIndex++] = b64_index_table[in[2] & 0x3f]; + + encodedCount += 4; + + if (encodedCount == BASE64_CHUNKED_LEN) + { + if (bufIndex + 1 < (int)chunkSize) + { + out[bufIndex++] = 0x0d; + out[bufIndex++] = 0x0a; + } + encodedCount = 0; + } + + dataReady = bufIndex >= (int)chunkSize - 4; + } + else + { + memcpy(out + bufIndex, in, size); + bufIndex += size; + + if (bufIndex + 1 == BASE64_CHUNKED_LEN) + { + if (bufIndex + 2 < (int)chunkSize) + { + out[bufIndex++] = 0x0d; + out[bufIndex++] = 0x0a; + } + } + + dataReady = bufIndex + 1 >= (int)chunkSize - size; + } +} + +MB_FS *ESP_Mail_Client::getMBFS() +{ + return mbfs; +} + +SMTPSession::SMTPSession(Client *client) +{ + setClient(client); +} + +SMTPSession::SMTPSession() +{ +} + +SMTPSession::~SMTPSession() +{ + closeSession(); +} + +bool SMTPSession::connect(Session_Config *session_config, bool login) +{ + _sessionSSL = false; + _sessionLogin = login; + + if (session_config) + session_config->clearPorts(); + + this->_customCmdResCallback = NULL; + + int ptr = toAddr(*session_config); + session_config->addPtr(&_configPtrList, ptr); + + if (!handleConnection(session_config, _sessionSSL)) + return false; + + if (!_sessionLogin) + return true; + + _loginStatus = MailClient.smtpAuth(this, _sessionSSL); + + return _loginStatus; +} + +bool SMTPSession::mLogin(MB_StringPtr email, MB_StringPtr password, bool isToken) +{ + if (_loginStatus) + return true; + + if (!MailClient.sessionExisted(this)) + return false; + + _session_cfg->login.email = email; + + _session_cfg->login.accessToken.clear(); + _session_cfg->login.password.clear(); + + if (isToken) + _session_cfg->login.accessToken = password; + else + _session_cfg->login.password = password; + + _loginStatus = MailClient.smtpAuth(this, _sessionSSL); + + return _loginStatus; +} + +bool SMTPSession::isAuthenticated() +{ + return _authenticated; +} + +bool SMTPSession::isLoggedIn() +{ + return _loginStatus; +} + +int SMTPSession::customConnect(Session_Config *session_config, smtpResponseCallback callback, int commandID) +{ + this->_customCmdResCallback = callback; + + if (commandID > -1) + this->_commandID = commandID; + else + this->_commandID++; + + bool ssl = false; + if (!handleConnection(session_config, ssl)) + return -1; + + return this->_responseStatus.statusCode; +} + +bool SMTPSession::handleConnection(Session_Config *session_config, bool &ssl) +{ + _session_cfg = session_config; + + if (!client.isInitialized()) + return MailClient.handleSMTPError(this, TCP_CLIENT_ERROR_NOT_INITIALIZED); + + // Resources are also released if network disconnected. + if (!MailClient.reconnect(this)) + return false; + + // Close previous connection first to free resources. + MailClient.closeTCPSession(this); + + _session_cfg = session_config; + + MailClient.setCert(_session_cfg, _session_cfg->certificate.cert_data); + + ssl = false; + + if (!connect(ssl)) + { + MailClient.closeTCPSession(this); + return false; + } + + return true; +} + +bool SMTPSession::connect(bool &ssl) +{ + if (!MailClient.reconnect(this)) + return false; + + ssl = false; + _secure = true; + bool secureMode = true; + + MB_String s; + + client.rxBufDivider = 16; // minimum rx buffer for smtp status response + client.txBufDivider = 8; // medium tx buffer for faster attachment/inline data transfer + + MailClient.preparePortFunction(_session_cfg, true, _secure, secureMode, ssl); + +#if !defined(SILENT_MODE) + MailClient.printLibInfo(this); +#endif + + MailClient.prepareTime(_session_cfg, this); + + MailClient.setSecure(client, _session_cfg); + + if (!MailClient.beginConnection(_session_cfg, this, secureMode)) + return false; + + // server connected +#if !defined(SILENT_MODE) + if (!_customCmdResCallback) + { + + MailClient.printDebug(this, + esp_mail_dbg_str_4 /* "SMTP server connected" */, + esp_mail_cb_str_12 /* "SMTP server connected, wait for greeting..." */, + esp_mail_debug_tag_type_client, + true, + false); + } +#endif + + client.setTimeout(tcpTimeout); + + // expected success status code 220 for ready to service + // expected failure status code 421 + if (!MailClient.handleSMTPResponse(this, esp_mail_smtp_cmd_initial_state, esp_mail_smtp_status_code_220, SMTP_STATUS_SMTP_GREETING_GET_RESPONSE_FAILED)) + return false; + + return true; +} + +int SMTPSession::mSendCustomCommand(MB_StringPtr cmd, smtpResponseCallback callback, int commandID) +{ + _customCmdResCallback = callback; + + if (commandID > -1) + _commandID = commandID; + else + _commandID++; + + MB_String _cmd = cmd; + + if (MailClient.smtpSend(this, _cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return -1; + + if (!MailClient.handleSMTPResponse(this, esp_mail_smtp_cmd_custom, esp_mail_smtp_status_code_0, SMTP_STATUS_SEND_CUSTOM_COMMAND_FAILED)) + return -1; + + bool tlsCmd = false; + for (int i = esp_mail_auth_capability_plain; i < esp_mail_auth_capability_maxType; i++) + { + if (MailClient.strposP(_cmd.c_str(), smtp_auth_capabilities[i].text, 0) > -1) + { + if (i == esp_mail_auth_capability_starttls) + tlsCmd = true; + else + _waitForAuthenticate = true; + } + } + + if (MailClient.strposP(_cmd.c_str(), smtp_commands[esp_mail_smtp_command_quit].text, 0, false) > -1) + { + _authenticated = false; + _waitForAuthenticate = false; + } + + if (_waitForAuthenticate && _responseStatus.statusCode == esp_mail_smtp_status_code_235) + { + _authenticated = true; + _waitForAuthenticate = false; + _loginStatus = true; + } + + if (tlsCmd) + { + bool verify = false; + + if (_session_cfg) + verify = _session_cfg->certificate.verify; + + if (!client.connectSSL(verify)) + return false; + + // set the secure mode + if (_session_cfg) + { + // We reset the prefer connection mode in case user set it. + _session_cfg->secure.startTLS = false; + _session_cfg->secure.mode = esp_mail_secure_mode_undefined; + } + + _secure = true; + } + + return this->_responseStatus.statusCode; +} + +bool SMTPSession::mSendData(MB_StringPtr data) +{ + + MB_String _data = data; + + if (MailClient.smtpSend(this, _data.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + return true; +} + +bool SMTPSession::mSendData(uint8_t *data, size_t size) +{ + + if (MailClient.smtpSend(this, data, size) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + return true; +} + +void SMTPSession::debug(int level) +{ + if (level > esp_mail_debug_level_none) + { + if (level > esp_mail_debug_level_basic && level < esp_mail_debug_level_maintainer) + level = esp_mail_debug_level_basic; + _debugLevel = level; + _debug = true; + client.setDebugLevel(level); + } + else + { + _debugLevel = esp_mail_debug_level_none; + _debug = false; + client.setDebugLevel(0); + } +} + +String SMTPSession::errorReason() +{ + String s = MailClient.errorReason(true, _responseStatus.errorCode, ""); + return s; +} + +int SMTPSession::statusCode() +{ + return _responseStatus.statusCode; +} + +String SMTPSession::statusMessage() +{ + return _responseStatus.text.c_str(); +} + +int SMTPSession::errorCode() +{ + return _responseStatus.errorCode; +} + +bool SMTPSession::closeSession() +{ + + if (!connected()) + return false; + + _cbData._sentSuccess = _sentSuccessCount; + _cbData._sentFailed = _sentFailedCount; + +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_7 /* "Closing the session..." */, + esp_mail_dbg_str_11 /* "terminate the SMTP session" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + bool ret = true; + + if (_loginStatus) + { + +/* Sign out */ +#if !defined(ESP8266) + + // QUIT command asks SMTP server to close the TCP session. + // The connection may drop immediately. + + // There is memory leaks bug in ESP8266 BearSSLWiFiClientSecure class when the remote server + // drops the connection. + + ret = MailClient.smtpSend(this, smtp_commands[esp_mail_smtp_command_quit].text, true) > 0; + + // This may return false due to connection drops before get any response. + + // expected success status code 221 + // expected error status code 500 + MailClient.handleSMTPResponse(this, esp_mail_smtp_cmd_logout, esp_mail_smtp_status_code_221, SMTP_STATUS_SEND_BODY_FAILED); + + if (_responseStatus.statusCode == esp_mail_smtp_status_code_500) + return false; +#endif + + if (ret) + { + +#if !defined(SILENT_MODE) + if (_sentSuccessCount > 0) + { + MailClient.printDebug(this, + esp_mail_cb_str_13 /* "Message sent successfully" */, + esp_mail_dbg_str_12 /* "message sent successfully" */, + esp_mail_debug_tag_type_client, + true, + false); + } + + if (_statusCallback) + MailClient.callBackSendNewLine(this, true); +#endif + + _authenticated = false; + _waitForAuthenticate = false; + } + } + +#if !defined(SILENT_MODE) + if (_statusCallback) + sendingResult.clear(); +#endif + + return MailClient.handleSMTPError(this, 0, ret); +} + +bool SMTPSession::connected() +{ + return client.connected(); +} + +void SMTPSession::callback(smtpStatusCallback smtpCallback) +{ + _statusCallback = smtpCallback; +} + +SMTP_Status SMTPSession::status() +{ + return _cbData; +} + +void SMTPSession::setSystemTime(time_t ts, float gmtOffset) +{ + MailClient.Time.setTimestamp(ts, gmtOffset); +} + +void SMTPSession::keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount) +{ + this->client.keepAlive(tcpKeepIdleSeconds, tcpKeepIntervalSeconds, tcpKeepCount); +} + +bool SMTPSession::isKeepAlive() +{ + return this->client.isKeepAlive(); +} + +void SMTPSession::setTCPTimeout(unsigned long timeoutSec) +{ + tcpTimeout = timeoutSec; +} + +void SMTPSession::setClient(Client *client) +{ + this->client.setClient(client); +} + +void SMTPSession::setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password) +{ + this->client.setGSMClient(client, modem, pin, apn, user, password); +} + +void SMTPSession::networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB) +{ + this->client.networkConnectionRequestCallback(networkConnectionCB); +} + +void SMTPSession::networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB) +{ + this->client.networkStatusRequestCallback(networkStatusCB); +} + +void SMTPSession::setNetworkStatus(bool status) +{ + this->client.setNetworkStatus(status); + MailClient.networkStatus = status; +} + +void SMTPSession::setSSLBufferSize(int rx, int tx) +{ + this->client.setIOBufferSize(rx, tx); +} + +SMTP_Status::SMTP_Status() +{ +} + +SMTP_Status::~SMTP_Status() +{ + empty(); +} + +const char *SMTP_Status::info() +{ + return _info.c_str(); +} + +bool SMTP_Status::success() +{ + return _success; +} + +size_t SMTP_Status::completedCount() +{ + return _sentSuccess; +} + +size_t SMTP_Status::failedCount() +{ + return _sentFailed; +} + +void SMTP_Status::empty() +{ + _info.clear(); +} + +#endif + +#endif /* ESP_MAIL_SMTP_H */ diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_TCPClient.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_TCPClient.h new file mode 100644 index 000000000000..9302f6d4e042 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_TCPClient.h @@ -0,0 +1,1093 @@ +/** + * + * The Network Upgradable Arduino Secure TCP Client Class, ESP_Mail_TCPClient.h v1.0.1 + * + * Created August 27, 2023 + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef ESP_MAIL_TCPCLIENT_H +#define ESP_MAIL_TCPCLIENT_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" + +#include "ESP_Mail_Const.h" + +#if defined(ESP32) && (defined(ENABLE_SMTP) || defined(ENABLE_IMAP)) +#include "IPAddress.h" +#include "lwip/sockets.h" +#endif + +#if defined(ESP32) + +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) +#define WIFI_HAS_HOST_BY_NAME +#endif +#include "extras/WiFiClientImpl.h" +#define BASE_WIFICLIENT WiFiClientImpl + +#elif defined(ESP_MAIL_WIFI_IS_AVAILABLE) +#include "WiFiClient.h" +#define BASE_WIFICLIENT WiFiClient +#endif + +#include "SSLClient/ESP_SSLClient.h" + +class ESP_Mail_TCPClient +{ +public: + ESP_Mail_TCPClient() + { +#if !defined(ESP_MAIL_DISABLE_SSL) + _tcp_client = new ESP_SSLClient(); +#endif + } + + ~ESP_Mail_TCPClient() + { + clear(); +#if !defined(ESP_MAIL_DISABLE_SSL) + if (_tcp_client) + delete _tcp_client; + _tcp_client = nullptr; +#endif + } + + /** + * Set the client. + * @param client The Client interface. + */ + void setClient(Client *client) + { + clear(); + _basic_client = client; + _client_type = esp_mail_client_type_external_basic_client; + } + + /** Assign TinyGsm Clients. + * + * @param client The pointer to TinyGsmClient. + * @param modem The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data + * @param pin The SIM pin. + * @param apn The GPRS APN (Access Point Name). + * @param user The GPRS user. + * @param password The GPRS password. + */ + void setGSMClient(Client *client, void *modem = nullptr, const char *pin = nullptr, const char *apn = nullptr, const char *user = nullptr, const char *password = nullptr) + { +#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) + _pin = pin; + _apn = apn; + _user = user; + _password = password; + _modem = modem; + _client_type = esp_mail_client_type_external_gsm_client; + _basic_client = client; +#endif + } + + /** + * Set Root CA certificate to verify. + * @param caCert The certificate. + */ + void setCACert(const char *caCert) + { +#if !defined(ESP_MAIL_DISABLE_SSL) + if (caCert) + { + if (_x509) + delete _x509; + + _x509 = new X509List(caCert); + _tcp_client->setTrustAnchors(_x509); + + setCertType(esp_mail_cert_type_data); + setTA(true); + } + else + { + setCertType(esp_mail_cert_type_none); + setInSecure(); + } +#endif + } + + /** + * Set Root CA certificate to verify. + * @param certFile The certificate file path. + * @param storageType The storage type mb_fs_mem_storage_type_flash or mb_fs_mem_storage_type_sd. + * @return true when certificate loaded successfully. + */ + bool setCertFile(const char *certFile, mb_fs_mem_storage_type storageType) + { +#if !defined(ESP_MAIL_DISABLE_SSL) + if (!_mbfs) + return false; + + if (_clock_ready && strlen(certFile) > 0) + { + MB_String filename = certFile; + if (filename.length() > 0) + { + if (filename[0] != '/') + filename.prepend('/'); + } + + int len = _mbfs->open(filename, storageType, mb_fs_open_mode_read); + if (len > -1) + { + uint8_t *der = (uint8_t *)_mbfs->newP(len); + if (_mbfs->available(storageType)) + _mbfs->read(storageType, der, len); + _mbfs->close(storageType); + + if (_x509) + delete _x509; + + _x509 = new X509List(der, len); + _tcp_client->setTrustAnchors(_x509); + setTA(true); + _mbfs->delP(&der); + + setCertType(esp_mail_cert_type_file); + } + } +#endif + + return getCertType() == esp_mail_cert_type_file; + } + + /** + * Set TCP connection time out in seconds. + * @param timeoutSec The time out in seconds. + */ + void setTimeout(uint32_t timeoutSec) + { + _tcp_client->setTimeout(timeoutSec); + } + + /** Set the BearSSL IO buffer size. + * + * @param rx The BearSSL receive buffer size in bytes. + * @param tx The BearSSL trasmit buffer size in bytes. + */ + void setIOBufferSize(int rx, int tx) + { + _rx_size = rx; + _tx_size = tx; + } + + /** + * Get the ethernet link status. + * @return true for link up or false for link down. + */ + bool ethLinkUp() + { + bool ret = false; + +#if !defined(ESP_MAIL_DISABLE_NATIVE_ETHERNET) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) + +#if defined(ESP_MAIL_ETH_IS_AVAILABLE) + +#if defined(ESP32) + if (validIP(ETH.localIP())) + { + ETH.linkUp(); + ret = true; + } +#elif defined(ESP8266) + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + if (!_session_config) + return false; +#endif + +#if defined(ESP8266) && defined(ESP8266_CORE_SDK_V3_X_X) + +#if defined(INC_ENC28J60_LWIP) + if (_session_config->spi_ethernet_module.enc28j60) + { + ret = _session_config->spi_ethernet_module.enc28j60->status() == WL_CONNECTED; + goto ex; + } +#endif +#if defined(INC_W5100_LWIP) + if (_session_config->spi_ethernet_module.w5100) + { + ret = _session_config->spi_ethernet_module.w5100->status() == WL_CONNECTED; + goto ex; + } +#endif +#if defined(INC_W5500_LWIP) + if (_session_config->spi_ethernet_module.w5500) + { + ret = _session_config->spi_ethernet_module.w5500->status() == WL_CONNECTED; + goto ex; + } +#endif +#elif defined(MB_ARDUINO_PICO) + +#endif + + return ret; + +#if defined(INC_ENC28J60_LWIP) || defined(INC_W5100_LWIP) || defined(INC_W5500_LWIP) + ex: +#endif + // workaround for ESP8266 Ethernet + delayMicroseconds(0); +#endif + +#endif + +#endif + + return ret; + } + + /** + * Checking for valid IP. + * @return true for valid. + */ + bool validIP(IPAddress ip) + { + char buf[16]; + sprintf(buf, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); + return strcmp(buf, "0.0.0.0") != 0; + } + + /** + * Ethernet DNS workaround. + */ + void ethDNSWorkAround() + { + +#if !defined(ESP_MAIL_DISABLE_NATIVE_ETHERNET) && (defined(ENABLE_SMTP) || defined(ENABLE_IMAP)) + if (!_session_config) + return; + +#if defined(ESP8266_CORE_SDK_V3_X_X) + +#if defined(INC_ENC28J60_LWIP) + if (_session_config->spi_ethernet_module.enc28j60) + goto ex; +#endif +#if defined(INC_W5100_LWIP) + if (_session_config->spi_ethernet_module.w5100) + goto ex; +#endif +#if defined(INC_W5500_LWIP) + if (_session_config->spi_ethernet_module.w5500) + goto ex; +#endif + +#elif defined(MB_ARDUINO_PICO) + +#endif + + return; + +#if defined(INC_ENC28J60_LWIP) || defined(INC_W5100_LWIP) || defined(INC_W5500_LWIP) + ex: +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + BASE_WIFICLIENT client; + client.connect(_session_config->server.host_name.c_str(), _session_config->server.port); + client.stop(); +#endif +#endif + +#endif + } + + /** + * Get the network status. + * @return true for connected or false for not connected. + */ + bool networkReady() + { + + // We will not invoke the network status request when device has built-in WiFi or Ethernet and it is connected. + if (_client_type == esp_mail_client_type_external_gsm_client) + { + _network_status = gprsConnected(); + if (!_network_status) + gprsConnect(); + } + else if (WiFI_CONNECTED || ethLinkUp()) + _network_status = true; + else if (_client_type == esp_mail_client_type_external_basic_client) + { + if (!_network_status_cb) + _last_error = 1; + else + _network_status_cb(); + } + + return _network_status; + } + + /** + * Reconnect the network. + */ + void networkReconnect() + { + + if (_client_type == esp_mail_client_type_external_basic_client) + { +#if defined(ESP_MAIL_HAS_WIFI_DISCONNECT) + // We can reconnect WiFi when device connected via built-in WiFi that supports reconnect + if (WiFI_CONNECTED) + { + WiFi.reconnect(); + return; + } + +#endif + + if (_network_connection_cb) + _network_connection_cb(); + } + else if (_client_type == esp_mail_client_type_external_gsm_client) + { + gprsDisconnect(); + gprsConnect(); + } + else if (_client_type == esp_mail_client_type_internal_basic_client) + { + +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) +#if defined(ESP32) || defined(ESP8266) + WiFi.reconnect(); +#else + if (_wifi_multi && _wifi_multi->credentials.size()) + _wifi_multi->reconnect(); +#endif +#endif + } + } + + /** + * Disconnect the network. + */ + void networkDisconnect() {} + + /** + * Get the Client type. + * @return The esp_mail_client_type enum value. + */ + esp_mail_client_type type() { return _client_type; } + + /** + * Get the Client initialization status. + * @return The initialization status. + */ + bool isInitialized() + { + bool rdy = true; +#if !defined(ESP_MAIL_WIFI_IS_AVAILABLE) + if (_client_type == esp_mail_client_type_external_basic_client && + (!_network_connection_cb || !_network_status_cb)) + rdy = false; + else if (_client_type != esp_mail_client_type_external_basic_client || + _client_type != esp_mail_client_type_external_gsm_client) + rdy = false; +#else + // assume external client is WiFiClient and network status request callback is not required + // when device was connected to network using on board WiFi + if (_client_type == esp_mail_client_type_external_basic_client && + (!_network_connection_cb || (!_network_status_cb && !WiFI_CONNECTED && !ethLinkUp()))) + { + rdy = false; + } + +#endif + + if (!rdy) + { +#if !defined(SILENT_MODE) && (defined(ENABLE_SMTP) || defined(ENABLE_IMAP)) + if (_debug_level > 0) + { + if (!_network_connection_cb) + esp_mail_debug_print_tag(esp_mail_error_client_str_2 /* "network connection callback is required" */, esp_mail_debug_tag_type_error, true); + if (!WiFI_CONNECTED && !ethLinkUp()) + { + if (!_network_status_cb) + esp_mail_debug_print_tag(esp_mail_error_client_str_3 /* "network connection status callback is required" */, esp_mail_debug_tag_type_error, true); + } + } +#endif + } + + return rdy; + } + + /** + * Set Root CA certificate to verify. + * @param name The host name. + * @param ip The ip address result. + * @return 1 for success or 0 for failed. + */ + int hostByName(const char *name, IPAddress &ip) + { +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + return WiFi.hostByName(name, ip); +#else + return 1; +#endif + } + + /** + * Store the host name and port. + * @param host The host name to connect. + * @param port The port to connect. + * @return true. + */ + bool begin(const char *host, uint16_t port) + { + _host = host; + _port = port; +#if !defined(ESP_MAIL_DISABLE_SSL) + _tcp_client->setBufferSizes(_rx_size >= _minRXTXBufSize && _rx_size <= _maxRXBufSize ? _rx_size : _maxRXBufSize / rxBufDivider, + _tx_size >= _minRXTXBufSize && _tx_size <= _maxTXBufSize ? _tx_size : _maxTXBufSize / txBufDivider); +#endif + _last_error = 0; + return true; + } + + /** + * Start TCP connection using stored host name and port. + * @param secure The secure mode option. + * @param verify The Root CA certificate verification option. + * @return true for success or false for error. + */ + + bool connect(bool secured, bool verify) + { + bool ret = false; + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + _last_error = 0; + +#if !defined(ESP_MAIL_DISABLE_SSL) + _tcp_client->enableSSL(secured); + setSecure(secured); + setVerify(verify); +#endif + + if (connected()) + { + flush(); + return true; + } + + if (!_basic_client) + { + if (_client_type == esp_mail_client_type_external_basic_client) + { + _last_error = 1; + return false; + } + else if (_client_type != esp_mail_client_type_external_gsm_client) + { +// Device has no built-in WiFi, external client required. +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + _basic_client = new BASE_WIFICLIENT(); + _client_type = esp_mail_client_type_internal_basic_client; +#else + _last_error = 1; + return false; +#endif + } + } + +#if defined(ESP_MAIL_DISABLE_SSL) + _tcp_client = _basic_client; +#else + _tcp_client->setClient(_basic_client); +#endif + + if (!_tcp_client->connect(_host.c_str(), _port)) + return false; + +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) && (defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO)) + if (_client_type == esp_mail_client_type_internal_basic_client) + reinterpret_cast(_basic_client)->setNoDelay(true); +#endif + + // For TCP keepalive should work in ESP8266 core > 3.1.2. + // https://github.com/esp8266/Arduino/pull/8940 + + // Not currently supported by WiFiClientSecure in Arduino Pico core + + if (_client_type == esp_mail_client_type_internal_basic_client) + { + if (isKeepAliveSet()) + { +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + +#if defined(ESP8266) + if (_tcpKeepIdleSeconds == 0 || _tcpKeepIntervalSeconds == 0 || _tcpKeepCount == 0) + reinterpret_cast(_basic_client)->disableKeepAlive(); + else + reinterpret_cast(_basic_client)->keepAlive(_tcpKeepIdleSeconds, _tcpKeepIntervalSeconds, _tcpKeepCount); + +#elif defined(ESP32) + + if (_tcpKeepIdleSeconds == 0 || _tcpKeepIntervalSeconds == 0 || _tcpKeepCount == 0) + { + _tcpKeepIdleSeconds = 0; + _tcpKeepIntervalSeconds = 0; + _tcpKeepCount = 0; + } + + bool success = setOption(TCP_KEEPIDLE, &_tcpKeepIdleSeconds) > -1 && + setOption(TCP_KEEPINTVL, &_tcpKeepIntervalSeconds) > -1 && + setOption(TCP_KEEPCNT, &_tcpKeepCount) > -1; + if (!success) + _isKeepAlive = false; +#endif + +#endif + } + } + + ret = connected(); + if (!ret) + stop(); +#endif + return ret; + } + + /** + * Upgrade the current connection by setting up the SSL and perform the SSL handshake. + * + * @param verify The Root CA certificate verification option + * @return operating result. + */ + + bool connectSSL(bool verify) + { +#if !defined(ESP_MAIL_DISABLE_SSL) + _tcp_client->setDebugLevel(2); + + bool ret = _tcp_client->connected(); + + if (ret) + { + setVerify(verify); + ret = _tcp_client->connectSSL(_host.c_str(), _port); + if (ret) + _secured = true; + } + + if (!ret) + stop(); + + return ret; +#endif + return false; + } + + /** + * Stop TCP connection. + */ + void stop() + { + if (_tcp_client) + _tcp_client->stop(); + } + + /** + * Get the TCP connection status. + * @return true for connected or false for not connected. + */ + bool connected() { return _tcp_client && _tcp_client->connected(); }; + + /** + * The TCP data write function. + * @param data The data to write. + * @param len The length of data to write. + * @return The size of data that was successfully written or 0 for error. + */ + int write(uint8_t *data, int len) + { + if (!_tcp_client) + return TCP_CLIENT_ERROR_NOT_INITIALIZED; + + if (!data) + return TCP_CLIENT_ERROR_SEND_DATA_FAILED; + + if (len == 0) + return TCP_CLIENT_ERROR_SEND_DATA_FAILED; + + if (!networkReady()) + return TCP_CLIENT_ERROR_NOT_CONNECTED; + + if (!connect(isSecure(), isVerify())) + return TCP_CLIENT_ERROR_CONNECTION_REFUSED; + + int toSend = _chunkSize; + int sent = 0; + while (sent < len) + { + if (sent + toSend > len) + toSend = len - sent; + + if ((int)_tcp_client->write(data + sent, toSend) != toSend) + return TCP_CLIENT_ERROR_SEND_DATA_FAILED; + + sent += toSend; + } + + return len; + } + + /** + * The TCP data send function. + * @param data The data to send. + * @return The size of data that was successfully sent or 0 for error. + */ + int send(const char *data) { return write((uint8_t *)data, strlen(data)); } + + /** + * The TCP data print function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int print(const char *data) { return send(data); } + + /** + * The TCP data print function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int print(int data) + { + char buf[64]; + memset(buf, 0, 64); + sprintf(buf, (const char *)FPSTR("%d"), data); + int ret = send(buf); + return ret; + } + + /** + * The TCP data print with new line function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int println(const char *data) + { + int len = send(data); + if (len < 0) + return len; + int sz = send((const char *)FPSTR("\r\n")); + if (sz < 0) + return sz; + return len + sz; + } + + /** + * The TCP data print with new line function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int println(int data) + { + char buf[64]; + memset(buf, 0, 64); + sprintf(buf, (const char *)FPSTR("%d\r\n"), data); + int ret = send(buf); + return ret; + } + + /** + * Get available data size to read. + * @return The avaiable data size. + */ + int available() + { + if (!_basic_client) + return TCP_CLIENT_ERROR_NOT_INITIALIZED; + + return _tcp_client->available(); + } + + /** + * The TCP data read function. + * @return The read value or -1 for error. + */ + int read() + { + if (!_basic_client) + return TCP_CLIENT_ERROR_NOT_INITIALIZED; + + return _tcp_client->read(); + } + + /** + * The TCP data read function. + * @param buf The data buffer. + * @param len The length of data that read. + * @return The size of data that was successfully read or negative value for error. + */ + int readBytes(uint8_t *buf, int len) + { + if (!_basic_client) + return TCP_CLIENT_ERROR_NOT_INITIALIZED; + + return _tcp_client->read(buf, len); + } + + /** + * The TCP data read function. + * @param buf The data buffer. + * @param len The length of data that read. + * @return The size of data that was successfully read or negative value for error. + */ + int readBytes(char *buf, int len) + { + return readBytes((uint8_t *)buf, len); + } + + /** + * Wait for all receive buffer data read. + */ + void flush() + { + if (_tcp_client) + _tcp_client->flush(); + } + + /** + * Set the network connection request callback. + * @param networkConnectionCB The callback function that handles the network connection. + */ + void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB) + { + _network_connection_cb = networkConnectionCB; + } + + /** + * Set the network status request callback. + * @param networkStatusCB The callback function that calls the setNetworkStatus function to set the network status. + */ + void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB) + { + _network_status_cb = networkStatusCB; + } + + /** + * Set the network status which should call in side the networkStatusRequestCallback function. + * @param status The status of network. + */ + void setNetworkStatus(bool status) + { + _network_status = status; + } + + void setMBFS(MB_FS *mbfs) { _mbfs = mbfs; } + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + void setSession(Session_Config *session_config) + { + _session_config = session_config; + } +#endif + + void setClockReady(bool rdy) + { + _clock_ready = rdy; + } + + void setCertType(esp_mail_cert_type type) { _cert_type = type; } + + esp_mail_cert_type getCertType() { return _cert_type; } + + void setDebugLevel(int debug) { _debug_level = debug; } + + unsigned long tcpTimeout() + { + if (_tcp_client) + return 1000 * _tcp_client->getTimeout(); + return 0; + } + + void disconnect(){}; + + void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount) + { + _tcpKeepIdleSeconds = tcpKeepIdleSeconds; + _tcpKeepIntervalSeconds = tcpKeepIntervalSeconds; + _tcpKeepCount = tcpKeepCount; + _isKeepAlive = tcpKeepIdleSeconds > 0 && tcpKeepIntervalSeconds > 0 && tcpKeepCount > 0; + } + + bool isKeepAliveSet() { return _tcpKeepIdleSeconds > -1 && _tcpKeepIntervalSeconds > -1 && _tcpKeepCount > -1; }; + + bool isKeepAlive() { return _isKeepAlive; }; + + void clear() + { +#if !defined(ESP_MAIL_DISABLE_SSL) + if (_basic_client && _client_type == esp_mail_client_type_internal_basic_client) + { +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + delete (BASE_WIFICLIENT *)_basic_client; +#else + delete _basic_client; +#endif + _basic_client = nullptr; + } +#else + _basic_client = nullptr; +#endif + _client_type = esp_mail_client_type_undefined; + } + + void setWiFi(esp_mail_wifi_credentials_t *wifi) { _wifi_multi = wifi; } + + bool gprsConnect() + { +#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) + TinyGsm *gsmModem = (TinyGsm *)_modem; + if (gsmModem) + { + // Unlock your SIM card with a PIN if needed + if (_pin.length() && gsmModem->getSimStatus() != 3) + gsmModem->simUnlock(_pin.c_str()); + +#if defined(TINY_GSM_MODEM_XBEE) + // The XBee must run the gprsConnect function BEFORE waiting for network! + gsmModem->gprsConnect(_apn.c_str(), _user.c_str(), _password.c_str()); +#endif + +#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) + if (_debug_level > 0 && _last_error == 0) + esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR("Waiting for network..."), esp_mail_debug_tag_type_info, false); +#endif + if (!gsmModem->waitForNetwork()) + { +#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) + if (_debug_level > 0 && _last_error == 0) + esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR(" fail"), esp_mail_debug_tag_type_info, true, false); +#endif + _last_error = 1; + _network_status = false; + return false; + } + +#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) + if (_debug_level > 0 && _last_error == 0) + esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR(" success"), esp_mail_debug_tag_type_info, true, false); +#endif + + if (gsmModem->isNetworkConnected()) + { +#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) + if (_debug_level > 0 && _last_error == 0) + { + esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR("Connecting to "), esp_mail_debug_tag_type_info, false); + esp_mail_debug_print_tag(_apn.c_str(), esp_mail_debug_tag_type_info, false, false); + } +#endif + _network_status = gsmModem->gprsConnect(_apn.c_str(), _user.c_str(), _password.c_str()) && + gsmModem->isGprsConnected(); + +#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) + if (_debug_level > 0 && _last_error == 0) + { + if (_network_status) + esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR(" success"), esp_mail_debug_tag_type_info, true, false); + else + esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR(" fail"), esp_mail_debug_tag_type_info, true, false); + } +#endif + } + + if (!_network_status) + _last_error = 1; + + return _network_status; + } + +#endif + return false; + } + + bool gprsConnected() + { +#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) + TinyGsm *gsmModem = (TinyGsm *)_modem; + _network_status = gsmModem && gsmModem->isGprsConnected(); +#endif + return _network_status; + } + + bool gprsDisconnect() + { +#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) + TinyGsm *gsmModem = (TinyGsm *)_modem; + _network_status = gsmModem && gsmModem->gprsDisconnect(); +#endif + return !_network_status; + } + + bool gprsGetTime(int &year, int &month, int &day, int &hour, int &min, int &sec, float &timezone) + { +#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) && defined(TINY_GSM_MODEM_HAS_TIME) + + if (!gprsConnected()) + return 0; + + TinyGsm *gsmModem = (TinyGsm *)_modem; + year = 0; + month = 0; + day = 0; + hour = 0; + min = 0; + sec = 0; + timezone = 0; + for (int8_t i = 5; i; i--) + { + if (gsmModem->getNetworkTime(&year, &month, &day, &hour, &min, &sec, &timezone)) + { + return true; + } + } +#endif + return false; + } + + int setOption(int option, int *value) + { +#if defined(ESP32) && defined(ESP_MAIL_WIFI_IS_AVAILABLE) + // Actually we wish to use setSocketOption directly but it is ambiguous in old ESP32 core v1.0.x.; + // Use setOption instead for old core support. + return reinterpret_cast(_basic_client)->setOption(option, value); +#endif + return 0; + } + + void setTA(bool hasTA) + { + _has_ta = hasTA; + } + + void setSecure(bool secure) + { + _secured = secure; + } + + void setInSecure() + { +#if !defined(ESP_MAIL_DISABLE_SSL) + _use_insecure = true; + setTA(false); +#endif + } + + void setVerify(bool verify) + { +#if !defined(ESP_MAIL_DISABLE_SSL) + if (_has_ta) + _use_insecure = !verify; + + if (_use_insecure) + _tcp_client->setInsecure(); +#endif + } + + bool isSecure() + { + return _secured; + } + + bool isVerify() + { + return !_use_insecure; + } + + int rxBufDivider = 16; + int txBufDivider = 32; + +private: + // lwIP TCP Keepalive idle in seconds. + int _tcpKeepIdleSeconds = -1; + // lwIP TCP Keepalive interval in seconds. + int _tcpKeepIntervalSeconds = -1; + // lwIP TCP Keepalive count. + int _tcpKeepCount = -1; + bool _isKeepAlive = false; + + uint16_t _bsslRxSize = 1024; + uint16_t _bsslTxSize = 1024; + const int _maxRXBufSize = 16384; // SSL full supported 16 kB + const int _maxTXBufSize = 16384; + const int _minRXTXBufSize = 512; +#if defined(ESP_MAIL_DISABLE_SSL) + Client *_tcp_client = nullptr; +#else + ESP_SSLClient *_tcp_client = nullptr; + X509List *_x509 = nullptr; +#endif + + MB_String _host; + uint16_t _port = 443; + + MB_FS *_mbfs = nullptr; + Client *_basic_client = nullptr; + esp_mail_wifi_credentials_t *_wifi_multi = nullptr; +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + Session_Config *_session_config = nullptr; +#endif + NetworkConnectionRequestCallback _network_connection_cb = NULL; + NetworkStatusRequestCallback _network_status_cb = NULL; +#if defined(ESP_MAIL_HAS_WIFIMULTI) + WiFiMulti *_multi = nullptr; +#endif +#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) + MB_String _pin, _apn, _user, _password; + void *_modem = nullptr; +#endif + + bool _has_ta = false; + bool _secured = false; + bool _use_insecure = false; + int _debug_level = 0; + int _chunkSize = 1024; + bool _clock_ready = false; + int _last_error = 0; + volatile bool _network_status = false; + int _rx_size = -1, _tx_size = -1; + + esp_mail_cert_type _cert_type = esp_mail_cert_type_undefined; + esp_mail_client_type _client_type = esp_mail_client_type_undefined; +}; + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/HeapStat.h b/lib/libesp32/ESP-Mail-Client/src/HeapStat.h new file mode 100644 index 000000000000..c6ed4e865123 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/HeapStat.h @@ -0,0 +1,146 @@ +/** Memory usage info for debugging purpose + +#include "HeapStat.h" + +HeapStat heapInfo; + +void setup() +{ + Serial.begin(115200); +} + +void loop() +{ + // Other codes here + + // Collect memory info + heapInfo.collect(); + + // Print memory info + heapInfo.print(); + +} + +*/ + +#ifndef HEAP_STAT_H +#define HEAP_STAT_H + +#if defined(ESP8266) || defined(ESP32) +#ifndef MB_ARDUINO_ESP +#define MB_ARDUINO_ESP +#endif +#endif + +#if defined(ARDUINO_ARCH_RP2040) + +#if defined(ARDUINO_NANO_RP2040_CONNECT) +#ifndef MB_ARDUINO_NANO_RP2040_CONNECT +#define MB_ARDUINO_NANO_RP2040_CONNECT +#endif +#else +#ifndef MB_ARDUINO_PICO +#define MB_ARDUINO_PICO +#endif +#endif + +#endif + +#include "ESP_Mail_Client.h" + +class HeapStat +{ +private: + int current_heap = 0; + int first_round_heap = 0; + int min_heap = 0; + int max_heap = 0; + int diff_heap_from_first_round = 0; + int diff_heap_from_current_round = 0; + int _count = 0; + + int getFreeHeap() + { +#if defined(MB_ARDUINO_ESP) + return ESP.getFreeHeap(); +#elif defined(MB_ARDUINO_PICO) + return rp2040.getFreeHeap(); +#else + return 0; +#endif + } + +public: + HeapStat() {} + ~HeapStat() {} + + void reset() + { + current_heap = 0; + first_round_heap = 0; + min_heap = 0; + max_heap = 0; + diff_heap_from_first_round = 0; + diff_heap_from_current_round = 0; + _count = 0; + } + + void collect() + { + _count++; + + if (max_heap < getFreeHeap()) + max_heap = getFreeHeap(); + + if (min_heap == 0 || min_heap > getFreeHeap()) + min_heap = getFreeHeap(); + + if (first_round_heap == 0) + first_round_heap = getFreeHeap(); + + if (current_heap > 0) + { + diff_heap_from_first_round = getFreeHeap() - first_round_heap; + diff_heap_from_current_round = getFreeHeap() - current_heap; + } + + current_heap = getFreeHeap(); + } + + int current() + { + return current_heap; + } + + int min() + { + return min_heap; + } + + int max() + { + return max_heap; + } + + int diff1() + { + return diff_heap_from_first_round; + } + + int diffN() + { + return diff_heap_from_current_round; + } + + int count() + { + return _count; + } + + void print() + { + MailClient.printf("#### Heap Info\n#### Current: %d, Min: %d, Max: %d, Diff_1: %d, Diff_%d: %d\n", current(), min(), max(), diff1(), count(), diffN()); + } +}; + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/README.md b/lib/libesp32/ESP-Mail-Client/src/README.md new file mode 100644 index 000000000000..8fe3158760ce --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/README.md @@ -0,0 +1,3416 @@ +# ESP Mail Client Arduino Library + + +The description of the available functions in the current reease are shown below. + + +## Global functions + + +#### Sending Email through the SMTP server. + +param **`smtp`** The pointer to SMTP session object which holds the data and the TCP client. + +param **`msg`** The pointer to SMTP_Message class which contains the header, body, and attachments. + +param **`closeSession`** The option to Close the SMTP session after sent. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp +bool sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession = true); +``` + + + +#### Append message to the mailbox + +param **`imap`** The pointer to IMAP sesssion object which holds the data and the TCP client. + +param **`msg`** The pointer to SMTP_Message class which contains the header, body, and attachments. + +param **`lastAppend`** The last message to append (optional). In case MULTIAPPEND extension + +is supported, set this to false will append messages in single APPEND command. + +param **`flags`** The flags to set to this message. + + param **`dateTime`** The date/time to set to this message (optional). + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp +bool appendMessage(IMAPSession *imap, SMTP_Message *msg, T flags = ""); +``` + + +#### Reading Email through IMAP server. + +param **`imap`** The pointer to IMAP sesssion object which holds the data and the TCP client. + +param **`closeSession`** The option to close the IMAP session after fetching or searching the Email. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp +bool readMail(IMAPSession *imap, bool closeSession = true); +``` + + + + + +#### Set the argument to the Flags for the specified message. + +param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. + +param **`msgUID`** The UID of the message. + +param **`flags`** The flag list to set. + +param **`closeSession`** The option to close the IMAP session after set flag. + +param **`silent`** The option to ignore the response. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool setFlag(IMAPSession *imap, int msgUID, flags, bool closeSession, bool silent = false, int32_t modsequence = -1); +``` + + + + + +#### Set the argument to the Flags for the specified message. + +param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. + +param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or +message sequence number or ranges of UID or sequence number. + +param **`UID`** The option for sequenceSet whether it is UID or message sequence number. + +param **`flags`** The flag list to set. + +param **`closeSession`** The option to close the IMAP session after set flag. + +param **`silent`** The option to ignore the response. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool setFlag(IMAPSession *imap, sequenceSet, bool UID, flags, bool closeSession, bool silent = false, int32_t modsequence = -1); +``` + + + + + +#### Add the argument to the Flags for the specified message. + +param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. + +param **`msgUID`** The UID of the message. + +param **`flags`** The flag list to add. + +param **`closeSession`** The option to close the IMAP session after add flag. + +param **`silent`** The option to ignore the response. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool addFlag(IMAPSession *imap, int msgUID, flags, bool closeSession, int32_t modsequence = -1); +``` + + + + + +#### Add the argument to the Flags for the specified message. + +param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. + +param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or +message sequence number or ranges of UID or sequence number. + +param **`UID`** The option for sequenceSet whether it is UID or message sequence number. + +param **`flags`** The flag list to add. + +param **`closeSession`** The option to close the IMAP session after set flag. + +param **`silent`** The option to ignore the response. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool addFlag(IMAPSession *imap, sequenceSet, bool UID, flags, bool closeSession, bool silent = false, int32_t modsequence = -1); +``` + + + + + +#### Remove the argument from the Flags for the specified message. + +param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. + +param **`msgUID`** The UID of the message that flags to be removed. + +param **`flags`** The flag list to remove. + +param **`closeSession`** The option to close the IMAP session after remove flag. + +param **`silent`** The option to ignore the response. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool removeFlag(IMAPSession *imap, int msgUID, flags, bool closeSession, int32_t modsequence = -1); +``` + + + + + +#### Remove the argument from the Flags for the specified message. + +param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. + +param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or +message sequence number or ranges of UID or sequence number. + +param **`UID`** The option for sequenceSet whether it is UID or message sequence number. + +param **`flags`** The flag list to remove. + +param **`closeSession`** The option to close the IMAP session after set flag. + +param **`silent`** The option to ignore the response. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool removeFlag(IMAPSession *imap, sequenceSet, bool UID, flags, bool closeSession, bool silent = false, int32_t modsequence = -1); +``` + + + + + + +#### Reconnect WiFi or network if lost connection. + +param **`reconnect`** The boolean to set/unset WiFi AP reconnection. + +```cpp +void networkReconnect(bool reconnect); +``` + + + + +#### Initiate SD card with SPI port configuration. + +param **`ss`** The SPI Chip/Slave Select pin. + +param **`sck`** The SPI Clock pin. + +param **`miso`** The SPI MISO pin. + +param **`mosi`** The SPI MOSI pin. + +aram **`frequency`** The SPI frequency. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp +bool sdBegin(int8_t ss = -1, int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1, uint32_t frequency = 4000000); +``` + + + + + +#### Initiate SD card with SD FS configurations (ESP8266 only). + +param **`ss`** SPI Chip/Slave Select pin. + +param **`sdFSConfig`** The pointer to SDFSConfig object (ESP8266 only). + +return **`boolean`** type status indicates the success of the operation. + +```cpp + bool sdBegin(SDFSConfig *sdFSConfig); +``` + + + + + +#### Initiate SD card with chip select and SPI configuration (ESP32 only). + +param **`ss`** The SPI Chip/Slave Select pin. + +param **`spiConfig`** The pointer to SPIClass object for SPI configuartion. + +param **`frequency`** The SPI frequency. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp +bool sdBegin(int8_t ss, SPIClass *spiConfig = nullptr, uint32_t frequency = 4000000); +``` + + + + + +#### Initiate SD card with SdFat SPI and pins configurations (with SdFat included only). + +param **`sdFatSPIConfig`** The pointer to SdSpiConfig object for SdFat SPI configuration. + +param **`ss`** The SPI Chip/Slave Select pin. + +param **`sck`** The SPI Clock pin. + +param **`miso`** The SPI MISO pin. + +param **`mosi`** The SPI MOSI pin. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp + bool sdBegin(SdSpiConfig *sdFatSPIConfig, int8_t ss = -1, int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1); +``` + + + + + +#### Initiate SD card with SdFat SDIO configuration (with SdFat included only). + +param **`sdFatSDIOConfig`** The pointer to SdioConfig object for SdFat SDIO configuration. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp + bool sdBegin(SdioConfig *sdFatSDIOConfig); +``` + + + + +#### Initialize the SD_MMC card (ESP32 only). + +param **`mountpoint`** The mounting point. + +param **`mode1bit`** Allow 1 bit data line (SPI mode). + +param **`format_if_mount_failed`** Format SD_MMC card if mount failed. + +return **`Boolean`** type status indicates the success of the operation. + +```cpp +bool sdMMCBegin(const char *mountpoint = "/sdcard", bool mode1bit = false, bool format_if_mount_failed = false); +``` + + + + +#### Get free Heap memory. + +return **`int`** Free memory amount in byte. + +```cpp +int getFreeHeap(); +``` + + + + + +## IMAPSession class functions + + +The following functions are available from the IMAP Session class. + +This class used for controlling IMAP transports and retrieving the data from the IMAP server. + + + + +#### Set the tcp timeout. + +param **`timeoutSec`** The tcp timeout in seconds. + +```cpp +void setTCPTimeout(unsigned long timeoutSec); +``` + + + +#### Assign custom Client from Arduino Clients. + +param **`client`** The pointer to Arduino Client derived class e.g. WiFiClient, WiFiClientSecure, EthernetClient or GSMClient. + +```cpp +void setClient(Client *client); +``` + + +#### Assign TinyGsm Clients. + +param **`client`** The pointer to TinyGsmClient. + +param **`modem`** The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data. + +param **`pin`** The SIM pin. + +param **`apn`** The GPRS APN (Access Point Name). + +param **`user`** The GPRS user. + +param **`password`** The GPRS password. + +```cpp +void setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password); +``` + + +#### Assign the callback function to handle the network connection for custom Client. + +param **`networkConnectionCB`** The function that handles the network connection. + +```cpp +void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB); +``` + + + +#### Assign the callback function to handle the network connection status acknowledgement. + +param **`networkStatusCB`** The function that handle the network connection status acknowledgement. + +```cpp +void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB); +``` + + + +#### Set the network status acknowledgement. + +param **`status`** The network status. + +```cpp +void setNetworkStatus(bool status); +``` + + + +#### Set the BearSSL IO buffer size. + +param **`rx`** The BearSSL receive buffer size in bytes. + +param **`tx`** The BearSSL trasmit buffer size in bytes. + +```cpp +void setSSLBufferSize(int rx = -1, int tx = -1); +``` + + + +#### Set system time with timestamp. + +param **`ts`** timestamp in seconds from midnight Jan 1, 1970. + +param **`gmtOffset`** The GMT offset. + +This function allows the internal time setting by timestamp i.e. timestamp from external RTC. + +```cpp +void setSystemTime(time_t ts, float gmtOffset = 0); +``` + + + +#### Begin the IMAP server connection. + +param **`session_config`** The pointer to Session_Config structured data that keeps the server and log in details. + +param **`imap_data`** The pointer to IMAP_Data structured data that keeps the operation options. + +param **`login`** The bool option for login after server connection. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool connect(Session_Config *session_config, IMAP_Data *imap_data, bool login = true); +``` + + + +#### Login to IMAP server using Email and password. + +param **`email`** The IMAP server account email. + +param **`password`** The IMAP server account password. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bbool loginWithPassword( email, password); +``` + + + +#### Login to IMAP server using Email and access token. + +param **`email`** The IMAP server account email. + +param **`token`** The Access token to log in. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bbool loginWithAccessToken( email, token); +``` + + +#### Send the client identification to the server + +param **`identification`** The pointer to IMAP_Identification structured data that keeps + +the key properties e.g., name, version, os, os_version, vendor, support_url, address, + +date, command, arguments, and environment. + +```cpp +bool id(IMAP_Identification *identification); +``` + + +#### Return the server ID returns from ID command. + +return **`The server ID string.`** + +```cpp +String serverID(); +``` + + +#### Return the SASL authentication status. + +return **`boolean`** The boolean value indicates SASL authentication status. + +```cpp +bool isAuthenticated(); +``` + + +#### Return the log in status. + +return **`boolean`** The boolean value indicates log in status. + +```cpp +bool isLoggedIn(); +``` + + +#### Return firmware update result when attachment filename matches. + +return **`boolean`** The boolean value indicates the firmware update status. + +```cpp +bool isFirmwareUpdateSuccess(); +``` + + +#### Close the IMAP session. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool closeSession(); +``` + + +#### Setup TCP KeepAlive for internal TCP client. + +param **`tcpKeepIdleSeconds`** lwIP TCP Keepalive idle in seconds. + +param **`tcpKeepIntervalSeconds`** lwIP TCP Keepalive interval in seconds. + +param **`tcpKeepCount`** lwIP TCP Keepalive count. + +For the TCP (KeepAlive) options, see [this doc](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options). + +If value of one of these parameters is zero, the TCP KeepAlive will be disabled. + +You can check the server connecting status, by exexuting `.connected()` which will return true when connection to the server is still alive. + +```cpp +void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount); +``` + + + +#### Get TCP KeepAlive status. + +return **`Boolean`** status of TCP Keepalive. + +```cpp +bool isKeepAlive(); +``` + + + +#### Get TCP connection status. + +return **`boolean`** The boolean value indicates the connection status. + +```cpp +bool connected(); +``` + + + + + + +#### Set to enable the debug. + +param **`level`** The level to enable the debug message + +level = 0, no debugging + +level = 1, basic level debugging + +```cpp +void debug(int level); +``` + + + + + +#### Get the list of all the mailbox folders since the TCP session was opened and user was authenticated. + +param **`folders`** The FoldersCollection class that contains the collection of the +FolderInfo structured data. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool getFolders(FoldersCollection &folders); +``` + + + + + +#### Select or open the mailbox folder to search or fetch the message inside. + +param **`folderName`** The known mailbox folder name. The default name is INBOX. + +param **`readOnly`** The option to open the mailbox for read only. Set this option to false when you wish +to modify the Flags using the setFlag, addFlag and removeFlag functions. + +return **`boolean`** The boolean value which indicates the success of operation. + +note: the function will exit immediately and return true if the time since previous success folder selection (open) with the same readOnly mode, is less than 5 seconds. + +```cpp +bool selectFolder( folderName, bool readOnly = true); +``` + + + + + +#### Open the mailbox folder to read or search the mesages. + +param **`folderName`** The name of known mailbox folder to be opened. + +param **`readOnly`** The option to open the mailbox for reading only. Set this option to false when you wish +to modify the flags using the setFlag, addFlag and removeFlag functions. + +return **`boolean`** The boolean value which indicates the success of operation. + +note: the function will exit immediately and return true if the time since previous success folder selection (open) with the same readOnly mode, is less than 5 seconds. + +```cpp +bool openFolder( folderName, bool readOnly = true); +``` + + + + + +#### Close the mailbox folder that was opened. + +param **`expunge`** The option to allow emty the deleted flag set messages in case folder was open with editable mode. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool closeFolder(bool expunge = false); +``` + + + + + + +#### Create folder. + +param **`folderName`** The name of folder to create. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool createFolder( folderName); +``` + + + + + +#### Get subscribes mailboxes. + +param **`reference`** The reference name. + +param **`mailbox`** The mailbox name with possible wildcards. + +param **`folders`** The return FoldersCollection that contains the folder info e.g., name, attribute and delimiter. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool getSubscribesMailboxes( reference, mailbox, FoldersCollection &folders); +``` + + + + +#### Subscribe mailbox. + +param **`folderName`** The name of folder to subscribe. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool subscribe( folderName) +``` + + + + +#### Unsubscribe mailbox. + +param **`folderName`** The name of folder to unsubscribe. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool unSubscribe( folderName) +``` + + + + + +#### Rename folder. + +param **`currentFolderName`** The name of folder to create. + +param **`newFolderName`** The new name of folder to create. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool renameFolder( currentFolderName, newFolderName); +``` + + + +#### Delete folder. + +param **`folderName`** The name of folder to delete.. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool deleteFolder( folderName); +``` + + + + + + +#### Get UID number in selected or opened mailbox. + +param **`msgNum`** The message number or order in the total message numbers. + +return **`boolean`** The boolean value which indicates the success of operation. + +Returns 0 when fail to get UID. + +```cpp +int getUID(int msgNum); +``` + + + + + + + +#### Get message flags in selected or opened mailbox. + +param **`msgNum`** The message number or order in the total message numbers. + +return **`string`** Message flags in selected or opened mailbox. + +empty string when fail to get flags. + +```cpp +const char *getFlags(int msgNum); +``` + + + + + + +#### Send the custom IMAP command and get the result via callback. + +param **`cmd`** The command string. + +param **`callback`** The function that accepts IMAP_Response as parameter. + +param **`tag`** The tag string to pass to the callback function. + +return **`boolean`** The boolean value which indicates the success of operation. + +imap.connect and imap.selectFolder or imap.openFolder are needed to call once prior to call this function. + +```cpp +bool sendCustomCommand( cmd, imapResponseCallback callback, tag); +``` + + + + + +#### Send the custom IMAP command data string. + +param **`data`** The string data. + +param **`lastData`** The flag represents the last data to send (optional). + +return **`boolean`** The boolean value which indicates the success of operation. + +Should be used after calling sendCustomCommand("APPEND xxxxxx"); + +```cpp +bool sendCustomData(T data, bool lastData = false); +``` + + + + + +#### Send the custom IMAP command data. + +param **`data`** The byte data. + +param **`size`** The data size. + +param **`lastData`** The flag represents the last data to send (optional). + +return **`boolean`** The boolean value which indicates the success of operation. + +Should be used after calling ssendCustomCommand("APPEND xxxxxx"); + +```cpp +bool sendCustomData(uint8_t *data, size_t size, bool lastData = false); +``` + + + + +#### Begin the IMAP server connection without authentication. + +param **`session_config`** The pointer to Session_Config structured data that keeps the server and log in details. + +param **`callback`** The callback function that accepts IMAP_Response as parameter. + +param **`tag`** The tag that pass to the callback function. + +return **`The boolean`** value indicates the success of operation. + +```cpp +bool customConnect(Session_Config *session_config, imapResponseCallback callback, tag); +``` + + + + +#### Copy the messages to the defined mailbox folder. + +param **`toCopy`** The pointer to the MessageList class that contains the list of messages to copy. + +param **`dest`** The destination folder that the messages to copy to. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool copyMessages(MessageList *toCopy, dest); +``` + + + + + +#### Copy the messages to the defined mailbox folder. + +param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or +message sequence number or ranges of UID or sequence number. + +param **`UID`** The option for sequenceSet whether it is UID or message sequence number. + +param **`dest`** The destination folder that the messages to copy to. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool copyMessages( sequenceSet, bool UID, dest); +``` + + + + + + +#### Move the messages to the defined mailbox folder. + +param **`toMove`** The pointer to the MessageList class that contains the list of messages to move. + +param **`dest`** The destination folder that the messages to move to. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool moveMessages(MessageList *toMove, dest); +``` + + + + + +#### Move the messages to the defined mailbox folder. + +param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or +message sequence number or ranges of UID or sequence number. + +param **`UID`** The option for sequenceSet whether it is UID or message sequence number. + +param **`dest`** The destination folder that the messages to move to. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool moveMessages( sequenceSet, bool UID, dest); +``` + + + + + + +#### Delete the messages in the opened mailbox folder. + +param **`toDelete`** The pointer to the MessageList class that contains the list of messages to delete. + +param **`expunge`** The boolean option to expunge all messages. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool deleteMessages(MessageList *toDelete, bool expunge = false, int32_t modsequence = -1); +``` + + + + + + +#### Delete the messages in the opened mailbox folder. + +param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or +message sequence number or ranges of UID or sequence number. + +param **`UID`** The option for sequenceSet whether it is UID or message sequence number. + +param **`expunge`** The boolean option to expunge all messages. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool deleteMessages( sequenceSet, bool UID, bool expunge = false, int32_t modsequence = -1); +``` + + + + + + +#### Get the quota root's resource usage and limits. + +param **`quotaRoot`** The quota root to get. + +param **`info`** The pointer to `IMAP_Quota_Root_Info` that contains quota root's resource name, usage and limit. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool getQuota( quotaRoot, IMAP_Quota_Root_Info *info); +``` + + + + + +#### Set the quota root's resource usage and limits. + +param **`quotaRoot`** The quota root to set. + +param **`data`** The pointer to `IMAP_Quota_Root_Info` that contains quota root's resource name, usage and limit. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool setQuota( quotaRoot, IMAP_Quota_Root_Info *data); +``` + + + + + +#### Get the list of quota roots for the named mailbox. + +param **`mailbox`** The mailbox name. + +param **`quotaRootsList`** The pointer to `IMAP_Quota_Roots_List` that contains the list of `IMAP_Quota_Root_Info`. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool getQuotaRoot( mailbox, IMAP_Quota_Roots_List *quotaRootsList); +``` + + + + + +#### Get the ACLs for a mailbox. + +param **`mailbox`** The mailbox name. + +param **`aclList`** The pointer to the returning `IMAP_Rights_List` object. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool getACL( mailbox, IMAP_Rights_List *aclList); +``` + + + + + + +#### Get the ACLs for a mailbox. + +param **`mailbox`** The mailbox name. + +param **`acl`** The pointer to the acl IMAP_Rights_Info to set. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool setACL( mailbox, IMAP_Rights_Info *acl); +``` + + + + + + +#### Delete the ACLs set for identifier on mailbox. + +param **`mailbox`** The mailbox name. + +param **`identifier`** The identifier (user) to remove the rights. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool deleteACL( mailbox, identifier); +``` + + + + + +#### Show my ACLs for a mailbox. + +param **`mailbox`** The mailbox name. + +param **`acl`** The pointer to the returning `IMAP_Rights_Info` object. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool myRights( mailbox, IMAP_Rights_Info *acl); +``` + + + + + +#### Returns IMAP namespaces. + +param **`mailbox`** The mailbox name. + +param **`ns`** The pointer to the returning `IMAP_Namespaces_List` object. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool getNamespace(IMAP_Namespaces_List *ns); +``` + + + + + + +#### Enable IMAP capability. + +param **`capability`** The mailbox name. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool enable( capability); +``` + + + + + +#### Listen for the selected or open mailbox for updates. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool listen(); +``` + + + + + + +#### Stop listen for the mailbox for updates. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool stopListen(); +``` + + + + + + + +#### Check for the selected or open mailbox updates. + +return **`boolean`** The boolean value which indicates the changes status of mailbox. + +```cpp +bool folderChanged(); +``` + + + + + + +#### Assign the callback function that returns the operating status when fetching or reading the Email. + +param **`imapCallback`** The function that accepts the `imapStatusCallback` as parameter. + +```cpp +void callback(imapStatusCallback imapCallback); +``` + + + + +#### Assign the callback function to decode the string based on the character set. + +param **`callback`** The function that accepts the pointer to `IMAP_Decoding_Info` as parameter. + +```cpp +void characterDecodingCallback(imapCharacterDecodingCallback callback); +``` + + + +#### Assign the callback function that returns the MIME data stream from fetching or reading the Email. + +param **`mimeDataStreamCallback`** The function that accepts the `MIME_Stream_Info` as parameter. + +```cpp +void mimeDataStreamCallback(MIMEDataStreamCallback mimeDataStreamCallback); +``` + + + + + +#### Determine if no message body contained in the search result and only the message header is available. + +```cpp +bool headerOnly(); +``` + + + + + +#### Get the message list from search or fetch the Emails + +return **`The IMAP_MSG_List structured`** data which contains the text and html contents, +attachments, inline images, embedded rfc822 messages details for each message. + +```cpp +IMAP_MSG_List data(); +``` + + + + +#### Get the details of the selected or opned mailbox folder + +return **`The SelectedFolderInfo class`** instance which contains the info about flags, total messages, next UID, +earch count and the available messages count. + +```cpp +SelectedFolderInfo selectedFolder(); +``` + + + + + +#### Get the error details when readingg the Emails. + +return **`String`** The string of error details. + +```cpp +String errorReason(); +``` + + +#### Get the operating status error code. + +return **`int`** The value of operating status error code. + +The negative value indicated error. + +See src/ESP_Mail_Error.h and extras/MB_FS.h + +```cpp +int errorCode(); +``` + + + +#### Clear all the cache data stored in the IMAP session object. + +```cpp +void empty(); +``` + + + +#### Get the status of message fetching and searching. + +return **`IMAP_Status`** The IMAP_Status object contains the fetching and searching statuses. + +```cpp +IMAP_Status status(); +``` + + + +#### Get the JSON string of file name list of files that stored in SD card. + +return **`The JSON string`** of filenames. + +note This will available only when standard SD library was used and file storage is SD. + +```cpp +String fileList(); +``` + + +## SMTPSession class functions + + +The following functions are available from the SMTP Session class. + +This class is similar to the IMAP session class, used for controlling SMTP transports +and retrieving the data from the SMTP server. + + + + +#### Set the tcp timeout. + +param **`timeoutSec`** The tcp timeout in seconds. + +```cpp +void setTCPTimeout(unsigned long timeoutSec); +``` + + + +#### Assign custom Client from Arduino Clients. + +param **`client`** The pointer to Arduino Client derived class e.g. WiFiClient, WiFiClientSecure, EthernetClient or GSMClient. + +```cpp +void setClient(Client *client); +``` + + +#### Assign TinyGsm Clients. + +param **`client`** The pointer to TinyGsmClient. + +param **`modem`** The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data. + +param **`pin`** The SIM pin. + +param **`apn`** The GPRS APN (Access Point Name). + +param **`user`** The GPRS user. + +param **`password`** The GPRS password. + +```cpp +void setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password); +``` + + + +#### Assign the callback function to handle the network connection for custom Client. + +param **`networkConnectionCB`** The function that handles the network connection. + +```cpp +void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB); +``` + + +#### Assign the callback function to handle the network connection status acknowledgement. + +param **`networkStatusCB`** The function that handle the network connection status acknowledgement. + +```cpp +void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB); +``` + + + +#### Set the network status acknowledgement. + +param **`status`** The network status. + +```cpp +void setNetworkStatus(bool status); +``` + + + +#### Set the BearSSL IO buffer size. + +param **`rx`** The BearSSL receive buffer size in bytes. + +param **`tx`** The BearSSL trasmit buffer size in bytes. + +```cpp +void setSSLBufferSize(int rx = -1, int tx = -1); +``` + + + +#### Set system time with timestamp. + +param **`ts`** timestamp in seconds from midnight Jan 1, 1970. + +param **`gmtOffset`** The GMT offset. + +This function allows the internal time setting by timestamp i.e. timestamp from external RTC. + +```cpp +void setSystemTime(time_t ts, float gmtOffset = 0); +``` + + + +#### Begin the SMTP server connection. + +param **`session_config`** The pointer to Session_Config structured data that keeps the server and log in details. + +param **`login`** The bool option for login after server connection. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp +bool connect(Session_Config *session_config, bool login = true); +``` + + + +#### Login to SMTP server using Email and password. + +param **`email`** The SMTP server account email. + +param **`password`** The SMTP server account password. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool loginWithPassword( email, password); +``` + + + +#### Login to SMTP server using Email and access token. + +param **`email`** The SMTP server account email. + +param **`token`** The Access token to log in. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool loginWithAccessToken( email, token); +``` + + +#### Return the SASL authentication status. + +return **`boolean`** The boolean value indicates SASL authentication status. + +```cpp +bool isAuthenticated(); +``` + + + +#### Return the log in status. + +return **`boolean`** The boolean value indicates log in status. + +```cpp +bool isLoggedIn(); +``` + + +#### Close the SMTP session. + +```cpp +bool closeSession(); +``` + + + +#### Setup TCP KeepAlive for internal TCP client. + +param **`tcpKeepIdleSeconds`** lwIP TCP Keepalive idle in seconds. + +param **`tcpKeepIntervalSeconds`** lwIP TCP Keepalive interval in seconds. + +param **`tcpKeepCount`** lwIP TCP Keepalive count. + +For the TCP (KeepAlive) options, see [this doc](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options). + +If value of one of these parameters is zero, the TCP KeepAlive will be disabled. + +You can check the server connecting status, by exexuting `.connected()` which will return true when connection to the server is still alive. + +```cpp +void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount); +``` + + + +#### Get TCP KeepAlive status. + +return **`Boolean`** status of TCP Keepalive. + +```cpp +bool isKeepAlive(); +``` + + + +#### Get TCP connection status. + +return **`boolean`** The boolean value indicates the connection status. + +```cpp +bool connected(); +``` + + + + +#### Begin the SMTP server connection without authentication. + +param **`session_config`** The pointer to Session_Config structured data that keeps the server and log in details. + +param **`callback`** The callback function that accepts the SMTP_Response as parameter. + +param **`commandID`** The command identifier number that will pass to the callback. + +return **`The int`** value of response code. + +If commandID was not set or set to -1, the command identifier will be auto increased started from zero. + +```cpp +int customConnect(Session_Config *session_config, smtpResponseCallback callback, int commandID = -1); +``` + + + + + + +#### Send the custom SMTP command and get the result via callback. + +param **`cmd`** The command string. + +param **`callback`** The function that accepts the SMTP_Response as parameter. + +return **`boolean`** The boolean value which indicates the success of operation. + +smtp.connect or smtp.customConnect is needed to call once prior to call this function. + +```cpp +bool sendCustomCommand( cmd, smtpResponseCallback callback); +``` + + + + + +#### Send the custom SMTP command data string. + +param **`data`** The string data. + +return **`The boolean`** value which indicates the success of operation. + +Should be used after calling sendCustomCommand("DATA"); + +```cpp +bool sendCustomData( data); +``` + + + + +#### Send the custom SMTP command data. + +param **`data`** The byte data. + +param **`size`** The data size. + +return **`The boolean`** value which indicates the success of operation. + +Should be used after calling sendCustomCommand("DATA"); + +```cpp +bool sendCustomData(uint8_t *data, size_t size); +``` + + + + + +#### Set to enable the debug. + +param **`level`** The level to enable the debug message + +level = 0, no debugging + +level = 1, basic level debugging + +```cpp +void debug(int level); +``` + + + + + +#### Get the error details when sending the Email + +return **`String`** The string of error details. + +```cpp +String errorReason(); +``` + + +#### Get the operating status error code. + +return **`int`** The value of operating status error code. + +The negative value indicated error. + +See src/ESP_Mail_Error.h and extras/MB_FS.h + +```cpp +int errorCode(); +``` + + + +#### Get the SMTP server response status code. + +return **`int`** The value of SMTP server response status code. + +See RFC 5321 standard's documentation. + +```cpp +int statusCode(); +``` + + + +#### Get the SMTP server response status message. + +return **`String`** The value of SMTP server response status message. + +```cpp +String statusMessage(); +``` + + + +#### Set the Email sending status callback function. + +param **`smtpCallback`** The callback function that accept the `smtpStatusCallback` param. + +```cpp +void callback(smtpStatusCallback smtpCallback); +``` + + +#### Get the status of message fetching and searching. + +return **`SMTP_Status`** The SMTP_Status object contains the sending status. + +```cpp +SMTP_Status status(); +``` + +## SMTP_Message class functions + + +The following functions are available from the SMTP Message class. + +This class is used for storing the message data including headers, body and attachments +which will be processed with the SMTP session class. + + + + +#### To reset the SMTP_Attachment item data + +param **`att`** The SMTP_Attachment class that stores the info about attachment + +This function was used for clear the internal data of attachment item to be ready for reuse. + +```cpp +void resetAttachItem(SMTP_Attachment &att); +``` + + + +#### To clear all data in SMTP_Message class included headers, bodies and attachments + +```cpp +void clear(); +``` + + + + +#### To clear all the inline images in SMTP_Message class. + +```cpp +void clearInlineimages(); +``` + + + + + +#### To clear all the attachments. + +```cpp +void clearAttachments(); +``` + + + + + +#### To clear all rfc822 message attachment. + +```cpp +void clearRFC822Messages(); +``` + + + + + +#### To clear the primary recipient mailboxes. + +```cpp +void clearRecipients(); +``` + + + + + +#### To clear the Carbon-copy recipient mailboxes. + +```cpp +void clearCc(); +``` + + + + + +#### To clear the Blind-carbon-copy recipient mailboxes. + +```cpp +void clearBcc(); +``` + + +#### To clear the custom message headers. + +```cpp +void clearHeader(); +``` + + + + +#### To add attachment to the message. + +param **`att`** The SMTP_Attachment data item + +```cpp +void addAttachment(SMTP_Attachment &att); +``` + + + + + +#### To add parallel attachment to the message. + +param **`att`** The SMTP_Attachment data item + +```cpp +void addParallelAttachment(SMTP_Attachment &att); +``` + + + + + +#### To add inline image to the message. + +param **`att`** The SMTP_Attachment data item + +```cpp +void addInlineImage(SMTP_Attachment &att); +``` + + + + + +#### To add rfc822 message to the message. + +param **`msg`** The RFC822_Message class object + +```cpp +void addMessage(SMTP_Message &msg); +``` + + + + + +#### To add the primary recipient mailbox to the message. + +param **`name`** The name of primary recipient + +param **`email`** The Email address of primary recipient + +```cpp +void addRecipient( name, email); +``` + + + + + +#### To add Carbon-copy recipient mailbox. + +param **`email`** The Email address of secondary recipient + +```cpp +void addCc( email); +``` + + + + + +#### To add Blind-carbon-copy recipient mailbox. + +param **`email`** The Email address of the tertiary recipient + +```cpp +void addBcc( email); +``` + + + + + +#### To add the custom header to the message. + +param **`hdr`** The header name and value + +```cpp +void addHeader( hdr); +``` + + + + +##### [properties] The message author config + +This property has the sub properties + +###### [const char*] name - The sender name. + +###### [const char*] email - The sender Email address. + +```cpp +esp_mail_email_info_t sender; +``` + + +##### [properties] The topic of message + +```cpp +const char *subject; +``` + + +##### [properties] The message type + +```cpp +byte type; +``` + + +##### [properties] The PLAIN text message + +This property has the sub properties + +###### [esp_mail_smtp_embed_message_body_t] embed - The option to embed this message content as a file. + +###### [const char*] content - The PLAIN text content of the message. + +###### [esp_mail_blob_message_content_t] blob - The blob that contins PLAIN text content of the message. + +###### [esp_mail_file_message_content_t] file - The file that contins PLAIN text content of the message. + +###### [const char*] charSet - The character transcoding of the PLAIN text content of the message. + +###### [const char*] content_type - The content type of message. + +###### [const char*] transfer_encoding - The option to encode the content for data transfer. + +###### [boolean] flowed - The option to send the PLAIN text with wrapping. + +```cpp +esp_mail_plain_body_t text; +``` + + +##### [properties] The HTML text message + +This propery has the sub properties + +###### [const char*] content - The HTML content of the message. + +###### [esp_mail_blob_message_content_t] blob - The blob that contins HTML content of the message. + +###### [esp_mail_file_message_content_t] file - The file that contins HTML content of the message. + +###### [const char*] charSet - The character transcoding of the HTML content of the message. + +###### [const char*] content_type - The content type of message. + +###### [const char*] transfer_encoding - The option to encode the content for data transfer. + +```cpp +esp_mail_html_body_t html; +``` + + +##### [properties] The response config + +This propery has the sub properties + +###### [const char*] reply_to - The author Email address to reply. + +###### [const char*] return_path - The sender Email address to return the message. + +###### [int] notify - The Delivery Status Notifications enumeration e.g. + +esp_mail_smtp_notify_never = 0, + +esp_mail_smtp_notify_success = 1, + +esp_mail_smtp_notify_failure = 2, and + +esp_mail_smtp_notify_delay = 4 + +```cpp +esp_mail_smtp_msg_response_t response; +``` + + +##### [properties] The priority of the message + +This property has the enumeration values + +esp_mail_smtp_priority_high = 1, + +esp_mail_smtp_priority_normal = 3, + +esp_mail_smtp_priority_low = 5 + +```cpp +esp_mail_smtp_priority priority; +``` + + +##### [properties] The enable options + +This propery has the sub property + +###### [boolean] chunking - enable chunk data sending for large message. + +```cpp +esp_mail_smtp_enable_option_t enable; +``` + + +##### [properties] The message from config + +This property has the sub properties + +###### [const char*] name - The messsage author name. + +###### [const char*] email - The message author Email address. + +```cpp +esp_mail_email_info_t from; +``` + + +##### [properties] The message identifier + +```cpp +const char *ID; +``` + +##### [properties] The keywords or phrases, separated by commas + +```cpp +const char *keywords; +``` + + +##### [properties] The comments about message + +```cpp +const char *comments; +``` + + +##### [properties] The date of message + +```cpp +const char *date; +``` + + +##### [properties] The return recipient of the message + +```cpp +const char *return_path; +``` + + + +##### [properties] The field that contains the parent's message ID of the message to which this one is a reply + +```cpp +const char *in_reply_to; +``` + + + +##### [properties] The field that contains the parent's references (if any) and followed by the parent's message ID (if any) of the message to which this one is a reply + +```cpp +const char *references; +``` + + +## IMAP_Status class functions + + +The following functions are available from the IMAP Status class. + +This class is used as the callback parameter for retrieving the status while reading the Email. + + + + +#### Get the information of each process in the reading operation. + +return **`string`** The info for each process + +```cpp +const char *info(); +``` + + + + +#### Get the status of completion. + +return **`boolean`** The bool value indicates that all reading processes are finished + +```cpp +bool success(); +``` + + + + + +#### To clear all data store in this class. + +```cpp +void empty(); +``` + + + + + + +## SMTP_Status class functions + + +The following functions are available from the SMTP Status class. + +This class is used as the callback parameter for retrieving the status while sending the Email. + + + + +#### Get the information of each process in the sending operation. + +return **`string`** The info for each process + +```cpp +const char *info(); +``` + + + + +#### Get the status of completion. + +return **`boolean`** The bool value indicates that all sending processes are finished + +```cpp +bool success(); +``` + + + + + +#### To clear all data store in this class. + +```cpp +void empty(); +``` + + + + +#### Get the number of complete sending message. + +return **`number`** The number of message that was sent + +```cpp +size_t completedCount(); +``` + + + + + +#### Get the number of failed sending message. + +return **`number`** The number of message that was not sent + +```cpp +size_t failedCount(); +``` + + + + +## SendingResult class functions + + +The following functions are available from the SendingResult class. + +This class is used for retrieving the info about the result of sending the messages. + + + + +#### Get the information of a message sending status. + +param **`index`** The index number of a message sending status + +return **`SMTP_Result`** The SMTP_Result type data that provides these properties + +##### [bool] completed - The status of the message + +#### [MB_String] recipients - The primary recipient mailbox of the message + +#### [MB_String] subject - The topic of the message + +#### [time_t] timesstamp - The timestamp of the message + +```cpp +SMTP_Result getItem(size_t index); +``` + + + + + +#### Get the amount of the result data. + +return **`number`** The number of result item + +```cpp +size_t size(); +``` + + + + +## SMTP_Response type data + +The following properties are available from the SMTP_Response data type. + +This data type obtains the response from sending custom SMTP commands. + + +#### [Properties] The command identifier + +```cpp +int id; +``` + +#### [Properties] The response text + +```cpp +MB_String text; +``` + + +#### [Properties] The response code + +```cpp +int respCode; +``` + + + + +## FoldersCollection class functions + + +The following functions are available from the FoldersCollection class. + +This class is used for retrieving the info about the mailbox folders which available to read or serach +in the user Email mailbox. + + + + +#### Get the information of a folder in a folder collection. + +param **`index`** The index number of folders + +return **`esp_mail_folder_info_item_t`** The esp_mail_folder_info_item_t structured data that provides these properties + +#### [MB_String] name - The name of folder + +#### [MB_String] attributes - The attributes of folder + +#### [MB_String] delimiter - The delimeter of folder + +```cpp +esp_mail_folder_info_item_t info(size_t index); +``` + + + + + +#### Get the number of folders in the collection. + +return **`number`** The number of folder in the collection + +```cpp +size_t size(); +``` + + + + + + +## SelectedFolderInfo class functions + + +The following functions are available from the SelectedFolderInfo class. + +This class is used for retrieving the info about the sselected or opened mailbox folder. + + + + +#### Get the numbers of flags in the user Email mailbox. + +return **`number`** The numbers of flags + +```cpp +size_t flagCount(); +``` + + + + + +#### Get the numbers of messages in this mailbox. + +return **`number`** The numbers of messages in the selected mailbox folder + +```cpp +size_t msgCount(); +``` + + + + + + +#### Get the numbers of messages in this mailbox that recent flag was set. + +return **`number`** The numbers of messages in the selected mailbox folder that recent flag was set + +```cpp +size_t recentCount(); +``` + + + + + + +#### Get the order of message in number of message in this mailbox that reoved. + +return **`IMAP_Polling_Status`** The data that holds the polling status. + +The IMAP_Polling_Status has the properties e.g. type, messageNum, and argument. + +The type property is the type of status e.g.imap_polling_status_type_undefined, imap_polling_status_type_new_message, +imap_polling_status_type_remove_message, and imap_polling_status_type_fetch_message. + +The messageNum property is message number or order from the total number of message that added, fetched or deleted. + +The argument property is the argument of commands e.g. FETCH + +```cpp +struct IMAP_Polling_Status pollingStatus(); +``` + + + + + + + + +#### Get the predicted next message UID in the sselected folder. + +return **`number`** The number represents the next message UID number + +```cpp +size_t nextUID(); +``` + + + + + + + +#### Get the numbers of messages from search result based on the search criteria. + +return **`number`** The total number of messsages from search + +```cpp +size_t searchCount(); +``` + + + + + +#### Get the numbers of messages to be stored in the ressult. + +return **`number`** The number of messsage stored from search + +```cpp +size_t availableMessages(); +``` + + + + + +#### Get the flag argument at the specified index. + +return **`index`** The index of flag in the flags list + +return **`String`** The argument of selected flag + +```cpp +String flag(size_t index); +``` + + + + +## Session_Config type data + + +The following properties are available from the Session_Config data type. + +This data type is used for storing the session info about the server and login credentials. + + +#### [Properties] The server config + +This property has the sub properties + +##### [MB_String] host_name - The hostName of the server. + +##### [uint16_t] port - The port on the server to connect to. + +```cpp +esp_mail_sesson_sever_config_t server; +``` + + +#### [Properties] The log in config + +This property has the sub properties + +##### [MB_String] email - The user Email address to log in. + +##### [consst char *] password - The user password to log in. + +##### [consst char *] accessToken - The OAuth2.0 access token to log in. + +##### [consst char *] user_domain - The host name or public IP of client system. + +```cpp +esp_mail_sesson_login_config_t login; +``` + + +#### [Properties] The secure config + +This property has the sub properties + +##### [bool] startTLS - The option to send the command to start the TLS connection. + +```cpp +esp_mail_sesson_secure_config_t secure; +``` + + +#### [Properties] The ports and protocols config + +This property has the sub properties + +##### [port_function *] list - The list (aray) of port_function. + +##### [size_t] size - The size of array. + +```cpp +esp_mail_ports_functions ports_functions; +``` + + + + +#### [Properties] The certificate config + +##### [const char *] cert_data - The certificate data (base64 data). + +##### [const char *] cert_file - The certificate file (DER format). + +##### [esp_mail_file_storage_type] cert_file_storage_type - The storage type. + +##### [bool] verify - The cerificate verification option. + +```cpp +esp_mail_sesson_cert_config_t certificate; +``` + + + +#### [Properties] SPI Ethernet Module config for ESP8266 + +##### [ENC28J60lwIP *] enc28j60 - The ENC28J60 Ethernet module lwip interfac. + +##### [Wiznet5100lwIP *] w5100 - The W5100 Ethernet module lwip interfac. + +##### [Wiznet5500lwIP *] w5500 - The W5500 Ethernet module lwip interfac. + +```cpp +esp_mail_spi_ethernet_module_t spi_ethernet_module; +``` + + + +#### [Properties] The callback function for WiFi connection + +```cpp +NetworkConnectionHandler network_connection_handler; +``` + + + + +## port_function type data + +#### [Properties] The port number + +```cpp +uint16_t port; +``` + +#### [Properties] The protocol + +The port protocol e.g. esp_mail_protocol_plain_text, esp_mail_protocol_ssl and esp_mail_protocol_tls. + +```cpp +esp_mail_protocol protocol; +``` + + + + +## IMAP_Data type data + + +The following properties are available from the IMAP_Data data type. + +This data type is used for storing the IMAP transport and operating options to +control and store the operation result e.g. the messahe contents from search and fetch. + + + + +#### [Properties] The config for fetching + +This property has the sub properties + +##### [MB_String] uid - The UID of message to fetch. + +##### [MB_String] number - The message sequence number to fetch. + +##### [esp_mail_imap_sequence_set_t] sequence_set - The sequence set options. + +##### [MB_String] set_seen - Set the message flag as seen. + +```cpp +esp_mail_imap_fetch_config_t fetch; +``` + + +#### [Properties] The config for IMAP sequence set fetching + +This property has the sub properties + +##### [MB_String] string - The sequence set string i.g., unique identifier (UID) +or message sequence number or ranges of UID or sequence number. + +##### [bool] UID - The option for sequenceSet whether it is UID or message sequence number. + +##### [bool] headerOnly - The option for header only fetching. + +```cpp +esp_mail_imap_sequence_set_t fetch; +``` + + +#### [Properties] The config for search + +This property has the sub properties + +##### [MB_String] criteria - The search criteria. + +##### [boolean] unseen_msg - The option to search the unseen message. + +```cpp +esp_mail_imap_search_config_t search; +``` + + +#### [Properties] The config about the limits + +This property has the sub properties + +##### [size_t] search - The maximum messages from the search result. + +##### [size_t] fetch - The maximum messages from the sequence set fetching result. + +##### [size_t] msg_size - The maximum size of the memory buffer to store the message content. + +This is only limit for data to be stored in the IMAPSession. + +##### [size_t] attachment_size - The maximum size of each attachment to download. + +The IMAP idle (polling) timeout in ms (1 min to 29 min). Default is 10 min. + +##### [size_t] imap_idle_timeout - The IMAP idle timeout in ms. + +The IMAP idle (polling) host check interval in ms (30 sec to imap_idle_timeout) +for internet availability checking to ensure the connection is active. + +Default is 1 min. + +##### [size_t] imap_idle_host_check_interval - The IMAP idle host check interval in ms. + + +```cpp +esp_mail_imap_limit_config_t limit; +``` + + + +#### [Properties] The config to enable the features + +This property has the sub properties + +##### [boolean] text - To store the PLAIN text of the message in the IMAPSession. + +##### [boolean] html - To store the HTML of the message in the IMAPSession. + +##### [boolean] rfc822 - To store the rfc822 messages in the IMAPSession. + +##### [boolean] download_status - To enable the download status via the serial port. + +##### [boolean] recent_sort - To sort the message UID of the search result in descending order. + +##### [boolean] header_case_sesitive - To allow case sesitive in header parsing. + +```cpp +esp_mail_imap_enable_config_t enable; +``` + + + +#### [Properties] The config about downloads + +This property has the sub properties + +##### [boolean] text - To download the PLAIN text content of the message. + +##### [boolean] html - To download the HTML content of the message. + +##### [boolean] attachment - To download the attachments of the message. + +##### [boolean] inlineImg - To download the inline image of the message. + +##### [boolean] rfc822 - To download the rfc822 mesages in the message. + +##### [boolean] header - To download the message header. + +```cpp +esp_mail_imap_download_config_t download; +``` + + + +#### [Properties] The config about the storage and path to save the downloaded file. + +This property has the sub properties + +##### [const char*] saved_path - The path to save the downloaded file. + +##### [esp_mail_file_storage_type] type - The type of file storages enumeration e.g. + +esp_mail_file_storage_type_none = 0, + +esp_mail_file_storage_type_flash = 1, and + +esp_mail_file_storage_type_sd = 2 + +```cpp +esp_mail_imap_storage_config_t storage; +``` + + +#### [Properties] The config about firmware updates and downloads for ESP32, ESP8266 and Raspberry Pi Pico. + +This property has the sub properties + +##### [string] attach_filename - Update firmware using message attachments if one of its filename matches. + +##### [bool] save_to_file - Save firmware file option. + +```cpp +esp_mail_imap_firmware_config_t firmware_update; +``` + + + +## esp_mail_smtp_embed_message_body_t structured data + + +The following properties are available from the IMAP_Data data type. + +This data type is used for storing the IMAP transport and operating options to +control and store the operation result e.g. the messahe contents from search and fetch. + + + + +##### [Properties] Enable to send this message body as file + +```cpp +bool enable; +``` + + +##### [Properties] The name of embedded file + +```cpp +const char* enable; +``` + + +##### [Properties] The embedded type enumeration + +esp_mail_smtp_embed_message_type_attachment = 0 + +sp_mail_smtp_embed_message_type_inline = 1 + +```cpp +esp_mail_smtp_embed_message_type type; +``` + +## esp_mail_blob_message_content_t structured data + + +The following properties are available from the esp_mail_blob_message_content_t data type. + +This data type is used for storing the blob info of message body. + + + +##### [Properties] The array of content in flash memory. + +```cpp +const uint8_t * data; +``` + + +##### [Properties] The array size in bytes. + +```cpp +size_t size; +``` + + + + + +## esp_mail_file_message_content_t structured data + + +The following properties are available from the esp_mail_file_message_content_t data type. + +This data type is used for storing the file info of message body. + + +##### [Properties] The file path include its name. + +```cpp +const char *name; +``` + + +##### [Properties] The type of file storages. + +```cpp +esp_mail_file_storage_type type; +``` + + + + + +## IMAP_MSG_Item type data + + +The following properties are available from the IMAP_MSG_Item data type. + +This data type is used for message item info and its contents from search and fetch. + + + + +#### [Properties] The message number + +```cpp +int msgNo; +``` + + +#### [Properties] The message UID + +```cpp +int UID; +``` + + +#### [Properties] The message identifier + +```cpp +const char *ID; +``` + + + +#### [Properties] The language(s) for auto-responses + +```cpp +const char *acceptLang; +``` + + + +#### [Properties] The language of message content + +```cpp +const char *contentLang; +``` + + + +#### [Properties] The mailbox of message author + +```cpp +const char *from; +``` + + +#### [Properties] The charset of the mailbox of message author (deprecate) + +```cpp +const char *fromCharset; +``` + + +#### [Properties] The primary recipient mailbox + +```cpp +const char *to; +``` + + +#### [Properties] The charset of the primary recipient mailbox (deprecate) + +```cpp +const char *toCharset; +``` + + +#### [Properties] The Carbon-copy recipient mailboxes + +```cpp +const char *cc; +``` + + +#### [Properties] The charset of the Carbon-copy recipient mailbox header (deprecate) + +```cpp +const char *ccCharset; +``` + +#### [Properties] The message date and time + +```cpp +const char *date; +``` + +#### [Properties] The topic of message + +```cpp +const char *subject; +``` + +#### [Properties] The topic of message charset (deprecate) + +```cpp +const char *subjectCharset; +``` + +#### [Properties] The PLAIN text content of the message + +```cpp +esp_mail_plain_body_t text; +``` + +#### [Properties] The HTML content of the message + +```cpp +esp_mail_html_body_t html; +``` + +#### [Properties] The sender Email + +```cpp +const char *sender; +``` + + +#### [Properties] The charset of the sender Email (obsoleted) + +```cpp +const char *senderCharset; +``` + + +#### [Properties] The keywords or phrases, separated by commas + +```cpp +const char *keyword; +``` + +#### [Properties] The comments about message + +```cpp +const char *comments; +``` + + +#### [Properties] The return recipient of the message + +```cpp +const char *return_path; +``` + + +#### [Properties] The Email address to reply + +```cpp +const char *reply_to; +``` + + +#### [Properties] The field that contains the parent's message ID of the message to which this one is a reply + +```cpp +const char *in_reply_to; +``` + + +#### [Properties] The field that contains the parent's references (if any) and followed by the parent's message ID (if any) of the message to which this one is a reply + +```cpp +const char *references; +``` + + +#### [Properties] The Blind carbon-copy recipients + +```cpp +const char *bcc; +``` + +#### [Properties] The charset of the Blind carbon-copy recipient mailbox header (obsoleted) + +```cpp +const char *bccCharset; +``` + + +#### [Properties] The error description from fetching the message + +```cpp +const char *fetchError; +``` + + +#### [Properties] The info about the attachments in the message + +```cpp +std::vector attachments; +``` + +#### [Properties] The info about the rfc822 messages included in the message + +```cpp +std::vector rfc822; +``` + + + + +## IMAP_Response type data + +The following properties are available from the IMAP_Response data type. + +This data type obtains the response from sending custom IMAP commands. + + +#### [Properties] The status tag + +```cpp +MB_String tag; +``` + +#### [Properties] The status text + +```cpp +MB_String text; +``` + + +#### [Properties] The completion of response + +```cpp +bool completed; +``` + + + + + + +## MIME_Data_Stream_Info type data + +The following properties are available from the MIME_Data_Stream_Info data type. + +This data type obtains the IMAP multipart body or MIME stream data via the callback function. + + +#### [Properties] The message UID + +```cpp +uint32_t uid; +``` + +#### [Properties] The content type of the message part + +```cpp +const char *type; +``` + +#### [Properties] The content disposition of the message part + +```cpp +const char *disposition; +``` + + +#### [Properties] The content character set of the message part + +```cpp +const char *charSet; +``` + + +#### [Properties] The text content flowed format parameter of the message part + +```cpp +bool flowed; +``` + + +#### [Properties] The text content format DelSp parameter of the message part + +```cpp +bool delsp; +``` + + +#### [Properties] The content transfer encoding of the message part + +```cpp +const char *transfer_encoding; +``` + + +#### [Properties] The content ID of the inline attachment type message part + +```cpp +const char *cid; +``` + + +#### [Properties] The content description of the message part + +```cpp +const char *description; +``` + +#### [Properties] The file name of the attachment type message part + +```cpp +const char *filename; +``` + + +#### [Properties] The name of the attachment type message part + +```cpp +const char *name; +``` + + +#### [Properties] The creation date of the message part + +```cpp +const char *date; +``` + +#### [Properties] The size of the attachment (unencoded) type message part + +```cpp +size_t size; +``` + + +#### [Properties] The total octet of the message part + +```cpp +size_t octet_size; +``` + +#### [Properties] The current octet count of the message part that currently parses + +```cpp +int octet_count; +``` + +#### [Properties] The size of content (unencoded) of message part + +```cpp +size_t data_size; +``` + + +#### [Properties] The data buffer of message part that currently parses + +```cpp +void *data; +``` + + +#### [Properties] The flag that states the first chunk data of message part that currently parses + +```cpp +bool isFirstData; +``` + +#### [Properties] The flag that states the final chunk data of message part that currently parses + +```cpp +bool isLastData; +``` + + + + +## IMAP_Decoding_Info type data + +The following properties are available from the IMAP_Decoding_Info data type. + +This data type obtains the IMAP header and text (plain and html) strings to be decoded via the callback function based on its character set. + + +#### [Properties] The character set of the string to decode + +```cpp +const char *charset; +``` + +#### [Properties] The string to decode + +```cpp +const char *data; +``` + + +#### [Properties] The type of data that currently processed + +0 or IMAP_Decoding_Info::message_part_type_header + +1 or IMAP_Decoding_Info::message_part_type_text + +```cpp +message_part_type type; +``` + + + + + +## Search Criteria + +Search crieria is used for searching the mailbox for messages that match +the given searching criteria. + +Searching criteria consist of one or more search keys. When multiple keys are +specified, the result is the intersection (AND function) of all the messages +that match those keys. + +Example: + + **`DELETED FROM "SMITH" SINCE 1-Feb-1994`** refers +to all deleted messages from Smith that were placed in the mailbox since +February 1, 1994. + +A search key can also be a parenthesized list of one or more search keys +(e.g., for use with the OR and NOT keys). + +**`SINCE 10-Feb-2019`** will search all messages that received since 10 Feb 2019 + +**`UID SEARCH ALL`** will seach all message which will return the message UID +that can be use later for fetch one or more messages. + + +The following keywords can be used for the search criteria. + + +**ALL** - All messages in the mailbox; the default initial key for ANDing. + +**ANSWERED** - Messages with the \Answered flag set. + +**BCC** - Messages that contain the specified string in the envelope structure's BCC field. + +**BEFORE** - Messages whose internal date (disregarding time and timezone) is earlier than the specified date. + +**BODY** - Messages that contain the specified string in the body of the message. + +**CC** - Messages that contain the specified string in the envelope structure's CC field. + +**DELETED** - Messages with the \Deleted flag set. + +**DRAFT** - Messages with the \Draft flag set. + +**FLAGGED** - Messages with the \Flagged flag set. + +**FROM** - Messages that contain the specified string in the envelope structure's FROM field. + +**HEADER** - Messages that have a header with the specified field-name (as defined in [RFC-2822]) + +and that contains the specified string in the text of the header (what comes after the colon). + +If the string to search is zero-length, this matches all messages that have a header line with + +the specified field-name regardless of the contents. + +**KEYWORD** - Messages with the specified keyword flag set. + +**LARGER** - Messages with an (RFC-2822) size larger than the specified number of octets. + +**NEW** - Messages that have the \Recent flag set but not the \Seen flag. + +This is functionally equivalent to **"(RECENT UNSEEN)"**. + +**NOT** - Messages that do not match the specified search key. + +**OLD** - Messages that do not have the \Recent flag set. This is functionally equivalent to + +**"NOT RECENT"** (as opposed to **"NOT NEW"**). + +**ON** - Messages whose internal date (disregarding time and timezone) is within the specified date. + +**OR** - Messages that match either search key. + +**RECENT** - Messages that have the \Recent flag set. + +**SEEN** - Messages that have the \Seen flag set. + +**SENTBEFORE** - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is earlier than the specified date. + +**SENTON** - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is within the specified date. + +**SENTSINCE** - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is within or later than the specified date. + +**SINCE** - Messages whose internal date (disregarding time and timezone) is within or later than the specified date. + +**SMALLER** - Messages with an (RFC-2822) size smaller than the specified number of octets. + +**SUBJECT** - Messages that contain the specified string in the envelope structure's SUBJECT field. + +**TEXT** - Messages that contain the specified string in the header or body of the message. + +**TO** - Messages that contain the specified string in the envelope structure's TO field. + +**UID** - Messages with unique identifiers corresponding to the specified unique identifier set. + +Sequence set ranges are permitted. + +**UNANSWERED** - Messages that do not have the \Answered flag set. + +**UNDELETED** - Messages that do not have the \Deleted flag set. + +**UNDRAFT** - Messages that do not have the \Draft flag set. + +**UNFLAGGED** - Messages that do not have the \Flagged flag set. + +**UNKEYWORD** - Messages that do not have the specified keyword flag set. + +**UNSEEN** - Messages that do not have the \Seen flag set. + + + + + + + + + +## MailClient.Time functions + + +The helper function to set and get the system time. + + + + + +#### Set the system time from the NTP server. + +param **`gmtOffset`** The GMT time offset in hour. + +param **`daylightOffset`** The Daylight time offset in hour. + +return **`boolean`** The status indicates the success of operation. + +This requires internet connection + +```cpp +bool setClock(float gmtOffset, float daylightOffset); +``` + + + + + +#### Get the timestamp from the year, month, date, hour, minute, and second provided. + +param **`year`** The year. + +param **`mon`** The months from 1 to 12. + +param **`date`** The dates. + +param **`hour`** The hours. + +param **`mins`** The minutes. + +param **`sec`** The seconds. + +return **`time_t`** The value of timestamp. + +```cpp +time_t getTimestamp(int year, int mon, int date, int hour, int mins, int sec); +``` + + + + +#### Get the timestamp from the time string. + +param **`gmt`** Return GMT time. + +return **`timestamp`** of time string. + +```cpp +time_t getTimestamp(const char* timeString, bool gmt = false); +``` + + + + + + +#### Get the current timestamp. + +return **`uint64_t`** The value of current timestamp. + +```cpp +uint64_t getCurrentTimestamp(); +``` + + + + + + +#### Get the current date time string that valid for Email + +return **`String`** The current date time string. + +```cpp +String getDateTimeString(); +``` + + + + + + +## License + +The MIT License (MIT) + +Copyright (c) 2023 K. Suwatchai (Mobizt) + + +Permission is hereby granted, free of charge, to any person returning a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/Custom_ESP_SSLClient_FS.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/Custom_ESP_SSLClient_FS.h new file mode 100644 index 000000000000..1f28bdb0cab3 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/Custom_ESP_SSLClient_FS.h @@ -0,0 +1,23 @@ + +#ifndef CUSTOM_ESP_SSLCLIENT_FS_H +#define CUSTOM_ESP_SSLCLIENT_FS_H + +#include "../ESP_Mail_FS.h" + +#if defined(ESP_MAIL_DISABLE_SSL) +#undef USE_LIB_SSL_ENGINE +#undef USE_EMBED_SSL_ENGINE +#endif + +#if defined(ESP_MAIL_USE_PSRAM) +#if !defined(ESP_SSLCLIENT_USE_PSRAM) +#define ESP_SSLCLIENT_USE_PSRAM +#endif +#else +#undef ESP_SSLCLIENT_USE_PSRAM +#endif + +#undef ESP_SSLCLIENT_ENABLE_DEBUG +#undef ESP_SSLCLIENT_ENABLE_SSL_ERROR_STRING + +#endif diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient.h new file mode 100644 index 000000000000..a77b08080b0b --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient.h @@ -0,0 +1,79 @@ +/** + * + * The ESP SSL Client Class, ESP_SSLClient.h v2.1.6 + * + * Created August 27, 2023 + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef ESP_SSLCLIENT_H +#define ESP_SSLCLIENT_H + +#include "ESP_SSLClient_FS.h" + +#ifndef SSLCLIENT_CONNECTION_UPGRADABLE +#define SSLCLIENT_CONNECTION_UPGRADABLE +#endif +#include "ESP_SSLClient_Const.h" +#if defined(USE_EMBED_SSL_ENGINE) || defined(USE_LIB_SSL_ENGINE) +#include "client/BSSL_TCP_Client.h" +class ESP_SSLClient : public BSSL_TCP_Client +{ +public: + ESP_SSLClient(){}; + ~ESP_SSLClient(){}; +}; + +class ESP_SSLClient2 : public BSSL_TCP_Client +{ +public: + ESP_SSLClient2(Client &client, bool enableSSL = true) : _base_client(client) + { + setClient(&_base_client, enableSSL); + }; + ~ESP_SSLClient2(){}; + +private: + Client &_base_client; +}; + +#else +class ESP_SSLClient +{ +public: + ESP_SSLClient(){}; + ~ESP_SSLClient(){}; +}; + +class ESP_SSLClient2 +{ +public: + ESP_SSLClient2(Client &client, bool enableSSL = true) : _base_client(client){}; + ~ESP_SSLClient2(){}; + +private: + Client &_base_client; +}; +#endif + +#endif diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient_Const.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient_Const.h new file mode 100644 index 000000000000..290e702bac7c --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient_Const.h @@ -0,0 +1,138 @@ +#ifndef ESP_SSLCLIENT_CONST_H +#define ESP_SSLCLIENT_CONST_H + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wvla" + +#include "ESP_SSLClient_FS.h" + +#include +#include + +#if defined(__AVR__) +#undef USE_LIB_SSL_ENGINE +#undef USE_EMBED_SSL_ENGINE +#error "Not support AVR architecture" +#endif + +#define ESP_SSLCLIENT_VALID_TIMESTAMP 1690979919 + +#ifndef SSLCLIENT_CONNECTION_UPGRADABLE +#define SSLCLIENT_CONNECTION_UPGRADABLE +#endif + +#ifdef ESP_SSLCLIENT_ENABLE_DEBUG +#if !defined(ESP_SSLCLIENT_DEBUG_PORT) +#define ESP_SSLCLIENT_DEBUG_PORT Serial +#endif +#define ESP_SSLCLIENT_DEBUG_PRINT ESP_SSLCLIENT_DEBUG_PORT.print +#else +#define ESP_SSLCLIENT_DEBUG_PRINT(...) +#endif + +#if !defined(FPSTR) +#define FPSTR +#endif + +#if defined(USE_EMBED_SSL_ENGINE) || defined(USE_LIB_SSL_ENGINE) + +enum esp_ssl_client_debug_level +{ + esp_ssl_debug_none = 0, + esp_ssl_debug_error = 1, + esp_ssl_debug_warn = 2, + esp_ssl_debug_info = 3, + esp_ssl_debug_dump = 4 +}; + +enum esp_ssl_client_error_types +{ + esp_ssl_ok, + esp_ssl_connection_fail, + esp_ssl_write_error, + esp_ssl_read_error, + esp_ssl_out_of_memory, + esp_ssl_internal_error +}; + +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + +static void esp_ssl_debug_print_prefix(const char *func_name, int level) +{ + ESP_SSLCLIENT_DEBUG_PRINT(PSTR("> ")); + // print the debug level + switch (level) + { + case esp_ssl_debug_info: + ESP_SSLCLIENT_DEBUG_PRINT(PSTR("INFO.")); + break; + case esp_ssl_debug_warn: + ESP_SSLCLIENT_DEBUG_PRINT(PSTR("WARN.")); + break; + case esp_ssl_debug_error: + ESP_SSLCLIENT_DEBUG_PRINT(PSTR("ERROR.")); + break; + default: + break; + } + + // print the function name + ESP_SSLCLIENT_DEBUG_PRINT(PSTR("")); + ESP_SSLCLIENT_DEBUG_PRINT(func_name); + ESP_SSLCLIENT_DEBUG_PRINT(PSTR(": ")); +} + +static void esp_ssl_debug_print(PGM_P msg, int debug_level, int level, const char *func_name) +{ + if (debug_level >= level) + { + esp_ssl_debug_print_prefix(func_name, level); + ESP_SSLCLIENT_DEBUG_PRINT(msg); + ESP_SSLCLIENT_DEBUG_PRINT("\r\n"); + } +} + +#endif + +static uint8_t htoi(unsigned char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'A' && c <= 'F') + return 10 + c - 'A'; + else if (c >= 'a' && c <= 'f') + return 10 + c - 'a'; + else + return 255; +} + +// Helper function which aborts a TLS handshake by sending TLS +// ClientAbort and ClientClose messages. +static bool send_abort(Client *probe, bool supportsLen) +{ + // If we're still connected, send the appropriate notice that + // we're aborting the handshake per RFCs. + static const uint8_t clientAbort_P[] PROGMEM = { + 0x15 /*alert*/, 0x03, 0x03 /*TLS 1.2*/, 0x00, 0x02, + 1, 90 /* warning: user_cancelled */ + }; + static const uint8_t clientClose_P[] PROGMEM = { + 0x15 /*alert*/, 0x03, 0x03 /*TLS 1.2*/, 0x00, 0x02, + 1, 0 /* warning: close_notify */ + }; + if (probe->connected()) + { + uint8_t msg[sizeof(clientAbort_P)]; + memcpy_P(msg, clientAbort_P, sizeof(clientAbort_P)); + probe->write(msg, sizeof(clientAbort_P)); + memcpy_P(msg, clientClose_P, sizeof(clientClose_P)); + probe->write(msg, sizeof(clientClose_P)); + } + return supportsLen; +} + +const uint16_t _secure_ports[26] = {443 /* HTTPS */, 465 /* SMTP */, 563 /* NNTP */, 636 /* LDAPS */, 695 /* IEEE-MMS-SSL */, 832 /* NETCONF */, 853 /* DNS */, 989 /* FTPS */, 990 /* FTPS */, 992 /* Telnet */, 993 /* IMAP */, 995 /* POP3 */, 4116 /* Smartcard */, 4843 /* OPC */, 5061 /* SIP */, 5085 /* LLIP */, 5349 /* NAT */, 5671 /* AMQP */, 5986 /* WinRM-HTTPS */, 6513 /* NETCONF */, 6514 /* Syslog */, 6515 /* Elipse RPC */, 6619 /* OFTP */, 8243 /* Apache Synapse */, 8403 /* GxFWD */, 8883 /* MQTT */}; + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient_FS.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient_FS.h new file mode 100644 index 000000000000..8c56a873cc27 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient_FS.h @@ -0,0 +1,42 @@ +#ifndef ESP_SSLClient_FS_H +#define ESP_SSLClient_FS_H + +// #if (defined(ESP8266) || defined(ARDUINO_ARCH_RP2040)) && !defined(ARDUINO_NANO_RP2040_CONNECT) +// // for ESP8266 and Raspberry Pi Pico (RP2040) only except for Arduino Nano RP2040 Connect +// #define USE_EMBED_SSL_ENGINE +// #else +#define USE_LIB_SSL_ENGINE +// #endif + +#pragma once + +// for enable debugging +#define ESP_SSLCLIENT_ENABLE_DEBUG + +/** Call ssl_client.setDebugLevel(x) to set the debug + * esp_ssl_debug_none = 0 + * esp_ssl_debug_error = 1 + * esp_ssl_debug_warn = 2 + * esp_ssl_debug_info = 3 + * esp_ssl_debug_dump = 4 + */ + +// for debug port +#define ESP_SSLCLIENT_DEBUG_PORT Serial + +// for SSL Error String +#define ESP_SSLCLIENT_ENABLE_SSL_ERROR_STRING + +// for Filesystem support that required for CertStore +#define ESP_SSLCLIENT_USE_FILESYSTEM + +// For external SRAM (PSRAM) support +#define ESP_SSLCLIENT_USE_PSRAM + +#if defined __has_include +#if __has_include() +#include "Custom_ESP_SSLClient_FS.h" +#endif +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl.h new file mode 100644 index 000000000000..cc1e52795ee1 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_H__ +#define BR_BEARSSL_H__ + +#include +#include + +/** \mainpage BearSSL API + * + * # API Layout + * + * The functions and structures defined by the BearSSL API are located + * in various header files: + * + * | Header file | Elements | + * | :-------------- | :------------------------------------------------ | + * | bearssl_hash.h | Hash functions | + * | bearssl_hmac.h | HMAC | + * | bearssl_kdf.h | Key Derivation Functions | + * | bearssl_rand.h | Pseudorandom byte generators | + * | bearssl_prf.h | PRF implementations (for SSL/TLS) | + * | bearssl_block.h | Symmetric encryption | + * | bearssl_aead.h | AEAD algorithms (combined encryption + MAC) | + * | bearssl_rsa.h | RSA encryption and signatures | + * | bearssl_ec.h | Elliptic curves support (including ECDSA) | + * | bearssl_ssl.h | SSL/TLS engine interface | + * | bearssl_x509.h | X.509 certificate decoding and validation | + * | bearssl_pem.h | Base64/PEM decoding support functions | + * + * Applications using BearSSL are supposed to simply include `bearssl.h` + * as follows: + * + * #include + * + * The `bearssl.h` file itself includes all the other header files. It is + * possible to include specific header files, but it has no practical + * advantage for the application. The API is separated into separate + * header files only for documentation convenience. + * + * + * # Conventions + * + * ## MUST and SHALL + * + * In all descriptions, the usual "MUST", "SHALL", "MAY",... terminology + * is used. Failure to meet requirements expressed with a "MUST" or + * "SHALL" implies undefined behaviour, which means that segmentation + * faults, buffer overflows, and other similar adverse events, may occur. + * + * In general, BearSSL is not very forgiving of programming errors, and + * does not include much failsafes or error reporting when the problem + * does not arise from external transient conditions, and can be fixed + * only in the application code. This is done so in order to make the + * total code footprint lighter. + * + * + * ## `NULL` values + * + * Function parameters with a pointer type shall not be `NULL` unless + * explicitly authorised by the documentation. As an exception, when + * the pointer aims at a sequence of bytes and is accompanied with + * a length parameter, and the length is zero (meaning that there is + * no byte at all to retrieve), then the pointer may be `NULL` even if + * not explicitly allowed. + * + * + * ## Memory Allocation + * + * BearSSL does not perform dynamic memory allocation. This implies that + * for any functionality that requires a non-transient state, the caller + * is responsible for allocating the relevant context structure. Such + * allocation can be done in any appropriate area, including static data + * segments, the heap, and the stack, provided that proper alignment is + * respected. The header files define these context structures + * (including size and contents), so the C compiler should handle + * alignment automatically. + * + * Since there is no dynamic resource allocation, there is also nothing to + * release. When the calling code is done with a BearSSL feature, it + * may simple release the context structures it allocated itself, with + * no "close function" to call. If the context structures were allocated + * on the stack (as local variables), then even that release operation is + * implicit. + * + * + * ## Structure Contents + * + * Except when explicitly indicated, structure contents are opaque: they + * are included in the header files so that calling code may know the + * structure sizes and alignment requirements, but callers SHALL NOT + * access individual fields directly. For fields that are supposed to + * be read from or written to, the API defines accessor functions (the + * simplest of these accessor functions are defined as `static inline` + * functions, and the C compiler will optimise them away). + * + * + * # API Usage + * + * BearSSL usage for running a SSL/TLS client or server is described + * on the [BearSSL Web site](https://www.bearssl.org/api1.html). The + * BearSSL source archive also comes with sample code. + */ + +#include "bearssl_hash.h" +#include "bearssl_hmac.h" +#include "bearssl_kdf.h" +#include "bearssl_rand.h" +#include "bearssl_prf.h" +#include "bearssl_block.h" +#include "bearssl_aead.h" +#include "bearssl_rsa.h" +#include "bearssl_ec.h" +#include "bearssl_ssl.h" +#include "bearssl_x509.h" +#include "bearssl_pem.h" + +/** \brief Type for a configuration option. + * + * A "configuration option" is a value that is selected when the BearSSL + * library itself is compiled. Most options are boolean; their value is + * then either 1 (option is enabled) or 0 (option is disabled). Some + * values have other integer values. Option names correspond to macro + * names. Some of the options can be explicitly set in the internal + * `"config.h"` file. + */ +typedef struct { + /** \brief Configurable option name. */ + const char *name; + /** \brief Configurable option value. */ + long value; +} br_config_option; + +/** \brief Get configuration report. + * + * This function returns compiled configuration options, each as a + * 'long' value. Names match internal macro names, in particular those + * that can be set in the `"config.h"` inner file. For boolean options, + * the numerical value is 1 if enabled, 0 if disabled. For maximum + * key sizes, values are expressed in bits. + * + * The returned array is terminated by an entry whose `name` is `NULL`. + * + * \return the configuration report. + */ +const br_config_option *br_get_config(void); + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_aead.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_aead.h new file mode 100644 index 000000000000..621de90e9783 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_aead.h @@ -0,0 +1,1064 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_AEAD_H__ +#define BR_BEARSSL_AEAD_H__ + +#include +#include + +#include "bearssl_block.h" +#include "bearssl_hash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_aead.h + * + * # Authenticated Encryption with Additional Data + * + * This file documents the API for AEAD encryption. + * + * + * ## Procedural API + * + * An AEAD algorithm processes messages and provides confidentiality + * (encryption) and checked integrity (MAC). It uses the following + * parameters: + * + * - A symmetric key. Exact size depends on the AEAD algorithm. + * + * - A nonce (IV). Size depends on the AEAD algorithm; for most + * algorithms, it is crucial for security that any given nonce + * value is never used twice for the same key and distinct + * messages. + * + * - Data to encrypt and protect. + * + * - Additional authenticated data, which is covered by the MAC but + * otherwise left untouched (i.e. not encrypted). + * + * The AEAD algorithm encrypts the data, and produces an authentication + * tag. It is assumed that the encrypted data, the tag, the additional + * authenticated data and the nonce are sent to the receiver; the + * additional data and the nonce may be implicit (e.g. using elements of + * the underlying transport protocol, such as record sequence numbers). + * The receiver will recompute the tag value and compare it with the one + * received; if they match, then the data is correct, and can be + * decrypted and used; otherwise, at least one of the elements was + * altered in transit, normally leading to wholesale rejection of the + * complete message. + * + * For each AEAD algorithm, identified by a symbolic name (hereafter + * denoted as "`xxx`"), the following functions are defined: + * + * - `br_xxx_init()` + * + * Initialise the AEAD algorithm, on a provided context structure. + * Exact parameters depend on the algorithm, and may include + * pointers to extra implementations and context structures. The + * secret key is provided at this point, either directly or + * indirectly. + * + * - `br_xxx_reset()` + * + * Start a new AEAD computation. The nonce value is provided as + * parameter to this function. + * + * - `br_xxx_aad_inject()` + * + * Inject some additional authenticated data. Additional data may + * be provided in several chunks of arbitrary length. + * + * - `br_xxx_flip()` + * + * This function MUST be called after injecting all additional + * authenticated data, and before beginning to encrypt the plaintext + * (or decrypt the ciphertext). + * + * - `br_xxx_run()` + * + * Process some plaintext (to encrypt) or ciphertext (to decrypt). + * Encryption/decryption is done in place. Data may be provided in + * several chunks of arbitrary length. + * + * - `br_xxx_get_tag()` + * + * Compute the authentication tag. All message data (encrypted or + * decrypted) must have been injected at that point. Also, this + * call may modify internal context elements, so it may be called + * only once for a given AEAD computation. + * + * - `br_xxx_check_tag()` + * + * An alternative to `br_xxx_get_tag()`, meant to be used by the + * receiver: the authentication tag is internally recomputed, and + * compared with the one provided as parameter. + * + * This API makes the following assumptions on the AEAD algorithm: + * + * - Encryption does not expand the size of the ciphertext; there is + * no padding. This is true of most modern AEAD modes such as GCM. + * + * - The additional authenticated data must be processed first, + * before the encrypted/decrypted data. + * + * - Nonce, plaintext and additional authenticated data all consist + * in an integral number of bytes. There is no provision to use + * elements whose length in bits is not a multiple of 8. + * + * Each AEAD algorithm has its own requirements and limits on the sizes + * of additional data and plaintext. This API does not provide any + * way to report invalid usage; it is up to the caller to ensure that + * the provided key, nonce, and data elements all fit the algorithm's + * requirements. + * + * + * ## Object-Oriented API + * + * Each context structure begins with a field (called `vtable`) that + * points to an instance of a structure that references the relevant + * functions through pointers. Each such structure contains the + * following: + * + * - `reset` + * + * Pointer to the reset function, that allows starting a new + * computation. + * + * - `aad_inject` + * + * Pointer to the additional authenticated data injection function. + * + * - `flip` + * + * Pointer to the function that transitions from additional data + * to main message data processing. + * + * - `get_tag` + * + * Pointer to the function that computes and returns the tag. + * + * - `check_tag` + * + * Pointer to the function that computes and verifies the tag against + * a received value. + * + * Note that there is no OOP method for context initialisation: the + * various AEAD algorithms have different requirements that would not + * map well to a single initialisation API. + * + * The OOP API is not provided for CCM, due to its specific requirements + * (length of plaintext must be known in advance). + */ + +/** + * \brief Class type of an AEAD algorithm. + */ +typedef struct br_aead_class_ br_aead_class; +struct br_aead_class_ { + + /** + * \brief Size (in bytes) of authentication tags created by + * this AEAD algorithm. + */ + size_t tag_size; + + /** + * \brief Reset an AEAD context. + * + * This function resets an already initialised AEAD context for + * a new computation run. Implementations and keys are + * conserved. This function can be called at any time; it + * cancels any ongoing AEAD computation that uses the provided + * context structure. + + * The provided IV is a _nonce_. Each AEAD algorithm has its + * own requirements on IV size and contents; for most of them, + * it is crucial to security that each nonce value is used + * only once for a given secret key. + * + * \param cc AEAD context structure. + * \param iv AEAD nonce to use. + * \param len AEAD nonce length (in bytes). + */ + void (*reset)(const br_aead_class **cc, const void *iv, size_t len); + + /** + * \brief Inject additional authenticated data. + * + * The provided data is injected into a running AEAD + * computation. Additional data must be injected _before_ the + * call to `flip()`. Additional data can be injected in several + * chunks of arbitrary length. + * + * \param cc AEAD context structure. + * \param data pointer to additional authenticated data. + * \param len length of additional authenticated data (in bytes). + */ + void (*aad_inject)(const br_aead_class **cc, + const void *data, size_t len); + + /** + * \brief Finish injection of additional authenticated data. + * + * This function MUST be called before beginning the actual + * encryption or decryption (with `run()`), even if no + * additional authenticated data was injected. No additional + * authenticated data may be injected after this function call. + * + * \param cc AEAD context structure. + */ + void (*flip)(const br_aead_class **cc); + + /** + * \brief Encrypt or decrypt some data. + * + * Data encryption or decryption can be done after `flip()` has + * been called on the context. If `encrypt` is non-zero, then + * the provided data shall be plaintext, and it is encrypted in + * place. Otherwise, the data shall be ciphertext, and it is + * decrypted in place. + * + * Data may be provided in several chunks of arbitrary length. + * + * \param cc AEAD context structure. + * \param encrypt non-zero for encryption, zero for decryption. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ + void (*run)(const br_aead_class **cc, int encrypt, + void *data, size_t len); + + /** + * \brief Compute authentication tag. + * + * Compute the AEAD authentication tag. The tag length depends + * on the AEAD algorithm; it is written in the provided `tag` + * buffer. This call terminates the AEAD run: no data may be + * processed with that AEAD context afterwards, until `reset()` + * is called to initiate a new AEAD run. + * + * The tag value must normally be sent along with the encrypted + * data. When decrypting, the tag value must be recomputed and + * compared with the received tag: if the two tag values differ, + * then either the tag or the encrypted data was altered in + * transit. As an alternative to this function, the + * `check_tag()` function may be used to compute and check the + * tag value. + * + * Tag length depends on the AEAD algorithm. + * + * \param cc AEAD context structure. + * \param tag destination buffer for the tag. + */ + void (*get_tag)(const br_aead_class **cc, void *tag); + + /** + * \brief Compute and check authentication tag. + * + * This function is an alternative to `get_tag()`, and is + * normally used on the receiving end (i.e. when decrypting + * messages). The tag value is recomputed and compared with the + * provided tag value. If they match, 1 is returned; on + * mismatch, 0 is returned. A returned value of 0 means that the + * data or the tag was altered in transit, normally leading to + * wholesale rejection of the complete message. + * + * Tag length depends on the AEAD algorithm. + * + * \param cc AEAD context structure. + * \param tag tag value to compare with. + * \return 1 on success (exact match of tag value), 0 otherwise. + */ + uint32_t (*check_tag)(const br_aead_class **cc, const void *tag); + + /** + * \brief Compute authentication tag (with truncation). + * + * This function is similar to `get_tag()`, except that the tag + * length is provided. Some AEAD algorithms allow several tag + * lengths, usually by truncating the normal tag. Shorter tags + * mechanically increase success probability of forgeries. + * The range of allowed tag lengths depends on the algorithm. + * + * \param cc AEAD context structure. + * \param tag destination buffer for the tag. + * \param len tag length (in bytes). + */ + void (*get_tag_trunc)(const br_aead_class **cc, void *tag, size_t len); + + /** + * \brief Compute and check authentication tag (with truncation). + * + * This function is similar to `check_tag()` except that it + * works over an explicit tag length. See `get_tag()` for a + * discussion of explicit tag lengths; the range of allowed tag + * lengths depends on the algorithm. + * + * \param cc AEAD context structure. + * \param tag tag value to compare with. + * \param len tag length (in bytes). + * \return 1 on success (exact match of tag value), 0 otherwise. + */ + uint32_t (*check_tag_trunc)(const br_aead_class **cc, + const void *tag, size_t len); +}; + +/** + * \brief Context structure for GCM. + * + * GCM is an AEAD mode that combines a block cipher in CTR mode with a + * MAC based on GHASH, to provide authenticated encryption: + * + * - Any block cipher with 16-byte blocks can be used with GCM. + * + * - The nonce can have any length, from 0 up to 2^64-1 bits; however, + * 96-bit nonces (12 bytes) are recommended (nonces with a length + * distinct from 12 bytes are internally hashed, which risks reusing + * nonce value with a small but not always negligible probability). + * + * - Additional authenticated data may have length up to 2^64-1 bits. + * + * - Message length may range up to 2^39-256 bits at most. + * + * - The authentication tag has length 16 bytes. + * + * The GCM initialisation function receives as parameter an + * _initialised_ block cipher implementation context, with the secret + * key already set. A pointer to that context will be kept within the + * GCM context structure. It is up to the caller to allocate and + * initialise that block cipher context. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_aead_class *vtable; + +#ifndef BR_DOXYGEN_IGNORE + const br_block_ctr_class **bctx; + br_ghash gh; + unsigned char h[16]; + unsigned char j0_1[12]; + unsigned char buf[16]; + unsigned char y[16]; + uint32_t j0_2, jc; + uint64_t count_aad, count_ctr; +#endif +} br_gcm_context; + +/** + * \brief Initialize a GCM context. + * + * A block cipher implementation, with its initialised context structure, + * is provided. The block cipher MUST use 16-byte blocks in CTR mode, + * and its secret key MUST have been already set in the provided context. + * A GHASH implementation must also be provided. The parameters are linked + * in the GCM context. + * + * After this function has been called, the `br_gcm_reset()` function must + * be called, to provide the IV for GCM computation. + * + * \param ctx GCM context structure. + * \param bctx block cipher context (already initialised with secret key). + * \param gh GHASH implementation. + */ +void br_gcm_init(br_gcm_context *ctx, + const br_block_ctr_class **bctx, br_ghash gh); + +/** + * \brief Reset a GCM context. + * + * This function resets an already initialised GCM context for a new + * computation run. Implementations and keys are conserved. This function + * can be called at any time; it cancels any ongoing GCM computation that + * uses the provided context structure. + * + * The provided IV is a _nonce_. It is critical to GCM security that IV + * values are not repeated for the same encryption key. IV can have + * arbitrary length (up to 2^64-1 bits), but the "normal" length is + * 96 bits (12 bytes). + * + * \param ctx GCM context structure. + * \param iv GCM nonce to use. + * \param len GCM nonce length (in bytes). + */ +void br_gcm_reset(br_gcm_context *ctx, const void *iv, size_t len); + +/** + * \brief Inject additional authenticated data into GCM. + * + * The provided data is injected into a running GCM computation. Additional + * data must be injected _before_ the call to `br_gcm_flip()`. + * Additional data can be injected in several chunks of arbitrary length; + * the maximum total size of additional authenticated data is 2^64-1 + * bits. + * + * \param ctx GCM context structure. + * \param data pointer to additional authenticated data. + * \param len length of additional authenticated data (in bytes). + */ +void br_gcm_aad_inject(br_gcm_context *ctx, const void *data, size_t len); + +/** + * \brief Finish injection of additional authenticated data into GCM. + * + * This function MUST be called before beginning the actual encryption + * or decryption (with `br_gcm_run()`), even if no additional authenticated + * data was injected. No additional authenticated data may be injected + * after this function call. + * + * \param ctx GCM context structure. + */ +void br_gcm_flip(br_gcm_context *ctx); + +/** + * \brief Encrypt or decrypt some data with GCM. + * + * Data encryption or decryption can be done after `br_gcm_flip()` + * has been called on the context. If `encrypt` is non-zero, then the + * provided data shall be plaintext, and it is encrypted in place. + * Otherwise, the data shall be ciphertext, and it is decrypted in place. + * + * Data may be provided in several chunks of arbitrary length. The maximum + * total length for data is 2^39-256 bits, i.e. about 65 gigabytes. + * + * \param ctx GCM context structure. + * \param encrypt non-zero for encryption, zero for decryption. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ +void br_gcm_run(br_gcm_context *ctx, int encrypt, void *data, size_t len); + +/** + * \brief Compute GCM authentication tag. + * + * Compute the GCM authentication tag. The tag is a 16-byte value which + * is written in the provided `tag` buffer. This call terminates the + * GCM run: no data may be processed with that GCM context afterwards, + * until `br_gcm_reset()` is called to initiate a new GCM run. + * + * The tag value must normally be sent along with the encrypted data. + * When decrypting, the tag value must be recomputed and compared with + * the received tag: if the two tag values differ, then either the tag + * or the encrypted data was altered in transit. As an alternative to + * this function, the `br_gcm_check_tag()` function can be used to + * compute and check the tag value. + * + * \param ctx GCM context structure. + * \param tag destination buffer for the tag (16 bytes). + */ +void br_gcm_get_tag(br_gcm_context *ctx, void *tag); + +/** + * \brief Compute and check GCM authentication tag. + * + * This function is an alternative to `br_gcm_get_tag()`, normally used + * on the receiving end (i.e. when decrypting value). The tag value is + * recomputed and compared with the provided tag value. If they match, 1 + * is returned; on mismatch, 0 is returned. A returned value of 0 means + * that the data or the tag was altered in transit, normally leading to + * wholesale rejection of the complete message. + * + * \param ctx GCM context structure. + * \param tag tag value to compare with (16 bytes). + * \return 1 on success (exact match of tag value), 0 otherwise. + */ +uint32_t br_gcm_check_tag(br_gcm_context *ctx, const void *tag); + +/** + * \brief Compute GCM authentication tag (with truncation). + * + * This function is similar to `br_gcm_get_tag()`, except that it allows + * the tag to be truncated to a smaller length. The intended tag length + * is provided as `len` (in bytes); it MUST be no more than 16, but + * it may be smaller. Note that decreasing tag length mechanically makes + * forgeries easier; NIST SP 800-38D specifies that the tag length shall + * lie between 12 and 16 bytes (inclusive), but may be truncated down to + * 4 or 8 bytes, for specific applications that can tolerate it. It must + * also be noted that successful forgeries leak information on the + * authentication key, making subsequent forgeries easier. Therefore, + * tag truncation, and in particular truncation to sizes lower than 12 + * bytes, shall be envisioned only with great care. + * + * The tag is written in the provided `tag` buffer. This call terminates + * the GCM run: no data may be processed with that GCM context + * afterwards, until `br_gcm_reset()` is called to initiate a new GCM + * run. + * + * The tag value must normally be sent along with the encrypted data. + * When decrypting, the tag value must be recomputed and compared with + * the received tag: if the two tag values differ, then either the tag + * or the encrypted data was altered in transit. As an alternative to + * this function, the `br_gcm_check_tag_trunc()` function can be used to + * compute and check the tag value. + * + * \param ctx GCM context structure. + * \param tag destination buffer for the tag. + * \param len tag length (16 bytes or less). + */ +void br_gcm_get_tag_trunc(br_gcm_context *ctx, void *tag, size_t len); + +/** + * \brief Compute and check GCM authentication tag (with truncation). + * + * This function is an alternative to `br_gcm_get_tag_trunc()`, normally used + * on the receiving end (i.e. when decrypting value). The tag value is + * recomputed and compared with the provided tag value. If they match, 1 + * is returned; on mismatch, 0 is returned. A returned value of 0 means + * that the data or the tag was altered in transit, normally leading to + * wholesale rejection of the complete message. + * + * Tag length MUST be 16 bytes or less. The normal GCM tag length is 16 + * bytes. See `br_check_tag_trunc()` for some discussion on the potential + * perils of truncating authentication tags. + * + * \param ctx GCM context structure. + * \param tag tag value to compare with. + * \param len tag length (in bytes). + * \return 1 on success (exact match of tag value), 0 otherwise. + */ +uint32_t br_gcm_check_tag_trunc(br_gcm_context *ctx, + const void *tag, size_t len); + +/** + * \brief Class instance for GCM. + */ +extern const br_aead_class br_gcm_vtable; + +/** + * \brief Context structure for EAX. + * + * EAX is an AEAD mode that combines a block cipher in CTR mode with + * CBC-MAC using the same block cipher and the same key, to provide + * authenticated encryption: + * + * - Any block cipher with 16-byte blocks can be used with EAX + * (technically, other block sizes are defined as well, but this + * is not implemented by these functions; shorter blocks also + * imply numerous security issues). + * + * - The nonce can have any length, as long as nonce values are + * not reused (thus, if nonces are randomly selected, the nonce + * size should be such that reuse probability is negligible). + * + * - Additional authenticated data length is unlimited. + * + * - Message length is unlimited. + * + * - The authentication tag has length 16 bytes. + * + * The EAX initialisation function receives as parameter an + * _initialised_ block cipher implementation context, with the secret + * key already set. A pointer to that context will be kept within the + * EAX context structure. It is up to the caller to allocate and + * initialise that block cipher context. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_aead_class *vtable; + +#ifndef BR_DOXYGEN_IGNORE + const br_block_ctrcbc_class **bctx; + unsigned char L2[16]; + unsigned char L4[16]; + unsigned char nonce[16]; + unsigned char head[16]; + unsigned char ctr[16]; + unsigned char cbcmac[16]; + unsigned char buf[16]; + size_t ptr; +#endif +} br_eax_context; + +/** + * \brief EAX captured state. + * + * Some internal values computed by EAX may be captured at various + * points, and reused for another EAX run with the same secret key, + * for lower per-message overhead. Captured values do not depend on + * the nonce. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + unsigned char st[3][16]; +#endif +} br_eax_state; + +/** + * \brief Initialize an EAX context. + * + * A block cipher implementation, with its initialised context + * structure, is provided. The block cipher MUST use 16-byte blocks in + * CTR + CBC-MAC mode, and its secret key MUST have been already set in + * the provided context. The parameters are linked in the EAX context. + * + * After this function has been called, the `br_eax_reset()` function must + * be called, to provide the nonce for EAX computation. + * + * \param ctx EAX context structure. + * \param bctx block cipher context (already initialised with secret key). + */ +void br_eax_init(br_eax_context *ctx, const br_block_ctrcbc_class **bctx); + +/** + * \brief Capture pre-AAD state. + * + * This function precomputes key-dependent data, and stores it in the + * provided `st` structure. This structure should then be used with + * `br_eax_reset_pre_aad()`, or updated with `br_eax_get_aad_mac()` + * and then used with `br_eax_reset_post_aad()`. + * + * The EAX context structure is unmodified by this call. + * + * \param ctx EAX context structure. + * \param st recipient for captured state. + */ +void br_eax_capture(const br_eax_context *ctx, br_eax_state *st); + +/** + * \brief Reset an EAX context. + * + * This function resets an already initialised EAX context for a new + * computation run. Implementations and keys are conserved. This function + * can be called at any time; it cancels any ongoing EAX computation that + * uses the provided context structure. + * + * It is critical to EAX security that nonce values are not repeated for + * the same encryption key. Nonces can have arbitrary length. If nonces + * are randomly generated, then a nonce length of at least 128 bits (16 + * bytes) is recommended, to make nonce reuse probability sufficiently + * low. + * + * \param ctx EAX context structure. + * \param nonce EAX nonce to use. + * \param len EAX nonce length (in bytes). + */ +void br_eax_reset(br_eax_context *ctx, const void *nonce, size_t len); + +/** + * \brief Reset an EAX context with a pre-AAD captured state. + * + * This function is an alternative to `br_eax_reset()`, that reuses a + * previously captured state structure for lower per-message overhead. + * The state should have been populated with `br_eax_capture_state()` + * but not updated with `br_eax_get_aad_mac()`. + * + * After this function is called, additional authenticated data MUST + * be injected. At least one byte of additional authenticated data + * MUST be provided with `br_eax_aad_inject()`; computation result will + * be incorrect if `br_eax_flip()` is called right away. + * + * After injection of the AAD and call to `br_eax_flip()`, at least + * one message byte must be provided. Empty messages are not supported + * with this reset mode. + * + * \param ctx EAX context structure. + * \param st pre-AAD captured state. + * \param nonce EAX nonce to use. + * \param len EAX nonce length (in bytes). + */ +void br_eax_reset_pre_aad(br_eax_context *ctx, const br_eax_state *st, + const void *nonce, size_t len); + +/** + * \brief Reset an EAX context with a post-AAD captured state. + * + * This function is an alternative to `br_eax_reset()`, that reuses a + * previously captured state structure for lower per-message overhead. + * The state should have been populated with `br_eax_capture_state()` + * and then updated with `br_eax_get_aad_mac()`. + * + * After this function is called, message data MUST be injected. The + * `br_eax_flip()` function MUST NOT be called. At least one byte of + * message data MUST be provided with `br_eax_run()`; empty messages + * are not supported with this reset mode. + * + * \param ctx EAX context structure. + * \param st post-AAD captured state. + * \param nonce EAX nonce to use. + * \param len EAX nonce length (in bytes). + */ +void br_eax_reset_post_aad(br_eax_context *ctx, const br_eax_state *st, + const void *nonce, size_t len); + +/** + * \brief Inject additional authenticated data into EAX. + * + * The provided data is injected into a running EAX computation. Additional + * data must be injected _before_ the call to `br_eax_flip()`. + * Additional data can be injected in several chunks of arbitrary length; + * the total amount of additional authenticated data is unlimited. + * + * \param ctx EAX context structure. + * \param data pointer to additional authenticated data. + * \param len length of additional authenticated data (in bytes). + */ +void br_eax_aad_inject(br_eax_context *ctx, const void *data, size_t len); + +/** + * \brief Finish injection of additional authenticated data into EAX. + * + * This function MUST be called before beginning the actual encryption + * or decryption (with `br_eax_run()`), even if no additional authenticated + * data was injected. No additional authenticated data may be injected + * after this function call. + * + * \param ctx EAX context structure. + */ +void br_eax_flip(br_eax_context *ctx); + +/** + * \brief Obtain a copy of the MAC on additional authenticated data. + * + * This function may be called only after `br_eax_flip()`; it copies the + * AAD-specific MAC value into the provided state. The MAC value depends + * on the secret key and the additional data itself, but not on the + * nonce. The updated state `st` is meant to be used as parameter for a + * further `br_eax_reset_post_aad()` call. + * + * \param ctx EAX context structure. + * \param st captured state to update. + */ +static inline void +br_eax_get_aad_mac(const br_eax_context *ctx, br_eax_state *st) +{ + memcpy(st->st[1], ctx->head, sizeof ctx->head); +} + +/** + * \brief Encrypt or decrypt some data with EAX. + * + * Data encryption or decryption can be done after `br_eax_flip()` + * has been called on the context. If `encrypt` is non-zero, then the + * provided data shall be plaintext, and it is encrypted in place. + * Otherwise, the data shall be ciphertext, and it is decrypted in place. + * + * Data may be provided in several chunks of arbitrary length. + * + * \param ctx EAX context structure. + * \param encrypt non-zero for encryption, zero for decryption. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ +void br_eax_run(br_eax_context *ctx, int encrypt, void *data, size_t len); + +/** + * \brief Compute EAX authentication tag. + * + * Compute the EAX authentication tag. The tag is a 16-byte value which + * is written in the provided `tag` buffer. This call terminates the + * EAX run: no data may be processed with that EAX context afterwards, + * until `br_eax_reset()` is called to initiate a new EAX run. + * + * The tag value must normally be sent along with the encrypted data. + * When decrypting, the tag value must be recomputed and compared with + * the received tag: if the two tag values differ, then either the tag + * or the encrypted data was altered in transit. As an alternative to + * this function, the `br_eax_check_tag()` function can be used to + * compute and check the tag value. + * + * \param ctx EAX context structure. + * \param tag destination buffer for the tag (16 bytes). + */ +void br_eax_get_tag(br_eax_context *ctx, void *tag); + +/** + * \brief Compute and check EAX authentication tag. + * + * This function is an alternative to `br_eax_get_tag()`, normally used + * on the receiving end (i.e. when decrypting value). The tag value is + * recomputed and compared with the provided tag value. If they match, 1 + * is returned; on mismatch, 0 is returned. A returned value of 0 means + * that the data or the tag was altered in transit, normally leading to + * wholesale rejection of the complete message. + * + * \param ctx EAX context structure. + * \param tag tag value to compare with (16 bytes). + * \return 1 on success (exact match of tag value), 0 otherwise. + */ +uint32_t br_eax_check_tag(br_eax_context *ctx, const void *tag); + +/** + * \brief Compute EAX authentication tag (with truncation). + * + * This function is similar to `br_eax_get_tag()`, except that it allows + * the tag to be truncated to a smaller length. The intended tag length + * is provided as `len` (in bytes); it MUST be no more than 16, but + * it may be smaller. Note that decreasing tag length mechanically makes + * forgeries easier; NIST SP 800-38D specifies that the tag length shall + * lie between 12 and 16 bytes (inclusive), but may be truncated down to + * 4 or 8 bytes, for specific applications that can tolerate it. It must + * also be noted that successful forgeries leak information on the + * authentication key, making subsequent forgeries easier. Therefore, + * tag truncation, and in particular truncation to sizes lower than 12 + * bytes, shall be envisioned only with great care. + * + * The tag is written in the provided `tag` buffer. This call terminates + * the EAX run: no data may be processed with that EAX context + * afterwards, until `br_eax_reset()` is called to initiate a new EAX + * run. + * + * The tag value must normally be sent along with the encrypted data. + * When decrypting, the tag value must be recomputed and compared with + * the received tag: if the two tag values differ, then either the tag + * or the encrypted data was altered in transit. As an alternative to + * this function, the `br_eax_check_tag_trunc()` function can be used to + * compute and check the tag value. + * + * \param ctx EAX context structure. + * \param tag destination buffer for the tag. + * \param len tag length (16 bytes or less). + */ +void br_eax_get_tag_trunc(br_eax_context *ctx, void *tag, size_t len); + +/** + * \brief Compute and check EAX authentication tag (with truncation). + * + * This function is an alternative to `br_eax_get_tag_trunc()`, normally used + * on the receiving end (i.e. when decrypting value). The tag value is + * recomputed and compared with the provided tag value. If they match, 1 + * is returned; on mismatch, 0 is returned. A returned value of 0 means + * that the data or the tag was altered in transit, normally leading to + * wholesale rejection of the complete message. + * + * Tag length MUST be 16 bytes or less. The normal EAX tag length is 16 + * bytes. See `br_check_tag_trunc()` for some discussion on the potential + * perils of truncating authentication tags. + * + * \param ctx EAX context structure. + * \param tag tag value to compare with. + * \param len tag length (in bytes). + * \return 1 on success (exact match of tag value), 0 otherwise. + */ +uint32_t br_eax_check_tag_trunc(br_eax_context *ctx, + const void *tag, size_t len); + +/** + * \brief Class instance for EAX. + */ +extern const br_aead_class br_eax_vtable; + +/** + * \brief Context structure for CCM. + * + * CCM is an AEAD mode that combines a block cipher in CTR mode with + * CBC-MAC using the same block cipher and the same key, to provide + * authenticated encryption: + * + * - Any block cipher with 16-byte blocks can be used with CCM + * (technically, other block sizes are defined as well, but this + * is not implemented by these functions; shorter blocks also + * imply numerous security issues). + * + * - The authentication tag length, and plaintext length, MUST be + * known when starting processing data. Plaintext and ciphertext + * can still be provided by chunks, but the total size must match + * the value provided upon initialisation. + * + * - The nonce length is constrained between 7 and 13 bytes (inclusive). + * Furthermore, the plaintext length, when encoded, must fit over + * 15-nonceLen bytes; thus, if the nonce has length 13 bytes, then + * the plaintext length cannot exceed 65535 bytes. + * + * - Additional authenticated data length is practically unlimited + * (formal limit is at 2^64 bytes). + * + * - The authentication tag has length 4 to 16 bytes (even values only). + * + * The CCM initialisation function receives as parameter an + * _initialised_ block cipher implementation context, with the secret + * key already set. A pointer to that context will be kept within the + * CCM context structure. It is up to the caller to allocate and + * initialise that block cipher context. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + const br_block_ctrcbc_class **bctx; + unsigned char ctr[16]; + unsigned char cbcmac[16]; + unsigned char tagmask[16]; + unsigned char buf[16]; + size_t ptr; + size_t tag_len; +#endif +} br_ccm_context; + +/** + * \brief Initialize a CCM context. + * + * A block cipher implementation, with its initialised context + * structure, is provided. The block cipher MUST use 16-byte blocks in + * CTR + CBC-MAC mode, and its secret key MUST have been already set in + * the provided context. The parameters are linked in the CCM context. + * + * After this function has been called, the `br_ccm_reset()` function must + * be called, to provide the nonce for CCM computation. + * + * \param ctx CCM context structure. + * \param bctx block cipher context (already initialised with secret key). + */ +void br_ccm_init(br_ccm_context *ctx, const br_block_ctrcbc_class **bctx); + +/** + * \brief Reset a CCM context. + * + * This function resets an already initialised CCM context for a new + * computation run. Implementations and keys are conserved. This function + * can be called at any time; it cancels any ongoing CCM computation that + * uses the provided context structure. + * + * The `aad_len` parameter contains the total length, in bytes, of the + * additional authenticated data. It may be zero. That length MUST be + * exact. + * + * The `data_len` parameter contains the total length, in bytes, of the + * data that will be injected (plaintext or ciphertext). That length MUST + * be exact. Moreover, that length MUST be less than 2^(8*(15-nonce_len)). + * + * The nonce length (`nonce_len`), in bytes, must be in the 7..13 range + * (inclusive). + * + * The tag length (`tag_len`), in bytes, must be in the 4..16 range, and + * be an even integer. Short tags mechanically allow for higher forgery + * probabilities; hence, tag sizes smaller than 12 bytes shall be used only + * with care. + * + * It is critical to CCM security that nonce values are not repeated for + * the same encryption key. Random generation of nonces is not generally + * recommended, due to the relatively small maximum nonce value. + * + * Returned value is 1 on success, 0 on error. An error is reported if + * the tag or nonce length is out of range, or if the + * plaintext/ciphertext length cannot be encoded with the specified + * nonce length. + * + * \param ctx CCM context structure. + * \param nonce CCM nonce to use. + * \param nonce_len CCM nonce length (in bytes, 7 to 13). + * \param aad_len additional authenticated data length (in bytes). + * \param data_len plaintext/ciphertext length (in bytes). + * \param tag_len tag length (in bytes). + * \return 1 on success, 0 on error. + */ +int br_ccm_reset(br_ccm_context *ctx, const void *nonce, size_t nonce_len, + uint64_t aad_len, uint64_t data_len, size_t tag_len); + +/** + * \brief Inject additional authenticated data into CCM. + * + * The provided data is injected into a running CCM computation. Additional + * data must be injected _before_ the call to `br_ccm_flip()`. + * Additional data can be injected in several chunks of arbitrary length, + * but the total amount MUST exactly match the value which was provided + * to `br_ccm_reset()`. + * + * \param ctx CCM context structure. + * \param data pointer to additional authenticated data. + * \param len length of additional authenticated data (in bytes). + */ +void br_ccm_aad_inject(br_ccm_context *ctx, const void *data, size_t len); + +/** + * \brief Finish injection of additional authenticated data into CCM. + * + * This function MUST be called before beginning the actual encryption + * or decryption (with `br_ccm_run()`), even if no additional authenticated + * data was injected. No additional authenticated data may be injected + * after this function call. + * + * \param ctx CCM context structure. + */ +void br_ccm_flip(br_ccm_context *ctx); + +/** + * \brief Encrypt or decrypt some data with CCM. + * + * Data encryption or decryption can be done after `br_ccm_flip()` + * has been called on the context. If `encrypt` is non-zero, then the + * provided data shall be plaintext, and it is encrypted in place. + * Otherwise, the data shall be ciphertext, and it is decrypted in place. + * + * Data may be provided in several chunks of arbitrary length, provided + * that the total length exactly matches the length provided to the + * `br_ccm_reset()` call. + * + * \param ctx CCM context structure. + * \param encrypt non-zero for encryption, zero for decryption. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ +void br_ccm_run(br_ccm_context *ctx, int encrypt, void *data, size_t len); + +/** + * \brief Compute CCM authentication tag. + * + * Compute the CCM authentication tag. This call terminates the CCM + * run: all data must have been injected with `br_ccm_run()` (in zero, + * one or more successive calls). After this function has been called, + * no more data can br processed; a `br_ccm_reset()` call is required + * to start a new message. + * + * The tag length was provided upon context initialisation (last call + * to `br_ccm_reset()`); it is returned by this function. + * + * The tag value must normally be sent along with the encrypted data. + * When decrypting, the tag value must be recomputed and compared with + * the received tag: if the two tag values differ, then either the tag + * or the encrypted data was altered in transit. As an alternative to + * this function, the `br_ccm_check_tag()` function can be used to + * compute and check the tag value. + * + * \param ctx CCM context structure. + * \param tag destination buffer for the tag (up to 16 bytes). + * \return the tag length (in bytes). + */ +size_t br_ccm_get_tag(br_ccm_context *ctx, void *tag); + +/** + * \brief Compute and check CCM authentication tag. + * + * This function is an alternative to `br_ccm_get_tag()`, normally used + * on the receiving end (i.e. when decrypting value). The tag value is + * recomputed and compared with the provided tag value. If they match, 1 + * is returned; on mismatch, 0 is returned. A returned value of 0 means + * that the data or the tag was altered in transit, normally leading to + * wholesale rejection of the complete message. + * + * \param ctx CCM context structure. + * \param tag tag value to compare with (up to 16 bytes). + * \return 1 on success (exact match of tag value), 0 otherwise. + */ +uint32_t br_ccm_check_tag(br_ccm_context *ctx, const void *tag); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_block.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_block.h new file mode 100644 index 000000000000..22a9434ee251 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_block.h @@ -0,0 +1,2623 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_BLOCK_H__ +#define BR_BEARSSL_BLOCK_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_block.h + * + * # Block Ciphers and Symmetric Ciphers + * + * This file documents the API for block ciphers and other symmetric + * ciphers. + * + * + * ## Procedural API + * + * For a block cipher implementation, up to three separate sets of + * functions are provided, for CBC encryption, CBC decryption, and CTR + * encryption/decryption. Each set has its own context structure, + * initialised with the encryption key. + * + * For CBC encryption and decryption, the data to encrypt or decrypt is + * referenced as a sequence of blocks. The implementations assume that + * there is no partial block; no padding is applied or removed. The + * caller is responsible for handling any kind of padding. + * + * Function for CTR encryption are defined only for block ciphers with + * blocks of 16 bytes or more (i.e. AES, but not DES/3DES). + * + * Each implemented block cipher is identified by an "internal name" + * from which are derived the names of structures and functions that + * implement the cipher. For the block cipher of internal name "`xxx`", + * the following are defined: + * + * - `br_xxx_BLOCK_SIZE` + * + * A macro that evaluates to the block size (in bytes) of the + * cipher. For all implemented block ciphers, this value is a + * power of two. + * + * - `br_xxx_cbcenc_keys` + * + * Context structure that contains the subkeys resulting from the key + * expansion. These subkeys are appropriate for CBC encryption. The + * structure first field is called `vtable` and points to the + * appropriate OOP structure. + * + * - `br_xxx_cbcenc_init(br_xxx_cbcenc_keys *ctx, const void *key, size_t len)` + * + * Perform key expansion: subkeys for CBC encryption are computed and + * written in the provided context structure. The key length MUST be + * adequate for the implemented block cipher. This function also sets + * the `vtable` field. + * + * - `br_xxx_cbcenc_run(const br_xxx_cbcenc_keys *ctx, void *iv, void *data, size_t len)` + * + * Perform CBC encryption of `len` bytes, in place. The encrypted data + * replaces the cleartext. `len` MUST be a multiple of the block length + * (if it is not, the function may loop forever or overflow a buffer). + * The IV is provided with the `iv` pointer; it is also updated with + * a copy of the last encrypted block. + * + * - `br_xxx_cbcdec_keys` + * + * Context structure that contains the subkeys resulting from the key + * expansion. These subkeys are appropriate for CBC decryption. The + * structure first field is called `vtable` and points to the + * appropriate OOP structure. + * + * - `br_xxx_cbcdec_init(br_xxx_cbcenc_keys *ctx, const void *key, size_t len)` + * + * Perform key expansion: subkeys for CBC decryption are computed and + * written in the provided context structure. The key length MUST be + * adequate for the implemented block cipher. This function also sets + * the `vtable` field. + * + * - `br_xxx_cbcdec_run(const br_xxx_cbcdec_keys *ctx, void *iv, void *data, size_t num_blocks)` + * + * Perform CBC decryption of `len` bytes, in place. The decrypted data + * replaces the ciphertext. `len` MUST be a multiple of the block length + * (if it is not, the function may loop forever or overflow a buffer). + * The IV is provided with the `iv` pointer; it is also updated with + * a copy of the last _encrypted_ block. + * + * - `br_xxx_ctr_keys` + * + * Context structure that contains the subkeys resulting from the key + * expansion. These subkeys are appropriate for CTR encryption and + * decryption. The structure first field is called `vtable` and + * points to the appropriate OOP structure. + * + * - `br_xxx_ctr_init(br_xxx_ctr_keys *ctx, const void *key, size_t len)` + * + * Perform key expansion: subkeys for CTR encryption and decryption + * are computed and written in the provided context structure. The + * key length MUST be adequate for the implemented block cipher. This + * function also sets the `vtable` field. + * + * - `br_xxx_ctr_run(const br_xxx_ctr_keys *ctx, const void *iv, uint32_t cc, void *data, size_t len)` (returns `uint32_t`) + * + * Perform CTR encryption/decryption of some data. Processing is done + * "in place" (the output data replaces the input data). This function + * implements the "standard incrementing function" from NIST SP800-38A, + * annex B: the IV length shall be 4 bytes less than the block size + * (i.e. 12 bytes for AES) and the counter is the 32-bit value starting + * with `cc`. The data length (`len`) is not necessarily a multiple of + * the block size. The new counter value is returned, which supports + * chunked processing, provided that each chunk length (except possibly + * the last one) is a multiple of the block size. + * + * - `br_xxx_ctrcbc_keys` + * + * Context structure that contains the subkeys resulting from the + * key expansion. These subkeys are appropriate for doing combined + * CTR encryption/decryption and CBC-MAC, as used in the CCM and EAX + * authenticated encryption modes. The structure first field is + * called `vtable` and points to the appropriate OOP structure. + * + * - `br_xxx_ctrcbc_init(br_xxx_ctr_keys *ctx, const void *key, size_t len)` + * + * Perform key expansion: subkeys for combined CTR + * encryption/decryption and CBC-MAC are computed and written in the + * provided context structure. The key length MUST be adequate for + * the implemented block cipher. This function also sets the + * `vtable` field. + * + * - `br_xxx_ctrcbc_encrypt(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len)` + * + * Perform CTR encryption of some data, and CBC-MAC. Processing is + * done "in place" (the output data replaces the input data). This + * function applies CTR encryption on the data, using a full + * block-size counter (i.e. for 128-bit blocks, the counter is + * incremented as a 128-bit value). The 'ctr' array contains the + * initial value for the counter (used in the first block) and it is + * updated with the new value after data processing. The 'cbcmac' + * value shall point to a block-sized value which is used as IV for + * CBC-MAC, computed over the encrypted data (output of CTR + * encryption); the resulting CBC-MAC is written over 'cbcmac' on + * output. + * + * The data length MUST be a multiple of the block size. + * + * - `br_xxx_ctrcbc_decrypt(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *cbcmac, void *data, size_t len)` + * + * Perform CTR decryption of some data, and CBC-MAC. Processing is + * done "in place" (the output data replaces the input data). This + * function applies CTR decryption on the data, using a full + * block-size counter (i.e. for 128-bit blocks, the counter is + * incremented as a 128-bit value). The 'ctr' array contains the + * initial value for the counter (used in the first block) and it is + * updated with the new value after data processing. The 'cbcmac' + * value shall point to a block-sized value which is used as IV for + * CBC-MAC, computed over the encrypted data (input of CTR + * encryption); the resulting CBC-MAC is written over 'cbcmac' on + * output. + * + * The data length MUST be a multiple of the block size. + * + * - `br_xxx_ctrcbc_ctr(const br_xxx_ctrcbc_keys *ctx, void *ctr, void *data, size_t len)` + * + * Perform CTR encryption or decryption of the provided data. The + * data is processed "in place" (the output data replaces the input + * data). A full block-sized counter is applied (i.e. for 128-bit + * blocks, the counter is incremented as a 128-bit value). The 'ctr' + * array contains the initial value for the counter (used in the + * first block), and it is updated with the new value after data + * processing. + * + * The data length MUST be a multiple of the block size. + * + * - `br_xxx_ctrcbc_mac(const br_xxx_ctrcbc_keys *ctx, void *cbcmac, const void *data, size_t len)` + * + * Compute CBC-MAC over the provided data. The IV for CBC-MAC is + * provided as 'cbcmac'; the output is written over the same array. + * The data itself is untouched. The data length MUST be a multiple + * of the block size. + * + * + * It shall be noted that the key expansion functions return `void`. If + * the provided key length is not allowed, then there will be no error + * reporting; implementations need not validate the key length, thus an + * invalid key length may result in undefined behaviour (e.g. buffer + * overflow). + * + * Subkey structures contain no interior pointer, and no external + * resources are allocated upon key expansion. They can thus be + * discarded without any explicit deallocation. + * + * + * ## Object-Oriented API + * + * Each context structure begins with a field (called `vtable`) that + * points to an instance of a structure that references the relevant + * functions through pointers. Each such structure contains the + * following: + * + * - `context_size` + * + * The size (in bytes) of the context structure for subkeys. + * + * - `block_size` + * + * The cipher block size (in bytes). + * + * - `log_block_size` + * + * The base-2 logarithm of cipher block size (e.g. 4 for blocks + * of 16 bytes). + * + * - `init` + * + * Pointer to the key expansion function. + * + * - `run` + * + * Pointer to the encryption/decryption function. + * + * For combined CTR/CBC-MAC encryption, the `vtable` has a slightly + * different structure: + * + * - `context_size` + * + * The size (in bytes) of the context structure for subkeys. + * + * - `block_size` + * + * The cipher block size (in bytes). + * + * - `log_block_size` + * + * The base-2 logarithm of cipher block size (e.g. 4 for blocks + * of 16 bytes). + * + * - `init` + * + * Pointer to the key expansion function. + * + * - `encrypt` + * + * Pointer to the CTR encryption + CBC-MAC function. + * + * - `decrypt` + * + * Pointer to the CTR decryption + CBC-MAC function. + * + * - `ctr` + * + * Pointer to the CTR encryption/decryption function. + * + * - `mac` + * + * Pointer to the CBC-MAC function. + * + * For block cipher "`xxx`", static, constant instances of these + * structures are defined, under the names: + * + * - `br_xxx_cbcenc_vtable` + * - `br_xxx_cbcdec_vtable` + * - `br_xxx_ctr_vtable` + * - `br_xxx_ctrcbc_vtable` + * + * + * ## Implemented Block Ciphers + * + * Provided implementations are: + * + * | Name | Function | Block Size (bytes) | Key lengths (bytes) | + * | :-------- | :------- | :----------------: | :-----------------: | + * | aes_big | AES | 16 | 16, 24 and 32 | + * | aes_small | AES | 16 | 16, 24 and 32 | + * | aes_ct | AES | 16 | 16, 24 and 32 | + * | aes_ct64 | AES | 16 | 16, 24 and 32 | + * | aes_x86ni | AES | 16 | 16, 24 and 32 | + * | aes_pwr8 | AES | 16 | 16, 24 and 32 | + * | des_ct | DES/3DES | 8 | 8, 16 and 24 | + * | des_tab | DES/3DES | 8 | 8, 16 and 24 | + * + * **Note:** DES/3DES nominally uses keys of 64, 128 and 192 bits (i.e. 8, + * 16 and 24 bytes), but some of the bits are ignored by the algorithm, so + * the _effective_ key lengths, from a security point of view, are 56, + * 112 and 168 bits, respectively. + * + * `aes_big` is a "classical" AES implementation, using tables. It + * is fast but not constant-time, since it makes data-dependent array + * accesses. + * + * `aes_small` is an AES implementation optimized for code size. It + * is substantially slower than `aes_big`; it is not constant-time + * either. + * + * `aes_ct` is a constant-time implementation of AES; its code is about + * as big as that of `aes_big`, while its performance is comparable to + * that of `aes_small`. However, it is constant-time. This + * implementation should thus be considered to be the "default" AES in + * BearSSL, to be used unless the operational context guarantees that a + * non-constant-time implementation is safe, or an architecture-specific + * constant-time implementation can be used (e.g. using dedicated + * hardware opcodes). + * + * `aes_ct64` is another constant-time implementation of AES. It is + * similar to `aes_ct` but uses 64-bit values. On 32-bit machines, + * `aes_ct64` is not faster than `aes_ct`, often a bit slower, and has + * a larger footprint; however, on 64-bit architectures, `aes_ct64` + * is typically twice faster than `aes_ct` for modes that allow parallel + * operations (i.e. CTR, and CBC decryption, but not CBC encryption). + * + * `aes_x86ni` exists only on x86 architectures (32-bit and 64-bit). It + * uses the AES-NI opcodes when available. + * + * `aes_pwr8` exists only on PowerPC / POWER architectures (32-bit and + * 64-bit, both little-endian and big-endian). It uses the AES opcodes + * present in POWER8 and later. + * + * `des_tab` is a classic, table-based implementation of DES/3DES. It + * is not constant-time. + * + * `des_ct` is an constant-time implementation of DES/3DES. It is + * substantially slower than `des_tab`. + * + * ## ChaCha20 and Poly1305 + * + * ChaCha20 is a stream cipher. Poly1305 is a MAC algorithm. They + * are described in [RFC 7539](https://tools.ietf.org/html/rfc7539). + * + * Two function pointer types are defined: + * + * - `br_chacha20_run` describes a function that implements ChaCha20 + * only. + * + * - `br_poly1305_run` describes an implementation of Poly1305, + * in the AEAD combination with ChaCha20 specified in RFC 7539 + * (the ChaCha20 implementation is provided as a function pointer). + * + * `chacha20_ct` is a straightforward implementation of ChaCha20 in + * plain C; it is constant-time, small, and reasonably fast. + * + * `chacha20_sse2` leverages SSE2 opcodes (on x86 architectures that + * support these opcodes). It is faster than `chacha20_ct`. + * + * `poly1305_ctmul` is an implementation of the ChaCha20+Poly1305 AEAD + * construction, where the Poly1305 part is performed with mixed 32-bit + * multiplications (operands are 32-bit, result is 64-bit). + * + * `poly1305_ctmul32` implements ChaCha20+Poly1305 using pure 32-bit + * multiplications (32-bit operands, 32-bit result). It is slower than + * `poly1305_ctmul`, except on some specific architectures such as + * the ARM Cortex M0+. + * + * `poly1305_ctmulq` implements ChaCha20+Poly1305 with mixed 64-bit + * multiplications (operands are 64-bit, result is 128-bit) on 64-bit + * platforms that support such operations. + * + * `poly1305_i15` implements ChaCha20+Poly1305 with the generic "i15" + * big integer implementation. It is meant mostly for testing purposes, + * although it can help with saving a few hundred bytes of code footprint + * on systems where code size is scarce. + */ + +/** + * \brief Class type for CBC encryption implementations. + * + * A `br_block_cbcenc_class` instance points to the functions implementing + * a specific block cipher, when used in CBC mode for encrypting data. + */ +typedef struct br_block_cbcenc_class_ br_block_cbcenc_class; +struct br_block_cbcenc_class_ { + /** + * \brief Size (in bytes) of the context structure appropriate + * for containing subkeys. + */ + size_t context_size; + + /** + * \brief Size of individual blocks (in bytes). + */ + unsigned block_size; + + /** + * \brief Base-2 logarithm of the size of individual blocks, + * expressed in bytes. + */ + unsigned log_block_size; + + /** + * \brief Initialisation function. + * + * This function sets the `vtable` field in the context structure. + * The key length MUST be one of the key lengths supported by + * the implementation. + * + * \param ctx context structure to initialise. + * \param key secret key. + * \param key_len key length (in bytes). + */ + void (*init)(const br_block_cbcenc_class **ctx, + const void *key, size_t key_len); + + /** + * \brief Run the CBC encryption. + * + * The `iv` parameter points to the IV for this run; it is + * updated with a copy of the last encrypted block. The data + * is encrypted "in place"; its length (`len`) MUST be a + * multiple of the block size. + * + * \param ctx context structure (already initialised). + * \param iv IV for CBC encryption (updated). + * \param data data to encrypt. + * \param len data length (in bytes, multiple of block size). + */ + void (*run)(const br_block_cbcenc_class *const *ctx, + void *iv, void *data, size_t len); +}; + +/** + * \brief Class type for CBC decryption implementations. + * + * A `br_block_cbcdec_class` instance points to the functions implementing + * a specific block cipher, when used in CBC mode for decrypting data. + */ +typedef struct br_block_cbcdec_class_ br_block_cbcdec_class; +struct br_block_cbcdec_class_ { + /** + * \brief Size (in bytes) of the context structure appropriate + * for containing subkeys. + */ + size_t context_size; + + /** + * \brief Size of individual blocks (in bytes). + */ + unsigned block_size; + + /** + * \brief Base-2 logarithm of the size of individual blocks, + * expressed in bytes. + */ + unsigned log_block_size; + + /** + * \brief Initialisation function. + * + * This function sets the `vtable` field in the context structure. + * The key length MUST be one of the key lengths supported by + * the implementation. + * + * \param ctx context structure to initialise. + * \param key secret key. + * \param key_len key length (in bytes). + */ + void (*init)(const br_block_cbcdec_class **ctx, + const void *key, size_t key_len); + + /** + * \brief Run the CBC decryption. + * + * The `iv` parameter points to the IV for this run; it is + * updated with a copy of the last encrypted block. The data + * is decrypted "in place"; its length (`len`) MUST be a + * multiple of the block size. + * + * \param ctx context structure (already initialised). + * \param iv IV for CBC decryption (updated). + * \param data data to decrypt. + * \param len data length (in bytes, multiple of block size). + */ + void (*run)(const br_block_cbcdec_class *const *ctx, + void *iv, void *data, size_t len); +}; + +/** + * \brief Class type for CTR encryption/decryption implementations. + * + * A `br_block_ctr_class` instance points to the functions implementing + * a specific block cipher, when used in CTR mode for encrypting or + * decrypting data. + */ +typedef struct br_block_ctr_class_ br_block_ctr_class; +struct br_block_ctr_class_ { + /** + * \brief Size (in bytes) of the context structure appropriate + * for containing subkeys. + */ + size_t context_size; + + /** + * \brief Size of individual blocks (in bytes). + */ + unsigned block_size; + + /** + * \brief Base-2 logarithm of the size of individual blocks, + * expressed in bytes. + */ + unsigned log_block_size; + + /** + * \brief Initialisation function. + * + * This function sets the `vtable` field in the context structure. + * The key length MUST be one of the key lengths supported by + * the implementation. + * + * \param ctx context structure to initialise. + * \param key secret key. + * \param key_len key length (in bytes). + */ + void (*init)(const br_block_ctr_class **ctx, + const void *key, size_t key_len); + + /** + * \brief Run the CTR encryption or decryption. + * + * The `iv` parameter points to the IV for this run; its + * length is exactly 4 bytes less than the block size (e.g. + * 12 bytes for AES/CTR). The IV is combined with a 32-bit + * block counter to produce the block value which is processed + * with the block cipher. + * + * The data to encrypt or decrypt is updated "in place". Its + * length (`len` bytes) is not required to be a multiple of + * the block size; if the final block is partial, then the + * corresponding key stream bits are dropped. + * + * The resulting counter value is returned. + * + * \param ctx context structure (already initialised). + * \param iv IV for CTR encryption/decryption. + * \param cc initial value for the block counter. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + * \return the new block counter value. + */ + uint32_t (*run)(const br_block_ctr_class *const *ctx, + const void *iv, uint32_t cc, void *data, size_t len); +}; + +/** + * \brief Class type for combined CTR and CBC-MAC implementations. + * + * A `br_block_ctrcbc_class` instance points to the functions implementing + * a specific block cipher, when used in CTR mode for encrypting or + * decrypting data, along with CBC-MAC. + */ +typedef struct br_block_ctrcbc_class_ br_block_ctrcbc_class; +struct br_block_ctrcbc_class_ { + /** + * \brief Size (in bytes) of the context structure appropriate + * for containing subkeys. + */ + size_t context_size; + + /** + * \brief Size of individual blocks (in bytes). + */ + unsigned block_size; + + /** + * \brief Base-2 logarithm of the size of individual blocks, + * expressed in bytes. + */ + unsigned log_block_size; + + /** + * \brief Initialisation function. + * + * This function sets the `vtable` field in the context structure. + * The key length MUST be one of the key lengths supported by + * the implementation. + * + * \param ctx context structure to initialise. + * \param key secret key. + * \param key_len key length (in bytes). + */ + void (*init)(const br_block_ctrcbc_class **ctx, + const void *key, size_t key_len); + + /** + * \brief Run the CTR encryption + CBC-MAC. + * + * The `ctr` parameter points to the counter; its length shall + * be equal to the block size. It is updated by this function + * as encryption proceeds. + * + * The `cbcmac` parameter points to the IV for CBC-MAC. The MAC + * is computed over the encrypted data (output of CTR + * encryption). Its length shall be equal to the block size. The + * computed CBC-MAC value is written over the `cbcmac` array. + * + * The data to encrypt is updated "in place". Its length (`len` + * bytes) MUST be a multiple of the block size. + * + * \param ctx context structure (already initialised). + * \param ctr counter for CTR encryption (initial and final). + * \param cbcmac IV and output buffer for CBC-MAC. + * \param data data to encrypt. + * \param len data length (in bytes). + */ + void (*encrypt)(const br_block_ctrcbc_class *const *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + + /** + * \brief Run the CTR decryption + CBC-MAC. + * + * The `ctr` parameter points to the counter; its length shall + * be equal to the block size. It is updated by this function + * as decryption proceeds. + * + * The `cbcmac` parameter points to the IV for CBC-MAC. The MAC + * is computed over the encrypted data (i.e. before CTR + * decryption). Its length shall be equal to the block size. The + * computed CBC-MAC value is written over the `cbcmac` array. + * + * The data to decrypt is updated "in place". Its length (`len` + * bytes) MUST be a multiple of the block size. + * + * \param ctx context structure (already initialised). + * \param ctr counter for CTR encryption (initial and final). + * \param cbcmac IV and output buffer for CBC-MAC. + * \param data data to decrypt. + * \param len data length (in bytes). + */ + void (*decrypt)(const br_block_ctrcbc_class *const *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + + /** + * \brief Run the CTR encryption/decryption only. + * + * The `ctr` parameter points to the counter; its length shall + * be equal to the block size. It is updated by this function + * as decryption proceeds. + * + * The data to decrypt is updated "in place". Its length (`len` + * bytes) MUST be a multiple of the block size. + * + * \param ctx context structure (already initialised). + * \param ctr counter for CTR encryption (initial and final). + * \param data data to decrypt. + * \param len data length (in bytes). + */ + void (*ctr)(const br_block_ctrcbc_class *const *ctx, + void *ctr, void *data, size_t len); + + /** + * \brief Run the CBC-MAC only. + * + * The `cbcmac` parameter points to the IV for CBC-MAC. The MAC + * is computed over the encrypted data (i.e. before CTR + * decryption). Its length shall be equal to the block size. The + * computed CBC-MAC value is written over the `cbcmac` array. + * + * The data is unmodified. Its length (`len` bytes) MUST be a + * multiple of the block size. + * + * \param ctx context structure (already initialised). + * \param cbcmac IV and output buffer for CBC-MAC. + * \param data data to decrypt. + * \param len data length (in bytes). + */ + void (*mac)(const br_block_ctrcbc_class *const *ctx, + void *cbcmac, const void *data, size_t len); +}; + +/* + * Traditional, table-based AES implementation. It is fast, but uses + * internal tables (in particular a 1 kB table for encryption, another + * 1 kB table for decryption, and a 256-byte table for key schedule), + * and it is not constant-time. In contexts where cache-timing attacks + * apply, this implementation may leak the secret key. + */ + +/** \brief AES block size (16 bytes). */ +#define br_aes_big_BLOCK_SIZE 16 + +/** + * \brief Context for AES subkeys (`aes_big` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_big_cbcenc_keys; + +/** + * \brief Context for AES subkeys (`aes_big` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_big_cbcdec_keys; + +/** + * \brief Context for AES subkeys (`aes_big` implementation, CTR encryption + * and decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctr_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_big_ctr_keys; + +/** + * \brief Context for AES subkeys (`aes_big` implementation, CTR encryption + * and decryption + CBC-MAC). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctrcbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_big_ctrcbc_keys; + +/** + * \brief Class instance for AES CBC encryption (`aes_big` implementation). + */ +extern const br_block_cbcenc_class br_aes_big_cbcenc_vtable; + +/** + * \brief Class instance for AES CBC decryption (`aes_big` implementation). + */ +extern const br_block_cbcdec_class br_aes_big_cbcdec_vtable; + +/** + * \brief Class instance for AES CTR encryption and decryption + * (`aes_big` implementation). + */ +extern const br_block_ctr_class br_aes_big_ctr_vtable; + +/** + * \brief Class instance for AES CTR encryption/decryption + CBC-MAC + * (`aes_big` implementation). + */ +extern const br_block_ctrcbc_class br_aes_big_ctrcbc_vtable; + +/** + * \brief Context initialisation (key schedule) for AES CBC encryption + * (`aes_big` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_big_cbcenc_init(br_aes_big_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CBC decryption + * (`aes_big` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_big_cbcdec_init(br_aes_big_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR encryption + * and decryption (`aes_big` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_big_ctr_init(br_aes_big_ctr_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC + * (`aes_big` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_big_ctrcbc_init(br_aes_big_ctrcbc_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_big_cbcenc_run(const br_aes_big_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_big_cbcdec_run(const br_aes_big_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CTR encryption and decryption with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (constant, 12 bytes). + * \param cc initial block counter value. + * \param data data to encrypt or decrypt (updated). + * \param len data length (in bytes). + * \return new block counter value. + */ +uint32_t br_aes_big_ctr_run(const br_aes_big_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief CTR encryption + CBC-MAC with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_big_ctrcbc_encrypt(const br_aes_big_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR decryption + CBC-MAC with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_big_ctrcbc_decrypt(const br_aes_big_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR encryption/decryption with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param data data to MAC (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_big_ctrcbc_ctr(const br_aes_big_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len); + +/** + * \brief CBC-MAC with AES (`aes_big` implementation). + * + * \param ctx context (already initialised). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to MAC (unmodified). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_big_ctrcbc_mac(const br_aes_big_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len); + +/* + * AES implementation optimized for size. It is slower than the + * traditional table-based AES implementation, but requires much less + * code. It still uses data-dependent table accesses (albeit within a + * much smaller 256-byte table), which makes it conceptually vulnerable + * to cache-timing attacks. + */ + +/** \brief AES block size (16 bytes). */ +#define br_aes_small_BLOCK_SIZE 16 + +/** + * \brief Context for AES subkeys (`aes_small` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_small_cbcenc_keys; + +/** + * \brief Context for AES subkeys (`aes_small` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_small_cbcdec_keys; + +/** + * \brief Context for AES subkeys (`aes_small` implementation, CTR encryption + * and decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctr_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_small_ctr_keys; + +/** + * \brief Context for AES subkeys (`aes_small` implementation, CTR encryption + * and decryption + CBC-MAC). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctrcbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_small_ctrcbc_keys; + +/** + * \brief Class instance for AES CBC encryption (`aes_small` implementation). + */ +extern const br_block_cbcenc_class br_aes_small_cbcenc_vtable; + +/** + * \brief Class instance for AES CBC decryption (`aes_small` implementation). + */ +extern const br_block_cbcdec_class br_aes_small_cbcdec_vtable; + +/** + * \brief Class instance for AES CTR encryption and decryption + * (`aes_small` implementation). + */ +extern const br_block_ctr_class br_aes_small_ctr_vtable; + +/** + * \brief Class instance for AES CTR encryption/decryption + CBC-MAC + * (`aes_small` implementation). + */ +extern const br_block_ctrcbc_class br_aes_small_ctrcbc_vtable; + +/** + * \brief Context initialisation (key schedule) for AES CBC encryption + * (`aes_small` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_small_cbcenc_init(br_aes_small_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CBC decryption + * (`aes_small` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_small_cbcdec_init(br_aes_small_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR encryption + * and decryption (`aes_small` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_small_ctr_init(br_aes_small_ctr_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC + * (`aes_small` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_small_ctrcbc_init(br_aes_small_ctrcbc_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_small_cbcenc_run(const br_aes_small_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_small_cbcdec_run(const br_aes_small_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CTR encryption and decryption with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (constant, 12 bytes). + * \param cc initial block counter value. + * \param data data to decrypt (updated). + * \param len data length (in bytes). + * \return new block counter value. + */ +uint32_t br_aes_small_ctr_run(const br_aes_small_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief CTR encryption + CBC-MAC with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_small_ctrcbc_encrypt(const br_aes_small_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR decryption + CBC-MAC with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_small_ctrcbc_decrypt(const br_aes_small_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR encryption/decryption with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param data data to MAC (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_small_ctrcbc_ctr(const br_aes_small_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len); + +/** + * \brief CBC-MAC with AES (`aes_small` implementation). + * + * \param ctx context (already initialised). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to MAC (unmodified). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_small_ctrcbc_mac(const br_aes_small_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len); + +/* + * Constant-time AES implementation. Its size is similar to that of + * 'aes_big', and its performance is similar to that of 'aes_small' (faster + * decryption, slower encryption). However, it is constant-time, i.e. + * immune to cache-timing and similar attacks. + */ + +/** \brief AES block size (16 bytes). */ +#define br_aes_ct_BLOCK_SIZE 16 + +/** + * \brief Context for AES subkeys (`aes_ct` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_ct_cbcenc_keys; + +/** + * \brief Context for AES subkeys (`aes_ct` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_ct_cbcdec_keys; + +/** + * \brief Context for AES subkeys (`aes_ct` implementation, CTR encryption + * and decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctr_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_ct_ctr_keys; + +/** + * \brief Context for AES subkeys (`aes_ct` implementation, CTR encryption + * and decryption + CBC-MAC). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctrcbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[60]; + unsigned num_rounds; +#endif +} br_aes_ct_ctrcbc_keys; + +/** + * \brief Class instance for AES CBC encryption (`aes_ct` implementation). + */ +extern const br_block_cbcenc_class br_aes_ct_cbcenc_vtable; + +/** + * \brief Class instance for AES CBC decryption (`aes_ct` implementation). + */ +extern const br_block_cbcdec_class br_aes_ct_cbcdec_vtable; + +/** + * \brief Class instance for AES CTR encryption and decryption + * (`aes_ct` implementation). + */ +extern const br_block_ctr_class br_aes_ct_ctr_vtable; + +/** + * \brief Class instance for AES CTR encryption/decryption + CBC-MAC + * (`aes_ct` implementation). + */ +extern const br_block_ctrcbc_class br_aes_ct_ctrcbc_vtable; + +/** + * \brief Context initialisation (key schedule) for AES CBC encryption + * (`aes_ct` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct_cbcenc_init(br_aes_ct_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CBC decryption + * (`aes_ct` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct_cbcdec_init(br_aes_ct_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR encryption + * and decryption (`aes_ct` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct_ctr_init(br_aes_ct_ctr_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC + * (`aes_ct` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct_ctrcbc_init(br_aes_ct_ctrcbc_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_ct_cbcenc_run(const br_aes_ct_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_ct_cbcdec_run(const br_aes_ct_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CTR encryption and decryption with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (constant, 12 bytes). + * \param cc initial block counter value. + * \param data data to decrypt (updated). + * \param len data length (in bytes). + * \return new block counter value. + */ +uint32_t br_aes_ct_ctr_run(const br_aes_ct_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief CTR encryption + CBC-MAC with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct_ctrcbc_encrypt(const br_aes_ct_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR decryption + CBC-MAC with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct_ctrcbc_decrypt(const br_aes_ct_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR encryption/decryption with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param data data to MAC (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct_ctrcbc_ctr(const br_aes_ct_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len); + +/** + * \brief CBC-MAC with AES (`aes_ct` implementation). + * + * \param ctx context (already initialised). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to MAC (unmodified). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct_ctrcbc_mac(const br_aes_ct_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len); + +/* + * 64-bit constant-time AES implementation. It is similar to 'aes_ct' + * but uses 64-bit registers, making it about twice faster than 'aes_ct' + * on 64-bit platforms, while remaining constant-time and with a similar + * code size. (The doubling in performance is only for CBC decryption + * and CTR mode; CBC encryption is non-parallel and cannot benefit from + * the larger registers.) + */ + +/** \brief AES block size (16 bytes). */ +#define br_aes_ct64_BLOCK_SIZE 16 + +/** + * \brief Context for AES subkeys (`aes_ct64` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t skey[30]; + unsigned num_rounds; +#endif +} br_aes_ct64_cbcenc_keys; + +/** + * \brief Context for AES subkeys (`aes_ct64` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t skey[30]; + unsigned num_rounds; +#endif +} br_aes_ct64_cbcdec_keys; + +/** + * \brief Context for AES subkeys (`aes_ct64` implementation, CTR encryption + * and decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctr_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t skey[30]; + unsigned num_rounds; +#endif +} br_aes_ct64_ctr_keys; + +/** + * \brief Context for AES subkeys (`aes_ct64` implementation, CTR encryption + * and decryption + CBC-MAC). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctrcbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t skey[30]; + unsigned num_rounds; +#endif +} br_aes_ct64_ctrcbc_keys; + +/** + * \brief Class instance for AES CBC encryption (`aes_ct64` implementation). + */ +extern const br_block_cbcenc_class br_aes_ct64_cbcenc_vtable; + +/** + * \brief Class instance for AES CBC decryption (`aes_ct64` implementation). + */ +extern const br_block_cbcdec_class br_aes_ct64_cbcdec_vtable; + +/** + * \brief Class instance for AES CTR encryption and decryption + * (`aes_ct64` implementation). + */ +extern const br_block_ctr_class br_aes_ct64_ctr_vtable; + +/** + * \brief Class instance for AES CTR encryption/decryption + CBC-MAC + * (`aes_ct64` implementation). + */ +extern const br_block_ctrcbc_class br_aes_ct64_ctrcbc_vtable; + +/** + * \brief Context initialisation (key schedule) for AES CBC encryption + * (`aes_ct64` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct64_cbcenc_init(br_aes_ct64_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CBC decryption + * (`aes_ct64` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct64_cbcdec_init(br_aes_ct64_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR encryption + * and decryption (`aes_ct64` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct64_ctr_init(br_aes_ct64_ctr_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC + * (`aes_ct64` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_ct64_ctrcbc_init(br_aes_ct64_ctrcbc_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_ct64_cbcenc_run(const br_aes_ct64_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_ct64_cbcdec_run(const br_aes_ct64_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CTR encryption and decryption with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (constant, 12 bytes). + * \param cc initial block counter value. + * \param data data to decrypt (updated). + * \param len data length (in bytes). + * \return new block counter value. + */ +uint32_t br_aes_ct64_ctr_run(const br_aes_ct64_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief CTR encryption + CBC-MAC with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct64_ctrcbc_encrypt(const br_aes_ct64_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR decryption + CBC-MAC with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct64_ctrcbc_decrypt(const br_aes_ct64_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR encryption/decryption with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param data data to MAC (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct64_ctrcbc_ctr(const br_aes_ct64_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len); + +/** + * \brief CBC-MAC with AES (`aes_ct64` implementation). + * + * \param ctx context (already initialised). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to MAC (unmodified). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_ct64_ctrcbc_mac(const br_aes_ct64_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len); + +/* + * AES implementation using AES-NI opcodes (x86 platform). + */ + +/** \brief AES block size (16 bytes). */ +#define br_aes_x86ni_BLOCK_SIZE 16 + +/** + * \brief Context for AES subkeys (`aes_x86ni` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_x86ni_cbcenc_keys; + +/** + * \brief Context for AES subkeys (`aes_x86ni` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_x86ni_cbcdec_keys; + +/** + * \brief Context for AES subkeys (`aes_x86ni` implementation, CTR encryption + * and decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctr_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_x86ni_ctr_keys; + +/** + * \brief Context for AES subkeys (`aes_x86ni` implementation, CTR encryption + * and decryption + CBC-MAC). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctrcbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_x86ni_ctrcbc_keys; + +/** + * \brief Class instance for AES CBC encryption (`aes_x86ni` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_x86ni_cbcenc_get_vtable()`. + */ +extern const br_block_cbcenc_class br_aes_x86ni_cbcenc_vtable; + +/** + * \brief Class instance for AES CBC decryption (`aes_x86ni` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_x86ni_cbcdec_get_vtable()`. + */ +extern const br_block_cbcdec_class br_aes_x86ni_cbcdec_vtable; + +/** + * \brief Class instance for AES CTR encryption and decryption + * (`aes_x86ni` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_x86ni_ctr_get_vtable()`. + */ +extern const br_block_ctr_class br_aes_x86ni_ctr_vtable; + +/** + * \brief Class instance for AES CTR encryption/decryption + CBC-MAC + * (`aes_x86ni` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_x86ni_ctrcbc_get_vtable()`. + */ +extern const br_block_ctrcbc_class br_aes_x86ni_ctrcbc_vtable; + +/** + * \brief Context initialisation (key schedule) for AES CBC encryption + * (`aes_x86ni` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_x86ni_cbcenc_init(br_aes_x86ni_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CBC decryption + * (`aes_x86ni` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_x86ni_cbcdec_init(br_aes_x86ni_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR encryption + * and decryption (`aes_x86ni` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_x86ni_ctr_init(br_aes_x86ni_ctr_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC + * (`aes_x86ni` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_x86ni_ctrcbc_init(br_aes_x86ni_ctrcbc_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_x86ni_cbcenc_run(const br_aes_x86ni_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_x86ni_cbcdec_run(const br_aes_x86ni_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CTR encryption and decryption with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (constant, 12 bytes). + * \param cc initial block counter value. + * \param data data to decrypt (updated). + * \param len data length (in bytes). + * \return new block counter value. + */ +uint32_t br_aes_x86ni_ctr_run(const br_aes_x86ni_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief CTR encryption + CBC-MAC with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_x86ni_ctrcbc_encrypt(const br_aes_x86ni_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR decryption + CBC-MAC with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_x86ni_ctrcbc_decrypt(const br_aes_x86ni_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR encryption/decryption with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param data data to MAC (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_x86ni_ctrcbc_ctr(const br_aes_x86ni_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len); + +/** + * \brief CBC-MAC with AES (`aes_x86ni` implementation). + * + * \param ctx context (already initialised). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to MAC (unmodified). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_x86ni_ctrcbc_mac(const br_aes_x86ni_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len); + +/** + * \brief Obtain the `aes_x86ni` AES-CBC (encryption) implementation, if + * available. + * + * This function returns a pointer to `br_aes_x86ni_cbcenc_vtable`, if + * that implementation was compiled in the library _and_ the x86 AES + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_x86ni` AES-CBC (encryption) implementation, or `NULL`. + */ +const br_block_cbcenc_class *br_aes_x86ni_cbcenc_get_vtable(void); + +/** + * \brief Obtain the `aes_x86ni` AES-CBC (decryption) implementation, if + * available. + * + * This function returns a pointer to `br_aes_x86ni_cbcdec_vtable`, if + * that implementation was compiled in the library _and_ the x86 AES + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_x86ni` AES-CBC (decryption) implementation, or `NULL`. + */ +const br_block_cbcdec_class *br_aes_x86ni_cbcdec_get_vtable(void); + +/** + * \brief Obtain the `aes_x86ni` AES-CTR implementation, if available. + * + * This function returns a pointer to `br_aes_x86ni_ctr_vtable`, if + * that implementation was compiled in the library _and_ the x86 AES + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_x86ni` AES-CTR implementation, or `NULL`. + */ +const br_block_ctr_class *br_aes_x86ni_ctr_get_vtable(void); + +/** + * \brief Obtain the `aes_x86ni` AES-CTR + CBC-MAC implementation, if + * available. + * + * This function returns a pointer to `br_aes_x86ni_ctrcbc_vtable`, if + * that implementation was compiled in the library _and_ the x86 AES + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_x86ni` AES-CTR implementation, or `NULL`. + */ +const br_block_ctrcbc_class *br_aes_x86ni_ctrcbc_get_vtable(void); + +/* + * AES implementation using POWER8 opcodes. + */ + +/** \brief AES block size (16 bytes). */ +#define br_aes_pwr8_BLOCK_SIZE 16 + +/** + * \brief Context for AES subkeys (`aes_pwr8` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_pwr8_cbcenc_keys; + +/** + * \brief Context for AES subkeys (`aes_pwr8` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_pwr8_cbcdec_keys; + +/** + * \brief Context for AES subkeys (`aes_pwr8` implementation, CTR encryption + * and decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctr_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_pwr8_ctr_keys; + +/** + * \brief Context for AES subkeys (`aes_pwr8` implementation, CTR encryption + * and decryption + CBC-MAC). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_ctrcbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + union { + unsigned char skni[16 * 15]; + } skey; + unsigned num_rounds; +#endif +} br_aes_pwr8_ctrcbc_keys; + +/** + * \brief Class instance for AES CBC encryption (`aes_pwr8` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_pwr8_cbcenc_get_vtable()`. + */ +extern const br_block_cbcenc_class br_aes_pwr8_cbcenc_vtable; + +/** + * \brief Class instance for AES CBC decryption (`aes_pwr8` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_pwr8_cbcdec_get_vtable()`. + */ +extern const br_block_cbcdec_class br_aes_pwr8_cbcdec_vtable; + +/** + * \brief Class instance for AES CTR encryption and decryption + * (`aes_pwr8` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_pwr8_ctr_get_vtable()`. + */ +extern const br_block_ctr_class br_aes_pwr8_ctr_vtable; + +/** + * \brief Class instance for AES CTR encryption/decryption + CBC-MAC + * (`aes_pwr8` implementation). + * + * Since this implementation might be omitted from the library, or the + * AES opcode unavailable on the current CPU, a pointer to this class + * instance should be obtained through `br_aes_pwr8_ctrcbc_get_vtable()`. + */ +extern const br_block_ctrcbc_class br_aes_pwr8_ctrcbc_vtable; + +/** + * \brief Context initialisation (key schedule) for AES CBC encryption + * (`aes_pwr8` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_pwr8_cbcenc_init(br_aes_pwr8_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CBC decryption + * (`aes_pwr8` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_pwr8_cbcdec_init(br_aes_pwr8_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR encryption + * and decryption (`aes_pwr8` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_pwr8_ctr_init(br_aes_pwr8_ctr_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for AES CTR + CBC-MAC + * (`aes_pwr8` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_aes_pwr8_ctrcbc_init(br_aes_pwr8_ctrcbc_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_pwr8_cbcenc_run(const br_aes_pwr8_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 16). + */ +void br_aes_pwr8_cbcdec_run(const br_aes_pwr8_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CTR encryption and decryption with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (constant, 12 bytes). + * \param cc initial block counter value. + * \param data data to decrypt (updated). + * \param len data length (in bytes). + * \return new block counter value. + */ +uint32_t br_aes_pwr8_ctr_run(const br_aes_pwr8_ctr_keys *ctx, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief CTR encryption + CBC-MAC with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_pwr8_ctrcbc_encrypt(const br_aes_pwr8_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR decryption + CBC-MAC with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_pwr8_ctrcbc_decrypt(const br_aes_pwr8_ctrcbc_keys *ctx, + void *ctr, void *cbcmac, void *data, size_t len); + +/** + * \brief CTR encryption/decryption with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param ctr counter for CTR (16 bytes, updated). + * \param data data to MAC (updated). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_pwr8_ctrcbc_ctr(const br_aes_pwr8_ctrcbc_keys *ctx, + void *ctr, void *data, size_t len); + +/** + * \brief CBC-MAC with AES (`aes_pwr8` implementation). + * + * \param ctx context (already initialised). + * \param cbcmac IV for CBC-MAC (updated). + * \param data data to MAC (unmodified). + * \param len data length (in bytes, MUST be a multiple of 16). + */ +void br_aes_pwr8_ctrcbc_mac(const br_aes_pwr8_ctrcbc_keys *ctx, + void *cbcmac, const void *data, size_t len); + +/** + * \brief Obtain the `aes_pwr8` AES-CBC (encryption) implementation, if + * available. + * + * This function returns a pointer to `br_aes_pwr8_cbcenc_vtable`, if + * that implementation was compiled in the library _and_ the POWER8 + * crypto opcodes are available on the currently running CPU. If either + * of these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_pwr8` AES-CBC (encryption) implementation, or `NULL`. + */ +const br_block_cbcenc_class *br_aes_pwr8_cbcenc_get_vtable(void); + +/** + * \brief Obtain the `aes_pwr8` AES-CBC (decryption) implementation, if + * available. + * + * This function returns a pointer to `br_aes_pwr8_cbcdec_vtable`, if + * that implementation was compiled in the library _and_ the POWER8 + * crypto opcodes are available on the currently running CPU. If either + * of these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_pwr8` AES-CBC (decryption) implementation, or `NULL`. + */ +const br_block_cbcdec_class *br_aes_pwr8_cbcdec_get_vtable(void); + +/** + * \brief Obtain the `aes_pwr8` AES-CTR implementation, if available. + * + * This function returns a pointer to `br_aes_pwr8_ctr_vtable`, if that + * implementation was compiled in the library _and_ the POWER8 crypto + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_pwr8` AES-CTR implementation, or `NULL`. + */ +const br_block_ctr_class *br_aes_pwr8_ctr_get_vtable(void); + +/** + * \brief Obtain the `aes_pwr8` AES-CTR + CBC-MAC implementation, if + * available. + * + * This function returns a pointer to `br_aes_pwr8_ctrcbc_vtable`, if + * that implementation was compiled in the library _and_ the POWER8 AES + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `NULL`. + * + * \return the `aes_pwr8` AES-CTR implementation, or `NULL`. + */ +const br_block_ctrcbc_class *br_aes_pwr8_ctrcbc_get_vtable(void); + +/** + * \brief Aggregate structure large enough to be used as context for + * subkeys (CBC encryption) for all AES implementations. + */ +typedef union { + const br_block_cbcenc_class *vtable; + br_aes_big_cbcenc_keys c_big; + br_aes_small_cbcenc_keys c_small; + br_aes_ct_cbcenc_keys c_ct; + br_aes_ct64_cbcenc_keys c_ct64; + br_aes_x86ni_cbcenc_keys c_x86ni; + br_aes_pwr8_cbcenc_keys c_pwr8; +} br_aes_gen_cbcenc_keys; + +/** + * \brief Aggregate structure large enough to be used as context for + * subkeys (CBC decryption) for all AES implementations. + */ +typedef union { + const br_block_cbcdec_class *vtable; + br_aes_big_cbcdec_keys c_big; + br_aes_small_cbcdec_keys c_small; + br_aes_ct_cbcdec_keys c_ct; + br_aes_ct64_cbcdec_keys c_ct64; + br_aes_x86ni_cbcdec_keys c_x86ni; + br_aes_pwr8_cbcdec_keys c_pwr8; +} br_aes_gen_cbcdec_keys; + +/** + * \brief Aggregate structure large enough to be used as context for + * subkeys (CTR encryption and decryption) for all AES implementations. + */ +typedef union { + const br_block_ctr_class *vtable; + br_aes_big_ctr_keys c_big; + br_aes_small_ctr_keys c_small; + br_aes_ct_ctr_keys c_ct; + br_aes_ct64_ctr_keys c_ct64; + br_aes_x86ni_ctr_keys c_x86ni; + br_aes_pwr8_ctr_keys c_pwr8; +} br_aes_gen_ctr_keys; + +/** + * \brief Aggregate structure large enough to be used as context for + * subkeys (CTR encryption/decryption + CBC-MAC) for all AES implementations. + */ +typedef union { + const br_block_ctrcbc_class *vtable; + br_aes_big_ctrcbc_keys c_big; + br_aes_small_ctrcbc_keys c_small; + br_aes_ct_ctrcbc_keys c_ct; + br_aes_ct64_ctrcbc_keys c_ct64; + br_aes_x86ni_ctrcbc_keys c_x86ni; + br_aes_pwr8_ctrcbc_keys c_pwr8; +} br_aes_gen_ctrcbc_keys; + +/* + * Traditional, table-based implementation for DES/3DES. Since tables are + * used, cache-timing attacks are conceptually possible. + */ + +/** \brief DES/3DES block size (8 bytes). */ +#define br_des_tab_BLOCK_SIZE 8 + +/** + * \brief Context for DES subkeys (`des_tab` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[96]; + unsigned num_rounds; +#endif +} br_des_tab_cbcenc_keys; + +/** + * \brief Context for DES subkeys (`des_tab` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[96]; + unsigned num_rounds; +#endif +} br_des_tab_cbcdec_keys; + +/** + * \brief Class instance for DES CBC encryption (`des_tab` implementation). + */ +extern const br_block_cbcenc_class br_des_tab_cbcenc_vtable; + +/** + * \brief Class instance for DES CBC decryption (`des_tab` implementation). + */ +extern const br_block_cbcdec_class br_des_tab_cbcdec_vtable; + +/** + * \brief Context initialisation (key schedule) for DES CBC encryption + * (`des_tab` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_des_tab_cbcenc_init(br_des_tab_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for DES CBC decryption + * (`des_tab` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_des_tab_cbcdec_init(br_des_tab_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with DES (`des_tab` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 8). + */ +void br_des_tab_cbcenc_run(const br_des_tab_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with DES (`des_tab` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 8). + */ +void br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/* + * Constant-time implementation for DES/3DES. It is substantially slower + * (by a factor of about 4x), but also immune to cache-timing attacks. + */ + +/** \brief DES/3DES block size (8 bytes). */ +#define br_des_ct_BLOCK_SIZE 8 + +/** + * \brief Context for DES subkeys (`des_ct` implementation, CBC encryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcenc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[96]; + unsigned num_rounds; +#endif +} br_des_ct_cbcenc_keys; + +/** + * \brief Context for DES subkeys (`des_ct` implementation, CBC decryption). + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** \brief Pointer to vtable for this context. */ + const br_block_cbcdec_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint32_t skey[96]; + unsigned num_rounds; +#endif +} br_des_ct_cbcdec_keys; + +/** + * \brief Class instance for DES CBC encryption (`des_ct` implementation). + */ +extern const br_block_cbcenc_class br_des_ct_cbcenc_vtable; + +/** + * \brief Class instance for DES CBC decryption (`des_ct` implementation). + */ +extern const br_block_cbcdec_class br_des_ct_cbcdec_vtable; + +/** + * \brief Context initialisation (key schedule) for DES CBC encryption + * (`des_ct` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_des_ct_cbcenc_init(br_des_ct_cbcenc_keys *ctx, + const void *key, size_t len); + +/** + * \brief Context initialisation (key schedule) for DES CBC decryption + * (`des_ct` implementation). + * + * \param ctx context to initialise. + * \param key secret key. + * \param len secret key length (in bytes). + */ +void br_des_ct_cbcdec_init(br_des_ct_cbcdec_keys *ctx, + const void *key, size_t len); + +/** + * \brief CBC encryption with DES (`des_ct` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to encrypt (updated). + * \param len data length (in bytes, MUST be multiple of 8). + */ +void br_des_ct_cbcenc_run(const br_des_ct_cbcenc_keys *ctx, void *iv, + void *data, size_t len); + +/** + * \brief CBC decryption with DES (`des_ct` implementation). + * + * \param ctx context (already initialised). + * \param iv IV (updated). + * \param data data to decrypt (updated). + * \param len data length (in bytes, MUST be multiple of 8). + */ +void br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx, void *iv, + void *data, size_t len); + +/* + * These structures are large enough to accommodate subkeys for all + * DES/3DES implementations. + */ + +/** + * \brief Aggregate structure large enough to be used as context for + * subkeys (CBC encryption) for all DES implementations. + */ +typedef union { + const br_block_cbcenc_class *vtable; + br_des_tab_cbcenc_keys tab; + br_des_ct_cbcenc_keys ct; +} br_des_gen_cbcenc_keys; + +/** + * \brief Aggregate structure large enough to be used as context for + * subkeys (CBC decryption) for all DES implementations. + */ +typedef union { + const br_block_cbcdec_class *vtable; + br_des_tab_cbcdec_keys c_tab; + br_des_ct_cbcdec_keys c_ct; +} br_des_gen_cbcdec_keys; + +/** + * \brief Type for a ChaCha20 implementation. + * + * An implementation follows the description in RFC 7539: + * + * - Key is 256 bits (`key` points to exactly 32 bytes). + * + * - IV is 96 bits (`iv` points to exactly 12 bytes). + * + * - Block counter is over 32 bits and starts at value `cc`; the + * resulting value is returned. + * + * Data (pointed to by `data`, of length `len`) is encrypted/decrypted + * in place. If `len` is not a multiple of 64, then the excess bytes from + * the last block processing are dropped (therefore, "chunked" processing + * works only as long as each non-final chunk has a length multiple of 64). + * + * \param key secret key (32 bytes). + * \param iv IV (12 bytes). + * \param cc initial counter value. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ +typedef uint32_t (*br_chacha20_run)(const void *key, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief ChaCha20 implementation (straightforward C code, constant-time). + * + * \see br_chacha20_run + * + * \param key secret key (32 bytes). + * \param iv IV (12 bytes). + * \param cc initial counter value. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ +uint32_t br_chacha20_ct_run(const void *key, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief ChaCha20 implementation (SSE2 code, constant-time). + * + * This implementation is available only on x86 platforms, depending on + * compiler support. Moreover, in 32-bit mode, it might not actually run, + * if the underlying hardware does not implement the SSE2 opcode (in + * 64-bit mode, SSE2 is part of the ABI, so if the code could be compiled + * at all, then it can run). Use `br_chacha20_sse2_get()` to safely obtain + * a pointer to that function. + * + * \see br_chacha20_run + * + * \param key secret key (32 bytes). + * \param iv IV (12 bytes). + * \param cc initial counter value. + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + */ +uint32_t br_chacha20_sse2_run(const void *key, + const void *iv, uint32_t cc, void *data, size_t len); + +/** + * \brief Obtain the `sse2` ChaCha20 implementation, if available. + * + * This function returns a pointer to `br_chacha20_sse2_run`, if + * that implementation was compiled in the library _and_ the SSE2 + * opcodes are available on the currently running CPU. If either of + * these conditions is not met, then this function returns `0`. + * + * \return the `sse2` ChaCha20 implementation, or `0`. + */ +br_chacha20_run br_chacha20_sse2_get(void); + +/** + * \brief Type for a ChaCha20+Poly1305 AEAD implementation. + * + * The provided data is encrypted or decrypted with ChaCha20. The + * authentication tag is computed on the concatenation of the + * additional data and the ciphertext, with the padding and lengths + * as described in RFC 7539 (section 2.8). + * + * After decryption, the caller is responsible for checking that the + * computed tag matches the expected value. + * + * \param key secret key (32 bytes). + * \param iv nonce (12 bytes). + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + * \param aad additional authenticated data. + * \param aad_len length of additional authenticated data (in bytes). + * \param tag output buffer for the authentication tag. + * \param ichacha implementation of ChaCha20. + * \param encrypt non-zero for encryption, zero for decryption. + */ +typedef void (*br_poly1305_run)(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt); + +/** + * \brief ChaCha20+Poly1305 AEAD implementation (mixed 32-bit multiplications). + * + * \see br_poly1305_run + * + * \param key secret key (32 bytes). + * \param iv nonce (12 bytes). + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + * \param aad additional authenticated data. + * \param aad_len length of additional authenticated data (in bytes). + * \param tag output buffer for the authentication tag. + * \param ichacha implementation of ChaCha20. + * \param encrypt non-zero for encryption, zero for decryption. + */ +void br_poly1305_ctmul_run(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt); + +/** + * \brief ChaCha20+Poly1305 AEAD implementation (pure 32-bit multiplications). + * + * \see br_poly1305_run + * + * \param key secret key (32 bytes). + * \param iv nonce (12 bytes). + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + * \param aad additional authenticated data. + * \param aad_len length of additional authenticated data (in bytes). + * \param tag output buffer for the authentication tag. + * \param ichacha implementation of ChaCha20. + * \param encrypt non-zero for encryption, zero for decryption. + */ +void br_poly1305_ctmul32_run(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt); + +/** + * \brief ChaCha20+Poly1305 AEAD implementation (i15). + * + * This implementation relies on the generic big integer code "i15" + * (which uses pure 32-bit multiplications). As such, it may save a + * little code footprint in a context where "i15" is already included + * (e.g. for elliptic curves or for RSA); however, it is also + * substantially slower than the ctmul and ctmul32 implementations. + * + * \see br_poly1305_run + * + * \param key secret key (32 bytes). + * \param iv nonce (12 bytes). + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + * \param aad additional authenticated data. + * \param aad_len length of additional authenticated data (in bytes). + * \param tag output buffer for the authentication tag. + * \param ichacha implementation of ChaCha20. + * \param encrypt non-zero for encryption, zero for decryption. + */ +void br_poly1305_i15_run(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt); + +/** + * \brief ChaCha20+Poly1305 AEAD implementation (ctmulq). + * + * This implementation uses 64-bit multiplications (result over 128 bits). + * It is available only on platforms that offer such a primitive (in + * practice, 64-bit architectures). Use `br_poly1305_ctmulq_get()` to + * dynamically obtain a pointer to that function, or 0 if not supported. + * + * \see br_poly1305_run + * + * \param key secret key (32 bytes). + * \param iv nonce (12 bytes). + * \param data data to encrypt or decrypt. + * \param len data length (in bytes). + * \param aad additional authenticated data. + * \param aad_len length of additional authenticated data (in bytes). + * \param tag output buffer for the authentication tag. + * \param ichacha implementation of ChaCha20. + * \param encrypt non-zero for encryption, zero for decryption. + */ +void br_poly1305_ctmulq_run(const void *key, const void *iv, + void *data, size_t len, const void *aad, size_t aad_len, + void *tag, br_chacha20_run ichacha, int encrypt); + +/** + * \brief Get the ChaCha20+Poly1305 "ctmulq" implementation, if available. + * + * This function returns a pointer to the `br_poly1305_ctmulq_run()` + * function if supported on the current platform; otherwise, it returns 0. + * + * \return the ctmulq ChaCha20+Poly1305 implementation, or 0. + */ +br_poly1305_run br_poly1305_ctmulq_get(void); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_ec.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_ec.h new file mode 100644 index 000000000000..ad07476e7896 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_ec.h @@ -0,0 +1,983 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_EC_H__ +#define BR_BEARSSL_EC_H__ + +#include +#include + +#include "bearssl_rand.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_ec.h + * + * # Elliptic Curves + * + * This file documents the EC implementations provided with BearSSL, and + * ECDSA. + * + * ## Elliptic Curve API + * + * Only "named curves" are supported. Each EC implementation supports + * one or several named curves, identified by symbolic identifiers. + * These identifiers are small integers, that correspond to the values + * registered by the + * [IANA](http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8). + * + * Since all currently defined elliptic curve identifiers are in the 0..31 + * range, it is convenient to encode support of some curves in a 32-bit + * word, such that bit x corresponds to curve of identifier x. + * + * An EC implementation is incarnated by a `br_ec_impl` instance, that + * offers the following fields: + * + * - `supported_curves` + * + * A 32-bit word that documents the identifiers of the curves supported + * by this implementation. + * + * - `generator()` + * + * Callback method that returns a pointer to the conventional generator + * point for that curve. + * + * - `order()` + * + * Callback method that returns a pointer to the subgroup order for + * that curve. That value uses unsigned big-endian encoding. + * + * - `xoff()` + * + * Callback method that returns the offset and length of the X + * coordinate in an encoded point. + * + * - `mul()` + * + * Multiply a curve point with an integer. + * + * - `mulgen()` + * + * Multiply the curve generator with an integer. This may be faster + * than the generic `mul()`. + * + * - `muladd()` + * + * Multiply two curve points by two integers, and return the sum of + * the two products. + * + * All curve points are represented in uncompressed format. The `mul()` + * and `muladd()` methods take care to validate that the provided points + * are really part of the relevant curve subgroup. + * + * For all point multiplication functions, the following holds: + * + * - Functions validate that the provided points are valid members + * of the relevant curve subgroup. An error is reported if that is + * not the case. + * + * - Processing is constant-time, even if the point operands are not + * valid. This holds for both the source and resulting points, and + * the multipliers (integers). Only the byte length of the provided + * multiplier arrays (not their actual value length in bits) may + * leak through timing-based side channels. + * + * - The multipliers (integers) MUST be lower than the subgroup order. + * If this property is not met, then the result is indeterminate, + * but an error value is not necessarily returned. + * + * + * ## ECDSA + * + * ECDSA signatures have two standard formats, called "raw" and "asn1". + * Internally, such a signature is a pair of modular integers `(r,s)`. + * The "raw" format is the concatenation of the unsigned big-endian + * encodings of these two integers, possibly left-padded with zeros so + * that they have the same encoded length. The "asn1" format is the + * DER encoding of an ASN.1 structure that contains the two integer + * values: + * + * ECDSASignature ::= SEQUENCE { + * r INTEGER, + * s INTEGER + * } + * + * In general, in all of X.509 and SSL/TLS, the "asn1" format is used. + * BearSSL offers ECDSA implementations for both formats; conversion + * functions between the two formats are also provided. Conversion of a + * "raw" format signature into "asn1" may enlarge a signature by no more + * than 9 bytes for all supported curves; conversely, conversion of an + * "asn1" signature to "raw" may expand the signature but the "raw" + * length will never be more than twice the length of the "asn1" length + * (and usually it will be shorter). + * + * Note that for a given signature, the "raw" format is not fully + * deterministic, in that it does not enforce a minimal common length. + */ + +/* + * Standard curve ID. These ID are equal to the assigned numerical + * identifiers assigned to these curves for TLS: + * http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 + */ + +/** \brief Identifier for named curve sect163k1. */ +#define BR_EC_sect163k1 1 + +/** \brief Identifier for named curve sect163r1. */ +#define BR_EC_sect163r1 2 + +/** \brief Identifier for named curve sect163r2. */ +#define BR_EC_sect163r2 3 + +/** \brief Identifier for named curve sect193r1. */ +#define BR_EC_sect193r1 4 + +/** \brief Identifier for named curve sect193r2. */ +#define BR_EC_sect193r2 5 + +/** \brief Identifier for named curve sect233k1. */ +#define BR_EC_sect233k1 6 + +/** \brief Identifier for named curve sect233r1. */ +#define BR_EC_sect233r1 7 + +/** \brief Identifier for named curve sect239k1. */ +#define BR_EC_sect239k1 8 + +/** \brief Identifier for named curve sect283k1. */ +#define BR_EC_sect283k1 9 + +/** \brief Identifier for named curve sect283r1. */ +#define BR_EC_sect283r1 10 + +/** \brief Identifier for named curve sect409k1. */ +#define BR_EC_sect409k1 11 + +/** \brief Identifier for named curve sect409r1. */ +#define BR_EC_sect409r1 12 + +/** \brief Identifier for named curve sect571k1. */ +#define BR_EC_sect571k1 13 + +/** \brief Identifier for named curve sect571r1. */ +#define BR_EC_sect571r1 14 + +/** \brief Identifier for named curve secp160k1. */ +#define BR_EC_secp160k1 15 + +/** \brief Identifier for named curve secp160r1. */ +#define BR_EC_secp160r1 16 + +/** \brief Identifier for named curve secp160r2. */ +#define BR_EC_secp160r2 17 + +/** \brief Identifier for named curve secp192k1. */ +#define BR_EC_secp192k1 18 + +/** \brief Identifier for named curve secp192r1. */ +#define BR_EC_secp192r1 19 + +/** \brief Identifier for named curve secp224k1. */ +#define BR_EC_secp224k1 20 + +/** \brief Identifier for named curve secp224r1. */ +#define BR_EC_secp224r1 21 + +/** \brief Identifier for named curve secp256k1. */ +#define BR_EC_secp256k1 22 + +/** \brief Identifier for named curve secp256r1. */ +#define BR_EC_secp256r1 23 + +/** \brief Identifier for named curve secp384r1. */ +#define BR_EC_secp384r1 24 + +/** \brief Identifier for named curve secp521r1. */ +#define BR_EC_secp521r1 25 + +/** \brief Identifier for named curve brainpoolP256r1. */ +#define BR_EC_brainpoolP256r1 26 + +/** \brief Identifier for named curve brainpoolP384r1. */ +#define BR_EC_brainpoolP384r1 27 + +/** \brief Identifier for named curve brainpoolP512r1. */ +#define BR_EC_brainpoolP512r1 28 + +/** \brief Identifier for named curve Curve25519. */ +#define BR_EC_curve25519 29 + +/** \brief Identifier for named curve Curve448. */ +#define BR_EC_curve448 30 + +/** + * \brief Structure for an EC public key. + */ +typedef struct { + /** \brief Identifier for the curve used by this key. */ + int curve; + /** \brief Public curve point (uncompressed format). */ + unsigned char *q; + /** \brief Length of public curve point (in bytes). */ + size_t qlen; +} br_ec_public_key; + +/** + * \brief Structure for an EC private key. + * + * The private key is an integer modulo the curve subgroup order. The + * encoding below tolerates extra leading zeros. In general, it is + * recommended that the private key has the same length as the curve + * subgroup order. + */ +typedef struct { + /** \brief Identifier for the curve used by this key. */ + int curve; + /** \brief Private key (integer, unsigned big-endian encoding). */ + unsigned char *x; + /** \brief Private key length (in bytes). */ + size_t xlen; +} br_ec_private_key; + +/** + * \brief Type for an EC implementation. + */ +typedef struct { + /** + * \brief Supported curves. + * + * This word is a bitfield: bit `x` is set if the curve of ID `x` + * is supported. E.g. an implementation supporting both NIST P-256 + * (secp256r1, ID 23) and NIST P-384 (secp384r1, ID 24) will have + * value `0x01800000` in this field. + */ + uint32_t supported_curves; + + /** + * \brief Get the conventional generator. + * + * This function returns the conventional generator (encoded + * curve point) for the specified curve. This function MUST NOT + * be called if the curve is not supported. + * + * \param curve curve identifier. + * \param len receiver for the encoded generator length (in bytes). + * \return the encoded generator. + */ + const unsigned char *(*generator)(int curve, size_t *len); + + /** + * \brief Get the subgroup order. + * + * This function returns the order of the subgroup generated by + * the conventional generator, for the specified curve. Unsigned + * big-endian encoding is used. This function MUST NOT be called + * if the curve is not supported. + * + * \param curve curve identifier. + * \param len receiver for the encoded order length (in bytes). + * \return the encoded order. + */ + const unsigned char *(*order)(int curve, size_t *len); + + /** + * \brief Get the offset and length for the X coordinate. + * + * This function returns the offset and length (in bytes) of + * the X coordinate in an encoded non-zero point. + * + * \param curve curve identifier. + * \param len receiver for the X coordinate length (in bytes). + * \return the offset for the X coordinate (in bytes). + */ + size_t (*xoff)(int curve, size_t *len); + + /** + * \brief Multiply a curve point by an integer. + * + * The source point is provided in array `G` (of size `Glen` bytes); + * the multiplication result is written over it. The multiplier + * `x` (of size `xlen` bytes) uses unsigned big-endian encoding. + * + * Rules: + * + * - The specified curve MUST be supported. + * + * - The source point must be a valid point on the relevant curve + * subgroup (and not the "point at infinity" either). If this is + * not the case, then this function returns an error (0). + * + * - The multiplier integer MUST be non-zero and less than the + * curve subgroup order. If this property does not hold, then + * the result is indeterminate and an error code is not + * guaranteed. + * + * Returned value is 1 on success, 0 on error. On error, the + * contents of `G` are indeterminate. + * + * \param G point to multiply. + * \param Glen length of the encoded point (in bytes). + * \param x multiplier (unsigned big-endian). + * \param xlen multiplier length (in bytes). + * \param curve curve identifier. + * \return 1 on success, 0 on error. + */ + uint32_t (*mul)(unsigned char *G, size_t Glen, + const unsigned char *x, size_t xlen, int curve); + + /** + * \brief Multiply the generator by an integer. + * + * The multiplier MUST be non-zero and less than the curve + * subgroup order. Results are indeterminate if this property + * does not hold. + * + * \param R output buffer for the point. + * \param x multiplier (unsigned big-endian). + * \param xlen multiplier length (in bytes). + * \param curve curve identifier. + * \return encoded result point length (in bytes). + */ + size_t (*mulgen)(unsigned char *R, + const unsigned char *x, size_t xlen, int curve); + + /** + * \brief Multiply two points by two integers and add the + * results. + * + * The point `x*A + y*B` is computed and written back in the `A` + * array. + * + * Rules: + * + * - The specified curve MUST be supported. + * + * - The source points (`A` and `B`) must be valid points on + * the relevant curve subgroup (and not the "point at + * infinity" either). If this is not the case, then this + * function returns an error (0). + * + * - If the `B` pointer is `NULL`, then the conventional + * subgroup generator is used. With some implementations, + * this may be faster than providing a pointer to the + * generator. + * + * - The multiplier integers (`x` and `y`) MUST be non-zero + * and less than the curve subgroup order. If either integer + * is zero, then an error is reported, but if one of them is + * not lower than the subgroup order, then the result is + * indeterminate and an error code is not guaranteed. + * + * - If the final result is the point at infinity, then an + * error is returned. + * + * Returned value is 1 on success, 0 on error. On error, the + * contents of `A` are indeterminate. + * + * \param A first point to multiply. + * \param B second point to multiply (`NULL` for the generator). + * \param len common length of the encoded points (in bytes). + * \param x multiplier for `A` (unsigned big-endian). + * \param xlen length of multiplier for `A` (in bytes). + * \param y multiplier for `A` (unsigned big-endian). + * \param ylen length of multiplier for `A` (in bytes). + * \param curve curve identifier. + * \return 1 on success, 0 on error. + */ + uint32_t (*muladd)(unsigned char *A, const unsigned char *B, size_t len, + const unsigned char *x, size_t xlen, + const unsigned char *y, size_t ylen, int curve); +} br_ec_impl; + +/** + * \brief EC implementation "i31". + * + * This implementation internally uses generic code for modular integers, + * with a representation as sequences of 31-bit words. It supports secp256r1, + * secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521). + */ +extern const br_ec_impl br_ec_prime_i31; + +/** + * \brief EC implementation "i15". + * + * This implementation internally uses generic code for modular integers, + * with a representation as sequences of 15-bit words. It supports secp256r1, + * secp384r1 and secp521r1 (aka NIST curves P-256, P-384 and P-521). + */ +extern const br_ec_impl br_ec_prime_i15; + +/** + * \brief EC implementation "m15" for P-256. + * + * This implementation uses specialised code for curve secp256r1 (also + * known as NIST P-256), with optional Karatsuba decomposition, and fast + * modular reduction thanks to the field modulus special format. Only + * 32-bit multiplications are used (with 32-bit results, not 64-bit). + */ +extern const br_ec_impl br_ec_p256_m15; + +/** + * \brief EC implementation "m31" for P-256. + * + * This implementation uses specialised code for curve secp256r1 (also + * known as NIST P-256), relying on multiplications of 31-bit values + * (MUL31). + */ +extern const br_ec_impl br_ec_p256_m31; + +/** + * \brief EC implementation "m62" (specialised code) for P-256. + * + * This implementation uses custom code relying on multiplication of + * integers up to 64 bits, with a 128-bit result. This implementation is + * defined only on platforms that offer the 64x64->128 multiplication + * support; use `br_ec_p256_m62_get()` to dynamically obtain a pointer + * to that implementation. + */ +extern const br_ec_impl br_ec_p256_m62; + +/** + * \brief Get the "m62" implementation of P-256, if available. + * + * \return the implementation, or 0. + */ +const br_ec_impl *br_ec_p256_m62_get(void); + +/** + * \brief EC implementation "m64" (specialised code) for P-256. + * + * This implementation uses custom code relying on multiplication of + * integers up to 64 bits, with a 128-bit result. This implementation is + * defined only on platforms that offer the 64x64->128 multiplication + * support; use `br_ec_p256_m64_get()` to dynamically obtain a pointer + * to that implementation. + */ +extern const br_ec_impl br_ec_p256_m64; + +/** + * \brief Get the "m64" implementation of P-256, if available. + * + * \return the implementation, or 0. + */ +const br_ec_impl *br_ec_p256_m64_get(void); + +/** + * \brief EC implementation "i15" (generic code) for Curve25519. + * + * This implementation uses the generic code for modular integers (with + * 15-bit words) to support Curve25519. Due to the specificities of the + * curve definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). + */ +extern const br_ec_impl br_ec_c25519_i15; + +/** + * \brief EC implementation "i31" (generic code) for Curve25519. + * + * This implementation uses the generic code for modular integers (with + * 31-bit words) to support Curve25519. Due to the specificities of the + * curve definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). + */ +extern const br_ec_impl br_ec_c25519_i31; + +/** + * \brief EC implementation "m15" (specialised code) for Curve25519. + * + * This implementation uses custom code relying on multiplication of + * integers up to 15 bits. Due to the specificities of the curve + * definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). + */ +extern const br_ec_impl br_ec_c25519_m15; + +/** + * \brief EC implementation "m31" (specialised code) for Curve25519. + * + * This implementation uses custom code relying on multiplication of + * integers up to 31 bits. Due to the specificities of the curve + * definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). + */ +extern const br_ec_impl br_ec_c25519_m31; + +/** + * \brief EC implementation "m62" (specialised code) for Curve25519. + * + * This implementation uses custom code relying on multiplication of + * integers up to 62 bits, with a 124-bit result. This implementation is + * defined only on platforms that offer the 64x64->128 multiplication + * support; use `br_ec_c25519_m62_get()` to dynamically obtain a pointer + * to that implementation. Due to the specificities of the curve + * definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). + */ +extern const br_ec_impl br_ec_c25519_m62; + +/** + * \brief Get the "m62" implementation of Curve25519, if available. + * + * \return the implementation, or 0. + */ +const br_ec_impl *br_ec_c25519_m62_get(void); + +/** + * \brief EC implementation "m64" (specialised code) for Curve25519. + * + * This implementation uses custom code relying on multiplication of + * integers up to 64 bits, with a 128-bit result. This implementation is + * defined only on platforms that offer the 64x64->128 multiplication + * support; use `br_ec_c25519_m64_get()` to dynamically obtain a pointer + * to that implementation. Due to the specificities of the curve + * definition, the following applies: + * + * - `muladd()` is not implemented (the function returns 0 systematically). + * - `order()` returns 2^255-1, since the point multiplication algorithm + * accepts any 32-bit integer as input (it clears the top bit and low + * three bits systematically). + */ +extern const br_ec_impl br_ec_c25519_m64; + +/** + * \brief Get the "m64" implementation of Curve25519, if available. + * + * \return the implementation, or 0. + */ +const br_ec_impl *br_ec_c25519_m64_get(void); + +/** + * \brief Aggregate EC implementation "m15". + * + * This implementation is a wrapper for: + * + * - `br_ec_c25519_m15` for Curve25519 + * - `br_ec_p256_m15` for NIST P-256 + * - `br_ec_prime_i15` for other curves (NIST P-384 and NIST-P512) + */ +extern const br_ec_impl br_ec_all_m15; + +/** + * \brief Aggregate EC implementation "m31". + * + * This implementation is a wrapper for: + * + * - `br_ec_c25519_m31` for Curve25519 + * - `br_ec_p256_m31` for NIST P-256 + * - `br_ec_prime_i31` for other curves (NIST P-384 and NIST-P512) + */ +extern const br_ec_impl br_ec_all_m31; + +/** + * \brief Aggregate EC implementation "m31". + * + * This implementation is a wrapper for: + * + * - `br_ec_p256_m31` for NIST P-256 + * - `br_ec_prime_i31` for other curves (NIST P-384 and NIST-P512) + */ +extern const br_ec_impl br_ec_prime_fast_256; + +/** + * \brief Get the "default" EC implementation for the current system. + * + * This returns a pointer to the preferred implementation on the + * current system. + * + * \return the default EC implementation. + */ +const br_ec_impl *br_ec_get_default(void); + +/** + * \brief Convert a signature from "raw" to "asn1". + * + * Conversion is done "in place" and the new length is returned. + * Conversion may enlarge the signature, but by no more than 9 bytes at + * most. On error, 0 is returned (error conditions include an odd raw + * signature length, or an oversized integer). + * + * \param sig signature to convert. + * \param sig_len signature length (in bytes). + * \return the new signature length, or 0 on error. + */ +size_t br_ecdsa_raw_to_asn1(void *sig, size_t sig_len); + +/** + * \brief Convert a signature from "asn1" to "raw". + * + * Conversion is done "in place" and the new length is returned. + * Conversion may enlarge the signature, but the new signature length + * will be less than twice the source length at most. On error, 0 is + * returned (error conditions include an invalid ASN.1 structure or an + * oversized integer). + * + * \param sig signature to convert. + * \param sig_len signature length (in bytes). + * \return the new signature length, or 0 on error. + */ +size_t br_ecdsa_asn1_to_raw(void *sig, size_t sig_len); + +/** + * \brief Type for an ECDSA signer function. + * + * A pointer to the EC implementation is provided. The hash value is + * assumed to have the length inferred from the designated hash function + * class. + * + * Signature is written in the buffer pointed to by `sig`, and the length + * (in bytes) is returned. On error, nothing is written in the buffer, + * and 0 is returned. This function returns 0 if the specified curve is + * not supported by the provided EC implementation. + * + * The signature format is either "raw" or "asn1", depending on the + * implementation; maximum length is predictable from the implemented + * curve: + * + * | curve | raw | asn1 | + * | :--------- | --: | ---: | + * | NIST P-256 | 64 | 72 | + * | NIST P-384 | 96 | 104 | + * | NIST P-521 | 132 | 139 | + * + * \param impl EC implementation to use. + * \param hf hash function used to process the data. + * \param hash_value signed data (hashed). + * \param sk EC private key. + * \param sig destination buffer. + * \return the signature length (in bytes), or 0 on error. + */ +typedef size_t (*br_ecdsa_sign)(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig); + +/** + * \brief Type for an ECDSA signature verification function. + * + * A pointer to the EC implementation is provided. The hashed value, + * computed over the purportedly signed data, is also provided with + * its length. + * + * The signature format is either "raw" or "asn1", depending on the + * implementation. + * + * Returned value is 1 on success (valid signature), 0 on error. This + * function returns 0 if the specified curve is not supported by the + * provided EC implementation. + * + * \param impl EC implementation to use. + * \param hash signed data (hashed). + * \param hash_len hash value length (in bytes). + * \param pk EC public key. + * \param sig signature. + * \param sig_len signature length (in bytes). + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_ecdsa_vrfy)(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, const void *sig, size_t sig_len); + +/** + * \brief ECDSA signature generator, "i31" implementation, "asn1" format. + * + * \see br_ecdsa_sign() + * + * \param impl EC implementation to use. + * \param hf hash function used to process the data. + * \param hash_value signed data (hashed). + * \param sk EC private key. + * \param sig destination buffer. + * \return the signature length (in bytes), or 0 on error. + */ +size_t br_ecdsa_i31_sign_asn1(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig); + +/** + * \brief ECDSA signature generator, "i31" implementation, "raw" format. + * + * \see br_ecdsa_sign() + * + * \param impl EC implementation to use. + * \param hf hash function used to process the data. + * \param hash_value signed data (hashed). + * \param sk EC private key. + * \param sig destination buffer. + * \return the signature length (in bytes), or 0 on error. + */ +size_t br_ecdsa_i31_sign_raw(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig); + +/** + * \brief ECDSA signature verifier, "i31" implementation, "asn1" format. + * + * \see br_ecdsa_vrfy() + * + * \param impl EC implementation to use. + * \param hash signed data (hashed). + * \param hash_len hash value length (in bytes). + * \param pk EC public key. + * \param sig signature. + * \param sig_len signature length (in bytes). + * \return 1 on success, 0 on error. + */ +uint32_t br_ecdsa_i31_vrfy_asn1(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, const void *sig, size_t sig_len); + +/** + * \brief ECDSA signature verifier, "i31" implementation, "raw" format. + * + * \see br_ecdsa_vrfy() + * + * \param impl EC implementation to use. + * \param hash signed data (hashed). + * \param hash_len hash value length (in bytes). + * \param pk EC public key. + * \param sig signature. + * \param sig_len signature length (in bytes). + * \return 1 on success, 0 on error. + */ +uint32_t br_ecdsa_i31_vrfy_raw(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, const void *sig, size_t sig_len); + +/** + * \brief ECDSA signature generator, "i15" implementation, "asn1" format. + * + * \see br_ecdsa_sign() + * + * \param impl EC implementation to use. + * \param hf hash function used to process the data. + * \param hash_value signed data (hashed). + * \param sk EC private key. + * \param sig destination buffer. + * \return the signature length (in bytes), or 0 on error. + */ +size_t br_ecdsa_i15_sign_asn1(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig); + +/** + * \brief ECDSA signature generator, "i15" implementation, "raw" format. + * + * \see br_ecdsa_sign() + * + * \param impl EC implementation to use. + * \param hf hash function used to process the data. + * \param hash_value signed data (hashed). + * \param sk EC private key. + * \param sig destination buffer. + * \return the signature length (in bytes), or 0 on error. + */ +size_t br_ecdsa_i15_sign_raw(const br_ec_impl *impl, + const br_hash_class *hf, const void *hash_value, + const br_ec_private_key *sk, void *sig); + +/** + * \brief ECDSA signature verifier, "i15" implementation, "asn1" format. + * + * \see br_ecdsa_vrfy() + * + * \param impl EC implementation to use. + * \param hash signed data (hashed). + * \param hash_len hash value length (in bytes). + * \param pk EC public key. + * \param sig signature. + * \param sig_len signature length (in bytes). + * \return 1 on success, 0 on error. + */ +uint32_t br_ecdsa_i15_vrfy_asn1(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, const void *sig, size_t sig_len); + +/** + * \brief ECDSA signature verifier, "i15" implementation, "raw" format. + * + * \see br_ecdsa_vrfy() + * + * \param impl EC implementation to use. + * \param hash signed data (hashed). + * \param hash_len hash value length (in bytes). + * \param pk EC public key. + * \param sig signature. + * \param sig_len signature length (in bytes). + * \return 1 on success, 0 on error. + */ +uint32_t br_ecdsa_i15_vrfy_raw(const br_ec_impl *impl, + const void *hash, size_t hash_len, + const br_ec_public_key *pk, const void *sig, size_t sig_len); + +/** + * \brief Get "default" ECDSA implementation (signer, asn1 format). + * + * This returns the preferred implementation of ECDSA signature generation + * ("asn1" output format) on the current system. + * + * \return the default implementation. + */ +br_ecdsa_sign br_ecdsa_sign_asn1_get_default(void); + +/** + * \brief Get "default" ECDSA implementation (signer, raw format). + * + * This returns the preferred implementation of ECDSA signature generation + * ("raw" output format) on the current system. + * + * \return the default implementation. + */ +br_ecdsa_sign br_ecdsa_sign_raw_get_default(void); + +/** + * \brief Get "default" ECDSA implementation (verifier, asn1 format). + * + * This returns the preferred implementation of ECDSA signature verification + * ("asn1" output format) on the current system. + * + * \return the default implementation. + */ +br_ecdsa_vrfy br_ecdsa_vrfy_asn1_get_default(void); + +/** + * \brief Get "default" ECDSA implementation (verifier, raw format). + * + * This returns the preferred implementation of ECDSA signature verification + * ("raw" output format) on the current system. + * + * \return the default implementation. + */ +br_ecdsa_vrfy br_ecdsa_vrfy_raw_get_default(void); + +/** + * \brief Maximum size for EC private key element buffer. + * + * This is the largest number of bytes that `br_ec_keygen()` may need or + * ever return. + */ +#define BR_EC_KBUF_PRIV_MAX_SIZE 72 + +/** + * \brief Maximum size for EC public key element buffer. + * + * This is the largest number of bytes that `br_ec_compute_public()` may + * need or ever return. + */ +#define BR_EC_KBUF_PUB_MAX_SIZE 145 + +/** + * \brief Generate a new EC private key. + * + * If the specified `curve` is not supported by the elliptic curve + * implementation (`impl`), then this function returns zero. + * + * The `sk` structure fields are set to the new private key data. In + * particular, `sk.x` is made to point to the provided key buffer (`kbuf`), + * in which the actual private key data is written. That buffer is assumed + * to be large enough. The `BR_EC_KBUF_PRIV_MAX_SIZE` defines the maximum + * size for all supported curves. + * + * The number of bytes used in `kbuf` is returned. If `kbuf` is `NULL`, then + * the private key is not actually generated, and `sk` may also be `NULL`; + * the minimum length for `kbuf` is still computed and returned. + * + * If `sk` is `NULL` but `kbuf` is not `NULL`, then the private key is + * still generated and stored in `kbuf`. + * + * \param rng_ctx source PRNG context (already initialized). + * \param impl the elliptic curve implementation. + * \param sk the private key structure to fill, or `NULL`. + * \param kbuf the key element buffer, or `NULL`. + * \param curve the curve identifier. + * \return the key data length (in bytes), or zero. + */ +size_t br_ec_keygen(const br_prng_class **rng_ctx, + const br_ec_impl *impl, br_ec_private_key *sk, + void *kbuf, int curve); + +/** + * \brief Compute EC public key from EC private key. + * + * This function uses the provided elliptic curve implementation (`impl`) + * to compute the public key corresponding to the private key held in `sk`. + * The public key point is written into `kbuf`, which is then linked from + * the `*pk` structure. The size of the public key point, i.e. the number + * of bytes used in `kbuf`, is returned. + * + * If `kbuf` is `NULL`, then the public key point is NOT computed, and + * the public key structure `*pk` is unmodified (`pk` may be `NULL` in + * that case). The size of the public key point is still returned. + * + * If `pk` is `NULL` but `kbuf` is not `NULL`, then the public key + * point is computed and stored in `kbuf`, and its size is returned. + * + * If the curve used by the private key is not supported by the curve + * implementation, then this function returns zero. + * + * The private key MUST be valid. An off-range private key value is not + * necessarily detected, and leads to unpredictable results. + * + * \param impl the elliptic curve implementation. + * \param pk the public key structure to fill (or `NULL`). + * \param kbuf the public key point buffer (or `NULL`). + * \param sk the source private key. + * \return the public key point length (in bytes), or zero. + */ +size_t br_ec_compute_pub(const br_ec_impl *impl, br_ec_public_key *pk, + void *kbuf, const br_ec_private_key *sk); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_hash.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_hash.h new file mode 100644 index 000000000000..8d5a2a8ee7ac --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_hash.h @@ -0,0 +1,1352 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_HASH_H__ +#define BR_BEARSSL_HASH_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_hash.h + * + * # Hash Functions + * + * This file documents the API for hash functions. + * + * + * ## Procedural API + * + * For each implemented hash function, of name "`xxx`", the following + * elements are defined: + * + * - `br_xxx_vtable` + * + * An externally defined instance of `br_hash_class`. + * + * - `br_xxx_SIZE` + * + * A macro that evaluates to the output size (in bytes) of the + * hash function. + * + * - `br_xxx_ID` + * + * A macro that evaluates to a symbolic identifier for the hash + * function. Such identifiers are used with HMAC and signature + * algorithm implementations. + * + * NOTE: for the "standard" hash functions defined in [the TLS + * standard](https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1), + * the symbolic identifiers match the constants used in TLS, i.e. + * 1 to 6 for MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512, + * respectively. + * + * - `br_xxx_context` + * + * Context for an ongoing computation. It is allocated by the + * caller, and a pointer to it is passed to all functions. A + * context contains no interior pointer, so it can be moved around + * and cloned (with a simple `memcpy()` or equivalent) in order to + * capture the function state at some point. Computations that use + * distinct context structures are independent of each other. The + * first field of `br_xxx_context` is always a pointer to the + * `br_xxx_vtable` structure; `br_xxx_init()` sets that pointer. + * + * - `br_xxx_init(br_xxx_context *ctx)` + * + * Initialise the provided context. Previous contents of the structure + * are ignored. This calls resets the context to the start of a new + * hash computation; it also sets the first field of the context + * structure (called `vtable`) to a pointer to the statically + * allocated constant `br_xxx_vtable` structure. + * + * - `br_xxx_update(br_xxx_context *ctx, const void *data, size_t len)` + * + * Add some more bytes to the hash computation represented by the + * provided context. + * + * - `br_xxx_out(const br_xxx_context *ctx, void *out)` + * + * Complete the hash computation and write the result in the provided + * buffer. The output buffer MUST be large enough to accommodate the + * result. The context is NOT modified by this operation, so this + * function can be used to get a "partial hash" while still keeping + * the possibility of adding more bytes to the input. + * + * - `br_xxx_state(const br_xxx_context *ctx, void *out)` + * + * Get a copy of the "current state" for the computation so far. For + * MD functions (MD5, SHA-1, SHA-2 family), this is the running state + * resulting from the processing of the last complete input block. + * Returned value is the current input length (in bytes). + * + * - `br_xxx_set_state(br_xxx_context *ctx, const void *stb, uint64_t count)` + * + * Set the internal state to the provided values. The 'stb' and + * 'count' values shall match that which was obtained from + * `br_xxx_state()`. This restores the hash state only if the state + * values were at an appropriate block boundary. This does NOT set + * the `vtable` pointer in the context. + * + * Context structures can be discarded without any explicit deallocation. + * Hash function implementations are purely software and don't reserve + * any resources outside of the context structure itself. + * + * + * ## Object-Oriented API + * + * For each hash function that follows the procedural API described + * above, an object-oriented API is also provided. In that API, function + * pointers from the vtable (`br_xxx_vtable`) are used. The vtable + * incarnates object-oriented programming. An introduction on the OOP + * concept used here can be read on the BearSSL Web site:
+ *    [https://www.bearssl.org/oop.html](https://www.bearssl.org/oop.html) + * + * The vtable offers functions called `init()`, `update()`, `out()`, + * `set()` and `set_state()`, which are in fact the functions from + * the procedural API. That vtable also contains two informative fields: + * + * - `context_size` + * + * The size of the context structure (`br_xxx_context`), in bytes. + * This can be used by generic implementations to perform dynamic + * context allocation. + * + * - `desc` + * + * A "descriptor" field that encodes some information on the hash + * function: symbolic identifier, output size, state size, + * internal block size, details on the padding. + * + * Users of this object-oriented API (in particular generic HMAC + * implementations) may make the following assumptions: + * + * - Hash output size is no more than 64 bytes. + * - Hash internal state size is no more than 64 bytes. + * - Internal block size is a power of two, no less than 16 and no more + * than 256. + * + * + * ## Implemented Hash Functions + * + * Implemented hash functions are: + * + * | Function | Name | Output length | State length | + * | :-------- | :------ | :-----------: | :----------: | + * | MD5 | md5 | 16 | 16 | + * | SHA-1 | sha1 | 20 | 20 | + * | SHA-224 | sha224 | 28 | 32 | + * | SHA-256 | sha256 | 32 | 32 | + * | SHA-384 | sha384 | 48 | 64 | + * | SHA-512 | sha512 | 64 | 64 | + * | MD5+SHA-1 | md5sha1 | 36 | 36 | + * + * (MD5+SHA-1 is the concatenation of MD5 and SHA-1 computed over the + * same input; in the implementation, the internal data buffer is + * shared, thus making it more memory-efficient than separate MD5 and + * SHA-1. It can be useful in implementing SSL 3.0, TLS 1.0 and TLS + * 1.1.) + * + * + * ## Multi-Hasher + * + * An aggregate hasher is provided, that can compute several standard + * hash functions in parallel. It uses `br_multihash_context` and a + * procedural API. It is configured with the implementations (the vtables) + * that it should use; it will then compute all these hash functions in + * parallel, on the same input. It is meant to be used in cases when the + * hash of an object will be used, but the exact hash function is not + * known yet (typically, streamed processing on X.509 certificates). + * + * Only the standard hash functions (MD5, SHA-1, SHA-224, SHA-256, SHA-384 + * and SHA-512) are supported by the multi-hasher. + * + * + * ## GHASH + * + * GHASH is not a generic hash function; it is a _universal_ hash function, + * which, as the name does not say, means that it CANNOT be used in most + * places where a hash function is needed. GHASH is used within the GCM + * encryption mode, to provide the checked integrity functionality. + * + * A GHASH implementation is basically a function that uses the type defined + * in this file under the name `br_ghash`: + * + * typedef void (*br_ghash)(void *y, const void *h, const void *data, size_t len); + * + * The `y` pointer refers to a 16-byte value which is used as input, and + * receives the output of the GHASH invocation. `h` is a 16-byte secret + * value (that serves as key). `data` and `len` define the input data. + * + * Three GHASH implementations are provided, all constant-time, based on + * the use of integer multiplications with appropriate masking to cancel + * carry propagation. + */ + +/** + * \brief Class type for hash function implementations. + * + * A `br_hash_class` instance references the methods implementing a hash + * function. Constant instances of this structure are defined for each + * implemented hash function. Such instances are also called "vtables". + * + * Vtables are used to support object-oriented programming, as + * described on [the BearSSL Web site](https://www.bearssl.org/oop.html). + */ +typedef struct br_hash_class_ br_hash_class; +struct br_hash_class_ { + /** + * \brief Size (in bytes) of the context structure appropriate for + * computing this hash function. + */ + size_t context_size; + + /** + * \brief Descriptor word that contains information about the hash + * function. + * + * For each word `xxx` described below, use `BR_HASHDESC_xxx_OFF` + * and `BR_HASHDESC_xxx_MASK` to access the specific value, as + * follows: + * + * (hf->desc >> BR_HASHDESC_xxx_OFF) & BR_HASHDESC_xxx_MASK + * + * The defined elements are: + * + * - `ID`: the symbolic identifier for the function, as defined + * in [TLS](https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1) + * (MD5 = 1, SHA-1 = 2,...). + * + * - `OUT`: hash output size, in bytes. + * + * - `STATE`: internal running state size, in bytes. + * + * - `LBLEN`: base-2 logarithm for the internal block size, as + * defined for HMAC processing (this is 6 for MD5, SHA-1, SHA-224 + * and SHA-256, since these functions use 64-byte blocks; for + * SHA-384 and SHA-512, this is 7, corresponding to their + * 128-byte blocks). + * + * The descriptor may contain a few other flags. + */ + uint32_t desc; + + /** + * \brief Initialisation method. + * + * This method takes as parameter a pointer to a context area, + * that it initialises. The first field of the context is set + * to this vtable; other elements are initialised for a new hash + * computation. + * + * \param ctx pointer to (the first field of) the context. + */ + void (*init)(const br_hash_class **ctx); + + /** + * \brief Data injection method. + * + * The `len` bytes starting at address `data` are injected into + * the running hash computation incarnated by the specified + * context. The context is updated accordingly. It is allowed + * to have `len == 0`, in which case `data` is ignored (and could + * be `NULL`), and nothing happens. + * on the input data. + * + * \param ctx pointer to (the first field of) the context. + * \param data pointer to the first data byte to inject. + * \param len number of bytes to inject. + */ + void (*update)(const br_hash_class **ctx, const void *data, size_t len); + + /** + * \brief Produce hash output. + * + * The hash output corresponding to all data bytes injected in the + * context since the last `init()` call is computed, and written + * in the buffer pointed to by `dst`. The hash output size depends + * on the implemented hash function (e.g. 16 bytes for MD5). + * The context is _not_ modified by this call, so further bytes + * may be afterwards injected to continue the current computation. + * + * \param ctx pointer to (the first field of) the context. + * \param dst destination buffer for the hash output. + */ + void (*out)(const br_hash_class *const *ctx, void *dst); + + /** + * \brief Get running state. + * + * This method saves the current running state into the `dst` + * buffer. What constitutes the "running state" depends on the + * hash function; for Merkle-Damgård hash functions (like + * MD5 or SHA-1), this is the output obtained after processing + * each block. The number of bytes injected so far is returned. + * The context is not modified by this call. + * + * \param ctx pointer to (the first field of) the context. + * \param dst destination buffer for the state. + * \return the injected total byte length. + */ + uint64_t (*state)(const br_hash_class *const *ctx, void *dst); + + /** + * \brief Set running state. + * + * This methods replaces the running state for the function. + * + * \param ctx pointer to (the first field of) the context. + * \param stb source buffer for the state. + * \param count injected total byte length. + */ + void (*set_state)(const br_hash_class **ctx, + const void *stb, uint64_t count); +}; + +#ifndef BR_DOXYGEN_IGNORE +#define BR_HASHDESC_ID(id) ((uint32_t)(id) << BR_HASHDESC_ID_OFF) +#define BR_HASHDESC_ID_OFF 0 +#define BR_HASHDESC_ID_MASK 0xFF + +#define BR_HASHDESC_OUT(size) ((uint32_t)(size) << BR_HASHDESC_OUT_OFF) +#define BR_HASHDESC_OUT_OFF 8 +#define BR_HASHDESC_OUT_MASK 0x7F + +#define BR_HASHDESC_STATE(size) ((uint32_t)(size) << BR_HASHDESC_STATE_OFF) +#define BR_HASHDESC_STATE_OFF 15 +#define BR_HASHDESC_STATE_MASK 0xFF + +#define BR_HASHDESC_LBLEN(ls) ((uint32_t)(ls) << BR_HASHDESC_LBLEN_OFF) +#define BR_HASHDESC_LBLEN_OFF 23 +#define BR_HASHDESC_LBLEN_MASK 0x0F + +#define BR_HASHDESC_MD_PADDING ((uint32_t)1 << 28) +#define BR_HASHDESC_MD_PADDING_128 ((uint32_t)1 << 29) +#define BR_HASHDESC_MD_PADDING_BE ((uint32_t)1 << 30) +#endif + +/* + * Specific hash functions. + * + * Rules for contexts: + * -- No interior pointer. + * -- No pointer to external dynamically allocated resources. + * -- First field is called 'vtable' and is a pointer to a + * const-qualified br_hash_class instance (pointer is set by init()). + * -- SHA-224 and SHA-256 contexts are identical. + * -- SHA-384 and SHA-512 contexts are identical. + * + * Thus, contexts can be moved and cloned to capture the hash function + * current state; and there is no need for any explicit "release" function. + */ + +/** + * \brief Symbolic identifier for MD5. + */ +#define br_md5_ID 1 + +/** + * \brief MD5 output size (in bytes). + */ +#define br_md5_SIZE 16 + +/** + * \brief Constant vtable for MD5. + */ +extern const br_hash_class br_md5_vtable; + +/** + * \brief MD5 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char buf[64]; + uint64_t count; + uint32_t val[4]; +#endif +} br_md5_context; + +/** + * \brief MD5 context initialisation. + * + * This function initialises or resets a context for a new MD5 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_md5_init(br_md5_context *ctx); + +/** + * \brief Inject some data bytes in a running MD5 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_md5_update(br_md5_context *ctx, const void *data, size_t len); + +/** + * \brief Compute MD5 output. + * + * The MD5 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_md5_out(const br_md5_context *ctx, void *out); + +/** + * \brief Save MD5 running state. + * + * The running state for MD5 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_md5_state(const br_md5_context *ctx, void *out); + +/** + * \brief Restore MD5 running state. + * + * The running state for MD5 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_md5_set_state(br_md5_context *ctx, const void *stb, uint64_t count); + +/** + * \brief Symbolic identifier for SHA-1. + */ +#define br_sha1_ID 2 + +/** + * \brief SHA-1 output size (in bytes). + */ +#define br_sha1_SIZE 20 + +/** + * \brief Constant vtable for SHA-1. + */ +extern const br_hash_class br_sha1_vtable; + +/** + * \brief SHA-1 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char buf[64]; + uint64_t count; + uint32_t val[5]; +#endif +} br_sha1_context; + +/** + * \brief SHA-1 context initialisation. + * + * This function initialises or resets a context for a new SHA-1 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_sha1_init(br_sha1_context *ctx); + +/** + * \brief Inject some data bytes in a running SHA-1 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_sha1_update(br_sha1_context *ctx, const void *data, size_t len); + +/** + * \brief Compute SHA-1 output. + * + * The SHA-1 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_sha1_out(const br_sha1_context *ctx, void *out); + +/** + * \brief Save SHA-1 running state. + * + * The running state for SHA-1 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_sha1_state(const br_sha1_context *ctx, void *out); + +/** + * \brief Restore SHA-1 running state. + * + * The running state for SHA-1 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_sha1_set_state(br_sha1_context *ctx, const void *stb, uint64_t count); + +/** + * \brief Symbolic identifier for SHA-224. + */ +#define br_sha224_ID 3 + +/** + * \brief SHA-224 output size (in bytes). + */ +#define br_sha224_SIZE 28 + +/** + * \brief Constant vtable for SHA-224. + */ +extern const br_hash_class br_sha224_vtable; + +/** + * \brief SHA-224 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char buf[64]; + uint64_t count; + uint32_t val[8]; +#endif +} br_sha224_context; + +/** + * \brief SHA-224 context initialisation. + * + * This function initialises or resets a context for a new SHA-224 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_sha224_init(br_sha224_context *ctx); + +/** + * \brief Inject some data bytes in a running SHA-224 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_sha224_update(br_sha224_context *ctx, const void *data, size_t len); + +/** + * \brief Compute SHA-224 output. + * + * The SHA-224 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_sha224_out(const br_sha224_context *ctx, void *out); + +/** + * \brief Save SHA-224 running state. + * + * The running state for SHA-224 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_sha224_state(const br_sha224_context *ctx, void *out); + +/** + * \brief Restore SHA-224 running state. + * + * The running state for SHA-224 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_sha224_set_state(br_sha224_context *ctx, + const void *stb, uint64_t count); + +/** + * \brief Symbolic identifier for SHA-256. + */ +#define br_sha256_ID 4 + +/** + * \brief SHA-256 output size (in bytes). + */ +#define br_sha256_SIZE 32 + +/** + * \brief Constant vtable for SHA-256. + */ +extern const br_hash_class br_sha256_vtable; + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief SHA-256 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +} br_sha256_context; +#else +typedef br_sha224_context br_sha256_context; +#endif + +/** + * \brief SHA-256 context initialisation. + * + * This function initialises or resets a context for a new SHA-256 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_sha256_init(br_sha256_context *ctx); + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief Inject some data bytes in a running SHA-256 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_sha256_update(br_sha256_context *ctx, const void *data, size_t len); +#else +#define br_sha256_update br_sha224_update +#endif + +/** + * \brief Compute SHA-256 output. + * + * The SHA-256 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_sha256_out(const br_sha256_context *ctx, void *out); + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief Save SHA-256 running state. + * + * The running state for SHA-256 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_sha256_state(const br_sha256_context *ctx, void *out); +#else +#define br_sha256_state br_sha224_state +#endif + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief Restore SHA-256 running state. + * + * The running state for SHA-256 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_sha256_set_state(br_sha256_context *ctx, + const void *stb, uint64_t count); +#else +#define br_sha256_set_state br_sha224_set_state +#endif + +/** + * \brief Symbolic identifier for SHA-384. + */ +#define br_sha384_ID 5 + +/** + * \brief SHA-384 output size (in bytes). + */ +#define br_sha384_SIZE 48 + +/** + * \brief Constant vtable for SHA-384. + */ +extern const br_hash_class br_sha384_vtable; + +/** + * \brief SHA-384 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char buf[128]; + uint64_t count; + uint64_t val[8]; +#endif +} br_sha384_context; + +/** + * \brief SHA-384 context initialisation. + * + * This function initialises or resets a context for a new SHA-384 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_sha384_init(br_sha384_context *ctx); + +/** + * \brief Inject some data bytes in a running SHA-384 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_sha384_update(br_sha384_context *ctx, const void *data, size_t len); + +/** + * \brief Compute SHA-384 output. + * + * The SHA-384 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_sha384_out(const br_sha384_context *ctx, void *out); + +/** + * \brief Save SHA-384 running state. + * + * The running state for SHA-384 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_sha384_state(const br_sha384_context *ctx, void *out); + +/** + * \brief Restore SHA-384 running state. + * + * The running state for SHA-384 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_sha384_set_state(br_sha384_context *ctx, + const void *stb, uint64_t count); + +/** + * \brief Symbolic identifier for SHA-512. + */ +#define br_sha512_ID 6 + +/** + * \brief SHA-512 output size (in bytes). + */ +#define br_sha512_SIZE 64 + +/** + * \brief Constant vtable for SHA-512. + */ +extern const br_hash_class br_sha512_vtable; + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief SHA-512 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +} br_sha512_context; +#else +typedef br_sha384_context br_sha512_context; +#endif + +/** + * \brief SHA-512 context initialisation. + * + * This function initialises or resets a context for a new SHA-512 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_sha512_init(br_sha512_context *ctx); + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief Inject some data bytes in a running SHA-512 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_sha512_update(br_sha512_context *ctx, const void *data, size_t len); +#else +#define br_sha512_update br_sha384_update +#endif + +/** + * \brief Compute SHA-512 output. + * + * The SHA-512 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_sha512_out(const br_sha512_context *ctx, void *out); + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief Save SHA-512 running state. + * + * The running state for SHA-512 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_sha512_state(const br_sha512_context *ctx, void *out); +#else +#define br_sha512_state br_sha384_state +#endif + +#ifdef BR_DOXYGEN_IGNORE +/** + * \brief Restore SHA-512 running state. + * + * The running state for SHA-512 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_sha512_set_state(br_sha512_context *ctx, + const void *stb, uint64_t count); +#else +#define br_sha512_set_state br_sha384_set_state +#endif + +/* + * "md5sha1" is a special hash function that computes both MD5 and SHA-1 + * on the same input, and produces a 36-byte output (MD5 and SHA-1 + * concatenation, in that order). State size is also 36 bytes. + */ + +/** + * \brief Symbolic identifier for MD5+SHA-1. + * + * MD5+SHA-1 is the concatenation of MD5 and SHA-1, computed over the + * same input. It is not one of the functions identified in TLS, so + * we give it a symbolic identifier of value 0. + */ +#define br_md5sha1_ID 0 + +/** + * \brief MD5+SHA-1 output size (in bytes). + */ +#define br_md5sha1_SIZE 36 + +/** + * \brief Constant vtable for MD5+SHA-1. + */ +extern const br_hash_class br_md5sha1_vtable; + +/** + * \brief MD5+SHA-1 context. + * + * First field is a pointer to the vtable; it is set by the initialisation + * function. Other fields are not supposed to be accessed by user code. + */ +typedef struct { + /** + * \brief Pointer to vtable for this context. + */ + const br_hash_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char buf[64]; + uint64_t count; + uint32_t val_md5[4]; + uint32_t val_sha1[5]; +#endif +} br_md5sha1_context; + +/** + * \brief MD5+SHA-1 context initialisation. + * + * This function initialises or resets a context for a new SHA-512 + * computation. It also sets the vtable pointer. + * + * \param ctx pointer to the context structure. + */ +void br_md5sha1_init(br_md5sha1_context *ctx); + +/** + * \brief Inject some data bytes in a running MD5+SHA-1 computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_md5sha1_update(br_md5sha1_context *ctx, const void *data, size_t len); + +/** + * \brief Compute MD5+SHA-1 output. + * + * The MD5+SHA-1 output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `out`. The context + * itself is not modified, so extra bytes may be injected afterwards + * to continue that computation. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the hash output. + */ +void br_md5sha1_out(const br_md5sha1_context *ctx, void *out); + +/** + * \brief Save MD5+SHA-1 running state. + * + * The running state for MD5+SHA-1 (output of the last internal block + * processing) is written in the buffer pointed to by `out`. The + * number of bytes injected since the last initialisation or reset + * call is returned. The context is not modified. + * + * \param ctx pointer to the context structure. + * \param out destination buffer for the running state. + * \return the injected total byte length. + */ +uint64_t br_md5sha1_state(const br_md5sha1_context *ctx, void *out); + +/** + * \brief Restore MD5+SHA-1 running state. + * + * The running state for MD5+SHA-1 is set to the provided values. + * + * \param ctx pointer to the context structure. + * \param stb source buffer for the running state. + * \param count the injected total byte length. + */ +void br_md5sha1_set_state(br_md5sha1_context *ctx, + const void *stb, uint64_t count); + +/** + * \brief Aggregate context for configurable hash function support. + * + * The `br_hash_compat_context` type is a type which is large enough to + * serve as context for all standard hash functions defined above. + */ +typedef union { + const br_hash_class *vtable; + br_md5_context md5; + br_sha1_context sha1; + br_sha224_context sha224; + br_sha256_context sha256; + br_sha384_context sha384; + br_sha512_context sha512; + br_md5sha1_context md5sha1; +} br_hash_compat_context; + +/* + * The multi-hasher is a construct that handles hashing of the same input + * data with several hash functions, with a single shared input buffer. + * It can handle MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 + * simultaneously, though which functions are activated depends on + * the set implementation pointers. + */ + +/** + * \brief Multi-hasher context structure. + * + * The multi-hasher runs up to six hash functions in the standard TLS list + * (MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512) in parallel, over + * the same input. + * + * The multi-hasher does _not_ follow the OOP structure with a vtable. + * Instead, it is configured with the vtables of the hash functions it + * should run. Structure fields are not supposed to be accessed directly. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + unsigned char buf[128]; + uint64_t count; + uint32_t val_32[25]; + uint64_t val_64[16]; + const br_hash_class *impl[6]; +#endif +} br_multihash_context; + +/** + * \brief Clear a multi-hasher context. + * + * This should always be called once on a given context, _before_ setting + * the implementation pointers. + * + * \param ctx the multi-hasher context. + */ +void br_multihash_zero(br_multihash_context *ctx); + +/** + * \brief Set a hash function implementation. + * + * Implementations shall be set _after_ clearing the context (with + * `br_multihash_zero()`) but _before_ initialising the computation + * (with `br_multihash_init()`). The hash function implementation + * MUST be one of the standard hash functions (MD5, SHA-1, SHA-224, + * SHA-256, SHA-384 or SHA-512); it may also be `NULL` to remove + * an implementation from the multi-hasher. + * + * \param ctx the multi-hasher context. + * \param id the hash function symbolic identifier. + * \param impl the hash function vtable, or `NULL`. + */ +static inline void +br_multihash_setimpl(br_multihash_context *ctx, + int id, const br_hash_class *impl) +{ + /* + * This code relies on hash functions ID being values 1 to 6, + * in the MD5 to SHA-512 order. + */ + ctx->impl[id - 1] = impl; +} + +/** + * \brief Get a hash function implementation. + * + * This function returns the currently configured vtable for a given + * hash function (by symbolic ID). If no such function was configured in + * the provided multi-hasher context, then this function returns `NULL`. + * + * \param ctx the multi-hasher context. + * \param id the hash function symbolic identifier. + * \return the hash function vtable, or `NULL`. + */ +static inline const br_hash_class * +br_multihash_getimpl(const br_multihash_context *ctx, int id) +{ + return ctx->impl[id - 1]; +} + +/** + * \brief Reset a multi-hasher context. + * + * This function prepares the context for a new hashing computation, + * for all implementations configured at that point. + * + * \param ctx the multi-hasher context. + */ +void br_multihash_init(br_multihash_context *ctx); + +/** + * \brief Inject some data bytes in a running multi-hashing computation. + * + * The provided context is updated with some data bytes. If the number + * of bytes (`len`) is zero, then the data pointer (`data`) is ignored + * and may be `NULL`, and this function does nothing. + * + * \param ctx pointer to the context structure. + * \param data pointer to the injected data. + * \param len injected data length (in bytes). + */ +void br_multihash_update(br_multihash_context *ctx, + const void *data, size_t len); + +/** + * \brief Compute a hash output from a multi-hasher. + * + * The hash output for the concatenation of all bytes injected in the + * provided context since the last initialisation or reset call, is + * computed and written in the buffer pointed to by `dst`. The hash + * function to use is identified by `id` and must be one of the standard + * hash functions. If that hash function was indeed configured in the + * multi-hasher context, the corresponding hash value is written in + * `dst` and its length (in bytes) is returned. If the hash function + * was _not_ configured, then nothing is written in `dst` and 0 is + * returned. + * + * The context itself is not modified, so extra bytes may be injected + * afterwards to continue the hash computations. + * + * \param ctx pointer to the context structure. + * \param id the hash function symbolic identifier. + * \param dst destination buffer for the hash output. + * \return the hash output length (in bytes), or 0. + */ +size_t br_multihash_out(const br_multihash_context *ctx, int id, void *dst); + +/** + * \brief Type for a GHASH implementation. + * + * GHASH is a sort of keyed hash meant to be used to implement GCM in + * combination with a block cipher (with 16-byte blocks). + * + * The `y` array has length 16 bytes and is used for input and output; in + * a complete GHASH run, it starts with an all-zero value. `h` is a 16-byte + * value that serves as key (it is derived from the encryption key in GCM, + * using the block cipher). The data length (`len`) is expressed in bytes. + * The `y` array is updated. + * + * If the data length is not a multiple of 16, then the data is implicitly + * padded with zeros up to the next multiple of 16. Thus, when using GHASH + * in GCM, this method may be called twice, for the associated data and + * for the ciphertext, respectively; the zero-padding implements exactly + * the GCM rules. + * + * \param y the array to update. + * \param h the GHASH key. + * \param data the input data (may be `NULL` if `len` is zero). + * \param len the input data length (in bytes). + */ +typedef void (*br_ghash)(void *y, const void *h, const void *data, size_t len); + +/** + * \brief GHASH implementation using multiplications (mixed 32-bit). + * + * This implementation uses multiplications of 32-bit values, with a + * 64-bit result. It is constant-time (if multiplications are + * constant-time). + * + * \param y the array to update. + * \param h the GHASH key. + * \param data the input data (may be `NULL` if `len` is zero). + * \param len the input data length (in bytes). + */ +void br_ghash_ctmul(void *y, const void *h, const void *data, size_t len); + +/** + * \brief GHASH implementation using multiplications (strict 32-bit). + * + * This implementation uses multiplications of 32-bit values, with a + * 32-bit result. It is usually somewhat slower than `br_ghash_ctmul()`, + * but it is expected to be faster on architectures for which the + * 32-bit multiplication opcode does not yield the upper 32 bits of the + * product. It is constant-time (if multiplications are constant-time). + * + * \param y the array to update. + * \param h the GHASH key. + * \param data the input data (may be `NULL` if `len` is zero). + * \param len the input data length (in bytes). + */ +void br_ghash_ctmul32(void *y, const void *h, const void *data, size_t len); + +/** + * \brief GHASH implementation using multiplications (64-bit). + * + * This implementation uses multiplications of 64-bit values, with a + * 64-bit result. It is constant-time (if multiplications are + * constant-time). It is substantially faster than `br_ghash_ctmul()` + * and `br_ghash_ctmul32()` on most 64-bit architectures. + * + * \param y the array to update. + * \param h the GHASH key. + * \param data the input data (may be `NULL` if `len` is zero). + * \param len the input data length (in bytes). + */ +void br_ghash_ctmul64(void *y, const void *h, const void *data, size_t len); + +/** + * \brief GHASH implementation using the `pclmulqdq` opcode (part of the + * AES-NI instructions). + * + * This implementation is available only on x86 platforms where the + * compiler supports the relevant intrinsic functions. Even if the + * compiler supports these functions, the local CPU might not support + * the `pclmulqdq` opcode, meaning that a call will fail with an + * illegal instruction exception. To safely obtain a pointer to this + * function when supported (or 0 otherwise), use `br_ghash_pclmul_get()`. + * + * \param y the array to update. + * \param h the GHASH key. + * \param data the input data (may be `NULL` if `len` is zero). + * \param len the input data length (in bytes). + */ +void br_ghash_pclmul(void *y, const void *h, const void *data, size_t len); + +/** + * \brief Obtain the `pclmul` GHASH implementation, if available. + * + * If the `pclmul` implementation was compiled in the library (depending + * on the compiler abilities) _and_ the local CPU appears to support the + * opcode, then this function will return a pointer to the + * `br_ghash_pclmul()` function. Otherwise, it will return `0`. + * + * \return the `pclmul` GHASH implementation, or `0`. + */ +br_ghash br_ghash_pclmul_get(void); + +/** + * \brief GHASH implementation using the POWER8 opcodes. + * + * This implementation is available only on POWER8 platforms (and later). + * To safely obtain a pointer to this function when supported (or 0 + * otherwise), use `br_ghash_pwr8_get()`. + * + * \param y the array to update. + * \param h the GHASH key. + * \param data the input data (may be `NULL` if `len` is zero). + * \param len the input data length (in bytes). + */ +void br_ghash_pwr8(void *y, const void *h, const void *data, size_t len); + +/** + * \brief Obtain the `pwr8` GHASH implementation, if available. + * + * If the `pwr8` implementation was compiled in the library (depending + * on the compiler abilities) _and_ the local CPU appears to support the + * opcode, then this function will return a pointer to the + * `br_ghash_pwr8()` function. Otherwise, it will return `0`. + * + * \return the `pwr8` GHASH implementation, or `0`. + */ +br_ghash br_ghash_pwr8_get(void); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_hmac.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_hmac.h new file mode 100644 index 000000000000..70e9dd11e26f --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_hmac.h @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_HMAC_H__ +#define BR_BEARSSL_HMAC_H__ + +#include +#include + +#include "bearssl_hash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_hmac.h + * + * # HMAC + * + * HMAC is initialized with a key and an underlying hash function; it + * then fills a "key context". That context contains the processed + * key. + * + * With the key context, a HMAC context can be initialized to process + * the input bytes and obtain the MAC output. The key context is not + * modified during that process, and can be reused. + * + * IMPORTANT: HMAC shall be used only with functions that have the + * following properties: + * + * - hash output size does not exceed 64 bytes; + * - hash internal state size does not exceed 64 bytes; + * - internal block length is a power of 2 between 16 and 256 bytes. + */ + +/** + * \brief HMAC key context. + * + * The HMAC key context is initialised with a hash function implementation + * and a secret key. Contents are opaque (callers should not access them + * directly). The caller is responsible for allocating the context where + * appropriate. Context initialisation and usage incurs no dynamic + * allocation, so there is no release function. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + const br_hash_class *dig_vtable; + unsigned char ksi[64], kso[64]; +#endif +} br_hmac_key_context; + +/** + * \brief HMAC key context initialisation. + * + * Initialise the key context with the provided key, using the hash function + * identified by `digest_vtable`. This supports arbitrary key lengths. + * + * \param kc HMAC key context to initialise. + * \param digest_vtable pointer to the hash function implementation vtable. + * \param key pointer to the HMAC secret key. + * \param key_len HMAC secret key length (in bytes). + */ +void br_hmac_key_init(br_hmac_key_context *kc, + const br_hash_class *digest_vtable, const void *key, size_t key_len); + +/* + * \brief Get the underlying hash function. + * + * This function returns a pointer to the implementation vtable of the + * hash function used for this HMAC key context. + * + * \param kc HMAC key context. + * \return the hash function implementation. + */ +static inline const br_hash_class *br_hmac_key_get_digest( + const br_hmac_key_context *kc) +{ + return kc->dig_vtable; +} + +/** + * \brief HMAC computation context. + * + * The HMAC computation context maintains the state for a single HMAC + * computation. It is modified as input bytes are injected. The context + * is caller-allocated and has no release function since it does not + * dynamically allocate external resources. Its contents are opaque. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + br_hash_compat_context dig; + unsigned char kso[64]; + size_t out_len; +#endif +} br_hmac_context; + +/** + * \brief HMAC computation initialisation. + * + * Initialise a HMAC context with a key context. The key context is + * unmodified. Relevant data from the key context is immediately copied; + * the key context can thus be independently reused, modified or released + * without impacting this HMAC computation. + * + * An explicit output length can be specified; the actual output length + * will be the minimum of that value and the natural HMAC output length. + * If `out_len` is 0, then the natural HMAC output length is selected. The + * "natural output length" is the output length of the underlying hash + * function. + * + * \param ctx HMAC context to initialise. + * \param kc HMAC key context (already initialised with the key). + * \param out_len HMAC output length (0 to select "natural length"). + */ +void br_hmac_init(br_hmac_context *ctx, + const br_hmac_key_context *kc, size_t out_len); + +/** + * \brief Get the HMAC output size. + * + * The HMAC output size is the number of bytes that will actually be + * produced with `br_hmac_out()` with the provided context. This function + * MUST NOT be called on a non-initialised HMAC computation context. + * The returned value is the minimum of the HMAC natural length (output + * size of the underlying hash function) and the `out_len` parameter which + * was used with the last `br_hmac_init()` call on that context (if the + * initialisation `out_len` parameter was 0, then this function will + * return the HMAC natural length). + * + * \param ctx the (already initialised) HMAC computation context. + * \return the HMAC actual output size. + */ +static inline size_t +br_hmac_size(br_hmac_context *ctx) +{ + return ctx->out_len; +} + +/* + * \brief Get the underlying hash function. + * + * This function returns a pointer to the implementation vtable of the + * hash function used for this HMAC context. + * + * \param hc HMAC context. + * \return the hash function implementation. + */ +static inline const br_hash_class *br_hmac_get_digest( + const br_hmac_context *hc) +{ + return hc->dig.vtable; +} + +/** + * \brief Inject some bytes in HMAC. + * + * The provided `len` bytes are injected as extra input in the HMAC + * computation incarnated by the `ctx` HMAC context. It is acceptable + * that `len` is zero, in which case `data` is ignored (and may be + * `NULL`) and this function does nothing. + */ +void br_hmac_update(br_hmac_context *ctx, const void *data, size_t len); + +/** + * \brief Compute the HMAC output. + * + * The destination buffer MUST be large enough to accommodate the result; + * its length is at most the "natural length" of HMAC (i.e. the output + * length of the underlying hash function). The context is NOT modified; + * further bytes may be processed. Thus, "partial HMAC" values can be + * efficiently obtained. + * + * Returned value is the output length (in bytes). + * + * \param ctx HMAC computation context. + * \param out destination buffer for the HMAC output. + * \return the produced value length (in bytes). + */ +size_t br_hmac_out(const br_hmac_context *ctx, void *out); + +/** + * \brief Constant-time HMAC computation. + * + * This function compute the HMAC output in constant time. Some extra + * input bytes are processed, then the output is computed. The extra + * input consists in the `len` bytes pointed to by `data`. The `len` + * parameter must lie between `min_len` and `max_len` (inclusive); + * `max_len` bytes are actually read from `data`. Computing time (and + * memory access pattern) will not depend upon the data byte contents or + * the value of `len`. + * + * The output is written in the `out` buffer, that MUST be large enough + * to receive it. + * + * The difference `max_len - min_len` MUST be less than 230 + * (i.e. about one gigabyte). + * + * This function computes the output properly only if the underlying + * hash function uses MD padding (i.e. MD5, SHA-1, SHA-224, SHA-256, + * SHA-384 or SHA-512). + * + * The provided context is NOT modified. + * + * \param ctx the (already initialised) HMAC computation context. + * \param data the extra input bytes. + * \param len the extra input length (in bytes). + * \param min_len minimum extra input length (in bytes). + * \param max_len maximum extra input length (in bytes). + * \param out destination buffer for the HMAC output. + * \return the produced value length (in bytes). + */ +size_t br_hmac_outCT(const br_hmac_context *ctx, + const void *data, size_t len, size_t min_len, size_t max_len, + void *out); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_kdf.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_kdf.h new file mode 100644 index 000000000000..f0968320f2ff --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_kdf.h @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2018 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_KDF_H__ +#define BR_BEARSSL_KDF_H__ + +#include +#include + +#include "bearssl_hash.h" +#include "bearssl_hmac.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_kdf.h + * + * # Key Derivation Functions + * + * KDF are functions that takes a variable length input, and provide a + * variable length output, meant to be used to derive subkeys from a + * master key. + * + * ## HKDF + * + * HKDF is a KDF defined by [RFC 5869](https://tools.ietf.org/html/rfc5869). + * It is based on HMAC, itself using an underlying hash function. Any + * hash function can be used, as long as it is compatible with the rules + * for the HMAC implementation (i.e. output size is 64 bytes or less, hash + * internal state size is 64 bytes or less, and the internal block length is + * a power of 2 between 16 and 256 bytes). HKDF has two phases: + * + * - HKDF-Extract: the input data in ingested, along with a "salt" value. + * + * - HKDF-Expand: the output is produced, from the result of processing + * the input and salt, and using an extra non-secret parameter called + * "info". + * + * The "salt" and "info" strings are non-secret and can be empty. Their role + * is normally to bind the input and output, respectively, to conventional + * identifiers that qualifu them within the used protocol or application. + * + * The implementation defined in this file uses the following functions: + * + * - `br_hkdf_init()`: initialize an HKDF context, with a hash function, + * and the salt. This starts the HKDF-Extract process. + * + * - `br_hkdf_inject()`: inject more input bytes. This function may be + * called repeatedly if the input data is provided by chunks. + * + * - `br_hkdf_flip()`: end the HKDF-Extract process, and start the + * HKDF-Expand process. + * + * - `br_hkdf_produce()`: get the next bytes of output. This function + * may be called several times to obtain the full output by chunks. + * For correct HKDF processing, the same "info" string must be + * provided for each call. + * + * Note that the HKDF total output size (the number of bytes that + * HKDF-Expand is willing to produce) is limited: if the hash output size + * is _n_ bytes, then the maximum output size is _255*n_. + * + * ## SHAKE + * + * SHAKE is defined in + * [FIPS 202](https://csrc.nist.gov/publications/detail/fips/202/final) + * under two versions: SHAKE128 and SHAKE256, offering an alleged + * "security level" of 128 and 256 bits, respectively (SHAKE128 is + * about 20 to 25% faster than SHAKE256). SHAKE internally relies on + * the Keccak family of sponge functions, not on any externally provided + * hash function. Contrary to HKDF, SHAKE does not have a concept of + * either a "salt" or an "info" string. The API consists in four + * functions: + * + * - `br_shake_init()`: initialize a SHAKE context for a given + * security level. + * + * - `br_shake_inject()`: inject more input bytes. This function may be + * called repeatedly if the input data is provided by chunks. + * + * - `br_shake_flip()`: end the data injection process, and start the + * data production process. + * + * - `br_shake_produce()`: get the next bytes of output. This function + * may be called several times to obtain the full output by chunks. + */ + +/** + * \brief HKDF context. + * + * The HKDF context is initialized with a hash function implementation + * and a salt value. Contents are opaque (callers should not access them + * directly). The caller is responsible for allocating the context where + * appropriate. Context initialisation and usage incurs no dynamic + * allocation, so there is no release function. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + union { + br_hmac_context hmac_ctx; + br_hmac_key_context prk_ctx; + } u; + unsigned char buf[64]; + size_t ptr; + size_t dig_len; + unsigned chunk_num; +#endif +} br_hkdf_context; + +/** + * \brief HKDF context initialization. + * + * The underlying hash function and salt value are provided. Arbitrary + * salt lengths can be used. + * + * HKDF makes a difference between a salt of length zero, and an + * absent salt (the latter being equivalent to a salt consisting of + * bytes of value zero, of the same length as the hash function output). + * If `salt_len` is zero, then this function assumes that the salt is + * present but of length zero. To specify an _absent_ salt, use + * `BR_HKDF_NO_SALT` as `salt` parameter (`salt_len` is then ignored). + * + * \param hc HKDF context to initialise. + * \param digest_vtable pointer to the hash function implementation vtable. + * \param salt HKDF-Extract salt. + * \param salt_len HKDF-Extract salt length (in bytes). + */ +void br_hkdf_init(br_hkdf_context *hc, const br_hash_class *digest_vtable, + const void *salt, size_t salt_len); + +/** + * \brief The special "absent salt" value for HKDF. + */ +#define BR_HKDF_NO_SALT (&br_hkdf_no_salt) + +#ifndef BR_DOXYGEN_IGNORE +extern const unsigned char br_hkdf_no_salt; +#endif + +/** + * \brief HKDF input injection (HKDF-Extract). + * + * This function injects some more input bytes ("key material") into + * HKDF. This function may be called several times, after `br_hkdf_init()` + * but before `br_hkdf_flip()`. + * + * \param hc HKDF context. + * \param ikm extra input bytes. + * \param ikm_len number of extra input bytes. + */ +void br_hkdf_inject(br_hkdf_context *hc, const void *ikm, size_t ikm_len); + +/** + * \brief HKDF switch to the HKDF-Expand phase. + * + * This call terminates the HKDF-Extract process (input injection), and + * starts the HKDF-Expand process (output production). + * + * \param hc HKDF context. + */ +void br_hkdf_flip(br_hkdf_context *hc); + +/** + * \brief HKDF output production (HKDF-Expand). + * + * Produce more output bytes from the current state. This function may be + * called several times, but only after `br_hkdf_flip()`. + * + * Returned value is the number of actually produced bytes. The total + * output length is limited to 255 times the output length of the + * underlying hash function. + * + * \param hc HKDF context. + * \param info application specific information string. + * \param info_len application specific information string length (in bytes). + * \param out destination buffer for the HKDF output. + * \param out_len the length of the requested output (in bytes). + * \return the produced output length (in bytes). + */ +size_t br_hkdf_produce(br_hkdf_context *hc, + const void *info, size_t info_len, void *out, size_t out_len); + +/** + * \brief SHAKE context. + * + * The HKDF context is initialized with a "security level". The internal + * notion is called "capacity"; the capacity is twice the security level + * (for instance, SHAKE128 has capacity 256). + * + * The caller is responsible for allocating the context where + * appropriate. Context initialisation and usage incurs no dynamic + * allocation, so there is no release function. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + unsigned char dbuf[200]; + size_t dptr; + size_t rate; + uint64_t A[25]; +#endif +} br_shake_context; + +/** + * \brief SHAKE context initialization. + * + * The context is initialized for the provided "security level". + * Internally, this sets the "capacity" to twice the security level; + * thus, for SHAKE128, the `security_level` parameter should be 128, + * which corresponds to a 256-bit capacity. + * + * Allowed security levels are all multiples of 32, from 32 to 768, + * inclusive. Larger security levels imply lower performance; levels + * beyond 256 bits don't make much sense. Standard levels are 128 + * and 256 bits (for SHAKE128 and SHAKE256, respectively). + * + * \param sc SHAKE context to initialise. + * \param security_level security level (in bits). + */ +void br_shake_init(br_shake_context *sc, int security_level); + +/** + * \brief SHAKE input injection. + * + * This function injects some more input bytes ("key material") into + * SHAKE. This function may be called several times, after `br_shake_init()` + * but before `br_shake_flip()`. + * + * \param sc SHAKE context. + * \param data extra input bytes. + * \param len number of extra input bytes. + */ +void br_shake_inject(br_shake_context *sc, const void *data, size_t len); + +/** + * \brief SHAKE switch to production phase. + * + * This call terminates the input injection process, and starts the + * output production process. + * + * \param sc SHAKE context. + */ +void br_shake_flip(br_shake_context *hc); + +/** + * \brief SHAKE output production. + * + * Produce more output bytes from the current state. This function may be + * called several times, but only after `br_shake_flip()`. + * + * There is no practical limit to the number of bytes that may be produced. + * + * \param sc SHAKE context. + * \param out destination buffer for the SHAKE output. + * \param len the length of the requested output (in bytes). + */ +void br_shake_produce(br_shake_context *sc, void *out, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_pem.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_pem.h new file mode 100644 index 000000000000..13b3b4b3940f --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_pem.h @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_PEM_H__ +#define BR_BEARSSL_PEM_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_pem.h + * + * # PEM Support + * + * PEM is a traditional encoding layer use to store binary objects (in + * particular X.509 certificates, and private keys) in text files. While + * the acronym comes from an old, defunct standard ("Privacy Enhanced + * Mail"), the format has been reused, with some variations, by many + * systems, and is a _de facto_ standard, even though it is not, actually, + * specified in all clarity anywhere. + * + * ## Format Details + * + * BearSSL contains a generic, streamed PEM decoder, which handles the + * following format: + * + * - The input source (a sequence of bytes) is assumed to be the + * encoding of a text file in an ASCII-compatible charset. This + * includes ISO-8859-1, Windows-1252, and UTF-8 encodings. Each + * line ends on a newline character (U+000A LINE FEED). The + * U+000D CARRIAGE RETURN characters are ignored, so the code + * accepts both Windows-style and Unix-style line endings. + * + * - Each object begins with a banner that occurs at the start of + * a line; the first banner characters are "`-----BEGIN `" (five + * dashes, the word "BEGIN", and a space). The banner matching is + * not case-sensitive. + * + * - The _object name_ consists in the characters that follow the + * banner start sequence, up to the end of the line, but without + * trailing dashes (in "normal" PEM, there are five trailing + * dashes, but this implementation is not picky about these dashes). + * The BearSSL decoder normalises the name characters to uppercase + * (for ASCII letters only) and accepts names up to 127 characters. + * + * - The object ends with a banner that again occurs at the start of + * a line, and starts with "`-----END `" (again case-insensitive). + * + * - Between that start and end banner, only Base64 data shall occur. + * Base64 converts each sequence of three bytes into four + * characters; the four characters are ASCII letters, digits, "`+`" + * or "`-`" signs, and one or two "`=`" signs may occur in the last + * quartet. Whitespace is ignored (whitespace is any ASCII character + * of code 32 or less, so control characters are whitespace) and + * lines may have arbitrary length; the only restriction is that the + * four characters of a quartet must appear on the same line (no + * line break inside a quartet). + * + * - A single file may contain more than one PEM object. Bytes that + * occur between objects are ignored. + * + * + * ## PEM Decoder API + * + * The PEM decoder offers a state-machine API. The caller allocates a + * decoder context, then injects source bytes. Source bytes are pushed + * with `br_pem_decoder_push()`. The decoder stops accepting bytes when + * it reaches an "event", which is either the start of an object, the + * end of an object, or a decoding error within an object. + * + * The `br_pem_decoder_event()` function is used to obtain the current + * event; it also clears it, thus allowing the decoder to accept more + * bytes. When a object start event is raised, the decoder context + * offers the found object name (normalised to ASCII uppercase). + * + * When an object is reached, the caller must set an appropriate callback + * function, which will receive (by chunks) the decoded object data. + * + * Since the decoder context makes no dynamic allocation, it requires + * no explicit deallocation. + */ + +/** + * \brief PEM decoder context. + * + * Contents are opaque (they should not be accessed directly). + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + /* CPU for the T0 virtual machine. */ + struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; + } cpu; + uint32_t dp_stack[32]; + uint32_t rp_stack[32]; + int err; + + const unsigned char *hbuf; + size_t hlen; + + void (*dest)(void *dest_ctx, const void *src, size_t len); + void *dest_ctx; + + unsigned char event; + char name[128]; + unsigned char buf[255]; + size_t ptr; +#endif +} br_pem_decoder_context; + +/** + * \brief Initialise a PEM decoder structure. + * + * \param ctx decoder context to initialise. + */ +void br_pem_decoder_init(br_pem_decoder_context *ctx); + +/** + * \brief Push some bytes into the decoder. + * + * Returned value is the number of bytes actually consumed; this may be + * less than the number of provided bytes if an event is raised. When an + * event is raised, it must be read (with `br_pem_decoder_event()`); + * until the event is read, this function will return 0. + * + * \param ctx decoder context. + * \param data new data bytes. + * \param len number of new data bytes. + * \return the number of bytes actually received (may be less than `len`). + */ +size_t br_pem_decoder_push(br_pem_decoder_context *ctx, + const void *data, size_t len); + +/** + * \brief Set the receiver for decoded data. + * + * When an object is entered, the provided function (with opaque context + * pointer) will be called repeatedly with successive chunks of decoded + * data for that object. If `dest` is set to 0, then decoded data is + * simply ignored. The receiver can be set at any time, but, in practice, + * it should be called immediately after receiving a "start of object" + * event. + * + * \param ctx decoder context. + * \param dest callback for receiving decoded data. + * \param dest_ctx opaque context pointer for the `dest` callback. + */ +static inline void +br_pem_decoder_setdest(br_pem_decoder_context *ctx, + void (*dest)(void *dest_ctx, const void *src, size_t len), + void *dest_ctx) +{ + ctx->dest = dest; + ctx->dest_ctx = dest_ctx; +} + +/** + * \brief Get the last event. + * + * If an event was raised, then this function returns the event value, and + * also clears it, thereby allowing the decoder to proceed. If no event + * was raised since the last call to `br_pem_decoder_event()`, then this + * function returns 0. + * + * \param ctx decoder context. + * \return the raised event, or 0. + */ +int br_pem_decoder_event(br_pem_decoder_context *ctx); + +/** + * \brief Event: start of object. + * + * This event is raised when the start of a new object has been detected. + * The object name (normalised to uppercase) can be accessed with + * `br_pem_decoder_name()`. + */ +#define BR_PEM_BEGIN_OBJ 1 + +/** + * \brief Event: end of object. + * + * This event is raised when the end of the current object is reached + * (normally, i.e. with no decoding error). + */ +#define BR_PEM_END_OBJ 2 + +/** + * \brief Event: decoding error. + * + * This event is raised when decoding fails within an object. + * This formally closes the current object and brings the decoder back + * to the "out of any object" state. The offending line in the source + * is consumed. + */ +#define BR_PEM_ERROR 3 + +/** + * \brief Get the name of the encountered object. + * + * The encountered object name is defined only when the "start of object" + * event is raised. That name is normalised to uppercase (for ASCII letters + * only) and does not include trailing dashes. + * + * \param ctx decoder context. + * \return the current object name. + */ +static inline const char * +br_pem_decoder_name(br_pem_decoder_context *ctx) +{ + return ctx->name; +} + +/** + * \brief Encode an object in PEM. + * + * This function encodes the provided binary object (`data`, of length `len` + * bytes) into PEM. The `banner` text will be included in the header and + * footer (e.g. use `"CERTIFICATE"` to get a `"BEGIN CERTIFICATE"` header). + * + * The length (in characters) of the PEM output is returned; that length + * does NOT include the terminating zero, that this function nevertheless + * adds. If using the returned value for allocation purposes, the allocated + * buffer size MUST be at least one byte larger than the returned size. + * + * If `dest` is `NULL`, then the encoding does not happen; however, the + * length of the encoded object is still computed and returned. + * + * The `data` pointer may be `NULL` only if `len` is zero (when encoding + * an object of length zero, which is not very useful), or when `dest` + * is `NULL` (in that case, source data bytes are ignored). + * + * Some `flags` can be specified to alter the encoding behaviour: + * + * - If `BR_PEM_LINE64` is set, then line-breaking will occur after + * every 64 characters of output, instead of the default of 76. + * + * - If `BR_PEM_CRLF` is set, then end-of-line sequence will use + * CR+LF instead of a single LF. + * + * The `data` and `dest` buffers may overlap, in which case the source + * binary data is destroyed in the process. Note that the PEM-encoded output + * is always larger than the source binary. + * + * \param dest the destination buffer (or `NULL`). + * \param data the source buffer (can be `NULL` in some cases). + * \param len the source length (in bytes). + * \param banner the PEM banner expression. + * \param flags the behavioural flags. + * \return the PEM object length (in characters), EXCLUDING the final zero. + */ +size_t br_pem_encode(void *dest, const void *data, size_t len, + const char *banner, unsigned flags); + +/** + * \brief PEM encoding flag: split lines at 64 characters. + */ +#define BR_PEM_LINE64 0x0001 + +/** + * \brief PEM encoding flag: use CR+LF line endings. + */ +#define BR_PEM_CRLF 0x0002 + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_prf.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_prf.h new file mode 100644 index 000000000000..f611bf937f8e --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_prf.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_PRF_H__ +#define BR_BEARSSL_PRF_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_prf.h + * + * # The TLS PRF + * + * The "PRF" is the pseudorandom function used internally during the + * SSL/TLS handshake, notably to expand negotiated shared secrets into + * the symmetric encryption keys that will be used to process the + * application data. + * + * TLS 1.0 and 1.1 define a PRF that is based on both MD5 and SHA-1. This + * is implemented by the `br_tls10_prf()` function. + * + * TLS 1.2 redefines the PRF, using an explicit hash function. The + * `br_tls12_sha256_prf()` and `br_tls12_sha384_prf()` functions apply that + * PRF with, respectively, SHA-256 and SHA-384. Most standard cipher suites + * rely on the SHA-256 based PRF, but some use SHA-384. + * + * The PRF always uses as input three parameters: a "secret" (some + * bytes), a "label" (ASCII string), and a "seed" (again some bytes). An + * arbitrary output length can be produced. The "seed" is provided as an + * arbitrary number of binary chunks, that gets internally concatenated. + */ + +/** + * \brief Type for a seed chunk. + * + * Each chunk may have an arbitrary length, and may be empty (no byte at + * all). If the chunk length is zero, then the pointer to the chunk data + * may be `NULL`. + */ +typedef struct { + /** + * \brief Pointer to the chunk data. + */ + const void *data; + + /** + * \brief Chunk length (in bytes). + */ + size_t len; +} br_tls_prf_seed_chunk; + +/** + * \brief PRF implementation for TLS 1.0 and 1.1. + * + * This PRF is the one specified by TLS 1.0 and 1.1. It internally uses + * MD5 and SHA-1. + * + * \param dst destination buffer. + * \param len output length (in bytes). + * \param secret secret value (key) for this computation. + * \param secret_len length of "secret" (in bytes). + * \param label PRF label (zero-terminated ASCII string). + * \param seed_num number of seed chunks. + * \param seed seed chnks for this computation (usually non-secret). + */ +void br_tls10_prf(void *dst, size_t len, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed); + +/** + * \brief PRF implementation for TLS 1.2, with SHA-256. + * + * This PRF is the one specified by TLS 1.2, when the underlying hash + * function is SHA-256. + * + * \param dst destination buffer. + * \param len output length (in bytes). + * \param secret secret value (key) for this computation. + * \param secret_len length of "secret" (in bytes). + * \param label PRF label (zero-terminated ASCII string). + * \param seed_num number of seed chunks. + * \param seed seed chnks for this computation (usually non-secret). + */ +void br_tls12_sha256_prf(void *dst, size_t len, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed); + +/** + * \brief PRF implementation for TLS 1.2, with SHA-384. + * + * This PRF is the one specified by TLS 1.2, when the underlying hash + * function is SHA-384. + * + * \param dst destination buffer. + * \param len output length (in bytes). + * \param secret secret value (key) for this computation. + * \param secret_len length of "secret" (in bytes). + * \param label PRF label (zero-terminated ASCII string). + * \param seed_num number of seed chunks. + * \param seed seed chnks for this computation (usually non-secret). + */ +void br_tls12_sha384_prf(void *dst, size_t len, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed); + +/** + * brief A convenient type name for a PRF implementation. + * + * \param dst destination buffer. + * \param len output length (in bytes). + * \param secret secret value (key) for this computation. + * \param secret_len length of "secret" (in bytes). + * \param label PRF label (zero-terminated ASCII string). + * \param seed_num number of seed chunks. + * \param seed seed chnks for this computation (usually non-secret). + */ +typedef void (*br_tls_prf_impl)(void *dst, size_t len, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_rand.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_rand.h new file mode 100644 index 000000000000..82c590b51b64 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_rand.h @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_RAND_H__ +#define BR_BEARSSL_RAND_H__ + +#include +#include + +#include "bearssl_block.h" +#include "bearssl_hash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_rand.h + * + * # Pseudo-Random Generators + * + * A PRNG is a state-based engine that outputs pseudo-random bytes on + * demand. It is initialized with an initial seed, and additional seed + * bytes can be added afterwards. Bytes produced depend on the seeds and + * also on the exact sequence of calls (including sizes requested for + * each call). + * + * + * ## Procedural and OOP API + * + * For the PRNG of name "`xxx`", two API are provided. The _procedural_ + * API defined a context structure `br_xxx_context` and three functions: + * + * - `br_xxx_init()` + * + * Initialise the context with an initial seed. + * + * - `br_xxx_generate()` + * + * Produce some pseudo-random bytes. + * + * - `br_xxx_update()` + * + * Inject some additional seed. + * + * The initialisation function sets the first context field (`vtable`) + * to a pointer to the vtable that supports the OOP API. The OOP API + * provides access to the same functions through function pointers, + * named `init()`, `generate()` and `update()`. + * + * Note that the context initialisation method may accept additional + * parameters, provided as a 'const void *' pointer at API level. These + * additional parameters depend on the implemented PRNG. + * + * + * ## HMAC_DRBG + * + * HMAC_DRBG is defined in [NIST SP 800-90A Revision + * 1](http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf). + * It uses HMAC repeatedly, over some configurable underlying hash + * function. In BearSSL, it is implemented under the "`hmac_drbg`" name. + * The "extra parameters" pointer for context initialisation should be + * set to a pointer to the vtable for the underlying hash function (e.g. + * pointer to `br_sha256_vtable` to use HMAC_DRBG with SHA-256). + * + * According to the NIST standard, each request shall produce up to + * 219 bits (i.e. 64 kB of data); moreover, the context shall + * be reseeded at least once every 248 requests. This + * implementation does not maintain the reseed counter (the threshold is + * too high to be reached in practice) and does not object to producing + * more than 64 kB in a single request; thus, the code cannot fail, + * which corresponds to the fact that the API has no room for error + * codes. However, this implies that requesting more than 64 kB in one + * `generate()` request, or making more than 248 requests + * without reseeding, is formally out of NIST specification. There is + * no currently known security penalty for exceeding the NIST limits, + * and, in any case, HMAC_DRBG usage in implementing SSL/TLS always + * stays much below these thresholds. + * + * + * ## AESCTR_DRBG + * + * AESCTR_DRBG is a custom PRNG based on AES-128 in CTR mode. This is + * meant to be used only in situations where you are desperate for + * speed, and have an hardware-optimized AES/CTR implementation. Whether + * this will yield perceptible improvements depends on what you use the + * pseudorandom bytes for, and how many you want; for instance, RSA key + * pair generation uses a substantial amount of randomness, and using + * AESCTR_DRBG instead of HMAC_DRBG yields a 15 to 20% increase in key + * generation speed on a recent x86 CPU (Intel Core i7-6567U at 3.30 GHz). + * + * Internally, it uses CTR mode with successive counter values, starting + * at zero (counter value expressed over 128 bits, big-endian convention). + * The counter is not allowed to reach 32768; thus, every 32768*16 bytes + * at most, the `update()` function is run (on an empty seed, if none is + * provided). The `update()` function computes the new AES-128 key by + * applying a custom hash function to the concatenation of a state-dependent + * word (encryption of an all-one block with the current key) and the new + * seed. The custom hash function uses Hirose's construction over AES-256; + * see the comments in `aesctr_drbg.c` for details. + * + * This DRBG does not follow an existing standard, and thus should be + * considered as inadequate for production use until it has been properly + * analysed. + */ + +/** + * \brief Class type for PRNG implementations. + * + * A `br_prng_class` instance references the methods implementing a PRNG. + * Constant instances of this structure are defined for each implemented + * PRNG. Such instances are also called "vtables". + */ +typedef struct br_prng_class_ br_prng_class; +struct br_prng_class_ { + /** + * \brief Size (in bytes) of the context structure appropriate for + * running this PRNG. + */ + size_t context_size; + + /** + * \brief Initialisation method. + * + * The context to initialise is provided as a pointer to its + * first field (the vtable pointer); this function sets that + * first field to a pointer to the vtable. + * + * The extra parameters depend on the implementation; each + * implementation defines what kind of extra parameters it + * expects (if any). + * + * Requirements on the initial seed depend on the implemented + * PRNG. + * + * \param ctx PRNG context to initialise. + * \param params extra parameters for the PRNG. + * \param seed initial seed. + * \param seed_len initial seed length (in bytes). + */ + void (*init)(const br_prng_class **ctx, const void *params, + const void *seed, size_t seed_len); + + /** + * \brief Random bytes generation. + * + * This method produces `len` pseudorandom bytes, in the `out` + * buffer. The context is updated accordingly. + * + * \param ctx PRNG context. + * \param out output buffer. + * \param len number of pseudorandom bytes to produce. + */ + void (*generate)(const br_prng_class **ctx, void *out, size_t len); + + /** + * \brief Inject additional seed bytes. + * + * The provided seed bytes are added into the PRNG internal + * entropy pool. + * + * \param ctx PRNG context. + * \param seed additional seed. + * \param seed_len additional seed length (in bytes). + */ + void (*update)(const br_prng_class **ctx, + const void *seed, size_t seed_len); +}; + +/** + * \brief Context for HMAC_DRBG. + * + * The context contents are opaque, except the first field, which + * supports OOP. + */ +typedef struct { + /** + * \brief Pointer to the vtable. + * + * This field is set with the initialisation method/function. + */ + const br_prng_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char K[64]; + unsigned char V[64]; + const br_hash_class *digest_class; +#endif +} br_hmac_drbg_context; + +/** + * \brief Statically allocated, constant vtable for HMAC_DRBG. + */ +extern const br_prng_class br_hmac_drbg_vtable; + +/** + * \brief HMAC_DRBG initialisation. + * + * The context to initialise is provided as a pointer to its first field + * (the vtable pointer); this function sets that first field to a + * pointer to the vtable. + * + * The `seed` value is what is called, in NIST terminology, the + * concatenation of the "seed", "nonce" and "personalization string", in + * that order. + * + * The `digest_class` parameter defines the underlying hash function. + * Formally, the NIST standard specifies that the hash function shall + * be only SHA-1 or one of the SHA-2 functions. This implementation also + * works with any other implemented hash function (such as MD5), but + * this is non-standard and therefore not recommended. + * + * \param ctx HMAC_DRBG context to initialise. + * \param digest_class vtable for the underlying hash function. + * \param seed initial seed. + * \param seed_len initial seed length (in bytes). + */ +void br_hmac_drbg_init(br_hmac_drbg_context *ctx, + const br_hash_class *digest_class, const void *seed, size_t seed_len); + +/** + * \brief Random bytes generation with HMAC_DRBG. + * + * This method produces `len` pseudorandom bytes, in the `out` + * buffer. The context is updated accordingly. Formally, requesting + * more than 65536 bytes in one request falls out of specification + * limits (but it won't fail). + * + * \param ctx HMAC_DRBG context. + * \param out output buffer. + * \param len number of pseudorandom bytes to produce. + */ +void br_hmac_drbg_generate(br_hmac_drbg_context *ctx, void *out, size_t len); + +/** + * \brief Inject additional seed bytes in HMAC_DRBG. + * + * The provided seed bytes are added into the HMAC_DRBG internal + * entropy pool. The process does not _replace_ existing entropy, + * thus pushing non-random bytes (i.e. bytes which are known to the + * attackers) does not degrade the overall quality of generated bytes. + * + * \param ctx HMAC_DRBG context. + * \param seed additional seed. + * \param seed_len additional seed length (in bytes). + */ +void br_hmac_drbg_update(br_hmac_drbg_context *ctx, + const void *seed, size_t seed_len); + +/** + * \brief Get the hash function implementation used by a given instance of + * HMAC_DRBG. + * + * This calls MUST NOT be performed on a context which was not + * previously initialised. + * + * \param ctx HMAC_DRBG context. + * \return the hash function vtable. + */ +static inline const br_hash_class * +br_hmac_drbg_get_hash(const br_hmac_drbg_context *ctx) +{ + return ctx->digest_class; +} + +/** + * \brief Type for a provider of entropy seeds. + * + * A "seeder" is a function that is able to obtain random values from + * some source and inject them as entropy seed in a PRNG. A seeder + * shall guarantee that the total entropy of the injected seed is large + * enough to seed a PRNG for purposes of cryptographic key generation + * (i.e. at least 128 bits). + * + * A seeder may report a failure to obtain adequate entropy. Seeders + * shall endeavour to fix themselves transient errors by trying again; + * thus, callers may consider reported errors as permanent. + * + * \param ctx PRNG context to seed. + * \return 1 on success, 0 on error. + */ +typedef int (*br_prng_seeder)(const br_prng_class **ctx); + +/** + * \brief Get a seeder backed by the operating system or hardware. + * + * Get a seeder that feeds on RNG facilities provided by the current + * operating system or hardware. If no such facility is known, then 0 + * is returned. + * + * If `name` is not `NULL`, then `*name` is set to a symbolic string + * that identifies the seeder implementation. If no seeder is returned + * and `name` is not `NULL`, then `*name` is set to a pointer to the + * constant string `"none"`. + * + * \param name receiver for seeder name, or `NULL`. + * \return the system seeder, if available, or 0. + */ +br_prng_seeder br_prng_seeder_system(const char **name); + +/** + * \brief Context for AESCTR_DRBG. + * + * The context contents are opaque, except the first field, which + * supports OOP. + */ +typedef struct { + /** + * \brief Pointer to the vtable. + * + * This field is set with the initialisation method/function. + */ + const br_prng_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + br_aes_gen_ctr_keys sk; + uint32_t cc; +#endif +} br_aesctr_drbg_context; + +/** + * \brief Statically allocated, constant vtable for AESCTR_DRBG. + */ +extern const br_prng_class br_aesctr_drbg_vtable; + +/** + * \brief AESCTR_DRBG initialisation. + * + * The context to initialise is provided as a pointer to its first field + * (the vtable pointer); this function sets that first field to a + * pointer to the vtable. + * + * The internal AES key is first set to the all-zero key; then, the + * `br_aesctr_drbg_update()` function is called with the provided `seed`. + * The call is performed even if the seed length (`seed_len`) is zero. + * + * The `aesctr` parameter defines the underlying AES/CTR implementation. + * + * \param ctx AESCTR_DRBG context to initialise. + * \param aesctr vtable for the AES/CTR implementation. + * \param seed initial seed (can be `NULL` if `seed_len` is zero). + * \param seed_len initial seed length (in bytes). + */ +void br_aesctr_drbg_init(br_aesctr_drbg_context *ctx, + const br_block_ctr_class *aesctr, const void *seed, size_t seed_len); + +/** + * \brief Random bytes generation with AESCTR_DRBG. + * + * This method produces `len` pseudorandom bytes, in the `out` + * buffer. The context is updated accordingly. + * + * \param ctx AESCTR_DRBG context. + * \param out output buffer. + * \param len number of pseudorandom bytes to produce. + */ +void br_aesctr_drbg_generate(br_aesctr_drbg_context *ctx, + void *out, size_t len); + +/** + * \brief Inject additional seed bytes in AESCTR_DRBG. + * + * The provided seed bytes are added into the AESCTR_DRBG internal + * entropy pool. The process does not _replace_ existing entropy, + * thus pushing non-random bytes (i.e. bytes which are known to the + * attackers) does not degrade the overall quality of generated bytes. + * + * \param ctx AESCTR_DRBG context. + * \param seed additional seed. + * \param seed_len additional seed length (in bytes). + */ +void br_aesctr_drbg_update(br_aesctr_drbg_context *ctx, + const void *seed, size_t seed_len); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_rsa.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_rsa.h new file mode 100644 index 000000000000..18e953bb1627 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_rsa.h @@ -0,0 +1,1660 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_RSA_H__ +#define BR_BEARSSL_RSA_H__ + +#include +#include + +#include "bearssl_hash.h" +#include "bearssl_rand.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_rsa.h + * + * # RSA + * + * This file documents the RSA implementations provided with BearSSL. + * Note that the SSL engine accesses these implementations through a + * configurable API, so it is possible to, for instance, run a SSL + * server which uses a RSA engine which is not based on this code. + * + * ## Key Elements + * + * RSA public and private keys consist in lists of big integers. All + * such integers are represented with big-endian unsigned notation: + * first byte is the most significant, and the value is positive (so + * there is no dedicated "sign bit"). Public and private key structures + * thus contain, for each such integer, a pointer to the first value byte + * (`unsigned char *`), and a length (`size_t`) which is the number of + * relevant bytes. As a general rule, minimal-length encoding is not + * enforced: values may have extra leading bytes of value 0. + * + * RSA public keys consist in two integers: + * + * - the modulus (`n`); + * - the public exponent (`e`). + * + * RSA private keys, as defined in + * [PKCS#1](https://tools.ietf.org/html/rfc3447), contain eight integers: + * + * - the modulus (`n`); + * - the public exponent (`e`); + * - the private exponent (`d`); + * - the first prime factor (`p`); + * - the second prime factor (`q`); + * - the first reduced exponent (`dp`, which is `d` modulo `p-1`); + * - the second reduced exponent (`dq`, which is `d` modulo `q-1`); + * - the CRT coefficient (`iq`, the inverse of `q` modulo `p`). + * + * However, the implementations defined in BearSSL use only five of + * these integers: `p`, `q`, `dp`, `dq` and `iq`. + * + * ## Security Features and Limitations + * + * The implementations contained in BearSSL have the following limitations + * and features: + * + * - They are constant-time. This means that the execution time and + * memory access pattern may depend on the _lengths_ of the private + * key components, but not on their value, nor on the value of + * the operand. Note that this property is not achieved through + * random masking, but "true" constant-time code. + * + * - They support only private keys with two prime factors. RSA private + * keys with three or more prime factors are nominally supported, but + * rarely used; they may offer faster operations, at the expense of + * more code and potentially a reduction in security if there are + * "too many" prime factors. + * + * - The public exponent may have arbitrary length. Of course, it is + * a good idea to keep public exponents small, so that public key + * operations are fast; but, contrary to some widely deployed + * implementations, BearSSL has no problem with public exponents + * longer than 32 bits. + * + * - The two prime factors of the modulus need not have the same length + * (but severely imbalanced factor lengths might reduce security). + * Similarly, there is no requirement that the first factor (`p`) + * be greater than the second factor (`q`). + * + * - Prime factors and modulus must be smaller than a compile-time limit. + * This is made necessary by the use of fixed-size stack buffers, and + * the limit has been adjusted to keep stack usage under 2 kB for the + * RSA operations. Currently, the maximum modulus size is 4096 bits, + * and the maximum prime factor size is 2080 bits. + * + * - The RSA functions themselves do not enforce lower size limits, + * except that which is absolutely necessary for the operation to + * mathematically make sense (e.g. a PKCS#1 v1.5 signature with + * SHA-1 requires a modulus of at least 361 bits). It is up to users + * of this code to enforce size limitations when appropriate (e.g. + * the X.509 validation engine, by default, rejects RSA keys of + * less than 1017 bits). + * + * - Within the size constraints expressed above, arbitrary bit lengths + * are supported. There is no requirement that prime factors or + * modulus have a size multiple of 8 or 16. + * + * - When verifying PKCS#1 v1.5 signatures, both variants of the hash + * function identifying header (with and without the ASN.1 NULL) are + * supported. When producing such signatures, the variant with the + * ASN.1 NULL is used. + * + * ## Implementations + * + * Three RSA implementations are included: + * + * - The **i32** implementation internally represents big integers + * as arrays of 32-bit integers. It is perfunctory and portable, + * but not very efficient. + * + * - The **i31** implementation uses 32-bit integers, each containing + * 31 bits worth of integer data. The i31 implementation is somewhat + * faster than the i32 implementation (the reduced integer size makes + * carry propagation easier) for a similar code footprint, but uses + * very slightly larger stack buffers (about 4% bigger). + * + * - The **i62** implementation is similar to the i31 implementation, + * except that it internally leverages the 64x64->128 multiplication + * opcode. This implementation is available only on architectures + * where such an opcode exists. It is much faster than i31. + * + * - The **i15** implementation uses 16-bit integers, each containing + * 15 bits worth of integer data. Multiplication results fit on + * 32 bits, so this won't use the "widening" multiplication routine + * on ARM Cortex M0/M0+, for much better performance and constant-time + * execution. + */ + +/** + * \brief RSA public key. + * + * The structure references the modulus and the public exponent. Both + * integers use unsigned big-endian representation; extra leading bytes + * of value 0 are allowed. + */ +typedef struct { + /** \brief Modulus. */ + unsigned char *n; + /** \brief Modulus length (in bytes). */ + size_t nlen; + /** \brief Public exponent. */ + unsigned char *e; + /** \brief Public exponent length (in bytes). */ + size_t elen; +} br_rsa_public_key; + +/** + * \brief RSA private key. + * + * The structure references the private factors, reduced private + * exponents, and CRT coefficient. It also contains the bit length of + * the modulus. The big integers use unsigned big-endian representation; + * extra leading bytes of value 0 are allowed. However, the modulus bit + * length (`n_bitlen`) MUST be exact. + */ +typedef struct { + /** \brief Modulus bit length (in bits, exact value). */ + uint32_t n_bitlen; + /** \brief First prime factor. */ + unsigned char *p; + /** \brief First prime factor length (in bytes). */ + size_t plen; + /** \brief Second prime factor. */ + unsigned char *q; + /** \brief Second prime factor length (in bytes). */ + size_t qlen; + /** \brief First reduced private exponent. */ + unsigned char *dp; + /** \brief First reduced private exponent length (in bytes). */ + size_t dplen; + /** \brief Second reduced private exponent. */ + unsigned char *dq; + /** \brief Second reduced private exponent length (in bytes). */ + size_t dqlen; + /** \brief CRT coefficient. */ + unsigned char *iq; + /** \brief CRT coefficient length (in bytes). */ + size_t iqlen; +} br_rsa_private_key; + +/** + * \brief Type for a RSA public key engine. + * + * The public key engine performs the modular exponentiation of the + * provided value with the public exponent. The value is modified in + * place. + * + * The value length (`xlen`) is verified to have _exactly_ the same + * length as the modulus (actual modulus length, without extra leading + * zeros in the modulus representation in memory). If the length does + * not match, then this function returns 0 and `x[]` is unmodified. + * + * It `xlen` is correct, then `x[]` is modified. Returned value is 1 + * on success, 0 on error. Error conditions include an oversized `x[]` + * (the array has the same length as the modulus, but the numerical value + * is not lower than the modulus) and an invalid modulus (e.g. an even + * integer). If an error is reported, then the new contents of `x[]` are + * unspecified. + * + * \param x operand to exponentiate. + * \param xlen length of the operand (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_public)(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk); + +/** + * \brief Type for a RSA signature verification engine (PKCS#1 v1.5). + * + * Parameters are: + * + * - The signature itself. The provided array is NOT modified. + * + * - The encoded OID for the hash function. The provided array must begin + * with a single byte that contains the length of the OID value (in + * bytes), followed by exactly that many bytes. This parameter may + * also be `NULL`, in which case the raw hash value should be used + * with the PKCS#1 v1.5 "type 1" padding (as used in SSL/TLS up + * to TLS-1.1, with a 36-byte hash value). + * + * - The hash output length, in bytes. + * + * - The public key. + * + * - An output buffer for the hash value. The caller must still compare + * it with the hash of the data over which the signature is computed. + * + * **Constraints:** + * + * - Hash length MUST be no more than 64 bytes. + * + * - OID value length MUST be no more than 32 bytes (i.e. `hash_oid[0]` + * must have a value in the 0..32 range, inclusive). + * + * This function verifies that the signature length (`xlen`) matches the + * modulus length (this function returns 0 on mismatch). If the modulus + * size exceeds the maximum supported RSA size, then the function also + * returns 0. + * + * Returned value is 1 on success, 0 on error. + * + * Implementations of this type need not be constant-time. + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash_len expected hash value length (in bytes). + * \param pk RSA public key. + * \param hash_out output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_pkcs1_vrfy)(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out); + +/** + * \brief Type for a RSA signature verification engine (PSS). + * + * Parameters are: + * + * - The signature itself. The provided array is NOT modified. + * + * - The hash function which was used to hash the message. + * + * - The hash function to use with MGF1 within the PSS padding. This + * is not necessarily the same hash function as the one which was + * used to hash the signed message. + * + * - The hashed message (as an array of bytes). + * + * - The PSS salt length (in bytes). + * + * - The public key. + * + * **Constraints:** + * + * - Hash message length MUST be no more than 64 bytes. + * + * Note that, contrary to PKCS#1 v1.5 signature, the hash value of the + * signed data cannot be extracted from the signature; it must be + * provided to the verification function. + * + * This function verifies that the signature length (`xlen`) matches the + * modulus length (this function returns 0 on mismatch). If the modulus + * size exceeds the maximum supported RSA size, then the function also + * returns 0. + * + * Returned value is 1 on success, 0 on error. + * + * Implementations of this type need not be constant-time. + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hf_data hash function applied on the message. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hash value of the signed message. + * \param salt_len PSS salt length (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_pss_vrfy)(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk); + +/** + * \brief Type for a RSA encryption engine (OAEP). + * + * Parameters are: + * + * - A source of random bytes. The source must be already initialized. + * + * - A hash function, used internally with the mask generation function + * (MGF1). + * + * - A label. The `label` pointer may be `NULL` if `label_len` is zero + * (an empty label, which is the default in PKCS#1 v2.2). + * + * - The public key. + * + * - The destination buffer. Its maximum length (in bytes) is provided; + * if that length is lower than the public key length, then an error + * is reported. + * + * - The source message. + * + * The encrypted message output has exactly the same length as the modulus + * (mathematical length, in bytes, not counting extra leading zeros in the + * modulus representation in the public key). + * + * The source message (`src`, length `src_len`) may overlap with the + * destination buffer (`dst`, length `dst_max_len`). + * + * This function returns the actual encrypted message length, in bytes; + * on error, zero is returned. An error is reported if the output buffer + * is not large enough, or the public is invalid, or the public key + * modulus exceeds the maximum supported RSA size. + * + * \param rnd source of random bytes. + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param pk RSA public key. + * \param dst destination buffer. + * \param dst_max_len destination buffer length (maximum encrypted data size). + * \param src message to encrypt. + * \param src_len source message length (in bytes). + * \return encrypted message length (in bytes), or 0 on error. + */ +typedef size_t (*br_rsa_oaep_encrypt)( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len); + +/** + * \brief Type for a RSA private key engine. + * + * The `x[]` buffer is modified in place, and its length is inferred from + * the modulus length (`x[]` is assumed to have a length of + * `(sk->n_bitlen+7)/8` bytes). + * + * Returned value is 1 on success, 0 on error. + * + * \param x operand to exponentiate. + * \param sk RSA private key. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_private)(unsigned char *x, + const br_rsa_private_key *sk); + +/** + * \brief Type for a RSA signature generation engine (PKCS#1 v1.5). + * + * Parameters are: + * + * - The encoded OID for the hash function. The provided array must begin + * with a single byte that contains the length of the OID value (in + * bytes), followed by exactly that many bytes. This parameter may + * also be `NULL`, in which case the raw hash value should be used + * with the PKCS#1 v1.5 "type 1" padding (as used in SSL/TLS up + * to TLS-1.1, with a 36-byte hash value). + * + * - The hash value computes over the data to sign (its length is + * expressed in bytes). + * + * - The RSA private key. + * + * - The output buffer, that receives the signature. + * + * Returned value is 1 on success, 0 on error. Error conditions include + * a too small modulus for the provided hash OID and value, or some + * invalid key parameters. The signature length is exactly + * `(sk->n_bitlen+7)/8` bytes. + * + * This function is expected to be constant-time with regards to the + * private key bytes (lengths of the modulus and the individual factors + * may leak, though) and to the hashed data. + * + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash hash value. + * \param hash_len hash value length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the signature value. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_pkcs1_sign)(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief Type for a RSA signature generation engine (PSS). + * + * Parameters are: + * + * - An initialized PRNG for salt generation. If the salt length is + * zero (`salt_len` parameter), then the PRNG is optional (this is + * not the typical case, as the security proof of RSA/PSS is + * tighter when a non-empty salt is used). + * + * - The hash function which was used to hash the message. + * + * - The hash function to use with MGF1 within the PSS padding. This + * is not necessarily the same function as the one used to hash the + * message. + * + * - The hashed message. + * + * - The salt length, in bytes. + * + * - The RSA private key. + * + * - The output buffer, that receives the signature. + * + * Returned value is 1 on success, 0 on error. Error conditions include + * a too small modulus for the provided hash and salt lengths, or some + * invalid key parameters. The signature length is exactly + * `(sk->n_bitlen+7)/8` bytes. + * + * This function is expected to be constant-time with regards to the + * private key bytes (lengths of the modulus and the individual factors + * may leak, though) and to the hashed data. + * + * \param rng PRNG for salt generation (`NULL` if `salt_len` is zero). + * \param hf_data hash function used to hash the signed data. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hashed message. + * \param salt_len salt length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the signature value. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_pss_sign)(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash_value, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief Encoded OID for SHA-1 (in RSA PKCS#1 signatures). + */ +#define BR_HASH_OID_SHA1 \ + ((const unsigned char *)"\x05\x2B\x0E\x03\x02\x1A") + +/** + * \brief Encoded OID for SHA-224 (in RSA PKCS#1 signatures). + */ +#define BR_HASH_OID_SHA224 \ + ((const unsigned char *)"\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04") + +/** + * \brief Encoded OID for SHA-256 (in RSA PKCS#1 signatures). + */ +#define BR_HASH_OID_SHA256 \ + ((const unsigned char *)"\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01") + +/** + * \brief Encoded OID for SHA-384 (in RSA PKCS#1 signatures). + */ +#define BR_HASH_OID_SHA384 \ + ((const unsigned char *)"\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02") + +/** + * \brief Encoded OID for SHA-512 (in RSA PKCS#1 signatures). + */ +#define BR_HASH_OID_SHA512 \ + ((const unsigned char *)"\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03") + +/** + * \brief Type for a RSA decryption engine (OAEP). + * + * Parameters are: + * + * - A hash function, used internally with the mask generation function + * (MGF1). + * + * - A label. The `label` pointer may be `NULL` if `label_len` is zero + * (an empty label, which is the default in PKCS#1 v2.2). + * + * - The private key. + * + * - The source and destination buffer. The buffer initially contains + * the encrypted message; the buffer contents are altered, and the + * decrypted message is written at the start of that buffer + * (decrypted message is always shorter than the encrypted message). + * + * If decryption fails in any way, then `*len` is unmodified, and the + * function returns 0. Otherwise, `*len` is set to the decrypted message + * length, and 1 is returned. The implementation is responsible for + * checking that the input message length matches the key modulus length, + * and that the padding is correct. + * + * Implementations MUST use constant-time check of the validity of the + * OAEP padding, at least until the leading byte and hash value have + * been checked. Whether overall decryption worked, and the length of + * the decrypted message, may leak. + * + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param sk RSA private key. + * \param data input/output buffer. + * \param len encrypted/decrypted message length. + * \return 1 on success, 0 on error. + */ +typedef uint32_t (*br_rsa_oaep_decrypt)( + const br_hash_class *dig, const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len); + +/* + * RSA "i32" engine. Integers are internally represented as arrays of + * 32-bit integers, and the core multiplication primitive is the + * 32x32->64 multiplication. + */ + +/** + * \brief RSA public key engine "i32". + * + * \see br_rsa_public + * + * \param x operand to exponentiate. + * \param xlen length of the operand (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_public(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk); + +/** + * \brief RSA signature verification engine "i32" (PKCS#1 v1.5 signatures). + * + * \see br_rsa_pkcs1_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash_len expected hash value length (in bytes). + * \param pk RSA public key. + * \param hash_out output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_pkcs1_vrfy(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out); + +/** + * \brief RSA signature verification engine "i32" (PSS signatures). + * + * \see br_rsa_pss_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hf_data hash function applied on the message. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hash value of the signed message. + * \param salt_len PSS salt length (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_pss_vrfy(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk); + +/** + * \brief RSA private key engine "i32". + * + * \see br_rsa_private + * + * \param x operand to exponentiate. + * \param sk RSA private key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_private(unsigned char *x, + const br_rsa_private_key *sk); + +/** + * \brief RSA signature generation engine "i32" (PKCS#1 v1.5 signatures). + * + * \see br_rsa_pkcs1_sign + * + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash hash value. + * \param hash_len hash value length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_pkcs1_sign(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief RSA signature generation engine "i32" (PSS signatures). + * + * \see br_rsa_pss_sign + * + * \param rng PRNG for salt generation (`NULL` if `salt_len` is zero). + * \param hf_data hash function used to hash the signed data. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hashed message. + * \param salt_len salt length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the signature value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_pss_sign(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash_value, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x); + +/* + * RSA "i31" engine. Similar to i32, but only 31 bits are used per 32-bit + * word. This uses slightly more stack space (about 4% more) and code + * space, but it quite faster. + */ + +/** + * \brief RSA public key engine "i31". + * + * \see br_rsa_public + * + * \param x operand to exponentiate. + * \param xlen length of the operand (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_public(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk); + +/** + * \brief RSA signature verification engine "i31" (PKCS#1 v1.5 signatures). + * + * \see br_rsa_pkcs1_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash_len expected hash value length (in bytes). + * \param pk RSA public key. + * \param hash_out output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_pkcs1_vrfy(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out); + +/** + * \brief RSA signature verification engine "i31" (PSS signatures). + * + * \see br_rsa_pss_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hf_data hash function applied on the message. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hash value of the signed message. + * \param salt_len PSS salt length (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_pss_vrfy(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk); + +/** + * \brief RSA private key engine "i31". + * + * \see br_rsa_private + * + * \param x operand to exponentiate. + * \param sk RSA private key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_private(unsigned char *x, + const br_rsa_private_key *sk); + +/** + * \brief RSA signature generation engine "i31" (PKCS#1 v1.5 signatures). + * + * \see br_rsa_pkcs1_sign + * + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash hash value. + * \param hash_len hash value length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_pkcs1_sign(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief RSA signature generation engine "i31" (PSS signatures). + * + * \see br_rsa_pss_sign + * + * \param rng PRNG for salt generation (`NULL` if `salt_len` is zero). + * \param hf_data hash function used to hash the signed data. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hashed message. + * \param salt_len salt length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the signature value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_pss_sign(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash_value, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x); + +/* + * RSA "i62" engine. Similar to i31, but internal multiplication use + * 64x64->128 multiplications. This is available only on architecture + * that offer such an opcode. + */ + +/** + * \brief RSA public key engine "i62". + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_public_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_public + * + * \param x operand to exponentiate. + * \param xlen length of the operand (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_public(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk); + +/** + * \brief RSA signature verification engine "i62" (PKCS#1 v1.5 signatures). + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_pkcs1_vrfy_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_pkcs1_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash_len expected hash value length (in bytes). + * \param pk RSA public key. + * \param hash_out output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_pkcs1_vrfy(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out); + +/** + * \brief RSA signature verification engine "i62" (PSS signatures). + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_pss_vrfy_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_pss_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hf_data hash function applied on the message. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hash value of the signed message. + * \param salt_len PSS salt length (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_pss_vrfy(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk); + +/** + * \brief RSA private key engine "i62". + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_private_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_private + * + * \param x operand to exponentiate. + * \param sk RSA private key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_private(unsigned char *x, + const br_rsa_private_key *sk); + +/** + * \brief RSA signature generation engine "i62" (PKCS#1 v1.5 signatures). + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_pkcs1_sign_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_pkcs1_sign + * + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash hash value. + * \param hash_len hash value length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_pkcs1_sign(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief RSA signature generation engine "i62" (PSS signatures). + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_pss_sign_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_pss_sign + * + * \param rng PRNG for salt generation (`NULL` if `salt_len` is zero). + * \param hf_data hash function used to hash the signed data. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hashed message. + * \param salt_len salt length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the signature value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_pss_sign(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash_value, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief Get the RSA "i62" implementation (public key operations), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_public br_rsa_i62_public_get(void); + +/** + * \brief Get the RSA "i62" implementation (PKCS#1 v1.5 signature verification), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_pkcs1_vrfy br_rsa_i62_pkcs1_vrfy_get(void); + +/** + * \brief Get the RSA "i62" implementation (PSS signature verification), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_pss_vrfy br_rsa_i62_pss_vrfy_get(void); + +/** + * \brief Get the RSA "i62" implementation (private key operations), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_private br_rsa_i62_private_get(void); + +/** + * \brief Get the RSA "i62" implementation (PKCS#1 v1.5 signature generation), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_pkcs1_sign br_rsa_i62_pkcs1_sign_get(void); + +/** + * \brief Get the RSA "i62" implementation (PSS signature generation), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_pss_sign br_rsa_i62_pss_sign_get(void); + +/** + * \brief Get the RSA "i62" implementation (OAEP encryption), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_oaep_encrypt br_rsa_i62_oaep_encrypt_get(void); + +/** + * \brief Get the RSA "i62" implementation (OAEP decryption), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_oaep_decrypt br_rsa_i62_oaep_decrypt_get(void); + +/* + * RSA "i15" engine. Integers are represented as 15-bit integers, so + * the code uses only 32-bit multiplication (no 64-bit result), which + * is vastly faster (and constant-time) on the ARM Cortex M0/M0+. + */ + +/** + * \brief RSA public key engine "i15". + * + * \see br_rsa_public + * + * \param x operand to exponentiate. + * \param xlen length of the operand (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_public(unsigned char *x, size_t xlen, + const br_rsa_public_key *pk); + +/** + * \brief RSA signature verification engine "i15" (PKCS#1 v1.5 signatures). + * + * \see br_rsa_pkcs1_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash_len expected hash value length (in bytes). + * \param pk RSA public key. + * \param hash_out output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_pkcs1_vrfy(const unsigned char *x, size_t xlen, + const unsigned char *hash_oid, size_t hash_len, + const br_rsa_public_key *pk, unsigned char *hash_out); + +/** + * \brief RSA signature verification engine "i15" (PSS signatures). + * + * \see br_rsa_pss_vrfy + * + * \param x signature buffer. + * \param xlen signature length (in bytes). + * \param hf_data hash function applied on the message. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hash value of the signed message. + * \param salt_len PSS salt length (in bytes). + * \param pk RSA public key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_pss_vrfy(const unsigned char *x, size_t xlen, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const void *hash, size_t salt_len, const br_rsa_public_key *pk); + +/** + * \brief RSA private key engine "i15". + * + * \see br_rsa_private + * + * \param x operand to exponentiate. + * \param sk RSA private key. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_private(unsigned char *x, + const br_rsa_private_key *sk); + +/** + * \brief RSA signature generation engine "i15" (PKCS#1 v1.5 signatures). + * + * \see br_rsa_pkcs1_sign + * + * \param hash_oid encoded hash algorithm OID (or `NULL`). + * \param hash hash value. + * \param hash_len hash value length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the hash value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_pkcs1_sign(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief RSA signature generation engine "i15" (PSS signatures). + * + * \see br_rsa_pss_sign + * + * \param rng PRNG for salt generation (`NULL` if `salt_len` is zero). + * \param hf_data hash function used to hash the signed data. + * \param hf_mgf1 hash function to use with MGF1. + * \param hash hashed message. + * \param salt_len salt length (in bytes). + * \param sk RSA private key. + * \param x output buffer for the signature value. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_pss_sign(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash_value, size_t salt_len, + const br_rsa_private_key *sk, unsigned char *x); + +/** + * \brief Get "default" RSA implementation (public-key operations). + * + * This returns the preferred implementation of RSA (public-key operations) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_public br_rsa_public_get_default(void); + +/** + * \brief Get "default" RSA implementation (private-key operations). + * + * This returns the preferred implementation of RSA (private-key operations) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_private br_rsa_private_get_default(void); + +/** + * \brief Get "default" RSA implementation (PKCS#1 v1.5 signature verification). + * + * This returns the preferred implementation of RSA (signature verification) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_pkcs1_vrfy br_rsa_pkcs1_vrfy_get_default(void); + +/** + * \brief Get "default" RSA implementation (PSS signature verification). + * + * This returns the preferred implementation of RSA (signature verification) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_pss_vrfy br_rsa_pss_vrfy_get_default(void); + +/** + * \brief Get "default" RSA implementation (PKCS#1 v1.5 signature generation). + * + * This returns the preferred implementation of RSA (signature generation) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_pkcs1_sign br_rsa_pkcs1_sign_get_default(void); + +/** + * \brief Get "default" RSA implementation (PSS signature generation). + * + * This returns the preferred implementation of RSA (signature generation) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_pss_sign br_rsa_pss_sign_get_default(void); + +/** + * \brief Get "default" RSA implementation (OAEP encryption). + * + * This returns the preferred implementation of RSA (OAEP encryption) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_oaep_encrypt br_rsa_oaep_encrypt_get_default(void); + +/** + * \brief Get "default" RSA implementation (OAEP decryption). + * + * This returns the preferred implementation of RSA (OAEP decryption) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_oaep_decrypt br_rsa_oaep_decrypt_get_default(void); + +/** + * \brief RSA decryption helper, for SSL/TLS. + * + * This function performs the RSA decryption for a RSA-based key exchange + * in a SSL/TLS server. The provided RSA engine is used. The `data` + * parameter points to the value to decrypt, of length `len` bytes. On + * success, the 48-byte pre-master secret is copied into `data`, starting + * at the first byte of that buffer; on error, the contents of `data` + * become indeterminate. + * + * This function first checks that the provided value length (`len`) is + * not lower than 59 bytes, and matches the RSA modulus length; if neither + * of this property is met, then this function returns 0 and the buffer + * is unmodified. + * + * Otherwise, decryption and then padding verification are performed, both + * in constant-time. A decryption error, or a bad padding, or an + * incorrect decrypted value length are reported with a returned value of + * 0; on success, 1 is returned. The caller (SSL server engine) is supposed + * to proceed with a random pre-master secret in case of error. + * + * \param core RSA private key engine. + * \param sk RSA private key. + * \param data input/output buffer. + * \param len length (in bytes) of the data to decrypt. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_ssl_decrypt(br_rsa_private core, const br_rsa_private_key *sk, + unsigned char *data, size_t len); + +/** + * \brief RSA encryption (OAEP) with the "i15" engine. + * + * \see br_rsa_oaep_encrypt + * + * \param rnd source of random bytes. + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param pk RSA public key. + * \param dst destination buffer. + * \param dst_max_len destination buffer length (maximum encrypted data size). + * \param src message to encrypt. + * \param src_len source message length (in bytes). + * \return encrypted message length (in bytes), or 0 on error. + */ +size_t br_rsa_i15_oaep_encrypt( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len); + +/** + * \brief RSA decryption (OAEP) with the "i15" engine. + * + * \see br_rsa_oaep_decrypt + * + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param sk RSA private key. + * \param data input/output buffer. + * \param len encrypted/decrypted message length. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i15_oaep_decrypt( + const br_hash_class *dig, const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len); + +/** + * \brief RSA encryption (OAEP) with the "i31" engine. + * + * \see br_rsa_oaep_encrypt + * + * \param rnd source of random bytes. + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param pk RSA public key. + * \param dst destination buffer. + * \param dst_max_len destination buffer length (maximum encrypted data size). + * \param src message to encrypt. + * \param src_len source message length (in bytes). + * \return encrypted message length (in bytes), or 0 on error. + */ +size_t br_rsa_i31_oaep_encrypt( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len); + +/** + * \brief RSA decryption (OAEP) with the "i31" engine. + * + * \see br_rsa_oaep_decrypt + * + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param sk RSA private key. + * \param data input/output buffer. + * \param len encrypted/decrypted message length. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i31_oaep_decrypt( + const br_hash_class *dig, const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len); + +/** + * \brief RSA encryption (OAEP) with the "i32" engine. + * + * \see br_rsa_oaep_encrypt + * + * \param rnd source of random bytes. + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param pk RSA public key. + * \param dst destination buffer. + * \param dst_max_len destination buffer length (maximum encrypted data size). + * \param src message to encrypt. + * \param src_len source message length (in bytes). + * \return encrypted message length (in bytes), or 0 on error. + */ +size_t br_rsa_i32_oaep_encrypt( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len); + +/** + * \brief RSA decryption (OAEP) with the "i32" engine. + * + * \see br_rsa_oaep_decrypt + * + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param sk RSA private key. + * \param data input/output buffer. + * \param len encrypted/decrypted message length. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i32_oaep_decrypt( + const br_hash_class *dig, const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len); + +/** + * \brief RSA encryption (OAEP) with the "i62" engine. + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_oaep_encrypt_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_oaep_encrypt + * + * \param rnd source of random bytes. + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param pk RSA public key. + * \param dst destination buffer. + * \param dst_max_len destination buffer length (maximum encrypted data size). + * \param src message to encrypt. + * \param src_len source message length (in bytes). + * \return encrypted message length (in bytes), or 0 on error. + */ +size_t br_rsa_i62_oaep_encrypt( + const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, + const br_rsa_public_key *pk, + void *dst, size_t dst_max_len, + const void *src, size_t src_len); + +/** + * \brief RSA decryption (OAEP) with the "i62" engine. + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_oaep_decrypt_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_oaep_decrypt + * + * \param dig hash function to use with MGF1. + * \param label label value (may be `NULL` if `label_len` is zero). + * \param label_len label length, in bytes. + * \param sk RSA private key. + * \param data input/output buffer. + * \param len encrypted/decrypted message length. + * \return 1 on success, 0 on error. + */ +uint32_t br_rsa_i62_oaep_decrypt( + const br_hash_class *dig, const void *label, size_t label_len, + const br_rsa_private_key *sk, void *data, size_t *len); + +/** + * \brief Get buffer size to hold RSA private key elements. + * + * This macro returns the length (in bytes) of the buffer needed to + * receive the elements of a RSA private key, as generated by one of + * the `br_rsa_*_keygen()` functions. If the provided size is a constant + * expression, then the whole macro evaluates to a constant expression. + * + * \param size target key size (modulus size, in bits) + * \return the length of the private key buffer, in bytes. + */ +#define BR_RSA_KBUF_PRIV_SIZE(size) (5 * (((size) + 15) >> 4)) + +/** + * \brief Get buffer size to hold RSA public key elements. + * + * This macro returns the length (in bytes) of the buffer needed to + * receive the elements of a RSA public key, as generated by one of + * the `br_rsa_*_keygen()` functions. If the provided size is a constant + * expression, then the whole macro evaluates to a constant expression. + * + * \param size target key size (modulus size, in bits) + * \return the length of the public key buffer, in bytes. + */ +#define BR_RSA_KBUF_PUB_SIZE(size) (4 + (((size) + 7) >> 3)) + +/** + * \brief Type for RSA key pair generator implementation. + * + * This function generates a new RSA key pair whose modulus has bit + * length `size` bits. The private key elements are written in the + * `kbuf_priv` buffer, and pointer values and length fields to these + * elements are populated in the provided private key structure `sk`. + * Similarly, the public key elements are written in `kbuf_pub`, with + * pointers and lengths set in `pk`. + * + * If `pk` is `NULL`, then `kbuf_pub` may be `NULL`, and only the + * private key is set. + * + * If `pubexp` is not zero, then its value will be used as public + * exponent. Valid RSA public exponent values are odd integers + * greater than 1. If `pubexp` is zero, then the public exponent will + * have value 3. + * + * The provided PRNG (`rng_ctx`) must have already been initialized + * and seeded. + * + * Returned value is 1 on success, 0 on error. An error is reported + * if the requested range is outside of the supported key sizes, or + * if an invalid non-zero public exponent value is provided. Supported + * range starts at 512 bits, and up to an implementation-defined + * maximum (by default 4096 bits). Note that key sizes up to 768 bits + * have been broken in practice, and sizes lower than 2048 bits are + * usually considered to be weak and should not be used. + * + * \param rng_ctx source PRNG context (already initialized) + * \param sk RSA private key structure (destination) + * \param kbuf_priv buffer for private key elements + * \param pk RSA public key structure (destination), or `NULL` + * \param kbuf_pub buffer for public key elements, or `NULL` + * \param size target RSA modulus size (in bits) + * \param pubexp public exponent to use, or zero + * \return 1 on success, 0 on error (invalid parameters) + */ +typedef uint32_t (*br_rsa_keygen)( + const br_prng_class **rng_ctx, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp); + +/** + * \brief RSA key pair generation with the "i15" engine. + * + * \see br_rsa_keygen + * + * \param rng_ctx source PRNG context (already initialized) + * \param sk RSA private key structure (destination) + * \param kbuf_priv buffer for private key elements + * \param pk RSA public key structure (destination), or `NULL` + * \param kbuf_pub buffer for public key elements, or `NULL` + * \param size target RSA modulus size (in bits) + * \param pubexp public exponent to use, or zero + * \return 1 on success, 0 on error (invalid parameters) + */ +uint32_t br_rsa_i15_keygen( + const br_prng_class **rng_ctx, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp); + +/** + * \brief RSA key pair generation with the "i31" engine. + * + * \see br_rsa_keygen + * + * \param rng_ctx source PRNG context (already initialized) + * \param sk RSA private key structure (destination) + * \param kbuf_priv buffer for private key elements + * \param pk RSA public key structure (destination), or `NULL` + * \param kbuf_pub buffer for public key elements, or `NULL` + * \param size target RSA modulus size (in bits) + * \param pubexp public exponent to use, or zero + * \return 1 on success, 0 on error (invalid parameters) + */ +uint32_t br_rsa_i31_keygen( + const br_prng_class **rng_ctx, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp); + +/** + * \brief RSA key pair generation with the "i62" engine. + * + * This function is defined only on architecture that offer a 64x64->128 + * opcode. Use `br_rsa_i62_keygen_get()` to dynamically obtain a pointer + * to that function. + * + * \see br_rsa_keygen + * + * \param rng_ctx source PRNG context (already initialized) + * \param sk RSA private key structure (destination) + * \param kbuf_priv buffer for private key elements + * \param pk RSA public key structure (destination), or `NULL` + * \param kbuf_pub buffer for public key elements, or `NULL` + * \param size target RSA modulus size (in bits) + * \param pubexp public exponent to use, or zero + * \return 1 on success, 0 on error (invalid parameters) + */ +uint32_t br_rsa_i62_keygen( + const br_prng_class **rng_ctx, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp); + +/** + * \brief Get the RSA "i62" implementation (key pair generation), + * if available. + * + * \return the implementation, or 0. + */ +br_rsa_keygen br_rsa_i62_keygen_get(void); + +/** + * \brief Get "default" RSA implementation (key pair generation). + * + * This returns the preferred implementation of RSA (key pair generation) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_keygen br_rsa_keygen_get_default(void); + +/** + * \brief Type for a modulus computing function. + * + * Such a function computes the public modulus from the private key. The + * encoded modulus (unsigned big-endian) is written on `n`, and the size + * (in bytes) is returned. If `n` is `NULL`, then the size is returned but + * the modulus itself is not computed. + * + * If the key size exceeds an internal limit, 0 is returned. + * + * \param n destination buffer (or `NULL`). + * \param sk RSA private key. + * \return the modulus length (in bytes), or 0. + */ +typedef size_t (*br_rsa_compute_modulus)(void *n, const br_rsa_private_key *sk); + +/** + * \brief Recompute RSA modulus ("i15" engine). + * + * \see br_rsa_compute_modulus + * + * \param n destination buffer (or `NULL`). + * \param sk RSA private key. + * \return the modulus length (in bytes), or 0. + */ +size_t br_rsa_i15_compute_modulus(void *n, const br_rsa_private_key *sk); + +/** + * \brief Recompute RSA modulus ("i31" engine). + * + * \see br_rsa_compute_modulus + * + * \param n destination buffer (or `NULL`). + * \param sk RSA private key. + * \return the modulus length (in bytes), or 0. + */ +size_t br_rsa_i31_compute_modulus(void *n, const br_rsa_private_key *sk); + +/** + * \brief Get "default" RSA implementation (recompute modulus). + * + * This returns the preferred implementation of RSA (recompute modulus) + * on the current system. + * + * \return the default implementation. + */ +br_rsa_compute_modulus br_rsa_compute_modulus_get_default(void); + +/** + * \brief Type for a public exponent computing function. + * + * Such a function recomputes the public exponent from the private key. + * 0 is returned if any of the following occurs: + * + * - Either `p` or `q` is not equal to 3 modulo 4. + * + * - The public exponent does not fit on 32 bits. + * + * - An internal limit is exceeded. + * + * - The private key is invalid in some way. + * + * For all private keys produced by the key generator functions + * (`br_rsa_keygen` type), this function succeeds and returns the true + * public exponent. The public exponent is always an odd integer greater + * than 1. + * + * \return the public exponent, or 0. + */ +typedef uint32_t (*br_rsa_compute_pubexp)(const br_rsa_private_key *sk); + +/** + * \brief Recompute RSA public exponent ("i15" engine). + * + * \see br_rsa_compute_pubexp + * + * \return the public exponent, or 0. + */ +uint32_t br_rsa_i15_compute_pubexp(const br_rsa_private_key *sk); + +/** + * \brief Recompute RSA public exponent ("i31" engine). + * + * \see br_rsa_compute_pubexp + * + * \return the public exponent, or 0. + */ +uint32_t br_rsa_i31_compute_pubexp(const br_rsa_private_key *sk); + +/** + * \brief Get "default" RSA implementation (recompute public exponent). + * + * This returns the preferred implementation of RSA (recompute public + * exponent) on the current system. + * + * \return the default implementation. + */ +br_rsa_compute_pubexp br_rsa_compute_pubexp_get_default(void); + +/** + * \brief Type for a private exponent computing function. + * + * An RSA private key (`br_rsa_private_key`) contains two reduced + * private exponents, which are sufficient to perform private key + * operations. However, standard encoding formats for RSA private keys + * require also a copy of the complete private exponent (non-reduced), + * which this function recomputes. + * + * This function suceeds if all the following conditions hold: + * + * - Both private factors `p` and `q` are equal to 3 modulo 4. + * + * - The provided public exponent `pubexp` is correct, and, in particular, + * is odd, relatively prime to `p-1` and `q-1`, and greater than 1. + * + * - No internal storage limit is exceeded. + * + * For all private keys produced by the key generator functions + * (`br_rsa_keygen` type), this function succeeds. Note that the API + * restricts the public exponent to a maximum size of 32 bits. + * + * The encoded private exponent is written in `d` (unsigned big-endian + * convention), and the length (in bytes) is returned. If `d` is `NULL`, + * then the exponent is not written anywhere, but the length is still + * returned. On error, 0 is returned. + * + * Not all error conditions are detected when `d` is `NULL`; therefore, the + * returned value shall be checked also when actually producing the value. + * + * \param d destination buffer (or `NULL`). + * \param sk RSA private key. + * \param pubexp the public exponent. + * \return the private exponent length (in bytes), or 0. + */ +typedef size_t (*br_rsa_compute_privexp)(void *d, + const br_rsa_private_key *sk, uint32_t pubexp); + +/** + * \brief Recompute RSA private exponent ("i15" engine). + * + * \see br_rsa_compute_privexp + * + * \param d destination buffer (or `NULL`). + * \param sk RSA private key. + * \param pubexp the public exponent. + * \return the private exponent length (in bytes), or 0. + */ +size_t br_rsa_i15_compute_privexp(void *d, + const br_rsa_private_key *sk, uint32_t pubexp); + +/** + * \brief Recompute RSA private exponent ("i31" engine). + * + * \see br_rsa_compute_privexp + * + * \param d destination buffer (or `NULL`). + * \param sk RSA private key. + * \param pubexp the public exponent. + * \return the private exponent length (in bytes), or 0. + */ +size_t br_rsa_i31_compute_privexp(void *d, + const br_rsa_private_key *sk, uint32_t pubexp); + +/** + * \brief Get "default" RSA implementation (recompute private exponent). + * + * This returns the preferred implementation of RSA (recompute private + * exponent) on the current system. + * + * \return the default implementation. + */ +br_rsa_compute_privexp br_rsa_compute_privexp_get_default(void); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_ssl.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_ssl.h new file mode 100644 index 000000000000..8ad2d69c57eb --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_ssl.h @@ -0,0 +1,4331 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_SSL_H__ +#define BR_BEARSSL_SSL_H__ + +#include +#include + +#include "bearssl_block.h" +#include "bearssl_hash.h" +#include "bearssl_hmac.h" +#include "bearssl_prf.h" +#include "bearssl_rand.h" +#include "bearssl_x509.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file bearssl_ssl.h + * + * # SSL + * + * For an overview of the SSL/TLS API, see [the BearSSL Web + * site](https://www.bearssl.org/api1.html). + * + * The `BR_TLS_*` constants correspond to the standard cipher suites and + * their values in the [IANA + * registry](http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4). + * + * The `BR_ALERT_*` constants are for standard TLS alert messages. When + * a fatal alert message is sent of received, then the SSL engine context + * status is set to the sum of that alert value (an integer in the 0..255 + * range) and a fixed offset (`BR_ERR_SEND_FATAL_ALERT` for a sent alert, + * `BR_ERR_RECV_FATAL_ALERT` for a received alert). + */ + +/** \brief Optimal input buffer size. */ +#define BR_SSL_BUFSIZE_INPUT (16384 + 325) + +/** \brief Optimal output buffer size. */ +#define BR_SSL_BUFSIZE_OUTPUT (16384 + 85) + +/** \brief Optimal buffer size for monodirectional engine + (shared input/output buffer). */ +#define BR_SSL_BUFSIZE_MONO BR_SSL_BUFSIZE_INPUT + +/** \brief Optimal buffer size for bidirectional engine + (single buffer split into two separate input/output buffers). */ +#define BR_SSL_BUFSIZE_BIDI (BR_SSL_BUFSIZE_INPUT + BR_SSL_BUFSIZE_OUTPUT) + +/* + * Constants for known SSL/TLS protocol versions (SSL 3.0, TLS 1.0, TLS 1.1 + * and TLS 1.2). Note that though there is a constant for SSL 3.0, that + * protocol version is not actually supported. + */ + +/** \brief Protocol version: SSL 3.0 (unsupported). */ +#define BR_SSL30 0x0300 +/** \brief Protocol version: TLS 1.0. */ +#define BR_TLS10 0x0301 +/** \brief Protocol version: TLS 1.1. */ +#define BR_TLS11 0x0302 +/** \brief Protocol version: TLS 1.2. */ +#define BR_TLS12 0x0303 + +/* + * Error constants. They are used to report the reason why a context has + * been marked as failed. + * + * Implementation note: SSL-level error codes should be in the 1..31 + * range. The 32..63 range is for certificate decoding and validation + * errors. Received fatal alerts imply an error code in the 256..511 range. + */ + +/** \brief SSL status: no error so far (0). */ +#define BR_ERR_OK 0 + +/** \brief SSL status: caller-provided parameter is incorrect. */ +#define BR_ERR_BAD_PARAM 1 + +/** \brief SSL status: operation requested by the caller cannot be applied + with the current context state (e.g. reading data while outgoing data + is waiting to be sent). */ +#define BR_ERR_BAD_STATE 2 + +/** \brief SSL status: incoming protocol or record version is unsupported. */ +#define BR_ERR_UNSUPPORTED_VERSION 3 + +/** \brief SSL status: incoming record version does not match the expected + version. */ +#define BR_ERR_BAD_VERSION 4 + +/** \brief SSL status: incoming record length is invalid. */ +#define BR_ERR_BAD_LENGTH 5 + +/** \brief SSL status: incoming record is too large to be processed, or + buffer is too small for the handshake message to send. */ +#define BR_ERR_TOO_LARGE 6 + +/** \brief SSL status: decryption found an invalid padding, or the record + MAC is not correct. */ +#define BR_ERR_BAD_MAC 7 + +/** \brief SSL status: no initial entropy was provided, and none can be + obtained from the OS. */ +#define BR_ERR_NO_RANDOM 8 + +/** \brief SSL status: incoming record type is unknown. */ +#define BR_ERR_UNKNOWN_TYPE 9 + +/** \brief SSL status: incoming record or message has wrong type with + regards to the current engine state. */ +#define BR_ERR_UNEXPECTED 10 + +/** \brief SSL status: ChangeCipherSpec message from the peer has invalid + contents. */ +#define BR_ERR_BAD_CCS 12 + +/** \brief SSL status: alert message from the peer has invalid contents + (odd length). */ +#define BR_ERR_BAD_ALERT 13 + +/** \brief SSL status: incoming handshake message decoding failed. */ +#define BR_ERR_BAD_HANDSHAKE 14 + +/** \brief SSL status: ServerHello contains a session ID which is larger + than 32 bytes. */ +#define BR_ERR_OVERSIZED_ID 15 + +/** \brief SSL status: server wants to use a cipher suite that we did + not claim to support. This is also reported if we tried to advertise + a cipher suite that we do not support. */ +#define BR_ERR_BAD_CIPHER_SUITE 16 + +/** \brief SSL status: server wants to use a compression that we did not + claim to support. */ +#define BR_ERR_BAD_COMPRESSION 17 + +/** \brief SSL status: server's max fragment length does not match + client's. */ +#define BR_ERR_BAD_FRAGLEN 18 + +/** \brief SSL status: secure renegotiation failed. */ +#define BR_ERR_BAD_SECRENEG 19 + +/** \brief SSL status: server sent an extension type that we did not + announce, or used the same extension type several times in a single + ServerHello. */ +#define BR_ERR_EXTRA_EXTENSION 20 + +/** \brief SSL status: invalid Server Name Indication contents (when + used by the server, this extension shall be empty). */ +#define BR_ERR_BAD_SNI 21 + +/** \brief SSL status: invalid ServerHelloDone from the server (length + is not 0). */ +#define BR_ERR_BAD_HELLO_DONE 22 + +/** \brief SSL status: internal limit exceeded (e.g. server's public key + is too large). */ +#define BR_ERR_LIMIT_EXCEEDED 23 + +/** \brief SSL status: Finished message from peer does not match the + expected value. */ +#define BR_ERR_BAD_FINISHED 24 + +/** \brief SSL status: session resumption attempt with distinct version + or cipher suite. */ +#define BR_ERR_RESUME_MISMATCH 25 + +/** \brief SSL status: unsupported or invalid algorithm (ECDHE curve, + signature algorithm, hash function). */ +#define BR_ERR_INVALID_ALGORITHM 26 + +/** \brief SSL status: invalid signature (on ServerKeyExchange from + server, or in CertificateVerify from client). */ +#define BR_ERR_BAD_SIGNATURE 27 + +/** \brief SSL status: peer's public key does not have the proper type + or is not allowed for requested operation. */ +#define BR_ERR_WRONG_KEY_USAGE 28 + +/** \brief SSL status: client did not send a certificate upon request, + or the client certificate could not be validated. */ +#define BR_ERR_NO_CLIENT_AUTH 29 + +/** \brief SSL status: I/O error or premature close on underlying + transport stream. This error code is set only by the simplified + I/O API ("br_sslio_*"). */ +#define BR_ERR_IO 31 + +/** \brief SSL status: base value for a received fatal alert. + + When a fatal alert is received from the peer, the alert value + is added to this constant. */ +#define BR_ERR_RECV_FATAL_ALERT 256 + +/** \brief SSL status: base value for a sent fatal alert. + + When a fatal alert is sent to the peer, the alert value is added + to this constant. */ +#define BR_ERR_SEND_FATAL_ALERT 512 + +/* ===================================================================== */ + +/** + * \brief Decryption engine for SSL. + * + * When processing incoming records, the SSL engine will use a decryption + * engine that uses a specific context structure, and has a set of + * methods (a vtable) that follows this template. + * + * The decryption engine is responsible for applying decryption, verifying + * MAC, and keeping track of the record sequence number. + */ +typedef struct br_sslrec_in_class_ br_sslrec_in_class; +struct br_sslrec_in_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Test validity of the incoming record length. + * + * This function returns 1 if the announced length for an + * incoming record is valid, 0 otherwise, + * + * \param ctx decryption engine context. + * \param record_len incoming record length. + * \return 1 of a valid length, 0 otherwise. + */ + int (*check_length)(const br_sslrec_in_class *const *ctx, + size_t record_len); + + /** + * \brief Decrypt the incoming record. + * + * This function may assume that the record length is valid + * (it has been previously tested with `check_length()`). + * Decryption is done in place; `*len` is updated with the + * cleartext length, and the address of the first plaintext + * byte is returned. If the record is correct but empty, then + * `*len` is set to 0 and a non-`NULL` pointer is returned. + * + * On decryption/MAC error, `NULL` is returned. + * + * \param ctx decryption engine context. + * \param record_type record type (23 for application data, etc). + * \param version record version. + * \param payload address of encrypted payload. + * \param len pointer to payload length (updated). + * \return pointer to plaintext, or `NULL` on error. + */ + unsigned char *(*decrypt)(const br_sslrec_in_class **ctx, + int record_type, unsigned version, + void *payload, size_t *len); +}; + +/** + * \brief Encryption engine for SSL. + * + * When building outgoing records, the SSL engine will use an encryption + * engine that uses a specific context structure, and has a set of + * methods (a vtable) that follows this template. + * + * The encryption engine is responsible for applying encryption and MAC, + * and keeping track of the record sequence number. + */ +typedef struct br_sslrec_out_class_ br_sslrec_out_class; +struct br_sslrec_out_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Compute maximum plaintext sizes and offsets. + * + * When this function is called, the `*start` and `*end` + * values contain offsets designating the free area in the + * outgoing buffer for plaintext data; that free area is + * preceded by a 5-byte space which will receive the record + * header. + * + * The `max_plaintext()` function is responsible for adjusting + * both `*start` and `*end` to make room for any record-specific + * header, MAC, padding, and possible split. + * + * \param ctx encryption engine context. + * \param start pointer to start of plaintext offset (updated). + * \param end pointer to start of plaintext offset (updated). + */ + void (*max_plaintext)(const br_sslrec_out_class *const *ctx, + size_t *start, size_t *end); + + /** + * \brief Perform record encryption. + * + * This function encrypts the record. The plaintext address and + * length are provided. Returned value is the start of the + * encrypted record (or sequence of records, if a split was + * performed), _including_ the 5-byte header, and `*len` is + * adjusted to the total size of the record(s), there again + * including the header(s). + * + * \param ctx decryption engine context. + * \param record_type record type (23 for application data, etc). + * \param version record version. + * \param plaintext address of plaintext. + * \param len pointer to plaintext length (updated). + * \return pointer to start of built record. + */ + unsigned char *(*encrypt)(const br_sslrec_out_class **ctx, + int record_type, unsigned version, + void *plaintext, size_t *len); +}; + +/** + * \brief Context for a no-encryption engine. + * + * The no-encryption engine processes outgoing records during the initial + * handshake, before encryption is applied. + */ +typedef struct { + /** \brief No-encryption engine vtable. */ + const br_sslrec_out_class *vtable; +} br_sslrec_out_clear_context; + +/** \brief Static, constant vtable for the no-encryption engine. */ +extern const br_sslrec_out_class br_sslrec_out_clear_vtable; + +/* ===================================================================== */ + +/** + * \brief Record decryption engine class, for CBC mode. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for CBC processing: block cipher implementation, block cipher key, + * HMAC parameters (hash function, key, MAC length), and IV. If the + * IV is `NULL`, then a per-record IV will be used (TLS 1.1+). + */ +typedef struct br_sslrec_in_cbc_class_ br_sslrec_in_cbc_class; +struct br_sslrec_in_cbc_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CBC decryption). + * \param bc_key block cipher key. + * \param bc_key_len block cipher key length (in bytes). + * \param dig_impl hash function for HMAC. + * \param mac_key HMAC key. + * \param mac_key_len HMAC key length (in bytes). + * \param mac_out_len HMAC output length (in bytes). + * \param iv initial IV (or `NULL`). + */ + void (*init)(const br_sslrec_in_cbc_class **ctx, + const br_block_cbcdec_class *bc_impl, + const void *bc_key, size_t bc_key_len, + const br_hash_class *dig_impl, + const void *mac_key, size_t mac_key_len, size_t mac_out_len, + const void *iv); +}; + +/** + * \brief Record encryption engine class, for CBC mode. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for CBC processing: block cipher implementation, block cipher key, + * HMAC parameters (hash function, key, MAC length), and IV. If the + * IV is `NULL`, then a per-record IV will be used (TLS 1.1+). + */ +typedef struct br_sslrec_out_cbc_class_ br_sslrec_out_cbc_class; +struct br_sslrec_out_cbc_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CBC encryption). + * \param bc_key block cipher key. + * \param bc_key_len block cipher key length (in bytes). + * \param dig_impl hash function for HMAC. + * \param mac_key HMAC key. + * \param mac_key_len HMAC key length (in bytes). + * \param mac_out_len HMAC output length (in bytes). + * \param iv initial IV (or `NULL`). + */ + void (*init)(const br_sslrec_out_cbc_class **ctx, + const br_block_cbcenc_class *bc_impl, + const void *bc_key, size_t bc_key_len, + const br_hash_class *dig_impl, + const void *mac_key, size_t mac_key_len, size_t mac_out_len, + const void *iv); +}; + +/** + * \brief Context structure for decrypting incoming records with + * CBC + HMAC. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_sslrec_in_cbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_cbcdec_class *vtable; + br_aes_gen_cbcdec_keys aes; + br_des_gen_cbcdec_keys des; + } bc; + br_hmac_key_context mac; + size_t mac_len; + unsigned char iv[16]; + int explicit_IV; +#endif +} br_sslrec_in_cbc_context; + +/** + * \brief Static, constant vtable for record decryption with CBC. + */ +extern const br_sslrec_in_cbc_class br_sslrec_in_cbc_vtable; + +/** + * \brief Context structure for encrypting outgoing records with + * CBC + HMAC. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_sslrec_out_cbc_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_cbcenc_class *vtable; + br_aes_gen_cbcenc_keys aes; + br_des_gen_cbcenc_keys des; + } bc; + br_hmac_key_context mac; + size_t mac_len; + unsigned char iv[16]; + int explicit_IV; +#endif +} br_sslrec_out_cbc_context; + +/** + * \brief Static, constant vtable for record encryption with CBC. + */ +extern const br_sslrec_out_cbc_class br_sslrec_out_cbc_vtable; + +/* ===================================================================== */ + +/** + * \brief Record decryption engine class, for GCM mode. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for GCM processing: block cipher implementation, block cipher key, + * GHASH implementation, and 4-byte IV. + */ +typedef struct br_sslrec_in_gcm_class_ br_sslrec_in_gcm_class; +struct br_sslrec_in_gcm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param gh_impl GHASH implementation. + * \param iv static IV (4 bytes). + */ + void (*init)(const br_sslrec_in_gcm_class **ctx, + const br_block_ctr_class *bc_impl, + const void *key, size_t key_len, + br_ghash gh_impl, + const void *iv); +}; + +/** + * \brief Record encryption engine class, for GCM mode. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for GCM processing: block cipher implementation, block cipher key, + * GHASH implementation, and 4-byte IV. + */ +typedef struct br_sslrec_out_gcm_class_ br_sslrec_out_gcm_class; +struct br_sslrec_out_gcm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param gh_impl GHASH implementation. + * \param iv static IV (4 bytes). + */ + void (*init)(const br_sslrec_out_gcm_class **ctx, + const br_block_ctr_class *bc_impl, + const void *key, size_t key_len, + br_ghash gh_impl, + const void *iv); +}; + +/** + * \brief Context structure for processing records with GCM. + * + * The same context structure is used for encrypting and decrypting. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + union { + const void *gen; + const br_sslrec_in_gcm_class *in; + const br_sslrec_out_gcm_class *out; + } vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_ctr_class *vtable; + br_aes_gen_ctr_keys aes; + } bc; + br_ghash gh; + unsigned char iv[4]; + unsigned char h[16]; +#endif +} br_sslrec_gcm_context; + +/** + * \brief Static, constant vtable for record decryption with GCM. + */ +extern const br_sslrec_in_gcm_class br_sslrec_in_gcm_vtable; + +/** + * \brief Static, constant vtable for record encryption with GCM. + */ +extern const br_sslrec_out_gcm_class br_sslrec_out_gcm_vtable; + +/* ===================================================================== */ + +/** + * \brief Record decryption engine class, for ChaCha20+Poly1305. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for ChaCha20+Poly1305 processing: ChaCha20 implementation, + * Poly1305 implementation, key, and 12-byte IV. + */ +typedef struct br_sslrec_in_chapol_class_ br_sslrec_in_chapol_class; +struct br_sslrec_in_chapol_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param ichacha ChaCha20 implementation. + * \param ipoly Poly1305 implementation. + * \param key secret key (32 bytes). + * \param iv static IV (12 bytes). + */ + void (*init)(const br_sslrec_in_chapol_class **ctx, + br_chacha20_run ichacha, + br_poly1305_run ipoly, + const void *key, const void *iv); +}; + +/** + * \brief Record encryption engine class, for ChaCha20+Poly1305. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for ChaCha20+Poly1305 processing: ChaCha20 implementation, + * Poly1305 implementation, key, and 12-byte IV. + */ +typedef struct br_sslrec_out_chapol_class_ br_sslrec_out_chapol_class; +struct br_sslrec_out_chapol_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param ichacha ChaCha20 implementation. + * \param ipoly Poly1305 implementation. + * \param key secret key (32 bytes). + * \param iv static IV (12 bytes). + */ + void (*init)(const br_sslrec_out_chapol_class **ctx, + br_chacha20_run ichacha, + br_poly1305_run ipoly, + const void *key, const void *iv); +}; + +/** + * \brief Context structure for processing records with ChaCha20+Poly1305. + * + * The same context structure is used for encrypting and decrypting. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + union { + const void *gen; + const br_sslrec_in_chapol_class *in; + const br_sslrec_out_chapol_class *out; + } vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + unsigned char key[32]; + unsigned char iv[12]; + br_chacha20_run ichacha; + br_poly1305_run ipoly; +#endif +} br_sslrec_chapol_context; + +/** + * \brief Static, constant vtable for record decryption with ChaCha20+Poly1305. + */ +extern const br_sslrec_in_chapol_class br_sslrec_in_chapol_vtable; + +/** + * \brief Static, constant vtable for record encryption with ChaCha20+Poly1305. + */ +extern const br_sslrec_out_chapol_class br_sslrec_out_chapol_vtable; + +/* ===================================================================== */ + +/** + * \brief Record decryption engine class, for CCM mode. + * + * This class type extends the decryption engine class with an + * initialisation method that receives the parameters needed + * for CCM processing: block cipher implementation, block cipher key, + * and 4-byte IV. + */ +typedef struct br_sslrec_in_ccm_class_ br_sslrec_in_ccm_class; +struct br_sslrec_in_ccm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_in_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR+CBC). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param iv static IV (4 bytes). + * \param tag_len tag length (in bytes) + */ + void (*init)(const br_sslrec_in_ccm_class **ctx, + const br_block_ctrcbc_class *bc_impl, + const void *key, size_t key_len, + const void *iv, size_t tag_len); +}; + +/** + * \brief Record encryption engine class, for CCM mode. + * + * This class type extends the encryption engine class with an + * initialisation method that receives the parameters needed + * for CCM processing: block cipher implementation, block cipher key, + * and 4-byte IV. + */ +typedef struct br_sslrec_out_ccm_class_ br_sslrec_out_ccm_class; +struct br_sslrec_out_ccm_class_ { + /** + * \brief Superclass, as first vtable field. + */ + br_sslrec_out_class inner; + + /** + * \brief Engine initialisation method. + * + * This method sets the vtable field in the context. + * + * \param ctx context to initialise. + * \param bc_impl block cipher implementation (CTR+CBC). + * \param key block cipher key. + * \param key_len block cipher key length (in bytes). + * \param iv static IV (4 bytes). + * \param tag_len tag length (in bytes) + */ + void (*init)(const br_sslrec_out_ccm_class **ctx, + const br_block_ctrcbc_class *bc_impl, + const void *key, size_t key_len, + const void *iv, size_t tag_len); +}; + +/** + * \brief Context structure for processing records with CCM. + * + * The same context structure is used for encrypting and decrypting. + * + * The first field points to the vtable. The other fields are opaque + * and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + union { + const void *gen; + const br_sslrec_in_ccm_class *in; + const br_sslrec_out_ccm_class *out; + } vtable; +#ifndef BR_DOXYGEN_IGNORE + uint64_t seq; + union { + const br_block_ctrcbc_class *vtable; + br_aes_gen_ctrcbc_keys aes; + } bc; + unsigned char iv[4]; + size_t tag_len; +#endif +} br_sslrec_ccm_context; + +/** + * \brief Static, constant vtable for record decryption with CCM. + */ +extern const br_sslrec_in_ccm_class br_sslrec_in_ccm_vtable; + +/** + * \brief Static, constant vtable for record encryption with CCM. + */ +extern const br_sslrec_out_ccm_class br_sslrec_out_ccm_vtable; + +/* ===================================================================== */ + +/** + * \brief Type for session parameters, to be saved for session resumption. + */ +typedef struct { + /** \brief Session ID buffer. */ + unsigned char session_id[32]; + /** \brief Session ID length (in bytes, at most 32). */ + unsigned char session_id_len; + /** \brief Protocol version. */ + uint16_t version; + /** \brief Cipher suite. */ + uint16_t cipher_suite; + /** \brief Master secret. */ + unsigned char master_secret[48]; +} br_ssl_session_parameters; + +#ifndef BR_DOXYGEN_IGNORE +/* + * Maximum number of cipher suites supported by a client or server. + */ +#define BR_MAX_CIPHER_SUITES 48 +#endif + +/** + * \brief Context structure for SSL engine. + * + * This strucuture is common to the client and server; both the client + * context (`br_ssl_client_context`) and the server context + * (`br_ssl_server_context`) include a `br_ssl_engine_context` as their + * first field. + * + * The engine context manages records, including alerts, closures, and + * transitions to new encryption/MAC algorithms. Processing of handshake + * records is delegated to externally provided code. This structure + * should not be used directly. + * + * Structure contents are opaque and shall not be accessed directly. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + /* + * The error code. When non-zero, then the state is "failed" and + * no I/O may occur until reset. + */ + int err; + + /* + * Configured I/O buffers. They are either disjoint, or identical. + */ + unsigned char *ibuf, *obuf; + size_t ibuf_len, obuf_len; + + /* + * Maximum fragment length applies to outgoing records; incoming + * records can be processed as long as they fit in the input + * buffer. It is guaranteed that incoming records at least as big + * as max_frag_len can be processed. + */ + uint16_t max_frag_len; + unsigned char log_max_frag_len; + unsigned char max_frag_len_negotiated; + unsigned char peer_log_max_frag_len; + + /* + * Buffering management registers. + */ + size_t ixa, ixb, ixc; + size_t oxa, oxb, oxc; + unsigned char iomode; + unsigned char incrypt; + + /* + * Shutdown flag: when set to non-zero, incoming record bytes + * will not be accepted anymore. This is used after a close_notify + * has been received: afterwards, the engine no longer claims that + * it could receive bytes from the transport medium. + */ + unsigned char shutdown_recv; + + /* + * 'record_type_in' is set to the incoming record type when the + * record header has been received. + * 'record_type_out' is used to make the next outgoing record + * header when it is ready to go. + */ + unsigned char record_type_in, record_type_out; + + /* + * When a record is received, its version is extracted: + * -- if 'version_in' is 0, then it is set to the received version; + * -- otherwise, if the received version is not identical to + * the 'version_in' contents, then a failure is reported. + * + * This implements the SSL requirement that all records shall + * use the negotiated protocol version, once decided (in the + * ServerHello). It is up to the handshake handler to adjust this + * field when necessary. + */ + uint16_t version_in; + + /* + * 'version_out' is used when the next outgoing record is ready + * to go. + */ + uint16_t version_out; + + /* + * Record handler contexts. + */ + union { + const br_sslrec_in_class *vtable; + br_sslrec_in_cbc_context cbc; + br_sslrec_gcm_context gcm; + br_sslrec_chapol_context chapol; + br_sslrec_ccm_context ccm; + } in; + union { + const br_sslrec_out_class *vtable; + br_sslrec_out_clear_context clear; + br_sslrec_out_cbc_context cbc; + br_sslrec_gcm_context gcm; + br_sslrec_chapol_context chapol; + br_sslrec_ccm_context ccm; + } out; + + /* + * The "application data" flag. Value: + * 0 handshake is in process, no application data acceptable + * 1 application data can be sent and received + * 2 closing, no application data can be sent, but some + * can still be received (and discarded) + */ + unsigned char application_data; + + /* + * Context RNG. + * + * rng_init_done is initially 0. It is set to 1 when the + * basic structure of the RNG is set, and 2 when some + * entropy has been pushed in. The value 2 marks the RNG + * as "properly seeded". + * + * rng_os_rand_done is initially 0. It is set to 1 when + * some seeding from the OS or hardware has been attempted. + */ + br_hmac_drbg_context rng; + int rng_init_done; + int rng_os_rand_done; + + /* + * Supported minimum and maximum versions, and cipher suites. + */ + uint16_t version_min; + uint16_t version_max; + uint16_t suites_buf[BR_MAX_CIPHER_SUITES]; + unsigned char suites_num; + + /* + * For clients, the server name to send as a SNI extension. For + * servers, the name received in the SNI extension (if any). + */ + char server_name[256]; + + /* + * "Security parameters". These are filled by the handshake + * handler, and used when switching encryption state. + */ + unsigned char client_random[32]; + unsigned char server_random[32]; + br_ssl_session_parameters session; + + /* + * ECDHE elements: curve and point from the peer. The server also + * uses that buffer for the point to send to the client. + */ + unsigned char ecdhe_curve; + unsigned char ecdhe_point[133]; + unsigned char ecdhe_point_len; + + /* + * Secure renegotiation (RFC 5746): 'reneg' can be: + * 0 first handshake (server support is not known) + * 1 peer does not support secure renegotiation + * 2 peer supports secure renegotiation + * + * The saved_finished buffer contains the client and the + * server "Finished" values from the last handshake, in + * that order (12 bytes each). + */ + unsigned char reneg; + unsigned char saved_finished[24]; + + /* + * Behavioural flags. + */ + uint32_t flags; + + /* + * Context variables for the handshake processor. The 'pad' must + * be large enough to accommodate an RSA-encrypted pre-master + * secret, or an RSA signature; since we want to support up to + * RSA-4096, this means at least 512 bytes. (Other pad usages + * require its length to be at least 256.) + */ + struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; + } cpu; + uint32_t dp_stack[32]; + uint32_t rp_stack[32]; + unsigned char pad[512]; + unsigned char *hbuf_in, *hbuf_out, *saved_hbuf_out; + size_t hlen_in, hlen_out; + void (*hsrun)(void *ctx); + + /* + * The 'action' value communicates OOB information between the + * engine and the handshake processor. + * + * From the engine: + * 0 invocation triggered by I/O + * 1 invocation triggered by explicit close + * 2 invocation triggered by explicit renegotiation + */ + unsigned char action; + + /* + * State for alert messages. Value is either 0, or the value of + * the alert level byte (level is either 1 for warning, or 2 for + * fatal; we convert all other values to 'fatal'). + */ + unsigned char alert; + + /* + * Closure flags. This flag is set when a close_notify has been + * received from the peer. + */ + unsigned char close_received; + + /* + * Multi-hasher for the handshake messages. The handshake handler + * is responsible for resetting it when appropriate. + */ + br_multihash_context mhash; + + /* + * Pointer to the X.509 engine. The engine is supposed to be + * already initialized. It is used to validate the peer's + * certificate. + */ + const br_x509_class **x509ctx; + + /* + * Certificate chain to send. This is used by both client and + * server, when they send their respective Certificate messages. + * If chain_len is 0, then chain may be NULL. + */ + const br_x509_certificate *chain; + size_t chain_len; + const unsigned char *cert_cur; + size_t cert_len; + + /* + * List of supported protocol names (ALPN extension). If unset, + * (number of names is 0), then: + * - the client sends no ALPN extension; + * - the server ignores any incoming ALPN extension. + * + * Otherwise: + * - the client sends an ALPN extension with all the names; + * - the server selects the first protocol in its list that + * the client also supports, or fails (fatal alert 120) + * if the client sends an ALPN extension and there is no + * match. + * + * The 'selected_protocol' field contains 1+n if the matching + * name has index n in the list (the value is 0 if no match was + * performed, e.g. the peer did not send an ALPN extension). + */ + const char **protocol_names; + uint16_t protocol_names_num; + uint16_t selected_protocol; + + /* + * Pointers to implementations; left to NULL for unsupported + * functions. For the raw hash functions, implementations are + * referenced from the multihasher (mhash field). + */ + br_tls_prf_impl prf10; + br_tls_prf_impl prf_sha256; + br_tls_prf_impl prf_sha384; + const br_block_cbcenc_class *iaes_cbcenc; + const br_block_cbcdec_class *iaes_cbcdec; + const br_block_ctr_class *iaes_ctr; + const br_block_ctrcbc_class *iaes_ctrcbc; + const br_block_cbcenc_class *ides_cbcenc; + const br_block_cbcdec_class *ides_cbcdec; + br_ghash ighash; + br_chacha20_run ichacha; + br_poly1305_run ipoly; + const br_sslrec_in_cbc_class *icbc_in; + const br_sslrec_out_cbc_class *icbc_out; + const br_sslrec_in_gcm_class *igcm_in; + const br_sslrec_out_gcm_class *igcm_out; + const br_sslrec_in_chapol_class *ichapol_in; + const br_sslrec_out_chapol_class *ichapol_out; + const br_sslrec_in_ccm_class *iccm_in; + const br_sslrec_out_ccm_class *iccm_out; + const br_ec_impl *iec; + br_rsa_pkcs1_vrfy irsavrfy; + br_ecdsa_vrfy iecdsa; +#endif +} br_ssl_engine_context; + +/** + * \brief Get currently defined engine behavioural flags. + * + * \param cc SSL engine context. + * \return the flags. + */ +static inline uint32_t +br_ssl_engine_get_flags(br_ssl_engine_context *cc) +{ + return cc->flags; +} + +/** + * \brief Set all engine behavioural flags. + * + * \param cc SSL engine context. + * \param flags new value for all flags. + */ +static inline void +br_ssl_engine_set_all_flags(br_ssl_engine_context *cc, uint32_t flags) +{ + cc->flags = flags; +} + +/** + * \brief Set some engine behavioural flags. + * + * The flags set in the `flags` parameter are set in the context; other + * flags are untouched. + * + * \param cc SSL engine context. + * \param flags additional set flags. + */ +static inline void +br_ssl_engine_add_flags(br_ssl_engine_context *cc, uint32_t flags) +{ + cc->flags |= flags; +} + +/** + * \brief Clear some engine behavioural flags. + * + * The flags set in the `flags` parameter are cleared from the context; other + * flags are untouched. + * + * \param cc SSL engine context. + * \param flags flags to remove. + */ +static inline void +br_ssl_engine_remove_flags(br_ssl_engine_context *cc, uint32_t flags) +{ + cc->flags &= ~flags; +} + +/** + * \brief Behavioural flag: enforce server preferences. + * + * If this flag is set, then the server will enforce its own cipher suite + * preference order; otherwise, it follows the client preferences. + */ +#define BR_OPT_ENFORCE_SERVER_PREFERENCES ((uint32_t)1 << 0) + +/** + * \brief Behavioural flag: disable renegotiation. + * + * If this flag is set, then renegotiations are rejected unconditionally: + * they won't be honoured if asked for programmatically, and requests from + * the peer are rejected. + */ +#define BR_OPT_NO_RENEGOTIATION ((uint32_t)1 << 1) + +/** + * \brief Behavioural flag: tolerate lack of client authentication. + * + * If this flag is set in a server and the server requests a client + * certificate, but the authentication fails (the client does not send + * a certificate, or the client's certificate chain cannot be validated), + * then the connection keeps on. Without this flag, a failed client + * authentication terminates the connection. + * + * Notes: + * + * - If the client's certificate can be validated and its public key is + * supported, then a wrong signature value terminates the connection + * regardless of that flag. + * + * - If using full-static ECDH, then a failure to validate the client's + * certificate prevents the handshake from succeeding. + */ +#define BR_OPT_TOLERATE_NO_CLIENT_AUTH ((uint32_t)1 << 2) + +/** + * \brief Behavioural flag: fail on application protocol mismatch. + * + * The ALPN extension ([RFC 7301](https://tools.ietf.org/html/rfc7301)) + * allows the client to send a list of application protocol names, and + * the server to select one. A mismatch is one of the following occurrences: + * + * - On the client: the client sends a list of names, the server + * responds with a protocol name which is _not_ part of the list of + * names sent by the client. + * + * - On the server: the client sends a list of names, and the server + * is also configured with a list of names, but there is no common + * protocol name between the two lists. + * + * Normal behaviour in case of mismatch is to report no matching name + * (`br_ssl_engine_get_selected_protocol()` returns `NULL`) and carry on. + * If the flag is set, then a mismatch implies a protocol failure (if + * the mismatch is detected by the server, it will send a fatal alert). + * + * Note: even with this flag, `br_ssl_engine_get_selected_protocol()` + * may still return `NULL` if the client or the server does not send an + * ALPN extension at all. + */ +#define BR_OPT_FAIL_ON_ALPN_MISMATCH ((uint32_t)1 << 3) + +/** + * \brief Set the minimum and maximum supported protocol versions. + * + * The two provided versions MUST be supported by the implementation + * (i.e. TLS 1.0, 1.1 and 1.2), and `version_max` MUST NOT be lower + * than `version_min`. + * + * \param cc SSL engine context. + * \param version_min minimum supported TLS version. + * \param version_max maximum supported TLS version. + */ +static inline void +br_ssl_engine_set_versions(br_ssl_engine_context *cc, + unsigned version_min, unsigned version_max) +{ + cc->version_min = (uint16_t)version_min; + cc->version_max = (uint16_t)version_max; +} + +/** + * \brief Set the list of cipher suites advertised by this context. + * + * The provided array is copied into the context. It is the caller + * responsibility to ensure that all provided suites will be supported + * by the context. The engine context has enough room to receive _all_ + * suites supported by the implementation. The provided array MUST NOT + * contain duplicates. + * + * If the engine is for a client, the "signaling" pseudo-cipher suite + * `TLS_FALLBACK_SCSV` can be added at the end of the list, if the + * calling application is performing a voluntary downgrade (voluntary + * downgrades are not recommended, but if such a downgrade is done, then + * adding the fallback pseudo-suite is a good idea). + * + * \param cc SSL engine context. + * \param suites cipher suites. + * \param suites_num number of cipher suites. + */ +void br_ssl_engine_set_suites(br_ssl_engine_context *cc, + const uint16_t *suites, size_t suites_num); + +/** + * \brief Set the X.509 engine. + * + * The caller shall ensure that the X.509 engine is properly initialised. + * + * \param cc SSL engine context. + * \param x509ctx X.509 certificate validation context. + */ +static inline void +br_ssl_engine_set_x509(br_ssl_engine_context *cc, const br_x509_class **x509ctx) +{ + cc->x509ctx = x509ctx; +} + +/** + * \brief Set the supported protocol names. + * + * Protocol names are part of the ALPN extension ([RFC + * 7301](https://tools.ietf.org/html/rfc7301)). Each protocol name is a + * character string, containing no more than 255 characters (256 with the + * terminating zero). When names are set, then: + * + * - The client will send an ALPN extension, containing the names. If + * the server responds with an ALPN extension, the client will verify + * that the response contains one of its name, and report that name + * through `br_ssl_engine_get_selected_protocol()`. + * + * - The server will parse incoming ALPN extension (from clients), and + * try to find a common protocol; if none is found, the connection + * is aborted with a fatal alert. On match, a response ALPN extension + * is sent, and name is reported through + * `br_ssl_engine_get_selected_protocol()`. + * + * The provided array is linked in, and must remain valid while the + * connection is live. + * + * Names MUST NOT be empty. Names MUST NOT be longer than 255 characters + * (excluding the terminating 0). + * + * \param ctx SSL engine context. + * \param names list of protocol names (zero-terminated). + * \param num number of protocol names (MUST be 1 or more). + */ +static inline void +br_ssl_engine_set_protocol_names(br_ssl_engine_context *ctx, + const char **names, size_t num) +{ + ctx->protocol_names = names; + ctx->protocol_names_num = (uint16_t)num; +} + +/** + * \brief Get the selected protocol. + * + * If this context was initialised with a non-empty list of protocol + * names, and both client and server sent ALPN extensions during the + * handshake, and a common name was found, then that name is returned. + * Otherwise, `NULL` is returned. + * + * The returned pointer is one of the pointers provided to the context + * with `br_ssl_engine_set_protocol_names()`. + * + * \return the selected protocol, or `NULL`. + */ +static inline const char * +br_ssl_engine_get_selected_protocol(br_ssl_engine_context *ctx) +{ + unsigned k; + + k = ctx->selected_protocol; + return (k == 0 || k == 0xFFFF) ? NULL : ctx->protocol_names[k - 1]; +} + +/** + * \brief Set a hash function implementation (by ID). + * + * Hash functions set with this call will be used for SSL/TLS specific + * usages, not X.509 certificate validation. Only "standard" hash functions + * may be set (MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512). If `impl` + * is `NULL`, then the hash function support is removed, not added. + * + * \param ctx SSL engine context. + * \param id hash function identifier. + * \param impl hash function implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_hash(br_ssl_engine_context *ctx, + int id, const br_hash_class *impl) +{ + br_multihash_setimpl(&ctx->mhash, id, impl); +} + +/** + * \brief Get a hash function implementation (by ID). + * + * This function retrieves a hash function implementation which was + * set with `br_ssl_engine_set_hash()`. + * + * \param ctx SSL engine context. + * \param id hash function identifier. + * \return the hash function implementation (or `NULL`). + */ +static inline const br_hash_class * +br_ssl_engine_get_hash(br_ssl_engine_context *ctx, int id) +{ + return br_multihash_getimpl(&ctx->mhash, id); +} + +/** + * \brief Set the PRF implementation (for TLS 1.0 and 1.1). + * + * This function sets (or removes, if `impl` is `NULL`) the implementation + * for the PRF used in TLS 1.0 and 1.1. + * + * \param cc SSL engine context. + * \param impl PRF implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_prf10(br_ssl_engine_context *cc, br_tls_prf_impl impl) +{ + cc->prf10 = impl; +} + +/** + * \brief Set the PRF implementation with SHA-256 (for TLS 1.2). + * + * This function sets (or removes, if `impl` is `NULL`) the implementation + * for the SHA-256 variant of the PRF used in TLS 1.2. + * + * \param cc SSL engine context. + * \param impl PRF implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_prf_sha256(br_ssl_engine_context *cc, br_tls_prf_impl impl) +{ + cc->prf_sha256 = impl; +} + +/** + * \brief Set the PRF implementation with SHA-384 (for TLS 1.2). + * + * This function sets (or removes, if `impl` is `NULL`) the implementation + * for the SHA-384 variant of the PRF used in TLS 1.2. + * + * \param cc SSL engine context. + * \param impl PRF implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_prf_sha384(br_ssl_engine_context *cc, br_tls_prf_impl impl) +{ + cc->prf_sha384 = impl; +} + +/** + * \brief Set the AES/CBC implementations. + * + * \param cc SSL engine context. + * \param impl_enc AES/CBC encryption implementation (or `NULL`). + * \param impl_dec AES/CBC decryption implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_aes_cbc(br_ssl_engine_context *cc, + const br_block_cbcenc_class *impl_enc, + const br_block_cbcdec_class *impl_dec) +{ + cc->iaes_cbcenc = impl_enc; + cc->iaes_cbcdec = impl_dec; +} + +/** + * \brief Set the "default" AES/CBC implementations. + * + * This function configures in the engine the AES implementations that + * should provide best runtime performance on the local system, while + * still being safe (in particular, constant-time). It also sets the + * handlers for CBC records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_aes_cbc(br_ssl_engine_context *cc); + +/** + * \brief Set the AES/CTR implementation. + * + * \param cc SSL engine context. + * \param impl AES/CTR encryption/decryption implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_aes_ctr(br_ssl_engine_context *cc, + const br_block_ctr_class *impl) +{ + cc->iaes_ctr = impl; +} + +/** + * \brief Set the "default" implementations for AES/GCM (AES/CTR + GHASH). + * + * This function configures in the engine the AES/CTR and GHASH + * implementation that should provide best runtime performance on the local + * system, while still being safe (in particular, constant-time). It also + * sets the handlers for GCM records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_aes_gcm(br_ssl_engine_context *cc); + +/** + * \brief Set the DES/CBC implementations. + * + * \param cc SSL engine context. + * \param impl_enc DES/CBC encryption implementation (or `NULL`). + * \param impl_dec DES/CBC decryption implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_des_cbc(br_ssl_engine_context *cc, + const br_block_cbcenc_class *impl_enc, + const br_block_cbcdec_class *impl_dec) +{ + cc->ides_cbcenc = impl_enc; + cc->ides_cbcdec = impl_dec; +} + +/** + * \brief Set the "default" DES/CBC implementations. + * + * This function configures in the engine the DES implementations that + * should provide best runtime performance on the local system, while + * still being safe (in particular, constant-time). It also sets the + * handlers for CBC records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc); + +/** + * \brief Set the GHASH implementation (used in GCM mode). + * + * \param cc SSL engine context. + * \param impl GHASH implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_ghash(br_ssl_engine_context *cc, br_ghash impl) +{ + cc->ighash = impl; +} + +/** + * \brief Set the ChaCha20 implementation. + * + * \param cc SSL engine context. + * \param ichacha ChaCha20 implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_chacha20(br_ssl_engine_context *cc, + br_chacha20_run ichacha) +{ + cc->ichacha = ichacha; +} + +/** + * \brief Set the Poly1305 implementation. + * + * \param cc SSL engine context. + * \param ipoly Poly1305 implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_poly1305(br_ssl_engine_context *cc, + br_poly1305_run ipoly) +{ + cc->ipoly = ipoly; +} + +/** + * \brief Set the "default" ChaCha20 and Poly1305 implementations. + * + * This function configures in the engine the ChaCha20 and Poly1305 + * implementations that should provide best runtime performance on the + * local system, while still being safe (in particular, constant-time). + * It also sets the handlers for ChaCha20+Poly1305 records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_chapol(br_ssl_engine_context *cc); + +/** + * \brief Set the AES/CTR+CBC implementation. + * + * \param cc SSL engine context. + * \param impl AES/CTR+CBC encryption/decryption implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_aes_ctrcbc(br_ssl_engine_context *cc, + const br_block_ctrcbc_class *impl) +{ + cc->iaes_ctrcbc = impl; +} + +/** + * \brief Set the "default" implementations for AES/CCM. + * + * This function configures in the engine the AES/CTR+CBC + * implementation that should provide best runtime performance on the local + * system, while still being safe (in particular, constant-time). It also + * sets the handlers for CCM records. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_aes_ccm(br_ssl_engine_context *cc); + +/** + * \brief Set the record encryption and decryption engines for CBC + HMAC. + * + * \param cc SSL engine context. + * \param impl_in record CBC decryption implementation (or `NULL`). + * \param impl_out record CBC encryption implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_cbc(br_ssl_engine_context *cc, + const br_sslrec_in_cbc_class *impl_in, + const br_sslrec_out_cbc_class *impl_out) +{ + cc->icbc_in = impl_in; + cc->icbc_out = impl_out; +} + +/** + * \brief Set the record encryption and decryption engines for GCM. + * + * \param cc SSL engine context. + * \param impl_in record GCM decryption implementation (or `NULL`). + * \param impl_out record GCM encryption implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_gcm(br_ssl_engine_context *cc, + const br_sslrec_in_gcm_class *impl_in, + const br_sslrec_out_gcm_class *impl_out) +{ + cc->igcm_in = impl_in; + cc->igcm_out = impl_out; +} + +/** + * \brief Set the record encryption and decryption engines for CCM. + * + * \param cc SSL engine context. + * \param impl_in record CCM decryption implementation (or `NULL`). + * \param impl_out record CCM encryption implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_ccm(br_ssl_engine_context *cc, + const br_sslrec_in_ccm_class *impl_in, + const br_sslrec_out_ccm_class *impl_out) +{ + cc->iccm_in = impl_in; + cc->iccm_out = impl_out; +} + +/** + * \brief Set the record encryption and decryption engines for + * ChaCha20+Poly1305. + * + * \param cc SSL engine context. + * \param impl_in record ChaCha20 decryption implementation (or `NULL`). + * \param impl_out record ChaCha20 encryption implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_chapol(br_ssl_engine_context *cc, + const br_sslrec_in_chapol_class *impl_in, + const br_sslrec_out_chapol_class *impl_out) +{ + cc->ichapol_in = impl_in; + cc->ichapol_out = impl_out; +} + +/** + * \brief Set the EC implementation. + * + * The elliptic curve implementation will be used for ECDH and ECDHE + * cipher suites, and for ECDSA support. + * + * \param cc SSL engine context. + * \param iec EC implementation (or `NULL`). + */ +static inline void +br_ssl_engine_set_ec(br_ssl_engine_context *cc, const br_ec_impl *iec) +{ + cc->iec = iec; +} + +/** + * \brief Set the "default" EC implementation. + * + * This function sets the elliptic curve implementation for ECDH and + * ECDHE cipher suites, and for ECDSA support. It selects the fastest + * implementation on the current system. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_ec(br_ssl_engine_context *cc); + +/** + * \brief Get the EC implementation configured in the provided engine. + * + * \param cc SSL engine context. + * \return the EC implementation. + */ +static inline const br_ec_impl * +br_ssl_engine_get_ec(br_ssl_engine_context *cc) +{ + return cc->iec; +} + +/** + * \brief Set the RSA signature verification implementation. + * + * On the client, this is used to verify the server's signature on its + * ServerKeyExchange message (for ECDHE_RSA cipher suites). On the server, + * this is used to verify the client's CertificateVerify message (if a + * client certificate is requested, and that certificate contains a RSA key). + * + * \param cc SSL engine context. + * \param irsavrfy RSA signature verification implementation. + */ +static inline void +br_ssl_engine_set_rsavrfy(br_ssl_engine_context *cc, br_rsa_pkcs1_vrfy irsavrfy) +{ + cc->irsavrfy = irsavrfy; +} + +/** + * \brief Set the "default" RSA implementation (signature verification). + * + * This function sets the RSA implementation (signature verification) + * to the fastest implementation available on the current platform. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_rsavrfy(br_ssl_engine_context *cc); + +/** + * \brief Get the RSA implementation (signature verification) configured + * in the provided engine. + * + * \param cc SSL engine context. + * \return the RSA signature verification implementation. + */ +static inline br_rsa_pkcs1_vrfy +br_ssl_engine_get_rsavrfy(br_ssl_engine_context *cc) +{ + return cc->irsavrfy; +} + +/* + * \brief Set the ECDSA implementation (signature verification). + * + * On the client, this is used to verify the server's signature on its + * ServerKeyExchange message (for ECDHE_ECDSA cipher suites). On the server, + * this is used to verify the client's CertificateVerify message (if a + * client certificate is requested, that certificate contains an EC key, + * and full-static ECDH is not used). + * + * The ECDSA implementation will use the EC core implementation configured + * in the engine context. + * + * \param cc client context. + * \param iecdsa ECDSA verification implementation. + */ +static inline void +br_ssl_engine_set_ecdsa(br_ssl_engine_context *cc, br_ecdsa_vrfy iecdsa) +{ + cc->iecdsa = iecdsa; +} + +/** + * \brief Set the "default" ECDSA implementation (signature verification). + * + * This function sets the ECDSA implementation (signature verification) + * to the fastest implementation available on the current platform. This + * call also sets the elliptic curve implementation itself, there again + * to the fastest EC implementation available. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_set_default_ecdsa(br_ssl_engine_context *cc); + +/** + * \brief Get the ECDSA implementation (signature verification) configured + * in the provided engine. + * + * \param cc SSL engine context. + * \return the ECDSA signature verification implementation. + */ +static inline br_ecdsa_vrfy +br_ssl_engine_get_ecdsa(br_ssl_engine_context *cc) +{ + return cc->iecdsa; +} + +/** + * \brief Set the I/O buffer for the SSL engine. + * + * Once this call has been made, `br_ssl_client_reset()` or + * `br_ssl_server_reset()` MUST be called before using the context. + * + * The provided buffer will be used as long as the engine context is + * used. The caller is responsible for keeping it available. + * + * If `bidi` is 0, then the engine will operate in half-duplex mode + * (it won't be able to send data while there is unprocessed incoming + * data in the buffer, and it won't be able to receive data while there + * is unsent data in the buffer). The optimal buffer size in half-duplex + * mode is `BR_SSL_BUFSIZE_MONO`; if the buffer is larger, then extra + * bytes are ignored. If the buffer is smaller, then this limits the + * capacity of the engine to support all allowed record sizes. + * + * If `bidi` is 1, then the engine will split the buffer into two + * parts, for separate handling of outgoing and incoming data. This + * enables full-duplex processing, but requires more RAM. The optimal + * buffer size in full-duplex mode is `BR_SSL_BUFSIZE_BIDI`; if the + * buffer is larger, then extra bytes are ignored. If the buffer is + * smaller, then the split will favour the incoming part, so that + * interoperability is maximised. + * + * \param cc SSL engine context + * \param iobuf I/O buffer. + * \param iobuf_len I/O buffer length (in bytes). + * \param bidi non-zero for full-duplex mode. + */ +void br_ssl_engine_set_buffer(br_ssl_engine_context *cc, + void *iobuf, size_t iobuf_len, int bidi); + +/** + * \brief Set the I/O buffers for the SSL engine. + * + * Once this call has been made, `br_ssl_client_reset()` or + * `br_ssl_server_reset()` MUST be called before using the context. + * + * This function is similar to `br_ssl_engine_set_buffer()`, except + * that it enforces full-duplex mode, and the two I/O buffers are + * provided as separate chunks. + * + * The macros `BR_SSL_BUFSIZE_INPUT` and `BR_SSL_BUFSIZE_OUTPUT` + * evaluate to the optimal (maximum) sizes for the input and output + * buffer, respectively. + * + * \param cc SSL engine context + * \param ibuf input buffer. + * \param ibuf_len input buffer length (in bytes). + * \param obuf output buffer. + * \param obuf_len output buffer length (in bytes). + */ +void br_ssl_engine_set_buffers_bidi(br_ssl_engine_context *cc, + void *ibuf, size_t ibuf_len, void *obuf, size_t obuf_len); + +/** + * \brief Determine if MFLN negotiation was successful + * + * \param cc SSL engine context. + */ +static inline uint8_t +br_ssl_engine_get_mfln_negotiated(br_ssl_engine_context *cc) +{ + return cc->max_frag_len_negotiated; +} + +/** + * \brief Inject some "initial entropy" in the context. + * + * This entropy will be added to what can be obtained from the + * underlying operating system, if that OS is supported. + * + * This function may be called several times; all injected entropy chunks + * are cumulatively mixed. + * + * If entropy gathering from the OS is supported and compiled in, then this + * step is optional. Otherwise, it is mandatory to inject randomness, and + * the caller MUST take care to push (as one or several successive calls) + * enough entropy to achieve cryptographic resistance (at least 80 bits, + * preferably 128 or more). The engine will report an error if no entropy + * was provided and none can be obtained from the OS. + * + * Take care that this function cannot assess the cryptographic quality of + * the provided bytes. + * + * In all generality, "entropy" must here be considered to mean "that + * which the attacker cannot predict". If your OS/architecture does not + * have a suitable source of randomness, then you can make do with the + * combination of a large enough secret value (possibly a copy of an + * asymmetric private key that you also store on the system) AND a + * non-repeating value (e.g. current time, provided that the local clock + * cannot be reset or altered by the attacker). + * + * \param cc SSL engine context. + * \param data extra entropy to inject. + * \param len length of the extra data (in bytes). + */ +void br_ssl_engine_inject_entropy(br_ssl_engine_context *cc, + const void *data, size_t len); + +/** + * \brief Get the "server name" in this engine. + * + * For clients, this is the name provided with `br_ssl_client_reset()`; + * for servers, this is the name received from the client as part of the + * ClientHello message. If there is no such name (e.g. the client did + * not send an SNI extension) then the returned string is empty + * (returned pointer points to a byte of value 0). + * + * The returned pointer refers to a buffer inside the context, which may + * be overwritten as part of normal SSL activity (even within the same + * connection, if a renegotiation occurs). + * + * \param cc SSL engine context. + * \return the server name (possibly empty). + */ +static inline const char * +br_ssl_engine_get_server_name(const br_ssl_engine_context *cc) +{ + return cc->server_name; +} + +/** + * \brief Get the protocol version. + * + * This function returns the protocol version that is used by the + * engine. That value is set after sending (for a server) or receiving + * (for a client) the ServerHello message. + * + * \param cc SSL engine context. + * \return the protocol version. + */ +static inline unsigned +br_ssl_engine_get_version(const br_ssl_engine_context *cc) +{ + return cc->session.version; +} + +/** + * \brief Get a copy of the session parameters. + * + * The session parameters are filled during the handshake, so this + * function shall not be called before completion of the handshake. + * The initial handshake is completed when the context first allows + * application data to be injected. + * + * This function copies the current session parameters into the provided + * structure. Beware that the session parameters include the master + * secret, which is sensitive data, to handle with great care. + * + * \param cc SSL engine context. + * \param pp destination structure for the session parameters. + */ +static inline void +br_ssl_engine_get_session_parameters(const br_ssl_engine_context *cc, + br_ssl_session_parameters *pp) +{ + memcpy(pp, &cc->session, sizeof *pp); +} + +/** + * \brief Set the session parameters to the provided values. + * + * This function is meant to be used in the client, before doing a new + * handshake; a session resumption will be attempted with these + * parameters. In the server, this function has no effect. + * + * \param cc SSL engine context. + * \param pp source structure for the session parameters. + */ +static inline void +br_ssl_engine_set_session_parameters(br_ssl_engine_context *cc, + const br_ssl_session_parameters *pp) +{ + memcpy(&cc->session, pp, sizeof *pp); +} + +/** + * \brief Get identifier for the curve used for key exchange. + * + * If the cipher suite uses ECDHE, then this function returns the + * identifier for the curve used for transient parameters. This is + * defined during the course of the handshake, when the ServerKeyExchange + * is sent (on the server) or received (on the client). If the + * cipher suite does not use ECDHE (e.g. static ECDH, or RSA key + * exchange), then this value is indeterminate. + * + * @param cc SSL engine context. + * @return the ECDHE curve identifier. + */ +static inline int +br_ssl_engine_get_ecdhe_curve(br_ssl_engine_context *cc) +{ + return cc->ecdhe_curve; +} + +/** + * \brief Get the current engine state. + * + * An SSL engine (client or server) has, at any time, a state which is + * the combination of zero, one or more of these flags: + * + * - `BR_SSL_CLOSED` + * + * Engine is finished, no more I/O (until next reset). + * + * - `BR_SSL_SENDREC` + * + * Engine has some bytes to send to the peer. + * + * - `BR_SSL_RECVREC` + * + * Engine expects some bytes from the peer. + * + * - `BR_SSL_SENDAPP` + * + * Engine may receive application data to send (or flush). + * + * - `BR_SSL_RECVAPP` + * + * Engine has obtained some application data from the peer, + * that should be read by the caller. + * + * If no flag at all is set (state value is 0), then the engine is not + * fully initialised yet. + * + * The `BR_SSL_CLOSED` flag is exclusive; when it is set, no other flag + * is set. To distinguish between a normal closure and an error, use + * `br_ssl_engine_last_error()`. + * + * Generally speaking, `BR_SSL_SENDREC` and `BR_SSL_SENDAPP` are mutually + * exclusive: the input buffer, at any point, either accumulates + * plaintext data, or contains an assembled record that is being sent. + * Similarly, `BR_SSL_RECVREC` and `BR_SSL_RECVAPP` are mutually exclusive. + * This may change in a future library version. + * + * \param cc SSL engine context. + * \return the current engine state. + */ +unsigned br_ssl_engine_current_state(const br_ssl_engine_context *cc); + +/** \brief SSL engine state: closed or failed. */ +#define BR_SSL_CLOSED 0x0001 +/** \brief SSL engine state: record data is ready to be sent to the peer. */ +#define BR_SSL_SENDREC 0x0002 +/** \brief SSL engine state: engine may receive records from the peer. */ +#define BR_SSL_RECVREC 0x0004 +/** \brief SSL engine state: engine may accept application data to send. */ +#define BR_SSL_SENDAPP 0x0008 +/** \brief SSL engine state: engine has received application data. */ +#define BR_SSL_RECVAPP 0x0010 + +/** + * \brief Get the engine error indicator. + * + * The error indicator is `BR_ERR_OK` (0) if no error was encountered + * since the last call to `br_ssl_client_reset()` or + * `br_ssl_server_reset()`. Other status values are "sticky": they + * remain set, and prevent all I/O activity, until cleared. Only the + * reset calls clear the error indicator. + * + * \param cc SSL engine context. + * \return 0, or a non-zero error code. + */ +static inline int +br_ssl_engine_last_error(const br_ssl_engine_context *cc) +{ + return cc->err; +} + +/* + * There are four I/O operations, each identified by a symbolic name: + * + * sendapp inject application data in the engine + * recvapp retrieving application data from the engine + * sendrec sending records on the transport medium + * recvrec receiving records from the transport medium + * + * Terminology works thus: in a layered model where the SSL engine sits + * between the application and the network, "send" designates operations + * where bytes flow from application to network, and "recv" for the + * reverse operation. Application data (the plaintext that is to be + * conveyed through SSL) is "app", while encrypted records are "rec". + * Note that from the SSL engine point of view, "sendapp" and "recvrec" + * designate bytes that enter the engine ("inject" operation), while + * "recvapp" and "sendrec" designate bytes that exit the engine + * ("extract" operation). + * + * For the operation 'xxx', two functions are defined: + * + * br_ssl_engine_xxx_buf + * Returns a pointer and length to the buffer to use for that + * operation. '*len' is set to the number of bytes that may be read + * from the buffer (extract operation) or written to the buffer + * (inject operation). If no byte may be exchanged for that operation + * at that point, then '*len' is set to zero, and NULL is returned. + * The engine state is unmodified by this call. + * + * br_ssl_engine_xxx_ack + * Informs the engine that 'len' bytes have been read from the buffer + * (extract operation) or written to the buffer (inject operation). + * The 'len' value MUST NOT be zero. The 'len' value MUST NOT exceed + * that which was obtained from a preceding br_ssl_engine_xxx_buf() + * call. + */ + +/** + * \brief Get buffer for application data to send. + * + * If the engine is ready to accept application data to send to the + * peer, then this call returns a pointer to the buffer where such + * data shall be written, and its length is written in `*len`. + * Otherwise, `*len` is set to 0 and `NULL` is returned. + * + * \param cc SSL engine context. + * \param len receives the application data output buffer length, or 0. + * \return the application data output buffer, or `NULL`. + */ +unsigned char *br_ssl_engine_sendapp_buf( + const br_ssl_engine_context *cc, size_t *len); + +/** + * \brief Inform the engine of some new application data. + * + * After writing `len` bytes in the buffer returned by + * `br_ssl_engine_sendapp_buf()`, the application shall call this + * function to trigger any relevant processing. The `len` parameter + * MUST NOT be 0, and MUST NOT exceed the value obtained in the + * `br_ssl_engine_sendapp_buf()` call. + * + * \param cc SSL engine context. + * \param len number of bytes pushed (not zero). + */ +void br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len); + +/** + * \brief Get buffer for received application data. + * + * If the engine has received application data from the peer, then this + * call returns a pointer to the buffer from where such data shall be + * read, and its length is written in `*len`. Otherwise, `*len` is set + * to 0 and `NULL` is returned. + * + * \param cc SSL engine context. + * \param len receives the application data input buffer length, or 0. + * \return the application data input buffer, or `NULL`. + */ +unsigned char *br_ssl_engine_recvapp_buf( + const br_ssl_engine_context *cc, size_t *len); + +/** + * \brief Acknowledge some received application data. + * + * After reading `len` bytes from the buffer returned by + * `br_ssl_engine_recvapp_buf()`, the application shall call this + * function to trigger any relevant processing. The `len` parameter + * MUST NOT be 0, and MUST NOT exceed the value obtained in the + * `br_ssl_engine_recvapp_buf()` call. + * + * \param cc SSL engine context. + * \param len number of bytes read (not zero). + */ +void br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len); + +/** + * \brief Get buffer for record data to send. + * + * If the engine has prepared some records to send to the peer, then this + * call returns a pointer to the buffer from where such data shall be + * read, and its length is written in `*len`. Otherwise, `*len` is set + * to 0 and `NULL` is returned. + * + * \param cc SSL engine context. + * \param len receives the record data output buffer length, or 0. + * \return the record data output buffer, or `NULL`. + */ +unsigned char *br_ssl_engine_sendrec_buf( + const br_ssl_engine_context *cc, size_t *len); + +/** + * \brief Acknowledge some sent record data. + * + * After reading `len` bytes from the buffer returned by + * `br_ssl_engine_sendrec_buf()`, the application shall call this + * function to trigger any relevant processing. The `len` parameter + * MUST NOT be 0, and MUST NOT exceed the value obtained in the + * `br_ssl_engine_sendrec_buf()` call. + * + * \param cc SSL engine context. + * \param len number of bytes read (not zero). + */ +void br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len); + +/** + * \brief Get buffer for incoming records. + * + * If the engine is ready to accept records from the peer, then this + * call returns a pointer to the buffer where such data shall be + * written, and its length is written in `*len`. Otherwise, `*len` is + * set to 0 and `NULL` is returned. + * + * \param cc SSL engine context. + * \param len receives the record data input buffer length, or 0. + * \return the record data input buffer, or `NULL`. + */ +unsigned char *br_ssl_engine_recvrec_buf( + const br_ssl_engine_context *cc, size_t *len); + +/** + * \brief Inform the engine of some new record data. + * + * After writing `len` bytes in the buffer returned by + * `br_ssl_engine_recvrec_buf()`, the application shall call this + * function to trigger any relevant processing. The `len` parameter + * MUST NOT be 0, and MUST NOT exceed the value obtained in the + * `br_ssl_engine_recvrec_buf()` call. + * + * \param cc SSL engine context. + * \param len number of bytes pushed (not zero). + */ +void br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len); + +/** + * \brief Flush buffered application data. + * + * If some application data has been buffered in the engine, then wrap + * it into a record and mark it for sending. If no application data has + * been buffered but the engine would be ready to accept some, AND the + * `force` parameter is non-zero, then an empty record is assembled and + * marked for sending. In all other cases, this function does nothing. + * + * Empty records are technically legal, but not all existing SSL/TLS + * implementations support them. Empty records can be useful as a + * transparent "keep-alive" mechanism to maintain some low-level + * network activity. + * + * \param cc SSL engine context. + * \param force non-zero to force sending an empty record. + */ +void br_ssl_engine_flush(br_ssl_engine_context *cc, int force); + +/** + * \brief Initiate a closure. + * + * If, at that point, the context is open and in ready state, then a + * `close_notify` alert is assembled and marked for sending; this + * triggers the closure protocol. Otherwise, no such alert is assembled. + * + * \param cc SSL engine context. + */ +void br_ssl_engine_close(br_ssl_engine_context *cc); + +/** + * \brief Initiate a renegotiation. + * + * If the engine is failed or closed, or if the peer is known not to + * support secure renegotiation (RFC 5746), or if renegotiations have + * been disabled with the `BR_OPT_NO_RENEGOTIATION` flag, or if there + * is buffered incoming application data, then this function returns 0 + * and nothing else happens. + * + * Otherwise, this function returns 1, and a renegotiation attempt is + * triggered (if a handshake is already ongoing at that point, then + * no new handshake is triggered). + * + * \param cc SSL engine context. + * \return 1 on success, 0 on error. + */ +int br_ssl_engine_renegotiate(br_ssl_engine_context *cc); + +/** + * \brief Export key material from a connected SSL engine (RFC 5705). + * + * This calls compute a secret key of arbitrary length from the master + * secret of a connected SSL engine. If the provided context is not + * currently in "application data" state (initial handshake is not + * finished, another handshake is ongoing, or the connection failed or + * was closed), then this function returns 0. Otherwise, a secret key of + * length `len` bytes is computed and written in the buffer pointed to + * by `dst`, and 1 is returned. + * + * The computed key follows the specification described in RFC 5705. + * That RFC includes two key computations, with and without a "context + * value". If `context` is `NULL`, then the variant without context is + * used; otherwise, the `context_len` bytes located at the address + * pointed to by `context` are used in the computation. Note that it + * is possible to have a "with context" key with a context length of + * zero bytes, by setting `context` to a non-`NULL` value but + * `context_len` to 0. + * + * When context bytes are used, the context length MUST NOT exceed + * 65535 bytes. + * + * \param cc SSL engine context. + * \param dst destination buffer for exported key. + * \param len exported key length (in bytes). + * \param label disambiguation label. + * \param context context value (or `NULL`). + * \param context_len context length (in bytes). + * \return 1 on success, 0 on error. + */ +int br_ssl_key_export(br_ssl_engine_context *cc, + void *dst, size_t len, const char *label, + const void *context, size_t context_len); + +/* + * Pre-declaration for the SSL client context. + */ +typedef struct br_ssl_client_context_ br_ssl_client_context; + +/** + * \brief Type for the client certificate, if requested by the server. + */ +typedef struct { + /** + * \brief Authentication type. + * + * This is either `BR_AUTH_RSA` (RSA signature), `BR_AUTH_ECDSA` + * (ECDSA signature), or `BR_AUTH_ECDH` (static ECDH key exchange). + */ + int auth_type; + + /** + * \brief Hash function for computing the CertificateVerify. + * + * This is the symbolic identifier for the hash function that + * will be used to produce the hash of handshake messages, to + * be signed into the CertificateVerify. For full static ECDH + * (client and server certificates are both EC in the same + * curve, and static ECDH is used), this value is set to -1. + * + * Take care that with TLS 1.0 and 1.1, that value MUST match + * the protocol requirements: value must be 0 (MD5+SHA-1) for + * a RSA signature, or 2 (SHA-1) for an ECDSA signature. Only + * TLS 1.2 allows for other hash functions. + */ + int hash_id; + + /** + * \brief Certificate chain to send to the server. + * + * This is an array of `br_x509_certificate` objects, each + * normally containing a DER-encoded certificate. The client + * code does not try to decode these elements. If there is no + * chain to send to the server, then this pointer shall be + * set to `NULL`. + */ + const br_x509_certificate *chain; + + /** + * \brief Certificate chain length (number of certificates). + * + * If there is no chain to send to the server, then this value + * shall be set to 0. + */ + size_t chain_len; + +} br_ssl_client_certificate; + +/* + * Note: the constants below for signatures match the TLS constants. + */ + +/** \brief Client authentication type: static ECDH. */ +#define BR_AUTH_ECDH 0 +/** \brief Client authentication type: RSA signature. */ +#define BR_AUTH_RSA 1 +/** \brief Client authentication type: ECDSA signature. */ +#define BR_AUTH_ECDSA 3 + +/** + * \brief Class type for a certificate handler (client side). + * + * A certificate handler selects a client certificate chain to send to + * the server, upon explicit request from that server. It receives + * the list of trust anchor DN from the server, and supported types + * of certificates and signatures, and returns the chain to use. It + * is also invoked to perform the corresponding private key operation + * (a signature, or an ECDH computation). + * + * The SSL client engine will first push the trust anchor DN with + * `start_name_list()`, `start_name()`, `append_name()`, `end_name()` + * and `end_name_list()`. Then it will call `choose()`, to select the + * actual chain (and signature/hash algorithms). Finally, it will call + * either `do_sign()` or `do_keyx()`, depending on the algorithm choices. + */ +typedef struct br_ssl_client_certificate_class_ br_ssl_client_certificate_class; +struct br_ssl_client_certificate_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Begin reception of a list of trust anchor names. This + * is called while parsing the incoming CertificateRequest. + * + * \param pctx certificate handler context. + */ + void (*start_name_list)(const br_ssl_client_certificate_class **pctx); + + /** + * \brief Begin reception of a new trust anchor name. + * + * The total encoded name length is provided; it is less than + * 65535 bytes. + * + * \param pctx certificate handler context. + * \param len encoded name length (in bytes). + */ + void (*start_name)(const br_ssl_client_certificate_class **pctx, + size_t len); + + /** + * \brief Receive some more bytes for the current trust anchor name. + * + * The provided reference (`data`) points to a transient buffer + * they may be reused as soon as this function returns. The chunk + * length (`len`) is never zero. + * + * \param pctx certificate handler context. + * \param data anchor name chunk. + * \param len anchor name chunk length (in bytes). + */ + void (*append_name)(const br_ssl_client_certificate_class **pctx, + const unsigned char *data, size_t len); + + /** + * \brief End current trust anchor name. + * + * This function is called when all the encoded anchor name data + * has been provided. + * + * \param pctx certificate handler context. + */ + void (*end_name)(const br_ssl_client_certificate_class **pctx); + + /** + * \brief End list of trust anchor names. + * + * This function is called when all the anchor names in the + * CertificateRequest message have been obtained. + * + * \param pctx certificate handler context. + */ + void (*end_name_list)(const br_ssl_client_certificate_class **pctx); + + /** + * \brief Select client certificate and algorithms. + * + * This callback function shall fill the provided `choices` + * structure with the selected algorithms and certificate chain. + * The `hash_id`, `chain` and `chain_len` fields must be set. If + * the client cannot or does not wish to send a certificate, + * then it shall set `chain` to `NULL` and `chain_len` to 0. + * + * The `auth_types` parameter describes the authentication types, + * signature algorithms and hash functions that are supported by + * both the client context and the server, and compatible with + * the current protocol version. This is a bit field with the + * following contents: + * + * - If RSA signatures with hash function x are supported, then + * bit x is set. + * + * - If ECDSA signatures with hash function x are supported, + * then bit 8+x is set. + * + * - If static ECDH is supported, with a RSA-signed certificate, + * then bit 16 is set. + * + * - If static ECDH is supported, with an ECDSA-signed certificate, + * then bit 17 is set. + * + * Notes: + * + * - When using TLS 1.0 or 1.1, the hash function for RSA + * signatures is always the special MD5+SHA-1 (id 0), and the + * hash function for ECDSA signatures is always SHA-1 (id 2). + * + * - When using TLS 1.2, the list of hash functions is trimmed + * down to include only hash functions that the client context + * can support. The actual server list can be obtained with + * `br_ssl_client_get_server_hashes()`; that list may be used + * to select the certificate chain to send to the server. + * + * \param pctx certificate handler context. + * \param cc SSL client context. + * \param auth_types supported authentication types and algorithms. + * \param choices destination structure for the policy choices. + */ + void (*choose)(const br_ssl_client_certificate_class **pctx, + const br_ssl_client_context *cc, uint32_t auth_types, + br_ssl_client_certificate *choices); + + /** + * \brief Perform key exchange (client part). + * + * This callback is invoked in case of a full static ECDH key + * exchange: + * + * - the cipher suite uses `ECDH_RSA` or `ECDH_ECDSA`; + * + * - the server requests a client certificate; + * + * - the client has, and sends, a client certificate that + * uses an EC key in the same curve as the server's key, + * and chooses static ECDH (the `hash_id` field in the choice + * structure was set to -1). + * + * In that situation, this callback is invoked to compute the + * client-side ECDH: the provided `data` (of length `*len` bytes) + * is the server's public key point (as decoded from its + * certificate), and the client shall multiply that point with + * its own private key, and write back the X coordinate of the + * resulting point in the same buffer, starting at offset 0. + * The `*len` value shall be modified to designate the actual + * length of the X coordinate. + * + * The callback must uphold the following: + * + * - If the input array does not have the proper length for + * an encoded curve point, then an error (0) shall be reported. + * + * - If the input array has the proper length, then processing + * MUST be constant-time, even if the data is not a valid + * encoded point. + * + * - This callback MUST check that the input point is valid. + * + * Returned value is 1 on success, 0 on error. + * + * \param pctx certificate handler context. + * \param data server public key point. + * \param len public key point length / X coordinate length. + * \return 1 on success, 0 on error. + */ + uint32_t (*do_keyx)(const br_ssl_client_certificate_class **pctx, + unsigned char *data, size_t *len); + + /** + * \brief Perform a signature (client authentication). + * + * This callback is invoked when a client certificate was sent, + * and static ECDH is not used. It shall compute a signature, + * using the client's private key, over the provided hash value + * (which is the hash of all previous handshake messages). + * + * On input, the hash value to sign is in `data`, of size + * `hv_len`; the involved hash function is identified by + * `hash_id`. The signature shall be computed and written + * back into `data`; the total size of that buffer is `len` + * bytes. + * + * This callback shall verify that the signature length does not + * exceed `len` bytes, and abstain from writing the signature if + * it does not fit. + * + * For RSA signatures, the `hash_id` may be 0, in which case + * this is the special header-less signature specified in TLS 1.0 + * and 1.1, with a 36-byte hash value. Otherwise, normal PKCS#1 + * v1.5 signatures shall be computed. + * + * For ECDSA signatures, the signature value shall use the ASN.1 + * based encoding. + * + * Returned value is the signature length (in bytes), or 0 on error. + * + * \param pctx certificate handler context. + * \param hash_id hash function identifier. + * \param hv_len hash value length (in bytes). + * \param data input/output buffer (hash value, then signature). + * \param len total buffer length (in bytes). + * \return signature length (in bytes) on success, or 0 on error. + */ + size_t (*do_sign)(const br_ssl_client_certificate_class **pctx, + int hash_id, size_t hv_len, unsigned char *data, size_t len); +}; + +/** + * \brief A single-chain RSA client certificate handler. + * + * This handler uses a single certificate chain, with a RSA + * signature. The list of trust anchor DN is ignored. + * + * Apart from the first field (vtable pointer), its contents are + * opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_client_certificate_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + const br_x509_certificate *chain; + size_t chain_len; + const br_rsa_private_key *sk; + br_rsa_pkcs1_sign irsasign; +#endif +} br_ssl_client_certificate_rsa_context; + +/** + * \brief A single-chain EC client certificate handler. + * + * This handler uses a single certificate chain, with a RSA + * signature. The list of trust anchor DN is ignored. + * + * This handler may support both static ECDH, and ECDSA signatures + * (either usage may be selectively disabled). + * + * Apart from the first field (vtable pointer), its contents are + * opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_client_certificate_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + const br_x509_certificate *chain; + size_t chain_len; + const br_ec_private_key *sk; + unsigned allowed_usages; + unsigned issuer_key_type; + const br_multihash_context *mhash; + const br_ec_impl *iec; + br_ecdsa_sign iecdsa; +#endif +} br_ssl_client_certificate_ec_context; + +/** + * \brief Context structure for a SSL client. + * + * The first field (called `eng`) is the SSL engine; all functions that + * work on a `br_ssl_engine_context` structure shall take as parameter + * a pointer to that field. The other structure fields are opaque and + * must not be accessed directly. + */ +struct br_ssl_client_context_ { + /** + * \brief The encapsulated engine context. + */ + br_ssl_engine_context eng; + +#ifndef BR_DOXYGEN_IGNORE + /* + * Minimum ClientHello length; padding with an extension (RFC + * 7685) is added if necessary to match at least that length. + * Such padding is nominally unnecessary, but it has been used + * to work around some server implementation bugs. + */ + uint16_t min_clienthello_len; + + /* + * Bit field for algoithms (hash + signature) supported by the + * server when requesting a client certificate. + */ + uint32_t hashes; + + /* + * Server's public key curve. + */ + int server_curve; + + /* + * Context for certificate handler. + */ + const br_ssl_client_certificate_class **client_auth_vtable; + + /* + * Client authentication type. + */ + unsigned char auth_type; + + /* + * Hash function to use for the client signature. This is 0xFF + * if static ECDH is used. + */ + unsigned char hash_id; + + /* + * For the core certificate handlers, thus avoiding (in most + * cases) the need for an externally provided policy context. + */ + union { + const br_ssl_client_certificate_class *vtable; + br_ssl_client_certificate_rsa_context single_rsa; + br_ssl_client_certificate_ec_context single_ec; + } client_auth; + + /* + * Implementations. + */ + br_rsa_public irsapub; +#endif +}; + +/** + * \brief Get the hash functions and signature algorithms supported by + * the server. + * + * This value is a bit field: + * + * - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`, + * then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1, + * or 2 to 6 for the SHA family). + * + * - If ECDSA is supported with hash function of ID `x`, then bit `8+x` + * is set. + * + * - Newer algorithms are symbolic 16-bit identifiers that do not + * represent signature algorithm and hash function separately. If + * the TLS-level identifier is `0x0800+x` for a `x` in the 0..15 + * range, then bit `16+x` is set. + * + * "New algorithms" are currently defined only in draft documents, so + * this support is subject to possible change. Right now (early 2017), + * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA + * on Curve448) to bit 24. If the identifiers on the wire change in + * future document, then the decoding mechanism in BearSSL will be + * amended to keep mapping ed25519 and ed448 on bits 23 and 24, + * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not + * guaranteed yet. + * + * \param cc client context. + * \return the server-supported hash functions and signature algorithms. + */ +static inline uint32_t +br_ssl_client_get_server_hashes(const br_ssl_client_context *cc) +{ + return cc->hashes; +} + +/** + * \brief Get the server key curve. + * + * This function returns the ID for the curve used by the server's public + * key. This is set when the server's certificate chain is processed; + * this value is 0 if the server's key is not an EC key. + * + * \return the server's public key curve ID, or 0. + */ +static inline int +br_ssl_client_get_server_curve(const br_ssl_client_context *cc) +{ + return cc->server_curve; +} + +/* + * Each br_ssl_client_init_xxx() function sets the list of supported + * cipher suites and used implementations, as specified by the profile + * name 'xxx'. Defined profile names are: + * + * full all supported versions and suites; constant-time implementations + * TODO: add other profiles + */ + +/** + * \brief SSL client profile: full. + * + * This function initialises the provided SSL client context with + * all supported algorithms and cipher suites. It also initialises + * a companion X.509 validation engine with all supported algorithms, + * and the provided trust anchors; the X.509 engine will be used by + * the client context to validate the server's certificate. + * + * \param cc client context to initialise. + * \param xc X.509 validation context to initialise. + * \param trust_anchors trust anchors to use. + * \param trust_anchors_num number of trust anchors. + */ +void br_ssl_client_init_full(br_ssl_client_context *cc, + br_x509_minimal_context *xc, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); + +/** + * \brief SSL client profile: TLS1.2 minus weak ciphers + * + * This function initialises the provided SSL client context with + * most (see brief) supported algorithms and cipher suites. It also initialises + * a companion X.509 validation engine with most supported algorithms, + * and the provided trust anchors; the X.509 engine will be used by + * the client context to validate the server's certificate. + * + * \param cc client context to initialise. + * \param xc X.509 validation context to initialise. + * \param trust_anchors trust anchors to use. + * \param trust_anchors_num number of trust anchors. + */ +void br_client_init_TLS12_only(br_ssl_client_context *cc, + br_x509_minimal_context *xc, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); + +/** + * \brief Clear the complete contents of a SSL client context. + * + * Everything is cleared, including the reference to the configured buffer, + * implementations, cipher suites and state. This is a preparatory step + * to assembling a custom profile. + * + * \param cc client context to clear. + */ +void br_ssl_client_zero(br_ssl_client_context *cc); + +/** + * \brief Set an externally provided client certificate handler context. + * + * The handler's methods are invoked when the server requests a client + * certificate. + * + * \param cc client context. + * \param pctx certificate handler context (pointer to its vtable field). + */ +static inline void +br_ssl_client_set_client_certificate(br_ssl_client_context *cc, + const br_ssl_client_certificate_class **pctx) +{ + cc->client_auth_vtable = pctx; +} + +/** + * \brief Set the RSA public-key operations implementation. + * + * This will be used to encrypt the pre-master secret with the server's + * RSA public key (RSA-encryption cipher suites only). + * + * \param cc client context. + * \param irsapub RSA public-key encryption implementation. + */ +static inline void +br_ssl_client_set_rsapub(br_ssl_client_context *cc, br_rsa_public irsapub) +{ + cc->irsapub = irsapub; +} + +/** + * \brief Set the "default" RSA implementation for public-key operations. + * + * This sets the RSA implementation in the client context (for encrypting + * the pre-master secret, in `TLS_RSA_*` cipher suites) to the fastest + * available on the current platform. + * + * \param cc client context. + */ +void br_ssl_client_set_default_rsapub(br_ssl_client_context *cc); + +/** + * \brief Set the minimum ClientHello length (RFC 7685 padding). + * + * If this value is set and the ClientHello would be shorter, then + * the Pad ClientHello extension will be added with enough padding bytes + * to reach the target size. Because of the extension header, the resulting + * size will sometimes be slightly more than `len` bytes if the target + * size cannot be exactly met. + * + * The target length relates to the _contents_ of the ClientHello, not + * counting its 4-byte header. For instance, if `len` is set to 512, + * then the padding will bring the ClientHello size to 516 bytes with its + * header, and 521 bytes when counting the 5-byte record header. + * + * \param cc client context. + * \param len minimum ClientHello length (in bytes). + */ +static inline void +br_ssl_client_set_min_clienthello_len(br_ssl_client_context *cc, uint16_t len) +{ + cc->min_clienthello_len = len; +} + +/** + * \brief Prepare or reset a client context for a new connection. + * + * The `server_name` parameter is used to fill the SNI extension; the + * X.509 "minimal" engine will also match that name against the server + * names included in the server's certificate. If the parameter is + * `NULL` then no SNI extension will be sent, and the X.509 "minimal" + * engine (if used for server certificate validation) will not check + * presence of any specific name in the received certificate. + * + * Therefore, setting the `server_name` to `NULL` shall be reserved + * to cases where alternate or additional methods are used to ascertain + * that the right server public key is used (e.g. a "known key" model). + * + * If `resume_session` is non-zero and the context was previously used + * then the session parameters may be reused (depending on whether the + * server previously sent a non-empty session ID, and accepts the session + * resumption). The session parameters for session resumption can also + * be set explicitly with `br_ssl_engine_set_session_parameters()`. + * + * On failure, the context is marked as failed, and this function + * returns 0. A possible failure condition is when no initial entropy + * was injected, and none could be obtained from the OS (either OS + * randomness gathering is not supported, or it failed). + * + * \param cc client context. + * \param server_name target server name, or `NULL`. + * \param resume_session non-zero to try session resumption. + * \return 0 on failure, 1 on success. + */ +int br_ssl_client_reset(br_ssl_client_context *cc, + const char *server_name, int resume_session); + +/** + * \brief Forget any session in the context. + * + * This means that the next handshake that uses this context will + * necessarily be a full handshake (this applies both to new connections + * and to renegotiations). + * + * \param cc client context. + */ +static inline void +br_ssl_client_forget_session(br_ssl_client_context *cc) +{ + cc->eng.session.session_id_len = 0; +} + +/** + * \brief Set client certificate chain and key (single RSA case). + * + * This function sets a client certificate chain, that the client will + * send to the server whenever a client certificate is requested. This + * certificate uses an RSA public key; the corresponding private key is + * invoked for authentication. Trust anchor names sent by the server are + * ignored. + * + * The provided chain and private key are linked in the client context; + * they must remain valid as long as they may be used, i.e. normally + * for the duration of the connection, since they might be invoked + * again upon renegotiations. + * + * \param cc SSL client context. + * \param chain client certificate chain (SSL order: EE comes first). + * \param chain_len client chain length (number of certificates). + * \param sk client private key. + * \param irsasign RSA signature implementation (PKCS#1 v1.5). + */ +void br_ssl_client_set_single_rsa(br_ssl_client_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk, br_rsa_pkcs1_sign irsasign); + +/* + * \brief Set the client certificate chain and key (single EC case). + * + * This function sets a client certificate chain, that the client will + * send to the server whenever a client certificate is requested. This + * certificate uses an EC public key; the corresponding private key is + * invoked for authentication. Trust anchor names sent by the server are + * ignored. + * + * The provided chain and private key are linked in the client context; + * they must remain valid as long as they may be used, i.e. normally + * for the duration of the connection, since they might be invoked + * again upon renegotiations. + * + * The `allowed_usages` is a combination of usages, namely + * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`. The `BR_KEYTYPE_KEYX` + * value allows full static ECDH, while the `BR_KEYTYPE_SIGN` value + * allows ECDSA signatures. If ECDSA signatures are used, then an ECDSA + * signature implementation must be provided; otherwise, the `iecdsa` + * parameter may be 0. + * + * The `cert_issuer_key_type` value is either `BR_KEYTYPE_RSA` or + * `BR_KEYTYPE_EC`; it is the type of the public key used the the CA + * that issued (signed) the client certificate. That value is used with + * full static ECDH: support of the certificate by the server depends + * on how the certificate was signed. (Note: when using TLS 1.2, this + * parameter is ignored; but its value matters for TLS 1.0 and 1.1.) + * + * \param cc server context. + * \param chain server certificate chain to send. + * \param chain_len chain length (number of certificates). + * \param sk server private key (EC). + * \param allowed_usages allowed private key usages. + * \param cert_issuer_key_type issuing CA's key type. + * \param iec EC core implementation. + * \param iecdsa ECDSA signature implementation ("asn1" format). + */ +void br_ssl_client_set_single_ec(br_ssl_client_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk, unsigned allowed_usages, + unsigned cert_issuer_key_type, + const br_ec_impl *iec, br_ecdsa_sign iecdsa); + +/** + * \brief Type for a "translated cipher suite", as an array of two + * 16-bit integers. + * + * The first element is the cipher suite identifier (as used on the wire). + * The second element is the concatenation of four 4-bit elements which + * characterise the cipher suite contents. In most to least significant + * order, these 4-bit elements are: + * + * - Bits 12 to 15: key exchange + server key type + * + * | val | symbolic constant | suite type | details | + * | :-- | :----------------------- | :---------- | :----------------------------------------------- | + * | 0 | `BR_SSLKEYX_RSA` | RSA | RSA key exchange, key is RSA (encryption) | + * | 1 | `BR_SSLKEYX_ECDHE_RSA` | ECDHE_RSA | ECDHE key exchange, key is RSA (signature) | + * | 2 | `BR_SSLKEYX_ECDHE_ECDSA` | ECDHE_ECDSA | ECDHE key exchange, key is EC (signature) | + * | 3 | `BR_SSLKEYX_ECDH_RSA` | ECDH_RSA | Key is EC (key exchange), cert signed with RSA | + * | 4 | `BR_SSLKEYX_ECDH_ECDSA` | ECDH_ECDSA | Key is EC (key exchange), cert signed with ECDSA | + * + * - Bits 8 to 11: symmetric encryption algorithm + * + * | val | symbolic constant | symmetric encryption | key strength (bits) | + * | :-- | :--------------------- | :------------------- | :------------------ | + * | 0 | `BR_SSLENC_3DES_CBC` | 3DES/CBC | 168 | + * | 1 | `BR_SSLENC_AES128_CBC` | AES-128/CBC | 128 | + * | 2 | `BR_SSLENC_AES256_CBC` | AES-256/CBC | 256 | + * | 3 | `BR_SSLENC_AES128_GCM` | AES-128/GCM | 128 | + * | 4 | `BR_SSLENC_AES256_GCM` | AES-256/GCM | 256 | + * | 5 | `BR_SSLENC_CHACHA20` | ChaCha20/Poly1305 | 256 | + * + * - Bits 4 to 7: MAC algorithm + * + * | val | symbolic constant | MAC type | details | + * | :-- | :----------------- | :----------- | :------------------------------------ | + * | 0 | `BR_SSLMAC_AEAD` | AEAD | No dedicated MAC (encryption is AEAD) | + * | 2 | `BR_SSLMAC_SHA1` | HMAC/SHA-1 | Value matches `br_sha1_ID` | + * | 4 | `BR_SSLMAC_SHA256` | HMAC/SHA-256 | Value matches `br_sha256_ID` | + * | 5 | `BR_SSLMAC_SHA384` | HMAC/SHA-384 | Value matches `br_sha384_ID` | + * + * - Bits 0 to 3: hash function for PRF when used with TLS-1.2 + * + * | val | symbolic constant | hash function | details | + * | :-- | :----------------- | :------------ | :----------------------------------- | + * | 4 | `BR_SSLPRF_SHA256` | SHA-256 | Value matches `br_sha256_ID` | + * | 5 | `BR_SSLPRF_SHA384` | SHA-384 | Value matches `br_sha384_ID` | + * + * For instance, cipher suite `TLS_RSA_WITH_AES_128_GCM_SHA256` has + * standard identifier 0x009C, and is translated to 0x0304, for, in + * that order: RSA key exchange (0), AES-128/GCM (3), AEAD integrity (0), + * SHA-256 in the TLS PRF (4). + */ +typedef uint16_t br_suite_translated[2]; + +#ifndef BR_DOXYGEN_IGNORE +/* + * Constants are already documented in the br_suite_translated type. + */ + +#define BR_SSLKEYX_RSA 0 +#define BR_SSLKEYX_ECDHE_RSA 1 +#define BR_SSLKEYX_ECDHE_ECDSA 2 +#define BR_SSLKEYX_ECDH_RSA 3 +#define BR_SSLKEYX_ECDH_ECDSA 4 + +#define BR_SSLENC_3DES_CBC 0 +#define BR_SSLENC_AES128_CBC 1 +#define BR_SSLENC_AES256_CBC 2 +#define BR_SSLENC_AES128_GCM 3 +#define BR_SSLENC_AES256_GCM 4 +#define BR_SSLENC_CHACHA20 5 + +#define BR_SSLMAC_AEAD 0 +#define BR_SSLMAC_SHA1 br_sha1_ID +#define BR_SSLMAC_SHA256 br_sha256_ID +#define BR_SSLMAC_SHA384 br_sha384_ID + +#define BR_SSLPRF_SHA256 br_sha256_ID +#define BR_SSLPRF_SHA384 br_sha384_ID + +#endif + +/* + * Pre-declaration for the SSL server context. + */ +typedef struct br_ssl_server_context_ br_ssl_server_context; + +/** + * \brief Type for the server policy choices, taken after analysis of + * the client message (ClientHello). + */ +typedef struct { + /** + * \brief Cipher suite to use with that client. + */ + uint16_t cipher_suite; + + /** + * \brief Hash function or algorithm for signing the ServerKeyExchange. + * + * This parameter is ignored for `TLS_RSA_*` and `TLS_ECDH_*` + * cipher suites; it is used only for `TLS_ECDHE_*` suites, in + * which the server _signs_ the ephemeral EC Diffie-Hellman + * parameters sent to the client. + * + * This identifier must be one of the following values: + * + * - `0xFF00 + id`, where `id` is a hash function identifier + * (0 for MD5+SHA-1, or 2 to 6 for one of the SHA functions); + * + * - a full 16-bit identifier, lower than `0xFF00`. + * + * If the first option is used, then the SSL engine will + * compute the hash of the data that is to be signed, with the + * designated hash function. The `do_sign()` method will be + * invoked with that hash value provided in the the `data` + * buffer. + * + * If the second option is used, then the SSL engine will NOT + * compute a hash on the data; instead, it will provide the + * to-be-signed data itself in `data`, i.e. the concatenation of + * the client random, server random, and encoded ECDH + * parameters. Furthermore, with TLS-1.2 and later, the 16-bit + * identifier will be used "as is" in the protocol, in the + * SignatureAndHashAlgorithm; for instance, `0x0401` stands for + * RSA PKCS#1 v1.5 signature (the `01`) with SHA-256 as hash + * function (the `04`). + * + * Take care that with TLS 1.0 and 1.1, the hash function is + * constrainted by the protocol: RSA signature must use + * MD5+SHA-1 (so use `0xFF00`), while ECDSA must use SHA-1 + * (`0xFF02`). Since TLS 1.0 and 1.1 don't include a + * SignatureAndHashAlgorithm field in their ServerKeyExchange + * messages, any value below `0xFF00` will be usable to send the + * raw ServerKeyExchange data to the `do_sign()` callback, but + * that callback must still follow the protocol requirements + * when generating the signature. + */ + unsigned algo_id; + + /** + * \brief Certificate chain to send to the client. + * + * This is an array of `br_x509_certificate` objects, each + * normally containing a DER-encoded certificate. The server + * code does not try to decode these elements. + */ + const br_x509_certificate *chain; + + /** + * \brief Certificate chain length (number of certificates). + */ + size_t chain_len; + +} br_ssl_server_choices; + +/** + * \brief Class type for a policy handler (server side). + * + * A policy handler selects the policy parameters for a connection + * (cipher suite and other algorithms, and certificate chain to send to + * the client); it also performs the server-side computations involving + * its permanent private key. + * + * The SSL server engine will invoke first `choose()`, once the + * ClientHello message has been received, then either `do_keyx()` + * `do_sign()`, depending on the cipher suite. + */ +typedef struct br_ssl_server_policy_class_ br_ssl_server_policy_class; +struct br_ssl_server_policy_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Select algorithms and certificates for this connection. + * + * This callback function shall fill the provided `choices` + * structure with the policy choices for this connection. This + * entails selecting the cipher suite, hash function for signing + * the ServerKeyExchange (applicable only to ECDHE cipher suites), + * and certificate chain to send. + * + * The callback receives a pointer to the server context that + * contains the relevant data. In particular, the functions + * `br_ssl_server_get_client_suites()`, + * `br_ssl_server_get_client_hashes()` and + * `br_ssl_server_get_client_curves()` can be used to obtain + * the cipher suites, hash functions and elliptic curves + * supported by both the client and server, respectively. The + * `br_ssl_engine_get_version()` and `br_ssl_engine_get_server_name()` + * functions yield the protocol version and requested server name + * (SNI), respectively. + * + * This function may modify its context structure (`pctx`) in + * arbitrary ways to keep track of its own choices. + * + * This function shall return 1 if appropriate policy choices + * could be made, or 0 if this connection cannot be pursued. + * + * \param pctx policy context. + * \param cc SSL server context. + * \param choices destination structure for the policy choices. + * \return 1 on success, 0 on error. + */ + int (*choose)(const br_ssl_server_policy_class **pctx, + const br_ssl_server_context *cc, + br_ssl_server_choices *choices); + + /** + * \brief Perform key exchange (server part). + * + * This callback is invoked to perform the server-side cryptographic + * operation for a key exchange that is not ECDHE. This callback + * uses the private key. + * + * **For RSA key exchange**, the provided `data` (of length `*len` + * bytes) shall be decrypted with the server's private key, and + * the 48-byte premaster secret copied back to the first 48 bytes + * of `data`. + * + * - The caller makes sure that `*len` is at least 59 bytes. + * + * - This callback MUST check that the provided length matches + * that of the key modulus; it shall report an error otherwise. + * + * - If the length matches that of the RSA key modulus, then + * processing MUST be constant-time, even if decryption fails, + * or the padding is incorrect, or the plaintext message length + * is not exactly 48 bytes. + * + * - This callback needs not check the two first bytes of the + * obtained pre-master secret (the caller will do that). + * + * - If an error is reported (0), then what the callback put + * in the first 48 bytes of `data` is unimportant (the caller + * will use random bytes instead). + * + * **For ECDH key exchange**, the provided `data` (of length `*len` + * bytes) is the elliptic curve point from the client. The + * callback shall multiply it with its private key, and store + * the resulting X coordinate in `data`, starting at offset 0, + * and set `*len` to the length of the X coordinate. + * + * - If the input array does not have the proper length for + * an encoded curve point, then an error (0) shall be reported. + * + * - If the input array has the proper length, then processing + * MUST be constant-time, even if the data is not a valid + * encoded point. + * + * - This callback MUST check that the input point is valid. + * + * Returned value is 1 on success, 0 on error. + * + * \param pctx policy context. + * \param data key exchange data from the client. + * \param len key exchange data length (in bytes). + * \return 1 on success, 0 on error. + */ + uint32_t (*do_keyx)(const br_ssl_server_policy_class **pctx, + unsigned char *data, size_t *len); + + /** + * \brief Perform a signature (for a ServerKeyExchange message). + * + * This callback function is invoked for ECDHE cipher suites. On + * input, the hash value or message to sign is in `data`, of + * size `hv_len`; the involved hash function or algorithm is + * identified by `algo_id`. The signature shall be computed and + * written back into `data`; the total size of that buffer is + * `len` bytes. + * + * This callback shall verify that the signature length does not + * exceed `len` bytes, and abstain from writing the signature if + * it does not fit. + * + * The `algo_id` value matches that which was written in the + * `choices` structures by the `choose()` callback. This will be + * one of the following: + * + * - `0xFF00 + id` for a hash function identifier `id`. In + * that case, the `data` buffer contains a hash value + * already computed over the data that is to be signed, + * of length `hv_len`. The `id` may be 0 to designate the + * special MD5+SHA-1 concatenation (old-style RSA signing). + * + * - Another value, lower than `0xFF00`. The `data` buffer + * then contains the raw, non-hashed data to be signed + * (concatenation of the client and server randoms and + * ECDH parameters). The callback is responsible to apply + * any relevant hashing as part of the signing process. + * + * Returned value is the signature length (in bytes), or 0 on error. + * + * \param pctx policy context. + * \param algo_id hash function / algorithm identifier. + * \param data input/output buffer (message/hash, then signature). + * \param hv_len hash value or message length (in bytes). + * \param len total buffer length (in bytes). + * \return signature length (in bytes) on success, or 0 on error. + */ + size_t (*do_sign)(const br_ssl_server_policy_class **pctx, + unsigned algo_id, + unsigned char *data, size_t hv_len, size_t len); +}; + +/** + * \brief A single-chain RSA policy handler. + * + * This policy context uses a single certificate chain, and a RSA + * private key. The context can be restricted to only signatures or + * only key exchange. + * + * Apart from the first field (vtable pointer), its contents are + * opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_server_policy_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + const br_x509_certificate *chain; + size_t chain_len; + const br_rsa_private_key *sk; + unsigned allowed_usages; + br_rsa_private irsacore; + br_rsa_pkcs1_sign irsasign; +#endif +} br_ssl_server_policy_rsa_context; + +/** + * \brief A single-chain EC policy handler. + * + * This policy context uses a single certificate chain, and an EC + * private key. The context can be restricted to only signatures or + * only key exchange. + * + * Due to how TLS is defined, this context must be made aware whether + * the server certificate was itself signed with RSA or ECDSA. The code + * does not try to decode the certificate to obtain that information. + * + * Apart from the first field (vtable pointer), its contents are + * opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_server_policy_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + const br_x509_certificate *chain; + size_t chain_len; + const br_ec_private_key *sk; + unsigned allowed_usages; + unsigned cert_issuer_key_type; + const br_multihash_context *mhash; + const br_ec_impl *iec; + br_ecdsa_sign iecdsa; +#endif +} br_ssl_server_policy_ec_context; + +/** + * \brief Class type for a session parameter cache. + * + * Session parameters are saved in the cache with `save()`, and + * retrieved with `load()`. The cache implementation can apply any + * storage and eviction strategy that it sees fit. The SSL server + * context that performs the request is provided, so that its + * functionalities may be used by the implementation (e.g. hash + * functions or random number generation). + */ +typedef struct br_ssl_session_cache_class_ br_ssl_session_cache_class; +struct br_ssl_session_cache_class_ { + /** + * \brief Context size (in bytes). + */ + size_t context_size; + + /** + * \brief Record a session. + * + * This callback should record the provided session parameters. + * The `params` structure is transient, so its contents shall + * be copied into the cache. The session ID has been randomly + * generated and always has length exactly 32 bytes. + * + * \param ctx session cache context. + * \param server_ctx SSL server context. + * \param params session parameters to save. + */ + void (*save)(const br_ssl_session_cache_class **ctx, + br_ssl_server_context *server_ctx, + const br_ssl_session_parameters *params); + + /** + * \brief Lookup a session in the cache. + * + * The session ID to lookup is in `params` and always has length + * exactly 32 bytes. If the session parameters are found in the + * cache, then the parameters shall be copied into the `params` + * structure. Returned value is 1 on successful lookup, 0 + * otherwise. + * + * \param ctx session cache context. + * \param server_ctx SSL server context. + * \param params destination for session parameters. + * \return 1 if found, 0 otherwise. + */ + int (*load)(const br_ssl_session_cache_class **ctx, + br_ssl_server_context *server_ctx, + br_ssl_session_parameters *params); +}; + +/** + * \brief Context for a basic cache system. + * + * The system stores session parameters in a buffer provided at + * initialisation time. Each entry uses exactly 100 bytes, and + * buffer sizes up to 4294967295 bytes are supported. + * + * Entries are evicted with a LRU (Least Recently Used) policy. A + * search tree is maintained to keep lookups fast even with large + * caches. + * + * Apart from the first field (vtable pointer), the structure + * contents are opaque and shall not be accessed directly. + */ +typedef struct { + /** \brief Pointer to vtable. */ + const br_ssl_session_cache_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + unsigned char *store; + size_t store_len, store_ptr; + unsigned char index_key[32]; + const br_hash_class *hash; + int init_done; + uint32_t head, tail, root; +#endif +} br_ssl_session_cache_lru; + +/** + * \brief Initialise a LRU session cache with the provided storage space. + * + * The provided storage space must remain valid as long as the cache + * is used. Arbitrary lengths are supported, up to 4294967295 bytes; + * each entry uses up exactly 100 bytes. + * + * \param cc session cache context. + * \param store storage space for cached entries. + * \param store_len storage space length (in bytes). + */ +void br_ssl_session_cache_lru_init(br_ssl_session_cache_lru *cc, + unsigned char *store, size_t store_len); + +/** + * \brief Forget an entry in an LRU session cache. + * + * The session cache context must have been initialised. The entry + * with the provided session ID (of exactly 32 bytes) is looked for + * in the cache; if located, it is disabled. + * + * \param cc session cache context. + * \param id session ID to forget. + */ +void br_ssl_session_cache_lru_forget( + br_ssl_session_cache_lru *cc, const unsigned char *id); + +/** + * \brief Context structure for a SSL server. + * + * The first field (called `eng`) is the SSL engine; all functions that + * work on a `br_ssl_engine_context` structure shall take as parameter + * a pointer to that field. The other structure fields are opaque and + * must not be accessed directly. + */ +struct br_ssl_server_context_ { + /** + * \brief The encapsulated engine context. + */ + br_ssl_engine_context eng; + +#ifndef BR_DOXYGEN_IGNORE + /* + * Maximum version from the client. + */ + uint16_t client_max_version; + + /* + * Session cache. + */ + const br_ssl_session_cache_class **cache_vtable; + + /* + * Translated cipher suites supported by the client. The list + * is trimmed to include only the cipher suites that the + * server also supports; they are in the same order as in the + * client message. + */ + br_suite_translated client_suites[BR_MAX_CIPHER_SUITES]; + unsigned char client_suites_num; + + /* + * Hash functions supported by the client, with ECDSA and RSA + * (bit mask). For hash function with id 'x', set bit index is + * x for RSA, x+8 for ECDSA. For newer algorithms, with ID + * 0x08**, bit 16+k is set for algorithm 0x0800+k. + */ + uint32_t hashes; + + /* + * Curves supported by the client (bit mask, for named curves). + */ + uint32_t curves; + + /* + * Context for chain handler. + */ + const br_ssl_server_policy_class **policy_vtable; + uint16_t sign_hash_id; + + /* + * For the core handlers, thus avoiding (in most cases) the + * need for an externally provided policy context. + */ + union { + const br_ssl_server_policy_class *vtable; + br_ssl_server_policy_rsa_context single_rsa; + br_ssl_server_policy_ec_context single_ec; + } chain_handler; + + /* + * Buffer for the ECDHE private key. + */ + unsigned char ecdhe_key[70]; + size_t ecdhe_key_len; + + /* + * Trust anchor names for client authentication. "ta_names" and + * "tas" cannot be both non-NULL. + */ + const br_x500_name *ta_names; + const br_x509_trust_anchor *tas; + size_t num_tas; + size_t cur_dn_index; + const unsigned char *cur_dn; + size_t cur_dn_len; + + /* + * Buffer for the hash value computed over all handshake messages + * prior to CertificateVerify, and identifier for the hash function. + */ + unsigned char hash_CV[64]; + size_t hash_CV_len; + int hash_CV_id; + + /* + * Server-specific implementations. + * (none for now) + */ +#endif +}; + +/* + * Each br_ssl_server_init_xxx() function sets the list of supported + * cipher suites and used implementations, as specified by the profile + * name 'xxx'. Defined profile names are: + * + * full_rsa all supported algorithm, server key type is RSA + * full_ec all supported algorithm, server key type is EC + * TODO: add other profiles + * + * Naming scheme for "minimal" profiles: min123 + * + * -- character 1: key exchange + * r = RSA + * e = ECDHE_RSA + * f = ECDHE_ECDSA + * u = ECDH_RSA + * v = ECDH_ECDSA + * -- character 2: version / PRF + * 0 = TLS 1.0 / 1.1 with MD5+SHA-1 + * 2 = TLS 1.2 with SHA-256 + * 3 = TLS 1.2 with SHA-384 + * -- character 3: encryption + * a = AES/CBC + * d = 3DES/CBC + * g = AES/GCM + * c = ChaCha20+Poly1305 + */ + +/** + * \brief SSL server profile: full_rsa. + * + * This function initialises the provided SSL server context with + * all supported algorithms and cipher suites that rely on a RSA + * key pair. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_full_rsa(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: full_ec. + * + * This function initialises the provided SSL server context with + * all supported algorithms and cipher suites that rely on an EC + * key pair. + * + * The key type of the CA that issued the server's certificate must + * be provided, since it matters for ECDH cipher suites (ECDH_RSA + * suites require a RSA-powered CA). The key type is either + * `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len chain length (number of certificates). + * \param cert_issuer_key_type certificate issuer's key type. + * \param sk EC private key. + */ +void br_ssl_server_init_full_ec(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + unsigned cert_issuer_key_type, const br_ec_private_key *sk); + +/** + * \brief SSL server profile: minr2g. + * + * This profile uses only TLS_RSA_WITH_AES_128_GCM_SHA256. Server key is + * RSA, and RSA key exchange is used (not forward secure, but uses little + * CPU in the client). + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_minr2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: mine2g. + * + * This profile uses only TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256. Server key + * is RSA, and ECDHE key exchange is used. This suite provides forward + * security, with a higher CPU expense on the client, and a somewhat + * larger code footprint (compared to "minr2g"). + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_mine2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: minf2g. + * + * This profile uses only TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256. + * Server key is EC, and ECDHE key exchange is used. This suite provides + * forward security, with a higher CPU expense on the client and server + * (by a factor of about 3 to 4), and a somewhat larger code footprint + * (compared to "minu2g" and "minv2g"). + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minf2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + +/** + * \brief SSL server profile: minu2g. + * + * This profile uses only TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256. + * Server key is EC, and ECDH key exchange is used; the issuing CA used + * a RSA key. + * + * The "minu2g" and "minv2g" profiles do not provide forward secrecy, + * but are the lightest on the server (for CPU usage), and are rather + * inexpensive on the client as well. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minu2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + +/** + * \brief SSL server profile: minv2g. + * + * This profile uses only TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256. + * Server key is EC, and ECDH key exchange is used; the issuing CA used + * an EC key. + * + * The "minu2g" and "minv2g" profiles do not provide forward secrecy, + * but are the lightest on the server (for CPU usage), and are rather + * inexpensive on the client as well. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minv2g(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + +/** + * \brief SSL server profile: mine2c. + * + * This profile uses only TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256. + * Server key is RSA, and ECDHE key exchange is used. This suite + * provides forward security. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk RSA private key. + */ +void br_ssl_server_init_mine2c(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk); + +/** + * \brief SSL server profile: minf2c. + * + * This profile uses only TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256. + * Server key is EC, and ECDHE key exchange is used. This suite provides + * forward security. + * + * \param cc server context to initialise. + * \param chain server certificate chain. + * \param chain_len certificate chain length (number of certificate). + * \param sk EC private key. + */ +void br_ssl_server_init_minf2c(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk); + +/** + * \brief Get the supported client suites. + * + * This function shall be called only after the ClientHello has been + * processed, typically from the policy engine. The returned array + * contains the cipher suites that are supported by both the client + * and the server; these suites are in client preference order, unless + * the `BR_OPT_ENFORCE_SERVER_PREFERENCES` flag was set, in which case + * they are in server preference order. + * + * The suites are _translated_, which means that each suite is given + * as two 16-bit integers: the standard suite identifier, and its + * translated version, broken down into its individual components, + * as explained with the `br_suite_translated` type. + * + * The returned array is allocated in the context and will be rewritten + * by each handshake. + * + * \param cc server context. + * \param num receives the array size (number of suites). + * \return the translated common cipher suites, in preference order. + */ +static inline const br_suite_translated * +br_ssl_server_get_client_suites(const br_ssl_server_context *cc, size_t *num) +{ + *num = cc->client_suites_num; + return cc->client_suites; +} + +/** + * \brief Get the hash functions and signature algorithms supported by + * the client. + * + * This value is a bit field: + * + * - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`, + * then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1, + * or 2 to 6 for the SHA family). + * + * - If ECDSA is supported with hash function of ID `x`, then bit `8+x` + * is set. + * + * - Newer algorithms are symbolic 16-bit identifiers that do not + * represent signature algorithm and hash function separately. If + * the TLS-level identifier is `0x0800+x` for a `x` in the 0..15 + * range, then bit `16+x` is set. + * + * "New algorithms" are currently defined only in draft documents, so + * this support is subject to possible change. Right now (early 2017), + * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA + * on Curve448) to bit 24. If the identifiers on the wire change in + * future document, then the decoding mechanism in BearSSL will be + * amended to keep mapping ed25519 and ed448 on bits 23 and 24, + * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not + * guaranteed yet. + * + * \param cc server context. + * \return the client-supported hash functions and signature algorithms. + */ +static inline uint32_t +br_ssl_server_get_client_hashes(const br_ssl_server_context *cc) +{ + return cc->hashes; +} + +/** + * \brief Get the elliptic curves supported by the client. + * + * This is a bit field (bit x is set if curve of ID x is supported). + * + * \param cc server context. + * \return the client-supported elliptic curves. + */ +static inline uint32_t +br_ssl_server_get_client_curves(const br_ssl_server_context *cc) +{ + return cc->curves; +} + +/** + * \brief Clear the complete contents of a SSL server context. + * + * Everything is cleared, including the reference to the configured buffer, + * implementations, cipher suites and state. This is a preparatory step + * to assembling a custom profile. + * + * \param cc server context to clear. + */ +void br_ssl_server_zero(br_ssl_server_context *cc); + +/** + * \brief Set an externally provided policy context. + * + * The policy context's methods are invoked to decide the cipher suite + * and certificate chain, and to perform operations involving the server's + * private key. + * + * \param cc server context. + * \param pctx policy context (pointer to its vtable field). + */ +static inline void +br_ssl_server_set_policy(br_ssl_server_context *cc, + const br_ssl_server_policy_class **pctx) +{ + cc->policy_vtable = pctx; +} + +/** + * \brief Set the server certificate chain and key (single RSA case). + * + * This function uses a policy context included in the server context. + * It configures use of a single server certificate chain with a RSA + * private key. The `allowed_usages` is a combination of usages, namely + * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`; this enables or disables + * the corresponding cipher suites (i.e. `TLS_RSA_*` use the RSA key for + * key exchange, while `TLS_ECDHE_RSA_*` use the RSA key for signatures). + * + * \param cc server context. + * \param chain server certificate chain to send to the client. + * \param chain_len chain length (number of certificates). + * \param sk server private key (RSA). + * \param allowed_usages allowed private key usages. + * \param irsacore RSA core implementation. + * \param irsasign RSA signature implementation (PKCS#1 v1.5). + */ +void br_ssl_server_set_single_rsa(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_rsa_private_key *sk, unsigned allowed_usages, + br_rsa_private irsacore, br_rsa_pkcs1_sign irsasign); + +/** + * \brief Set the server certificate chain and key (single EC case). + * + * This function uses a policy context included in the server context. + * It configures use of a single server certificate chain with an EC + * private key. The `allowed_usages` is a combination of usages, namely + * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`; this enables or disables + * the corresponding cipher suites (i.e. `TLS_ECDH_*` use the EC key for + * key exchange, while `TLS_ECDHE_ECDSA_*` use the EC key for signatures). + * + * In order to support `TLS_ECDH_*` cipher suites (non-ephemeral ECDH), + * the algorithm type of the key used by the issuing CA to sign the + * server's certificate must be provided, as `cert_issuer_key_type` + * parameter (this value is either `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`). + * + * \param cc server context. + * \param chain server certificate chain to send. + * \param chain_len chain length (number of certificates). + * \param sk server private key (EC). + * \param allowed_usages allowed private key usages. + * \param cert_issuer_key_type issuing CA's key type. + * \param iec EC core implementation. + * \param iecdsa ECDSA signature implementation ("asn1" format). + */ +void br_ssl_server_set_single_ec(br_ssl_server_context *cc, + const br_x509_certificate *chain, size_t chain_len, + const br_ec_private_key *sk, unsigned allowed_usages, + unsigned cert_issuer_key_type, + const br_ec_impl *iec, br_ecdsa_sign iecdsa); + +/** + * \brief Activate client certificate authentication. + * + * The trust anchor encoded X.500 names (DN) to send to the client are + * provided. A client certificate will be requested and validated through + * the X.509 validator configured in the SSL engine. If `num` is 0, then + * client certificate authentication is disabled. + * + * If the client does not send a certificate, or on validation failure, + * the handshake aborts. Unauthenticated clients can be tolerated by + * setting the `BR_OPT_TOLERATE_NO_CLIENT_AUTH` flag. + * + * The provided array is linked in, not copied, so that pointer must + * remain valid as long as anchor names may be used. + * + * \param cc server context. + * \param ta_names encoded trust anchor names. + * \param num number of encoded trust anchor names. + */ +static inline void +br_ssl_server_set_trust_anchor_names(br_ssl_server_context *cc, + const br_x500_name *ta_names, size_t num) +{ + cc->ta_names = ta_names; + cc->tas = NULL; + cc->num_tas = num; +} + +/** + * \brief Activate client certificate authentication. + * + * This is a variant for `br_ssl_server_set_trust_anchor_names()`: the + * trust anchor names are provided not as an array of stand-alone names + * (`br_x500_name` structures), but as an array of trust anchors + * (`br_x509_trust_anchor` structures). The server engine itself will + * only use the `dn` field of each trust anchor. This is meant to allow + * defining a single array of trust anchors, to be used here and in the + * X.509 validation engine itself. + * + * The provided array is linked in, not copied, so that pointer must + * remain valid as long as anchor names may be used. + * + * \param cc server context. + * \param tas trust anchors (only names are used). + * \param num number of trust anchors. + */ +static inline void +br_ssl_server_set_trust_anchor_names_alt(br_ssl_server_context *cc, + const br_x509_trust_anchor *tas, size_t num) +{ + cc->ta_names = NULL; + cc->tas = tas; + cc->num_tas = num; +} + +/** + * \brief Configure the cache for session parameters. + * + * The cache context is provided as a pointer to its first field (vtable + * pointer). + * + * \param cc server context. + * \param vtable session cache context. + */ +static inline void +br_ssl_server_set_cache(br_ssl_server_context *cc, + const br_ssl_session_cache_class **vtable) +{ + cc->cache_vtable = vtable; +} + +/** + * \brief Prepare or reset a server context for handling an incoming client. + * + * \param cc server context. + * \return 1 on success, 0 on error. + */ +int br_ssl_server_reset(br_ssl_server_context *cc); + +/* ===================================================================== */ + +/* + * Context for the simplified I/O context. The transport medium is accessed + * through the low_read() and low_write() callback functions, each with + * its own opaque context pointer. + * + * low_read() read some bytes, at most 'len' bytes, into data[]. The + * returned value is the number of read bytes, or -1 on error. + * The 'len' parameter is guaranteed never to exceed 20000, + * so the length always fits in an 'int' on all platforms. + * + * low_write() write up to 'len' bytes, to be read from data[]. The + * returned value is the number of written bytes, or -1 on + * error. The 'len' parameter is guaranteed never to exceed + * 20000, so the length always fits in an 'int' on all + * parameters. + * + * A socket closure (if the transport medium is a socket) should be reported + * as an error (-1). The callbacks shall endeavour to block until at least + * one byte can be read or written; a callback returning 0 at times is + * acceptable, but this normally leads to the callback being immediately + * called again, so the callback should at least always try to block for + * some time if no I/O can take place. + * + * The SSL engine naturally applies some buffering, so the callbacks need + * not apply buffers of their own. + */ +/** + * \brief Context structure for the simplified SSL I/O wrapper. + * + * This structure is initialised with `br_sslio_init()`. Its contents + * are opaque and shall not be accessed directly. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + br_ssl_engine_context *engine; + int (*low_read)(void *read_context, + unsigned char *data, size_t len); + void *read_context; + int (*low_write)(void *write_context, + const unsigned char *data, size_t len); + void *write_context; +#endif +} br_sslio_context; + +/** + * \brief Initialise a simplified I/O wrapper context. + * + * The simplified I/O wrapper offers a simpler read/write API for a SSL + * engine (client or server), using the provided callback functions for + * reading data from, or writing data to, the transport medium. + * + * The callback functions have the following semantics: + * + * - Each callback receives an opaque context value (of type `void *`) + * that the callback may use arbitrarily (or possibly ignore). + * + * - `low_read()` reads at least one byte, at most `len` bytes, from + * the transport medium. Read bytes shall be written in `data`. + * + * - `low_write()` writes at least one byte, at most `len` bytes, unto + * the transport medium. The bytes to write are read from `data`. + * + * - The `len` parameter is never zero, and is always lower than 20000. + * + * - The number of processed bytes (read or written) is returned. Since + * that number is less than 20000, it always fits on an `int`. + * + * - On error, the callbacks return -1. Reaching end-of-stream is an + * error. Errors are permanent: the SSL connection is terminated. + * + * - Callbacks SHOULD NOT return 0. This is tolerated, as long as + * callbacks endeavour to block for some non-negligible amount of + * time until at least one byte can be sent or received (if a + * callback returns 0, then the wrapper invokes it again + * immediately). + * + * - Callbacks MAY return as soon as at least one byte is processed; + * they MAY also insist on reading or writing _all_ requested bytes. + * Since SSL is a self-terminated protocol (each record has a length + * header), this does not change semantics. + * + * - Callbacks need not apply any buffering (for performance) since SSL + * itself uses buffers. + * + * \param ctx wrapper context to initialise. + * \param engine SSL engine to wrap. + * \param low_read callback for reading data from the transport. + * \param read_context context pointer for `low_read()`. + * \param low_write callback for writing data on the transport. + * \param write_context context pointer for `low_write()`. + */ +void br_sslio_init(br_sslio_context *ctx, + br_ssl_engine_context *engine, + int (*low_read)(void *read_context, + unsigned char *data, size_t len), + void *read_context, + int (*low_write)(void *write_context, + const unsigned char *data, size_t len), + void *write_context); + +/** + * \brief Read some application data from a SSL connection. + * + * If `len` is zero, then this function returns 0 immediately. In + * all other cases, it never returns 0. + * + * This call returns only when at least one byte has been obtained. + * Returned value is the number of bytes read, or -1 on error. The + * number of bytes always fits on an 'int' (data from a single SSL/TLS + * record is returned). + * + * On error or SSL closure, this function returns -1. The caller should + * inspect the error status on the SSL engine to distinguish between + * normal closure and error. + * + * \param cc SSL wrapper context. + * \param dst destination buffer for application data. + * \param len maximum number of bytes to obtain. + * \return number of bytes obtained, or -1 on error. + */ +int br_sslio_read(br_sslio_context *cc, void *dst, size_t len); + +/** + * \brief Read application data from a SSL connection. + * + * This calls returns only when _all_ requested `len` bytes are read, + * or an error is reached. Returned value is 0 on success, -1 on error. + * A normal (verified) SSL closure before that many bytes are obtained + * is reported as an error by this function. + * + * \param cc SSL wrapper context. + * \param dst destination buffer for application data. + * \param len number of bytes to obtain. + * \return 0 on success, or -1 on error. + */ +int br_sslio_read_all(br_sslio_context *cc, void *dst, size_t len); + +/** + * \brief Write some application data unto a SSL connection. + * + * If `len` is zero, then this function returns 0 immediately. In + * all other cases, it never returns 0. + * + * This call returns only when at least one byte has been written. + * Returned value is the number of bytes written, or -1 on error. The + * number of bytes always fits on an 'int' (less than 20000). + * + * On error or SSL closure, this function returns -1. The caller should + * inspect the error status on the SSL engine to distinguish between + * normal closure and error. + * + * **Important:** SSL is buffered; a "written" byte is a byte that was + * injected into the wrapped SSL engine, but this does not necessarily mean + * that it has been scheduled for sending. Use `br_sslio_flush()` to + * ensure that all pending data has been sent to the transport medium. + * + * \param cc SSL wrapper context. + * \param src source buffer for application data. + * \param len maximum number of bytes to write. + * \return number of bytes written, or -1 on error. + */ +int br_sslio_write(br_sslio_context *cc, const void *src, size_t len); + +/** + * \brief Write application data unto a SSL connection. + * + * This calls returns only when _all_ requested `len` bytes have been + * written, or an error is reached. Returned value is 0 on success, -1 + * on error. A normal (verified) SSL closure before that many bytes are + * written is reported as an error by this function. + * + * **Important:** SSL is buffered; a "written" byte is a byte that was + * injected into the wrapped SSL engine, but this does not necessarily mean + * that it has been scheduled for sending. Use `br_sslio_flush()` to + * ensure that all pending data has been sent to the transport medium. + * + * \param cc SSL wrapper context. + * \param src source buffer for application data. + * \param len number of bytes to write. + * \return 0 on success, or -1 on error. + */ +int br_sslio_write_all(br_sslio_context *cc, const void *src, size_t len); + +/** + * \brief Flush pending data. + * + * This call makes sure that any buffered application data in the + * provided context (including the wrapped SSL engine) has been sent + * to the transport medium (i.e. accepted by the `low_write()` callback + * method). If there is no such pending data, then this function does + * nothing (and returns a success, i.e. 0). + * + * If the underlying transport medium has its own buffers, then it is + * up to the caller to ensure the corresponding flushing. + * + * Returned value is 0 on success, -1 on error. + * + * \param cc SSL wrapper context. + * \return 0 on success, or -1 on error. + */ +int br_sslio_flush(br_sslio_context *cc); + +/** + * \brief Close the SSL connection. + * + * This call runs the SSL closure protocol (sending a `close_notify`, + * receiving the response `close_notify`). When it returns, the SSL + * connection is finished. It is still up to the caller to manage the + * possible transport-level termination, if applicable (alternatively, + * the underlying transport stream may be reused for non-SSL messages). + * + * Returned value is 0 on success, -1 on error. A failure by the peer + * to process the complete closure protocol (i.e. sending back the + * `close_notify`) is an error. + * + * \param cc SSL wrapper context. + * \return 0 on success, or -1 on error. + */ +int br_sslio_close(br_sslio_context *cc); + +/* ===================================================================== */ + +/* + * Symbolic constants for cipher suites. + */ + +/* From RFC 5246 */ +#define BR_TLS_NULL_WITH_NULL_NULL 0x0000 +#define BR_TLS_RSA_WITH_NULL_MD5 0x0001 +#define BR_TLS_RSA_WITH_NULL_SHA 0x0002 +#define BR_TLS_RSA_WITH_NULL_SHA256 0x003B +#define BR_TLS_RSA_WITH_RC4_128_MD5 0x0004 +#define BR_TLS_RSA_WITH_RC4_128_SHA 0x0005 +#define BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x000A +#define BR_TLS_RSA_WITH_AES_128_CBC_SHA 0x002F +#define BR_TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 +#define BR_TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C +#define BR_TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D +#define BR_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA 0x000D +#define BR_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA 0x0010 +#define BR_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA 0x0013 +#define BR_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016 +#define BR_TLS_DH_DSS_WITH_AES_128_CBC_SHA 0x0030 +#define BR_TLS_DH_RSA_WITH_AES_128_CBC_SHA 0x0031 +#define BR_TLS_DHE_DSS_WITH_AES_128_CBC_SHA 0x0032 +#define BR_TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033 +#define BR_TLS_DH_DSS_WITH_AES_256_CBC_SHA 0x0036 +#define BR_TLS_DH_RSA_WITH_AES_256_CBC_SHA 0x0037 +#define BR_TLS_DHE_DSS_WITH_AES_256_CBC_SHA 0x0038 +#define BR_TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039 +#define BR_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 0x003E +#define BR_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 0x003F +#define BR_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 0x0040 +#define BR_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067 +#define BR_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 0x0068 +#define BR_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 0x0069 +#define BR_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 0x006A +#define BR_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B +#define BR_TLS_DH_anon_WITH_RC4_128_MD5 0x0018 +#define BR_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA 0x001B +#define BR_TLS_DH_anon_WITH_AES_128_CBC_SHA 0x0034 +#define BR_TLS_DH_anon_WITH_AES_256_CBC_SHA 0x003A +#define BR_TLS_DH_anon_WITH_AES_128_CBC_SHA256 0x006C +#define BR_TLS_DH_anon_WITH_AES_256_CBC_SHA256 0x006D + +/* From RFC 4492 */ +#define BR_TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 +#define BR_TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 +#define BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 +#define BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 +#define BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 +#define BR_TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 +#define BR_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 +#define BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A +#define BR_TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B +#define BR_TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C +#define BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D +#define BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E +#define BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F +#define BR_TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 +#define BR_TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 +#define BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 +#define BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 +#define BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 +#define BR_TLS_ECDH_anon_WITH_NULL_SHA 0xC015 +#define BR_TLS_ECDH_anon_WITH_RC4_128_SHA 0xC016 +#define BR_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA 0xC017 +#define BR_TLS_ECDH_anon_WITH_AES_128_CBC_SHA 0xC018 +#define BR_TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019 + +/* From RFC 5288 */ +#define BR_TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C +#define BR_TLS_RSA_WITH_AES_256_GCM_SHA384 0x009D +#define BR_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x009E +#define BR_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x009F +#define BR_TLS_DH_RSA_WITH_AES_128_GCM_SHA256 0x00A0 +#define BR_TLS_DH_RSA_WITH_AES_256_GCM_SHA384 0x00A1 +#define BR_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 0x00A2 +#define BR_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 0x00A3 +#define BR_TLS_DH_DSS_WITH_AES_128_GCM_SHA256 0x00A4 +#define BR_TLS_DH_DSS_WITH_AES_256_GCM_SHA384 0x00A5 +#define BR_TLS_DH_anon_WITH_AES_128_GCM_SHA256 0x00A6 +#define BR_TLS_DH_anon_WITH_AES_256_GCM_SHA384 0x00A7 + +/* From RFC 5289 */ +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 +#define BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 +#define BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 +#define BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 +#define BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 +#define BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 +#define BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C +#define BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D +#define BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E +#define BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F +#define BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 +#define BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 +#define BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 + +/* From RFC 6655 and 7251 */ +#define BR_TLS_RSA_WITH_AES_128_CCM 0xC09C +#define BR_TLS_RSA_WITH_AES_256_CCM 0xC09D +#define BR_TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 +#define BR_TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD +#define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE +#define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF + +/* From RFC 7905 */ +#define BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 +#define BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 +#define BR_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA +#define BR_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAB +#define BR_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC +#define BR_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD +#define BR_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE + +/* From RFC 7507 */ +#define BR_TLS_FALLBACK_SCSV 0x5600 + +/* + * Symbolic constants for alerts. + */ +#define BR_ALERT_CLOSE_NOTIFY 0 +#define BR_ALERT_UNEXPECTED_MESSAGE 10 +#define BR_ALERT_BAD_RECORD_MAC 20 +#define BR_ALERT_RECORD_OVERFLOW 22 +#define BR_ALERT_DECOMPRESSION_FAILURE 30 +#define BR_ALERT_HANDSHAKE_FAILURE 40 +#define BR_ALERT_BAD_CERTIFICATE 42 +#define BR_ALERT_UNSUPPORTED_CERTIFICATE 43 +#define BR_ALERT_CERTIFICATE_REVOKED 44 +#define BR_ALERT_CERTIFICATE_EXPIRED 45 +#define BR_ALERT_CERTIFICATE_UNKNOWN 46 +#define BR_ALERT_ILLEGAL_PARAMETER 47 +#define BR_ALERT_UNKNOWN_CA 48 +#define BR_ALERT_ACCESS_DENIED 49 +#define BR_ALERT_DECODE_ERROR 50 +#define BR_ALERT_DECRYPT_ERROR 51 +#define BR_ALERT_PROTOCOL_VERSION 70 +#define BR_ALERT_INSUFFICIENT_SECURITY 71 +#define BR_ALERT_INTERNAL_ERROR 80 +#define BR_ALERT_USER_CANCELED 90 +#define BR_ALERT_NO_RENEGOTIATION 100 +#define BR_ALERT_UNSUPPORTED_EXTENSION 110 +#define BR_ALERT_NO_APPLICATION_PROTOCOL 120 + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_x509.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_x509.h new file mode 100644 index 000000000000..b86b488bd5bb --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/bearssl_x509.h @@ -0,0 +1,1588 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef BR_BEARSSL_X509_H__ +#define BR_BEARSSL_X509_H__ + +#include +#include + +#include "bearssl_ec.h" +#include "bearssl_hash.h" +#include "bearssl_rsa.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \file bearssl_x509.h + * + * # X.509 Certificate Chain Processing + * + * An X.509 processing engine receives an X.509 chain, chunk by chunk, + * as received from a SSL/TLS client or server (the client receives the + * server's certificate chain, and the server receives the client's + * certificate chain if it requested a client certificate). The chain + * is thus injected in the engine in SSL order (end-entity first). + * + * The engine's job is to return the public key to use for SSL/TLS. + * How exactly that key is obtained and verified is entirely up to the + * engine. + * + * **The "known key" engine** returns a public key which is already known + * from out-of-band information (e.g. the client _remembers_ the key from + * a previous connection, as in the usual SSH model). This is the simplest + * engine since it simply ignores the chain, thereby avoiding the need + * for any decoding logic. + * + * **The "minimal" engine** implements minimal X.509 decoding and chain + * validation: + * + * - The provided chain should validate "as is". There is no attempt + * at reordering, skipping or downloading extra certificates. + * + * - X.509 v1, v2 and v3 certificates are supported. + * + * - Trust anchors are a DN and a public key. Each anchor is either a + * "CA" anchor, or a non-CA. + * + * - If the end-entity certificate matches a non-CA anchor (subject DN + * is equal to the non-CA name, and public key is also identical to + * the anchor key), then this is a _direct trust_ case and the + * remaining certificates are ignored. + * + * - Unless direct trust is applied, the chain must be verifiable up to + * a certificate whose issuer DN matches the DN from a "CA" trust anchor, + * and whose signature is verifiable against that anchor's public key. + * Subsequent certificates in the chain are ignored. + * + * - The engine verifies subject/issuer DN matching, and enforces + * processing of Basic Constraints and Key Usage extensions. The + * Authority Key Identifier, Subject Key Identifier, Issuer Alt Name, + * Subject Directory Attribute, CRL Distribution Points, Freshest CRL, + * Authority Info Access and Subject Info Access extensions are + * ignored. The Subject Alt Name is decoded for the end-entity + * certificate under some conditions (see below). Other extensions + * are ignored if non-critical, or imply chain rejection if critical. + * + * - The Subject Alt Name extension is parsed for names of type `dNSName` + * when decoding the end-entity certificate, and only if there is a + * server name to match. If there is no SAN extension, then the + * Common Name from the subjectDN is used. That name matching is + * case-insensitive and honours a single starting wildcard (i.e. if + * the name in the certificate starts with "`*.`" then this matches + * any word as first element). Note: this name matching is performed + * also in the "direct trust" model. + * + * - DN matching is byte-to-byte equality (a future version might + * include some limited processing for case-insensitive matching and + * whitespace normalisation). + * + * - Successful validation produces a public key type but also a set + * of allowed usages (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`). + * The caller is responsible for checking that the key type and + * usages are compatible with the expected values (e.g. with the + * selected cipher suite, when the client validates the server's + * certificate). + * + * **Important caveats:** + * + * - The "minimal" engine does not check revocation status. The relevant + * extensions are ignored, and CRL or OCSP responses are not gathered + * or checked. + * + * - The "minimal" engine does not currently support Name Constraints + * (some basic functionality to handle sub-domains may be added in a + * later version). + * + * - The decoder is not "validating" in the sense that it won't reject + * some certificates with invalid field values when these fields are + * not actually processed. + */ + +/* + * X.509 error codes are in the 32..63 range. + */ + +/** \brief X.509 status: validation was successful; this is not actually + an error. */ +#define BR_ERR_X509_OK 32 + +/** \brief X.509 status: invalid value in an ASN.1 structure. */ +#define BR_ERR_X509_INVALID_VALUE 33 + +/** \brief X.509 status: truncated certificate. */ +#define BR_ERR_X509_TRUNCATED 34 + +/** \brief X.509 status: empty certificate chain (no certificate at all). */ +#define BR_ERR_X509_EMPTY_CHAIN 35 + +/** \brief X.509 status: decoding error: inner element extends beyond + outer element size. */ +#define BR_ERR_X509_INNER_TRUNC 36 + +/** \brief X.509 status: decoding error: unsupported tag class (application + or private). */ +#define BR_ERR_X509_BAD_TAG_CLASS 37 + +/** \brief X.509 status: decoding error: unsupported tag value. */ +#define BR_ERR_X509_BAD_TAG_VALUE 38 + +/** \brief X.509 status: decoding error: indefinite length. */ +#define BR_ERR_X509_INDEFINITE_LENGTH 39 + +/** \brief X.509 status: decoding error: extraneous element. */ +#define BR_ERR_X509_EXTRA_ELEMENT 40 + +/** \brief X.509 status: decoding error: unexpected element. */ +#define BR_ERR_X509_UNEXPECTED 41 + +/** \brief X.509 status: decoding error: expected constructed element, but + is primitive. */ +#define BR_ERR_X509_NOT_CONSTRUCTED 42 + +/** \brief X.509 status: decoding error: expected primitive element, but + is constructed. */ +#define BR_ERR_X509_NOT_PRIMITIVE 43 + +/** \brief X.509 status: decoding error: BIT STRING length is not multiple + of 8. */ +#define BR_ERR_X509_PARTIAL_BYTE 44 + +/** \brief X.509 status: decoding error: BOOLEAN value has invalid length. */ +#define BR_ERR_X509_BAD_BOOLEAN 45 + +/** \brief X.509 status: decoding error: value is off-limits. */ +#define BR_ERR_X509_OVERFLOW 46 + +/** \brief X.509 status: invalid distinguished name. */ +#define BR_ERR_X509_BAD_DN 47 + +/** \brief X.509 status: invalid date/time representation. */ +#define BR_ERR_X509_BAD_TIME 48 + +/** \brief X.509 status: certificate contains unsupported features that + cannot be ignored. */ +#define BR_ERR_X509_UNSUPPORTED 49 + +/** \brief X.509 status: key or signature size exceeds internal limits. */ +#define BR_ERR_X509_LIMIT_EXCEEDED 50 + +/** \brief X.509 status: key type does not match that which was expected. */ +#define BR_ERR_X509_WRONG_KEY_TYPE 51 + +/** \brief X.509 status: signature is invalid. */ +#define BR_ERR_X509_BAD_SIGNATURE 52 + +/** \brief X.509 status: validation time is unknown. */ +#define BR_ERR_X509_TIME_UNKNOWN 53 + +/** \brief X.509 status: certificate is expired or not yet valid. */ +#define BR_ERR_X509_EXPIRED 54 + +/** \brief X.509 status: issuer/subject DN mismatch in the chain. */ +#define BR_ERR_X509_DN_MISMATCH 55 + +/** \brief X.509 status: expected server name was not found in the chain. */ +#define BR_ERR_X509_BAD_SERVER_NAME 56 + +/** \brief X.509 status: unknown critical extension in certificate. */ +#define BR_ERR_X509_CRITICAL_EXTENSION 57 + +/** \brief X.509 status: not a CA, or path length constraint violation */ +#define BR_ERR_X509_NOT_CA 58 + +/** \brief X.509 status: Key Usage extension prohibits intended usage. */ +#define BR_ERR_X509_FORBIDDEN_KEY_USAGE 59 + +/** \brief X.509 status: public key found in certificate is too small. */ +#define BR_ERR_X509_WEAK_PUBLIC_KEY 60 + +/** \brief X.509 status: chain could not be linked to a trust anchor. */ +#define BR_ERR_X509_NOT_TRUSTED 62 + +/** + * \brief Aggregate structure for public keys. + */ +typedef struct { + /** \brief Key type: `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC` */ + unsigned char key_type; + /** \brief Actual public key. */ + union { + /** \brief RSA public key. */ + br_rsa_public_key rsa; + /** \brief EC public key. */ + br_ec_public_key ec; + } key; +} br_x509_pkey; + +/** + * \brief Distinguished Name (X.500) structure. + * + * The DN is DER-encoded. + */ +typedef struct { + /** \brief Encoded DN data. */ + unsigned char *data; + /** \brief Encoded DN length (in bytes). */ + size_t len; +} br_x500_name; + +/** + * \brief Trust anchor structure. + */ +typedef struct { + /** \brief Encoded DN (X.500 name). */ + br_x500_name dn; + /** \brief Anchor flags (e.g. `BR_X509_TA_CA`). */ + unsigned flags; + /** \brief Anchor public key. */ + br_x509_pkey pkey; +} br_x509_trust_anchor; + +/** + * \brief Trust anchor flag: CA. + * + * A "CA" anchor is deemed fit to verify signatures on certificates. + * A "non-CA" anchor is accepted only for direct trust (server's + * certificate name and key match the anchor). + */ +#define BR_X509_TA_CA 0x0001 + +/* + * Key type: combination of a basic key type (low 4 bits) and some + * optional flags. + * + * For a public key, the basic key type only is set. + * + * For an expected key type, the flags indicate the intended purpose(s) + * for the key; the basic key type may be set to 0 to indicate that any + * key type compatible with the indicated purpose is acceptable. + */ +/** \brief Key type: algorithm is RSA. */ +#define BR_KEYTYPE_RSA 1 +/** \brief Key type: algorithm is EC. */ +#define BR_KEYTYPE_EC 2 + +/** + * \brief Key type: usage is "key exchange". + * + * This value is combined (with bitwise OR) with the algorithm + * (`BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`) when informing the X.509 + * validation engine that it should find a public key of that type, + * fit for key exchanges (e.g. `TLS_RSA_*` and `TLS_ECDH_*` cipher + * suites). + */ +#define BR_KEYTYPE_KEYX 0x10 + +/** + * \brief Key type: usage is "signature". + * + * This value is combined (with bitwise OR) with the algorithm + * (`BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`) when informing the X.509 + * validation engine that it should find a public key of that type, + * fit for signatures (e.g. `TLS_ECDHE_*` cipher suites). + */ +#define BR_KEYTYPE_SIGN 0x20 + +/* + * start_chain Called when a new chain is started. If 'server_name' + * is not NULL and non-empty, then it is a name that + * should be looked for in the EE certificate (in the + * SAN extension as dNSName, or in the subjectDN's CN + * if there is no SAN extension). + * The caller ensures that the provided 'server_name' + * pointer remains valid throughout validation. + * + * start_cert Begins a new certificate in the chain. The provided + * length is in bytes; this is the total certificate length. + * + * append Get some additional bytes for the current certificate. + * + * end_cert Ends the current certificate. + * + * end_chain Called at the end of the chain. Returned value is + * 0 on success, or a non-zero error code. + * + * get_pkey Returns the EE certificate public key. + * + * For a complete chain, start_chain() and end_chain() are always + * called. For each certificate, start_cert(), some append() calls, then + * end_cert() are called, in that order. There may be no append() call + * at all if the certificate is empty (which is not valid but may happen + * if the peer sends exactly that). + * + * get_pkey() shall return a pointer to a structure that is valid as + * long as a new chain is not started. This may be a sub-structure + * within the context for the engine. This function MAY return a valid + * pointer to a public key even in some cases of validation failure, + * depending on the validation engine. + */ + +/** + * \brief Class type for an X.509 engine. + * + * A certificate chain validation uses a caller-allocated context, which + * contains the running state for that validation. Methods are called + * in due order: + * + * - `start_chain()` is called at the start of the validation. + * - Certificates are processed one by one, in SSL order (end-entity + * comes first). For each certificate, the following methods are + * called: + * + * - `start_cert()` at the beginning of the certificate. + * - `append()` is called zero, one or more times, to provide + * the certificate (possibly in chunks). + * - `end_cert()` at the end of the certificate. + * + * - `end_chain()` is called when the last certificate in the chain + * was processed. + * - `get_pkey()` is called after chain processing, if the chain + * validation was successful. + * + * A context structure may be reused; the `start_chain()` method shall + * ensure (re)initialisation. + */ +typedef struct br_x509_class_ br_x509_class; +struct br_x509_class_ { + /** + * \brief X.509 context size, in bytes. + */ + size_t context_size; + + /** + * \brief Start a new chain. + * + * This method shall set the vtable (first field) of the context + * structure. + * + * The `server_name`, if not `NULL`, will be considered as a + * fully qualified domain name, to be matched against the `dNSName` + * elements of the end-entity certificate's SAN extension (if there + * is no SAN, then the Common Name from the subjectDN will be used). + * If `server_name` is `NULL` then no such matching is performed. + * + * \param ctx validation context. + * \param server_name server name to match (or `NULL`). + */ + void (*start_chain)(const br_x509_class **ctx, + const char *server_name); + + /** + * \brief Start a new certificate. + * + * \param ctx validation context. + * \param length new certificate length (in bytes). + */ + void (*start_cert)(const br_x509_class **ctx, uint32_t length); + + /** + * \brief Receive some bytes for the current certificate. + * + * This function may be called several times in succession for + * a given certificate. The caller guarantees that for each + * call, `len` is not zero, and the sum of all chunk lengths + * for a certificate matches the total certificate length which + * was provided in the previous `start_cert()` call. + * + * If the new certificate is empty (no byte at all) then this + * function won't be called at all. + * + * \param ctx validation context. + * \param buf certificate data chunk. + * \param len certificate data chunk length (in bytes). + */ + void (*append)(const br_x509_class **ctx, + const unsigned char *buf, size_t len); + + /** + * \brief Finish the current certificate. + * + * This function is called when the end of the current certificate + * is reached. + * + * \param ctx validation context. + */ + void (*end_cert)(const br_x509_class **ctx); + + /** + * \brief Finish the chain. + * + * This function is called at the end of the chain. It shall + * return either 0 if the validation was successful, or a + * non-zero error code. The `BR_ERR_X509_*` constants are + * error codes, though other values may be possible. + * + * \param ctx validation context. + * \return 0 on success, or a non-zero error code. + */ + unsigned (*end_chain)(const br_x509_class **ctx); + + /** + * \brief Get the resulting end-entity public key. + * + * The decoded public key is returned. The returned pointer + * may be valid only as long as the context structure is + * unmodified, i.e. it may cease to be valid if the context + * is released or reused. + * + * This function _may_ return `NULL` if the validation failed. + * However, returning a public key does not mean that the + * validation was wholly successful; some engines may return + * a decoded public key even if the chain did not end on a + * trusted anchor. + * + * If validation succeeded and `usage` is not `NULL`, then + * `*usage` is filled with a combination of `BR_KEYTYPE_SIGN` + * and/or `BR_KEYTYPE_KEYX` that specifies the validated key + * usage types. It is the caller's responsibility to check + * that value against the intended use of the public key. + * + * \param ctx validation context. + * \return the end-entity public key, or `NULL`. + */ + const br_x509_pkey *(*get_pkey)( + const br_x509_class *const *ctx, unsigned *usages); +}; + +/** + * \brief The "known key" X.509 engine structure. + * + * The structure contents are opaque (they shall not be accessed directly), + * except for the first field (the vtable). + * + * The "known key" engine returns an externally configured public key, + * and totally ignores the certificate contents. + */ +typedef struct { + /** \brief Reference to the context vtable. */ + const br_x509_class *vtable; +#ifndef BR_DOXYGEN_IGNORE + br_x509_pkey pkey; + unsigned usages; +#endif +} br_x509_knownkey_context; + +/** + * \brief Class instance for the "known key" X.509 engine. + */ +extern const br_x509_class br_x509_knownkey_vtable; + +/** + * \brief Initialize a "known key" X.509 engine with a known RSA public key. + * + * The `usages` parameter indicates the allowed key usages for that key + * (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`). + * + * The provided pointers are linked in, not copied, so they must remain + * valid while the public key may be in usage. + * + * \param ctx context to initialise. + * \param pk known public key. + * \param usages allowed key usages. + */ +void br_x509_knownkey_init_rsa(br_x509_knownkey_context *ctx, + const br_rsa_public_key *pk, unsigned usages); + +/** + * \brief Initialize a "known key" X.509 engine with a known EC public key. + * + * The `usages` parameter indicates the allowed key usages for that key + * (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`). + * + * The provided pointers are linked in, not copied, so they must remain + * valid while the public key may be in usage. + * + * \param ctx context to initialise. + * \param pk known public key. + * \param usages allowed key usages. + */ +void br_x509_knownkey_init_ec(br_x509_knownkey_context *ctx, + const br_ec_public_key *pk, unsigned usages); + +#ifndef BR_DOXYGEN_IGNORE +/* + * The minimal X.509 engine has some state buffers which must be large + * enough to simultaneously accommodate: + * -- the public key extracted from the current certificate; + * -- the signature on the current certificate or on the previous + * certificate; + * -- the public key extracted from the EE certificate. + * + * We store public key elements in their raw unsigned big-endian + * encoding. We want to support up to RSA-4096 with a short (up to 64 + * bits) public exponent, thus a buffer for a public key must have + * length at least 520 bytes. Similarly, a RSA-4096 signature has length + * 512 bytes. + * + * Though RSA public exponents can formally be as large as the modulus + * (mathematically, even larger exponents would work, but PKCS#1 forbids + * them), exponents that do not fit on 32 bits are extremely rare, + * notably because some widespread implementations (e.g. Microsoft's + * CryptoAPI) don't support them. Moreover, large public exponent do not + * seem to imply any tangible security benefit, and they increase the + * cost of public key operations. The X.509 "minimal" engine will tolerate + * public exponents of arbitrary size as long as the modulus and the + * exponent can fit together in the dedicated buffer. + * + * EC public keys are shorter than RSA public keys; even with curve + * NIST P-521 (the largest curve we care to support), a public key is + * encoded over 133 bytes only. + */ +#define BR_X509_BUFSIZE_KEY 520 +#define BR_X509_BUFSIZE_SIG 512 +#endif + +/** + * \brief Type for receiving a name element. + * + * An array of such structures can be provided to the X.509 decoding + * engines. If the specified elements are found in the certificate + * subject DN or the SAN extension, then the name contents are copied + * as zero-terminated strings into the buffer. + * + * The decoder converts TeletexString and BMPString to UTF8String, and + * ensures that the resulting string is zero-terminated. If the string + * does not fit in the provided buffer, then the copy is aborted and an + * error is reported. + */ +typedef struct { + /** + * \brief Element OID. + * + * For X.500 name elements (to be extracted from the subject DN), + * this is the encoded OID for the requested name element; the + * first byte shall contain the length of the DER-encoded OID + * value, followed by the OID value (for instance, OID 2.5.4.3, + * for id-at-commonName, will be `03 55 04 03`). This is + * equivalent to full DER encoding with the length but without + * the tag. + * + * For SAN name elements, the first byte (`oid[0]`) has value 0, + * followed by another byte that matches the expected GeneralName + * tag. Allowed second byte values are then: + * + * - 1: `rfc822Name` + * + * - 2: `dNSName` + * + * - 6: `uniformResourceIdentifier` + * + * - 0: `otherName` + * + * If first and second byte are 0, then this is a SAN element of + * type `otherName`; the `oid[]` array should then contain, right + * after the two bytes of value 0, an encoded OID (with the same + * conventions as for X.500 name elements). If a match is found + * for that OID, then the corresponding name element will be + * extracted, as long as it is a supported string type. + */ + const unsigned char *oid; + + /** + * \brief Destination buffer. + */ + char *buf; + + /** + * \brief Length (in bytes) of the destination buffer. + * + * The buffer MUST NOT be smaller than 1 byte. + */ + size_t len; + + /** + * \brief Decoding status. + * + * Status is 0 if the name element was not found, 1 if it was + * found and decoded, or -1 on error. Error conditions include + * an unrecognised encoding, an invalid encoding, or a string + * too large for the destination buffer. + */ + int status; + +} br_name_element; + +/** + * \brief The "minimal" X.509 engine structure. + * + * The structure contents are opaque (they shall not be accessed directly), + * except for the first field (the vtable). + * + * The "minimal" engine performs a rudimentary but serviceable X.509 path + * validation. + */ +typedef struct { + const br_x509_class *vtable; + +#ifndef BR_DOXYGEN_IGNORE + /* Structure for returning the EE public key. */ + br_x509_pkey pkey; + + /* CPU for the T0 virtual machine. */ + struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; + } cpu; + uint32_t dp_stack[32]; + uint32_t rp_stack[32]; + int err; + + /* Server name to match with the SAN / CN of the EE certificate. */ + const char *server_name; + + /* Validated key usages. */ + unsigned char key_usages; + + /* Explicitly set date and time. */ + uint32_t days, seconds; + + /* Current certificate length (in bytes). Set to 0 when the + certificate has been fully processed. */ + uint32_t cert_length; + + /* Number of certificates processed so far in the current chain. + It is incremented at the end of the processing of a certificate, + so it is 0 for the EE. */ + uint32_t num_certs; + + /* Certificate data chunk. */ + const unsigned char *hbuf; + size_t hlen; + + /* The pad serves as destination for various operations. */ + unsigned char pad[256]; + + /* Buffer for EE public key data. */ + unsigned char ee_pkey_data[BR_X509_BUFSIZE_KEY]; + + /* Buffer for currently decoded public key. */ + unsigned char pkey_data[BR_X509_BUFSIZE_KEY]; + + /* Signature type: signer key type, offset to the hash + function OID (in the T0 data block) and hash function + output length (TBS hash length). */ + unsigned char cert_signer_key_type; + uint16_t cert_sig_hash_oid; + unsigned char cert_sig_hash_len; + + /* Current/last certificate signature. */ + unsigned char cert_sig[BR_X509_BUFSIZE_SIG]; + uint16_t cert_sig_len; + + /* Minimum RSA key length (difference in bytes from 128). */ + int16_t min_rsa_size; + + /* Configured trust anchors. */ + const br_x509_trust_anchor *trust_anchors; + size_t trust_anchors_num; + + /* private context for dynamic callbacks */ + void *trust_anchor_dynamic_ctx; + /* Dynamic trust anchor, for on-the-fly loading of TAs */ + const br_x509_trust_anchor* (*trust_anchor_dynamic)(void *ctx, void *hashed_dn, size_t hashed_dn_len); + /* And a chance to free any dynamically allocated TA returned from above */ + void (*trust_anchor_dynamic_free)(void *ctx, const br_x509_trust_anchor *ta); + + /* + * Multi-hasher for the TBS. + */ + unsigned char do_mhash; + br_multihash_context mhash; + unsigned char tbs_hash[64]; + + /* + * Simple hasher for the subject/issuer DN. + */ + unsigned char do_dn_hash; + const br_hash_class *dn_hash_impl; + br_hash_compat_context dn_hash; + unsigned char current_dn_hash[64]; + unsigned char next_dn_hash[64]; + unsigned char saved_dn_hash[64]; + + /* + * Name elements to gather. + */ + br_name_element *name_elts; + size_t num_name_elts; + + /* + * Public key cryptography implementations (signature verification). + */ + br_rsa_pkcs1_vrfy irsa; + br_ecdsa_vrfy iecdsa; + const br_ec_impl *iec; +#endif + +} br_x509_minimal_context; + +/** + * \brief Class instance for the "minimal" X.509 engine. + */ +extern const br_x509_class br_x509_minimal_vtable; + +/** + * \brief Initialise a "minimal" X.509 engine. + * + * The `dn_hash_impl` parameter shall be a hash function internally used + * to match X.500 names (subject/issuer DN, and anchor names). Any standard + * hash function may be used, but a collision-resistant hash function is + * advised. + * + * After initialization, some implementations for signature verification + * (hash functions and signature algorithms) MUST be added. + * + * \param ctx context to initialise. + * \param dn_hash_impl hash function for DN comparisons. + * \param trust_anchors trust anchors. + * \param trust_anchors_num number of trust anchors. + */ +void br_x509_minimal_init(br_x509_minimal_context *ctx, + const br_hash_class *dn_hash_impl, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); + +/** + * \brief Set the optional dynamic trust anchor lookup callbacks + * + * The dynamic trust anchor lookup callbacks allow an application to implement + * a non-memory resident trust anchor store. This can be useful on embedded + * systems where RAM is at a premium, but there is an external stable store, + * such as embedded flash or SD card, to keep many CA certificates. Set or + * leave these functions as NULL to not use such a feature. + * + * The dynamic routine will be passed in the hashed DN in question using the + * dn_hash_impl, and should compare this DN to its set of hashed known DNs. + * Of course, the same dn_hash_impl needs to be used in the dynamic routine. + * After the trust_anchor* is used, the dynamic_free callback is given a + * chance to deallocate its memory, if needed. + * + * \param ctx context to initialise. + * \param dynamic_ctx private context for the dynamic callback + * \param trust_anchor_dynamic provides a trust_anchor* for a hashed_dn + * \param trust_anchor_dynamic_free allows deallocation of returned TA + */ +static inline void +br_x509_minimal_set_dynamic(br_x509_minimal_context *ctx, void *dynamic_ctx, + const br_x509_trust_anchor* (*dynamic)(void *ctx, void *hashed_dn, size_t hashed_dn_len), + void (*dynamic_free)(void *ctx, const br_x509_trust_anchor *ta)) +{ + ctx->trust_anchor_dynamic_ctx = dynamic_ctx; + ctx->trust_anchor_dynamic = dynamic; + ctx->trust_anchor_dynamic_free = dynamic_free; +} + +/** + * \brief Set a supported hash function in an X.509 "minimal" engine. + * + * Hash functions are used with signature verification algorithms. + * Once initialised (with `br_x509_minimal_init()`), the context must + * be configured with the hash functions it shall support for that + * purpose. The hash function identifier MUST be one of the standard + * hash function identifiers (1 to 6, for MD5, SHA-1, SHA-224, SHA-256, + * SHA-384 and SHA-512). + * + * If `impl` is `NULL`, this _removes_ support for the designated + * hash function. + * + * \param ctx validation context. + * \param id hash function identifier (from 1 to 6). + * \param impl hash function implementation (or `NULL`). + */ +static inline void +br_x509_minimal_set_hash(br_x509_minimal_context *ctx, + int id, const br_hash_class *impl) +{ + br_multihash_setimpl(&ctx->mhash, id, impl); +} + +/** + * \brief Set a RSA signature verification implementation in the X.509 + * "minimal" engine. + * + * Once initialised (with `br_x509_minimal_init()`), the context must + * be configured with the signature verification implementations that + * it is supposed to support. If `irsa` is `0`, then the RSA support + * is disabled. + * + * \param ctx validation context. + * \param irsa RSA signature verification implementation (or `0`). + */ +static inline void +br_x509_minimal_set_rsa(br_x509_minimal_context *ctx, + br_rsa_pkcs1_vrfy irsa) +{ + ctx->irsa = irsa; +} + +/** + * \brief Set a ECDSA signature verification implementation in the X.509 + * "minimal" engine. + * + * Once initialised (with `br_x509_minimal_init()`), the context must + * be configured with the signature verification implementations that + * it is supposed to support. + * + * If `iecdsa` is `0`, then this call disables ECDSA support; in that + * case, `iec` may be `NULL`. Otherwise, `iecdsa` MUST point to a function + * that verifies ECDSA signatures with format "asn1", and it will use + * `iec` as underlying elliptic curve support. + * + * \param ctx validation context. + * \param iec elliptic curve implementation (or `NULL`). + * \param iecdsa ECDSA implementation (or `0`). + */ +static inline void +br_x509_minimal_set_ecdsa(br_x509_minimal_context *ctx, + const br_ec_impl *iec, br_ecdsa_vrfy iecdsa) +{ + ctx->iecdsa = iecdsa; + ctx->iec = iec; +} + +/** + * \brief Initialise a "minimal" X.509 engine with default algorithms. + * + * This function performs the same job as `br_x509_minimal_init()`, but + * also sets implementations for RSA, ECDSA, and the standard hash + * functions. + * + * \param ctx context to initialise. + * \param trust_anchors trust anchors. + * \param trust_anchors_num number of trust anchors. + */ +void br_x509_minimal_init_full(br_x509_minimal_context *ctx, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num); + +/** + * \brief Set the validation time for the X.509 "minimal" engine. + * + * The validation time is set as two 32-bit integers, for days and + * seconds since a fixed epoch: + * + * - Days are counted in a proleptic Gregorian calendar since + * January 1st, 0 AD. Year "0 AD" is the one that preceded "1 AD"; + * it is also traditionally known as "1 BC". + * + * - Seconds are counted since midnight, from 0 to 86400 (a count of + * 86400 is possible only if a leap second happened). + * + * The validation date and time is understood in the UTC time zone. + * + * If the validation date and time are not explicitly set, but BearSSL + * was compiled with support for the system clock on the underlying + * platform, then the current time will automatically be used. Otherwise, + * not setting the validation date and time implies a validation + * failure (except in case of direct trust of the EE key). + * + * \param ctx validation context. + * \param days days since January 1st, 0 AD (Gregorian calendar). + * \param seconds seconds since midnight (0 to 86400). + */ +static inline void +br_x509_minimal_set_time(br_x509_minimal_context *ctx, + uint32_t days, uint32_t seconds) +{ + ctx->days = days; + ctx->seconds = seconds; +} + +/** + * \brief Set the minimal acceptable length for RSA keys (X.509 "minimal" + * engine). + * + * The RSA key length is expressed in bytes. The default minimum key + * length is 128 bytes, corresponding to 1017 bits. RSA keys shorter + * than the configured length will be rejected, implying validation + * failure. This setting applies to keys extracted from certificates + * (both end-entity, and intermediate CA) but not to "CA" trust anchors. + * + * \param ctx validation context. + * \param byte_length minimum RSA key length, **in bytes** (not bits). + */ +static inline void +br_x509_minimal_set_minrsa(br_x509_minimal_context *ctx, int byte_length) +{ + ctx->min_rsa_size = (int16_t)(byte_length - 128); +} + +/** + * \brief Set the name elements to gather. + * + * The provided array is linked in the context. The elements are + * gathered from the EE certificate. If the same element type is + * requested several times, then the relevant structures will be filled + * in the order the matching values are encountered in the certificate. + * + * \param ctx validation context. + * \param elts array of name element structures to fill. + * \param num_elts number of name element structures to fill. + */ +static inline void +br_x509_minimal_set_name_elements(br_x509_minimal_context *ctx, + br_name_element *elts, size_t num_elts) +{ + ctx->name_elts = elts; + ctx->num_name_elts = num_elts; +} + +/** + * \brief X.509 decoder context. + * + * This structure is _not_ for X.509 validation, but for extracting + * names and public keys from encoded certificates. Intended usage is + * to use (self-signed) certificates as trust anchors. + * + * Contents are opaque and shall not be accessed directly. + */ +typedef struct { + +#ifndef BR_DOXYGEN_IGNORE + /* Structure for returning the public key. */ + br_x509_pkey pkey; + + /* CPU for the T0 virtual machine. */ + struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; + } cpu; + uint32_t dp_stack[32]; + uint32_t rp_stack[32]; + int err; + + /* The pad serves as destination for various operations. */ + unsigned char pad[256]; + + /* Flag set when decoding succeeds. */ + unsigned char decoded; + + /* Validity dates. */ + uint32_t notbefore_days, notbefore_seconds; + uint32_t notafter_days, notafter_seconds; + + /* The "CA" flag. This is set to true if the certificate contains + a Basic Constraints extension that asserts CA status. */ + unsigned char isCA; + + /* DN processing: the subject DN is extracted and pushed to the + provided callback. */ + unsigned char copy_dn; + void *append_dn_ctx; + void (*append_dn)(void *ctx, const void *buf, size_t len); + + /* Certificate data chunk. */ + const unsigned char *hbuf; + size_t hlen; + + /* Buffer for decoded public key. */ + unsigned char pkey_data[BR_X509_BUFSIZE_KEY]; + + /* Type of key and hash function used in the certificate signature. */ + unsigned char signer_key_type; + unsigned char signer_hash_id; +#endif + +} br_x509_decoder_context_libmail; + +/** + * \brief Initialise an X.509 decoder context for processing a new + * certificate. + * + * The `append_dn()` callback (with opaque context `append_dn_ctx`) + * will be invoked to receive, chunk by chunk, the certificate's + * subject DN. If `append_dn` is `0` then the subject DN will be + * ignored. + * + * \param ctx X.509 decoder context to initialise. + * \param append_dn DN receiver callback (or `0`). + * \param append_dn_ctx context for the DN receiver callback. + */ +void br_x509_decoder_init_libmail(br_x509_decoder_context_libmail *ctx, + void (*append_dn)(void *ctx, const void *buf, size_t len), + void *append_dn_ctx); + +/** + * \brief Push some certificate bytes into a decoder context. + * + * If `len` is non-zero, then that many bytes are pushed, from address + * `data`, into the provided decoder context. + * + * \param ctx X.509 decoder context. + * \param data certificate data chunk. + * \param len certificate data chunk length (in bytes). + */ +void br_x509_decoder_push_libmail(br_x509_decoder_context_libmail *ctx, + const void *data, size_t len); + +/** + * \brief Obtain the decoded public key. + * + * Returned value is a pointer to a structure internal to the decoder + * context; releasing or reusing the decoder context invalidates that + * structure. + * + * If decoding was not finished, or failed, then `NULL` is returned. + * + * \param ctx X.509 decoder context. + * \return the public key, or `NULL` on unfinished/error. + */ +static inline br_x509_pkey * +br_x509_decoder_get_pkey(br_x509_decoder_context_libmail *ctx) +{ + if (ctx->decoded && ctx->err == 0) { + return &ctx->pkey; + } else { + return NULL; + } +} + +/** + * \brief Get decoder error status. + * + * If no error was reported yet but the certificate decoding is not + * finished, then the error code is `BR_ERR_X509_TRUNCATED`. If decoding + * was successful, then 0 is returned. + * + * \param ctx X.509 decoder context. + * \return 0 on successful decoding, or a non-zero error code. + */ +static inline int +br_x509_decoder_last_error(br_x509_decoder_context_libmail *ctx) +{ + if (ctx->err != 0) { + return ctx->err; + } + if (!ctx->decoded) { + return BR_ERR_X509_TRUNCATED; + } + return 0; +} + +/** + * \brief Get the "isCA" flag from an X.509 decoder context. + * + * This flag is set if the decoded certificate claims to be a CA through + * a Basic Constraints extension. This flag should not be read before + * decoding completed successfully. + * + * \param ctx X.509 decoder context. + * \return the "isCA" flag. + */ +static inline int +br_x509_decoder_isCA(br_x509_decoder_context_libmail *ctx) +{ + return ctx->isCA; +} + +/** + * \brief Get the issuing CA key type (type of algorithm used to sign the + * decoded certificate). + * + * This is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. The value 0 is returned + * if the signature type was not recognised. + * + * \param ctx X.509 decoder context. + * \return the issuing CA key type. + */ +static inline int +br_x509_decoder_get_signer_key_type(br_x509_decoder_context_libmail *ctx) +{ + return ctx->signer_key_type; +} + +/** + * \brief Get the identifier for the hash function used to sign the decoded + * certificate. + * + * This is 0 if the hash function was not recognised. + * + * \param ctx X.509 decoder context. + * \return the signature hash function identifier. + */ +static inline int +br_x509_decoder_get_signer_hash_id(br_x509_decoder_context_libmail *ctx) +{ + return ctx->signer_hash_id; +} + +/** + * \brief Type for an X.509 certificate (DER-encoded). + */ +typedef struct { + /** \brief The DER-encoded certificate data. */ + unsigned char *data; + /** \brief The DER-encoded certificate length (in bytes). */ + size_t data_len; +} br_x509_certificate; + +/** + * \brief Private key decoder context. + * + * The private key decoder recognises RSA and EC private keys, either in + * their raw, DER-encoded format, or wrapped in an unencrypted PKCS#8 + * archive (again DER-encoded). + * + * Structure contents are opaque and shall not be accessed directly. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + /* Structure for returning the private key. */ + union { + br_rsa_private_key rsa; + br_ec_private_key ec; + } key; + + /* CPU for the T0 virtual machine. */ + struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; + } cpu; + uint32_t dp_stack[32]; + uint32_t rp_stack[32]; + int err; + + /* Private key data chunk. */ + const unsigned char *hbuf; + size_t hlen; + + /* The pad serves as destination for various operations. */ + unsigned char pad[256]; + + /* Decoded key type; 0 until decoding is complete. */ + unsigned char key_type; + + /* Buffer for the private key elements. It shall be large enough + to accommodate all elements for a RSA-4096 private key (roughly + five 2048-bit integers, possibly a bit more). */ + unsigned char key_data[3 * BR_X509_BUFSIZE_SIG]; +#endif +} br_skey_decoder_context; + +/** + * \brief Initialise a private key decoder context. + * + * \param ctx key decoder context to initialise. + */ +void br_skey_decoder_init(br_skey_decoder_context *ctx); + +/** + * \brief Push some data bytes into a private key decoder context. + * + * If `len` is non-zero, then that many data bytes, starting at address + * `data`, are pushed into the decoder. + * + * \param ctx key decoder context. + * \param data private key data chunk. + * \param len private key data chunk length (in bytes). + */ +void br_skey_decoder_push(br_skey_decoder_context *ctx, + const void *data, size_t len); + +/** + * \brief Get the decoding status for a private key. + * + * Decoding status is 0 on success, or a non-zero error code. If the + * decoding is unfinished when this function is called, then the + * status code `BR_ERR_X509_TRUNCATED` is returned. + * + * \param ctx key decoder context. + * \return 0 on successful decoding, or a non-zero error code. + */ +static inline int +br_skey_decoder_last_error(const br_skey_decoder_context *ctx) +{ + if (ctx->err != 0) { + return ctx->err; + } + if (ctx->key_type == 0) { + return BR_ERR_X509_TRUNCATED; + } + return 0; +} + +/** + * \brief Get the decoded private key type. + * + * Private key type is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. If decoding is + * not finished or failed, then 0 is returned. + * + * \param ctx key decoder context. + * \return decoded private key type, or 0. + */ +static inline int +br_skey_decoder_key_type(const br_skey_decoder_context *ctx) +{ + if (ctx->err == 0) { + return ctx->key_type; + } else { + return 0; + } +} + +/** + * \brief Get the decoded RSA private key. + * + * This function returns `NULL` if the decoding failed, or is not + * finished, or the key is not RSA. The returned pointer references + * structures within the context that can become invalid if the context + * is reused or released. + * + * \param ctx key decoder context. + * \return decoded RSA private key, or `NULL`. + */ +static inline const br_rsa_private_key * +br_skey_decoder_get_rsa(const br_skey_decoder_context *ctx) +{ + if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_RSA) { + return &ctx->key.rsa; + } else { + return NULL; + } +} + +/** + * \brief Get the decoded EC private key. + * + * This function returns `NULL` if the decoding failed, or is not + * finished, or the key is not EC. The returned pointer references + * structures within the context that can become invalid if the context + * is reused or released. + * + * \param ctx key decoder context. + * \return decoded EC private key, or `NULL`. + */ +static inline const br_ec_private_key * +br_skey_decoder_get_ec(const br_skey_decoder_context *ctx) +{ + if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_EC) { + return &ctx->key.ec; + } else { + return NULL; + } +} + +/** + * \brief Public key decoder context. + * + * The public key decoder recognises RSA and EC private keys, either in + * their raw, DER-encoded format, or wrapped in an unencrypted PKCS#8 + * archive (again DER-encoded). + * + * Structure contents are opaque and shall not be accessed directly. + */ +typedef struct { +#ifndef BR_DOXYGEN_IGNORE + /* Structure for returning the private key. */ + union { + br_rsa_public_key rsa; + br_ec_public_key ec; + } key; + + /* CPU for the T0 virtual machine. */ + struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; + } cpu; + uint32_t dp_stack[32]; + uint32_t rp_stack[32]; + int err; + + /* Private key data chunk. */ + const unsigned char *hbuf; + size_t hlen; + + /* The pad serves as destination for various operations. */ + unsigned char pad[256]; + + /* Decoded key type; 0 until decoding is complete. */ + unsigned char key_type; + + /* Buffer for the private key elements. It shall be large enough + to accommodate all elements for a RSA-4096 private key (roughly + five 2048-bit integers, possibly a bit more). */ + unsigned char key_data[3 * BR_X509_BUFSIZE_SIG]; +#endif +} br_pkey_decoder_context; + + +/** + * \brief Initialise a public key decoder context. + * + * \param ctx key decoder context to initialise. + */ +void br_pkey_decoder_init(br_pkey_decoder_context *ctx); + +/** + * \brief Push some data bytes into a public key decoder context. + * + * If `len` is non-zero, then that many data bytes, starting at address + * `data`, are pushed into the decoder. + * + * \param ctx key decoder context. + * \param data private key data chunk. + * \param len private key data chunk length (in bytes). + */ +void br_pkey_decoder_push(br_pkey_decoder_context *ctx, + const void *data, size_t len); + +/** + * \brief Get the decoding status for a public key. + * + * Decoding status is 0 on success, or a non-zero error code. If the + * decoding is unfinished when this function is called, then the + * status code `BR_ERR_X509_TRUNCATED` is returned. + * + * \param ctx key decoder context. + * \return 0 on successful decoding, or a non-zero error code. + */ +static inline int +br_pkey_decoder_last_error(const br_pkey_decoder_context *ctx) +{ + if (ctx->err != 0) { + return ctx->err; + } + if (ctx->key_type == 0) { + return BR_ERR_X509_TRUNCATED; + } + return 0; +} + +/** + * \brief Get the decoded public key type. + * + * Public key type is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. If decoding is + * not finished or failed, then 0 is returned. + * + * \param ctx key decoder context. + * \return decoded private key type, or 0. + */ +static inline int +br_pkey_decoder_key_type(const br_pkey_decoder_context *ctx) +{ + if (ctx->err == 0) { + return ctx->key_type; + } else { + return 0; + } +} + +/** + * \brief Get the decoded RSA public key. + * + * This function returns `NULL` if the decoding failed, or is not + * finished, or the key is not RSA. The returned pointer references + * structures within the context that can become invalid if the context + * is reused or released. + * + * \param ctx key decoder context. + * \return decoded RSA public key, or `NULL`. + */ +static inline const br_rsa_public_key * +br_pkey_decoder_get_rsa(const br_pkey_decoder_context *ctx) +{ + if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_RSA) { + return &ctx->key.rsa; + } else { + return NULL; + } +} + +/** + * \brief Get the decoded EC private key. + * + * This function returns `NULL` if the decoding failed, or is not + * finished, or the key is not EC. The returned pointer references + * structures within the context that can become invalid if the context + * is reused or released. + * + * \param ctx key decoder context. + * \return decoded EC private key, or `NULL`. + */ +static inline const br_ec_public_key * +br_pkey_decoder_get_ec(const br_pkey_decoder_context *ctx) +{ + if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_EC) { + return &ctx->key.ec; + } else { + return NULL; + } +} + +/** + * \brief Encode an RSA private key (raw DER format). + * + * This function encodes the provided key into the "raw" format specified + * in PKCS#1 (RFC 8017, Appendix C, type `RSAPrivateKey`), with DER + * encoding rules. + * + * The key elements are: + * + * - `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`) + * + * - `pk`: the public key (`n` and `e`) + * + * - `d` (size: `dlen` bytes): the private exponent + * + * The public key elements, and the private exponent `d`, can be + * recomputed from the private key (see `br_rsa_compute_modulus()`, + * `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`). + * + * If `dest` is not `NULL`, then the encoded key is written at that + * address, and the encoded length (in bytes) is returned. If `dest` is + * `NULL`, then nothing is written, but the encoded length is still + * computed and returned. + * + * \param dest the destination buffer (or `NULL`). + * \param sk the RSA private key. + * \param pk the RSA public key. + * \param d the RSA private exponent. + * \param dlen the RSA private exponent length (in bytes). + * \return the encoded key length (in bytes). + */ +size_t br_encode_rsa_raw_der(void *dest, const br_rsa_private_key *sk, + const br_rsa_public_key *pk, const void *d, size_t dlen); + +/** + * \brief Encode an RSA private key (PKCS#8 DER format). + * + * This function encodes the provided key into the PKCS#8 format + * (RFC 5958, type `OneAsymmetricKey`). It wraps around the "raw DER" + * format for the RSA key, as implemented by `br_encode_rsa_raw_der()`. + * + * The key elements are: + * + * - `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`) + * + * - `pk`: the public key (`n` and `e`) + * + * - `d` (size: `dlen` bytes): the private exponent + * + * The public key elements, and the private exponent `d`, can be + * recomputed from the private key (see `br_rsa_compute_modulus()`, + * `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`). + * + * If `dest` is not `NULL`, then the encoded key is written at that + * address, and the encoded length (in bytes) is returned. If `dest` is + * `NULL`, then nothing is written, but the encoded length is still + * computed and returned. + * + * \param dest the destination buffer (or `NULL`). + * \param sk the RSA private key. + * \param pk the RSA public key. + * \param d the RSA private exponent. + * \param dlen the RSA private exponent length (in bytes). + * \return the encoded key length (in bytes). + */ +size_t br_encode_rsa_pkcs8_der(void *dest, const br_rsa_private_key *sk, + const br_rsa_public_key *pk, const void *d, size_t dlen); + +/** + * \brief Encode an EC private key (raw DER format). + * + * This function encodes the provided key into the "raw" format specified + * in RFC 5915 (type `ECPrivateKey`), with DER encoding rules. + * + * The private key is provided in `sk`, the public key being `pk`. If + * `pk` is `NULL`, then the encoded key will not include the public key + * in its `publicKey` field (which is nominally optional). + * + * If `dest` is not `NULL`, then the encoded key is written at that + * address, and the encoded length (in bytes) is returned. If `dest` is + * `NULL`, then nothing is written, but the encoded length is still + * computed and returned. + * + * If the key cannot be encoded (e.g. because there is no known OBJECT + * IDENTIFIER for the used curve), then 0 is returned. + * + * \param dest the destination buffer (or `NULL`). + * \param sk the EC private key. + * \param pk the EC public key (or `NULL`). + * \return the encoded key length (in bytes), or 0. + */ +size_t br_encode_ec_raw_der(void *dest, + const br_ec_private_key *sk, const br_ec_public_key *pk); + +/** + * \brief Encode an EC private key (PKCS#8 DER format). + * + * This function encodes the provided key into the PKCS#8 format + * (RFC 5958, type `OneAsymmetricKey`). The curve is identified + * by an OID provided as parameters to the `privateKeyAlgorithm` + * field. The private key value (contents of the `privateKey` field) + * contains the DER encoding of the `ECPrivateKey` type defined in + * RFC 5915, without the `parameters` field (since they would be + * redundant with the information in `privateKeyAlgorithm`). + * + * The private key is provided in `sk`, the public key being `pk`. If + * `pk` is not `NULL`, then the encoded public key is included in the + * `publicKey` field of the private key value (but not in the `publicKey` + * field of the PKCS#8 `OneAsymmetricKey` wrapper). + * + * If `dest` is not `NULL`, then the encoded key is written at that + * address, and the encoded length (in bytes) is returned. If `dest` is + * `NULL`, then nothing is written, but the encoded length is still + * computed and returned. + * + * If the key cannot be encoded (e.g. because there is no known OBJECT + * IDENTIFIER for the used curve), then 0 is returned. + * + * \param dest the destination buffer (or `NULL`). + * \param sk the EC private key. + * \param pk the EC public key (or `NULL`). + * \return the encoded key length (in bytes), or 0. + */ +size_t br_encode_ec_pkcs8_der(void *dest, + const br_ec_private_key *sk, const br_ec_public_key *pk); + +/** + * \brief PEM banner for RSA private key (raw). + */ +#define BR_ENCODE_PEM_RSA_RAW "RSA PRIVATE KEY" + +/** + * \brief PEM banner for EC private key (raw). + */ +#define BR_ENCODE_PEM_EC_RAW "EC PRIVATE KEY" + +/** + * \brief PEM banner for an RSA or EC private key in PKCS#8 format. + */ +#define BR_ENCODE_PEM_PKCS8 "PRIVATE KEY" + +#ifdef __cplusplus +} +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/config.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/config.h new file mode 100644 index 000000000000..08e78dedf36d --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/config.h @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef CONFIG_H__ +#define CONFIG_H__ + +/* + * This file contains compile-time flags that can override the + * autodetection performed in relevant files. Each flag is a macro; it + * deactivates the feature if defined to 0, activates it if defined to a + * non-zero integer (normally 1). If the macro is not defined, then + * autodetection applies. + */ + +/* + * When BR_64 is enabled, 64-bit integer types are assumed to be + * efficient (i.e. the architecture has 64-bit registers and can + * do 64-bit operations as fast as 32-bit operations). + * +#define BR_64 1 + */ + +/* + * When BR_LOMUL is enabled, then multiplications of 32-bit values whose + * result are truncated to the low 32 bits are assumed to be + * substantially more efficient than 32-bit multiplications that yield + * 64-bit results. This is typically the case on low-end ARM Cortex M + * systems (M0, M0+, M1, and arguably M3 and M4 as well). +#define BR_LOMUL 1 + */ + +/* + * When BR_SLOW_MUL is enabled, multiplications are assumed to be + * substantially slow with regards to other integer operations, thus + * making it worth to make more operations for a given task if it allows + * using less multiplications. + * +#define BR_SLOW_MUL 1 + */ + +/* + * When BR_SLOW_MUL15 is enabled, short multplications (on 15-bit words) + * are assumed to be substantially slow with regards to other integer + * operations, thus making it worth to make more integer operations if + * it allows using less multiplications. + * +#define BR_SLOW_MUL15 1 + */ + +/* + * When BR_CT_MUL31 is enabled, multiplications of 31-bit values (used + * in the "i31" big integer implementation) use an alternate implementation + * which is slower and larger than the normal multiplication, but should + * ensure constant-time multiplications even on architectures where the + * multiplication opcode takes a variable number of cycles to complete. + * +#define BR_CT_MUL31 1 + */ + +/* + * When BR_CT_MUL15 is enabled, multiplications of 15-bit values (held + * in 32-bit words) use an alternate implementation which is slower and + * larger than the normal multiplication, but should ensure + * constant-time multiplications on most/all architectures where the + * basic multiplication is not constant-time. +#define BR_CT_MUL15 1 + */ + +/* + * When BR_NO_ARITH_SHIFT is enabled, arithmetic right shifts (with sign + * extension) are performed with a sequence of operations which is bigger + * and slower than a simple right shift on a signed value. This avoids + * relying on an implementation-defined behaviour. However, most if not + * all C compilers use sign extension for right shifts on signed values, + * so this alternate macro is disabled by default. +#define BR_NO_ARITH_SHIFT 1 + */ + +/* + * When BR_RDRAND is enabled, the SSL engine will use the RDRAND opcode + * to automatically obtain quality randomness for seeding its internal + * PRNG. Since that opcode is present only in recent x86 CPU, its + * support is dynamically tested; if the current CPU does not support + * it, then another random source will be used, such as /dev/urandom or + * CryptGenRandom(). + * +#define BR_RDRAND 1 + */ + +/* + * When BR_USE_GETENTROPY is enabled, the SSL engine will use the + * getentropy() function to obtain quality randomness for seeding its + * internal PRNG. On Linux and FreeBSD, getentropy() is implemented by + * the standard library with the system call getrandom(); on OpenBSD, + * getentropy() is the system call, and there is no getrandom() wrapper, + * hence the use of the getentropy() function for maximum portability. + * + * If the getentropy() call fails, and BR_USE_URANDOM is not explicitly + * disabled, then /dev/urandom will be used as a fallback mechanism. On + * FreeBSD and OpenBSD, this does not change much, since /dev/urandom + * will block if not enough entropy has been obtained since last boot. + * On Linux, /dev/urandom might not block, which can be troublesome in + * early boot stages, which is why getentropy() is preferred. + * +#define BR_USE_GETENTROPY 1 + */ + +/* + * When BR_USE_URANDOM is enabled, the SSL engine will use /dev/urandom + * to automatically obtain quality randomness for seeding its internal + * PRNG. + * +#define BR_USE_URANDOM 1 + */ + +/* + * When BR_USE_WIN32_RAND is enabled, the SSL engine will use the Win32 + * (CryptoAPI) functions (CryptAcquireContext(), CryptGenRandom()...) to + * automatically obtain quality randomness for seeding its internal PRNG. + * + * Note: if both BR_USE_URANDOM and BR_USE_WIN32_RAND are defined, the + * former takes precedence. + * +#define BR_USE_WIN32_RAND 1 + */ + +/* + * When BR_USE_UNIX_TIME is enabled, the X.509 validation engine obtains + * the current time from the OS by calling time(), and assuming that the + * returned value (a 'time_t') is an integer that counts time in seconds + * since the Unix Epoch (Jan 1st, 1970, 00:00 UTC). + */ +#define BR_USE_UNIX_TIME 0 + + +/* + * When BR_USE_WIN32_TIME is enabled, the X.509 validation engine obtains + * the current time from the OS by calling the Win32 function + * GetSystemTimeAsFileTime(). + * + * Note: if both BR_USE_UNIX_TIME and BR_USE_WIN32_TIME are defined, the + * former takes precedence. + * +#define BR_USE_WIN32_TIME 1 + */ + +/* + * When BR_ARMEL_CORTEXM_GCC is enabled, some operations are replaced with + * inline assembly which is shorter and/or faster. This should be used + * only when all of the following are true: + * - target architecture is ARM in Thumb mode + * - target endianness is little-endian + * - compiler is GCC (or GCC-compatible for inline assembly syntax) + * + * This is meant for the low-end cores (Cortex M0, M0+, M1, M3). + * Note: if BR_LOMUL is not explicitly enabled or disabled, then + * enabling BR_ARMEL_CORTEXM_GCC also enables BR_LOMUL. + */ +#if defined(__arm__) && defined(__thumb__) +#define BR_ARMEL_CORTEXM_GCC 1 +#endif + +/* + * When BR_AES_X86NI is enabled, the AES implementation using the x86 "NI" + * instructions (dedicated AES opcodes) will be compiled. If this is not + * enabled explicitly, then that AES implementation will be compiled only + * if a compatible compiler is detected. If set explicitly to 0, the + * implementation will not be compiled at all. + * +#define BR_AES_X86NI 1 + */ + +/* + * When BR_SSE2 is enabled, SSE2 intrinsics will be used for some + * algorithm implementations that use them (e.g. chacha20_sse2). If this + * is not enabled explicitly, then support for SSE2 intrinsics will be + * automatically detected. If set explicitly to 0, then SSE2 code will + * not be compiled at all. + * +#define BR_SSE2 1 + */ + +/* + * When BR_POWER8 is enabled, the AES implementation using the POWER ISA + * 2.07 opcodes (available on POWER8 processors and later) is compiled. + * If this is not enabled explicitly, then that implementation will be + * compiled only if a compatible compiler is detected, _and_ the target + * architecture is POWER8 or later. + * +#define BR_POWER8 1 + */ + +/* + * When BR_INT128 is enabled, then code using the 'unsigned __int64' + * and 'unsigned __int128' types will be used to leverage 64x64->128 + * unsigned multiplications. This should work with GCC and compatible + * compilers on 64-bit architectures. + * +#define BR_INT128 1 + */ + +/* + * When BR_UMUL128 is enabled, then code using the '_umul128()' and + * '_addcarry_u64()' intrinsics will be used to implement 64x64->128 + * unsigned multiplications. This should work on Visual C on x64 systems. + * +#define BR_UMUL128 1 + */ + +/* + * When BR_LE_UNALIGNED is enabled, then the current architecture is + * assumed to use little-endian encoding for integers, and to tolerate + * unaligned accesses with no or minimal time penalty. + * +#define BR_LE_UNALIGNED 1 + */ + +/* + * When BR_BE_UNALIGNED is enabled, then the current architecture is + * assumed to use big-endian encoding for integers, and to tolerate + * unaligned accesses with no or minimal time penalty. + * +#define BR_BE_UNALIGNED 1 + */ + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/inner.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/inner.h new file mode 100644 index 000000000000..1c4b4f3c5573 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/inner.h @@ -0,0 +1,2583 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#ifndef INNER_H__ +#define INNER_H__ + +#include +#include + +#include "config.h" +#include "bearssl.h" + +/* + * On MSVC, disable the warning about applying unary minus on an + * unsigned type: it is standard, we do it all the time, and for + * good reasons. + */ +#if _MSC_VER +#pragma warning( disable : 4146 ) +#endif + +/* + * Maximum size for a RSA modulus (in bits). Allocated stack buffers + * depend on that size, so this value should be kept small. Currently, + * 2048-bit RSA keys offer adequate security, and should still do so for + * the next few decades; however, a number of widespread PKI have + * already set their root keys to RSA-4096, so we should be able to + * process such keys. + * + * This value MUST be a multiple of 64. This value MUST NOT exceed 47666 + * (some computations in RSA key generation rely on the factor size being + * no more than 23833 bits). RSA key sizes beyond 3072 bits don't make a + * lot of sense anyway. + */ +#define BR_MAX_RSA_SIZE 4096 + +/* + * Minimum size for a RSA modulus (in bits); this value is used only to + * filter out invalid parameters for key pair generation. Normally, + * applications should not use RSA keys smaller than 2048 bits; but some + * specific cases might need shorter keys, for legacy or research + * purposes. + */ +#define BR_MIN_RSA_SIZE 512 + +/* + * Maximum size for a RSA factor (in bits). This is for RSA private-key + * operations. Default is to support factors up to a bit more than half + * the maximum modulus size. + * + * This value MUST be a multiple of 32. + */ +#define BR_MAX_RSA_FACTOR ((BR_MAX_RSA_SIZE + 64) >> 1) + +/* + * Maximum size for an EC curve (modulus or order), in bits. Size of + * stack buffers depends on that parameter. This size MUST be a multiple + * of 8 (so that decoding an integer with that many bytes does not + * overflow). + */ +#define BR_MAX_EC_SIZE 528 + +/* + * Some macros to recognize the current architecture. Right now, we are + * interested into automatically recognizing architecture with efficient + * 64-bit types so that we may automatically use implementations that + * use 64-bit registers in that case. Future versions may detect, e.g., + * availability of SSE2 intrinsics. + * + * If 'unsigned long' is a 64-bit type, then we assume that 64-bit types + * are efficient. Otherwise, we rely on macros that depend on compiler, + * OS and architecture. In any case, failure to detect the architecture + * as 64-bit means that the 32-bit code will be used, and that code + * works also on 64-bit architectures (the 64-bit code may simply be + * more efficient). + * + * The test on 'unsigned long' should already catch most cases, the one + * notable exception being Windows code where 'unsigned long' is kept to + * 32-bit for compatibility with all the legacy code that liberally uses + * the 'DWORD' type for 32-bit values. + * + * Macro names are taken from: http://nadeausoftware.com/articles/2012/02/c_c_tip_how_detect_processor_type_using_compiler_predefined_macros + */ +#ifndef BR_64 +#if ((ULONG_MAX >> 31) >> 31) == 3 +#define BR_64 1 +#elif defined(__ia64) || defined(__itanium__) || defined(_M_IA64) +#define BR_64 1 +#elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) \ + || defined(__64BIT__) || defined(_LP64) || defined(__LP64__) +#define BR_64 1 +#elif defined(__sparc64__) +#define BR_64 1 +#elif defined(__x86_64__) || defined(_M_X64) +#define BR_64 1 +#elif defined(__aarch64__) || defined(_M_ARM64) +#define BR_64 1 +#elif defined(__mips64) +#define BR_64 1 +#endif +#endif + +/* + * Set BR_LOMUL on platforms where it makes sense. + */ +#ifndef BR_LOMUL +#if BR_ARMEL_CORTEXM_GCC +#define BR_LOMUL 1 +#endif +#endif + +/* + * Architecture detection. + */ +#ifndef BR_i386 +#if __i386__ || _M_IX86 +#define BR_i386 1 +#endif +#endif + +#ifndef BR_amd64 +#if __x86_64__ || _M_X64 +#define BR_amd64 1 +#endif +#endif + +/* + * Compiler brand and version. + * + * Implementations that use intrinsics need to detect the compiler type + * and version because some specific actions may be needed to activate + * the corresponding opcodes, both for header inclusion, and when using + * them in a function. + * + * BR_GCC, BR_CLANG and BR_MSC will be set to 1 for, respectively, GCC, + * Clang and MS Visual C. For each of them, sub-macros will be defined + * for versions; each sub-macro is set whenever the compiler version is + * at least as recent as the one corresponding to the macro. + */ + +/* + * GCC thresholds are on versions 4.4 to 4.9 and 5.0. + */ +#ifndef BR_GCC +#if __GNUC__ && !__clang__ +#define BR_GCC 1 + +#if __GNUC__ > 4 +#define BR_GCC_5_0 1 +#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 9 +#define BR_GCC_4_9 1 +#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 8 +#define BR_GCC_4_8 1 +#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 7 +#define BR_GCC_4_7 1 +#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 6 +#define BR_GCC_4_6 1 +#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 5 +#define BR_GCC_4_5 1 +#elif __GNUC__ == 4 && __GNUC_MINOR__ >= 4 +#define BR_GCC_4_4 1 +#endif + +#if BR_GCC_5_0 +#define BR_GCC_4_9 1 +#endif +#if BR_GCC_4_9 +#define BR_GCC_4_8 1 +#endif +#if BR_GCC_4_8 +#define BR_GCC_4_7 1 +#endif +#if BR_GCC_4_7 +#define BR_GCC_4_6 1 +#endif +#if BR_GCC_4_6 +#define BR_GCC_4_5 1 +#endif +#if BR_GCC_4_5 +#define BR_GCC_4_4 1 +#endif + +#endif +#endif + +/* + * Clang thresholds are on versions 3.7.0 and 3.8.0. + */ +#ifndef BR_CLANG +#if __clang__ +#define BR_CLANG 1 + +#if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 8) +#define BR_CLANG_3_8 1 +#elif __clang_major__ == 3 && __clang_minor__ >= 7 +#define BR_CLANG_3_7 1 +#endif + +#if BR_CLANG_3_8 +#define BR_CLANG_3_7 1 +#endif + +#endif +#endif + +/* + * MS Visual C thresholds are on Visual Studio 2005 to 2015. + */ +#ifndef BR_MSC +#if _MSC_VER +#define BR_MSC 1 + +#if _MSC_VER >= 1900 +#define BR_MSC_2015 1 +#elif _MSC_VER >= 1800 +#define BR_MSC_2013 1 +#elif _MSC_VER >= 1700 +#define BR_MSC_2012 1 +#elif _MSC_VER >= 1600 +#define BR_MSC_2010 1 +#elif _MSC_VER >= 1500 +#define BR_MSC_2008 1 +#elif _MSC_VER >= 1400 +#define BR_MSC_2005 1 +#endif + +#if BR_MSC_2015 +#define BR_MSC_2013 1 +#endif +#if BR_MSC_2013 +#define BR_MSC_2012 1 +#endif +#if BR_MSC_2012 +#define BR_MSC_2010 1 +#endif +#if BR_MSC_2010 +#define BR_MSC_2008 1 +#endif +#if BR_MSC_2008 +#define BR_MSC_2005 1 +#endif + +#endif +#endif + +/* + * GCC 4.4+ and Clang 3.7+ allow tagging specific functions with a + * 'target' attribute that activates support for specific opcodes. + */ +#if BR_GCC_4_4 || BR_CLANG_3_7 +#define BR_TARGET(x) __attribute__((target(x))) +#else +#define BR_TARGET(x) +#endif + +/* + * AES-NI intrinsics are available on x86 (32-bit and 64-bit) with + * GCC 4.8+, Clang 3.7+ and MSC 2012+. + */ +#ifndef BR_AES_X86NI +#if (BR_i386 || BR_amd64) && (BR_GCC_4_8 || BR_CLANG_3_7 || BR_MSC_2012) +#define BR_AES_X86NI 1 +#endif +#endif + +/* + * SSE2 intrinsics are available on x86 (32-bit and 64-bit) with + * GCC 4.4+, Clang 3.7+ and MSC 2005+. + */ +#ifndef BR_SSE2 +#if (BR_i386 || BR_amd64) && (BR_GCC_4_4 || BR_CLANG_3_7 || BR_MSC_2005) +#define BR_SSE2 1 +#endif +#endif + +/* + * RDRAND intrinsics are available on x86 (32-bit and 64-bit) with + * GCC 4.6+, Clang 3.7+ and MSC 2012+. + */ +#ifndef BR_RDRAND +#if (BR_i386 || BR_amd64) && (BR_GCC_4_6 || BR_CLANG_3_7 || BR_MSC_2012) +#define BR_RDRAND 1 +#endif +#endif + +/* + * Determine type of OS for random number generation. Macro names and + * values are documented on: + * https://sourceforge.net/p/predef/wiki/OperatingSystems/ + * + * Win32's CryptGenRandom() should be available on Windows systems. + * + * /dev/urandom should work on all Unix-like systems (including macOS X). + * + * getentropy() is present on Linux (Glibc 2.25+), FreeBSD (12.0+) and + * OpenBSD (5.6+). For OpenBSD, there does not seem to be easy to use + * macros to test the minimum version, so we just assume that it is + * recent enough (last version without getentropy() has gone out of + * support in May 2015). + * + * Ideally we should use getentropy() on macOS (10.12+) too, but I don't + * know how to test the exact OS version with preprocessor macros. + * + * TODO: enrich the list of detected system. + */ + +#ifndef BR_USE_URANDOM +#if defined _AIX \ + || defined __ANDROID__ \ + || defined __FreeBSD__ \ + || defined __NetBSD__ \ + || defined __OpenBSD__ \ + || defined __DragonFly__ \ + || defined __linux__ \ + || (defined __sun && (defined __SVR4 || defined __svr4__)) \ + || (defined __APPLE__ && defined __MACH__) +#define BR_USE_URANDOM 1 +#endif +#endif + +#ifndef BR_USE_GETENTROPY +#if (defined __linux__ \ + && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))) \ + || (defined __FreeBSD__ && __FreeBSD__ >= 12) \ + || defined __OpenBSD__ +#define BR_USE_GETENTROPY 1 +#endif +#endif + +#ifndef BR_USE_WIN32_RAND +#if defined _WIN32 || defined _WIN64 +#define BR_USE_WIN32_RAND 1 +#endif +#endif + +/* + * POWER8 crypto support. We rely on compiler macros for the + * architecture, since we do not have a reliable, simple way to detect + * the required support at runtime (we could try running an opcode, and + * trapping the exception or signal on illegal instruction, but this + * induces some non-trivial OS dependencies that we would prefer to + * avoid if possible). + */ +#ifndef BR_POWER8 +#if __GNUC__ && ((_ARCH_PWR8 || _ARCH_PPC) && __CRYPTO__) +#define BR_POWER8 1 +#endif +#endif + +/* + * Detect endinanness on POWER8. + */ +#if BR_POWER8 +#if defined BR_POWER8_LE +#undef BR_POWER8_BE +#if BR_POWER8_LE +#define BR_POWER8_BE 0 +#else +#define BR_POWER8_BE 1 +#endif +#elif defined BR_POWER8_BE +#undef BR_POWER8_LE +#if BR_POWER8_BE +#define BR_POWER8_LE 0 +#else +#define BR_POWER8_LE 1 +#endif +#else +#if __LITTLE_ENDIAN__ +#define BR_POWER8_LE 1 +#define BR_POWER8_BE 0 +#else +#define BR_POWER8_LE 0 +#define BR_POWER8_BE 1 +#endif +#endif +#endif + +/* + * Detect support for 128-bit integers. + */ +#if !defined BR_INT128 && !defined BR_UMUL128 +#ifdef __SIZEOF_INT128__ +#define BR_INT128 1 +#elif _M_X64 +#define BR_UMUL128 1 +#endif +#endif + +/* + * Detect support for unaligned accesses with known endianness. + * + * x86 (both 32-bit and 64-bit) is little-endian and allows unaligned + * accesses. + * + * POWER/PowerPC allows unaligned accesses when big-endian. POWER8 and + * later also allow unaligned accesses when little-endian. + */ +#if !defined BR_LE_UNALIGNED && !defined BR_BE_UNALIGNED + +#if __i386 || __i386__ || __x86_64__ || _M_IX86 || _M_X64 +#define BR_LE_UNALIGNED 1 +#elif BR_POWER8_BE +#define BR_BE_UNALIGNED 1 +#elif BR_POWER8_LE +#define BR_LE_UNALIGNED 1 +#elif (__powerpc__ || __powerpc64__ || _M_PPC || _ARCH_PPC || _ARCH_PPC64) \ + && __BIG_ENDIAN__ +#define BR_BE_UNALIGNED 1 +#endif + +#endif + +/* + * Detect support for an OS-provided time source. + */ + +#ifndef BR_USE_UNIX_TIME +#if defined __unix__ || defined __linux__ \ + || defined _POSIX_SOURCE || defined _POSIX_C_SOURCE \ + || (defined __APPLE__ && defined __MACH__) +#define BR_USE_UNIX_TIME 1 +#endif +#endif + +#ifndef BR_USE_WIN32_TIME +#if defined _WIN32 || defined _WIN64 +#define BR_USE_WIN32_TIME 1 +#endif +#endif + +/* ==================================================================== */ +/* + * Encoding/decoding functions. + * + * 32-bit and 64-bit decoding, both little-endian and big-endian, is + * implemented with the inline functions below. + * + * When allowed by some compile-time options (autodetected or provided), + * optimised code is used, to perform direct memory access when the + * underlying architecture supports it, both for endianness and + * alignment. This, however, may trigger strict aliasing issues; the + * code below uses unions to perform (supposedly) safe type punning. + * Since the C aliasing rules are relatively complex and were amended, + * or at least re-explained with different phrasing, in all successive + * versions of the C standard, it is always a bit risky to bet that any + * specific version of a C compiler got it right, for some notion of + * "right". + */ + +typedef union { + uint16_t u; + unsigned char b[sizeof(uint16_t)]; +} br_union_u16; + +typedef union { + uint32_t u; + unsigned char b[sizeof(uint32_t)]; +} br_union_u32; + +typedef union { + uint64_t u; + unsigned char b[sizeof(uint64_t)]; +} br_union_u64; + +static inline void +br_enc16le(void *dst, unsigned x) +{ +#if BR_LE_UNALIGNED + ((br_union_u16 *)dst)->u = x; +#else + unsigned char *buf; + + buf = dst; + buf[0] = (unsigned char)x; + buf[1] = (unsigned char)(x >> 8); +#endif +} + +static inline void +br_enc16be(void *dst, unsigned x) +{ +#if BR_BE_UNALIGNED + ((br_union_u16 *)dst)->u = x; +#else + unsigned char *buf; + + buf = dst; + buf[0] = (unsigned char)(x >> 8); + buf[1] = (unsigned char)x; +#endif +} + +static inline unsigned +br_dec16le(const void *src) +{ +#if BR_LE_UNALIGNED + return ((const br_union_u16 *)src)->u; +#else + const unsigned char *buf; + + buf = src; + return (unsigned)buf[0] | ((unsigned)buf[1] << 8); +#endif +} + +static inline unsigned +br_dec16be(const void *src) +{ +#if BR_BE_UNALIGNED + return ((const br_union_u16 *)src)->u; +#else + const unsigned char *buf; + + buf = src; + return ((unsigned)buf[0] << 8) | (unsigned)buf[1]; +#endif +} + +static inline void +br_enc32le(void *dst, uint32_t x) +{ +#if BR_LE_UNALIGNED + ((br_union_u32 *)dst)->u = x; +#else + unsigned char *buf; + + buf = dst; + buf[0] = (unsigned char)x; + buf[1] = (unsigned char)(x >> 8); + buf[2] = (unsigned char)(x >> 16); + buf[3] = (unsigned char)(x >> 24); +#endif +} + +static inline void +br_enc32be(void *dst, uint32_t x) +{ +#if BR_BE_UNALIGNED + ((br_union_u32 *)dst)->u = x; +#else + unsigned char *buf; + + buf = dst; + buf[0] = (unsigned char)(x >> 24); + buf[1] = (unsigned char)(x >> 16); + buf[2] = (unsigned char)(x >> 8); + buf[3] = (unsigned char)x; +#endif +} + +static inline uint32_t +br_dec32le(const void *src) +{ +#if BR_LE_UNALIGNED + return ((const br_union_u32 *)src)->u; +#else + const unsigned char *buf; + + buf = src; + return (uint32_t)buf[0] + | ((uint32_t)buf[1] << 8) + | ((uint32_t)buf[2] << 16) + | ((uint32_t)buf[3] << 24); +#endif +} + +static inline uint32_t +br_dec32be(const void *src) +{ +#if BR_BE_UNALIGNED + return ((const br_union_u32 *)src)->u; +#else + const unsigned char *buf; + + buf = src; + return ((uint32_t)buf[0] << 24) + | ((uint32_t)buf[1] << 16) + | ((uint32_t)buf[2] << 8) + | (uint32_t)buf[3]; +#endif +} + +static inline void +br_enc64le(void *dst, uint64_t x) +{ +#if BR_LE_UNALIGNED + ((br_union_u64 *)dst)->u = x; +#else + unsigned char *buf; + + buf = dst; + br_enc32le(buf, (uint32_t)x); + br_enc32le(buf + 4, (uint32_t)(x >> 32)); +#endif +} + +static inline void +br_enc64be(void *dst, uint64_t x) +{ +#if BR_BE_UNALIGNED + ((br_union_u64 *)dst)->u = x; +#else + unsigned char *buf; + + buf = dst; + br_enc32be(buf, (uint32_t)(x >> 32)); + br_enc32be(buf + 4, (uint32_t)x); +#endif +} + +static inline uint64_t +br_dec64le(const void *src) +{ +#if BR_LE_UNALIGNED + return ((const br_union_u64 *)src)->u; +#else + const unsigned char *buf; + + buf = src; + return (uint64_t)br_dec32le(buf) + | ((uint64_t)br_dec32le(buf + 4) << 32); +#endif +} + +static inline uint64_t +br_dec64be(const void *src) +{ +#if BR_BE_UNALIGNED + return ((const br_union_u64 *)src)->u; +#else + const unsigned char *buf; + + buf = src; + return ((uint64_t)br_dec32be(buf) << 32) + | (uint64_t)br_dec32be(buf + 4); +#endif +} + +/* + * Range decoding and encoding (for several successive values). + */ +void br_range_dec16le(uint16_t *v, size_t num, const void *src); +void br_range_dec16be(uint16_t *v, size_t num, const void *src); +void br_range_enc16le(void *dst, const uint16_t *v, size_t num); +void br_range_enc16be(void *dst, const uint16_t *v, size_t num); + +void br_range_dec32le(uint32_t *v, size_t num, const void *src); +void br_range_dec32be(uint32_t *v, size_t num, const void *src); +void br_range_enc32le(void *dst, const uint32_t *v, size_t num); +void br_range_enc32be(void *dst, const uint32_t *v, size_t num); + +void br_range_dec64le(uint64_t *v, size_t num, const void *src); +void br_range_dec64be(uint64_t *v, size_t num, const void *src); +void br_range_enc64le(void *dst, const uint64_t *v, size_t num); +void br_range_enc64be(void *dst, const uint64_t *v, size_t num); + +/* + * Byte-swap a 32-bit integer. + */ +static inline uint32_t +br_swap32(uint32_t x) +{ + x = ((x & (uint32_t)0x00FF00FF) << 8) + | ((x >> 8) & (uint32_t)0x00FF00FF); + return (x << 16) | (x >> 16); +} + +/* ==================================================================== */ +/* + * Support code for hash functions. + */ + +/* + * IV for MD5, SHA-1, SHA-224 and SHA-256. + */ +extern const uint32_t br_md5_IV[]; +extern const uint32_t br_sha1_IV[]; +extern const uint32_t br_sha224_IV[]; +extern const uint32_t br_sha256_IV[]; + +/* + * Round functions for MD5, SHA-1, SHA-224 and SHA-256 (SHA-224 and + * SHA-256 use the same round function). + */ +void br_md5_round(const unsigned char *buf, uint32_t *val); +void br_sha1_round(const unsigned char *buf, uint32_t *val); +void br_sha2small_round(const unsigned char *buf, uint32_t *val); + +/* + * The core function for the TLS PRF. It computes + * P_hash(secret, label + seed), and XORs the result into the dst buffer. + */ +void br_tls_phash(void *dst, size_t len, + const br_hash_class *dig, + const void *secret, size_t secret_len, const char *label, + size_t seed_num, const br_tls_prf_seed_chunk *seed); + +/* + * Copy all configured hash implementations from a multihash context + * to another. + */ +static inline void +br_multihash_copyimpl(br_multihash_context *dst, + const br_multihash_context *src) +{ + memcpy((void *)dst->impl, src->impl, sizeof src->impl); +} + +/* ==================================================================== */ +/* + * Constant-time primitives. These functions manipulate 32-bit values in + * order to provide constant-time comparisons and multiplexers. + * + * Boolean values (the "ctl" bits) MUST have value 0 or 1. + * + * Implementation notes: + * ===================== + * + * The uintN_t types are unsigned and with width exactly N bits; the C + * standard guarantees that computations are performed modulo 2^N, and + * there can be no overflow. Negation (unary '-') works on unsigned types + * as well. + * + * The intN_t types are guaranteed to have width exactly N bits, with no + * padding bit, and using two's complement representation. Casting + * intN_t to uintN_t really is conversion modulo 2^N. Beware that intN_t + * types, being signed, trigger implementation-defined behaviour on + * overflow (including raising some signal): with GCC, while modular + * arithmetics are usually applied, the optimizer may assume that + * overflows don't occur (unless the -fwrapv command-line option is + * added); Clang has the additional -ftrapv option to explicitly trap on + * integer overflow or underflow. + */ + +/* + * Negate a boolean. + */ +static inline uint32_t +NOT(uint32_t ctl) +{ + return ctl ^ 1; +} + +/* + * Multiplexer: returns x if ctl == 1, y if ctl == 0. + */ +static inline uint32_t +MUX(uint32_t ctl, uint32_t x, uint32_t y) +{ + return y ^ (-ctl & (x ^ y)); +} + +/* + * Equality check: returns 1 if x == y, 0 otherwise. + */ +static inline uint32_t +EQ(uint32_t x, uint32_t y) +{ + uint32_t q; + + q = x ^ y; + return NOT((q | -q) >> 31); +} + +/* + * Inequality check: returns 1 if x != y, 0 otherwise. + */ +static inline uint32_t +NEQ(uint32_t x, uint32_t y) +{ + uint32_t q; + + q = x ^ y; + return (q | -q) >> 31; +} + +/* + * Comparison: returns 1 if x > y, 0 otherwise. + */ +static inline uint32_t +GT(uint32_t x, uint32_t y) +{ + /* + * If both x < 2^31 and x < 2^31, then y-x will have its high + * bit set if x > y, cleared otherwise. + * + * If either x >= 2^31 or y >= 2^31 (but not both), then the + * result is the high bit of x. + * + * If both x >= 2^31 and y >= 2^31, then we can virtually + * subtract 2^31 from both, and we are back to the first case. + * Since (y-2^31)-(x-2^31) = y-x, the subtraction is already + * fine. + */ + uint32_t z; + + z = y - x; + return (z ^ ((x ^ y) & (x ^ z))) >> 31; +} + +/* + * Other comparisons (greater-or-equal, lower-than, lower-or-equal). + */ +#define GE(x, y) NOT(GT(y, x)) +#define LT(x, y) GT(y, x) +#define LE(x, y) NOT(GT(x, y)) + +/* + * General comparison: returned value is -1, 0 or 1, depending on + * whether x is lower than, equal to, or greater than y. + */ +static inline int32_t +CMP(uint32_t x, uint32_t y) +{ + return (int32_t)GT(x, y) | -(int32_t)GT(y, x); +} + +/* + * Returns 1 if x == 0, 0 otherwise. Take care that the operand is signed. + */ +static inline uint32_t +EQ0(int32_t x) +{ + uint32_t q; + + q = (uint32_t)x; + return ~(q | -q) >> 31; +} + +/* + * Returns 1 if x > 0, 0 otherwise. Take care that the operand is signed. + */ +static inline uint32_t +GT0(int32_t x) +{ + /* + * High bit of -x is 0 if x == 0, but 1 if x > 0. + */ + uint32_t q; + + q = (uint32_t)x; + return (~q & -q) >> 31; +} + +/* + * Returns 1 if x >= 0, 0 otherwise. Take care that the operand is signed. + */ +static inline uint32_t +GE0(int32_t x) +{ + return ~(uint32_t)x >> 31; +} + +/* + * Returns 1 if x < 0, 0 otherwise. Take care that the operand is signed. + */ +static inline uint32_t +LT0(int32_t x) +{ + return (uint32_t)x >> 31; +} + +/* + * Returns 1 if x <= 0, 0 otherwise. Take care that the operand is signed. + */ +static inline uint32_t +LE0(int32_t x) +{ + uint32_t q; + + /* + * ~-x has its high bit set if and only if -x is nonnegative (as + * a signed int), i.e. x is in the -(2^31-1) to 0 range. We must + * do an OR with x itself to account for x = -2^31. + */ + q = (uint32_t)x; + return (q | ~-q) >> 31; +} + +/* + * Conditional copy: src[] is copied into dst[] if and only if ctl is 1. + * dst[] and src[] may overlap completely (but not partially). + */ +void br_ccopy(uint32_t ctl, void *dst, const void *src, size_t len); + +#define CCOPY br_ccopy + +/* + * Compute the bit length of a 32-bit integer. Returned value is between 0 + * and 32 (inclusive). + */ +static inline uint32_t +BIT_LENGTH(uint32_t x) +{ + uint32_t k, c; + + k = NEQ(x, 0); + c = GT(x, 0xFFFF); x = MUX(c, x >> 16, x); k += c << 4; + c = GT(x, 0x00FF); x = MUX(c, x >> 8, x); k += c << 3; + c = GT(x, 0x000F); x = MUX(c, x >> 4, x); k += c << 2; + c = GT(x, 0x0003); x = MUX(c, x >> 2, x); k += c << 1; + k += GT(x, 0x0001); + return k; +} + +/* + * Compute the minimum of x and y. + */ +static inline uint32_t +MIN(uint32_t x, uint32_t y) +{ + return MUX(GT(x, y), y, x); +} + +/* + * Compute the maximum of x and y. + */ +static inline uint32_t +MAX(uint32_t x, uint32_t y) +{ + return MUX(GT(x, y), x, y); +} + +/* + * Multiply two 32-bit integers, with a 64-bit result. This default + * implementation assumes that the basic multiplication operator + * yields constant-time code. + */ +#define MUL(x, y) ((uint64_t)(x) * (uint64_t)(y)) + +#if BR_CT_MUL31 + +/* + * Alternate implementation of MUL31, that will be constant-time on some + * (old) platforms where the default MUL31 is not. Unfortunately, it is + * also substantially slower, and yields larger code, on more modern + * platforms, which is why it is deactivated by default. + * + * MUL31_lo() must do some extra work because on some platforms, the + * _signed_ multiplication may return early if the top bits are 1. + * Simply truncating (casting) the output of MUL31() would not be + * sufficient, because the compiler may notice that we keep only the low + * word, and then replace automatically the unsigned multiplication with + * a signed multiplication opcode. + */ +#define MUL31(x, y) ((uint64_t)((x) | (uint32_t)0x80000000) \ + * (uint64_t)((y) | (uint32_t)0x80000000) \ + - ((uint64_t)(x) << 31) - ((uint64_t)(y) << 31) \ + - ((uint64_t)1 << 62)) +static inline uint32_t +MUL31_lo(uint32_t x, uint32_t y) +{ + uint32_t xl, xh; + uint32_t yl, yh; + + xl = (x & 0xFFFF) | (uint32_t)0x80000000; + xh = (x >> 16) | (uint32_t)0x80000000; + yl = (y & 0xFFFF) | (uint32_t)0x80000000; + yh = (y >> 16) | (uint32_t)0x80000000; + return (xl * yl + ((xl * yh + xh * yl) << 16)) & (uint32_t)0x7FFFFFFF; +} + +#else + +/* + * Multiply two 31-bit integers, with a 62-bit result. This default + * implementation assumes that the basic multiplication operator + * yields constant-time code. + * The MUL31_lo() macro returns only the low 31 bits of the product. + */ +#define MUL31(x, y) ((uint64_t)(x) * (uint64_t)(y)) +#define MUL31_lo(x, y) (((uint32_t)(x) * (uint32_t)(y)) & (uint32_t)0x7FFFFFFF) + +#endif + +/* + * Multiply two words together; the sum of the lengths of the two + * operands must not exceed 31 (for instance, one operand may use 16 + * bits if the other fits on 15). If BR_CT_MUL15 is non-zero, then the + * macro will contain some extra operations that help in making the + * operation constant-time on some platforms, where the basic 32-bit + * multiplication is not constant-time. + */ +#if BR_CT_MUL15 +#define MUL15(x, y) (((uint32_t)(x) | (uint32_t)0x80000000) \ + * ((uint32_t)(y) | (uint32_t)0x80000000) \ + & (uint32_t)0x7FFFFFFF) +#else +#define MUL15(x, y) ((uint32_t)(x) * (uint32_t)(y)) +#endif + +/* + * Arithmetic right shift (sign bit is copied). What happens when + * right-shifting a negative value is _implementation-defined_, so it + * does not trigger undefined behaviour, but it is still up to each + * compiler to define (and document) what it does. Most/all compilers + * will do an arithmetic shift, the sign bit being used to fill the + * holes; this is a native operation on the underlying CPU, and it would + * make little sense for the compiler to do otherwise. GCC explicitly + * documents that it follows that convention. + * + * Still, if BR_NO_ARITH_SHIFT is defined (and non-zero), then an + * alternate version will be used, that does not rely on such + * implementation-defined behaviour. Unfortunately, it is also slower + * and yields bigger code, which is why it is deactivated by default. + */ +#if BR_NO_ARITH_SHIFT +#define ARSH(x, n) (((uint32_t)(x) >> (n)) \ + | ((-((uint32_t)(x) >> 31)) << (32 - (n)))) +#else +#define ARSH(x, n) ((*(int32_t *)&(x)) >> (n)) +#endif + +/* + * Constant-time division. The dividend hi:lo is divided by the + * divisor d; the quotient is returned and the remainder is written + * in *r. If hi == d, then the quotient does not fit on 32 bits; + * returned value is thus truncated. If hi > d, returned values are + * indeterminate. + */ +uint32_t br_divrem(uint32_t hi, uint32_t lo, uint32_t d, uint32_t *r); + +/* + * Wrapper for br_divrem(); the remainder is returned, and the quotient + * is discarded. + */ +static inline uint32_t +br_rem(uint32_t hi, uint32_t lo, uint32_t d) +{ + uint32_t r; + + br_divrem(hi, lo, d, &r); + return r; +} + +/* + * Wrapper for br_divrem(); the quotient is returned, and the remainder + * is discarded. + */ +static inline uint32_t +br_div(uint32_t hi, uint32_t lo, uint32_t d) +{ + uint32_t r; + + return br_divrem(hi, lo, d, &r); +} + +/* ==================================================================== */ + +/* + * Integers 'i32' + * -------------- + * + * The 'i32' functions implement computations on big integers using + * an internal representation as an array of 32-bit integers. For + * an array x[]: + * -- x[0] contains the "announced bit length" of the integer + * -- x[1], x[2]... contain the value in little-endian order (x[1] + * contains the least significant 32 bits) + * + * Multiplications rely on the elementary 32x32->64 multiplication. + * + * The announced bit length specifies the number of bits that are + * significant in the subsequent 32-bit words. Unused bits in the + * last (most significant) word are set to 0; subsequent words are + * uninitialized and need not exist at all. + * + * The execution time and memory access patterns of all computations + * depend on the announced bit length, but not on the actual word + * values. For modular integers, the announced bit length of any integer + * modulo n is equal to the actual bit length of n; thus, computations + * on modular integers are "constant-time" (only the modulus length may + * leak). + */ + +/* + * Compute the actual bit length of an integer. The argument x should + * point to the first (least significant) value word of the integer. + * The len 'xlen' contains the number of 32-bit words to access. + * + * CT: value or length of x does not leak. + */ +uint32_t br_i32_bit_length(uint32_t *x, size_t xlen); + +/* + * Decode an integer from its big-endian unsigned representation. The + * "true" bit length of the integer is computed, but all words of x[] + * corresponding to the full 'len' bytes of the source are set. + * + * CT: value or length of x does not leak. + */ +void br_i32_decode(uint32_t *x, const void *src, size_t len); + +/* + * Decode an integer from its big-endian unsigned representation. The + * integer MUST be lower than m[]; the announced bit length written in + * x[] will be equal to that of m[]. All 'len' bytes from the source are + * read. + * + * Returned value is 1 if the decode value fits within the modulus, 0 + * otherwise. In the latter case, the x[] buffer will be set to 0 (but + * still with the announced bit length of m[]). + * + * CT: value or length of x does not leak. Memory access pattern depends + * only of 'len' and the announced bit length of m. Whether x fits or + * not does not leak either. + */ +uint32_t br_i32_decode_mod(uint32_t *x, + const void *src, size_t len, const uint32_t *m); + +/* + * Reduce an integer (a[]) modulo another (m[]). The result is written + * in x[] and its announced bit length is set to be equal to that of m[]. + * + * x[] MUST be distinct from a[] and m[]. + * + * CT: only announced bit lengths leak, not values of x, a or m. + */ +void br_i32_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m); + +/* + * Decode an integer from its big-endian unsigned representation, and + * reduce it modulo the provided modulus m[]. The announced bit length + * of the result is set to be equal to that of the modulus. + * + * x[] MUST be distinct from m[]. + */ +void br_i32_decode_reduce(uint32_t *x, + const void *src, size_t len, const uint32_t *m); + +/* + * Encode an integer into its big-endian unsigned representation. The + * output length in bytes is provided (parameter 'len'); if the length + * is too short then the integer is appropriately truncated; if it is + * too long then the extra bytes are set to 0. + */ +void br_i32_encode(void *dst, size_t len, const uint32_t *x); + +/* + * Multiply x[] by 2^32 and then add integer z, modulo m[]. This + * function assumes that x[] and m[] have the same announced bit + * length, and the announced bit length of m[] matches its true + * bit length. + * + * x[] and m[] MUST be distinct arrays. + * + * CT: only the common announced bit length of x and m leaks, not + * the values of x, z or m. + */ +void br_i32_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m); + +/* + * Extract one word from an integer. The offset is counted in bits. + * The word MUST entirely fit within the word elements corresponding + * to the announced bit length of a[]. + */ +static inline uint32_t +br_i32_word(const uint32_t *a, uint32_t off) +{ + size_t u; + unsigned j; + + u = (size_t)(off >> 5) + 1; + j = (unsigned)off & 31; + if (j == 0) { + return a[u]; + } else { + return (a[u] >> j) | (a[u + 1] << (32 - j)); + } +} + +/* + * Test whether an integer is zero. + */ +uint32_t br_i32_iszero(const uint32_t *x); + +/* + * Add b[] to a[] and return the carry (0 or 1). If ctl is 0, then a[] + * is unmodified, but the carry is still computed and returned. The + * arrays a[] and b[] MUST have the same announced bit length. + * + * a[] and b[] MAY be the same array, but partial overlap is not allowed. + */ +uint32_t br_i32_add(uint32_t *a, const uint32_t *b, uint32_t ctl); + +/* + * Subtract b[] from a[] and return the carry (0 or 1). If ctl is 0, + * then a[] is unmodified, but the carry is still computed and returned. + * The arrays a[] and b[] MUST have the same announced bit length. + * + * a[] and b[] MAY be the same array, but partial overlap is not allowed. + */ +uint32_t br_i32_sub(uint32_t *a, const uint32_t *b, uint32_t ctl); + +/* + * Compute d+a*b, result in d. The initial announced bit length of d[] + * MUST match that of a[]. The d[] array MUST be large enough to + * accommodate the full result, plus (possibly) an extra word. The + * resulting announced bit length of d[] will be the sum of the announced + * bit lengths of a[] and b[] (therefore, it may be larger than the actual + * bit length of the numerical result). + * + * a[] and b[] may be the same array. d[] must be disjoint from both a[] + * and b[]. + */ +void br_i32_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b); + +/* + * Zeroize an integer. The announced bit length is set to the provided + * value, and the corresponding words are set to 0. + */ +static inline void +br_i32_zero(uint32_t *x, uint32_t bit_len) +{ + *x ++ = bit_len; + memset(x, 0, ((bit_len + 31) >> 5) * sizeof *x); +} + +/* + * Compute -(1/x) mod 2^32. If x is even, then this function returns 0. + */ +uint32_t br_i32_ninv32(uint32_t x); + +/* + * Convert a modular integer to Montgomery representation. The integer x[] + * MUST be lower than m[], but with the same announced bit length. + */ +void br_i32_to_monty(uint32_t *x, const uint32_t *m); + +/* + * Convert a modular integer back from Montgomery representation. The + * integer x[] MUST be lower than m[], but with the same announced bit + * length. The "m0i" parameter is equal to -(1/m0) mod 2^32, where m0 is + * the least significant value word of m[] (this works only if m[] is + * an odd integer). + */ +void br_i32_from_monty(uint32_t *x, const uint32_t *m, uint32_t m0i); + +/* + * Compute a modular Montgomery multiplication. d[] is filled with the + * value of x*y/R modulo m[] (where R is the Montgomery factor). The + * array d[] MUST be distinct from x[], y[] and m[]. x[] and y[] MUST be + * numerically lower than m[]. x[] and y[] MAY be the same array. The + * "m0i" parameter is equal to -(1/m0) mod 2^32, where m0 is the least + * significant value word of m[] (this works only if m[] is an odd + * integer). + */ +void br_i32_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, + const uint32_t *m, uint32_t m0i); + +/* + * Compute a modular exponentiation. x[] MUST be an integer modulo m[] + * (same announced bit length, lower value). m[] MUST be odd. The + * exponent is in big-endian unsigned notation, over 'elen' bytes. The + * "m0i" parameter is equal to -(1/m0) mod 2^32, where m0 is the least + * significant value word of m[] (this works only if m[] is an odd + * integer). The t1[] and t2[] parameters must be temporary arrays, + * each large enough to accommodate an integer with the same size as m[]. + */ +void br_i32_modpow(uint32_t *x, const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2); + +/* ==================================================================== */ + +/* + * Integers 'i31' + * -------------- + * + * The 'i31' functions implement computations on big integers using + * an internal representation as an array of 32-bit integers. For + * an array x[]: + * -- x[0] encodes the array length and the "announced bit length" + * of the integer: namely, if the announced bit length is k, + * then x[0] = ((k / 31) << 5) + (k % 31). + * -- x[1], x[2]... contain the value in little-endian order, 31 + * bits per word (x[1] contains the least significant 31 bits). + * The upper bit of each word is 0. + * + * Multiplications rely on the elementary 32x32->64 multiplication. + * + * The announced bit length specifies the number of bits that are + * significant in the subsequent 32-bit words. Unused bits in the + * last (most significant) word are set to 0; subsequent words are + * uninitialized and need not exist at all. + * + * The execution time and memory access patterns of all computations + * depend on the announced bit length, but not on the actual word + * values. For modular integers, the announced bit length of any integer + * modulo n is equal to the actual bit length of n; thus, computations + * on modular integers are "constant-time" (only the modulus length may + * leak). + */ + +/* + * Test whether an integer is zero. + */ +uint32_t br_i31_iszero(const uint32_t *x); + +/* + * Add b[] to a[] and return the carry (0 or 1). If ctl is 0, then a[] + * is unmodified, but the carry is still computed and returned. The + * arrays a[] and b[] MUST have the same announced bit length. + * + * a[] and b[] MAY be the same array, but partial overlap is not allowed. + */ +uint32_t br_i31_add(uint32_t *a, const uint32_t *b, uint32_t ctl); + +/* + * Subtract b[] from a[] and return the carry (0 or 1). If ctl is 0, + * then a[] is unmodified, but the carry is still computed and returned. + * The arrays a[] and b[] MUST have the same announced bit length. + * + * a[] and b[] MAY be the same array, but partial overlap is not allowed. + */ +uint32_t br_i31_sub(uint32_t *a, const uint32_t *b, uint32_t ctl); + +/* + * Compute the ENCODED actual bit length of an integer. The argument x + * should point to the first (least significant) value word of the + * integer. The len 'xlen' contains the number of 32-bit words to + * access. The upper bit of each value word MUST be 0. + * Returned value is ((k / 31) << 5) + (k % 31) if the bit length is k. + * + * CT: value or length of x does not leak. + */ +uint32_t br_i31_bit_length(uint32_t *x, size_t xlen); + +/* + * Decode an integer from its big-endian unsigned representation. The + * "true" bit length of the integer is computed and set in the encoded + * announced bit length (x[0]), but all words of x[] corresponding to + * the full 'len' bytes of the source are set. + * + * CT: value or length of x does not leak. + */ +void br_i31_decode(uint32_t *x, const void *src, size_t len); + +/* + * Decode an integer from its big-endian unsigned representation. The + * integer MUST be lower than m[]; the (encoded) announced bit length + * written in x[] will be equal to that of m[]. All 'len' bytes from the + * source are read. + * + * Returned value is 1 if the decode value fits within the modulus, 0 + * otherwise. In the latter case, the x[] buffer will be set to 0 (but + * still with the announced bit length of m[]). + * + * CT: value or length of x does not leak. Memory access pattern depends + * only of 'len' and the announced bit length of m. Whether x fits or + * not does not leak either. + */ +uint32_t br_i31_decode_mod(uint32_t *x, + const void *src, size_t len, const uint32_t *m); + +/* + * Zeroize an integer. The announced bit length is set to the provided + * value, and the corresponding words are set to 0. The ENCODED bit length + * is expected here. + */ +static inline void +br_i31_zero(uint32_t *x, uint32_t bit_len) +{ + *x ++ = bit_len; + memset(x, 0, ((bit_len + 31) >> 5) * sizeof *x); +} + +/* + * Right-shift an integer. The shift amount must be lower than 31 + * bits. + */ +void br_i31_rshift(uint32_t *x, int count); + +/* + * Reduce an integer (a[]) modulo another (m[]). The result is written + * in x[] and its announced bit length is set to be equal to that of m[]. + * + * x[] MUST be distinct from a[] and m[]. + * + * CT: only announced bit lengths leak, not values of x, a or m. + */ +void br_i31_reduce(uint32_t *x, const uint32_t *a, const uint32_t *m); + +/* + * Decode an integer from its big-endian unsigned representation, and + * reduce it modulo the provided modulus m[]. The announced bit length + * of the result is set to be equal to that of the modulus. + * + * x[] MUST be distinct from m[]. + */ +void br_i31_decode_reduce(uint32_t *x, + const void *src, size_t len, const uint32_t *m); + +/* + * Multiply x[] by 2^31 and then add integer z, modulo m[]. This + * function assumes that x[] and m[] have the same announced bit + * length, the announced bit length of m[] matches its true + * bit length. + * + * x[] and m[] MUST be distinct arrays. z MUST fit in 31 bits (upper + * bit set to 0). + * + * CT: only the common announced bit length of x and m leaks, not + * the values of x, z or m. + */ +void br_i31_muladd_small(uint32_t *x, uint32_t z, const uint32_t *m); + +/* + * Encode an integer into its big-endian unsigned representation. The + * output length in bytes is provided (parameter 'len'); if the length + * is too short then the integer is appropriately truncated; if it is + * too long then the extra bytes are set to 0. + */ +void br_i31_encode(void *dst, size_t len, const uint32_t *x); + +/* + * Compute -(1/x) mod 2^31. If x is even, then this function returns 0. + */ +uint32_t br_i31_ninv31(uint32_t x); + +/* + * Compute a modular Montgomery multiplication. d[] is filled with the + * value of x*y/R modulo m[] (where R is the Montgomery factor). The + * array d[] MUST be distinct from x[], y[] and m[]. x[] and y[] MUST be + * numerically lower than m[]. x[] and y[] MAY be the same array. The + * "m0i" parameter is equal to -(1/m0) mod 2^31, where m0 is the least + * significant value word of m[] (this works only if m[] is an odd + * integer). + */ +void br_i31_montymul(uint32_t *d, const uint32_t *x, const uint32_t *y, + const uint32_t *m, uint32_t m0i); + +/* + * Convert a modular integer to Montgomery representation. The integer x[] + * MUST be lower than m[], but with the same announced bit length. + */ +void br_i31_to_monty(uint32_t *x, const uint32_t *m); + +/* + * Convert a modular integer back from Montgomery representation. The + * integer x[] MUST be lower than m[], but with the same announced bit + * length. The "m0i" parameter is equal to -(1/m0) mod 2^32, where m0 is + * the least significant value word of m[] (this works only if m[] is + * an odd integer). + */ +void br_i31_from_monty(uint32_t *x, const uint32_t *m, uint32_t m0i); + +/* + * Compute a modular exponentiation. x[] MUST be an integer modulo m[] + * (same announced bit length, lower value). m[] MUST be odd. The + * exponent is in big-endian unsigned notation, over 'elen' bytes. The + * "m0i" parameter is equal to -(1/m0) mod 2^31, where m0 is the least + * significant value word of m[] (this works only if m[] is an odd + * integer). The t1[] and t2[] parameters must be temporary arrays, + * each large enough to accommodate an integer with the same size as m[]. + */ +void br_i31_modpow(uint32_t *x, const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *t1, uint32_t *t2); + +/* + * Compute a modular exponentiation. x[] MUST be an integer modulo m[] + * (same announced bit length, lower value). m[] MUST be odd. The + * exponent is in big-endian unsigned notation, over 'elen' bytes. The + * "m0i" parameter is equal to -(1/m0) mod 2^31, where m0 is the least + * significant value word of m[] (this works only if m[] is an odd + * integer). The tmp[] array is used for temporaries, and has size + * 'twlen' words; it must be large enough to accommodate at least two + * temporary values with the same size as m[] (including the leading + * "bit length" word). If there is room for more temporaries, then this + * function may use the extra room for window-based optimisation, + * resulting in faster computations. + * + * Returned value is 1 on success, 0 on error. An error is reported if + * the provided tmp[] array is too short. + */ +uint32_t br_i31_modpow_opt(uint32_t *x, const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *tmp, size_t twlen); + +/* + * Compute d+a*b, result in d. The initial announced bit length of d[] + * MUST match that of a[]. The d[] array MUST be large enough to + * accommodate the full result, plus (possibly) an extra word. The + * resulting announced bit length of d[] will be the sum of the announced + * bit lengths of a[] and b[] (therefore, it may be larger than the actual + * bit length of the numerical result). + * + * a[] and b[] may be the same array. d[] must be disjoint from both a[] + * and b[]. + */ +void br_i31_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b); + +/* + * Compute x/y mod m, result in x. Values x and y must be between 0 and + * m-1, and have the same announced bit length as m. Modulus m must be + * odd. The "m0i" parameter is equal to -1/m mod 2^31. The array 't' + * must point to a temporary area that can hold at least three integers + * of the size of m. + * + * m may not overlap x and y. x and y may overlap each other (this can + * be useful to test whether a value is invertible modulo m). t must be + * disjoint from all other arrays. + * + * Returned value is 1 on success, 0 otherwise. Success is attained if + * y is invertible modulo m. + */ +uint32_t br_i31_moddiv(uint32_t *x, const uint32_t *y, + const uint32_t *m, uint32_t m0i, uint32_t *t); + +/* ==================================================================== */ + +/* + * FIXME: document "i15" functions. + */ + +static inline void +br_i15_zero(uint16_t *x, uint16_t bit_len) +{ + *x ++ = bit_len; + memset(x, 0, ((bit_len + 15) >> 4) * sizeof *x); +} + +uint32_t br_i15_iszero(const uint16_t *x); + +uint16_t br_i15_ninv15(uint16_t x); + +uint32_t br_i15_add(uint16_t *a, const uint16_t *b, uint32_t ctl); + +uint32_t br_i15_sub(uint16_t *a, const uint16_t *b, uint32_t ctl); + +void br_i15_muladd_small(uint16_t *x, uint16_t z, const uint16_t *m); + +void br_i15_montymul(uint16_t *d, const uint16_t *x, const uint16_t *y, + const uint16_t *m, uint16_t m0i); + +void br_i15_to_monty(uint16_t *x, const uint16_t *m); + +void br_i15_modpow(uint16_t *x, const unsigned char *e, size_t elen, + const uint16_t *m, uint16_t m0i, uint16_t *t1, uint16_t *t2); + +uint32_t br_i15_modpow_opt(uint16_t *x, const unsigned char *e, size_t elen, + const uint16_t *m, uint16_t m0i, uint16_t *tmp, size_t twlen); + +void br_i15_encode(void *dst, size_t len, const uint16_t *x); + +uint32_t br_i15_decode_mod(uint16_t *x, + const void *src, size_t len, const uint16_t *m); + +void br_i15_rshift(uint16_t *x, int count); + +uint32_t br_i15_bit_length(uint16_t *x, size_t xlen); + +void br_i15_decode(uint16_t *x, const void *src, size_t len); + +void br_i15_from_monty(uint16_t *x, const uint16_t *m, uint16_t m0i); + +void br_i15_decode_reduce(uint16_t *x, + const void *src, size_t len, const uint16_t *m); + +void br_i15_reduce(uint16_t *x, const uint16_t *a, const uint16_t *m); + +void br_i15_mulacc(uint16_t *d, const uint16_t *a, const uint16_t *b); + +uint32_t br_i15_moddiv(uint16_t *x, const uint16_t *y, + const uint16_t *m, uint16_t m0i, uint16_t *t); + +/* + * Variant of br_i31_modpow_opt() that internally uses 64x64->128 + * multiplications. It expects the same parameters as br_i31_modpow_opt(), + * except that the temporaries should be 64-bit integers, not 32-bit + * integers. + */ +uint32_t br_i62_modpow_opt(uint32_t *x31, const unsigned char *e, size_t elen, + const uint32_t *m31, uint32_t m0i31, uint64_t *tmp, size_t twlen); + +/* + * Type for a function with the same API as br_i31_modpow_opt() (some + * implementations of this type may have stricter alignment requirements + * on the temporaries). + */ +typedef uint32_t (*br_i31_modpow_opt_type)(uint32_t *x, + const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *tmp, size_t twlen); + +/* + * Wrapper for br_i62_modpow_opt() that uses the same type as + * br_i31_modpow_opt(); however, it requires its 'tmp' argument to the + * 64-bit aligned. + */ +uint32_t br_i62_modpow_opt_as_i31(uint32_t *x, + const unsigned char *e, size_t elen, + const uint32_t *m, uint32_t m0i, uint32_t *tmp, size_t twlen); + +/* ==================================================================== */ + +static inline size_t +br_digest_size(const br_hash_class *digest_class) +{ + return (size_t)(digest_class->desc >> BR_HASHDESC_OUT_OFF) + & BR_HASHDESC_OUT_MASK; +} + +/* + * Get the output size (in bytes) of a hash function. + */ +size_t br_digest_size_by_ID(int digest_id); + +/* + * Get the OID (encoded OBJECT IDENTIFIER value, without tag and length) + * for a hash function. If digest_id is not a supported digest identifier + * (in particular if it is equal to 0, i.e. br_md5sha1_ID), then NULL is + * returned and *len is set to 0. + */ +const unsigned char *br_digest_OID(int digest_id, size_t *len); + +/* ==================================================================== */ +/* + * DES support functions. + */ + +/* + * Apply DES Initial Permutation. + */ +void br_des_do_IP(uint32_t *xl, uint32_t *xr); + +/* + * Apply DES Final Permutation (inverse of IP). + */ +void br_des_do_invIP(uint32_t *xl, uint32_t *xr); + +/* + * Key schedule unit: for a DES key (8 bytes), compute 16 subkeys. Each + * subkey is two 28-bit words represented as two 32-bit words; the PC-2 + * bit extration is NOT applied. + */ +void br_des_keysched_unit(uint32_t *skey, const void *key); + +/* + * Reversal of 16 DES sub-keys (for decryption). + */ +void br_des_rev_skey(uint32_t *skey); + +/* + * DES/3DES key schedule for 'des_tab' (encryption direction). Returned + * value is the number of rounds. + */ +unsigned br_des_tab_keysched(uint32_t *skey, const void *key, size_t key_len); + +/* + * DES/3DES key schedule for 'des_ct' (encryption direction). Returned + * value is the number of rounds. + */ +unsigned br_des_ct_keysched(uint32_t *skey, const void *key, size_t key_len); + +/* + * DES/3DES subkey decompression (from the compressed bitsliced subkeys). + */ +void br_des_ct_skey_expand(uint32_t *sk_exp, + unsigned num_rounds, const uint32_t *skey); + +/* + * DES/3DES block encryption/decryption ('des_tab'). + */ +void br_des_tab_process_block(unsigned num_rounds, + const uint32_t *skey, void *block); + +/* + * DES/3DES block encryption/decryption ('des_ct'). + */ +void br_des_ct_process_block(unsigned num_rounds, + const uint32_t *skey, void *block); + +/* ==================================================================== */ +/* + * AES support functions. + */ + +/* + * The AES S-box (256-byte table). + */ +extern const unsigned char br_aes_S[]; + +/* + * AES key schedule. skey[] is filled with n+1 128-bit subkeys, where n + * is the number of rounds (10 to 14, depending on key size). The number + * of rounds is returned. If the key size is invalid (not 16, 24 or 32), + * then 0 is returned. + * + * This implementation uses a 256-byte table and is NOT constant-time. + */ +unsigned br_aes_keysched(uint32_t *skey, const void *key, size_t key_len); + +/* + * AES key schedule for decryption ('aes_big' implementation). + */ +unsigned br_aes_big_keysched_inv(uint32_t *skey, + const void *key, size_t key_len); + +/* + * AES block encryption with the 'aes_big' implementation (fast, but + * not constant-time). This function encrypts a single block "in place". + */ +void br_aes_big_encrypt(unsigned num_rounds, const uint32_t *skey, void *data); + +/* + * AES block decryption with the 'aes_big' implementation (fast, but + * not constant-time). This function decrypts a single block "in place". + */ +void br_aes_big_decrypt(unsigned num_rounds, const uint32_t *skey, void *data); + +/* + * AES block encryption with the 'aes_small' implementation (small, but + * slow and not constant-time). This function encrypts a single block + * "in place". + */ +void br_aes_small_encrypt(unsigned num_rounds, + const uint32_t *skey, void *data); + +/* + * AES block decryption with the 'aes_small' implementation (small, but + * slow and not constant-time). This function decrypts a single block + * "in place". + */ +void br_aes_small_decrypt(unsigned num_rounds, + const uint32_t *skey, void *data); + +/* + * The constant-time implementation is "bitsliced": the 128-bit state is + * split over eight 32-bit words q* in the following way: + * + * -- Input block consists in 16 bytes: + * a00 a10 a20 a30 a01 a11 a21 a31 a02 a12 a22 a32 a03 a13 a23 a33 + * In the terminology of FIPS 197, this is a 4x4 matrix which is read + * column by column. + * + * -- Each byte is split into eight bits which are distributed over the + * eight words, at the same rank. Thus, for a byte x at rank k, bit 0 + * (least significant) of x will be at rank k in q0 (if that bit is b, + * then it contributes "b << k" to the value of q0), bit 1 of x will be + * at rank k in q1, and so on. + * + * -- Ranks given to bits are in "row order" and are either all even, or + * all odd. Two independent AES states are thus interleaved, one using + * the even ranks, the other the odd ranks. Row order means: + * a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23 a30 a31 a32 a33 + * + * Converting input bytes from two AES blocks to bitslice representation + * is done in the following way: + * -- Decode first block into the four words q0 q2 q4 q6, in that order, + * using little-endian convention. + * -- Decode second block into the four words q1 q3 q5 q7, in that order, + * using little-endian convention. + * -- Call br_aes_ct_ortho(). + * + * Converting back to bytes is done by using the reverse operations. Note + * that br_aes_ct_ortho() is its own inverse. + */ + +/* + * Perform bytewise orthogonalization of eight 32-bit words. Bytes + * of q0..q7 are spread over all words: for a byte x that occurs + * at rank i in q[j] (byte x uses bits 8*i to 8*i+7 in q[j]), the bit + * of rank k in x (0 <= k <= 7) goes to q[k] at rank 8*i+j. + * + * This operation is an involution. + */ +void br_aes_ct_ortho(uint32_t *q); + +/* + * The AES S-box, as a bitsliced constant-time version. The input array + * consists in eight 32-bit words; 32 S-box instances are computed in + * parallel. Bits 0 to 7 of each S-box input (bit 0 is least significant) + * are spread over the words 0 to 7, at the same rank. + */ +void br_aes_ct_bitslice_Sbox(uint32_t *q); + +/* + * Like br_aes_bitslice_Sbox(), but for the inverse S-box. + */ +void br_aes_ct_bitslice_invSbox(uint32_t *q); + +/* + * Compute AES encryption on bitsliced data. Since input is stored on + * eight 32-bit words, two block encryptions are actually performed + * in parallel. + */ +void br_aes_ct_bitslice_encrypt(unsigned num_rounds, + const uint32_t *skey, uint32_t *q); + +/* + * Compute AES decryption on bitsliced data. Since input is stored on + * eight 32-bit words, two block decryptions are actually performed + * in parallel. + */ +void br_aes_ct_bitslice_decrypt(unsigned num_rounds, + const uint32_t *skey, uint32_t *q); + +/* + * AES key schedule, constant-time version. skey[] is filled with n+1 + * 128-bit subkeys, where n is the number of rounds (10 to 14, depending + * on key size). The number of rounds is returned. If the key size is + * invalid (not 16, 24 or 32), then 0 is returned. + */ +unsigned br_aes_ct_keysched(uint32_t *comp_skey, + const void *key, size_t key_len); + +/* + * Expand AES subkeys as produced by br_aes_ct_keysched(), into + * a larger array suitable for br_aes_ct_bitslice_encrypt() and + * br_aes_ct_bitslice_decrypt(). + */ +void br_aes_ct_skey_expand(uint32_t *skey, + unsigned num_rounds, const uint32_t *comp_skey); + +/* + * For the ct64 implementation, the same bitslicing technique is used, + * but four instances are interleaved. First instance uses bits 0, 4, + * 8, 12,... of each word; second instance uses bits 1, 5, 9, 13,... + * and so on. + */ + +/* + * Perform bytewise orthogonalization of eight 64-bit words. Bytes + * of q0..q7 are spread over all words: for a byte x that occurs + * at rank i in q[j] (byte x uses bits 8*i to 8*i+7 in q[j]), the bit + * of rank k in x (0 <= k <= 7) goes to q[k] at rank 8*i+j. + * + * This operation is an involution. + */ +void br_aes_ct64_ortho(uint64_t *q); + +/* + * Interleave bytes for an AES input block. If input bytes are + * denoted 0123456789ABCDEF, and have been decoded with little-endian + * convention (w[0] contains 0123, with '3' being most significant; + * w[1] contains 4567, and so on), then output word q0 will be + * set to 08192A3B (again little-endian convention) and q1 will + * be set to 4C5D6E7F. + */ +void br_aes_ct64_interleave_in(uint64_t *q0, uint64_t *q1, const uint32_t *w); + +/* + * Perform the opposite of br_aes_ct64_interleave_in(). + */ +void br_aes_ct64_interleave_out(uint32_t *w, uint64_t q0, uint64_t q1); + +/* + * The AES S-box, as a bitsliced constant-time version. The input array + * consists in eight 64-bit words; 64 S-box instances are computed in + * parallel. Bits 0 to 7 of each S-box input (bit 0 is least significant) + * are spread over the words 0 to 7, at the same rank. + */ +void br_aes_ct64_bitslice_Sbox(uint64_t *q); + +/* + * Like br_aes_bitslice_Sbox(), but for the inverse S-box. + */ +void br_aes_ct64_bitslice_invSbox(uint64_t *q); + +/* + * Compute AES encryption on bitsliced data. Since input is stored on + * eight 64-bit words, four block encryptions are actually performed + * in parallel. + */ +void br_aes_ct64_bitslice_encrypt(unsigned num_rounds, + const uint64_t *skey, uint64_t *q); + +/* + * Compute AES decryption on bitsliced data. Since input is stored on + * eight 64-bit words, four block decryptions are actually performed + * in parallel. + */ +void br_aes_ct64_bitslice_decrypt(unsigned num_rounds, + const uint64_t *skey, uint64_t *q); + +/* + * AES key schedule, constant-time version. skey[] is filled with n+1 + * 128-bit subkeys, where n is the number of rounds (10 to 14, depending + * on key size). The number of rounds is returned. If the key size is + * invalid (not 16, 24 or 32), then 0 is returned. + */ +unsigned br_aes_ct64_keysched(uint64_t *comp_skey, + const void *key, size_t key_len); + +/* + * Expand AES subkeys as produced by br_aes_ct64_keysched(), into + * a larger array suitable for br_aes_ct64_bitslice_encrypt() and + * br_aes_ct64_bitslice_decrypt(). + */ +void br_aes_ct64_skey_expand(uint64_t *skey, + unsigned num_rounds, const uint64_t *comp_skey); + +/* + * Test support for AES-NI opcodes. + */ +int br_aes_x86ni_supported(void); + +/* + * AES key schedule, using x86 AES-NI instructions. This yields the + * subkeys in the encryption direction. Number of rounds is returned. + * Key size MUST be 16, 24 or 32 bytes; otherwise, 0 is returned. + */ +unsigned br_aes_x86ni_keysched_enc(unsigned char *skni, + const void *key, size_t len); + +/* + * AES key schedule, using x86 AES-NI instructions. This yields the + * subkeys in the decryption direction. Number of rounds is returned. + * Key size MUST be 16, 24 or 32 bytes; otherwise, 0 is returned. + */ +unsigned br_aes_x86ni_keysched_dec(unsigned char *skni, + const void *key, size_t len); + +/* + * Test support for AES POWER8 opcodes. + */ +int br_aes_pwr8_supported(void); + +/* + * AES key schedule, using POWER8 instructions. This yields the + * subkeys in the encryption direction. Number of rounds is returned. + * Key size MUST be 16, 24 or 32 bytes; otherwise, 0 is returned. + */ +unsigned br_aes_pwr8_keysched(unsigned char *skni, + const void *key, size_t len); + +/* ==================================================================== */ +/* + * RSA. + */ + +/* + * Apply proper PKCS#1 v1.5 padding (for signatures). 'hash_oid' is + * the encoded hash function OID, or NULL. + */ +uint32_t br_rsa_pkcs1_sig_pad(const unsigned char *hash_oid, + const unsigned char *hash, size_t hash_len, + uint32_t n_bitlen, unsigned char *x); + +/* + * Check PKCS#1 v1.5 padding (for signatures). 'hash_oid' is the encoded + * hash function OID, or NULL. The provided 'sig' value is _after_ the + * modular exponentiation, i.e. it should be the padded hash. On + * success, the hashed message is extracted. + */ +uint32_t br_rsa_pkcs1_sig_unpad(const unsigned char *sig, size_t sig_len, + const unsigned char *hash_oid, size_t hash_len, + unsigned char *hash_out); + +/* + * Apply proper PSS padding. The 'x' buffer is output only: it + * receives the value that is to be exponentiated. + */ +uint32_t br_rsa_pss_sig_pad(const br_prng_class **rng, + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash, size_t salt_len, + uint32_t n_bitlen, unsigned char *x); + +/* + * Check PSS padding. The provided value is the one _after_ + * the modular exponentiation; it is modified by this function. + * This function infers the signature length from the public key + * size, i.e. it assumes that this has already been verified (as + * part of the exponentiation). + */ +uint32_t br_rsa_pss_sig_unpad( + const br_hash_class *hf_data, const br_hash_class *hf_mgf1, + const unsigned char *hash, size_t salt_len, + const br_rsa_public_key *pk, unsigned char *x); + +/* + * Apply OAEP padding. Returned value is the actual padded string length, + * or zero on error. + */ +size_t br_rsa_oaep_pad(const br_prng_class **rnd, const br_hash_class *dig, + const void *label, size_t label_len, const br_rsa_public_key *pk, + void *dst, size_t dst_nax_len, const void *src, size_t src_len); + +/* + * Unravel and check OAEP padding. If the padding is correct, then 1 is + * returned, '*len' is adjusted to the length of the message, and the + * data is moved to the start of the 'data' buffer. If the padding is + * incorrect, then 0 is returned and '*len' is untouched. Either way, + * the complete buffer contents are altered. + */ +uint32_t br_rsa_oaep_unpad(const br_hash_class *dig, + const void *label, size_t label_len, void *data, size_t *len); + +/* + * Compute MGF1 for a given seed, and XOR the output into the provided + * buffer. + */ +void br_mgf1_xor(void *data, size_t len, + const br_hash_class *dig, const void *seed, size_t seed_len); + +/* + * Inner function for RSA key generation; used by the "i31" and "i62" + * implementations. + */ +uint32_t br_rsa_i31_keygen_inner(const br_prng_class **rng, + br_rsa_private_key *sk, void *kbuf_priv, + br_rsa_public_key *pk, void *kbuf_pub, + unsigned size, uint32_t pubexp, br_i31_modpow_opt_type mp31); + +/* ==================================================================== */ +/* + * Elliptic curves. + */ + +/* + * Type for generic EC parameters: curve order (unsigned big-endian + * encoding) and encoded conventional generator. + */ +typedef struct { + int curve; + const unsigned char *order; + size_t order_len; + const unsigned char *generator; + size_t generator_len; +} br_ec_curve_def; + +extern const br_ec_curve_def br_secp256r1; +extern const br_ec_curve_def br_secp384r1; +extern const br_ec_curve_def br_secp521r1; + +/* + * For Curve25519, the advertised "order" really is 2^255-1, since the + * point multipliction function really works over arbitrary 255-bit + * scalars. This value is only meant as a hint for ECDH key generation; + * only ECDSA uses the exact curve order, and ECDSA is not used with + * that specific curve. + */ +extern const br_ec_curve_def br_curve25519; + +/* + * Decode some bytes as an i31 integer, with truncation (corresponding + * to the 'bits2int' operation in RFC 6979). The target ENCODED bit + * length is provided as last parameter. The resulting value will have + * this declared bit length, and consists the big-endian unsigned decoding + * of exactly that many bits in the source (capped at the source length). + */ +void br_ecdsa_i31_bits2int(uint32_t *x, + const void *src, size_t len, uint32_t ebitlen); + +/* + * Decode some bytes as an i15 integer, with truncation (corresponding + * to the 'bits2int' operation in RFC 6979). The target ENCODED bit + * length is provided as last parameter. The resulting value will have + * this declared bit length, and consists the big-endian unsigned decoding + * of exactly that many bits in the source (capped at the source length). + */ +void br_ecdsa_i15_bits2int(uint16_t *x, + const void *src, size_t len, uint32_t ebitlen); + +/* ==================================================================== */ +/* + * ASN.1 support functions. + */ + +/* + * A br_asn1_uint structure contains encoding information about an + * INTEGER nonnegative value: pointer to the integer contents (unsigned + * big-endian representation), length of the integer contents, + * and length of the encoded value. The data shall have minimal length: + * - If the integer value is zero, then 'len' must be zero. + * - If the integer value is not zero, then data[0] must be non-zero. + * + * Under these conditions, 'asn1len' is necessarily equal to either len + * or len+1. + */ +typedef struct { + const unsigned char *data; + size_t len; + size_t asn1len; +} br_asn1_uint; + +/* + * Given an encoded integer (unsigned big-endian, with possible leading + * bytes of value 0), returned the "prepared INTEGER" structure. + */ +br_asn1_uint br_asn1_uint_prepare(const void *xdata, size_t xlen); + +/* + * Encode an ASN.1 length. The length of the encoded length is returned. + * If 'dest' is NULL, then no encoding is performed, but the length of + * the encoded length is still computed and returned. + */ +size_t br_asn1_encode_length(void *dest, size_t len); + +/* + * Convenient macro for computing lengths of lengths. + */ +#define len_of_len(len) br_asn1_encode_length(NULL, len) + +/* + * Encode a (prepared) ASN.1 INTEGER. The encoded length is returned. + * If 'dest' is NULL, then no encoding is performed, but the length of + * the encoded integer is still computed and returned. + */ +size_t br_asn1_encode_uint(void *dest, br_asn1_uint pp); + +/* + * Get the OID that identifies an elliptic curve. Returned value is + * the DER-encoded OID, with the length (always one byte) but without + * the tag. Thus, the first byte of the returned buffer contains the + * number of subsequent bytes in the value. If the curve is not + * recognised, NULL is returned. + */ +const unsigned char *br_get_curve_OID(int curve); + +/* + * Inner function for EC private key encoding. This is equivalent to + * the API function br_encode_ec_raw_der(), except for an extra + * parameter: if 'include_curve_oid' is zero, then the curve OID is + * _not_ included in the output blob (this is for PKCS#8 support). + */ +size_t br_encode_ec_raw_der_inner(void *dest, + const br_ec_private_key *sk, const br_ec_public_key *pk, + int include_curve_oid); + +/* ==================================================================== */ +/* + * SSL/TLS support functions. + */ + +/* + * Record types. + */ +#define BR_SSL_CHANGE_CIPHER_SPEC 20 +#define BR_SSL_ALERT 21 +#define BR_SSL_HANDSHAKE 22 +#define BR_SSL_APPLICATION_DATA 23 + +/* + * Handshake message types. + */ +#define BR_SSL_HELLO_REQUEST 0 +#define BR_SSL_CLIENT_HELLO 1 +#define BR_SSL_SERVER_HELLO 2 +#define BR_SSL_CERTIFICATE 11 +#define BR_SSL_SERVER_KEY_EXCHANGE 12 +#define BR_SSL_CERTIFICATE_REQUEST 13 +#define BR_SSL_SERVER_HELLO_DONE 14 +#define BR_SSL_CERTIFICATE_VERIFY 15 +#define BR_SSL_CLIENT_KEY_EXCHANGE 16 +#define BR_SSL_FINISHED 20 + +/* + * Alert levels. + */ +#define BR_LEVEL_WARNING 1 +#define BR_LEVEL_FATAL 2 + +/* + * Low-level I/O state. + */ +#define BR_IO_FAILED 0 +#define BR_IO_IN 1 +#define BR_IO_OUT 2 +#define BR_IO_INOUT 3 + +/* + * Mark a SSL engine as failed. The provided error code is recorded if + * the engine was not already marked as failed. If 'err' is 0, then the + * engine is marked as closed (without error). + */ +void br_ssl_engine_fail(br_ssl_engine_context *cc, int err); + +/* + * Test whether the engine is closed (normally or as a failure). + */ +static inline int +br_ssl_engine_closed(const br_ssl_engine_context *cc) +{ + return cc->iomode == BR_IO_FAILED; +} + +/* + * Configure a new maximum fragment length. If possible, the maximum + * length for outgoing records is immediately adjusted (if there are + * not already too many buffered bytes for that). + */ +void br_ssl_engine_new_max_frag_len( + br_ssl_engine_context *rc, unsigned max_frag_len); + +/* + * Test whether the current incoming record has been fully received + * or not. This functions returns 0 only if a complete record header + * has been received, but some of the (possibly encrypted) payload + * has not yet been obtained. + */ +int br_ssl_engine_recvrec_finished(const br_ssl_engine_context *rc); + +/* + * Flush the current record (if not empty). This is meant to be called + * from the handshake processor only. + */ +void br_ssl_engine_flush_record(br_ssl_engine_context *cc); + +/* + * Test whether there is some accumulated payload to send. + */ +static inline int +br_ssl_engine_has_pld_to_send(const br_ssl_engine_context *rc) +{ + return rc->oxa != rc->oxb && rc->oxa != rc->oxc; +} + +/* + * Initialize RNG in engine. Returned value is 1 on success, 0 on error. + * This function will try to use the OS-provided RNG, if available. If + * there is no OS-provided RNG, or if it failed, and no entropy was + * injected by the caller, then a failure will be reported. On error, + * the context error code is set. + */ +int br_ssl_engine_init_rand(br_ssl_engine_context *cc); + +/* + * Reset the handshake-related parts of the engine. + */ +void br_ssl_engine_hs_reset(br_ssl_engine_context *cc, + void (*hsinit)(void *), void (*hsrun)(void *)); + +/* + * Get the PRF to use for this context, for the provided PRF hash + * function ID. + */ +br_tls_prf_impl br_ssl_engine_get_PRF(br_ssl_engine_context *cc, int prf_id); + +/* + * Consume the provided pre-master secret and compute the corresponding + * master secret. The 'prf_id' is the ID of the hash function to use + * with the TLS 1.2 PRF (ignored if the version is TLS 1.0 or 1.1). + */ +void br_ssl_engine_compute_master(br_ssl_engine_context *cc, + int prf_id, const void *pms, size_t len); + +/* + * Switch to CBC decryption for incoming records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF (ignored if not TLS 1.2+) + * mac_id id of hash function for HMAC + * bc_impl block cipher implementation (CBC decryption) + * cipher_key_len block cipher key length (in bytes) + */ +void br_ssl_engine_switch_cbc_in(br_ssl_engine_context *cc, + int is_client, int prf_id, int mac_id, + const br_block_cbcdec_class *bc_impl, size_t cipher_key_len); + +/* + * Switch to CBC encryption for outgoing records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF (ignored if not TLS 1.2+) + * mac_id id of hash function for HMAC + * bc_impl block cipher implementation (CBC encryption) + * cipher_key_len block cipher key length (in bytes) + */ +void br_ssl_engine_switch_cbc_out(br_ssl_engine_context *cc, + int is_client, int prf_id, int mac_id, + const br_block_cbcenc_class *bc_impl, size_t cipher_key_len); + +/* + * Switch to GCM decryption for incoming records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF + * bc_impl block cipher implementation (CTR) + * cipher_key_len block cipher key length (in bytes) + */ +void br_ssl_engine_switch_gcm_in(br_ssl_engine_context *cc, + int is_client, int prf_id, + const br_block_ctr_class *bc_impl, size_t cipher_key_len); + +/* + * Switch to GCM encryption for outgoing records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF + * bc_impl block cipher implementation (CTR) + * cipher_key_len block cipher key length (in bytes) + */ +void br_ssl_engine_switch_gcm_out(br_ssl_engine_context *cc, + int is_client, int prf_id, + const br_block_ctr_class *bc_impl, size_t cipher_key_len); + +/* + * Switch to ChaCha20+Poly1305 decryption for incoming records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF + */ +void br_ssl_engine_switch_chapol_in(br_ssl_engine_context *cc, + int is_client, int prf_id); + +/* + * Switch to ChaCha20+Poly1305 encryption for outgoing records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF + */ +void br_ssl_engine_switch_chapol_out(br_ssl_engine_context *cc, + int is_client, int prf_id); + +/* + * Switch to CCM decryption for incoming records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF + * bc_impl block cipher implementation (CTR+CBC) + * cipher_key_len block cipher key length (in bytes) + * tag_len tag length (in bytes) + */ +void br_ssl_engine_switch_ccm_in(br_ssl_engine_context *cc, + int is_client, int prf_id, + const br_block_ctrcbc_class *bc_impl, + size_t cipher_key_len, size_t tag_len); + +/* + * Switch to GCM encryption for outgoing records. + * cc the engine context + * is_client non-zero for a client, zero for a server + * prf_id id of hash function for PRF + * bc_impl block cipher implementation (CTR+CBC) + * cipher_key_len block cipher key length (in bytes) + * tag_len tag length (in bytes) + */ +void br_ssl_engine_switch_ccm_out(br_ssl_engine_context *cc, + int is_client, int prf_id, + const br_block_ctrcbc_class *bc_impl, + size_t cipher_key_len, size_t tag_len); + +/* + * Calls to T0-generated code. + */ +void br_ssl_hs_client_init_main(void *ctx); +void br_ssl_hs_client_run(void *ctx); +void br_ssl_hs_server_init_main(void *ctx); +void br_ssl_hs_server_run(void *ctx); + +/* + * Get the hash function to use for signatures, given a bit mask of + * supported hash functions. This implements a strict choice order + * (namely SHA-256, SHA-384, SHA-512, SHA-224, SHA-1). If the mask + * does not document support of any of these hash functions, then this + * functions returns 0. + */ +int br_ssl_choose_hash(unsigned bf); + +/* ==================================================================== */ + +/* + * PowerPC / POWER assembly stuff. The special BR_POWER_ASM_MACROS macro + * must be defined before including this file; this is done by source + * files that use some inline assembly for PowerPC / POWER machines. + */ + +#if BR_POWER_ASM_MACROS + +#define lxvw4x(xt, ra, rb) lxvw4x_(xt, ra, rb) +#define stxvw4x(xt, ra, rb) stxvw4x_(xt, ra, rb) + +#define bdnz(foo) bdnz_(foo) +#define bdz(foo) bdz_(foo) +#define beq(foo) beq_(foo) + +#define li(rx, value) li_(rx, value) +#define addi(rx, ra, imm) addi_(rx, ra, imm) +#define cmpldi(rx, imm) cmpldi_(rx, imm) +#define mtctr(rx) mtctr_(rx) +#define vspltb(vrt, vrb, uim) vspltb_(vrt, vrb, uim) +#define vspltw(vrt, vrb, uim) vspltw_(vrt, vrb, uim) +#define vspltisb(vrt, imm) vspltisb_(vrt, imm) +#define vspltisw(vrt, imm) vspltisw_(vrt, imm) +#define vrlw(vrt, vra, vrb) vrlw_(vrt, vra, vrb) +#define vsbox(vrt, vra) vsbox_(vrt, vra) +#define vxor(vrt, vra, vrb) vxor_(vrt, vra, vrb) +#define vand(vrt, vra, vrb) vand_(vrt, vra, vrb) +#define vsro(vrt, vra, vrb) vsro_(vrt, vra, vrb) +#define vsl(vrt, vra, vrb) vsl_(vrt, vra, vrb) +#define vsldoi(vt, va, vb, sh) vsldoi_(vt, va, vb, sh) +#define vsr(vrt, vra, vrb) vsr_(vrt, vra, vrb) +#define vaddcuw(vrt, vra, vrb) vaddcuw_(vrt, vra, vrb) +#define vadduwm(vrt, vra, vrb) vadduwm_(vrt, vra, vrb) +#define vsububm(vrt, vra, vrb) vsububm_(vrt, vra, vrb) +#define vsubuwm(vrt, vra, vrb) vsubuwm_(vrt, vra, vrb) +#define vsrw(vrt, vra, vrb) vsrw_(vrt, vra, vrb) +#define vcipher(vt, va, vb) vcipher_(vt, va, vb) +#define vcipherlast(vt, va, vb) vcipherlast_(vt, va, vb) +#define vncipher(vt, va, vb) vncipher_(vt, va, vb) +#define vncipherlast(vt, va, vb) vncipherlast_(vt, va, vb) +#define vperm(vt, va, vb, vc) vperm_(vt, va, vb, vc) +#define vpmsumd(vt, va, vb) vpmsumd_(vt, va, vb) +#define xxpermdi(vt, va, vb, d) xxpermdi_(vt, va, vb, d) + +#define lxvw4x_(xt, ra, rb) "\tlxvw4x\t" #xt "," #ra "," #rb "\n" +#define stxvw4x_(xt, ra, rb) "\tstxvw4x\t" #xt "," #ra "," #rb "\n" + +#define label(foo) #foo "%=:\n" +#define bdnz_(foo) "\tbdnz\t" #foo "%=\n" +#define bdz_(foo) "\tbdz\t" #foo "%=\n" +#define beq_(foo) "\tbeq\t" #foo "%=\n" + +#define li_(rx, value) "\tli\t" #rx "," #value "\n" +#define addi_(rx, ra, imm) "\taddi\t" #rx "," #ra "," #imm "\n" +#define cmpldi_(rx, imm) "\tcmpldi\t" #rx "," #imm "\n" +#define mtctr_(rx) "\tmtctr\t" #rx "\n" +#define vspltb_(vrt, vrb, uim) "\tvspltb\t" #vrt "," #vrb "," #uim "\n" +#define vspltw_(vrt, vrb, uim) "\tvspltw\t" #vrt "," #vrb "," #uim "\n" +#define vspltisb_(vrt, imm) "\tvspltisb\t" #vrt "," #imm "\n" +#define vspltisw_(vrt, imm) "\tvspltisw\t" #vrt "," #imm "\n" +#define vrlw_(vrt, vra, vrb) "\tvrlw\t" #vrt "," #vra "," #vrb "\n" +#define vsbox_(vrt, vra) "\tvsbox\t" #vrt "," #vra "\n" +#define vxor_(vrt, vra, vrb) "\tvxor\t" #vrt "," #vra "," #vrb "\n" +#define vand_(vrt, vra, vrb) "\tvand\t" #vrt "," #vra "," #vrb "\n" +#define vsro_(vrt, vra, vrb) "\tvsro\t" #vrt "," #vra "," #vrb "\n" +#define vsl_(vrt, vra, vrb) "\tvsl\t" #vrt "," #vra "," #vrb "\n" +#define vsldoi_(vt, va, vb, sh) "\tvsldoi\t" #vt "," #va "," #vb "," #sh "\n" +#define vsr_(vrt, vra, vrb) "\tvsr\t" #vrt "," #vra "," #vrb "\n" +#define vaddcuw_(vrt, vra, vrb) "\tvaddcuw\t" #vrt "," #vra "," #vrb "\n" +#define vadduwm_(vrt, vra, vrb) "\tvadduwm\t" #vrt "," #vra "," #vrb "\n" +#define vsububm_(vrt, vra, vrb) "\tvsububm\t" #vrt "," #vra "," #vrb "\n" +#define vsubuwm_(vrt, vra, vrb) "\tvsubuwm\t" #vrt "," #vra "," #vrb "\n" +#define vsrw_(vrt, vra, vrb) "\tvsrw\t" #vrt "," #vra "," #vrb "\n" +#define vcipher_(vt, va, vb) "\tvcipher\t" #vt "," #va "," #vb "\n" +#define vcipherlast_(vt, va, vb) "\tvcipherlast\t" #vt "," #va "," #vb "\n" +#define vncipher_(vt, va, vb) "\tvncipher\t" #vt "," #va "," #vb "\n" +#define vncipherlast_(vt, va, vb) "\tvncipherlast\t" #vt "," #va "," #vb "\n" +#define vperm_(vt, va, vb, vc) "\tvperm\t" #vt "," #va "," #vb "," #vc "\n" +#define vpmsumd_(vt, va, vb) "\tvpmsumd\t" #vt "," #va "," #vb "\n" +#define xxpermdi_(vt, va, vb, d) "\txxpermdi\t" #vt "," #va "," #vb "," #d "\n" + +#endif + +/* ==================================================================== */ +/* + * Special "activate intrinsics" code, needed for some compiler versions. + * This is defined at the end of this file, so that it won't impact any + * of the inline functions defined previously; and it is controlled by + * a specific macro defined in the caller code. + * + * Calling code conventions: + * + * - Caller must define BR_ENABLE_INTRINSICS before including "inner.h". + * - Functions that use intrinsics must be enclosed in an "enabled" + * region (between BR_TARGETS_X86_UP and BR_TARGETS_X86_DOWN). + * - Functions that use intrinsics must be tagged with the appropriate + * BR_TARGET(). + */ + +#if BR_ENABLE_INTRINSICS && (BR_GCC_4_4 || BR_CLANG_3_7 || BR_MSC_2005) + +/* + * x86 intrinsics (both 32-bit and 64-bit). + */ +#if BR_i386 || BR_amd64 + +/* + * On GCC before version 5.0, we need to use the pragma to enable the + * target options globally, because the 'target' function attribute + * appears to be unreliable. Before 4.6 we must also avoid the + * push_options / pop_options mechanism, because it tends to trigger + * some internal compiler errors. + */ +#if BR_GCC && !BR_GCC_5_0 +#if BR_GCC_4_6 +#define BR_TARGETS_X86_UP \ + _Pragma("GCC push_options") \ + _Pragma("GCC target(\"sse2,ssse3,sse4.1,aes,pclmul,rdrnd\")") +#define BR_TARGETS_X86_DOWN \ + _Pragma("GCC pop_options") +#else +#define BR_TARGETS_X86_UP \ + _Pragma("GCC target(\"sse2,ssse3,sse4.1,aes,pclmul\")") +#define BR_TARGETS_X86_DOWN +#endif +#pragma GCC diagnostic ignored "-Wpsabi" +#endif + +#if BR_CLANG && !BR_CLANG_3_8 +#undef __SSE2__ +#undef __SSE3__ +#undef __SSSE3__ +#undef __SSE4_1__ +#undef __AES__ +#undef __PCLMUL__ +#undef __RDRND__ +#define __SSE2__ 1 +#define __SSE3__ 1 +#define __SSSE3__ 1 +#define __SSE4_1__ 1 +#define __AES__ 1 +#define __PCLMUL__ 1 +#define __RDRND__ 1 +#endif + +#ifndef BR_TARGETS_X86_UP +#define BR_TARGETS_X86_UP +#endif +#ifndef BR_TARGETS_X86_DOWN +#define BR_TARGETS_X86_DOWN +#endif + +#if BR_GCC || BR_CLANG +BR_TARGETS_X86_UP +#include +#include +#define br_bswap32 __builtin_bswap32 +BR_TARGETS_X86_DOWN +#endif + +#if BR_MSC +#include +#include +#include +#define br_bswap32 _byteswap_ulong +#endif + +static inline int +br_cpuid(uint32_t mask_eax, uint32_t mask_ebx, + uint32_t mask_ecx, uint32_t mask_edx) +{ +#if BR_GCC || BR_CLANG + unsigned eax, ebx, ecx, edx; + + if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) { + if ((eax & mask_eax) == mask_eax + && (ebx & mask_ebx) == mask_ebx + && (ecx & mask_ecx) == mask_ecx + && (edx & mask_edx) == mask_edx) + { + return 1; + } + } +#elif BR_MSC + int info[4]; + + __cpuid(info, 1); + if (((uint32_t)info[0] & mask_eax) == mask_eax + && ((uint32_t)info[1] & mask_ebx) == mask_ebx + && ((uint32_t)info[2] & mask_ecx) == mask_ecx + && ((uint32_t)info[3] & mask_edx) == mask_edx) + { + return 1; + } +#endif + return 0; +} + +#endif + +#endif + +/* ==================================================================== */ + +#endif + + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/sysrng.c b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/sysrng.c new file mode 100644 index 000000000000..9533079e0e21 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/sysrng.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2017 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#define BR_ENABLE_INTRINSICS 1 +#include "inner.h" + +#if BR_USE_GETENTROPY +#include +#endif + +#if BR_USE_URANDOM +#include +#include +#include +#include +#endif + +#if BR_USE_WIN32_RAND +#include +#include +#pragma comment(lib, "advapi32") +#endif + +/* + * Seeder that uses the RDRAND opcodes (on x86 CPU). + */ +#if BR_RDRAND +BR_TARGETS_X86_UP +BR_TARGET("rdrnd") +static int +seeder_rdrand(const br_prng_class **ctx) +{ + unsigned char tmp[32]; + size_t u; + + for (u = 0; u < sizeof tmp; u += sizeof(uint32_t)) { + int j; + uint32_t x; + + /* + * We use the 32-bit intrinsic so that code is compatible + * with both 32-bit and 64-bit architectures. + * + * Intel recommends trying at least 10 times in case of + * failure. + * + * AMD bug: there are reports that some AMD processors + * have a bug that makes them fail silently after a + * suspend/resume cycle, in which case RDRAND will report + * a success but always return 0xFFFFFFFF. + * see: https://bugzilla.kernel.org/show_bug.cgi?id=85911 + * + * As a mitigation, if the 32-bit value is 0 or -1, then + * it is considered a failure and tried again. This should + * reliably detect the buggy case, at least. This also + * implies that the selected seed values can never be + * 0x00000000 or 0xFFFFFFFF, which is not a problem since + * we are generating a seed for a PRNG, and we overdo it + * a bit (we generate 32 bytes of randomness, and 256 bits + * of entropy are really overkill). + */ + for (j = 0; j < 10; j ++) { + if (_rdrand32_step(&x) && x != 0 && x != (uint32_t)-1) { + goto next_word; + } + } + return 0; + next_word: + br_enc32le(tmp + u, x); + } + (*ctx)->update(ctx, tmp, sizeof tmp); + return 1; +} +BR_TARGETS_X86_DOWN + +static int +rdrand_supported(void) +{ + /* + * The RDRND support is bit 30 of ECX, as returned by CPUID. + */ + return br_cpuid(0, 0, 0x40000000, 0); +} +#endif + +/* + * Seeder that uses /dev/urandom (on Unix-like systems). + */ +#if BR_USE_URANDOM +static int +seeder_urandom(const br_prng_class **ctx) +{ + int f; + + f = open("/dev/urandom", O_RDONLY); + if (f >= 0) { + unsigned char tmp[32]; + size_t u; + + for (u = 0; u < sizeof tmp;) { + ssize_t len; + + len = read(f, tmp + u, (sizeof tmp) - u); + if (len < 0) { + if (errno == EINTR) { + continue; + } + break; + } + u += (size_t)len; + } + close(f); + if (u == sizeof tmp) { + (*ctx)->update(ctx, tmp, sizeof tmp); + return 1; + } + } + return 0; +} +#endif + +/* + * Seeder that uses getentropy() (backed by getrandom() on some systems, + * e.g. Linux). On failure, it will use the /dev/urandom seeder (if + * enabled). + */ +#if BR_USE_GETENTROPY +static int +seeder_getentropy(const br_prng_class **ctx) +{ + unsigned char tmp[32]; + + if (getentropy(tmp, sizeof tmp) == 0) { + (*ctx)->update(ctx, tmp, sizeof tmp); + return 1; + } +#if BR_USE_URANDOM + return seeder_urandom(ctx); +#else + return 0; +#endif +} +#endif + +/* + * Seeder that uses CryptGenRandom() (on Windows). + */ +#if BR_USE_WIN32_RAND +static int +seeder_win32(const br_prng_class **ctx) +{ + HCRYPTPROV hp; + + if (CryptAcquireContext(&hp, 0, 0, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + { + BYTE buf[32]; + BOOL r; + + r = CryptGenRandom(hp, sizeof buf, buf); + CryptReleaseContext(hp, 0); + if (r) { + (*ctx)->update(ctx, buf, sizeof buf); + return 1; + } + } + return 0; +} +#endif + +/* + * An aggregate seeder that uses RDRAND, and falls back to an OS-provided + * source if RDRAND fails. + */ +#if BR_RDRAND && (BR_USE_GETENTROPY || BR_USE_URANDOM || BR_USE_WIN32_RAND) +static int +seeder_rdrand_with_fallback(const br_prng_class **ctx) +{ + if (!seeder_rdrand(ctx)) { +#if BR_USE_GETENTROPY + return seeder_getentropy(ctx); +#elif BR_USE_URANDOM + return seeder_urandom(ctx); +#elif BR_USE_WIN32_RAND + return seeder_win32(ctx); +#else +#error "macro selection has gone wrong" +#endif + } + return 1; +} +#endif + +/* see bearssl_rand.h */ +br_prng_seeder +br_prng_seeder_system(const char **name) +{ +#if BR_RDRAND + if (rdrand_supported()) { + if (name != NULL) { + *name = "rdrand"; + } +#if BR_USE_GETENTROPY || BR_USE_URANDOM || BR_USE_WIN32_RAND + return &seeder_rdrand_with_fallback; +#else + return &seeder_rdrand; +#endif + } +#endif +#if BR_USE_GETENTROPY + if (name != NULL) { + *name = "getentropy"; + } + return &seeder_getentropy; +#elif BR_USE_URANDOM + if (name != NULL) { + *name = "urandom"; + } + return &seeder_urandom; +#elif BR_USE_WIN32_RAND + if (name != NULL) { + *name = "win32"; + } + return &seeder_win32; +#else + if (name != NULL) { + *name = "none"; + } + return 0; +#endif +} + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/x509_decoder.c b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/x509_decoder.c new file mode 100644 index 000000000000..abf5df76fd0a --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/x509_decoder.c @@ -0,0 +1,779 @@ +/* Automatically generated code; do not modify directly. */ + + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#include +#include + +typedef struct { + uint32_t *dp; + uint32_t *rp; + const unsigned char *ip; +} t0_context; + +static uint32_t +t0_parse7E_unsigned(const unsigned char **p) +{ + uint32_t x; + + x = 0; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + return x; + } + } +} + +static int32_t +t0_parse7E_signed(const unsigned char **p) +{ + int neg; + uint32_t x; + + neg = ((**p) >> 6) & 1; + x = (uint32_t)-neg; + for (;;) { + unsigned y; + + y = *(*p) ++; + x = (x << 7) | (uint32_t)(y & 0x7F); + if (y < 0x80) { + if (neg) { + return -(int32_t)~x - 1; + } else { + return (int32_t)x; + } + } + } +} + +#define T0_VBYTE(x, n) (unsigned char)((((uint32_t)(x) >> (n)) & 0x7F) | 0x80) +#define T0_FBYTE(x, n) (unsigned char)(((uint32_t)(x) >> (n)) & 0x7F) +#define T0_SBYTE(x) (unsigned char)((((uint32_t)(x) >> 28) + 0xF8) ^ 0xF8) +#define T0_INT1(x) T0_FBYTE(x, 0) +#define T0_INT2(x) T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT3(x) T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT4(x) T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) +#define T0_INT5(x) T0_SBYTE(x), T0_VBYTE(x, 21), T0_VBYTE(x, 14), T0_VBYTE(x, 7), T0_FBYTE(x, 0) + +/* static const unsigned char t0_datablock[]; */ + + +void br_x509_decoder_init_main_libmail(void *t0ctx); + +void br_x509_decoder_run_libmail(void *t0ctx); + + + +#include "inner.h" + + + + + +#include "inner.h" + +#define CTX ((br_x509_decoder_context_libmail *)(void *)((unsigned char *)t0ctx - offsetof(br_x509_decoder_context_libmail, cpu))) +#define CONTEXT_NAME br_x509_decoder_context_libmail + +/* see bearssl_x509.h */ +void +br_x509_decoder_init_libmail(br_x509_decoder_context_libmail *ctx, + void (*append_dn)(void *ctx, const void *buf, size_t len), + void *append_dn_ctx) +{ + memset(ctx, 0, sizeof *ctx); + /* obsolete + ctx->err = 0; + ctx->hbuf = NULL; + ctx->hlen = 0; + */ + ctx->append_dn = append_dn; + ctx->append_dn_ctx = append_dn_ctx; + ctx->cpu.dp = &ctx->dp_stack[0]; + ctx->cpu.rp = &ctx->rp_stack[0]; + br_x509_decoder_init_main_libmail(&ctx->cpu); + br_x509_decoder_run_libmail(&ctx->cpu); +} + +/* see bearssl_x509.h */ +void +br_x509_decoder_push_libmail(br_x509_decoder_context_libmail *ctx, + const void *data, size_t len) +{ + ctx->hbuf = data; + ctx->hlen = len; + br_x509_decoder_run_libmail(&ctx->cpu); +} + + + +static const unsigned char t0_datablock[] = { + 0x00, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x01, 0x0C, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, + 0x0D, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x08, 0x2A, 0x86, + 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, + 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, + 0x04, 0x01, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01, 0x08, + 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x08, 0x2A, 0x86, 0x48, + 0xCE, 0x3D, 0x04, 0x03, 0x03, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, + 0x03, 0x04, 0x00, 0x1F, 0x03, 0xFC, 0x07, 0x7F, 0x0B, 0x5E, 0x0F, 0x1F, + 0x12, 0xFE, 0x16, 0xBF, 0x1A, 0x9F, 0x1E, 0x7E, 0x22, 0x3F, 0x26, 0x1E, + 0x29, 0xDF, 0x00, 0x1F, 0x03, 0xFD, 0x07, 0x9F, 0x0B, 0x7E, 0x0F, 0x3F, + 0x13, 0x1E, 0x16, 0xDF, 0x1A, 0xBF, 0x1E, 0x9E, 0x22, 0x5F, 0x26, 0x3E, + 0x29, 0xFF, 0x03, 0x55, 0x1D, 0x13 +}; + +static const unsigned char t0_codeblock[] = { + 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x01, + 0x01, 0x09, 0x00, 0x00, 0x01, 0x01, 0x0A, 0x00, 0x00, 0x1A, 0x1A, 0x00, + 0x00, 0x01, T0_INT1(BR_ERR_X509_BAD_BOOLEAN), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_BAD_TAG_CLASS), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_BAD_TAG_VALUE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_BAD_TIME), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_EXTRA_ELEMENT), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_INDEFINITE_LENGTH), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_INNER_TRUNC), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_LIMIT_EXCEEDED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_NOT_CONSTRUCTED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_NOT_PRIMITIVE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_OVERFLOW), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_PARTIAL_BYTE), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_UNEXPECTED), 0x00, 0x00, 0x01, + T0_INT1(BR_ERR_X509_UNSUPPORTED), 0x00, 0x00, 0x01, + T0_INT1(BR_KEYTYPE_EC), 0x00, 0x00, 0x01, T0_INT1(BR_KEYTYPE_RSA), + 0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, copy_dn)), 0x00, 0x00, + 0x01, T0_INT2(offsetof(CONTEXT_NAME, decoded)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, isCA)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(br_x509_decoder_context_libmail, pkey_data)), 0x01, + T0_INT2(BR_X509_BUFSIZE_KEY), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, notafter_days)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, notafter_seconds)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, notbefore_days)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, notbefore_seconds)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, pad)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, signer_hash_id)), 0x00, 0x00, 0x01, + T0_INT2(offsetof(CONTEXT_NAME, signer_key_type)), 0x00, 0x00, 0x01, + 0x80, 0x45, 0x00, 0x00, 0x01, 0x80, 0x4E, 0x00, 0x00, 0x01, 0x80, 0x54, + 0x00, 0x00, 0x01, 0x81, 0x36, 0x00, 0x02, 0x03, 0x00, 0x03, 0x01, 0x1B, + 0x02, 0x01, 0x13, 0x26, 0x02, 0x00, 0x0F, 0x15, 0x00, 0x00, 0x05, 0x02, + 0x34, 0x1D, 0x00, 0x00, 0x06, 0x02, 0x35, 0x1D, 0x00, 0x00, 0x01, 0x10, + 0x4F, 0x00, 0x00, 0x11, 0x05, 0x02, 0x38, 0x1D, 0x4C, 0x00, 0x00, 0x11, + 0x05, 0x02, 0x38, 0x1D, 0x4D, 0x00, 0x00, 0x06, 0x02, 0x30, 0x1D, 0x00, + 0x00, 0x1B, 0x19, 0x01, 0x08, 0x0E, 0x26, 0x29, 0x19, 0x09, 0x00, 0x00, + 0x01, 0x30, 0x0A, 0x1B, 0x01, 0x00, 0x01, 0x09, 0x4B, 0x05, 0x02, 0x2F, + 0x1D, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x01, 0x80, 0x5A, 0x00, 0x00, + 0x01, 0x80, 0x62, 0x00, 0x00, 0x01, 0x80, 0x6B, 0x00, 0x00, 0x01, 0x80, + 0x74, 0x00, 0x00, 0x01, 0x80, 0x7D, 0x00, 0x00, 0x01, 0x3D, 0x00, 0x00, + 0x20, 0x11, 0x06, 0x04, 0x2B, 0x6B, 0x7A, 0x71, 0x00, 0x04, 0x01, 0x00, + 0x3D, 0x25, 0x01, 0x00, 0x3C, 0x25, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x6D, + 0x6D, 0x70, 0x1B, 0x01, 0x20, 0x11, 0x06, 0x11, 0x1A, 0x4C, 0x6B, 0x70, + 0x01, 0x02, 0x50, 0x6E, 0x01, 0x02, 0x12, 0x06, 0x02, 0x39, 0x1D, 0x51, + 0x70, 0x01, 0x02, 0x50, 0x6C, 0x6D, 0x7A, 0x6D, 0x7A, 0x6D, 0x65, 0x43, + 0x24, 0x42, 0x24, 0x65, 0x41, 0x24, 0x40, 0x24, 0x51, 0x01, 0x01, 0x3C, + 0x25, 0x6D, 0x7A, 0x01, 0x00, 0x3C, 0x25, 0x6D, 0x6D, 0x60, 0x05, 0x02, + 0x39, 0x1D, 0x74, 0x1C, 0x06, 0x1C, 0x7A, 0x61, 0x6D, 0x3F, 0x68, 0x03, + 0x00, 0x3F, 0x26, 0x02, 0x00, 0x09, 0x26, 0x02, 0x00, 0x0A, 0x68, 0x03, + 0x01, 0x51, 0x51, 0x02, 0x00, 0x02, 0x01, 0x18, 0x04, 0x1E, 0x5A, 0x1C, + 0x06, 0x18, 0x64, 0x03, 0x02, 0x51, 0x61, 0x1B, 0x03, 0x03, 0x1B, 0x3F, + 0x23, 0x0D, 0x06, 0x02, 0x33, 0x1D, 0x62, 0x02, 0x02, 0x02, 0x03, 0x17, + 0x04, 0x02, 0x39, 0x1D, 0x51, 0x01, 0x00, 0x3E, 0x25, 0x71, 0x01, 0x21, + 0x5B, 0x01, 0x22, 0x5B, 0x1B, 0x01, 0x23, 0x11, 0x06, 0x28, 0x1A, 0x4C, + 0x6B, 0x6D, 0x1B, 0x06, 0x1D, 0x6D, 0x60, 0x1A, 0x70, 0x1B, 0x01, 0x01, + 0x11, 0x06, 0x03, 0x63, 0x1A, 0x70, 0x01, 0x04, 0x50, 0x6B, 0x4A, 0x1C, + 0x06, 0x03, 0x5F, 0x04, 0x01, 0x7B, 0x51, 0x51, 0x04, 0x60, 0x51, 0x51, + 0x04, 0x08, 0x01, 0x7F, 0x11, 0x05, 0x02, 0x38, 0x1D, 0x1A, 0x51, 0x6D, + 0x60, 0x06, 0x80, 0x63, 0x75, 0x1C, 0x06, 0x06, 0x01, 0x02, 0x3B, 0x04, + 0x80, 0x57, 0x76, 0x1C, 0x06, 0x06, 0x01, 0x03, 0x3B, 0x04, 0x80, 0x4D, + 0x77, 0x1C, 0x06, 0x06, 0x01, 0x04, 0x3B, 0x04, 0x80, 0x43, 0x78, 0x1C, + 0x06, 0x05, 0x01, 0x05, 0x3B, 0x04, 0x3A, 0x79, 0x1C, 0x06, 0x05, 0x01, + 0x06, 0x3B, 0x04, 0x31, 0x55, 0x1C, 0x06, 0x05, 0x01, 0x02, 0x3A, 0x04, + 0x28, 0x56, 0x1C, 0x06, 0x05, 0x01, 0x03, 0x3A, 0x04, 0x1F, 0x57, 0x1C, + 0x06, 0x05, 0x01, 0x04, 0x3A, 0x04, 0x16, 0x58, 0x1C, 0x06, 0x05, 0x01, + 0x05, 0x3A, 0x04, 0x0D, 0x59, 0x1C, 0x06, 0x05, 0x01, 0x06, 0x3A, 0x04, + 0x04, 0x01, 0x00, 0x01, 0x00, 0x04, 0x04, 0x01, 0x00, 0x01, 0x00, 0x46, + 0x25, 0x45, 0x25, 0x7A, 0x61, 0x7A, 0x51, 0x1A, 0x01, 0x01, 0x3D, 0x25, + 0x73, 0x30, 0x1D, 0x00, 0x00, 0x01, 0x81, 0x06, 0x00, 0x01, 0x54, 0x0D, + 0x06, 0x02, 0x32, 0x1D, 0x1B, 0x03, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x00, + 0x6D, 0x71, 0x1B, 0x01, 0x01, 0x11, 0x06, 0x08, 0x63, 0x01, 0x01, 0x15, + 0x3E, 0x25, 0x04, 0x01, 0x2B, 0x7A, 0x00, 0x00, 0x70, 0x01, 0x06, 0x50, + 0x6F, 0x00, 0x00, 0x70, 0x01, 0x03, 0x50, 0x6B, 0x72, 0x06, 0x02, 0x37, + 0x1D, 0x00, 0x00, 0x26, 0x1B, 0x06, 0x07, 0x21, 0x1B, 0x06, 0x01, 0x16, + 0x04, 0x76, 0x2B, 0x00, 0x00, 0x01, 0x01, 0x50, 0x6A, 0x01, 0x01, 0x10, + 0x06, 0x02, 0x2C, 0x1D, 0x72, 0x27, 0x00, 0x00, 0x60, 0x05, 0x02, 0x39, + 0x1D, 0x47, 0x1C, 0x06, 0x04, 0x01, 0x17, 0x04, 0x12, 0x48, 0x1C, 0x06, + 0x04, 0x01, 0x18, 0x04, 0x0A, 0x49, 0x1C, 0x06, 0x04, 0x01, 0x19, 0x04, + 0x02, 0x39, 0x1D, 0x00, 0x04, 0x70, 0x1B, 0x01, 0x17, 0x01, 0x18, 0x4B, + 0x05, 0x02, 0x2F, 0x1D, 0x01, 0x18, 0x11, 0x03, 0x00, 0x4D, 0x6B, 0x66, + 0x02, 0x00, 0x06, 0x0C, 0x01, 0x80, 0x64, 0x08, 0x03, 0x01, 0x66, 0x02, + 0x01, 0x09, 0x04, 0x0E, 0x1B, 0x01, 0x32, 0x0D, 0x06, 0x04, 0x01, 0x80, + 0x64, 0x09, 0x01, 0x8E, 0x6C, 0x09, 0x03, 0x01, 0x02, 0x01, 0x01, 0x82, + 0x6D, 0x08, 0x02, 0x01, 0x01, 0x03, 0x09, 0x01, 0x04, 0x0C, 0x09, 0x02, + 0x01, 0x01, 0x80, 0x63, 0x09, 0x01, 0x80, 0x64, 0x0C, 0x0A, 0x02, 0x01, + 0x01, 0x83, 0x0F, 0x09, 0x01, 0x83, 0x10, 0x0C, 0x09, 0x03, 0x03, 0x01, + 0x01, 0x01, 0x0C, 0x67, 0x2A, 0x01, 0x01, 0x0E, 0x02, 0x01, 0x01, 0x04, + 0x07, 0x28, 0x02, 0x01, 0x01, 0x80, 0x64, 0x07, 0x27, 0x02, 0x01, 0x01, + 0x83, 0x10, 0x07, 0x28, 0x1F, 0x15, 0x06, 0x03, 0x01, 0x18, 0x09, 0x5D, + 0x09, 0x52, 0x1B, 0x01, 0x05, 0x14, 0x02, 0x03, 0x09, 0x03, 0x03, 0x01, + 0x1F, 0x15, 0x01, 0x01, 0x26, 0x67, 0x02, 0x03, 0x09, 0x2A, 0x03, 0x03, + 0x01, 0x00, 0x01, 0x17, 0x67, 0x01, 0x9C, 0x10, 0x08, 0x03, 0x02, 0x01, + 0x00, 0x01, 0x3B, 0x67, 0x01, 0x3C, 0x08, 0x02, 0x02, 0x09, 0x03, 0x02, + 0x01, 0x00, 0x01, 0x3C, 0x67, 0x02, 0x02, 0x09, 0x03, 0x02, 0x72, 0x1B, + 0x01, 0x2E, 0x11, 0x06, 0x0D, 0x1A, 0x72, 0x1B, 0x01, 0x30, 0x01, 0x39, + 0x4B, 0x06, 0x03, 0x1A, 0x04, 0x74, 0x01, 0x80, 0x5A, 0x10, 0x06, 0x02, + 0x2F, 0x1D, 0x51, 0x02, 0x03, 0x02, 0x02, 0x00, 0x01, 0x72, 0x53, 0x01, + 0x0A, 0x08, 0x03, 0x00, 0x72, 0x53, 0x02, 0x00, 0x09, 0x00, 0x02, 0x03, + 0x00, 0x03, 0x01, 0x66, 0x1B, 0x02, 0x01, 0x02, 0x00, 0x4B, 0x05, 0x02, + 0x2F, 0x1D, 0x00, 0x00, 0x23, 0x70, 0x01, 0x02, 0x50, 0x0B, 0x69, 0x00, + 0x03, 0x1B, 0x03, 0x00, 0x03, 0x01, 0x03, 0x02, 0x6B, 0x72, 0x1B, 0x01, + 0x81, 0x00, 0x13, 0x06, 0x02, 0x36, 0x1D, 0x1B, 0x01, 0x00, 0x11, 0x06, + 0x0B, 0x1A, 0x1B, 0x05, 0x04, 0x1A, 0x01, 0x00, 0x00, 0x72, 0x04, 0x6F, + 0x02, 0x01, 0x1B, 0x05, 0x02, 0x33, 0x1D, 0x2A, 0x03, 0x01, 0x02, 0x02, + 0x25, 0x02, 0x02, 0x29, 0x03, 0x02, 0x1B, 0x06, 0x03, 0x72, 0x04, 0x68, + 0x1A, 0x02, 0x00, 0x02, 0x01, 0x0A, 0x00, 0x01, 0x72, 0x1B, 0x01, 0x81, + 0x00, 0x0D, 0x06, 0x01, 0x00, 0x01, 0x81, 0x00, 0x0A, 0x1B, 0x05, 0x02, + 0x31, 0x1D, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x12, 0x06, + 0x19, 0x02, 0x00, 0x2A, 0x03, 0x00, 0x1B, 0x01, 0x83, 0xFF, 0xFF, 0x7F, + 0x12, 0x06, 0x02, 0x32, 0x1D, 0x01, 0x08, 0x0E, 0x26, 0x72, 0x23, 0x09, + 0x04, 0x60, 0x00, 0x00, 0x6A, 0x5E, 0x00, 0x00, 0x6B, 0x7A, 0x00, 0x00, + 0x70, 0x4E, 0x6B, 0x00, 0x01, 0x6B, 0x1B, 0x05, 0x02, 0x36, 0x1D, 0x72, + 0x1B, 0x01, 0x81, 0x00, 0x13, 0x06, 0x02, 0x36, 0x1D, 0x03, 0x00, 0x1B, + 0x06, 0x16, 0x72, 0x02, 0x00, 0x1B, 0x01, 0x87, 0xFF, 0xFF, 0x7F, 0x13, + 0x06, 0x02, 0x36, 0x1D, 0x01, 0x08, 0x0E, 0x09, 0x03, 0x00, 0x04, 0x67, + 0x1A, 0x02, 0x00, 0x00, 0x00, 0x6B, 0x1B, 0x01, 0x81, 0x7F, 0x12, 0x06, + 0x08, 0x7A, 0x01, 0x00, 0x44, 0x25, 0x01, 0x00, 0x00, 0x1B, 0x44, 0x25, + 0x44, 0x29, 0x62, 0x01, 0x7F, 0x00, 0x01, 0x72, 0x03, 0x00, 0x02, 0x00, + 0x01, 0x05, 0x14, 0x01, 0x01, 0x15, 0x1E, 0x02, 0x00, 0x01, 0x06, 0x14, + 0x1B, 0x01, 0x01, 0x15, 0x06, 0x02, 0x2D, 0x1D, 0x01, 0x04, 0x0E, 0x02, + 0x00, 0x01, 0x1F, 0x15, 0x1B, 0x01, 0x1F, 0x11, 0x06, 0x02, 0x2E, 0x1D, + 0x09, 0x00, 0x00, 0x1B, 0x05, 0x05, 0x01, 0x00, 0x01, 0x7F, 0x00, 0x70, + 0x00, 0x00, 0x1B, 0x05, 0x02, 0x32, 0x1D, 0x2A, 0x73, 0x00, 0x00, 0x22, + 0x1B, 0x01, 0x00, 0x13, 0x06, 0x01, 0x00, 0x1A, 0x16, 0x04, 0x74, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x00, 0x01, 0x15, 0x00, 0x00, + 0x01, 0x1F, 0x00, 0x00, 0x01, 0x29, 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, + 0x7B, 0x1A, 0x00, 0x00, 0x1B, 0x06, 0x07, 0x7C, 0x1B, 0x06, 0x01, 0x16, + 0x04, 0x76, 0x00, 0x00, 0x01, 0x00, 0x20, 0x21, 0x0B, 0x2B, 0x00 +}; + +static const uint16_t t0_caddr[] = { + 0, + 5, + 10, + 15, + 20, + 24, + 28, + 32, + 36, + 40, + 44, + 48, + 52, + 56, + 60, + 64, + 68, + 72, + 76, + 80, + 84, + 88, + 93, + 98, + 103, + 111, + 116, + 121, + 126, + 131, + 136, + 141, + 146, + 151, + 156, + 161, + 166, + 181, + 187, + 193, + 198, + 206, + 214, + 220, + 231, + 246, + 250, + 255, + 260, + 265, + 270, + 275, + 279, + 289, + 620, + 625, + 639, + 659, + 666, + 678, + 692, + 707, + 740, + 960, + 974, + 991, + 1000, + 1067, + 1123, + 1127, + 1131, + 1136, + 1184, + 1210, + 1254, + 1265, + 1274, + 1287, + 1291, + 1295, + 1299, + 1303, + 1307, + 1311, + 1315, + 1327 +}; + +#define T0_INTERPRETED 39 + +#define T0_ENTER(ip, rp, slot) do { \ + const unsigned char *t0_newip; \ + uint32_t t0_lnum; \ + t0_newip = &t0_codeblock[t0_caddr[(slot) - T0_INTERPRETED]]; \ + t0_lnum = t0_parse7E_unsigned(&t0_newip); \ + (rp) += t0_lnum; \ + *((rp) ++) = (uint32_t)((ip) - &t0_codeblock[0]) + (t0_lnum << 16); \ + (ip) = t0_newip; \ + } while (0) + +#define T0_DEFENTRY(name, slot) \ +void \ +name(void *ctx) \ +{ \ + t0_context *t0ctx = ctx; \ + t0ctx->ip = &t0_codeblock[0]; \ + T0_ENTER(t0ctx->ip, t0ctx->rp, slot); \ +} + +T0_DEFENTRY(br_x509_decoder_init_main_libmail, 92) + +#define T0_NEXT(t0ipp) (*(*(t0ipp)) ++) + +void +br_x509_decoder_run_libmail(void *t0ctx) +{ + uint32_t *dp, *rp; + const unsigned char *ip; + +#define T0_LOCAL(x) (*(rp - 2 - (x))) +#define T0_POP() (*-- dp) +#define T0_POPi() (*(int32_t *)(-- dp)) +#define T0_PEEK(x) (*(dp - 1 - (x))) +#define T0_PEEKi(x) (*(int32_t *)(dp - 1 - (x))) +#define T0_PUSH(v) do { *dp = (v); dp ++; } while (0) +#define T0_PUSHi(v) do { *(int32_t *)dp = (v); dp ++; } while (0) +#define T0_RPOP() (*-- rp) +#define T0_RPOPi() (*(int32_t *)(-- rp)) +#define T0_RPUSH(v) do { *rp = (v); rp ++; } while (0) +#define T0_RPUSHi(v) do { *(int32_t *)rp = (v); rp ++; } while (0) +#define T0_ROLL(x) do { \ + size_t t0len = (size_t)(x); \ + uint32_t t0tmp = *(dp - 1 - t0len); \ + memmove(dp - t0len - 1, dp - t0len, t0len * sizeof *dp); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_SWAP() do { \ + uint32_t t0tmp = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_ROT() do { \ + uint32_t t0tmp = *(dp - 3); \ + *(dp - 3) = *(dp - 2); \ + *(dp - 2) = *(dp - 1); \ + *(dp - 1) = t0tmp; \ +} while (0) +#define T0_NROT() do { \ + uint32_t t0tmp = *(dp - 1); \ + *(dp - 1) = *(dp - 2); \ + *(dp - 2) = *(dp - 3); \ + *(dp - 3) = t0tmp; \ +} while (0) +#define T0_PICK(x) do { \ + uint32_t t0depth = (x); \ + T0_PUSH(T0_PEEK(t0depth)); \ +} while (0) +#define T0_CO() do { \ + goto t0_exit; \ +} while (0) +#define T0_RET() goto t0_next + + dp = ((t0_context *)t0ctx)->dp; + rp = ((t0_context *)t0ctx)->rp; + ip = ((t0_context *)t0ctx)->ip; + goto t0_next; + for (;;) { + uint32_t t0x; + + t0_next: + t0x = T0_NEXT(&ip); + if (t0x < T0_INTERPRETED) { + switch (t0x) { + int32_t t0off; + + case 0: /* ret */ + t0x = T0_RPOP(); + rp -= (t0x >> 16); + t0x &= 0xFFFF; + if (t0x == 0) { + ip = NULL; + goto t0_exit; + } + ip = &t0_codeblock[t0x]; + break; + case 1: /* literal constant */ + T0_PUSHi(t0_parse7E_signed(&ip)); + break; + case 2: /* read local */ + T0_PUSH(T0_LOCAL(t0_parse7E_unsigned(&ip))); + break; + case 3: /* write local */ + T0_LOCAL(t0_parse7E_unsigned(&ip)) = T0_POP(); + break; + case 4: /* jump */ + t0off = t0_parse7E_signed(&ip); + ip += t0off; + break; + case 5: /* jump if */ + t0off = t0_parse7E_signed(&ip); + if (T0_POP()) { + ip += t0off; + } + break; + case 6: /* jump if not */ + t0off = t0_parse7E_signed(&ip); + if (!T0_POP()) { + ip += t0off; + } + break; + case 7: { + /* %25 */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSHi(a % b); + + } + break; + case 8: { + /* * */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a * b); + + } + break; + case 9: { + /* + */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a + b); + + } + break; + case 10: { + /* - */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a - b); + + } + break; + case 11: { + /* -rot */ + T0_NROT(); + } + break; + case 12: { + /* / */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSHi(a / b); + + } + break; + case 13: { + /* < */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a < b)); + + } + break; + case 14: { + /* << */ + + int c = (int)T0_POPi(); + uint32_t x = T0_POP(); + T0_PUSH(x << c); + + } + break; + case 15: { + /* <= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a <= b)); + + } + break; + case 16: { + /* <> */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a != b)); + + } + break; + case 17: { + /* = */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(-(uint32_t)(a == b)); + + } + break; + case 18: { + /* > */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a > b)); + + } + break; + case 19: { + /* >= */ + + int32_t b = T0_POPi(); + int32_t a = T0_POPi(); + T0_PUSH(-(uint32_t)(a >= b)); + + } + break; + case 20: { + /* >> */ + + int c = (int)T0_POPi(); + int32_t x = T0_POPi(); + T0_PUSHi(x >> c); + + } + break; + case 21: { + /* and */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a & b); + + } + break; + case 22: { + /* co */ + T0_CO(); + } + break; + case 23: { + /* copy-ec-pkey */ + + size_t qlen = T0_POP(); + uint32_t curve = T0_POP(); + CTX->pkey.key_type = BR_KEYTYPE_EC; + CTX->pkey.key.ec.curve = curve; + CTX->pkey.key.ec.q = CTX->pkey_data; + CTX->pkey.key.ec.qlen = qlen; + + } + break; + case 24: { + /* copy-rsa-pkey */ + + size_t elen = T0_POP(); + size_t nlen = T0_POP(); + CTX->pkey.key_type = BR_KEYTYPE_RSA; + CTX->pkey.key.rsa.n = CTX->pkey_data; + CTX->pkey.key.rsa.nlen = nlen; + CTX->pkey.key.rsa.e = CTX->pkey_data + nlen; + CTX->pkey.key.rsa.elen = elen; + + } + break; + case 25: { + /* data-get8 */ + + size_t addr = T0_POP(); + T0_PUSH(t0_datablock[addr]); + + } + break; + case 26: { + /* drop */ + (void)T0_POP(); + } + break; + case 27: { + /* dup */ + T0_PUSH(T0_PEEK(0)); + } + break; + case 28: { + /* eqOID */ + + const unsigned char *a2 = &t0_datablock[T0_POP()]; + const unsigned char *a1 = &CTX->pad[0]; + size_t len = a1[0]; + int x; + if (len == a2[0]) { + x = -(memcmp(a1 + 1, a2 + 1, len) == 0); + } else { + x = 0; + } + T0_PUSH((uint32_t)x); + + } + break; + case 29: { + /* fail */ + + CTX->err = T0_POPi(); + T0_CO(); + + } + break; + case 30: { + /* neg */ + + uint32_t a = T0_POP(); + T0_PUSH(-a); + + } + break; + case 31: { + /* or */ + + uint32_t b = T0_POP(); + uint32_t a = T0_POP(); + T0_PUSH(a | b); + + } + break; + case 32: { + /* over */ + T0_PUSH(T0_PEEK(1)); + } + break; + case 33: { + /* read-blob-inner */ + + uint32_t len = T0_POP(); + uint32_t addr = T0_POP(); + size_t clen = CTX->hlen; + if (clen > len) { + clen = (size_t)len; + } + if (addr != 0) { + memcpy((unsigned char *)CTX + addr, CTX->hbuf, clen); + } + if (CTX->copy_dn && CTX->append_dn) { + CTX->append_dn(CTX->append_dn_ctx, CTX->hbuf, clen); + } + CTX->hbuf += clen; + CTX->hlen -= clen; + T0_PUSH(addr + clen); + T0_PUSH(len - clen); + + } + break; + case 34: { + /* read8-low */ + + if (CTX->hlen == 0) { + T0_PUSHi(-1); + } else { + unsigned char x = *CTX->hbuf ++; + if (CTX->copy_dn && CTX->append_dn) { + CTX->append_dn(CTX->append_dn_ctx, &x, 1); + } + CTX->hlen --; + T0_PUSH(x); + } + + } + break; + case 35: { + /* rot */ + T0_ROT(); + } + break; + case 36: { + /* set32 */ + + uint32_t addr = T0_POP(); + *(uint32_t *)(void *)((unsigned char *)CTX + addr) = T0_POP(); + + } + break; + case 37: { + /* set8 */ + + uint32_t addr = T0_POP(); + *((unsigned char *)CTX + addr) = (unsigned char)T0_POP(); + + } + break; + case 38: { + /* swap */ + T0_SWAP(); + } + break; + } + + } else { + T0_ENTER(ip, rp, t0x); + } + } +t0_exit: + ((t0_context *)t0ctx)->dp = dp; + ((t0_context *)t0ctx)->rp = rp; + ((t0_context *)t0ctx)->ip = ip; +} + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/x509_knownkey.c b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/x509_knownkey.c new file mode 100644 index 000000000000..f1f5af1bc7ce --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/x509_knownkey.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#include "inner.h" + +/* see bearssl_x509.h */ +void +br_x509_knownkey_init_rsa(br_x509_knownkey_context *ctx, + const br_rsa_public_key *pk, unsigned usages) +{ + ctx->vtable = &br_x509_knownkey_vtable; + ctx->pkey.key_type = BR_KEYTYPE_RSA; + ctx->pkey.key.rsa = *pk; + ctx->usages = usages; +} + +/* see bearssl_x509.h */ +void +br_x509_knownkey_init_ec(br_x509_knownkey_context *ctx, + const br_ec_public_key *pk, unsigned usages) +{ + ctx->vtable = &br_x509_knownkey_vtable; + ctx->pkey.key_type = BR_KEYTYPE_EC; + ctx->pkey.key.ec = *pk; + ctx->usages = usages; +} + +static void +kk_start_chain(const br_x509_class **ctx, const char *server_name) +{ + (void)ctx; + (void)server_name; +} + +static void +kk_start_cert(const br_x509_class **ctx, uint32_t length) +{ + (void)ctx; + (void)length; +} + +static void +kk_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) +{ + (void)ctx; + (void)buf; + (void)len; +} + +static void +kk_end_cert(const br_x509_class **ctx) +{ + (void)ctx; +} + +static unsigned +kk_end_chain(const br_x509_class **ctx) +{ + (void)ctx; + return 0; +} + +static const br_x509_pkey * +kk_get_pkey(const br_x509_class *const *ctx, unsigned *usages) +{ + const br_x509_knownkey_context *xc; + + xc = (const br_x509_knownkey_context *)ctx; + if (usages != NULL) { + *usages = xc->usages; + } + return &xc->pkey; +} + +/* see bearssl_x509.h */ +const br_x509_class br_x509_knownkey_vtable = { + sizeof(br_x509_knownkey_context), + kk_start_chain, + kk_start_cert, + kk_append, + kk_end_cert, + kk_end_chain, + kk_get_pkey +}; + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/x509_minimal_full.c b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/x509_minimal_full.c new file mode 100644 index 000000000000..9ca15d263ef3 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/bssl/x509_minimal_full.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016 Thomas Pornin + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "../ESP_SSLClient_FS.h" +#if defined(USE_LIB_SSL_ENGINE) + +#include "inner.h" + +/* see bearssl_x509.h */ +void +br_x509_minimal_init_full(br_x509_minimal_context *xc, + const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) +{ + /* + * All hash functions are activated. + * Note: the X.509 validation engine will nonetheless refuse to + * validate signatures that use MD5 as hash function. + */ + static const br_hash_class *hashes[] = { + &br_md5_vtable, + &br_sha1_vtable, + &br_sha224_vtable, + &br_sha256_vtable, + &br_sha384_vtable, + &br_sha512_vtable + }; + + int id; + + br_x509_minimal_init(xc, &br_sha256_vtable, + trust_anchors, trust_anchors_num); + br_x509_minimal_set_rsa(xc, &br_rsa_i31_pkcs1_vrfy); + br_x509_minimal_set_ecdsa(xc, + &br_ec_prime_i31, &br_ecdsa_i31_vrfy_asn1); + for (id = br_md5_ID; id <= br_sha512_ID; id ++) { + const br_hash_class *hc; + + hc = hashes[id - 1]; + br_x509_minimal_set_hash(xc, id, hc); + } +} + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_CertStore.cpp b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_CertStore.cpp new file mode 100644 index 000000000000..f4f06eac5584 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_CertStore.cpp @@ -0,0 +1,282 @@ +/* + CertStoreBearSSL.cpp - Library for Arduino ESP8266 + Copyright (c) 2018 Earle F. Philhower, III + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef BSSL_CERTSTORE_CPP +#define BSSL_CERTSTORE_CPP + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wvla" + +#include +#include "../ESP_SSLClient_FS.h" +#include "../ESP_SSLClient_Const.h" +#if defined(USE_LIB_SSL_ENGINE) + +#include "BSSL_CertStore.h" + +#if defined(ESP_SSL_FS_SUPPORTED) + +#include + +#if defined(DEBUG_ESP_SSL) && defined(DEBUG_ESP_PORT) +#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR("BSSL:" fmt), ##__VA_ARGS__) +#else +#define DEBUG_BSSL(...) +#endif + +namespace bssl +{ + + extern "C" + { + // Callback for the x509 decoder + static void dn_append(void *ctx, const void *buf, size_t len) + { + br_sha256_context *sha1 = (br_sha256_context *)ctx; + br_sha256_update(sha1, buf, len); + } + } + + CertStore::~CertStore() + { + free(_indexName); + free(_dataName); + } + + CertStore::CertInfo CertStore::_preprocessCert(uint32_t length, uint32_t offset, const void *raw) + { + CertStore::CertInfo ci; + + // Clear the CertInfo + memset(&ci, 0, sizeof(ci)); + + // Process it using SHA256, same as the hashed_dn + br_x509_decoder_context_libmail *ctx = new (std::nothrow) br_x509_decoder_context_libmail; + br_sha256_context *sha256 = new (std::nothrow) br_sha256_context; + if (!ctx || !sha256) + { + if (ctx) + delete ctx; + if (sha256) + delete sha256; + DEBUG_BSSL("CertStore::_preprocessCert: OOM\n"); + return ci; + } + + br_sha256_init(sha256); + br_x509_decoder_init_libmail(ctx, dn_append, sha256); + br_x509_decoder_push_libmail(ctx, (const void *)raw, length); + + // Copy result to structure + br_sha256_out(sha256, &ci.sha256); + ci.length = length; + ci.offset = offset; + + // Clean up allocated memory + delete sha256; + delete ctx; + + // Return result + return ci; + } + + // The certs.ar file is a UNIX ar format file, concatenating all the + // individual certificates into a single blob in a space-efficient way. + int CertStore::initCertStore(FS &fs, const char *indexFileName, const char *dataFileName) + { + int count = 0; + uint32_t offset = 0; + + _fs = &fs; + + // In case initCertStore called multiple times, don't leak old filenames + free(_indexName); + free(_dataName); + + // No strdup_P, so manually do it + _indexName = (char *)malloc(strlen_P(indexFileName) + 1); + _dataName = (char *)malloc(strlen_P(dataFileName) + 1); + if (!_indexName || !_dataName) + { + free(_indexName); + free(_dataName); + return 0; + } + memcpy_P(_indexName, indexFileName, strlen_P(indexFileName) + 1); + memcpy_P(_dataName, dataFileName, strlen_P(dataFileName) + 1); + + File index = _fs->open(_indexName, FILE_WRITE); + if (!index) + { + return 0; + } + + File data = _fs->open(_dataName, FILE_READ); + if (!data) + { + index.close(); + return 0; + } + + uint8_t magic[8]; + if (data.read(magic, sizeof(magic)) != sizeof(magic) || + memcmp(magic, "!\n", sizeof(magic))) + { + data.close(); + index.close(); + return 0; + } + offset += sizeof(magic); + + while (true) + { + uint8_t fileHeader[60]; + // 0..15 = filename in ASCII + // 48...57 = length in decimal ASCII + int32_t length; + if (data.read(fileHeader, sizeof(fileHeader)) != sizeof(fileHeader)) + { + break; + } + offset += sizeof(fileHeader); + fileHeader[58] = 0; + if (1 != sscanf((char *)(fileHeader + 48), "%d", (int *)(&length)) || !length) + { + break; + } + + void *raw = malloc(length); + if (!raw) + { + break; + } + if ((int)data.read((uint8_t *)raw, length) != length) + { + free(raw); + break; + } + + // If the filename starts with "//" then this is a rename file, skip it + if (fileHeader[0] != '/' || fileHeader[1] != '/') + { + CertStore::CertInfo ci = _preprocessCert(length, offset, raw); + if (index.write((uint8_t *)&ci, sizeof(ci)) != (ssize_t)sizeof(ci)) + { + free(raw); + break; + } + count++; + } + + offset += length; + free(raw); + if (offset & 1) + { + uint8_t x; + data.read(&x, 1); + offset++; + } + } + data.close(); + index.close(); + return count; + } + + void CertStore::installCertStore(br_x509_minimal_context *ctx) + { + br_x509_minimal_set_dynamic(ctx, (void *)this, findHashedTA, freeHashedTA); + } + + const br_x509_trust_anchor *CertStore::findHashedTA(void *ctx, void *hashed_dn, size_t len) + { + CertStore *cs = static_cast(ctx); + CertStore::CertInfo ci; + + if (!cs || len != sizeof(ci.sha256) || !cs->_indexName || !cs->_dataName || !cs->_fs) + { + return nullptr; + } + + File index = cs->_fs->open(cs->_indexName, FILE_READ); + if (!index) + { + return nullptr; + } + + while (index.read((uint8_t *)&ci, sizeof(ci)) == sizeof(ci)) + { + if (!memcmp(ci.sha256, hashed_dn, sizeof(ci.sha256))) + { + index.close(); + uint8_t *der = (uint8_t *)malloc(ci.length); + if (!der) + { + return nullptr; + } + File data = cs->_fs->open(cs->_dataName, FILE_READ); + if (!data) + { + free(der); + return nullptr; + } + if (!data.seek(ci.offset, SeekSet)) + { + data.close(); + free(der); + return nullptr; + } + if ((int)data.read(der, ci.length) != (int)ci.length) + { + free(der); + return nullptr; + } + data.close(); + cs->_x509 = new (std::nothrow) X509List(der, ci.length); + free(der); + if (!cs->_x509) + { + DEBUG_BSSL("CertStore::findHashedTA: OOM\n"); + return nullptr; + } + + br_x509_trust_anchor *ta = (br_x509_trust_anchor *)cs->_x509->getTrustAnchors(); + memcpy(ta->dn.data, ci.sha256, sizeof(ci.sha256)); + ta->dn.len = sizeof(ci.sha256); + + return ta; + } + } + index.close(); + return nullptr; + } + + void CertStore::freeHashedTA(void *ctx, const br_x509_trust_anchor *ta) + { + CertStore *cs = static_cast(ctx); + (void)ta; // Unused + delete cs->_x509; + cs->_x509 = nullptr; + } + +} + +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_CertStoreBearSSL.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_CertStore.h similarity index 62% rename from lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_CertStoreBearSSL.h rename to lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_CertStore.h index fd9f8c537508..42b9633406e8 100644 --- a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_CertStoreBearSSL.h +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_CertStore.h @@ -1,5 +1,5 @@ /* - Copy of CertStoreBearSSL.h - Library for Arduino ESP8266 + CertStoreBearSSL.h - Library for Arduino ESP8266 Copyright (c) 2018 Earle F. Philhower, III This library is free software; you can redistribute it and/or @@ -16,27 +16,54 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef BSSL_CERTSTORE_H +#define BSSL_CERTSTORE_H -#ifndef ESP_Mail_CertStoreBearSSL_H -#define ESP_Mail_CertStoreBearSSL_H - -#ifdef ESP8266 +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wvla" #include -#include "ESP_Mail_BearSSLHelpers.h" -#include +#include "../ESP_SSLClient_FS.h" +#include "../ESP_SSLClient_Const.h" +#if defined(USE_LIB_SSL_ENGINE) + + +#if defined __has_include +#if __has_include() && defined(ESP_SSLCLIENT_USE_FILESYSTEM) #include +#define ESP_SSL_FS_SUPPORTED +#endif +#endif + +#if defined(ESP_SSL_FS_SUPPORTED) + + +#include "../bssl/bearssl.h" +#include "BSSL_Helper.h" + +using namespace bssl; // Base class for the certificate stores, which allow use // of a large set of certificates stored on FS or SD card to // be dynamically used when validating a X509 certificate -namespace ESP_Mail { +namespace bssl +{ + + class CertStoreBase + { + public: + virtual ~CertStoreBase() {} + + // Installs the cert store into the X509 decoder (normally via static function callbacks) + virtual void installCertStore(br_x509_minimal_context *ctx) = 0; + }; -class ESP_Mail_CertStore { + class CertStore : public CertStoreBase + { public: - ESP_Mail_CertStore() { }; - ~ESP_Mail_CertStore(); + CertStore(){}; + ~CertStore(); // Set the file interface instances, do preprocessing int initCertStore(FS &fs, const char *indexFileName, const char *dataFileName); @@ -48,25 +75,27 @@ class ESP_Mail_CertStore { FS *_fs = nullptr; char *_indexName = nullptr; char *_dataName = nullptr; - ESP_Mail_X509List *_x509 = nullptr; + X509List *_x509 = nullptr; // These need to be static as they are callbacks from BearSSL C code static const br_x509_trust_anchor *findHashedTA(void *ctx, void *hashed_dn, size_t len); static void freeHashedTA(void *ctx, const br_x509_trust_anchor *ta); // The binary format of the index file - class ESP_Mail_CertInfo { + class CertInfo + { public: uint8_t sha256[32]; uint32_t offset; uint32_t length; }; - static ESP_Mail_CertInfo _preprocessCert(uint32_t length, uint32_t offset, const void *raw); + static CertInfo _preprocessCert(uint32_t length, uint32_t offset, const void *raw); + }; }; -}; +#endif -#endif /* ESP8266 */ +#endif -#endif /* ESP_Mail_CertStoreBearSSL_H */ +#endif diff --git a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_BearSSLHelpers.cpp b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.cpp similarity index 82% rename from lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_BearSSLHelpers.cpp rename to lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.cpp index 9c44c94ce54c..3d4d62684bdf 100644 --- a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_BearSSLHelpers.cpp +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.cpp @@ -1,1108 +1,1053 @@ -/* - Copy of BearSSLHelpers.cpp - - WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries - - Mostly compatible with Arduino WiFi shield library and standard - WiFiClient/ServerSecure (except for certificate handling). - - Copyright (c) 2018 Earle F. Philhower, III - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#ifndef ESP_Mail_BearSSLHelpers_CPP -#define ESP_Mail_BearSSLHelpers_CPP - -#ifdef ESP8266 - -#include "ESP_Mail_BearSSLHelpers.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef ARDUINO_SIGNING -#define ARDUINO_SIGNING 0 -#endif - -namespace ESP_Mail_brssl -{ - // Code here is pulled from brssl sources, with the copyright and license - // shown below. I've rewritten things using C++ semantics and removed - // custom VEC_* calls (std::vector to the rescue) and adjusted things to - // allow for long-running operation (i.e. some memory issues when DERs - // passed into the decoders). Bugs are most likely my fault. - - // Original (c) message follows: - /* - Copyright (c) 2016 Thomas Pornin - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - - class private_key - { - public: - int key_type; /* BR_KEYTYPE_RSA or BR_KEYTYPE_EC */ - union - { - br_rsa_private_key rsa; - br_ec_private_key ec; - } key; - }; - - class public_key - { - public: - int key_type; /* BR_KEYTYPE_RSA or BR_KEYTYPE_EC */ - union - { - br_rsa_public_key rsa; - br_ec_public_key ec; - } key; - }; - - class pem_object - { - public: - char *name; - unsigned char *data; - size_t data_len; - }; - - // Forward definitions - void free_ta_contents(br_x509_trust_anchor *ta); - void free_public_key(public_key *pk); - void free_private_key(private_key *sk); - bool looks_like_DER(const unsigned char *buf, size_t len); - pem_object *decode_pem(const void *src, size_t len, size_t *num); - void free_pem_object_contents(pem_object *po); - - // Used as callback multiple places to append a string to a vector - static void byte_vector_append(void *ctx, const void *buff, size_t len) - { - std::vector *vec = static_cast *>(ctx); - vec->reserve(vec->size() + len); // Allocate extra space all at once - for (size_t i = 0; i < len; i++) - { - vec->push_back(((uint8_t *)buff)[i]); - } - } - - static bool certificate_to_trust_anchor_inner(br_x509_trust_anchor *ta, const br_x509_certificate *xc) - { - std::unique_ptr dc(new br_x509_decoder_context); // auto-delete on exit - std::vector vdn; - br_x509_pkey *pk; - - // Clear everything in the Trust Anchor - memset(ta, 0, sizeof(*ta)); - - br_x509_decoder_init(dc.get(), byte_vector_append, (void *)&vdn, 0, 0); - br_x509_decoder_push(dc.get(), xc->data, xc->data_len); - pk = br_x509_decoder_get_pkey(dc.get()); - if (pk == nullptr) - { - return false; // No key present, something broken in the cert! - } - - // Copy the raw certificate data - ta->dn.data = (uint8_t *)malloc(vdn.size()); - if (!ta->dn.data) - { - return false; // OOM, but nothing yet allocated - } - memcpy(ta->dn.data, &vdn[0], vdn.size()); - ta->dn.len = vdn.size(); - ta->flags = 0; - if (br_x509_decoder_isCA(dc.get())) - { - ta->flags |= BR_X509_TA_CA; - } - - // Extract the public key - switch (pk->key_type) - { - case BR_KEYTYPE_RSA: - ta->pkey.key_type = BR_KEYTYPE_RSA; - ta->pkey.key.rsa.n = (uint8_t *)malloc(pk->key.rsa.nlen); - ta->pkey.key.rsa.e = (uint8_t *)malloc(pk->key.rsa.elen); - if ((ta->pkey.key.rsa.n == nullptr) || (ta->pkey.key.rsa.e == nullptr)) - { - free_ta_contents(ta); // OOM, so clean up - return false; - } - memcpy(ta->pkey.key.rsa.n, pk->key.rsa.n, pk->key.rsa.nlen); - ta->pkey.key.rsa.nlen = pk->key.rsa.nlen; - memcpy(ta->pkey.key.rsa.e, pk->key.rsa.e, pk->key.rsa.elen); - ta->pkey.key.rsa.elen = pk->key.rsa.elen; - return true; - case BR_KEYTYPE_EC: - ta->pkey.key_type = BR_KEYTYPE_EC; - ta->pkey.key.ec.curve = pk->key.ec.curve; - ta->pkey.key.ec.q = (uint8_t *)malloc(pk->key.ec.qlen); - if (ta->pkey.key.ec.q == nullptr) - { - free_ta_contents(ta); // OOM, so clean up - return false; - } - memcpy(ta->pkey.key.ec.q, pk->key.ec.q, pk->key.ec.qlen); - ta->pkey.key.ec.qlen = pk->key.ec.qlen; - return true; - default: - free_ta_contents(ta); // Unknown key type - return false; - } - - // Should never get here, if so there was an unknown error - return false; - } - - br_x509_trust_anchor *certificate_to_trust_anchor(const br_x509_certificate *xc) - { - br_x509_trust_anchor *ta = (br_x509_trust_anchor *)malloc(sizeof(br_x509_trust_anchor)); - if (!ta) - { - return nullptr; - } - - if (!certificate_to_trust_anchor_inner(ta, xc)) - { - free(ta); - return nullptr; - } - return ta; - } - - void free_ta_contents(br_x509_trust_anchor *ta) - { - if (ta) - { - free(ta->dn.data); - if (ta->pkey.key_type == BR_KEYTYPE_RSA) - { - free(ta->pkey.key.rsa.n); - free(ta->pkey.key.rsa.e); - } - else if (ta->pkey.key_type == BR_KEYTYPE_EC) - { - free(ta->pkey.key.ec.q); - } - memset(ta, 0, sizeof(*ta)); - } - } - - // Checks if a bitstream looks like a valid DER(binary) encoding. - // Basically tries to verify the length of all included segments - // matches the length of the input buffer. Does not actually - // validate any contents. - bool looks_like_DER(const unsigned char *buff, size_t len) - { - if (len < 2) - { - return false; - } - if (pgm_read_byte(buff++) != 0x30) - { - return false; - } - int fb = pgm_read_byte(buff++); - len -= 2; - if (fb < 0x80) - { - return (size_t)fb == len; - } - else if (fb == 0x80) - { - return false; - } - else - { - fb -= 0x80; - if (len < (size_t)fb + 2) - { - return false; - } - len -= (size_t)fb; - size_t dlen = 0; - while (fb-- > 0) - { - if (dlen > (len >> 8)) - { - return false; - } - dlen = (dlen << 8) + (size_t)pgm_read_byte(buff++); - } - return dlen == len; - } - } - - void free_pem_object_contents(pem_object *po) - { - if (po) - { - free(po->name); - free(po->data); - po->name = nullptr; - po->data = nullptr; - } - } - - // Converts a PEM (~=base64) source into a set of DER-encoded binary blobs. - // Each blob is named by the ---- BEGIN xxx ---- field, and multiple - // blobs may be returned. - pem_object *decode_pem(const void *src, size_t len, size_t *num) - { - std::vector pem_list; - std::unique_ptr pc(new br_pem_decoder_context); // auto-delete on exit - if (!pc.get()) - { - return nullptr; - } - pem_object po, *pos; - const unsigned char *buff; - std::vector bv; - - *num = 0; - br_pem_decoder_init(pc.get()); - buff = (const unsigned char *)src; - po.name = nullptr; - po.data = nullptr; - po.data_len = 0; - bool inobj = false; - bool extra_nl = true; - - while (len > 0) - { - size_t tlen; - - tlen = br_pem_decoder_push(pc.get(), buff, len); - buff += tlen; - len -= tlen; - switch (br_pem_decoder_event(pc.get())) - { - case BR_PEM_BEGIN_OBJ: - po.name = strdup(br_pem_decoder_name(pc.get())); - br_pem_decoder_setdest(pc.get(), byte_vector_append, &bv); - inobj = true; - break; - - case BR_PEM_END_OBJ: - if (inobj) - { - // Stick data into the vector - po.data = (uint8_t *)malloc(bv.size()); - if (po.data) - { - memcpy(po.data, &bv[0], bv.size()); - po.data_len = bv.size(); - pem_list.push_back(po); - } - // Clean up state for next blob processing - bv.clear(); - po.name = nullptr; - po.data = nullptr; - po.data_len = 0; - inobj = false; - } - break; - - case BR_PEM_ERROR: - free(po.name); - for (size_t i = 0; i < pem_list.size(); i++) - { - free_pem_object_contents(&pem_list[i]); - } - return nullptr; - - default: - // Do nothing here, the parser is still working on things - break; - } - - if (len == 0 && extra_nl) - { - extra_nl = false; - buff = (const unsigned char *)"\n"; - len = 1; - } - } - - if (inobj) - { - free(po.name); - for (size_t i = 0; i < pem_list.size(); i++) - { - free_pem_object_contents(&pem_list[i]); - } - return nullptr; - } - - pos = (pem_object *)malloc((1 + pem_list.size()) * sizeof(*pos)); - if (pos) - { - *num = pem_list.size(); - pem_list.push_back(po); // Null-terminate list - memcpy(pos, &pem_list[0], pem_list.size() * sizeof(*pos)); - } - return pos; - } - - // Parse out DER or PEM encoded certificates from a binary buffer, - // potentially stored in PROGMEM. - br_x509_certificate *read_certificates(const char *buff, size_t len, size_t *num) - { - std::vector cert_list; - pem_object *pos; - size_t u, num_pos; - br_x509_certificate *xcs; - br_x509_certificate dummy; - - *num = 0; - - if (looks_like_DER((const unsigned char *)buff, len)) - { - xcs = (br_x509_certificate *)malloc(2 * sizeof(*xcs)); - if (!xcs) - { - return nullptr; - } - xcs[0].data = (uint8_t *)malloc(len); - if (!xcs[0].data) - { - free(xcs); - return nullptr; - } - memcpy_P(xcs[0].data, buff, len); - xcs[0].data_len = len; - xcs[1].data = nullptr; - xcs[1].data_len = 0; - *num = 1; - return xcs; - } - - pos = decode_pem(buff, len, &num_pos); - if (!pos) - { - return nullptr; - } - for (u = 0; u < num_pos; u++) - { - if (!strcmp_P(pos[u].name, PSTR("CERTIFICATE")) || !strcmp_P(pos[u].name, PSTR("X509 CERTIFICATE"))) - { - br_x509_certificate xc; - xc.data = pos[u].data; - xc.data_len = pos[u].data_len; - pos[u].data = nullptr; // Don't free the data we moved to the xc vector! - cert_list.push_back(xc); - } - } - for (u = 0; u < num_pos; u++) - { - free_pem_object_contents(&pos[u]); - } - free(pos); - - if (cert_list.size() == 0) - { - return nullptr; - } - *num = cert_list.size(); - dummy.data = nullptr; - dummy.data_len = 0; - cert_list.push_back(dummy); - xcs = (br_x509_certificate *)malloc(cert_list.size() * sizeof(*xcs)); - if (!xcs) - { - for (size_t i = 0; i < cert_list.size(); i++) - { - free(cert_list[i].data); // Clean up any captured data blobs - } - return nullptr; - } - memcpy(xcs, &cert_list[0], cert_list.size() * sizeof(br_x509_certificate)); - // XCS now has [].data pointing to the previously allocated blobs, so don't - // want to free anything in cert_list[]. - return xcs; - } - - void free_certificates(br_x509_certificate *certs, size_t num) - { - if (certs) - { - for (size_t u = 0; u < num; u++) - { - free(certs[u].data); - } - free(certs); - } - } - - static public_key *decode_public_key(const unsigned char *buff, size_t len) - { - std::unique_ptr dc(new br_pkey_decoder_context); // auto-delete on exit - if (!dc.get()) - { - return nullptr; - } - - public_key *pk = nullptr; - - br_pkey_decoder_init(dc.get()); - br_pkey_decoder_push(dc.get(), buff, len); - int err = br_pkey_decoder_last_error(dc.get()); - if (err != 0) - { - return nullptr; - } - - const br_rsa_public_key *rk = nullptr; - const br_ec_public_key *ek = nullptr; - switch (br_pkey_decoder_key_type(dc.get())) - { - case BR_KEYTYPE_RSA: - rk = br_pkey_decoder_get_rsa(dc.get()); - pk = (public_key *)malloc(sizeof *pk); - if (!pk) - { - return nullptr; - } - pk->key_type = BR_KEYTYPE_RSA; - pk->key.rsa.n = (uint8_t *)malloc(rk->nlen); - pk->key.rsa.e = (uint8_t *)malloc(rk->elen); - if (!pk->key.rsa.n || !pk->key.rsa.e) - { - free(pk->key.rsa.n); - free(pk->key.rsa.e); - free(pk); - return nullptr; - } - memcpy(pk->key.rsa.n, rk->n, rk->nlen); - pk->key.rsa.nlen = rk->nlen; - memcpy(pk->key.rsa.e, rk->e, rk->elen); - pk->key.rsa.elen = rk->elen; - return pk; - - case BR_KEYTYPE_EC: - ek = br_pkey_decoder_get_ec(dc.get()); - pk = (public_key *)malloc(sizeof *pk); - if (!pk) - { - return nullptr; - } - pk->key_type = BR_KEYTYPE_EC; - pk->key.ec.q = (uint8_t *)malloc(ek->qlen); - if (!pk->key.ec.q) - { - free(pk); - return nullptr; - } - memcpy(pk->key.ec.q, ek->q, ek->qlen); - pk->key.ec.qlen = ek->qlen; - return pk; - - default: - return nullptr; - } - } - - void free_public_key(public_key *pk) - { - if (pk) - { - if (pk->key_type == BR_KEYTYPE_RSA) - { - free(pk->key.rsa.n); - free(pk->key.rsa.e); - } - else if (pk->key_type == BR_KEYTYPE_EC) - { - free(pk->key.ec.q); - } - free(pk); - } - } - - static private_key *decode_private_key(const unsigned char *buff, size_t len) - { - std::unique_ptr dc(new br_skey_decoder_context); // auto-delete on exit - if (!dc.get()) - { - return nullptr; - } - - private_key *sk = nullptr; - - br_skey_decoder_init(dc.get()); - br_skey_decoder_push(dc.get(), buff, len); - int err = br_skey_decoder_last_error(dc.get()); - if (err != 0) - { - return nullptr; - } - - const br_rsa_private_key *rk = nullptr; - const br_ec_private_key *ek = nullptr; - switch (br_skey_decoder_key_type(dc.get())) - { - case BR_KEYTYPE_RSA: - rk = br_skey_decoder_get_rsa(dc.get()); - sk = (private_key *)malloc(sizeof *sk); - if (!sk) - { - return nullptr; - } - sk->key_type = BR_KEYTYPE_RSA; - sk->key.rsa.p = (uint8_t *)malloc(rk->plen); - sk->key.rsa.q = (uint8_t *)malloc(rk->qlen); - sk->key.rsa.dp = (uint8_t *)malloc(rk->dplen); - sk->key.rsa.dq = (uint8_t *)malloc(rk->dqlen); - sk->key.rsa.iq = (uint8_t *)malloc(rk->iqlen); - if (!sk->key.rsa.p || !sk->key.rsa.q || !sk->key.rsa.dp || !sk->key.rsa.dq || !sk->key.rsa.iq) - { - free_private_key(sk); - return nullptr; - } - sk->key.rsa.n_bitlen = rk->n_bitlen; - memcpy(sk->key.rsa.p, rk->p, rk->plen); - sk->key.rsa.plen = rk->plen; - memcpy(sk->key.rsa.q, rk->q, rk->qlen); - sk->key.rsa.qlen = rk->qlen; - memcpy(sk->key.rsa.dp, rk->dp, rk->dplen); - sk->key.rsa.dplen = rk->dplen; - memcpy(sk->key.rsa.dq, rk->dq, rk->dqlen); - sk->key.rsa.dqlen = rk->dqlen; - memcpy(sk->key.rsa.iq, rk->iq, rk->iqlen); - sk->key.rsa.iqlen = rk->iqlen; - return sk; - - case BR_KEYTYPE_EC: - ek = br_skey_decoder_get_ec(dc.get()); - sk = (private_key *)malloc(sizeof *sk); - sk->key_type = BR_KEYTYPE_EC; - sk->key.ec.curve = ek->curve; - sk->key.ec.x = (uint8_t *)malloc(ek->xlen); - if (!sk->key.ec.x) - { - free_private_key(sk); - return nullptr; - } - memcpy(sk->key.ec.x, ek->x, ek->xlen); - sk->key.ec.xlen = ek->xlen; - return sk; - - default: - return nullptr; - } - } - - void free_private_key(private_key *sk) - { - if (sk) - { - switch (sk->key_type) - { - case BR_KEYTYPE_RSA: - free(sk->key.rsa.p); - free(sk->key.rsa.q); - free(sk->key.rsa.dp); - free(sk->key.rsa.dq); - free(sk->key.rsa.iq); - break; - case BR_KEYTYPE_EC: - free(sk->key.ec.x); - break; - default: - // Could be an uninitted key, no sub elements to free - break; - } - free(sk); - } - } - - void free_pem_object(pem_object *pos) - { - if (pos != nullptr) - { - for (size_t u = 0; pos[u].name; u++) - { - free_pem_object_contents(&pos[u]); - } - free(pos); - } - } - - private_key *read_private_key(const char *buff, size_t len) - { - private_key *sk = nullptr; - pem_object *pos = nullptr; - - if (looks_like_DER((const unsigned char *)buff, len)) - { - sk = decode_private_key((const unsigned char *)buff, len); - return sk; - } - - size_t num; - pos = decode_pem(buff, len, &num); - if (pos == nullptr) - { - return nullptr; // PEM decode error - } - for (size_t u = 0; pos[u].name; u++) - { - const char *name = pos[u].name; - if (!strcmp_P(name, PSTR("RSA PRIVATE KEY")) || !strcmp_P(name, PSTR("EC PRIVATE KEY")) || !strcmp_P(name, PSTR("PRIVATE KEY"))) - { - sk = decode_private_key(pos[u].data, pos[u].data_len); - free_pem_object(pos); - return sk; - } - } - // If we hit here, no match - free_pem_object(pos); - return nullptr; - } - - public_key *read_public_key(const char *buff, size_t len) - { - public_key *pk = nullptr; - pem_object *pos = nullptr; - - if (looks_like_DER((const unsigned char *)buff, len)) - { - pk = decode_public_key((const unsigned char *)buff, len); - return pk; - } - size_t num; - pos = decode_pem(buff, len, &num); - if (pos == nullptr) - { - return nullptr; // PEM decode error - } - for (size_t u = 0; pos[u].name; u++) - { - const char *name = pos[u].name; - if (!strcmp_P(name, PSTR("RSA PUBLIC KEY")) || !strcmp_P(name, PSTR("EC PUBLIC KEY")) || !strcmp_P(name, PSTR("PUBLIC KEY"))) - { - pk = decode_public_key(pos[u].data, pos[u].data_len); - free_pem_object(pos); - return pk; - } - } - - // We hit here == no key found - free_pem_object(pos); - return pk; - } - -}; // namespace ESP_Mail_brssl - -namespace ESP_Mail -{ - - // ----- Public Key ----- - - PublicKey::PublicKey() - { - _key = nullptr; - } - - PublicKey::PublicKey(const char *pemKey) - { - _key = nullptr; - parse(pemKey); - } - - PublicKey::PublicKey(const uint8_t *derKey, size_t derLen) - { - _key = nullptr; - parse(derKey, derLen); - } - - PublicKey::~PublicKey() - { - if (_key) - { - ESP_Mail_brssl::free_public_key(_key); - } - } - - bool PublicKey::parse(const char *pemKey) - { - return parse((const uint8_t *)pemKey, strlen_P(pemKey)); - } - - bool PublicKey::parse(const uint8_t *derKey, size_t derLen) - { - if (_key) - { - ESP_Mail_brssl::free_public_key(_key); - _key = nullptr; - } - _key = ESP_Mail_brssl::read_public_key((const char *)derKey, derLen); - return _key ? true : false; - } - - bool PublicKey::isRSA() const - { - if (!_key || _key->key_type != BR_KEYTYPE_RSA) - { - return false; - } - return true; - } - - bool PublicKey::isEC() const - { - if (!_key || _key->key_type != BR_KEYTYPE_EC) - { - return false; - } - return true; - } - - const br_rsa_public_key *PublicKey::getRSA() const - { - if (!_key || _key->key_type != BR_KEYTYPE_RSA) - { - return nullptr; - } - return &_key->key.rsa; - } - - const br_ec_public_key *PublicKey::getEC() const - { - if (!_key || _key->key_type != BR_KEYTYPE_EC) - { - return nullptr; - } - return &_key->key.ec; - } - - // ----- Private Key ----- - - PrivateKey::PrivateKey() - { - _key = nullptr; - } - - PrivateKey::PrivateKey(const char *pemKey) - { - _key = nullptr; - parse(pemKey); - } - - PrivateKey::PrivateKey(const uint8_t *derKey, size_t derLen) - { - _key = nullptr; - parse(derKey, derLen); - } - - PrivateKey::~PrivateKey() - { - if (_key) - { - ESP_Mail_brssl::free_private_key(_key); - } - } - - bool PrivateKey::parse(const char *pemKey) - { - return parse((const uint8_t *)pemKey, strlen_P(pemKey)); - } - - bool PrivateKey::parse(const uint8_t *derKey, size_t derLen) - { - if (_key) - { - ESP_Mail_brssl::free_private_key(_key); - _key = nullptr; - } - _key = ESP_Mail_brssl::read_private_key((const char *)derKey, derLen); - return _key ? true : false; - } - - bool PrivateKey::isRSA() const - { - if (!_key || _key->key_type != BR_KEYTYPE_RSA) - { - return false; - } - return true; - } - - bool PrivateKey::isEC() const - { - if (!_key || _key->key_type != BR_KEYTYPE_EC) - { - return false; - } - return true; - } - - const br_rsa_private_key *PrivateKey::getRSA() const - { - if (!_key || _key->key_type != BR_KEYTYPE_RSA) - { - return nullptr; - } - return &_key->key.rsa; - } - - const br_ec_private_key *PrivateKey::getEC() const - { - if (!_key || _key->key_type != BR_KEYTYPE_EC) - { - return nullptr; - } - return &_key->key.ec; - } - - // ----- Certificate Lists ----- - - ESP_Mail_X509List::ESP_Mail_X509List() - { - _count = 0; - _cert = nullptr; - _ta = nullptr; - } - - ESP_Mail_X509List::ESP_Mail_X509List(const char *pemCert) - { - _count = 0; - _cert = nullptr; - _ta = nullptr; - append(pemCert); - } - - ESP_Mail_X509List::ESP_Mail_X509List(const uint8_t *derCert, size_t derLen) - { - _count = 0; - _cert = nullptr; - _ta = nullptr; - append(derCert, derLen); - } - - ESP_Mail_X509List::~ESP_Mail_X509List() - { - ESP_Mail_brssl::free_certificates(_cert, _count); // also frees cert - for (size_t i = 0; i < _count; i++) - { - ESP_Mail_brssl::free_ta_contents(&_ta[i]); - } - free(_ta); - } - - bool ESP_Mail_X509List::append(const char *pemCert) - { - return append((const uint8_t *)pemCert, strlen_P(pemCert)); - } - - bool ESP_Mail_X509List::append(const uint8_t *derCert, size_t derLen) - { - size_t numCerts; - br_x509_certificate *newCerts = ESP_Mail_brssl::read_certificates((const char *)derCert, derLen, &numCerts); - if (!newCerts) - { - return false; - } - - // Add in the certificates - br_x509_certificate *saveCert = _cert; - _cert = (br_x509_certificate *)realloc(_cert, (numCerts + _count) * sizeof(br_x509_certificate)); - if (!_cert) - { - free(newCerts); - _cert = saveCert; - return false; - } - memcpy(&_cert[_count], newCerts, numCerts * sizeof(br_x509_certificate)); - free(newCerts); - - // Build TAs for each certificate - br_x509_trust_anchor *saveTa = _ta; - _ta = (br_x509_trust_anchor *)realloc(_ta, (numCerts + _count) * sizeof(br_x509_trust_anchor)); - if (!_ta) - { - _ta = saveTa; - return false; - } - for (size_t i = 0; i < numCerts; i++) - { - br_x509_trust_anchor *newTa = ESP_Mail_brssl::certificate_to_trust_anchor(&_cert[_count + i]); - if (newTa) - { - _ta[_count + i] = *newTa; - free(newTa); - } - else - { - return false; // OOM - } - } - _count += numCerts; - - return true; - } - - // SHA256 hash for updater - void HashSHA256::begin() - { - br_sha256_init(&_cc); - memset(_sha256, 0, sizeof(_sha256)); - } - - void HashSHA256::add(const void *data, uint32_t len) - { - br_sha256_update(&_cc, data, len); - } - - void HashSHA256::end() - { - br_sha256_out(&_cc, _sha256); - } - - int HashSHA256::len() - { - return sizeof(_sha256); - } - - const void *HashSHA256::hash() - { - return (const void *)_sha256; - } - - const unsigned char *HashSHA256::oid() - { - return BR_HASH_OID_SHA256; - } - - // SHA256 verifier - uint32_t SigningVerifier::length() - { - if (!_pubKey) - { - return 0; - } - else if (_pubKey->isRSA()) - { - return _pubKey->getRSA()->nlen; - } - else if (_pubKey->isEC()) - { - return _pubKey->getEC()->qlen; - } - else - { - return 0; - } - } - /* - -// We need to use the 2nd stack to do a verification, so do the thunk -// directly inside the class function for ease of use. -extern "C" bool SigningVerifier_verify(PublicKey *_pubKey, UpdaterHashClass *hash, const void *signature, uint32_t signatureLen) { - if (_pubKey->isRSA()) { - bool ret; - unsigned char vrf[hash->len()]; - br_rsa_pkcs1_vrfy vrfy = br_rsa_pkcs1_vrfy_get_default(); - ret = vrfy((const unsigned char *)signature, signatureLen, hash->oid(), sizeof(vrf), _pubKey->getRSA(), vrf); - if (!ret || memcmp(vrf, hash->hash(), sizeof(vrf)) ) { - return false; - } else { - return true; - } - } else { - br_ecdsa_vrfy vrfy = br_ecdsa_vrfy_raw_get_default(); - // The EC verifier actually does the compare, unlike the RSA one - return vrfy(br_ec_get_default(), hash->hash(), hash->len(), _pubKey->getEC(), (const unsigned char *)signature, signatureLen); - } -}; - - - -#if !CORE_MOCK -make_stack_thunk(SigningVerifier_verify); -extern "C" bool thunk_SigningVerifier_verify(PublicKey *_pubKey, UpdaterHashClass *hash, const void *signature, uint32_t signatureLen); -#endif - -bool SigningVerifier::verify(UpdaterHashClass *hash, const void *signature, uint32_t signatureLen) { - if (!_pubKey || !hash || !signature || signatureLen != length()) return false; -#if !CORE_MOCK - return thunk_SigningVerifier_verify(_pubKey, hash, signature, signatureLen); -#else - return SigningVerifier_verify(_pubKey, hash, signature, signatureLen); -#endif -} - - - -#if !CORE_MOCK - -// Second stack thunked helpers -make_stack_thunk(br_ssl_engine_recvapp_ack); -make_stack_thunk(br_ssl_engine_recvapp_buf); -make_stack_thunk(br_ssl_engine_recvrec_ack); -make_stack_thunk(br_ssl_engine_recvrec_buf); -make_stack_thunk(br_ssl_engine_sendapp_ack); -make_stack_thunk(br_ssl_engine_sendapp_buf); -make_stack_thunk(br_ssl_engine_sendrec_ack); -make_stack_thunk(br_ssl_engine_sendrec_buf); - -#endif -*/ - -}; // namespace ESP_Mail - -#if ARDUINO_SIGNING -namespace -{ - static ESP_Mail::PublicKey signingPubKey(signing_pubkey); - static ESP_Mail::HashSHA256 __signingHash; - static ESP_Mail::SigningVerifier __signingVerifier(&signingPubKey); -}; // namespace - -namespace esp8266 -{ - UpdaterHashClass &updaterSigningHash = __signingHash; - UpdaterVerifyClass &updaterSigningVerifier = __signingVerifier; -}; // namespace esp8266 -#endif - -#endif /* ESP8266 */ - -#endif /* ESP_Mail_BearSSLHelpers_CPP */ \ No newline at end of file +/* + WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries + - Mostly compatible with Arduino WiFi shield library and standard + WiFiClient/ServerSecure (except for certificate handling). + + Copyright (c) 2018 Earle F. Philhower, III + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef BSSL_HELPER_CPP +#define BSSL_HELPER_CPP + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wvla" + +#include +#include "../ESP_SSLClient_FS.h" +#include "../ESP_SSLClient_Const.h" +#if defined(USE_LIB_SSL_ENGINE) + +#include "BSSL_Helper.h" +#include +#include +#include "../bssl/bearssl.h" +#include +#include +#if defined __has_include +#if __has_include() +#include +#endif +#endif + +namespace key_bssl +{ + // Code here is pulled from brssl sources, with the copyright and license + // shown below. I've rewritten things using C++ semantics and removed + // custom VEC_* calls (std::vector to the rescue) and adjusted things to + // allow for long-running operation (i.e. some memory issues when DERs + // passed into the decoders). Bugs are most likely my fault. + + // Original (c) message follows: + /* + Copyright (c) 2016 Thomas Pornin + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + + class private_key + { + public: + int key_type; /* BR_KEYTYPE_RSA or BR_KEYTYPE_EC */ + union + { + br_rsa_private_key rsa; + br_ec_private_key ec; + } key; + }; + + class public_key + { + public: + int key_type; /* BR_KEYTYPE_RSA or BR_KEYTYPE_EC */ + union + { + br_rsa_public_key rsa; + br_ec_public_key ec; + } key; + }; + + class pem_object + { + public: + char *name; + unsigned char *data; + size_t data_len; + }; + + // Forward definitions + void free_ta_contents(br_x509_trust_anchor *ta); + void free_public_key(public_key *pk); + void free_private_key(private_key *sk); + bool looks_like_DER(const unsigned char *buf, size_t len); + pem_object *decode_pem(const void *src, size_t len, size_t *num); + void free_pem_object_contents(pem_object *po); + char *strdupImpl(const char *s); + + // Used as callback multiple places to append a string to a vector + static void byte_vector_append(void *ctx, const void *buff, size_t len) + { + std::vector *vec = static_cast *>(ctx); + vec->reserve(vec->size() + len); // Allocate extra space all at once + for (size_t i = 0; i < len; i++) + { + vec->push_back(((uint8_t *)buff)[i]); + } + } + + static bool certificate_to_trust_anchor_inner(br_x509_trust_anchor *ta, const br_x509_certificate *xc) + { + std::unique_ptr dc(new br_x509_decoder_context_libmail); // auto-delete on exit + std::vector vdn; + br_x509_pkey *pk; + + // Clear everything in the Trust Anchor + memset(ta, 0, sizeof(*ta)); + + br_x509_decoder_init_libmail(dc.get(), byte_vector_append, (void *)&vdn); + br_x509_decoder_push_libmail(dc.get(), xc->data, xc->data_len); + pk = br_x509_decoder_get_pkey(dc.get()); + if (pk == nullptr) + { + return false; // No key present, something broken in the cert! + } + + // Copy the raw certificate data + ta->dn.data = (uint8_t *)malloc(vdn.size()); + if (!ta->dn.data) + { + return false; // OOM, but nothing yet allocated + } + memcpy(ta->dn.data, &vdn[0], vdn.size()); + ta->dn.len = vdn.size(); + ta->flags = 0; + if (br_x509_decoder_isCA(dc.get())) + { + ta->flags |= BR_X509_TA_CA; + } + + // Extract the public key + switch (pk->key_type) + { + case BR_KEYTYPE_RSA: + ta->pkey.key_type = BR_KEYTYPE_RSA; + ta->pkey.key.rsa.n = (uint8_t *)malloc(pk->key.rsa.nlen); + ta->pkey.key.rsa.e = (uint8_t *)malloc(pk->key.rsa.elen); + if ((ta->pkey.key.rsa.n == nullptr) || (ta->pkey.key.rsa.e == nullptr)) + { + free_ta_contents(ta); // OOM, so clean up + return false; + } + memcpy(ta->pkey.key.rsa.n, pk->key.rsa.n, pk->key.rsa.nlen); + ta->pkey.key.rsa.nlen = pk->key.rsa.nlen; + memcpy(ta->pkey.key.rsa.e, pk->key.rsa.e, pk->key.rsa.elen); + ta->pkey.key.rsa.elen = pk->key.rsa.elen; + return true; + case BR_KEYTYPE_EC: + ta->pkey.key_type = BR_KEYTYPE_EC; + ta->pkey.key.ec.curve = pk->key.ec.curve; + ta->pkey.key.ec.q = (uint8_t *)malloc(pk->key.ec.qlen); + if (ta->pkey.key.ec.q == nullptr) + { + free_ta_contents(ta); // OOM, so clean up + return false; + } + memcpy(ta->pkey.key.ec.q, pk->key.ec.q, pk->key.ec.qlen); + ta->pkey.key.ec.qlen = pk->key.ec.qlen; + return true; + default: + free_ta_contents(ta); // Unknown key type + return false; + } + + // Should never get here, if so there was an unknown error + return false; + } + + br_x509_trust_anchor *certificate_to_trust_anchor(const br_x509_certificate *xc) + { + br_x509_trust_anchor *ta = (br_x509_trust_anchor *)malloc(sizeof(br_x509_trust_anchor)); + if (!ta) + { + return nullptr; + } + + if (!certificate_to_trust_anchor_inner(ta, xc)) + { + free(ta); + return nullptr; + } + return ta; + } + + void free_ta_contents(br_x509_trust_anchor *ta) + { + if (ta) + { + free(ta->dn.data); + if (ta->pkey.key_type == BR_KEYTYPE_RSA) + { + free(ta->pkey.key.rsa.n); + free(ta->pkey.key.rsa.e); + } + else if (ta->pkey.key_type == BR_KEYTYPE_EC) + { + free(ta->pkey.key.ec.q); + } + memset(ta, 0, sizeof(*ta)); + } + } + + // Checks if a bitstream looks like a valid DER(binary) encoding. + // Basically tries to verify the length of all included segments + // matches the length of the input buffer. Does not actually + // validate any contents. + bool looks_like_DER(const unsigned char *buff, size_t len) + { + if (len < 2) + { + return false; + } + if (pgm_read_byte(buff++) != 0x30) + { + return false; + } + int fb = pgm_read_byte(buff++); + len -= 2; + if (fb < 0x80) + { + return (size_t)fb == len; + } + else if (fb == 0x80) + { + return false; + } + else + { + fb -= 0x80; + if (len < (size_t)fb + 2) + { + return false; + } + len -= (size_t)fb; + size_t dlen = 0; + while (fb-- > 0) + { + if (dlen > (len >> 8)) + { + return false; + } + dlen = (dlen << 8) + (size_t)pgm_read_byte(buff++); + } + return dlen == len; + } + } + + void free_pem_object_contents(pem_object *po) + { + if (po) + { + free(po->name); + free(po->data); + po->name = nullptr; + po->data = nullptr; + } + } + + char *strdupImpl(const char *s) + { + size_t slen = strlen(s); + char *result = (char *)malloc(slen + 1); + if (!result) + return NULL; + memcpy(result, s, slen + 1); + return result; + } + + // Converts a PEM (~=base64) source into a set of DER-encoded binary blobs. + // Each blob is named by the ---- BEGIN xxx ---- field, and multiple + // blobs may be returned. + pem_object *decode_pem(const void *src, size_t len, size_t *num) + { + std::vector pem_list; + std::unique_ptr pc(new br_pem_decoder_context); // auto-delete on exit + if (!pc.get()) + { + return nullptr; + } + pem_object po, *pos; + const unsigned char *buff; + std::vector bv; + + *num = 0; + br_pem_decoder_init(pc.get()); + buff = (const unsigned char *)src; + po.name = nullptr; + po.data = nullptr; + po.data_len = 0; + bool inobj = false; + bool extra_nl = true; + + while (len > 0) + { + size_t tlen; + + tlen = br_pem_decoder_push(pc.get(), buff, len); + buff += tlen; + len -= tlen; + switch (br_pem_decoder_event(pc.get())) + { + case BR_PEM_BEGIN_OBJ: + po.name = strdupImpl(br_pem_decoder_name(pc.get())); + br_pem_decoder_setdest(pc.get(), byte_vector_append, &bv); + inobj = true; + break; + + case BR_PEM_END_OBJ: + if (inobj) + { + // Stick data into the vector + po.data = (uint8_t *)malloc(bv.size()); + if (po.data) + { + memcpy(po.data, &bv[0], bv.size()); + po.data_len = bv.size(); + pem_list.push_back(po); + } + // Clean up state for next blob processing + bv.clear(); + po.name = nullptr; + po.data = nullptr; + po.data_len = 0; + inobj = false; + } + break; + + case BR_PEM_ERROR: + free(po.name); + for (size_t i = 0; i < pem_list.size(); i++) + { + free_pem_object_contents(&pem_list[i]); + } + return nullptr; + + default: + // Do nothing here, the parser is still working on things + break; + } + + if (len == 0 && extra_nl) + { + extra_nl = false; + buff = (const unsigned char *)"\n"; + len = 1; + } + } + + if (inobj) + { + free(po.name); + for (size_t i = 0; i < pem_list.size(); i++) + { + free_pem_object_contents(&pem_list[i]); + } + return nullptr; + } + + pos = (pem_object *)malloc((1 + pem_list.size()) * sizeof(*pos)); + if (pos) + { + *num = pem_list.size(); + pem_list.push_back(po); // Null-terminate list + memcpy(pos, &pem_list[0], pem_list.size() * sizeof(*pos)); + } + return pos; + } + + // Parse out DER or PEM encoded certificates from a binary buffer, + // potentially stored in PROGMEM. + br_x509_certificate *read_certificates(const char *buff, size_t len, size_t *num) + { + std::vector cert_list; + pem_object *pos; + size_t u, num_pos; + br_x509_certificate *xcs; + br_x509_certificate dummy; + + *num = 0; + + if (looks_like_DER((const unsigned char *)buff, len)) + { + xcs = (br_x509_certificate *)malloc(2 * sizeof(*xcs)); + if (!xcs) + { + return nullptr; + } + xcs[0].data = (uint8_t *)malloc(len); + if (!xcs[0].data) + { + free(xcs); + return nullptr; + } + memcpy_P(xcs[0].data, buff, len); + xcs[0].data_len = len; + xcs[1].data = nullptr; + xcs[1].data_len = 0; + *num = 1; + return xcs; + } + + pos = decode_pem(buff, len, &num_pos); + if (!pos) + { + return nullptr; + } + for (u = 0; u < num_pos; u++) + { + if (!strcmp_P(pos[u].name, PSTR("CERTIFICATE")) || !strcmp_P(pos[u].name, PSTR("X509 CERTIFICATE"))) + { + br_x509_certificate xc; + xc.data = pos[u].data; + xc.data_len = pos[u].data_len; + pos[u].data = nullptr; // Don't free the data we moved to the xc vector! + cert_list.push_back(xc); + } + } + for (u = 0; u < num_pos; u++) + { + free_pem_object_contents(&pos[u]); + } + free(pos); + + if (cert_list.size() == 0) + { + return nullptr; + } + *num = cert_list.size(); + dummy.data = nullptr; + dummy.data_len = 0; + cert_list.push_back(dummy); + xcs = (br_x509_certificate *)malloc(cert_list.size() * sizeof(*xcs)); + if (!xcs) + { + for (size_t i = 0; i < cert_list.size(); i++) + { + free(cert_list[i].data); // Clean up any captured data blobs + } + return nullptr; + } + memcpy(xcs, &cert_list[0], cert_list.size() * sizeof(br_x509_certificate)); + // XCS now has [].data pointing to the previously allocated blobs, so don't + // want to free anything in cert_list[]. + return xcs; + } + + void free_certificates(br_x509_certificate *certs, size_t num) + { + if (certs) + { + for (size_t u = 0; u < num; u++) + { + free(certs[u].data); + } + free(certs); + } + } + + static public_key *decode_public_key(const unsigned char *buff, size_t len) + { + std::unique_ptr dc(new br_pkey_decoder_context); // auto-delete on exit + if (!dc.get()) + { + return nullptr; + } + + public_key *pk = nullptr; + // https://github.com/yglukhov/bearssl_pkey_decoder + br_pkey_decoder_init(dc.get()); + br_pkey_decoder_push(dc.get(), buff, len); + int err = br_pkey_decoder_last_error(dc.get()); + if (err != 0) + { + return nullptr; + } + + const br_rsa_public_key *rk = nullptr; + const br_ec_public_key *ek = nullptr; + switch (br_pkey_decoder_key_type(dc.get())) + { + case BR_KEYTYPE_RSA: + rk = br_pkey_decoder_get_rsa(dc.get()); + pk = (public_key *)malloc(sizeof *pk); + if (!pk) + { + return nullptr; + } + pk->key_type = BR_KEYTYPE_RSA; + pk->key.rsa.n = (uint8_t *)malloc(rk->nlen); + pk->key.rsa.e = (uint8_t *)malloc(rk->elen); + if (!pk->key.rsa.n || !pk->key.rsa.e) + { + free(pk->key.rsa.n); + free(pk->key.rsa.e); + free(pk); + return nullptr; + } + memcpy(pk->key.rsa.n, rk->n, rk->nlen); + pk->key.rsa.nlen = rk->nlen; + memcpy(pk->key.rsa.e, rk->e, rk->elen); + pk->key.rsa.elen = rk->elen; + return pk; + + case BR_KEYTYPE_EC: + ek = br_pkey_decoder_get_ec(dc.get()); + pk = (public_key *)malloc(sizeof *pk); + if (!pk) + { + return nullptr; + } + pk->key_type = BR_KEYTYPE_EC; + pk->key.ec.q = (uint8_t *)malloc(ek->qlen); + if (!pk->key.ec.q) + { + free(pk); + return nullptr; + } + memcpy(pk->key.ec.q, ek->q, ek->qlen); + pk->key.ec.qlen = ek->qlen; + pk->key.ec.curve = ek->curve; + return pk; + + default: + return nullptr; + } + } + + void free_public_key(public_key *pk) + { + if (pk) + { + if (pk->key_type == BR_KEYTYPE_RSA) + { + free(pk->key.rsa.n); + free(pk->key.rsa.e); + } + else if (pk->key_type == BR_KEYTYPE_EC) + { + free(pk->key.ec.q); + } + free(pk); + } + } + + static private_key *decode_private_key(const unsigned char *buff, size_t len) + { + std::unique_ptr dc(new br_skey_decoder_context); // auto-delete on exit + if (!dc.get()) + { + return nullptr; + } + + private_key *sk = nullptr; + + br_skey_decoder_init(dc.get()); + br_skey_decoder_push(dc.get(), buff, len); + int err = br_skey_decoder_last_error(dc.get()); + if (err != 0) + { + return nullptr; + } + + const br_rsa_private_key *rk = nullptr; + const br_ec_private_key *ek = nullptr; + switch (br_skey_decoder_key_type(dc.get())) + { + case BR_KEYTYPE_RSA: + rk = br_skey_decoder_get_rsa(dc.get()); + sk = (private_key *)malloc(sizeof *sk); + if (!sk) + { + return nullptr; + } + sk->key_type = BR_KEYTYPE_RSA; + sk->key.rsa.p = (uint8_t *)malloc(rk->plen); + sk->key.rsa.q = (uint8_t *)malloc(rk->qlen); + sk->key.rsa.dp = (uint8_t *)malloc(rk->dplen); + sk->key.rsa.dq = (uint8_t *)malloc(rk->dqlen); + sk->key.rsa.iq = (uint8_t *)malloc(rk->iqlen); + if (!sk->key.rsa.p || !sk->key.rsa.q || !sk->key.rsa.dp || !sk->key.rsa.dq || !sk->key.rsa.iq) + { + free_private_key(sk); + return nullptr; + } + sk->key.rsa.n_bitlen = rk->n_bitlen; + memcpy(sk->key.rsa.p, rk->p, rk->plen); + sk->key.rsa.plen = rk->plen; + memcpy(sk->key.rsa.q, rk->q, rk->qlen); + sk->key.rsa.qlen = rk->qlen; + memcpy(sk->key.rsa.dp, rk->dp, rk->dplen); + sk->key.rsa.dplen = rk->dplen; + memcpy(sk->key.rsa.dq, rk->dq, rk->dqlen); + sk->key.rsa.dqlen = rk->dqlen; + memcpy(sk->key.rsa.iq, rk->iq, rk->iqlen); + sk->key.rsa.iqlen = rk->iqlen; + return sk; + + case BR_KEYTYPE_EC: + ek = br_skey_decoder_get_ec(dc.get()); + sk = (private_key *)malloc(sizeof *sk); + if (!sk) + { + return nullptr; + } + sk->key_type = BR_KEYTYPE_EC; + sk->key.ec.curve = ek->curve; + sk->key.ec.x = (uint8_t *)malloc(ek->xlen); + if (!sk->key.ec.x) + { + free_private_key(sk); + return nullptr; + } + memcpy(sk->key.ec.x, ek->x, ek->xlen); + sk->key.ec.xlen = ek->xlen; + return sk; + + default: + return nullptr; + } + } + + void free_private_key(private_key *sk) + { + if (sk) + { + switch (sk->key_type) + { + case BR_KEYTYPE_RSA: + free(sk->key.rsa.p); + free(sk->key.rsa.q); + free(sk->key.rsa.dp); + free(sk->key.rsa.dq); + free(sk->key.rsa.iq); + break; + case BR_KEYTYPE_EC: + free(sk->key.ec.x); + break; + default: + // Could be an uninitted key, no sub elements to free + break; + } + free(sk); + } + } + + void free_pem_object(pem_object *pos) + { + if (pos != nullptr) + { + for (size_t u = 0; pos[u].name; u++) + { + free_pem_object_contents(&pos[u]); + } + free(pos); + } + } + + private_key *read_private_key(const char *buff, size_t len) + { + private_key *sk = nullptr; + pem_object *pos = nullptr; + + if (looks_like_DER((const unsigned char *)buff, len)) + { + sk = decode_private_key((const unsigned char *)buff, len); + return sk; + } + + size_t num; + pos = decode_pem(buff, len, &num); + if (pos == nullptr) + { + return nullptr; // PEM decode error + } + for (size_t u = 0; pos[u].name; u++) + { + const char *name = pos[u].name; + if (!strcmp_P(name, PSTR("RSA PRIVATE KEY")) || !strcmp_P(name, PSTR("EC PRIVATE KEY")) || !strcmp_P(name, PSTR("PRIVATE KEY"))) + { + sk = decode_private_key(pos[u].data, pos[u].data_len); + free_pem_object(pos); + return sk; + } + } + // If we hit here, no match + free_pem_object(pos); + return nullptr; + } + + public_key *read_public_key(const char *buff, size_t len) + { + public_key *pk = nullptr; + pem_object *pos = nullptr; + + if (looks_like_DER((const unsigned char *)buff, len)) + { + pk = decode_public_key((const unsigned char *)buff, len); + return pk; + } + size_t num; + pos = decode_pem(buff, len, &num); + if (pos == nullptr) + { + return nullptr; // PEM decode error + } + for (size_t u = 0; pos[u].name; u++) + { + const char *name = pos[u].name; + if (!strcmp_P(name, PSTR("RSA PUBLIC KEY")) || !strcmp_P(name, PSTR("EC PUBLIC KEY")) || !strcmp_P(name, PSTR("PUBLIC KEY"))) + { + pk = decode_public_key(pos[u].data, pos[u].data_len); + free_pem_object(pos); + return pk; + } + } + + // We hit here == no key found + free_pem_object(pos); + return pk; + } + + static uint8_t *loadStream(Stream &stream, size_t size) + { + uint8_t *dest = (uint8_t *)malloc(size); + if (!dest) + { + return nullptr; // OOM error + } + if (size != stream.readBytes(dest, size)) + { + free(dest); // Error during read + return nullptr; + } + return dest; + } +}; + +namespace bssl +{ + + // ----- Public Key ----- + + PublicKey::PublicKey() + { + _key = nullptr; + } + + PublicKey::PublicKey(const char *pemKey) + { + _key = nullptr; + parse(pemKey); + } + + PublicKey::PublicKey(const uint8_t *derKey, size_t derLen) + { + _key = nullptr; + parse(derKey, derLen); + } + + PublicKey::PublicKey(Stream &stream, size_t size) + { + _key = nullptr; + auto buff = key_bssl::loadStream(stream, size); + if (buff) + { + parse(buff, size); + free(buff); + } + } + + PublicKey::~PublicKey() + { + if (_key) + { + key_bssl::free_public_key(_key); + } + } + + bool PublicKey::parse(const char *pemKey) + { + return parse((const uint8_t *)pemKey, strlen_P(pemKey)); + } + + bool PublicKey::parse(const uint8_t *derKey, size_t derLen) + { + if (_key) + { + key_bssl::free_public_key(_key); + _key = nullptr; + } + _key = key_bssl::read_public_key((const char *)derKey, derLen); + return _key ? true : false; + } + + bool PublicKey::isRSA() const + { + if (!_key || _key->key_type != BR_KEYTYPE_RSA) + { + return false; + } + return true; + } + + bool PublicKey::isEC() const + { + if (!_key || _key->key_type != BR_KEYTYPE_EC) + { + return false; + } + return true; + } + + const br_rsa_public_key *PublicKey::getRSA() const + { + if (!_key || _key->key_type != BR_KEYTYPE_RSA) + { + return nullptr; + } + return &_key->key.rsa; + } + + const br_ec_public_key *PublicKey::getEC() const + { + if (!_key || _key->key_type != BR_KEYTYPE_EC) + { + return nullptr; + } + return &_key->key.ec; + } + + // ----- Private Key ----- + + PrivateKey::PrivateKey() + { + _key = nullptr; + } + + PrivateKey::PrivateKey(const char *pemKey) + { + _key = nullptr; + parse(pemKey); + } + + PrivateKey::PrivateKey(const uint8_t *derKey, size_t derLen) + { + _key = nullptr; + parse(derKey, derLen); + } + + PrivateKey::PrivateKey(Stream &stream, size_t size) + { + _key = nullptr; + auto buff = key_bssl::loadStream(stream, size); + if (buff) + { + parse(buff, size); + free(buff); + } + } + + PrivateKey::~PrivateKey() + { + if (_key) + { + key_bssl::free_private_key(_key); + } + } + + bool PrivateKey::parse(const char *pemKey) + { + return parse((const uint8_t *)pemKey, strlen_P(pemKey)); + } + + bool PrivateKey::parse(const uint8_t *derKey, size_t derLen) + { + if (_key) + { + key_bssl::free_private_key(_key); + _key = nullptr; + } + _key = key_bssl::read_private_key((const char *)derKey, derLen); + return _key ? true : false; + } + + bool PrivateKey::isRSA() const + { + if (!_key || _key->key_type != BR_KEYTYPE_RSA) + { + return false; + } + return true; + } + + bool PrivateKey::isEC() const + { + if (!_key || _key->key_type != BR_KEYTYPE_EC) + { + return false; + } + return true; + } + + const br_rsa_private_key *PrivateKey::getRSA() const + { + if (!_key || _key->key_type != BR_KEYTYPE_RSA) + { + return nullptr; + } + return &_key->key.rsa; + } + + const br_ec_private_key *PrivateKey::getEC() const + { + if (!_key || _key->key_type != BR_KEYTYPE_EC) + { + return nullptr; + } + return &_key->key.ec; + } + + // ----- Certificate Lists ----- + + X509List::X509List() + { + _count = 0; + _cert = nullptr; + _ta = nullptr; + } + + X509List::X509List(const char *pemCert) + { + _count = 0; + _cert = nullptr; + _ta = nullptr; + append(pemCert); + } + + X509List::X509List(const uint8_t *derCert, size_t derLen) + { + _count = 0; + _cert = nullptr; + _ta = nullptr; + append(derCert, derLen); + } + + X509List::X509List(Stream &stream, size_t size) + { + _count = 0; + _cert = nullptr; + _ta = nullptr; + auto buff = key_bssl::loadStream(stream, size); + if (buff) + { + append(buff, size); + free(buff); + } + } + + X509List::~X509List() + { + key_bssl::free_certificates(_cert, _count); // also frees cert + for (size_t i = 0; i < _count; i++) + { + key_bssl::free_ta_contents(&_ta[i]); + } + free(_ta); + } + + bool X509List::append(const char *pemCert) + { + return append((const uint8_t *)pemCert, strlen_P(pemCert)); + } + + bool X509List::append(const uint8_t *derCert, size_t derLen) + { + size_t numCerts; + br_x509_certificate *newCerts = key_bssl::read_certificates((const char *)derCert, derLen, &numCerts); + if (!newCerts) + { + return false; + } + + // Add in the certificates + br_x509_certificate *saveCert = _cert; + _cert = (br_x509_certificate *)realloc(_cert, (numCerts + _count) * sizeof(br_x509_certificate)); + if (!_cert) + { + free(newCerts); + _cert = saveCert; + return false; + } + memcpy(&_cert[_count], newCerts, numCerts * sizeof(br_x509_certificate)); + free(newCerts); + + // Build TAs for each certificate + br_x509_trust_anchor *saveTa = _ta; + _ta = (br_x509_trust_anchor *)realloc(_ta, (numCerts + _count) * sizeof(br_x509_trust_anchor)); + if (!_ta) + { + _ta = saveTa; + return false; + } + for (size_t i = 0; i < numCerts; i++) + { + br_x509_trust_anchor *newTa = key_bssl::certificate_to_trust_anchor(&_cert[_count + i]); + if (newTa) + { + _ta[_count + i] = *newTa; + free(newTa); + } + else + { + return false; // OOM + } + } + _count += numCerts; + + return true; + } + +}; + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.h new file mode 100644 index 000000000000..ca7ff0c1f50e --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.h @@ -0,0 +1,447 @@ + +/* + WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries + - Mostly compatible with Arduino WiFi shield library and standard + WiFiClient/ServerSecure (except for certificate handling). + + Copyright (c) 2018 Earle F. Philhower, III + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef BSSL_HELPER_H +#define BSSL_HELPER_H + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wvla" + +#include +#include "../ESP_SSLClient_FS.h" +#include "../ESP_SSLClient_Const.h" + +#if defined(USE_EMBED_SSL_ENGINE) + +#if defined(ESP8266) + +#ifdef __GNUC__ +#if __GNUC__ > 4 || __GNUC__ == 10 +#if defined(ARDUINO_ESP8266_GIT_VER) +#if ARDUINO_ESP8266_GIT_VER > 0 +#define ESP8266_CORE_SDK_V3_X_X +#endif +#endif +#endif +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#else + +#include +#include +#include +#include + +#endif + +#elif defined(USE_LIB_SSL_ENGINE) + +#include "../bssl/bearssl.h" + +#endif + +#if defined(USE_LIB_SSL_ENGINE) || defined(USE_EMBED_SSL_ENGINE) +// Cache for a TLS session with a server +// Use with BearSSL::WiFiClientSecure::setSession +// to accelerate the TLS handshake +class BearSSL_Session +{ + friend class BSSL_SSL_Client; + +public: + BearSSL_Session() + { + memset(&_session, 0, sizeof(_session)); + } + + br_ssl_session_parameters *getSession() + { + return &_session; + } + +private: + // The actual BearSSL session information + br_ssl_session_parameters _session; +}; + +static const uint16_t suites_P[] PROGMEM = { +#ifndef BEARSSL_SSL_BASIC + BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + BR_TLS_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_RSA_WITH_AES_128_CCM, + BR_TLS_RSA_WITH_AES_256_CCM, + BR_TLS_RSA_WITH_AES_128_CCM_8, + BR_TLS_RSA_WITH_AES_256_CCM_8, +#endif + BR_TLS_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_RSA_WITH_AES_256_CBC_SHA256, + BR_TLS_RSA_WITH_AES_128_CBC_SHA, + BR_TLS_RSA_WITH_AES_256_CBC_SHA, +#ifndef BEARSSL_SSL_BASIC + BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA +#endif +}; + +// For apps which want to use less secure but faster ciphers, only +static const uint16_t faster_suites_P[] PROGMEM = { + BR_TLS_RSA_WITH_AES_256_CBC_SHA256, + BR_TLS_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_RSA_WITH_AES_256_CBC_SHA, + BR_TLS_RSA_WITH_AES_128_CBC_SHA}; + +// Internal opaque structures, not needed by user applications +namespace key_bssl +{ + class public_key; + class private_key; +}; + +namespace bssl +{ + + // Holds either a single public RSA or EC key for use when BearSSL wants a pubkey. + // Copies all associated data so no need to keep input PEM/DER keys. + // All inputs can be either in RAM or PROGMEM. + class PublicKey + { + public: + PublicKey(); + PublicKey(const char *pemKey); + PublicKey(const uint8_t *derKey, size_t derLen); + PublicKey(Stream &stream, size_t size); + PublicKey(Stream &stream) : PublicKey(stream, stream.available()){}; + ~PublicKey(); + + bool parse(const char *pemKey); + bool parse(const uint8_t *derKey, size_t derLen); + + // Accessors for internal use, not needed by apps + bool isRSA() const; + bool isEC() const; + const br_rsa_public_key *getRSA() const; + const br_ec_public_key *getEC() const; + + // Disable the copy constructor, we're pointer based + PublicKey(const PublicKey &that) = delete; + PublicKey &operator=(const PublicKey &that) = delete; + + private: + key_bssl::public_key *_key; + }; + + // Holds either a single private RSA or EC key for use when BearSSL wants a secretkey. + // Copies all associated data so no need to keep input PEM/DER keys. + // All inputs can be either in RAM or PROGMEM. + class PrivateKey + { + public: + PrivateKey(); + PrivateKey(const char *pemKey); + PrivateKey(const uint8_t *derKey, size_t derLen); + PrivateKey(Stream &stream, size_t size); + PrivateKey(Stream &stream) : PrivateKey(stream, stream.available()){}; + ~PrivateKey(); + + bool parse(const char *pemKey); + bool parse(const uint8_t *derKey, size_t derLen); + + // Accessors for internal use, not needed by apps + bool isRSA() const; + bool isEC() const; + const br_rsa_private_key *getRSA() const; + const br_ec_private_key *getEC() const; + + // Disable the copy constructor, we're pointer based + PrivateKey(const PrivateKey &that) = delete; + PrivateKey &operator=(const PrivateKey &that) = delete; + + private: + key_bssl::private_key *_key; + }; + + // Holds one or more X.509 certificates and associated trust anchors for + // use whenever BearSSL needs a cert or TA. May want to have multiple + // certs for things like a series of trusted CAs (but check the CertStore class + // for a more memory efficient way). + // Copies all associated data so no need to keep input PEM/DER certs. + // All inputs can be either in RAM or PROGMEM. + class X509List + { + public: + X509List(); + X509List(const char *pemCert); + X509List(const uint8_t *derCert, size_t derLen); + X509List(Stream &stream, size_t size); + X509List(Stream &stream) : X509List(stream, stream.available()){}; + ~X509List(); + + bool append(const char *pemCert); + bool append(const uint8_t *derCert, size_t derLen); + + // Accessors + size_t getCount() const + { + return _count; + } + const br_x509_certificate *getX509Certs() const + { + return _cert; + } + const br_x509_trust_anchor *getTrustAnchors() const + { + return _ta; + } + + // Disable the copy constructor, we're pointer based + X509List(const X509List &that) = delete; + X509List &operator=(const X509List &that) = delete; + + private: + size_t _count; + br_x509_certificate *_cert; + br_x509_trust_anchor *_ta; + }; + + extern "C" + { + + // Install hashes into the SSL engine + static void br_ssl_client_install_hashes(br_ssl_engine_context *eng) + { + br_ssl_engine_set_hash(eng, br_md5_ID, &br_md5_vtable); + br_ssl_engine_set_hash(eng, br_sha1_ID, &br_sha1_vtable); + br_ssl_engine_set_hash(eng, br_sha224_ID, &br_sha224_vtable); + br_ssl_engine_set_hash(eng, br_sha256_ID, &br_sha256_vtable); + br_ssl_engine_set_hash(eng, br_sha384_ID, &br_sha384_vtable); + br_ssl_engine_set_hash(eng, br_sha512_ID, &br_sha512_vtable); + } + + static void br_x509_minimal_install_hashes(br_x509_minimal_context *x509) + { + br_x509_minimal_set_hash(x509, br_md5_ID, &br_md5_vtable); + br_x509_minimal_set_hash(x509, br_sha1_ID, &br_sha1_vtable); + br_x509_minimal_set_hash(x509, br_sha224_ID, &br_sha224_vtable); + br_x509_minimal_set_hash(x509, br_sha256_ID, &br_sha256_vtable); + br_x509_minimal_set_hash(x509, br_sha384_ID, &br_sha384_vtable); + br_x509_minimal_set_hash(x509, br_sha512_ID, &br_sha512_vtable); + } + + // Default initializion for our SSL clients + static void br_ssl_client_base_init(br_ssl_client_context *cc, const uint16_t *cipher_list, int cipher_cnt) + { + uint16_t suites[cipher_cnt]; + memcpy_P(suites, cipher_list, cipher_cnt * sizeof(cipher_list[0])); + br_ssl_client_zero(cc); + br_ssl_engine_add_flags(&cc->eng, BR_OPT_NO_RENEGOTIATION); // forbid SSL renegotiation, as we free the Private Key after handshake + br_ssl_engine_set_versions(&cc->eng, BR_TLS10, BR_TLS12); + br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); + br_ssl_client_set_default_rsapub(cc); + br_ssl_engine_set_default_rsavrfy(&cc->eng); +#ifndef BEARSSL_SSL_BASIC + br_ssl_engine_set_default_ecdsa(&cc->eng); +#endif + br_ssl_client_install_hashes(&cc->eng); + br_ssl_engine_set_prf10(&cc->eng, &br_tls10_prf); + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf); + br_ssl_engine_set_default_aes_cbc(&cc->eng); +#ifndef BEARSSL_SSL_BASIC + br_ssl_engine_set_default_aes_gcm(&cc->eng); + br_ssl_engine_set_default_aes_ccm(&cc->eng); + br_ssl_engine_set_default_des_cbc(&cc->eng); + br_ssl_engine_set_default_chapol(&cc->eng); +#endif + } + + // BearSSL doesn't define a true insecure decoder, so we make one ourselves + // from the simple parser. It generates the issuer and subject hashes and + // the SHA1 fingerprint, only one (or none!) of which will be used to + // "verify" the certificate. + + // Private x509 decoder state + struct br_x509_insecure_context + { + const br_x509_class *vtable; + bool done_cert; + const uint8_t *match_fingerprint; + br_sha1_context sha1_cert; + bool allow_self_signed; + br_sha256_context sha256_subject; + br_sha256_context sha256_issuer; + br_x509_decoder_context_libmail ctx; + }; + + // Callback for the x509_minimal subject DN + static void insecure_subject_dn_append(void *ctx, const void *buf, size_t len) + { + br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; + br_sha256_update(&xc->sha256_subject, buf, len); + } + + // Callback for the x509_minimal issuer DN + static void insecure_issuer_dn_append(void *ctx, const void *buf, size_t len) + { + br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; + br_sha256_update(&xc->sha256_issuer, buf, len); + } + + // Callback for each certificate present in the chain (but only operates + // on the first one by design). + static void insecure_start_cert(const br_x509_class **ctx, uint32_t length) + { + (void)ctx; + (void)length; + } + + // Callback for each byte stream in the chain. Only process first cert. + static void insecure_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) + { + br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; + // Don't process anything but the first certificate in the chain + if (!xc->done_cert) + { + br_sha1_update(&xc->sha1_cert, buf, len); + br_x509_decoder_push_libmail(&xc->ctx, (const void *)buf, len); + } + } + // Callback on the first byte of any certificate + static void insecure_start_chain(const br_x509_class **ctx, const char *server_name) + { + br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; +#if defined(USE_EMBED_SSL_ENGINE) + br_x509_decoder_init_libmail(&xc->ctx, insecure_subject_dn_append, xc, insecure_issuer_dn_append, xc); +#elif defined(ESP32) || defined(USE_LIB_SSL_ENGINE) + br_x509_decoder_init_libmail(&xc->ctx, insecure_subject_dn_append, xc); +#endif + xc->done_cert = false; + br_sha1_init(&xc->sha1_cert); + br_sha256_init(&xc->sha256_subject); + br_sha256_init(&xc->sha256_issuer); + (void)server_name; + } + + // Callback on individual cert end. + static void insecure_end_cert(const br_x509_class **ctx) + { + br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; + xc->done_cert = true; + } + + // Callback when complete chain has been parsed. + // Return 0 on validation success, !0 on validation error + static unsigned insecure_end_chain(const br_x509_class **ctx) + { + const br_x509_insecure_context *xc = (const br_x509_insecure_context *)ctx; + if (!xc->done_cert) + { + // BSSL_BSSL_SSL_Client_DEBUG_PRINTF("insecure_end_chain: No cert seen\n"); + return 1; // error + } + + // Handle SHA1 fingerprint matching + char res[20]; + br_sha1_out(&xc->sha1_cert, res); + if (xc->match_fingerprint && memcmp(res, xc->match_fingerprint, sizeof(res))) + { + + return BR_ERR_X509_NOT_TRUSTED; + } + + // Handle self-signer certificate acceptance + char res_issuer[32]; + char res_subject[32]; + br_sha256_out(&xc->sha256_issuer, res_issuer); + br_sha256_out(&xc->sha256_subject, res_subject); + if (xc->allow_self_signed && memcmp(res_subject, res_issuer, sizeof(res_issuer))) + { + // BSSL_BSSL_SSL_Client_DEBUG_PRINTF("insecure_end_chain: Didn't get self-signed cert\n"); + return BR_ERR_X509_NOT_TRUSTED; + } + + // Default (no validation at all) or no errors in prior checks = success. + return 0; + } + + // Return the public key from the validator (set by x509_minimal) + static const br_x509_pkey *insecure_get_pkey(const br_x509_class *const *ctx, unsigned *usages) + { + const br_x509_insecure_context *xc = (const br_x509_insecure_context *)ctx; + if (usages != nullptr) + { + *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN; // I said we were insecure! + } + return &xc->ctx.pkey; + } + } + +}; +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_SSL_Client.cpp b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_SSL_Client.cpp new file mode 100644 index 000000000000..2b90a1859a8e --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_SSL_Client.cpp @@ -0,0 +1,2203 @@ +/** + * BSSL_SSL_Client library v1.0.11 for Arduino devices. + * + * Created August 27, 2003 + * + * This work contains codes based on WiFiClientSecure from Earle F. Philhower and SSLClient from OSU OPEnS Lab. + * + * Copyright (c) 2018 Earle F. Philhower, III + * + * Copyright 2019 OSU OPEnS Lab + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef BSSL_SSL_CLIENT_CPP +#define BSSL_SSL_CLIENT_CPP + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wvla" + +#include +#include "../ESP_SSLClient_FS.h" +#include "../ESP_SSLClient_Const.h" +#if defined(USE_LIB_SSL_ENGINE) || defined(USE_EMBED_SSL_ENGINE) + +#include "BSSL_Helper.h" +#include "BSSL_SSL_Client.h" + +#if defined(ESP8266) && defined(MMU_EXTERNAL_HEAP) && defined(ESP_SSLCLIENT_USE_PSRAM) +#include +#include +#define ESP_SSLCLIENT_ESP8266_USE_EXTERNAL_HEAP +#endif + +#if defined(USE_EMBED_SSL_ENGINE) +#include +#include +#include +#include "StackThunk.h" +#include "lwip/opt.h" +#include "lwip/ip.h" +#include "lwip/tcp.h" +#include "lwip/inet.h" +#include "lwip/netif.h" + +#if 1 +#if !CORE_MOCK + +// The BearSSL thunks in use for now +#define br_ssl_engine_recvapp_ack thunk_br_ssl_engine_recvapp_ack +#define br_ssl_engine_recvapp_buf thunk_br_ssl_engine_recvapp_buf +#define br_ssl_engine_recvrec_ack thunk_br_ssl_engine_recvrec_ack +#define br_ssl_engine_recvrec_buf thunk_br_ssl_engine_recvrec_buf +#define br_ssl_engine_sendapp_ack thunk_br_ssl_engine_sendapp_ack +#define br_ssl_engine_sendapp_buf thunk_br_ssl_engine_sendapp_buf +#define br_ssl_engine_sendrec_ack thunk_br_ssl_engine_sendrec_ack +#define br_ssl_engine_sendrec_buf thunk_br_ssl_engine_sendrec_buf + +#endif +#endif + +#endif + +BSSL_SSL_Client::BSSL_SSL_Client(Client *client) +{ + setClient(client); + mClear(); + mClearAuthenticationSettings(); +#if defined(ESP_SSL_FS_SUPPORTED) + _certStore = nullptr; // Don't want to remove cert store on a clear, should be long lived +#endif + _sk = nullptr; +#if defined(USE_EMBED_SSL_ENGINE) + stack_thunk_add_ref(); +#endif +} + +BSSL_SSL_Client::~BSSL_SSL_Client() +{ + if (_basic_client) + { + if (_basic_client->connected()) + _basic_client->stop(); + _basic_client = nullptr; + } + freeImpl(&_cipher_list); + mFreeSSL(); +#if defined(USE_EMBED_SSL_ENGINE) + stack_thunk_del_ref(); +#endif +} + +void BSSL_SSL_Client::setClient(Client *client, bool ssl) +{ + _basic_client = client; + _isSSLEnabled = ssl; +} + +void BSSL_SSL_Client::setDebugLevel(int level) +{ + if (level < esp_ssl_debug_none || level > esp_ssl_debug_dump) + _debug_level = esp_ssl_debug_none; + else + _debug_level = level; +} + +int BSSL_SSL_Client::connect(IPAddress ip, uint16_t port) +{ + if (_isSSLEnabled && mIsSecurePort(port)) // SSL connect + return connectSSL(ip, port); + + if (!mConnectBasicClient(nullptr, ip, port)) + return 0; + + return 1; +} + +int BSSL_SSL_Client::connect(const char *host, uint16_t port) +{ + if (_isSSLEnabled && mIsSecurePort(port)) + return connectSSL(host, port); + + if (!mConnectBasicClient(host, IPAddress(), port)) + return 0; + + return 1; +} + +uint8_t BSSL_SSL_Client::connected() +{ + if (!mIsClientInitialized(false)) + return 0; + + if (!_secure) + return _basic_client->connected(); + + // check all of the error cases + const auto c_con = _basic_client->connected(); + const auto br_con = br_ssl_engine_current_state(_eng) != BR_SSL_CLOSED && _is_connected; + const auto wr_ok = getWriteError() == 0; + // if we're in an error state, close the connection and set a write error + if (br_con && !c_con) + { + // If we've got a write error, the client probably failed for some reason + if (_basic_client->getWriteError()) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + String s = PSTR("Socket was unexpectedly interrupted. m_client error: "); + s += _basic_client->getWriteError(); + esp_ssl_debug_print(s.c_str(), _debug_level, esp_ssl_debug_info, __func__); +#endif + setWriteError(esp_ssl_write_error); + } + // Else tell the user the endpoint closed the socket on us (ouch) + else + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + // esp_ssl_debug_print(PSTR("Socket was dropped unexpectedly (this can be an alternative to closing the connection)."), _debug_level, esp_ssl_debug_warn, func_name); +#endif + } + + // set the write error so the engine doesn't try to close the connection + _is_connected = false; + stop(); + } + else if (!wr_ok) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Not connected because write error is set."), _debug_level, esp_ssl_debug_error, __func__); + mPrintClientError(getWriteError(), esp_ssl_debug_error, __func__); +#endif + } + + return c_con && br_con; +} + +void BSSL_SSL_Client::validate(const char *host, uint16_t port) +{ + mConnectionValidate(host, IPAddress(), port); +} + +void BSSL_SSL_Client::validate(IPAddress ip, uint16_t port) +{ + mConnectionValidate(nullptr, ip, port); +} + +int BSSL_SSL_Client::available() +{ + if (!mIsClientInitialized(false)) + return 0; + + if (!_secure) + return _basic_client->available(); + + // connection check + if (!mSoftConnected(__func__)) + return 0; + + // run the SSL engine until we are waiting for either user input or a server response + unsigned state = mUpdateEngine(); + if (state == 0) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("SSL engine failed to update."), _debug_level, esp_ssl_debug_error, __func__); +#endif + } + else if (state & BR_SSL_RECVAPP) + { + // return how many received bytes we have + _recvapp_buf = br_ssl_engine_recvapp_buf(_eng, &_recvapp_len); + return (int)(_recvapp_len); + } + else if (state == BR_SSL_CLOSED) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("SSL Engine closed after update."), _debug_level, esp_ssl_debug_info, __func__); +#endif + } + // flush the buffer if it's stuck in the SENDAPP state + else if (state & BR_SSL_SENDAPP) + br_ssl_engine_flush(_eng, 0); + // other state, or client is closed + return 0; +} + +int BSSL_SSL_Client::read() +{ + uint8_t read_val; + return read(&read_val, 1) > 0 ? read_val : -1; +}; + +int BSSL_SSL_Client::read(uint8_t *buf, size_t size) +{ + if (!mIsClientInitialized(false)) + return 0; + + if (!_secure) + return _basic_client->read(buf, size); + + // check that the engine is ready to read + if (available() <= 0 || !size) + return -1; + // read the buffer, send the ack, and return the bytes read + _recvapp_buf = br_ssl_engine_recvapp_buf(_eng, &_recvapp_len); + const size_t read_amount = size > _recvapp_len ? _recvapp_len : size; + if (buf) + memcpy(buf, _recvapp_buf, read_amount); + // tell engine we read that many bytes + br_ssl_engine_recvapp_ack(_eng, read_amount); + // tell the user we read that many bytes + return read_amount; +} + +size_t BSSL_SSL_Client::write(const uint8_t *buf, size_t size) +{ + if (!mIsClientInitialized(false)) + return 0; + + if (!_secure) + return _basic_client->write(buf, size); + + const char *func_name = __func__; +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + // super debug + if (_debug_level >= esp_ssl_debug_dump) + ESP_SSLCLIENT_DEBUG_PORT.write(buf, size); +#endif + // check if the socket is still open and such + if (!mSoftConnected(func_name) || !buf || !size) + return 0; + // wait until bearssl is ready to send + if (mRunUntil(BR_SSL_SENDAPP) < 0) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Failed while waiting for the engine to enter BR_SSL_SENDAPP."), _debug_level, esp_ssl_debug_error, func_name); +#endif + return 0; + } + // add to the bearssl io buffer, simply appending whatever we want to write + size_t alen; + unsigned char *br_buf = br_ssl_engine_sendapp_buf(_eng, &alen); + size_t cur_idx = 0; + if (alen == 0) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("BearSSL returned zero length buffer for sending, did an internal error occur?"), _debug_level, esp_ssl_debug_error, func_name); +#endif + return 0; + } + // while there are still elements to write + while (cur_idx < size) + { + // if we're about to fill the buffer, we need to send the data and then wait + // for another oppurtinity to send + // so we only send the smallest of the buffer size or our data size - how much we've already sent + const size_t cpamount = size - cur_idx >= alen - _write_idx ? alen - _write_idx : size - cur_idx; + memcpy(br_buf + _write_idx, buf + cur_idx, cpamount); + // increment write idx + _write_idx += cpamount; + // increment the buffer pointer + cur_idx += cpamount; + // if we filled the buffer, reset _write_idx, and mark the data for sending + if (_write_idx == alen) + { + // indicate to bearssl that we are done writing + br_ssl_engine_sendapp_ack(_eng, _write_idx); + // reset the write index + _write_idx = 0; + // write to the socket immediatly + if (mRunUntil(BR_SSL_SENDAPP) < 0) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Failed while waiting for the engine to enter BR_SSL_SENDAPP."), _debug_level, esp_ssl_debug_error, func_name); +#endif + return 0; + } + // reset the buffer pointer + br_buf = br_ssl_engine_sendapp_buf(_eng, &alen); + } + } + // works oky + return size; +} + +size_t BSSL_SSL_Client::write(uint8_t b) +{ + return write(&b, 1); +} + +size_t BSSL_SSL_Client::write_P(PGM_P buf, size_t size) +{ + char dest[size]; + memcpy_P((void *)dest, buf, size); + return write((const uint8_t *)dest, size); +} + +size_t BSSL_SSL_Client::write(Stream &stream) +{ + if (!mIsClientInitialized(false)) + return 0; + + if (!connected()) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Connect not completed yet."), _debug_level, esp_ssl_debug_error, __func__); +#endif + return 0; + } + + size_t dl = stream.available(); + uint8_t buf[dl]; + stream.readBytes(buf, dl); + return write(buf, dl); +} + +int BSSL_SSL_Client::peek() +{ + + if (!_sc || !available()) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Not connected, none left available."), _debug_level, esp_ssl_debug_error, __func__); +#endif + return -1; + } + + if (!_secure) + return _basic_client->peek(); + + _recvapp_buf = br_ssl_engine_recvapp_buf(_eng, &_recvapp_len); + if (_recvapp_buf && _recvapp_len) + return _recvapp_buf[0]; + +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("No data left."), _debug_level, esp_ssl_debug_error, __func__); +#endif + return -1; +} + +size_t BSSL_SSL_Client::peekBytes(uint8_t *buffer, size_t length) +{ + if (!mIsClientInitialized(false) || !_secure) + return 0; + + size_t to_copy = 0; + if (!_sc) + return 0; + + unsigned long _startMillis = millis(); + while ((available() < (int)length) && ((millis() - _startMillis) < 5000)) + { + yield(); + } + + to_copy = _recvapp_len < length ? _recvapp_len : length; + memcpy(buffer, _recvapp_buf, to_copy); + return to_copy; +} + +// Don't validate the chain, just accept whatever is given. VERY INSECURE! +void BSSL_SSL_Client::setInsecure() +{ + mClearAuthenticationSettings(); + _use_insecure = true; +} + +void BSSL_SSL_Client::enableSSL(bool enable) +{ + _isSSLEnabled = enable; +} + +int BSSL_SSL_Client::connectSSL(IPAddress ip, uint16_t port) +{ + + if (!mIsClientInitialized(true)) + return 0; + + if (!_basic_client->connected() && !mConnectBasicClient(nullptr, ip, port)) + return 0; + + _ip = ip; + _port = port; + + return mConnectSSL(nullptr); +} + +int BSSL_SSL_Client::connectSSL(const char *host, uint16_t port) +{ + + if (!mIsClientInitialized(true)) + return 0; + + if (!_basic_client->connected() && !mConnectBasicClient(host, IPAddress(), port)) + return 0; + + _host = host; + _port = port; + + return mConnectSSL(host); +} + +void BSSL_SSL_Client::stop() +{ + if (!_secure) + return; + + // Only if we've already connected, store session params and clear the connection options + if (_session) + br_ssl_engine_get_session_parameters(_eng, _session->getSession()); + + // tell the SSL connection to gracefully close + // Disabled to prevent close_notify from hanging BSSL_SSL_Client + // br_ssl_engine_close(_eng); + // if the engine isn't closed, and the socket is still open + auto state = br_ssl_engine_current_state(_eng); + if (state != BR_SSL_CLOSED && state != 0 && connected()) + { + // Discard any incoming application data. + _recvapp_buf = br_ssl_engine_recvapp_buf(_eng, &_recvapp_len); + if (_recvapp_buf != nullptr) + br_ssl_engine_recvapp_ack(_eng, _recvapp_len); + // run SSL to finish any existing transactions + flush(); + } + + // close the socket + if (_basic_client) + { + _basic_client->flush(); + _basic_client->stop(); + } + + mFreeSSL(); +} + +void BSSL_SSL_Client::setTimeout(unsigned int timeoutMs) { _timeout = timeoutMs; } + +void BSSL_SSL_Client::setHandshakeTimeout(unsigned int timeoutMs) { _handshake_timeout = timeoutMs; } + +void BSSL_SSL_Client::flush() +{ + if (!_secure && _basic_client) + { + _basic_client->flush(); + return; + } + + if (_write_idx > 0) + { + if (mRunUntil(BR_SSL_RECVAPP) < 0) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Could not flush write buffer!"), _debug_level, esp_ssl_debug_error, __func__); + int error = br_ssl_engine_last_error(_eng); + if (error != BR_ERR_OK) + mPrintSSLError(error, esp_ssl_debug_error, __func__); + if (getWriteError()) + mPrintClientError(getWriteError(), esp_ssl_debug_error, __func__); +#endif + } + } +} + +void BSSL_SSL_Client::setBufferSizes(int recv, int xmit) +{ + // Following constants taken from bearssl/src/ssl/ssl_engine.c (not exported unfortunately) + const int MAX_OUT_OVERHEAD = 85; + const int MAX_IN_OVERHEAD = 325; + + // The data buffers must be between 512B and 16KB + recv = std::max(512, std::min(16384, recv)); + xmit = std::max(512, std::min(16384, xmit)); + + // Add in overhead for SSL protocol + recv += MAX_IN_OVERHEAD; + xmit += MAX_OUT_OVERHEAD; + _iobuf_in_size = recv; + _iobuf_out_size = xmit; +} + +int BSSL_SSL_Client::availableForWrite() +{ + if (!mIsClientInitialized(false) || !_secure) + return 0; + + // code taken from ::write() + if (!connected() || !_handshake_done) + { + return 0; + } + // Get BearSSL to a state where we can send + if (mRunUntil(BR_SSL_SENDAPP) < 0) + { + return 0; + } + if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) + { + size_t sendapp_len; + (void)br_ssl_engine_sendapp_buf(_eng, &sendapp_len); + // We want to call br_ssl_engine_sendapp_ack(0) but 0 is forbidden (bssl doc). + // After checking br_ssl_engine_sendapp_buf() src code, + // it seems that it is OK to not call ack when the buffer is left untouched. + // forbidden: br_ssl_engine_sendapp_ack(_eng, 0); + return (int)sendapp_len; + } + return 0; +} + +void BSSL_SSL_Client::setSession(BearSSL_Session *session) { _session = session; }; + +// Assume a given public key, don't validate or use cert info at all +void BSSL_SSL_Client::setKnownKey(const PublicKey *pk, unsigned usages) +{ + mClearAuthenticationSettings(); + _knownkey = pk; + _knownkey_usages = usages; +} + +// Only check SHA1 fingerprint of certificate +bool BSSL_SSL_Client::setFingerprint(const uint8_t fingerprint[20]) +{ + mClearAuthenticationSettings(); + _use_fingerprint = true; + memcpy_P(_fingerprint, fingerprint, 20); + return true; +} + +// Set a fingerprint by parsing an ASCII string +bool BSSL_SSL_Client::setFingerprint(const char *fpStr) +{ + int idx = 0; + uint8_t c, d; + uint8_t fp[20]; + + while (idx < 20) + { + c = pgm_read_byte(fpStr++); + if (!c) + { + break; // String ended, done processing + } + d = pgm_read_byte(fpStr++); + if (!d) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("FP too short"), _debug_level, esp_ssl_debug_error, __func__); +#endif + return false; // Only half of the last hex digit, error + } + c = htoi(c); + d = htoi(d); + if ((c > 15) || (d > 15)) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Invalid char"), _debug_level, esp_ssl_debug_error, __func__); +#endif + return false; // Error in one of the hex characters + } + fp[idx++] = (c << 4) | d; + + // Skip 0 or more spaces or colons + while (pgm_read_byte(fpStr) && (pgm_read_byte(fpStr) == ' ' || pgm_read_byte(fpStr) == ':')) + { + fpStr++; + } + } + if ((idx != 20) || pgm_read_byte(fpStr)) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Garbage at end of fp"), _debug_level, esp_ssl_debug_error, __func__); +#endif + return false; // Garbage at EOL or we didn't have enough hex digits + } + return setFingerprint(fp); +} + +// Accept any certificate that's self-signed +void BSSL_SSL_Client::allowSelfSignedCerts() +{ + mClearAuthenticationSettings(); + _use_self_signed = true; +} + +// Install certificates of trusted CAs or specific site +void BSSL_SSL_Client::setTrustAnchors(const X509List *ta) +{ + mClearAuthenticationSettings(); + _ta = ta; +} + +// In cases when NTP is not used, app must set a time manually to check cert validity +void BSSL_SSL_Client::setX509Time(time_t now) +{ + _now = now; +} + +void BSSL_SSL_Client::setClientRSACert(const X509List *chain, const PrivateKey *sk) +{ + if (_esp32_chain) + { + delete _esp32_chain; + _esp32_chain = nullptr; + } + if (_esp32_sk) + { + delete _esp32_sk; + _esp32_sk = nullptr; + } + _chain = chain; + _sk = sk; +} + +void BSSL_SSL_Client::setClientECCert(const X509List *chain, const PrivateKey *sk, unsigned allowed_usages, unsigned cert_issuer_key_type) +{ + if (_esp32_chain) + { + delete _esp32_chain; + _esp32_chain = nullptr; + } + if (_esp32_sk) + { + delete _esp32_sk; + _esp32_sk = nullptr; + } + _chain = chain; + _sk = sk; + _allowed_usages = allowed_usages; + _cert_issuer_key_type = cert_issuer_key_type; +} + +// Returns whether MFLN negotiation for the above buffer sizes succeeded (after connection) +int BSSL_SSL_Client::getMFLNStatus() +{ + return connected() && br_ssl_engine_get_mfln_negotiated(_eng); +} + +// Returns an error ID and possibly a string (if dest != null) of the last +// BearSSL reported error. +int BSSL_SSL_Client::getLastSSLError(char *dest, size_t len) +{ + int err = 0; + const char *t = ""; + const char *recv_fatal = ""; + const char *send_fatal = ""; + if (_sc) + err = br_ssl_engine_last_error(_eng); + + if (_oom_err) + err = -1000; + else + { + if (err & BR_ERR_RECV_FATAL_ALERT) + { +#if defined(ESP_SSLCLIENT_ENABLE_SSL_ERROR_STRING) + recv_fatal = PSTR("SSL received fatal alert - "); +#endif + err &= ~BR_ERR_RECV_FATAL_ALERT; + } + if (err & BR_ERR_SEND_FATAL_ALERT) + { +#if defined(ESP_SSLCLIENT_ENABLE_SSL_ERROR_STRING) + send_fatal = PSTR("SSL sent fatal alert - "); +#endif + err &= ~BR_ERR_SEND_FATAL_ALERT; + } + } +#if defined(ESP_SSLCLIENT_ENABLE_SSL_ERROR_STRING) + switch (err) + { + case -1000: + t = PSTR("Unable to allocate memory for SSL structures and buffers."); + break; + case BR_ERR_BAD_PARAM: + t = PSTR("Caller-provided parameter is incorrect."); + break; + case BR_ERR_BAD_STATE: + t = PSTR("Operation requested by the caller cannot be applied with the current context state (e.g. reading data while outgoing data is waiting to be sent)."); + break; + case BR_ERR_UNSUPPORTED_VERSION: + t = PSTR("Incoming protocol or record version is unsupported."); + break; + case BR_ERR_BAD_VERSION: + t = PSTR("Incoming record version does not match the expected version."); + break; + case BR_ERR_BAD_LENGTH: + t = PSTR("Incoming record length is invalid."); + break; + case BR_ERR_TOO_LARGE: + t = PSTR("Incoming record is too large to be processed, or buffer is too small for the handshake message to send."); + break; + case BR_ERR_BAD_MAC: + t = PSTR("Decryption found an invalid padding, or the record MAC is not correct."); + break; + case BR_ERR_NO_RANDOM: + t = PSTR("No initial entropy was provided, and none can be obtained from the OS."); + break; + case BR_ERR_UNKNOWN_TYPE: + t = PSTR("Incoming record type is unknown."); + break; + case BR_ERR_UNEXPECTED: + t = PSTR("Incoming record or message has wrong type with regards to the current engine state."); + break; + case BR_ERR_BAD_CCS: + t = PSTR("ChangeCipherSpec message from the peer has invalid contents."); + break; + case BR_ERR_BAD_ALERT: + t = PSTR("Alert message from the peer has invalid contents (odd length)."); + break; + case BR_ERR_BAD_HANDSHAKE: + t = PSTR("Incoming handshake message decoding failed."); + break; + case BR_ERR_OVERSIZED_ID: + t = PSTR("ServerHello contains a session ID which is larger than 32 bytes."); + break; + case BR_ERR_BAD_CIPHER_SUITE: + t = PSTR("Server wants to use a cipher suite that we did not claim to support. This is also reported if we tried to advertise a cipher suite that we do not support."); + break; + case BR_ERR_BAD_COMPRESSION: + t = PSTR("Server wants to use a compression that we did not claim to support."); + break; + case BR_ERR_BAD_FRAGLEN: + t = PSTR("Server's max fragment length does not match client's."); + break; + case BR_ERR_BAD_SECRENEG: + t = PSTR("Secure renegotiation failed."); + break; + case BR_ERR_EXTRA_EXTENSION: + t = PSTR("Server sent an extension type that we did not announce, or used the same extension type several times in a single ServerHello."); + break; + case BR_ERR_BAD_SNI: + t = PSTR("Invalid Server Name Indication contents (when used by the server, this extension shall be empty)."); + break; + case BR_ERR_BAD_HELLO_DONE: + t = PSTR("Invalid ServerHelloDone from the server (length is not 0)."); + break; + case BR_ERR_LIMIT_EXCEEDED: + t = PSTR("Internal limit exceeded (e.g. server's public key is too large)."); + break; + case BR_ERR_BAD_FINISHED: + t = PSTR("Finished message from peer does not match the expected value."); + break; + case BR_ERR_RESUME_MISMATCH: + t = PSTR("Session resumption attempt with distinct version or cipher suite."); + break; + case BR_ERR_INVALID_ALGORITHM: + t = PSTR("Unsupported or invalid algorithm (ECDHE curve, signature algorithm, hash function)."); + break; + case BR_ERR_BAD_SIGNATURE: + t = PSTR("Invalid signature in ServerKeyExchange or CertificateVerify message."); + break; + case BR_ERR_WRONG_KEY_USAGE: + t = PSTR("Peer's public key does not have the proper type or is not allowed for the requested operation."); + break; + case BR_ERR_NO_CLIENT_AUTH: + t = PSTR("Client did not send a certificate upon request, or the client certificate could not be validated."); + break; + case BR_ERR_IO: + t = PSTR("I/O error or premature close on transport stream."); + break; + case BR_ERR_X509_INVALID_VALUE: + t = PSTR("Invalid value in an ASN.1 structure."); + break; + case BR_ERR_X509_TRUNCATED: + t = PSTR("Truncated certificate or other ASN.1 object."); + break; + case BR_ERR_X509_EMPTY_CHAIN: + t = PSTR("Empty certificate chain (no certificate at all)."); + break; + case BR_ERR_X509_INNER_TRUNC: + t = PSTR("Decoding error: inner element extends beyond outer element size."); + break; + case BR_ERR_X509_BAD_TAG_CLASS: + t = PSTR("Decoding error: unsupported tag class (application or private)."); + break; + case BR_ERR_X509_BAD_TAG_VALUE: + t = PSTR("Decoding error: unsupported tag value."); + break; + case BR_ERR_X509_INDEFINITE_LENGTH: + t = PSTR("Decoding error: indefinite length."); + break; + case BR_ERR_X509_EXTRA_ELEMENT: + t = PSTR("Decoding error: extraneous element."); + break; + case BR_ERR_X509_UNEXPECTED: + t = PSTR("Decoding error: unexpected element."); + break; + case BR_ERR_X509_NOT_CONSTRUCTED: + t = PSTR("Decoding error: expected constructed element, but is primitive."); + break; + case BR_ERR_X509_NOT_PRIMITIVE: + t = PSTR("Decoding error: expected primitive element, but is constructed."); + break; + case BR_ERR_X509_PARTIAL_BYTE: + t = PSTR("Decoding error: BIT STRING length is not multiple of 8."); + break; + case BR_ERR_X509_BAD_BOOLEAN: + t = PSTR("Decoding error: BOOLEAN value has invalid length."); + break; + case BR_ERR_X509_OVERFLOW: + t = PSTR("Decoding error: value is off-limits."); + break; + case BR_ERR_X509_BAD_DN: + t = PSTR("Invalid distinguished name."); + break; + case BR_ERR_X509_BAD_TIME: + t = PSTR("Invalid date/time representation."); + break; + case BR_ERR_X509_UNSUPPORTED: + t = PSTR("Certificate contains unsupported features that cannot be ignored."); + break; + case BR_ERR_X509_LIMIT_EXCEEDED: + t = PSTR("Key or signature size exceeds internal limits."); + break; + case BR_ERR_X509_WRONG_KEY_TYPE: + t = PSTR("Key type does not match that which was expected."); + break; + case BR_ERR_X509_BAD_SIGNATURE: + t = PSTR("Signature is invalid."); + break; + case BR_ERR_X509_TIME_UNKNOWN: + t = PSTR("Validation time is unknown."); + break; + case BR_ERR_X509_EXPIRED: + t = PSTR("Certificate is expired or not yet valid."); + break; + case BR_ERR_X509_DN_MISMATCH: + t = PSTR("Issuer/Subject DN mismatch in the chain."); + break; + case BR_ERR_X509_BAD_SERVER_NAME: + t = PSTR("Expected server name was not found in the chain."); + break; + case BR_ERR_X509_CRITICAL_EXTENSION: + t = PSTR("Unknown critical extension in certificate."); + break; + case BR_ERR_X509_NOT_CA: + t = PSTR("Not a CA, or path length constraint violation."); + break; + case BR_ERR_X509_FORBIDDEN_KEY_USAGE: + t = PSTR("Key Usage extension prohibits intended usage."); + break; + case BR_ERR_X509_WEAK_PUBLIC_KEY: + t = PSTR("Public key found in certificate is too small."); + break; + case BR_ERR_X509_NOT_TRUSTED: + t = PSTR("Chain could not be linked to a trust anchor."); + break; + default: + t = PSTR("Unknown error code."); + break; + } + + if (dest) + { + // snprintf is PSTR safe and guaranteed to 0-terminate + snprintf(dest, len, "%s%s%s", recv_fatal, send_fatal, t); + } + +#endif + + return err; +} + +// Attach a preconfigured certificate store +#if defined(ESP_SSL_FS_SUPPORTED) +void BSSL_SSL_Client::setCertStore(CertStoreBase *certStore) +{ + _certStore = certStore; +} +#endif + +// Set custom list of ciphers +bool BSSL_SSL_Client::setCiphers(const uint16_t *cipherAry, int cipherCount) +{ + _cipher_list = (uint16_t *)mallocImpl(cipherCount); + if (!_cipher_list) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("list empty"), _debug_level, esp_ssl_debug_error, __func__); +#endif + return false; + } + memcpy_P(_cipher_list, cipherAry, cipherCount * sizeof(uint16_t)); + _cipher_cnt = cipherCount; + return true; +} + +bool BSSL_SSL_Client::setCiphers(const std::vector &list) +{ + return setCiphers(&list[0], list.size()); +} + +bool BSSL_SSL_Client::setCiphersLessSecure() +{ + return setCiphers(faster_suites_P, sizeof(faster_suites_P) / sizeof(faster_suites_P[0])); +} + +bool BSSL_SSL_Client::setSSLVersion(uint32_t min, uint32_t max) +{ + if (((min != BR_TLS10) && (min != BR_TLS11) && (min != BR_TLS12)) || + ((max != BR_TLS10) && (max != BR_TLS11) && (max != BR_TLS12)) || + (max < min)) + { + return false; // Invalid options + } + _tls_min = min; + _tls_max = max; + return true; +} + +// Checks for support of Maximum Frame Length Negotiation at the given +// blocksize. Note that, per spec, only 512, 1024, 2048, and 4096 are +// supported. Many servers today do not support this negotiation. + +// TODO - Allow for fragmentation...but not very critical as the ServerHello +// we use comes to < 80 bytes which has no reason to ever be fragmented. +// TODO - Check the type of returned extensions and that the MFL is the exact +// same one we sent. Not critical as only horribly broken servers would +// return changed or add their own extensions. +bool BSSL_SSL_Client::probeMaxFragmentLength(IPAddress ip, uint16_t port, uint16_t len) +{ + return mProbeMaxFragmentLength(nullptr, ip, port, len); +} + +bool BSSL_SSL_Client::probeMaxFragmentLength(const char *name, uint16_t port, uint16_t len) +{ + return mProbeMaxFragmentLength(name, IPAddress(), port, len); +} + +bool BSSL_SSL_Client::probeMaxFragmentLength(const String &host, uint16_t port, uint16_t len) +{ + return BSSL_SSL_Client::probeMaxFragmentLength(host.c_str(), port, len); +} + +size_t BSSL_SSL_Client::peekAvailable() +{ + return available(); +} + +// return a pointer to available data buffer (size = peekAvailable()) +// semantic forbids any kind of read() before calling peekConsume() +const char *BSSL_SSL_Client::peekBuffer() +{ + return (const char *)_recvapp_buf; +} + +// consume bytes after use (see peekBuffer) +void BSSL_SSL_Client::peekConsume(size_t consume) +{ + // according to BSSL_SSL_Client::read: + br_ssl_engine_recvapp_ack(_eng, consume); + _recvapp_buf = nullptr; + _recvapp_len = 0; +} + +void BSSL_SSL_Client::setCACert(const char *rootCA) +{ + if (_esp32_ta) + delete _esp32_ta; + _esp32_ta = new X509List(rootCA); +} + +void BSSL_SSL_Client::setCertificate(const char *client_ca) +{ + if (_esp32_chain) + delete _esp32_chain; + _esp32_chain = new X509List(client_ca); +} + +void BSSL_SSL_Client::setPrivateKey(const char *private_key) +{ + if (_esp32_sk) + delete _esp32_sk; + _esp32_sk = new PrivateKey(private_key); +} + +bool BSSL_SSL_Client::loadCACert(Stream &stream, size_t size) +{ + bool ret = false; + auto buff = (char *)mallocImpl(size); + if (size == stream.readBytes(buff, size)) + { + setCACert(buff); + ret = true; + } + freeImpl(&buff); + return ret; +} + +bool BSSL_SSL_Client::loadCertificate(Stream &stream, size_t size) +{ + bool ret = false; + auto buff = (char *)mallocImpl(size); + if (size == stream.readBytes(buff, size)) + { + setCertificate(buff); + ret = true; + } + freeImpl(&buff); + return ret; +} + +bool BSSL_SSL_Client::loadPrivateKey(Stream &stream, size_t size) +{ + bool ret = false; + auto buff = (char *)mallocImpl(size); + if (size == stream.readBytes(buff, size)) + { + setPrivateKey(buff); + ret = true; + } + freeImpl(&buff); + return ret; +} + +int BSSL_SSL_Client::connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key) +{ + setSecure(rootCABuff, cli_cert, cli_key); + return connect(ip, port); +} + +int BSSL_SSL_Client::connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key) +{ + setSecure(rootCABuff, cli_cert, cli_key); + return connect(host, port); +} + +BSSL_SSL_Client &BSSL_SSL_Client::operator=(const BSSL_SSL_Client &other) +{ + stop(); + setClient(other._basic_client); + _use_insecure = other._use_insecure; + _timeout = other._timeout; + _handshake_timeout = other._handshake_timeout; + return *this; +} + +bool BSSL_SSL_Client::operator==(const BSSL_SSL_Client &rhs) +{ + return _basic_client == rhs._basic_client; +} + +unsigned int BSSL_SSL_Client::getTimeout() const { return _timeout; } + +void BSSL_SSL_Client::setSecure(const char *rootCABuff, const char *cli_cert, const char *cli_key) +{ + if (_esp32_ta) + { + delete _esp32_ta; + _esp32_ta = nullptr; + } + if (_esp32_chain) + { + delete _esp32_chain; + _esp32_chain = nullptr; + } + if (_esp32_sk) + { + delete _esp32_sk; + _esp32_sk = nullptr; + } + if (rootCABuff) + { + setCertificate(rootCABuff); + } + if (cli_cert && cli_key) + { + setCertificate(cli_cert); + setPrivateKey(cli_key); + } +} + +////////////////////////////////////////////////////// +// Private access +////////////////////////////////////////////////////// + +bool BSSL_SSL_Client::mProbeMaxFragmentLength(Client *probe, uint16_t len) +{ + + // Hardcoded TLS 1.2 packets used throughout + static const uint8_t clientHelloHead_P[] PROGMEM = { + 0x16, 0x03, 0x03, 0x00, 0, // TLS header, change last 2 bytes to len + 0x01, 0x00, 0x00, 0, // Last 3 bytes == length + 0x03, 0x03, // Proto version TLS 1.2 + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Random (gmtime + rand[28]) + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x00, // Session ID + }; + // Followed by our cipher-suite, generated on-the-fly + // 0x00, 0x02, // cipher suite len + // 0xc0, 0x13, // BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + static const uint8_t clientHelloTail_P[] PROGMEM = { + 0x01, 0x00, // No compression + 0x00, 26 + 14 + 6 + 5, // Extension length + 0x00, 0x0d, 0x00, 0x16, 0x00, 0x14, 0x04, 0x03, 0x03, 0x03, 0x05, 0x03, + 0x06, 0x03, 0x02, 0x03, 0x04, 0x01, 0x03, 0x01, 0x05, 0x01, 0x06, + 0x01, 0x02, 0x01, // Supported signature algorithms + 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, + 0x00, 0x1d, // Supported groups + 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, // Supported EC formats + 0x00, 0x01, // Max Frag Len + 0x00, 0x01, // len of MaxFragLen + }; + // Followed by a 1-byte MFLN size requesst + // 0x04 // 2^12 = 4K + uint8_t mfl; + + switch (len) + { + case 512: + mfl = 1; + break; + case 1024: + mfl = 2; + break; + case 2048: + mfl = 3; + break; + case 4096: + mfl = 4; + break; + default: + return false; // Invalid size + } + int ttlLen = sizeof(clientHelloHead_P) + (2 + sizeof(suites_P)) + (sizeof(clientHelloTail_P) + 1); + uint8_t *clientHello = (uint8_t *)mallocImpl(ttlLen); + if (!clientHello) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("OOM error."), _debug_level, esp_ssl_debug_error, __func__); +#endif + return false; + } + memcpy_P(clientHello, clientHelloHead_P, sizeof(clientHelloHead_P)); + clientHello[sizeof(clientHelloHead_P) + 0] = sizeof(suites_P) >> 8; // MSB byte len + clientHello[sizeof(clientHelloHead_P) + 1] = sizeof(suites_P) & 0xff; // LSB byte len + for (size_t i = 0; i < sizeof(suites_P) / sizeof(suites_P[0]); i++) + { + uint16_t flip = pgm_read_word(&suites_P[i]); + // Swap to network byte order + flip = ((flip >> 8) & 0xff) | ((flip & 0xff) << 8); + memcpy(clientHello + sizeof(clientHelloHead_P) + 2 + 2 * i, &flip, 2); + } + memcpy_P(clientHello + sizeof(clientHelloHead_P) + 2 + sizeof(suites_P), clientHelloTail_P, sizeof(clientHelloTail_P)); + clientHello[sizeof(clientHelloHead_P) + 2 + sizeof(suites_P) + sizeof(clientHelloTail_P)] = mfl; + + // Fix up TLS fragment length + clientHello[3] = (ttlLen - 5) >> 8; + clientHello[4] = (ttlLen - 5) & 0xff; + // Fix up ClientHello message length + clientHello[7] = (ttlLen - 5 - 4) >> 8; + clientHello[8] = (ttlLen - 5 - 4) & 0xff; + + int ret = probe->write(clientHello, ttlLen); + freeImpl(&clientHello); // We're done w/the hello message + if (!probe->connected() || (ret != ttlLen)) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Protocol error."), _debug_level, esp_ssl_debug_error, __func__); +#endif + return false; + } + + bool supportsLen = false; + uint8_t fragResp[5]; + int fragLen; + uint8_t hand[4]; + int handLen; + uint8_t protoVer[2]; + uint8_t rand[32]; + uint8_t sessionLen; + uint8_t cipher[2]; + uint8_t comp; + uint8_t extBytes[2]; + uint16_t extLen; + + ret = probe->readBytes(fragResp, 5); + if (!probe->connected() || (ret != 5) || (fragResp[0] != 0x16) || (fragResp[1] != 0x03) || (fragResp[2] != 0x03)) + { + // Short read, not a HANDSHAKE or not TLS 1.2, so it's not supported + return send_abort(probe, supportsLen); + } + fragLen = (fragResp[3] << 8) | fragResp[4]; + if (fragLen < 4 + 2 + 32 + 1 + 2 + 1) + { + // Too short to have an extension + return send_abort(probe, supportsLen); + } + + ret = probe->readBytes(hand, 4); + fragLen -= ret; + if ((ret != 4) || (hand[0] != 2)) + { + // Short read or not server_hello + return send_abort(probe, supportsLen); + } + handLen = (hand[1] << 16) | (hand[2] << 8) | hand[3]; + if (handLen != fragLen) + { + // Got some weird mismatch, this is invalid + return send_abort(probe, supportsLen); + } + + ret = probe->readBytes(protoVer, 2); + handLen -= ret; + if ((ret != 2) || (protoVer[0] != 0x03) || (protoVer[1] != 0x03)) + { + // Short read or not tls 1.2, so can't do MFLN + return send_abort(probe, supportsLen); + } + + ret = probe->readBytes(rand, 32); + handLen -= ret; + if (ret != 32) + { + // short read of random data + return send_abort(probe, supportsLen); + } + + ret = probe->readBytes(&sessionLen, 1); + handLen -= ret; + if ((ret != 1) || (sessionLen > 32)) + { + // short read of session len or invalid size + return send_abort(probe, supportsLen); + } + if (sessionLen) + { + ret = probe->readBytes(rand, sessionLen); + handLen -= ret; + if (ret != sessionLen) + { + // short session id read + return send_abort(probe, supportsLen); + } + } + + ret = probe->readBytes(cipher, 2); + handLen -= ret; + if (ret != 2) + { + // Short read...we don't check the cipher here + return send_abort(probe, supportsLen); + } + + ret = probe->readBytes(&comp, 1); + handLen -= ret; + if ((ret != 1) || comp != 0) + { + // short read or invalid compression + return send_abort(probe, supportsLen); + } + + ret = probe->readBytes(extBytes, 2); + handLen -= ret; + extLen = extBytes[1] | (extBytes[0] << 8); + if ((extLen == 0) || (ret != 2)) + { + return send_abort(probe, supportsLen); + } + + while (handLen > 0) + { + // Parse each extension and look for MFLN + uint8_t typeBytes[2]; + ret = probe->readBytes(typeBytes, 2); + handLen -= 2; + if ((ret != 2) || (handLen <= 0)) + { + return send_abort(probe, supportsLen); + } + uint8_t lenBytes[2]; + ret = probe->readBytes(lenBytes, 2); + handLen -= 2; + uint16_t extLen = lenBytes[1] | (lenBytes[0] << 8); + if ((ret != 2) || (handLen <= 0) || (extLen > 32) || (extLen > handLen)) + { + return send_abort(probe, supportsLen); + } + if ((typeBytes[0] == 0x00) && (typeBytes[1] == 0x01)) + { // MFLN extension! + // If present and 1-byte in length, it's supported + return send_abort(probe, extLen == 1 ? true : false); + } + // Skip the extension, move to next one + uint8_t junk[32]; + ret = probe->readBytes(junk, extLen); + handLen -= extLen; + if (ret != extLen) + { + return send_abort(probe, supportsLen); + } + } + return send_abort(probe, supportsLen); +} + +bool BSSL_SSL_Client::mProbeMaxFragmentLength(const char *name, IPAddress ip, uint16_t port, uint16_t len) +{ + if (!mIsClientInitialized(false)) + return false; + + _basic_client->stop(); + + if (!(name ? _basic_client->connect(name, port) : _basic_client->connect(ip, port))) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Can't connect."), _debug_level, esp_ssl_debug_error, __func__); +#endif + return false; + } + + bool ret = mProbeMaxFragmentLength(_basic_client, len); + _basic_client->stop(); + return ret; +} + +int BSSL_SSL_Client::mIsClientInitialized(bool notify) +{ + if (!_basic_client) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + if (notify) + esp_ssl_debug_print(PSTR("Basic client is not yet initialized."), _debug_level, esp_ssl_debug_error, __func__); +#endif + return 0; + } + return 1; +} + +int BSSL_SSL_Client::mConnectBasicClient(const char *host, IPAddress ip, uint16_t port) +{ + + if (!mConnectionValidate(host, ip, port)) + return 0; + + if (!(host ? _basic_client->connect(host, port) : _basic_client->connect(ip, port))) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Failed to connect to server using basic client."), _debug_level, esp_ssl_debug_error, __func__); +#endif + setWriteError(esp_ssl_connection_fail); + mFreeSSL(); + return 0; + } + + _secure = false; + _write_idx = 0; +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Basic client connected!"), _debug_level, esp_ssl_debug_info, __func__); +#endif + return 1; +} + +bool BSSL_SSL_Client::mSoftConnected(const char *func_name) +{ + // check if the socket is still open and such + if (getWriteError()) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Cannot operate if the write error is not reset."), _debug_level, esp_ssl_debug_error, func_name); + mPrintClientError(getWriteError(), esp_ssl_debug_error, func_name); +#endif + return false; + } + // check if the ssl engine is still open + if (!_is_connected || br_ssl_engine_current_state(_eng) == BR_SSL_CLOSED) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Cannot operate on a closed SSL connection."), _debug_level, esp_ssl_debug_error, func_name); + int error = br_ssl_engine_last_error(_eng); + if (error != BR_ERR_OK) + mPrintSSLError(error, esp_ssl_debug_error, func_name); +#endif + return false; + } + return true; +} + +int BSSL_SSL_Client::mConnectSSL(const char *host) +{ + +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Start connection."), _debug_level, esp_ssl_debug_info, __func__); +#endif + mFreeSSL(); + _oom_err = false; + +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + // BearSSL will reject all connections unless an authentication option is set, warn in DEBUG builds +#if defined(ESP_SSL_FS_SUPPORTED) +#define CRTSTORECOND &&!_certStore +#else +#define CRTSTORECOND +#endif + if (!_use_insecure && !_use_fingerprint && !_use_self_signed && !_knownkey CRTSTORECOND && !_ta) + { + esp_ssl_debug_print(PSTR("Connection *will* fail, no authentication method is setup."), _debug_level, esp_ssl_debug_warn, __func__); + } +#endif + + _sc = std::make_shared(); + _eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr + + _iobuf_in = (unsigned char *)mallocImpl(_iobuf_in_size); + _iobuf_out = (unsigned char *)mallocImpl(_iobuf_out_size); + + if (!_sc || !_iobuf_in || !_iobuf_out) + { + mFreeSSL(); // Frees _sc, _iobuf* + _oom_err = true; +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("OOM error."), _debug_level, esp_ssl_debug_error, __func__); +#endif + return 0; + } + + // If no cipher list yet set, use defaults + if (!_cipher_list) + bssl::br_ssl_client_base_init(_sc.get(), suites_P, sizeof(suites_P) / sizeof(suites_P[0])); + else + bssl::br_ssl_client_base_init(_sc.get(), _cipher_list, _cipher_cnt); + + // Only failure possible in the installation is OOM + if (!mInstallClientX509Validator()) + { + mFreeSSL(); + _oom_err = true; +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Can't install x509 validator."), _debug_level, esp_ssl_debug_error, __func__); +#endif + return 0; + } + + br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in, _iobuf_in_size, _iobuf_out, _iobuf_out_size); + br_ssl_engine_set_versions(_eng, _tls_min, _tls_max); + + // Apply any client certificates, if supplied. + if (_sk && _sk->isRSA()) + { + br_ssl_client_set_single_rsa(_sc.get(), _chain ? _chain->getX509Certs() : nullptr, _chain ? _chain->getCount() : 0, + _sk->getRSA(), br_rsa_pkcs1_sign_get_default()); + } + else if (_sk && _sk->isEC()) + { +#ifndef BEARSSL_SSL_BASIC + br_ssl_client_set_single_ec(_sc.get(), _chain ? _chain->getX509Certs() : nullptr, _chain ? _chain->getCount() : 0, + _sk->getEC(), _allowed_usages, + _cert_issuer_key_type, br_ec_get_default(), br_ecdsa_sign_asn1_get_default()); +#else + mFreeSSL(); +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Attempting to use EC cert in minimal cipher mode (no EC)."), _debug_level, esp_ssl_debug_error, __func__); +#endif + return 0; +#endif + } + else if (_esp32_sk && _esp32_chain) + { + br_ssl_client_set_single_rsa(_sc.get(), _esp32_chain->getX509Certs(), _esp32_chain->getCount(), + _esp32_sk->getRSA(), br_rsa_pkcs1_sign_get_default()); + } + + // clear the write error + setWriteError(esp_ssl_ok); + + // we want 128 bits to be safe, as recommended by the bearssl docs + uint8_t rng_seeds[16]; + + // prng + for (uint8_t i = 0; i < sizeof rng_seeds; i++) + rng_seeds[i] = static_cast(random(256)); + + br_ssl_engine_inject_entropy(_eng, rng_seeds, sizeof rng_seeds); + + // Restore session from the storage spot, if present + if (_session) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Set SSL session!"), _debug_level, esp_ssl_debug_info, __func__); +#endif + br_ssl_engine_set_session_parameters(_eng, _session->getSession()); + } + + if (!br_ssl_client_reset(_sc.get(), host, _session ? 1 : 0)) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Can't reset client."), _debug_level, esp_ssl_debug_error, __func__); + mPrintSSLError(br_ssl_engine_last_error(_eng), esp_ssl_debug_error, __func__); +#endif + setWriteError(esp_ssl_connection_fail); + mFreeSSL(); + return 0; + } + +// SSL/TLS handshake +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Wait for SSL handshake."), _debug_level, esp_ssl_debug_info, __func__); +#endif + + if (mRunUntil(BR_SSL_SENDAPP, _handshake_timeout) < 0) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Failed to initlalize the SSL layer."), _debug_level, esp_ssl_debug_error, __func__); + mPrintSSLError(br_ssl_engine_last_error(_eng), esp_ssl_debug_error, __func__); +#endif + mFreeSSL(); + return 0; + } + +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Connection successful!"), _debug_level, esp_ssl_debug_info, __func__); +#endif + _handshake_done = true; + _is_connected = true; + _secure = true; + + // Save session + if (_session) + br_ssl_engine_get_session_parameters(_eng, _session->getSession()); + + // Session is already validated here, there is no need to keep following + _x509_minimal = nullptr; + _x509_insecure = nullptr; + _x509_knownkey = nullptr; + + return 1; +} + +bool BSSL_SSL_Client::mConnectionValidate(const char *host, IPAddress ip, uint16_t port) +{ + if (!mIsClientInitialized(true)) + return false; + + if (_basic_client && _basic_client->connected() && + host + ? (strcasecmp(host, _host.c_str()) != 0 || port != _port) + : (ip != _ip || port != _port)) + { + _basic_client->stop(); + } + + return true; +} + +int BSSL_SSL_Client::mRunUntil(const unsigned target, unsigned long timeout) +{ + unsigned lastState = 0; + size_t lastLen = 0; + const unsigned long start = millis(); + for (;;) + { + unsigned state = mUpdateEngine(); + // error check + if (state == BR_SSL_CLOSED || getWriteError() != esp_ssl_ok) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + if (state == BR_SSL_CLOSED) + esp_ssl_debug_print(PSTR("Terminating because the ssl engine closed."), _debug_level, esp_ssl_debug_warn, __func__); + else + esp_ssl_debug_print(PSTR("Terminating with write error."), _debug_level, esp_ssl_debug_warn, __func__); +#endif + return -1; + } + // timeout check + if (millis() - start > ((timeout > 0) ? timeout : getTimeout())) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("SSL internals timed out!"), _debug_level, esp_ssl_debug_error, __func__); +#endif + setWriteError(esp_ssl_write_error); + stop(); + return -1; + } + // debug + if (state != lastState || lastState == 0) + { + lastState = state; +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("SSL state changed."), _debug_level, esp_ssl_debug_info, __func__); + mPrintSSLState(state, esp_ssl_debug_info, __func__); +#endif + } + if (state & BR_SSL_RECVREC) + { + size_t len; + br_ssl_engine_recvrec_buf(_eng, &len); + if (lastLen != len) + { + lastLen = len; +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + String s = PSTR("Expected bytes count: "); + s += len; + esp_ssl_debug_print(s.c_str(), _debug_level, esp_ssl_debug_info, __func__); +#endif + } + } + /* + * If we reached our target, then we are finished. + */ + if (state & target || (target == 0 && state == 0)) + return 0; + + /* + * If some application data must be read, and we did not + * exit, then this means that we are trying to write data, + * and that's not possible until the application data is + * read. This may happen if using a shared in/out buffer, + * and the underlying protocol is not strictly half-duplex. + * Normally this would be unrecoverable, however we can attempt + * to remedy the problem by telling the engine to discard + * the data. + */ + if (state & BR_SSL_RECVAPP) + { + _recvapp_buf = br_ssl_engine_recvapp_buf(_eng, &_recvapp_len); + if (_recvapp_buf != nullptr) + { + // if application data is ready in buffer, don't ignore, just return. + + // _write_idx = 0; + // esp_ssl_debug_print(PSTR("Discarded unread data to favor a write operation."), _debug_level, esp_ssl_debug_warn, __func__); + // br_ssl_engine_recvapp_ack(_eng, len); + // continue; + return 0; + } + else + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("SSL engine state is RECVAPP, however the buffer was null! (This is a problem with BearSSL internals)."), _debug_level, esp_ssl_debug_error, __func__); +#endif + setWriteError(esp_ssl_write_error); + stop(); + return -1; + } + } + + if (target & BR_SSL_SENDAPP) + { + // reset the write index + _write_idx = 0; + continue; + } + + /* + * We can reach that point if the target RECVAPP, and + * the state contains SENDAPP only. This may happen with + * a shared in/out buffer. In that case, we must flush + * the buffered data to "make room" for a new incoming + * record. + */ + if (state & BR_SSL_SENDAPP && target & BR_SSL_RECVAPP) + br_ssl_engine_flush(_eng, 0); + } +} + +unsigned BSSL_SSL_Client::mUpdateEngine() +{ + for (;;) + { + // get the state + unsigned state = br_ssl_engine_current_state(_eng); + // debug + if (_bssl_last_state == 0 || state != _bssl_last_state) + { + _bssl_last_state = state; +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + mPrintSSLState(state, esp_ssl_debug_info, __func__); +#endif + } + if (state & BR_SSL_CLOSED) + return state; + /* + * If there is some record data to send, do it. This takes + * precedence over everything else. + */ + if (state & BR_SSL_SENDREC) + { + unsigned char *buf; + size_t len; + int wlen; + + buf = br_ssl_engine_sendrec_buf(_eng, &len); + wlen = _basic_client->write(buf, len); + _basic_client->flush(); + if (wlen <= 0) + { + // if the arduino client encountered an error + if (_basic_client->getWriteError() || !_basic_client->connected()) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Error writing to basic client."), _debug_level, esp_ssl_debug_error, __func__); +#endif + setWriteError(esp_ssl_write_error); + } + // else presumably the socket just closed itself, so just stop the engine + stop(); + return 0; + } + if (wlen > 0) + { + br_ssl_engine_sendrec_ack(_eng, wlen); + } + continue; + } + + /* + * If the client has specified there is client data to send, and + * the engine is ready to handle it, send it along. + */ + if (_write_idx > 0) + { + // if we've reached the point where BR_SSL_SENDAPP is off but + // data has been written to the io buffer, something is wrong + if (!(state & BR_SSL_SENDAPP)) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Error _write_idx > 0 but the ssl engine is not ready for data."), _debug_level, esp_ssl_debug_error, __func__); +#endif + setWriteError(esp_ssl_write_error); + stop(); + return 0; + } + // else time to send the application data + else if (state & BR_SSL_SENDAPP) + { + size_t alen; + unsigned char *buf = br_ssl_engine_sendapp_buf(_eng, &alen); + // engine check + if (alen == 0 || buf == nullptr) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Engine set write flag but returned null buffer."), _debug_level, esp_ssl_debug_error, __func__); +#endif + setWriteError(esp_ssl_write_error); + stop(); + return 0; + } + // sanity check + if (alen < _write_idx) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("Alen is less than _write_idx."), _debug_level, esp_ssl_debug_error, __func__); +#endif + setWriteError(esp_ssl_internal_error); + stop(); + return 0; + } + // all good? lets send the data + // presumably the BSSL_SSL_Client::write function has already added + // data to *buf, so now we tell bearssl it's time for the + // encryption step. + // this will encrypt the data and presumably spit it out + // for BR_SSL_SENDREC to send over ethernet. + br_ssl_engine_sendapp_ack(_eng, _write_idx); + // reset the iobuffer index + _write_idx = 0; + // loop again! + continue; + } + } + + /* + * If there is some record data to recieve, check if we've + * recieved it so far. If we have, then we can update the state. + * else we can return that we're still waiting for the server. + */ + if (state & BR_SSL_RECVREC) + { + size_t len; + unsigned char *buf = br_ssl_engine_recvrec_buf(_eng, &len); + // do we have the record you're looking for? + const auto avail = _basic_client->available(); + if (avail > 0) + { + // I suppose so! + int rlen = _basic_client->read(buf, avail < (int)len ? avail : (int)len); + if (rlen <= 0) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + String s = PSTR("Error reading bytes from basic client. Write Error: "); + s += _basic_client->getWriteError(); + esp_ssl_debug_print(s.c_str(), _debug_level, esp_ssl_debug_error, __func__); +#endif + setWriteError(esp_ssl_write_error); + stop(); + return 0; + } + if (rlen > 0) + { + br_ssl_engine_recvrec_ack(_eng, rlen); + } + continue; + } + // guess not, tell the state we're waiting still + else + { + +#if defined __has_include +#if __has_include() + // Add a delay since spamming _basic_client->availible breaks the poor wiz chip + delay(10); +#endif +#endif + return state; + } + } + // if it's not any of the above states, then it must be waiting to send or recieve app data + // in which case we return + return state; + } +} + +void BSSL_SSL_Client::mPrintClientError(const int ssl_error, int level, const char *func_name) +{ +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + const char *msg = nullptr; + + switch (ssl_error) + { + case esp_ssl_ok: + msg = PSTR("SSL OK"); + break; + case esp_ssl_connection_fail: + msg = PSTR("SSL Connection fail"); + break; + case esp_ssl_write_error: + msg = PSTR("SSL Write error"); + break; + case esp_ssl_read_error: + msg = PSTR("SSL Read error"); + break; + case esp_ssl_out_of_memory: + msg = PSTR("SSL OOM error"); + break; + case esp_ssl_internal_error: + msg = PSTR("SSL Internal error"); + break; + } + + esp_ssl_debug_print(msg, _debug_level, level, func_name); +#endif +} + +void BSSL_SSL_Client::mPrintSSLError(const unsigned br_error_code, int level, const char *func_name) +{ +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + char dest[300]; + getLastSSLError(dest, 300); + esp_ssl_debug_print(dest, _debug_level, level, func_name); +#endif +} + +void BSSL_SSL_Client::mPrintSSLState(const unsigned state, int level, const char *func_name) +{ +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + const char *msg = nullptr; + + if (state == 0) + msg = PSTR("State Invalid"); + else if (state & BR_SSL_CLOSED) + msg = PSTR("State Connection close"); + else + { + if (state & BR_SSL_SENDREC) + msg = PSTR("State SENDREC"); + if (state & BR_SSL_RECVREC) + msg = PSTR("State RECVREC"); + if (state & BR_SSL_SENDAPP) + msg = PSTR("State SENDAPP"); + if (state & BR_SSL_RECVAPP) + msg = PSTR("State RECVAPP"); + } + + esp_ssl_debug_print(msg, _debug_level, level, func_name); +#endif +} + +bool BSSL_SSL_Client::mIsSecurePort(uint16_t port) +{ + int size = *(&_secure_ports + 1) - _secure_ports; + for (int i = 0; i < size; i++) + { + if (port == _secure_ports[i]) + return true; + } + + return false; +} + +void BSSL_SSL_Client::mBSSLX509InsecureInit(bssl::br_x509_insecure_context *ctx, int _use_fingerprint, const uint8_t _fingerprint[20], int _allow_self_signed) +{ + static const br_x509_class br_x509_insecure_vtable PROGMEM = { + sizeof(bssl::br_x509_insecure_context), + bssl::insecure_start_chain, + bssl::insecure_start_cert, + bssl::insecure_append, + bssl::insecure_end_cert, + bssl::insecure_end_chain, + bssl::insecure_get_pkey}; + + memset(ctx, 0, sizeof *ctx); + ctx->vtable = &br_x509_insecure_vtable; + ctx->done_cert = false; + ctx->match_fingerprint = _use_fingerprint ? _fingerprint : nullptr; + ctx->allow_self_signed = _allow_self_signed ? 1 : 0; +} + +void BSSL_SSL_Client::mClearAuthenticationSettings() +{ + _use_insecure = false; + _use_fingerprint = false; + _use_self_signed = false; + _knownkey = nullptr; + _ta = nullptr; + if (_esp32_ta) + { + delete _esp32_ta; + _esp32_ta = nullptr; + } +} + +void BSSL_SSL_Client::mClear() +{ + _timeout = 15000; + _sc = nullptr; + _eng = nullptr; + _x509_minimal = nullptr; + _x509_insecure = nullptr; + _x509_knownkey = nullptr; + + freeImpl(&_iobuf_in); + freeImpl(&_iobuf_out); + _now = 0; // You can override or ensure time() is correct w/configTime + _ta = nullptr; + setBufferSizes(16384, 512); // Minimum safe + _secure = false; + _recvapp_buf = nullptr; + _recvapp_len = 0; + _oom_err = false; + _session = nullptr; + freeImpl(&_cipher_list); + _cipher_cnt = 0; + _tls_min = BR_TLS10; + _tls_max = BR_TLS12; + if (_esp32_ta) + { + delete _esp32_ta; + _esp32_ta = nullptr; + } +} + +// X.509 validators differ from server to client +// Installs the appropriate X509 cert validation method for a client connection +bool BSSL_SSL_Client::mInstallClientX509Validator() +{ + + if (_use_insecure || _use_fingerprint || _use_self_signed) + { + // Use common insecure x509 authenticator + _x509_insecure = std::make_shared(); + if (!_x509_insecure) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("OOM for _x509_insecure"), _debug_level, esp_ssl_debug_error, __func__); +#endif + return false; + } + mBSSLX509InsecureInit(_x509_insecure.get(), _use_fingerprint, _fingerprint, _use_self_signed); + br_ssl_engine_set_x509(_eng, &_x509_insecure->vtable); + } + else if (_knownkey) + { + // Simple, pre-known public key authenticator, ignores cert completely. + _x509_knownkey = std::make_shared(); + if (!_x509_knownkey) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("OOM for _x509_knownkey"), _debug_level, esp_ssl_debug_error, __func__); +#endif + return false; + } + if (_knownkey->isRSA()) + { + br_x509_knownkey_init_rsa(_x509_knownkey.get(), _knownkey->getRSA(), _knownkey_usages); + } + else if (_knownkey->isEC()) + { +#ifndef BEARSSL_SSL_BASIC + br_x509_knownkey_init_ec(_x509_knownkey.get(), _knownkey->getEC(), _knownkey_usages); +#else + (void)_knownkey; + (void)_knownkey_usages; + esp_ssl_debug_print(PSTR("Attempting to use EC keys in minimal cipher mode (no EC)"), _debug_level, esp_ssl_debug_error, __func__); + return false; +#endif + } + br_ssl_engine_set_x509(_eng, &_x509_knownkey->vtable); + } + else + { + // X509 minimal validator. Checks dates, cert chain for trusted CA, etc. + _x509_minimal = std::make_shared(); + if (!_x509_minimal) + { +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + esp_ssl_debug_print(PSTR("OOM for _x509_minimal"), _debug_level, esp_ssl_debug_error, __func__); +#endif + return false; + } + if (_esp32_ta) + { + br_x509_minimal_init(_x509_minimal.get(), &br_sha256_vtable, _esp32_ta->getTrustAnchors(), _esp32_ta->getCount()); + } + else + { + br_x509_minimal_init(_x509_minimal.get(), &br_sha256_vtable, _ta ? _ta->getTrustAnchors() : nullptr, _ta ? _ta->getCount() : 0); + } + br_x509_minimal_set_rsa(_x509_minimal.get(), br_ssl_engine_get_rsavrfy(_eng)); +#ifndef BEARSSL_SSL_BASIC + br_x509_minimal_set_ecdsa(_x509_minimal.get(), br_ssl_engine_get_ec(_eng), br_ssl_engine_get_ecdsa(_eng)); +#endif + bssl::br_x509_minimal_install_hashes(_x509_minimal.get()); + +#if (defined(ESP32) || defined(ESP8266) || defined(ARDUINO_ARCH_RP2040)) && !defined(ARDUINO_NANO_RP2040_CONNECT) + if (_now < ESP_SSLCLIENT_VALID_TIMESTAMP) + _now = time(nullptr); +#endif + if (_now) + { + // Magic constants convert to x509 times + br_x509_minimal_set_time(_x509_minimal.get(), ((uint32_t)_now) / 86400 + 719528, ((uint32_t)_now) % 86400); + } +#if defined(ESP_SSL_FS_SUPPORTED) + if (_certStore) + { + _certStore->installCertStore(_x509_minimal.get()); + } +#endif + br_ssl_engine_set_x509(_eng, &_x509_minimal->vtable); + } + return true; +} + +void BSSL_SSL_Client::mFreeSSL() +{ + // These are smart pointers and will free if refcnt==0 + _sc = nullptr; + _x509_minimal = nullptr; + _x509_insecure = nullptr; + _x509_knownkey = nullptr; + freeImpl(&_iobuf_in); + freeImpl(&_iobuf_out); + // Reset non-allocated ptrs (pointing to bits potentially free'd above) + _recvapp_buf = nullptr; + _recvapp_len = 0; + // This connection is toast + _handshake_done = false; + _timeout = 15000; + _secure = false; + _is_connected = false; +} + +uint8_t *BSSL_SSL_Client::mStreamLoad(Stream &stream, size_t size) +{ + uint8_t *dest = (uint8_t *)malloc(size + 1); + if (!dest) + { + return nullptr; + } + if (size != stream.readBytes(dest, size)) + { + free(dest); + dest = nullptr; + return nullptr; + } + dest[size] = '\0'; + return dest; +} + +// Allocate memory +void *BSSL_SSL_Client::mallocImpl(size_t len, bool clear) +{ + void *p; + size_t newLen = getReservedLen(len); +#if defined(BOARD_HAS_PSRAM) && defined(ESP_SSLCLIENT_USE_PSRAM) + + if (ESP.getPsramSize() > 0) + p = (void *)ps_malloc(newLen); + else + p = (void *)malloc(newLen); + + if (!p) + return NULL; + +#else + +#if defined(ESP_SSLCLIENT_ESP8266_USE_EXTERNAL_HEAP) + ESP.setExternalHeap(); +#endif + + p = (void *)malloc(newLen); + bool nn = p ? true : false; + +#if defined(ESP_SSLCLIENT_ESP8266_USE_EXTERNAL_HEAP) + ESP.resetHeap(); +#endif + + if (!nn) + return NULL; + +#endif + if (clear) + memset(p, 0, newLen); + return p; +} + +// Free reserved memory at pointer. +void BSSL_SSL_Client::freeImpl(void *ptr) +{ + void **p = (void **)ptr; + if (*p) + { + free(*p); + *p = 0; + } +} + +size_t BSSL_SSL_Client::getReservedLen(size_t len) +{ + int blen = len + 1; + + int newlen = (blen / 4) * 4; + + if (newlen < blen) + newlen += 4; + + return (size_t)newlen; +} + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_SSL_Client.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_SSL_Client.h new file mode 100644 index 000000000000..98a42685d898 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_SSL_Client.h @@ -0,0 +1,349 @@ +/** + * BSSL_SSL_Client library v1.0.11 for Arduino devices. + * + * Created August 27, 2003 + * + * This work contains codes based on WiFiClientSecure from Earle F. Philhower and SSLClient from OSU OPEnS Lab. + * + * Copyright (c) 2018 Earle F. Philhower, III + * + * Copyright 2019 OSU OPEnS Lab + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef BSSL_SSL_CLIENT_H +#define BSSL_SSL_CLIENT_H + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wvla" + +#include +#include "../ESP_SSLClient_FS.h" +#include "../ESP_SSLClient_Const.h" +#if defined(USE_LIB_SSL_ENGINE) || defined(USE_EMBED_SSL_ENGINE) + +#include +#include +#if defined __has_include +#if __has_include() +#include +#endif +#endif + +#if defined(USE_LIB_SSL_ENGINE) + +#include "BSSL_Helper.h" +#include "BSSL_CertStore.h" + +using namespace bssl; + +#elif defined(USE_EMBED_SSL_ENGINE) + +#include "BearSSLHelpers.h" +#include "BSSL_Helper.h" +#include "CertStoreBearSSL.h" + +using namespace BearSSL; + +#include + +#if defined(ESP8266) + +#include "PolledTimeout.h" +#if defined(ESP8266_CORE_SDK_V3_X_X) +#include +#endif + +#if __has_include() +#include +#endif + +#endif + +#endif + +class BSSL_SSL_Client : public Client +{ +public: + explicit BSSL_SSL_Client(Client *client = nullptr); + + ~BSSL_SSL_Client(); + + void setClient(Client *client, bool ssl = false); + + void setDebugLevel(int level); + + int connect(IPAddress ip, uint16_t port) override; + + int connect(const char *host, uint16_t port) override; + + uint8_t connected() override; + + void validate(const char *host, uint16_t port); + + void validate(IPAddress ip, uint16_t port); + + int available() override; + + int read() override; + + int read(uint8_t *buf, size_t size) override; + + size_t write(const uint8_t *buf, size_t size) override; + + size_t write(uint8_t b) override; + + size_t write_P(PGM_P buf, size_t size); + + size_t write(Stream &stream); + + int peek() override; + + size_t peekBytes(uint8_t *buffer, size_t length); + + void setInsecure(); + + void enableSSL(bool enable); + + int connectSSL(IPAddress ip, uint16_t port); + + int connectSSL(const char *host, uint16_t port); + + void stop() override; + + void setTimeout(unsigned int timeoutMs); + + void setHandshakeTimeout(unsigned int timeoutMs); + + void flush() override; + + void setBufferSizes(int recv, int xmit); + + operator bool() { return connected() > 0; } + + int availableForWrite(); + + void setSession(BearSSL_Session *session); + + void setKnownKey(const PublicKey *pk, unsigned usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN); + + bool setFingerprint(const uint8_t fingerprint[20]); + + bool setFingerprint(const char *fpStr); + + void allowSelfSignedCerts(); + + void setTrustAnchors(const X509List *ta); + + void setX509Time(time_t now); + + void setClientRSACert(const X509List *chain, const PrivateKey *sk); + + void setClientECCert(const X509List *chain, const PrivateKey *sk, unsigned allowed_usages, unsigned cert_issuer_key_type); + + int getMFLNStatus(); + + int getLastSSLError(char *dest, size_t len); +#if defined(ESP_SSL_FS_SUPPORTED) + void setCertStore(CertStoreBase *certStore); +#endif + bool setCiphers(const uint16_t *cipherAry, int cipherCount); + + bool setCiphers(const std::vector &list); + + bool setCiphersLessSecure(); + + bool setSSLVersion(uint32_t min, uint32_t max); + + bool probeMaxFragmentLength(IPAddress ip, uint16_t port, uint16_t len); + + bool probeMaxFragmentLength(const char *hostname, uint16_t port, uint16_t len); + + bool probeMaxFragmentLength(const String &host, uint16_t port, uint16_t len); + + size_t peekAvailable(); + + const char *peekBuffer(); + + void peekConsume(size_t consume); + + void setCACert(const char *rootCA); + + void setCertificate(const char *client_ca); + + void setPrivateKey(const char *private_key); + + bool loadCACert(Stream &stream, size_t size); + + bool loadCertificate(Stream &stream, size_t size); + + bool loadPrivateKey(Stream &stream, size_t size); + + int connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key); + + int connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key); + + BSSL_SSL_Client &operator=(const BSSL_SSL_Client &other); + + bool operator==(const bool value) { return bool() == value; } + + bool operator!=(const bool value) { return bool() != value; } + + bool operator==(const BSSL_SSL_Client &); + + bool operator!=(const BSSL_SSL_Client &rhs) { return !this->operator==(rhs); }; + + unsigned int getTimeout() const; + + void setSecure(const char *rootCABuff, const char *cli_cert, const char *cli_key); + +private: + // Checks for support of Maximum Frame Length Negotiation at the given + // blocksize. Note that, per spec, only 512, 1024, 2048, and 4096 are + // supported. Many servers today do not support this negotiation. + + // TODO - Allow for fragmentation...but not very critical as the ServerHello + // we use comes to < 80 bytes which has no reason to ever be fragmented. + // TODO - Check the type of returned extensions and that the MFL is the exact + // same one we sent. Not critical as only horribly broken servers would + // return changed or add their own extensions. + bool mProbeMaxFragmentLength(Client *probe, uint16_t len); + + bool mProbeMaxFragmentLength(const char *name, IPAddress ip, uint16_t port, uint16_t len); + + int mIsClientInitialized(bool notify); + + int mConnectBasicClient(const char *host, IPAddress ip, uint16_t port); + // Returns whether or not the engine is connected, without polling the client over SPI or other (as opposed to connected()) + bool mSoftConnected(const char *func_name); + + int mConnectSSL(const char *host = nullptr); + + bool mConnectionValidate(const char *host, IPAddress ip, uint16_t port); + + int mRunUntil(const unsigned target, unsigned long timeout = 0); + + unsigned mUpdateEngine(); + + void mPrintClientError(const int ssl_error, int level, const char *func_name); + + void mPrintSSLError(const unsigned br_error_code, int level, const char *func_name); + + void mPrintSSLState(const unsigned br_state, int level, const char *func_name); + + bool mIsSecurePort(uint16_t port); + + void mBSSLX509InsecureInit(bssl::br_x509_insecure_context *ctx, int _use_fingerprint, const uint8_t _fingerprint[20], int _allow_self_signed); + + void mClearAuthenticationSettings(); + + void mClear(); + + bool mInstallClientX509Validator(); + + void mFreeSSL(); + + uint8_t *mStreamLoad(Stream &stream, size_t size); + + void *mallocImpl(size_t len, bool clear = true); + + void freeImpl(void *ptr); + + size_t getReservedLen(size_t len); + + // store whether to enable debug logging + int _debug_level = 0; + + bool _is_connected; + + // store the index of where we are writing in the buffer + // so we can send our records all at once to prevent + // weird timing issues + size_t _write_idx; + + // store the last BearSSL state so we can print changes to the console + unsigned _bssl_last_state; + + bool _secure = false; + + Client *_basic_client = nullptr; + + std::shared_ptr _sc; + br_ssl_engine_context *_eng = nullptr; // &_sc->eng, to allow for client or server contexts + std::shared_ptr _x509_minimal; + std::shared_ptr _x509_insecure; + std::shared_ptr _x509_knownkey; + + unsigned char *_iobuf_in = nullptr; + unsigned char *_iobuf_out = nullptr; + int _iobuf_in_size = 512; + int _iobuf_out_size = 512; + + time_t _now = 0; + const X509List *_ta = nullptr; +#if defined(ESP_SSL_FS_SUPPORTED) + CertStoreBase *_certStore = 0; +#endif + // Optional client certificate + const X509List *_chain = nullptr; + const PrivateKey *_sk = nullptr; + unsigned int _allowed_usages = 0; + unsigned int _cert_issuer_key_type = 0; + + // Optional storage space pointer for session parameters + // Will be used on connect and updated on close + BearSSL_Session *_session = nullptr; + + bool _use_insecure = false; + bool _use_fingerprint = false; + uint8_t _fingerprint[20]; + bool _use_self_signed = false; + const PublicKey *_knownkey; + unsigned int _knownkey_usages = 0; + + // Custom cipher list pointer or nullptr if default + uint16_t *_cipher_list = nullptr; + uint8_t _cipher_cnt = 0; + + // TLS ciphers allowed + uint32_t _tls_min = BR_TLS10; + uint32_t _tls_max = BR_TLS12; + + X509List *_esp32_ta = nullptr; + X509List *_esp32_chain = nullptr; + PrivateKey *_esp32_sk = nullptr; + + bool _handshake_done = false; + bool _oom_err = false; + unsigned char *_recvapp_buf = nullptr; + size_t _recvapp_len; + unsigned long _timeout = 15000; + unsigned long _handshake_timeout = 60000; + bool _isSSLEnabled = false; + String _host; + uint16_t _port = 0; + IPAddress _ip; +}; + +#endif + +#endif /** BSSL_SSL_Client_H */ diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_TCP_Client.cpp b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_TCP_Client.cpp new file mode 100644 index 000000000000..f9f90075fdff --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_TCP_Client.cpp @@ -0,0 +1,461 @@ +/** + * BSSL_TCP_Client v2.0.12 for Arduino devices. + * + * Created August 27, 2023 + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + WiFiClientSecure.cpp - Client Secure class for ESP32 + Copyright (c) 2016 Hristo Gochkov All right reserved. + Additions Copyright (C) 2017 Evandro Luis Copercini. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef BSSL_TCP_CLIENT_CPP +#define BSSL_TCP_CLIENT_CPP + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wvla" + +#include +#include "../ESP_SSLClient_FS.h" +#include "../ESP_SSLClient_Const.h" +#if defined(USE_LIB_SSL_ENGINE) || defined(USE_EMBED_SSL_ENGINE) + +#include "BSSL_TCP_Client.h" +// #include +// #include +// #include + +#undef connect +#undef write +#undef read + +BSSL_TCP_Client::BSSL_TCP_Client() +{ + setClient(nullptr); + _ssl_client.setTimeout(120000); + _use_insecure = false; +} + +BSSL_TCP_Client::~BSSL_TCP_Client() +{ + stop(); + setClient(nullptr); +} + +void BSSL_TCP_Client::setClient(Client *client, bool enableSSL) +{ + _basic_client = client; + _ssl_client.setClient(_basic_client, enableSSL); +} + +void BSSL_TCP_Client::setDebugLevel(int level) +{ + _ssl_client.setDebugLevel(level); +} + +int BSSL_TCP_Client::connect(IPAddress ip, uint16_t port) +{ + return connect(ip, port, 0); +} + +int BSSL_TCP_Client::connect(IPAddress ip, uint16_t port, int32_t timeout) +{ + _port = port; + + if (timeout > 0) + { + _timeout = timeout; + if (_basic_client) + _basic_client->setTimeout(_timeout); + _ssl_client.setTimeout(_timeout); + } + + return _ssl_client.connect(ip, port); +} + +int BSSL_TCP_Client::connect(const char *host, uint16_t port) +{ + return connect(host, port, 0); +} + +int BSSL_TCP_Client::connect(const char *host, uint16_t port, int32_t timeout) +{ + + _host = host; + _port = port; + + if (timeout > 0) + { + _timeout = timeout; + if (_basic_client) + _basic_client->setTimeout(_timeout); + _ssl_client.setTimeout(_timeout); + } + + return _ssl_client.connect(host, port); +} + +uint8_t BSSL_TCP_Client::connected() +{ + return _ssl_client.connected(); +} + +void BSSL_TCP_Client::validate(const char *host, uint16_t port) +{ + _ssl_client.validate(host, port); +} + +void BSSL_TCP_Client::validate(IPAddress ip, uint16_t port) +{ + _ssl_client.validate(ip, port); +} + +int BSSL_TCP_Client::available() +{ + return _ssl_client.available(); +} + +int BSSL_TCP_Client::read() +{ + uint8_t data = -1; + int res = read(&data, 1); + if (res < 0) + return res; + return data; +} + +int BSSL_TCP_Client::read(uint8_t *buf, size_t size) +{ + if (!_ssl_client.connected()) + return 0; + return _ssl_client.read(buf, size); +} + +int BSSL_TCP_Client::send(const char *data) +{ + return write((uint8_t *)data, strlen(data)); +} + +int BSSL_TCP_Client::print(const char *data) +{ + return send(data); +} + +int BSSL_TCP_Client::print(const String &data) +{ + return print(data.c_str()); +} + +int BSSL_TCP_Client::print(int data) +{ + char buf[64]; + memset(buf, 0, 64); + sprintf(buf, (const char *)FPSTR("%d"), data); + int ret = send(buf); + return ret; +} + +int BSSL_TCP_Client::println(const char *data) +{ + int len = send(data); + if (len < 0) + return len; + int sz = send((const char *)FPSTR("\r\n")); + if (sz < 0) + return sz; + return len + sz; +} + +int BSSL_TCP_Client::println(const String &data) +{ + return println(data.c_str()); +} + +int BSSL_TCP_Client::println(int data) +{ + char buf[64]; + memset(buf, 0, 64); + sprintf(buf, (const char *)FPSTR("%d\r\n"), data); + int ret = send(buf); + return ret; +} + +size_t BSSL_TCP_Client::write(const uint8_t *buf, size_t size) +{ + if (!_ssl_client.connected()) + return 0; + return _ssl_client.write(buf, size); +} + +size_t BSSL_TCP_Client::write(uint8_t data) +{ + return write(&data, 1); +} + +size_t BSSL_TCP_Client::write_P(PGM_P buf, size_t size) { return _ssl_client.write_P(buf, size); } + +size_t BSSL_TCP_Client::write(const char *buf) { return write((const uint8_t *)buf, strlen(buf)); } + +size_t BSSL_TCP_Client::write(Stream &stream) { return _ssl_client.write(stream); } + +int BSSL_TCP_Client::peek() +{ + return _ssl_client.peek(); +} + +void BSSL_TCP_Client::setInsecure() +{ + _ssl_client.setInsecure(); + _use_insecure = true; +} + +void BSSL_TCP_Client::enableSSL(bool enable) +{ + _ssl_client.enableSSL(enable); +} + +bool BSSL_TCP_Client::connectSSL() +{ + if (!_ssl_client.connectSSL(_host.c_str(), _port)) + { + stop(); + return 0; + } + return 1; +} + +bool BSSL_TCP_Client::connectSSL(const String host, uint16_t port) { return connectSSL(); } + +void BSSL_TCP_Client::stop() +{ + _ssl_client.stop(); +} + +int BSSL_TCP_Client::setTimeout(uint32_t seconds) +{ + _timeout = seconds * 1000; + _ssl_client.setTimeout(_timeout); + return 1; +} + +int BSSL_TCP_Client::getTimeout() { return _ssl_client.getTimeout() / 1000; } + +void BSSL_TCP_Client::setHandshakeTimeout(unsigned long handshake_timeout) +{ + _handshake_timeout = handshake_timeout * 1000; + _ssl_client.setHandshakeTimeout(_handshake_timeout); +} + +void BSSL_TCP_Client::flush() +{ + if (!_basic_client) + return; + + while (available() > 0) + read(); +} + +void BSSL_TCP_Client::setBufferSizes(int recv, int xmit) +{ + _ssl_client.setBufferSizes(recv, xmit); +} + +int BSSL_TCP_Client::availableForWrite() { return _ssl_client.availableForWrite(); }; + +void BSSL_TCP_Client::setSession(BearSSL_Session *session) { _ssl_client.setSession(session); }; + +void BSSL_TCP_Client::setKnownKey(const PublicKey *pk, unsigned usages) +{ + _ssl_client.setKnownKey(pk, usages); +} + +bool BSSL_TCP_Client::setFingerprint(const uint8_t fingerprint[20]) +{ + return _ssl_client.setFingerprint(fingerprint); +} + +bool BSSL_TCP_Client::setFingerprint(const char *fpStr) +{ + return _ssl_client.setFingerprint(fpStr); +} + +void BSSL_TCP_Client::allowSelfSignedCerts() +{ + _ssl_client.allowSelfSignedCerts(); +} + +void BSSL_TCP_Client::setTrustAnchors(const X509List *ta) +{ + _ssl_client.setTrustAnchors(ta); +} + +void BSSL_TCP_Client::setX509Time(time_t now) +{ + _ssl_client.setX509Time(now); +} + +void BSSL_TCP_Client::setClientRSACert(const X509List *cert, const PrivateKey *sk) +{ + _ssl_client.setClientRSACert(cert, sk); +} + +void BSSL_TCP_Client::setClientECCert(const X509List *cert, const PrivateKey *sk, unsigned allowed_usages, unsigned cert_issuer_key_type) +{ + _ssl_client.setClientECCert(cert, sk, allowed_usages, cert_issuer_key_type); +} + +int BSSL_TCP_Client::getMFLNStatus() { return _ssl_client.getMFLNStatus(); }; + +int BSSL_TCP_Client::getLastSSLError(char *dest, size_t len) +{ + return _ssl_client.getLastSSLError(dest, len); +} + +#if defined(ESP_SSL_FS_SUPPORTED) +void BSSL_TCP_Client::setCertStore(CertStoreBase *certStore) +{ + _ssl_client.setCertStore(certStore); +} +#endif + +bool BSSL_TCP_Client::setCiphers(const uint16_t *cipherAry, int cipherCount) +{ + return _ssl_client.setCiphers(cipherAry, cipherCount); +} + +bool BSSL_TCP_Client::setCiphers(const std::vector &list) +{ + return _ssl_client.setCiphers(list); +} + +bool BSSL_TCP_Client::setCiphersLessSecure() +{ + return _ssl_client.setCiphersLessSecure(); +} + +bool BSSL_TCP_Client::setSSLVersion(uint32_t min, uint32_t max) +{ + return _ssl_client.setSSLVersion(min, max); +} + +bool BSSL_TCP_Client::probeMaxFragmentLength(IPAddress ip, uint16_t port, uint16_t len) { return _ssl_client.probeMaxFragmentLength(ip, port, len); }; + +bool BSSL_TCP_Client::probeMaxFragmentLength(const char *hostname, uint16_t port, uint16_t len) { return _ssl_client.probeMaxFragmentLength(hostname, port, len); }; + +bool BSSL_TCP_Client::probeMaxFragmentLength(const String &host, uint16_t port, uint16_t len) { return _ssl_client.probeMaxFragmentLength(host, port, len); }; + +// peek buffer API is present +bool BSSL_TCP_Client::hasPeekBufferAPI() const { return true; } + +// return number of byte accessible by peekBuffer() +size_t BSSL_TCP_Client::peekAvailable() { return _ssl_client.peekAvailable(); } + +// return a pointer to available data buffer (size = peekAvailable()) +// semantic forbids any kind of read() before calling peekConsume() +const char *BSSL_TCP_Client::peekBuffer() { return _ssl_client.peekBuffer(); } + +// consume bytes after use (see peekBuffer) +void BSSL_TCP_Client::peekConsume(size_t consume) { return _ssl_client.peekConsume(consume); } + +void BSSL_TCP_Client::setCACert(const char *rootCA) +{ + _ssl_client.setCACert(rootCA); +} + +void BSSL_TCP_Client::setCertificate(const char *client_ca) { return _ssl_client.setCertificate(client_ca); } + +void BSSL_TCP_Client::setPrivateKey(const char *private_key) { return _ssl_client.setPrivateKey(private_key); } + +bool BSSL_TCP_Client::loadCACert(Stream &stream, size_t size) +{ + char *dest = mStreamLoad(stream, size); + bool ret = false; + if (dest) + { + setCACert(dest); + ret = true; + } + return ret; +} + +bool BSSL_TCP_Client::loadCertificate(Stream &stream, size_t size) { return _ssl_client.loadCertificate(stream, size); } + +bool BSSL_TCP_Client::loadPrivateKey(Stream &stream, size_t size) { return _ssl_client.loadPrivateKey(stream, size); } + +int BSSL_TCP_Client::connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key) { return _ssl_client.connect(ip, port, rootCABuff, cli_cert, cli_key); } + +int BSSL_TCP_Client::connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key) { return _ssl_client.connect(host, port, rootCABuff, cli_cert, cli_key); } + +BSSL_TCP_Client &BSSL_TCP_Client::operator=(const BSSL_TCP_Client &other) +{ + stop(); + setClient(other._basic_client); + _use_insecure = other._use_insecure; + _timeout = other._timeout; + _handshake_timeout = other._handshake_timeout; + _ssl_client.setTimeout(_timeout); + _ssl_client.setHandshakeTimeout(_handshake_timeout); + if (_use_insecure) + _ssl_client.setInsecure(); + return *this; +} + +char *BSSL_TCP_Client::mStreamLoad(Stream &stream, size_t size) +{ + char *dest = (char *)malloc(size + 1); + if (!dest) + { + return nullptr; + } + if (size != stream.readBytes(dest, size)) + { + free(dest); + dest = nullptr; + return nullptr; + } + dest[size] = '\0'; + return dest; +} + +bool BSSL_TCP_Client::operator==(const BSSL_TCP_Client &rhs) +{ + return _basic_client == rhs._basic_client && _port == rhs._port && _host == rhs._host; +} + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_TCP_Client.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_TCP_Client.h new file mode 100644 index 000000000000..f70dbddfb60f --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_TCP_Client.h @@ -0,0 +1,437 @@ +/** + * BSSL_TCP_Client v2.0.12 for Arduino devices. + * + * Created August 27, 2023 + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + WiFiClientSecure.h - Base class that provides Client SSL to ESP32 + Copyright (c) 2011 Adrian McEwen. All right reserved. + Additions Copyright (C) 2017 Evandro Luis Copercini. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef BSSL_TCP_CLIENT_H +#define BSSL_TCP_CLIENT_H + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wvla" + +#include +#include "../ESP_SSLClient_FS.h" +#include "../ESP_SSLClient_Const.h" +#if defined(USE_LIB_SSL_ENGINE) || defined(USE_EMBED_SSL_ENGINE) + +#include "BSSL_SSL_Client.h" + +#include + +class BSSL_TCP_Client : public Client +{ + +protected: + bool _use_insecure; + +public: + BSSL_TCP_Client *next; + + // The default class constructor + BSSL_TCP_Client(); + + // The class deconstructor + ~BSSL_TCP_Client(); + + /** + * Set the client. + * @param client The pointer to Client interface. + * @param enableSSL The ssl option; true for enable, false for disable. + * + * Due to the client pointer is assigned, to avoid dangling pointer, + * client should be existed as long as it was used for transportation. + */ + void setClient(Client *client, bool enableSSL = true); + + /** + * Set debug level. + * @param level The debug level or esp_ssl_client_debug_level. + * esp_ssl_debug_none = 0 + * esp_ssl_debug_error = 1 + * esp_ssl_debug_warn = 2 + * esp_ssl_debug_info = 3 + * esp_ssl_debug_dump = 4 + */ + void setDebugLevel(int level); + + /** + * Connect to server. + * @param ip The server IP to connect. + * @param port The server port to connecte. + * @return 1 for success or 0 for error. + */ + int connect(IPAddress ip, uint16_t port) override; + + /** + * Connect to server. + * @param ip The server IP to connect. + * @param port The server port to connect. + * @param timeout The connection time out in miiliseconds. + * @return 1 for success or 0 for error. + */ + int connect(IPAddress ip, uint16_t port, int32_t timeout); + + /** + * Connect to server. + * @param host The server host name. + * @param port The server port to connect. + * @return 1 for success or 0 for error. + */ + int connect(const char *host, uint16_t port) override; + + /** + * Connect to server. + * @param host The server host name. + * @param port The server port to connect. + * @param timeout The connection time out in miiliseconds. + * @return 1 for success or 0 for error. + */ + int connect(const char *host, uint16_t port, int32_t timeout); + + /** + * Get TCP connection status. + * @return 1 for connected or 0 for not connected. + */ + uint8_t connected() override; + + /** + * Validate the last Client connection with these host and port. + * @param host The server host name. + * @param port The server port to connect. + * The Client connection will be closed when the provided host or port is not match with that of last connection. + */ + void validate(const char *host, uint16_t port); + + /** + * Validate the last Client connection with these IP and port. + * @param ip The server IP to connect. + * @param port The server port to connect. + * The Client connection will be closed when the provided IP or port is not match with that of last connection. + */ + void validate(IPAddress ip, uint16_t port); + + /** + * Get available data size to read. + * @return The avaiable data size. + * @note Get available data directly via lwIP for non-secure mode or via mbedTLS for secure mode. + */ + int available() override; + + /** + * The TCP data read function. + * @return A byte data that was successfully read or -1 for error. + * @note Get data directly via lwIP for non-secure mode or via mbedTLS to deccrypt data for secure mode. + */ + int read() override; + + /** + * The TCP data read function. + * @param buf The data buffer. + * @param size The length of data that read. + * @return The size of data that was successfully read or 0 for error. + * @note Get data directly via lwIP for non-secure mode or via mbedTLS to deccrypt data for secure mode. + */ + int read(uint8_t *buf, size_t size) override; + + /** + * The TCP data send function. + * @param data The data to send. + * @return The size of data that was successfully sent or 0 for error. + */ + int send(const char *data); + + /** + * The TCP data print function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int print(const char *data); + + /** + * The TCP data print function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int print(const String &data); + + /** + * The TCP data print function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int print(int data); + + /** + * The TCP data print with new line function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int println(const char *data); + + /** + * The TCP data print with new line function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int println(const String &data); + + /** + * The TCP data print with new line function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int println(int data); + + /** + * The TCP data write function. + * @param buf The data to write. + * @param size The length of data to write. + * @return The size of data that was successfully written or 0 for error. + * @note Send data directly via lwIP for non-secure mode or via mbedTLS to encrypt for secure mode. + */ + size_t write(const uint8_t *buf, size_t size) override; + + /** + * The TCP data write function. + * @param data The byte of data to write. + * @return The size of data that was successfully written (1) or 0 for error. + * @note Send data directly via lwIP for non-secure mode or via mbedTLS to encrypt for secure mode. + */ + size_t write(uint8_t data) override; + + /** + * The TCP data write function. + * @param buf The PGM data to write. + * @param size The length of data to write. + * @return The size of data that was successfully written or 0 for error. + */ + size_t write_P(PGM_P buf, size_t size); + + /** + * The TCP data write function. + * @param buf The string data to write. + * @return The size of data that was successfully written or 0 for error. + */ + size_t write(const char *buf); + + /** + * The TCP data write function. + * @param stream The stream data to write. + * @return The size of data that was successfully written or 0 for error. + */ + size_t write(Stream &stream); + + /** + * Read one byte from Stream with time out. + * @return The byte of data that was successfully read or -1 for timed out. + */ + int peek() override; + + /** + * Disable certificate verification and ignore the authentication. + */ + void setInsecure(); // Don't validate the chain, just accept whatever is given. VERY INSECURE! + + /** + * Enable/disable the SSL layer transport. + * @param enable The enable option; true for enable, false to disable. + */ + void enableSSL(bool enable); + + /** + * Upgrade the current connection by setting up the SSL and perform the SSL handshake. + * + * @return operating result. + */ + bool connectSSL(); + + /** + * Upgrade the current connection by setting up the SSL and perform the SSL handshake. + * @param host The host to connect (unused). + * @param port The port to connect (unused). + * @return operating result. + */ + bool connectSSL(const String host, uint16_t port); + + /** + * Stop the TCP connection and release resources. + */ + void stop() override; + + /** + * Set the TCP timeout in seconds. + * @param seconds The TCP timeout in seconds. + */ + int setTimeout(uint32_t seconds); + + /** + * Get the TCP timeout in seconds. + * @return The TCP timeout in seconds. + */ + int getTimeout(); + + /** + * Set the SSL handshake timeout in seconds. + * @param handshake_timeout The SSL handshake timeout in seconds. + */ + void setHandshakeTimeout(unsigned long handshake_timeout); + + /** + * Wait for all receive buffer data read. + */ + void flush() override; + + /** + * Sets the requested buffer size for transmit and receive + * @param recv The receive buffer size. + * @param xmit The transmit buffer size. + */ + void setBufferSizes(int recv, int xmit); + + operator bool() { return connected(); } + + int availableForWrite(); + + void setSession(BearSSL_Session *session); + + void setKnownKey(const PublicKey *pk, unsigned usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN); + + /** + * Verify certificate's SHA256 fingerprint. + * + * @param fingerprint The certificate's SHA256 fingerprint data to compare with server certificate's SHA256 fingerprint. + * @return verification result. + */ + bool setFingerprint(const uint8_t fingerprint[20]); + + bool setFingerprint(const char *fpStr); + + void allowSelfSignedCerts(); + + void setTrustAnchors(const X509List *ta); + + void setX509Time(time_t now); + + void setClientRSACert(const X509List *cert, const PrivateKey *sk); + + void setClientECCert(const X509List *cert, const PrivateKey *sk, unsigned allowed_usages, unsigned cert_issuer_key_type); + + int getMFLNStatus(); + + int getLastSSLError(char *dest = NULL, size_t len = 0); +#if defined(ESP_SSL_FS_SUPPORTED) + void setCertStore(CertStoreBase *certStore); +#endif + bool setCiphers(const uint16_t *cipherAry, int cipherCount); + + bool setCiphers(const std::vector &list); + + bool setCiphersLessSecure(); + + bool setSSLVersion(uint32_t min = BR_TLS10, uint32_t max = BR_TLS12); + + bool probeMaxFragmentLength(IPAddress ip, uint16_t port, uint16_t len); + + bool probeMaxFragmentLength(const char *hostname, uint16_t port, uint16_t len); + + bool probeMaxFragmentLength(const String &host, uint16_t port, uint16_t len); + + bool hasPeekBufferAPI() const; + + size_t peekAvailable(); + + const char *peekBuffer(); + + void peekConsume(size_t consume); + + /** + * Set the Root CA or CA certificate. + * @param rootCA The Root CA or CA certificate. + */ + void setCACert(const char *rootCA); + + void setCertificate(const char *client_ca); + + void setPrivateKey(const char *private_key); + + /** + * Read and set CA cert from file (Stream). + * @param stream The Stream interface. + * @param size The size of data to read. + * @return The operating result. + */ + bool loadCACert(Stream &stream, size_t size); + + bool loadCertificate(Stream &stream, size_t size); + + bool loadPrivateKey(Stream &stream, size_t size); + + int connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key); + + int connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key); + + BSSL_TCP_Client &operator=(const BSSL_TCP_Client &other); + + bool operator==(const bool value) { return bool() == value; } + + bool operator!=(const bool value) { return bool() != value; } + + bool operator==(const BSSL_TCP_Client &); + + bool operator!=(const BSSL_TCP_Client &rhs) { return !this->operator==(rhs); }; + +private: + String _host; + uint16_t _port; + BSSL_SSL_Client _ssl_client; + Client *_basic_client = nullptr; + unsigned long _timeout = 15000; + unsigned long _handshake_timeout = 60000; + + char *mStreamLoad(Stream &stream, size_t size); +}; + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/Build_Options.h b/lib/libesp32/ESP-Mail-Client/src/extras/Build_Options.h new file mode 100644 index 000000000000..a2251f896c8c --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/Build_Options.h @@ -0,0 +1,52 @@ +#ifndef BUILD_OPTIONS_H +#define BUILD_OPTIONS_H + +#if defined(DISABLE_ALL_OPTIONS) +#undef ENABLE_NTP_TIME +#undef ENABLE_ERROR_STRING +#undef ENABLE_IMAP +#undef ENABLE_SMTP +#undef ESP_MAIL_USE_PSRAM +#undef ESP_MAIL_DEFAULT_SD_FS +#undef ESP_MAIL_CARD_TYPE_SD +#undef ESP_MAIL_CARD_TYPE_SD_MMC +#undef ESP_MAIL_DEFAULT_FLASH_FS +#undef ESP_MAIL_DEFAULT_DEBUG_PORT +#endif + +#if defined(DISABLE_NTP_TIME) +#undef ENABLE_NTP_TIME +#endif + +#if defined(DISABLE_ERROR_STRING) +#undef ENABLE_ERROR_STRING +#endif + +#if defined(DISABLE_IMAP) +#undef ENABLE_IMAP +#endif + +#if defined(DISABLE_SMTP) +#undef ENABLE_SMTP +#endif + +#if defined(DISABLE_PSRAM) +#undef ESP_MAIL_USE_PSRAM +#endif + +#if defined(DISABLE_SD) +#undef ESP_MAIL_DEFAULT_SD_FS +#undef ESP_MAIL_CARD_TYPE_SD_MMC +#undef ESP_MAIL_DEFAULT_FLASH_FS +#endif + +#if defined(DISABLE_FLASH) +#undef ESP_MAIL_DEFAULT_FLASH_FS +#undef ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED +#endif + +#if defined(ESP_MAIL_DEFAULT_DEBUG_PORT) +#undef ESP_MAIL_DEFAULT_DEBUG_PORT +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/ESP8266_Supports.h b/lib/libesp32/ESP-Mail-Client/src/extras/ESP8266_Supports.h new file mode 100644 index 000000000000..5604690c697c --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/ESP8266_Supports.h @@ -0,0 +1,52 @@ +#ifndef ESP8266_SUPPORTS_H +#define ESP8266_SUPPORTS_H +#include +#include "MB_MCU.h" +#if defined(ESP8266) || defined(MB_ARDUINO_PICO) + +#include + +//__GNUC__ +//__GNUC_MINOR__ +//__GNUC_PATCHLEVEL__ + +#ifdef __GNUC__ +#if __GNUC__ > 4 || __GNUC__ == 10 +#if defined(ARDUINO_ESP8266_GIT_VER) +#if ARDUINO_ESP8266_GIT_VER > 0 +#define ESP8266_CORE_SDK_V3_X_X +#endif +#endif +#endif +#endif + +#if defined __has_include + +#if __has_include() +#include +#endif + +#if __has_include()&& defined(ENABLE_ESP8266_ENC28J60_ETH) +#define INC_ENC28J60_LWIP +#include +#endif + +#if __has_include() && defined(ENABLE_ESP8266_W5100_ETH) +#define INC_W5100_LWIP +#include +#endif + +#if __has_include()&& defined(ENABLE_ESP8266_W5500_ETH) +#define INC_W5500_LWIP +#include +#endif + +#if defined(MB_ARDUINO_PICO) + +#endif + +#endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS.h b/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS.h new file mode 100644 index 000000000000..96740627bc12 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS.h @@ -0,0 +1,1137 @@ +/** + * The MB_FS, filesystems wrapper class v1.0.16 + * + * This wrapper class is for SD and Flash filesystems interface which supports SdFat (//https://github.com/greiman/SdFat) + * + * Created June 14, 2023 + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef MBFS_CLASS_H +#define MBFS_CLASS_H + +#include +#include "MB_MCU.h" + +#define FS_NO_GLOBALS +#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) +#include +#endif +#endif +#include "MB_FS_Interfaces.h" +#include MB_STRING_INCLUDE_CLASS + +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) +#include "SPI.h" +#endif + +#if defined(ESP32) && __has_include() +#ifdef _LITTLEFS_H_ +#define MB_FS_USE_POSIX_STAT +#include +namespace mb_fs_ns +{ + inline bool exists(const char *mountPoint, const char *filename) + { + MB_String path = mountPoint; + path += filename; + struct stat st; + return stat(path.c_str(), &st) == 0; + } +}; +#endif +#endif + +using namespace mb_string; + +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) +#include +#endif + +#define MB_FS_ERROR_FILE_IO_ERROR -300 +#define MB_FS_ERROR_FILE_NOT_FOUND -301 +#define MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY -302 +#define MB_FS_ERROR_SD_STORAGE_IS_NOT_READY -303 +#define MB_FS_ERROR_FILE_STILL_OPENED -304 + +typedef enum +{ + mb_fs_mem_storage_type_undefined, + mb_fs_mem_storage_type_flash, + mb_fs_mem_storage_type_sd +} mb_fs_mem_storage_type; + +typedef enum +{ + mb_fs_open_mode_undefined = -1, + mb_fs_open_mode_read = 0, + mb_fs_open_mode_write, + mb_fs_open_mode_append +} mb_fs_open_mode; + +#define mbfs_file_type mb_fs_mem_storage_type +#define mbfs_flash mb_fs_mem_storage_type_flash +#define mbfs_sd mb_fs_mem_storage_type_sd +#define mbfs_undefined mb_fs_mem_storage_type_undefined + +#define mbfs_type (mbfs_file_type) + +#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) +#if !defined(MBFS_SDFAT_ENABLED) +struct mbfs_sd_config_info_t +{ + int ss = -1; +}; +#endif +#elif defined(ESP32) || defined(MBFS_SDFAT_ENABLED) + +#if defined(ESP32) +struct mbfs_sd_mmc_config_info_t +{ + const char *mountpoint = ""; + bool mode1bit = false; + bool format_if_mount_failed = false; +}; +#endif + +struct mbfs_sd_config_info_t +{ + int ss = -1; + int sck = -1; + int miso = -1; + int mosi = -1; + uint32_t frequency = 4000000; + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + + SdSpiConfig *sdFatSPIConfig = nullptr; + SdioConfig *sdFatSDIOConfig = nullptr; + +#endif + +#if defined(ESP32) + +#if defined(MBFS_SD_FS) + SPIClass *spiConfig = nullptr; +#endif + mbfs_sd_mmc_config_info_t sdMMCConfig; +#endif + +#if defined(MBFS_SDFAT_ENABLED) + SPIClass *spiConfig = nullptr; +#endif +}; + +#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) +struct mbfs_sd_config_info_t +{ + int ss = -1; +#if defined(MBFS_SD_FS) + SDFSConfig *sdFSConfig = nullptr; +#endif +}; +#else +struct mbfs_sd_config_info_t +{ + int ss = -1; +}; +#endif + +class MB_FS +{ + +public: + MB_FS() {} + ~MB_FS() {} + + struct mbfs_sd_config_info_t sd_config; + + // Assign the SD card interfaces with GPIO pins. + bool sdBegin(int ss = -1, int sck = -1, int miso = -1, int mosi = -1, uint32_t frequency = 4000000) + { + if (sd_rdy) + return true; + +#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) + sd_config.ss = ss; +#if defined(ESP32) + sd_config.sck = sck; + sd_config.miso = miso; + sd_config.mosi = mosi; + SPI.begin(sck, miso, mosi, ss); + sd_config.frequency = frequency; + return sdSPIBegin(ss, &SPI, frequency); +#elif defined(ESP8266) || defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) + sd_rdy = MBFS_SD_FS.begin(ss); + return sd_rdy; +#elif defined(MB_ARDUINO_PICO) + SDFSConfig c; + c.setCSPin(ss); + c.setSPISpeed(frequency); + MBFS_SD_FS.setConfig(c); + sd_rdy = MBFS_SD_FS.begin(); + return sd_rdy; +#endif + +#endif + return false; + } + +#if defined(ESP32) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) + + // Assign the SD card interfaces with SPIClass object pointer (ESP32 only). + bool sdSPIBegin(int ss, SPIClass *spiConfig, uint32_t frequency) + { + + if (sd_rdy) + return true; + + sd_config.frequency = frequency; + +#if defined(ESP32) + + sd_config.ss = ss; + + if (spiConfig) + sd_config.spiConfig = spiConfig; + else + sd_config.spiConfig = &SPI; + +#if !defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + if (ss > -1) + sd_rdy = MBFS_SD_FS.begin(ss, *sd_config.spiConfig, frequency); + else + sd_rdy = MBFS_SD_FS.begin(); +#endif + +#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) + + cfg->_int.sd_config.sck = sck; + + if (ss > -1) + sd_rdy = MBFS_SD_FS.begin(ss); + else + sd_rdy = MBFS_SD_FS.begin(SD_CS_PIN); +#endif + + return sd_rdy; + } + +#endif + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + + // Assign the SD card interfaces with SdSpiConfig object pointer and SPI pins assignment. + bool sdFatBegin(SdSpiConfig *sdFatSPIConfig, int ss, int sck, int miso, int mosi) + { + + if (sd_rdy) + return true; + + if (sdFatSPIConfig) + { + sd_config.sdFatSPIConfig = sdFatSPIConfig; + sd_config.spiConfig = &SPI; + sd_config.ss = ss; + +#if defined(ESP32) + if (ss > -1) + sd_config.spiConfig->begin(sck, miso, mosi, ss); +#endif + + sd_rdy = MBFS_SD_FS.begin(*sd_config.sdFatSPIConfig); + return sd_rdy; + } + + return false; + } + + // Assign the SD card interfaces with SdioConfig object pointer. + bool sdFatBegin(SdioConfig *sdFatSDIOConfig) + { + + if (sd_rdy) + return true; + +#if defined(HAS_SDIO_CLASS) // Default is 0 (no SDIO) in SdFatConfig.h + +#if HAS_SDIO_CLASS + + if (sdFatSDIOConfig) + { + sd_config.sdFatSDIOConfig = sdFatSDIOConfig; + + sd_rdy = MBFS_SD_FS.begin(*sd_config.sdFatSDIOConfig); + return sd_rdy; + } +#endif + +#endif + + return false; + } +#endif + +#if (defined(ESP8266) || defined(MB_ARDUINO_PICO)) && defined(MBFS_SD_FS) + // Assign the SD card interfaces with SDFSConfig object pointer (ESP8266 and Pico only). + bool sdFatBegin(SDFSConfig *sdFSConfig) + { + + if (sd_rdy) + return true; + + if (sdFSConfig) + { + sd_config.sdFSConfig = sdFSConfig; + SDFS.setConfig(*sd_config.sdFSConfig); + sd_rdy = SDFS.begin(); + return sd_rdy; + } + + return false; + } +#endif + + // Assign the SD_MMC card interfaces (ESP32 only). + bool sdMMCBegin(const char *mountpoint, bool mode1bit, bool format_if_mount_failed) + { + + if (sd_rdy) + return true; + +#if defined(ESP32) +#if defined(MBFS_CARD_TYPE_SD_MMC) + + sd_config.sdMMCConfig.mountpoint = mountpoint; + sd_config.sdMMCConfig.mode1bit = mode1bit; + sd_config.sdMMCConfig.format_if_mount_failed = format_if_mount_failed; + + sd_rdy = MBFS_SD_FS.begin(mountpoint, mode1bit, format_if_mount_failed); + return sd_rdy; +#endif +#endif + return false; + } + + // Check the mounting status of Flash storage. + bool flashReady() + { +#if defined MBFS_FLASH_FS + + if (flash_rdy) + return true; + +#if defined(ESP32) + +#if defined(MBFS_FORMAT_FLASH) + flash_rdy = MBFS_FLASH_FS.begin(true); +#else + flash_rdy = MBFS_FLASH_FS.begin(); +#endif + +#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) + flash_rdy = MBFS_FLASH_FS.begin(); +#endif + +#endif + + return flash_rdy; + } + + // Check the mounting status of SD storage. + bool sdReady() + { + +#if defined(MBFS_SD_FS) + + if (sd_rdy) + return true; + +#if defined(ESP32) + +#if defined(MBFS_CARD_TYPE_SD) + + if (!sd_config.spiConfig) + { + if (sd_config.ss > -1) + SPI.begin(sd_config.sck, sd_config.miso, sd_config.mosi, sd_config.ss); + sd_config.spiConfig = &SPI; + } + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + + if (!sd_rdy) + { + if (sd_config.sdFatSPIConfig) + sd_rdy = MBFS_SD_FS.begin(*sd_config.sdFatSPIConfig); + else if (sd_config.sdFatSDIOConfig) + sd_rdy = MBFS_SD_FS.begin(*sd_config.sdFatSDIOConfig); + } + +#else + if (!sd_rdy) + sd_rdy = sdSPIBegin(sd_config.ss, sd_config.spiConfig, sd_config.frequency); + +#endif + +#elif defined(MBFS_CARD_TYPE_SD_MMC) + if (!sd_rdy) + sd_rdy = sdMMCBegin(sd_config.sdMMCConfig.mountpoint, sd_config.sdMMCConfig.mode1bit, sd_config.sdMMCConfig.format_if_mount_failed); +#endif + +#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) + if (!sd_rdy) + { + if (sd_config.sdFSConfig) + sd_rdy = sdFatBegin(sd_config.sdFSConfig); + else + sd_rdy = sdBegin(sd_config.ss); + } + +#elif defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) + if (!sd_rdy) + sd_rdy = sdBegin(sd_config.ss); +#endif + +#endif + + return sd_rdy; + } + + // Check the mounting status of Flash or SD storage with mb_fs_mem_storage_type. + bool checkStorageReady(mbfs_file_type type) + { + +#if defined(MBFS_USE_FILE_STORAGE) + if (type == mbfs_flash) + { + if (!flash_rdy) + flashReady(); + return flash_rdy; + } + else if (type == mbfs_sd) + { + if (!sd_rdy) + sdReady(); + return sd_rdy; + } +#endif + + return false; + } + + // Open file for read or write with file name, mb_fs_mem_storage_type and mb_fs_open_mode. + // return size of file (read) or 0 (write) or negative value for error + int open(const MB_String &filename, mbfs_file_type type, mb_fs_open_mode mode) + { + +#if defined(MBFS_USE_FILE_STORAGE) + + if (!checkStorageReady(type)) + { + if (type == mbfs_flash) + return MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY; + else if (type == mbfs_sd) + return MB_FS_ERROR_SD_STORAGE_IS_NOT_READY; + else + return MB_FS_ERROR_FILE_IO_ERROR; + } + + if (mode == mb_fs_open_mode_read) + { + if (!existed(filename.c_str(), type)) + return MB_FS_ERROR_FILE_NOT_FOUND; + } + + int ret = openFile(filename, type, mode); + + if (ret < 0) + return ret; + + if (ready(type)) + return ret; + +#endif + return MB_FS_ERROR_FILE_IO_ERROR; + } + + // Check if file is already open. + bool ready(mbfs_file_type type) + { +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + return true; +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + return true; +#endif + return false; + } + + // Get file for read/write with file name, mb_fs_mem_storage_type and mb_fs_open_mode. + int size(mbfs_file_type type) + { + int size = 0; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + size = mb_flashFs.size(); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + size = mb_sdFs.size(); +#endif + return size; + } + + // Check if file is ready to read/write. + int available(mbfs_file_type type) + { + int available = 0; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + available = mb_flashFs.available(); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + available = mb_sdFs.available(); +#endif + return available; + } + + // Read byte array. Return the number of bytes that completed read or negative value for error. + int read(mbfs_file_type type, uint8_t *buf, size_t len) + { + int read = 0; +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + read = mb_flashFs.read(buf, len); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + read = mb_sdFs.read(buf, len); +#endif + return read; + } + + // Print char array. Return the number of bytes that completed write or negative value for error. + int print(mbfs_file_type type, const char *str) + { + int write = 0; +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + write = mb_flashFs.print(str); +#endif +#if defined(MBFS_SD_FS) + + if (type == mbfs_sd && mb_sdFs) + write = mb_sdFs.print(str); +#endif + return write; + } + + // Print char array with new line. Return the number of bytes that completed write or negative value for error. + int println(mbfs_file_type type, const char *str) + { + int write = print(type, str); + if (write == (int)strlen(str)) + write += print(type, (const char *)MBSTRING_FLASH_MCR("\n")); + return write; + } + + // Print integer. Return the number of bytes that completed write or negative value for error. + int print(mbfs_file_type type, int v) + { + int write = 0; +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + write = mb_flashFs.print(v); +#endif +#if defined(MBFS_SD_FS) + + if (type == mbfs_sd && mb_sdFs) + write = mb_sdFs.print(v); +#endif + return write; + } + + // Print integer with newline. Return the number of bytes that completed write or negative value for error. + int println(mbfs_file_type type, int v) + { + int write = print(type, v); + if (write > 0) + write += print(type, (const char *)MBSTRING_FLASH_MCR("\n")); + return write; + } + + int print(mbfs_file_type type, unsigned int v) + { + int write = 0; +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + write = mb_flashFs.print(v); +#endif +#if defined(MBFS_SD_FS) + + if (type == mbfs_sd && mb_sdFs) + write = mb_sdFs.print(v); +#endif + return write; + } + + // Print integer with newline. Return the number of bytes that completed write or negative value for error. + int println(mbfs_file_type type, unsigned int v) + { + int write = print(type, v); + if (write > 0) + write += print(type, (const char *)MBSTRING_FLASH_MCR("\n")); + return write; + } + + // Write byte array. Return the number of bytes that completed write or negative value for error. + int write(mbfs_file_type type, uint8_t *buf, size_t len) + { + int write = 0; +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + write = mb_flashFs.write(buf, len); +#endif +#if defined(MBFS_SD_FS) + + if (type == mbfs_sd && mb_sdFs) + write = mb_sdFs.write(buf, len); +#endif + return write; + } + + // Close file. + void close(mbfs_file_type type) + { + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs && flash_opened) + { + mb_flashFs.close(); + flash_filename_crc = 0; + flash_opened = false; + flash_open_mode = mb_fs_open_mode_undefined; + } +#endif + +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs && sd_opened) + { + mb_sdFs.close(); + sd_filename_crc = 0; + sd_opened = false; + sd_open_mode = mb_fs_open_mode_undefined; + } +#endif + } + + // Check file existence. + bool existed(const MB_String &filename, mbfs_file_type type) + { + + if (!checkStorageReady(type)) + return false; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash) + { + +// The workaround for ESP32 LittleFS when calling vfs_api.cpp open() issue. +// See https://github.com/espressif/arduino-esp32/issues/7615 +#if defined(MB_FS_USE_POSIX_STAT) + return mb_fs_ns::exists("/littlefs", filename.c_str()); +#else + return MBFS_FLASH_FS.exists(filename.c_str()); +#endif + } + +#endif + +#if defined(MBFS_SD_FS) + if (type == mbfs_sd) + { +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + MBFS_SD_FILE file; + bool ret = file.open(filename.c_str(), O_RDONLY); + file.close(); + return ret; +#else + return MBFS_SD_FS.exists(filename.c_str()); +#endif + } +#endif + + return false; + } + + // Seek to position in file. + bool seek(mbfs_file_type type, int pos) + { + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + return mb_flashFs.seek(pos); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + return mb_sdFs.seek(pos); +#endif + + return false; + } + + // Read byte. Return the 1 for completed read or negative value for error. + int read(mbfs_file_type type) + { +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + return mb_flashFs.read(); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + return mb_sdFs.read(); +#endif + return -1; + } + + // Write byte. Return the 1 for completed write or negative value for error. + int write(mbfs_file_type type, uint8_t v) + { +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + return mb_flashFs.write(v); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + return mb_sdFs.write(v); +#endif + return -1; + } + + bool remove(const MB_String &filename, mbfs_file_type type) + { + if (!checkStorageReady(type)) + return false; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && !flashReady()) + return false; +#endif + +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && !sdReady()) + return false; +#endif + + if (!existed(filename, type)) + return true; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash) + return MBFS_FLASH_FS.remove(filename.c_str()); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd) + { +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + if (mb_sdFs.open(filename.c_str(), O_RDWR | O_CREAT | O_APPEND)) + { + mb_sdFs.remove(); + mb_sdFs.close(); + return true; + } +#else + return MBFS_SD_FS.remove(filename.c_str()); +#endif + } + +#endif + return false; + } + +// Get the Flash file instance. +#if defined(MBFS_FLASH_FS) + fs::File &getFlashFile() + { + return mb_flashFs; + } +#endif + +// Get the SD file instance. +#if defined(MBFS_SD_FS) + MBFS_SD_FILE &getSDFile() + { + return mb_sdFs; + } +#endif + + // Get name of opened file. + const char *name(mbfs_file_type type) + { +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + return flash_file.c_str(); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + return sd_file.c_str(); +#endif + + return ""; + } + + // Calculate CRC16 of byte array. + uint16_t calCRC(const char *buf) + { + uint8_t x; + uint16_t crc = 0xFFFF; + + int length = (int)strlen(buf); + + while (length--) + { + x = crc >> 8 ^ *buf++; + x ^= x >> 4; + crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x << 5)) ^ ((uint16_t)x); + } + return crc; + } + + // Free reserved memory at pointer. + void delP(void *ptr) + { + void **p = (void **)ptr; + if (*p) + { + free(*p); + *p = 0; + } + } + + // Allocate memory + void *newP(size_t len, bool clear = true) + { + void *p; + size_t newLen = getReservedLen(len); +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) + + if (ESP.getPsramSize() > 0) + p = (void *)ps_malloc(newLen); + else + p = (void *)malloc(newLen); + + if (!p) + return NULL; + +#else + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.setExternalHeap(); +#endif + + p = (void *)malloc(newLen); + bool nn = p ? true : false; + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.resetHeap(); +#endif + + if (!nn) + return NULL; + +#endif + if (clear) + memset(p, 0, newLen); + return p; + } + + size_t getReservedLen(size_t len) + { + int blen = len + 1; + + int newlen = (blen / 4) * 4; + + if (newlen < blen) + newlen += 4; + + return (size_t)newlen; + } + + void createDirs(MB_String dirs, mbfs_file_type type) + { + if (!longNameSupported()) + return; + + MB_String dir; + int count = 0; + int lastPos = 0; + for (size_t i = 0; i < dirs.length(); i++) + { + dir.append(1, dirs[i]); + count++; + if (dirs[i] == '/' && i > 0) + { + if (dir.length() > 0) + { + + lastPos = dir.length() - 1; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash) + MBFS_FLASH_FS.mkdir(dir.substr(0, dir.length() - 1).c_str()); +#endif + +#if defined(MBFS_SD_FS) + if (type == mbfs_sd) + MBFS_SD_FS.mkdir(dir.substr(0, dir.length() - 1).c_str()); +#endif + } + count = 0; + } + } + + if (count > 0) + { + if (dir.find('.', lastPos) == MB_String::npos) + { +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash) + MBFS_FLASH_FS.mkdir(dir.c_str()); +#endif + +#if defined(MBFS_SD_FS) + if (type == mbfs_sd) + MBFS_SD_FS.mkdir(dir.c_str()); +#endif + } + } + + dir.clear(); + } + + bool longNameSupported() + { + +#if defined(MBFS_SDFAT_ENABLED) || defined(MBFS_FLASH_FS) + return true; +#endif + +#if defined(MBFS_SD_FS) && (defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO)) + return true; +#endif + + return false; + } + +private: + uint16_t flash_filename_crc = 0; + uint16_t sd_filename_crc = 0; + MB_String flash_file, sd_file; + mb_fs_open_mode flash_open_mode = mb_fs_open_mode_undefined; + mb_fs_open_mode sd_open_mode = mb_fs_open_mode_undefined; + bool flash_opened = false; + bool sd_opened = false; + bool sd_rdy = false; + bool flash_rdy = false; + uint16_t loopCount = 0; + +#if defined(MBFS_FLASH_FS) + fs::File mb_flashFs; +#endif +#if defined(MBFS_SD_FS) + MBFS_SD_FILE mb_sdFs; +#endif + + int openFile(const MB_String &filename, mb_fs_mem_storage_type type, mb_fs_open_mode mode) + { + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash) + return openFlashFile(filename, mode); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd) + return openSDFile(filename, mode); +#endif + return MB_FS_ERROR_FILE_IO_ERROR; + } + + int openSDFile(const MB_String &filename, mb_fs_open_mode mode) + { + int ret = MB_FS_ERROR_FILE_IO_ERROR; + +#if defined(MBFS_SD_FS) + + if (mode == mb_fs_open_mode_read || mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) + { + uint16_t crc = calCRC(filename.c_str()); + + if (mode == sd_open_mode && flash_filename_crc == crc && sd_opened) // same sd file opened, leave it + return MB_FS_ERROR_FILE_STILL_OPENED; + + if (sd_opened) + close(mbfs_sd); // sd file opened, close it + + flash_filename_crc = crc; + } + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + + if (mode == mb_fs_open_mode_read) + { + if (mb_sdFs.open(filename.c_str(), O_RDONLY)) + { + sd_file = filename; + sd_opened = true; + sd_open_mode = mode; + ret = mb_sdFs.size(); + } + } + else if (mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) + { + if (mode == mb_fs_open_mode_write) + remove(filename, mb_fs_mem_storage_type_sd); + + createDirs(filename, mb_fs_mem_storage_type_sd); + if (mb_sdFs.open(filename.c_str(), O_RDWR | O_CREAT | O_APPEND)) + { + sd_file = filename; + sd_opened = true; + sd_open_mode = mode; + ret = 0; + } + } + +#else + + if (mode == mb_fs_open_mode_read) + { +#if defined(ESP32) || defined(ESP8266) + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), FILE_READ); +#else + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), "r"); +#endif + if (mb_sdFs) + { + sd_file = filename; + sd_opened = true; + sd_open_mode = mode; + ret = mb_sdFs.size(); + } + } + else if (mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) + { + if (mode == mb_fs_open_mode_write) + remove(filename, mb_fs_mem_storage_type_sd); + + createDirs(filename, mb_fs_mem_storage_type_sd); +#if defined(ESP32) + if (mode == mb_fs_open_mode_write) + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), FILE_WRITE); + else + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), FILE_APPEND); +#elif defined(ESP8266) + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), FILE_WRITE); +#else + if (mode == mb_fs_open_mode_write) + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), "w"); + else + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), "a"); +#endif + + if (mb_sdFs) + { + sd_file = filename; + sd_opened = true; + sd_open_mode = mode; + ret = 0; + } + } +#endif + +#endif + return ret; + } + + int openFlashFile(const MB_String &filename, mb_fs_open_mode mode) + { + int ret = MB_FS_ERROR_FILE_IO_ERROR; + +#if defined(MBFS_FLASH_FS) + + if (mode == mb_fs_open_mode_read || mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) + { + uint16_t crc = calCRC(filename.c_str()); + if (mode == flash_open_mode && sd_filename_crc == crc && flash_opened) // same flash file opened, leave it + return MB_FS_ERROR_FILE_STILL_OPENED; + + if (flash_opened) + close(mbfs_flash); // flash file opened, close it + + sd_filename_crc = crc; + } + + if (mode == mb_fs_open_mode_read) + { + mb_flashFs = MBFS_FLASH_FS.open(filename.c_str(), "r"); + if (mb_flashFs) + { + flash_file = filename; + flash_opened = true; + flash_open_mode = mode; + ret = mb_flashFs.size(); + } + } + else if (mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) + { + if (mode == mb_fs_open_mode_write) + remove(filename, mb_fs_mem_storage_type_flash); + + createDirs(filename, mb_fs_mem_storage_type_flash); + if (mode == mb_fs_open_mode_write) + mb_flashFs = MBFS_FLASH_FS.open(filename.c_str(), "w"); + else + mb_flashFs = MBFS_FLASH_FS.open(filename.c_str(), "a"); + + if (mb_flashFs) + { + flash_file = filename; + flash_opened = true; + flash_open_mode = mode; + ret = 0; + } + } + +#endif + return ret; + } +}; + +#endif diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS_Interfaces.h b/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS_Interfaces.h new file mode 100644 index 000000000000..9bdc1e75d197 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS_Interfaces.h @@ -0,0 +1,94 @@ +#pragma once + +/* Convert specific definitions to MB_FS definitions */ +#ifndef MB_FS_INTERFACES_H +#define MB_FS_INTERFACES_H + +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +// include definitions file +#include "./ESP_Mail_FS.h" + +// 1. ESP_MAIL_DEFAULT_FLASH_FS -> MBFS_FLASH_FS +#if defined ESP_MAIL_DEFAULT_FLASH_FS +#define MBFS_FLASH_FS ESP_MAIL_DEFAULT_FLASH_FS +#endif + +// 2. ESP_MAIL_DEFAULT_SD_FS -> MBFS_SD_FS +#if defined ESP_MAIL_DEFAULT_SD_FS +#define MBFS_SD_FS ESP_MAIL_DEFAULT_SD_FS +#endif + +// 3. ESP_MAIL_CARD_TYPE_SD -> MBFS_CARD_TYPE_SD +#if defined(ESP_MAIL_CARD_TYPE_SD) +#define MBFS_CARD_TYPE_SD /* */ ESP_MAIL_CARD_TYPE_SD +#endif + +// 4. ESP_MAIL_CARD_TYPE_SD_MMC -> MBFS_CARD_TYPE_SD_MMC +#if defined(ESP_MAIL_CARD_TYPE_SD_MMC) +#define MBFS_CARD_TYPE_SD_MMC /* */ ESP_MAIL_CARD_TYPE_SD_MMC +#endif + +// 5. ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED -> MBFS_FORMAT_FLASH +#if defined(ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED) +#define MBFS_FORMAT_FLASH /* */ ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED +#endif + +#if defined(MBFS_SD_FS) || defined(MBFS_FLASH_FS) +#define MBFS_USE_FILE_STORAGE +#endif + +// Only SdFat library from Bill Greiman +#if defined(ESP32) && defined(SD_FAT_VERSION) && defined(SD_FAT_VERSION_STR) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) +#define MBFS_ESP32_SDFAT_ENABLED +#ifndef ESP_MAIL_USE_SDFAT +#define ESP_MAIL_USE_SDFAT +#endif +#endif + +// Only SdFat library from Bill Greiman +#if !defined(ESP32) && !defined(ESP8266) && !defined(ARDUINO_ARCH_RP2040) && defined(SD_FAT_VERSION) && defined(SD_FAT_VERSION_STR) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) +#define MBFS_SDFAT_ENABLED +#ifndef ESP_MAIL_USE_SDFAT +#define ESP_MAIL_USE_SDFAT +#endif +#endif + +// For MB_String +#if defined(ESP_MAIL_USE_PSRAM) +#define MB_STRING_USE_PSRAM +#endif + +#if defined(MBFS_SD_FS) + +#if !defined(ESP_MAIL_SD_FILE) + +#if defined(MBFS_ESP32_SDFAT_ENABLED) +#define MBFS_SD_FILE SdFile +#else +#if defined(ESP32) || defined(ESP8266) || defined(ARDUINO_ARCH_RP2040) +#define MBFS_SD_FILE fs::File +#else +#define MBFS_SD_FILE File +#endif + +#endif + +#else + +#define MBFS_SD_FILE ESP_MAIL_SD_FILE + +#endif + +#endif + +#ifndef MB_STRING_INCLUDE_CLASS +#define MB_STRING_INCLUDE_CLASS "MB_String.h" +#endif + + + +#endif /* MB_FS_INTERFACES_H */ diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/MB_MCU.h b/lib/libesp32/ESP-Mail-Client/src/extras/MB_MCU.h new file mode 100644 index 000000000000..3009e67bb4bc --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/MB_MCU.h @@ -0,0 +1,67 @@ +#pragma once + +#ifndef MB_MCU_H +#define MB_MCU_H + + +#if defined(ESP8266) || defined(ESP32) +#ifndef MB_ARDUINO_ESP +#define MB_ARDUINO_ESP +#endif +#endif + +#if defined(__arm__) +#ifndef MB_ARDUINO_ARM +#define MB_ARDUINO_ARM +#endif +#endif + +// Renesas +#if defined(ARDUINO_PORTENTA_C33) + +#endif + +// Renesas +#if defined(ARDUINO_UNOWIFIR4) + +#endif + +// Renesas +#if defined(ARDUINO_MINIMA) + +#endif + +#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) || defined(ARDUINO_PORTENTA_X8) + +#endif + + +#if defined(ARDUINO_ARCH_SAMD) +#ifndef MB_ARDUINO_ARCH_SAMD +#define MB_ARDUINO_ARCH_SAMD +#endif +#endif + +#if defined(ARDUINO_ARCH_RP2040) + +#if defined(ARDUINO_NANO_RP2040_CONNECT) +#ifndef MB_ARDUINO_NANO_RP2040_CONNECT +#define MB_ARDUINO_NANO_RP2040_CONNECT +#endif +#else +#ifndef MB_ARDUINO_PICO +#define MB_ARDUINO_PICO +#endif +#endif + +#endif + + +#if defined(TEENSYDUINO) +#ifndef MB_ARDUINO_TEENSY +#define MB_ARDUINO_TEENSY +#endif +#endif + + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/MB_String.h b/lib/libesp32/ESP-Mail-Client/src/extras/MB_String.h new file mode 100644 index 000000000000..775ade48d53e --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/MB_String.h @@ -0,0 +1,2075 @@ + +/** + * Mobizt's SRAM/PSRAM supported String, version 1.2.9 + * + * Created December 3, 2022 + * + * Changes Log + * + * v1.2.9 + * - substring optimization + * + * v1.2.8 + * - Add support StringSumHelper class in Arduino + * + * v1.2.7 + * - Fix string sub type checking issue + * + * v1.2.6 + * - Update trim() function + * + * v1.2.5 + * - Fixed double string issue and add support long double + * + * v1.2.4 + * - Check PSRAM availability before allocating the memory + * + * v1.2.3 + * - Fixed flash string F and PSTR handle + * + * v1.2.2 + * - Add supports more MCUs. + * + * v1.2.1 + * - Add flash string manipulation functions. + * + * v1.2.0 + * - Add supports bool, integer and float manipulation. + * + * v1.1.2 + * - Fix substring with zero length returns the original string issue. + * + * v1.1.1 + * - Fix possible ESP8266 code exit without resetting the external heap stack + * + * v1.1.0 + * - Add support ESP8266 external virtual RAM (SRAM or PSRAM) + * + * v1.0.1 + * - Add trim function + * - Add version enum + * + * v1.0.0 + * - Initial release + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef MB_String_H +#define MB_String_H + +#include +#if !defined(__AVR__) +#include +#include +#include +#endif + +#define MB_STRING_MAJOR 1 +#define MB_STRING_MINOR 2 +#define MB_STRING_PATCH 5 + +#if defined(ESP8266) && defined(MMU_EXTERNAL_HEAP) && defined(MB_STRING_USE_PSRAM) +#include +#include +#define ESP8266_USE_EXTERNAL_HEAP +#endif + +#if defined(ESP8266) || defined(ESP32) +#define MBSTRING_FLASH_MCR FPSTR +#elif defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) +#define MBSTRING_FLASH_MCR PSTR +#else +#define MBSTRING_FLASH_MCR(s) (s) +#endif + +class MB_String; + +#define pgm2Str(p) (MB_String().appendP(p).c_str()) +#define num2Str(v, p) (MB_String().appendNum(v, p).c_str()) + +#if defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F4) +#define MB_IS_SAME std::is_same +#define MB_ENABLE_IF std::enable_if +#else +#define MB_IS_SAME is_same +#define MB_ENABLE_IF enable_if +#endif + +namespace mb_string +{ + enum mb_string_sub_type + { + mb_string_sub_type_none, + mb_string_sub_type_bool, + mb_string_sub_type_float, + mb_string_sub_type_double, + mb_string_sub_type_int8, + mb_string_sub_type_uint8, + mb_string_sub_type_int16, + mb_string_sub_type_uint16, + mb_string_sub_type_int32, + mb_string_sub_type_uint32, + mb_string_sub_type_int64, + mb_string_sub_type_uint64, + mb_string_sub_type_cstring, + mb_string_sub_type_chars, + mb_string_sub_type_mb_string, + mb_string_sub_type_arduino_string, + mb_string_sub_type_std_string, + mb_string_sub_type_fptr, + mb_string_sub_type_string_sum_helper + + }; + + typedef struct mb_string_ptr_t + { + + public: + mb_string_ptr_t(uint32_t addr = 0, mb_string_sub_type type = mb_string_sub_type_cstring, int precision = -1, const StringSumHelper *s = nullptr) + { + _addr = addr; + _type = type; + _precision = precision; + _ssh = s; + } + int precision() { return _precision; } + mb_string_sub_type type() { return _type; } + uint32_t address() { return _addr; } + const StringSumHelper *stringsumhelper() { return _ssh; } + + private: + mb_string_sub_type _type = mb_string_sub_type_none; + int _precision = -1; + uint32_t _addr = 0; + const StringSumHelper *_ssh = nullptr; + + } MB_StringPtr; + + template + struct enable_if + { + }; + template + struct enable_if + { + typedef T type; + }; + template + struct is_same + { + static bool const value = false; + }; + template + struct is_same + { + static bool const value = true; + }; + + template + struct is_num_int8 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_num_uint8 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_num_int16 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_num_uint16 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_num_int32 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value || + MB_IS_SAME::value || MB_IS_SAME::value || + MB_IS_SAME::value; + }; + + template + struct is_num_uint32 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value || + MB_IS_SAME::value; + }; + + template + struct is_num_int64 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_num_uint64 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_num_neg_int + { + static bool const value = is_num_int8::value || is_num_int16::value || + is_num_int32::value || is_num_int64::value; + }; + + template + struct is_num_pos_int + { + static bool const value = is_num_uint8::value || is_num_uint16::value || + is_num_uint32::value || is_num_uint64::value; + }; + + template + struct is_num_int + { + static bool const value = is_num_pos_int::value || is_num_neg_int::value; + }; + + template + struct is_num_float + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_bool + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct cs_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct ccs_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct as_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct cas_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct ss_t + { +#if !defined(__AVR__) + static bool const value = MB_IS_SAME::value; +#else + static bool const value = false; +#endif + }; + + template + struct css_t + { +#if !defined(__AVR__) + static bool const value = MB_IS_SAME::value; +#else + static bool const value = false; +#endif + }; + + template + struct ssh_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct fs_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct mbs_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct cmbs_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct pgm_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct is_const_chars + { + static bool const value = cs_t::value || ccs_t::value; + }; + + template + struct is_arduino_string + { + static bool const value = as_t::value || cas_t::value; + }; + + template + struct is_std_string + { + static bool const value = ss_t::value || css_t::value; + }; + + template + struct is_mb_string + { + static bool const value = mbs_t::value || cmbs_t::value; + }; + + template + struct is_arduino_string_sum_helper + { + static bool const value = ssh_t::value; + }; + + template + struct is_arduino_flash_string_helper + { + static bool const value = fs_t::value; + }; + + template + struct is_string + { + static bool const value = is_const_chars::value || is_arduino_string::value || + is_arduino_string_sum_helper::value || is_arduino_flash_string_helper::value || + is_std_string::value || is_mb_string::value; + }; + + template + uint32_t toAddr(T &v) { return reinterpret_cast(&v); } + +#if defined(__AVR__) + template + T addrTo(int address) + { + return reinterpret_cast(address); + } +#else + template + auto addrTo(int address) -> typename MB_ENABLE_IF::value, T>::type + { + return reinterpret_cast(address); + } +#endif + + template + auto getSubType(T val) -> typename MB_ENABLE_IF::value || is_num_float::value || MB_IS_SAME::value || is_const_chars::value || is_arduino_flash_string_helper::value || is_arduino_string::value || is_std_string::value || is_mb_string::value || MB_IS_SAME::value, mb_string_sub_type>::type + { + if (is_num_uint64::value) + return mb_string_sub_type_uint64; + else if (is_num_int64::value) + return mb_string_sub_type_int64; + else if (is_num_uint32::value) + return mb_string_sub_type_uint32; + else if (is_num_int32::value) + return mb_string_sub_type_int32; + else if (is_num_uint16::value) + return mb_string_sub_type_uint16; + else if (is_num_int16::value) + return mb_string_sub_type_int16; + else if (is_num_uint8::value) + return mb_string_sub_type_uint8; + else if (is_num_int8::value) + return mb_string_sub_type_int8; + else if (MB_IS_SAME::value) + return mb_string_sub_type_bool; + else if (MB_IS_SAME::value) + return mb_string_sub_type_float; + else if (MB_IS_SAME::value) + return mb_string_sub_type_double; + else if (is_arduino_string::value) + return mb_string_sub_type_arduino_string; + else if (is_std_string::value) + return mb_string_sub_type_std_string; + else if (is_mb_string::value) + return mb_string_sub_type_mb_string; + else if (is_arduino_flash_string_helper::value) + return mb_string_sub_type_fptr; + else if (MB_IS_SAME::value) + return mb_string_sub_type_string_sum_helper; + else if (ccs_t::value) + return mb_string_sub_type_cstring; + else if (cs_t::value) + return mb_string_sub_type_chars; + + return mb_string_sub_type_int8; + } + + template + auto getSubType(T *val) -> typename MB_ENABLE_IF::value || is_num_float::value || MB_IS_SAME::value || is_const_chars::value || is_arduino_flash_string_helper::value || is_arduino_string::value || is_std_string::value || is_mb_string::value || MB_IS_SAME::value, mb_string_sub_type>::type + { + return getSubType(*val); + } + + template + auto toStringPtr(const T &val) -> typename MB_ENABLE_IF::value || is_arduino_string::value || is_mb_string::value, MB_StringPtr>::type + { + return MB_StringPtr(reinterpret_cast(&val), getSubType(val)); + } + + template + auto toStringPtr(const T &val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type + { +#if defined(ESP8266) + return MB_StringPtr(reinterpret_cast(&val), getSubType(val), -1); + +#else + return MB_StringPtr(reinterpret_cast(&val), getSubType(val), -1, &val); +#endif + } + + template + auto toStringPtr(T val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type { return MB_StringPtr(reinterpret_cast(val), getSubType(val)); } + + template + auto toStringPtr(T &val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type { return MB_StringPtr(reinterpret_cast(val), getSubType(val)); } + +#if !defined(__AVR__) + template + auto toStringPtr(T val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type + { + return MB_StringPtr(); + } +#endif + + template + auto toStringPtr(T val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type + { + return val; + } + + template + auto toStringPtr(T &val, int precision = -1) -> typename MB_ENABLE_IF::value || is_num_float::value || MB_IS_SAME::value, MB_StringPtr>::type { return MB_StringPtr(reinterpret_cast(&val), getSubType(val), precision); } +} + +using namespace mb_string; + +class MB_String +{ +public: + MB_String() + { +#if defined(ESP8266_USE_EXTERNAL_HEAP) + // reserve default 1 byte external heap to refer to its pointer later + reset(1); +#endif + }; + + ~MB_String() + { + allocate(0, false); + }; + + MB_String(const char *cstr) + { + if (cstr) + copy(cstr, strlen_P(cstr)); + } + + MB_String(const MB_String &value) + { + *this = value; + } + + MB_String(const __FlashStringHelper *str) + { + *this = str; + } + +#if !defined(ESP8266) + MB_String(StringSumHelper rval) + { + *this = rval; + } +#endif + + MB_String(MB_StringPtr value) + { + *this = value; + } + + MB_String(String value) + { + *this = value; + } + + MB_String(bool value) + { + appendNum(value); + } + + MB_String(unsigned char value, unsigned char base = 10) + { + int len = 1 + 8 * sizeof(unsigned char); + reserve(len); + + if (bufLen > 0) + utoa(value, buf, base); + } + + MB_String(int value, unsigned char base = 10) + { + int len = 2 + 8 * sizeof(int); + reserve(len); + + if (bufLen > 0) + { + if (base == 10) + sprintf(buf, (const char *)MBSTRING_FLASH_MCR("%d"), value); + else + itoa(value, buf, base); + } + } + + MB_String(unsigned int value, unsigned char base = 10) + { + int len = 1 + 8 * sizeof(unsigned int); + reserve(len); + + if (bufLen > 0) + utoa(value, buf, base); + } + + MB_String(long value, unsigned char base = 10) + { + int len = 2 + 8 * sizeof(long); + reserve(len); + + if (bufLen > 0) + { + if (base == 10) + sprintf(buf, (const char *)MBSTRING_FLASH_MCR("%ld"), value); + else + ltoa(value, buf, base); + } + } + + MB_String(unsigned long value, unsigned char base = 10) + { + int len = 1 + 8 * sizeof(unsigned long); + reserve(len); + + if (bufLen > 0) + ultoa(value, buf, base); + } + + MB_String(float value, unsigned char decimalPlaces = 2) + { + reserve(33); + if (bufLen > 0) + { + char *v = toFloatStr(value, 0, decimalPlaces); + if (v) + { + strcpy(buf, v); + delP(&v); + } + } + } + + MB_String(double value, unsigned char decimalPlaces = 3) + { + reserve(33); + + if (bufLen > 0) + { + char *v = toFloatStr(value, 1, decimalPlaces); + if (v) + { + strcpy(buf, v); + delP(&v); + } + } + } + + MB_String(long double value, unsigned char decimalPlaces = 3) + { + reserve(65); + if (bufLen > 0) + { + char *v = toFloatStr(value, 2, decimalPlaces); + if (v) + { + strcpy(buf, v); + delP(&v); + } + } + } + +#if !defined(__AVR__) + MB_String &operator=(const std::string &rhs) + { + if (rhs.length() > 0) + copy(rhs.c_str(), rhs.length()); + else + clear(); + + return *this; + } +#endif + MB_String &operator=(const String &rhs) + { + + if (rhs.length() > 0) + copy(rhs.c_str(), rhs.length()); + else + clear(); + + return *this; + } + + MB_String &operator=(const __FlashStringHelper *str) + { + if (str) + appendF(str, true); + + return *this; + } + +#if !defined(ESP8266) + MB_String &operator=(StringSumHelper rval) + { + String temp = rval; + *this = temp; + return *this; + } + + MB_String &operator+=(StringSumHelper rval) + { + String temp = rval; + *this += temp; + return *this; + } +#endif + + MB_String &operator+=(const __FlashStringHelper *str) + { + if (str) + appendF(str); + + return *this; + } + + unsigned char operator==(const MB_String &rhs) const + { + return equals(rhs); + } + + unsigned char operator==(const char *cstr) const + { + return equals(cstr); + } + + unsigned char operator!=(const MB_String &rhs) const + { + return !equals(rhs); + } + + unsigned char operator!=(const char *cstr) const + { + return !equals(cstr); + } +#if !defined(__AVR__) + MB_String &operator+=(const std::string &rhs) + { + concat(rhs.c_str()); + return (*this); + } +#endif + MB_String &operator+=(const String &rhs) + { + concat(rhs.c_str()); + return (*this); + } + + MB_String &operator=(const MB_String &rhs) + { + if (this == &rhs) + return *this; + + if (rhs.length() > 0) + copy(rhs.buf, rhs.length()); + else + clear(); + + return *this; + } + + MB_String &operator+=(const MB_String &rhs) + { + concat(rhs); + return (*this); + } + + MB_String &operator+=(const char *cstr) + { + size_t len = strlen_P(cstr); + size_t slen = length(); + + if (_reserve(slen + len, false)) + { + strcat_P(buf, (PGM_P)cstr); + *(buf + slen + len) = '\0'; + } + + return (*this); + } + + MB_String &operator+=(char cstr) + { + append(1, cstr); + return (*this); + } + + MB_String &operator+=(bool value) + { + appendNum(value); + return (*this); + } + + MB_String &operator=(MB_StringPtr ptr) + { + setPtr(ptr); + return (*this); + } + + MB_String &operator+=(MB_StringPtr ptr) + { + appendPtr(ptr); + return (*this); + } + + template + auto operator=(T value) -> typename MB_ENABLE_IF::value || is_num_float::value || is_bool::value, MB_String &>::type + { + clear(); + appendNum(value); + return (*this); + } + + template + auto operator+=(T value) -> typename MB_ENABLE_IF::value || is_num_float::value || is_bool::value, MB_String &>::type + { + appendNum(value); + return (*this); + } + + MB_String &appendP(PGM_P pgms, bool clear = false) + { + if (clear) + this->clear(); + + char *t = pgmStr(pgms); + if (t) + { + *this += t; + delP(&t); + } + + return (*this); + } + + MB_String &appendF(const __FlashStringHelper *pstr, bool clear = false) + { + if (clear) + this->clear(); + + int len = strlen_P((PGM_P)pstr); + if (len > 0) + { + unsigned int newlen = length() + len; + reserve(newlen); + + if (bufLen > 0) + memcpy_P(buf + length(), (PGM_P)pstr, len + 1); + } + + return (*this); + } + + MB_String &setPtr(MB_StringPtr src) + { + clear(); + appendPtr(src); + return (*this); + }; + + MB_String &appendPtr(MB_StringPtr src) + { + if (src.type() == mb_string_sub_type_fptr) + appendF(addrTo(src.address())); + else if (src.type() == mb_string_sub_type_cstring || src.type() == mb_string_sub_type_chars) + *this += addrTo(src.address()); + else if (src.type() == mb_string_sub_type_arduino_string) + *this += *addrTo(src.address()); + else if (src.type() == mb_string_sub_type_string_sum_helper) +#if !defined(ESP8266) + *this += *src.stringsumhelper(); +#else + *this += *addrTo(src.address()); +#endif +#if !defined(__AVR__) + else if (src.type() == mb_string_sub_type_std_string) + *this += *addrTo(src.address()); +#endif + else if (src.type() == mb_string_sub_type_mb_string) + *this += *addrTo(src.address()); + else if (src.type() == mb_string_sub_type_uint64) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_int64) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_uint32) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_int32) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_uint16) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_int16) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_uint8) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_int8) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_bool) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_float) + appendNum(*addrTo(src.address()), src.precision()); + else if (src.type() == mb_string_sub_type_double) + appendNum(*addrTo(src.address()), src.precision()); + + return (*this); + }; + + template + auto appendNum(T value, int precision = 0) -> typename MB_ENABLE_IF::value || is_bool::value, MB_String &>::type + { + char *s = NULL; + + if (is_bool::value) + s = boolStr(value); + else if (is_num_neg_int::value) + { +#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) + s = int32Str(value); +#else + s = int64Str(value); +#endif + } + else if (is_num_pos_int::value) + { +#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) + s = uint32Str(value); +#else + s = uint64Str(value); +#endif + } + + if (s) + { + *this += s; + delP(&s); + } + + return (*this); + } + + MB_String &appendNum(float value, int precision = 5) + { + if (precision < 0) + precision = 5; + + char *s = toFloatStr(value, 0, precision); + if (s) + { + *this += s; + delP(&s); + } + return (*this); + } + + MB_String &appendNum(double value, int precision = 9) + { + if (precision < 0) + precision = 9; + + char *s = toFloatStr(value, 1, precision); + if (s) + { + *this += s; + delP(&s); + } + return (*this); + } + + MB_String &appendNum(long double value, int precision = 9) + { + if (precision < 0) + precision = 9; + + char *s = toFloatStr(value, 2, precision); + if (s) + { + *this += s; + delP(&s); + } + return (*this); + } + + MB_String &operator=(const char *cstr) + { + if (cstr) + copy(cstr, strlen_P(cstr)); + else + clear(); + + return *this; + } + + MB_String &operator=(char c) + { + clear(); + if (_reserve(1, false)) + { + *(buf) = c; + *(buf + 1) = '\0'; + } + + return *this; + } + + void trim() + { + int p1 = 0, p2 = length() - 1; + while (p1 < (int)length()) + { + if (buf[p1] > 32) + break; + p1++; + } + + while (p2 >= 0) + { + if (buf[p2] > 32) + break; + p2--; + } + + if (p1 == (int)length() && p2 < 0) + { + clear(); + return; + } + + if (p2 >= p1 && p2 >= 0 && p1 < (int)length()) + { + memmove(buf, buf + p1, p2 - p1 + 1); + buf[p2 - p1 + 1] = '\0'; + _reserve(p2 - p1 + 1, true); + } + } + + void append(const char *cstr, size_t n) + { + if (!cstr) + return; + + size_t slen = length(); + + if (n > strlen(cstr)) + n = strlen(cstr); + + if (_reserve(slen + n, false)) + { + memmove(buf + slen, cstr, n); + *(buf + slen + n) = '\0'; + } + } + + void append(size_t n, char c) + { + size_t slen = length(); + + if (_reserve(slen + n, false)) + { + for (size_t i = 0; i < n; i++) + *(buf + slen + i) = c; + *(buf + slen + n) = '\0'; + } + } + + void prepend(char c) + { + size_t slen = length(); + size_t len = 1; + + if (maxLength() < slen + len) + _reserve(slen + len, false); + + memmove(buf + len, buf, slen); + buf[0] = c; + buf[len + slen] = '\0'; + } + + void prepend(const char *cstr) + { + size_t slen = length(); + size_t len = strlen(cstr); + + if (maxLength() < slen + len) + _reserve(slen + len, false); + + memmove(buf + len, buf, slen); + memmove(buf, cstr, len); + buf[len + slen] = '\0'; + } + + const char *c_str() const + { + if (!buf) + return ""; + return (const char *)buf; + } + + char operator[](size_t index) const + { + if (index >= bufLen || !buf) + return 0; + return buf[index]; + } + + char &operator[](size_t index) + { + static char c; + if (index >= bufLen || !buf) + { + c = '\0'; + return c; + } + return buf[index]; + } + + void swap(MB_String &rhs) + { + rhs.clear(); + } + + void shrink_to_fit() + { + size_t slen = length(); + _reserve(slen, true); + } + + void pop_back() + { + if (length() > 0) + { + size_t slen = length(); + if (slen > 0) + buf[slen - 1] = '\0'; + _reserve(slen, true); + } + } + + size_t size() const + { + return length(); + } + + size_t bufferLength() const + { + return bufLen; + } + + size_t find(const MB_String &s, size_t index = 0) const + { + if (!s.buf) + return -1; + return strpos(buf, s.buf, index); + } + + size_t find(const char *s, size_t index = 0) const + { + return strpos(buf, s, index); + } + + size_t find(char c, size_t index = 0) const + { + return strpos(buf, c, index); + } + + size_t rfind(const char *s, size_t index = npos) const + { + return rstrpos(buf, s, index); + } + + size_t rfind(char c, size_t index = npos) const + { + return rstrpos(buf, c, index); + } + + void erase(size_t index = 0, size_t len = npos) + { + + if (!buf || index >= length()) + return; + + if (index + len > length() || len == npos) + len = length() - index; + + int rightLen = length() - index - len; + + memmove(buf + index, buf + index + len, rightLen); + + buf[index + rightLen] = '\0'; + + _reserve(length(), true); + } + + size_t length() const + { + if (!buf) + return 0; + return strlen(buf); + } + + MB_String substr(size_t offset, size_t len = npos) const + { + MB_String out; + substr(out, offset, len); + return out; + } + + void substr(MB_String &out, size_t offset, size_t len = npos) const + { + if (len > 0 && length() > 0 && offset < length()) + { + if (len > length() - offset) + len = length() - offset; + out.copy(buf + offset, len); + } + } + + void clear() + { +#if defined(ESP8266_USE_EXTERNAL_HEAP) + reset(1); +#else + allocate(0, false); +#endif + } + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + void reset(size_t len) + { + if (len == 0) + len = 4; + ESP.setExternalHeap(); + if (buf) + buf = (char *)realloc(buf, len); + else + buf = (char *)malloc(len); + ESP.resetHeap(); + + if (buf) + { + bufLen = len; + memset(buf, 0, len); + } + } +#endif + + void resize(size_t len) + { + if (_reserve(len, true)) + buf[len] = '\0'; + } + + MB_String &replace(size_t pos, size_t len, const char *replace) + { + size_t repLen = strlen(replace); + + if (length() > 0 && length() > pos && repLen > 0) + { + if (pos + len > length()) + len = length() - pos; + + if (repLen > len) + { + size_t rightLen = length() - pos - len; + + if (maxLength() < length() + repLen - len) + _reserve(length() + repLen - len, false); + + memmove(buf + pos + repLen, buf + pos + len, rightLen); + buf[pos + repLen + rightLen] = '\0'; + } + + memmove(buf + pos, replace, repLen); + } + + return *this; + } + + MB_String &replace(size_t pos, size_t len, const MB_String &replace) + { + return this->replace(pos, len, replace.c_str()); + } + + MB_String &insert(size_t pos, size_t n, char c) + { + size_t slen = length(); + + size_t rightLen = slen - pos; + + if (maxLength() < slen + n) + _reserve(slen + n, false); + + if (maxLength() >= slen + n) + { + memmove(buf + pos + n, buf + pos, rightLen); + + for (size_t i = 0; i < n; i++) + *(buf + pos + i) = c; + + buf[pos + n + rightLen] = '\0'; + } + + return *this; + } + + MB_String &insert(size_t pos, const char *cstr) + { + size_t insLen = strlen(cstr); + + if (length() > 0 && length() > pos && insLen > 0) + { + + size_t rightLen = length() - pos; + + if (maxLength() < length() + insLen) + _reserve(length() + insLen, false); + + memmove(buf + pos + insLen, buf + pos, rightLen); + buf[pos + insLen + rightLen] = '\0'; + memmove(buf + pos, cstr, insLen); + } + + return *this; + } + + MB_String &insert(size_t pos, const MB_String &str) + { + return insert(pos, str.c_str()); + } + + MB_String &insert(size_t pos, char c) + { + char temp[2]{c, '\0'}; + return insert(pos, temp); + } + + size_t find_first_of(const char *cstr, size_t pos = 0) const + { + if (!cstr) + return -1; + + return strpos(buf, cstr, pos); + } + + size_t find_first_of(const MB_String &str, size_t pos = 0) const + { + if (length() == 0 || pos >= length()) + return -1; + + return find_first_of(str.buf, pos); + } + + size_t find_first_not_of(const char *cstr, size_t pos = 0) const + { + if (length() == 0 || pos >= length()) + return -1; + + int size = strcspn(buf + pos, cstr); + if (size == 0) + { + while (size == 0 && pos < length()) + { + size = strcspn(buf + pos, cstr); + pos++; + } + + if (pos > 0) + pos--; + } + + return pos; + } + + size_t find_first_not_of(const MB_String &str, size_t pos = 0) const + { + if (length() == 0 || pos >= length() || str.length() == 0) + return -1; + + return find_first_not_of(str.buf, pos); + } + + size_t find_last_of(const char *cstr, size_t pos = npos) const + { + if (!cstr) + return -1; + + return rstrpos(buf, cstr, pos); + } + + size_t find_last_of(const MB_String &str, size_t pos = npos) const + { + if (str.length() == 0) + return -1; + + return find_last_of(str.buf, pos); + } + + size_t find_last_not_of(const char *cstr, size_t pos = npos) const + { + if (length() == 0) + return -1; + + if (pos >= length()) + pos = length() - 1; + + int p = length() - 1; + int size = strcspn(buf + p, cstr); + if (size == 0) + { + while (size == 0 && p > 0) + { + size = strcspn(buf + p, cstr); + p--; + } + p++; + } + + return p; + } + + size_t find_last_not_of(const MB_String &str, size_t pos = npos) const + { + if (str.length() == 0) + return -1; + + return find_last_not_of(str.buf, pos); + } + + MB_String & replaceAll(const char *find, const char *replace) + { + if (length() == 0) + return *this;; + + int i, cnt = 0; + int repLen = strlen(replace); + int findLen = strlen(find); + + MB_String temp = buf; + char *s = temp.buf; + clear(); + + for (i = 0; s[i] != '\0'; i++) + { + if (strstr(&s[i], find) == &s[i]) + { + cnt++; + i += findLen - 1; + } + } + + if (_reserve(i + cnt * (repLen - findLen) + 1, false)) + { + i = 0; + while (*s) + { + if (strstr(s, find) == s) + { + strcpy(&buf[i], replace); + i += repLen; + s += findLen; + } + else + buf[i++] = *s++; + } + + buf[i] = '\0'; + } + + temp.clear(); + + return *this; + } + + void replaceAll(const MB_String &find, const MB_String &replace) + { + replaceAll(find.c_str(), replace.c_str()); + } + + bool empty() const + { + return length() == 0; + } + + void reserve(size_t len) + { + if (_reserve(len, false)) + buf[len] = '\0'; + } + + static const size_t npos = -1; + +private: +#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) + + char *int32Str(signed long value) + { + char *t = (char *)newP(64); + sprintf(t, (const char *)MBSTRING_FLASH_MCR("%ld"), value); + return t; + } + + char *uint32Str(unsigned long value) + { + char *t = (char *)newP(64); + sprintf(t, (const char *)MBSTRING_FLASH_MCR("%lu"), value); + return t; + } + +#endif + + char *int64Str(signed long long value) + { + char *t = (char *)newP(64); + sprintf(t, (const char *)MBSTRING_FLASH_MCR("%lld"), value); + return t; + } + + char *uint64Str(unsigned long long value) + { + char *t = (char *)newP(64); + sprintf(t, (const char *)MBSTRING_FLASH_MCR("%llu"), value); + return t; + } + + char *boolStr(bool value) + { + char *t = (char *)newP(8); + value ? strcpy(t, (const char *)MBSTRING_FLASH_MCR("true")) : strcpy(t, (const char *)MBSTRING_FLASH_MCR("false")); + return t; + } + + char *toFloatStr(long double value, int type, int precision) + { + int width = type == 0 ? 32 : 64; + + char *t = (char *)newP(width); + + if (t) + { + MB_String fmt = MBSTRING_FLASH_MCR("%."); + fmt += precision; + if (type == 2) + fmt += MBSTRING_FLASH_MCR("L"); + fmt += MBSTRING_FLASH_MCR("f"); + sprintf(t, fmt.c_str(), value); + trim(t); + } + + return t; + } + + char *nullStr() + { + char *t = (char *)newP(6); + strcpy(t, (const char *)MBSTRING_FLASH_MCR("null")); + return t; + } + + char *pgmStr(PGM_P p) + { + char *t = (char *)newP(strlen_P(p)); + strcpy_P(t, p); + return t; + } + + void trim(char *s) + { + if (!s) + return; + size_t i = strlen(s) - 1; + while (s[i] == '0' && i > 0) + { + if (s[i - 1] == '.') + { + i--; + break; + } + if (s[i - 1] != '0') + break; + i--; + } + if (i < strlen(s) - 1) + s[i] = '\0'; + } + + void *newP(size_t len) + { + void *p; + size_t newLen = getReservedLen(len); +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) + if (ESP.getPsramSize() > 0) + p = (void *)ps_malloc(newLen); + else + p = (void *)malloc(newLen); + if (!p) + return NULL; + +#else + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.setExternalHeap(); +#endif + + p = (void *)malloc(newLen); + bool nn = p ? true : false; + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.resetHeap(); +#endif + + if (!nn) + return NULL; + +#endif + memset(p, 0, newLen); + return p; + } + + void delP(void *ptr) + { + void **p = (void **)ptr; + if (*p) + { + free(*p); + *p = 0; + } + } + + size_t getReservedLen(size_t len) + { + int blen = len + 1; + + int newlen = (blen / 4) * 4; + + if (newlen < blen) + newlen += 4; + + return (size_t)newlen; + } + + size_t maxLength() const + { + if (bufferLength() == 0) + return 0; + return bufferLength() - 1; + } + + void concat(const MB_String &s) + { + if (s.length() == 0) + return; + + if (&s == this) + { + size_t slen = length(); + + if (2 * slen > maxLength()) + { + if (!_reserve(2 * slen, false)) + return; + } + + memmove(buf + slen, buf, slen); + buf[2 * slen] = '\0'; + } + else + { + concat(s.buf, s.length()); + } + } + + void concat(const char *cstr, size_t len) + { + if (!cstr) + return; + + size_t slen = length(); + + if (slen + len > maxLength()) + { + if (!_reserve(slen + len, false)) + return; + } + + memmove(buf + slen, cstr, len); + buf[slen + len] = '\0'; + } + + void concat(const char *cstr) + { + if (!cstr) + return; + + concat(cstr, strlen(cstr)); + } + + void move(MB_String &rhs) + { + if (buf) + { + if (bufLen >= rhs.bufLen) + { + strcpy(buf, rhs.buf); + bufLen = rhs.bufLen; + rhs.bufLen = 0; + return; + } + else + { + free(buf); + } + } + buf = rhs.buf; + bufLen = rhs.bufLen; + rhs.buf = NULL; + } + + void allocate(size_t len, bool shrink) + { + + if (len == 0) + { + if (buf) + free(buf); + buf = NULL; + bufLen = 0; + return; + } + + if (len > bufLen || shrink) + { + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.setExternalHeap(); +#endif + + if (shrink || (bufLen > 0 && buf)) + { + int slen = length(); + +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) + if (ESP.getPsramSize() > 0) + buf = (char *)ps_realloc(buf, len); + else + buf = (char *)realloc(buf, len); +#else + buf = (char *)realloc(buf, len); +#endif + if (buf) + { + buf[slen] = '\0'; + bufLen = len; + } + } + else + { +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) + if (ESP.getPsramSize() > 0) + buf = (char *)ps_malloc(len); + else + buf = (char *)malloc(len); +#else + buf = (char *)malloc(len); +#endif + if (buf) + { + buf[0] = '\0'; + bufLen = len; + } + } + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.resetHeap(); +#endif + } + } + + MB_String ©(const char *cstr, size_t length) + { + + if (!_reserve(length, false)) + { + clear(); + return *this; + } + + memcpy_P(buf, (PGM_P)cstr, length); + buf[length] = '\0'; + + return *this; + } + + bool _reserve(size_t len, bool shrink) + { + + size_t newlen = getReservedLen(len); + if (shrink) + allocate(newlen, true); + else if (newlen > bufLen) + allocate(newlen, false); + + return newlen <= bufLen; + } + + int strpos(const char *haystack, const char *needle, int offset) const + { + if (!haystack || !needle) + return -1; + + int hlen = strlen(haystack); + int nlen = strlen(needle); + + if (hlen == 0 || nlen == 0) + return -1; + + int hidx = offset, nidx = 0; + while ((*(haystack + hidx) != '\0') && (*(needle + nidx) != '\0') && hidx < hlen) + { + if (*(needle + nidx) != *(haystack + hidx)) + { + hidx++; + nidx = 0; + } + else + { + nidx++; + hidx++; + if (nidx == nlen) + return hidx - nidx; + } + } + + return -1; + } + + int strpos(const char *haystack, char needle, int offset) const + { + if (!haystack || needle == 0) + return -1; + + int hlen = strlen(haystack); + + if (hlen == 0) + return -1; + + int hidx = offset; + while ((*(haystack + hidx) != '\0') && hidx < hlen) + { + if (needle == *(haystack + hidx)) + return hidx; + hidx++; + } + + return -1; + } + + int rstrpos(const char *haystack, const char *needle, int offset /* start search from this offset to the left string */) const + { + if (!haystack || !needle) + return -1; + + int hlen = strlen(haystack); + int nlen = strlen(needle); + + if (hlen == 0 || nlen == 0) + return -1; + + int hidx = offset; + + if (hidx >= hlen || (size_t)offset == npos) + hidx = hlen - 1; + + int nidx = nlen - 1; + + while (hidx >= 0) + { + if (*(needle + nidx) != *(haystack + hidx)) + { + hidx--; + nidx = nlen - 1; + } + else + { + if (nidx == 0) + return hidx + nidx; + nidx--; + hidx--; + } + } + + return -1; + } + + int rstrpos(const char *haystack, char needle, int offset /* start search from this offset to the left char */) const + { + if (!haystack || needle == 0) + return -1; + + int hlen = strlen(haystack); + + if (hlen == 0) + return -1; + + int hidx = offset; + + if (hidx >= hlen || (size_t)offset == npos) + hidx = hlen - 1; + + while (hidx >= 0) + { + if (needle == *(haystack + hidx)) + return hidx; + hidx--; + } + + return -1; + } + + int compareTo(const MB_String &s) const + { + if (!buf || !s.buf) + { + if (s.buf && s.length() > 0) + return 0 - *(unsigned char *)s.buf; + if (buf && length() > 0) + return *(unsigned char *)buf; + return 0; + } + return strcmp(buf, s.buf); + } + + unsigned char equals(const MB_String &s2) const + { + return (length() == s2.length() && compareTo(s2) == 0); + } + + unsigned char equals(const char *cstr) const + { + if (length() == 0) + return (cstr == NULL || *cstr == 0); + if (cstr == NULL) + return buf[0] == 0; + return strcmp(buf, cstr) == 0; + } + + char *ultoa(unsigned long value, char *str, int radix) + { + const char *format = NULL; + + switch (radix) + { + case 8: + format = "%o"; + break; + case 10: + format = "%ul"; + break; + case 16: + format = "%x"; + break; + } + + if (format == NULL) + return str; + + int size = sprintf(str, format, value); + return &str[size]; + } + +#if (!defined(ESP32) && !defined(ESP8266) && !defined(ARDUINO_ARCH_STM32) && !defined(ARDUINO_ARCH_SAMD)) || defined(ARDUINO_NANO_RP2040_CONNECT) + char *ltoa(long value, char *str, int radix) + { + const char *format = NULL; + + switch (radix) + { + case 8: + format = "%o"; + break; + case 10: + format = "%l"; + break; + case 16: + format = "%x"; + break; + } + + if (format == NULL) + return str; + + int size = sprintf(str, format, value); + return &str[size]; + } + + char *utoa(unsigned int value, char *str, int radix) + { + const char *format = NULL; + + switch (radix) + { + case 8: + format = "%o"; + break; + case 10: + format = "%u"; + break; + case 16: + format = "%x"; + break; + } + + if (format == NULL) + return str; + + int size = sprintf(str, format, value); + return &str[size]; + } + + char *itoa(int value, char *str, int radix) + { + const char *format = NULL; + + switch (radix) + { + case 8: + format = "%o"; + break; + case 10: + format = "%d"; + break; + case 16: + format = "%x"; + break; + } + + if (format == NULL) + return str; + + int size = sprintf(str, format, value); + return &str[size]; + } +#endif + + char *buf = NULL; + size_t bufLen = 0; +}; + +inline MB_String operator+(const MB_String &lhs, const MB_String &rhs) +{ + MB_String res; + res.reserve(lhs.length() + rhs.length()); + res += lhs; + res += rhs; + return res; +} + +#if !defined(__AVR__) + +inline MB_String operator+(MB_String &&lhs, const MB_String &rhs) +{ + lhs += rhs; + return std::move(lhs); +} + +inline MB_String operator+(MB_String &lhs, MB_String &&rhs) +{ + lhs += rhs; + return std::move(lhs); +} + +inline MB_String operator+(MB_String &lhs, char rhs) +{ + lhs += rhs; + return std::move(lhs); +} + +inline MB_String operator+(char lhs, MB_String &rhs) +{ + rhs.insert(0, lhs); + return rhs; +} + +inline MB_String operator+(MB_String &&lhs, char rhs) +{ + return std::move(lhs.insert(0, rhs)); +} + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/MB_Time.h b/lib/libesp32/ESP-Mail-Client/src/extras/MB_Time.h new file mode 100644 index 000000000000..73d84ac2bee9 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/MB_Time.h @@ -0,0 +1,435 @@ +#ifndef MB_Time_H +#define MB_Time_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +/* + * Time helper class v1.0.7 + * + * Created August 28, 2023 + * + * Do not remove or modify this file as it required for AVR, ARM, SAMD devices and external client to work. + * + * The MIT License (MIT) + * Copyright (c) 2022 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "Networks_Provider.h" + +#define ESP_TIME_DEFAULT_TS 1577836800 +#define ESP_TIME_NON_TS -1000 + +#include +#include + +#if defined(ESP32) && !defined(ESP_ARDUINO_VERSION) /* ESP32 core < v2.0.x */ +#include +#else +#include +#endif + +#if defined(ESP_MAIL_USE_PSRAM) +#define MB_STRING_USE_PSRAM +#endif + +#include "MB_String.h" +#include "MB_MCU.h" + +#if defined(ESP8266) +#include "user_interface.h" +#endif + +#if defined(__AVR__) || defined(MB_ARDUINO_TEENSY) +#define MB_TIME_PGM_ATTR +#else +#define MB_TIME_PGM_ATTR PROGMEM +#endif + +#if !defined(MB_ARDUINO_ESP) +static const char *mb_months[12] MB_TIME_PGM_ATTR = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; +#endif + +enum base_time_type_t +{ + base_time_type_undefined = -1, + base_time_type_unset = 0, + base_time_type_auto = 1, + base_time_type_user = 2 +}; + +class MB_Time +{ +public: + MB_Time() + { + } + + ~MB_Time() + { + clear(); + } + + void clear() + { +#if defined(ENABLE_NTP_TIME) + if (_sv1.length()) + { + _sv1.clear(); + _sv2.clear(); + _sv3.clear(); + } +#endif + } + + void readNTPTime(unsigned long waitMs, bool debugProgress) + { + if (!timeReady()) + { + if (WiFI_CONNECTED) + { + +#if defined(ENABLE_NTP_TIME) +#if (defined(ESP32) || defined(ESP8266)) + configTime(_gmt_offset * 3600, _daylight_offset * 60, _sv1.c_str(), _sv2.c_str(), _sv3.c_str()); +#elif defined(ARDUINO_RASPBERRY_PI_PICO_W) + NTP.begin(_sv1.c_str(), _sv2.c_str()); + NTP.waitSet(); +#endif +#endif + unsigned long ms = millis(); + +#if !defined(SILENT_MODE) + unsigned long pgms = 0; +#endif + do + { +#if defined(ESP_MAIL_HAS_WIFI_TIME) + _base_ts = WiFi.getTime() > ESP_TIME_DEFAULT_TS ? WiFi.getTime() : _base_ts; +#elif defined(ENABLE_NTP_TIME) + _base_ts = time(nullptr) > ESP_TIME_DEFAULT_TS ? time(nullptr) : _base_ts; +#else + break; +#endif + +#if !defined(SILENT_MODE) + if (debugProgress && millis() - pgms > 50) + { + pgms = millis(); + esp_mail_debug_print(".", false); + } +#endif + + yield_impl(); + } while (millis() - ms < waitMs && _base_ts < ESP_TIME_DEFAULT_TS); +#if !defined(SILENT_MODE) + if (debugProgress) + esp_mail_debug_print("", true); +#endif + } + } + } + + int setTimestamp(time_t ts, float gmtOffset) + { + _gmt_offset = gmtOffset; + _base_time_type = ts > ESP_TIME_DEFAULT_TS ? base_time_type_user : base_time_type_unset; +#if defined(MB_ARDUINO_ESP) + struct timeval tm; // sec, us + tm.tv_sec = ts; + tm.tv_usec = 0; + return settimeofday((const struct timeval *)&tm, 0); +#else + _ts_offset = ts - millis() / 1000; + return 1; +#endif + } + + /** Get the timestamp from the year, month, date, hour, minute, + * and second provided. + * + * @param year The year. + * @param mon The month from 1 to 12. + * @param date The dates. + * @param hour The hours. + * @param mins The minutes. + * @param sec The seconds. + * @return time_t The value of timestamp. + */ + time_t getTimestamp(int year, int mon, int date, int hour, int mins, int sec) + { + struct tm timeinfo; + timeinfo.tm_year = year - 1900; + timeinfo.tm_mon = mon - 1; + timeinfo.tm_mday = date; + timeinfo.tm_hour = hour; + timeinfo.tm_min = mins; + timeinfo.tm_sec = sec; + time_t ts = mktime(&timeinfo); + return ts; + } + + /** Get the timestamp from the RFC 2822 time string. + * e.g. Mon, 02 May 2022 00:30:00 +0000 or 02 May 2022 00:30:00 +0000 + * + * @param gmt Return the GMT time. + * @return timestamp of time string. + */ + time_t getTimestamp(const char *timeString, bool gmt = false) + { +#if defined(MB_ARDUINO_ESP) + struct tm timeinfo; + + if (strstr(timeString, ",") != NULL) + strptime(timeString, "%a, %d %b %Y %H:%M:%S %z", &timeinfo); + else + strptime(timeString, "%d %b %Y %H:%M:%S %z", &timeinfo); + + time_t ts = mktime(&timeinfo); + return ts; + +#else + + time_t ts = 0; + _vectorImpl tk; + MB_String s1 = timeString; + + splitToken(s1, tk, ' '); + int day = 0, mon = 0, year = 0, hr = 0, mins = 0, sec = 0, tz_h = 0, tz_m = 0; + + int tkindex = tk.size() == 5 ? -1 : 0; // No week days? + + // some response may include (UTC) and (ICT) + if (tk.size() >= 5) + { + day = atoi(tk[tkindex + 1].c_str()); + for (size_t i = 0; i < 12; i++) + { + if (strcmp_P(mb_months[i], tk[tkindex + 2].c_str()) == 0) + mon = i; + } + + // RFC 822 year to RFC 2822 + if (tk[tkindex + 3].length() == 2) + tk[tkindex + 3].prepend("20"); + + year = atoi(tk[tkindex + 3].c_str()); + + _vectorImpl tk2; + splitToken(tk[tkindex + 4], tk2, ':'); + if (tk2.size() == 3) + { + hr = atoi(tk2[0].c_str()); + mins = atoi(tk2[1].c_str()); + sec = atoi(tk2[2].c_str()); + } + + ts = getTimestamp(year, mon + 1, day, hr, mins, sec); + + if (tk[tkindex + 5].length() == 5 && gmt) + { + char tmp[6]; + memset(tmp, 0, 6); + strncpy(tmp, tk[tkindex + 5].c_str() + 1, 2); + tz_h = atoi(tmp); + + memset(tmp, 0, 6); + strncpy(tmp, tk[tkindex + 5].c_str() + 3, 2); + tz_m = atoi(tmp); + + time_t tz = tz_h * 60 * 60 + tz_m * 60; + if (tk[tkindex + 5][0] == '+') + ts -= tz; // remove time zone offset + else + ts += tz; + } + } + return ts; +#endif + } + + /** Get the current timestamp. + * + * @return uint64_t The value of current timestamp. + */ + uint64_t getCurrentTimestamp() + { + getBaseTime(); + return _base_ts; + } + + /** Get the current rfc822 date time string that valid for Email. + * @return String The current date time string. + */ + String getDateTimeString() + { + getBaseTime(); + + char tbuf[40]; + strftime(tbuf, 40, "%a, %d %b %Y %H:%M:%S %z", &_time_info); + MB_String tStr = tbuf, tzStr; + + int p = _gmt_offset < 0 ? -1 : 1; + float dif = (p * (_gmt_offset * 10 - (int)_gmt_offset * 10)) * 60.0 / 10; + tzStr = (_gmt_offset < 0) ? '-' : '+'; + + if ((int)_gmt_offset < 10) + tzStr += 0; + + tzStr += (int)_gmt_offset; + + if (dif < 10) + tzStr += 0; + + tzStr += (int)dif; + + // replace for valid timezone + tStr.replaceAll("+0000", tzStr); + return tStr.c_str(); + } + + String getDateTimeString(time_t ts, const char *format) + { + char tbuf[100]; + strftime(tbuf, 100, format, localtime(&ts)); + return tbuf; + } + + void begin(float gmtOffset, float daylightOffset, const char *servers) + { + if (timeReady() && _base_time_type == base_time_type_undefined) + _base_time_type = base_time_type_auto; + else if (_base_time_type == base_time_type_undefined) + _base_time_type = base_time_type_unset; + +#if defined(ENABLE_NTP_TIME) && (defined(ESP32) || defined(ESP8266) || defined(ARDUINO_RASPBERRY_PI_PICO_W)) + + _vectorImpl tk; + MB_String sv = servers; + + clear(); + + splitToken(sv, tk, ','); + + if (tk.size() > 0) + _sv1 = tk[0]; + if (tk.size() > 1) + _sv2 = tk[1]; + if (tk.size() > 2) + _sv3 = tk[2]; + +#endif + + if ((gmtOffset > ESP_TIME_NON_TS && _gmt_offset != gmtOffset) || (daylightOffset > ESP_TIME_NON_TS && _daylight_offset != daylightOffset)) + { + // Reset system timestamp when config changed + _base_ts = 0; + if (gmtOffset > ESP_TIME_NON_TS) + _gmt_offset = gmtOffset; + if (daylightOffset > ESP_TIME_NON_TS) + _daylight_offset = daylightOffset; + + if (_base_time_type == base_time_type_unset) + setTimestamp(millis(), _gmt_offset); + } + } + + /** get the clock ready state + */ + bool timeReady() + { + getBaseTime(); + return _time_ready; + } + +private: + time_t _base_ts = 0; + struct tm _time_info; + float _gmt_offset = ESP_TIME_NON_TS; + float _daylight_offset = ESP_TIME_NON_TS; + void splitToken(MB_String &str, _vectorImpl &tk, char delim) + { + size_t current, previous = 0; + current = str.find(delim, previous); + MB_String s; + while (current != MB_String::npos) + { + + s = str.substr(previous, current - previous); + s.trim(); + + if (s.length() > 0) + tk.push_back(s); + previous = current + 1; + current = str.find(delim, previous); + } + + s = str.substr(previous, current - previous); + + s.trim(); + + if (s.length() > 0) + tk.push_back(s); + + s.clear(); + } + + // 9Safe) Get base timestamp + void getBaseTime() + { + +#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) + + if (_base_ts < time(nullptr) && time(nullptr) > ESP_TIME_DEFAULT_TS) + _base_ts = time(nullptr); + +#if defined(ESP32) + getLocalTime(&_time_info); +#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) + localtime_r(&_base_ts, &_time_info); +#endif + +#elif defined(ESP_MAIL_HAS_WIFI_TIME) + if (WiFI_CONNECTED) + _base_ts = WiFi.getTime() > ESP_TIME_DEFAULT_TS ? WiFi.getTime() : _base_ts; +#else + _base_ts = _ts_offset + millis() / 1000; +#endif + + _time_ready = _base_ts > ESP_TIME_DEFAULT_TS; + if (_time_ready) + _ts_offset = _base_ts - millis() / 1000; + } + +#if defined(ENABLE_NTP_TIME) + // in ESP8266 these NTP sever strings should be existed during configuring time. + MB_String _sv1, _sv2, _sv3; +#endif + + uint32_t _ts_offset = 0; + bool _time_ready = false; + base_time_type_t _base_time_type = base_time_type_undefined; +}; + +#endif // MB_Time_H diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/Networks_Provider.h b/lib/libesp32/ESP-Mail-Client/src/extras/Networks_Provider.h new file mode 100644 index 000000000000..fd523be67e2a --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/Networks_Provider.h @@ -0,0 +1,131 @@ +#ifndef ESP_MAIL_NETWORKS_PROVIDER_H +#define ESP_MAIL_NETWORKS_PROVIDER_H + +#include "../ESP_Mail_FS.h" + +#include "../ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +#if __has_include() +#include +#endif + +#include "ESP8266_Supports.h" + +// Renesas devices +#if defined(ARDUINO_UNOWIFIR4) || defined(ARDUINO_MINIMA) || defined(ARDUINO_PORTENTA_C33) +#define ESP_MAIL_STRSEP strsepImpl +#define ESP_MAIL_USE_STRSEP_IMPL +#else +#define ESP_MAIL_STRSEP strsep +#endif + +#if defined(ESP32) || defined(ESP8266) || defined(ARDUINO_RASPBERRY_PI_PICO_W) || \ + defined(ARDUINO_UNOWIFIR4) || defined(ARDUINO_PORTENTA_C33) || \ + defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) || \ + __has_include() ||__has_include() + +#if !defined(ESP_MAIL_DISABLE_ONBOARD_WIFI) + +#define ESP_MAIL_WIFI_IS_AVAILABLE + +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#if !defined(ARDUINO_RASPBERRY_PI_PICO_W) && \ + !defined(MB_ARDUINO_ARCH_SAMD) && \ + !defined(MB_ARDUINO_MBED_PORTENTA) && \ + !defined(ARDUINO_UNOWIFIR4) && \ + !defined(ARDUINO_PORTENTA_C33) && \ + !defined(ARDUINO_NANO_RP2040_CONNECT) +#define ESP_MAIL_HAS_WIFI_DISCONNECT +#endif + +#if defined(ARDUINO_PORTENTA_C33) +#define CONST_STRING_CAST char * // C33 WiFi library SSID is char array +#else +#define CONST_STRING_CAST const char * +#endif + +// WiFiS3 getTime is currently return 0 (not implemented) +#if __has_include() || __has_include() +#define ESP_MAIL_HAS_WIFI_TIME +#endif + +#if defined(MB_ARDUINO_PICO) && __has_include() +#define ESP_MAIL_HAS_WIFIMULTI +#endif + +#endif + +#endif + +#if !defined(ESP_MAIL_DISABLE_NATIVE_ETHERNET) + +#if defined(ESP32) && __has_include() +#include +#define ESP_MAIL_ETH_IS_AVAILABLE +#elif defined(ESP8266) && defined(ESP8266_CORE_SDK_V3_X_X) +#if defined(INC_ENC28J60_LWIP) || defined(INC_W5100_LWIP) || defined(INC_W5500_LWIP) +#define ESP_MAIL_ETH_IS_AVAILABLE +#endif +#endif + +#endif + +#if defined(TINY_GSM_MODEM_SIM800) || \ + defined(TINY_GSM_MODEM_SIM808) || \ + defined(TINY_GSM_MODEM_SIM868) || \ + defined(TINY_GSM_MODEM_SIM900) || \ + defined(TINY_GSM_MODEM_SIM7000) || \ + defined(TINY_GSM_MODEM_SIM7000) || \ + defined(TINY_GSM_MODEM_SIM7000SSL) || \ + defined(TINY_GSM_MODEM_SIM7070) || \ + defined(TINY_GSM_MODEM_SIM7080) || \ + defined(TINY_GSM_MODEM_SIM7090) || \ + defined(TINY_GSM_MODEM_SIM5320) || \ + defined(TINY_GSM_MODEM_SIM5360) || \ + defined(TINY_GSM_MODEM_SIM5300) || \ + defined(TINY_GSM_MODEM_SIM7100) || \ + defined(TINY_GSM_MODEM_SIM7600) || \ + defined(TINY_GSM_MODEM_SIM7800) || \ + defined(TINY_GSM_MODEM_SIM7500) || \ + defined(TINY_GSM_MODEM_UBLOX) || \ + defined(TINY_GSM_MODEM_SARAR4) || \ + defined(TINY_GSM_MODEM_M95) || \ + defined(TINY_GSM_MODEM_BG96) || \ + defined(TINY_GSM_MODEM_A6) || \ + defined(TINY_GSM_MODEM_A7) || \ + defined(TINY_GSM_MODEM_M590) || \ + defined(TINY_GSM_MODEM_MC60) || \ + defined(TINY_GSM_MODEM_MC60E) || \ + defined(TINY_GSM_MODEM_XBEE) || \ + defined(TINY_GSM_MODEM_SEQUANS_MONARCH) +#define ESP_MAIL_TINYGSM_IS_AVAILABLE +#endif + +#if defined(ESP_MAIL_TINYGSM_IS_AVAILABLE) && __has_include() +#include +#define ESP_MAIL_GSM_MODEM_IS_AVAILABLE +#endif + +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) +#define WiFI_CONNECTED (WiFi.status() == WL_CONNECTED) +#else +#define WiFI_CONNECTED false +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/RFC2047.cpp b/lib/libesp32/ESP-Mail-Client/src/extras/RFC2047.cpp new file mode 100644 index 000000000000..95e5ac140808 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/RFC2047.cpp @@ -0,0 +1,192 @@ +#ifndef RFC2047_CPP +#define RFC2047_CPP + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +#include "RFC2047.h" + +RFC2047_Decoder::RFC2047_Decoder() {} +RFC2047_Decoder::~RFC2047_Decoder() {} + +void RFC2047_Decoder::decode(MB_FS *mbfs, char *d, const char *s, size_t dlen) +{ + if (!mbfs) + return; + + this->mbfs = mbfs; + + const char *p, *q; + size_t n; + int found_encoded = 0; + + dlen--; /* save room for the terminal nul */ + + while (*s && dlen > 0) + { + if ((p = strstr(s, "=?")) == NULL || + (q = strchr(p + 2, '?')) == NULL || + (q = strchr(q + 1, '?')) == NULL || + (q = strstr(q + 1, "?=")) == NULL) + { + /* no encoded words */ + if (d != s) + strfcpy(d, s, dlen + 1); + return; + } + + if (p != s) + { + n = (size_t)(p - s); + /* ignore spaces between encoded words */ + if (!found_encoded || strspn(s, " \t\r\n") != n) + { + if (n > dlen) + n = dlen; + if (d != s) + memcpy(d, s, n); + d += n; + dlen -= n; + } + } + + rfc2047DecodeWord(d, p, dlen); + found_encoded = 1; + s = q + 2; + n = strlen(d); + dlen -= n; + d += n; + } + *d = 0; +} + +void RFC2047_Decoder::rfc2047DecodeWord(char *d, const char *s, size_t dlen) +{ + + if (!mbfs) + return; + + char *p = safe_strdup(s); + char *pp = p; + char *end = p; + char *pd = d; + size_t len = dlen; + int enc = 0, filter = 0, count = 0, c1, c2, c3, c4; + + while (pp != NULL) + { + // See RFC2047.h + ESP_MAIL_STRSEP(&end, "?"); + count++; + switch (count) + { + case 2: + if (strcasecmp(pp, Charset) != 0) + { + filter = 1; + } + break; + case 3: + if (toupper(*pp) == 'Q') + enc = ENCQUOTEDPRINTABLE; + else if (toupper(*pp) == 'B') + enc = ENCBASE64; + else + return; + break; + case 4: + if (enc == ENCQUOTEDPRINTABLE) + { + while (*pp && len > 0) + { + if (*pp == '_') + { + *pd++ = ' '; + len--; + } + else if (*pp == '=') + { + *pd++ = (hexval(pp[1]) << 4) | hexval(pp[2]); + len--; + pp += 2; + } + else + { + *pd++ = *pp; + len--; + } + pp++; + } + *pd = 0; + } + else if (enc == ENCBASE64) + { + while (*pp && len > 0) + { + c1 = base64val(pp[0]); + c2 = base64val(pp[1]); + *pd++ = (c1 << 2) | ((c2 >> 4) & 0x3); + if (--len == 0) + break; + + if (pp[2] == '=') + break; + + c3 = base64val(pp[2]); + *pd++ = ((c2 & 0xf) << 4) | ((c3 >> 2) & 0xf); + if (--len == 0) + break; + + if (pp[3] == '=') + break; + + c4 = base64val(pp[3]); + *pd++ = ((c3 & 0x3) << 6) | c4; + if (--len == 0) + break; + + pp += 4; + } + *pd = 0; + } + break; + } + + pp = end; + } + + mbfs->delP(&p); + + if (filter) + { + pd = d; + while (*pd) + { + if (!IsPrint(*pd)) + *pd = '?'; + pd++; + } + } + return; +} + +char *RFC2047_Decoder::safe_strdup(const char *s) +{ + + if (!mbfs) + return 0; + + char *p; + size_t l; + + if (!s || !*s) + return 0; + l = strlen(s) + 1; + p = (char *)mbfs->newP(l); + memcpy(p, s, l); + return (p); +} + +#endif // RFC2047_CPP \ No newline at end of file diff --git a/lib/libesp32/lib_mail/src/extras/RFC2047.h b/lib/libesp32/ESP-Mail-Client/src/extras/RFC2047.h similarity index 58% rename from lib/libesp32/lib_mail/src/extras/RFC2047.h rename to lib/libesp32/ESP-Mail-Client/src/extras/RFC2047.h index 1753a2119e56..baadaa672b81 100644 --- a/lib/libesp32/lib_mail/src/extras/RFC2047.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/RFC2047.h @@ -1,12 +1,43 @@ +#pragma once #ifndef RFC2047_H #define RFC2047_H +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif #include +#include "ESP_Mail_FS.h" +#include "MB_FS.h" +#include "Networks_Provider.h" +#if defined(ESP32) +#if defined(BOARD_HAS_PSRAM) && defined(ESP_Mail_USE_PSRAM) +#include +#endif +#endif -#define strfcpy(A,B,C) strncpy(A,B,C), *(A+(C)-1)=0 +#define strfcpy(A, B, C) strncpy(A, B, C), *(A + (C)-1) = 0 + +#if defined(ESP_MAIL_USE_STRSEP_IMPL) +// This is strsep implementation because strdup may not available in some platform. +static char *__attribute__((used)) strsepImpl(char **stringp, const char *delim) +{ + char *rv = *stringp; + if (rv) + { + *stringp += strcspn(*stringp, delim); + if (**stringp) + *(*stringp)++ = '\0'; + else + *stringp = 0; + } + return rv; +} + +#endif enum { @@ -41,29 +72,23 @@ __attribute__((used)) static int Index_64[128] = { 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1}; #define IsPrint(c) (isprint((unsigned char)(c)) || \ - ((unsigned char)(c) >= 0xa0)) + ((unsigned char)(c) >= 0xa0)) #define hexval(c) Index_hex[(unsigned int)(c)] #define base64val(c) Index_64[(unsigned int)(c)] -class RFC2047_Decoder{ - - public: - RFC2047_Decoder(); - ~RFC2047_Decoder(); - void rfc2047Decode(char *d, const char *s, size_t dlen); - - - private: - void rfc2047DecodeWord(char *d, const char *s, size_t dlen); - void *safe_calloc (size_t nmemb, size_t size); - void *safe_malloc (unsigned int siz); - void safe_realloc (void **p, size_t siz); - void safe_free (void *ptr); - char *safe_strdup (const char *s); +class RFC2047_Decoder +{ +public: + RFC2047_Decoder(); + ~RFC2047_Decoder(); + void decode(MB_FS *mbfs, char *d, const char *s, size_t dlen); +private: + void rfc2047DecodeWord(char *d, const char *s, size_t dlen); + char *safe_strdup(const char *s); + MB_FS *mbfs = nullptr; }; - -#endif //RFC2047_H \ No newline at end of file +#endif // RFC2047_H \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/SDHelper.h b/lib/libesp32/ESP-Mail-Client/src/extras/SDHelper.h new file mode 100644 index 000000000000..48490c473259 --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/SDHelper.h @@ -0,0 +1,163 @@ +#pragma once + +#ifndef SD_HELPER_H_ +#define SD_HELPER_H_ + +#include +#include + +// If SD Card used for storage, assign SD card type and FS used in src/ESP_Mail_FS.h and +// change the config for that card interfaces in this file (src/extras/SDHelper.h) + +#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) + +#if defined(ESP32) + +#define SPI_CS_PIN 13 +#define SPI_SCK_PIN 14 +#define SPI_MISO_PIN 2 +#define SPI_MOSI_PIN 15 +#define SPI_CLOCK_IN_MHz 16 + +// #define SPI_CS_PIN 5 +// #define SPI_SCK_PIN 18 +// #define SPI_MISO_PIN 19 +// #define SPI_MOSI_PIN 23 +// #define SPI_CLOCK_IN_MHz 4 // may work on lower clock rate + +#elif defined(ESP8266) +#define SPI_CS_PIN 15 +#elif defined(MB_ARDUINO_PICO) +// Use SPI 1's SS (GPIO 13) port as CS for SPI +#define SPI_CS_PIN PIN_SPI1_SS +#elif defined(MB_ARDUINO_ARCH_SAMD) || defined(MB_ARDUINO_NANO_RP2040_CONNECT) || defined(MB_ARDUINO_TEENSY) + +#define SPI_CS_PIN 4 + +#if defined(MBFS_SDFAT_ENABLED) +#define SPI_SCK_PIN -1 +#define SPI_MISO_PIN -1 +#define SPI_MOSI_PIN -1 +#define SPI_CLOCK_IN_MHz 4 // works on lower clock rate +#endif + +#endif + +// if SdFat library installed and ESP_Mail_FS.h was set to use it (for ESP32 only) +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + +// https://github.com/greiman/SdFat +SdSpiConfig sdFatSPIConfig(SPI_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(SPI_CLOCK_IN_MHz)); + +#elif defined(ESP32) // if ESP32 and no SdFat library installed + +SPIClass spi; + +#elif defined(ESP8266) + +SDFSConfig sdFSConfig(SPI_CS_PIN, SPI_HALF_SPEED); + +#elif defined(MB_ARDUINO_PICO) + +/** Use Pico SPI 1 for SPI + * MISO GPIO 12 + * MOSI GPIO 15 + * SCK GPIO 14 + * SS GPIO 13 + */ +SDFSConfig sdFSConfig(SPI_CS_PIN, SPI_HALF_SPEED, SPI1); + +#endif + +#endif + +bool SD_Card_Mounting() +{ + +#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + + Serial.print("\nMounting SD Card... "); + + if (!MailClient.sdBegin(&sdFatSPIConfig, SPI_CS_PIN, SPI_SCK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN)) // pointer to SdSpiConfig, SS, SCK,MISO, MOSI + { + Serial.println("failed\n"); + return false; + } + else + { + Serial.println("success\n"); + return true; + } + +#elif defined(ESP32) // if ESP32 and no SdFat library installed + + Serial.print("\nMounting SD Card... "); + + spi.begin(SPI_SCK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN, SPI_CS_PIN); // SPI pins config -> SCK,MISO, MOSI, SS + if (!MailClient.sdBegin(SPI_CS_PIN, &spi)) // SS, pointer to SPIClass <- SPIClass object should defined as static or global + { + Serial.println("failed\n"); + return false; + } + else + { + Serial.println("success\n"); + return true; + } +#elif defined(ESP8266) + + Serial.print("\nMounting SD Card... "); + + if (!MailClient.sdBegin(SPI_CS_PIN)) // or Firebase.sdBegin(&sdFSConfig) + { + Serial.println("failed\n"); + return false; + } + else + { + Serial.println("success\n"); + return true; + } + +#elif defined(MB_ARDUINO_PICO) + + Serial.print("\nMounting SD Card... "); + + if (!MailClient.sdBegin(&sdFSConfig)) // We begin with the SDFSConfig to use SPI 1 port + { + Serial.println("failed\n"); + return false; + } + else + { + Serial.println("success\n"); + return true; + } + +#endif + +#endif + +#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD_MMC) + + Serial.print("\nMounting SD_MMC Card... "); + + if (!MailClient.sdMMCBegin("/sdcard", false, true)) + { + Serial.println("failed\n"); + return false; + } + else + { + Serial.println("success\n"); + return true; + } +#endif + + Serial.println("\nSD filesystem was not setup yet."); + return false; +} + +#endif diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/WiFiClientImpl.h b/lib/libesp32/ESP-Mail-Client/src/extras/WiFiClientImpl.h new file mode 100644 index 000000000000..99be542a3b8f --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/WiFiClientImpl.h @@ -0,0 +1,565 @@ +/** + * WiFiClientImpl v1.0.1 + * + * This library provides the base client in replacement of ESP32 WiFiClient. + * + * The WiFiClient in ESP32 cannot be used in multithreading environment as in FreeRTOS task + * which can (always) lead to the assetion error "pbuf_free: p->ref > 0". + * + * Created August 20, 2023 + * + * The MIT License (MIT) + * Copyright (c) 2022 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined(WIFICLIENT_IMPL_H) && defined(ESP32) +#define WIFICLIENT_IMPL_H + +#include +class WiFiClientImpl : public Client +{ +public: + WiFiClientImpl(){}; + virtual ~WiFiClientImpl() { tcpClose(); }; + int connect(IPAddress ip, uint16_t port) { return tcpConnect(ip, port, _timeout); } + int connect(IPAddress ip, uint16_t port, int32_t timeout_ms) { return tcpConnect(ip, port, timeout_ms); } + int connect(const char *host, uint16_t port) + { + IPAddress address((uint32_t)0); +#if defined(WIFI_HAS_HOST_BY_NAME) + if (!WiFiGenericClass::hostByName(host, address)) + return -1; +#endif + return tcpConnect(address, port, _timeout); + } + int connect(const char *host, uint16_t port, int32_t timeout_ms) + { + _timeout = timeout_ms; + return connect(host, port); + } + size_t write(uint8_t data) { return write(&data, 1); } + size_t write(const uint8_t *buf, size_t size) { return tcpWrite(buf, size); } + size_t write_P(PGM_P buf, size_t size) { return write(buf, size); } + size_t write(Stream &stream) + { + uint8_t *buf = (uint8_t *)malloc(1360); + if (!buf) + { + return 0; + } + size_t toRead = 0, toWrite = 0, written = 0; + size_t available = stream.available(); + while (available) + { + toRead = (available > 1360) ? 1360 : available; + toWrite = stream.readBytes(buf, toRead); + written += write(buf, toWrite); + available = stream.available(); + } + free(buf); + buf = nullptr; + return written; + } + int available() { return tcpAavailable(); } + int read() + { + uint8_t data = 0; + int res = read(&data, 1); + if (res < 0) + { + return res; + } + if (res == 0) + { // No data available. + return -1; + } + return data; + } + int read(uint8_t *buf, size_t size) { return tcpRead(buf, size); } + int peek() { return tcpPeek(); } + void flush() + { + if (r_available()) + fillRxBuffer(); + _fillPos = _fillSize; + } + + void stop() { tcpClose(); } + uint8_t connected() { return tcpConnected(); } + + operator bool() + { + return connected(); + } + WiFiClientImpl &operator=(const WiFiClientImpl &other); + bool operator==(const bool value) + { + return bool() == value; + } + bool operator!=(const bool value) + { + return bool() != value; + } + bool operator==(const WiFiClientImpl &); + bool operator!=(const WiFiClientImpl &rhs) + { + return !this->operator==(rhs); + }; + + virtual int fd() const { return _socket; } + + int setSocketOption(int option, char *value, size_t len) + { + return setSocketOption(SOL_SOCKET, option, (const void *)value, len); + } + int setSocketOption(int level, int option, const void *value, size_t len) + { + int res = setsockopt(_socket, level, option, value, len); + if (res < 0) + { + log_e("fail on %d, errno: %d, \"%s\"", _socket, errno, strerror(errno)); + } + return res; + } + int setOption(int option, int *value) + { + return setSocketOption(IPPROTO_TCP, option, (const void *)value, sizeof(int)); + } + int getOption(int option, int *value) + { + socklen_t size = sizeof(int); + int res = getsockopt(_socket, IPPROTO_TCP, option, (char *)value, &size); + if (res < 0) + { + log_e("fail on fd %d, errno: %d, \"%s\"", _socket, errno, strerror(errno)); + } + return res; + } + + int setTimeout(uint32_t seconds) + { + Client::setTimeout(seconds * 1000); // This should be here? + _timeout = seconds * 1000; + if (_socket >= 0) + { + struct timeval tv; + tv.tv_sec = seconds; + tv.tv_usec = 0; + if (setSocketOption(SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) + { + return -1; + } + return setSocketOption(SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval)); + } + else + { + return 0; + } + } + + int setNoDelay(bool nodelay) + { + int flag = nodelay; + return setOption(TCP_NODELAY, &flag); + } + + bool getNoDelay() + { + int flag = 0; + getOption(TCP_NODELAY, &flag); + return flag; + } + + IPAddress remoteIP() const + { + return remoteIP(_socket); + } + + IPAddress remoteIP(int fd) const + { + struct sockaddr_storage addr; + socklen_t len = sizeof addr; + getpeername(fd, (struct sockaddr *)&addr, &len); + struct sockaddr_in *s = (struct sockaddr_in *)&addr; + return IPAddress((uint32_t)(s->sin_addr.s_addr)); + } + + uint16_t remotePort() const + { + return remotePort(_socket); + } + + uint16_t remotePort(int fd) const + { + struct sockaddr_storage addr; + socklen_t len = sizeof addr; + getpeername(fd, (struct sockaddr *)&addr, &len); + struct sockaddr_in *s = (struct sockaddr_in *)&addr; + return ntohs(s->sin_port); + } + + IPAddress localIP() const + { + return localIP(_socket); + } + + IPAddress localIP(int fd) const + { + struct sockaddr_storage addr; + socklen_t len = sizeof addr; + getsockname(fd, (struct sockaddr *)&addr, &len); + struct sockaddr_in *s = (struct sockaddr_in *)&addr; + return IPAddress((uint32_t)(s->sin_addr.s_addr)); + } + + uint16_t localPort() const + { + return localPort(_socket); + } + + uint16_t localPort(int fd) const + { + struct sockaddr_storage addr; + socklen_t len = sizeof addr; + getsockname(fd, (struct sockaddr *)&addr, &len); + struct sockaddr_in *s = (struct sockaddr_in *)&addr; + return ntohs(s->sin_port); + } + + // friend class WiFiServer; + using Print::write; + +private: + int _socket = -1; + int _timeout = 30000; + size_t _rxBuffSize = 2048; + uint8_t *_rxBuff = nullptr; + size_t _fillPos = 0; + size_t _fillSize = 0; + bool _failed = false; + bool _connected = false; + + size_t r_available() + { + if (_socket < 0) + { + return 0; + } + int count; +#ifdef ESP_IDF_VERSION_MAJOR + int res = lwip_ioctl(_socket, FIONREAD, &count); +#else + int res = lwip_ioctl_r(_socket, FIONREAD, &count); +#endif + if (res < 0) + { + _failed = true; + return 0; + } + return count; + } + + size_t fillRxBuffer() + { + if (!_rxBuff && !allocRxBuffer(_rxBuffSize)) + return 0; + + if (_fillSize && _fillPos == _fillSize) + { + _fillSize = 0; + _fillPos = 0; + } + + if (!_rxBuff || _rxBuffSize <= _fillSize || !r_available()) + { + return 0; + } + int res = recv(_socket, _rxBuff + _fillSize, _rxBuffSize - _fillSize, MSG_DONTWAIT); + if (res < 0) + { + if (errno != EWOULDBLOCK) + { + _failed = true; + } + return 0; + } + _fillSize += res; + return res; + } + + bool failed() + { + return _failed; + } + + int tcpConnect(const IPAddress &ip, uint32_t port, int timeout) + { + int enable = 1; + + log_v("Starting socket"); + + _socket = -1; + + _socket = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (_socket < 0) + { + return _socket; + } + + struct sockaddr_in serv_addr; + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = ip; + serv_addr.sin_port = htons(port); + + if (timeout <= 0) + timeout = 30000; // Milli seconds. + + fd_set fdset; + struct timeval tv; + FD_ZERO(&fdset); + FD_SET(_socket, &fdset); + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + int res = lwip_connect(_socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); + + if (res < 0 && errno != EINPROGRESS) + { + log_e("connect on fd %d, errno: %d, \"%s\"", _socket, errno, strerror(errno)); + tcpClose(); + return -1; + } + + res = select(_socket + 1, nullptr, &fdset, nullptr, timeout < 0 ? nullptr : &tv); + if (res < 0) + { + log_e("select on fd %d, errno: %d, \"%s\"", _socket, errno, strerror(errno)); + tcpClose(); + return -1; + } + else if (res == 0) + { + log_i("select returned due to timeout %d ms for fd %d", timeout, _socket); + tcpClose(); + return -1; + } + else + { + int sockerr; + socklen_t len = (socklen_t)sizeof(int); + res = getsockopt(_socket, SOL_SOCKET, SO_ERROR, &sockerr, &len); + + if (res < 0) + { + log_e("getsockopt on fd %d, errno: %d, \"%s\"", _socket, errno, strerror(errno)); + tcpClose(); + return -1; + } + + if (sockerr != 0) + { + log_e("socket error on fd %d, errno: %d, \"%s\"", _socket, sockerr, strerror(sockerr)); + tcpClose(); + return -1; + } + } + + lwip_setsockopt(_socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + lwip_setsockopt(_socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + + lwip_setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)); + lwip_setsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)); + + fcntl(_socket, F_SETFL, fcntl(_socket, F_GETFL, 0) | O_NONBLOCK); + + _connected = true; + + return 1; + } + + void tcpClose() + { + lwip_close(_socket); + _socket = -1; + _connected = false; + freeRxBuffer(); + } + + int tcpAavailable() + { + return _fillSize - _fillPos + r_available(); + } + + int tcpPeek() + { + if (!_rxBuff || _fillPos == _fillSize && !fillRxBuffer()) + { + return -1; + } + return _rxBuff[_fillPos]; + } + + size_t tcpWrite(const uint8_t *buf, size_t size) + { + if (!tcpConnected() || !size) + return 0; + + int res = 0; + int retry = 10; + int socketFileDescriptor = _socket; + size_t totalBytesSent = 0; + size_t bytesRemaining = size; + + while (retry) + { + // use select to make sure the socket is ready for writing + fd_set set; + struct timeval tv; + FD_ZERO(&set); // empties the set + FD_SET(socketFileDescriptor, &set); // adds FD to the set + tv.tv_sec = 0; + tv.tv_usec = 1000000; + retry--; + + if (select(socketFileDescriptor + 1, NULL, &set, NULL, &tv) < 0) + { + return 0; + } + + if (FD_ISSET(socketFileDescriptor, &set)) + { + res = send(socketFileDescriptor, (void *)buf, bytesRemaining, MSG_DONTWAIT); + if (res > 0) + { + totalBytesSent += res; + if (totalBytesSent >= size) + { + // completed successfully + retry = 0; + } + else + { + buf += res; + bytesRemaining -= res; + retry = 10; + } + } + else if (res < 0) + { + log_e("fail on fd %d, errno: %d, \"%s\"", _socket, errno, strerror(errno)); + if (errno != EAGAIN) + { + // if resource was busy, can try again, otherwise give up + res = 0; + retry = 0; + } + } + else + { + // Try again + } + } + } + return totalBytesSent; + + // return ssize_t or signed size_t for error + return lwip_write(_socket, buf, size); + } + + size_t tcpRead(uint8_t *dst, size_t len) + { + + if (!dst || !len || (_fillPos == _fillSize && !fillRxBuffer())) + { + return _failed ? -1 : 0; + } + + int remain = _fillSize - _fillPos; + if (len <= remain || ((len - remain) <= (_rxBuffSize - _fillSize) && fillRxBuffer() >= (len - remain))) + { + if (len == 1) + { + *dst = _rxBuff[_fillPos]; + } + else + { + memcpy(dst, _rxBuff + _fillPos, len); + } + _fillPos += len; + return len; + } + + size_t left = len; + size_t toRead = remain; + uint8_t *buf = dst; + memcpy(buf, _rxBuff + _fillPos, toRead); + _fillPos += toRead; + left -= toRead; + buf += toRead; + while (left) + { + if (!fillRxBuffer()) + { + return len - left; + } + remain = _fillSize - _fillPos; + toRead = (remain > left) ? left : remain; + memcpy(buf, _rxBuff + _fillPos, toRead); + _fillPos += toRead; + left -= toRead; + buf += toRead; + } + return len; + } + + int tcpConnected() + { + return _socket >= 0; + } + + bool allocRxBuffer(size_t size) + { + if (_rxBuff) + freeRxBuffer(); + + _rxBuff = (uint8_t *)malloc(size); + if (!_rxBuff) + { + + log_e("Not enough memory to allocate buffer"); + _failed = true; + return false; + } + + return true; + } + + void freeRxBuffer() + { + if (_rxBuff) + free(_rxBuff); + + _rxBuff = nullptr; + } +}; + +#endif /* WIFICLIENT_IMPL_H */ diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.c b/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.c new file mode 100644 index 000000000000..1a595f4fce3c --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.c @@ -0,0 +1,1048 @@ +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2019, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. These routines are thread +// safe and reentrant! +// Use this instead of the bloated standard/newlib printf cause these use +// malloc for printf (and may not be thread safe). +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef MB_PRINT_C +#define MB_PRINT_C + +#include +#include + +#include "mb_print.h" + +// define this globally (e.g. gcc -DMB_PRINT_INCLUDE_CONFIG_H ...) to include the +// printf_config.h header file +// default: undefined +#ifdef MB_PRINT_INCLUDE_CONFIG_H +#include "printf_config.h" +#endif + +// 'ntoa' conversion buffer size, this must be big enough to hold one converted +// numeric number including padded zeros (dynamically created on stack) +// default: 32 byte +#ifndef MB_PRINT_NTOA_BUFFER_SIZE +#define MB_PRINT_NTOA_BUFFER_SIZE 32U +#endif + +// 'ftoa' conversion buffer size, this must be big enough to hold one converted +// float number including padded zeros (dynamically created on stack) +// default: 32 byte +#ifndef MB_PRINT_FTOA_BUFFER_SIZE +#define MB_PRINT_FTOA_BUFFER_SIZE 32U +#endif + +// support for the floating point type (%f) +// default: activated +#ifndef MB_PRINT_DISABLE_SUPPORT_FLOAT +#define MB_PRINT_SUPPORT_FLOAT +#endif + +// support for exponential floating point notation (%e/%g) +// default: activated +#ifndef MB_PRINT_DISABLE_SUPPORT_EXPONENTIAL +#define MB_PRINT_SUPPORT_EXPONENTIAL +#endif + +// define the default floating point precision +// default: 6 digits +#ifndef MB_PRINT_DEFAULT_FLOAT_PRECISION +#define MB_PRINT_DEFAULT_FLOAT_PRECISION 6U +#endif + +// define the largest float suitable to print with %f +// default: 1e9 +#ifndef MB_PRINT_MAX_FLOAT +#define MB_PRINT_MAX_FLOAT 1e9 +#endif + +// support for the long long types (%llu or %p) +// default: activated +#ifndef MB_PRINT_DISABLE_SUPPORT_LONG_LONG +#define MB_PRINT_SUPPORT_LONG_LONG +#endif + +// support for the ptrdiff_t type (%t) +// ptrdiff_t is normally defined in as long or long long type +// default: activated +#ifndef MB_PRINT_DISABLE_SUPPORT_PTRDIFF_T +#define MB_PRINT_SUPPORT_PTRDIFF_T +#endif + +/////////////////////////////////////////////////////////////////////////////// + +// internal flag definitions +#define MB_PRINT_FLAGS_ZEROPAD (1U << 0U) +#define MB_PRINT_FLAGS_LEFT (1U << 1U) +#define MB_PRINT_FLAGS_PLUS (1U << 2U) +#define MB_PRINT_FLAGS_SPACE (1U << 3U) +#define MB_PRINT_FLAGS_HASH (1U << 4U) +#define MB_PRINT_FLAGS_UPPERCASE (1U << 5U) +#define MB_PRINT_FLAGS_CHAR (1U << 6U) +#define MB_PRINT_FLAGS_SHORT (1U << 7U) +#define MB_PRINT_FLAGS_LONG (1U << 8U) +#define MB_PRINT_FLAGS_LONG_LONG (1U << 9U) +#define MB_PRINT_FLAGS_PRECISION (1U << 10U) +#define MB_PRINT_FLAGS_ADAPT_EXP (1U << 11U) + +// import float.h for DBL_MAX +#if defined(MB_PRINT_SUPPORT_FLOAT) +#include +#endif + +// output function type +typedef void (*mb_print_out_fn_type)(char character, void *buffer, size_t idx, size_t maxlen); + +// wrapper (used as buffer) for output function type +typedef struct +{ + void (*fct)(char character, void *arg); + void *arg; +} mb_print_out_fn_wrap_type; + +// internal buffer output +static inline void mb_print_out_buffer(char character, void *buffer, size_t idx, size_t maxlen) +{ + if (idx < maxlen) + { + ((char *)buffer)[idx] = character; + } +} + +// internal null output +static inline void mb_print_out_null(char character, void *buffer, size_t idx, size_t maxlen) +{ + (void)character; + (void)buffer; + (void)idx; + (void)maxlen; +} + +// internal _putchar wrapper +static inline void mb_print_out_char(char character, void *buffer, size_t idx, size_t maxlen) +{ + (void)buffer; + (void)idx; + (void)maxlen; + if (character) + { + mb_print_putchar(character); + } +} + +// internal output function wrapper +static inline void mb_print_out_fn(char character, void *buffer, size_t idx, size_t maxlen) +{ + (void)idx; + (void)maxlen; + if (character) + { + // buffer is the output fct pointer + ((mb_print_out_fn_wrap_type *)buffer)->fct(character, ((mb_print_out_fn_wrap_type *)buffer)->arg); + } +} + +// internal secure strlen +// \return The length of the string (excluding the terminating 0) limited by 'maxsize' +static inline unsigned int mb_print_strlen(const char *str, size_t maxsize) +{ + const char *s; + for (s = str; *s && maxsize--; ++s) + ; + return (unsigned int)(s - str); +} + +// internal test if char is a digit (0-9) +// \return true if char is a digit +static inline bool mb_print_is_digit(char ch) +{ + return (ch >= '0') && (ch <= '9'); +} + +// internal ASCII string to unsigned int conversion +static unsigned int mb_print_atoi(const char **str) +{ + unsigned int i = 0U; + while (mb_print_is_digit(**str)) + { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; +} + +// output the specified string in reverse, taking care of any zero-padding +static size_t mb_print_out_rev(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, const char *buf, size_t len, unsigned int width, unsigned int flags) +{ + const size_t start_idx = idx; + + // pad spaces up to given width + if (!(flags & MB_PRINT_FLAGS_LEFT) && !(flags & MB_PRINT_FLAGS_ZEROPAD)) + { + for (size_t i = len; i < width; i++) + { + out(' ', buffer, idx++, maxlen); + } + } + + // reverse string + while (len) + { + out(buf[--len], buffer, idx++, maxlen); + } + + // append pad spaces up to given width + if (flags & MB_PRINT_FLAGS_LEFT) + { + while (idx - start_idx < width) + { + out(' ', buffer, idx++, maxlen); + } + } + + return idx; +} + +// internal itoa format +static size_t mb_print_itoa_format(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, char *buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) +{ + // pad leading zeros + if (!(flags & MB_PRINT_FLAGS_LEFT)) + { + if (width && (flags & MB_PRINT_FLAGS_ZEROPAD) && (negative || (flags & (MB_PRINT_FLAGS_PLUS | MB_PRINT_FLAGS_SPACE)))) + { + width--; + } + while ((len < prec) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) + { + buf[len++] = '0'; + } + while ((flags & MB_PRINT_FLAGS_ZEROPAD) && (len < width) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) + { + buf[len++] = '0'; + } + } + + // handle hash + if (flags & MB_PRINT_FLAGS_HASH) + { + if (!(flags & MB_PRINT_FLAGS_PRECISION) && len && ((len == prec) || (len == width))) + { + len--; + if (len && (base == 16U)) + { + len--; + } + } + if ((base == 16U) && !(flags & MB_PRINT_FLAGS_UPPERCASE) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) + { + buf[len++] = 'x'; + } + else if ((base == 16U) && (flags & MB_PRINT_FLAGS_UPPERCASE) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) + { + buf[len++] = 'X'; + } + else if ((base == 2U) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) + { + buf[len++] = 'b'; + } + if (len < MB_PRINT_NTOA_BUFFER_SIZE) + { + buf[len++] = '0'; + } + } + + if (len < MB_PRINT_NTOA_BUFFER_SIZE) + { + if (negative) + { + buf[len++] = '-'; + } + else if (flags & MB_PRINT_FLAGS_PLUS) + { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & MB_PRINT_FLAGS_SPACE) + { + buf[len++] = ' '; + } + } + + return mb_print_out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +} + +// internal itoa for 'long' type +static size_t mb_print_itoa_long(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[MB_PRINT_NTOA_BUFFER_SIZE]; + size_t len = 0U; + + // no hash for 0 values + if (!value) + { + flags &= ~MB_PRINT_FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & MB_PRINT_FLAGS_PRECISION) || value) + { + do + { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & MB_PRINT_FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < MB_PRINT_NTOA_BUFFER_SIZE)); + } + + return mb_print_itoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} + +// internal itoa for 'long long' type +#if defined(MB_PRINT_SUPPORT_LONG_LONG) +static size_t mb_print_itoa_long_long(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[MB_PRINT_NTOA_BUFFER_SIZE]; + size_t len = 0U; + + // no hash for 0 values + if (!value) + { + flags &= ~MB_PRINT_FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & MB_PRINT_FLAGS_PRECISION) || value) + { + do + { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & MB_PRINT_FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < MB_PRINT_NTOA_BUFFER_SIZE)); + } + + return mb_print_itoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} +#endif // MB_PRINT_SUPPORT_LONG_LONG + +#if defined(MB_PRINT_SUPPORT_FLOAT) + +#if defined(MB_PRINT_SUPPORT_EXPONENTIAL) +// forward declaration so that mb_print_ftoa can switch to exp notation for values > MB_PRINT_MAX_FLOAT +static size_t mb_print_ftoa_exp(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); +#endif + +// internal ftoa for fixed decimal floating point +static size_t mb_print_ftoa(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[MB_PRINT_FTOA_BUFFER_SIZE]; + size_t len = 0U; + double diff = 0.0; + + // powers of 10 + static const double pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; + + // test for special values + if (value != value) + return mb_print_out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); + if (value < -DBL_MAX) + return mb_print_out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); + if (value > DBL_MAX) + return mb_print_out_rev(out, buffer, idx, maxlen, (flags & MB_PRINT_FLAGS_PLUS) ? "fni+" : "fni", (flags & MB_PRINT_FLAGS_PLUS) ? 4U : 3U, width, flags); + + // test for very large values + // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad + if ((value > MB_PRINT_MAX_FLOAT) || (value < -MB_PRINT_MAX_FLOAT)) + { +#if defined(MB_PRINT_SUPPORT_EXPONENTIAL) + return mb_print_ftoa_exp(out, buffer, idx, maxlen, value, prec, width, flags); +#else + return 0U; +#endif + } + + // test for negative + bool negative = false; + if (value < 0) + { + negative = true; + value = 0 - value; + } + + // set default precision, if not set explicitly + if (!(flags & MB_PRINT_FLAGS_PRECISION)) + { + prec = MB_PRINT_DEFAULT_FLOAT_PRECISION; + } + // limit precision to 9, cause a prec >= 10 can lead to overflow errors + while ((len < MB_PRINT_FTOA_BUFFER_SIZE) && (prec > 9U)) + { + buf[len++] = '0'; + prec--; + } + + int whole = (int)value; + double tmp = (value - whole) * pow10[prec]; + unsigned long frac = (unsigned long)tmp; + diff = tmp - frac; + + if (diff > 0.5) + { + ++frac; + // handle rollover, e.g. case 0.99 with prec 1 is 1.0 + if (frac >= pow10[prec]) + { + frac = 0; + ++whole; + } + } + else if (diff < 0.5) + { + } + else if ((frac == 0U) || (frac & 1U)) + { + // if halfway, round up if odd OR if last digit is 0 + ++frac; + } + + if (prec == 0U) + { + diff = value - (double)whole; + if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) + { + // exactly 0.5 and ODD, then round up + // 1.5 -> 2, but 2.5 -> 2 + ++whole; + } + } + else + { + unsigned int count = prec; + // now do fractional part, as an unsigned number + while (len < MB_PRINT_FTOA_BUFFER_SIZE) + { + --count; + buf[len++] = (char)(48U + (frac % 10U)); + if (!(frac /= 10U)) + { + break; + } + } + // add extra 0s + while ((len < MB_PRINT_FTOA_BUFFER_SIZE) && (count-- > 0U)) + { + buf[len++] = '0'; + } + if (len < MB_PRINT_FTOA_BUFFER_SIZE) + { + // add decimal + buf[len++] = '.'; + } + } + + // do whole part, number is reversed + while (len < MB_PRINT_FTOA_BUFFER_SIZE) + { + buf[len++] = (char)(48 + (whole % 10)); + if (!(whole /= 10)) + { + break; + } + } + + // pad leading zeros + if (!(flags & MB_PRINT_FLAGS_LEFT) && (flags & MB_PRINT_FLAGS_ZEROPAD)) + { + if (width && (negative || (flags & (MB_PRINT_FLAGS_PLUS | MB_PRINT_FLAGS_SPACE)))) + { + width--; + } + while ((len < width) && (len < MB_PRINT_FTOA_BUFFER_SIZE)) + { + buf[len++] = '0'; + } + } + + if (len < MB_PRINT_FTOA_BUFFER_SIZE) + { + if (negative) + { + buf[len++] = '-'; + } + else if (flags & MB_PRINT_FLAGS_PLUS) + { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & MB_PRINT_FLAGS_SPACE) + { + buf[len++] = ' '; + } + } + + return mb_print_out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +} + +#if defined(MB_PRINT_SUPPORT_EXPONENTIAL) +// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse +static size_t mb_print_ftoa_exp(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +{ + // check for NaN and special values + if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) + { + return mb_print_ftoa(out, buffer, idx, maxlen, value, prec, width, flags); + } + + // determine the sign + const bool negative = value < 0; + if (negative) + { + value = -value; + } + + // default precision + if (!(flags & MB_PRINT_FLAGS_PRECISION)) + { + prec = MB_PRINT_DEFAULT_FLOAT_PRECISION; + } + + // determine the decimal exponent + // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) + union + { + uint64_t U; + double F; + } conv; + + conv.F = value; + int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 + conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) + // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 + int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); + // now we want to compute 10^expval but we want to be sure it won't overflow + exp2 = (int)(expval * 3.321928094887362 + 0.5); + const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; + const double z2 = z * z; + conv.U = (uint64_t)(exp2 + 1023) << 52U; + // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex + conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); + // correct for rounding errors + if (value < conv.F) + { + expval--; + conv.F /= 10; + } + + // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters + unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; + + // in "%g" mode, "prec" is the number of *significant figures* not decimals + if (flags & MB_PRINT_FLAGS_ADAPT_EXP) + { + // do we want to fall-back to "%f" mode? + if ((value >= 1e-4) && (value < 1e6)) + { + if ((int)prec > expval) + { + prec = (unsigned)((int)prec - expval - 1); + } + else + { + prec = 0; + } + flags |= MB_PRINT_FLAGS_PRECISION; // make sure mb_print_ftoa respects precision + // no characters in exponent + minwidth = 0U; + expval = 0; + } + else + { + // we use one sigfig for the whole part + if ((prec > 0) && (flags & MB_PRINT_FLAGS_PRECISION)) + { + --prec; + } + } + } + + // will everything fit? + unsigned int fwidth = width; + if (width > minwidth) + { + // we didn't fall-back so subtract the characters required for the exponent + fwidth -= minwidth; + } + else + { + // not enough characters, so go back to default sizing + fwidth = 0U; + } + if ((flags & MB_PRINT_FLAGS_LEFT) && minwidth) + { + // if we're padding on the right, DON'T pad the floating part + fwidth = 0U; + } + + // rescale the float value + if (expval) + { + value /= conv.F; + } + + // output the floating part + const size_t start_idx = idx; + idx = mb_print_ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~MB_PRINT_FLAGS_ADAPT_EXP); + + // output the exponent part + if (minwidth) + { + // output the exponential symbol + out((flags & MB_PRINT_FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); + // output the exponent value + idx = mb_print_itoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth - 1, MB_PRINT_FLAGS_ZEROPAD | MB_PRINT_FLAGS_PLUS); + // might need to right-pad spaces + if (flags & MB_PRINT_FLAGS_LEFT) + { + while (idx - start_idx < width) + out(' ', buffer, idx++, maxlen); + } + } + return idx; +} +#endif // MB_PRINT_SUPPORT_EXPONENTIAL +#endif // MB_PRINT_SUPPORT_FLOAT + +// internal vsnprintf +static int mb_print_vsnprintf_int(mb_print_out_fn_type out, char *buffer, const size_t maxlen, const char *format, va_list va) +{ + unsigned int flags, width, precision, n; + size_t idx = 0U; + + if (!buffer) + { + // use null output function + out = mb_print_out_null; + } + + while (*format) + { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') + { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } + else + { + // yes, evaluate it + format++; + } + + // evaluate flags + flags = 0U; + do + { + switch (*format) + { + case '0': + flags |= MB_PRINT_FLAGS_ZEROPAD; + format++; + n = 1U; + break; + case '-': + flags |= MB_PRINT_FLAGS_LEFT; + format++; + n = 1U; + break; + case '+': + flags |= MB_PRINT_FLAGS_PLUS; + format++; + n = 1U; + break; + case ' ': + flags |= MB_PRINT_FLAGS_SPACE; + format++; + n = 1U; + break; + case '#': + flags |= MB_PRINT_FLAGS_HASH; + format++; + n = 1U; + break; + default: + n = 0U; + break; + } + } while (n); + + // evaluate width field + width = 0U; + if (mb_print_is_digit(*format)) + { + width = mb_print_atoi(&format); + } + else if (*format == '*') + { + const int w = va_arg(va, int); + if (w < 0) + { + flags |= MB_PRINT_FLAGS_LEFT; // reverse padding + width = (unsigned int)-w; + } + else + { + width = (unsigned int)w; + } + format++; + } + + // evaluate precision field + precision = 0U; + if (*format == '.') + { + flags |= MB_PRINT_FLAGS_PRECISION; + format++; + if (mb_print_is_digit(*format)) + { + precision = mb_print_atoi(&format); + } + else if (*format == '*') + { + const int prec = (int)va_arg(va, int); + precision = prec > 0 ? (unsigned int)prec : 0U; + format++; + } + } + + // evaluate length field + switch (*format) + { + case 'l': + flags |= MB_PRINT_FLAGS_LONG; + format++; + if (*format == 'l') + { + flags |= MB_PRINT_FLAGS_LONG_LONG; + format++; + } + break; + case 'h': + flags |= MB_PRINT_FLAGS_SHORT; + format++; + if (*format == 'h') + { + flags |= MB_PRINT_FLAGS_CHAR; + format++; + } + break; +#if defined(MB_PRINT_SUPPORT_PTRDIFF_T) + case 't': + flags |= (sizeof(ptrdiff_t) == sizeof(long) ? MB_PRINT_FLAGS_LONG : MB_PRINT_FLAGS_LONG_LONG); + format++; + break; +#endif + case 'j': + flags |= (sizeof(intmax_t) == sizeof(long) ? MB_PRINT_FLAGS_LONG : MB_PRINT_FLAGS_LONG_LONG); + format++; + break; + case 'z': + flags |= (sizeof(size_t) == sizeof(long) ? MB_PRINT_FLAGS_LONG : MB_PRINT_FLAGS_LONG_LONG); + format++; + break; + default: + break; + } + + // evaluate specifier + switch (*format) + { + case 'd': + case 'i': + case 'u': + case 'x': + case 'X': + case 'o': + case 'b': + { + // set the base + unsigned int base; + if (*format == 'x' || *format == 'X') + { + base = 16U; + } + else if (*format == 'o') + { + base = 8U; + } + else if (*format == 'b') + { + base = 2U; + } + else + { + base = 10U; + flags &= ~MB_PRINT_FLAGS_HASH; // no hash for dec format + } + // uppercase + if (*format == 'X') + { + flags |= MB_PRINT_FLAGS_UPPERCASE; + } + + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) + { + flags &= ~(MB_PRINT_FLAGS_PLUS | MB_PRINT_FLAGS_SPACE); + } + + // ignore '0' flag when precision is given + if (flags & MB_PRINT_FLAGS_PRECISION) + { + flags &= ~MB_PRINT_FLAGS_ZEROPAD; + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) + { + // signed + if (flags & MB_PRINT_FLAGS_LONG_LONG) + { +#if defined(MB_PRINT_SUPPORT_LONG_LONG) + const long long value = va_arg(va, long long); + idx = mb_print_itoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); +#endif + } + else if (flags & MB_PRINT_FLAGS_LONG) + { + const long value = va_arg(va, long); + idx = mb_print_itoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + else + { + const int value = (flags & MB_PRINT_FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & MB_PRINT_FLAGS_SHORT) ? (short int)va_arg(va, int) + : va_arg(va, int); + idx = mb_print_itoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + } + else + { + // unsigned + if (flags & MB_PRINT_FLAGS_LONG_LONG) + { +#if defined(MB_PRINT_SUPPORT_LONG_LONG) + idx = mb_print_itoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); +#endif + } + else if (flags & MB_PRINT_FLAGS_LONG) + { + idx = mb_print_itoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); + } + else + { + const unsigned int value = (flags & MB_PRINT_FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & MB_PRINT_FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) + : va_arg(va, unsigned int); + idx = mb_print_itoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); + } + } + format++; + break; + } +#if defined(MB_PRINT_SUPPORT_FLOAT) + case 'f': + case 'F': + if (*format == 'F') + flags |= MB_PRINT_FLAGS_UPPERCASE; + idx = mb_print_ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; +#if defined(MB_PRINT_SUPPORT_EXPONENTIAL) + case 'e': + case 'E': + case 'g': + case 'G': + if ((*format == 'g') || (*format == 'G')) + flags |= MB_PRINT_FLAGS_ADAPT_EXP; + if ((*format == 'E') || (*format == 'G')) + flags |= MB_PRINT_FLAGS_UPPERCASE; + idx = mb_print_ftoa_exp(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; +#endif // MB_PRINT_SUPPORT_EXPONENTIAL +#endif // MB_PRINT_SUPPORT_FLOAT + case 'c': + { + unsigned int l = 1U; + // pre padding + if (!(flags & MB_PRINT_FLAGS_LEFT)) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & MB_PRINT_FLAGS_LEFT) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 's': + { + const char *p = va_arg(va, char *); + unsigned int l = mb_print_strlen(p, precision ? precision : (size_t)-1); + // pre padding + if (flags & MB_PRINT_FLAGS_PRECISION) + { + l = (l < precision ? l : precision); + } + if (!(flags & MB_PRINT_FLAGS_LEFT)) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && (!(flags & MB_PRINT_FLAGS_PRECISION) || precision--)) + { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & MB_PRINT_FLAGS_LEFT) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 'p': + { + width = sizeof(void *) * 2U; + flags |= MB_PRINT_FLAGS_ZEROPAD | MB_PRINT_FLAGS_UPPERCASE; +#if defined(MB_PRINT_SUPPORT_LONG_LONG) + const bool is_ll = sizeof(uintptr_t) == sizeof(long long); + if (is_ll) + { + idx = mb_print_itoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void *), false, 16U, precision, width, flags); + } + else + { +#endif + idx = mb_print_itoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void *)), false, 16U, precision, width, flags); +#if defined(MB_PRINT_SUPPORT_LONG_LONG) + } +#endif + format++; + break; + } + + case '%': + out('%', buffer, idx++, maxlen); + format++; + break; + + default: + out(*format, buffer, idx++, maxlen); + format++; + break; + } + } + + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + + // return written chars without terminating \0 + return (int)idx; +} + +/////////////////////////////////////////////////////////////////////////////// + +int mb_print_printf(const char *format, ...) +{ + va_list va; + va_start(va, format); + char buffer[1]; + const int ret = mb_print_vsnprintf_int(mb_print_out_char, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + +int mb_print_sprintf(char *buffer, const char *format, ...) +{ + va_list va; + va_start(va, format); + const int ret = mb_print_vsnprintf_int(mb_print_out_buffer, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + +int mb_print_snprintf_(char *buffer, size_t count, const char *format, ...) +{ + va_list va; + va_start(va, format); + const int ret = mb_print_vsnprintf_int(mb_print_out_buffer, buffer, count, format, va); + va_end(va); + return ret; +} + +int mb_print_vprintf(const char *format, va_list va) +{ + char buffer[1]; + return mb_print_vsnprintf_int(mb_print_out_char, buffer, (size_t)-1, format, va); +} + +int mb_print_vsnprintf_(char *buffer, size_t count, const char *format, va_list va) +{ + return mb_print_vsnprintf_int(mb_print_out_buffer, buffer, count, format, va); +} + +int mb_print_fnprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...) +{ + va_list va; + va_start(va, format); + const mb_print_out_fn_wrap_type out_fct_wrap = {out, arg}; + const int ret = mb_print_vsnprintf_int(mb_print_out_fn, (char *)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); + va_end(va); + return ret; +} + +#endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.h b/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.h new file mode 100644 index 000000000000..5ec3727bdfff --- /dev/null +++ b/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.h @@ -0,0 +1,108 @@ +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2019, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. +// Use this instead of bloated standard/newlib printf. +// These routines are thread safe and reentrant. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#ifndef _PRINTF_H_ +#define _PRINTF_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * Output a character to a custom device like UART, used by the printf() function + * This function is declared here only. You have to write your custom implementation somewhere + * \param character Character to output + */ + void mb_print_putchar(char character) __attribute__((used)); + + /** + * Tiny printf implementation + * You have to implement _putchar if you use printf() + * To avoid conflicts with the regular printf() API it is overridden by macro defines + * and internal underscore-appended functions like printf_() are used + * \param format A string that specifies the format of the output + * \return The number of characters that are written into the array, not counting the terminating null character + */ + int mb_print_printf(const char *format, ...) __attribute__((used)); + + /** + * Tiny sprintf implementation + * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! + * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! + * \param format A string that specifies the format of the output + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ + int mb_print_sprintf(char *buffer, const char *format, ...) __attribute__((used)); + + /** + * Tiny snprintf/vsnprintf implementation + * \param buffer A pointer to the buffer where to store the formatted string + * \param count The maximum number of characters to store in the buffer, including a terminating null character + * \param format A string that specifies the format of the output + * \param va A value identifying a variable arguments list + * \return The number of characters that COULD have been written into the buffer, not counting the terminating + * null character. A value equal or larger than count indicates truncation. Only when the returned value + * is non-negative and less than count, the string has been completely written. + */ +#define mb_print_snprintf mb_print_snprintf_ +#define mb_print_vsnprintf mb_print_vsnprintf_ + int mb_print_snprintf_(char *buffer, size_t count, const char *format, ...) __attribute__((used)); + int mb_print_vsnprintf_(char *buffer, size_t count, const char *format, va_list va) __attribute__((used)); + + /** + * Tiny vprintf implementation + * \param format A string that specifies the format of the output + * \param va A value identifying a variable arguments list + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ + int mb_print_vprintf(const char *format, va_list va) __attribute__((used)); + + /** + * printf with output function + * You may use this as dynamic alternative to printf() with its fixed _putchar() output + * \param out An output function which takes one character and an argument pointer + * \param arg An argument pointer for user data passed to output function + * \param format A string that specifies the format of the output + * \return The number of characters that are sent to the output function, not counting the terminating null character + */ + int mb_print_fnprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...) __attribute__((used)); + +#ifdef __cplusplus +} +#endif + +#endif // _PRINTF_H_ \ No newline at end of file diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp index d5d8edb3c33e..ea288d5478ed 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp @@ -111,18 +111,6 @@ void WiFiClass32::scrubDNS(void) { } else { dns_setserver(i, IP4_ADDR_ANY); } -#else // USE_IPV6 - uint32_t ip_dns = ip_addr_get_ip4_u32(dns_getserver(i)); - // Step 1. save valid values from DNS - if (has_v4 && (uint32_t)ip_dns != 0) { - ip_addr_set_ip4_u32_val(dns_save4[i], ip_dns); - } - // Step 2. scrub addresses not supported - if (!has_v4) { - ip_addr_set_ip4_u32_val(dns_save4[i], 0L); - } - // Step 3. restore saved value - dns_setserver(i, &dns_save4[i]); #endif // USE_IPV6 } // AddLog(LOG_LEVEL_DEBUG, "IP>: DNS: from(%s %s) to (%s %s) has4/6:%i-%i", dns_entry0.c_str(), dns_entry1.c_str(), IPAddress(dns_getserver(0)).toString().c_str(), IPAddress(dns_getserver(1)).toString().c_str(), has_v4, has_v6); diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h index 943b89e9aad5..94cf3d6c1a21 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h @@ -76,8 +76,8 @@ class WiFiClass32 : public WiFiClass void scrubDNS(void); protected: - ip_addr_t dns_save4[DNS_MAX_SERVERS] = {}; // IPv4 DNS servers #ifdef USE_IPV6 + ip_addr_t dns_save4[DNS_MAX_SERVERS] = {}; // IPv4 DNS servers ip_addr_t dns_save6[DNS_MAX_SERVERS] = {}; // IPv6 DNS servers #endif // USE_IPV6 }; diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp index dfc8c3dab0f8..d31aaed2b58c 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp @@ -16,6 +16,7 @@ #ifdef ESP32 #include "Arduino.h" +#include "esp_idf_version.h" #include "esp8266toEsp32.h" #include "driver/ledc.h" @@ -33,7 +34,11 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D #else #define LEDC_DEFAULT_CLK LEDC_AUTO_CLK #endif -#define LEDC_MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM +#if (ESP_IDF_VERSION_MAJOR >= 5) + #define LEDC_MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDTH +#else + #define LEDC_MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM +#endif // define our limits to ease any change from esp-idf #define MAX_TIMERS LEDC_TIMER_MAX // 4 timers for all ESP32 variants @@ -43,16 +48,14 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D // replicated from `tasmota.h` -#if defined(CONFIG_IDF_TARGET_ESP32) - const uint8_t MAX_PWMS = 16; // ESP32: 16 ledc PWM channels in total - TODO for now -#elif defined(CONFIG_IDF_TARGET_ESP32S2) - const uint8_t MAX_PWMS = 8; // ESP32S2: 8 ledc PWM channels in total -#elif defined(CONFIG_IDF_TARGET_ESP32S3) - const uint8_t MAX_PWMS = 8; // ESP32S2: 8 ledc PWM channels in total -#elif defined(CONFIG_IDF_TARGET_ESP32C3) - const uint8_t MAX_PWMS = 6; // ESP32C3: 6 ledc PWM channels in total +#if CONFIG_IDF_TARGET_ESP32 +const uint8_t MAX_PWMS = 16; // ESP32: 16 ledc PWM channels in total - TODO for now +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +const uint8_t MAX_PWMS = 8; // ESP32S2/S3: 8 ledc PWM channels in total +#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 +const uint8_t MAX_PWMS = 6; // ESP32C2/C3/C6: 6 ledc PWM channels in total #else - const uint8_t MAX_PWMS = 5; // Unknown - revert to 5 PWM max +const uint8_t MAX_PWMS = 5; // Unknown - revert to 5 PWM max #endif // current configuration of timers: frequency and resolution diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h index c544d5d30379..8cae8d49955d 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h @@ -53,7 +53,7 @@ uint8_t ledcReadResolution(uint8_t chan); // was not yet attached. // // Returns: hardware channel number, or -1 if it failed -int analogAttach(uint32_t pin, bool output_invert = false); // returns the ledc channel, or -1 if failed. This is implicitly called by analogWrite if the channel was not already allocated +int32_t analogAttach(uint32_t pin, bool output_invert = false); // returns the ledc channel, or -1 if failed. This is implicitly called by analogWrite if the channel was not already allocated // change both freq and range // `0`: set to global value @@ -126,7 +126,12 @@ uint32_t analogGetTimerFrequency(uint8_t timer); #define ESPhttpUpdate httpUpdate +#if ESP_IDF_VERSION_MAJOR >= 5 +#include "rom/ets_sys.h" +#else #define os_delay_us ets_delay_us +#endif + // Serial minimal type to hold the config typedef int SerConfu8; //typedef int SerialConfig; // Will be replaced enum in esp32_hal-uart.h (#7926) diff --git a/lib/libesp32/Berry-HttpClientLight/library.json b/lib/libesp32/HttpClientLight/library.json similarity index 90% rename from lib/libesp32/Berry-HttpClientLight/library.json rename to lib/libesp32/HttpClientLight/library.json index c9e5208f9293..46522f90aed1 100644 --- a/lib/libesp32/Berry-HttpClientLight/library.json +++ b/lib/libesp32/HttpClientLight/library.json @@ -1,5 +1,5 @@ { - "name": "HttpClient light for Berry", + "name": "HttpClient light", "version": "1.0", "description": "Forked version of Arduino HttpClient to support BearSSL instead of mbedTLS", "license": "MIT", diff --git a/lib/libesp32/Berry-HttpClientLight/src/HTTPUpdateLight.cpp b/lib/libesp32/HttpClientLight/src/HTTPUpdateLight.cpp similarity index 100% rename from lib/libesp32/Berry-HttpClientLight/src/HTTPUpdateLight.cpp rename to lib/libesp32/HttpClientLight/src/HTTPUpdateLight.cpp diff --git a/lib/libesp32/Berry-HttpClientLight/src/HTTPUpdateLight.h b/lib/libesp32/HttpClientLight/src/HTTPUpdateLight.h similarity index 100% rename from lib/libesp32/Berry-HttpClientLight/src/HTTPUpdateLight.h rename to lib/libesp32/HttpClientLight/src/HTTPUpdateLight.h diff --git a/lib/libesp32/Berry-HttpClientLight/src/HttpClientLight.cpp b/lib/libesp32/HttpClientLight/src/HttpClientLight.cpp similarity index 100% rename from lib/libesp32/Berry-HttpClientLight/src/HttpClientLight.cpp rename to lib/libesp32/HttpClientLight/src/HttpClientLight.cpp diff --git a/lib/libesp32/Berry-HttpClientLight/src/HttpClientLight.h b/lib/libesp32/HttpClientLight/src/HttpClientLight.h similarity index 100% rename from lib/libesp32/Berry-HttpClientLight/src/HttpClientLight.h rename to lib/libesp32/HttpClientLight/src/HttpClientLight.h diff --git a/lib/libesp32/Berry-HttpClientLight/src/TasUpdate.h b/lib/libesp32/HttpClientLight/src/TasUpdate.h similarity index 100% rename from lib/libesp32/Berry-HttpClientLight/src/TasUpdate.h rename to lib/libesp32/HttpClientLight/src/TasUpdate.h diff --git a/lib/libesp32/Berry-HttpClientLight/src/TasUpdater.cpp b/lib/libesp32/HttpClientLight/src/TasUpdater.cpp similarity index 99% rename from lib/libesp32/Berry-HttpClientLight/src/TasUpdater.cpp rename to lib/libesp32/HttpClientLight/src/TasUpdater.cpp index e359ff96fee3..d69463515e1f 100644 --- a/lib/libesp32/Berry-HttpClientLight/src/TasUpdater.cpp +++ b/lib/libesp32/HttpClientLight/src/TasUpdater.cpp @@ -1,6 +1,10 @@ #include "TasUpdate.h" #include "Arduino.h" +#if ESP_IDF_VERSION_MAJOR >= 5 +#include "spi_flash_mmap.h" +#else #include "esp_spi_flash.h" +#endif #include "esp_ota_ops.h" #include "esp_image_format.h" diff --git a/lib/libesp32/Zip-readonly-FS/src/ZipReadFS.cpp b/lib/libesp32/Zip-readonly-FS/src/ZipReadFS.cpp index 5e642105b184..5d5590f36318 100644 --- a/lib/libesp32/Zip-readonly-FS/src/ZipReadFS.cpp +++ b/lib/libesp32/Zip-readonly-FS/src/ZipReadFS.cpp @@ -125,6 +125,8 @@ class ZipEntryFileImpl : public FileImpl { class ZipReadFileImpl; typedef std::shared_ptr ZipReadFileImplPtr; + +// this is the proxy FileImpl - used for passing through real files. class ZipReadFileImpl : public FileImpl { public: ZipReadFileImpl(File f) { _f = f; } @@ -163,7 +165,9 @@ class ZipReadFileImpl : public FileImpl { return _f.isDirectory(); } FileImplPtr openNextFile(const char* mode) { - return nullptr; // TODO + File f = _f.openNextFile(mode); + return ZipReadFileImplPtr(new ZipReadFileImpl(f)); + //return nullptr; // TODO } void rewindDirectory(void) { return _f.rewindDirectory(); @@ -469,6 +473,9 @@ FileImplPtr ZipReadFSImpl::open(const char* path, const char* mode, const bool c char *tok; char *prefix = strtok_r(sub_path, "#", &tok); char *suffix = strtok_r(NULL, "", &tok); + if (!suffix || *suffix == 0){ // bad filename - nothing after # + return ZipReadFileImplPtr(); // return an error + } // if suffix starts with '/', skip the first char if (*suffix == '/') { suffix++; } // AddLog(LOG_LEVEL_DEBUG, "ZIP: prefix=%s suffix=%s", prefix, suffix); diff --git a/lib/libesp32/berry/Makefile b/lib/libesp32/berry/Makefile index 0847eb4b2caf..5907e22db480 100755 --- a/lib/libesp32/berry/Makefile +++ b/lib/libesp32/berry/Makefile @@ -3,7 +3,7 @@ DEBUG_FLAGS = -O0 -g -DBE_DEBUG TEST_FLAGS = $(DEBUG_FLAGS) --coverage -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined LIBS = -lm TARGET = berry -CC = gcc +CC = clang # install clang!! gcc seems to produce a defect berry binary MKDIR = mkdir LFLAGS = diff --git a/lib/libesp32/berry/berry.exe b/lib/libesp32/berry/berry.exe index 7dfe426b590b..9d90681671ec 100644 Binary files a/lib/libesp32/berry/berry.exe and b/lib/libesp32/berry/berry.exe differ diff --git a/lib/libesp32/berry/default/berry_conf.h b/lib/libesp32/berry/default/berry_conf.h index 18d64ad81bdb..13200f530993 100644 --- a/lib/libesp32/berry/default/berry_conf.h +++ b/lib/libesp32/berry/default/berry_conf.h @@ -60,6 +60,14 @@ **/ #define BE_USE_PRECOMPILED_OBJECT 1 +/* Macro: BE_DEBUG_SOURCE_FILE + * Indicate if each function remembers its source file name + * 0: do not keep the file name (saves 4 bytes per function) + * 1: keep the source file name + * Default: 1 + **/ +#define BE_DEBUG_SOURCE_FILE 0 + /* Macro: BE_DEBUG_RUNTIME_INFO * Set runtime error debugging information. * 0: unable to output source file and line number at runtime. diff --git a/lib/libesp32/berry/gen.sh b/lib/libesp32/berry/gen.sh index e67d6a426aa7..2df6ad838e94 100755 --- a/lib/libesp32/berry/gen.sh +++ b/lib/libesp32/berry/gen.sh @@ -2,7 +2,7 @@ # # generate all precompiled Berry structures from multiple modules # -# Should be eventually included in the build process +# Included in the Platformio build process with `pio-tools/gen-berry-structures.py # -rm generate/be_*.h -python3 tools/coc/coc -o generate src default ../berry_tasmota/src ../berry_mapping/src ../berry_int64/src ../../libesp32_lvgl/lv_binding_berry/src ../../libesp32_lvgl/lv_binding_berry/src/solidify ../../libesp32_lvgl/lv_binding_berry/generate -c default/berry_conf.h +rm -Rf ./generate/be_*.h +python3 tools/coc/coc -o generate src default ../berry_tasmota/src ../berry_mapping/src ../berry_int64/src ../../libesp32_lvgl/lv_binding_berry/src ../berry_matter/src/solidify ../berry_matter/src ../../libesp32_lvgl/lv_binding_berry/src/solidify ../../libesp32_lvgl/lv_binding_berry/generate -c default/berry_conf.h diff --git a/lib/libesp32/berry/src/be_api.c b/lib/libesp32/berry/src/be_api.c index fb2b8e0176a5..ba5b915d2d9d 100644 --- a/lib/libesp32/berry/src/be_api.c +++ b/lib/libesp32/berry/src/be_api.c @@ -1038,7 +1038,9 @@ BERRY_API int be_pcall(bvm *vm, int argc) return be_protectedcall(vm, f, argc); } +#ifdef __GNUC__ __attribute__((noreturn)) +#endif BERRY_API void be_raise(bvm *vm, const char *except, const char *msg) { be_pushstring(vm, except); diff --git a/lib/libesp32/berry/src/be_baselib.c b/lib/libesp32/berry/src/be_baselib.c index 592d74a5302c..3cc2e9f2c5f7 100644 --- a/lib/libesp32/berry/src/be_baselib.c +++ b/lib/libesp32/berry/src/be_baselib.c @@ -14,11 +14,12 @@ #include "be_vector.h" #include "be_string.h" #include "be_map.h" +#include "be_strlib.h" #include #define READLINE_STEP 100 -static int l_assert(bvm *vm) +int be_baselib_assert(bvm *vm) { int argc = be_top(vm); /* assertion fails when there is no argument @@ -33,7 +34,7 @@ static int l_assert(bvm *vm) be_return_nil(vm); } -static int l_print(bvm *vm) +int be_baselib_print(bvm *vm) { int i, argc = be_top(vm); for (i = 1; i <= argc; ++i) { @@ -68,7 +69,7 @@ static int m_readline(bvm *vm) be_return(vm); } -static int l_input(bvm *vm) +int be_baselib_input(bvm *vm) { if (be_top(vm) && be_isstring(vm, 1)) { /* echo prompt */ be_writestring(be_tostring(vm, 1)); @@ -118,7 +119,7 @@ static bbool obj2int(bvm *vm, bvalue *var, bint *val) return bfalse; } -static int l_super(bvm *vm) +int be_baselib_super(bvm *vm) { int argc = be_top(vm); @@ -197,7 +198,7 @@ static int l_super(bvm *vm) be_return_nil(vm); } -static int l_type(bvm *vm) +int be_baselib_type(bvm *vm) { if (be_top(vm)) { be_pushstring(vm, be_typename(vm, 1)); @@ -206,7 +207,7 @@ static int l_type(bvm *vm) be_return_nil(vm); } -static int l_classname(bvm *vm) +int be_baselib_classname(bvm *vm) { if (be_top(vm)) { const char *t = be_classname(vm, 1); @@ -218,7 +219,7 @@ static int l_classname(bvm *vm) be_return_nil(vm); } -static int l_classof(bvm *vm) +int be_baselib_classof(bvm *vm) { if (be_top(vm) && be_classof(vm, 1)) { be_return(vm); @@ -226,7 +227,7 @@ static int l_classof(bvm *vm) be_return_nil(vm); } -static int l_number(bvm *vm) +int be_baselib_number(bvm *vm) { if (be_top(vm)) { if (be_isstring(vm, 1)) { @@ -240,7 +241,7 @@ static int l_number(bvm *vm) be_return_nil(vm); } -static int l_int(bvm *vm) +int be_baselib_int(bvm *vm) { if (be_top(vm)) { if (be_isstring(vm, 1)) { @@ -272,7 +273,7 @@ static int l_int(bvm *vm) be_return_nil(vm); } -static int l_real(bvm *vm) +int be_baselib_real(bvm *vm) { if (be_top(vm)) { if (be_isstring(vm, 1)) { @@ -296,7 +297,7 @@ static int check_method(bvm *vm, const char *attr) be_isinstance(vm, 1) && be_getmethod(vm, 1, attr); } -static int l_iterator(bvm *vm) +int be_baselib_iterator(bvm *vm) { if (be_top(vm) && be_isfunction(vm, 1)) { be_return(vm); /* return the argument[0]::function */ @@ -357,7 +358,7 @@ static int l_call(bvm *vm) be_return_nil(vm); } -static int l_str(bvm *vm) +int be_baselib_str(bvm *vm) { if (be_top(vm)) { be_tostring(vm, 1); @@ -378,7 +379,7 @@ static int l_bool(bvm *vm) } -static int l_size(bvm *vm) +int be_baselib_size(bvm *vm) { if (be_top(vm) && be_isstring(vm, 1)) { be_pushint(vm, be_strlen(vm, 1)); @@ -393,7 +394,7 @@ static int l_size(bvm *vm) be_return_nil(vm); } -static int l_module(bvm *vm) +int be_baselib_module(bvm *vm) { int argc = be_top(vm); be_newmodule(vm); @@ -436,7 +437,7 @@ static int m_compile_file(bvm *vm) } #endif -static int l_compile(bvm *vm) +int be_baselib_compile(bvm *vm) { #if BE_USE_SCRIPT_COMPILER if (be_top(vm) && be_isstring(vm, 1)) { @@ -467,12 +468,12 @@ static int _issubv(bvm *vm, bbool (*filter)(bvm*, int)) be_return(vm); } -static int l_issubclass(bvm *vm) +int be_baselib_issubclass(bvm *vm) { return _issubv(vm, be_isclass); } -static int l_isinstance(bvm *vm) +int be_baselib_isinstance(bvm *vm) { return _issubv(vm, be_isinstance); } @@ -480,23 +481,23 @@ static int l_isinstance(bvm *vm) #if !BE_USE_PRECOMPILED_OBJECT void be_load_baselib(bvm *vm) { - be_regfunc(vm, "assert", l_assert); - be_regfunc(vm, "print", l_print); - be_regfunc(vm, "input", l_input); - be_regfunc(vm, "super", l_super); - be_regfunc(vm, "type", l_type); - be_regfunc(vm, "classname", l_classname); - be_regfunc(vm, "classof", l_classof); - be_regfunc(vm, "number", l_number); - be_regfunc(vm, "str", l_str); - be_regfunc(vm, "int", l_int); - be_regfunc(vm, "real", l_real); - be_regfunc(vm, "module", l_module); - be_regfunc(vm, "size", l_size); - be_regfunc(vm, "compile", l_compile); - be_regfunc(vm, "issubclass", l_issubclass); - be_regfunc(vm, "isinstance", l_isinstance); - be_regfunc(vm, "__iterator__", l_iterator); + be_regfunc(vm, "assert", be_baselib_assert); + be_regfunc(vm, "print", be_baselib_print); + be_regfunc(vm, "input", be_baselib_input); + be_regfunc(vm, "super", be_baselib_super); + be_regfunc(vm, "type", be_baselib_type); + be_regfunc(vm, "classname", be_baselib_classname); + be_regfunc(vm, "classof", be_baselib_classof); + be_regfunc(vm, "number", be_baselib_number); + be_regfunc(vm, "str", be_baselib_str); + be_regfunc(vm, "int", be_baselib_int); + be_regfunc(vm, "real", be_baselib_real); + be_regfunc(vm, "module", be_baselib_module); + be_regfunc(vm, "size", be_baselib_size); + be_regfunc(vm, "compile", be_baselib_compile); + be_regfunc(vm, "issubclass", be_baselib_issubclass); + be_regfunc(vm, "isinstance", be_baselib_isinstance); + be_regfunc(vm, "__iterator__", be_baselib_iterator); } /* call must be added later to respect order of builtins */ @@ -504,6 +505,7 @@ void be_load_baselib_next(bvm *vm) { be_regfunc(vm, "call", l_call); be_regfunc(vm, "bool", l_bool); + be_regfunc(vm, "format", be_str_format); } #else extern const bclass be_class_list; @@ -513,23 +515,23 @@ extern const bclass be_class_bytes; extern int be_nfunc_open(bvm *vm); /* @const_object_info_begin vartab m_builtin (scope: local) { - assert, func(l_assert) - print, func(l_print) - input, func(l_input) - super, func(l_super) - type, func(l_type) - classname, func(l_classname) - classof, func(l_classof) - number, func(l_number) - str, func(l_str) - int, func(l_int) - real, func(l_real) - module, func(l_module) - size, func(l_size) - compile, func(l_compile) - issubclass, func(l_issubclass) - isinstance, func(l_isinstance) - __iterator__, func(l_iterator) + assert, func(be_baselib_assert) + print, func(be_baselib_print) + input, func(be_baselib_input) + super, func(be_baselib_super) + type, func(be_baselib_type) + classname, func(be_baselib_classname) + classof, func(be_baselib_classof) + number, func(be_baselib_number) + str, func(be_baselib_str) + int, func(be_baselib_int) + real, func(be_baselib_real) + module, func(be_baselib_module) + size, func(be_baselib_size) + compile, func(be_baselib_compile) + issubclass, func(be_baselib_issubclass) + isinstance, func(be_baselib_isinstance) + __iterator__, func(be_baselib_iterator) open, func(be_nfunc_open) list, class(be_class_list) map, class(be_class_map) @@ -537,6 +539,7 @@ vartab m_builtin (scope: local) { bytes, class(be_class_bytes) call, func(l_call) bool, func(l_bool) + format, func(be_str_format) } @const_object_info_end */ #include "../generate/be_fixed_m_builtin.h" diff --git a/lib/libesp32/berry/src/be_baselib.h b/lib/libesp32/berry/src/be_baselib.h new file mode 100644 index 000000000000..582b0871b75d --- /dev/null +++ b/lib/libesp32/berry/src/be_baselib.h @@ -0,0 +1,31 @@ +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef __BE_BASELIB_H +#define __BE_BASELIB_H + +#include "be_object.h" + +int be_baselib_assert(bvm *vm); +int be_baselib_print(bvm *vm); +int be_baselib_input(bvm *vm); +int be_baselib_super(bvm *vm); +int be_baselib_type(bvm *vm); +int be_baselib_classname(bvm *vm); +int be_baselib_classof(bvm *vm); +int be_baselib_number(bvm *vm); +int be_baselib_str(bvm *vm); +int be_baselib_int(bvm *vm); +int be_baselib_real(bvm *vm); +int be_baselib_module(bvm *vm); +int be_baselib_size(bvm *vm); +int be_baselib_compile(bvm *vm); +int be_baselib_issubclass(bvm *vm); +int be_baselib_isinstance(bvm *vm); +int be_baselib_iterator(bvm *vm); + +#endif diff --git a/lib/libesp32/berry/src/be_bytecode.c b/lib/libesp32/berry/src/be_bytecode.c index 14a5950fc02f..133a96618075 100644 --- a/lib/libesp32/berry/src/be_bytecode.c +++ b/lib/libesp32/berry/src/be_bytecode.c @@ -114,6 +114,8 @@ static void save_string(void *fp, bstring *s) const char *data = str(s); save_word(fp, length); be_fwrite(fp, data, length); + } else { + save_word(fp, 0); } } @@ -247,7 +249,11 @@ static void save_proto(bvm *vm, void *fp, bproto *proto) { if (proto) { save_string(fp, proto->name); /* name */ +#if BE_DEBUG_SOURCE_FILE save_string(fp, proto->source); /* source */ +#else + save_string(fp, NULL); /* source */ +#endif save_byte(fp, proto->argc); /* argc */ save_byte(fp, proto->nstack); /* nstack */ save_byte(fp, proto->varg); /* varg */ @@ -551,7 +557,11 @@ static bbool load_proto(bvm *vm, void *fp, bproto **proto, int info, int version if (str_len(name)) { *proto = be_newproto(vm); (*proto)->name = name; +#if BE_DEBUG_SOURCE_FILE (*proto)->source = load_string(vm, fp); +#else + load_string(vm, fp); /* discard name */ +#endif (*proto)->argc = load_byte(fp); (*proto)->nstack = load_byte(fp); if (version > 1) { diff --git a/lib/libesp32/berry/src/be_byteslib.c b/lib/libesp32/berry/src/be_byteslib.c index 665d630f3a3e..0a5c1747e6ea 100644 --- a/lib/libesp32/berry/src/be_byteslib.c +++ b/lib/libesp32/berry/src/be_byteslib.c @@ -356,6 +356,40 @@ static uint16_t buf_get2_be(buf_impl* attr, size_t offset) return 0; } +static uint32_t buf_get3_le(buf_impl* attr, size_t offset) +{ + if ((int32_t)offset + 2 < attr->len) { + return attr->bufptr[offset] | (attr->bufptr[offset+1] << 8) | (attr->bufptr[offset+2] << 16); + } + return 0; +} + +static uint16_t buf_get3_be(buf_impl* attr, size_t offset) +{ + if ((int32_t)offset + 2 < attr->len) { + return attr->bufptr[offset+2] | (attr->bufptr[offset+1] << 8) | (attr->bufptr[offset] << 16); + } + return 0; +} + +static void buf_set3_le(buf_impl* attr, size_t offset, uint32_t data) +{ + if ((int32_t)offset + 2 < attr->len) { + attr->bufptr[offset] = data & 0xFF; + attr->bufptr[offset+1] = (data >> 8) & 0xFF; + attr->bufptr[offset+2] = (data >> 16) & 0xFF; + } +} + +static void buf_set3_be(buf_impl* attr, size_t offset, uint32_t data) +{ + if ((int32_t)offset + 2 < attr->len) { + attr->bufptr[offset+2] = data & 0xFF; + attr->bufptr[offset+1] = (data >> 8) & 0xFF; + attr->bufptr[offset] = (data >> 16) & 0xFF; + } +} + static void buf_set4_le(buf_impl* attr, size_t offset, uint32_t data) { if ((int32_t)offset + 3 < attr->len) { @@ -832,12 +866,18 @@ static int m_get(bvm *vm, bbool sign) case 2: ret = buf_get2_le(&attr, idx); if (sign) { ret = (int16_t)(uint16_t) ret; } break; + case 3: ret = buf_get3_le(&attr, idx); + if (sign & (ret & 0x800000)) { ret = ret | 0xFF000000; } + break; case 4: ret = buf_get4_le(&attr, idx); break; case -2: ret = buf_get2_be(&attr, idx); if (sign) { ret = (int16_t)(uint16_t) ret; } break; + case -3: ret = buf_get3_be(&attr, idx); + if (sign & (ret & 0x800000)) { ret = ret | 0xFF000000; } + break; case -4: ret = buf_get4_be(&attr, idx); break; - default: be_raise(vm, "type_error", "size must be -4, -2, -1, 0, 1, 2 or 4."); + default: be_raise(vm, "type_error", "size must be -4, -3, -2, -1, 0, 1, 2, 3 or 4."); } be_pop(vm, argc - 1); if (vsize != 0) { @@ -911,10 +951,12 @@ static int m_set(bvm *vm) case -1: /* fallback below */ case 1: buf_set1(&attr, idx, value); break; case 2: buf_set2_le(&attr, idx, value); break; + case 3: buf_set3_le(&attr, idx, value); break; case 4: buf_set4_le(&attr, idx, value); break; case -2: buf_set2_be(&attr, idx, value); break; + case -3: buf_set3_be(&attr, idx, value); break; case -4: buf_set4_be(&attr, idx, value); break; - default: be_raise(vm, "type_error", "size must be -4, -2, -1, 0, 1, 2 or 4."); + default: be_raise(vm, "type_error", "size must be -4, -3, -2, -1, 0, 1, 2, 3 or 4."); } be_pop(vm, argc - 1); m_write_attributes(vm, 1, &attr); /* update attributes */ diff --git a/lib/libesp32/berry/src/be_code.c b/lib/libesp32/berry/src/be_code.c index 1a890390e073..ac4208a01977 100644 --- a/lib/libesp32/berry/src/be_code.c +++ b/lib/libesp32/berry/src/be_code.c @@ -81,7 +81,8 @@ static int codeABx(bfuncinfo *finfo, bopcode op, int a, int bx) /* Move value from register b to register a */ /* Check the previous instruction to compact both instruction as one if possible */ /* If b is a constant, add LDCONST or add MOVE otherwise */ -static void code_move(bfuncinfo *finfo, int a, int b) +/* returns false if the move operation happened, or true if there was a register optimization and `b` should be replaced by `a` */ +static bbool code_move(bfuncinfo *finfo, int a, int b) { if (finfo->pc) { /* If not the first instruction of the function */ binstruction *i = be_vector_end(&finfo->code); /* get the last instruction */ @@ -91,7 +92,14 @@ static void code_move(bfuncinfo *finfo, int a, int b) int x = IGET_RA(*i), y = IGET_RKB(*i), z = IGET_RKC(*i); if (b == x && (a == y || (op < OP_NEG && a == z))) { *i = (*i & ~IRA_MASK) | ISET_RA(a); - return; + return btrue; + } + } + if (!isK(b)) { /* OP_MOVE */ + /* check if the previous OP_MOVE is not identical */ + binstruction mov = ISET_OP(OP_MOVE) | ISET_RA(a) | ISET_RKB(b) | ISET_RKC(0); + if (mov == *i) { + return btrue; /* previous instruction is the same move, remove duplicate */ } } } @@ -100,6 +108,7 @@ static void code_move(bfuncinfo *finfo, int a, int b) } else { codeABC(finfo, OP_MOVE, a, b, 0); } + return bfalse; } /* Free register at top (checks that it´s a register) */ @@ -107,7 +116,7 @@ static void code_move(bfuncinfo *finfo, int a, int b) static void free_expreg(bfuncinfo *finfo, bexpdesc *e) { /* release temporary register */ - if (e && e->type == ETREG) { + if (e && e->type == ETREG && e->v.idx == finfo->freereg - 1) { /* free ETREG only if it's top of stack */ be_code_freeregs(finfo, 1); } } @@ -670,20 +679,25 @@ static void setsfxvar(bfuncinfo *finfo, bopcode op, bexpdesc *e1, int src) /* Assign expr e2 to e1 */ /* e1 must be in a register and have a valid idx */ +/* if `keep_reg` is true, do not release registre */ /* return 1 if assignment was possible, 0 if type is not compatible */ -int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2) +int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, bbool keep_reg) { int src = exp2reg(finfo, e2, e1->type == ETLOCAL ? e1->v.idx : -1); /* Convert e2 to kreg */ /* If e1 is a local variable, use the register */ - if (e1->type != ETLOCAL || e1->v.idx != src) { + if (!keep_reg && (e1->type != ETLOCAL || e1->v.idx != src)) { free_expreg(finfo, e2); /* free source (checks only ETREG) */ /* TODO e2 is at top */ } switch (e1->type) { case ETLOCAL: /* It can't be ETREG. */ if (e1->v.idx != src) { - code_move(finfo, e1->v.idx, src); /* do explicit move only if needed */ + bbool reg_optimized = code_move(finfo, e1->v.idx, src); /* do explicit move only if needed */ + if (reg_optimized) { + free_expreg(finfo, e2); /* free source (checks only ETREG) */ + *e2 = *e1; /* now e2 is e1 ETLOCAL */ + } } break; case ETGLOBAL: /* store to grobal R(A) -> G(Bx) by global index */ @@ -714,7 +728,7 @@ int be_code_nextreg(bfuncinfo *finfo, bexpdesc *e) { int dst = finfo->freereg; int src = exp2anyreg(finfo, e); /* get variable register index */ - if (e->type != ETREG) { /* move local and const to new register */ + if ((e->type != ETREG) || (src < dst - 1)) { /* move local and const to new register, don't move if already top of stack */ code_move(finfo, dst, src); be_code_allocregs(finfo, 1); } else { @@ -887,7 +901,7 @@ void be_code_import(bfuncinfo *finfo, bexpdesc *m, bexpdesc *v) codeABC(finfo, OP_IMPORT, dst, src, 0); m->type = ETREG; m->v.idx = dst; - be_code_setvar(finfo, v, m); + be_code_setvar(finfo, v, m, bfalse); } } diff --git a/lib/libesp32/berry/src/be_code.h b/lib/libesp32/berry/src/be_code.h index cc45d4e06c7e..f0ef2e1943c8 100644 --- a/lib/libesp32/berry/src/be_code.h +++ b/lib/libesp32/berry/src/be_code.h @@ -16,7 +16,7 @@ int be_code_allocregs(bfuncinfo *finfo, int count); void be_code_prebinop(bfuncinfo *finfo, int op, bexpdesc *e); void be_code_binop(bfuncinfo *finfo, int op, bexpdesc *e1, bexpdesc *e2, int dst); int be_code_unop(bfuncinfo *finfo, int op, bexpdesc *e); -int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2); +int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, bbool keep_reg); int be_code_nextreg(bfuncinfo *finfo, bexpdesc *e); int be_code_jump(bfuncinfo *finfo); void be_code_jumpto(bfuncinfo *finfo, int dst); diff --git a/lib/libesp32/berry/src/be_debug.c b/lib/libesp32/berry/src/be_debug.c index 58f81f2b416c..142c4ea5eab4 100644 --- a/lib/libesp32/berry/src/be_debug.c +++ b/lib/libesp32/berry/src/be_debug.c @@ -137,7 +137,7 @@ void be_print_inst(binstruction ins, int pc, void* fout) logbuf("%s", opc2str(op)); break; } - memcpy(__lbuf_tmp, __lbuf, strlen(__lbuf)+1); + memcpy(__lbuf_tmp, __lbuf, strlen(__lbuf) + 1); logbuf("%s\n", __lbuf_tmp); if (fout) { be_fwrite(fout, __lbuf, strlen(__lbuf)); @@ -156,7 +156,9 @@ void be_dumpclosure(bclosure *cl) #if BE_DEBUG_RUNTIME_INFO blineinfo *lineinfo = proto->lineinfo; #endif +#if BE_DEBUG_SOURCE_FILE logfmt("source '%s', ", str(proto->source)); +#endif logfmt("function '%s':\n", str(proto->name)); #if BE_DEBUG_RUNTIME_INFO if (lineinfo) { /* first line */ @@ -184,8 +186,10 @@ static void sourceinfo(bproto *proto, binstruction *ip) blineinfo *end = it + proto->nlineinfo; int pc = cast_int(ip - proto->code - 1); /* now vm->ip has been increased */ for (; it < end && pc > it->endpc; ++it); - sprintf(buf, ":%d:", it->linenumber); + snprintf(buf, sizeof(buf), ":%d:", it->linenumber); +#if BE_DEBUG_SOURCE_FILE be_writestring(str(proto->source)); +#endif be_writestring(buf); } else { be_writestring(":"); @@ -262,7 +266,9 @@ static void hook_callnative(bvm *vm, int mask) be_stack_require(vm, BE_STACK_FREE_MIN + 2); info.type = mask; info.line = cf->lineinfo->linenumber; +#if BE_DEBUG_SOURCE_FILE info.source = str(cl->proto->source); +#endif info.func_name = str(cl->proto->name); info.data = hb->data; hb->hook(vm, &info); diff --git a/lib/libesp32/berry/src/be_debuglib.c b/lib/libesp32/berry/src/be_debuglib.c index 153af55fb3ba..502935b6c59b 100644 --- a/lib/libesp32/berry/src/be_debuglib.c +++ b/lib/libesp32/berry/src/be_debuglib.c @@ -167,14 +167,45 @@ static int m_counters(bvm *vm) map_insert(vm, "call", vm->counter_call); map_insert(vm, "get", vm->counter_get); map_insert(vm, "set", vm->counter_set); + map_insert(vm, "getgbl", vm->counter_get_global); map_insert(vm, "try", vm->counter_try); map_insert(vm, "raise", vm->counter_exc); map_insert(vm, "objects", vm->counter_gc_kept); + map_insert(vm, "mem_alloc", vm->counter_mem_alloc); + map_insert(vm, "mem_free", vm->counter_mem_free); + map_insert(vm, "mem_realloc", vm->counter_mem_realloc); be_pop(vm, 1); be_return(vm); } #endif +static int m_allocs(bvm *vm) { +#if BE_USE_PERF_COUNTERS + be_pushint(vm, vm->counter_mem_alloc); + be_return(vm); +#else + be_return_nil(vm); +#endif +} + +static int m_frees(bvm *vm) { +#if BE_USE_PERF_COUNTERS + be_pushint(vm, vm->counter_mem_free); + be_return(vm); +#else + be_return_nil(vm); +#endif +} + +static int m_reallocs(bvm *vm) { +#if BE_USE_PERF_COUNTERS + be_pushint(vm, vm->counter_mem_realloc); + be_return(vm); +#else + be_return_nil(vm); +#endif +} + #if !BE_USE_PRECOMPILED_OBJECT be_native_module_attr_table(debug) { be_native_module_function("attrdump", m_attrdump), @@ -207,6 +238,10 @@ module debug (scope: global, depend: BE_USE_DEBUG_MODULE) { top, func(m_top) varname, func(m_varname), BE_DEBUG_VAR_INFO upvname, func(m_upvname), BE_DEBUG_VAR_INFO + // individual counters + allocs, func(m_allocs) + frees, func(m_frees) + reallocs, func(m_reallocs) } @const_object_info_end */ #include "../generate/be_fixed_debug.h" diff --git a/lib/libesp32/berry/src/be_exec.c b/lib/libesp32/berry/src/be_exec.c index 9be2793d7e62..43791c66a341 100644 --- a/lib/libesp32/berry/src/be_exec.c +++ b/lib/libesp32/berry/src/be_exec.c @@ -183,8 +183,9 @@ int be_protectedparser(bvm *vm, return res; } -static const char* _sgets(void *data, size_t *size) +static const char* _sgets(struct blexer* lexer, void *data, size_t *size) { + (void)lexer; struct strbuf *sb = data; *size = sb->len; if (sb->len) { @@ -194,8 +195,9 @@ static const char* _sgets(void *data, size_t *size) return NULL; } -static const char* _fgets(void *data, size_t *size) +static const char* _fgets(struct blexer* lexer, void *data, size_t *size) { + (void)lexer; struct filebuf *fb = data; *size = be_fread(fb->fp, fb->buf, sizeof(fb->buf)); if (*size) { diff --git a/lib/libesp32/berry/src/be_func.c b/lib/libesp32/berry/src/be_func.c index d492299540f4..b1280d9ec0ae 100644 --- a/lib/libesp32/berry/src/be_func.c +++ b/lib/libesp32/berry/src/be_func.c @@ -108,7 +108,9 @@ bproto* be_newproto(bvm *vm) p->codesize = 0; p->argc = 0; p->varg = 0; +#if BE_DEBUG_SOURCE_FILE p->source = NULL; +#endif #if BE_DEBUG_RUNTIME_INFO p->lineinfo = NULL; p->nlineinfo = 0; diff --git a/lib/libesp32/berry/src/be_gc.c b/lib/libesp32/berry/src/be_gc.c index f7532e2392ab..e66afa56d6b9 100644 --- a/lib/libesp32/berry/src/be_gc.c +++ b/lib/libesp32/berry/src/be_gc.c @@ -231,7 +231,9 @@ static void mark_proto(bvm *vm, bgcobject *obj) mark_gray(vm, gc_object(*ptab)); } gc_setdark_safe(p->name); +#if BE_DEBUG_SOURCE_FILE gc_setdark_safe(p->source); +#endif #if BE_DEBUG_VAR_INFO if (p->nvarinfo) { bvarinfo *vinfo = p->varinfo; diff --git a/lib/libesp32/berry/src/be_introspectlib.c b/lib/libesp32/berry/src/be_introspectlib.c index a87ce3932806..4f98f2d94e07 100644 --- a/lib/libesp32/berry/src/be_introspectlib.c +++ b/lib/libesp32/berry/src/be_introspectlib.c @@ -70,12 +70,15 @@ static int m_findmember(bvm *vm) if (top >= 3) { protected = !be_tobool(vm, 3); } - if (top >= 2) { - if (protected && (be_isinstance(vm, 1) || be_ismodule(vm, 1) || be_isclass(vm, 1)) && be_isstring(vm, 2)) { - int ret = be_execprotected(vm, &m_findmember_protected, (void*) be_tostring(vm, 2)); - if (ret == BE_OK) { - be_return(vm); + if (top >= 2 && be_isstring(vm, 2)) { + if (protected) { + if (be_isinstance(vm, 1) || be_ismodule(vm, 1) || be_isclass(vm, 1)) { + int ret = be_execprotected(vm, &m_findmember_protected, (void*) be_tostring(vm, 2)); + if (ret == BE_OK) { + be_return(vm); + } } + be_return_nil(vm); } else { /* run unprotected */ if (be_getmember(vm, 1, be_tostring(vm, 2))) { diff --git a/lib/libesp32/berry/src/be_lexer.c b/lib/libesp32/berry/src/be_lexer.c index 7b3f05726645..8a038a507f21 100644 --- a/lib/libesp32/berry/src/be_lexer.c +++ b/lib/libesp32/berry/src/be_lexer.c @@ -13,14 +13,15 @@ #include "be_map.h" #include "be_vm.h" #include "be_strlib.h" +#include #define SHORT_STR_LEN 32 #define EOS '\0' /* end of source */ #define type_count() (int)array_count(kwords_tab) #define lexbuf(lex) ((lex)->buf.s) -#define isvalid(lex) ((lex)->cursor < (lex)->endbuf) -#define lgetc(lex) ((lex)->cursor) +#define isvalid(lex) ((lex)->reader.cursor < (lex)->endbuf) +#define lgetc(lex) ((lex)->reader.cursor) #define setstr(lex, v) ((lex)->token.u.s = (v)) #define setint(lex, v) ((lex)->token.u.i = (v)) #define setreal(lex, v) ((lex)->token.u.r = (v)) @@ -39,7 +40,8 @@ static const char* const kwords_tab[] = { ":", "?", "->", "if", "elif", "else", "while", "for", "def", "end", "class", "break", "continue", "return", "true", "false", "nil", "var", "do", - "import", "as", "try", "except", "raise", "static" + "import", "as", "try", "except", "raise", "static", + ":=", }; void be_lexerror(blexer *lexer, const char *msg) @@ -102,12 +104,12 @@ static int next(blexer *lexer) struct blexerreader *lr = &lexer->reader; if (!(lr->len--)) { static const char eos = EOS; - const char *s = lr->readf(lr->data, &lr->len); + const char *s = lr->readf(lexer, lr->data, &lr->len); lr->s = s ? s : &eos; --lr->len; } - lexer->cursor = *lr->s++; - return lexer->cursor; + lexer->reader.cursor = *lr->s++; + return lexer->reader.cursor; } static void clear_buf(blexer *lexer) @@ -115,10 +117,7 @@ static void clear_buf(blexer *lexer) lexer->buf.len = 0; } -/* save and next */ -static int save(blexer *lexer) -{ - int ch = lgetc(lexer); +static void save_char(blexer *lexer, int ch) { struct blexerbuf *buf = &lexer->buf; if (buf->len >= buf->size) { size_t size = buf->size << 1; @@ -126,6 +125,13 @@ static int save(blexer *lexer) buf->size = size; } buf->s[buf->len++] = (char)ch; +} + +/* save and next */ +static int save(blexer *lexer) +{ + int ch = lgetc(lexer); + save_char(lexer, ch); return next(lexer); } @@ -247,7 +253,7 @@ static int skip_newline(blexer *lexer) next(lexer); /* skip "\n\r" or "\r\n" */ } lexer->linenumber++; - return lexer->cursor; + return lexer->reader.cursor; } static void skip_comment(blexer *lexer) @@ -373,12 +379,225 @@ static btokentype scan_numeral(blexer *lexer) return type; } +/* structure for a temporary reader used by transpiler, with attributes for an allocated buffer and size */ +struct blexerreader_save { + struct blexerreader reader; + char* s; + size_t size; + char cursor; +}; + +/* buf reader for transpiled code from f-strings */ +/* it restores the original reader when the transpiler buffer is empty */ +/* the first pass returns a single byte buffer with the saved cursor */ +/* the second pass restores the original reader */ +static const char* _bufgets(struct blexer* lexer, void *data, size_t *size) +{ + /* this is called once the temporaty transpiler buffer is empty */ + struct blexerreader *reader = &lexer->reader; /* current reader which is temporary only for the transpiler */ + struct blexerreader_save *reader_save = data; /* original reader that needs to be restored once the buffer is empty */ + + /* first case, we saved the cursor (fist char), we server it now */ + if (reader_save->reader.cursor >= 0) { /* serve the previously saved cursor */ + /* copy cursor to a 'char' type */ + reader_save->cursor = reader_save->reader.cursor; + reader_save->reader.cursor = -1; /* no more cursor saved */ + *size = 1; + return &reader_save->cursor; + } + + /* second case, the saved cursor was returned, now restore the normal flow of the original reader */ + /* restore the original reader */ + *reader = reader_save->reader; + + /* free the memory from the structure */ + be_free(lexer->vm, reader_save->s, reader_save->size); /* free the buffer */ + be_free(lexer->vm, reader_save, sizeof(struct blexerreader_save)); /* free the structure */ + + if (!reader->len) { /* just in case the original buffer was also */ + return reader->readf(lexer, reader->data, size); + } + /* the following is not necessary, but safer */ + *size = reader->len; + return reader->s; +} + +static btokentype scan_string(blexer *lexer); /* forward declaration */ + +/* scan f-string and transpile it to `format(...)` syntax then feeding the normal lexer and parser */ +static void scan_f_string(blexer *lexer) +{ + char ch; + clear_buf(lexer); + scan_string(lexer); /* first scan the entire string in lexer->buf */ + + /* save original reader until the transpiled is processed */ + /* reader will be restored by the reader function once the transpiled buffer is empty */ + struct blexerreader_save *reader_save = (struct blexerreader_save *) be_malloc(lexer->vm, sizeof(struct blexerreader_save)); /* temporary reader */ + reader_save->reader = lexer->reader; + + /* save blexerbuf which contains the unparsed_fstring */ + struct blexerbuf buf_unparsed_fstr = lexer->buf; + + /* prepare and allocated a temporary buffer to save parsed f_string */ + lexer->buf.size = lexer->buf.size + 20; + lexer->buf.s = be_malloc(lexer->vm, lexer->buf.size); + lexer->buf.len = 0; + + /* parse f_string */ + /* First pass, check syntax and extract string literals, and format */ + save_char(lexer, '('); + save_char(lexer, '"'); + for (size_t i = 0; i < buf_unparsed_fstr.len; i++) { + ch = buf_unparsed_fstr.s[i]; + switch (ch) { + case '%': /* % needs to be encoded as %% */ + save_char(lexer, '%'); + save_char(lexer, '%'); + break; + case '\\': /* \ needs to be encoded as \\ */ + save_char(lexer, '\\'); + save_char(lexer, '\\'); + break; + case '"': /* " needs to be encoded as \" */ + save_char(lexer, '\\'); + save_char(lexer, '"'); + break; + case '}': /* }} is converted as } yet we tolerate a single } */ + if ((i+1 < buf_unparsed_fstr.len) && (buf_unparsed_fstr.s[i+1] == '}')) { i++; } /* if '}}' replace with '}' */ + save_char(lexer, '}'); + break; + case '\n': + save_char(lexer, '\\'); + save_char(lexer, 'n'); + break; + case '\r': + save_char(lexer, '\\'); + save_char(lexer, 'r'); + break; + default: /* copy any other character */ + save_char(lexer, ch); + break; + case '{': /* special case for { */ + i++; /* in all cases skip to next char */ + if ((i < buf_unparsed_fstr.len) && (buf_unparsed_fstr.s[i] == '{')) { + save_char(lexer, '{'); /* {{ is simply encoded as { and continue parsing */ + } else { + /* we still don't know if '=' is present, so we copy the expression each time, and rollback if we find out the '=' is not present */ + size_t rollback = lexer->buf.len; /* mark the end of string for later rollback if '=' is not present */ + /* parse inner part */ + /* skip everything until either ':' or '}' or '=' */ + /* if end of string is reached before '}' raise en error */ + for (; i < buf_unparsed_fstr.len; i++) { + ch = buf_unparsed_fstr.s[i]; + if (ch == ':' || ch == '}') { break; } + save_char(lexer, ch); /* copy any character unless it's ':' or '}' */ + if (ch == '=') { break; } /* '=' is copied but breaks parsing as well */ + } + /* safe check if we reached the end of the string */ + if (i >= buf_unparsed_fstr.len) { be_raise(lexer->vm, "syntax_error", "'}' expected"); } + /* if '=' detected then do some additional checks */ + if (ch == '=') { + i++; /* skip '=' and check we haven't reached the end */ + if (i >= buf_unparsed_fstr.len) { be_raise(lexer->vm, "syntax_error", "'}' expected"); } + ch = buf_unparsed_fstr.s[i]; + if ((ch != ':') && (ch != '}')) { /* '=' must be immediately followed by ':' or '}' */ + be_raise(lexer->vm, "syntax_error", "':' or '}' expected after '='"); + } + } else { + /* no '=' present, rollback the text of the expression */ + lexer->buf.len = rollback; + } + save_char(lexer, '%'); /* start format encoding */ + if (ch == ':') { + /* copy format */ + i++; + if ((i < buf_unparsed_fstr.len) && (buf_unparsed_fstr.s[i] == '%')) { i++; } /* skip '%' following ':' */ + for (; i < buf_unparsed_fstr.len; i++) { + ch = buf_unparsed_fstr.s[i]; + if (ch == '}') { break; } + save_char(lexer, ch); + } + if (i >= buf_unparsed_fstr.len) { be_raise(lexer->vm, "syntax_error", "'}' expected"); } + } else { + /* if no formatting, output '%s' */ + save_char(lexer, 's'); + } + } + break; + } + } + save_char(lexer, '"'); /* finish format string */ + + /* Second pass - add arguments if any */ + for (size_t i = 0; i < buf_unparsed_fstr.len; i++) { + /* skip any character that is not '{' followed by '{' */ + if (buf_unparsed_fstr.s[i] == '{') { + i++; /* in all cases skip to next char */ + if ((i < buf_unparsed_fstr.len) && (buf_unparsed_fstr.s[i] == '{')) { continue; } + /* extract argument */ + save_char(lexer, ','); /* add ',' to start next argument to `format()` */ + for (; i < buf_unparsed_fstr.len; i++) { + ch = buf_unparsed_fstr.s[i]; + if (ch == '=' || ch == ':' || ch == '}') { break; } + save_char(lexer, ch); /* copy expression until we reach ':', '=' or '}' */ + } + /* no need to check for end of string here, it was done already in first pass */ + if (ch == ':' || ch == '=') { /* if '=' or ':', skip everyting until '}' */ + i++; + for (; i < buf_unparsed_fstr.len; i++) { + ch = buf_unparsed_fstr.s[i]; + if (ch == '}') { break; } + } + } + } + } + save_char(lexer, ')'); /* add final ')' */ + + /* Situation now: */ + /* `buf_unparsed_fstr` contains the buffer of the input unparsed f-string, ex: "age: {age:2i}" */ + /* `lexer->buf` contains the buffer of the transpiled f-string without call to format(), ex: '("age: %2i", age)' */ + /* `reader_save` contains the original reader to continue parsing after f-string */ + /* `lexer->reader` will contain a temporary reader from the parsed f-string */ + + /* extract the parsed f-string from the temporary buffer (needs later deallocation) */ + char * parsed_fstr_s = lexer->buf.s; /* needs later deallocation with parsed_fstr_size */ + size_t parsed_fstr_len = lexer->buf.len; + size_t parsed_fstr_size = lexer->buf.size; + + /* restore buf to lexer */ + lexer->buf = buf_unparsed_fstr; + + /* change the temporary reader to the parsed f-string */ + lexer->reader.len = parsed_fstr_len; + lexer->reader.data = (void*) reader_save; /* link to the saved context */ + lexer->reader.s = parsed_fstr_s; /* reader is responisble to deallocate later this buffer */ + lexer->reader.readf = _bufgets; + + /* add information needed for `_bufgets` to later deallocate the buffer */ + reader_save->size = parsed_fstr_size; + reader_save->s = parsed_fstr_s; + + /* start parsing the parsed f-string, which is btw always '(' */ + next(lexer); + + /* remember that we are still in `scan_identifier()`, we replace the 'f' identifier to 'format' which is the global function to call */ + static const char FORMAT[] = "format"; + lexer->buf.len = sizeof(FORMAT) - 1; /* we now that buf size is at least SHORT_STR_LEN (32) */ + memmove(lexer->buf.s, FORMAT, lexer->buf.len); +} + static btokentype scan_identifier(blexer *lexer) { int type; bstring *s; save(lexer); match(lexer, is_word); + /* check if the form is f"aaaa" or f'aaa' */ + char ch = lgetc(lexer); + if ((lexer->buf.len == 1) && (lexer->buf.s[0] == 'f') && (ch == '"' || ch == '\'')) { + scan_f_string(lexer); + } s = buf_tostr(lexer); type = str_extra(s); if (type >= KeyIf && type < type_count()) { @@ -394,7 +613,9 @@ static int skip_delimiter(blexer *lexer) { int c = lgetc(lexer); int delimeter_present = 0; while (1) { - if (c == '\r' || c == '\n') { + if (c == '#') { + skip_comment(lexer); + } else if (c == '\r' || c == '\n') { skip_newline(lexer); } else if (c == ' ' || c == '\t' || c == '\f' || c == '\v') { next(lexer); @@ -531,7 +752,9 @@ static btokentype lexer_next(blexer *lexer) case '}': next(lexer); return OptRBR; case ',': next(lexer); return OptComma; case ';': next(lexer); return OptSemic; - case ':': next(lexer); return OptColon; + case ':': + next(lexer); + return check_next(lexer, '=') ? OptWalrus : OptColon; case '?': next(lexer); return OptQuestion; case '^': return scan_assign(lexer, OptXorAssign, OptBitXor); case '~': next(lexer); return OptFlip; diff --git a/lib/libesp32/berry/src/be_lexer.h b/lib/libesp32/berry/src/be_lexer.h index 4670709462f0..e166a1a64f51 100644 --- a/lib/libesp32/berry/src/be_lexer.h +++ b/lib/libesp32/berry/src/be_lexer.h @@ -89,7 +89,9 @@ typedef enum { KeyTry, /* keyword try */ KeyExcept, /* keyword except */ KeyRaise, /* keyword raise */ - KeyStatic /* keyword static */ + KeyStatic, /* keyword static */ + /* Walrus operator */ + OptWalrus, /* operator, := */ } btokentype; struct blexerreader { @@ -97,6 +99,7 @@ struct blexerreader { size_t len; void *data; breader readf; + int cursor; }; struct blexerbuf { @@ -123,7 +126,6 @@ typedef struct blexer { struct blexerreader reader; bmap *strtab; bvm *vm; - int cursor; } blexer; void be_lexer_init(blexer *lexer, bvm *vm, diff --git a/lib/libesp32/berry/src/be_listlib.c b/lib/libesp32/berry/src/be_listlib.c index a98b679df303..9cbfa38b0994 100644 --- a/lib/libesp32/berry/src/be_listlib.c +++ b/lib/libesp32/berry/src/be_listlib.c @@ -262,6 +262,14 @@ static int m_size(bvm *vm) be_return(vm); } +static int m_tobool(bvm *vm) +{ + be_getmember(vm, 1, ".p"); + list_check_data(vm, 1); + be_pushbool(vm, be_data_size(vm, -1) > 0); + be_return(vm); +} + static int m_resize(bvm *vm) { be_getmember(vm, 1, ".p"); @@ -507,6 +515,7 @@ void be_load_listlib(bvm *vm) { "reverse", m_reverse }, { "copy", m_copy }, { "keys", m_keys }, + { "tobool", m_tobool } { "..", m_connect }, { "+", m_merge }, { "==", m_equal }, @@ -536,6 +545,7 @@ class be_class_list (scope: global, name: list) { reverse, func(m_reverse) copy, func(m_copy) keys, func(m_keys) + tobool, func(m_tobool) .., func(m_connect) +, func(m_merge) ==, func(m_equal) diff --git a/lib/libesp32/berry/src/be_maplib.c b/lib/libesp32/berry/src/be_maplib.c index fc9f09fe7d0f..bf05f1a2934b 100644 --- a/lib/libesp32/berry/src/be_maplib.c +++ b/lib/libesp32/berry/src/be_maplib.c @@ -150,6 +150,14 @@ static int m_size(bvm *vm) be_return(vm); } +static int m_tobool(bvm *vm) +{ + be_getmember(vm, 1, ".p"); + map_check_data(vm, 1); + be_pushbool(vm, be_data_size(vm, -1) > 0); + be_return(vm); +} + static int iter_closure(bvm *vm) { /* for better performance, we operate the upvalues @@ -229,6 +237,7 @@ void be_load_maplib(bvm *vm) { "insert", m_insert }, { "iter", m_iter }, { "keys", m_keys }, + { "tobool", m_tobool } { NULL, NULL } }; be_regclass(vm, "map", members); @@ -249,6 +258,7 @@ class be_class_map (scope: global, name: map) { insert, func(m_insert) iter, func(m_iter) keys, func(m_keys) + tobool, func(m_tobool) } @const_object_info_end */ #include "../generate/be_fixed_be_class_map.h" diff --git a/lib/libesp32/berry/src/be_mem.c b/lib/libesp32/berry/src/be_mem.c index 976afece15bd..36e30866a7fc 100644 --- a/lib/libesp32/berry/src/be_mem.c +++ b/lib/libesp32/berry/src/be_mem.c @@ -60,12 +60,19 @@ BERRY_API void* be_realloc(bvm *vm, void *ptr, size_t old_size, size_t new_size) while (1) { /* Case 1: new allocation */ +#if BE_USE_PERF_COUNTERS + vm->counter_mem_alloc++; +#endif if (!ptr || (old_size == 0)) { block = malloc_from_pool(vm, new_size); } /* Case 2: deallocate */ else if (new_size == 0) { +#if BE_USE_PERF_COUNTERS + vm->counter_mem_free++; +#endif + if (ptr == NULL) { return NULL; } /* safeguard */ #if BE_USE_DEBUG_GC memset(ptr, 0xFF, old_size); /* fill the structure with invalid pointers */ #endif @@ -75,6 +82,9 @@ BERRY_API void* be_realloc(bvm *vm, void *ptr, size_t old_size, size_t new_size) /* Case 3: reallocate with a different size */ else if (new_size && old_size) { // TODO we already know they are not null TODO +#if BE_USE_PERF_COUNTERS + vm->counter_mem_realloc++; +#endif if (new_size <= POOL32_SIZE || old_size <=POOL32_SIZE) { /* complex case with different pools */ if (new_size <= POOL16_SIZE && old_size <= POOL16_SIZE) { diff --git a/lib/libesp32/berry/src/be_module.c b/lib/libesp32/berry/src/be_module.c index ff550301149e..17e5c4dcd077 100644 --- a/lib/libesp32/berry/src/be_module.c +++ b/lib/libesp32/berry/src/be_module.c @@ -126,6 +126,7 @@ static char* fixpath(bvm *vm, bstring *path, size_t *size) { char *buffer; const char *split, *base; +#if BE_DEBUG_SOURCE_FILE bvalue *func = vm->cf->func; bclosure *cl = var_toobj(func); if (var_isclosure(func)) { @@ -133,6 +134,9 @@ static char* fixpath(bvm *vm, bstring *path, size_t *size) } else { base = "/"; } +#else + base = "/"; +#endif split = be_splitpath(base); *size = split - base + (size_t)str_len(path) + SUFFIX_LEN; buffer = be_malloc(vm, *size); diff --git a/lib/libesp32/berry/src/be_object.h b/lib/libesp32/berry/src/be_object.h index ac6e940bfad4..fd29090adb45 100644 --- a/lib/libesp32/berry/src/be_object.h +++ b/lib/libesp32/berry/src/be_object.h @@ -151,16 +151,18 @@ typedef struct bproto { bbyte nupvals; /* upvalue count */ bbyte argc; /* argument count */ bbyte varg; /* variable argument position + 1 */ + int16_t codesize; /* code size */ + int16_t nconst; /* constants count */ + int16_t nproto; /* proto count */ bgcobject *gray; /* for gc gray list */ bupvaldesc *upvals; bvalue *ktab; /* constants table */ struct bproto **ptab; /* proto table */ binstruction *code; /* instructions sequence */ bstring *name; /* function name */ - int codesize; /* code size */ - int nconst; /* constants count */ - int nproto; /* proto count */ +#if BE_DEBUG_SOURCE_FILE bstring *source; /* source file name */ +#endif #if BE_DEBUG_RUNTIME_INFO /* debug information */ blineinfo *lineinfo; int nlineinfo; @@ -195,7 +197,8 @@ typedef struct { bntvfunc destroy; } bcommomobj; -typedef const char* (*breader)(void*, size_t*); +struct blexer; +typedef const char* (*breader)(struct blexer*, void*, size_t*); #define cast(_T, _v) ((_T)(_v)) #define cast_int(_v) cast(int, _v) diff --git a/lib/libesp32/berry/src/be_parser.c b/lib/libesp32/berry/src/be_parser.c index 5e58df6ccefd..3afedf41c998 100644 --- a/lib/libesp32/berry/src/be_parser.c +++ b/lib/libesp32/berry/src/be_parser.c @@ -80,6 +80,7 @@ typedef struct { static void stmtlist(bparser *parser); static void block(bparser *parser, int type); static void expr(bparser *parser, bexpdesc *e); +static void walrus_expr(bparser *parser, bexpdesc *e); static void sub_expr(bparser *parser, bexpdesc *e, int prio); static const bbyte binary_op_prio_tab[] = { @@ -195,6 +196,7 @@ static void begin_block(bfuncinfo *finfo, bblockinfo *binfo, int type) finfo->binfo = binfo; /* tell parser this is the current block */ binfo->type = (bbyte)type; binfo->hasupval = 0; + binfo->sideeffect = 0; binfo->beginpc = finfo->pc; /* set starting pc for this block */ binfo->nactlocals = (bbyte)be_list_count(finfo->local); /* count number of local variables in previous block */ if (type & BLOCK_LOOP) { @@ -224,6 +226,7 @@ static void end_block(bparser *parser) end_block_ex(parser, -1); } +#if BE_DEBUG_SOURCE_FILE /* Return the name of the source for this parser, could be `string`, `stdin` or the name of the current function */ static bstring* parser_source(bparser *parser) @@ -233,6 +236,7 @@ static bstring* parser_source(bparser *parser) } return be_newstr(parser->vm, parser->lexer.fname); } +#endif /* Initialize a function block and create a new `bprotoˋ */ static void begin_func(bparser *parser, bfuncinfo *finfo, bblockinfo *binfo) @@ -250,7 +254,9 @@ static void begin_func(bparser *parser, bfuncinfo *finfo, bblockinfo *binfo) be_vector_init(vm, &finfo->pvec, sizeof(bproto*)); /* vector for subprotos */ proto->ptab = be_vector_data(&finfo->pvec); proto->nproto = be_vector_capacity(&finfo->pvec); +#if BE_DEBUG_SOURCE_FILE proto->source = parser_source(parser); /* keep a copy of source for function */ +#endif finfo->local = be_list_new(vm); /* list for local variables */ var_setlist(vm->top, finfo->local); /* push list of local variables on the stack (avoid gc) */ be_stackpush(vm); @@ -364,7 +370,7 @@ static btokentype get_unary_op(bparser *parser) static btokentype get_assign_op(bparser *parser) { btokentype op = next_type(parser); - if (op >= OptAssign && op <= OptRsfAssign) { + if ((op >= OptAssign && op <= OptRsfAssign) || op == OptWalrus) { return op; } return OP_NOT_ASSIGN; @@ -627,7 +633,7 @@ static bproto* funcbody(bparser *parser, bstring *name, bclass *c, int type) new_var(parser, parser_newstr(parser, "_class"), &e1); /* new implicit variable '_class' */ init_exp(&e2, ETCONST, 0); be_code_implicit_class(parser->finfo, &e2, c); - be_code_setvar(parser->finfo, &e1, &e2); + be_code_setvar(parser->finfo, &e1, &e2, bfalse); finfo.proto->varg |= BE_VA_STATICMETHOD; } stmtlist(parser); /* parse statement without final `end` */ @@ -731,7 +737,7 @@ static void map_nextmember(bparser *parser, bexpdesc *l) match_token(parser, OptColon); /* ':' */ expr(parser, &e); /* value in `e` */ check_var(parser, &e); /* check if value is correct */ - be_code_setvar(finfo, &v, &e); /* set suffi INDEX value to e */ + be_code_setvar(finfo, &v, &e, bfalse); /* set suffi INDEX value to e */ } static void list_expr(bparser *parser, bexpdesc *e) @@ -791,6 +797,7 @@ static void call_expr(bparser *parser, bexpdesc *e) int argc = 0, base; int ismember = e->type == ETMEMBER; + parser->finfo->binfo->sideeffect = 1; /* has side effect */ /* func '(' [exprlist] ')' */ check_var(parser, e); /* code function index to next register */ @@ -888,8 +895,7 @@ static void primary_expr(bparser *parser, bexpdesc *e) switch (next_type(parser)) { case OptLBK: /* '(' expr ')' */ scan_next_token(parser); /* skip '(' */ - /* sub_expr() is more efficient because there is no need to initialize e. */ - sub_expr(parser, e, ASSIGN_OP_PRIO); + expr(parser, e); check_var(parser, e); match_token(parser, OptRBK); /* skip ')' */ break; @@ -964,9 +970,10 @@ static void suffix_alloc_reg(bparser *parser, bexpdesc *l) bbool is_suffix = l->type == ETINDEX || l->type == ETMEMBER; /* is suffix */ bbool is_suffix_reg = l->v.ss.tt == ETREG || l->v.ss.tt == ETLOCAL || l->v.ss.tt == ETGLOBAL || l->v.ss.tt == ETNGLOBAL; /* if suffix, does it need a register */ bbool is_global = l->type == ETGLOBAL || l->type == ETNGLOBAL; + bbool is_upval = l->type == ETUPVAL; /* in the suffix expression, if the object is a temporary * variable (l->v.ss.tt == ETREG), it needs to be cached. */ - if (is_global || (is_suffix && is_suffix_reg)) { + if (is_global || is_upval || (is_suffix && is_suffix_reg)) { be_code_allocregs(finfo, 1); } } @@ -1025,17 +1032,19 @@ static void assign_expr(bparser *parser) bexpdesc e; btokentype op; int line = parser->lexer.linenumber; + parser->finfo->binfo->sideeffect = 0; /* reinit side effect marker */ expr(parser, &e); /* left expression */ check_symbol(parser, &e); op = get_assign_op(parser); if (op != OP_NOT_ASSIGN) { /* assign operator */ bexpdesc e1; + parser->finfo->binfo->sideeffect = 1; scan_next_token(parser); compound_assign(parser, op, &e, &e1); if (check_newvar(parser, &e)) { /* new variable */ new_var(parser, e.v.s, &e); } - if (be_code_setvar(parser->finfo, &e, &e1)) { + if (be_code_setvar(parser->finfo, &e, &e1, bfalse)) { parser->lexer.linenumber = line; parser_error(parser, "try to assign constant expressions."); @@ -1105,6 +1114,9 @@ static void sub_expr(bparser *parser, bexpdesc *e, int prio) check_var(parser, e); /* check that left part is valid */ scan_next_token(parser); /* move to next token */ be_code_prebinop(finfo, op, e); /* and or */ + if (op == OptConnect) { + parser->finfo->binfo->sideeffect = 1; + } init_exp(&e2, ETVOID, 0); sub_expr(parser, &e2, binary_op_prio(op)); /* parse right side */ if ((e2.type == ETVOID) && (op == OptConnect)) { @@ -1120,13 +1132,36 @@ static void sub_expr(bparser *parser, bexpdesc *e, int prio) } } +static void walrus_expr(bparser *parser, bexpdesc *e) +{ + int line = parser->lexer.linenumber; + sub_expr(parser, e, ASSIGN_OP_PRIO); /* left expression */ + btokentype op = next_type(parser); + if (op == OptWalrus) { + check_symbol(parser, e); + bexpdesc e1 = *e; /* copy var to e1, e will get the result of expression */ + parser->finfo->binfo->sideeffect = 1; /* has side effect */ + scan_next_token(parser); /* skip ':=' */ + expr(parser, e); + check_var(parser, e); + if (check_newvar(parser, &e1)) { /* new variable */ + new_var(parser, e1.v.s, e); + } + if (be_code_setvar(parser->finfo, &e1, e, btrue /* do not release register */ )) { + parser->lexer.linenumber = line; + parser_error(parser, + "try to assign constant expressions."); + } + } +} + /* Parse new expression and return value in `e` (overwritten) */ /* Initializes an empty expdes and parse subexpr */ /* Always allocates a new temp register at top of freereg */ static void expr(bparser *parser, bexpdesc *e) { init_exp(e, ETVOID, 0); - sub_expr(parser, e, ASSIGN_OP_PRIO); + walrus_expr(parser, e); } static void expr_stmt(bparser *parser) @@ -1245,7 +1280,7 @@ static void for_iter(bparser *parser, bstring *var, bexpdesc *it) finfo->binfo->beginpc = finfo->pc; /* itvar = .it() */ init_exp(&e, ETLOCAL, new_localvar(parser, var)); /* new itvar */ - be_code_setvar(finfo, &e, it); /* code function to variable '.it' */ + be_code_setvar(finfo, &e, it, bfalse); /* code function to variable '.it' */ be_code_call(finfo, e.v.idx, 0); /* itvar <- call .it() */ stmtlist(parser); } @@ -1439,7 +1474,7 @@ static void class_static_assignment_expr(bparser *parser, bexpdesc *e, bstring * key.v.s = name; be_code_member(parser->finfo, &e1, &key); /* compute member accessor */ - be_code_setvar(parser->finfo, &e1, &e2); /* set member */ + be_code_setvar(parser->finfo, &e1, &e2, bfalse); /* set member */ } } @@ -1531,7 +1566,25 @@ static void class_stmt(bparser *parser) new_var(parser, name, &e); be_code_class(parser->finfo, &e, c); class_inherit(parser, &e); + + bblockinfo binfo; + begin_block(parser->finfo, &binfo, 0); + + bstring *class_str = parser_newstr(parser, "_class"); /* we always define `_class` local variable */ + if (e.type == ETLOCAL) { + bexpdesc e1; /* if inline class, we add a second local variable for _class */ + init_exp(&e1, ETLOCAL, 0); + e1.v.idx = new_localvar(parser, class_str); + be_code_setvar(parser->finfo, &e1, &e, 1); + } else { /* if global class, we just reuse the newly created class in the register */ + init_exp(&e, ETLOCAL, 0); + e.v.idx = new_localvar(parser, class_str); + } + begin_varinfo(parser, class_str); + class_block(parser, c, &e); + end_block(parser); + be_class_compress(parser->vm, c); /* compress class size */ match_token(parser, KeyEnd); /* skip 'end' */ } else { @@ -1563,7 +1616,7 @@ static void classstaticclass_stmt(bparser *parser, bclass *c_out, bexpdesc *e_ou key.v.s = name; /* assign the class to the static member */ be_code_member(parser->finfo, &e1, &key); /* compute member accessor */ - be_code_setvar(parser->finfo, &e1, &e_class); /* set member */ + be_code_setvar(parser->finfo, &e1, &e_class, bfalse); /* set member */ } else { parser_error(parser, "class name error"); } @@ -1615,7 +1668,7 @@ static void var_field(bparser *parser) init_exp(&e2, ETNIL, 0); } new_var(parser, name, &e1); /* new variable */ - be_code_setvar(parser->finfo, &e1, &e2); + be_code_setvar(parser->finfo, &e1, &e2, bfalse); } static void var_stmt(bparser *parser) @@ -1731,6 +1784,9 @@ static void throw_stmt(bparser *parser) static void statement(bparser *parser) { + /* save value of sideeffect */ + bbyte sideeffect = parser->finfo->binfo->sideeffect; + parser->finfo->binfo->sideeffect = 1; /* by default declare side effect */ switch (next_type(parser)) { case KeyIf: if_stmt(parser); break; case KeyWhile: while_stmt(parser); break; @@ -1745,8 +1801,16 @@ static void statement(bparser *parser) case KeyVar: var_stmt(parser); break; case KeyTry: try_stmt(parser); break; case KeyRaise: throw_stmt(parser); break; - case OptSemic: scan_next_token(parser); break; /* empty statement */ - default: expr_stmt(parser); break; + case OptSemic: + parser->finfo->binfo->sideeffect = sideeffect; /* restore sideeffect */ + scan_next_token(parser); break; /* empty statement */ + default: + parser->finfo->binfo->sideeffect = sideeffect; /* restore sideeffect */ + expr_stmt(parser); + if (comp_is_strict(parser->vm) && parser->finfo->binfo->sideeffect == 0) { + push_error(parser, "strict: expression without side effect detected"); + } + break; } be_assert(parser->finfo->freereg >= be_list_count(parser->finfo->local)); } diff --git a/lib/libesp32/berry/src/be_parser.h b/lib/libesp32/berry/src/be_parser.h index 5b5510f2ceaa..8498bfa996e5 100644 --- a/lib/libesp32/berry/src/be_parser.h +++ b/lib/libesp32/berry/src/be_parser.h @@ -53,6 +53,7 @@ typedef struct bblockinfo { bbyte nactlocals; /* number of active local variables */ bbyte type; /* block type mask */ bbyte hasupval; /* has upvalue mark */ + bbyte sideeffect; /* did the last expr/statement had a side effect */ int breaklist; /* break list */ int beginpc; /* begin pc */ int continuelist; /* continue list */ diff --git a/lib/libesp32/berry/src/be_rangelib.c b/lib/libesp32/berry/src/be_rangelib.c index 3682ae3ceb6f..187807021205 100644 --- a/lib/libesp32/berry/src/be_rangelib.c +++ b/lib/libesp32/berry/src/be_rangelib.c @@ -11,31 +11,70 @@ static int m_init(bvm *vm) { + int argc = be_top(vm); + if (argc < 3) { be_raise(vm, "value_error", "missing arguments"); } + if (!be_isint(vm, 2) || !be_isint(vm, 3)) { be_raise(vm, "value_error", "arguments must be 'int'"); } be_pushvalue(vm, 2); be_setmember(vm, 1, "__lower__"); be_pop(vm, 1); be_pushvalue(vm, 3); be_setmember(vm, 1, "__upper__"); + int incr = 1; /* default increment is '1' */ + if (argc >= 4) { + if (!be_isint(vm, 4)) { be_raise(vm, "value_error", "arguments must be 'int'"); } + incr = be_toint(vm, 4); + if (incr == 0) { be_raise(vm, "value_error", "increment cannot be zero"); } + } + be_pushint(vm, incr); + be_setmember(vm, 1, "__incr__"); be_return_nil(vm); } static int m_tostring(bvm *vm) { - be_pushstring(vm, "("); - be_getmember(vm, 1, "__lower__"); - be_tostring(vm, -1); - be_strconcat(vm, -2); - be_pop(vm, 1); - be_pushstring(vm, ".."); - be_strconcat(vm, -2); - be_pop(vm, 1); - be_getmember(vm, 1, "__upper__"); - be_tostring(vm, -1); - be_strconcat(vm, -2); - be_pop(vm, 1); - be_pushstring(vm, ")"); - be_strconcat(vm, -2); + be_getmember(vm, 1, "__incr__"); + int incr = be_toint(vm, -1); be_pop(vm, 1); + if (incr == 1) { + be_pushstring(vm, "("); + be_getmember(vm, 1, "__lower__"); + be_tostring(vm, -1); + be_strconcat(vm, -2); + be_pop(vm, 1); + be_pushstring(vm, ".."); + be_strconcat(vm, -2); + be_pop(vm, 1); + be_getmember(vm, 1, "__upper__"); + be_tostring(vm, -1); + be_strconcat(vm, -2); + be_pop(vm, 1); + be_pushstring(vm, ")"); + be_strconcat(vm, -2); + be_pop(vm, 1); + } else { + be_pushstring(vm, "range("); + be_getmember(vm, 1, "__lower__"); + be_tostring(vm, -1); + be_strconcat(vm, -2); + be_pop(vm, 1); + be_pushstring(vm, ", "); + be_strconcat(vm, -2); + be_pop(vm, 1); + be_getmember(vm, 1, "__upper__"); + be_tostring(vm, -1); + be_strconcat(vm, -2); + be_pop(vm, 1); + be_pushstring(vm, ", "); + be_strconcat(vm, -2); + be_pop(vm, 1); + be_getmember(vm, 1, "__incr__"); + be_tostring(vm, -1); + be_strconcat(vm, -2); + be_pop(vm, 1); + be_pushstring(vm, ")"); + be_strconcat(vm, -2); + be_pop(vm, 1); + } be_return(vm); } @@ -51,13 +90,30 @@ static int m_lower(bvm *vm) be_return(vm); } +static int m_incr(bvm *vm) +{ + be_getmember(vm, 1, "__incr__"); + be_return(vm); +} + static int m_setrange(bvm *vm) { + int argc = be_top(vm); + if (argc < 3) { be_raise(vm, "value_error", "missing arguments"); } + if (!be_isint(vm, 2) || !be_isint(vm, 3)) { be_raise(vm, "value_error", "arguments must be 'int'"); } be_pushvalue(vm, 2); be_setmember(vm, 1, "__lower__"); be_pop(vm, 1); be_pushvalue(vm, 3); be_setmember(vm, 1, "__upper__"); + int incr = 1; /* default increment is '1' */ + if (argc >= 4) { + if (!be_isint(vm, 4)) { be_raise(vm, "value_error", "arguments must be 'int'"); } + incr = be_toint(vm, 4); + if (incr == 0) { be_raise(vm, "value_error", "increment cannot be zero"); } + } + be_pushint(vm, incr); + be_setmember(vm, 1, "__incr__"); be_return_nil(vm); } @@ -68,25 +124,30 @@ static int iter_closure(bvm *vm) bntvclos *func = var_toobj(vm->cf->func); bvalue *uv0 = be_ntvclos_upval(func, 0)->value; bvalue *uv1 = be_ntvclos_upval(func, 1)->value; + bvalue *uv2 = be_ntvclos_upval(func, 2)->value; bint lower = var_toint(uv0); /* upvalue[0] => lower */ bint upper = var_toint(uv1); /* upvalue[1] => upper */ - if (lower > upper) { + bint incr = var_toint(uv2); /* upvalue[2] => incr */ + if ((incr > 0 && lower > upper) || (incr < 0 && lower < upper)) { be_stop_iteration(vm); } - var_toint(uv0) = lower + 1; /* set upvale[0] */ + var_toint(uv0) = lower + incr; /* set upvale[0] */ be_pushint(vm, lower); /* push the return value */ be_return(vm); } static int m_iter(bvm *vm) { - be_pushntvclosure(vm, iter_closure, 2); + be_pushntvclosure(vm, iter_closure, 3); be_getmember(vm, 1, "__lower__"); be_setupval(vm, -2, 0); be_pop(vm, 1); be_getmember(vm, 1, "__upper__"); be_setupval(vm, -2, 1); be_pop(vm, 1); + be_getmember(vm, 1, "__incr__"); + be_setupval(vm, -2, 2); + be_pop(vm, 1); be_return(vm); } @@ -96,6 +157,7 @@ void be_load_rangelib(bvm *vm) static const bnfuncinfo members[] = { { "__lower__", NULL }, { "__upper__", NULL }, + { "__incr__", NULL }, { "init", m_init }, { "tostring", m_tostring }, { "lower", m_lower }, @@ -111,10 +173,12 @@ void be_load_rangelib(bvm *vm) class be_class_range (scope: global, name: range) { __lower__, var __upper__, var + __incr__, var init, func(m_init) tostring, func(m_tostring) lower, func(m_lower) upper, func(m_upper) + incr, func(m_incr) setrange, func(m_setrange) iter, func(m_iter) } diff --git a/lib/libesp32/berry/src/be_solidifylib.c b/lib/libesp32/berry/src/be_solidifylib.c index ed3cea94831c..b0164ddbac17 100644 --- a/lib/libesp32/berry/src/be_solidifylib.c +++ b/lib/libesp32/berry/src/be_solidifylib.c @@ -31,7 +31,7 @@ extern const bclass be_class_map; be_vector_count(&(vm)->gbldesc.builtin.vlist) #ifndef INST_BUF_SIZE -#define INST_BUF_SIZE 288 +#define INST_BUF_SIZE 768 #endif #define logfmt(...) \ diff --git a/lib/libesp32/berry/src/be_strlib.c b/lib/libesp32/berry/src/be_strlib.c index 2c5424634d5a..a52b8b670496 100644 --- a/lib/libesp32/berry/src/be_strlib.c +++ b/lib/libesp32/berry/src/be_strlib.c @@ -12,6 +12,7 @@ #include "be_module.h" #include "be_exec.h" #include "be_mem.h" +#include "be_baselib.h" #include #include #include @@ -51,22 +52,22 @@ bstring* be_num2str(bvm *vm, bvalue *v) { char buf[25]; if (var_isint(v)) { - sprintf(buf, BE_INT_FORMAT, var_toint(v)); + snprintf(buf, sizeof(buf),BE_INT_FORMAT, var_toint(v)); } else if (var_isreal(v)) { - sprintf(buf, "%g", var_toreal(v)); + snprintf(buf, sizeof(buf), "%g", var_toreal(v)); } else { - sprintf(buf, "(nan)"); + snprintf(buf, sizeof(buf), "(nan)"); } return be_newstr(vm, buf); } -static void module2str(char *buf, bvalue *v) +static void module2str(char *buf, size_t buf_len, bvalue *v) { const char *name = be_module_name(cast(bmodule*, var_toobj(v))); if (name) { - sprintf(buf, "", name); + snprintf(buf, buf_len, "", name); } else { - sprintf(buf, "", var_toobj(v)); + snprintf(buf, buf_len, "", var_toobj(v)); } } @@ -82,26 +83,26 @@ static bstring* sim2str(bvm *vm, bvalue *v) break; case BE_INDEX: case BE_INT: - sprintf(sbuf, BE_INT_FORMAT, var_toint(v)); + snprintf(sbuf, sizeof(sbuf), BE_INT_FORMAT, var_toint(v)); break; case BE_REAL: - sprintf(sbuf, "%g", var_toreal(v)); + snprintf(sbuf, sizeof(sbuf), "%g", var_toreal(v)); break; case BE_CLOSURE: case BE_NTVCLOS: case BE_NTVFUNC: case BE_CTYPE_FUNC: - sprintf(sbuf, "", var_toobj(v)); + snprintf(sbuf, sizeof(sbuf), "", var_toobj(v)); break; case BE_CLASS: - sprintf(sbuf, "", + snprintf(sbuf, sizeof(sbuf), "", str(be_class_name(cast(bclass*, var_toobj(v))))); break; case BE_MODULE: - module2str(sbuf, v); + module2str(sbuf, sizeof(sbuf), v); break; case BE_COMPTR: - sprintf(sbuf, "", var_toobj(v)); + snprintf(sbuf, sizeof(sbuf), "", var_toobj(v)); break; default: - strcpy(sbuf, "(unknown value)"); + strncpy(sbuf, "(unknown value)", sizeof(sbuf)); break; } return be_newstr(vm, sbuf); @@ -116,8 +117,10 @@ static bstring* ins2str(bvm *vm, int idx) be_incrtop(vm); /* push the obj::tostring to stack */ if (basetype(type) != BE_FUNCTION) { bstring *name = be_class_name(be_instance_class(obj)); - char *sbuf = be_malloc(vm, (size_t)str_len(name) + 16); - sprintf(sbuf, "", str(name)); + size_t buf_len = (size_t) str_len(name) + 16; + char *sbuf = be_malloc(vm, buf_len); + /* TODO what if sbuf cannot be allocated */ + snprintf(sbuf, buf_len, "", str(name)); be_stackpop(vm, 1); /* pop the obj::tostring */ s = be_newstr(vm, sbuf); be_free(vm, sbuf, (size_t)str_len(name) + 16); @@ -216,7 +219,7 @@ const char* be_pushvfstr(bvm *vm, const char *format, va_list arg) } case 'p': { char buf[2 * sizeof(void*) + 4]; - sprintf(buf, "%p", va_arg(arg, void*)); + snprintf(buf, sizeof(buf), "%p", va_arg(arg, void*)); pushstr(vm, buf, strlen(buf)); break; } @@ -556,7 +559,49 @@ static void mode_fixlen(char *mode, const char *lenmode) mode[l + lm] = '\0'; } -static int str_format(bvm *vm) +static bbool convert_to_int(bvm *vm, int index, bint *val) +{ + bbool converted = bfalse; + if (val == NULL) { return bfalse; } + if (be_isint(vm, index)) { + *val = be_toint(vm, index); + converted = btrue; + } else { + be_pushntvfunction(vm, be_baselib_int); + be_pushvalue(vm, index); + be_call(vm, 1); + be_pop(vm, 1); + if (be_isint(vm, -1)) { + *val = be_toint(vm, -1); + converted = btrue; + } + be_pop(vm, 1); + } + return converted; +} + +static bbool convert_to_real(bvm *vm, int index, breal *val) +{ + bbool converted = bfalse; + if (val == NULL) { return bfalse; } + if (be_isnumber(vm, index)) { + *val = be_toreal(vm, index); + converted = btrue; + } else { + be_pushntvfunction(vm, be_baselib_real); + be_pushvalue(vm, index); + be_call(vm, 1); + be_pop(vm, 1); + if (be_isnumber(vm, -1)) { + *val = be_toreal(vm, -1); + converted = btrue; + } + be_pop(vm, 1); + } + return converted; +} + +int be_str_format(bvm *vm) { int top = be_top(vm); if (top > 0 && be_isstring(vm, 1)) { @@ -585,32 +630,41 @@ static int str_format(bvm *vm) break; case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': - if (be_isint(vm, index)) { + { + bint val; + if (convert_to_int(vm, index, &val)) { mode_fixlen(mode, BE_INT_FMTLEN); - sprintf(buf, mode, be_toint(vm, index)); + snprintf(buf, sizeof(buf), mode, val); } be_pushstring(vm, buf); break; + } case 'e': case 'E': case 'f': case 'g': case 'G': - if (be_isnumber(vm, index)) { - sprintf(buf, mode, be_toreal(vm, index)); + { + breal val; + if (convert_to_real(vm, index, &val)) { + snprintf(buf, sizeof(buf), mode, val); } be_pushstring(vm, buf); break; + } case 'c': - if (be_isint(vm, index)) { - sprintf(buf, "%c", (int)be_toint(vm, index)); + { + bint val; + if (convert_to_int(vm, index, &val)) { + snprintf(buf, sizeof(buf), "%c", (int)val); } be_pushstring(vm, buf); break; + } case 's': { const char *s = be_tostring(vm, index); int len = be_strlen(vm, index); if (len > 100 && strlen(mode) == 2) { be_pushvalue(vm, index); } else { - sprintf(buf, mode, s); + snprintf(buf, sizeof(buf), mode, s); be_pushstring(vm, buf); } break; @@ -758,10 +812,10 @@ static int str_i2hex(bvm *vm) if (top >= 2 && be_isint(vm, 2)) { bint num = be_toint(vm, 2); if (num > 0 && num <= 16) { - sprintf(fmt, "%%.%d" BE_INT_FMTLEN "X", (int)num); + snprintf(fmt, sizeof(fmt), "%%.%d" BE_INT_FMTLEN "X", (int)num); } } - sprintf(buf, fmt, value); + snprintf(buf, sizeof(buf), fmt, value); be_pushstring(vm, buf); be_return(vm); } @@ -888,7 +942,7 @@ static int str_escape(bvm *vm) #if !BE_USE_PRECOMPILED_OBJECT be_native_module_attr_table(string) { - be_native_module_function("format", str_format), + be_native_module_function("format", be_str_format), be_native_module_function("count", str_count), be_native_module_function("split", str_split), be_native_module_function("find", str_find), @@ -906,7 +960,7 @@ be_define_native_module(string, NULL); #else /* @const_object_info_begin module string (scope: global, depend: BE_USE_STRING_MODULE) { - format, func(str_format) + format, func(be_str_format) count, func(str_count) split, func(str_split) find, func(str_find) diff --git a/lib/libesp32/berry/src/be_strlib.h b/lib/libesp32/berry/src/be_strlib.h index 703fce0548ab..093c37c63877 100644 --- a/lib/libesp32/berry/src/be_strlib.h +++ b/lib/libesp32/berry/src/be_strlib.h @@ -25,6 +25,7 @@ const char* be_splitpath(const char *path); const char* be_splitname(const char *path); const char* be_pushvfstr(bvm *vm, const char *format, va_list arg); bstring* be_strindex(bvm *vm, bstring *str, bvalue *idx); +int be_str_format(bvm *vm); #ifdef __cplusplus } diff --git a/lib/libesp32/berry/src/be_vector.h b/lib/libesp32/berry/src/be_vector.h index 3991986ca355..15f399cc6378 100644 --- a/lib/libesp32/berry/src/be_vector.h +++ b/lib/libesp32/berry/src/be_vector.h @@ -38,7 +38,6 @@ void be_vector_remove_end(bvector *vector); void be_vector_resize(bvm *vm, bvector *vector, int count); void be_vector_clear(bvector *vector); void* be_vector_release(bvm *vm, bvector *vector); -void* be_vector_release_32(bvm *vm, bvector *vector); /* specialized call for 32 bits aligned accesses */ int be_nextsize(int value); #endif diff --git a/lib/libesp32/berry/src/be_vm.c b/lib/libesp32/berry/src/be_vm.c index eb2b6ef63628..b234308d0ce8 100644 --- a/lib/libesp32/berry/src/be_vm.c +++ b/lib/libesp32/berry/src/be_vm.c @@ -507,10 +507,14 @@ BERRY_API bvm* be_vm_new(void) vm->counter_call = 0; vm->counter_get = 0; vm->counter_set = 0; + vm->counter_get_global = 0; vm->counter_try = 0; vm->counter_exc = 0; vm->counter_gc_kept = 0; vm->counter_gc_freed = 0; + vm->counter_mem_alloc = 0; + vm->counter_mem_free = 0; + vm->counter_mem_realloc = 0; #endif return vm; } @@ -579,6 +583,9 @@ static void vm_exec(bvm *vm) dispatch(); } opcase(GETNGBL): { /* get Global by name */ +#if BE_USE_PERF_COUNTERS + vm->counter_get_global++; +#endif bvalue *v = RA(); bvalue *b = RKB(); if (var_isstr(b)) { diff --git a/lib/libesp32/berry/src/be_vm.h b/lib/libesp32/berry/src/be_vm.h index 1e83c912fffe..ba05579bfef4 100644 --- a/lib/libesp32/berry/src/be_vm.h +++ b/lib/libesp32/berry/src/be_vm.h @@ -114,10 +114,14 @@ struct bvm { uint32_t counter_call; /* counter for calls, VM or native */ uint32_t counter_get; /* counter for GETMBR or GETMET */ uint32_t counter_set; /* counter for SETMBR */ + uint32_t counter_get_global; /* counter for GETNBGL */ uint32_t counter_try; /* counter for `try` statement */ uint32_t counter_exc; /* counter for raised exceptions */ uint32_t counter_gc_kept; /* counter for objects scanned by last gc */ uint32_t counter_gc_freed; /* counter for objects freed by last gc */ + uint32_t counter_mem_alloc; /* counter for memory allocations */ + uint32_t counter_mem_free; /* counter for memory frees */ + uint32_t counter_mem_realloc; /* counter for memory reallocations */ uint32_t micros_gc0; uint32_t micros_gc1; diff --git a/lib/libesp32/berry/src/berry.h b/lib/libesp32/berry/src/berry.h index 1a99b9190261..962a01ebbdbc 100644 --- a/lib/libesp32/berry/src/berry.h +++ b/lib/libesp32/berry/src/berry.h @@ -477,6 +477,21 @@ typedef bclass_ptr bclass_array[]; #define be_local_const_upval(ins, idx) { ins, idx } #endif +/** + * @def BE_DEBUG_SOURCE_FILE + * @brief conditional block in bproto depending on compilation options + * + */ +#if BE_DEBUG_SOURCE_FILE + #define PROTO_SOURCE_FILE(n) \ + ((bstring*) n), /**< source */ + #define PROTO_SOURCE_FILE_STR(n) \ + be_local_const_str(n##_str_source), /**< source */ +#else + #define PROTO_SOURCE_FILE(n) + #define PROTO_SOURCE_FILE_STR(n) +#endif + /** * @def PROTO_RUNTIME_BLOCK * @brief conditional block in bproto depending on compilation options @@ -484,8 +499,8 @@ typedef bclass_ptr bclass_array[]; */ #if BE_DEBUG_RUNTIME_INFO #define PROTO_RUNTIME_BLOCK \ - NULL, /**< varinfo */ \ - 0, /**< nvarinfo */ + NULL, /**< lineinfo */ \ + 0, /**< nlineinfo */ #else #define PROTO_RUNTIME_BLOCK #endif @@ -517,16 +532,16 @@ typedef bclass_ptr bclass_array[]; BE_IIF(_is_upval)(sizeof(_name##_upvals)/sizeof(bupvaldesc),0), /**< nupvals */ \ (_argc), /**< argc */ \ 0, /**< varg */ \ + sizeof(_name##_code)/sizeof(uint32_t), /**< codesize */ \ + BE_IIF(_is_const)(sizeof(_name##_ktab)/sizeof(bvalue),0), /**< nconst */ \ + BE_IIF(_is_subproto)(sizeof(_name##_subproto)/sizeof(bproto*),0), /**< proto */ \ NULL, /**< bgcobject *gray */ \ BE_IIF(_is_upval)((bupvaldesc*)&_name##_upvals,NULL), /**< bupvaldesc *upvals */ \ BE_IIF(_is_const)((bvalue*)&_name##_ktab,NULL), /**< ktab */ \ BE_IIF(_is_subproto)((struct bproto**)&_name##_subproto,NULL), /**< bproto **ptab */ \ (binstruction*) &_name##_code, /**< code */ \ be_local_const_str(_name##_str_name), /**< name */ \ - sizeof(_name##_code)/sizeof(uint32_t), /**< codesize */ \ - BE_IIF(_is_const)(sizeof(_name##_ktab)/sizeof(bvalue),0), /**< nconst */ \ - BE_IIF(_is_subproto)(sizeof(_name##_subproto)/sizeof(bproto*),0), /**< proto */ \ - be_local_const_str(_name##_str_source), /**< source */ \ + PROTO_SOURCE_FILE_STR(_name) /**< source */ \ PROTO_RUNTIME_BLOCK /**< */ \ PROTO_VAR_INFO_BLOCK /**< */ \ } @@ -545,16 +560,16 @@ typedef bclass_ptr bclass_array[]; BE_IIF(_has_upval)(sizeof(*_upvals)/sizeof(bupvaldesc),0), /**< nupvals */ \ (_argc), /**< argc */ \ (_varg), /**< varg */ \ + sizeof(*_code)/sizeof(binstruction), /**< codesize */ \ + BE_IIF(_has_const)(sizeof(*_ktab)/sizeof(bvalue),0), /**< nconst */ \ + BE_IIF(_has_subproto)(sizeof(*_protos)/sizeof(bproto*),0), /**< proto */ \ NULL, /**< bgcobject *gray */ \ (bupvaldesc*) _upvals, /**< bupvaldesc *upvals */ \ (bvalue*) _ktab, /**< ktab */ \ (struct bproto**) _protos, /**< bproto **ptab */ \ (binstruction*) _code, /**< code */ \ ((bstring*) _fname), /**< name */ \ - sizeof(*_code)/sizeof(binstruction), /**< codesize */ \ - BE_IIF(_has_const)(sizeof(*_ktab)/sizeof(bvalue),0), /**< nconst */ \ - BE_IIF(_has_subproto)(sizeof(*_protos)/sizeof(bproto*),0), /**< proto */ \ - ((bstring*) _source), /**< source */ \ + PROTO_SOURCE_FILE(_source) /**< source */ \ PROTO_RUNTIME_BLOCK /**< */ \ PROTO_VAR_INFO_BLOCK /**< */ \ } @@ -2050,7 +2065,9 @@ BERRY_API void be_exit(bvm *vm, int status); * @param except * @param msg */ +#ifdef __GNUC__ __attribute__((noreturn)) +#endif BERRY_API void be_raise(bvm *vm, const char *except, const char *msg); /** diff --git a/lib/libesp32/berry/tests/bool.be b/lib/libesp32/berry/tests/bool.be index ac5a69ab5f96..b0323c3df197 100644 --- a/lib/libesp32/berry/tests/bool.be +++ b/lib/libesp32/berry/tests/bool.be @@ -36,7 +36,13 @@ assert(bool(3.5) == true) assert(bool('') == false) # changed behavior assert(bool('a') == true) assert(bool(list) == true) -assert(bool(list()) == true) +assert(bool(list()) == false) # changed behavior +assert(bool([]) == false) # changed behavior +assert(bool([0]) == true) +assert(bool(map()) == false) # changed behavior +assert(bool({}) == false) # changed behavior +assert(bool({false:false}) == true) +assert(bool({nil:nil}) == false)# changed behavior - `nil` key is ignored so the map is empty import introspect assert(bool(introspect.toptr(0x1000)) == true) diff --git a/lib/libesp32/berry/tests/class_static.be b/lib/libesp32/berry/tests/class_static.be index 1b3d0f9282bf..dbe8c222e3f3 100644 --- a/lib/libesp32/berry/tests/class_static.be +++ b/lib/libesp32/berry/tests/class_static.be @@ -140,4 +140,18 @@ assert(classname(a) == 'A') assert(classname(b) == 'B') assert(A.B.f() == 1) assert(b.g() == 2) -assert(super(B) == nil) +assert(super(A.B) == nil) + +#- `_class` initializer can now be used in initializer code -# +class A + static var a = 1 + static var b = _class + static var c = [_class.a, _class.b] + static def f(x) + return _class + end +end +assert(A.a == 1) +assert(A.b == A) +assert(A.c == [1, A]) +assert(A.f(1) == A) diff --git a/lib/libesp32/berry/tests/closure.be b/lib/libesp32/berry/tests/closure.be index 2474fede9d48..757c2a94450c 100644 --- a/lib/libesp32/berry/tests/closure.be +++ b/lib/libesp32/berry/tests/closure.be @@ -11,3 +11,6 @@ tick() assert(l[0]() == [1, 100]) assert(l[1]() == [2, 100]) assert(l[2]() == [3, 100]) + +# the following failed to compile #344 +def test() var nv = 1 var f = def() nv += 2*1 print(nv) end end diff --git a/lib/libesp32/berry/tests/range.be b/lib/libesp32/berry/tests/range.be new file mode 100644 index 000000000000..08b5add8d8fa --- /dev/null +++ b/lib/libesp32/berry/tests/range.be @@ -0,0 +1,39 @@ +# test for ranges + +# expand a range object as list +def expand(iter) + var ret = [] + for i: iter + ret.push(i) + end + return ret +end + +assert(expand(0..5) == [0, 1, 2, 3, 4, 5]) +assert(expand(0..0) == [0]) +assert(expand(5..0) == []) +var r = 1..5 +assert(r.lower() == 1) +assert(r.upper() == 5) +assert(r.incr() == 1) + +assert(expand(range(0,5)) == [0, 1, 2, 3, 4, 5]) +assert(expand(range(0,5,2)) == [0, 2, 4]) +assert(expand(range(0,5,12)) == [0]) +assert(expand(range(0,5,-1)) == []) + +assert(expand(range(5,0,-1)) == [5, 4, 3, 2, 1, 0]) +assert(expand(range(5,0,-2)) == [5, 3, 1]) +assert(expand(range(5,5,-2)) == [5]) +assert(expand(range(0,5,-2)) == []) + +def assert_value_error(c) + try + compile(c)() + assert(false, 'unexpected execution flow') + except 'value_error' as e, m + end +end + +# range with increment zero shoud raise an error +assert_value_error("range(1,2,0)") diff --git a/lib/libesp32/berry/tests/string.be b/lib/libesp32/berry/tests/string.be index aeb0d0ad5eb6..82f8244515b8 100644 --- a/lib/libesp32/berry/tests/string.be +++ b/lib/libesp32/berry/tests/string.be @@ -88,3 +88,84 @@ assert(string.replace("hellollo", "aa", "xx") == "hellollo") assert(string.replace("hello", "ll", "") == "heo") assert(string.replace("hello", "", "xx") == "hello") assert(string.replace("hello", "", "") == "hello") + +# multi-line strings +var s = "a" "b""c" +assert(s == 'abc') + +s = 'a'"b"'''c' +assert(s == 'abc') + +s = "a" +'b' + "" + "c" +assert(s == 'abc') + +s = "a" #- b -# "b" #--# "c" +assert(s == 'abc') + +s = "a"# + # "z" + "b" # zz + "c" +assert(s == 'abc') + +# string.format with automatic conversion +import string + +assert(string.format("%i", 3) == '3') +assert(string.format("%i", "3") == '3') +assert(string.format("%i", "03") == '3') +assert(string.format("%i", nil) == '') + +class A def toint() return 42 end end +a=A() +class B end +b=B() + +assert(string.format("%i", a) == '42') +assert(string.format("%i", b) == '') + +assert(string.format("%i", nil) == '') +assert(string.format("%i", true) == '1') +assert(string.format("%i", false) == '0') + +assert(string.format("%c", a) == '*') + +assert(string.format("%f", 3.5) == '3.500000') +assert(string.format("%f", 3) == '3.000000') +assert(string.format("%.1f", 3) == '3.0') +assert(string.format("%.1f", nil) == '') +assert(string.format("%.1f", true) == '') +assert(string.format("%.1f", false) == '') +assert(string.format("%.1f", a) == '') + +assert(string.format("%s", a) == '') +assert(string.format("%s", 0) == '0') +assert(string.format("%s", nil) == 'nil') +assert(string.format("%s", true) == 'true') +assert(string.format("%s", false) == 'false') + +# format is now synonym to string.format +assert(format == string.format) +assert(format("%.1f", 3) == '3.0') + +# f-strings +assert(f"" == '') +assert(f'' == '') +assert(f"abc\n\r\t" == 'abc\n\r\t') +assert(f'{{a}}' == '{a}') +assert(f'\\\\' == '\\\\') + +assert(f"A = {1+1}" == 'A = 2') +assert(f"A = {1+1:s}" == 'A = 2') +assert(f"A = {1+1:i}" == 'A = 2') +assert(f"A = {1+1:04i}" == 'A = 0002') + +assert(f"P = {3.1415:.2f}" == 'P = 3.14') + +var a = 'foobar{0}' +assert(f"S = {a}" == 'S = foobar{0}') +assert(f"S = {a:i}" == 'S = 0') +assert(f"{a=}" == 'a=foobar{0}') diff --git a/lib/libesp32/berry/tests/walrus.be b/lib/libesp32/berry/tests/walrus.be new file mode 100644 index 000000000000..faa92fa15e10 --- /dev/null +++ b/lib/libesp32/berry/tests/walrus.be @@ -0,0 +1,35 @@ +# test for the walrus operator +var a = 1 +assert((a := a + 1) == 2) +assert((a := a + 1) == 3) + +def f() + var defer = 10 + var ret = [] + for i:0..100 + if (defer := defer - 1) == 0 + ret.push(i) + defer = 10 + end + end + return ret +end +assert(f() == [9, 19, 29, 39, 49, 59, 69, 79, 89, 99]) + +# test for expressions with no side effects +def assert_attribute_error(c) + try + compile(c)() + assert(false, 'unexpected execution flow') + except 'syntax_error' as e, m + end +end + +# below the expressions `a` or `a b` have no side effect and do not generate any code, this is an error when in strict mode +import strict +var a, b +assert_attribute_error("var a,b def f() a b end") +assert_attribute_error("var a,b def f() a end") + +# while the following does have side effect +def f() a := b end diff --git a/lib/libesp32/berry/tools/coc/block_builder.py b/lib/libesp32/berry/tools/coc/block_builder.py index 2d76465df455..6535fd40be46 100644 --- a/lib/libesp32/berry/tools/coc/block_builder.py +++ b/lib/libesp32/berry/tools/coc/block_builder.py @@ -159,7 +159,7 @@ def name(self, block): def writefile(self, filename, text): otext = "#include \"be_constobj.h\"\n\n" + text - with open(filename, "w") as f: + with open(filename, "w", encoding='utf-8') as f: f.write(otext) def dumpfile(self, path): diff --git a/lib/libesp32/berry/tools/coc/coc b/lib/libesp32/berry/tools/coc/coc index 2111b1ea27d0..1a12c01e6afc 100755 --- a/lib/libesp32/berry/tools/coc/coc +++ b/lib/libesp32/berry/tools/coc/coc @@ -34,7 +34,7 @@ class builder: if re.search(r"\.(h|c|cc|cpp)$", filename): # print(f"> parse {filename}") text = "" - with open(filename) as f: + with open(filename, encoding='utf-8') as f: text = f.read() # print(f"> len(text)={len(text)}") parser = coc_parser(text) diff --git a/lib/libesp32/berry/tools/coc/macro_table.py b/lib/libesp32/berry/tools/coc/macro_table.py index 8b4518ddc955..de741040e11f 100644 --- a/lib/libesp32/berry/tools/coc/macro_table.py +++ b/lib/libesp32/berry/tools/coc/macro_table.py @@ -22,7 +22,7 @@ def parse_value(self, s): def scan_file(self, filename): str = "" - with open(filename) as f: + with open(filename, encoding='utf-8') as f: str = f.read() r = macro_table.pat.findall(str) for it in r: diff --git a/lib/libesp32/berry/tools/grammar/berry.ebnf b/lib/libesp32/berry/tools/grammar/berry.ebnf index 1b387ae0ddcf..86eef9b58206 100644 --- a/lib/libesp32/berry/tools/grammar/berry.ebnf +++ b/lib/libesp32/berry/tools/grammar/berry.ebnf @@ -5,9 +5,10 @@ block = {statement}; (* statement define *) statement = class_stmt | func_stmt | var_stmt | if_stmt | while_stmt | for_stmt | break_stmt | return_stmt | expr_stmt | import_stmt | - try_stmt | throw_stmt | ';'; + try_stmt | throw_stmt | do_stmt | ';'; if_stmt = 'if' expr block {'elif' expr block} ['else' block] 'end'; while_stmt = 'while' expr block 'end'; +do_stmt = 'do' block 'end'; for_stmt = 'for' ID ':' expr block 'end'; break_stmt = 'break' | 'continue'; return_stmt = 'return' [expr]; @@ -28,7 +29,7 @@ throw_stmt = 'raise' expr [',' expr]; var_stmt = 'var' ID ['=' expr] {',' ID ['=' expr]}; (* expression define *) expr_stmt = expr [assign_op expr]; -expr = suffix_expr | unop expr | expr binop expr | range_expr | cond_expr; +expr = suffix_expr | unop expr | expr binop expr | range_expr | cond_expr | walrus_expr; cond_expr = expr '?' expr ':' expr; (* conditional expression *) assign_op = '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>='; @@ -36,9 +37,11 @@ binop = '<' | '<=' | '==' | '!=' | '>' | '>=' | '||' | '&&' | '<<' | '>>' | '&' | '|' | '^' | '+' | '-' | '*' | '/' | '%'; range_expr = expr '..' [expr] unop = '-' | '!' | '~'; +walrus_expr = expr ':=' expr suffix_expr = primary_expr {call_expr | ('.' ID) | '[' expr ']'}; primary_expr = '(' expr ')' | simple_expr | list_expr | map_expr | anon_func | lambda_expr; -simple_expr = INTEGER | REAL | STRING | ID | 'true' | 'false' | 'nil'; +simple_expr = INTEGER | REAL | STRING | ID | 'true' | 'false' | 'nil' | f_string; +f_string = 'f' STRING call_expr = '(' [expr {',' expr}] ')'; list_expr = '[' {expr ','} [expr] ']'; map_expr = '{' {expr ':' expr ','} [expr ':' expr] '}'; diff --git a/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/.vsixmanifest b/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/.vsixmanifest similarity index 100% rename from lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/.vsixmanifest rename to lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/.vsixmanifest diff --git a/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/CHANGELOG.md b/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/CHANGELOG.md similarity index 73% rename from lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/CHANGELOG.md rename to lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/CHANGELOG.md index 6f51bbccafba..2867fd3abd7e 100755 --- a/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/CHANGELOG.md +++ b/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/CHANGELOG.md @@ -4,4 +4,5 @@ All notable changes to the "none" extension will be documented in this file. Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. ## [Unreleased] -- Initial release \ No newline at end of file +- Initial release +- add support for f-strings, `_class` and indent on `do` diff --git a/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/README.md b/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/README.md similarity index 100% rename from lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/README.md rename to lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/README.md diff --git a/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-configuration.json b/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/berry-configuration.json similarity index 93% rename from lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-configuration.json rename to lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/berry-configuration.json index 4be01969f8f6..50dde1c39836 100755 --- a/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-configuration.json +++ b/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/berry-configuration.json @@ -26,7 +26,7 @@ ["'", "'"] ], "indentationRules": { - "increaseIndentPattern": "(^((\\s*(class|while|for|if|elif|else|try|except))|(.*\\bdef))\\b((?!\\b(end)\\b).)*)$", + "increaseIndentPattern": "(^((\\s*(class|while|for|if|elif|else|try|except|do))|(.*\\bdef))\\b((?!\\b(end)\\b).)*)$", "decreaseIndentPattern": "^\\s*((\\b(elif|else|except|end)\\b)|(\\)))" } } \ No newline at end of file diff --git a/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-icon.png b/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/berry-icon.png similarity index 100% rename from lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/berry-icon.png rename to lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/berry-icon.png diff --git a/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/package.json b/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/package.json similarity index 98% rename from lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/package.json rename to lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/package.json index 1f206315b536..6837eb54e31f 100755 --- a/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/package.json +++ b/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/package.json @@ -2,7 +2,7 @@ "name": "berry", "displayName": "Berry Script Language", "description": "A small embedded script language.", - "version": "0.1.0", + "version": "1.1.0", "publisher": "skiars", "engines": { "vscode": "^1.15.1" diff --git a/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/berry.json b/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/syntaxes/berry.json similarity index 56% rename from lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/berry.json rename to lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/syntaxes/berry.json index 661d969a5440..4087fb10c048 100755 --- a/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/berry.json +++ b/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/syntaxes/berry.json @@ -44,11 +44,55 @@ "patterns": [ { "name": "string.quoted.double.berry", - "match": "\"(\\\\.|[^\"])*\"" + "begin": "(\"|')", + "end": "\\1", + "patterns": [ + { + "name": "constant.character.escape.berry", + "match": "(\\\\x[\\h]{2})|(\\\\[0-7]{3})|(\\\\\\\\)|(\\\\\")|(\\\\')|(\\\\a)|(\\\\b)|(\\\\f)|(\\\\n)|(\\\\r)|(\\\\t)|(\\\\v)" + } + ] }, { - "name": "string.quoted.single.berry", - "match": "'(\\\\.|[^'])*'" + "name": "string.quoted.other.berry", + "begin": "f(\"|')", + "end": "\\1", + "patterns": [ + { + "name": "constant.character.escape.berry", + "match": "(\\\\x[\\h]{2})|(\\\\[0-7]{3})|(\\\\\\\\)|(\\\\\")|(\\\\')|(\\\\a)|(\\\\b)|(\\\\f)|(\\\\n)|(\\\\r)|(\\\\t)|(\\\\v)" + }, + { + "name": "string.quoted.other.berry", + "match": "\\{\\{[^\\}]*\\}\\}" + }, + { + "name": "keyword.other.unit.berry", + "begin": "\\{", + "end": "\\}", + "patterns": [ + { + "include": "#keywords" + }, + { + "include": "#numbers" + }, + { + "include": "#identifier" + }, + { + "include": "#operator" + }, + { + "include": "#member" + }, + { + "include": "#function" + } + ] + } + + ] } ] }, @@ -67,7 +111,7 @@ "keywords": { "patterns": [{ "name": "keyword.berry", - "match": "\\b(var|static|def|class|true|false|nil|self|super|import|as)\\b" + "match": "\\b(var|static|def|class|true|false|nil|self|super|import|as|_class)\\b" }] }, "identifier": { diff --git a/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/bytecode.json b/lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/syntaxes/bytecode.json similarity index 100% rename from lib/libesp32/berry/tools/plugins/vscode/skiars.berry-0.1.0/syntaxes/bytecode.json rename to lib/libesp32/berry/tools/plugins/vscode/skiars.berry-1.1.0/syntaxes/bytecode.json diff --git a/lib/libesp32/berry_int64/library.json b/lib/libesp32/berry_int64/library.json index 8fe3f3258273..6c72492e12ef 100644 --- a/lib/libesp32/berry_int64/library.json +++ b/lib/libesp32/berry_int64/library.json @@ -1,5 +1,5 @@ { - "name": "Berry int64 implementation for 32 bits architceture", + "name": "Berry int64 implementation for 32 bits architecture", "version": "1.0", "description": "Berry int64", "license": "MIT", diff --git a/lib/libesp32/berry_mapping/src/be_cb_module.c b/lib/libesp32/berry_mapping/src/be_cb_module.c index 8054398d4956..111ba95e052d 100644 --- a/lib/libesp32/berry_mapping/src/be_cb_module.c +++ b/lib/libesp32/berry_mapping/src/be_cb_module.c @@ -22,10 +22,10 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D * We allow 4 parameters, or 3 if method (first arg is `self`) * This could be extended if needed \*********************************************************************************************/ -typedef int32_t (*berry_callback_t)(int32_t v0, int32_t v1, int32_t v2, int32_t v3); -static int32_t call_berry_cb(int32_t num, int32_t v0, int32_t v1, int32_t v2, int32_t v3); +typedef int (*berry_callback_t)(int v0, int v1, int v2, int v3); +static int call_berry_cb(int num, int v0, int v1, int v2, int v3); -#define BERRY_CB(n) int32_t berry_cb_##n(int32_t v0, int32_t v1, int32_t v2, int32_t v3) { return call_berry_cb(n, v0, v1, v2, v3); } +#define BERRY_CB(n) int berry_cb_##n(int v0, int v1, int v2, int v3) { return call_berry_cb(n, v0, v1, v2, v3); } // list the callbacks BERRY_CB(0); BERRY_CB(1); @@ -85,7 +85,7 @@ typedef struct be_callback_handler_list_t { static be_callback_hook be_cb_hooks[BE_MAX_CB] = {0}; -static int32_t be_cb_gen_cb(bvm *vm); +static int be_cb_gen_cb(bvm *vm); static be_callback_handler_list_t be_callback_default_gen_cb = { NULL, be_const_func(&be_cb_gen_cb), @@ -102,7 +102,7 @@ static be_callback_handler_list_t *be_callback_handler_list_head = &be_callback_ * * arg1: function (or closure) \*********************************************************************************************/ -static int32_t be_cb_add_handler(bvm *vm) { +static int be_cb_add_handler(bvm *vm) { int32_t top = be_top(vm); if (top >= 1 && be_isfunction(vm, 1)) { bvalue *v = be_indexof(vm, 1); @@ -129,7 +129,7 @@ static int32_t be_cb_add_handler(bvm *vm) { * * No args \*********************************************************************************************/ -static int32_t be_cb_list_handlers(bvm *vm) { +static int be_cb_list_handlers(bvm *vm) { be_newobject(vm, "list"); for (be_callback_handler_list_t *elt = be_callback_handler_list_head; elt != NULL; elt = elt->next) { if (elt->vm == vm) { /* on purpose don't show the default handler, just pretend it's not there since it's default */ @@ -153,7 +153,7 @@ static int32_t be_cb_list_handlers(bvm *vm) { * arg2: type name for callback (optional) * argN: any other callback specific arguments (unlimited number, passed as-is) \*********************************************************************************************/ -static int32_t be_cb_make_cb(bvm *vm) { +static int be_cb_make_cb(bvm *vm) { int32_t argc = be_top(vm); if (argc >= 1 && be_isfunction(vm, 1)) { @@ -187,7 +187,7 @@ static int32_t be_cb_make_cb(bvm *vm) { * * arg1: function (or closure) \*********************************************************************************************/ -static int32_t be_cb_gen_cb(bvm *vm) { +static int be_cb_gen_cb(bvm *vm) { int32_t top = be_top(vm); // tasmota_log_C(LOG_LEVEL_DEBUG, "BRY: gen_cb() called"); if (top >= 1 && be_isfunction(vm, 1)) { @@ -217,7 +217,7 @@ static int32_t be_cb_gen_cb(bvm *vm) { * `get_cb_list`: Return the list of callbacks for this vm * \*********************************************************************************************/ -static int32_t be_cb_get_cb_list(bvm *vm) { +static int be_cb_get_cb_list(bvm *vm) { be_newobject(vm, "list"); for (uint32_t i=0; i < BE_MAX_CB; i++) { if (be_cb_hooks[i].vm) { @@ -242,7 +242,7 @@ static int32_t be_cb_get_cb_list(bvm *vm) { * We allow 4 parameters, or 3 if method (first arg is `self`) * This could be extended if needed \*********************************************************************************************/ -static int32_t call_berry_cb(int32_t num, int32_t v0, int32_t v1, int32_t v2, int32_t v3) { +static int call_berry_cb(int num, int v0, int v1, int v2, int v3) { // call berry cb dispatcher int32_t ret = 0; // retrieve vm and function @@ -271,6 +271,26 @@ static int32_t call_berry_cb(int32_t num, int32_t v0, int32_t v1, int32_t v2, in return ret; } +/*********************************************************************************************\ + * `be_cb_deinit`: + * Clean any callback for this VM, they shouldn't call the registerd function anymore +\*********************************************************************************************/ +void be_cb_deinit(bvm *vm) { + // remove all cb for this vm + for (int32_t slot = 0; slot < BE_MAX_CB; slot++) { + if (be_cb_hooks[slot].vm == vm) { + be_cb_hooks[slot].vm = NULL; + be_cb_hooks[slot].f.type == BE_NIL; + } + } + // remove the vm gen_cb for this vm + for (be_callback_handler_list_t **elt_ptr = &be_callback_handler_list_head; *elt_ptr != NULL; elt_ptr = &(*elt_ptr)->next) { + if (((*elt_ptr)->next != NULL) && ((*elt_ptr)->next->vm == vm)) { + (*elt_ptr)->next = (*elt_ptr)->next->next; + } + } +} + /* @const_object_info_begin module cb (scope: global) { gen_cb, func(be_cb_gen_cb) diff --git a/lib/libesp32/berry_mapping/src/be_class_wrapper.c b/lib/libesp32/berry_mapping/src/be_class_wrapper.c index bbde814bb4d5..94cbb9f51bc9 100644 --- a/lib/libesp32/berry_mapping/src/be_class_wrapper.c +++ b/lib/libesp32/berry_mapping/src/be_class_wrapper.c @@ -360,7 +360,7 @@ int be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, i } } // berry_log_C(">> be_call_c_func arg %i, type %s", i, arg_type_check ? type_short_name : ""); - p[p_idx] = be_convert_single_elt(vm, i + arg_start, arg_type_check ? type_short_name : NULL, &buf_len); + p[p_idx] = be_convert_single_elt(vm, i + arg_start, arg_type_check ? type_short_name : NULL, (int*)&buf_len); // berry_log_C("< ret[%i]=%i", p_idx, p[p_idx]); p_idx++; @@ -486,7 +486,7 @@ int be_call_c_func(bvm *vm, const void * func, const char * return_type, const c } else { // class name be_find_global_or_module_member(vm, return_type); be_pushcomptr(vm, (void*) ret); // stack = class, ptr - be_call(vm, 1); // instanciate with 2 arguments, stack = instance, ptr, -1 + be_call(vm, 1); // instanciate with 1 argument (ptr) be_pop(vm, 1); // stack = instance be_return(vm); } diff --git a/lib/libesp32/berry_mapping/src/be_mapping.h b/lib/libesp32/berry_mapping/src/be_mapping.h index 9876278f391f..f0ab9d22c56b 100644 --- a/lib/libesp32/berry_mapping/src/be_mapping.h +++ b/lib/libesp32/berry_mapping/src/be_mapping.h @@ -109,6 +109,8 @@ extern int be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_ extern int be_call_c_func(bvm *vm, const void * func, const char * return_type, const char * arg_type); extern int be_call_ctype_func(bvm *vm, const void *definition); /* handler for Berry vm */ +extern void be_cb_deinit(bvm *vm); /* remove all callbacks from the VM (just before shutdown of VM) */ + #ifdef __cplusplus } #endif diff --git a/lib/libesp32/berry_matter/generate/Matter_generate_c.be b/lib/libesp32/berry_matter/generate/Matter_generate_c.be index 86155ec1c300..62f257078a4a 100644 --- a/lib/libesp32/berry_matter/generate/Matter_generate_c.be +++ b/lib/libesp32/berry_matter/generate/Matter_generate_c.be @@ -82,7 +82,7 @@ fprint(" const matter_command_t* commands;") fprint("} matter_cluster_t;") fprint() for cl:cl_ids - fprint(string.format("const matter_attribute_t matter_Attributes_%04X[] = {", cl)) + fprint(f"const matter_attribute_t matter_Attributes_{cl:04X}[] = {") var attributes = c[cl_id_name[cl]]['attributes'] var attr_id_name = {} for attr:attributes @@ -94,13 +94,13 @@ for cl:cl_ids var reportable = attributes[attr_id].find('reportable', false) var writable = attributes[attr_id].find('writable', false) var flags = (writable ? 0x01 : 0x00) | (reportable ? 0x02 : 0x00) - fprint(string.format(' { 0x%04X, %i, 0x%02X, "%s" },', attr_id, 0, flags, attributes[attr_id]['attributeName'])) + fprint(format(' { 0x%04X, %i, 0x%02X, "%s" },', attr_id, 0, flags, attributes[attr_id]['attributeName'])) end fprint(' { 0xFFFF, 0, 0x00, NULL },') fprint("};") fprint() # commands - fprint(string.format("const matter_command_t matter_Commands_%04X[] = {", cl)) + fprint(f"const matter_command_t matter_Commands_{cl:04X}[] = {") var commands = c[cl_id_name[cl]]['commands'] var cmd_id_name = {} for cmd:commands @@ -109,7 +109,7 @@ for cl:cl_ids var cmd_ids_local = k2l(cmd_id_name) for cmd_id:cmd_ids_local - fprint(string.format(' { 0x%04X, "%s" },', cmd_id, commands[cmd_id]['commandName'])) + fprint(format(' { 0x%04X, "%s" },', cmd_id, commands[cmd_id]['commandName'])) end fprint(' { 0xFFFF, NULL },') fprint("};") @@ -118,7 +118,7 @@ end fprint("const matter_cluster_t matterAllClusters[] = {") for cl:cl_ids - fprint(string.format(' { 0x%04X, "%s", matter_Attributes_%04X, matter_Commands_%04X },', cl, cl_id_name[cl], cl, cl)) + fprint(format(' { 0x%04X, "%s", matter_Attributes_%04X, matter_Commands_%04X },', cl, cl_id_name[cl], cl, cl)) end fprint(' { 0xFFFF, NULL, NULL },') fprint("};") diff --git a/lib/libesp32/berry_matter/generate/be_matter_clusters.h b/lib/libesp32/berry_matter/generate/be_matter_clusters.h index e25982844beb..350d8b9fcf82 100644 --- a/lib/libesp32/berry_matter/generate/be_matter_clusters.h +++ b/lib/libesp32/berry_matter/generate/be_matter_clusters.h @@ -1528,7 +1528,7 @@ const matter_cluster_t matterAllClusters[] = { { 0x0032, "DiagnosticLogs", matter_Attributes_0032, matter_Commands_0032 }, { 0x0033, "GeneralDiagnostics", matter_Attributes_0033, matter_Commands_0033 }, { 0x0034, "SoftwareDiagnostics", matter_Attributes_0034, matter_Commands_0034 }, - { 0x0035, "ThreadNetworkDiagnostics", matter_Attributes_0035, matter_Commands_0035 }, + // { 0x0035, "ThreadNetworkDiagnostics", matter_Attributes_0035, matter_Commands_0035 }, { 0x0036, "WiFiNetworkDiagnostics", matter_Attributes_0036, matter_Commands_0036 }, { 0x0037, "EthernetNetworkDiagnostics", matter_Attributes_0037, matter_Commands_0037 }, { 0x0039, "BridgedDeviceBasic", matter_Attributes_0039, matter_Commands_0039 }, @@ -1542,31 +1542,31 @@ const matter_cluster_t matterAllClusters[] = { { 0x0050, "ModeSelect", matter_Attributes_0050, matter_Commands_0050 }, { 0x0101, "DoorLock", matter_Attributes_0101, matter_Commands_0101 }, { 0x0102, "WindowCovering", matter_Attributes_0102, matter_Commands_0102 }, - { 0x0103, "BarrierControl", matter_Attributes_0103, matter_Commands_0103 }, + // { 0x0103, "BarrierControl", matter_Attributes_0103, matter_Commands_0103 }, { 0x0200, "PumpConfigurationAndControl", matter_Attributes_0200, matter_Commands_0200 }, { 0x0201, "Thermostat", matter_Attributes_0201, matter_Commands_0201 }, { 0x0202, "FanControl", matter_Attributes_0202, matter_Commands_0202 }, { 0x0204, "ThermostatUserInterfaceConfiguration", matter_Attributes_0204, matter_Commands_0204 }, { 0x0300, "ColorControl", matter_Attributes_0300, matter_Commands_0300 }, - { 0x0301, "BallastConfiguration", matter_Attributes_0301, matter_Commands_0301 }, + // { 0x0301, "BallastConfiguration", matter_Attributes_0301, matter_Commands_0301 }, { 0x0400, "IlluminanceMeasurement", matter_Attributes_0400, matter_Commands_0400 }, { 0x0402, "TemperatureMeasurement", matter_Attributes_0402, matter_Commands_0402 }, { 0x0403, "PressureMeasurement", matter_Attributes_0403, matter_Commands_0403 }, { 0x0404, "FlowMeasurement", matter_Attributes_0404, matter_Commands_0404 }, { 0x0405, "RelativeHumidityMeasurement", matter_Attributes_0405, matter_Commands_0405 }, { 0x0406, "OccupancySensing", matter_Attributes_0406, matter_Commands_0406 }, - { 0x0503, "WakeOnLan", matter_Attributes_0503, matter_Commands_0503 }, - { 0x0504, "Channel", matter_Attributes_0504, matter_Commands_0504 }, - { 0x0505, "TargetNavigator", matter_Attributes_0505, matter_Commands_0505 }, - { 0x0506, "MediaPlayback", matter_Attributes_0506, matter_Commands_0506 }, - { 0x0507, "MediaInput", matter_Attributes_0507, matter_Commands_0507 }, - { 0x0508, "LowPower", matter_Attributes_0508, matter_Commands_0508 }, - { 0x0509, "KeypadInput", matter_Attributes_0509, matter_Commands_0509 }, - { 0x050A, "ContentLauncher", matter_Attributes_050A, matter_Commands_050A }, - { 0x050B, "AudioOutput", matter_Attributes_050B, matter_Commands_050B }, - { 0x050C, "ApplicationLauncher", matter_Attributes_050C, matter_Commands_050C }, - { 0x050D, "ApplicationBasic", matter_Attributes_050D, matter_Commands_050D }, - { 0x050E, "AccountLogin", matter_Attributes_050E, matter_Commands_050E }, - { 0x0B04, "ElectricalMeasurement", matter_Attributes_0B04, matter_Commands_0B04 }, + // { 0x0503, "WakeOnLan", matter_Attributes_0503, matter_Commands_0503 }, + // { 0x0504, "Channel", matter_Attributes_0504, matter_Commands_0504 }, + // { 0x0505, "TargetNavigator", matter_Attributes_0505, matter_Commands_0505 }, + // { 0x0506, "MediaPlayback", matter_Attributes_0506, matter_Commands_0506 }, + // { 0x0507, "MediaInput", matter_Attributes_0507, matter_Commands_0507 }, + // { 0x0508, "LowPower", matter_Attributes_0508, matter_Commands_0508 }, + // { 0x0509, "KeypadInput", matter_Attributes_0509, matter_Commands_0509 }, + // { 0x050A, "ContentLauncher", matter_Attributes_050A, matter_Commands_050A }, + // { 0x050B, "AudioOutput", matter_Attributes_050B, matter_Commands_050B }, + // { 0x050C, "ApplicationLauncher", matter_Attributes_050C, matter_Commands_050C }, + // { 0x050D, "ApplicationBasic", matter_Attributes_050D, matter_Commands_050D }, + // { 0x050E, "AccountLogin", matter_Attributes_050E, matter_Commands_050E }, + // { 0x0B04, "ElectricalMeasurement", matter_Attributes_0B04, matter_Commands_0B04 }, { 0xFFFF, NULL, NULL }, }; diff --git a/lib/libesp32/berry_matter/generate/be_matter_vendors.h b/lib/libesp32/berry_matter/generate/be_matter_vendors.h new file mode 100644 index 000000000000..3b06fc0945a1 --- /dev/null +++ b/lib/libesp32/berry_matter/generate/be_matter_vendors.h @@ -0,0 +1,94 @@ +/*********************************************************************************\ +* List of Matter Vendors +* From: https://on.dcl.csa-iot.org/dcl/vendorinfo/vendors +* +* Generated content, do not edit +\*********************************************************************************/ +#include +#include + +typedef struct { + uint16_t id; + const char* name; +} matter_vendor_t; + +const matter_vendor_t matter_Vendors[] = { + + { 0x100B, "Signify"}, + { 0x101D, "Assa Abloy"}, + { 0x1021, "Legrand Group"}, + { 0x1037, "NXP Semiconductors"}, + { 0x105E, "Schneider"}, + { 0x109B, "Leviton"}, + { 0x10D0, "Qorvo"}, + { 0x10EE, "UEI"}, + { 0x10F2, "ubisys"}, + { 0x111D, "Comcast Communications"}, + { 0x115A, "Nanoleaf"}, + { 0x115F, "Aqara"}, + { 0x1160, "Sengled"}, + { 0x1168, "Leedarson"}, + { 0x117E, "Feibit"}, + { 0x1188, "TP-Link"}, + { 0x118C, "Midea Group"}, + { 0x120B, "HEIMAN"}, + { 0x1217, "Amazon Alexa"}, + { 0x1219, "ORVIBO"}, + { 0x125D, "Tuya"}, + { 0x127F, "Nordic Semiconductor ASA"}, + { 0x1280, "Siterwell"}, + { 0x1286, "CoolKit"}, + { 0x128F, "EGLO"}, + { 0x130A, "Eve"}, + { 0x130D, "BouffaloLab"}, + { 0x1312, "Yeelight"}, + { 0x131B, "Espressif Systems"}, + { 0x131E, "CAME S.p.A."}, + { 0x131F, "Longan.link"}, + { 0x1321, "SONOFF"}, + { 0x1333, "Becker Antriebe"}, + { 0x1339, "GE Lighting, a Savant company"}, + { 0x133F, "ASR"}, + { 0x1342, "Beken Corporation"}, + { 0x1344, "Eltako"}, + { 0x1345, "Meross"}, + { 0x1346, "Rafael"}, + { 0x1349, "Apple Home"}, + { 0x134E, "tado"}, + { 0x134F, "mediola"}, + { 0x1351, "HooRii Technology"}, + { 0x135D, "Nuki"}, + { 0x1362, "deveritec GmbH"}, + { 0x1365, "Dooya"}, + { 0x136E, "Ambi Labs Limited"}, + { 0x1371, "Tridonic"}, + { 0x1372, "innovation matters"}, + { 0x137F, "NEO"}, + { 0x1381, "Amazon Prime Video"}, + { 0x1384, "Apple Keychain"}, + { 0x1386, "Skylux"}, + { 0x1387, "Qianyan"}, + { 0x138A, "Nature"}, + { 0x1391, "Kasa"}, + { 0x1392, "Tapo"}, + { 0x1397, "SwitchBot"}, + { 0x139C, "Zemismart Technology Limited"}, + { 0x1400, "Uascent"}, + { 0x1403, "Arlec Australia"}, + { 0x1404, "Phaten"}, + { 0x1407, "ThirdReality"}, + { 0x1410, "Quectel"}, + { 0x1413, "1Home"}, + { 0x1415, "Caveman"}, + { 0x1419, "Lorex"}, + { 0x141B, "Rang Dong VN"}, + { 0x141E, "TUO Accessories LLC"}, + { 0x141F, "Ductech"}, + { 0x142D, "QH"}, + { 0x142F, "QIACHIP"}, + { 0x6006, "Google LLC"}, + + { 0x134B, "Nabu Casa"}, + + { 0xFFFF, NULL }, +}; diff --git a/lib/libesp32/berry_matter/solidify_all.be b/lib/libesp32/berry_matter/solidify_all.be index 0d69174b9aa7..cf19458aa9da 100755 --- a/lib/libesp32/berry_matter/solidify_all.be +++ b/lib/libesp32/berry_matter/solidify_all.be @@ -5,7 +5,7 @@ import os import global import solidify -import string +import string as string2 import re import sys @@ -18,13 +18,27 @@ var globs = "path,ctypes_bytes_dyn,tasmota,ccronexpr,gpio,light,webclient,load,M "_lvgl," "int64" -for g:string.split(globs, ",") +for g:string2.split(globs, ",") global.(g) = nil end var prefix_dir = "src/embedded/" var prefix_out = "src/solidify/" +def sort(l) + # insertion sort + for i:1..size(l)-1 + var k = l[i] + var j = i + while (j > 0) && (l[j-1] > k) + l[j] = l[j-1] + j -= 1 + end + l[j] = k + end + return l +end + def clean_directory(dir) var file_list = os.listdir(dir) for f : file_list @@ -44,9 +58,9 @@ def parse_file(fname, prefix_out) var compiled = compile(src) compiled() # run the compile code to instanciate the classes and modules # output solidified - var fname_h = string.split(fname, '.be')[0] + '.h' # take whatever is before the first '.be' + var fname_h = string2.split(fname, '.be')[0] + '.h' # take whatever is before the first '.be' var fout = open(prefix_out + "solidified_" + fname_h, "w") - fout.write(string.format("/* Solidification of %s */\n", fname_h)) + fout.write(f"/* Solidification of {fname_h} */\n") fout.write("/********************************************************************\\\n") fout.write("* Generated code, don't edit *\n") fout.write("\\********************************************************************/\n") @@ -56,13 +70,13 @@ def parse_file(fname, prefix_out) # print(directives) for directive : directives - var object_list = string.split(directive[1], ',') + var object_list = string2.split(directive[1], ',') var object_name = object_list[0] var weak = (object_list.find('weak') != nil) # do we solidify with weak strings? var o = global var cl_name = nil var obj_name = nil - for subname : string.split(object_name, '.') + for subname : string2.split(object_name, '.') o = o.(subname) cl_name = obj_name obj_name = subname @@ -78,6 +92,7 @@ end clean_directory(prefix_out) var src_file_list = os.listdir(prefix_dir) +src_file_list = sort(src_file_list) for src_file : src_file_list if src_file[0] == '.' continue end parse_file(src_file, prefix_out) diff --git a/lib/libesp32/berry_matter/src/be_matter_misc.cpp b/lib/libesp32/berry_matter/src/be_matter_misc.cpp index 2ec805183294..0e57c2aa54f8 100644 --- a/lib/libesp32/berry_matter/src/be_matter_misc.cpp +++ b/lib/libesp32/berry_matter/src/be_matter_misc.cpp @@ -31,6 +31,7 @@ static uint8_t ip_bytes[16] = {}; extern "C" const void* matter_get_ip_bytes(const char* ip_str, size_t* ret_len) { IPAddress ip; if (ip.fromString(ip_str)) { +#ifdef USE_IPV6 if (ip.isV4()) { uint32_t ip_32 = ip; memcpy(ip_bytes, &ip_32, 4); @@ -39,6 +40,11 @@ extern "C" const void* matter_get_ip_bytes(const char* ip_str, size_t* ret_len) memcpy(ip_bytes, ip.raw6(), 16); *ret_len = 16; } +#else + uint32_t ip_32 = ip; + memcpy(ip_bytes, &ip_32, 4); + *ret_len = 4; +#endif return ip_bytes; } else { *ret_len = 0; diff --git a/lib/libesp32/berry_matter/src/be_matter_module.c b/lib/libesp32/berry_matter/src/be_matter_module.c index 6469098a3768..f5a97b7aebbb 100644 --- a/lib/libesp32/berry_matter/src/be_matter_module.c +++ b/lib/libesp32/berry_matter/src/be_matter_module.c @@ -24,6 +24,7 @@ #include "be_constobj.h" #include "be_mapping.h" +#include // Matter logo static const uint8_t MATTER_LOGO[] = @@ -36,6 +37,46 @@ static const uint8_t MATTER_LOGO[] = "118.06a96.93,96.93,0,0,0-68.16,118.06l23.27-13.44a71.1,71.1,0,0,1,3.29-35.17L309.46,300l12.78-" "7.38V277.89l-54.39-31.4a71.13,71.13,0,0,1,28.82-20.43Z'/>"; +// Matter stylesheet +static const uint8_t MATTER_STYLESHEET[] = + ""; + +static const uint8_t MATTER_ADD_ENDPOINT_HINTS_JS[] = + ""; + +extern uint32_t matter_convert_seconds_to_dhm(uint32_t seconds, char *unit, uint32_t *color, bbool days); + +char* matter_seconds_to_dhm(int32_t seconds) { + static const char empty_resp[] = " "; + static char res[64]; // static to allow returning to Berry + char unit; + uint32_t color; // color of text + + if (seconds < 0) { return empty_resp; } // no value + + uint32_t val = matter_convert_seconds_to_dhm(seconds, &unit, &color, bfalse); + if (val < 100) { + snprintf(res, sizeof(res), "🕗%02d%c", + (color & 0xFF0000) >> 16, (color & 0x00FF00) >> 8, (color & 0x0000FF), + val, unit); + } else { + return empty_resp; + } + return res; +} +BE_FUNC_CTYPE_DECLARE(matter_seconds_to_dhm, "s", "i") + extern const bclass be_class_Matter_Counter; extern const bclass be_class_Matter_Verhoeff; extern const bclass be_class_Matter_QRCode; @@ -44,6 +85,17 @@ extern const bclass be_class_Matter_QRCode; #include "../generate/be_matter_clusters.h" #include "../generate/be_matter_opcodes.h" +#include "../generate/be_matter_vendors.h" + +const char* matter_get_vendor_name(uint16_t id) { + for (const matter_vendor_t * vnd = matter_Vendors; vnd->id != 0xFFFF; vnd++) { + if (vnd->id == id) { + return vnd->name; + } + } + return NULL; +} +BE_FUNC_CTYPE_DECLARE(matter_get_vendor_name, "s", "i") const char* matter_get_cluster_name(uint16_t cluster) { for (const matter_cluster_t * cl = matterAllClusters; cl->id != 0xFFFF; cl++) { @@ -125,14 +177,18 @@ BE_FUNC_CTYPE_DECLARE(matter_get_command_name, "s", "ii") extern const void* matter_get_ip_bytes(const char* ip_str, size_t* ret_len); BE_FUNC_CTYPE_DECLARE(matter_get_ip_bytes, "&", "s") +extern int matter_publish_command(bvm *vm); -#include "solidify/solidified_Matter_inspect.h" +#include "solidify/solidified_Matter_0_Inspect.h" extern const bclass be_class_Matter_TLV; // need to declare it upfront because of circular reference #include "solidify/solidified_Matter_Path.h" #include "solidify/solidified_Matter_TLV.h" #include "solidify/solidified_Matter_IM_Data.h" #include "solidify/solidified_Matter_UDPServer.h" +#include "solidify/solidified_Matter_TCP_async.h" +#include "solidify/solidified_Matter_HTTP_async.h" +#include "solidify/solidified_Matter_HTTP_remote.h" #include "solidify/solidified_Matter_Expirable.h" #include "solidify/solidified_Matter_Fabric.h" #include "solidify/solidified_Matter_Session.h" @@ -145,29 +201,55 @@ extern const bclass be_class_Matter_TLV; // need to declare it upfront because #include "solidify/solidified_Matter_IM_Subscription.h" #include "solidify/solidified_Matter_IM.h" #include "solidify/solidified_Matter_Control_Message.h" -#include "solidify/solidified_Matter_Plugin.h" +#include "solidify/solidified_Matter_Plugin_0.h" #include "solidify/solidified_Matter_Base38.h" #include "solidify/solidified_Matter_UI.h" #include "solidify/solidified_Matter_Device.h" +#include "solidify/solidified_Matter_Profiler.h" #include "../generate/be_matter_certs.h" -#include "solidify/solidified_Matter_Plugin_Root.h" -#include "solidify/solidified_Matter_Plugin_Device.h" -#include "solidify/solidified_Matter_Plugin_OnOff.h" -#include "solidify/solidified_Matter_Plugin_Light0.h" -#include "solidify/solidified_Matter_Plugin_Light1.h" -#include "solidify/solidified_Matter_Plugin_Light2.h" -#include "solidify/solidified_Matter_Plugin_Light3.h" -#include "solidify/solidified_Matter_Plugin_Shutter.h" -#include "solidify/solidified_Matter_Plugin_ShutterTilt.h" -#include "solidify/solidified_Matter_Plugin_Sensor.h" -#include "solidify/solidified_Matter_Plugin_Sensor_Pressure.h" -#include "solidify/solidified_Matter_Plugin_Sensor_Temp.h" -#include "solidify/solidified_Matter_Plugin_Sensor_Illuminance.h" -#include "solidify/solidified_Matter_Plugin_Sensor_Humidity.h" -#include "solidify/solidified_Matter_Plugin_Bridge_HTTP.h" -#include "solidify/solidified_Matter_Plugin_Bridge_OnOff.h" +#include "solidify/solidified_Matter_Plugin_1_Root.h" +#include "solidify/solidified_Matter_Plugin_2_Aggregator.h" +#include "solidify/solidified_Matter_Plugin_1_Device.h" +#include "solidify/solidified_Matter_Plugin_2_OnOff.h" +#include "solidify/solidified_Matter_Plugin_9_Virt_OnOff.h" +#include "solidify/solidified_Matter_Plugin_2_Light0.h" +#include "solidify/solidified_Matter_Plugin_9_Virt_Light0.h" +#include "solidify/solidified_Matter_Plugin_3_Light1.h" +#include "solidify/solidified_Matter_Plugin_9_Virt_Light1.h" +#include "solidify/solidified_Matter_Plugin_4_Light2.h" +#include "solidify/solidified_Matter_Plugin_9_Virt_Light2.h" +#include "solidify/solidified_Matter_Plugin_4_Light3.h" +#include "solidify/solidified_Matter_Plugin_9_Virt_Light3.h" +#include "solidify/solidified_Matter_Plugin_2_Shutter.h" +#include "solidify/solidified_Matter_Plugin_3_ShutterTilt.h" +#include "solidify/solidified_Matter_Plugin_2_Sensor.h" +#include "solidify/solidified_Matter_Plugin_3_Sensor_Pressure.h" +#include "solidify/solidified_Matter_Plugin_9_Virt_Sensor_Pressure.h" +#include "solidify/solidified_Matter_Plugin_3_Sensor_Temp.h" +#include "solidify/solidified_Matter_Plugin_9_Virt_Sensor_Temp.h" +#include "solidify/solidified_Matter_Plugin_3_Sensor_Illuminance.h" +#include "solidify/solidified_Matter_Plugin_9_Virt_Sensor_Illuminance.h" +#include "solidify/solidified_Matter_Plugin_3_Sensor_Humidity.h" +#include "solidify/solidified_Matter_Plugin_9_Virt_Sensor_Humidity.h" +#include "solidify/solidified_Matter_Plugin_3_Sensor_Occupancy.h" +#include "solidify/solidified_Matter_Plugin_3_Sensor_OnOff.h" +#include "solidify/solidified_Matter_Plugin_3_Sensor_Contact.h" +#include "solidify/solidified_Matter_Plugin_9_Virt_Sensor_Contact.h" +#include "solidify/solidified_Matter_Plugin_2_Bridge_HTTP.h" +#include "solidify/solidified_Matter_Plugin_4_Bridge_OnOff.h" +#include "solidify/solidified_Matter_Plugin_3_Bridge_Light0.h" +#include "solidify/solidified_Matter_Plugin_4_Bridge_Light1.h" +#include "solidify/solidified_Matter_Plugin_5_Bridge_Light2.h" +#include "solidify/solidified_Matter_Plugin_5_Bridge_Light3.h" +#include "solidify/solidified_Matter_Plugin_3_Bridge_Sensor.h" +#include "solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Pressure.h" +#include "solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Temp.h" +#include "solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Illuminance.h" +#include "solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Humidity.h" +#include "solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Occupancy.h" +#include "solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Contact.h" /*********************************************************************************************\ * Get a bytes() object of the certificate DAC/PAI_Cert @@ -195,14 +277,19 @@ static int matter_CD_FFF1_8000(bvm *vm) { return matter_return_static_bytes(vm, module matter (scope: global, strings: weak) { _LOGO, comptr(MATTER_LOGO) + _STYLESHEET, comptr(MATTER_STYLESHEET) + _ADD_ENDPOINT_JS, comptr(MATTER_ADD_ENDPOINT_HINTS_JS) MATTER_OPTION, int(151) // SetOption151 enables Matter + seconds_to_dhm, ctype_func(matter_seconds_to_dhm) Verhoeff, class(be_class_Matter_Verhoeff) Counter, class(be_class_Matter_Counter) setmember, closure(matter_setmember_closure) member, closure(matter_member_closure) get_ip_bytes, ctype_func(matter_get_ip_bytes) + publish_command, func(matter_publish_command) + get_vendor_name, ctype_func(matter_get_vendor_name) get_cluster_name, ctype_func(matter_get_cluster_name) get_attribute_name, ctype_func(matter_get_attribute_name) is_attribute_writable, ctype_func(matter_is_attribute_writable) @@ -211,7 +298,11 @@ module matter (scope: global, strings: weak) { get_opcode_name, ctype_func(matter_get_opcode_name) TLV, class(be_class_Matter_TLV) sort, closure(matter_sort_closure) + jitter, closure(matter_jitter_closure) inspect, closure(matter_inspect_closure) + consolidate_clusters, closure(matter_consolidate_clusters_closure) + UC_LIST, closure(matter_UC_LIST_closure) + Profiler, class(be_class_Matter_Profiler) // Status codes SUCCESS, int(0x00) @@ -261,6 +352,7 @@ module matter (scope: global, strings: weak) { StatusIB, class(be_class_Matter_StatusIB) StatusResponseMessage, class(be_class_Matter_StatusResponseMessage) ReadRequestMessage, class(be_class_Matter_ReadRequestMessage) + ReadRequestMessage_solo, class(be_class_Matter_ReadRequestMessage_solo) ReportDataMessage, class(be_class_Matter_ReportDataMessage) SubscribeRequestMessage, class(be_class_Matter_SubscribeRequestMessage) SubscribeResponseMessage, class(be_class_Matter_SubscribeResponseMessage) @@ -268,6 +360,7 @@ module matter (scope: global, strings: weak) { WriteResponseMessage, class(be_class_Matter_WriteResponseMessage) TimedRequestMessage, class(be_class_Matter_TimedRequestMessage) InvokeRequestMessage, class(be_class_Matter_InvokeRequestMessage) + InvokeRequestMessage_solo, class(be_class_Matter_InvokeRequestMessage_solo) InvokeResponseMessage, class(be_class_Matter_InvokeResponseMessage) // Matter Commisioning messages @@ -286,6 +379,9 @@ module matter (scope: global, strings: weak) { // UDP Server UDPPacket_sent, class(be_class_Matter_UDPPacket_sent) UDPServer, class(be_class_Matter_UDPServer) + TCP_async, class(be_class_Matter_TCP_async) + HTTP_async, class(be_class_Matter_HTTP_async) + HTTP_remote, class(be_class_Matter_HTTP_remote) // Expirable Expirable, class(be_class_Matter_Expirable) @@ -335,21 +431,46 @@ module matter (scope: global, strings: weak) { // Plugins Plugin_Root, class(be_class_Matter_Plugin_Root) // Generic behavior common to all devices + Plugin_Aggregator, class(be_class_Matter_Plugin_Aggregator) // Aggregator Plugin_Device, class(be_class_Matter_Plugin_Device) // Generic device (abstract) Plugin_OnOff, class(be_class_Matter_Plugin_OnOff) // Relay/Light behavior (OnOff) + Plugin_Virt_OnOff, class(be_class_Matter_Plugin_Virt_OnOff) // Relay/Light virtual (OnOff) Plugin_Light0, class(be_class_Matter_Plugin_Light0) // OnOff Light + Plugin_Virt_Light0, class(be_class_Matter_Plugin_Virt_Light0) // OnOff Light Virtual Plugin_Light1, class(be_class_Matter_Plugin_Light1) // Dimmable Light + Plugin_Virt_Light1, class(be_class_Matter_Plugin_Virt_Light1) // Dimmable Light Virtual Plugin_Light2, class(be_class_Matter_Plugin_Light2) // Color Temperature Light + Plugin_Virt_Light2, class(be_class_Matter_Plugin_Virt_Light2) // Color Temperature Light Virtual Plugin_Light3, class(be_class_Matter_Plugin_Light3) // Extended Color Light + Plugin_Virt_Light3, class(be_class_Matter_Plugin_Virt_Light3) // Extended Color Light Virtual Plugin_Shutter, class(be_class_Matter_Plugin_Shutter) // Shutter Plugin_ShutterTilt, class(be_class_Matter_Plugin_ShutterTilt) // Shutter + Tilt Plugin_Sensor, class(be_class_Matter_Plugin_Sensor) // Generic Sensor Plugin_Sensor_Pressure, class(be_class_Matter_Plugin_Sensor_Pressure) // Pressure Sensor + Plugin_Sensor_Virt_Pressure, class(be_class_Matter_Plugin_Virt_Sensor_Pressure) // Pressure Virtual Sensor Plugin_Sensor_Temp, class(be_class_Matter_Plugin_Sensor_Temp) // Temperature Sensor + Plugin_Virt_Sensor_Temp, class(be_class_Matter_Plugin_Virt_Sensor_Temp) // Temperature Sensor Plugin_Sensor_Illuminance, class(be_class_Matter_Plugin_Sensor_Illuminance) // Illuminance Sensor + Plugin_Virt_Sensor_Illuminance, class(be_class_Matter_Plugin_Virt_Sensor_Illuminance) // Illuminance Virtual Sensor Plugin_Sensor_Humidity, class(be_class_Matter_Plugin_Sensor_Humidity) // Humidity Sensor + Plugin_Sensor_Virt_Humidity, class(be_class_Matter_Plugin_Virt_Sensor_Humidity) // Humidity Virtual Sensor + Plugin_Sensor_Occupancy, class(be_class_Matter_Plugin_Sensor_Occupancy) // Occupancy Sensor + Plugin_Sensor_OnOff, class(be_class_Matter_Plugin_Sensor_OnOff) // Simple OnOff Sensor + Plugin_Sensor_Contact, class(be_class_Matter_Plugin_Sensor_Contact) // Contact Sensor + Plugin_Virt_Sensor_Contact, class(be_class_Matter_Plugin_Virt_Sensor_Contact) // Virtual Contact Sensor Plugin_Bridge_HTTP, class(be_class_Matter_Plugin_Bridge_HTTP) // HTTP bridge superclass Plugin_Bridge_OnOff, class(be_class_Matter_Plugin_Bridge_OnOff) // HTTP Relay/Light behavior (OnOff) + Plugin_Bridge_Light0, class(be_class_Matter_Plugin_Bridge_Light0) // HTTP OnOff Light + Plugin_Bridge_Light1, class(be_class_Matter_Plugin_Bridge_Light1) // HTTP Dimmer Light + Plugin_Bridge_Light2, class(be_class_Matter_Plugin_Bridge_Light2) // HTTP CT Light + Plugin_Bridge_Light3, class(be_class_Matter_Plugin_Bridge_Light3) // HTTP RGB Light + Plugin_Bridge_Sensor, class(be_class_Matter_Plugin_Bridge_Sensor) // HTTP generic sensor + Plugin_Bridge_Sensor_Pressure, class(be_class_Matter_Plugin_Bridge_Sensor_Pressure) // HTTP Pressure sensor + Plugin_Bridge_Sensor_Temp, class(be_class_Matter_Plugin_Bridge_Sensor_Temp) // HTTP Temperature sensor + Plugin_Bridge_Sensor_Illuminance, class(be_class_Matter_Plugin_Bridge_Sensor_Illuminance) // HTTP Illuminance sensor + Plugin_Bridge_Sensor_Humidity, class(be_class_Matter_Plugin_Bridge_Sensor_Humidity) // HTTP Humidity sensor + Plugin_Bridge_Sensor_Occupancy, class(be_class_Matter_Plugin_Bridge_Sensor_Occupancy) // HTTP Occupancy sensor + Plugin_Bridge_Sensor_Contact, class(be_class_Matter_Plugin_Bridge_Sensor_Contact) // HTTP Contact sensor } @const_object_info_end */ diff --git a/lib/libesp32/berry_matter/src/be_matter_qrcode.c b/lib/libesp32/berry_matter/src/be_matter_qrcode.c index 5bcddef86c72..9892cda93be4 100644 --- a/lib/libesp32/berry_matter/src/be_matter_qrcode.c +++ b/lib/libesp32/berry_matter/src/be_matter_qrcode.c @@ -32,7 +32,7 @@ // `matter.QRCode.encode_str(content:string) -> map` // -int32_t qr_encode_str(bvm *vm) { +int qr_encode_str(bvm *vm) { int32_t argc = be_top(vm); if (argc >= 1 && be_isstring(vm, 1)) { const char * data_str = be_tostring(vm, 1); diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_inspect.be b/lib/libesp32/berry_matter/src/embedded/Matter_0_Inspect.be similarity index 52% rename from lib/libesp32/berry_matter/src/embedded/Matter_inspect.be rename to lib/libesp32/berry_matter/src/embedded/Matter_0_Inspect.be index c9f9a15d2f12..5d6f31de06c0 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_inspect.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_0_Inspect.be @@ -35,11 +35,23 @@ def sort(l) end matter.sort = sort +#@ solidify:matter.jitter,weak +############################################################# +# jitter +# +# compute a random jitter time for an update_time value +def jitter(update_time) + # initialization to a random value within range + import crypto + var rand31 = crypto.random(4).get(0,4) & 0x7FFFFFFF # random int over 31 bits + return tasmota.millis(rand31 % update_time) +end +matter.jitter = jitter + #@ solidify:matter.inspect,weak # debug function def inspect(p) try - import string import introspect var keys = [] @@ -53,7 +65,7 @@ def inspect(p) for k : keys var v = introspect.get(p, k) # if type(v) == 'string' v = string.escape(v, true) end - r.push(string.format("'%s': %s", str(k), str(v))) + r.push(format("'%s': %s", str(k), str(v))) end return "{" + r.concat(", ") + "}" @@ -62,3 +74,42 @@ def inspect(p) end end matter.inspect = inspect + + +############################################################# +# consolidate_clusters +# +# Build a consolidated map of all the `CLUSTERS` static vars +# from the inheritance hierarchy +#@ solidify:matter.consolidate_clusters,weak +def consolidate_clusters(cl, m) + var cl_parent = super(cl).CLUSTERS + var ret = {} + # clone cl_parent + for k: cl_parent.keys() + # print(f"{k=} {cl_parent[k]=}") + ret[k] = cl_parent[k].copy() + end + # add all keys from m + # print("--- step 2") + for k: m.keys() + # print(f"{k=} {ret.find(k)=} {m[k]=}") + var l = ret.find(k) + if l == nil l = [] end + ret[k] = l + m[k] + end + # print(ret) + return ret +end +matter.consolidate_clusters = consolidate_clusters + +############################################################# +# consolidate_update_commands_list +# +# Build a consolidated list and remove duplicates +#@ solidify:matter.UC_LIST,weak +def UC_LIST(cl, *l) + var uc_parent = super(cl).UPDATE_COMMANDS + return uc_parent + l +end +matter.UC_LIST = UC_LIST diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Base38.be b/lib/libesp32/berry_matter/src/embedded/Matter_Base38.be index 7a5c84d407e1..2d9c2963396c 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Base38.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Base38.be @@ -26,7 +26,6 @@ class Matter_Base38 static def encode(raw) # encodes b38 (mutates `b`) def b38_enc(v, l) - import string var ENCODE = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-." var i = 0 var ret = "" diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Commissioning.be b/lib/libesp32/berry_matter/src/embedded/Matter_Commissioning.be index a77ea792d022..d2427a2ce8f4 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Commissioning.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Commissioning.be @@ -44,9 +44,8 @@ class Matter_Commisioning_Context ############################################################# def add_session(local_session_id, initiator_session_id, i2r, r2i, ac) - import string # create session object - tasmota.log(string.format("MTR: add_session local_session_id=%i initiator_session_id=%i", local_session_id, initiator_session_id), 3) + tasmota.log(format("MTR: add_session local_session_id=%i initiator_session_id=%i", local_session_id, initiator_session_id), 4) var session = self.device.sessions.create_session(local_session_id, initiator_session_id) session.set_keys(i2r, r2i, ac) @@ -59,7 +58,7 @@ class Matter_Commisioning_Context return false end - tasmota.log("MTR: received message " + matter.inspect(msg), 3) + # tasmota.log("MTR: received message " + matter.inspect(msg), 4) if msg.opcode == 0x10 # don't need to do anything, the message is acked already before this call elif msg.opcode == 0x20 @@ -75,8 +74,7 @@ class Matter_Commisioning_Context elif msg.opcode == 0x40 return self.parse_StatusReport(msg) else - import string - tasmota.log(string.format("MTR: >????????? Unknown OpCode (secure channel) %02X", msg.opcode), 2) + tasmota.log(format("MTR: >????????? Unknown OpCode (secure channel) %02X", msg.opcode), 2) return false end @@ -108,12 +106,11 @@ class Matter_Commisioning_Context def parse_PBKDFParamRequest(msg) import crypto - import string var session = msg.session # sanity checks if msg.opcode != 0x20 || msg.local_session_id != 0 || msg.protocol_id != 0 tasmota.log("MTR: invalid PBKDFParamRequest message", 2) - tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2) + tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 3) self.send_status_report(msg, 0x01, 0x0000, 0x0002, false) return false end @@ -125,7 +122,7 @@ class Matter_Commisioning_Context # sanity check for PBKDFParamRequest if pbkdfparamreq.passcodeId != 0 tasmota.log("MTR: non-zero passcode id", 2) - tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2) + tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 3) self.send_status_report(msg, 0x01, 0x0000, 0x0002, false) return false end @@ -133,7 +130,7 @@ class Matter_Commisioning_Context # record the initiator_session_id session.__future_initiator_session_id = pbkdfparamreq.initiator_session_id session.__future_local_session_id = self.device.sessions.gen_local_session_id() - tasmota.log(string.format("MTR: +Session (%6i) from '[%s]:%i'", session.__future_local_session_id, msg.remote_ip, msg.remote_port), 2) + tasmota.log(format("MTR: +Session (%6i) from '[%s]:%i'", session.__future_local_session_id, msg.remote_ip, msg.remote_port), 3) # prepare response var pbkdfparamresp = matter.PBKDFParamResponse() @@ -159,11 +156,12 @@ class Matter_Commisioning_Context def parse_Pake1(msg) import crypto + var session = msg.session # sanity checks if msg.opcode != 0x22 || msg.local_session_id != 0 || msg.protocol_id != 0 - tasmota.log("MTR: invalid Pake1 message", 2) - tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2) + tasmota.log("MTR: invalid Pake1 message", 3) + tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 3) self.send_status_report(msg, 0x01, 0x0000, 0x0002, false) return false end @@ -236,6 +234,9 @@ class Matter_Commisioning_Context var resp = msg.build_response(0x23 #-pake-2-#, true) # no reliable flag var raw = resp.encode_frame(pake2_raw) + # log the fact that a new commissioning is starting + tasmota.log(format("MTR: New Commissioning (PASE id=%i) from [%s]:%i", session.__future_local_session_id, session._ip, session._port), 2) + self.responder.send_response_frame(resp) return true end @@ -245,8 +246,8 @@ class Matter_Commisioning_Context var session = msg.session # sanity checks if msg.opcode != 0x24 || msg.local_session_id != 0 || msg.protocol_id != 0 - tasmota.log("MTR: invalid Pake3 message", 2) - tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2) + tasmota.log("MTR: invalid Pake3 message", 3) + tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 3) self.send_status_report(msg, 0x01, 0x0000, 0x0002, false) return false end @@ -257,14 +258,14 @@ class Matter_Commisioning_Context # check the value against computed if cA != session.__spake_cA - tasmota.log("MTR: invalid cA received", 2) - tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2) + tasmota.log("MTR: invalid cA received", 3) + tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 3) self.send_status_report(msg, 0x01, 0x0000, 0x0002, false) return false end # send PakeFinished and compute session key - var created = tasmota.rtc()['utc'] + var created = tasmota.rtc_utc() var session_keys = crypto.HKDF_SHA256().derive(session.__spake_Ke, bytes(), bytes().fromstring(self.SEKeys_Info), 48) var I2RKey = session_keys[0..15] var R2IKey = session_keys[16..31] @@ -288,18 +289,22 @@ class Matter_Commisioning_Context import crypto # Validate Sigma1 Destination ID, p.162 # traverse all existing fabrics - tasmota.log("MTR: SEARCHING: destinationId=" + destinationId.tohex(), 3) + if tasmota.loglevel(4) + tasmota.log("MTR: SEARCHING: destinationId=" + destinationId.tohex(), 4) + end for fabric : self.device.sessions.fabrics if fabric.noc == nil || fabric.fabric_id == nil || fabric.device_id == nil continue end - # compute candidateDestinationId, Section 4.13.2.4.1, “Destination Identifier” + # compute candidateDestinationId, Section 4.13.2.4.1, "Destination Identifier" var destinationMessage = initiatorRandom + fabric.get_ca_pub() + fabric.fabric_id + fabric.device_id var key = fabric.get_ipk_group_key() - tasmota.log("MTR: SIGMA1: destinationMessage=" + destinationMessage.tohex(), 3) - tasmota.log("MTR: SIGMA1: key_ipk=" + key.tohex(), 4) + # tasmota.log("MTR: SIGMA1: destinationMessage=" + destinationMessage.tohex(), 4) + # tasmota.log("MTR: SIGMA1: key_ipk=" + key.tohex(), 4) var h = crypto.HMAC_SHA256(key) h.update(destinationMessage) var candidateDestinationId = h.out() - tasmota.log("MTR: SIGMA1: candidateDestinationId=" + candidateDestinationId.tohex(), 3) + if tasmota.loglevel(4) + tasmota.log("MTR: SIGMA1: candidateDestinationId=" + candidateDestinationId.tohex(), 4) + end if candidateDestinationId == destinationId return fabric end @@ -314,23 +319,22 @@ class Matter_Commisioning_Context def parse_Sigma1(msg) import crypto - import string var session = msg.session # sanity checks if msg.opcode != 0x30 || msg.local_session_id != 0 || msg.protocol_id != 0 - # tasmota.log("MTR: invalid Sigma1 message", 2) - tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2) + # tasmota.log("MTR: invalid Sigma1 message", 3) + tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 3) self.send_status_report(msg, 0x01, 0x0000, 0x0002, false) return false end var sigma1 = matter.Sigma1().parse(msg.raw, msg.app_payload_idx) - tasmota.log(string.format("MTR: sigma1=%s", matter.inspect(sigma1)), 4) + # tasmota.log(format("MTR: sigma1=%s", matter.inspect(sigma1)), 4) session.__initiator_pub = sigma1.initiatorEphPubKey # find session var is_resumption = (sigma1.resumptionID != nil && sigma1.initiatorResumeMIC != nil) - tasmota.log(string.format("MTR: is_resumption=%i", is_resumption ? 1 : 0), 4) + # tasmota.log(format("MTR: is_resumption=%i", is_resumption ? 1 : 0), 4) # TODO disable resumption until fixed is_resumption = false @@ -338,7 +342,7 @@ class Matter_Commisioning_Context var session_resumption if is_resumption session_resumption = self.device.sessions.find_session_by_resumption_id(sigma1.resumptionID) - tasmota.log(string.format("MTR: session_resumption found session=%s session_resumption=%s", matter.inspect(session), matter.inspect(session_resumption)), 4) + # tasmota.log(format("MTR: session_resumption found session=%s session_resumption=%s", matter.inspect(session), matter.inspect(session_resumption)), 4) if session_resumption == nil || session_resumption._fabric == nil is_resumption = false end @@ -370,7 +374,7 @@ class Matter_Commisioning_Context session.set_mode_CASE() session.__future_initiator_session_id = sigma1.initiator_session_id # update initiator_session_id session.__future_local_session_id = self.device.sessions.gen_local_session_id() - tasmota.log(string.format("MTR: +Session (%6i) from '[%s]:%i'", session.__future_local_session_id, msg.remote_ip, msg.remote_port), 2) + tasmota.log(format("MTR: +Session (%6i) from '[%s]:%i'", session.__future_local_session_id, msg.remote_ip, msg.remote_port), 3) # Generate and Send Sigma2_Resume session.shared_secret = session_resumption.shared_secret @@ -406,7 +410,7 @@ class Matter_Commisioning_Context var i2r = session_keys[0..15] var r2i = session_keys[16..31] var ac = session_keys[32..47] - var created = tasmota.rtc()['utc'] + var created = tasmota.rtc_utc() # tasmota.log("MTR: ******************************", 4) # tasmota.log("MTR: I2RKey =" + i2r.tohex(), 4) @@ -449,7 +453,7 @@ class Matter_Commisioning_Context session._fabric = fabric if session == nil || session._fabric == nil - tasmota.log("MTR: StatusReport(GeneralCode: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: NO_SHARED_TRUST_ROOTS)", 2) + tasmota.log("MTR: StatusReport(GeneralCode: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: NO_SHARED_TRUST_ROOTS)", 3) self.send_status_report(msg, 0x01, 0x0000, 0x0001, false) return false end @@ -458,37 +462,42 @@ class Matter_Commisioning_Context session.__future_initiator_session_id = sigma1.initiator_session_id # update initiator_session_id session.__future_local_session_id = self.device.sessions.gen_local_session_id() - tasmota.log(string.format("MTR: +Session (%6i) from '[%s]:%i'", session.__future_local_session_id, msg.remote_ip, msg.remote_port), 2) + tasmota.log(format("MTR: +Session (%6i) from '[%s]:%i'", session.__future_local_session_id, msg.remote_ip, msg.remote_port), 3) - tasmota.log("MTR: fabric="+matter.inspect(session._fabric), 4) - tasmota.log("MTR: no_private_key="+session._fabric.no_private_key.tohex(), 4) - tasmota.log("MTR: noc ="+session._fabric.noc.tohex(), 4) - if session._fabric.get_icac() - tasmota.log("MTR: icac ="+session._fabric.get_icac().tohex(), 4) - end - tasmota.log("MTR: root_ca_cert ="+session._fabric.root_ca_certificate.tohex(), 4) + # tasmota.log("MTR: fabric="+matter.inspect(session._fabric), 4) + # tasmota.log("MTR: no_private_key="+session.get_pk().tohex(), 4) + # tasmota.log("MTR: noc ="+session.get_noc().tohex(), 4) + # if fabric.get_icac() + # tasmota.log("MTR: icac ="+fabric.get_icac().tohex(), 4) + # end + # tasmota.log("MTR: root_ca_cert ="+fabric.get_ca().tohex(), 4) # Compute Sigma2, p.162 - session.resumption_id = crypto.random(16) + session.resumption_id = crypto.random(16) # generate a new resumption id session.__responder_priv = crypto.random(32) session.__responder_pub = crypto.EC_P256().public_key(session.__responder_priv) - tasmota.log("MTR: ResponderEph_priv ="+session.__responder_priv.tohex(), 4) - tasmota.log("MTR: ResponderEph_pub ="+session.__responder_pub.tohex(), 4) + # tasmota.log("MTR: ResponderEph_priv ="+session.__responder_priv.tohex(), 4) + # tasmota.log("MTR: ResponderEph_pub ="+session.__responder_pub.tohex(), 4) var responderRandom = crypto.random(32) session.shared_secret = crypto.EC_P256().shared_key(session.__responder_priv, sigma1.initiatorEphPubKey) + # tasmota.log("MTR: * shared_secret = " + session.shared_secret.tohex(), 4) var sigma2_tbsdata = matter.TLV.Matter_TLV_struct() - sigma2_tbsdata.add_TLV(1, matter.TLV.B2, session.get_noc()) - sigma2_tbsdata.add_TLV(2, matter.TLV.B2, session.get_icac()) + sigma2_tbsdata.add_TLV(1, matter.TLV.B2, fabric.get_noc()) + sigma2_tbsdata.add_TLV(2, matter.TLV.B2, fabric.get_icac()) sigma2_tbsdata.add_TLV(3, matter.TLV.B2, session.__responder_pub) sigma2_tbsdata.add_TLV(4, matter.TLV.B2, sigma1.initiatorEphPubKey) - var TBSData2Signature = crypto.EC_P256().ecdsa_sign_sha256(session.get_pk(), sigma2_tbsdata.tlv2raw()) + var TBSData2Signature = crypto.EC_P256().ecdsa_sign_sha256(fabric.get_pk(), sigma2_tbsdata.tlv2raw()) + # tasmota.log("****************************************", 4) + # tasmota.log("MTR: * fabric.get_pk = " + str(fabric.get_pk()), 4) + # tasmota.log("MTR: * sigma2_tbsdata = " + str(sigma2_tbsdata), 4) + # tasmota.log("MTR: * TBSData2Signature = " + TBSData2Signature.tohex(), 4) var sigma2_tbedata = matter.TLV.Matter_TLV_struct() - sigma2_tbedata.add_TLV(1, matter.TLV.B2, session.get_noc()) - sigma2_tbedata.add_TLV(2, matter.TLV.B2, session.get_icac()) + sigma2_tbedata.add_TLV(1, matter.TLV.B2, fabric.get_noc()) + sigma2_tbedata.add_TLV(2, matter.TLV.B2, fabric.get_icac()) sigma2_tbedata.add_TLV(3, matter.TLV.B2, TBSData2Signature) sigma2_tbedata.add_TLV(4, matter.TLV.B2, session.resumption_id) @@ -502,7 +511,7 @@ class Matter_Commisioning_Context # Compute S2K, p.175 var s2k_info = bytes().fromstring(self.S2K_Info) - var s2k_salt = session.get_ipk_group_key() + responderRandom + session.__responder_pub + TranscriptHash + var s2k_salt = fabric.get_ipk_group_key() + responderRandom + session.__responder_pub + TranscriptHash var s2k = crypto.HKDF_SHA256().derive(session.shared_secret, s2k_salt, s2k_info, 16) # tasmota.log("MTR: * SharedSecret = " + session.shared_secret.tohex(), 4) @@ -532,6 +541,9 @@ class Matter_Commisioning_Context var resp = msg.build_response(0x31 #-sigma-2-#, true) # no reliable flag var raw = resp.encode_frame(sigma2_raw) + # log the fact that a new connection is starting + tasmota.log(format("MTR: New Connection (CASE id=%i) from [%s]:%i", session.__future_local_session_id, session._ip, session._port), 2) + self.responder.send_response_frame(resp) return true end @@ -543,7 +555,7 @@ class Matter_Commisioning_Context import crypto # sanity checks if msg.opcode != 0x32 || msg.local_session_id != 0 || msg.protocol_id != 0 - tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2) + tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 3) self.send_status_report(msg, 0x01, 0x0000, 0x0002, false) return false end @@ -579,8 +591,8 @@ class Matter_Commisioning_Context # tasmota.log("****************************************", 4) if TBETag3 != tag - tasmota.log("MTR: Tag don't match", 2) - tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2) + tasmota.log("MTR: Tag don't match", 3) + tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 3) self.send_status_report(msg, 0x01, 0x0000, 0x0002, false) return false end @@ -596,12 +608,12 @@ class Matter_Commisioning_Context # Success = Crypto_VerifyChain(certificates = [TBEData3.initiatorNOC, TBEData3.initiatorICAC, TrustedRCAC]), when TBEData3.initiatorICAC is present # TODO var initiatorNOCTLV = matter.TLV.parse(initiatorNOC) - tasmota.log("MTR: initiatorNOCTLV = " + str(initiatorNOCTLV), 3) + # tasmota.log("MTR: initiatorNOCTLV = " + str(initiatorNOCTLV), 4) var initiatorNOCPubKey = initiatorNOCTLV.findsubval(9) var initiatorNOCListDN = initiatorNOCTLV.findsub(6) var initiatorFabricId = initiatorNOCListDN.findsubval(17) if type(initiatorFabricId) == 'int' session.peer_node_id = int64.fromu32(initiatorFabricId).tobytes() else session.peer_node_id = initiatorFabricId.tobytes() end - tasmota.log("MTR: initiatorFabricId="+str(session.peer_node_id), 3) + # tasmota.log("MTR: initiatorFabricId="+str(session.peer_node_id), 4) var sigma3_tbs = matter.TLV.Matter_TLV_struct() sigma3_tbs.add_TLV(1, matter.TLV.B1, initiatorNOC) @@ -650,7 +662,7 @@ class Matter_Commisioning_Context var i2r = session_keys[0..15] var r2i = session_keys[16..31] var ac = session_keys[32..47] - var created = tasmota.rtc()['utc'] + var created = tasmota.rtc_utc() # tasmota.log("MTR: ******************************", 4) # tasmota.log("MTR: I2RKey =" + i2r.tohex(), 4) @@ -679,7 +691,7 @@ class Matter_Commisioning_Context # placeholder, nothing to run for now def parse_StatusReport(msg) var session = msg.session - tasmota.log("MTR: >Status "+msg.raw[msg.app_payload_idx..].tohex(), 2) + tasmota.log("MTR: >Status "+msg.raw[msg.app_payload_idx..].tohex(), 3) return false # we don't explicitly ack the message end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Control_Message.be b/lib/libesp32/berry_matter/src/embedded/Matter_Control_Message.be index d2d3192ba163..d00c0cd53492 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Control_Message.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Control_Message.be @@ -39,14 +39,13 @@ class Matter_Control_Message def process_incoming_control_message(msg) - tasmota.log("MTR: received control message " + matter.inspect(msg), 2) + tasmota.log("MTR: received control message " + matter.inspect(msg), 3) if msg.opcode == 0x00 return self.parse_MsgCounterSyncReq(msg) elif msg.opcode == 0x01 return self.parse_MsgCounterSyncRsp(msg) else - import string - tasmota.log(string.format("MTR: >????????? Unknown OpCode (control message) %02X", msg.opcode), 2) + tasmota.log(format("MTR: >????????? Unknown OpCode (control message) %02X", msg.opcode), 2) return false end @@ -58,9 +57,8 @@ class Matter_Control_Message # # Not yet implemented def parse_MsgCounterSyncReq(msg) - import string var session = msg.session - tasmota.log(string.format("MTR: >MCSyncReq * Not implemented %s", msg.raw[msg.app_payload_idx..].tohex()), 2) + tasmota.log(format("MTR: >MCSyncReq * Not implemented %s", msg.raw[msg.app_payload_idx..].tohex()), 2) return false # we don't explicitly ack the message end @@ -69,9 +67,8 @@ class Matter_Control_Message # # Not yet implemented def parse_MsgCounterSyncRsp(msg) - import string var session = msg.session - tasmota.log(string.format("MTR: >MCSyncRsp * Not implemented %s", msg.raw[msg.app_payload_idx..].tohex()), 2) + tasmota.log(format("MTR: >MCSyncRsp * Not implemented %s", msg.raw[msg.app_payload_idx..].tohex()), 2) return false # we don't explicitly ack the message end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Device.be b/lib/libesp32/berry_matter/src/embedded/Matter_Device.be index 8eff6f14047f..3e2439d2333d 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Device.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Device.be @@ -17,6 +17,8 @@ # along with this program. If not, see . # +import matter + #@ solidify:Matter_Device,weak class Matter_Device @@ -31,7 +33,9 @@ class Matter_Device var plugins_persist # true if plugins configuration needs to be saved var plugins_classes # map of registered classes by type name var plugins_config # map of JSON configuration for plugins + var plugins_config_remotes # map of information on each remote under "remotes" key, '{}' when empty var udp_server # `matter.UDPServer()` object + var profiler var message_handler # `matter.MessageHandler()` object var sessions # `matter.Session_Store()` objet var ui @@ -54,10 +58,14 @@ class Matter_Device # mDNS active announces var mdns_pase_eth # do we have an active PASE mDNS announce for eth var mdns_pase_wifi # do we have an active PASE mDNS announce for wifi + # for brige mode, list of HTTP_remote objects (only one instance per remote object) + var http_remotes # map of 'domain:port' to `Matter_HTTP_remote` instance or `nil` if no bridges # saved in parameters var root_discriminator # as `int` var root_passcode # as `int` var ipv4only # advertize only IPv4 addresses (no IPv6) + var disable_bridge_mode # default is bridge mode, this flag disables this mode for some non-compliant controllers + var next_ep # next endpoint to be allocated for bridge, start at 1 # context for PBKDF var root_iterations # PBKDF number of iterations # PBKDF information used only during PASE (freed afterwards) @@ -68,23 +76,26 @@ class Matter_Device ############################################################# def init() import crypto - import string if !tasmota.get_option(matter.MATTER_OPTION) matter.UI(self) # minimal UI return end # abort if SetOption 151 is not set + matter.profiler = matter.Profiler() self.started = false self.tick = 0 self.plugins = [] self.plugins_persist = false # plugins need to saved only when the first fabric is associated self.plugins_classes = {} + self.plugins_config_remotes = {} self.register_native_classes() # register all native classes self.vendorid = self.VENDOR_ID self.productid = self.PRODUCT_ID self.root_iterations = self.PBKDF_ITERATIONS + self.next_ep = 1 # start at endpoint 1 for dynamically allocated endpoints self.root_salt = crypto.random(16) self.ipv4only = false + self.disable_bridge_mode = false self.load_param() self.sessions = matter.Session_Store(self) @@ -124,6 +135,7 @@ class Matter_Device self.autoconf_device() # for now read sensors every 30 seconds + # TODO still needed? tasmota.add_cron("*/30 * * * * *", def () self._trigger_read_sensors() end, "matter_sensors_30s") self._start_udp(self.UDP_PORT) @@ -147,16 +159,15 @@ class Matter_Device # # Open window for `timeout_s` (default 10 minutes) def start_root_basic_commissioning(timeout_s) - import string if timeout_s == nil timeout_s = self.PASE_TIMEOUT end # show Manual pairing code in logs var pairing_code = self.compute_manual_pairing_code() - tasmota.log(string.format("MTR: Manual pairing code: %s-%s-%s", pairing_code[0..3], pairing_code[4..6], pairing_code[7..]), 2) + tasmota.log(format("MTR: Manual pairing code: %s", pairing_code), 2) # output MQTT var qr_code = self.compute_qrcode_content() - tasmota.publish_result(string.format('{"Matter":{"Commissioning":1,"PairingCode":"%s","QRCode":"%s"}}', pairing_code, qr_code), 'Matter') + tasmota.publish_result(format('{"Matter":{"Commissioning":1,"PairingCode":"%s","QRCode":"%s"}}', pairing_code, qr_code), 'Matter') # compute PBKDF self._compute_pbkdf(self.root_passcode, self.root_iterations, self.root_salt) @@ -165,17 +176,24 @@ class Matter_Device ##################################################################### # Remove a fabric and clean all corresponding values and mDNS entries - def remove_fabric(fabric_parent) - var sub_fabrics = self.sessions.find_children_fabrics(fabric_parent.get_fabric_index()) - if sub_fabrics == nil return end - for fabric_index : sub_fabrics - var fabric = self.sessions.find_fabric_by_index(fabric_index) - if fabric != nil - self.message_handler.im.subs_shop.remove_by_fabric(fabric) - self.mdns_remove_op_discovery(fabric) - self.sessions.remove_fabric(fabric) - end + def remove_fabric(fabric) + if fabric != nil + tasmota.log("MTR: removing fabric " + fabric.get_fabric_id().copy().reverse().tohex(), 2) + self.message_handler.im.subs_shop.remove_by_fabric(fabric) + self.mdns_remove_op_discovery(fabric) + self.sessions.remove_fabric(fabric) end + # var sub_fabrics = self.sessions.find_children_fabrics(fabric_parent.get_fabric_index()) + # if sub_fabrics == nil return end + # for fabric_index : sub_fabrics + # var fabric = self.sessions.find_fabric_by_index(fabric_index) + # if fabric != nil + # tasmota.log("MTR: removing fabric " + fabric.get_fabric_id().copy().reverse().tohex(), 2) + # self.message_handler.im.subs_shop.remove_by_fabric(fabric) + # self.mdns_remove_op_discovery(fabric) + # self.sessions.remove_fabric(fabric) + # end + # end self.sessions.save_fabrics() end @@ -238,7 +256,6 @@ class Matter_Device # def _compute_pbkdf(passcode_int, iterations, salt) import crypto - import string var passcode = bytes().add(passcode_int, 4) var tv = crypto.PBKDF2_HMAC_SHA256().derive(passcode, salt, iterations, 80) @@ -279,12 +296,11 @@ class Matter_Device #
# can be done only for root PASE (we need the passcode, but we don't get it with OpenCommissioningWindow command) def compute_manual_pairing_code() - import string var digit_1 = (self.root_discriminator & 0x0FFF) >> 10 var digit_2_6 = ((self.root_discriminator & 0x0300) << 6) | (self.root_passcode & 0x3FFF) var digit_7_10 = (self.root_passcode >> 14) - var ret = string.format("%1i%05i%04i", digit_1, digit_2_6, digit_7_10) + var ret = format("%1i%05i%04i", digit_1, digit_2_6, digit_7_10) ret += matter.Verhoeff.checksum(ret) return ret end @@ -372,8 +388,8 @@ class Matter_Device def _start_udp(port) if self.udp_server return end # already started if port == nil port = 5540 end - tasmota.log("MTR: starting UDP server on port: " + str(port), 2) - self.udp_server = matter.UDPServer("", port) + tasmota.log("MTR: Starting UDP server on port: " + str(port), 2) + self.udp_server = matter.UDPServer(self, "", port) self.udp_server.start(/ raw, addr, port -> self.msg_received(raw, addr, port)) end @@ -381,9 +397,9 @@ class Matter_Device # Start Operational Discovery for this session # # Deferred until next tick. - def start_operational_discovery_deferred(session) + def start_operational_discovery_deferred(fabric) # defer to next click - tasmota.set_timer(0, /-> self.start_operational_discovery(session)) + tasmota.set_timer(0, /-> self.start_operational_discovery(fabric)) end ############################################################# @@ -400,10 +416,9 @@ class Matter_Device # # Stop Basic Commissioning and clean PASE specific values (to save memory). # Announce fabric entry in mDNS. - def start_operational_discovery(session) + def start_operational_discovery(fabric) import crypto import mdns - import string self.stop_basic_commissioning() # close all PASE commissioning information # clear any PBKDF information to free memory @@ -411,10 +426,7 @@ class Matter_Device # self.root_w1 = nil self.root_L = nil - # we keep the PASE session for 1 minute - session.set_expire_in_seconds(60) - - self.mdns_announce_op_discovery(session.get_fabric()) + self.mdns_announce_op_discovery(fabric) end ############################################################# @@ -422,7 +434,10 @@ class Matter_Device # # Stop basic commissioning. def start_commissioning_complete(session) - tasmota.log("MTR: *** Commissioning complete ***", 2) + var fabric = session.get_fabric() + var fabric_id = fabric.get_fabric_id().copy().reverse().tohex() + var vendor_name = fabric.get_admin_vendor_name() + tasmota.log(f"MTR: --- Commissioning complete for Fabric '{fabric_id}' (Vendor {vendor_name}) ---", 2) self.stop_basic_commissioning() # by default close commissioning when it's complete end @@ -504,26 +519,22 @@ class Matter_Device return l end - import string var endpoint = ctx.endpoint - # var endpoint_mono = [ endpoint ] - var endpoint_found = false # did any endpoint match var cluster = ctx.cluster - # var cluster_mono = [ cluster ] - var cluster_found = false var attribute = ctx.attribute - # var attribute_mono = [ attribute ] + var endpoint_found = false # did any endpoint match + var cluster_found = false var attribute_found = false var direct = (ctx.endpoint != nil) && (ctx.cluster != nil) && (ctx.attribute != nil) # true if the target is a precise attribute, false if it results from an expansion and error are ignored - # tasmota.log(string.format("MTR: process_attribute_expansion %s", str(ctx)), 4) + # tasmota.log(f"MTR: process_attribute_expansion {str(ctx))}", 4) # build the list of candidates # list of all endpoints var all = {} # map of {endpoint: {cluster: {attributes:[pi]}} - # tasmota.log(string.format("MTR: endpoint=%s cluster=%s attribute=%s", endpoint, cluster, attribute), 4) + # tasmota.log(format("MTR: endpoint=%s cluster=%s attribute=%s", endpoint, cluster, attribute), 4) for pi: self.plugins var ep = pi.get_endpoint() # get supported endpoints for this plugin @@ -533,8 +544,8 @@ class Matter_Device endpoint_found = true # now explore the cluster list for 'ep' - var cluster_list = pi.get_cluster_list(ep) # cluster_list is the actual list of candidate cluster for this pluging and endpoint - # tasmota.log(string.format("MTR: pi=%s ep=%s cl_list=%s", str(pi), str(ep), str(cluster_list)), 4) + var cluster_list = pi.get_cluster_list() # cluster_list is the actual list of candidate cluster for this pluging and endpoint + # tasmota.log(format("MTR: pi=%s ep=%s cl_list=%s", str(pi), str(ep), str(cluster_list)), 4) for cl: cluster_list if cluster != nil && cl != cluster continue end # skip if specific cluster and no match # from now on, 'cl' is a good candidate @@ -542,8 +553,8 @@ class Matter_Device cluster_found = true # now filter on attributes - var attr_list = pi.get_attribute_list(ep, cl) - # tasmota.log(string.format("MTR: pi=%s ep=%s cl=%s at_list=%s", str(pi), str(ep), str(cl), str(attr_list)), 4) + var attr_list = pi.get_attribute_list(cl) + # tasmota.log(format("MTR: pi=%s ep=%s cl=%s at_list=%s", str(pi), str(ep), str(cl), str(attr_list)), 4) for at: attr_list if attribute != nil && at != attribute continue end # skip if specific attribute and no match # from now on, 'at' is a good candidate @@ -563,7 +574,7 @@ class Matter_Device for cl: keys_sorted(all[ep]) for at: keys_sorted(all[ep][cl]) for pi: all[ep][cl][at] - tasmota.log(string.format("MTR: expansion [%02X]%04X/%04X", ep, cl, at), 3) + # tasmota.log(format("MTR: expansion [%02X]%04X/%04X", ep, cl, at), 3) ctx.endpoint = ep ctx.cluster = cl ctx.attribute = at @@ -587,6 +598,44 @@ class Matter_Device end end + ############################################################# + # Optimized version for a single endpoint/cluster/attribute + # + # Retrieve the plugin for a read + def process_attribute_read_solo(ctx) + var endpoint = ctx.endpoint + # var endpoint_found = false # did any endpoint match + var cluster = ctx.cluster + # var cluster_found = false + var attribute = ctx.attribute + # var attribute_found = false + + # all 3 elements must be non-nil + if endpoint == nil || cluster == nil || attribute == nil return nil end + + # look for plugin + var pi = self.find_plugin_by_endpoint(endpoint) + if pi == nil # endpoint not found + ctx.status = matter.UNSUPPORTED_ENDPOINT + return nil + end + + # check cluster + if !pi.contains_cluster(cluster) + ctx.status = matter.UNSUPPORTED_CLUSTER + return nil + end + + # attribute list + if !pi.contains_attribute(cluster, attribute) + ctx.status = matter.UNSUPPORTED_ATTRIBUTE + return nil + end + + # all good + return pi + end + ############################################################# # Return the list of endpoints from all plugins (distinct), exclud endpoint zero if `exclude_zero` is `true` def get_active_endpoints(exclude_zero) @@ -601,25 +650,61 @@ class Matter_Device return ret end + ############################################################# + # Find plugin by endpoint + def find_plugin_by_endpoint(ep) + var idx = 0 + while idx < size(self.plugins) + var pl = self.plugins[idx] + if pl.get_endpoint() == ep + return pl + end + idx += 1 + end + return nil + end + + ############################################################# + # Find plugin by endpoint + def find_plugin_by_friendly_name(name) + if (name == nil) || (size(name) == 0) return nil end # invalid name + + var idx = 0 + while idx < size(self.plugins) + var pl = self.plugins[idx] + var pl_name = pl.get_name() + if (pl_name != nil) && (size(pl_name) > 0) && (pl_name == name) + return pl + end + idx += 1 + end + return nil + end + ############################################################# # Persistance of Matter Device parameters # ############################################################# # def save_param() - import string import json - var j = string.format('{"distinguish":%i,"passcode":%i,"ipv4only":%s', self.root_discriminator, self.root_passcode, self.ipv4only ? 'true':'false') + self.update_remotes_info() # update self.plugins_config_remotes + + var j = format('{"distinguish":%i,"passcode":%i,"ipv4only":%s,"disable_bridge_mode":%s,"nextep":%i', self.root_discriminator, self.root_passcode, self.ipv4only ? 'true':'false', self.disable_bridge_mode ? 'true':'false', self.next_ep) if self.plugins_persist j += ',"config":' j += json.dump(self.plugins_config) + if size(self.plugins_config_remotes) > 0 + j += ',"remotes":' + j += json.dump(self.plugins_config_remotes) + end end j += '}' try var f = open(self.FILENAME, "w") f.write(j) f.close() - tasmota.log(string.format("MTR: =Saved parameters%s", self.plugins_persist ? " and condiguration" : ""), 2) + tasmota.log(format("MTR: =Saved parameters%s", self.plugins_persist ? " and configuration" : ""), 2) return j except .. as e, m tasmota.log("MTR: Session_Store::save Exception:" + str(e) + "|" + str(m), 2) @@ -627,28 +712,61 @@ class Matter_Device end end + ############################################################# + # Get remote info by url + # + # Return a map, potentially empty + def get_plugin_remote_info(url) + return self.plugins_config_remotes.find(url, {}) + end + + ############################################################# + # update back all remote information from actual remotes + # + # returns a map or `nil` if no information + # also stores in `self.plugins_config_remotes` + def update_remotes_info() + var ret = {} + if self.http_remotes != nil + for url:self.http_remotes.keys() + var info = self.http_remotes[url].get_info() + if info != nil && size(info) > 0 + ret[url] = info + end + end + end + + self.plugins_config_remotes = ret + return ret + end + ############################################################# # Load Matter Device parameters def load_param() - import string import crypto try var f = open(self.FILENAME) var s = f.read() f.close() - import json var j = json.load(s) self.root_discriminator = j.find("distinguish", self.root_discriminator) self.root_passcode = j.find("passcode", self.root_passcode) self.ipv4only = bool(j.find("ipv4only", false)) + self.disable_bridge_mode = bool(j.find("disable_bridge_mode", false)) + self.next_ep = j.find("nextep", self.next_ep) self.plugins_config = j.find("config") - if self.plugins_config - self._load_plugins_config(self.plugins_config) + if self.plugins_config != nil + tasmota.log("MTR: load_config = " + str(self.plugins_config), 3) + self.adjust_next_ep() self.plugins_persist = true end + self.plugins_config_remotes = j.find("remotes", {}) + if self.plugins_config_remotes + tasmota.log("MTR: load_remotes = " + str(self.plugins_config_remotes), 3) + end except .. as e, m if e != "io_error" tasmota.log("MTR: Session_Store::load Exception:" + str(e) + "|" + str(m), 2) @@ -667,41 +785,56 @@ class Matter_Device if dirty self.save_param() end end + ############################################################# + # Convert a configuration to a log string + static def conf_to_log(plugin_conf) + var param_log = '' + for k:_class.k2l(plugin_conf) + if k == 'type' continue end + param_log += format(" %s:%s", k, plugin_conf[k]) + end + return param_log + end + ############################################################# # Load plugins configuration from json # # 'config' is a map # Ex: # {'32': {'filter': 'AXP192#Temperature', 'type': 'temperature'}, '40': {'filter': 'BMP280#Pressure', 'type': 'pressure'}, '34': {'filter': 'SHT3X#Temperature', 'type': 'temperature'}, '33': {'filter': 'BMP280#Temperature', 'type': 'temperature'}, '1': {'relay': 0, 'type': 'relay'}, '56': {'filter': 'SHT3X#Humidity', 'type': 'humidity'}, '0': {'type': 'root'}} - def _load_plugins_config(config) - import string - + def _instantiate_plugins_from_config(config) var endpoints = self.k2l_num(config) - tasmota.log("MTR: endpoints to be configured "+str(endpoints), 3) + # tasmota.log("MTR: endpoints to be configured "+str(endpoints), 4) + tasmota.log("MTR: Configuring endpoints", 2) + + # start with mandatory endpoint 0 for root node + self.plugins.push(matter.Plugin_Root(self, 0, {})) + tasmota.log(format("MTR: endpoint = %5i type:%s%s", 0, 'root', ''), 2) + + # always include an aggregator for dynamic endpoints + self.plugins.push(matter.Plugin_Aggregator(self, 0xFF00, {})) for ep: endpoints + if ep == 0 continue end # skip endpoint 0 try var plugin_conf = config[str(ep)] - tasmota.log(string.format("MTR: endpoint %i config %s", ep, plugin_conf), 3) + # tasmota.log(format("MTR: endpoint %i config %s", ep, plugin_conf), 3) var pi_class_name = plugin_conf.find('type') if pi_class_name == nil tasmota.log("MTR: no class name, skipping", 3) continue end + if pi_class_name == 'root' tasmota.log("MTR: only one root node allowed", 3) continue end var pi_class = self.plugins_classes.find(pi_class_name) if pi_class == nil tasmota.log("MTR: unknown class name '"+str(pi_class_name)+"' skipping", 2) continue end var pi = pi_class(self, ep, plugin_conf) self.plugins.push(pi) - var param_log = '' - for k:self.k2l(plugin_conf) - if k == 'type' continue end - param_log += string.format(" %s:%s", k, plugin_conf[k]) - end - tasmota.log(string.format("MTR: endpoint:%i type:%s%s", ep, pi_class_name, param_log), 2) + tasmota.log(format("MTR: endpoint = %5i type:%s%s", ep, pi_class_name, self.conf_to_log(plugin_conf)), 2) except .. as e, m tasmota.log("MTR: Exception" + str(e) + "|" + str(m), 2) end end + tasmota.log(format("MTR: endpoint = %5i type:%s%s", 0xFF00, 'aggregator', ''), 2) tasmota.publish_result('{"Matter":{"Initialized":1}}', 'Matter') end @@ -770,25 +903,25 @@ class Matter_Device # Add Hostname (based on MAC) with IPv4/IPv6 addresses var eth = tasmota.eth() self.hostname_eth = string.replace(eth.find("mac"), ':', '') - if !self.ipv4only - tasmota.log(string.format("MTR: calling mdns.add_hostname(%s, %s, %s)", self.hostname_eth, eth.find('ip6local',''), eth.find('ip','')), 3) + if !self.ipv4only || !eth.contains('ip6local') + # tasmota.log(format("MTR: calling mdns.add_hostname(%s, %s, %s)", self.hostname_eth, eth.find('ip6local',''), eth.find('ip','')), 4) mdns.add_hostname(self.hostname_eth, eth.find('ip6local',''), eth.find('ip',''), eth.find('ip6','')) else - tasmota.log(string.format("MTR: calling mdns.add_hostname(%s, %s)", self.hostname_eth, eth.find('ip','')), 3) + tasmota.log(format("MTR: calling mdns.add_hostname(%s, %s)", self.hostname_eth, eth.find('ip','')), 3) mdns.add_hostname(self.hostname_eth, eth.find('ip','')) end else var wifi = tasmota.wifi() self.hostname_wifi = string.replace(wifi.find("mac"), ':', '') - if !self.ipv4only - tasmota.log(string.format("MTR: calling mdns.add_hostname(%s, %s, %s)", self.hostname_wifi, wifi.find('ip6local',''), wifi.find('ip','')), 3) + if !self.ipv4only || !wifi.contains('ip6local') + # tasmota.log(format("MTR: calling mdns.add_hostname(%s, %s, %s)", self.hostname_wifi, wifi.find('ip6local',''), wifi.find('ip','')), 4) mdns.add_hostname(self.hostname_wifi, wifi.find('ip6local',''), wifi.find('ip',''), wifi.find('ip6','')) else - tasmota.log(string.format("MTR: calling mdns.add_hostname(%s, %s)", self.hostname_eth, wifi.find('ip','')), 3) + tasmota.log(format("MTR: calling mdns.add_hostname(%s, %s)", self.hostname_wifi, wifi.find('ip','')), 3) mdns.add_hostname(self.hostname_wifi, wifi.find('ip','')) end end - tasmota.log(string.format("MTR: start mDNS on %s host '%s.local'", is_eth ? "eth" : "wifi", is_eth ? self.hostname_eth : self.hostname_wifi), 2) + tasmota.log(format("MTR: start mDNS on %s host '%s.local'", is_eth ? "eth" : "wifi", is_eth ? self.hostname_eth : self.hostname_wifi), 3) except .. as e, m tasmota.log("MTR: Exception" + str(e) + "|" + str(m), 2) end @@ -800,7 +933,6 @@ class Matter_Device # Announce MDNS for PASE commissioning def mdns_announce_PASE() import mdns - import string import crypto var services = { @@ -817,46 +949,46 @@ class Matter_Device try if self.hostname_eth # Add Matter `_matterc._udp` service - tasmota.log(string.format("MTR: calling mdns.add_service(%s, %s, %i, %s, %s, %s)", "_matterc", "_udp", 5540, str(services), self.commissioning_instance_eth, self.hostname_eth), 3) + # tasmota.log(format("MTR: calling mdns.add_service(%s, %s, %i, %s, %s, %s)", "_matterc", "_udp", 5540, str(services), self.commissioning_instance_eth, self.hostname_eth), 4) mdns.add_service("_matterc", "_udp", 5540, services, self.commissioning_instance_eth, self.hostname_eth) self.mdns_pase_eth = true - tasmota.log(string.format("MTR: announce mDNS on %s '%s' ptr to `%s.local`", "eth", self.commissioning_instance_eth, self.hostname_eth), 2) + tasmota.log(format("MTR: announce mDNS on %s '%s' ptr to `%s.local`", "eth", self.commissioning_instance_eth, self.hostname_eth), 2) # `mdns.add_subtype(service:string, proto:string, instance:string, hostname:string, subtype:string) -> nil` var subtype = "_L" + str(self.commissioning_discriminator & 0xFFF) - tasmota.log("MTR: adding subtype: "+subtype, 2) + tasmota.log("MTR: adding subtype: "+subtype, 3) mdns.add_subtype("_matterc", "_udp", self.commissioning_instance_eth, self.hostname_eth, subtype) subtype = "_S" + str((self.commissioning_discriminator & 0xF00) >> 8) - tasmota.log("MTR: adding subtype: "+subtype, 2) + tasmota.log("MTR: adding subtype: "+subtype, 3) mdns.add_subtype("_matterc", "_udp", self.commissioning_instance_eth, self.hostname_eth, subtype) subtype = "_V" + str(self.vendorid) - tasmota.log("MTR: adding subtype: "+subtype, 2) + tasmota.log("MTR: adding subtype: "+subtype, 3) mdns.add_subtype("_matterc", "_udp", self.commissioning_instance_eth, self.hostname_eth, subtype) subtype = "_CM1" - tasmota.log("MTR: adding subtype: "+subtype, 2) + tasmota.log("MTR: adding subtype: "+subtype, 3) mdns.add_subtype("_matterc", "_udp", self.commissioning_instance_eth, self.hostname_eth, subtype) end if self.hostname_wifi - tasmota.log(string.format("MTR: calling mdns.add_service(%s, %s, %i, %s, %s, %s)", "_matterc", "_udp", 5540, str(services), self.commissioning_instance_wifi, self.hostname_wifi), 3) + # tasmota.log(format("MTR: calling mdns.add_service(%s, %s, %i, %s, %s, %s)", "_matterc", "_udp", 5540, str(services), self.commissioning_instance_wifi, self.hostname_wifi), 4) mdns.add_service("_matterc", "_udp", 5540, services, self.commissioning_instance_wifi, self.hostname_wifi) self.mdns_pase_wifi = true - tasmota.log(string.format("MTR: starting mDNS on %s '%s' ptr to `%s.local`", "wifi", self.commissioning_instance_wifi, self.hostname_wifi), 2) + tasmota.log(format("MTR: starting mDNS on %s '%s' ptr to `%s.local`", "wifi", self.commissioning_instance_wifi, self.hostname_wifi), 3) # `mdns.add_subtype(service:string, proto:string, instance:string, hostname:string, subtype:string) -> nil` var subtype = "_L" + str(self.commissioning_discriminator & 0xFFF) - tasmota.log("MTR: adding subtype: "+subtype, 2) + tasmota.log("MTR: adding subtype: "+subtype, 3) mdns.add_subtype("_matterc", "_udp", self.commissioning_instance_wifi, self.hostname_wifi, subtype) subtype = "_S" + str((self.commissioning_discriminator & 0xF00) >> 8) - tasmota.log("MTR: adding subtype: "+subtype, 2) + tasmota.log("MTR: adding subtype: "+subtype, 3) mdns.add_subtype("_matterc", "_udp", self.commissioning_instance_wifi, self.hostname_wifi, subtype) subtype = "_V" + str(self.vendorid) - tasmota.log("MTR: adding subtype: "+subtype, 2) + tasmota.log("MTR: adding subtype: "+subtype, 3) mdns.add_subtype("_matterc", "_udp", self.commissioning_instance_wifi, self.hostname_wifi, subtype) subtype = "_CM1" - tasmota.log("MTR: adding subtype: "+subtype, 2) + tasmota.log("MTR: adding subtype: "+subtype, 3) mdns.add_subtype("_matterc", "_udp", self.commissioning_instance_wifi, self.hostname_wifi, subtype) end except .. as e, m @@ -869,18 +1001,17 @@ class Matter_Device # MDNS remove any PASE announce def mdns_remove_PASE() import mdns - import string try if self.mdns_pase_eth - tasmota.log(string.format("MTR: calling mdns.remove_service(%s, %s, %s, %s)", "_matterc", "_udp", self.commissioning_instance_eth, self.hostname_eth), 3) - tasmota.log(string.format("MTR: remove mDNS on %s '%s'", "eth", self.commissioning_instance_eth), 2) + tasmota.log(format("MTR: calling mdns.remove_service(%s, %s, %s, %s)", "_matterc", "_udp", self.commissioning_instance_eth, self.hostname_eth), 3) + tasmota.log(format("MTR: remove mDNS on %s '%s'", "eth", self.commissioning_instance_eth), 3) self.mdns_pase_eth = false mdns.remove_service("_matterc", "_udp", self.commissioning_instance_eth, self.hostname_eth) end if self.mdns_pase_wifi - tasmota.log(string.format("MTR: calling mdns.remove_service(%s, %s, %s, %s)", "_matterc", "_udp", self.commissioning_instance_wifi, self.hostname_wifi), 3) - tasmota.log(string.format("MTR: remove mDNS on %s '%s'", "wifi", self.commissioning_instance_wifi), 2) + tasmota.log(format("MTR: calling mdns.remove_service(%s, %s, %s, %s)", "_matterc", "_udp", self.commissioning_instance_wifi, self.hostname_wifi), 3) + tasmota.log(format("MTR: remove mDNS on %s '%s'", "wifi", self.commissioning_instance_wifi), 3) self.mdns_pase_wifi = false mdns.remove_service("_matterc", "_udp", self.commissioning_instance_wifi, self.hostname_wifi) end @@ -903,23 +1034,22 @@ class Matter_Device # Start UDP mDNS announcements for commissioning def mdns_announce_op_discovery(fabric) import mdns - import string try var device_id = fabric.get_device_id().copy().reverse() var k_fabric = fabric.get_fabric_compressed() var op_node = k_fabric.tohex() + "-" + device_id.tohex() - tasmota.log("MTR: Operational Discovery node = " + op_node, 2) + tasmota.log("MTR: Operational Discovery node = " + op_node, 3) # mdns if (tasmota.eth().find("up")) - tasmota.log(string.format("MTR: adding mDNS on %s '%s' ptr to `%s.local`", "eth", op_node, self.hostname_eth), 3) + tasmota.log(format("MTR: adding mDNS on %s '%s' ptr to `%s.local`", "eth", op_node, self.hostname_eth), 3) mdns.add_service("_matter","_tcp", 5540, nil, op_node, self.hostname_eth) var subtype = "_I" + k_fabric.tohex() tasmota.log("MTR: adding subtype: "+subtype, 3) mdns.add_subtype("_matter", "_tcp", op_node, self.hostname_eth, subtype) end if (tasmota.wifi().find("up")) - tasmota.log(string.format("MTR: adding mDNS on %s '%s' ptr to `%s.local`", "wifi", op_node, self.hostname_wifi), 3) + tasmota.log(format("MTR: adding mDNS on %s '%s' ptr to `%s.local`", "wifi", op_node, self.hostname_wifi), 3) mdns.add_service("_matter","_tcp", 5540, nil, op_node, self.hostname_wifi) var subtype = "_I" + k_fabric.tohex() tasmota.log("MTR: adding subtype: "+subtype, 3) @@ -944,7 +1074,6 @@ class Matter_Device # Remove mDNS announce for fabric def mdns_remove_op_discovery(fabric) import mdns - import string try var device_id = fabric.get_device_id().copy().reverse() var k_fabric = fabric.get_fabric_compressed() @@ -952,11 +1081,11 @@ class Matter_Device # mdns if (tasmota.eth().find("up")) - tasmota.log(string.format("MTR: remove mDNS on %s '%s'", "eth", op_node), 2) + tasmota.log(format("MTR: remove mDNS on %s '%s'", "eth", op_node), 3) mdns.remove_service("_matter", "_tcp", op_node, self.hostname_eth) end if (tasmota.wifi().find("up")) - tasmota.log(string.format("MTR: remove mDNS on %s '%s'", "wifi", op_node), 2) + tasmota.log(format("MTR: remove mDNS on %s '%s'", "wifi", op_node), 3) mdns.remove_service("_matter", "_tcp", op_node, self.hostname_wifi) end except .. as e, m @@ -979,14 +1108,17 @@ class Matter_Device # Applies only if there are no plugins already configured ## TODO generate map instead def autoconf_device() - import string import json if size(self.plugins) > 0 return end # already configured - self.plugins_config = self.autoconf_device_map() - tasmota.log("MTR: autoconfig = " + str(self.plugins_config), 3) - self._load_plugins_config(self.plugins_config) + if !self.plugins_persist + self.plugins_config = self.autoconf_device_map() + self.plugins_config_remotes = {} + self.adjust_next_ep() + tasmota.log("MTR: autoconfig = " + str(self.plugins_config), 3) + end + self._instantiate_plugins_from_config(self.plugins_config) if !self.plugins_persist && self.sessions.count_active_fabrics() > 0 self.plugins_persist = true @@ -999,13 +1131,9 @@ class Matter_Device # # Applies only if there are no plugins already configured def autoconf_device_map() - import string import json var m = {} - # add the default plugin - m["0"] = {'type':'root'} - # check if we have a light var endpoint = 1 var light_present = false @@ -1040,14 +1168,14 @@ class Matter_Device var k = 'SHT' + str(idx) # SHT is zero based if !r_st13.contains(k) break end # no more SHTxxx var d = r_st13[k] - tasmota.log(string.format("MTR: '%s' = %s", k, str(d)), 3) - var relay1 = d.find('Relay1', 0) - 1 # relay base 0 or -1 if none - var relay2 = d.find('Relay2', 0) - 1 # relay base 0 or -1 if none + tasmota.log(format("MTR: '%s' = %s", k, str(d)), 3) + var relay1 = d.find('Relay1', -1) # relay base 1 or -1 if none + var relay2 = d.find('Relay2', -1) # relay base 1 or -1 if none - if relay1 >= 0 relays_reserved.push(relay1) end # mark relay1/2 as non-relays - if relay2 >= 0 relays_reserved.push(relay2) end + if relay1 > 0 relays_reserved.push(relay1 - 1) end # mark relay1/2 as non-relays + if relay2 > 0 relays_reserved.push(relay2 - 1) end - tasmota.log(string.format("MTR: relay1 = %s, relay2 = %s", relay1, relay2), 3) + tasmota.log(f"MTR: {relay1=} {relay2=}", 3) # is there tilt support var tilt_array = d.find('TiltConfig') var tilt_config = tilt_array && (tilt_array[2] > 0) @@ -1066,7 +1194,7 @@ class Matter_Device while relay_index < relay_count if relays_reserved.find(relay_index) == nil # if relay is actual relay - m[str(endpoint)] = {'type':'relay','relay':relay_index} + m[str(endpoint)] = {'type':'relay','relay':relay_index + 1} # Relay index start with 1 endpoint += 1 end relay_index += 1 @@ -1075,59 +1203,61 @@ class Matter_Device # auto-detect sensors var sensors = json.load(tasmota.read_sensors()) + var sensors_list = self.autoconf_sensors_list(sensors) + + for s: sensors_list + m[str(endpoint)] = s + endpoint += 1 + end + + # tasmota.publish_result('{"Matter":{"Initialized":1}}', 'Matter') # MQTT is not yet connected + return m + end + + + ############################################################# + # Autoconfigure from sensors + # + # Returns an ordered list + def autoconf_sensors_list(sensors) + var ret = [] # temperature sensors - # they are starting at endpoint `32..39` (8 max) - endpoint = 0x20 for k1:self.k2l(sensors) var sensor_2 = sensors[k1] if isinstance(sensor_2, map) && sensor_2.contains("Temperature") var temp_rule = k1 + "#Temperature" - m[str(endpoint)] = {'type':'temperature','filter':temp_rule} - endpoint += 1 + ret.push({'type':'temperature','filter':temp_rule}) end - if endpoint > 0x28 break end end # pressure sensors - # they are starting at endpoint `40..47` (8 max) - endpoint = 0x28 for k1:self.k2l(sensors) var sensor_2 = sensors[k1] if isinstance(sensor_2, map) && sensor_2.contains("Pressure") var temp_rule = k1 + "#Pressure" - m[str(endpoint)] = {'type':'pressure','filter':temp_rule} - endpoint += 1 + ret.push({'type':'pressure','filter':temp_rule}) end - if endpoint > 0x2F break end end # light sensors - # they are starting at endpoint `48..55` (8 max) - endpoint = 0x30 for k1:self.k2l(sensors) var sensor_2 = sensors[k1] if isinstance(sensor_2, map) && sensor_2.contains("Illuminance") var temp_rule = k1 + "#Illuminance" - m[str(endpoint)] = {'type':'illuminance','filter':temp_rule} - endpoint += 1 + ret.push({'type':'illuminance','filter':temp_rule}) end - if endpoint > 0x38 break end end # huidity sensors - # they are starting at endpoint `56..63` (8 max) - endpoint = 0x38 for k1:self.k2l(sensors) var sensor_2 = sensors[k1] if isinstance(sensor_2, map) && sensor_2.contains("Humidity") var temp_rule = k1 + "#Humidity" - m[str(endpoint)] = {'type':'humidity','filter':temp_rule} - endpoint += 1 + ret.push({'type':'humidity','filter':temp_rule}) end - if endpoint > 0x40 break end end - # tasmota.publish_result('{"Matter":{"Initialized":1}}', 'Matter') - return m + + return ret end # get keys of a map in sorted order @@ -1158,7 +1288,7 @@ class Matter_Device # get a class name light "light0" and return displayname def get_plugin_class_displayname(name) var cl = self.plugins_classes.find(name) - return cl ? cl.NAME : "" + return cl ? cl.DISPLAY_NAME : "" end ############################################################# @@ -1184,9 +1314,109 @@ class Matter_Device self.register_plugin_class(v) end end - tasmota.log("MTR: registered classes "+str(self.k2l(self.plugins_classes)), 3) + # tasmota.log("MTR: registered classes "+str(self.k2l(self.plugins_classes)), 3) end + ############################################################# + # Dynamic adding and removal of endpoints (bridge mode) + ############################################################# + # Add endpoint + # + # Args: + # `pi_class_name`: name of the type of pluging, ex: `light3` + # `plugin_conf`: map of configuration as native Berry map + # returns endpoint number newly allocated, or `nil` if failed + def bridge_add_endpoint(pi_class_name, plugin_conf) + var pi_class = self.plugins_classes.find(pi_class_name) + if pi_class == nil tasmota.log("MTR: unknown class name '"+str(pi_class_name)+"' skipping", 3) return end + + # get the next allocated endpoint number + var ep = self.next_ep + var ep_str = str(ep) + + var pi = pi_class(self, ep, plugin_conf) + self.plugins.push(pi) + + # add to in-memoru config + # Example: {'filter': 'AXP192#Temperature', 'type': 'temperature'} + var pi_conf = {'type': pi_class_name} + # copy args + for k:plugin_conf.keys() + pi_conf[k] = plugin_conf[k] + end + # add to main + tasmota.log(format("MTR: adding endpoint = %i type:%s%s", ep, pi_class_name, self.conf_to_log(plugin_conf)), 2) + self.plugins_config[ep_str] = pi_conf + self.plugins_persist = true + self.next_ep += 1 # increment next allocated endpoint before saving + + # try saving parameters + self.save_param() + self.signal_endpoints_changed() + + return ep + end + + ############################################################# + # Remove an existing endpoint + # + def bridge_remove_endpoint(ep) + import json + + var ep_str = str(ep) + var config + var f_in + + if !self.plugins_config.contains(ep_str) + tasmota.log("MTR: Cannot remove an enpoint not configured: " + ep_str, 3) + return + end + tasmota.log(format("MTR: deleting endpoint = %i", ep), 2) + self.plugins_config.remove(ep_str) + self.plugins_persist = true + + # now remove from in-memory configuration + var idx = 0 + while idx < size(self.plugins) + if ep == self.plugins[idx].get_endpoint() + self.plugins.remove(idx) + break + else + idx += 1 + end + end + + # clean any orphan remote + self.clean_remotes() + + # try saving parameters + self.save_param() + self.signal_endpoints_changed() + end + + ############################################################# + # Signal to controller that endpoints changed via subcriptions + # + def signal_endpoints_changed() + # mark parts lists as changed + self.attribute_updated(0x0000, 0x001D, 0x0003, false) + self.attribute_updated(0xFF00, 0x001D, 0x0003, false) + end + + ############################################################# + # Adjust next_ep + # + # Make sure that next_ep (used to allow dynamic endpoints) + # will not collide with an existing ep + def adjust_next_ep() + for k: self.plugins_config.keys() + var ep = int(k) + if ep >= self.next_ep + self.next_ep = ep + 1 + end + end + end + ##################################################################### # Events ##################################################################### @@ -1215,12 +1445,94 @@ class Matter_Device end end + ##################################################################### + # Manager HTTP remotes + ##################################################################### + # register new http remote + # + # If already registered, return current instance and check timeout + def register_http_remote(addr, timeout) + if self.http_remotes == nil self.http_remotes = {} end # lazy initialization + var http_remote + + if self.http_remotes.contains(addr) + http_remote = self.http_remotes[addr] + if timeout < http_remote.get_timeout() + http_remote.set_timeout(timeout) # reduce timeout if new value is shorter + end + else + http_remote = matter.HTTP_remote(self, addr, timeout) + if self.plugins_config_remotes.contains(addr) + http_remote.set_info(self.plugins_config_remotes[addr]) + end + self.http_remotes[addr] = http_remote + end + return http_remote + end + + ##################################################################### + # Remove HTTP remotes that are no longer referenced + def clean_remotes() + import introspect + + # print("clean_remotes", self.http_remotes) + # init all remotes with count 0 + if self.http_remotes # tests if `self.http_remotes` is not `nil` and not empty + var remotes_map = {} # key: remote object, value: count of references + + for http_remote: self.http_remotes + remotes_map[http_remote] = 0 + end + # print("remotes_map", remotes_map) + + # scan all endpoints + for pi: self.plugins + var http_remote = introspect.get(pi, "http_remote") + if http_remote != nil + remotes_map[http_remote] = remotes_map.find(http_remote, 0) + 1 + end + end + + # print("remotes_map2", remotes_map) + + # tasmota.log("MTR: remotes references: " + str(remotes_map), 3) + + var remote_to_remove = [] # we first get the list of remotes to remove, to not interfere with map iterator + for remote:remotes_map.keys() + if remotes_map[remote] == 0 + remote_to_remove.push(remote) + end + end + + for remote: remote_to_remove + tasmota.log("MTR: remove unused remote: " + remote.addr, 3) + remote.close() + self.http_remotes.remove(remote.addr) + end + + end + + end + + # def get_remotes_list() + ##################################################################### + # Get sorted list of remote endpoints + # def get_remotes_list() + # var ret = [] + # for hr: self.http_remotes + # ret.push(hr.addr) + # end + # return self.sort_distinct(ret) + # end + ##################################################################### # Commands `Mtr___` ##################################################################### # def register_commands() tasmota.add_cmd("MtrJoin", /cmd_found, idx, payload, payload_json -> self.MtrJoin(cmd_found, idx, payload, payload_json)) + tasmota.add_cmd("MtrUpdate", /cmd_found, idx, payload, payload_json -> self.MtrUpdate(cmd_found, idx, payload, payload_json)) + tasmota.add_cmd("MtrInfo", /cmd_found, idx, payload, payload_json -> self.MtrInfo(cmd_found, idx, payload, payload_json)) end ##################################################################### @@ -1238,6 +1550,114 @@ class Matter_Device tasmota.resp_cmnd_done() end + ##################################################################### + # `MtrUpdate` + # + # MtrUpdate {"ep":1, "Power":1} + # MtrUpdate {"name":"ep1", "power":1} + # MtrUpdate {"Name":"Light0", "Power":0} + # MtrUpdate {"Name":"Light0", "Power":1} + # MtrUpdate {"Name":"Light1", "Power":0} + # MtrUpdate {"Name":"Light1", "Power":1,"Bri":55} + # MtrUpdate {"Name":"Light2", "Power":0} + # MtrUpdate {"Name":"Light2", "Power":1, "CT":400, "Bri":20} + # MtrUpdate {"Name":"Light3", "Power":0} + # MtrUpdate {"Name":"Light3", "Power":1, "Bri":20, "Hue":85, "Sat":200} + # + def MtrUpdate(cmd_found, idx, payload, payload_json) + if payload_json == nil return tasmota.resp_cmnd_str("Invalid JSON") end + + var key_ep = tasmota.find_key_i(payload_json, 'Ep') + var key_name = tasmota.find_key_i(payload_json, 'Name') + if key_ep || key_name + var pl = nil # plugin instance + + if key_ep + var ep = int(payload_json[key_ep]) + if ep <= 0 return tasmota.resp_cmnd_str("Invalid 'Ep' attribute") end + pl = self.find_plugin_by_endpoint(ep) + payload_json.remove(key_ep) + end + + if key_name + if pl == nil + pl = self.find_plugin_by_friendly_name(payload_json[key_name]) + end + payload_json.remove(key_name) + end + + if (pl == nil) return tasmota.resp_cmnd_str("Invalid Device") end + if (!pl.VIRTUAL) return tasmota.resp_cmnd_str("Device is not virtual") end + # filter parameter accedpted by plugin, and rename with canonical + # Ex: {"power":1,"HUE":2} becomes {"Power":1,"Hue":2} + var uc = pl.consolidate_update_commands() + # check that all commands are in the list of supported commands + var cmd_cleaned = {} + for k: payload_json.keys() + var cleaned_command_idx = tasmota.find_list_i(uc, k) + if (cleaned_command_idx == nil) + tasmota.resp_cmnd_str(f"Invalid command '{payload_json[k]}'") + return + end + cmd_cleaned[uc[cleaned_command_idx]] = payload_json[k] + end + # call plug-in + pl.update_virtual(cmd_cleaned) + var state_json = pl.state_json() + if state_json + var cmnd_status = f'{{"{cmd_found}":{state_json}}}' + return tasmota.resp_cmnd(cmnd_status) + else + return tasmota.resp_cmnd_done() + end + end + + tasmota.resp_cmnd_str("Missing 'Device' attribute") + end + + ##################################################################### + # `MtrInfo` + # + # MtrInfo 9 + def MtrInfo(cmd_found, idx, payload, payload_json) + if payload == "" + # dump all devices + end + + if payload == "" + # dump all + for pl: self.plugins + self.MtrInfo_one(pl.endpoint) + end + + elif type(payload_json) == 'int' + # try ep number + self.MtrInfo_one(payload_json) + + else + # try by name + var pl = self.find_plugin_by_friendly_name(payload) + if pl != nil + self.MtrInfo_one(pl.endpoint) + end + end + + tasmota.resp_cmnd_done() + end + + # output for a single endpoint + def MtrInfo_one(ep) + var pl = self.find_plugin_by_endpoint(ep) + if pl == nil return end # abort + + var state_json = pl.state_json() + if state_json + var mtr_info = f'{{"' 'MtrInfo"' ':{state_json}}}' + # publish + # tasmota.publish_rule(mtr_info) + tasmota.publish_result(mtr_info, "") + end + end end matter.Device = Matter_Device diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Expirable.be b/lib/libesp32/berry_matter/src/embedded/Matter_Expirable.be index 391476982bc2..83da9d5d42bc 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Expirable.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Expirable.be @@ -96,7 +96,7 @@ class Matter_Expirable # set relative time in the future for expiration (in seconds) def set_expire_in_seconds(s, now) if s == nil return end - if now == nil now = tasmota.rtc()['utc'] end + if now == nil now = tasmota.rtc_utc() end self.set_expire_time(now + s) end @@ -104,7 +104,7 @@ class Matter_Expirable # set relative time in the future for expiration (in seconds) # returns `true` if expiration date has been reached def has_expired(now) - if now == nil now = tasmota.rtc()['utc'] end + if now == nil now = tasmota.rtc_utc() end if self._expiration != nil return now >= self._expiration end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Fabric.be b/lib/libesp32/berry_matter/src/embedded/Matter_Fabric.be index aee02ef36db6..2681197f2402 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Fabric.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Fabric.be @@ -75,7 +75,7 @@ class Matter_Fabric : Matter_Expirable self._store = store self._sessions = matter.Expirable_list() self.fabric_label = "" - self.created = tasmota.rtc()['utc'] + self.created = tasmota.rtc_utc() # init group counters self._counter_group_data_snd_impl = matter.Counter() self._counter_group_ctrl_snd_impl = matter.Counter() @@ -95,7 +95,66 @@ class Matter_Fabric : Matter_Expirable def get_ca() return self.root_ca_certificate end def get_fabric_index() return self.fabric_index end + def get_admin_vendor_name() + var vnd = self.admin_vendor + if vnd == nil return "" end + var name = matter.get_vendor_name(vnd) + if name != nil + return name + else + return f"0x{vnd:04X}" + end + end + def set_fabric_index(v) self.fabric_index = v end + def set_ca(ca) + self.root_ca_certificate = ca + end + def set_noc_icac(noc, icac) + self.noc = noc + self.icac = icac + end + def set_ipk_epoch_key(ipk_epoch_key) + self.ipk_epoch_key = ipk_epoch_key + end + def set_admin_subject_vendor(admin_subject, admin_vendor) + self.admin_subject = admin_subject + self.admin_vendor = admin_vendor + end + + def set_fabric_device(fabric_id, device_id, fc, fabric_parent) + self.fabric_id = fabric_id + self.device_id = device_id + self.fabric_compressed = fc + self.fabric_parent = (fabric_parent != nil) ? fabric_parent.get_fabric_index() : nil + end + + ############################################################# + # Generate a private key (or retrieve it) + # + # PK is generated by a commissioning session + def get_pk() + return self.no_private_key + end + def set_pk(pk) + self.no_private_key = pk + end + + ############################################################# + # Register the frabric as complete (end of commissioning) + def fabric_candidate() + self.set_expire_in_seconds(120) # expire in 2 minutes + self.assign_fabric_index() + self._store.add_fabric(self) + end + + ############################################################# + # Assign a new fabric index + def assign_fabric_index() + if (self.get_fabric_index() == nil) + self.set_fabric_index(self._store.next_fabric_idx()) + end + end ############################################################# # When hydrating from persistance, update counters @@ -109,15 +168,23 @@ class Matter_Fabric : Matter_Expirable self.counter_group_ctrl_snd = self._counter_group_ctrl_snd_impl.val() end + ############################################################# + # Register the fabric as complete (end of commissioning) + def fabric_completed() + self.set_no_expiration() + self.set_persist(true) + self.assign_fabric_index() + self._store.add_fabric(self) + end + ############################################################# # Management of security counters ############################################################# # Provide the next counter value, and update the last know persisted if needed # def counter_group_data_snd_next() - import string var next = self._counter_group_data_snd_impl.next() - tasmota.log(string.format("MTR: . Counter_group_data_snd=%i", next), 3) + tasmota.log(f"MTR: . Counter_group_data_snd={next:i}", 3) if matter.Counter.is_greater(next, self.counter_group_data_snd) self.counter_group_data_snd = next + self._GROUP_SND_INCR if self.does_persist() @@ -131,9 +198,8 @@ class Matter_Fabric : Matter_Expirable # Provide the next counter value, and update the last know persisted if needed # def counter_group_ctrl_snd_next() - import string var next = self._counter_group_ctrl_snd_impl.next() - tasmota.log(string.format("MTR: . Counter_group_ctrl_snd=%i", next), 3) + tasmota.log(f"MTR: . Counter_group_ctrl_snd={next:i}", 3) if matter.Counter.is_greater(next, self.counter_group_ctrl_snd) self.counter_group_ctrl_snd = next + self._GROUP_SND_INCR if self.does_persist() @@ -147,15 +213,13 @@ class Matter_Fabric : Matter_Expirable ############################################################# # Called before removal def log_new_fabric() - import string - tasmota.log(string.format("MTR: +Fabric fab='%s'", self.get_fabric_id().copy().reverse().tohex()), 2) + tasmota.log(format("MTR: +Fabric fab='%s' vendorid=%s", self.get_fabric_id().copy().reverse().tohex(), self.get_admin_vendor_name()), 3) end ############################################################# # Called before removal def before_remove() - import string - tasmota.log(string.format("MTR: -Fabric fab='%s' (removed)", self.get_fabric_id().copy().reverse().tohex()), 2) + tasmota.log(format("MTR: -Fabric fab='%s' (removed)", self.get_fabric_id().copy().reverse().tohex()), 3) end ############################################################# @@ -183,7 +247,9 @@ class Matter_Fabric : Matter_Expirable def add_session(s) if self._sessions.find(s) == nil while size(self._sessions) >= self._MAX_CASE - self._sessions.remove(self._sessions.find(self.get_oldest_session())) + var session_deleted = self.get_oldest_session() + self._sessions.remove(self._sessions.find(session_deleted)) + self._store.remove_session(session_deleted) end self._sessions.push(s) end @@ -218,7 +284,6 @@ class Matter_Fabric : Matter_Expirable ############################################################# def tojson() import json - import string import introspect self.persist_pre() @@ -234,7 +299,7 @@ class Matter_Fabric : Matter_Expirable var v = introspect.get(self, k) if v == nil continue end if isinstance(v, bytes) v = "$$" + v.tob64() end # bytes - r.push(string.format("%s:%s", json.dump(str(k)), json.dump(v))) + r.push(format("%s:%s", json.dump(str(k)), json.dump(v))) end # add sessions diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_HTTP_async.be b/lib/libesp32/berry_matter/src/embedded/Matter_HTTP_async.be new file mode 100644 index 000000000000..3d9abbf95326 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_HTTP_async.be @@ -0,0 +1,415 @@ +# +# Matter_HTTP_async.be - implements a generic async non-blocking TCP connection +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +#@ solidify:Matter_HTTP_async,weak + +# dummy declaration for solidification +class Matter_TCP_async end + +class Matter_HTTP_async : Matter_TCP_async + # var addr # remote address + # var port # remote port + # var timeout # timeout in ms + # var tcp # instance of tcpclientasync + # var time_start # timestamp when starting connection + # var tcp_connected # is tcp connected, true/false/nil (nil is in-progress) + var cmd # GET url command + var response # aggrated response + var response_offset # offset to parse in response + var status_code # status code looking for 200 + var payload # actual payload of the response (string) + # var status # status, see above + var http_status # status: 0/ in progress, 1/ finished ok, -1/ failed, -2/ timeout + # static var TIMEOUT = 1000 # default timeout: 500ms + var phase # parsing phase: 0/ status line, 1/ headers, 2/ payload chunked + var is_chunked # true if the content is chunked + var chunk_size # nil or int, size of the current chunk + static var HTTP_GET = "GET %s HTTP/1.1\r\nHost %s:%s\r\nConnection: close\r\n\r\n" # see https://stackoverflow.com/questions/6686261/what-at-the-bare-minimum-is-required-for-an-http-request + + static var HTTP_STATUS_REGEX = "HTTP/1\\.[0-1] (\\d+) .*?\r\n" # extract stattus code from first line + static var HTTP_HEADER_REGEX = "([A-Za-z0-9-]+): (.*?)\r\n" # extract a header with its 2 parts + static var HTTP_BODY_REGEX = "\r\n" # end of headers + static var HTTP_CHUNK_REGEX = "\r\n([A-Fa-f0-9]+)[ \t]*.*?\r\n" # extract the length of a chunk + static var SPINLOCK = 5 # delay in ms for spinlock + + ############################################################# + # init + def init(addr, port, timeout, fastloop) + super(self).init(addr, port, timeout, fastloop) + self.compile_re() + end + + ############################################################# + # compile once for all the regex + def compile_re() + import re + if !global.contains("_re_http_status") + global._re_http_status = re.compile(self.HTTP_STATUS_REGEX) + global._re_http_header = re.compile(self.HTTP_HEADER_REGEX) + global._re_http_body = re.compile(self.HTTP_BODY_REGEX) + global._re_http_chunk = re.compile(self.HTTP_CHUNK_REGEX) + end + end + + ############################################################# + # begin + # + # returns true if everything is ok, and connection started + # returns false if DNS failed + # returns nil if no network + def begin(cmd) + var ret = super(self).begin() + self.cmd = cmd + return ret + end + + ############################################################# + # begin_sync + # + # Synchronous (blocking version) + # + # returns nil if something went wrong + # returns the payload as string + def begin_sync(cmd, timeout) + var timeout_old = self.timeout + if timeout != nil self.set_timeout(timeout) end + var payload = nil + var spinlock = self.SPINLOCK + + # try + var ret = self.begin(cmd) + if ret # true just means that DNS was ok and that nothing went wrong + while self.http_status == 0 + self.loop() + tasmota.delay(spinlock) + end + end + + self.set_timeout(timeout_old) + return self.http_status > 0 ? self.payload : nil + end + + def reset() + super(self).reset() + # free buffers + self.cmd = nil + self.response = nil + self.response_offset = 0 + self.payload = "" + self.phase = 0 + self.http_status = 0 + self.is_chunked = false + self.chunk_size = nil + end + + ############################################################# + # parse_http_response + # + # Parse incoming HTTP response from self.response + def parse_http_response() + if self.phase == 0 + self.parse_http_status_line() + elif self.phase == 1 + self.parse_http_headers() + elif self.phase == 2 + self.parse_http_payload() + end + # if phase == 3 (payload raw) we don't parse anything and work for tcp connection to be closed + end + + ############################################################# + # parse_http_status_line + # + # Parse incoming HTTP status line + def parse_http_status_line() + var m = global._re_http_status.match2(self.response, self.response_offset) + # Ex: [17, '200'] + if m + self.response_offset = m[0] # move to following bytes + self.status_code = int(m[1]) + self.phase = 1 # proceed to parsing headers + self.parse_http_headers() + elif size(self.response) > 100 # if no match and we still have 100 bytes, then it fails + self.close() + self.status = -4 + end + end + + ############################################################# + # parse_http_status_line + # + # Parse incoming HTTP status line + def parse_http_headers() + while true + # print("parse_http_headers", "self.response_offset=", self.response_offset) + var m = global._re_http_header.match2(self.response, self.response_offset) + # print("m=", m) + # Ex: [32, 'Content-Type', 'application/json'] + if m + self.event_http_header(m[1], m[2]) + self.response_offset += m[0] + else # no more headers + var m2 = global._re_http_body.match2(self.response, self.response_offset) + if m2 + # end of headers + # we keep \r\n which is used by pattern + self.event_http_headers_end() # no more headers + self.phase = 2 + self.parse_http_payload() # continue to parsing payload + end + if size(self.response) > 1024 # we don't accept a single header larger than 1KB + self.close() + self.status = -4 + self.http_status = -1 + self.event_http_failed() + end + return + end + end + end + + ############################################################# + # parse_http_status_line + # + # Parse incoming HTTP status line + def parse_http_payload() + if self.is_chunked + while true + # if no current chunk size + if self.chunk_size == nil + var m = global._re_http_chunk.match2(self.response, self.response_offset) + if m + self.response_offset += m[0] + self.chunk_size = int('0x'+m[1]) + # if chunk size is zero, finished + if self.chunk_size == 0 + self.status = 2 # finished + self.response = '' # free space + self.response_offset = 0 + self.close() + # if self.http_status == 0 # this is now handled by the close event + # self.http_status = 1 + # self.event_http_finished() + # end + return + end + end + end + # do we have a chunk size + if self.chunk_size != nil + # print("chunk_size", self.chunk_size, size(self.response) - self.response_offset) + if self.chunk_size <= size(self.response) - self.response_offset + # we have a complete chunk in the buffer + self.payload += self.response[self.response_offset .. self.response_offset + self.chunk_size - 1] + self.response = self.response[self.response_offset + self.chunk_size .. ] # truncate to save space + self.response_offset = 0 + self.chunk_size = nil + # print(bytes().fromstring(self.response).tohex()) + else + return # return until more data is received + end + else + return + end + end + else + # non-chunked + self.payload += self.response[self.response_offset..] + self.response = "" + self.response_offset = 0 + end + end + + ############################################################# + # send_http + # + # Send http request + def send_http() + import string + # "GET %s HTTP/1.1\r\nHost %s:%s\r\nConnection: close\r\n\r\n" + self.response = "" + + # special formatting for IPv6 + var addr = self.addr + if string.find(addr, ':') >= 0 + addr = "[" + addr + "]" # IPv6 must be enclosed in brakets + end + + var req = format(self.HTTP_GET, self.cmd, addr, self.port) + var ret = self.write(req) + if ret != size(req) + # print("Could not send","size=",size(req),"ret=",ret) + self.close() + self.status = -4 + self.http_status = -1 + self.event_http_failed() + end + end + + + ############################################################# + # Events: method should be overriden + ############################################################# + # From TCP + # event_established: connection was established + # event_dnsfailed: dns resolution failed + # event_refused: connection was refused by peer + # event_timeout: connection timed out + # event_closed: connection was normally closed (after being established) + # event_available: incoming data is ready to be retrieved with `read()` or `readbytes()` + # event_listening: outgoing buffer is empty, ready to send data with `write()` + # From HTTP + # event_http_status_code: received HTTP status code (stored in `status_code`) + # event_http_header: received HTTP header (not stored except `is_chunked`) + # event_http_headers_end: all HTTP headers received + # Always finishes with one of: + # event_http_finished: HTTP finished, result is in `payload` + # event_http_failed: HTTP connection failed (not a timeout) + # event_http_timeout: HTTP timeout + + ############################################################# + # event_established + # + # When connection is established, we send the GET request in + # a single write, and we don't need to send anything more + def event_established() + self.send_http() + end + + ############################################################# + # event_available + # + # Data received + def event_available() + self.receive() + end + + ############################################################# + # event_http_status_code + # + # Received status_code + def event_http_status_code(status_code, status_message) + self.status_code = status_code + end + + ############################################################# + # event_http_header + # + # Received header + def event_http_header(header_key, header_value) + import string + header_key = string.tolower(header_key) + header_value = string.tolower(header_value) + # print("header=", header_key, header_value) + if header_key == 'transfer-encoding' && string.tolower(header_value) == 'chunked' + self.is_chunked = true + end + end + + ############################################################# + # event_http_headers_end + # + # All headers are received + def event_http_headers_end() + # print("event_http_headers_end") + # truncate to save space + if self.response_offset > 0 + self.response = self.response[self.response_offset .. ] + self.response_offset = 0 + end + end + + ############################################################# + # receive + # + # Receive and collate + def receive() + if self.tcp_connected != true return end # not connected + + if (tasmota.millis() - self.time_start) > self.timeout + # connection timeout + # print("Connected timeout in", tasmota.millis() - self.time_start, "ms") + self.status = -3 + self.close() + self.http_status = -2 + self.event_http_timeout() + else + + var avail = self.tcp.available() + var new_data = 0 + while avail > 0 + var s = self.tcp.read() + # print("read size=", size(s), "avail=", avail, "in", tasmota.millis() - self.time_start, "ms") + self.response += s + new_data += size(s) + avail = self.tcp.available() + end + + if new_data > 0 + # print("read size=", new_data, "in", tasmota.millis() - self.time_start, "ms") + self.parse_http_response() # try to parse response + end + + end + end + + ############################################################# + # event_http_finished + # + # Transaction finished sucessfully, result in self.payload + def event_http_finished() end + def event_closed() + if self.http_status == 0 + self.http_status = 1 + self.event_http_finished() + end + end + + ############################################################# + # event_http_failed + # + # Transaction finished sucessfully, result in self.payload + def event_http_failed() end + def event_refused() self.http_status = -1 self.event_http_failed() end + ############################################################# + # event_http_timeout + # + # Transaction finished sucessfully, result in self.payload + def event_http_timeout() end + def event_timeout() self.http_status = -2 self.event_http_timeout() end + +end +matter.HTTP_async = Matter_HTTP_async + +#- + +# Example + +tcp = matter.HTTP_async("192.168.2.200", 80, 1000) +tcp.begin("/cm?cmnd=Status%208") +tcp.begin("/") + +# Synchronous examples +tcp = matter.HTTP_async("192.168.2.200", 80, 1000) +print(tcp.begin_sync("/cm?cmnd=Status%208", 500)) +print(tcp.begin_sync("/", 500)) + +-# diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_HTTP_remote.be b/lib/libesp32/berry_matter/src/embedded/Matter_HTTP_remote.be new file mode 100644 index 000000000000..b466dc83d2b2 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_HTTP_remote.be @@ -0,0 +1,352 @@ +# +# Matter_HTTP_remote.be - implements an interface to query remotely Tasmota device via HTTP +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +#@ solidify:Matter_HTTP_remote,weak + +# dummy declaration for solidification +class Matter_HTTP_async end + +############################################################# +# This class has the following purposes: +# +# 1. Have multiple classes registered for async requests +# and dispatch to all instances results calling `cb(status, payload, index)` +# Async requests are currently only `Status ` requests +# and are dispatched with the `` index +# +# 2. Implement rate limiting when sending async `Status ` +# requests to align with the lowest cycle time. +# I.e. if plugin sends every 2 seconds and another every 3 seconds +# we only send every 2 seconds and dispatch results to all plugins. + +class Matter_HTTP_remote : Matter_HTTP_async + var device # reference to matter_device + var probe_update_time_map # number of milliseconds to wait for each async command (map) + var probe_next_timestamp_map # timestamp for last probe (in millis()) for each `Status ` + # if timestamp is `0`, this should be scheduled in priority + var async_cb_map # list of callbacks to call with `cb(http_status, payload)` + + # information about current async command in-flight + var current_cmd # current async command + # `nil` if current request is synchronous + var reachable # is the device reachable + var reachable_utc # last tick when the reachability was seen (avoids sending superfluous ping commands) + + # information gathered about the remote device (name, version...) + static var UPDATE_TIME = 5000 # update every 5s until first response + static var UPDATE_TIME2 = 300000 # then update every 5 minutes + static var UPDATE_CMD0 = "Status" # command to send for updates + static var UPDATE_CMD2 = "Status 2" # command to send for updates + static var UPDATE_CMD5 = "Status 5" # command to send for updates + var info # as a map + + ############################################################# + # init + def init(device, addr, timeout, fastloop) + self.device = device # if device is null, it's a temporary object not linked to a device + self.probe_update_time_map = {} + self.probe_next_timestamp_map = {} + self.async_cb_map = {} + self.current_cmd = nil + self.reachable = false # force a valid bool value + super(self).init(addr, 80, timeout, fastloop) + + # set up some reading information about the device + self.info = {} + if self.device + # we need different callbacks per command (don't create a single one for both calls) + self.add_schedule(self.UPDATE_CMD0, self.UPDATE_TIME, / status,payload,cmd -> self.parse_status_response(status,payload,cmd)) + self.add_schedule(self.UPDATE_CMD2, self.UPDATE_TIME, / status,payload,cmd -> self.parse_status_response(status,payload,cmd)) + self.add_schedule(self.UPDATE_CMD5, self.UPDATE_TIME, / status,payload,cmd -> self.parse_status_response(status,payload,cmd)) + end + end + + ############################################################# + # get/set remote_info map + def get_info() return self.info end + def set_info(v) self.info = v end + def info_changed() self.device.save_param() end # send a signal to global device that remote information changed + + ############################################################# + # parse response for `Status` and `Status 2` + def parse_status_response(status, payload, cmd) + if status != nil && status > 0 + # device is known to be reachable + self.device_is_alive(true) + + import json + var j = json.load(payload) + var code = nil # index of Status + if j + # filter + if j.contains("Status") # Status 0 (actually `Status` wihtout any number) + j = j["Status"] + code = 0 + elif j.contains("StatusFWR") # Status 2 + j = j["StatusFWR"] + code = 2 + elif j.contains("StatusNET") # Status 5 + j = j["StatusNET"] + code = 5 + end + # convert to shadow values + self.parse_update(j, code) # call parser + end + end + end + + ############################################################# + # Stub for updating shadow values (local copies of what we published to the Matter gateway) + # + # This call is synnchronous and blocking. + def parse_update(data, index) + var changed = false + if index == 0 # Status + var device_name = data.find("DeviceName") # we consider 'Tasmota' as the non-information default + if device_name == "Tasmota" device_name = nil end + + # did the value changed? + if self.info.find('name') != device_name + if device_name != nil + self.info['name'] = device_name + else + self.info.remove("name") + end + tasmota.log(f"MTR: update '{self.addr}' name='{device_name}'", 3) + changed = true + end + + # reduce the update time after a read is succesful + self.change_schedule(self.UPDATE_CMD0, self.UPDATE_TIME2) + elif index == 2 # Status 2 + var version = data.find("Version") + var hardware = data.find("Hardware") + + if self.info.find('version') != version + if version != nil + self.info['version'] = version + else + self.info.remove('version') + end + tasmota.log(f"MTR: update '{self.addr}' version='{version}'", 3) + changed = true + end + + if self.info.find('hardware') != hardware + if hardware != nil + self.info['hardware'] = hardware + else + self.info.remove('hardware') + end + tasmota.log(f"MTR: update '{self.addr}' hardware='{hardware}'", 3) + changed = true + end + + # reduce the update time after a read is succesful + self.change_schedule(self.UPDATE_CMD2, self.UPDATE_TIME2) + elif index == 5 + var mac = data.find("Mac") + + # did the value changed? + if self.info.find('mac') != mac + if mac != nil + self.info['mac'] = mac + else + self.info.remove("mac") + end + tasmota.log(f"MTR: update '{self.addr}' mac='{mac}'", 3) + changed = true + end + + # reduce the update time after a read is succesful + self.change_schedule(self.UPDATE_CMD5, self.UPDATE_TIME2) + end + + if changed self.info_changed() end + end + + ############################################################# + # device is alive, update reachable_utc + def device_is_alive(alive) + if alive + # device is known to be reachable + self.reachable = true + self.reachable_utc = tasmota.rtc_utc() + else + self.reachable = false + end + end + + ############################################################# + # Add an async command to scheduler + # + # cmd: the Tasmota command as string + # update_time: recurrence in ms (min time of all updates) + # cb: callback to this command (optional) + def add_schedule(cmd, update_time, cb) + if !self.probe_update_time_map.contains(cmd) || update_time < self.probe_update_time_map[cmd] + # if cmd is not already registered, or if the update_time needs to be reduced + self.probe_update_time_map[cmd] = update_time + self.probe_next_timestamp_map[cmd] = matter.jitter(update_time) + end + + # do we add a cb? + if cb != nil + self.add_async_cb(cb, cmd) + end + end + + ############################################################# + # Change schedule of current cmd + def change_schedule(cmd, update_time) + if self.probe_update_time_map.contains(cmd) + self.probe_update_time_map[cmd] = update_time + self.probe_next_timestamp_map[cmd] = matter.jitter(update_time) + end + end + + ############################################################# + # Add a callback to be called for a specific `cmd` or `nil` for all commands + def add_async_cb(cb, cmd) + self.async_cb_map[cb] = cmd + end + + ############################################################# + # Send event to all registered cb + # + def dispatch_cb(status, payload) + var idx = 0 + for cb: self.async_cb_map.keys() + var cmd_filter = self.async_cb_map[cb] + if cmd_filter == self.current_cmd || cmd_filter == nil # match command or match any + cb(status, payload, self.current_cmd) # call cb + end + end + end + + ############################################################# + # probe_async + # + # Sends a command like `Status ` asynchronously to get device status. + # Implement rate limiting for devices with multiple sub-devices + def probe_async(cmd) + import string + import webserver + if !tasmota.wifi()['up'] && !tasmota.eth()['up'] return nil end # no network + + self.current_cmd = cmd + var cmd_url = "/cm?cmnd=" + string.tr(cmd, ' ', '+') + tasmota.log(format("MTR: HTTP async request 'http://%s:%i%s'", self.addr, self.port, cmd_url), 3) + var ret = self.begin(cmd_url) + end + + ############################################################# + # begin_sync + # + # Synchronous (blocking version) + # + # returns nil if something went wrong + # returns the payload as string + # Note: sync request aborts any ongoing async request + def call_sync(cmd, timeout) + import string + import webserver + if !tasmota.wifi()['up'] && !tasmota.eth()['up'] return nil end # no network + + self.current_cmd = nil + var cmd_url = "/cm?cmnd=" + string.tr(cmd, ' ', '+') + tasmota.log(format("MTR: HTTP sync request 'http://%s:%i%s'", self.addr, self.port, cmd_url), 3) + var ret = super(self).begin_sync(cmd_url, timeout) + var payload_short = (ret) ? ret : 'nil' + if size(payload_short) > 30 payload_short = payload_short[0..29] + '...' end + tasmota.log(format("MTR: HTTP sync-resp in %i ms from %s: [%i] '%s'", tasmota.millis() - self.time_start, self.addr, size(self.payload), payload_short), 3) + return ret + end + + def event_http_finished() + if self.current_cmd == nil return end # do nothing if sync request + var payload_short = (self.payload != nil) ? self.payload : 'nil' + if size(payload_short) > 30 payload_short = payload_short[0..29] + '...' end + tasmota.log(format("MTR: HTTP async-resp in %i ms from %s: [%i] '%s'", tasmota.millis() - self.time_start, self.addr, size(self.payload), payload_short), 3) + self.dispatch_cb(self.http_status, self.payload) + end + def event_http_failed() + if self.current_cmd == nil return end # do nothing if sync request + tasmota.log("MTR: HTTP failed", 3) + self.dispatch_cb(self.http_status, nil) + end + def event_http_timeout() + if self.current_cmd == nil return end # do nothing if sync request + tasmota.log(format("MTR: HTTP timeout http_status=%i phase=%i tcp_status=%i size_payload=%i", self.http_status, self.phase, self.status, size(self.payload)), 3) + self.dispatch_cb(self.http_status, nil) + end + + ############################################################# + # scheduler + # + # check if the timer expired and update_shadow() needs to be called + def scheduler() + var cmd = nil # keep trakck of command + for k: self.probe_next_timestamp_map.keys() + if self.probe_next_timestamp_map[k] == 0 + cmd = k # schedule in priority + break + end + end + + if cmd == nil # if no priotity, find first eligible + for k: self.probe_next_timestamp_map.keys() + if tasmota.time_reached(self.probe_next_timestamp_map[k]) + cmd = k + break + end + end + end + + if cmd == nil return end # nothing to do + + if self.tcp_connected # we have already an async request in-flight + self.probe_next_timestamp_map[cmd] = 0 # mark as priority scheduling for near future + return + end + + # set new next timestamp + self.probe_next_timestamp_map[cmd] = tasmota.millis(self.probe_update_time_map[cmd]) # add update_time for command + + # trigger the command + self.probe_async(cmd) + end + + ############################################################# + # web_last_seen + # + # Show when the device was last seen + def web_last_seen() + import webserver + + var seconds = -1 # default if no known value + if self.reachable_utc != nil + seconds = tasmota.rtc_utc() - self.reachable_utc + end + return matter.seconds_to_dhm(seconds) + end +end +matter.HTTP_remote = Matter_HTTP_remote diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_IM.be b/lib/libesp32/berry_matter/src/embedded/Matter_IM.be index 50c17bd82a06..9f4c8613dced 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_IM.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_IM.be @@ -28,30 +28,53 @@ class Matter_IM var device var subs_shop # subscriptions shop - var send_queue # list of IM_Message queued for sending as part of exchange-id + var send_queue # list of IM_Message queued for sending as part of exchange-id + var read_request_solo # instance of ReadRequestMessage_solo to optimize single reads + var invoke_request_solo # instance of InvokeRequestMessage_solo to optimize single reads + var tlv_solo # instance of Matter_TLV_item for simple responses + def init(device) self.device = device self.send_queue = [] self.subs_shop = matter.IM_Subscription_Shop(self) + self.read_request_solo = matter.ReadRequestMessage_solo() + self.invoke_request_solo = matter.InvokeRequestMessage_solo() + self.tlv_solo = matter.TLV.Matter_TLV_item() end def process_incoming(msg) - # messages are always TLV, decode payload - # tasmota.log("MTR: received IM message " + matter.inspect(msg), 3) + var opcode = msg.opcode + + # Fast-Track processing + # first pass is optimized for simple frequent messages and avoids complete decoding of TLV + if opcode == 0x02 # Read Request + var read_request_solo = self.read_request_solo.from_raw(msg.raw, msg.app_payload_idx) + if read_request_solo != nil + # tasmota.log(f"MTR: process_incoming {read_request_solo=}") + return self.process_read_request_solo(msg, read_request_solo) + end + elif opcode == 0x08 # Invoke Request + var invoke_request_solo = self.invoke_request_solo.from_raw(msg.raw, msg.app_payload_idx) + # tasmota.log(f"MTR: {invoke_request_solo=} {msg.raw[msg.app_payload_idx .. ].tohex()} {msg.app_payload_idx=} {msg.raw.tohex()}") + if invoke_request_solo != nil + return self.process_invoke_request_solo(msg, invoke_request_solo) + end + end + + # tasmota.log("MTR: received IM message " + matter.inspect(msg), 3) var val = matter.TLV.parse(msg.raw, msg.app_payload_idx) # tasmota.log("MTR: IM TLV: " + str(val), 3) - var InteractionModelRevision = val.findsubval(0xFF) + # var InteractionModelRevision = val.findsubval(0xFF) # tasmota.log("MTR: InteractionModelRevision=" + (InteractionModelRevision != nil ? str(InteractionModelRevision) : "nil"), 4) - var opcode = msg.opcode if opcode == 0x01 # Status Response return self.process_status_response(msg, val) elif opcode == 0x02 # Read Request - self.send_ack_now(msg) + # self.send_ack_now(msg) # to improve latency, we don't automatically Ack on invoke request return self.process_read_request(msg, val) elif opcode == 0x03 # Subscribe Request self.send_ack_now(msg) @@ -66,7 +89,7 @@ class Matter_IM elif opcode == 0x07 # Write Response return self.process_write_response(msg, val) elif opcode == 0x08 # Invoke Request - self.send_ack_now(msg) + # self.send_ack_now(msg) # to improve latency, we don't automatically Ack on invoke request return self.process_invoke_request(msg, val) elif opcode == 0x09 # Invoke Response return self.process_invoke_response(msg, val) @@ -83,10 +106,9 @@ class Matter_IM # # return `true` if handled def process_incoming_ack(msg) - import string # check if there is an exchange_id interested in receiving this var message = self.find_sendqueue_by_exchangeid(msg.exchange_id) - tasmota.log(string.format("MTR: process_incoming_ack exch=%i message=%i", msg.exchange_id, message != nil ? 1 : 0), 3) + # tasmota.log(format("MTR: process_incoming_ack exch=%i message=%i", msg.exchange_id, message != nil ? 1 : 0), 4) if message return message.ack_received(msg) # dispatch to IM_Message end @@ -98,6 +120,7 @@ class Matter_IM # # returns `true` if packet could be sent def send_ack_now(msg) + if msg == nil return end msg.session._message_handler.send_encrypted_ack(msg, false #-not reliable-#) end @@ -116,7 +139,7 @@ class Matter_IM end if message.finish - tasmota.log("MTR: remove IM message exch="+str(message.resp.exchange_id), 3) + tasmota.log("MTR: remove IM message exch="+str(message.resp.exchange_id), 4) self.send_queue.remove(idx) else idx += 1 @@ -179,18 +202,17 @@ class Matter_IM # or raises an exception # return true if we handled the response and ack, false instead def process_status_response(msg, val) - import string var status = val.findsubval(0, 0xFF) var message = self.find_sendqueue_by_exchangeid(msg.exchange_id) if status == matter.SUCCESS if message return message.status_ok_received(msg) # re-arm the sending of next packets for the same exchange else - tasmota.log(string.format("MTR: >OK (%6i) exch=%i not found", msg.session.local_session_id, msg.exchange_id), 3) # don't show 'SUCCESS' to not overflow logs with non-information + tasmota.log(format("MTR: >OK (%6i) exch=%i not found", msg.session.local_session_id, msg.exchange_id), 4) # don't show 'SUCCESS' to not overflow logs with non-information end else # error - tasmota.log(string.format("MTR: >Status ERROR = 0x%02X", status), 2) + tasmota.log(format("MTR: >Status ERROR = 0x%02X", status), 3) if message message.status_error_received(msg) self.remove_sendqueue_by_exchangeid(msg.exchange_id) @@ -203,8 +225,7 @@ class Matter_IM # Inner code shared between read_attributes and subscribe_request # # query: `ReadRequestMessage` or `SubscribeRequestMessage` - def _inner_process_read_request(session, query, no_log) - import string + def _inner_process_read_request(session, query, msg, no_log) ### Inner function to be iterated upon # ret is the ReportDataMessage list to send back @@ -215,80 +236,114 @@ class Matter_IM # # should return true if answered, false if passing to next handler def read_single_attribute(ret, pi, ctx, direct) - import string var TLV = matter.TLV var attr_name = matter.get_attribute_name(ctx.cluster, ctx.attribute) attr_name = attr_name ? " (" + attr_name + ")" : "" + # Special case to report unsupported item, if pi==nil - var res = (pi != nil) ? pi.read_attribute(session, ctx) : nil + var res = (pi != nil) ? pi.read_attribute(session, ctx, self.tlv_solo) : nil var found = true # stop expansion since we have a value - var a1_raw # this is the bytes() block we need to add to response (or nil) + var a1_raw_or_list # contains either a bytes() buffer to append, or a list of bytes(), or nil if res != nil - var res_str = str(res) # get the value with anonymous tag before it is tagged, for logging - - var a1 = matter.AttributeReportIB() - a1.attribute_data = matter.AttributeDataIB() - a1.attribute_data.data_version = 1 - a1.attribute_data.path = matter.AttributePathIB() - a1.attribute_data.path.endpoint = ctx.endpoint - a1.attribute_data.path.cluster = ctx.cluster - a1.attribute_data.path.attribute = ctx.attribute - a1.attribute_data.data = res - - var a1_tlv = a1.to_TLV() - var a1_len = a1_tlv.encode_len() - var a1_bytes = bytes(a1_len) # pre-size bytes() to the actual size - a1_raw = a1_tlv.tlv2raw(a1_bytes) - # tasmota.log(string.format("MTR: guessed len=%i actual=%i '%s'", a1_len, size(a1_raw), a1_raw.tohex()), 2) + var res_str = "" + if !no_log + res_str = res.to_str_val() # get the value with anonymous tag before it is tagged, for logging + end + + # check if too big to encode as a single packet + if (res.is_list || res.is_array) && res.encode_len() > matter.IM_ReportData.MAX_MESSAGE + # tasmota.log(f"MTR: >>>>>> long response", 3) + a1_raw_or_list = [] # we return a list of block + var a1_raw = bytes(48) + var empty_list = TLV.Matter_TLV_array() + self.attributedata2raw(a1_raw, ctx, empty_list, false) + a1_raw_or_list.push(a1_raw) + # tasmota.log(f"MTR: >>>>>> long response global DELETE {a1_raw.tohex()}", 3) + + for elt:res.val + a1_raw = bytes(48) + # var list_item = TLV.Matter_TLV_array() + # list_item.val.push(elt) + self.attributedata2raw(a1_raw, ctx, elt, true #- add ListIndex:null -#) + # tasmota.log(f"MTR: >>>>>> long response global ADD {a1_raw.tohex()}", 3) + a1_raw_or_list.push(a1_raw) + end + # tasmota.log(f"MTR: >>>>>> long response global {a1_raw_or_list}", 3) + else + # normal encoding + # encode directly raw bytes() + a1_raw_or_list = bytes(48) # pre-reserve 48 bytes + self.attributedata2raw(a1_raw_or_list, ctx, res) + end if !no_log - tasmota.log(string.format("MTR: >Read_Attr (%6i) %s%s - %s", session.local_session_id, str(ctx), attr_name, res_str), 2) + tasmota.log(f"MTR: >Read_Attr ({session.local_session_id:6i}) {ctx}{attr_name} - {res_str}", 3) end elif ctx.status != nil if direct # we report an error only if a concrete direct read, not with wildcards - var a1 = matter.AttributeReportIB() - a1.attribute_status = matter.AttributeStatusIB() - a1.attribute_status.path = matter.AttributePathIB() - a1.attribute_status.status = matter.StatusIB() - a1.attribute_status.path.endpoint = ctx.endpoint - a1.attribute_status.path.cluster = ctx.cluster - a1.attribute_status.path.attribute = ctx.attribute - a1.attribute_status.status.status = ctx.status - - var a1_tlv = a1.to_TLV() - var a1_len = a1_tlv.encode_len() - var a1_bytes = bytes(a1_len) # pre-size bytes() to the actual size - a1_raw = a1_tlv.tlv2raw(a1_bytes) - - tasmota.log(string.format("MTR: >Read_Attr (%6i) %s%s - STATUS: 0x%02X %s", session.local_session_id, str(ctx), attr_name, ctx.status, ctx.status == matter.UNSUPPORTED_ATTRIBUTE ? "UNSUPPORTED_ATTRIBUTE" : ""), 2) + # encode directly raw bytes() + a1_raw_or_list = bytes(48) # pre-reserve 48 bytes + self.attributestatus2raw(a1_raw_or_list, ctx, ctx.status) + + if tasmota.loglevel(3) + tasmota.log(format("MTR: >Read_Attr (%6i) %s%s - STATUS: 0x%02X %s", session.local_session_id, str(ctx), attr_name, ctx.status, ctx.status == matter.UNSUPPORTED_ATTRIBUTE ? "UNSUPPORTED_ATTRIBUTE" : ""), 3) + end end else - tasmota.log(string.format("MTR: >Read_Attr (%6i) %s%s - IGNORED", session.local_session_id, str(ctx), attr_name), 2) + tasmota.log(format("MTR: >Read_Attr (%6i) %s%s - IGNORED", session.local_session_id, str(ctx), attr_name), 3) # ignore if content is nil and status is undefined found = false end - # check if we still have enough room in last block - if a1_raw # do we have bytes to add, and it's not zero size + # a1_raw_or_list if either nil, bytes(), of list(bytes()) + var idx = isinstance(a1_raw_or_list, list) ? 0 : nil # index in list, or nil if non-list + while a1_raw_or_list != nil + var elt = (idx == nil) ? a1_raw_or_list : a1_raw_or_list[idx] # dereference + if size(ret.attribute_reports) == 0 - ret.attribute_reports.push(a1_raw) # push raw binary instead of a TLV + ret.attribute_reports.push(elt) # push raw binary instead of a TLV else # already blocks present, see if we can add to the latest, or need to create a new block var last_block = ret.attribute_reports[-1] - if size(last_block) + size(a1_raw) <= matter.IM_ReportData.MAX_MESSAGE + if size(last_block) + size(elt) <= matter.IM_ReportData.MAX_MESSAGE # add to last block - last_block .. a1_raw + last_block .. elt else - ret.attribute_reports.push(a1_raw) # push raw binary instead of a TLV + ret.attribute_reports.push(elt) # push raw binary instead of a TLV + end + end + + if idx == nil + a1_raw_or_list = nil # stop loop + else + idx += 1 + if idx >= size(a1_raw_or_list) + a1_raw_or_list = nil # stop loop end end end + # check if we still have enough room in last block + # if a1_raw_or_list # do we have bytes to add, and it's not zero size + # if size(ret.attribute_reports) == 0 + # ret.attribute_reports.push(a1_raw_or_list) # push raw binary instead of a TLV + # else # already blocks present, see if we can add to the latest, or need to create a new block + # var last_block = ret.attribute_reports[-1] + # if size(last_block) + size(a1_raw_or_list) <= matter.IM_ReportData.MAX_MESSAGE + # # add to last block + # last_block .. a1_raw_or_list + # else + # ret.attribute_reports.push(a1_raw_or_list) # push raw binary instead of a TLV + # end + # end + # end + return found # return true if we had a match end var endpoints = self.device.get_active_endpoints() # structure is `ReadRequestMessage` 10.6.2 p.558 var ctx = matter.Path() + ctx.msg = msg # prepare the response var ret = matter.ReportDataMessage() @@ -300,6 +355,7 @@ class Matter_IM ctx.endpoint = q.endpoint ctx.cluster = q.cluster ctx.attribute = q.attribute + ctx.fabric_filtered = query.fabric_filtered ctx.status = matter.UNSUPPORTED_ATTRIBUTE #default error if returned `nil` # expand endpoint @@ -307,9 +363,9 @@ class Matter_IM # we need expansion, log first if ctx.cluster != nil && ctx.attribute != nil var attr_name = matter.get_attribute_name(ctx.cluster, ctx.attribute) - tasmota.log(string.format("MTR: >Read_Attr (%6i) %s", session.local_session_id, str(ctx) + (attr_name ? " (" + attr_name + ")" : "")), 2) + tasmota.log(format("MTR: >Read_Attr (%6i) %s", session.local_session_id, str(ctx) + (attr_name ? " (" + attr_name + ")" : "")), 3) else - tasmota.log(string.format("MTR: >Read_Attr (%6i) %s", session.local_session_id, str(ctx)), 2) + tasmota.log(format("MTR: >Read_Attr (%6i) %s", session.local_session_id, str(ctx)), 3) end end @@ -326,6 +382,290 @@ class Matter_IM return ret end + ############################################################# + # path2raw + # + # Encodes endpoint/cluster/attribute as `AttributePathIB` elements + # Takes sub-tag + # + # 1 = AttributePathIB + # 0 = EnableTagCompression bool opt + # 1 = Node + # 2 = Endpoint + # 3 = Cluste + # 4 = Attribute + # 5 = ListIndex (opt) + # + # 3701 1 = LIST + # 2402 01 2 = 1U (U1) + # 2403 39 3 = 0x39U (U1) + # 2404 11 4 = 0x11U (U1) + # [OPTIONAL ListIndex] + # 3405 5 = NULL + # 18 + def path2raw(raw, ctx, sub_tag, list_index_null) + # open struct + raw.add(0x37, 1) # add 37 + raw.add(sub_tag, 1) # add sub_tag + # add endpoint + if ctx.endpoint <= 0xFF # endpoint is 16 bits max + raw.add(0x2402, -2) # add 2402 + raw.add(ctx.endpoint, 1) + else + raw.add(0x2502, -2) # add 2502 + raw.add(ctx.endpoint, 2) + end + # add cluster + if ctx.cluster <= 0xFF # cluster is 32 bits max + raw.add(0x2403, -2) # add 2403 + raw.add(ctx.cluster, 1) + elif ctx.cluster <= 0xFFFF + raw.add(0x2503, -2) # add 2503 + raw.add(ctx.cluster, 2) + else + raw.add(0x2603, -2) # add 2603 + raw.add(ctx.cluster, 4) + end + # add attribute + if ctx.attribute <= 0xFF # cluster is 32 bits max + raw.add(0x2404, -2) # add 2404 + raw.add(ctx.attribute, 1) + elif ctx.attribute <= 0xFFFF + raw.add(0x2504, -2) # add 2504 + raw.add(ctx.attribute, 2) + else + raw.add(0x2604, -2) # add 2604 + raw.add(ctx.attribute, 4) + end + # do we add ListIndex: null + if list_index_null + raw.add(0x3405, -2) # add 3405 + end + # close + raw.add(0x18, 1) # add 18 + end + + ############################################################# + # attributedata2raw + # + # generate a raw version of AttributeDataIB + # + # Typical answer + # + # AttributeReportIB + # 0 = AttributeStatusIB + # 1 = AttributeDataIB + # 0 = DataVersion U1 + # 1 = AttributePathIB + # 0 = EnableTagCompression bool opt + # 1 = Node + # 2 = Endpoint + # 3 = Cluste + # 4 = Attribute + # 5 = ListIndex (opt) + # 2 = Data + # + # 153601.15350124000137012402012403392404111829021818.1824FF0118 + # 15350124000137012402012403392404111829021818 + # 1535012400013701 + # 240201240339240411 + # 1829021818 + # + # 15 + # 3501 1 = {} + # 2400 01 0 = 1U (U1) + # 3701 1 = LIST + # 2402 01 2 = 1U (U1) + # 2403 39 3 = 0x39U (U1) + # 2404 11 4 = 0x11U (U1) + # [OPTIONAL ListIndex] + # 3405 5 = NULL + # + # 18 + # 2902 2 = True + # 18 + # 18 + def attributedata2raw(raw, ctx, val, list_index_null) + raw.add(0x15350124, -4) # add 15350124 + raw.add(0x0001, -2) # add 0001 + + self.path2raw(raw, ctx, 0x01, list_index_null) + + # add value with tag 2 + val.tag_sub = 2 + val.tlv2raw(raw) + # close 2 structs + raw.add(0x1818, -2) + end + + ############################################################# + # attributedata2raw + # + # generate a raw version of AttributeStatusIB + # + # + # Typical answer + # + # AttributeReportIB + # 0 = AttributeStatusIB + # 0 = AttributePathIB + # 0 = EnableTagCompression bool opt + # 1 = Node + # 2 = Endpoint + # 3 = Cluste + # 4 = Attribute + # 5 = ListIndex (opt) + # 1 = StatusIB + # 0 = Status (u1) + # 1 = ClusterStatus (u1) + # 1 = AttributeDataIB + # + # 15360115350037002402012403022404031835012400041818181824FF0118 + # 153601 1535003700 - 2402012403022404031835012400041818181824FF0118 + # + # 15 + # 3601 + # + # 15 + # 3500 0 = struct + # 3700 0 = list + # 240201 2 = 1U endpoint + # 240302 3 = 2U cluster + # 240403 4 = 3U attribute + # 18 + # 3501 1 = struct + # 240004 0 = 4U status + # 18 + # 18 + # 18 + # + # 18 + # 24FF01 + # 18 + def attributestatus2raw(raw, ctx, status) + raw.add(0x15, 1) # add 15 + raw.add(0x3500, -2) # add 3500 + + self.path2raw(raw, ctx, 0x00) + + raw.add(0x3501, -2) # add 3501 for status + # status + if ctx.status <= 255 + raw.add(0x2400, -2) # add 2400 + raw.add(ctx.status, 1) + else + raw.add(0x2500, -2) # add 2500 + raw.add(ctx.status, 2) + end + # close + raw.add(0x1818, -2) # add 1818 + raw.add(0x18, 1) # add 18 + end + + ############################################################# + # attributedata2raw + # + # generate a raw version of InvokeResponseIB() + # Typical answer + # + # 1535013700240011240122240244183501240000181818 + # + # 0 = CommandDataIB + # 0 = CommandPathIB + # 0 = endpoint u2 + # 1 = cluster u4 + # 2 = command u4 + # 1 = + # 1 = CommandStatusIB + # 0 = CommandPathIB + # 0 = endpoint u2 + # 1 = cluster u4 + # 2 = command u4 + # 1 = StatusIB + # 0 = status u1 + # 1 = ClusterStatus u1 + # + # 1535013700240011240122240244183501240000181818 + # 15 + # 3501 1 = struct + # 3700 0 = list + # 240011 0 = endpoint + # 240122 1 = cluster + # 240244 2 = command + # 18 + # 3501 1 = struct + # 240000 0 = 0 (status) + # 18 + # 18 + # 18 + # + # 1535003700240011240122240244182401031818 + # 15 + # 3500 0 = struct + # 3700 0 = list + # 240011 0 = endpoint + # 240122 1 = cluster + # 240244 2 = command + # 18 + # 240103 1 = + # 18 + # 18 + def invokeresponse2raw(raw, ctx, val) + raw.add(0x15, 1) # add 15 + if val == nil + raw.add(0x3501, -2) # add 3500 + else + raw.add(0x3500, -2) # add 3500 + end + raw.add(0x3700, -2) # add 3700 + # add endpoint + if ctx.endpoint <= 0xFF # endpoint is 16 bits max + raw.add(0x2400, -2) # add 2400 + raw.add(ctx.endpoint, 1) + else + raw.add(0x2500, -2) # add 2500 + raw.add(ctx.endpoint, 2) + end + # add cluster + if ctx.cluster <= 0xFF # cluster is 32 bits max + raw.add(0x2401, -2) # add 2401 + raw.add(ctx.cluster, 1) + elif ctx.cluster <= 0xFFFF + raw.add(0x2501, -2) # add 2501 + raw.add(ctx.cluster, 2) + else + raw.add(0x2601, -2) # add 2601 + raw.add(ctx.cluster, 4) + end + # add attribute + if ctx.command <= 0xFF # cluster is 32 bits max + raw.add(0x2402, -2) # add 2402 + raw.add(ctx.command, 1) + elif ctx.command <= 0xFFFF + raw.add(0x2502, -2) # add 2502 + raw.add(ctx.command, 2) + else + raw.add(0x2602, -2) # add 2602 + raw.add(ctx.command, 4) + end + raw.add(0x18, 1) # add 18 + + # either value or statuc + if val == nil + var status = ctx.status + if status == nil status = matter.SUCCESS end + raw.add(0x3501, -2) # add 3501 + raw.add(0x2400, -2) # add 2400 + raw.add(ctx.status, 1) # add status:1 + raw.add(0x18, 1) # add 18 + else + val.tag_sub = 1 # set sub_tag for reponse + val.tlv2raw(raw) + end + # close + raw.add(0x1818, -2) # add 1818 + end + ############################################################# # process IM 0x02 Read Request # @@ -333,20 +673,134 @@ class Matter_IM # returns `true` if processed, `false` if silently ignored, # or raises an exception def process_read_request(msg, val) + matter.profiler.log("read_request_start") + # matter.profiler.log(str(val)) var query = matter.ReadRequestMessage().from_TLV(val) + # matter.profiler.log(str(query)) if query.attributes_requests != nil - var ret = self._inner_process_read_request(msg.session, query) + var ret = self._inner_process_read_request(msg.session, query, msg) self.send_report_data(msg, ret) end return true end + ############################################################# + # process IM 0x02 Read Request + # + # val is the TLV structure + # returns `true` if processed, `false` if silently ignored, + # or raises an exception + def process_read_request_solo(msg, ctx) + # prepare fallback error + ctx.status = matter.INVALID_ACTION + ctx.msg = msg + + # find pi for this endpoint/cluster/attribute + var pi = self.device.process_attribute_read_solo(ctx) + var res = nil + # matter.profiler.log("read_request_solo pi ok") + # tasmota.log(f"MTR: process_read_request_solo {pi=}") + + var raw # this is the bytes() block we need to add to response (or nil) + if pi != nil + ctx.status = matter.UNSUPPORTED_ATTRIBUTE # new fallback error + res = pi.read_attribute(msg.session, ctx, self.tlv_solo) + end + matter.profiler.log("read_request_solo read done") + + if res != nil + + # check if the payload is a complex structure and too long to fit in a single response packet + if (res.is_list || res.is_array) && res.encode_len() > matter.IM_ReportData.MAX_MESSAGE + # revert to standard + # the attribute will be read again, but it's hard to avoid it + res = nil # indicated to GC that we don't need it again + tasmota.log(f"MTR: Response to big, revert to non-solo", 3) + var val = matter.TLV.parse(msg.raw, msg.app_payload_idx) + return self.process_read_request(msg, val) + end + # encode directly raw bytes() + raw = bytes(48) # pre-reserve 48 bytes + + raw.add(0x15, 1) # add 15 + raw.add(0x3601, -2) # add 3601 + + self.attributedata2raw(raw, ctx, res) + + # add suffix 1824FF0118 + raw.add(0x1824FF01, -4) # add 1824FF01 + raw.add(0x18, 1) # add 18 + + elif ctx.status != nil + + # encode directly raw bytes() + raw = bytes(48) # pre-reserve 48 bytes + + raw.add(0x15, 1) # add 15 + raw.add(0x3601, -2) # add 3601 + + self.attributestatus2raw(raw, ctx, ctx.status) + + # add suffix 1824FF0118 + raw.add(0x1824FF01, -4) # add 1824FF01 + raw.add(0x18, 1) # add 18 + + else + tasmota.log(f"MTR: >Read_Attr ({msg.session.local_session_id:6i}) {ctx} - IGNORED", 3) + return false + end + + # send packet + var resp = msg.build_response(0x05 #-Report Data-#, true) + + var responder = self.device.message_handler + var msg_raw = msg.raw + msg_raw.clear() + resp.encode_frame(raw, msg_raw) # payload in cleartext + resp.encrypt() + if tasmota.loglevel(4) + tasmota.log(format("MTR: Read_Attr1({msg.session.local_session_id:6i}) {ctx}{attr_name} - {res_str}", 3) + end + # if matter.profiler.active && tasmota.loglevel(3) + # tasmota.log(f"MTR: {raw=}", 3) # TODO remove before flight + # end + elif ctx.status != nil + var unsupported_attribute = (ctx.status == matter.UNSUPPORTED_ATTRIBUTE ? "UNSUPPORTED_ATTRIBUTE" : "") + if tasmota.loglevel(3) + tasmota.log(f"MTR: >Read_Attr1({msg.session.local_session_id:6i}) {ctx}{attr_name} - STATUS: 0x{ctx.status:02X} {unsupported_attribute}", 3) + end + # if matter.profiler.active && tasmota.loglevel(3) + # tasmota.log(f"MTR: {raw=}", 3) # TODO remove before flight + # end + else + if tasmota.loglevel(3) + tasmota.log(f"MTR: >Read_Attr1({msg.session.local_session_id:6i}) {ctx}{attr_name} - IGNORED", 3) + end + end + + # matter.profiler.log("read_request_solo end") + return true + end + ############################################################# # process IM 0x03 Subscribe Request # def subscribe_request(msg, val) - import string var query = matter.SubscribeRequestMessage().from_TLV(val) if !query.keep_subscriptions @@ -360,16 +814,20 @@ class Matter_IM # expand a string with all attributes requested var attr_req = [] var ctx = matter.Path() + ctx.msg = msg for q:query.attributes_requests ctx.endpoint = q.endpoint ctx.cluster = q.cluster ctx.attribute = q.attribute attr_req.push(str(ctx)) end - tasmota.log(string.format("MTR: >Subscribe (%6i) %s (min=%i, max=%i, keep=%i) sub=%i", - msg.session.local_session_id, attr_req.concat(" "), sub.min_interval, sub.max_interval, query.keep_subscriptions ? 1 : 0, sub.subscription_id), 2) + tasmota.log(format("MTR: >Subscribe (%6i) %s (min=%i, max=%i, keep=%i) sub=%i fabric_filtered=%s", + msg.session.local_session_id, attr_req.concat(" "), sub.min_interval, sub.max_interval, query.keep_subscriptions ? 1 : 0, sub.subscription_id, query.fabric_filtered), 3) + if query.event_requests != nil && size(query.event_requests) > 0 + tasmota.log(f"MTR: >Subscribe (%6i) event_requests_size={size(query.event_requests)}", 3) + end - var ret = self._inner_process_read_request(msg.session, query, true #-no_log-#) + var ret = self._inner_process_read_request(msg.session, query, msg, true #-no_log-#) # ret is of type `Matter_ReportDataMessage` ret.subscription_id = sub.subscription_id # enrich with subscription id TODO self.send_subscribe_response(msg, ret, sub) @@ -383,10 +841,12 @@ class Matter_IM # returns `true` if processed, `false` if silently ignored, # or raises an exception def process_invoke_request(msg, val) - import string + # import debug # structure is `ReadRequestMessage` 10.6.2 p.558 # tasmota.log("MTR: IM:invoke_request processing start", 4) + matter.profiler.log("invoke_request_start") var ctx = matter.Path() + ctx.msg = msg var query = matter.InvokeRequestMessage().from_TLV(val) if query.invoke_requests != nil @@ -402,53 +862,46 @@ class Matter_IM ctx.status = matter.UNSUPPORTED_COMMAND #default error if returned `nil` var cmd_name = matter.get_command_name(ctx.cluster, ctx.command) + var ctx_str = str(ctx) # keep string before invoking, it is modified by response var res = self.device.invoke_request(msg.session, q.command_fields, ctx) + matter.profiler.log("COMMAND DONE") var params_log = (ctx.log != nil) ? "(" + str(ctx.log) + ") " : "" - tasmota.log(string.format("MTR: >Command (%6i) %s %s %s", msg.session.local_session_id, str(ctx), cmd_name ? cmd_name : "", params_log), 2) + tasmota.log(format("MTR: >Command (%6i) %s %s %s", msg.session.local_session_id, ctx_str, cmd_name ? cmd_name : "", params_log), 3) + # tasmota.log("MTR: Perf/Command = " + str(debug.counters()), 4) ctx.log = nil - var a1 = matter.InvokeResponseIB() + var raw = bytes(32) + # var a1 = matter.InvokeResponseIB() if res == true || ctx.status == matter.SUCCESS # special case, just respond ok - a1.status = matter.CommandStatusIB() - a1.status.command_path = matter.CommandPathIB() - a1.status.command_path.endpoint = ctx.endpoint - a1.status.command_path.cluster = ctx.cluster - a1.status.command_path.command = ctx.command - a1.status.status = matter.StatusIB() - a1.status.status.status = matter.SUCCESS - ret.invoke_responses.push(a1) - tasmota.log(string.format("MTR: Command1 (%6i) %s %s %s", msg.session.local_session_id, ctx_str, cmd_name ? cmd_name : "", params_log), 3) + end + # tasmota.log("MTR: Perf/Command = " + str(debug.counters()), 4) + ctx.log = nil + var raw = bytes(48) + + # prefix 1528003601 + raw.add(0x15280036, -4) # add 15280036 + raw.add(0x01, 1) # add 01 + if res == true || ctx.status == matter.SUCCESS # special case, just respond ok + ctx.status = matter.SUCCESS + self.invokeresponse2raw(raw, ctx, nil) + + if tasmota.loglevel(3) + tasmota.log(f"MTR: Command (%6i) TimedRequest=%i", msg.session.local_session_id, query.timeout), 2) + tasmota.log(format("MTR: >Command (%6i) TimedRequest=%i", msg.session.local_session_id, query.timeout), 3) # Send success status report self.send_status(msg, matter.SUCCESS) @@ -620,7 +1138,6 @@ class Matter_IM # send regular update for data subscribed # def send_subscribe_update(sub) - import string var session = sub.session # create a fake read request to feed to the ReportData @@ -636,10 +1153,10 @@ class Matter_IM fake_read.attributes_requests.push(p1) end - tasmota.log(string.format("MTR: " + str(e) + ", " + str(m) @@ -628,6 +629,238 @@ class Matter_ReadRequestMessage : Matter_IM_Message_base end matter.ReadRequestMessage = Matter_ReadRequestMessage + +################################################################################# +# ReadRequestMessage class optimized for a simple solo argument +################################################################################# +class Matter_Path end # for compilation +class Matter_ReadRequestMessage_solo : Matter_Path + # var endpoint # int + # var cluster # int + # var attribute # int + # var fabric_filtered # bool or nil + + def from_raw(raw, idx) + self.reset() + # must start with 15360017 + var sz = size(raw) + var val + if raw.get(idx, -4) != 0x15360017 return nil end + idx += 4 + while idx < sz + # expect 24 xx yy or 25 xx yyyy (little endian) + var tag = raw.get(idx+1, 1) + var b0 = raw.get(idx, 1) + if b0 == 0x24 # u1 + val = raw.get(idx+2, 1) + idx += 3 + elif b0 == 0x25 # u2 + val = raw.get(idx+2, 2) + idx += 4 + else + break + end + if tag == 2 + self.endpoint = val + elif tag == 3 + self.cluster = val + elif tag == 4 + self.attribute = val + else + return nil # unsupported tag + end + end + # expect 18 18 + val = raw.get(idx, -2) + if val != 0x1818 return nil end + idx += 2 + # fabric_filtered: 2803 or 2903 + val = raw.get(idx, -2) + if val == 0x2803 + self.fabric_filtered = false + idx += 2 + elif val == 0x2903 + self.fabric_filtered = true + idx += 2 + end + # skip 24FFxx + val = raw.get(idx, -2) + if val == 0x24FF idx += 3 end + # expect 18 + if raw.get(idx, 1) != 0x18 return nil end + idx += 1 + # sanity check + if self.endpoint == nil || + self.cluster == nil || + self.attribute == nil || + self.fabric_filtered == nil + return nil + end + # all good + return self + end + + # Example: read_attr Reachable + # 153600172402012403392404111818290324FF0118 + # 15 structure + # 3600 tag 00 array + # 17 list + # 2402 tag 02 u1 "endpoint" + # 01 + # 2403 tag 03 u1 "cluster" + # 39 57U + # 2404 tag 04 u1 "attribute" + # 11 17U + # 18 + # 18 + # 2903 tag 03 booltrue + # 24FF tag FF u1 + # 01 1U + # 18 + # {0 = [[[2 = 1U, 3 = 57U, 4 = 17U]]], 3 = true, 255 = 1U} + +end +matter.ReadRequestMessage_solo = Matter_ReadRequestMessage_solo +# test +# b = bytes('0000153600172402012403392404111818290324FF0118') +# m = matter.ReadRequestMessage_solo() +# mm = m.from_raw(b, 2) +# print(m) + + +################################################################################# +# InvokeRequestMessage class optimized for a simple solo argument +################################################################################# +class Matter_Path end # for compilation +class Matter_InvokeRequestMessage_solo : Matter_Path + var SuppressResponse + var TimedRequest + var command_fields + # var endpoint # int + # var cluster # int + # var attribute # int + # var fabric_filtered # bool or nil + + def reset() + var n = nil + super(self).reset() + self.SuppressResponse = n + self.TimedRequest = n + self.command_fields = n + end + + def from_raw(raw, idx) + self.reset() + # must start with 15360017 + var sz = size(raw) + var val + + if raw.get(idx, 1) != 0x15 return nil end + idx += 1 + # check SuppressResponse (optional) + val = raw.get(idx, -2) + if val == 0x2800 || val == 0x2900 + self.SuppressResponse = (val == 0x2900) + idx += 2 + end + # check TimedRequest (optional) + val = raw.get(idx, -2) + if val == 0x2801 || val == 0x2901 + self.SuppressResponse = (val == 0x2901) + idx += 2 + end + # start of CommandDataIB + if raw.get(idx, -2) != 0x3602 return nil end + idx += 2 + if raw.get(idx, 1) != 0x15 return nil end + idx += 1 + if raw.get(idx, -2) != 0x3700 return nil end + idx += 2 + # + while idx < sz + # expect 24 xx yy or 25 xx yyyy (little endian) + var tag = raw.get(idx+1, 1) + var b0 = raw.get(idx, 1) + if b0 == 0x24 # u1 + val = raw.get(idx+2, 1) + idx += 3 + elif b0 == 0x25 # u2 + val = raw.get(idx+2, 2) + idx += 4 + else + break + end + if tag == 0 + self.endpoint = val + elif tag == 1 + self.cluster = val + elif tag == 2 + self.command = val + else + return nil # unsupported tag + end + end + if raw.get(idx, 1) != 0x18 return nil end + idx += 1 + # command_fields + if raw.get(idx, -2) != 0x3501 return nil end + self.command_fields = matter.TLV.parse(raw, idx) + idx = self.command_fields.next_idx # skip structure + + # close + if raw.get(idx, -2) != 0x1818 return nil end + idx += 2 + if raw.get(idx, -4) != 0x24FF0118 return nil end + + # all good + return self + end + + # Example: command OnOff + # {0 = false, 1 = false, 2 = [{0 = [[0 = 1U, 1 = 6U, 2 = 0U]], 1 = {}}], 255 = 1U} + # 1528002801360215370024000124010624020018350118181824FF0118 + # + # 15 + # 2800 0 = false SuppressResponse + # 2801 1 = false TimedRequest + # 3602 2 = list of CommandDataIB + # 15 + # 3700 0 = CommandPathIB + # 240001 0 = 1U endpoint + # 240106 1 = 6U cluster + # 240200 2 = 0U command + # 18 + # 3501 1 = struct + # 18 + # 18 + # 18 + # 24FF01 FF = 1U + # 18 + + + + + + # 15 structure + # 3600 tag 00 array + # 17 list + # 2402 tag 02 u1 "endpoint" + # 01 + # 2403 tag 03 u1 "cluster" + # 39 57U + # 2404 tag 04 u1 "attribute" + # 11 17U + # 18 + # 18 + # 2903 tag 03 booltrue + # 24FF tag FF u1 + # 01 1U + # 18 + # {0 = [[[2 = 1U, 3 = 57U, 4 = 17U]]], 3 = true, 255 = 1U} + +end +matter.InvokeRequestMessage_solo = Matter_InvokeRequestMessage_solo + ################################################################################# # ReportDataMessage class ################################################################################# diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_IM_Message.be b/lib/libesp32/berry_matter/src/embedded/Matter_IM_Message.be index b0cdaa32ae22..cdf9be4c29ed 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_IM_Message.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_IM_Message.be @@ -44,11 +44,16 @@ class Matter_IM_Message # build a response message stub def init(msg, opcode, reliable) + self.reset(msg, opcode, reliable) + end + + def reset(msg, opcode, reliable) self.resp = msg.build_response(opcode, reliable) self.ready = true # by default send immediately self.expiration = tasmota.millis() + self.MSG_TIMEOUT self.last_counter = 0 # avoid `nil` value self.finish = false + self.data = nil end # the message is being removed due to expiration @@ -66,8 +71,7 @@ class Matter_IM_Message # Status Report OK received for previous message, proceed to next (if any) # return true if we manage the ack ourselves, false if it needs to be done upper def status_ok_received(msg) - import string - # tasmota.log(string.format("MTR: IM_Message status_ok_received exch=%i", self.resp.exchange_id), 3) + # tasmota.log(format("MTR: IM_Message status_ok_received exch=%i", self.resp.exchange_id), 3) self.expiration = tasmota.millis() + self.MSG_TIMEOUT # give more time if msg self.resp = msg.build_response(self.resp.opcode, self.resp.x_flag_r, self.resp) # update packet @@ -87,13 +91,20 @@ class Matter_IM_Message # default responder for data def send_im(responder) - import string - # tasmota.log(string.format("MTR: IM_Message send_im exch=%i ready=%i", self.resp.exchange_id, self.ready ? 1 : 0), 3) + # tasmota.log(format("MTR: IM_Message send_im exch=%i ready=%i", self.resp.exchange_id, self.ready ? 1 : 0), 3) if !self.ready return false end + # import debug var resp = self.resp - resp.encode_frame(self.data.to_TLV().tlv2raw()) # payload in cleartext + var data_tlv = self.data.to_TLV() + # matter.profiler.log(str(data_tlv)) + var data_raw = data_tlv.tlv2raw() # payload in cleartext + # matter.profiler.log(data_raw.tohex()) + resp.encode_frame(data_raw) # payload in cleartext resp.encrypt() - tasmota.log(string.format("MTR: >>>> send elements after encode") resp.encrypt() # print(">>>>> send elements after encrypt") - tasmota.log(string.format("MTR: 0 data.attribute_reports = next_elemnts - tasmota.log(string.format("MTR: to_be_sent_later size=%i exch=%i", size(data.attribute_reports), resp.exchange_id), 3) + # tasmota.log(format("MTR: to_be_sent_later size=%i exch=%i", size(data.attribute_reports), resp.exchange_id), 4) self.ready = false # wait for Status Report before continuing sending # keep alive else @@ -246,8 +256,7 @@ class Matter_IM_ReportDataSubscribed : Matter_IM_ReportData # ack received, confirm the heartbeat def ack_received(msg) - # import string - # tasmota.log(string.format("MTR: IM_ReportDataSubscribed ack_received sub=%i", self.sub.subscription_id), 3) + # tasmota.log(format("MTR: IM_ReportDataSubscribed ack_received sub=%i", self.sub.subscription_id), 3) super(self).ack_received(msg) if !self.report_data_phase # if ack is received while all data is sent, means that it finished without error @@ -262,16 +271,14 @@ class Matter_IM_ReportDataSubscribed : Matter_IM_ReportData # we received an ACK error, remove subscription def status_error_received(msg) - # import string - # tasmota.log(string.format("MTR: IM_ReportDataSubscribed status_error_received sub=%i exch=%i", self.sub.subscription_id, self.resp.exchange_id), 3) + # tasmota.log(format("MTR: IM_ReportDataSubscribed status_error_received sub=%i exch=%i", self.sub.subscription_id, self.resp.exchange_id), 3) self.sub.remove_self() end # ack received for previous message, proceed to next (if any) # return true if we manage the ack ourselves, false if it needs to be done upper def status_ok_received(msg) - # import string - # tasmota.log(string.format("MTR: IM_ReportDataSubscribed status_ok_received sub=%i exch=%i", self.sub.subscription_id, self.resp.exchange_id), 3) + # tasmota.log(format("MTR: IM_ReportDataSubscribed status_ok_received sub=%i exch=%i", self.sub.subscription_id, self.resp.exchange_id), 3) if self.report_data_phase return super(self).status_ok_received(msg) else @@ -284,14 +291,13 @@ class Matter_IM_ReportDataSubscribed : Matter_IM_ReportData # returns true if transaction is complete (remove object from queue) # default responder for data def send_im(responder) - import string - # tasmota.log(string.format("MTR: IM_ReportDataSubscribed send sub=%i exch=%i ready=%i", self.sub.subscription_id, self.resp.exchange_id, self.ready ? 1 : 0), 3) - # tasmota.log(string.format("MTR: ReportDataSubscribed::send_im size(self.data.attribute_reports)=%i ready=%s report_data_phase=%s", size(self.data.attribute_reports), str(self.ready), str(self.report_data_phase)), 3) + # tasmota.log(format("MTR: IM_ReportDataSubscribed send sub=%i exch=%i ready=%i", self.sub.subscription_id, self.resp.exchange_id, self.ready ? 1 : 0), 3) + # tasmota.log(format("MTR: ReportDataSubscribed::send_im size(self.data.attribute_reports)=%i ready=%s report_data_phase=%s", size(self.data.attribute_reports), str(self.ready), str(self.report_data_phase)), 3) if !self.ready return false end if size(self.data.attribute_reports) > 0 # do we have still attributes to send if self.report_data_phase super(self).send_im(responder) - # tasmota.log(string.format("MTR: ReportDataSubscribed::send_im called super finish=%i", self.finish), 3) + # tasmota.log(format("MTR: ReportDataSubscribed::send_im called super finish=%i", self.finish), 3) if !self.finish return end # ReportData needs to continue # ReportData is finished self.report_data_phase = false @@ -302,7 +308,9 @@ class Matter_IM_ReportDataSubscribed : Matter_IM_ReportData var resp = self.resp.build_standalone_ack(false) resp.encode_frame() resp.encrypt() - tasmota.log(string.format("MTR: Sub_OK (%6i) sub=%i", msg.session.local_session_id, self.sub.subscription_id), 2) + if tasmota.loglevel(3) + tasmota.log(format("MTR: >Sub_OK (%6i) sub=%i", msg.session.local_session_id, self.sub.subscription_id), 3) + end return super(self).status_ok_received(msg) end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_IM_Subscription.be b/lib/libesp32/berry_matter/src/embedded/Matter_IM_Subscription.be index 0f526d987469..b9c67ae0980e 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_IM_Subscription.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_IM_Subscription.be @@ -86,7 +86,7 @@ class Matter_IM_Subscription # remove self from subs_shop list def remove_self() - tasmota.log("MTR: -Sub_Del ( ) sub=" + str(self.subscription_id), 2) + tasmota.log("MTR: -Sub_Del ( ) sub=" + str(self.subscription_id), 3) self.subs_shop.remove_sub(self) end @@ -98,13 +98,12 @@ class Matter_IM_Subscription # we received a complete ack for previous message, rearm def re_arm() - import string self.wait_status = false var now = tasmota.millis() self.expiration = now + (self.max_interval - self.MAX_INTERVAL_MARGIN) * 1000 self.not_before = now + self.min_interval * 1000 - 1 if !self.is_keep_alive - tasmota.log(string.format("MTR: .Sub_Done ( ) sub=%i", self.subscription_id), 2) + tasmota.log(format("MTR: .Sub_Done ( ) sub=%i", self.subscription_id), 3) end end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Message.be b/lib/libesp32/berry_matter/src/embedded/Matter_Message.be index 81cbe4a7eed5..70ff59835460 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Message.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Message.be @@ -171,8 +171,12 @@ class Matter_Frame # # Header is built from attributes # `payload` is a bytes() buffer for the app payload - def encode_frame(payload) - var raw = bytes() + # + # you can pass a `raw` bytes() object to be used + def encode_frame(payload, raw) + if raw == nil + raw = bytes(16 + (payload ? size(payload) : 0)) + end # compute flags if self.flags == nil self.flags = 0x00 @@ -220,7 +224,7 @@ class Matter_Frame raw .. payload end - self.debug(raw) + # self.debug(raw) self.raw = raw return raw end @@ -229,7 +233,6 @@ class Matter_Frame # Generate a Standalone Acknowledgment # Uses `PROTOCOL_ID_SECURE_CHANNEL` no ecnryption required def build_standalone_ack(reliable) - import string # send back response var resp = classof(self)(self.message_handler) @@ -263,7 +266,6 @@ class Matter_Frame # # if 'resp' is not nil, update frame def build_response(opcode, reliable, resp) - import string # send back response if resp == nil resp = classof(self)(self.message_handler) @@ -301,8 +303,8 @@ class Matter_Frame if resp.local_session_id == 0 var op_name = matter.get_opcode_name(resp.opcode) - if !op_name op_name = string.format("0x%02X", resp.opcode) end - tasmota.log(string.format("MTR: >>>>>>>>>>>>>>>>>>> Compute Privacy TODO", 2) var k = session.get_i2r_privacy() + var mic = raw[-16..] # take last 16 bytes as signature var n = bytes().add(self.local_session_id, -2) + mic[5..15] # session in Big Endian var m = self.raw[4 .. self.payload_idx-1] var m_clear = crypto.AES_CTR(k).decrypt(m, n, 2) # replace in-place - self.raw = self.raw[0..3] + m_clear + m[self.self.payload_idx .. ] + self.raw = self.raw[0..3] + m_clear + m[self.payload_idx .. ] end - # use AES_CCM - var a = raw[0 .. self.payload_idx - 1] - var p = raw[self.payload_idx .. -17] # recompute nonce - var n = bytes() + var n = self.message_handler._n_bytes # use cached bytes() object to avoid allocation + n.clear() n.add(self.flags, 1) n.add(self.message_counter, 4) if self.source_node_id @@ -384,28 +388,26 @@ class Matter_Frame end # tasmota.log("MTR: ******************************", 4) + # tasmota.log("MTR: raw =" + raw.tohex(), 4) # tasmota.log("MTR: i2r =" + i2r.tohex(), 4) - # tasmota.log("MTR: p =" + p.tohex(), 4) - # tasmota.log("MTR: a =" + a.tohex(), 4) + # tasmota.log("MTR: p =" + raw[payload_idx .. -17].tohex(), 4) + # tasmota.log("MTR: a =" + raw[0 .. payload_idx - 1].tohex(), 4) # tasmota.log("MTR: n =" + n.tohex(), 4) - # tasmota.log("MTR: mic =" + mic.tohex(), 4) + # tasmota.log("MTR: mic =" + raw[-16..].tohex(), 4) # decrypt - var aes = crypto.AES_CCM(i2r, n, a, size(p), 16) - var cleartext = aes.decrypt(p) - var tag = aes.tag() - - # tasmota.log("MTR: ******************************", 4) - # tasmota.log("MTR: cleartext =" + cleartext.tohex(), 4) - # tasmota.log("MTR: tag =" + tag.tohex(), 4) - # tasmota.log("MTR: ******************************", 4) - - if tag != mic - tasmota.log("MTR: rejected packet due to invalid MIC", 2) - return nil + var ret = crypto.AES_CCM.decrypt1(i2r, # secret key + n, 0, size(n), # nonce / IV + raw, 0, payload_idx, # aad + raw, payload_idx, size(raw) - payload_idx - tag_len, # encrypted - decrypted in-place + raw, size(raw) - tag_len, tag_len) # MIC + if ret + # succcess + raw.resize(size(raw) - tag_len) # remove MIC + else + tasmota.log("MTR: rejected packet due to invalid MIC", 3) end - - return cleartext + return ret end ############################################################# @@ -416,15 +418,15 @@ class Matter_Frame import crypto var raw = self.raw var session = self.session + var payload_idx = self.payload_idx + var tag_len = 16 # encrypt the message with `i2r` key var r2i = session.get_r2i() - # use AES_CCM - var a = raw[0 .. self.payload_idx - 1] - var p = raw[self.payload_idx .. ] # recompute nonce - var n = bytes() + var n = self.message_handler._n_bytes # use cached bytes() object to avoid allocation + n.clear() n.add(self.flags, 1) n.add(self.message_counter, 4) if session.is_CASE() && session.get_device_id() @@ -432,30 +434,14 @@ class Matter_Frame end n.resize(13) # add zeros - # tasmota.log("MTR: cleartext: " + self.raw.tohex(), 4) - - # tasmota.log("MTR: ******************************", 4) - # tasmota.log("MTR: r2i =" + r2i.tohex(), 4) - # tasmota.log("MTR: p =" + p.tohex(), 4) - # tasmota.log("MTR: a =" + a.tohex(), 4) - # tasmota.log("MTR: n =" + n.tohex(), 4) - - # decrypt - var aes = crypto.AES_CCM(r2i, n, a, size(p), 16) - var ciphertext = aes.encrypt(p) - var tag = aes.tag() - - # tasmota.log("MTR: ******************************", 4) - # tasmota.log("MTR: ciphertext =" + ciphertext.tohex(), 4) - # tasmota.log("MTR: tag =" + tag.tohex(), 4) - # tasmota.log("MTR: ******************************", 4) - - # packet is good, put back content in raw - self.raw.resize(self.payload_idx) # remove cleartext payload - self.raw .. ciphertext # add ciphertext - self.raw .. tag # add MIC + # encrypt + raw.resize(size(raw) + tag_len) # make room for MIC + var ret = crypto.AES_CCM.encrypt1(r2i, # secret key + n, 0, size(n), # nonce / IV + raw, 0, payload_idx, # aad + raw, payload_idx, size(raw) - payload_idx - tag_len, # encrypted - decrypted in-place + raw, size(raw) - tag_len, tag_len) # MIC - # tasmota.log("MTR: encrypted: " + self.raw.tohex(), 4) end ############################################################# @@ -465,7 +451,7 @@ class Matter_Frame var r = matter.Frame(self.message_handler, raw) r.decode_header() r.decode_payload() - tasmota.log("MTR: sending decode: " + matter.inspect(r), 4) + # tasmota.log("MTR: sending decode: " + matter.inspect(r), 4) end end matter.Frame = Matter_Frame diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_MessageHandler.be b/lib/libesp32/berry_matter/src/embedded/Matter_MessageHandler.be index f68b0c48e999..63336e4f75f4 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_MessageHandler.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_MessageHandler.be @@ -30,12 +30,16 @@ class Matter_MessageHandler var im # Instance of `matter.IM` handling Interaction Model var control_message # Instance of `matter.Control_Message` for MCSP + # cache for decryption bytes + var _n_bytes # size 16 minimal, used by frame_buffer for decryption + ############################################################# def init(device) self.device = device self.commissioning = matter.Commisioning_Context(self) self.im = matter.IM(device) self.control_message = matter.Control_Message(self) + self._n_bytes = bytes(16) end ############################################################# @@ -44,11 +48,12 @@ class Matter_MessageHandler # reliable: do we send as reliable message # def send_simple_ack(frame, reliable) - import string if frame.x_flag_r # nothing to respond, check if we need a standalone ack var resp = frame.build_standalone_ack(reliable) resp.encode_frame() - tasmota.log(string.format("MTR: Received (%6i) %s rid=%i exch=%i from [%s]:%i", session.local_session_id, op_name, frame.message_counter, frame.exchange_id, addr, port), 2) + if !op_name op_name = format("0x%02X", frame.opcode) end + if tasmota.loglevel(3) + tasmota.log(format("MTR: >Received (%6i) %s rid=%i exch=%i from [%s]:%i", session.local_session_id, op_name, frame.message_counter, frame.exchange_id, addr, port), 3) + end else - tasmota.log(string.format("MTR: >rcv Ack (%6i) rid=%i exch=%i ack=%s %sfrom [%s]:%i", session.local_session_id, frame.message_counter, frame.x_flag_r ? "{reliable} " : "", frame.exchange_id, str(frame.ack_message_counter), addr, port), 3) + if tasmota.loglevel(4) + tasmota.log(format("MTR: >rcv Ack (%6i) rid=%i exch=%i ack=%s %sfrom [%s]:%i", session.local_session_id, frame.message_counter, frame.x_flag_r ? "{reliable} " : "", frame.exchange_id, str(frame.ack_message_counter), addr, port), 4) + end end ret = self.commissioning.process_incoming(frame) # if ret is false, the implicit Ack was not sent @@ -126,14 +139,19 @@ class Matter_MessageHandler else ############################################################# # encrypted message - tasmota.log(string.format("MTR: decode header: local_session_id=%i message_counter=%i", frame.local_session_id, frame.message_counter), 3) + # matter.profiler.log("msg_received_header_encrypted_message_received") + if tasmota.loglevel(4) + tasmota.log(format("MTR: decode header: local_session_id=%i message_counter=%i", frame.local_session_id, frame.message_counter), 4) + end var session = self.device.sessions.get_session_by_local_session_id(frame.local_session_id) + # matter.profiler.log("msg_received_header_session_retrieved") if session == nil - tasmota.log("MTR: unknown local_session_id="+str(frame.local_session_id), 2) + tasmota.log("MTR: unknown local_session_id="+str(frame.local_session_id), 3) # tasmota.log("MTR: frame="+matter.inspect(frame), 3) return false end + # matter.profiler.log("msg_received_session_found") if addr session._ip = addr end if port session._port = port end session._message_handler = self @@ -141,24 +159,28 @@ class Matter_MessageHandler # check if it's a duplicate if !session.counter_rcv_validate(frame.message_counter, true) - tasmota.log("MTR: . Duplicate encrypted message = " + str(frame.message_counter) + " counter=" + str(session.counter_rcv), 3) + if tasmota.loglevel(3) + tasmota.log("MTR: . Duplicate encrypted message = " + str(frame.message_counter) + " counter=" + str(session.counter_rcv), 3) + end self.send_encrypted_ack(frame, false #-not reliable-#) return false end - var cleartext = frame.decrypt() - if !cleartext return false end + var decrypt_ok = frame.decrypt() + matter.profiler.log("msg_received_header_frame_decrypted") + if !decrypt_ok return false end - # packet is good, put back content in raw - frame.raw = frame.raw[0 .. frame.payload_idx - 1] # remove encrypted payload - frame.raw .. cleartext # add cleartext + # matter.profiler.log("msg_received_payload_undecoded") # continue decoding - tasmota.log(string.format("MTR: idx=%i clear=%s", frame.payload_idx, frame.raw.tohex()), 4) + # tasmota.log(format("MTR: idx=%i clear=%s", frame.payload_idx, frame.raw.tohex()), 4) frame.decode_payload() - tasmota.log("MTR: > Decrypted message: protocol_id:"+str(frame.protocol_id)+" opcode="+str(frame.opcode)+" exchange_id="+str(frame.exchange_id & 0xFFFF), 3) + # matter.profiler.log("msg_received_payload_decoded") + if tasmota.loglevel(4) + tasmota.log("MTR: > Decrypted message: protocol_id:"+str(frame.protocol_id)+" opcode="+str(frame.opcode)+" exchange_id="+str(frame.exchange_id & 0xFFFF), 4) + end - tasmota.log(string.format("MTR: >rcv (%6i) [%02X/%02X] rid=%i exch=%i ack=%s %sfrom [%s]:%i", session.local_session_id, frame.protocol_id, frame.opcode, frame.message_counter, frame.exchange_id, str(frame.ack_message_counter), frame.x_flag_r ? "{reliable} " : "", addr, port), 3) + # tasmota.log(format("MTR: >rcv (%6i) [%02X/%02X] rid=%i exch=%i ack=%s %sfrom [%s]:%i", session.local_session_id, frame.protocol_id, frame.opcode, frame.message_counter, frame.exchange_id, str(frame.ack_message_counter), frame.x_flag_r ? "{reliable} " : "", addr, port), 3) self.device.received_ack(frame) # remove acknowledge packet from sending list @@ -176,7 +198,9 @@ class Matter_MessageHandler ret = true elif protocol_id == 0x0001 # PROTOCOL_ID_INTERACTION_MODEL # dispatch to IM Protocol Messages + matter.profiler.log("process_IM_start") ret = self.im.process_incoming(frame) + matter.profiler.log("process_IM_end") # if `ret` is true, we have something to send if ret self.im.send_enqueued(self) @@ -202,7 +226,7 @@ class Matter_MessageHandler return ret except .. as e, m - tasmota.log("MTR: MessageHandler::msg_received exception: "+str(e)+";"+str(m)) + tasmota.log("MTR: MessageHandler::msg_received exception: "+str(e)+";"+str(m), 2) if tasmota._debug_present import debug debug.traceback() @@ -223,6 +247,7 @@ class Matter_MessageHandler # msg.exchange_id: exchange id (int) # msg.local_session_id: local session (for logging) def send_response_frame(msg) + matter.profiler.log("send_response_frame") self.device.msg_send(msg) end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Path.be b/lib/libesp32/berry_matter/src/embedded/Matter_Path.be index fe04be0aa7cd..5dd1c7d775f1 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Path.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Path.be @@ -30,18 +30,33 @@ class Matter_Path var endpoint # endpoint or `nil` if expansion var cluster # cluster or `nil` if expansion var attribute # attribute or `nil` if expansion + var fabric_filtered # bool or nil var command # command var status # status to be returned (matter.SUCCESS or matter.) var log # any string that needs to be logged (used to show significant parameters for commands) + var msg # reference of the original message + + # reset the object, allows reuse of the same object + def reset() + var n = nil # it's actually more compact code to load `nil` into a register and assign all members + self.endpoint = n + self.cluster = n + self.attribute = n + self.fabric_filtered = n + self.command = n + self.status = n + self.log = n + self.msg = n + end def tostring() try - import string var s = "" - s += (self.endpoint != nil ? string.format("[%02X]", self.endpoint) : "[**]") - s += (self.cluster != nil ? string.format("%04X/", self.cluster) : "****/") - s += (self.attribute != nil ? string.format("%04X", self.attribute) : "") - s += (self.command != nil ? string.format("%04X", self.command) : "") + s += (self.endpoint != nil ? format("[%02X]", self.endpoint) : "[**]") + s += (self.cluster != nil ? format("%04X/", self.cluster) : "****/") + s += (self.attribute != nil ? format("%04X", self.attribute) : "") + s += (self.command != nil ? format("%04X", self.command) : "") + if self.fabric_filtered s += "!" end if self.attribute == nil && self.command == nil s += "****" end return s except .. as e, m diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_0.be similarity index 60% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_0.be index 8f725225db6c..3e7bb9e42c7e 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_0.be @@ -17,6 +17,8 @@ # along with this program. If not, see . # +import matter + # Matter modules for extensibility # template but not actually used @@ -25,20 +27,26 @@ class Matter_Plugin # Global type system for plugins static var TYPE = "" # name of the plug-in in json - static var NAME = "" # display name of the plug-in + static var DISPLAY_NAME = "" # display name of the plug-in static var ARG = "" # additional argument name (or empty if none) static var ARG_TYPE = / x -> str(x) # function to convert argument to the right type + static var ARG_HINT = "_Not used_" # Hint for entering the Argument (inside 'placeholder') # Behavior of the plugin, frequency at which `update_shadow()` is called static var UPDATE_TIME = 5000 # default is every 5 seconds + static var VIRTUAL = false # set to true only for virtual devices var update_next # next timestamp for update # Configuration of the plugin: clusters and type static var CLUSTERS = { 0x001D: [0,1,2,3,0xFFFC,0xFFFD], # Descriptor Cluster 9.5 p.453 + 0x0039: [0x11], # Bridged Device Basic Information 9.13 p.485 } + # Accepted Update commands for virtual devices + static var UPDATE_COMMANDS = [] var device # reference to the `device` global object var endpoint # current endpoint var clusters # map from cluster to list of attributes, typically constructed from CLUSTERS hierachy var tick # tick value when it was last updated + var node_label # name of the endpoint, used only in bridge mode, "" if none ############################################################# # MVC Model @@ -52,29 +60,60 @@ class Matter_Plugin # device: contains the root device object so the plugin can "call home" # endpoint: (int) the endpoint number (16 bits) # arguments: (map) the map for all complementary arguments that are plugin specific - def init(device, endpoint, arguments) + def init(device, endpoint, config) self.device = device self.endpoint = endpoint self.clusters = self.consolidate_clusters() + self.parse_configuration(config) + self.node_label = config.find("name", "") + end + + # proxy for the same method in IM + def ack_request(ctx) + var msg = ctx.msg + if msg != nil + self.device.message_handler.im.send_ack_now(msg) + end + ctx.msg = nil end ############################################################# - # return the map of all types - def get_types() - return self.TYPES + # parse_configuration + # + # Parse configuration map + # TO BE OVERRIDEN + def parse_configuration(config) + end + + ############################################################# + # is_local_device + # + # Returns true if it's a local device, or false for a + # remotely device controlled via HTTP + def is_local_device() + return true end ############################################################# # Stub for updating shadow values (local copies of what we published to the Matter gateway) + # + # This method should collect the data from the local or remote device + # and call `parse_update()` when data is available. + # + # TO BE OVERRIDDEN + # This call is synnchronous and blocking. def update_shadow() self.tick = self.device.tick end ############################################################# # Stub for updating shadow values (local copies of what we published to the Matter gateway) + # + # This call is synnchronous and blocking. def update_shadow_lazy() if self.tick != self.device.tick self.update_shadow() + self.tick = self.device.tick end end @@ -92,24 +131,49 @@ class Matter_Plugin # Build a consolidated map of all the `CLUSTERS` static vars # from the inheritance hierarchy def consolidate_clusters() - def real_super(o) return super(o) end # enclose `super()` in a static function to disable special behavior for super in instances - var ret = {} - var o = self # start with self - while o != nil # when we rich highest class, `super()` returns `nil` - var CL = o.CLUSTERS - for k: CL.keys() - # check if key already exists - if !ret.contains(k) ret[k] = [] end - for attr: CL[k] # iterate on values - if ret[k].find(attr) == nil - ret[k].push(attr) - end - end - end + return self.CLUSTERS + # def real_super(o) return super(o) end # enclose `super()` in a static function to disable special behavior for super in instances + # var ret = {} + # var o = self # start with self + # while o != nil # when we rich highest class, `super()` returns `nil` + # var CL = o.CLUSTERS + # for k: CL.keys() + # # check if key already exists + # if !ret.contains(k) ret[k] = [] end + # for attr: CL[k] # iterate on values + # if ret[k].find(attr) == nil + # ret[k].push(attr) + # end + # end + # end + + # o = real_super(o) + # end + # return ret + end + + ############################################################# + # consolidate_update_commands + # + # Return consolidated "update commands" for this class + def consolidate_update_commands() + return self.UPDATE_COMMANDS + end - o = real_super(o) + ############################################################# + # Publish to MQTT a command received from controller + # + # we limit to 3 commands (to we need more?) + def publish_command(key1, value1, key2, value2, key3, value3) + import json + var payload = f"{json.dump(key1)}:{json.dump(value1)}" + if key2 != nil + payload = f"{payload},{json.dump(key2)}:{json.dump(value2)}" end - return ret + if key3 != nil + payload = f"{payload},{json.dump(key3)}:{json.dump(value3)}" + end + matter.publish_command('MtrReceived', self.endpoint, self.node_label, payload) end ############################################################# @@ -117,16 +181,32 @@ class Matter_Plugin def get_endpoint() return self.endpoint end - def get_cluster_list(ep) + def get_cluster_list() var ret = [] for k: self.clusters.keys() ret.push(k) end return ret end - def get_attribute_list(ep, cluster) + def contains_cluster(cluster) + return self.clusters.contains(cluster) + end + def get_attribute_list(cluster) return self.clusters.find(cluster, []) end + def contains_attribute(cluster, attribute) + var attr_list = self.clusters.find(cluster) + if attr_list != nil + var idx = 0 + while idx < size(attr_list) + if attr_list[idx] == attribute + return true + end + idx += 1 + end + end + return false + end ############################################################# # Does it handle this endpoint and this cluster @@ -134,6 +214,14 @@ class Matter_Plugin return self.clusters.contains(cluster) && self.endpoints.find(endpoint) != nil end + def set_name(n) + if n != self.node_label + self.attribute_updated(0x0039, 0x0005) + end + self.node_label = n + end + def get_name() return self.node_label end + ############################################################# # MVC Model # @@ -141,7 +229,10 @@ class Matter_Plugin ############################################################# ############################################################# # read attribute - def read_attribute(session, ctx) + # + # Arg: + # `tlv_solo` contains an instance of `Matter_TLV_item` to avoid allocating a new object with TLV.create_TLV + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -150,7 +241,7 @@ class Matter_Plugin if attribute == 0x0000 # ---------- DeviceTypeList / list[DeviceTypeStruct] ---------- var dtl = TLV.Matter_TLV_array() - var types = self.get_types() + var types = self.TYPES for dt: types.keys() var d1 = dtl.add_struct() d1.add_TLV(0, TLV.U2, dt) # DeviceType @@ -170,11 +261,19 @@ class Matter_Plugin var pl = TLV.Matter_TLV_array() return pl elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0) # + return tlv_solo.set(TLV.U4, 0) # elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 1) # "Initial Release" + return tlv_solo.set(TLV.U4, 1) # "Initial Release" end + # ==================================================================================================== + elif cluster == 0x0039 # ========== Bridged Device Basic Information 9.13 p.485 ========== + + if attribute == 0x0011 # ---------- Reachable / bool ---------- + return tlv_solo.set(TLV.BOOL, 1) # by default we are reachable + else + return super(self).read_attribute(session, ctx, tlv_solo) # rest is handled by 0x0028 + end else return nil end @@ -244,13 +343,12 @@ class Matter_Plugin # check if the timer expired and update_shadow() needs to be called def every_250ms() if self.update_next == nil - # initialization to a random value within range - import crypto - var rand31 = crypto.random(4).get(0,4) & 0x7FFFFFFF # random int over 31 bits - self.update_next = tasmota.millis(rand31 % self.UPDATE_TIME) + self.update_next = matter.jitter(self.UPDATE_TIME) else if tasmota.time_reached(self.update_next) - self.update_shadow_lazy() # call update_shadow if not already called + if self.tick != self.device.tick + self.update_shadow() # call update_shadow if not already called + end self.update_next = tasmota.millis(self.UPDATE_TIME) # rearm timer end end @@ -283,6 +381,41 @@ class Matter_Plugin return conf end + ############################################################# + # append_state_json + # + # Output the current state in JSON + # Takes the JSON string prefix + # New values need to be appended with `,"key":value` (including prefix comma) + def append_state_json() + return "" + end + + # This is to be called by matter_device to get the full state JSON + # including "Ep":,"Name"=". +# + +import matter + +#@ solidify:Matter_Plugin_Device,weak + +class Matter_Plugin_Device : Matter_Plugin + static var CLUSTERS = matter.consolidate_clusters(_class, { + # 0x001D: inherited # Descriptor Cluster 9.5 p.453 + 0x0039: [3,5,0x0A,0x0F,0x11,0x12], # Bridged Device Basic Information 9.13 p.485 + 0x0003: [0,1,0xFFFC,0xFFFD], # Identify 1.2 p.16 + 0x0004: [0,0xFFFC,0xFFFD], # Groups 1.3 p.21 + 0x0005: [0,1,2,3,4,5,0xFFFC,0xFFFD], # Scenes 1.4 p.30 - no writable + }) + static var TYPES = { 0x0013: 1 } # fake type + static var NON_BRIDGE_VENDOR = [ 0x1217, 0x1381 ] # Fabric VendorID not supporting Bridge mode + # Inherited + # var device # reference to the `device` global object + # var endpoint # current endpoint + # var clusters # map from cluster to list of attributes, typically constructed from CLUSTERS hierachy + # var tick # tick value when it was last updated + # var node_label # name of the endpoint, used only in bridge mode, "" if none + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0003 # ========== Identify 1.2 p.16 ========== + if attribute == 0x0000 # ---------- IdentifyTime / u2 ---------- + return tlv_solo.set(TLV.U2, 0) # no identification in progress + elif attribute == 0x0001 # ---------- IdentifyType / enum8 ---------- + return tlv_solo.set(TLV.U1, 0) # IdentifyType = 0x00 None + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0) # no features + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 4) # "new data model format and notation" + end + + # ==================================================================================================== + elif cluster == 0x0004 # ========== Groups 1.3 p.21 ========== + if attribute == 0x0000 # ---------- ---------- + return nil # TODO + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0)# + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 4)# "new data model format and notation" + end + + # ==================================================================================================== + elif cluster == 0x0005 # ========== Scenes 1.4 p.30 - no writable ========== + if attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0) # 0 = no Level Control for Lighting + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 4) # 0 = no Level Control for Lighting + end + + # ==================================================================================================== + elif cluster == 0x001D # ========== Descriptor Cluster 9.5 p.453 ========== + + if attribute == 0x0000 # ---------- DeviceTypeList / list[DeviceTypeStruct] ---------- + # for device sub-classes, automatically add the Bridge Node type `0x0013: 1` + # unless the fabric doesn't support bridge mode (currently Alexa) + var dtl = TLV.Matter_TLV_array() + var types = self.TYPES + for dt: types.keys() + var d1 = dtl.add_struct() + d1.add_TLV(0, TLV.U2, dt) # DeviceType + d1.add_TLV(1, TLV.U2, types[dt]) # Revision + end + # if fabric is not Alexa + if (self.NON_BRIDGE_VENDOR.find(session.get_admin_vendor()) == nil) && (!self.device.disable_bridge_mode) + var d1 = dtl.add_struct() + d1.add_TLV(0, TLV.U2, 0x0013) # DeviceType + d1.add_TLV(1, TLV.U2, 1) # Revision + end + return dtl + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + + # ==================================================================================================== + elif cluster == 0x0039 # ========== Bridged Device Basic Information 9.13 p.485 ========== + import string + + if attribute == 0x0003 # ---------- ProductName / string ---------- + return tlv_solo.set(TLV.UTF1, tasmota.cmd("DeviceName", true)['DeviceName']) + elif attribute == 0x0005 # ---------- NodeLabel / string ---------- + return tlv_solo.set(TLV.UTF1, self.get_name()) + elif attribute == 0x000A # ---------- SoftwareVersionString / string ---------- + var version_full = tasmota.cmd("Status 2", true)['StatusFWR']['Version'] + var version_end = string.find(version_full, '(') + if version_end > 0 version_full = version_full[0..version_end - 1] end + return tlv_solo.set(TLV.UTF1, version_full) + elif attribute == 0x000F # ---------- SerialNumber / string ---------- + return tlv_solo.set(TLV.UTF1, tasmota.wifi().find("mac", "")) + elif attribute == 0x0011 # ---------- Reachable / bool ---------- + return tlv_solo.set(TLV.BOOL, 1) # by default we are reachable + elif attribute == 0x0012 # ---------- UniqueID / string 32 max ---------- + return tlv_solo.set(TLV.UTF1, tasmota.wifi().find("mac", "")) + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # Invoke a command + # + # returns a TLV object if successful, contains the response + # or an `int` to indicate a status + def invoke_request(session, val, ctx) + var TLV = matter.TLV + var cluster = ctx.cluster + var command = ctx.command + + # ==================================================================================================== + if cluster == 0x0003 # ========== Identify 1.2 p.16 ========== + + if command == 0x0000 # ---------- Identify ---------- + # ignore + return true + elif command == 0x0001 # ---------- IdentifyQuery ---------- + # create IdentifyQueryResponse + # ID=1 + # 0=Certificate (octstr) + var iqr = TLV.Matter_TLV_struct() + iqr.add_TLV(0, TLV.U2, 0) # Timeout + ctx.command = 0x00 # IdentifyQueryResponse + return iqr + elif command == 0x0040 # ---------- TriggerEffect ---------- + # ignore + return true + end + # ==================================================================================================== + elif cluster == 0x0004 # ========== Groups 1.3 p.21 ========== + # TODO + return true + + # ==================================================================================================== + elif cluster == 0x0005 # ========== Scenes 1.4 p.30 ========== + # TODO + return true + + else + return super(self).invoke_request(session, val, ctx) + end + end + + ############################################################# + # append_state_json + # + # Output the current state in JSON. + # The JSON is build via introspection to see what attributes + # exist and need to be output + # New values need to be appended with `,"key":value` (including prefix comma) + def append_state_json() + import introspect + var ret = "" + + # ret: string + # attribute: attrbute name + # key: in json + def _stats_json_inner(attribute, key) + import introspect + import json + var val + if (val := introspect.get(self, attribute)) != nil + if type(val) == 'bool' val = int(val) end # transform bool into 1/0 + ret += f',"{key}":{json.dump(val)}' + end + end + + # lights + # print(f'{self=} {type(self)} {introspect.members(self)=}') + _stats_json_inner("shadow_onoff", "Power") + _stats_json_inner("shadow_bri", "Bri") + _stats_json_inner("shadow_ct", "CT") + _stats_json_inner("shadow_hue", "Hue") + _stats_json_inner("shadow_sat", "Sat") + # shutters + _stats_json_inner("shadow_shutter_pos", "ShutterPos") + _stats_json_inner("shadow_shutter_target", "ShutterTarget") + _stats_json_inner("shadow_shutter_tilt", "ShutterTilt") + + # sensors + _stats_json_inner("shadow_contact", "Contact") + _stats_json_inner("shadow_occupancy", "Occupancy") + # print(ret) + return ret + end + +end +matter.Plugin_Device = Matter_Plugin_Device diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Root.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_1_Root.be similarity index 76% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Root.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_1_Root.be index 76f2440ff7fe..f02fedadfd12 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Root.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_1_Root.be @@ -17,20 +17,19 @@ # along with this program. If not, see . # -# Matter plug-in for root behavior +import matter -# dummy declaration for solidification -class Matter_Plugin end +# Matter plug-in for root behavior #@ solidify:Matter_Plugin_Root,weak class Matter_Plugin_Root : Matter_Plugin static var TYPE = "root" # name of the plug-in in json - static var NAME = "Root node" # display name of the plug-in - static var CLUSTERS = { + static var DISPLAY_NAME = "Root node" # display name of the plug-in + static var CLUSTERS = matter.consolidate_clusters(_class, { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 0x001F: [0,2,3,4], # Access Control Cluster, p.461 - 0x0028: [0,1,2,3,4,5,6,7,8,9,0x0A,0x0F,0x12,0x13],# Basic Information Cluster cluster 11.1 p.565 + 0x0028: [0,1,2,3,4,5,6,7,8,9,0x0A,0x0F,0x11,0x12,0x13],# Basic Information Cluster cluster 11.1 p.565 # 0x002A: [0,1,2,3], # OTA Software Update Requestor Cluster Definition 11.19.7 p.762 0x002B: [0,1], # Localization Configuration Cluster 11.3 p.580 0x002C: [0,1,2], # Time Format Localization Cluster 11.4 p.581 @@ -43,19 +42,19 @@ class Matter_Plugin_Root : Matter_Plugin 0x003C: [0,1,2], # Administrator Commissioning Cluster 11.18 p.725 0x003E: [0,1,2,3,4,5], # Node Operational Credentials Cluster 11.17 p.704 0x003F: [] # Group Key Management Cluster 11.2 p.572 - } + }) static var TYPES = { 0x0016: 1 } # Root node ############################################################# # Constructor - def init(device, endpoint, arguments) - super(self).init(device, endpoint, arguments) - end + # def init(device, endpoint, config) + # super(self).init(device, endpoint, config) + # end ############################################################# # read an attribute # - def read_attribute(session, ctx) + def read_attribute(session, ctx, tlv_solo) import string var TLV = matter.TLV var cluster = ctx.cluster @@ -64,18 +63,18 @@ class Matter_Plugin_Root : Matter_Plugin if cluster == 0x0030 # ========== GeneralCommissioning cluster 11.9 p.627 ========== if attribute == 0x0000 # ---------- Breadcrumb ---------- - return TLV.create_TLV(TLV.U8, session._breadcrumb) + return tlv_solo.set(TLV.U8, session._breadcrumb) elif attribute == 0x0001 # ---------- BasicCommissioningInfo / BasicCommissioningInfo---------- var bci = TLV.Matter_TLV_struct() bci.add_TLV(0, TLV.U2, 60) # FailSafeExpiryLengthSeconds bci.add_TLV(1, TLV.U2, 900) # MaxCumulativeFailsafeSeconds return bci elif attribute == 0x0002 # ---------- RegulatoryConfig / RegulatoryLocationType ---------- - return TLV.create_TLV(TLV.U1, 2) # 2 = IndoorOutdoor | esp-matter = 0 + return tlv_solo.set(TLV.U1, 2) # 2 = IndoorOutdoor | esp-matter = 0 elif attribute == 0x0003 # ---------- LocationCapability / RegulatoryLocationType---------- - return TLV.create_TLV(TLV.U1, 2) # 2 = IndoorOutdoor + return tlv_solo.set(TLV.U1, 2) # 2 = IndoorOutdoor elif attribute == 0x0004 # ---------- SupportsConcurrentConnection / bool ---------- - return TLV.create_TLV(TLV.BOOL, false) # false - maybe can set to true + return tlv_solo.set(TLV.BOOL, false) # false - maybe can set to true end # ==================================================================================================== elif cluster == 0x0032 # ========== Diagnostic Logs Cluster 11.10 p.637 ========== @@ -122,12 +121,12 @@ class Matter_Plugin_Root : Matter_Plugin end return nwi elif attribute == 0x0001 # ---------- RebootCount u16 ---------- - return TLV.create_TLV(TLV.U2, tasmota.cmd("Status 1", true)['StatusPRM']['BootCount']) + return tlv_solo.set(TLV.U2, tasmota.cmd("Status 1", true)['StatusPRM']['BootCount']) elif attribute == 0x0002 # ---------- UpTime u16 ---------- - return TLV.create_TLV(TLV.U4, tasmota.cmd("Status 11", true)['StatusSTS']['UptimeSec']) + return tlv_solo.set(TLV.U4, tasmota.cmd("Status 11", true)['StatusSTS']['UptimeSec']) # TODO add later other attributes elif attribute == 0x0008 # ---------- TestEventTriggersEnabled bool ---------- - return TLV.create_TLV(TLV.BOOL, false) # false - maybe can set to true + return tlv_solo.set(TLV.BOOL, false) # false - maybe can set to true end # ==================================================================================================== @@ -137,22 +136,25 @@ class Matter_Plugin_Root : Matter_Plugin # ==================================================================================================== elif cluster == 0x0038 # ========== Time Synchronization 11.16 p.689 ========== if attribute == 0x0000 # ---------- UTCTime / epoch_us ---------- - var epoch_us = int64(tasmota.rtc()['utc']) * int64(1000000) - return TLV.create_TLV(TLV.U8, epoch_us) # TODO test the conversion of int64() + var epoch_us = int64(tasmota.rtc_utc()) * int64(1000000) + return tlv_solo.set(TLV.U8, epoch_us) # TODO test the conversion of int64() elif attribute == 0x0001 # ---------- Granularity / enum ---------- - return TLV.create_TLV(TLV.U1, 3) # MillisecondsGranularity (NTP every hour, i.e. 36ms max drift) + return tlv_solo.set(TLV.U1, 3) # MillisecondsGranularity (NTP every hour, i.e. 36ms max drift) # TODO add some missing args elif attribute == 0x0007 # ---------- LocalTime / epoch_us ---------- var epoch_us = int64(tasmota.rtc()['local']) * int64(1000000) - return TLV.create_TLV(TLV.U8, epoch_us) # TODO test the conversion of int64() + return tlv_solo.set(TLV.U8, epoch_us) # TODO test the conversion of int64() end # ==================================================================================================== elif cluster == 0x003E # ========== Node Operational Credentials Cluster 11.17 p.704 ========== + self.ack_request(ctx) # long operation, send Ack first if attribute == 0x0000 # ---------- NOCs / list[NOCStruct] ---------- var nocl = TLV.Matter_TLV_array() # NOCs, p.711 - for loc_fabric: self.device.sessions.active_fabrics() + var fabs = ctx.fabric_filtered ? [session.get_fabric()] : self.device.sessions.active_fabrics() + for loc_fabric: fabs + if loc_fabric == nil continue end var nocs = nocl.add_struct(nil) nocs.add_TLV(1, TLV.B2, loc_fabric.get_noc()) # NOC nocs.add_TLV(2, TLV.B2, loc_fabric.get_icac()) # ICAC @@ -161,7 +163,9 @@ class Matter_Plugin_Root : Matter_Plugin return nocl elif attribute == 0x0001 # ---------- Fabrics / list[FabricDescriptorStruct] ---------- var fabrics = TLV.Matter_TLV_array() # Fabrics, p.711 - for loc_fabric: self.device.sessions.active_fabrics() + var fabs = ctx.fabric_filtered ? [session.get_fabric()] : self.device.sessions.active_fabrics() + for loc_fabric: fabs + if loc_fabric == nil continue end var root_ca_tlv = TLV.parse(loc_fabric.get_ca()) var fab = fabrics.add_struct(nil) # encoding see p.303 fab.add_TLV(1, TLV.B2, root_ca_tlv.findsubval(9)) # RootPublicKey @@ -173,16 +177,16 @@ class Matter_Plugin_Root : Matter_Plugin end return fabrics elif attribute == 0x0002 # ---------- SupportedFabrics / u1 ---------- - return TLV.create_TLV(TLV.U1, matter.Fabric._MAX_CASE) # Max 5 fabrics + return tlv_solo.set(TLV.U1, matter.Fabric._MAX_CASE) # Max 5 fabrics elif attribute == 0x0003 # ---------- CommissionedFabrics / u1 ---------- var fabric_actice = self.device.sessions.count_active_fabrics() - return TLV.create_TLV(TLV.U1, fabric_actice) # number of active fabrics + return tlv_solo.set(TLV.U1, fabric_actice) # number of active fabrics elif attribute == 0x0004 # ---------- TrustedRootCertificates / list[octstr] ---------- # TODO - elif attribute == 0x0005 # ---------- Current­ FabricIndex / u1 ---------- + elif attribute == 0x0005 # ---------- Current FabricIndex / u1 ---------- var fab_index = session._fabric.get_fabric_index() if fab_index == nil fab_index = 0 end # if PASE session, then the fabric index should be zero - return TLV.create_TLV(TLV.U1, fab_index) # number of active sessions + return tlv_solo.set(TLV.U1, fab_index) # number of active sessions end # ==================================================================================================== @@ -191,55 +195,58 @@ class Matter_Plugin_Root : Matter_Plugin var commissioning_open = self.device.is_commissioning_open() var basic_commissioning = self.device.is_root_commissioning_open() var val = commissioning_open ? (basic_commissioning ? 2 #-BasicWindowOpen-# : 1 #-EnhancedWindowOpen-#) : 0 #-WindowNotOpen-# - return TLV.create_TLV(TLV.U1, val) + return tlv_solo.set(TLV.U1, val) elif attribute == 0x0001 # ---------- AdminFabricIndex / u16 ---------- var admin_fabric = self.device.commissioning_admin_fabric if admin_fabric != nil - return TLV.create_TLV(TLV.U2, admin_fabric.get_fabric_index()) + return tlv_solo.set(TLV.U2, admin_fabric.get_fabric_index()) else - return TLV.create_TLV(TLV.NULL, nil) + return tlv_solo.set(TLV.NULL, nil) end elif attribute == 0x0002 # ---------- AdminVendorId / u16 ---------- var admin_fabric = self.device.commissioning_admin_fabric if admin_fabric != nil - return TLV.create_TLV(TLV.U2, admin_fabric.get_admin_vendor()) + return tlv_solo.set(TLV.U2, admin_fabric.get_admin_vendor()) else - return TLV.create_TLV(TLV.NULL, nil) + return tlv_solo.set(TLV.NULL, nil) end end # ==================================================================================================== elif cluster == 0x0028 # ========== Basic Information Cluster cluster 11.1 p.565 ========== + self.ack_request(ctx) # long operation, send Ack first if attribute == 0x0000 # ---------- DataModelRevision / CommissioningWindowStatus ---------- - return TLV.create_TLV(TLV.U2, 1) + return tlv_solo.set(TLV.U2, 1) elif attribute == 0x0001 # ---------- VendorName / string ---------- - return TLV.create_TLV(TLV.UTF1, "Tasmota") + return tlv_solo.set(TLV.UTF1, "Tasmota") elif attribute == 0x0002 # ---------- VendorID / vendor-id ---------- - return TLV.create_TLV(TLV.U2, self.device.vendorid) # Vendor ID reserved for development + return tlv_solo.set(TLV.U2, self.device.vendorid) # Vendor ID reserved for development elif attribute == 0x0003 # ---------- ProductName / string ---------- - return TLV.create_TLV(TLV.UTF1, tasmota.cmd("DeviceName", true)['DeviceName']) + return tlv_solo.set(TLV.UTF1, tasmota.cmd("DeviceName", true)['DeviceName']) elif attribute == 0x0004 # ---------- ProductID / u16 (opt) ---------- - return TLV.create_TLV(TLV.U2, 32768) # taken from esp-matter example + return tlv_solo.set(TLV.U2, 32768) # taken from esp-matter example elif attribute == 0x0005 # ---------- NodeLabel / string ---------- - return TLV.create_TLV(TLV.UTF1, tasmota.cmd("FriendlyName", true)['FriendlyName1']) + return tlv_solo.set(TLV.UTF1, tasmota.cmd("FriendlyName", true)['FriendlyName1']) elif attribute == 0x0006 # ---------- Location / string ---------- - return TLV.create_TLV(TLV.UTF1, "XX") # no location + return tlv_solo.set(TLV.UTF1, "XX") # no location elif attribute == 0x0007 # ---------- HardwareVersion / u16 ---------- - return TLV.create_TLV(TLV.U2, 0) + return tlv_solo.set(TLV.U2, 0) elif attribute == 0x0008 # ---------- HardwareVersionString / string ---------- - return TLV.create_TLV(TLV.UTF1, tasmota.cmd("Status 2", true)['StatusFWR']['Hardware']) + return tlv_solo.set(TLV.UTF1, tasmota.cmd("Status 2", true)['StatusFWR']['Hardware']) elif attribute == 0x0009 # ---------- SoftwareVersion / u32 ---------- - return TLV.create_TLV(TLV.U2, 1) + return tlv_solo.set(TLV.U2, 1) elif attribute == 0x000A # ---------- SoftwareVersionString / string ---------- var version_full = tasmota.cmd("Status 2", true)['StatusFWR']['Version'] var version_end = string.find(version_full, '(') if version_end > 0 version_full = version_full[0..version_end - 1] end - return TLV.create_TLV(TLV.UTF1, version_full) + return tlv_solo.set(TLV.UTF1, version_full) elif attribute == 0x000F # ---------- SerialNumber / string ---------- - return TLV.create_TLV(TLV.UTF1, tasmota.wifi().find("mac", "")) + return tlv_solo.set(TLV.UTF1, tasmota.wifi().find("mac", "")) + elif attribute == 0x0011 # ---------- Reachable / bool ---------- + return tlv_solo.set(TLV.BOOL, 1) # by default we are reachable elif attribute == 0x0012 # ---------- UniqueID / string 32 max ---------- - return TLV.create_TLV(TLV.UTF1, tasmota.wifi().find("mac", "")) + return tlv_solo.set(TLV.UTF1, tasmota.wifi().find("mac", "")) elif attribute == 0x0013 # ---------- CapabilityMinima / CapabilityMinimaStruct ---------- var cps = TLV.Matter_TLV_struct() cps.add_TLV(0, TLV.U2, 3) # CaseSessionsPerFabric = 3 @@ -257,18 +264,18 @@ class Matter_Plugin_Root : Matter_Plugin if attribute == 0x0000 # ---------- DefaultOTAProviders / list[ProviderLocationStruct] ---------- return TLV.Matter_TLV_array() # empty list for now TODO elif attribute == 0x0001 # ---------- UpdatePossible / bool ---------- - return TLV.create_TLV(TLV.BOOL, 0) # we claim that update is not possible, would require to go to Tasmota UI + return tlv_solo.set(TLV.BOOL, 0) # we claim that update is not possible, would require to go to Tasmota UI elif attribute == 0x0002 # ---------- UpdateState / UpdateStateEnum ---------- - return TLV.create_TLV(TLV.U1, 1) # Idle + return tlv_solo.set(TLV.U1, 1) # Idle elif attribute == 0x0003 # ---------- UpdateStateProgress / uint8 ---------- - return TLV.create_TLV(TLV.NULL, nil) # null, nothing in process + return tlv_solo.set(TLV.NULL, nil) # null, nothing in process end # ==================================================================================================== elif cluster == 0x002B # ========== Localization Configuration Cluster 11.3 p.580 ========== if attribute == 0x0000 # ---------- ActiveLocale / string ---------- - return TLV.create_TLV(TLV.UTF1, tasmota.locale()) + return tlv_solo.set(TLV.UTF1, tasmota.locale()) elif attribute == 0x0001 # ---------- SupportedLocales / list[string] ---------- var locl = TLV.Matter_TLV_array() locl.add_TLV(nil, TLV.UTF1, tasmota.locale()) @@ -279,9 +286,9 @@ class Matter_Plugin_Root : Matter_Plugin elif cluster == 0x002C # ========== Time Format Localization Cluster 11.4 p.581 ========== if attribute == 0x0000 # ---------- HourFormat / HourFormat ---------- - return TLV.create_TLV(TLV.U1, 1) # 1 = 24hr + return tlv_solo.set(TLV.U1, 1) # 1 = 24hr elif attribute == 0x0001 # ---------- ActiveCalendarType / CalendarType ---------- - return TLV.create_TLV(TLV.U1, 4) # 4 = Gregorian + return tlv_solo.set(TLV.U1, 4) # 4 = Gregorian elif attribute == 0x0002 # ---------- SupportedCalendarTypes / list[CalendarType] ---------- var callist = TLV.Matter_TLV_array() callist.add_TLV(nil, TLV.create_TLV(TLV.U1, 4)) @@ -291,9 +298,9 @@ class Matter_Plugin_Root : Matter_Plugin # ==================================================================================================== elif cluster == 0x0031 # ========== Network Commissioning Cluster cluster 11.8 p.606 ========== if attribute == 0x0003 # ---------- ConnectMaxTimeSeconds / uint8 ---------- - return TLV.create_TLV(TLV.U1, 30) # 30 - value taking from example in esp-matter + return tlv_solo.set(TLV.U1, 30) # 30 - value taking from example in esp-matter elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0x04) # Put Eth for now which should work for any on-network + return tlv_solo.set(TLV.U4, 0x04) # Put Eth for now which should work for any on-network end elif cluster == 0x001D # ========== Descriptor Cluster 9.5 p.453 ========== @@ -302,16 +309,20 @@ class Matter_Plugin_Root : Matter_Plugin if attribute == 0x0003 # ---------- PartsList / list[endpoint-no]---------- var pl = TLV.Matter_TLV_array() var eps = self.device.get_active_endpoints(true) + var disable_bridge_mode = self.device.disable_bridge_mode for ep: eps - pl.add_TLV(nil, TLV.U2, ep) # add each endpoint + # if bridge mode is disabled, don't announce Aggregatore (above 0xFF00) + if !disable_bridge_mode || ep < 0xFF00 + pl.add_TLV(nil, TLV.U2, ep) # add each endpoint + end end return pl else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end # no match found, return that the attribute is unsupported @@ -324,7 +335,6 @@ class Matter_Plugin_Root : Matter_Plugin # or an `int` to indicate a status def invoke_request(session, val, ctx) import crypto - import string var TLV = matter.TLV var cluster = ctx.cluster var command = ctx.command @@ -361,23 +371,28 @@ class Matter_Plugin_Root : Matter_Plugin return srcr elif command == 0x0004 # ---------- CommissioningComplete p.636 ---------- + self.ack_request(ctx) # long operation, send Ack first # no data - session._breadcrumb = 0 # clear breadcrumb - session.fabric_completed() # fabric information is complete, persist - session.set_no_expiration() - session.save() - - # create CommissioningCompleteResponse - # ID=1 - # 0=ErrorCode (OK=0) - # 1=DebugText - var ccr = TLV.Matter_TLV_struct() - ccr.add_TLV(0, TLV.U1, 0) # ErrorCode = OK - ccr.add_TLV(1, TLV.UTF1, "") # DebugText = "" - ctx.command = 0x05 # CommissioningCompleteResponse - - self.device.start_commissioning_complete_deferred(session) - return ccr + if session._fabric + session._breadcrumb = 0 # clear breadcrumb + session._fabric.fabric_completed() # fabric information is complete, persist + session.set_no_expiration() + session.save() + + # create CommissioningCompleteResponse + # ID=1 + # 0=ErrorCode (OK=0) + # 1=DebugText + var ccr = TLV.Matter_TLV_struct() + ccr.add_TLV(0, TLV.U1, 0) # ErrorCode = OK + ccr.add_TLV(1, TLV.UTF1, "") # DebugText = "" + ctx.command = 0x05 # CommissioningCompleteResponse + + self.device.start_commissioning_complete_deferred(session) + return ccr + else + raise "context_error", "CommissioningComplete: no fabric attached" + end end elif cluster == 0x003E # ========== Node Operational Credentials Cluster 11.17 p.704 ========== @@ -405,12 +420,12 @@ class Matter_Plugin_Root : Matter_Plugin var att_elts = TLV.Matter_TLV_struct() att_elts.add_TLV(1, TLV.B2, matter.CD_FFF1_8000()) # certification_declaration att_elts.add_TLV(2, TLV.B1, AttestationNonce) # attestation_nonce - att_elts.add_TLV(3, TLV.U4, tasmota.rtc()['utc']) # timestamp in epoch-s + att_elts.add_TLV(3, TLV.U4, tasmota.rtc_utc()) # timestamp in epoch-s var attestation_message = att_elts.tlv2raw() var ac = session.get_ac() var attestation_tbs = attestation_message + ac - tasmota.log("MTR: attestation_tbs=" + attestation_tbs.tohex(), 3) + # tasmota.log("MTR: attestation_tbs=" + attestation_tbs.tohex(), 4) var attestation_signature = crypto.EC_P256().ecdsa_sign_sha256(matter.DAC_Priv_FFF1_8000(), attestation_tbs) @@ -424,9 +439,11 @@ class Matter_Plugin_Root : Matter_Plugin return ar elif command == 0x0004 # ---------- CSRRequest ---------- + self.ack_request(ctx) # long operation, send Ack first var CSRNonce = val.findsubval(0) # octstr 32 if size(CSRNonce) != 32 return nil end # check size on nonce var IsForUpdateNOC = val.findsubval(1, false) # bool + # tasmota.log(format("MTR: CSRRequest CSRNonce=%s IsForUpdateNOC=%s", str(CSRNonce), str(IsForUpdateNOC)), 4) var csr = session.gen_CSR() @@ -436,7 +453,7 @@ class Matter_Plugin_Root : Matter_Plugin var nocsr_elements_message = nocsr_elements.tlv2raw() # sign with attestation challenge var nocsr_tbs = nocsr_elements_message + session.get_ac() - tasmota.log("MTR: nocsr_tbs=" + nocsr_tbs.tohex(), 3) + # tasmota.log("MTR: nocsr_tbs=" + nocsr_tbs.tohex(), 4) var attestation_signature = crypto.EC_P256().ecdsa_sign_sha256(matter.DAC_Priv_FFF1_8000(), nocsr_tbs) # create CSRResponse @@ -450,12 +467,14 @@ class Matter_Plugin_Root : Matter_Plugin elif command == 0x000B # ---------- AddTrustedRootCertificate ---------- var RootCACertificate = val.findsubval(0) # octstr 400 max - session.set_ca(RootCACertificate) - tasmota.log("MTR: received ca_root="+RootCACertificate.tohex(), 3) + # TODO - additional tests are expected according to 11.17.7.13. AddTrustedRootCertificate Command + session.set_temp_ca(RootCACertificate) + # tasmota.log("MTR: received ca_root="+RootCACertificate.tohex(), 4) ctx.status = matter.SUCCESS # OK return nil # trigger a standalone ack elif command == 0x0006 # ---------- AddNOC ---------- + tasmota.log("MTR: AddNoc Args=" + str(val), 4) var NOCValue = val.findsubval(0) # octstr max 400 var ICACValue = val.findsubval(1) # octstr max 400 # Apple sends an empty ICAC instead of a missing attribute, fix this @@ -463,21 +482,32 @@ class Matter_Plugin_Root : Matter_Plugin var IpkValue = val.findsubval(2) # octstr max 16 var CaseAdminSubject = val.findsubval(3) var AdminVendorId = val.findsubval(4) + # tasmota.log("MTR: AddNoc NOCValue=" + (NOCValue ? NOCValue.tohex() : ""), 3) + # tasmota.log("MTR: AddNoc ICACValue=" + (ICACValue ? ICACValue.tohex() : ""), 3) + # tasmota.log("MTR: AddNoc IpkValue=" + str(IpkValue), 3) + # tasmota.log("MTR: AddNoc CaseAdminSubject=" + str(CaseAdminSubject), 3) + # tasmota.log("MTR: AddNoc AdminVendorId=" + str(AdminVendorId), 3) - if session.get_ca() == nil + if session.get_temp_ca() == nil tasmota.log("MTR: Error: AdNOC without CA", 2) return nil end - session.set_noc(NOCValue, ICACValue) - session.set_ipk_epoch_key(IpkValue) - session.set_admin_subject_vendor(CaseAdminSubject, AdminVendorId) + var new_fabric = self.device.sessions.create_fabric() + new_fabric.set_ca(session.get_temp_ca()) # copy temporary CA to fabric + new_fabric.set_noc_icac(NOCValue, ICACValue) + new_fabric.set_ipk_epoch_key(IpkValue) + new_fabric.set_admin_subject_vendor(CaseAdminSubject, AdminVendorId) + new_fabric.set_pk(session.get_pk()) # copy the temporary commissioning PK to the fabric # extract important information from NOC var noc_cert = matter.TLV.parse(NOCValue) var dnlist = noc_cert.findsub(6) var fabric_id = dnlist.findsubval(21) var deviceid = dnlist.findsubval(17) + # tasmota.log("MTR: AddNoc noc_cert=" + str(noc_cert), 3) + # tasmota.log("MTR: AddNoc dnlist=" + str(dnlist), 3) + if !fabric_id || !deviceid tasmota.log("MTR: Error: no fabricid nor deviceid in NOC certificate", 2) return false @@ -486,25 +516,37 @@ class Matter_Plugin_Root : Matter_Plugin if type(fabric_id) == 'int' fabric_id = int64.fromu32(fabric_id).tobytes() else fabric_id = fabric_id.tobytes() end if type(deviceid) == 'int' deviceid = int64.fromu32(deviceid).tobytes() else deviceid = deviceid.tobytes() end - var root_ca = matter.TLV.parse(session.get_ca()).findsubval(9) # extract public key from ca - root_ca = root_ca[1..] # remove first byte as per Matter specification + # tasmota.log("MTR: AddNoc fabric_id=" + str(fabric_id), 3) + # tasmota.log("MTR: AddNoc deviceid=" + str(deviceid), 3) + + var root_ca_pub = session.get_temp_ca_pub() + # tasmota.log("MTR: AddNoc root_ca_pub=" + str(root_ca_pub), 3) + # tasmota.log("MTR: AddNoc root_ca_pub=" + root_ca_pub.tohex(), 3) + root_ca_pub = root_ca_pub[1..] # remove first byte as per Matter specification var info = bytes().fromstring("CompressedFabric") # as per spec, 4.3.2.2 p.99 var hk = crypto.HKDF_SHA256() var fabric_rev = fabric_id.copy().reverse() - var k_fabric = hk.derive(root_ca, fabric_rev, info, 8) - session.set_fabric_device(fabric_id, deviceid, k_fabric, self.device.commissioning_admin_fabric) + var k_fabric = hk.derive(root_ca_pub, fabric_rev, info, 8) + var parent_fabric = session._fabric ? session._fabric : self.device.commissioning_admin_fabric # get parent fabric whether CASE or PASE + new_fabric.set_fabric_device(fabric_id, deviceid, k_fabric, parent_fabric) + # tasmota.log("MTR: AddNoc k_fabric=" + str(k_fabric), 3) # We have a candidate fabric, add it as expirable for 2 minutes - session.persist_to_fabric() # fabric object is completed, persist it - session.fabric_candidate() + new_fabric.fabric_candidate() # move to next step - self.device.start_operational_discovery_deferred(session) - # session.fabric_completed() - tasmota.log("MTR: ------------------------------------------", 3) - tasmota.log("MTR: fabric=" + matter.inspect(session._fabric), 3) - tasmota.log("MTR: ------------------------------------------", 3) - session._fabric.log_new_fabric() # log that we registered a new fabric + self.device.start_operational_discovery_deferred(new_fabric) + + # we keep the PASE session for 1 minute + if session.is_PASE() + session.set_expire_in_seconds(60) + end + + # tasmota.log("MTR: ------------------------------------------", 3) + # tasmota.log("MTR: session=" + matter.inspect(session), 3) + # tasmota.log("MTR: fabric=" + matter.inspect(session._fabric), 3) + # tasmota.log("MTR: ------------------------------------------", 3) + new_fabric.log_new_fabric() # log that we registered a new fabric # create NOCResponse # 0=StatusCode # 1=FabricIndex (1-254) (opt) @@ -518,7 +560,7 @@ class Matter_Plugin_Root : Matter_Plugin elif command == 0x0009 # ---------- UpdateFabricLabel ---------- var label = val.findsubval(0) # Label string max 32 session.set_fabric_label(label) - tasmota.log(string.format("MTR: . Update fabric '%s' label='%s'", session._fabric.get_fabric_id().copy().reverse().tohex(), str(label)), 2) + tasmota.log(format("MTR: . Update fabric '%s' label='%s'", session._fabric.get_fabric_id().copy().reverse().tohex(), str(label)), 3) ctx.status = matter.SUCCESS # OK return nil # trigger a standalone ack @@ -528,7 +570,7 @@ class Matter_Plugin_Root : Matter_Plugin for fab: self.device.sessions.active_fabrics() if fab.get_fabric_index() == index - tasmota.log("MTR: removing fabric " + fab.get_fabric_id().copy().reverse().tohex(), 2) + # tasmota.log("MTR: removing fabric " + fab.get_fabric_id().copy().reverse().tohex(), 2) # defer actual removal to send a response tasmota.set_timer(2000, def () self.device.remove_fabric(fab) end) return true # Ok @@ -550,8 +592,8 @@ class Matter_Plugin_Root : Matter_Plugin var iterations = val.findsubval(3) # Iterations u4 var salt = val.findsubval(4) # Salt octstr - tasmota.log(string.format("MTR: OpenCommissioningWindow(timeout=%i, passcode=%s, discriminator=%i, iterations=%i, salt=%s)", - timeout, passcode_verifier.tohex(), discriminator, iterations, salt.tohex()), 2) + tasmota.log(format("MTR: OpenCommissioningWindow(timeout=%i, passcode=%s, discriminator=%i, iterations=%i, salt=%s)", + timeout, passcode_verifier.tohex(), discriminator, iterations, salt.tohex()), 4) # check values if timeout == nil || passcode_verifier == nil || discriminator == nil || iterations == nil || salt == nil @@ -559,7 +601,7 @@ class Matter_Plugin_Root : Matter_Plugin return nil # trigger a standalone ack end if size(passcode_verifier) != 32+65 || size(salt) < 16 || size(salt) > 32 - tasmota.log("MTR: wrong size for PAKE parameters") + tasmota.log("MTR: wrong size for PAKE parameters", 2) ctx.status = matter.CONSTRAINT_ERROR return nil # trigger a standalone ack end @@ -572,7 +614,7 @@ class Matter_Plugin_Root : Matter_Plugin return true # OK elif command == 0x0001 # ---------- OpenBasicCommissioningWindow ---------- var commissioning_timeout = val.findsubval(0) # CommissioningTimeout - tasmota.log("MTR: OpenBasicCommissioningWindow commissioning_timeout="+str(commissioning_timeout), 2) + tasmota.log("MTR: OpenBasicCommissioningWindow commissioning_timeout="+str(commissioning_timeout), 3) self.device.start_root_basic_commissioning(commissioning_timeout) return true elif command == 0x0002 # ---------- RevokeCommissioning ---------- @@ -598,7 +640,6 @@ class Matter_Plugin_Root : Matter_Plugin # write an attribute # def write_attribute(session, ctx, write_data) - import string var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -675,4 +716,4 @@ class Matter_Plugin_Root : Matter_Plugin end end matter.Plugin_Root = Matter_Plugin_Root - \ No newline at end of file + diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Aggregator.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Aggregator.be new file mode 100644 index 000000000000..39dd77cc9074 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Aggregator.be @@ -0,0 +1,67 @@ +# +# Matter_Plugin_Aggregator.be - implements the Aggregator endpoint +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for root behavior + +#@ solidify:Matter_Plugin_Aggregator,weak + +class Matter_Plugin_Aggregator : Matter_Plugin + static var TYPE = "aggregator" # name of the plug-in in json + static var DISPLAY_NAME = "Aggregator" # display name of the plug-in +# static var CLUSTERS = { +# # 0x001D: inherited # Descriptor Cluster 9.5 p.453 +# } + static var TYPES = { 0x000E: 1 } # Aggregator + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + if cluster == 0x001D # ========== Descriptor Cluster 9.5 p.453 ========== + + # overwrite PartsList + if attribute == 0x0003 # ---------- PartsList / list[endpoint-no]---------- + var pl = TLV.Matter_TLV_array() + var eps = self.device.get_active_endpoints(true) + for ep: eps + if ep < 0xFF00 + pl.add_TLV(nil, TLV.U2, ep) # add each endpoint + end + end + return pl + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + + end + # no match found, return that the attribute is unsupported + end + +end +matter.Plugin_Aggregator = Matter_Plugin_Aggregator + \ No newline at end of file diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Bridge_HTTP.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Bridge_HTTP.be new file mode 100644 index 000000000000..46087cd4e1e9 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Bridge_HTTP.be @@ -0,0 +1,299 @@ +# +# Matter_Plugin_Bridge_HTTP.be - implements base class for a Bridge via HTTP +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Bridge_HTTP.GetOptionReader,weak +#@ solidify:Matter_Plugin_Bridge_HTTP,weak + +class Matter_Plugin_Bridge_HTTP : Matter_Plugin_Device + static var TYPE = "" # name of the plug-in in json + static var DISPLAY_NAME = "" # display name of the plug-in + static var ARG = "" # additional argument name (or empty if none) + static var ARG_HTTP = "url" # domain name + static var UPDATE_TIME = 3000 # update every 3s + static var UPDATE_CMD = "Status 11" # command to send for updates + static var PROBE_TIMEOUT = 1700 # timeout of 1800 ms for probing, which gives at least 1s for TCP recovery + static var SYNC_TIMEOUT = 500 # timeout of 700 ms for probing + # static var CLUSTERS = { + # # 0x001D: inherited # Descriptor Cluster 9.5 p.453 + # # 0x0003: inherited # Identify 1.2 p.16 + # # 0x0004: inherited # Groups 1.3 p.21 + # # 0x0005: inherited # Scenes 1.4 p.30 - no writable + # # 0x0006: [0,0xFFFC,0xFFFD], # On/Off 1.5 p.48 + + # # 0x0028: [0,1,2,3,4,5,6,7,8,9,0x0A,0x0F,0x12,0x13],# Basic Information Cluster cluster 11.1 p.565 + # # 0x0039: [0x11] # Bridged Device Basic Information 9.13 p.485 + + # } + + var http_remote # instance of Matter_HTTP_remote + + ############################################################# + # Constructor + def init(device, endpoint, arguments) + super(self).init(device, endpoint, arguments) + + var addr = arguments.find(self.ARG_HTTP) + self.http_remote = self.device.register_http_remote(addr, self.PROBE_TIMEOUT) + self.register_cmd_cb() + end + + ############################################################# + # is_local_device + # + # Returns true if it's a local device, or false for a + # remotely device controlled via HTTP + def is_local_device() + return false + end + + ############################################################# + # register_cmd_cb + # + # Register recurrent command and callback + # Defined as a separate method to allow override + def register_cmd_cb() + self.http_remote.add_schedule(self.UPDATE_CMD, self.UPDATE_TIME, + / status,payload,cmd -> self.parse_http_response(status,payload,cmd)) + end + + ############################################################# + # Stub for updating shadow values (local copies of what we published to the Matter gateway) + # + # This method should collect the data from the local or remote device + # and call `parse_update()` when data is available. + def update_shadow() + self.tick = self.device.tick + var ret = self.call_remote_sync(self.UPDATE_CMD) + if ret + self.parse_http_response(1, ret, self.UPDATE_CMD) + end + end + + ############################################################# + # Stub for updating shadow values (local copies of what we published to the Matter gateway) + # + # TO BE OVERRIDDEN + def parse_update(data, index) + end + + ############################################################# + # call_remote_sync + # + # Call a remote Tasmota device, returns Berry native map or nil + # arg can be nil, in this case `cmd` has it all + def call_remote_sync(cmd, arg) + # if !self.http_remote return nil end + import json + + var retry = 2 # try 2 times if first failed + if arg != nil cmd = cmd + ' ' + str(arg) end + while retry > 0 + var ret = self.http_remote.call_sync(cmd, self.SYNC_TIMEOUT) + if ret != nil + self.http_remote.device_is_alive(true) + var j = json.load(ret) + return j + end + retry -= 1 + tasmota.log("MTR: HTTP GET retrying", 3) + end + self.http_remote.device_is_alive(false) + return nil + end + + ############################################################# + # parse_http_response + # + # Parse response from HTTP API and update shadows + # We support: + # `Status 8`: {"StatusSNS":{ [...] }} + # `Status 11`: {"StatusSTS":{ [...] }} + # `Status 13`: {"StatusSHT":{ [...] }} + def parse_http_response(status, payload, cmd) + if status > 0 + # device is known to be reachable + self.http_remote.device_is_alive(true) + var tick = self.device.tick + + import json + var j = json.load(payload) + var code = nil # index of Status + if j + # filter + if j.contains("StatusSNS") # Status 8 + j = j["StatusSNS"] + code = 8 + elif j.contains("StatusSTS") # Status 11 + j = j["StatusSTS"] + code = 11 + elif j.contains("StatusSHT") # Status 13 + j = j["StatusSTS"] + code = 13 + end + # convert to shadow values + self.parse_update(j, code) # call parser + end + end + end + + # ############################################################# + # # is_reachable() + # # + # # Pings the device and checks if it's reachable + # def is_reachable_lazy_sync() + # var cur_tick = self.device.tick + # if cur_tick != self.tick + # var ret = self.call_remote_sync("", "") # empty command works as a ping + # self.http_remote.device_is_alive(ret != nil) + # end + # return self.http_remote.reachable + # end + + ############################################################# + # read attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0039 # ========== Bridged Device Basic Information 9.13 p.485 ========== + import string + + if attribute == 0x0003 # ---------- ProductName / string ---------- + var name = self.http_remote.get_info().find("name") + if name + return tlv_solo.set(TLV.UTF1, name) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x000A # ---------- SoftwareVersionString / string ---------- + var version_full = self.http_remote.get_info().find("version") + if version_full + var version_end = string.find(version_full, '(') + if version_end > 0 version_full = version_full[0..version_end - 1] end + return tlv_solo.set(TLV.UTF1, version_full) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x000F || attribute == 0x0012 # ---------- SerialNumber || UniqueID / string ---------- + var mac = self.http_remote.get_info().find("mac") + if mac + return tlv_solo.set(TLV.UTF1, mac) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x0011 # ---------- Reachable / bool ---------- + # self.is_reachable_lazy_sync() # Not needed anymore + return tlv_solo.set(TLV.BOOL, self.http_remote.reachable) # TODO find a way to do a ping + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # every_250ms + # + # check if the timer expired and update_shadow() needs to be called + def every_250ms() + self.http_remote.scheduler() # defer to HTTP scheduler + # avoid calling update_shadow() since it's not applicable for HTTP remote + end + + ############################################################# + # web_values + # + # Show values of the remote device as HTML + static var PREFIX = "| %s " + def web_values() + import webserver + self.web_values_prefix() + webserver.content_send("<-- (" + self.DISPLAY_NAME + ") -->") + end + + # Show prefix before web value + def web_values_prefix() + import webserver + var name = self.get_name() + webserver.content_send(format(self.PREFIX, name ? webserver.html_escape(name) : "")) + end + + # Show on/off value as html + def web_value_onoff(onoff) + var onoff_html = (onoff != nil ? (onoff ? "On" : "Off") : "") + return onoff_html + end + + ############################################################# + # GetOption reader to decode `SetOption` values from `Status 3` + static class GetOptionReader + var flag, flag2, flag3, flag4, flag5, flag6 + + def init(j) + if j == nil raise "value_error", "invalid json" end + var so = j['SetOption'] + self.flag = bytes().fromhex(so[0]).reverse() + self.flag2 = bytes().fromhex(so[1]) + self.flag3 = bytes().fromhex(so[2]).reverse() + self.flag4 = bytes().fromhex(so[3]).reverse() + self.flag5 = bytes().fromhex(so[4]).reverse() + self.flag6 = bytes().fromhex(so[5]).reverse() + end + def getoption(x) + if x < 32 # SetOption0 .. 31 = Settings->flag + return self.flag.getbits(x, 1) + elif x < 50 # SetOption32 .. 49 = Settings->param + return self.flag2.get(x - 32, 1) + elif x < 82 # SetOption50 .. 81 = Settings->flag3 + return self.flag3.getbits(x - 50, 1) + elif x < 114 # SetOption82 .. 113 = Settings->flag4 + return self.flag4.getbits(x - 82, 1) + elif x < 146 # SetOption114 .. 145 = Settings->flag5 + return self.flag5.getbits(x - 114, 1) + elif x < 178 # SetOption146 .. 177 = Settings->flag6 + return self.flag6.getbits(x - 146, 1) + end + end + end + + #- Examples + + import json + + var p = '{"SerialLog":2,"WebLog":3,"MqttLog":0,"SysLog":0,"LogHost":"","LogPort":514,"SSId":["Livebox-781A",""],"TelePeriod":300,"Resolution":"558180C0","SetOption":["00008009","2805C80001800600003C5A0A192800000000","00000080","00006000","00006000","00000020"]}' + var j = json.load(p) + + var gor = matter.Plugin_Bridge_HTTP.GetOptionReader(j) + assert(gor.getoption(151) == 1) + assert(gor.getoption(150) == 0) + assert(gor.getoption(32) == 40) + assert(gor.getoption(37) == 128) + + -# +end +matter.Plugin_Bridge_HTTP = Matter_Plugin_Bridge_HTTP diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light0.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Light0.be similarity index 56% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light0.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Light0.be index 9e43a8189719..1dbdd226619a 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light0.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Light0.be @@ -17,32 +17,39 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Device end +# Matter plug-in for core behavior #@ solidify:Matter_Plugin_Light0,weak class Matter_Plugin_Light0 : Matter_Plugin_Device static var TYPE = "light0" # name of the plug-in in json - static var NAME = "Light 0 On" # display name of the plug-in + static var DISPLAY_NAME = "Light 0 On" # display name of the plug-in static var UPDATE_TIME = 250 # update every 250ms - static var CLUSTERS = { + static var CLUSTERS = matter.consolidate_clusters(_class, + { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 # 0x0003: inherited # Identify 1.2 p.16 # 0x0004: inherited # Groups 1.3 p.21 # 0x0005: inherited # Scenes 1.4 p.30 - no writable 0x0006: [0,0xFFFC,0xFFFD], # On/Off 1.5 p.48 - } + }) + static var UPDATE_COMMANDS = matter.UC_LIST(_class, "Power") static var TYPES = { 0x0100: 2 } # OnOff Light, but not actually used because Relay is managed by OnOff - var shadow_onoff + # Inherited + # var device # reference to the `device` global object + # var endpoint # current endpoint + # var clusters # map from cluster to list of attributes, typically constructed from CLUSTERS hierachy + # var tick # tick value when it was last updated + # var node_label # name of the endpoint, used only in bridge mode, "" if none + var shadow_onoff # (bool) status of the light power on/off ############################################################# # Constructor - def init(device, endpoint, arguments) - super(self).init(device, endpoint, arguments) + def init(device, endpoint, config) + super(self).init(device, endpoint, config) self.shadow_onoff = false end @@ -50,18 +57,37 @@ class Matter_Plugin_Light0 : Matter_Plugin_Device # Update shadow # def update_shadow() - import light - var light_status = light.get() - var pow = light_status.find('power', nil) - if pow != self.shadow_onoff self.attribute_updated(0x0006, 0x0000) self.shadow_onoff = pow end + if !self.VIRTUAL + import light + var light_status = light.get() + if light_status != nil + var pow = light_status.find('power', nil) + if pow != self.shadow_onoff + self.attribute_updated(0x0006, 0x0000) + self.shadow_onoff = pow + end + end + end super(self).update_shadow() end + def set_onoff(pow) + if !self.VIRTUAL + import light + light.set({'power':pow}) + self.update_shadow() + else + if pow != self.shadow_onoff + self.attribute_updated(0x0006, 0x0000) + self.shadow_onoff = pow + end + end + end + ############################################################# # read an attribute # - def read_attribute(session, ctx) - import string + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -70,15 +96,15 @@ class Matter_Plugin_Light0 : Matter_Plugin_Device if cluster == 0x0006 # ========== On/Off 1.5 p.48 ========== self.update_shadow_lazy() if attribute == 0x0000 # ---------- OnOff / bool ---------- - return TLV.create_TLV(TLV.BOOL, self.shadow_onoff) + return tlv_solo.set(TLV.BOOL, self.shadow_onoff) elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0) # 0 = no Level Control for Lighting + return tlv_solo.set(TLV.U4, 0) # 0 = no Level Control for Lighting elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 4) # 0 = no Level Control for Lighting + return tlv_solo.set(TLV.U4, 4) # 0 = no Level Control for Lighting end else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end end @@ -97,20 +123,39 @@ class Matter_Plugin_Light0 : Matter_Plugin_Device if cluster == 0x0006 # ========== On/Off 1.5 p.48 ========== self.update_shadow_lazy() if command == 0x0000 # ---------- Off ---------- - light.set({'power':false}) - self.update_shadow() + self.set_onoff(false) + self.publish_command('Power', 0) return true elif command == 0x0001 # ---------- On ---------- - light.set({'power':true}) - self.update_shadow() + self.set_onoff(true) + self.publish_command('Power', 1) return true elif command == 0x0002 # ---------- Toggle ---------- - light.set({'power':!self.shadow_onoff}) - self.update_shadow() + self.set_onoff(!self.shadow_onoff) + self.publish_command('Power', self.shadow_onoff ? 1 : 0) return true end end end + ############################################################# + # find_val_i - get value of map case insensitive + static def find_val_i(m, k) + var key_i = tasmota.find_key_i(m, k) + return m.find(key_i) + end + + ############################################################# + # update_virtual + # + # Update internal state for virtual devices + def update_virtual(payload_json) + var val_onoff = payload_json.find("Power") + if val_onoff != nil + self.set_onoff(bool(val_onoff)) + end + super(self).update_virtual(payload_json) + end + end matter.Plugin_Light0 = Matter_Plugin_Light0 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_OnOff.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_OnOff.be similarity index 58% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_OnOff.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_OnOff.be index 585a5bce5ba3..ad66d4c75ae4 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_OnOff.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_OnOff.be @@ -17,50 +17,65 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Device end +# Matter plug-in for core behavior #@ solidify:Matter_Plugin_OnOff,weak class Matter_Plugin_OnOff : Matter_Plugin_Device static var TYPE = "relay" # name of the plug-in in json - static var NAME = "Relay" # display name of the plug-in + static var DISPLAY_NAME = "Relay" # display name of the plug-in static var ARG = "relay" # additional argument name (or empty if none) static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type + static var ARG_HINT = "Relay number" static var UPDATE_TIME = 250 # update every 250ms - static var CLUSTERS = { + static var CLUSTERS = matter.consolidate_clusters(_class, { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 # 0x0003: inherited # Identify 1.2 p.16 # 0x0004: inherited # Groups 1.3 p.21 # 0x0005: inherited # Scenes 1.4 p.30 - no writable 0x0006: [0,0xFFFC,0xFFFD], # On/Off 1.5 p.48 - } - static var TYPES = { 0x010A: 2 } # On/Off Light + }) + static var UPDATE_COMMANDS = matter.UC_LIST(_class, "Power") + static var TYPES = { 0x010A: 2 } # On/Off Plug-in Unit - var tasmota_relay_index # Relay number in Tasmota (zero based) - var shadow_onoff # fake status for now # TODO + # Inherited + # var device # reference to the `device` global object + # var endpoint # current endpoint + # var clusters # map from cluster to list of attributes, typically constructed from CLUSTERS hierachy + # var tick # tick value when it was last updated + # var node_label # name of the endpoint, used only in bridge mode, "" if none + var tasmota_relay_index # Relay number in Tasmota (zero based) ############################################################# # Constructor - def init(device, endpoint, arguments) - super(self).init(device, endpoint, arguments) + def init(device, endpoint, config) + super(self).init(device, endpoint, config) self.shadow_onoff = false - self.tasmota_relay_index = arguments.find(self.ARG #-'relay'-#) - if self.tasmota_relay_index == nil self.tasmota_relay_index = 0 end + end + + ############################################################# + # parse_configuration + # + # Parse configuration map + def parse_configuration(config) + self.tasmota_relay_index = int(config.find(self.ARG #-'relay'-#, 1)) + if self.tasmota_relay_index <= 0 self.tasmota_relay_index = 1 end end ############################################################# # Update shadow # def update_shadow() - var state = tasmota.get_power(self.tasmota_relay_index) - if state != nil - if self.shadow_onoff != nil && self.shadow_onoff != bool(state) - self.attribute_updated(0x0006, 0x0000) + if !self.VIRTUAL + var pow = tasmota.get_power(self.tasmota_relay_index - 1) + if pow != nil + if self.shadow_onoff != bool(pow) + self.attribute_updated(0x0006, 0x0000) + end + self.shadow_onoff = pow end - self.shadow_onoff = state end super(self).update_shadow() end @@ -68,16 +83,22 @@ class Matter_Plugin_OnOff : Matter_Plugin_Device ############################################################# # Model # - def set_onoff(v) - tasmota.set_power(self.tasmota_relay_index, bool(v)) - self.update_shadow() + def set_onoff(pow) + if !self.VIRTUAL + tasmota.set_power(self.tasmota_relay_index - 1, bool(pow)) + self.update_shadow() + else + if pow != self.shadow_onoff + self.attribute_updated(0x0006, 0x0000) + self.shadow_onoff = pow + end + end end ############################################################# # read an attribute # - def read_attribute(session, ctx) - import string + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -86,15 +107,15 @@ class Matter_Plugin_OnOff : Matter_Plugin_Device if cluster == 0x0006 # ========== On/Off 1.5 p.48 ========== self.update_shadow_lazy() if attribute == 0x0000 # ---------- OnOff / bool ---------- - return TLV.create_TLV(TLV.BOOL, self.shadow_onoff) + return tlv_solo.set(TLV.BOOL, self.shadow_onoff) elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0) # 0 = no Level Control for Lighting + return tlv_solo.set(TLV.U4, 0) # 0 = no Level Control for Lighting elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 4) # 0 = no Level Control for Lighting + return tlv_solo.set(TLV.U4, 4) # 0 = no Level Control for Lighting end else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end end @@ -113,20 +134,32 @@ class Matter_Plugin_OnOff : Matter_Plugin_Device self.update_shadow_lazy() if command == 0x0000 # ---------- Off ---------- self.set_onoff(false) - self.update_shadow() + self.publish_command('Power', 0) return true elif command == 0x0001 # ---------- On ---------- self.set_onoff(true) - self.update_shadow() + self.publish_command('Power', 1) return true elif command == 0x0002 # ---------- Toggle ---------- self.set_onoff(!self.shadow_onoff) - self.update_shadow() + self.publish_command('Power', self.shadow_onoff ? 1 : 0) return true end end end + ############################################################# + # update_virtual + # + # Update internal state for virtual devices + def update_virtual(payload_json) + var val_onoff = payload_json.find("Power") + if val_onoff != nil + self.set_onoff(bool(val_onoff)) + end + super(self).update_virtual(payload_json) + end + end matter.Plugin_OnOff = Matter_Plugin_OnOff diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Sensor.be similarity index 68% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Sensor.be index c3f595045f33..bb44c91aa5f0 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Sensor.be @@ -17,25 +17,27 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Device end +# Matter plug-in for core behavior #@ solidify:Matter_Plugin_Sensor,weak class Matter_Plugin_Sensor : Matter_Plugin_Device static var ARG = "filter" # additional argument name (or empty if none) + static var ARG_HINT = "Filter pattern" static var UPDATE_TIME = 5000 # update sensor every 5s + static var JSON_NAME = "" # Name of the sensor attribute in JSON payloads var tasmota_sensor_filter # Rule-type filter to the value, like "ESP32#Temperature" var tasmota_sensor_matcher # Actual matcher object var shadow_value # Last known value ############################################################# - # Constructor - def init(device, endpoint, arguments) - super(self).init(device, endpoint, arguments) - self.tasmota_sensor_filter = arguments.find(self.ARG#-'filter'-#) + # parse_configuration + # + # Parse configuration map + def parse_configuration(config) + self.tasmota_sensor_filter = config.find(self.ARG#-'filter'-#) if self.tasmota_sensor_filter self.tasmota_sensor_matcher = tasmota.Rule_Matcher.parse(self.tasmota_sensor_filter) end @@ -51,9 +53,9 @@ class Matter_Plugin_Sensor : Matter_Plugin_Device var val = self.pre_value(real(self.tasmota_sensor_matcher.match(payload))) if val != nil if val != self.shadow_value - self.value_changed(val) + self.value_changed() + self.shadow_value = val end - self.shadow_value = val end end end @@ -63,7 +65,7 @@ class Matter_Plugin_Sensor : Matter_Plugin_Device # # This must be overriden. # This is where you call `self.attribute_updated(, )` - def value_changed(val) + def value_changed() # self.attribute_updated(0x0402, 0x0000) end @@ -76,5 +78,32 @@ class Matter_Plugin_Sensor : Matter_Plugin_Device return val end + ############################################################# + # update_virtual + # + # Update internal state for virtual devices + def update_virtual(payload_json) + var val = payload_json.find(self.JSON_NAME) + if val != nil + if type(val) == 'bool' val = int(val) end + + if self.shadow_value != val + self.value_changed() + self.shadow_value = val + end + end + super(self).update_virtual(payload_json) + end + + ############################################################# + # append_state_json + # + # Output the current state in JSON + # New values need to be appended with `,"key":value` (including prefix comma) + def append_state_json() + var val = (self.shadow_value != nil) ? self.shadow_value : "null" + return f',"{self.JSON_NAME}":{val}' + end + end matter.Plugin_Sensor = Matter_Plugin_Sensor diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Shutter.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Shutter.be similarity index 85% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Shutter.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Shutter.be index c08289cab29a..54e832f851b4 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Shutter.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_2_Shutter.be @@ -17,39 +17,39 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Device end +# Matter plug-in for core behavior #@ solidify:Matter_Plugin_Shutter,weak class Matter_Plugin_Shutter : Matter_Plugin_Device static var TYPE = "shutter" # name of the plug-in in json - static var NAME = "Shutter" # display name of the plug-in + static var DISPLAY_NAME = "Shutter" # display name of the plug-in static var ARG = "shutter" # additional argument name (or empty if none) static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type - static var CLUSTERS = { + static var ARG_HINT = "Relay number" + static var CLUSTERS = matter.consolidate_clusters(_class, { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 # 0x0003: inherited # Identify 1.2 p.16 # 0x0004: inherited # Groups 1.3 p.21 # 0x0005: inherited # Scenes 1.4 p.30 - no writable 0x0102: [0,5,7,0xA,0xB,0xD,0xE,0x17,0xFFFC,0xFFFD], # Window Covering 5.3 p.289 - } + }) static var TYPES = { 0x0202: 2 } # New data model format and notation var tasmota_shutter_index # Shutter number in Tasmota (zero based) var shadow_shutter_pos var shadow_shutter_target - var shadow_shutter_tilt var shadow_shutter_direction # 1=opening -1=closing 0=not moving TODO var shadow_shutter_inverted # 1=same as matter 0=matter must invert ############################################################# - # Constructor - def init(device, endpoint, arguments) - super(self).init(device, endpoint, arguments) - self.tasmota_shutter_index = arguments.find(self.ARG #-'relay'-#) + # parse_configuration + # + # Parse configuration map + def parse_configuration(config) + self.tasmota_shutter_index = config.find(self.ARG #-'relay'-#) if self.tasmota_shutter_index == nil self.tasmota_shutter_index = 0 end self.shadow_shutter_inverted = -1 end @@ -65,10 +65,10 @@ class Matter_Plugin_Shutter : Matter_Plugin_Device if r_st13.contains('StatusSHT') r_st13 = r_st13['StatusSHT'] # skip root var d = r_st13.find("SHT"+str(self.tasmota_shutter_index), {}).find('Opt') - tasmota.log("MTR: opt: "+str(d)) + # tasmota.log("MTR: opt: "+str(d)) if d != nil self.shadow_shutter_inverted = int(d[size(d)-1]) # inverted is at the most right character - tasmota.log("MTR: Inverted flag: "+str(self.shadow_shutter_inverted)) + # tasmota.log("MTR: Inverted flag: "+str(self.shadow_shutter_inverted)) end end end @@ -89,8 +89,7 @@ class Matter_Plugin_Shutter : Matter_Plugin_Device ############################################################# # read an attribute # - def read_attribute(session, ctx) - import string + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -101,42 +100,42 @@ class Matter_Plugin_Shutter : Matter_Plugin_Device self.update_shadow_lazy() self.update_inverted() if attribute == 0x0000 # ---------- Type / enum8 ---------- - return TLV.create_TLV(TLV.U1, 0xFF) # 0xFF = unknown type of shutter + return tlv_solo.set(TLV.U1, 0xFF) # 0xFF = unknown type of shutter elif attribute == 0x0005 # ---------- NumberOfActuationsLift / u16 ---------- - return TLV.create_TLV(TLV.U2, 0) + return tlv_solo.set(TLV.U2, 0) elif attribute == 0x0007 # ---------- ConfigStatus / u8 ---------- - return TLV.create_TLV(TLV.U1, 1 + 8) # Operational + Lift Position Aware + return tlv_solo.set(TLV.U1, 1 + 8) # Operational + Lift Position Aware elif attribute == 0x000D # ---------- EndProductType / u8 ---------- - return TLV.create_TLV(TLV.U1, 0xFF) # 0xFF = unknown type of shutter + return tlv_solo.set(TLV.U1, 0xFF) # 0xFF = unknown type of shutter elif attribute == 0x000E # ---------- CurrentPositionLiftPercent100ths / u16 ---------- if self.shadow_shutter_inverted == 0 matter_position = (100 - self.shadow_shutter_pos) * 100 else matter_position = self.shadow_shutter_pos * 100 end - return TLV.create_TLV(TLV.U2, matter_position) + return tlv_solo.set(TLV.U2, matter_position) elif attribute == 0x000A # ---------- OperationalStatus / u8 ---------- var op = self.shadow_shutter_direction == 0 ? 0 : (self.shadow_shutter_direction > 0 ? 1 : 2) - return TLV.create_TLV(TLV.U1, op) + return tlv_solo.set(TLV.U1, op) elif attribute == 0x000B # ---------- TargetPositionLiftPercent100ths / u16 ---------- if self.shadow_shutter_inverted == 0 matter_position = (100 - self.shadow_shutter_target) * 100 else matter_position = self.shadow_shutter_target * 100 end - return TLV.create_TLV(TLV.U2, matter_position) + return tlv_solo.set(TLV.U2, matter_position) elif attribute == 0x0017 # ---------- Mode / u8 ---------- - return TLV.create_TLV(TLV.U1, 0) # normal mode + return tlv_solo.set(TLV.U1, 0) # normal mode elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 1 + 4) # Lift + PA_LF + return tlv_solo.set(TLV.U4, 1 + 4) # Lift + PA_LF elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 5) # New data model format and notation + return tlv_solo.set(TLV.U4, 5) # New data model format and notation end else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end end @@ -193,11 +192,10 @@ class Matter_Plugin_Shutter : Matter_Plugin_Device # parse the output from `ShutterPosition` # Ex: `{"Shutter1":{"Position":50,"Direction":0,"Target":50,"Tilt":30}}` def parse_sensors(payload) - import string var k = "Shutter" + str(self.tasmota_shutter_index + 1) if payload.contains(k) var v = payload[k] - # tasmota.log(string.format("MTR: getting shutter values(%i): %s", self.endpoint, str(v)), 2) + # tasmota.log(format("MTR: getting shutter values(%i): %s", self.endpoint, str(v)), 2) # Position var val_pos = v.find("Position") if val_pos != nil diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_OnOff.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Bridge_Light0.be similarity index 55% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_OnOff.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Bridge_Light0.be index 49aa7a507053..fe0bc8a81018 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_OnOff.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Bridge_Light0.be @@ -1,5 +1,5 @@ # -# Matter_Plugin_Bridge_OnOff.be - implements the behavior for a Relay via HTTP (OnOff) +# Matter_Plugin_Bridge_Light0.be - implements the behavior for a remote generic Lighting (OnOff only) via HTTP # # Copyright (C) 2023 Stephan Hadinger & Theo Arends # @@ -17,70 +17,77 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Bridge_HTTP end +# Matter plug-in for core behavior -#@ solidify:Matter_Plugin_Bridge_OnOff,weak +#@ solidify:Matter_Plugin_Bridge_Light0,weak -class Matter_Plugin_Bridge_OnOff : Matter_Plugin_Bridge_HTTP - static var TYPE = "http_relay" # name of the plug-in in json - static var NAME = "🔗 Relay" # display name of the plug-in +class Matter_Plugin_Bridge_Light0 : Matter_Plugin_Bridge_HTTP + static var TYPE = "http_light0" # name of the plug-in in json + static var DISPLAY_NAME = "Light 0 On" # display name of the plug-in static var ARG = "relay" # additional argument name (or empty if none) + static var ARG_HINT = "Power number" static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type - static var CLUSTERS = { + # static var UPDATE_TIME = 3000 # update every 3s + # static var UPDATE_CMD = "Status 11" # command to send for updates + static var CLUSTERS = matter.consolidate_clusters(_class, { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 # 0x0003: inherited # Identify 1.2 p.16 # 0x0004: inherited # Groups 1.3 p.21 # 0x0005: inherited # Scenes 1.4 p.30 - no writable 0x0006: [0,0xFFFC,0xFFFD], # On/Off 1.5 p.48 - } - static var TYPES = { 0x010A: 2 } # On/Off Light + }) + static var TYPES = { 0x0100: 2 } # OnOff Light, but not actually used because Relay is managed by OnOff - var tasmota_http # domain name for HTTP - var tasmota_relay_index # Relay number in Tasmota (zero based) + var tasmota_relay_index # Relay number in Tasmota (one based) var shadow_onoff # fake status for now # TODO ############################################################# # Constructor def init(device, endpoint, arguments) - import string super(self).init(device, endpoint, arguments) self.shadow_onoff = false - self.tasmota_relay_index = arguments.find(self.ARG #-'relay'-#) - if self.tasmota_relay_index == nil self.tasmota_relay_index = 0 end + self.tasmota_relay_index = int(arguments.find(self.ARG #-'relay'-#, 1)) + if self.tasmota_relay_index <= 0 self.tasmota_relay_index = 1 end end ############################################################# - # Update shadow + # Stub for updating shadow values (local copies of what we published to the Matter gateway) # - def update_shadow() - var st11 = self.get_status_11() - if st11 - st11 = st11.find('StatusSTS', {}) # remove first level - var state = (st11.find("POWER") == "ON") + # This call is synnchronous and blocking. + def parse_update(data, index) + if index == 11 # Status 11 + var state = false + + if self.tasmota_relay_index == 1 && data.contains("POWER") # special case, can be `POWER` or `POWER1` + state = (data.find("POWER") == "ON") + else + state = (data.find("POWER" + str(self.tasmota_relay_index)) == "ON") + end + if self.shadow_onoff != nil && self.shadow_onoff != bool(state) self.attribute_updated(0x0006, 0x0000) end self.shadow_onoff = state end - super(self).update_shadow() end ############################################################# # Model # def set_onoff(v) - self.call_remote("Power", v ? "1" : "0") - self.update_shadow() + var ret = self.call_remote_sync("Power" + str(self.tasmota_relay_index), v ? "1" : "0") + if ret != nil + self.parse_update(ret, 11) # update shadow from return value + # self.tick = self.device.tick # prevent an explicit Status11 for as it is not needed if the subscription update is sent in same tick + end end ############################################################# # read an attribute # - def read_attribute(session, ctx) - import string + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -89,15 +96,15 @@ class Matter_Plugin_Bridge_OnOff : Matter_Plugin_Bridge_HTTP if cluster == 0x0006 # ========== On/Off 1.5 p.48 ========== self.update_shadow_lazy() if attribute == 0x0000 # ---------- OnOff / bool ---------- - return TLV.create_TLV(TLV.BOOL, self.shadow_onoff) + return tlv_solo.set(TLV.BOOL, self.shadow_onoff) elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0) # 0 = no Level Control for Lighting + return tlv_solo.set(TLV.U4, 0) # 0 = no Level Control for Lighting elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 4) # 0 = no Level Control for Lighting + return tlv_solo.set(TLV.U4, 4) # 0 = no Level Control for Lighting end else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end end @@ -113,23 +120,42 @@ class Matter_Plugin_Bridge_OnOff : Matter_Plugin_Bridge_HTTP # ==================================================================================================== if cluster == 0x0006 # ========== On/Off 1.5 p.48 ========== - self.update_shadow_lazy() if command == 0x0000 # ---------- Off ---------- self.set_onoff(false) - self.update_shadow() + self.publish_command('Power', 0) return true elif command == 0x0001 # ---------- On ---------- self.set_onoff(true) - self.update_shadow() + self.publish_command('Power', 1) return true elif command == 0x0002 # ---------- Toggle ---------- self.set_onoff(!self.shadow_onoff) - self.update_shadow() + self.publish_command('Power', self.shadow_onoff ? 1 : 0) return true end end end + ############################################################# + # web_values + # + # Show values of the remote device as HTML + def web_values() + import webserver + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(format("%s", self.web_value_onoff(self.shadow_onoff))) + end + + # Show prefix before web value + def web_values_prefix() + import webserver + var name = self.get_name() + if !name + name = "Power" + str(self.tasmota_relay_index) + end + webserver.content_send(format(self.PREFIX, name ? webserver.html_escape(name) : "")) + end + end -matter.Plugin_Bridge_OnOff = Matter_Plugin_Bridge_OnOff +matter.Plugin_Bridge_Light0 = Matter_Plugin_Bridge_Light0 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Bridge_Sensor.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Bridge_Sensor.be new file mode 100644 index 000000000000..301c1c02a769 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Bridge_Sensor.be @@ -0,0 +1,122 @@ +# +# Matter_Plugin_Bridge_Sensor.be - implements base class for a Sensor via HTTP to Tasmota +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Bridge_Sensor,weak + +class Matter_Plugin_Bridge_Sensor : Matter_Plugin_Bridge_HTTP + # static var TYPE = "" # name of the plug-in in json + # static var DISPLAY_NAME = "" # display name of the plug-in + static var ARG = "filter" # additional argument name (or empty if none) + static var ARG_HTTP = "url" # domain name + static var ARG_HINT = "Filter pattern" + static var UPDATE_TIME = 5000 # update every 5s + static var UPDATE_CMD = "Status 8" # command to send for updates + static var PROBE_TIMEOUT = 1700 # timeout of 1700 ms for probing, which gives at least 1s for TCP recovery + # static var SYNC_TIMEOUT = 500 # timeout of 700 ms for probing + var tasmota_sensor_filter # Rule-type filter to the value, like "ESP32#Temperature" + var tasmota_sensor_matcher # Actual matcher object + var shadow_value # Last known value + var temp_unit # temperature unit, "C" or "F" + static var TEMP_C = "C" + static var TEMP_F = "F" + var pressure_unit # pressure unit, "hPa" or "mmHg" or "inHg" + static var PRESSURE_HPA = "hPa" + static var PRESSURE_MMHG = "mmHg" + static var PRESSURE_INHG = "inHg" + + ############################################################# + # parse_configuration + # + # Parse configuration map + def parse_configuration(config) + self.tasmota_sensor_filter = config.find(self.ARG#-'filter'-#) + if self.tasmota_sensor_filter + self.tasmota_sensor_matcher = tasmota.Rule_Matcher.parse(self.tasmota_sensor_filter) + end + self.temp_unit = self.TEMP_C + self.pressure_unit = self.PRESSURE_HPA + end + + ############################################################# + # Stub for updating shadow values (local copies of what we published to the Matter gateway) + # + # TO BE OVERRIDDEN + def parse_update(data, index) + if index == 8 # Status 8 + if data.contains("TempUnit") + self.temp_unit = data["TempUnit"] + end + if data.contains("PressureUnit") + self.pressure_unit = data["PressureUnit"] + end + if self.tasmota_sensor_matcher + var val = self.pre_value(real(self.tasmota_sensor_matcher.match(data))) + if val != nil + if val != self.shadow_value + self.value_changed() + self.shadow_value = val + end + end + end + end + end + + ############################################################# + # Called when the value changed compared to shadow value + # + # This must be overriden. + # This is where you call `self.attribute_updated(, )` + def value_changed() + # self.attribute_updated(0x0402, 0x0000) + end + + ############################################################# + # Pre-process value + # + # This must be overriden. + # This allows to convert the raw sensor value to the target one, typically int + def pre_value(val) + return val + end + + ############################################################# + # Return the first item in the filter + def filter_name_html() + if self.tasmota_sensor_filter + import string + import webserver + return webserver.html_escape(string.split(self.tasmota_sensor_filter, '#')[0]) + end + return "" + end + + # Show prefix before web value + def web_values_prefix() + import webserver + var name = self.get_name() + if (!name) name = self.filter_name_html() end + webserver.content_send(format(self.PREFIX, name ? webserver.html_escape(name) : "")) + end + +end +matter.Plugin_Bridge_Sensor = Matter_Plugin_Bridge_Sensor diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light1.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Light1.be similarity index 56% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light1.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Light1.be index 531f3fd61b43..03a55b1c7d90 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light1.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Light1.be @@ -17,28 +17,34 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Light0 end +# Matter plug-in for core behavior #@ solidify:Matter_Plugin_Light1,weak class Matter_Plugin_Light1 : Matter_Plugin_Light0 static var TYPE = "light1" # name of the plug-in in json - static var NAME = "Light 1 Dimmer" # display name of the plug-in - static var CLUSTERS = { + static var DISPLAY_NAME = "Light 1 Dimmer" # display name of the plug-in + static var CLUSTERS = matter.consolidate_clusters(_class, { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 # 0x0003: inherited # Identify 1.2 p.16 # 0x0004: inherited # Groups 1.3 p.21 # 0x0005: inherited # Scenes 1.4 p.30 - no writable # 0x0006: inherited # On/Off 1.5 p.48 0x0008: [0,2,3,0x0F,0x11,0xFFFC,0xFFFD], # Level Control 1.6 p.57 - } + }) + static var UPDATE_COMMANDS = matter.UC_LIST(_class, "Bri") static var TYPES = { 0x0101: 2 } # Dimmable Light - var shadow_bri - # var shadow_onoff # inherited + # Inherited + # var device # reference to the `device` global object + # var endpoint # current endpoint + # var clusters # map from cluster to list of attributes, typically constructed from CLUSTERS hierachy + # var tick # tick value when it was last updated + # var node_label # name of the endpoint, used only in bridge mode, "" if none + # var shadow_onoff # (bool) status of the light power on/off + var shadow_bri # (int 0..254) brightness before Gamma correction - as per Matter 255 is not allowed ############################################################# # Constructor @@ -51,24 +57,57 @@ class Matter_Plugin_Light1 : Matter_Plugin_Light0 # Update shadow # def update_shadow() - import light - var light_status = light.get() - var bri = light_status.find('bri', nil) - if bri != nil - bri = tasmota.scale_uint(bri, 0, 255, 0, 254) - if bri != self.shadow_bri - self.attribute_updated(0x0008, 0x0000) - self.shadow_bri = bri + if !self.VIRTUAL + import light + var light_status = light.get() + if light_status != nil + var bri = light_status.find('bri', nil) + if bri != nil + bri = tasmota.scale_uint(bri, 0, 255, 0, 254) + if bri != self.shadow_bri + self.attribute_updated(0x0008, 0x0000) + self.shadow_bri = bri + end + end end end super(self).update_shadow() # superclass manages 'power' end + ############################################################# + # Set Bri + # + # `bri` is in range 0.255 and not 0..254 like in Matter + # `pow` can be bool on `nil` if no change + def set_bri(bri_254, pow) + if (bri_254 < 0) bri_254 = 0 end + if (bri_254 > 254) bri_254 = 254 end + pow = (pow != nil) ? bool(pow) : nil # nil or bool + if !self.VIRTUAL + import light + var bri_255 = tasmota.scale_uint(bri_254, 0, 254, 0, 255) + if pow == nil + light.set({'bri': bri_255}) + else + light.set({'bri': bri_255, 'power': pow}) + end + self.update_shadow() + else + if (pow != nil) && (pow != self.shadow_onoff) + self.attribute_updated(0x0006, 0x0000) + self.shadow_onoff = pow + end + if bri_254 != self.shadow_bri + self.attribute_updated(0x0008, 0x0000) + self.shadow_bri = bri_254 + end + end + end + ############################################################# # read an attribute # - def read_attribute(session, ctx) - import string + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -77,23 +116,23 @@ class Matter_Plugin_Light1 : Matter_Plugin_Light0 if cluster == 0x0008 # ========== Level Control 1.6 p.57 ========== self.update_shadow_lazy() if attribute == 0x0000 # ---------- CurrentLevel / u1 ---------- - return TLV.create_TLV(TLV.U1, self.shadow_bri) + return tlv_solo.set(TLV.U1, self.shadow_bri) elif attribute == 0x0002 # ---------- MinLevel / u1 ---------- - return TLV.create_TLV(TLV.U1, 0) + return tlv_solo.set(TLV.U1, 0) elif attribute == 0x0003 # ---------- MaxLevel / u1 ---------- - return TLV.create_TLV(TLV.U1, 254) + return tlv_solo.set(TLV.U1, 254) elif attribute == 0x000F # ---------- Options / map8 ---------- - return TLV.create_TLV(TLV.U1, 0) # + return tlv_solo.set(TLV.U1, 0) # elif attribute == 0x0011 # ---------- OnLevel / u1 ---------- - return TLV.create_TLV(TLV.U1, self.shadow_bri) + return tlv_solo.set(TLV.U1, self.shadow_bri) elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0X01) # OnOff + return tlv_solo.set(TLV.U4, 0X01) # OnOff elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 5) # "new data model format and notation" + return tlv_solo.set(TLV.U4, 5) # "new data model format and notation" end else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end end @@ -112,11 +151,10 @@ class Matter_Plugin_Light1 : Matter_Plugin_Light0 if cluster == 0x0008 # ========== Level Control 1.6 p.57 ========== self.update_shadow_lazy() if command == 0x0000 # ---------- MoveToLevel ---------- - var bri_in = val.findsubval(0) # Hue 0..254 - var bri = tasmota.scale_uint(bri_in, 0, 254, 0, 255) - light.set({'bri': bri}) - self.update_shadow() - ctx.log = "bri:"+str(bri_in) + var bri_254 = val.findsubval(0) # Hue 0..254 + self.set_bri(bri_254) + ctx.log = "bri:"+str(bri_254) + self.publish_command('Bri', bri_254, 'Dimmer', tasmota.scale_uint(bri_254, 0, 254, 0, 100)) return true elif command == 0x0001 # ---------- Move ---------- # TODO, we don't really support it @@ -128,12 +166,11 @@ class Matter_Plugin_Light1 : Matter_Plugin_Light0 # TODO, we don't really support it return true elif command == 0x0004 # ---------- MoveToLevelWithOnOff ---------- - var bri_in = val.findsubval(0) # Hue 0..254 - var bri = tasmota.scale_uint(bri_in, 0, 254, 0, 255) - var onoff = bri > 0 - light.set({'bri': bri, 'power': onoff}) - self.update_shadow() - ctx.log = "bri:"+str(bri_in) + var bri_254 = val.findsubval(0) # Hue 0..254 + var onoff = bri_254 > 0 + self.set_bri(bri_254, onoff) + ctx.log = "bri:"+str(bri_254) + self.publish_command('Bri', bri_254, 'Dimmer', tasmota.scale_uint(bri_254, 0, 254, 0, 100), 'Power', onoff ? 1 : 0) return true elif command == 0x0005 # ---------- MoveWithOnOff ---------- # TODO, we don't really support it @@ -151,5 +188,19 @@ class Matter_Plugin_Light1 : Matter_Plugin_Light0 end end + ############################################################# + # update_virtual + # + # Update internal state for virtual devices + def update_virtual(payload_json) + var val_onoff = payload_json.find("Power") + var val_bri = payload_json.find("Bri") + if val_bri != nil + self.set_bri(int(val_bri), val_onoff) + return # don't call super() because we already handeld 'Power' + end + super(self).update_virtual(payload_json) + end + end matter.Plugin_Light1 = Matter_Plugin_Light1 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Contact.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Contact.be new file mode 100644 index 000000000000..d420e09c469a --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Contact.be @@ -0,0 +1,132 @@ +# +# Matter_Plugin_Sensor_Contact.be - implements the behavior for a Contact Sensor +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Sensor_Contact,weak + +class Matter_Plugin_Sensor_Contact : Matter_Plugin_Device + static var TYPE = "contact" # name of the plug-in in json + static var DISPLAY_NAME = "Contact" # display name of the plug-in + static var ARG = "switch" # additional argument name (or empty if none) + static var ARG_HINT = "Switch number" + static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type + static var UPDATE_TIME = 750 # update every 750ms + static var CLUSTERS = matter.consolidate_clusters(_class, { + 0x0045: [0,0xFFFC,0xFFFD], # Boolean State p.70 - no writable + }) + static var TYPES = { 0x0015: 1 } # Contact Sensor, rev 1 + + var tasmota_switch_index # Switch number in Tasmota (one based) + var shadow_contact + + ############################################################# + # Constructor + def init(device, endpoint, config) + super(self).init(device, endpoint, config) + self.shadow_contact = false + end + + ############################################################# + # parse_configuration + # + # Parse configuration map + def parse_configuration(config) + self.tasmota_switch_index = int(config.find(self.ARG #-'switch'-#, 1)) + if self.tasmota_switch_index <= 0 self.tasmota_switch_index = 1 end + end + + ############################################################# + # Update shadow + # + def update_shadow() + super(self).update_shadow() + + import json + var ret = tasmota.cmd("Status 8", true) + if ret != nil + var j = json.load(ret) + if j != nil + var state = false + state = (j.find("Switch" + str(self.tasmota_switch_index)) == "ON") + + if self.shadow_contact != state + self.attribute_updated(0x0045, 0x0000) + self.shadow_contact = state + end + end + end + end + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0045 # ========== Boolean State ========== + if attribute == 0x0000 # ---------- StateValue / bool ---------- + if self.shadow_contact != nil + return tlv_solo.set(TLV.BOOL, self.shadow_contact) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0) + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 1) # 1 = Initial release + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # update_virtual + # + # Update internal state for virtual devices + def update_virtual(payload_json) + var val_onoff = payload_json.find("Contact") + if val_onoff != nil + val_onoff = bool(val_onoff) + if self.shadow_contact != val_onoff + self.attribute_updated(0x0045, 0x0000) + self.shadow_contact = val_onoff + end + end + super(self).update_virtual(payload_json) + end + + ############################################################# + # append_state_json + # + # Output the current state in JSON + # New values need to be appended with `,"key":value` (including prefix comma) + def append_state_json() + return f',"Contact":{int(self.shadow_contact)}' + end + +end +matter.Plugin_Sensor_Contact = Matter_Plugin_Sensor_Contact diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Humidity.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Humidity.be similarity index 77% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Humidity.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Humidity.be index 1165b9e65c6e..e3ff441846fc 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Humidity.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Humidity.be @@ -17,19 +17,20 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Sensor end +# Matter plug-in for core behavior #@ solidify:Matter_Plugin_Sensor_Humidity,weak class Matter_Plugin_Sensor_Humidity : Matter_Plugin_Sensor static var TYPE = "humidity" # name of the plug-in in json - static var NAME = "Humidity" # display name of the plug-in - static var CLUSTERS = { + static var DISPLAY_NAME = "Humidity" # display name of the plug-in + static var JSON_NAME = "Humidity" # Name of the sensor attribute in JSON payloads + static var UPDATE_COMMANDS = matter.UC_LIST(_class, "Humidity") + static var CLUSTERS = matter.consolidate_clusters(_class, { 0x0405: [0,1,2,0xFFFC,0xFFFD], # Humidity Measurement p.102 - no writable - } + }) static var TYPES = { 0x0307: 2 } # Humidity Sensor, rev 2 ############################################################# @@ -46,15 +47,14 @@ class Matter_Plugin_Sensor_Humidity : Matter_Plugin_Sensor # # This must be overriden. # This is where you call `self.attribute_updated(, )` - def value_changed(val) + def value_changed() self.attribute_updated(0x0405, 0x0000) end ############################################################# # read an attribute # - def read_attribute(session, ctx) - import string + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -63,22 +63,22 @@ class Matter_Plugin_Sensor_Humidity : Matter_Plugin_Sensor if cluster == 0x0405 # ========== Humidity Measurement 2.4 p.98 ========== if attribute == 0x0000 # ---------- Humidity / u16 ---------- if self.shadow_value != nil - return TLV.create_TLV(TLV.U2, int(self.shadow_value)) + return tlv_solo.set(TLV.U2, int(self.shadow_value)) else - return TLV.create_TLV(TLV.NULL, nil) + return tlv_solo.set(TLV.NULL, nil) end elif attribute == 0x0001 # ---------- MinMeasuredValue / u16 ---------- - return TLV.create_TLV(TLV.U2, 500) # 0% + return tlv_solo.set(TLV.U2, 500) # 0% elif attribute == 0x0002 # ---------- MaxMeasuredValue / u16 ---------- - return TLV.create_TLV(TLV.U2, 10000) # 100% + return tlv_solo.set(TLV.U2, 10000) # 100% elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0) # 0 = no Extended Range + return tlv_solo.set(TLV.U4, 0) # 0 = no Extended Range elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 3) # 3 = New data model format and notation + return tlv_solo.set(TLV.U4, 3) # 3 = New data model format and notation end else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Illuminance.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Illuminance.be similarity index 72% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Illuminance.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Illuminance.be index 1ba16a5eb52e..e49de236dc44 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Illuminance.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Illuminance.be @@ -17,20 +17,21 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Sensor end +# Matter plug-in for core behavior #@ solidify:Matter_Plugin_Sensor_Illuminance,weak class Matter_Plugin_Sensor_Illuminance : Matter_Plugin_Sensor static var TYPE = "illuminance" # name of the plug-in in json - static var NAME = "Illuminance" # display name of the plug-in - static var CLUSTERS = { + static var DISPLAY_NAME = "Illuminance" # display name of the plug-in + static var JSON_NAME = "Illuminance" # Name of the sensor attribute in JSON payloads + static var UPDATE_COMMANDS = matter.UC_LIST(_class, "Illuminance") + static var CLUSTERS = matter.consolidate_clusters(_class, { 0x0400: [0,1,2,0xFFFC,0xFFFD], # Illuminance Measurement p.95 - no writable - } - static var TYPES = { 0x0106: 2 } # Temperature Sensor, rev 2 + }) + static var TYPES = { 0x0106: 2 } # Illuminance Sensor, rev 2 ############################################################# # Pre-process value @@ -38,7 +39,14 @@ class Matter_Plugin_Sensor_Illuminance : Matter_Plugin_Sensor # This must be overriden. # This allows to convert the raw sensor value to the target one, typically int def pre_value(val) - return val != nil ? int(val) : nil # value in lux + if val == nil return nil end + import math + + if val < 0 + return 0 + else + return math.log10(val + 1) * 10000 + end end ############################################################# @@ -46,15 +54,14 @@ class Matter_Plugin_Sensor_Illuminance : Matter_Plugin_Sensor # # This must be overriden. # This is where you call `self.attribute_updated(, )` - def value_changed(val) + def value_changed() self.attribute_updated(0x0400, 0x0000) end ############################################################# # read an attribute # - def read_attribute(session, ctx) - import string + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -63,22 +70,22 @@ class Matter_Plugin_Sensor_Illuminance : Matter_Plugin_Sensor if cluster == 0x0400 # ========== Illuminance Measurement 2.2 p.95 ========== if attribute == 0x0000 # ---------- MeasuredValue / i16 ---------- if self.shadow_value != nil - return TLV.create_TLV(TLV.I2, int(self.shadow_value)) + return tlv_solo.set(TLV.U2, int(self.shadow_value)) else - return TLV.create_TLV(TLV.NULL, nil) + return tlv_solo.set(TLV.NULL, nil) end elif attribute == 0x0001 # ---------- MinMeasuredValue / i16 ---------- - return TLV.create_TLV(TLV.I2, 0) # 0 lux + return tlv_solo.set(TLV.U2, 1) # 1 lux elif attribute == 0x0002 # ---------- MaxMeasuredValue / i16 ---------- - return TLV.create_TLV(TLV.I2, 10000) # 10000 lux + return tlv_solo.set(TLV.U2, 0xFFFE) elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0) + return tlv_solo.set(TLV.U4, 0) elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 3) # 3 = New data model format and notation + return tlv_solo.set(TLV.U4, 3) # 3 = New data model format and notation end else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Occupancy.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Occupancy.be new file mode 100644 index 000000000000..7c2b0c925d77 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Occupancy.be @@ -0,0 +1,133 @@ +# +# Matter_Plugin_Sensor_Occupancy.be - implements the behavior for a Occupany Switch +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Sensor_Occupancy,weak + +class Matter_Plugin_Sensor_Occupancy : Matter_Plugin_Device + static var TYPE = "occupancy" # name of the plug-in in json + static var DISPLAY_NAME = "Occupancy" # display name of the plug-in + static var ARG = "switch" # additional argument name (or empty if none) + static var ARG_HINT = "Switch number" + static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type + static var UPDATE_TIME = 750 # update every 750ms + static var CLUSTERS = matter.consolidate_clusters(_class, { + 0x0406: [0,1,2,0xFFFC,0xFFFD], # Occupancy Sensing p.105 - no writable + }) + static var TYPES = { 0x0107: 2 } # Occupancy Sensor, rev 2 + + var tasmota_switch_index # Switch number in Tasmota (one based) + var shadow_occupancy + + ############################################################# + # Constructor + def init(device, endpoint, config) + super(self).init(device, endpoint, config) + self.shadow_occupancy = false + end + + ############################################################# + # parse_configuration + # + # Parse configuration map + def parse_configuration(config) + self.tasmota_switch_index = int(config.find(self.ARG #-'relay'-#, 1)) + if self.tasmota_switch_index <= 0 self.tasmota_switch_index = 1 end + end + + ############################################################# + # Update shadow + # + def update_shadow() + super(self).update_shadow() + var switch_str = "Switch" + str(self.tasmota_switch_index) + + var j = tasmota.cmd("Status 8", true) + if j != nil j = j.find("StatusSNS") end + if j != nil && j.contains(switch_str) + var state = (j.find(switch_str) == "ON") + + if (self.shadow_occupancy != state) + self.attribute_updated(0x0406, 0x0000) + end + self.shadow_occupancy = state + end + end + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0406 # ========== Occupancy Sensing ========== + if attribute == 0x0000 # ---------- Occupancy / U8 ---------- + if self.shadow_occupancy != nil + return tlv_solo.set(TLV.U1, self.shadow_occupancy) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x0001 # ---------- OccupancySensorType / enum8 ---------- + return tlv_solo.set(TLV.U1, 3) # physical contact + elif attribute == 0x0002 # ---------- OccupancySensorTypeBitmap / u8 ---------- + return tlv_solo.set(TLV.U1, 0) # unknown + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0) + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 3) # 4 = New data model format and notation + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # update_virtual + # + # Update internal state for virtual devices + def update_virtual(payload_json) + var val_onoff = payload_json.find("Occupancy") + if val_onoff != nil + val_onoff = bool(val_onoff) + if self.shadow_occupancy != val_onoff + self.attribute_updated(0x0406, 0x0000) + self.shadow_occupancy = val_onoff + end + end + super(self).update_virtual(payload_json) + end + + ############################################################# + # append_state_json + # + # Output the current state in JSON + # New values need to be appended with `,"key":value` (including prefix comma) + def append_state_json() + return f',"Occupancy":{int(self.shadow_occupancy)}' + end + +end +matter.Plugin_Sensor_Occupancy = Matter_Plugin_Sensor_Occupancy diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_OnOff.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_OnOff.be new file mode 100644 index 000000000000..79eb51c623e4 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_OnOff.be @@ -0,0 +1,101 @@ +# +# Matter_Plugin_Sensor_OnOff.be - implements the behavior for a Occupany Switch +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Sensor_OnOff,weak + +class Matter_Plugin_Sensor_OnOff : Matter_Plugin_Device + static var TYPE = "onoff" # name of the plug-in in json + static var DISPLAY_NAME = "OnOff Sensor" # display name of the plug-in + static var ARG = "switch" # additional argument name (or empty if none) + static var ARG_HINT = "Switch number" + static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type + static var UPDATE_TIME = 750 # update every 750ms + static var CLUSTERS = matter.consolidate_clusters(_class, { + 0x0006: [0,0xFFFC,0xFFFD], # On/Off 1.5 p.48 + }) + static var TYPES = { 0x0850: 2 } # OnOff Sensor, rev 2 + + var tasmota_switch_index # Switch number in Tasmota (one based) + var shadow_onoff + + ############################################################# + # parse_configuration + # + # Parse configuration map + def parse_configuration(config) + self.tasmota_switch_index = int(config.find(self.ARG #-'relay'-#, 1)) + if self.tasmota_switch_index <= 0 self.tasmota_switch_index = 1 end + end + + ############################################################# + # Update shadow + # + def update_shadow() + super(self).update_shadow() + var switch_str = "Switch" + str(self.tasmota_switch_index) + + var j = tasmota.cmd("Status 8", true) + if j != nil j = j.find("StatusSNS") end + if j != nil && j.contains(switch_str) + var state = (j.find(switch_str) == "ON") + + if (self.shadow_onoff != state) + self.attribute_updated(0x0006, 0x0000) + end + self.shadow_onoff = state + end + end + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0006 # ========== On/Off 1.5 p.48 ========== + self.update_shadow_lazy() + if attribute == 0x0000 # ---------- OnOff / bool ---------- + return tlv_solo.set(TLV.BOOL, self.shadow_onoff) + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0) # 0 = no Level Control for Lighting + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 4) # 0 = no Level Control for Lighting + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # append_state_json + # + # Output the current state in JSON + # New values need to be appended with `,"key":value` (including prefix comma) + def append_state_json() + return f',"OnOff":{int(self.shadow_onoff)}' + end + +end +matter.Plugin_Sensor_OnOff = Matter_Plugin_Sensor_OnOff diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Pressure.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Pressure.be similarity index 72% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Pressure.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Pressure.be index 0d87d296be9d..54a0b7627b3a 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Pressure.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Pressure.be @@ -17,20 +17,21 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Sensor end +# Matter plug-in for core behavior #@ solidify:Matter_Plugin_Sensor_Pressure,weak class Matter_Plugin_Sensor_Pressure : Matter_Plugin_Sensor static var TYPE = "pressure" # name of the plug-in in json - static var NAME = "Pressure" # display name of the plug-in - static var CLUSTERS = { - 0x0403: [0,1,2,0xFFFC,0xFFFD], # Temperature Measurement p.97 - no writable - } - static var TYPES = { 0x0305: 2 } # Temperature Sensor, rev 2 + static var DISPLAY_NAME = "Pressure" # display name of the plug-in + static var JSON_NAME = "Pressure" # Name of the sensor attribute in JSON payloads + static var UPDATE_COMMANDS = matter.UC_LIST(_class, "Pressure") + static var CLUSTERS = matter.consolidate_clusters(_class, { + 0x0403: [0,1,2,0xFFFC,0xFFFD], # Pressure Measurement + }) + static var TYPES = { 0x0305: 2 } # Pressure Sensor, rev 2 ############################################################# # Pre-process value @@ -46,15 +47,14 @@ class Matter_Plugin_Sensor_Pressure : Matter_Plugin_Sensor # # This must be overriden. # This is where you call `self.attribute_updated(, )` - def value_changed(val) + def value_changed() self.attribute_updated(0x0403, 0x0000) end ############################################################# # read an attribute # - def read_attribute(session, ctx) - import string + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -63,22 +63,22 @@ class Matter_Plugin_Sensor_Pressure : Matter_Plugin_Sensor if cluster == 0x0403 # ========== Pressure Measurement 2.4 p.98 ========== if attribute == 0x0000 # ---------- MeasuredValue / i16 ---------- if self.shadow_value != nil - return TLV.create_TLV(TLV.I2, int(self.shadow_value)) + return tlv_solo.set(TLV.I2, int(self.shadow_value)) else - return TLV.create_TLV(TLV.NULL, nil) + return tlv_solo.set(TLV.NULL, nil) end elif attribute == 0x0001 # ---------- MinMeasuredValue / i16 ---------- - return TLV.create_TLV(TLV.I2, 500) # 500 hPA + return tlv_solo.set(TLV.I2, 500) # 500 hPA elif attribute == 0x0002 # ---------- MaxMeasuredValue / i16 ---------- - return TLV.create_TLV(TLV.I2, 1500) # 1500 hPA + return tlv_solo.set(TLV.I2, 1500) # 1500 hPA elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0) # 0 = no Extended Range + return tlv_solo.set(TLV.U4, 0) # 0 = no Extended Range elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 3) # 3 = New data model format and notation + return tlv_solo.set(TLV.U4, 3) # 3 = New data model format and notation end else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Temp.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Temp.be similarity index 75% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Temp.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Temp.be index 4d2d9f23b14d..2b6ac22f7d48 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Temp.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_Sensor_Temp.be @@ -17,19 +17,20 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Sensor end +# Matter plug-in for core behavior #@ solidify:Matter_Plugin_Sensor_Temp,weak class Matter_Plugin_Sensor_Temp : Matter_Plugin_Sensor static var TYPE = "temperature" # name of the plug-in in json - static var NAME = "Temperature" # display name of the plug-in - static var CLUSTERS = { + static var DISPLAY_NAME = "Temperature" # display name of the plug-in + static var JSON_NAME = "Temperature" # Name of the sensor attribute in JSON payloads + static var UPDATE_COMMANDS = matter.UC_LIST(_class, "Temperature") + static var CLUSTERS = matter.consolidate_clusters(_class, { 0x0402: [0,1,2,0xFFFC,0xFFFD], # Temperature Measurement p.97 - no writable - } + }) static var TYPES = { 0x0302: 2 } # Temperature Sensor, rev 2 ############################################################# @@ -38,6 +39,9 @@ class Matter_Plugin_Sensor_Temp : Matter_Plugin_Sensor # This must be overriden. # This allows to convert the raw sensor value to the target one, typically int def pre_value(val) + if tasmota.get_option(8) == 1 # Fahrenheit + val = (val - 32) / 1.8 + end return val != nil ? int(val * 100) : nil end @@ -46,15 +50,14 @@ class Matter_Plugin_Sensor_Temp : Matter_Plugin_Sensor # # This must be overriden. # This is where you call `self.attribute_updated(, )` - def value_changed(val) + def value_changed() self.attribute_updated(0x0402, 0x0000) end ############################################################# # read an attribute # - def read_attribute(session, ctx) - import string + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -63,22 +66,22 @@ class Matter_Plugin_Sensor_Temp : Matter_Plugin_Sensor if cluster == 0x0402 # ========== Temperature Measurement 2.3 p.97 ========== if attribute == 0x0000 # ---------- MeasuredValue / i16 (*100) ---------- if self.shadow_value != nil - return TLV.create_TLV(TLV.I2, self.shadow_value) + return tlv_solo.set(TLV.I2, self.shadow_value) else - return TLV.create_TLV(TLV.NULL, nil) + return tlv_solo.set(TLV.NULL, nil) end elif attribute == 0x0001 # ---------- MinMeasuredValue / i16 (*100) ---------- - return TLV.create_TLV(TLV.I2, -5000) # -50 °C + return tlv_solo.set(TLV.I2, -5000) # -50 °C elif attribute == 0x0002 # ---------- MaxMeasuredValue / i16 (*100) ---------- - return TLV.create_TLV(TLV.I2, 15000) # 150 °C + return tlv_solo.set(TLV.I2, 15000) # 150 °C elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0) + return tlv_solo.set(TLV.U4, 0) elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 4) # 4 = New data model format and notation + return tlv_solo.set(TLV.U4, 4) # 4 = New data model format and notation end else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_ShutterTilt.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_ShutterTilt.be similarity index 87% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_ShutterTilt.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_ShutterTilt.be index 8c99aab519e3..f73548f69d68 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_ShutterTilt.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_3_ShutterTilt.be @@ -17,25 +17,24 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Shutter end +# Matter plug-in for core behavior #@ solidify:Matter_Plugin_ShutterTilt,weak class Matter_Plugin_ShutterTilt : Matter_Plugin_Shutter static var TYPE = "shutter+tilt" # name of the plug-in in json - static var NAME = "Shutter + Tilt" # display name of the plug-in + static var DISPLAY_NAME = "Shutter + Tilt" # display name of the plug-in # inherited static var ARG = "shutter" # additional argument name (or empty if none) # inherited static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type - static var CLUSTERS = { + static var CLUSTERS = matter.consolidate_clusters(_class, { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 # 0x0003: inherited # Identify 1.2 p.16 # 0x0004: inherited # Groups 1.3 p.21 # 0x0005: inherited # Scenes 1.4 p.30 - no writable 0x0102: [7,0xC,0xF,0xFFFC], # Window Covering 5.3 p.289 - } + }) # inherited static var TYPES = { 0x0202: 2 } # New data model format and notation # below is inherited @@ -44,6 +43,7 @@ class Matter_Plugin_ShutterTilt : Matter_Plugin_Shutter # var shadow_shutter_target # var shadow_shutter_tilt # var shadow_shutter_direction # 1=opening -1=closing 0=not moving TODO + var shadow_shutter_tilt var tilt_min, tilt_max ############################################################# @@ -58,7 +58,6 @@ class Matter_Plugin_ShutterTilt : Matter_Plugin_Shutter # parse the output from `ShutterPosition` # Ex: `{"Shutter1":{"Position":50,"Direction":0,"Target":50,"Tilt":30}}` def parse_sensors(payload) - import string var k = "Shutter" + str(self.tasmota_shutter_index + 1) if payload.contains(k) var v = payload[k] @@ -95,8 +94,7 @@ class Matter_Plugin_ShutterTilt : Matter_Plugin_Shutter ############################################################# # read an attribute # - def read_attribute(session, ctx) - import string + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -105,30 +103,30 @@ class Matter_Plugin_ShutterTilt : Matter_Plugin_Shutter if cluster == 0x0102 # ========== Window Covering 5.3 p.289 ========== self.update_shadow_lazy() if attribute == 0x0007 # ---------- ConfigStatus / u8 ---------- - return TLV.create_TLV(TLV.U1, 1 + 8 + 16) # Operational + Lift Position Aware + Tilt Position Aware + return tlv_solo.set(TLV.U1, 1 + 8 + 16) # Operational + Lift Position Aware + Tilt Position Aware elif attribute == 0x000F # ---------- CurrentPositionTiltPercent100ths / u8 ---------- self.update_tilt_min_max() if self.tilt_min != nil && self.tilt_max != nil var tilt_percentage = tasmota.scale_uint(self.shadow_shutter_tilt - self.tilt_min, 0, self.tilt_max - self.tilt_min, 0, 10000) - return TLV.create_TLV(TLV.U2, tilt_percentage) + return tlv_solo.set(TLV.U2, tilt_percentage) else - return TLV.create_TLV(TLV.NULL, nil) # return invalid + return tlv_solo.set(TLV.NULL, nil) # return invalid end elif attribute == 0x000C # ---------- TargetPositionTiltPercent100ths / u16 ---------- if self.tilt_min != nil && self.tilt_max != nil var tilt_percentage = tasmota.scale_uint(self.shadow_shutter_tilt - self.tilt_min, 0, self.tilt_max - self.tilt_min, 0, 10000) - return TLV.create_TLV(TLV.U2, tilt_percentage) + return tlv_solo.set(TLV.U2, tilt_percentage) else - return TLV.create_TLV(TLV.NULL, nil) # return invalid + return tlv_solo.set(TLV.NULL, nil) # return invalid end elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 3 + 4 + 16) # Lift + Tilt + PA_LF + PA_TL + return tlv_solo.set(TLV.U4, 3 + 4 + 16) # Lift + Tilt + PA_LF + PA_TL end end # else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end ############################################################# @@ -167,8 +165,5 @@ class Matter_Plugin_ShutterTilt : Matter_Plugin_Shutter end - ############################################################# - # parse sensor inherited - end matter.Plugin_ShutterTilt = Matter_Plugin_ShutterTilt diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Light1.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Light1.be new file mode 100644 index 000000000000..b20d27ff42bd --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Light1.be @@ -0,0 +1,189 @@ +# +# Matter_Plugin_Bridge_Light1.be - implements the behavior for a remote generic Lighting (Dimmer) via HTTP +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Bridge_Light1,weak + +class Matter_Plugin_Bridge_Light1 : Matter_Plugin_Bridge_Light0 + static var TYPE = "http_light1" # name of the plug-in in json + static var DISPLAY_NAME = "Light 1 Dimmer" # display name of the plug-in + # static var ARG = "relay" # additional argument name (or empty if none) + # static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type + static var CLUSTERS = matter.consolidate_clusters(_class, { + # 0x001D: inherited # Descriptor Cluster 9.5 p.453 + # 0x0003: inherited # Identify 1.2 p.16 + # 0x0004: inherited # Groups 1.3 p.21 + # 0x0005: inherited # Scenes 1.4 p.30 - no writable + # 0x0006: inherited # On/Off 1.5 p.48 + 0x0008: [0,2,3,0x0F,0x11,0xFFFC,0xFFFD], # Level Control 1.6 p.57 + }) + static var TYPES = { 0x0101: 2 } # Dimmable Light + + var shadow_bri + # var tasmota_relay_index # ingerited + # var shadow_onoff # inherited + + ############################################################# + # Stub for updating shadow values (local copies of what we published to the Matter gateway) + # + # This call is synnchronous and blocking. + def parse_update(data, index) + super(self).parse_update(data, index) + + if index == 11 # Status 11 + var dimmer = int(data.find("Dimmer")) # 0..100 + if dimmer != nil + var bri = tasmota.scale_uint(dimmer, 0, 100, 0, 254) + if bri != self.shadow_bri + self.attribute_updated(0x0008, 0x0000) + self.shadow_bri = bri + end + end + end + end + + ############################################################# + # Model + # + def set_bri(v) + var dimmer = tasmota.scale_uint(v, 0, 254, 0, 100) + var ret = self.call_remote_sync("Dimmer", str(dimmer)) + if ret != nil + self.parse_update(ret, 11) # update shadow from return value + end + end + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0008 # ========== Level Control 1.6 p.57 ========== + self.update_shadow_lazy() + if attribute == 0x0000 # ---------- CurrentLevel / u1 ---------- + if self.shadow_bri != nil + return tlv_solo.set(TLV.U1, self.shadow_bri) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x0002 # ---------- MinLevel / u1 ---------- + return tlv_solo.set(TLV.U1, 0) + elif attribute == 0x0003 # ---------- MaxLevel / u1 ---------- + return tlv_solo.set(TLV.U1, 254) + elif attribute == 0x000F # ---------- Options / map8 ---------- + return tlv_solo.set(TLV.U1, 0) # + elif attribute == 0x0011 # ---------- OnLevel / u1 ---------- + if self.shadow_bri != nil + return tlv_solo.set(TLV.U1, self.shadow_bri) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0X01) # OnOff + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 5) # "new data model format and notation" + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # Invoke a command + # + # returns a TLV object if successful, contains the response + # or an `int` to indicate a status + def invoke_request(session, val, ctx) + var TLV = matter.TLV + var cluster = ctx.cluster + var command = ctx.command + + # ==================================================================================================== + if cluster == 0x0008 # ========== Level Control 1.6 p.57 ========== + if command == 0x0000 # ---------- MoveToLevel ---------- + var bri_in = val.findsubval(0) # Hue 0..254 + self.set_bri(bri_in) + ctx.log = "bri:"+str(bri_in) + self.publish_command('Bri', tasmota.scale_uint(bri_in, 0, 254, 0, 255), + 'Dimmer', tasmota.scale_uint(bri_in, 0, 254, 0, 100)) + return true + elif command == 0x0001 # ---------- Move ---------- + # TODO, we don't really support it + return true + elif command == 0x0002 # ---------- Step ---------- + # TODO, we don't really support it + return true + elif command == 0x0003 # ---------- Stop ---------- + # TODO, we don't really support it + return true + elif command == 0x0004 # ---------- MoveToLevelWithOnOff ---------- + var bri_in = val.findsubval(0) # Hue 0..254 + self.set_bri(bri_in) + var onoff = bri_in > 0 + self.set_onoff(onoff) + ctx.log = "bri:"+str(bri_in) + self.publish_command('Bri', tasmota.scale_uint(bri_in, 0, 254, 0, 255), + 'Dimmer', tasmota.scale_uint(bri_in, 0, 254, 0, 100), + 'Power', onoff ? 1 : 0) + return true + elif command == 0x0005 # ---------- MoveWithOnOff ---------- + # TODO, we don't really support it + return true + elif command == 0x0006 # ---------- StepWithOnOff ---------- + # TODO, we don't really support it + return true + elif command == 0x0007 # ---------- StopWithOnOff ---------- + # TODO, we don't really support it + return true + end + + else + return super(self).invoke_request(session, val, ctx) + end + end + + ############################################################# + # web_values + # + # Show values of the remote device as HTML + def web_values() + import webserver + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(format("%s %s", self.web_value_onoff(self.shadow_onoff), self.web_value_dimmer())) + end + + # Show on/off value as html + def web_value_dimmer() + var bri_html = "" + if self.shadow_bri != nil + var bri = tasmota.scale_uint(self.shadow_bri, 0, 254, 0, 100) + bri_html = format("%i%%", bri) + end + return "🔅 " + bri_html; + end +end +matter.Plugin_Bridge_Light1 = Matter_Plugin_Bridge_Light1 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_OnOff.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_OnOff.be new file mode 100644 index 000000000000..a2c3f388ff9c --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_OnOff.be @@ -0,0 +1,43 @@ +# +# Matter_Plugin_Bridge_OnOff.be - implements the behavior for a Relay via HTTP (OnOff) +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Bridge_OnOff,weak + +class Matter_Plugin_Bridge_OnOff : Matter_Plugin_Bridge_Light0 + static var TYPE = "http_relay" # name of the plug-in in json + static var DISPLAY_NAME = "Relay" # display name of the plug-in + static var ARG_HINT = "Relay number" + static var TYPES = { 0x010A: 2 } # On/Off Plug-in Unit + + ############################################################# + # web_values + # + # Show values of the remote device as HTML + def web_values() + import webserver + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(format("Relay %i %s", self.tasmota_relay_index, self.web_value_onoff(self.shadow_onoff))) + end + +end +matter.Plugin_Bridge_OnOff = Matter_Plugin_Bridge_OnOff diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Contact.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Contact.be new file mode 100644 index 000000000000..d4f738e26864 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Contact.be @@ -0,0 +1,115 @@ +# +# Matter_Plugin_Bridge_Sensor_Contact.be - implements Contact Sensor via HTTP to Tasmota +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Bridge_Sensor_Contact,weak + +class Matter_Plugin_Bridge_Sensor_Contact : Matter_Plugin_Bridge_HTTP + static var TYPE = "http_contact" # name of the plug-in in json + static var DISPLAY_NAME = "Contact" # display name of the plug-in + static var ARG = "switch" # additional argument name (or empty if none) + static var ARG_HINT = "Switch number" + static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type + static var UPDATE_TIME = 5000 # update every 5s + static var UPDATE_CMD = "Status 8" # command to send for updates + + static var CLUSTERS = matter.consolidate_clusters(_class, { + 0x0045: [0,0xFFFC,0xFFFD], # Boolean State p.70 - no writable + }) + static var TYPES = { 0x0015: 1 } # Contact Sensor, rev 1 + + var tasmota_switch_index # Switch number in Tasmota (one based) + var shadow_contact + + ############################################################# + # Constructor + def init(device, endpoint, arguments) + super(self).init(device, endpoint, arguments) + self.tasmota_switch_index = int(arguments.find(self.ARG #-'switch'-#, 1)) + if self.tasmota_switch_index <= 0 self.tasmota_switch_index = 1 end + end + + ############################################################# + # Stub for updating shadow values (local copies of what we published to the Matter gateway) + # + # This call is synnchronous and blocking. + def parse_update(data, index) + if index == 8 # Status 8 + var state = false + + state = (data.find("Switch" + str(self.tasmota_switch_index)) == "ON") + + if self.shadow_contact != nil && self.shadow_contact != bool(state) + self.attribute_updated(0x0045, 0x0000) + end + self.shadow_contact = state + end + end + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0045 # ========== Boolean State ========== + if attribute == 0x0000 # ---------- StateValue / bool ---------- + if self.shadow_contact != nil + return tlv_solo.set(TLV.BOOL, self.shadow_contact) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0) + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 1) # 1 = Initial release + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # web_values + # + # Show values of the remote device as HTML + def web_values() + import webserver + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(format("Contact%i %s", self.tasmota_switch_index, self.web_value_onoff(self.shadow_contact))) + end + + # Show prefix before web value + def web_values_prefix() + import webserver + var name = self.get_name() + if !name + name = "Switch" + str(self.tasmota_switch_index) + end + webserver.content_send(format(self.PREFIX, name ? webserver.html_escape(name) : "")) + end +end +matter.Plugin_Bridge_Sensor_Contact = Matter_Plugin_Bridge_Sensor_Contact diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Humidity.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Humidity.be new file mode 100644 index 000000000000..7e8b62342631 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Humidity.be @@ -0,0 +1,96 @@ +# +# Matter_Plugin_Bridge_Sensor_Humidity.be - implements base class for a Humidity Sensor via HTTP to Tasmota +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Bridge_Sensor_Humidity,weak + +class Matter_Plugin_Bridge_Sensor_Humidity : Matter_Plugin_Bridge_Sensor + static var TYPE = "http_humidity" # name of the plug-in in json + static var DISPLAY_NAME = "Humidity" # display name of the plug-in + + static var CLUSTERS = matter.consolidate_clusters(_class, { + 0x0405: [0,1,2,0xFFFC,0xFFFD], # Humidity Measurement p.102 - no writable + }) + static var TYPES = { 0x0307: 2 } # Humidity Sensor, rev 2 + + ############################################################# + # Called when the value changed compared to shadow value + # + # This must be overriden. + # This is where you call `self.attribute_updated(, )` + def value_changed() + self.attribute_updated(0x0405, 0x0000) + end + + ############################################################# + # Pre-process value + # + # This must be overriden. + # This allows to convert the raw sensor value to the target one, typically int + def pre_value(val) + return val != nil ? int(val * 100) : nil # 1/100th of percentage + end + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0405 # ========== Humidity Measurement 2.4 p.98 ========== + if attribute == 0x0000 # ---------- Humidity / u16 ---------- + if self.shadow_value != nil + return tlv_solo.set(TLV.U2, int(self.shadow_value)) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x0001 # ---------- MinMeasuredValue / u16 ---------- + return tlv_solo.set(TLV.U2, 500) # 0% + elif attribute == 0x0002 # ---------- MaxMeasuredValue / u16 ---------- + return tlv_solo.set(TLV.U2, 10000) # 100% + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0) # 0 = no Extended Range + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 3) # 3 = New data model format and notation + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # web_values + # + # Show values of the remote device as HTML + def web_values() + import webserver + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(format("💧 %2.0f%%", + self.shadow_value != nil ? real(self.shadow_value) / 100 : nil)) + end + +end +matter.Plugin_Bridge_Sensor_Humidity = Matter_Plugin_Bridge_Sensor_Humidity diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Illuminance.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Illuminance.be new file mode 100644 index 000000000000..48e0bf8de538 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Illuminance.be @@ -0,0 +1,103 @@ +# +# Matter_Plugin_Bridge_Sensor_Illuminance.be - implements base class for a Light/Illuminance Sensor via HTTP to Tasmota +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Bridge_Sensor_Illuminance,weak + +class Matter_Plugin_Bridge_Sensor_Illuminance : Matter_Plugin_Bridge_Sensor + static var TYPE = "http_illuminance" # name of the plug-in in json + static var DISPLAY_NAME = "Illuminance" # display name of the plug-in + + static var CLUSTERS = matter.consolidate_clusters(_class, { + 0x0400: [0,1,2,0xFFFC,0xFFFD], # Illuminance Measurement p.95 - no writable + }) + static var TYPES = { 0x0106: 2 } # Illuminance Sensor, rev 2 + + ############################################################# + # Called when the value changed compared to shadow value + # + # This must be overriden. + # This is where you call `self.attribute_updated(, )` + def value_changed() + self.attribute_updated(0x0400, 0x0000) + end + + ############################################################# + # Pre-process value + # + # This must be overriden. + # This allows to convert the raw sensor value to the target one, typically int + def pre_value(val) + if val == nil return nil end + import math + + if val < 0 + return 0 + else + return math.log10(val + 1) * 10000 + end + end + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0400 # ========== Illuminance Measurement 2.2 p.95 ========== + if attribute == 0x0000 # ---------- MeasuredValue / i16 ---------- + if self.shadow_value != nil + return tlv_solo.set(TLV.U2, int(self.shadow_value)) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x0001 # ---------- MinMeasuredValue / i16 ---------- + return tlv_solo.set(TLV.U2, 1) # 1 lux + elif attribute == 0x0002 # ---------- MaxMeasuredValue / i16 ---------- + return tlv_solo.set(TLV.U2, 0xFFFE) + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0) + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 3) # 3 = New data model format and notation + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # web_values + # + # Show values of the remote device as HTML + def web_values() + import webserver + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(format("🔅 %ilux", + int(self.shadow_value))) + end + +end +matter.Plugin_Bridge_Sensor_Illuminance = Matter_Plugin_Bridge_Sensor_Illuminance diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Occupancy.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Occupancy.be new file mode 100644 index 000000000000..8279a608890d --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Occupancy.be @@ -0,0 +1,119 @@ +# +# Matter_Plugin_Bridge_Sensor_Occupancy.be - implements base class for a Occupancy Sensor via HTTP to Tasmota +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Bridge_Sensor_Occupancy,weak + +class Matter_Plugin_Bridge_Sensor_Occupancy : Matter_Plugin_Bridge_HTTP + static var TYPE = "http_occupancy" # name of the plug-in in json + static var DISPLAY_NAME = "Occupancy" # display name of the plug-in + static var ARG = "switch" # additional argument name (or empty if none) + static var ARG_HINT = "Switch number" + static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type + static var UPDATE_TIME = 5000 # update every 5s + static var UPDATE_CMD = "Status 8" # command to send for updates + + static var CLUSTERS = matter.consolidate_clusters(_class, { + 0x0406: [0,1,2,0xFFFC,0xFFFD], # Occupancy Sensing p.105 - no writable + }) + static var TYPES = { 0x0107: 2 } # Occupancy Sensor, rev 2 + + var tasmota_switch_index # Switch number in Tasmota (one based) + var shadow_occupancy + + ############################################################# + # Constructor + def init(device, endpoint, arguments) + super(self).init(device, endpoint, arguments) + self.tasmota_switch_index = int(arguments.find(self.ARG #-'relay'-#, 1)) + if self.tasmota_switch_index <= 0 self.tasmota_switch_index = 1 end + end + + ############################################################# + # Stub for updating shadow values (local copies of what we published to the Matter gateway) + # + # This call is synnchronous and blocking. + def parse_update(data, index) + if index == 8 # Status 8 + var state = false + + state = (data.find("Switch" + str(self.tasmota_switch_index)) == "ON") + + if self.shadow_occupancy != nil && self.shadow_occupancy != bool(state) + self.attribute_updated(0x0406, 0x0000) + end + self.shadow_occupancy = state + end + end + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0406 # ========== Occupancy Sensing ========== + if attribute == 0x0000 # ---------- Occupancy / U8 ---------- + if self.shadow_occupancy != nil + return tlv_solo.set(TLV.U1, self.shadow_occupancy) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x0001 # ---------- OccupancySensorType / enum8 ---------- + return tlv_solo.set(TLV.U1, 3) # physical contact + elif attribute == 0x0002 # ---------- OccupancySensorTypeBitmap / u8 ---------- + return tlv_solo.set(TLV.U1, 0) # unknown + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0) + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 3) # 4 = New data model format and notation + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # web_values + # + # Show values of the remote device as HTML + def web_values() + import webserver + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(format("Occupancy%i %s", self.tasmota_switch_index, self.web_value_onoff(self.shadow_occupancy))) + end + + # Show prefix before web value + def web_values_prefix() + import webserver + var name = self.get_name() + if !name + name = "Switch" + str(self.tasmota_switch_index) + end + webserver.content_send(format(self.PREFIX, name ? webserver.html_escape(name) : "")) + end +end +matter.Plugin_Bridge_Sensor_Occupancy = Matter_Plugin_Bridge_Sensor_Occupancy diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Pressure.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Pressure.be new file mode 100644 index 000000000000..86dec0081ce2 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Pressure.be @@ -0,0 +1,96 @@ +# +# Matter_Plugin_Bridge_Sensor_Temp.be - implements base class for a Pressure Sensor via HTTP to Tasmota +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Bridge_Sensor_Pressure,weak + +class Matter_Plugin_Bridge_Sensor_Pressure : Matter_Plugin_Bridge_Sensor + static var TYPE = "http_pressure" # name of the plug-in in json + static var DISPLAY_NAME = "Pressure" # display name of the plug-in + + static var CLUSTERS = matter.consolidate_clusters(_class, { + 0x0403: [0,1,2,0xFFFC,0xFFFD], # Pressure Measurement + }) + static var TYPES = { 0x0305: 2 } # Temperature Sensor, rev 2 + + ############################################################# + # Called when the value changed compared to shadow value + # + # This must be overriden. + # This is where you call `self.attribute_updated(, )` + def value_changed() + self.attribute_updated(0x0403, 0x0000) + end + + ############################################################# + # Pre-process value + # + # This must be overriden. + # This allows to convert the raw sensor value to the target one, typically int + def pre_value(val) + return val != nil ? int(val) : nil + end + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0403 # ========== Pressure Measurement 2.4 p.98 ========== + if attribute == 0x0000 # ---------- MeasuredValue / i16 ---------- + if self.shadow_value != nil + return tlv_solo.set(TLV.I2, int(self.shadow_value)) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x0001 # ---------- MinMeasuredValue / i16 ---------- + return tlv_solo.set(TLV.I2, 500) # 500 hPA + elif attribute == 0x0002 # ---------- MaxMeasuredValue / i16 ---------- + return tlv_solo.set(TLV.I2, 1500) # 1500 hPA + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0) # 0 = no Extended Range + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 3) # 3 = New data model format and notation + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # web_values + # + # Show values of the remote device as HTML + def web_values() + import webserver + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(format("⛅ %i hPa", + int(self.shadow_value))) + end + +end +matter.Plugin_Bridge_Sensor_Pressure = Matter_Plugin_Bridge_Sensor_Pressure diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Temp.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Temp.be new file mode 100644 index 000000000000..771c6eb7deb0 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Bridge_Sensor_Temp.be @@ -0,0 +1,99 @@ +# +# Matter_Plugin_Bridge_Sensor_Temp.be - implements base class for a Temperature Sensor via HTTP to Tasmota +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Bridge_Sensor_Temp,weak + +class Matter_Plugin_Bridge_Sensor_Temp : Matter_Plugin_Bridge_Sensor + static var TYPE = "http_temperature" # name of the plug-in in json + static var DISPLAY_NAME = "Temperature" # display name of the plug-in + + static var CLUSTERS = matter.consolidate_clusters(_class, { + 0x0402: [0,1,2,0xFFFC,0xFFFD], # Temperature Measurement p.97 - no writable + }) + static var TYPES = { 0x0302: 2 } # Temperature Sensor, rev 2 + + ############################################################# + # Called when the value changed compared to shadow value + # + # This must be overriden. + # This is where you call `self.attribute_updated(, )` + def value_changed() + self.attribute_updated(0x0402, 0x0000) + end + + ############################################################# + # Pre-process value + # + # This must be overriden. + # This allows to convert the raw sensor value to the target one, typically int + def pre_value(val) + if self.temp_unit == self.TEMP_F # Fahrenheit + val = (val - 32) / 1.8 + end + return val != nil ? int(val * 100) : nil + end + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0402 # ========== Temperature Measurement 2.3 p.97 ========== + if attribute == 0x0000 # ---------- MeasuredValue / i16 (*100) ---------- + if self.shadow_value != nil + return tlv_solo.set(TLV.I2, self.shadow_value) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x0001 # ---------- MinMeasuredValue / i16 (*100) ---------- + return tlv_solo.set(TLV.I2, -5000) # -50 °C + elif attribute == 0x0002 # ---------- MaxMeasuredValue / i16 (*100) ---------- + return tlv_solo.set(TLV.I2, 15000) # 150 °C + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0) + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 4) # 4 = New data model format and notation + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # web_values + # + # Show values of the remote device as HTML + def web_values() + import webserver + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(format("☀️ %.1f °C", + self.shadow_value != nil ? real(self.shadow_value) / 100 : nil)) + end + +end +matter.Plugin_Bridge_Sensor_Temp = Matter_Plugin_Bridge_Sensor_Temp diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light2.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Light2.be similarity index 61% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light2.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Light2.be index 9eee3be00951..c4d4f9317955 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light2.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Light2.be @@ -17,17 +17,16 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Light1 end +# Matter plug-in for core behavior #@ solidify:Matter_Plugin_Light2,weak class Matter_Plugin_Light2 : Matter_Plugin_Light1 static var TYPE = "light2" # name of the plug-in in json - static var NAME = "Light 2 CT" # display name of the plug-in - static var CLUSTERS = { + static var DISPLAY_NAME = "Light 2 CT" # display name of the plug-in + static var CLUSTERS = matter.consolidate_clusters(_class, { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 # 0x0003: inherited # Identify 1.2 p.16 # 0x0004: inherited # Groups 1.3 p.21 @@ -35,18 +34,27 @@ class Matter_Plugin_Light2 : Matter_Plugin_Light1 # 0x0006: inherited # On/Off 1.5 p.48 # 0x0008: inherited # Level Control 1.6 p.57 0x0300: [7,8,0xF,0x400B,0x400C,0xFFFC,0xFFFD], # Color Control 3.2 p.111 - } + }) + static var UPDATE_COMMANDS = matter.UC_LIST(_class, "CT") static var TYPES = { 0x010C: 2 } # Color Temperature Light - var shadow_ct - var ct_min, ct_max + # Inherited + # var device # reference to the `device` global object + # var endpoint # current endpoint + # var clusters # map from cluster to list of attributes, typically constructed from CLUSTERS hierachy + # var tick # tick value when it was last updated + # var node_label # name of the endpoint, used only in bridge mode, "" if none + # var shadow_onoff # (bool) status of the light power on/off + # var shadow_bri # (int 0..254) brightness before Gamma correction - as per Matter 255 is not allowed + var shadow_ct # (int 153..500, default 325) Color Temperatur in mireds + var ct_min, ct_max # min and max value allowed for CT, Alexa emulation requires to have a narrower range 200..380 ############################################################# # Constructor def init(device, endpoint, arguments) super(self).init(device, endpoint, arguments) self.shadow_ct = 325 - self.update_ct_minmax() + self.update_ct_minmax() # read SetOption to adjust ct min/max end ############################################################# @@ -57,51 +65,75 @@ class Matter_Plugin_Light2 : Matter_Plugin_Light1 self.update_ct_minmax() super(self).update_shadow() var light_status = light.get() - var ct = light_status.find('ct', nil) - if ct == nil ct = self.shadow_ct end - if ct != self.shadow_ct self.attribute_updated(0x0300, 0x0007) self.shadow_ct = ct end + if light_status != nil + var ct = light_status.find('ct', nil) + if ct == nil ct = self.shadow_ct end + if ct != self.shadow_ct + self.attribute_updated(0x0300, 0x0007) + self.shadow_ct = ct + end + end end ############################################################# # Update ct_min/max # + # Standard range is 153..500 but Alexa emulation reduces range to 200..380 + # Depending on `SetOption82` def update_ct_minmax() var ct_alexa_mode = tasmota.get_option(82) # if set, range is 200..380 instead of 153...500 self.ct_min = ct_alexa_mode ? 200 : 153 self.ct_max = ct_alexa_mode ? 380 : 500 end + ############################################################# + # set_ct + # + def set_ct(ct) + if ct < self.ct_min ct = self.ct_min end + if ct > self.ct_max ct = self.ct_max end + if !self.VIRTUAL + import light + light.set({'ct': ct}) + self.update_shadow() + else + if ct != self.shadow_ct + self.attribute_updated(0x0300, 0x0007) + self.shadow_ct = ct + end + end + end + ############################################################# # read an attribute # - def read_attribute(session, ctx) - import string + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute - + # ==================================================================================================== if cluster == 0x0300 # ========== Color Control 3.2 p.111 ========== self.update_shadow_lazy() if attribute == 0x0007 # ---------- ColorTemperatureMireds / u2 ---------- - return TLV.create_TLV(TLV.U1, self.shadow_ct) + return tlv_solo.set(TLV.U1, self.shadow_ct) elif attribute == 0x0008 # ---------- ColorMode / u1 ---------- - return TLV.create_TLV(TLV.U1, 2)# 2 = ColorTemperatureMireds + return tlv_solo.set(TLV.U1, 2)# 2 = ColorTemperatureMireds elif attribute == 0x000F # ---------- Options / u1 ---------- - return TLV.create_TLV(TLV.U1, 0) + return tlv_solo.set(TLV.U1, 0) elif attribute == 0x400B # ---------- ColorTempPhysicalMinMireds / u2 ---------- - return TLV.create_TLV(TLV.U1, self.ct_min) + return tlv_solo.set(TLV.U1, self.ct_min) elif attribute == 0x400C # ---------- ColorTempPhysicalMaxMireds / u2 ---------- - return TLV.create_TLV(TLV.U1, self.ct_max) + return tlv_solo.set(TLV.U1, self.ct_max) elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0x10) # CT + return tlv_solo.set(TLV.U4, 0x10) # CT elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 5) # "new data model format and notation, FeatureMap support" + return tlv_solo.set(TLV.U4, 5) # "new data model format and notation, FeatureMap support" end else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end end @@ -121,11 +153,9 @@ class Matter_Plugin_Light2 : Matter_Plugin_Light1 self.update_shadow_lazy() if command == 0x000A # ---------- MoveToColorTemperature ---------- var ct_in = val.findsubval(0) # CT - if ct_in < self.ct_min ct_in = self.ct_min end - if ct_in > self.ct_max ct_in = self.ct_max end - light.set({'ct': ct_in}) - self.update_shadow() + self.set_ct(ct_in) ctx.log = "ct:"+str(ct_in) + self.publish_command('CT', ct_in) return true elif command == 0x0047 # ---------- StopMoveStep ---------- # TODO, we don't really support it @@ -144,5 +174,17 @@ class Matter_Plugin_Light2 : Matter_Plugin_Light1 end + ############################################################# + # update_virtual + # + # Update internal state for virtual devices + def update_virtual(payload_json) + var val_ct = int(payload_json.find("CT")) # int or nil + if (val_ct != nil) + self.set_ct(val_ct) + end + super(self).update_virtual(payload_json) + end + end matter.Plugin_Light2 = Matter_Plugin_Light2 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light3.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Light3.be similarity index 54% rename from lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light3.be rename to lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Light3.be index acdce08379cd..8f7dd46fd65e 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light3.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_4_Light3.be @@ -17,17 +17,16 @@ # along with this program. If not, see . # -# Matter plug-in for core behavior +import matter -# dummy declaration for solidification -class Matter_Plugin_Light1 end +# Matter plug-in for core behavior #@ solidify:Matter_Plugin_Light3,weak class Matter_Plugin_Light3 : Matter_Plugin_Light1 static var TYPE = "light3" # name of the plug-in in json - static var NAME = "Light 3 RGB" # display name of the plug-in - static var CLUSTERS = { + static var DISPLAY_NAME = "Light 3 RGB" # display name of the plug-in + static var CLUSTERS = matter.consolidate_clusters(_class, { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 # 0x0003: inherited # Identify 1.2 p.16 # 0x0004: inherited # Groups 1.3 p.21 @@ -35,10 +34,21 @@ class Matter_Plugin_Light3 : Matter_Plugin_Light1 # 0x0006: inherited # On/Off 1.5 p.48 # 0x0008: inherited # Level Control 1.6 p.57 0x0300: [0,1,7,8,0xF,0x4001,0x400A,0xFFFC,0xFFFD],# Color Control 3.2 p.111 - } + }) + static var UPDATE_COMMANDS = matter.UC_LIST(_class, "Hue", "Sat") static var TYPES = { 0x010D: 2 } # Extended Color Light - var shadow_hue, shadow_sat + # Inherited + # var device # reference to the `device` global object + # var endpoint # current endpoint + # var clusters # map from cluster to list of attributes, typically constructed from CLUSTERS hierachy + # var tick # tick value when it was last updated + # var node_label # name of the endpoint, used only in bridge mode, "" if none + # var virtual # (bool) is the device pure virtual (i.e. not related to a device implementation by Tasmota) + # var shadow_onoff # (bool) status of the light power on/off + # var shadow_bri # (int 0..254) brightness before Gamma correction - as per Matter 255 is not allowed + var shadow_hue # (int 0..254) hue of color, may need to be extended to 0..360 for value in degrees + var shadow_sat # (int 0..254) saturation of color ############################################################# # Constructor @@ -52,22 +62,63 @@ class Matter_Plugin_Light3 : Matter_Plugin_Light1 # Update shadow # def update_shadow() - import light super(self).update_shadow() - var light_status = light.get() - var hue = light_status.find('hue', nil) - var sat = light_status.find('sat', nil) - if hue != nil hue = tasmota.scale_uint(hue, 0, 360, 0, 254) else hue = self.shadow_hue end - if sat != nil sat = tasmota.scale_uint(sat, 0, 255, 0, 254) else sat = self.shadow_sat end - if hue != self.shadow_hue self.attribute_updated(0x0300, 0x0000) self.shadow_hue = hue end - if sat != self.shadow_sat self.attribute_updated(0x0300, 0x0001) self.shadow_sat = sat end + if !self.VIRTUAL + import light + var light_status = light.get() + if light_status != nil + var hue = light_status.find('hue', nil) + var sat = light_status.find('sat', nil) + if hue != nil hue = tasmota.scale_uint(hue, 0, 360, 0, 254) else hue = self.shadow_hue end + if sat != nil sat = tasmota.scale_uint(sat, 0, 255, 0, 254) else sat = self.shadow_sat end + if hue != self.shadow_hue self.attribute_updated(0x0300, 0x0000) self.shadow_hue = hue end + if sat != self.shadow_sat self.attribute_updated(0x0300, 0x0001) self.shadow_sat = sat end + end + end + end + + ############################################################# + # set_hue_sat + # + # `hue` 0..254 or `nil` + # `sat` 0..255 or `nil` + def set_hue_sat(hue_254, sat_254) + # sanity checks on values + if hue_254 != nil + if hue_254 < 0 hue_254 = 0 end + if hue_254 > 254 hue_254 = 254 end + end + if sat_254 != nil + if sat_254 < 0 sat_254 = 0 end + if sat_254 > 254 sat_254 = 254 end + end + + if !self.VIRTUAL + var hue_360 = (hue_254 != nil) ? tasmota.scale_uint(hue_254, 0, 254, 0, 360) : nil + var sat_255 = (sat_254 != nil) ? tasmota.scale_uint(sat_254, 0, 254, 0, 255) : nil + + if (hue_360 != nil) && (sat_255 != nil) + light.set({'hue': hue_360, 'sat': sat_255}) + elif (hue_360 != nil) + light.set({'hue': hue_360}) + else + light.set({'sat': sat_255}) + end + self.update_shadow() + else + if hue_254 != nil + if hue_254 != self.shadow_hue self.attribute_updated(0x0300, 0x0000) self.shadow_hue = hue_254 end + end + if sat_254 != nil + if sat_254 != self.shadow_sat self.attribute_updated(0x0300, 0x0001) self.shadow_sat = sat_254 end + end + end end ############################################################# # read an attribute # - def read_attribute(session, ctx) - import string + def read_attribute(session, ctx, tlv_solo) var TLV = matter.TLV var cluster = ctx.cluster var attribute = ctx.attribute @@ -76,32 +127,32 @@ class Matter_Plugin_Light3 : Matter_Plugin_Light1 if cluster == 0x0300 # ========== Color Control 3.2 p.111 ========== self.update_shadow_lazy() if attribute == 0x0000 # ---------- CurrentHue / u1 ---------- - return TLV.create_TLV(TLV.U1, self.shadow_hue) + return tlv_solo.set(TLV.U1, self.shadow_hue) elif attribute == 0x0001 # ---------- CurrentSaturation / u2 ---------- - return TLV.create_TLV(TLV.U1, self.shadow_sat) + return tlv_solo.set(TLV.U1, self.shadow_sat) elif attribute == 0x0007 # ---------- ColorTemperatureMireds / u2 ---------- - return TLV.create_TLV(TLV.U1, 0) + return tlv_solo.set(TLV.U1, 0) elif attribute == 0x0008 # ---------- ColorMode / u1 ---------- - return TLV.create_TLV(TLV.U1, 0)# 0 = CurrentHue and CurrentSaturation + return tlv_solo.set(TLV.U1, 0)# 0 = CurrentHue and CurrentSaturation elif attribute == 0x000F # ---------- Options / u1 ---------- - return TLV.create_TLV(TLV.U1, 0) + return tlv_solo.set(TLV.U1, 0) elif attribute == 0x4001 # ---------- EnhancedColorMode / u1 ---------- - return TLV.create_TLV(TLV.U1, 0) + return tlv_solo.set(TLV.U1, 0) elif attribute == 0x400A # ---------- ColorCapabilities / map2 ---------- - return TLV.create_TLV(TLV.U1, 0) + return tlv_solo.set(TLV.U1, 0x01) # HS # Defined Primaries Information Attribute Set elif attribute == 0x0010 # ---------- NumberOfPrimaries / u1 ---------- - return TLV.create_TLV(TLV.U1, 0) + return tlv_solo.set(TLV.U1, 0) elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0x01) # HS + return tlv_solo.set(TLV.U4, 0x01) # HS elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 5) # "new data model format and notation, FeatureMap support" + return tlv_solo.set(TLV.U4, 5) # "new data model format and notation, FeatureMap support" end else - return super(self).read_attribute(session, ctx) + return super(self).read_attribute(session, ctx, tlv_solo) end end @@ -121,10 +172,9 @@ class Matter_Plugin_Light3 : Matter_Plugin_Light1 self.update_shadow_lazy() if command == 0x0000 # ---------- MoveToHue ---------- var hue_in = val.findsubval(0) # Hue 0..254 - var hue = tasmota.scale_uint(hue_in, 0, 254, 0, 360) - light.set({'hue': hue}) - self.update_shadow() + self.set_hue_sat(hue_in, nil) ctx.log = "hue:"+str(hue_in) + self.publish_command('Hue', hue_in) return true elif command == 0x0001 # ---------- MoveHue ---------- # TODO, we don't really support it @@ -134,10 +184,9 @@ class Matter_Plugin_Light3 : Matter_Plugin_Light1 return true elif command == 0x0003 # ---------- MoveToSaturation ---------- var sat_in = val.findsubval(0) # Sat 0..254 - var sat = tasmota.scale_uint(sat_in, 0, 254, 0, 255) - light.set({'sat': sat}) - self.update_shadow() + self.set_hue_sat(nil, sat_in) ctx.log = "sat:"+str(sat_in) + self.publish_command('Sat', sat_in) return true elif command == 0x0004 # ---------- MoveSaturation ---------- # TODO, we don't really support it @@ -147,12 +196,10 @@ class Matter_Plugin_Light3 : Matter_Plugin_Light1 return true elif command == 0x0006 # ---------- MoveToHueAndSaturation ---------- var hue_in = val.findsubval(0) # Hue 0..254 - var hue = tasmota.scale_uint(hue_in, 0, 254, 0, 360) var sat_in = val.findsubval(1) # Sat 0..254 - var sat = tasmota.scale_uint(sat_in, 0, 254, 0, 255) - light.set({'hue': hue, 'sat': sat}) - self.update_shadow() + self.set_hue_sat(hue_in, sat_in) ctx.log = "hue:"+str(hue_in)+" sat:"+str(sat_in) + self.publish_command('Hue', hue_in, 'Sat', sat_in) return true elif command == 0x0047 # ---------- StopMoveStep ---------- # TODO, we don't really support it @@ -165,5 +212,18 @@ class Matter_Plugin_Light3 : Matter_Plugin_Light1 end + ############################################################# + # update_virtual + # + # Update internal state for virtual devices + def update_virtual(payload_json) + var val_hue = int(payload_json.find("Hue")) # int or nil + var val_sat = int(payload_json.find("Sat")) # int or nil + if (val_hue != nil) || (val_sat != nil) + self.set_hue_sat(val_hue, val_sat) + end + super(self).update_virtual(payload_json) + end + end matter.Plugin_Light3 = Matter_Plugin_Light3 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_5_Bridge_Light2.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_5_Bridge_Light2.be new file mode 100644 index 000000000000..56d1d9de6d79 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_5_Bridge_Light2.be @@ -0,0 +1,189 @@ +# +# Matter_Plugin_Bridge_Light2.be - implements the behavior for a remote generic Lighting (CT) via HTTP +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Bridge_Light2,weak + +class Matter_Plugin_Bridge_Light2 : Matter_Plugin_Bridge_Light1 + static var TYPE = "http_light2" # name of the plug-in in json + static var DISPLAY_NAME = "Light 2 CT" # display name of the plug-in + # static var ARG = "relay" # additional argument name (or empty if none) + # static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type + static var CLUSTERS = matter.consolidate_clusters(_class, { + # 0x001D: inherited # Descriptor Cluster 9.5 p.453 + # 0x0003: inherited # Identify 1.2 p.16 + # 0x0004: inherited # Groups 1.3 p.21 + # 0x0005: inherited # Scenes 1.4 p.30 - no writable + # 0x0006: inherited # On/Off 1.5 p.48 + # 0x0008: inherited # Level Control 1.6 p.57 + 0x0300: [7,8,0xF,0x400A,0x400B,0x400C,0xFFFC,0xFFFD], # Color Control 3.2 p.111 + }) + static var TYPES = { 0x010C: 2 } # Dimmable Light + + var shadow_ct + var ct_min, ct_max + + ############################################################# + # Constructor + def init(device, endpoint, arguments) + super(self).init(device, endpoint, arguments) + self.update_ct_minmax() + end + + ############################################################# + # Stub for updating shadow values (local copies of what we published to the Matter gateway) + # + # TO BE OVERRIDDEN + # This call is synnchronous and blocking. + def parse_update(data, index) + super(self).parse_update(data, index) + + if index == 11 # Status 11 + var ct = int(data.find("CT")) # 153..500 + if ct != nil + if ct != self.shadow_ct + if ct < self.ct_min ct = self.ct_min end + if ct > self.ct_max ct = self.ct_max end + self.attribute_updated(0x0300, 0x0007) + self.shadow_ct = ct + end + end + end + end + + ############################################################# + # Update ct_min/max + # + def update_ct_minmax() + var ct_alexa_mode = tasmota.get_option(82) # if set, range is 200..380 instead of 153...500 + self.ct_min = ct_alexa_mode ? 200 : 153 + self.ct_max = ct_alexa_mode ? 380 : 500 + end + + ############################################################# + # Model + # + def set_ct(v) + var ret = self.call_remote_sync("CT", str(v)) + if ret != nil + self.parse_update(ret, 11) # update shadow from return value + end + end + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0300 # ========== Color Control 3.2 p.111 ========== + self.update_shadow_lazy() + if attribute == 0x0007 # ---------- ColorTemperatureMireds / u2 ---------- + if self.shadow_ct != nil + return tlv_solo.set(TLV.U1, self.shadow_ct) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x0008 # ---------- ColorMode / u1 ---------- + return tlv_solo.set(TLV.U1, 2)# 2 = ColorTemperatureMireds + elif attribute == 0x000F # ---------- Options / u1 ---------- + return tlv_solo.set(TLV.U1, 0) + elif attribute == 0x400B # ---------- ColorTempPhysicalMinMireds / u2 ---------- + return tlv_solo.set(TLV.U1, self.ct_min) + elif attribute == 0x400C # ---------- ColorTempPhysicalMaxMireds / u2 ---------- + return tlv_solo.set(TLV.U1, self.ct_max) + + elif attribute == 0x400A # ---------- ColorCapabilities / map32 ---------- + return tlv_solo.set(TLV.U4, 0x10) # CT + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0x10) # CT + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 5) # "new data model format and notation, FeatureMap support" + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # Invoke a command + # + # returns a TLV object if successful, contains the response + # or an `int` to indicate a status + def invoke_request(session, val, ctx) + var TLV = matter.TLV + var cluster = ctx.cluster + var command = ctx.command + + # ==================================================================================================== + if cluster == 0x0300 # ========== Color Control 3.2 p.111 ========== + if command == 0x000A # ---------- MoveToColorTemperature ---------- + var ct_in = val.findsubval(0) # CT + if ct_in < self.ct_min ct_in = self.ct_min end + if ct_in > self.ct_max ct_in = self.ct_max end + self.set_ct(ct_in) + ctx.log = "ct:"+str(ct_in) + self.publish_command('CT', ct_in) + return true + elif command == 0x0047 # ---------- StopMoveStep ---------- + # TODO, we don't really support it + return true + elif command == 0x004B # ---------- MoveColorTemperature ---------- + # TODO, we don't really support it + return true + elif command == 0x004C # ---------- StepColorTemperature ---------- + # TODO, we don't really support it + return true + end + + else + return super(self).invoke_request(session, val, ctx) + end + end + + ############################################################# + # web_values + # + # Show values of the remote device as HTML + def web_values() + import webserver + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(format("%s %s %s", + self.web_value_onoff(self.shadow_onoff), self.web_value_dimmer(), + self.web_value_ct())) + end + + # Show on/off value as html + def web_value_ct() + var ct_html = "" + if self.shadow_ct != nil + var ct_k = (((1000000 / self.shadow_ct) + 25) / 50) * 50 # convert in Kelvin + ct_html = format("%iK", ct_k) + end + return "⚪ " + ct_html; + end +end +matter.Plugin_Bridge_Light2 = Matter_Plugin_Bridge_Light2 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_5_Bridge_Light3.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_5_Bridge_Light3.be new file mode 100644 index 000000000000..abb4e9672da7 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_5_Bridge_Light3.be @@ -0,0 +1,220 @@ +# +# Matter_Plugin_Bridge_Light3.be - implements the behavior for a remote generic Lighting (RGB) via HTTP +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Bridge_Light3,weak + +class Matter_Plugin_Bridge_Light3 : Matter_Plugin_Bridge_Light1 + static var TYPE = "http_light3" # name of the plug-in in json + static var DISPLAY_NAME = "Light 3 RGB" # display name of the plug-in + # static var ARG = "relay" # additional argument name (or empty if none) + # static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type + static var CLUSTERS = matter.consolidate_clusters(_class, { + # 0x001D: inherited # Descriptor Cluster 9.5 p.453 + # 0x0003: inherited # Identify 1.2 p.16 + # 0x0004: inherited # Groups 1.3 p.21 + # 0x0005: inherited # Scenes 1.4 p.30 - no writable + # 0x0006: inherited # On/Off 1.5 p.48 + # 0x0008: inherited # Level Control 1.6 p.57 + 0x0300: [0,1,7,8,0xF,0x4001,0x400A,0xFFFC,0xFFFD],# Color Control 3.2 p.111 + }) + static var TYPES = { 0x010D: 2 } # Extended Color Light + + var shadow_hue, shadow_sat # 0..254 + + ############################################################# + # Constructor + def init(device, endpoint, arguments) + super(self).init(device, endpoint, arguments) + end + + ############################################################# + # Stub for updating shadow values (local copies of what we published to the Matter gateway) + # + # This call is synnchronous and blocking. + def parse_update(data, index) + super(self).parse_update(data, index) + + if index == 11 # Status 11 + var hsb = data.find("HSBColor") + if hsb + import string + var hsb_list = string.split(hsb, ",") + var hue = int(hsb_list[0]) + var sat = int(hsb_list[1]) + # dimmer is already available + + if hue != nil hue = tasmota.scale_uint(hue, 0, 360, 0, 254) else hue = self.shadow_hue end + if sat != nil sat = tasmota.scale_uint(sat, 0, 100, 0, 254) else sat = self.shadow_sat end + if hue != self.shadow_hue self.attribute_updated(0x0300, 0x0000) self.shadow_hue = hue end + if sat != self.shadow_sat self.attribute_updated(0x0300, 0x0001) self.shadow_sat = sat end + end + end + end + + ############################################################# + # Model + # + def set_hue(v) + var hue_360 = tasmota.scale_uint(v, 0, 254, 0, 360) + var ret = self.call_remote_sync("HSBColor1", hue_360) + if ret != nil + self.parse_update(ret, 11) # update shadow from return value + end + end + def set_sat(v) + var sat_100 = tasmota.scale_uint(v, 0, 254, 0, 100) + var ret = self.call_remote_sync("HSBColor2", sat_100) + if ret != nil + self.parse_update(ret, 11) # update shadow from return value + end + end + + ############################################################# + # read an attribute + # + def read_attribute(session, ctx, tlv_solo) + var TLV = matter.TLV + var cluster = ctx.cluster + var attribute = ctx.attribute + + # ==================================================================================================== + if cluster == 0x0300 # ========== Color Control 3.2 p.111 ========== + self.update_shadow_lazy() + if attribute == 0x0000 # ---------- CurrentHue / u1 ---------- + if self.shadow_hue != nil + return tlv_solo.set(TLV.U1, self.shadow_hue) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x0001 # ---------- CurrentSaturation / u2 ---------- + if self.shadow_sat != nil + return tlv_solo.set(TLV.U1, self.shadow_sat) + else + return tlv_solo.set(TLV.NULL, nil) + end + elif attribute == 0x0007 # ---------- ColorTemperatureMireds / u2 ---------- + return tlv_solo.set(TLV.U1, 0) + elif attribute == 0x0008 # ---------- ColorMode / u1 ---------- + return tlv_solo.set(TLV.U1, 0)# 0 = CurrentHue and CurrentSaturation + elif attribute == 0x000F # ---------- Options / u1 ---------- + return tlv_solo.set(TLV.U1, 0) + elif attribute == 0x4001 # ---------- EnhancedColorMode / u1 ---------- + return tlv_solo.set(TLV.U1, 0) + elif attribute == 0x400A # ---------- ColorCapabilities / map32 ---------- + return tlv_solo.set(TLV.U4, 0x01) # HS + + # Defined Primaries Information Attribute Set + elif attribute == 0x0010 # ---------- NumberOfPrimaries / u1 ---------- + return tlv_solo.set(TLV.U1, 0) + + elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- + return tlv_solo.set(TLV.U4, 0x01) # HS + elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- + return tlv_solo.set(TLV.U4, 5) # "new data model format and notation, FeatureMap support" + end + + else + return super(self).read_attribute(session, ctx, tlv_solo) + end + end + + ############################################################# + # Invoke a command + # + # returns a TLV object if successful, contains the response + # or an `int` to indicate a status + def invoke_request(session, val, ctx) + var TLV = matter.TLV + var cluster = ctx.cluster + var command = ctx.command + + # ==================================================================================================== + if cluster == 0x0300 # ========== Color Control 3.2 p.111 ========== + if command == 0x0000 # ---------- MoveToHue ---------- + var hue_in = val.findsubval(0) # Hue 0..254 + self.set_hue(hue_in) + ctx.log = "hue:"+str(hue_in) + self.publish_command('Hue', hue_in) + return true + elif command == 0x0001 # ---------- MoveHue ---------- + # TODO, we don't really support it + return true + elif command == 0x0002 # ---------- StepHue ---------- + # TODO, we don't really support it + return true + elif command == 0x0003 # ---------- MoveToSaturation ---------- + var sat_in = val.findsubval(0) # Sat 0..254 + self.set_sat(sat_in) + ctx.log = "sat:"+str(sat_in) + self.publish_command('Sat', sat_in) + return true + elif command == 0x0004 # ---------- MoveSaturation ---------- + # TODO, we don't really support it + return true + elif command == 0x0005 # ---------- StepSaturation ---------- + # TODO, we don't really support it + return true + elif command == 0x0006 # ---------- MoveToHueAndSaturation ---------- + var hue_in = val.findsubval(0) # Hue 0..254 + var sat_in = val.findsubval(1) # Sat 0..254 + self.set_hue(hue_in) + self.set_sat(sat_in) + ctx.log = "hue:"+str(hue_in)+" sat:"+str(sat_in) + self.publish_command('Hue', hue_in, 'Sat', sat_in) + return true + elif command == 0x0047 # ---------- StopMoveStep ---------- + # TODO, we don't really support it + return true + end + + else + return super(self).invoke_request(session, val, ctx) + end + end + + ############################################################# + # web_values + # + # Show values of the remote device as HTML + def web_values() + import webserver + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(format("%s %s %s", + self.web_value_onoff(self.shadow_onoff), self.web_value_dimmer(), + self.web_value_RGB())) + end + + # Show on/off value as html + def web_value_RGB() + if self.shadow_hue != nil && self.shadow_sat != nil + var l = light_state(3) # RGB virtual light state object + l.set_bri(255) # set full brightness to get full range RGB + l.set_huesat(tasmota.scale_uint(self.shadow_hue, 0, 254, 0, 360), tasmota.scale_uint(self.shadow_sat, 0, 254, 0, 255)) + var rgb_hex = format("#%02X%02X%02X", l.r, l.g, l.b) + var rgb_html = format('%s', rgb_hex, rgb_hex) + return rgb_html + end + return "" + end +end +matter.Plugin_Bridge_Light3 = Matter_Plugin_Bridge_Light3 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Light0.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Light0.be new file mode 100644 index 000000000000..cbe90af7d3b1 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Light0.be @@ -0,0 +1,34 @@ +# +# Matter_Plugin_Virt_Light0.be - implements the behavior for a virtual Light (OnOff only) +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Virt_Light0,weak + +class Matter_Plugin_Virt_Light0 : Matter_Plugin_Light0 + static var TYPE = "v_light0" # name of the plug-in in json + static var DISPLAY_NAME = "v.Light 0 On" # display name of the plug-in + static var ARG = "" # no arg for virtual device + static var ARG_HINT = "_Not used_" # Hint for entering the Argument (inside 'placeholder') + static var VIRTUAL = true # virtual device + +end +matter.Plugin_Virt_Light0 = Matter_Plugin_Virt_Light0 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Light1.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Light1.be new file mode 100644 index 000000000000..8697bf2df848 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Light1.be @@ -0,0 +1,34 @@ +# +# Matter_Plugin_Virt_Light1.be - implements the behavior for a virtual Light 1 channel (Dimmer) +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Virt_Light1,weak + +class Matter_Plugin_Virt_Light1 : Matter_Plugin_Light1 + static var TYPE = "v_light1" # name of the plug-in in json + static var DISPLAY_NAME = "v.Light 1 Dimmer" # display name of the plug-in + static var ARG = "" # no arg for virtual device + static var ARG_HINT = "_Not used_" # Hint for entering the Argument (inside 'placeholder') + static var VIRTUAL = true # virtual device + +end +matter.Plugin_Virt_Light1 = Matter_Plugin_Virt_Light1 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Light2.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Light2.be new file mode 100644 index 000000000000..20876b8424b7 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Light2.be @@ -0,0 +1,34 @@ +# +# Matter_Plugin_Virt_Light2.be - implements the behavior for a virtual Light with 2 channel (CT) +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Virt_Light2,weak + +class Matter_Plugin_Virt_Light2 : Matter_Plugin_Light2 + static var TYPE = "v_light2" # name of the plug-in in json + static var DISPLAY_NAME = "v.Light 2 CT" # display name of the plug-in + static var ARG = "" # no arg for virtual device + static var ARG_HINT = "_Not used_" # Hint for entering the Argument (inside 'placeholder') + static var VIRTUAL = true # virtual device + +end +matter.Plugin_Virt_Light2 = Matter_Plugin_Virt_Light2 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Light3.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Light3.be new file mode 100644 index 000000000000..15e7e2ae15df --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Light3.be @@ -0,0 +1,34 @@ +# +# Matter_Plugin_Virt_Light3.be - implements the behavior for a virtual Light with 3 channels (RGB) +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Virt_Light3,weak + +class Matter_Plugin_Virt_Light3 : Matter_Plugin_Light3 + static var TYPE = "v_light3" # name of the plug-in in json + static var DISPLAY_NAME = "v.Light 3 RGB" # display name of the plug-in + static var ARG = "" # no arg for virtual device + static var ARG_HINT = "_Not used_" # Hint for entering the Argument (inside 'placeholder') + static var VIRTUAL = true # virtual device + +end +matter.Plugin_Virt_Light3 = Matter_Plugin_Virt_Light3 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_OnOff.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_OnOff.be new file mode 100644 index 000000000000..d9bb5403bc15 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_OnOff.be @@ -0,0 +1,34 @@ +# +# Matter_Plugin_Virt_OnOff.be - implements the behavior for a Virtual Relay +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Virt_OnOff,weak + +class Matter_Plugin_Virt_OnOff : Matter_Plugin_OnOff + static var TYPE = "v_relay" # name of the plug-in in json + static var DISPLAY_NAME = "v.Relay" # display name of the plug-in + static var ARG = "" # no arg for virtual device + static var ARG_HINT = "_Not used_" # Hint for entering the Argument (inside 'placeholder') + static var VIRTUAL = true # virtual device + +end +matter.Plugin_Virt_OnOff = Matter_Plugin_Virt_OnOff diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Contact.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Contact.be new file mode 100644 index 000000000000..0cf722866c40 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Contact.be @@ -0,0 +1,34 @@ +# +# Matter_Plugin_9_Virt_Sensor_Contact.be - implements the behavior for a Virtual Contact Sensor +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Virt_Sensor_Contact,weak + +class Matter_Plugin_Virt_Sensor_Contact : Matter_Plugin_Sensor_Contact + static var TYPE = "v_contact" # name of the plug-in in json + static var DISPLAY_NAME = "v.Contact" # display name of the plug-in + static var ARG = "" # no arg for virtual device + static var ARG_HINT = "_Not used_" # Hint for entering the Argument (inside 'placeholder') + static var VIRTUAL = true # virtual device + +end +matter.Plugin_Virt_Sensor_Contact = Matter_Plugin_Virt_Sensor_Contact diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Humidity.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Humidity.be new file mode 100644 index 000000000000..0fb033a5531e --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Humidity.be @@ -0,0 +1,34 @@ +# +# Matter_Plugin_9_Virt_Sensor_Humidity.be - implements the behavior for a Virtual Humidity Sensor +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Virt_Sensor_Humidity,weak + +class Matter_Plugin_Virt_Sensor_Humidity : Matter_Plugin_Sensor_Humidity + static var TYPE = "v_humidity" # name of the plug-in in json + static var DISPLAY_NAME = "v.Humidity" # display name of the plug-in + static var ARG = "" # no arg for virtual device + static var ARG_HINT = "_Not used_" # Hint for entering the Argument (inside 'placeholder') + static var VIRTUAL = true # virtual device + +end +matter.Plugin_Virt_Sensor_Humidity = Matter_Plugin_Virt_Sensor_Humidity diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Illuminance.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Illuminance.be new file mode 100644 index 000000000000..76090f41af4f --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Illuminance.be @@ -0,0 +1,34 @@ +# +# Matter_Plugin_9_Virt_Sensor_Illuminance.be - implements the behavior for a Virtual Illuminance Sensor +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Virt_Sensor_Illuminance,weak + +class Matter_Plugin_Virt_Sensor_Illuminance : Matter_Plugin_Sensor_Illuminance + static var TYPE = "v_illuminance" # name of the plug-in in json + static var DISPLAY_NAME = "v.Illuminance" # display name of the plug-in + static var ARG = "" # no arg for virtual device + static var ARG_HINT = "_Not used_" # Hint for entering the Argument (inside 'placeholder') + static var VIRTUAL = true # virtual device + +end +matter.Plugin_Virt_Sensor_Illuminance = Matter_Plugin_Virt_Sensor_Illuminance diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Pressure.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Pressure.be new file mode 100644 index 000000000000..c661b2b0d13a --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Pressure.be @@ -0,0 +1,34 @@ +# +# Matter_Plugin_9_Virt_Sensor_Pressure.be - implements the behavior for a Virtual Temperature Sensor +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Virt_Sensor_Pressure,weak + +class Matter_Plugin_Virt_Sensor_Pressure : Matter_Plugin_Sensor_Pressure + static var TYPE = "v_pressure" # name of the plug-in in json + static var DISPLAY_NAME = "v.Pressure" # display name of the plug-in + static var ARG = "" # no arg for virtual device + static var ARG_HINT = "_Not used_" # Hint for entering the Argument (inside 'placeholder') + static var VIRTUAL = true # virtual device + +end +matter.Plugin_Virt_Sensor_Pressure = Matter_Plugin_Virt_Sensor_Pressure diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Temp.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Temp.be new file mode 100644 index 000000000000..8ad2b11e378c --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_9_Virt_Sensor_Temp.be @@ -0,0 +1,34 @@ +# +# Matter_Plugin_9_Virt_Sensor_Temp.be - implements the behavior for a Virtual Temperature Sensor +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +# Matter plug-in for core behavior + +#@ solidify:Matter_Plugin_Virt_Sensor_Temp,weak + +class Matter_Plugin_Virt_Sensor_Temp : Matter_Plugin_Sensor_Temp + static var TYPE = "v_temp" # name of the plug-in in json + static var DISPLAY_NAME = "v.Temperature" # display name of the plug-in + static var ARG = "" # no arg for virtual device + static var ARG_HINT = "_Not used_" # Hint for entering the Argument (inside 'placeholder') + static var VIRTUAL = true # virtual device + +end +matter.Plugin_Virt_Sensor_Temp = Matter_Plugin_Virt_Sensor_Temp diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_HTTP.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_HTTP.be deleted file mode 100644 index 612fe489df56..000000000000 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_HTTP.be +++ /dev/null @@ -1,228 +0,0 @@ -# -# Matter_Plugin_Bridge_HTTP.be - implements base class for a Bridge via HTTP -# -# Copyright (C) 2023 Stephan Hadinger & Theo Arends -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -# Matter plug-in for core behavior - -# dummy declaration for solidification -class Matter_Plugin_Device end - -#@ solidify:Matter_Plugin_Bridge_HTTP,weak - -class Matter_Plugin_Bridge_HTTP : Matter_Plugin_Device - static var TYPE = "" # name of the plug-in in json - static var NAME = "" # display name of the plug-in - static var ARG = "" # additional argument name (or empty if none) - static var ARG_HTTP = "url" # domain name - static var UPDATE_TIME = 3000 # update every 3s - static var HTTP_TIMEOUT = 300 # wait for 300ms max, since we're on LAN - static var CLUSTERS = { - # 0x001D: inherited # Descriptor Cluster 9.5 p.453 - # 0x0003: inherited # Identify 1.2 p.16 - # 0x0004: inherited # Groups 1.3 p.21 - # 0x0005: inherited # Scenes 1.4 p.30 - no writable - # 0x0006: [0,0xFFFC,0xFFFD], # On/Off 1.5 p.48 - - # 0x0028: [0,1,2,3,4,5,6,7,8,9,0x0A,0x0F,0x12,0x13],# Basic Information Cluster cluster 11.1 p.565 - 0x0039: [0x11] # Bridged Device Basic Information 9.13 p.485 - - } - # static var TYPES = { 0x010A: 2 } # On/Off Light - - var tasmota_http # domain name for HTTP, ex: 'http://192.168.1.10/' - var tasmota_status_8 # remote `Status 8` sensor values (last known) - var tasmota_status_11 # remote `Status 11` light values (last known) - # each contain a `_tick` attribute to known when they were last loaded - var reachable # is the device reachable - var reachable_tick # last tick when the reachability was seen (avoids sending superfluous ping commands) - - ############################################################# - # Constructor - def init(device, endpoint, arguments) - import string - super(self).init(device, endpoint, arguments) - - var http = arguments.find(self.ARG_HTTP) - if http - if string.find(http, '://') < 0 - http = "http://" + http + "/" - end - self.tasmota_http = http - else - tasmota.log(string.format("MTR: ERROR: 'url' is not configured for endpoint %i", endpoint), 2) - end - self.tasmota_status_8 = nil - self.tasmota_status_11 = nil - self.reachable = false # force a valid bool value - end - - ############################################################# - # return the map of all types, add the bridged type - def get_types() - var types = {} - for k: self.TYPES.keys() - types[k] = self.TYPES[k] - end - # Add Bridged Node - types[0x0013] = 1 # Bridged Node, v1 - return types - end - - ############################################################# - # call_remote - # - # Call a remote Tasmota device, returns Berry native map or nil - def call_remote(cmd, arg) - if !self.tasmota_http return nil end - import json - import string - if !tasmota.wifi()['up'] && !tasmota.eth()['up'] return nil end # no network - var retry = 2 # try 2 times if first failed - while retry > 0 - var cl = webclient() - cl.set_timeouts(1000, 1000) - cl.set_follow_redirects(false) - var url = string.format("%scm?cmnd=%s%%20%s", self.tasmota_http, cmd, arg ? arg : '') - tasmota.log("MTR: HTTP GET "+url, 3) - cl.begin(url) - var r = cl.GET() - tasmota.log("MTR: HTTP GET code=" + str(r), 3) - if r == 200 - var s = cl.get_string() - cl.close() - tasmota.log("MTR: HTTP GET payload=" + s, 3) - var j = json.load(s) - # device is known to be reachable - self.reachable = true - self.reachable_tick = self.device.tick - return j - end - cl.close() - - retry -= 1 - tasmota.log("MTR: HTTP GET retrying", 3) - end - self.reachable = false - return nil - end - - ############################################################# - # is_reachable() - # - # Pings the device and checks if it's reachable - def is_reachable() - if self.device.tick != self.reachable_tick - var ret = self.call_remote("", "") # empty command works as a ping - self.reachable = (ret != nil) - # self.reachable_tick = cur_tick # done by caller - end - return self.reachable - end - - ############################################################# - # get_status_8() - # - # Get remote `Status 8` values of sensors, and cache for the current tick - def get_status_8() - var cur_tick = self.device.tick - if self.tasmota_status_8 == nil || self.tasmota_status_8.find("_tick") != cur_tick - var ret = self.call_remote("Status", "8") # call `Status 8` - if ret - ret["_tick"] = cur_tick - self.tasmota_status_8 = ret - return ret - else - return nil - end - else - return self.tasmota_status_8 # return cached value - end - end - - ############################################################# - # get_status_11() - # - # Get remote `Status 11` values of sensors, and cache for the current tick - def get_status_11() - var cur_tick = self.device.tick - if self.tasmota_status_11 == nil || self.tasmota_status_11.find("_tick") != cur_tick - var ret = self.call_remote("Status", "11") # call `Status 8` - if ret - ret["_tick"] = cur_tick - self.tasmota_status_11 = ret - return ret - else - return nil - end - else - return self.tasmota_status_11 # return cached value - end - end - - ############################################################# - # read attribute - # - def read_attribute(session, ctx) - var TLV = matter.TLV - var cluster = ctx.cluster - var attribute = ctx.attribute - - # ==================================================================================================== - if cluster == 0x0039 # ========== Bridged Device Basic Information 9.13 p.485 ========== - - if attribute == 0x0000 # ---------- DataModelRevision / CommissioningWindowStatus ---------- - # return TLV.create_TLV(TLV.U2, 1) - elif attribute == 0x0011 # ---------- Reachable / bool ---------- - return TLV.create_TLV(TLV.BOOL, true) # TODO find a way to do a ping - end - - else - return super(self).read_attribute(session, ctx) - end - end - - ############################################################# - # UI Methods - ############################################################# - # ui_conf_to_string - # - # Convert the current plugin parameters to a single string - static def ui_conf_to_string(cl, conf) - var s = super(_class).ui_conf_to_string(cl, conf) - - var url = str(conf.find(_class.ARG_HTTP, '')) - var arg = s + "," + url - print("MTR: ui_conf_to_string", conf, cl, arg) - return arg - end - - ############################################################# - # ui_string_to_conf - # - # Convert the string in UI to actual parameters added to the map - static def ui_string_to_conf(cl, conf, arg) - import string - var elts = string.split(arg + ',', ',', 3) # add ',' at the end to be sure to have at least 2 arguments - conf[_class.ARG_HTTP] = elts[1] - super(_class).ui_string_to_conf(cl, conf, elts[0]) - print("ui_string_to_conf", conf, arg) - return conf - end - -end -matter.Plugin_Bridge_HTTP = Matter_Plugin_Bridge_HTTP diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Device.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Device.be deleted file mode 100644 index 648d008f0bbd..000000000000 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Device.be +++ /dev/null @@ -1,128 +0,0 @@ -# -# Matter_Plugin_Device.be - implements the behavior for a standard Device -# -# Copyright (C) 2023 Stephan Hadinger & Theo Arends -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -# dummy declaration for solidification -class Matter_Plugin end - -#@ solidify:Matter_Plugin_Device,weak - -class Matter_Plugin_Device : Matter_Plugin - static var CLUSTERS = { - # 0x001D: inherited # Descriptor Cluster 9.5 p.453 - 0x0003: [0,1,0xFFFC,0xFFFD], # Identify 1.2 p.16 - 0x0004: [0,0xFFFC,0xFFFD], # Groups 1.3 p.21 - 0x0005: [0,1,2,3,4,5,0xFFFC,0xFFFD], # Scenes 1.4 p.30 - no writable - } - static var TYPES = { 0x0000: 0 } # fake type - - ############################################################# - # Constructor - # def init(device, endpoint, arguments) - # super(self).init(device, endpoint, arguments) - # end - - ############################################################# - # read an attribute - # - def read_attribute(session, ctx) - import string - var TLV = matter.TLV - var cluster = ctx.cluster - var attribute = ctx.attribute - - # ==================================================================================================== - if cluster == 0x0003 # ========== Identify 1.2 p.16 ========== - if attribute == 0x0000 # ---------- IdentifyTime / u2 ---------- - return TLV.create_TLV(TLV.U2, 0) # no identification in progress - elif attribute == 0x0001 # ---------- IdentifyType / enum8 ---------- - return TLV.create_TLV(TLV.U1, 0) # IdentifyType = 0x00 None - elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0) # no features - elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 4) # "new data model format and notation" - end - - # ==================================================================================================== - elif cluster == 0x0004 # ========== Groups 1.3 p.21 ========== - if attribute == 0x0000 # ---------- ---------- - return nil # TODO - elif attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0)# - elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 4)# "new data model format and notation" - end - - # ==================================================================================================== - elif cluster == 0x0005 # ========== Scenes 1.4 p.30 - no writable ========== - if attribute == 0xFFFC # ---------- FeatureMap / map32 ---------- - return TLV.create_TLV(TLV.U4, 0) # 0 = no Level Control for Lighting - elif attribute == 0xFFFD # ---------- ClusterRevision / u2 ---------- - return TLV.create_TLV(TLV.U4, 4) # 0 = no Level Control for Lighting - end - - else - return super(self).read_attribute(session, ctx) - end - end - - ############################################################# - # Invoke a command - # - # returns a TLV object if successful, contains the response - # or an `int` to indicate a status - def invoke_request(session, val, ctx) - var TLV = matter.TLV - var cluster = ctx.cluster - var command = ctx.command - - # ==================================================================================================== - if cluster == 0x0003 # ========== Identify 1.2 p.16 ========== - - if command == 0x0000 # ---------- Identify ---------- - # ignore - return true - elif command == 0x0001 # ---------- IdentifyQuery ---------- - # create IdentifyQueryResponse - # ID=1 - # 0=Certificate (octstr) - var iqr = TLV.Matter_TLV_struct() - iqr.add_TLV(0, TLV.U2, 0) # Timeout - ctx.command = 0x00 # IdentifyQueryResponse - return iqr - elif command == 0x0040 # ---------- TriggerEffect ---------- - # ignore - return true - end - # ==================================================================================================== - elif cluster == 0x0004 # ========== Groups 1.3 p.21 ========== - # TODO - return true - - # ==================================================================================================== - elif cluster == 0x0005 # ========== Scenes 1.4 p.30 ========== - # TODO - return true - - else - return super(self).invoke_request(session, val, ctx) - end - end - -end -matter.Plugin_Device = Matter_Plugin_Device diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Profiler.be b/lib/libesp32/berry_matter/src/embedded/Matter_Profiler.be new file mode 100644 index 000000000000..fb9f1dd5630f --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Profiler.be @@ -0,0 +1,96 @@ +# +# Matter_Profiler.be - suppport for Matter profiler framework +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +#@ solidify:Matter_Profiler,weak + +################################################################################# +# Matter_Profiler +# +# Used to store all the elements of the reponse to an attribute or command +################################################################################# +class Matter_Profiler + static var PREALLOCATED = 50 + var millis + var names + var active + var allocs + var reallocs + var len # number of entries + + def init() + self.active = false + self.millis = list() + self.millis.resize(self.PREALLOCATED) # we force zero allocation when using profiler + self.names = list() + self.names.resize(self.PREALLOCATED) + self.allocs = list() + self.allocs.resize(self.PREALLOCATED) + self.reallocs = list() + self.reallocs.resize(self.PREALLOCATED) + self.len = 0 + end + + def set_active(v) + self.active = bool(v) + end + + def start() + if !self.active return end + var idx = 0 + while idx < self.PREALLOCATED + self.millis[idx] = nil + self.names[idx] = nil + idx += 1 + end + self.len = 0 + tasmota.gc() # To get deterministic values, we force a full GC before profiler + self.log("start") + end + + def log(name) + if !self.active return end + import debug + var len = self.len + if len >= self.PREALLOCATED return end # size overflow + self.millis[len] = tasmota.millis() + self.names[len] = name + self.allocs[len] = debug.allocs() + self.reallocs[len] = debug.reallocs() + self.len += 1 + end + + def dump(loglevel) + if !self.active return end + self.log("<--end-->") + tasmota.log("MTR: Profiler dump:", loglevel) + var origin = self.millis[0] + var allocs0 = self.allocs[0] + var reallocs0 = self.reallocs[0] + var idx = 1 + while idx < self.len + # tasmota.log(f"MTR: {self.millis[idx] - origin:4i} [{self.allocs[idx] - allocs0:4i}|{self.reallocs[idx] - reallocs0:4i}]'{self.names[idx]}'", loglevel) + tasmota.log(f"MTR: {self.millis[idx] - origin:4i} [{self.allocs[idx] - allocs0:4i}]'{self.names[idx]}'", loglevel) + idx += 1 + end + end + +end +matter.Profiler = Matter_Profiler diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Session.be b/lib/libesp32/berry_matter/src/embedded/Matter_Session.be index b0fe0185c755..dd17a0df0fe3 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Session.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Session.be @@ -48,6 +48,9 @@ class Matter_Session : Matter_Expirable var created # timestamp (UTC) when the session was created var last_used # timestamp (UTC) when the session was last used var _source_node_id # source node if bytes(8) (opt, used only when session is not established) + # temporary data for ArmFailSafe provisioning - before it is stored in a fabric + var _temp_root_ca_certificate # temporary root_ca_certificate added by `AddTrustedRootCertificate` before `AddNoc` + var _temp_pk # session_ids when the session will be active var __future_initiator_session_id var __future_local_session_id @@ -108,15 +111,14 @@ class Matter_Session : Matter_Expirable self._breadcrumb = 0 self._exchange_id = crypto.random(2).get(0,2) # generate a random 16 bits number, then increment with rollover - self._fabric = fabric ? fabric : self._store.create_fabric() + self._fabric = fabric self.update() end ############################################################# # Called before removal def before_remove() - import string - tasmota.log(string.format("MTR: -Session (%6i) (removed)", self.local_session_id), 3) + tasmota.log(format("MTR: -Session (%6i) (removed)", self.local_session_id), 3) end ############################################################# @@ -125,10 +127,8 @@ class Matter_Session : Matter_Expirable # Provide the next counter value, and update the last know persisted if needed # def counter_snd_next() - import string var next = self._counter_snd_impl.next() - tasmota.log(string.format("MTR: . Counter_snd=%i", next), 3) - # print(">>> NEXT counter_snd=", self.counter_snd, "_impl=", self._counter_snd_impl.val(), 4) + # tasmota.log(format("MTR: . Counter_snd=%i", next), 4) if matter.Counter.is_greater(next, self.counter_snd) self.counter_snd = next + self._COUNTER_SND_INCR if self.does_persist() @@ -165,38 +165,13 @@ class Matter_Session : Matter_Expirable ############################################################# # Update the timestamp or any other information def update() - self.last_used = tasmota.rtc()['utc'] + self.last_used = tasmota.rtc_utc() end def set_mode_PASE() self.set_mode(self._PASE) end def set_mode_CASE() self.set_mode(self._CASE) end def is_PASE() return self.mode == self._PASE end def is_CASE() return self.mode == self._CASE end - - ############################################################# - # Assign a new fabric index - def assign_fabric_index() - if (self._fabric.get_fabric_index() == nil) - self._fabric.set_fabric_index(self._store.next_fabric_idx()) - end - end - - ############################################################# - # Register the fabric as complete (end of commissioning) - def fabric_completed() - self._fabric.set_no_expiration() - self._fabric.set_persist(true) - self.assign_fabric_index() - self._store.add_fabric(self._fabric) - end - - ############################################################# - # Register the frabric as complete (end of commissioning) - def fabric_candidate() - self._fabric.set_expire_in_seconds(120) # expire in 2 minutes - self.assign_fabric_index() - self._store.add_fabric(self._fabric) - end ############################################################# # Persist to fabric @@ -241,26 +216,16 @@ class Matter_Session : Matter_Expirable self.attestation_challenge = ac self.created = st end - def set_ca(ca) - self._fabric.root_ca_certificate = ca - end - def set_noc(noc, icac) - self._fabric.noc = noc - self._fabric.icac = icac - end - def set_ipk_epoch_key(ipk_epoch_key) - self._fabric.ipk_epoch_key = ipk_epoch_key - end - def set_admin_subject_vendor(admin_subject, admin_vendor) - self._fabric.admin_subject = admin_subject - self._fabric.admin_vendor = admin_vendor + def set_temp_ca(ca) + self._temp_root_ca_certificate = ca end - - def set_fabric_device(fabric_id, device_id, fc, fabric_parent) - self._fabric.fabric_id = fabric_id - self._fabric.device_id = device_id - self._fabric.fabric_compressed = fc - self._fabric.fabric_parent = (fabric_parent != nil) ? fabric_parent.get_fabric_index() : nil + def get_temp_ca() return self._temp_root_ca_certificate end + def get_temp_ca_pub() + var ca = self._temp_root_ca_certificate + if ca + var m = matter.TLV.parse(ca) + return m.findsubval(9) + end end def set_fabric_label(s) if type(s) == 'string' @@ -269,12 +234,8 @@ class Matter_Session : Matter_Expirable end ############################################################# - def get_mode() - return self.mode - end - def get_i2r() - return self.i2rkey - end + def get_mode() return self.mode end + def get_i2r() return self.i2rkey end def get_i2r_privacy() # get and cache privacy key if self._i2r_privacy == nil import crypto @@ -283,48 +244,45 @@ class Matter_Session : Matter_Expirable end return self._i2r_privacy end - def get_r2i() - return self.r2ikey - end - def get_ac() - return self.attestation_challenge - end - def get_ca() - return self._fabric.root_ca_certificate - end - def get_ca_pub() - return self._fabric.get_ca_pub() - end + def get_r2i() return self.r2ikey end + def get_ac() return self.attestation_challenge end + + def get_ca() return self._fabric.root_ca_certificate end + def get_ca_pub() return self._fabric.get_ca_pub() end def get_fabric() return self._fabric end def get_noc() return self._fabric.noc end def get_icac() return self._fabric.icac end def get_ipk_epoch_key() return self._fabric.ipk_epoch_key end def get_fabric_id() return self._fabric.fabric_id end - def get_device_id() return self._fabric.device_id end + def get_fabric_index() return self._fabric ? self._fabric.fabric_index : nil end + def get_device_id() return self._fabric ? self._fabric.device_id : nil end def get_fabric_compressed() return self._fabric.fabric_compressed end def get_fabric_label() return self._fabric.fabric_label end def get_admin_subject() return self._fabric.admin_subject end def get_admin_vendor() return self._fabric.admin_vendor end ############################################################# - # Generate a private key (or retrieve it) + # Get operational key pair (private key) + # + # If there is a fabric, retrieve the PK from the fabric + # If there is no fabric, create a temporary PK in `_temp_pk` + # to be stored later in the fabric def get_pk() - if !self._fabric.no_private_key - import crypto - self._fabric.no_private_key = crypto.random(32) + if self._fabric + return self._fabric.get_pk() + else + if !self._temp_pk + import crypto + self._temp_pk = crypto.random(32) + end + return self._temp_pk end - return self._fabric.no_private_key end ############################################################# # Operational Group Key Derivation, 4.15.2, p.182 def get_ipk_group_key() - if self.get_ipk_epoch_key() == nil || self.get_fabric_compressed() == nil return nil end - import crypto - var hk = crypto.HKDF_SHA256() - var info = bytes().fromstring(self._GROUP_KEY) - var hash = hk.derive(self.get_ipk_epoch_key(), self.get_fabric_compressed(), info, 16) - return hash + return self._fabric.get_ipk_group_key() end ############################################################# @@ -335,7 +293,6 @@ class Matter_Session : Matter_Expirable ############################################################# def tojson() import json - import string import introspect self.persist_pre() @@ -355,7 +312,7 @@ class Matter_Session : Matter_Expirable elif type(v) == 'instance' continue # skip any other instance end - r.push(string.format("%s:%s", json.dump(str(k)), json.dump(v))) + r.push(format("%s:%s", json.dump(str(k)), json.dump(v))) end self.persist_post() return "{" + r.concat(",") + "}" diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Session_Store.be b/lib/libesp32/berry_matter/src/embedded/Matter_Session_Store.be index 27dfdd520e88..0c819b906152 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Session_Store.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Session_Store.be @@ -275,15 +275,14 @@ class Matter_Session_Store ############################################################# # find session by resumption id def find_session_by_resumption_id(resumption_id) - import string if !resumption_id return nil end var i = 0 var sessions = self.sessions while i < size(sessions) var session = sessions[i] - tasmota.log(string.format("MTR: session.resumption_id=%s vs %s", str(session.resumption_id), str(resumption_id)), 3) + tasmota.log(format("MTR: session.resumption_id=%s vs %s", str(session.resumption_id), str(resumption_id)), 4) if session.resumption_id == resumption_id && session.shared_secret != nil - tasmota.log(string.format("MTR: session.shared_secret=%s", str(session.shared_secret)), 3) + # tasmota.log(format("MTR: session.shared_secret=%s", str(session.shared_secret)), 4) session.update() return session end @@ -311,24 +310,27 @@ class Matter_Session_Store ############################################################# def save_fabrics() import json - self.remove_expired() # clean before saving - var sessions_saved = 0 - - var fabs = [] - for f : self.fabrics.persistables() - for _ : f._sessions.persistables() sessions_saved += 1 end # count persitable sessions - fabs.push(f.tojson()) - end - var fabs_size = size(fabs) - fabs = "[" + fabs.concat(",") + "]" - try - import string + self.remove_expired() # clean before saving + var sessions_saved = 0 + var fabrics_saved = 0 var f = open(self._FABRICS, "w") - f.write(fabs) + + f.write("[") + for fab : self.fabrics.persistables() + for _ : fab._sessions.persistables() sessions_saved += 1 end # count persitable sessions + if fabrics_saved > 0 + f.write(",") + end + var f_json = fab.tojson() + f.write(f_json) + fabrics_saved += 1 + end + f.write("]") + f.close() - tasmota.log(string.format("MTR: =Saved %i fabric(s) and %i session(s)", fabs_size, sessions_saved), 2) + tasmota.log(f"MTR: =Saved {fabrics_saved} fabric(s) and {sessions_saved} session(s)", 2) self.device.event_fabrics_saved() # signal event except .. as e, m tasmota.log("MTR: Session_Store::save Exception:" + str(e) + "|" + str(m), 2) @@ -338,7 +340,6 @@ class Matter_Session_Store ############################################################# # load fabrics and associated sessions def load_fabrics() - import string try self.sessions = matter.Expirable_list() # remove any left-over self.fabrics = matter.Expirable_list() # remove any left-over @@ -373,7 +374,7 @@ class Matter_Session_Store self.fabrics.push(fabric) end - tasmota.log(string.format("MTR: Loaded %i fabric(s)", size(self.fabrics)), 2) + tasmota.log(format("MTR: Loaded %i fabric(s)", size(self.fabrics)), 2) except .. as e, m if e != "io_error" tasmota.log("MTR: Session_Store::load Exception:" + str(e) + "|" + str(m), 2) diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_TCP_async.be b/lib/libesp32/berry_matter/src/embedded/Matter_TCP_async.be new file mode 100644 index 000000000000..ed13b725c7f1 --- /dev/null +++ b/lib/libesp32/berry_matter/src/embedded/Matter_TCP_async.be @@ -0,0 +1,238 @@ +# +# Matter_TCP_async.be - implements a generic async non-blocking TCP connection +# +# Copyright (C) 2023 Stephan Hadinger & Theo Arends +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import matter + +#@ solidify:Matter_TCP_async,weak + +# Status: +# nil = uninitialized +# 0 = starting (tcp_connected == nil) - still on-going +# 1 = connected (tcp_connected == true) +# 2 = finished (tcp_connected == false and result in response) +# -1 = DNS failed (tcp_connected == false) +# -2 = refused (tcp_connecetd == false) +# -3 = timeout (tcp_connecetd == false) +# -4 = error communication error + +class Matter_TCP_async + var addr # (string) remote address + var port # (int) remote port + var timeout # (int) timeout in ms + var tcp # instance of tcpclientasync + var time_start # (int) timestamp when starting connection + var tcp_connected # (bool or nil) is tcp connected, true/false/nil (nil is in-progress) + var status # (int) status, see above + static var TIMEOUT = 1000 # default timeout: 1000ms + + var fast_loop # (opt) either nil or a closure + + ############################################################# + # constructor + # + # fastloop: (opt) if 'true' uses fastloop instead of every_50ms + def init(addr, port, timeout, fastloop) + if timeout == nil timeout = self.TIMEOUT end + if port == nil port = 80 end + self.addr = str(addr) + self.port = int(port) + self.timeout = timeout + self.tcp = tcpclientasync() + if fastloop + self.fast_loop = / -> self.loop() # create a closure to use with fastloop + end + end + + ############################################################# + # begin + # + # returns true if everything is ok, and connection started + # returns false if DNS failed + # returns nil if no network + def begin() + self.reset() + + if !tasmota.wifi()['up'] && !tasmota.eth()['up'] return nil end # no network + self.time_start = tasmota.millis() + self.status = 0 + + if (self.tcp.connect(self.addr, self.port)) + if self.fast_loop + tasmota.remove_fast_loop(self.fast_loop) + tasmota.add_fast_loop(self.fast_loop) + else + tasmota.add_driver(self) + end + return true + else + tasmota.log(format("BRY: failed to resolve [%s]:%i", self.addr, self.port), 3) + self.close() + self.status = -1 + self.tcp_connected = false + self.event_dnsfailed() + return false + end + end + + ############################################################# + # Set a new timeout, or `nil` for default (1s) + def set_timeout(timeout) + if timeout == nil timeout = self.TIMEOUT end + self.timeout = timeout + end + def get_timeout() return self.timeout end + + ############################################################# + # Reset the instance to send a open a new connection + # This allows to reuse the same object. + def reset() + self.tcp.close() + self.tcp_connected = nil + end + + ############################################################# + # send_http + def close() + self.tcp.close() + if self.fast_loop + tasmota.remove_fast_loop(self.fast_loop) + else + tasmota.remove_driver(self) + end + # if it was connected, send event + if self.tcp_connected == true + self.event_closed() + end + self.tcp_connected = false + end + + def every_50ms() + self.loop() + end + + ############################################################# + # Main loop, check evolution and trigger events + ############################################################# + def loop() + var prev_connected = self.tcp_connected + if self.status == nil self.close() return end # safeguard, this is invalid state + + self.tcp_connected = self.tcp.connected() + # if not yet connected, check if we finally got a response + if prev_connected == nil # not yet connected + if self.tcp_connected == true + # we finally got connection + self.status = 1 + self.event_established() + # and continue below + elif self.tcp_connected == false + # connection failed + self.status = -2 + self.event_refused() + self.close() + return + elif (tasmota.millis() - self.time_start) > self.timeout + # connection timeout + self.status = -3 + self.tcp_connected = false # force to false + self.event_timeout() + end + end + + if (tasmota.millis() - self.time_start) > self.timeout + self.close() + self.status = -3 + self.event_timeout() + return + end + + if self.tcp_connected == false + if prev_connected == true + self.event_closed() + end + self.close() # close implicitly removes from loop + return + end + + # reading has priority because we don't want to lose data + if self.tcp.available() + self.event_available() + end + + # can we send data + if self.tcp.listening() + self.event_listening() + end + end + + def write(content) + if self.tcp_connected + return self.tcp.write(content) + end + return 0 + end + + def read() + if self.tcp_connected + return self.tcp.read() + end + return nil + end + + def readbytes() + if self.tcp_connected + return self.tcp.readbytes() + end + return nil + end + + def available() + if self.tcp_connected + return self.tcp.available() + end + return 0 + end + + def listening() + if self.tcp_connected + return self.tcp.listening() + end + return false + end + + ############################################################# + # Events: method should be overriden + ############################################################# + # event_established: connection was established + # event_dnsfailed: dns resolution failed + # event_refused: connection was refused by peer + # event_timeout: connection timed out + # event_closed: connection was normally closed (after being established) + # event_available: incoming data is ready to be retrieved with `read()` or `readbytes()` + # event_listening: outgoing buffer is empty, ready to send data with `write()` + def event_established() end + def event_dnsfailed() end + def event_refused() end + def event_timeout() end + def event_closed() end + def event_available() end + def event_listening() end + +end +matter.TCP_async = Matter_TCP_async diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_TLV.be b/lib/libesp32/berry_matter/src/embedded/Matter_TLV.be index 24c4567e2e62..9c19e0b36712 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_TLV.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_TLV.be @@ -94,6 +94,9 @@ class Matter_TLV static class Matter_TLV_item # we keep a shortcut reference to the Matter_TLV class static var TLV = Matter_TLV + static var is_list = false + static var is_array = false + static var is_struct = false # parent tag to inherit vendor/profile/tag var parent var next_idx # next idx in buffer (when parsing) @@ -113,6 +116,32 @@ class Matter_TLV self.parent = parent end + ############################################################# + # reset - allows reuse of the object + def reset(parent) + var n = nil + self.parent = parent + self.next_idx = n + self.tag_vendor = n + self.tag_profile = n + self.tag_number = n + self.tag_sub = n + self.typ = n + self.val = n + end + + ############################################################# + # set value, equivalent to create_TLV() without allocation + # + def set(t, value) + self.reset() + if value != nil || t == 0x14 #-t == matter.TLV.NULL-# # put the actual number for performance + self.typ = t + self.val = value + return self + end + end + ############################################################# # neutral converter def to_TLV() @@ -135,35 +164,35 @@ class Matter_TLV # # We are trying to follow the official Matter way of printing TLV # Ex: '42U' or '1 = 42U' or '0xFFF1::0xDEED:0xAA55FEED = 42U' - def tostring() - import string + def tostring(no_tag) # var s = " 0 s += "= " end end - if size(s) > 0 s += "= " end - # print value - if type(self.val) == 'int' s += string.format("%i", self.val) + if type(self.val) == 'int' s += format("%i", self.val) if self.typ >= self.TLV.U1 && self.typ <= self.TLV.U8 s += "U" end elif type(self.val) == 'bool' s += self.val ? "true" : "false" elif self.val == nil s += "null" - elif type(self.val) == 'real' s += string.format("%g", self.val) - elif type(self.val) == 'string' s += string.format('"%s"', self.val) + elif type(self.val) == 'real' s += format("%g", self.val) + elif type(self.val) == 'string' s += format('"%s"', self.val) elif isinstance(self.val, int64) s += self.val.tostring() if self.typ >= self.TLV.U1 && self.typ <= self.TLV.U8 s += "U" end elif type(self.val) == 'instance' - s += string.format("%s", self.val.tohex()) + s += format("%s", self.val.tohex()) end except .. as e, m @@ -172,6 +201,30 @@ class Matter_TLV return s end + # simplified version of tostring() for simple values + def to_str_val() + # print value + if type(self.val) == 'int' + if self.typ >= self.TLV.U1 && self.typ <= self.TLV.U8 + return str(self.val) + "U" + else + return str(self.val) + end + elif type(self.val) == 'bool' return self.val ? "true" : "false" + elif self.val == nil return "null" + elif type(self.val) == 'real' return str(self.val) + elif type(self.val) == 'string' return self.val + elif isinstance(self.val, int64) + if self.typ >= self.TLV.U1 && self.typ <= self.TLV.U8 + return self.val.tostring() + "U" + else + return self.val.tostring() + end + elif type(self.val) == 'instance' + return self.tostring(true) + end + end + ############################################################# # parse a bytes() array from `idx` # args: @@ -557,7 +610,10 @@ class Matter_TLV # class Matter_TLV_struct var _ end static class Matter_TLV_list : Matter_TLV_item - static var is_struct = false + # inherited + static var is_list = true + # static var is_array = false + # static var is_struct = false ################################################################################# def init(parent) @@ -567,27 +623,27 @@ class Matter_TLV end ################################################################################# - def tostring() - return self.tostring_inner(false, "[[", "]]") + def tostring(no_tag) + return self.tostring_inner(false, "[[", "]]", no_tag) end - def tostring_inner(sorted, pre, post) - import string + def tostring_inner(sorted, pre, post, no_tag) var s = "" try - if self.tag_profile == -1 - s += "Matter::" - if self.tag_number != nil s += string.format("0x%08X ", self.tag_number) end - else - if self.tag_vendor != nil s += string.format("0x%04X::", self.tag_vendor) end - if self.tag_profile != nil s += string.format("0x%04X:", self.tag_profile) end - if self.tag_number != nil s += string.format("0x%08X ", self.tag_number) end - if self.tag_sub != nil s += string.format("%i ", self.tag_sub) end + if no_tag != true + if self.tag_profile == -1 + s += "Matter::" + if self.tag_number != nil s += format("0x%08X ", self.tag_number) end + else + if self.tag_vendor != nil s += format("0x%04X::", self.tag_vendor) end + if self.tag_profile != nil s += format("0x%04X:", self.tag_profile) end + if self.tag_number != nil s += format("0x%08X ", self.tag_number) end + if self.tag_sub != nil s += format("%i ", self.tag_sub) end + end + if size(s) > 0 s += "= " end end - if size(s) > 0 s += "= " end - s += pre # sort values @@ -606,6 +662,11 @@ class Matter_TLV return s end + # simplified version of tostring() for simple values + def to_str_val() + return self.tostring(true) + end + ################################################################################# def parse(b, idx) # iterate until end of struct @@ -770,6 +831,8 @@ class Matter_TLV # Matter_TLV_struct class ################################################################################# static class Matter_TLV_struct : Matter_TLV_list + static var is_list = false + # static var is_array = false static var is_struct = true def init(parent) @@ -779,8 +842,8 @@ class Matter_TLV end ############################################################# - def tostring() - return self.tostring_inner(true, "{", "}") + def tostring(no_tag) + return self.tostring_inner(true, "{", "}", no_tag) end end @@ -788,6 +851,10 @@ class Matter_TLV # Matter_TLV_array class ################################################################################# static class Matter_TLV_array : Matter_TLV_list + static var is_list = false + static var is_array = true + # static var is_struct = false + def init(parent) super(self).init(parent) self.typ = self.TLV.ARRAY @@ -795,8 +862,8 @@ class Matter_TLV end ############################################################# - def tostring() - return self.tostring_inner(false, "[", "]") + def tostring(no_tag) + return self.tostring_inner(false, "[", "]", no_tag) end ############################################################# @@ -921,6 +988,12 @@ test_TLV(bytes("0001"), "1") test_TLV(bytes("08"), "false") test_TLV(bytes("09"), "true") +var TLV = matter.TLV +assert(TLV.create_TLV(TLV.BOOL, 1).tlv2raw() == bytes("09")) +assert(TLV.create_TLV(TLV.BOOL, true).tlv2raw() == bytes("09")) +assert(TLV.create_TLV(TLV.BOOL, 0).tlv2raw() == bytes("08")) +assert(TLV.create_TLV(TLV.BOOL, false).tlv2raw() == bytes("08")) + test_TLV(bytes("00FF"), "-1") test_TLV(bytes("05FFFF"), "65535U") diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_UDPServer.be b/lib/libesp32/berry_matter/src/embedded/Matter_UDPServer.be index 3578b71550e2..62bc065c8116 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_UDPServer.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_UDPServer.be @@ -66,20 +66,25 @@ class Matter_UDPServer static var RETRIES = 5 # 6 transmissions max (5 retries) - 1 more than spec `MRP_MAX_TRANSMISSIONS` 4.11.8 p.146 static var MAX_PACKETS_READ = 4 # read at most 4 packets per tick var addr, port # local addr and port + var device var listening # true if active var udp_socket var dispatch_cb # callback to call when a message is received var packets_sent # list map of packets sent to be acknowledged + var loop_cb # closure to pass to fast_loop + var packet # reuse the packer `bytes()` object at each iteration ############################################################# # Init UDP Server listening to `addr` and `port` (opt). # # By default, the server listens to `""` (all addresses) and port `5540` - def init(addr, port) + def init(device, addr, port) + self.device = device self.addr = addr ? addr : "" self.port = port ? port : 5540 self.listening = false self.packets_sent = [] + self.loop_cb = def () self.loop() end end ############################################################# @@ -95,7 +100,8 @@ class Matter_UDPServer if !ok raise "network_error", "could not open UDP server" end self.listening = true self.dispatch_cb = cb - tasmota.add_driver(self) + # tasmota.add_driver(self) + tasmota.add_fast_loop(self.loop_cb) end end @@ -105,7 +111,8 @@ class Matter_UDPServer if self.listening self.udp_socket.stop() self.listening = false - tasmota.remove_driver(self) + # tasmota.remove_driver(self) + tasmota.remove_fast_loop(self.loop_cb) end end @@ -115,20 +122,27 @@ class Matter_UDPServer # Read at most `MAX_PACKETS_READ (4) packets at each tick to # avoid any starvation. # Then resend queued outgoing packets. - def every_50ms() - import string + def loop() + # import debug + var profiler = matter.profiler var packet_read = 0 if self.udp_socket == nil return end - var packet = self.udp_socket.read() + var packet = self.udp_socket.read(self.packet) while packet != nil - # self.packet = packet + profiler.start() + self.packet = packet # save packet for next iteration packet_read += 1 var from_addr = self.udp_socket.remote_ip var from_port = self.udp_socket.remote_port - tasmota.log(string.format("MTR: UDP received from [%s]:%i", from_addr, from_port), 3) + if tasmota.loglevel(4) + tasmota.log(format("MTR: UDP received from [%s]:%i", from_addr, from_port), 4) + end + # tasmota.log("MTR: Perf/UDP_received = " + str(debug.counters()), 4) if self.dispatch_cb + profiler.log("udp_loop_dispatch") self.dispatch_cb(packet, from_addr, from_port) end + profiler.dump(2) # are we reading new packets? if packet_read < self.MAX_PACKETS_READ packet = self.udp_socket.read() @@ -139,17 +153,24 @@ class Matter_UDPServer self._resend_packets() # resend any packet end + def every_50ms() + self.loop() + end ############################################################# # Send packet now. # # Returns `true` if packet was successfully sent. def send(packet) - import string var ok = self.udp_socket.send(packet.addr ? packet.addr : self.udp_socket.remote_ip, packet.port ? packet.port : self.udp_socket.remote_port, packet.raw) + if ok - tasmota.log(string.format("MTR: sending packet to '[%s]:%i'", packet.addr, packet.port), 4) + if tasmota.loglevel(4) + tasmota.log(format("MTR: sending packet to '[%s]:%i'", packet.addr, packet.port), 4) + end else - tasmota.log(string.format("MTR: error sending packet to '[%s]:%i'", packet.addr, packet.port), 2) + if tasmota.loglevel(3) + tasmota.log(format("MTR: error sending packet to '[%s]:%i'", packet.addr, packet.port), 3) + end end return ok end @@ -169,15 +190,14 @@ class Matter_UDPServer var packet = self.packets_sent[idx] if tasmota.time_reached(packet.next_try) if packet.retries <= self.RETRIES - tasmota.log("MTR: . Resending packet id=" + str(packet.msg_id), 3) + tasmota.log("MTR: . Resending packet id=" + str(packet.msg_id), 4) self.send(packet) packet.next_try = tasmota.millis() + self._backoff_time(packet.retries) packet.retries += 1 idx += 1 else - import string self.packets_sent.remove(idx) - tasmota.log(string.format("MTR: . (%6i) Unacked packet '[%s]:%i' msg_id=%i", packet.session_id, packet.addr, packet.port, packet.msg_id), 2) + tasmota.log(format("MTR: . (%6i) Unacked packet '[%s]:%i' msg_id=%i", packet.session_id, packet.addr, packet.port, packet.msg_id), 3) end else idx += 1 @@ -191,13 +211,15 @@ class Matter_UDPServer var id = msg.ack_message_counter var exch = msg.exchange_id if id == nil return end - tasmota.log("MTR: receveived ACK id="+str(id), 3) + # tasmota.log("MTR: receveived ACK id="+str(id), 4) var idx = 0 while idx < size(self.packets_sent) var packet = self.packets_sent[idx] if packet.msg_id == id && packet.exchange_id == exch self.packets_sent.remove(idx) - tasmota.log("MTR: . Removed packet from sending list id=" + str(id), 3) + if tasmota.loglevel(4) + tasmota.log("MTR: . Removed packet from sending list id=" + str(id), 4) + end else idx += 1 end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_UI.be b/lib/libesp32/berry_matter/src/embedded/Matter_UI.be index 019af83d978f..278d8c250f88 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_UI.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_UI.be @@ -32,12 +32,34 @@ import matter # WebUI for the partition manager ################################################################################# class Matter_UI - static var _ROOT_TYPES = "root" static var _CLASSES_TYPES = "|relay|light0|light1|light2|light3|shutter|shutter+tilt" - "|temperature|pressure|illuminance|humidity" - "|-http|http_relay" + "|temperature|pressure|illuminance|humidity|occupancy|onoff|contact" + "|-virtual|v_relay|v_light0|v_light1|v_light2|v_light3" + "|v_temp|v_pressure|v_illuminance|v_humidity|v_contact" + # static var _CLASSES_HTTP = "-http" + static var _CLASSES_TYPES2= "|http_relay|http_light0|http_light1|http_light2|http_light3" + "|http_temperature|http_pressure|http_illuminance|http_humidity" + "|http_occupancy|http_contact" var device + # #################################################################################################### + # Static function to compare two maps (shallow compare) + # return true if equal + static def equal_map(a, b) + # all items of a are in b + for k: a.keys() + if !b.contains(k) return false end + if b[k] != a[k] return false end + end + for k: b.keys() + if !a.contains(k) return false end + if b[k] != a[k] return false end + end + return true + end + + # #################################################################################################### + # Constructor def init(device) self.device = device tasmota.add_driver(self) @@ -55,29 +77,42 @@ class Matter_UI webserver.content_send(" Configure Matter

") end + #- ---------------------------------------------------------------------- -# + #- Is Matter enabled? + #- ---------------------------------------------------------------------- -# + def matter_enabled() + return bool(tasmota.get_option(matter.MATTER_OPTION)) + end + #- ---------------------------------------------------------------------- -# #- Show commissioning information and QR Code # # Returns true if Matter is enabled #- ---------------------------------------------------------------------- -# - def show_enable(p) + def show_enable() import webserver - import string - var matter_enabled = tasmota.get_option(matter.MATTER_OPTION) - - webserver.content_send(string.format("
 Matter %s 

", - matter_enabled ? "Enabled" : "Disabled")) - - webserver.content_send("

Check the Matter documentation.

") - - webserver.content_send("
") - webserver.content_send(string.format("

") - - webserver.content_send("

") + var matter_enabled = self.matter_enabled + + webserver.content_send("
 Matter  " + "

Check the Matter documentation.

" + "
") + + # checkbox for Matter enable + var matter_enabled_checked = self.matter_enabled() ? 'checked' : '' + webserver.content_send(f"

") + webserver.content_send("

") + + if self.matter_enabled() + # checkbox for Matter commissioning + var commissioning_open_checked = self.device.commissioning_open != nil ? "checked" : "" + webserver.content_send(f"

") + webserver.content_send("

") + var disable_bridge_mode_checked = self.device.disable_bridge_mode ? " checked" : "" + webserver.content_send(f"

Force Static endpoints (non-bridge)

") + end - return matter_enabled + webserver.content_send("

" + "

") end #- ---------------------------------------------------------------------- -# @@ -133,24 +168,21 @@ class Matter_UI #- ---------------------------------------------------------------------- -# def show_commissioning_info() import webserver - import string var seconds_left = (self.device.commissioning_open - tasmota.millis()) / 1000 if seconds_left < 0 seconds_left = 0 end var min_left = (seconds_left + 30) / 60 - webserver.content_send(string.format("
 Commissioning open for %i min 

", min_left)) + webserver.content_send(f"
 Commissioning open for {min_left:i} min 

") var pairing_code = self.device.compute_manual_pairing_code() - webserver.content_send(string.format("

Manual pairing code:
%s-%s-%s


", pairing_code[0..3], pairing_code[4..6], pairing_code[7..])) + webserver.content_send(f"

Manual pairing code:
{pairing_code[0..3]}-{pairing_code[4..6]}-{pairing_code[7..]}


") - webserver.content_send(string.format("
")) + webserver.content_send("
") var qr_text = self.device.compute_qrcode_content() self.show_qrcode(qr_text) - webserver.content_send(string.format("

%s

", qr_text)) - webserver.content_send(string.format("
")) - - webserver.content_send("

") + webserver.content_send(f"

{qr_text}

") + webserver.content_send("

") end @@ -159,17 +191,18 @@ class Matter_UI #- ---------------------------------------------------------------------- -# def show_passcode_form() import webserver - import string - webserver.content_send("
 Matter Passcode 

") - webserver.content_send("
") - webserver.content_send("

Passcode:

") - webserver.content_send(string.format("", self.device.root_passcode)) + webserver.content_send("
 Matter Advanced Configuration 

") + # + webserver.content_send("" + "

Passcode:

") + webserver.content_send(f"") webserver.content_send("

Distinguish id:

") - webserver.content_send(string.format("", self.device.root_discriminator)) - webserver.content_send(string.format("

IPv4 only

", self.device.ipv4only ? " checked" : "")) - webserver.content_send("

") - webserver.content_send("

") + webserver.content_send(f"") + var ipv4only_checked = self.device.ipv4only ? " checked" : "" + webserver.content_send(f"

IPv4 only

") + webserver.content_send("

" + "

") end @@ -178,10 +211,9 @@ class Matter_UI #- ---------------------------------------------------------------------- -# def show_fabric_info() import webserver - import string - webserver.content_send("
 Fabrics 

") - webserver.content_send("

Associated fabrics:

") + webserver.content_send("
 Fabrics 

" + "

Associated fabrics:

") if size(self.device.sessions.sessions) == 0 webserver.content_send("

None

") @@ -195,15 +227,15 @@ class Matter_UI if !label label = "" end label = webserver.html_escape(label) # protect against HTML injection - webserver.content_send(string.format("
 #%i %s 

", f.get_fabric_index(), label)) + webserver.content_send(f"
 #{f.get_fabric_index():i} {label} ({f.get_admin_vendor_name()}) 

") var fabric_rev = f.get_fabric_id().copy().reverse() var deviceid_rev = f.get_device_id().copy().reverse() - webserver.content_send(string.format("Fabric: %s
", fabric_rev.tohex())) - webserver.content_send(string.format("Device: %s
 ", deviceid_rev.tohex())) + webserver.content_send(f"Fabric: {fabric_rev.tohex()}
") + webserver.content_send(f"Device: {deviceid_rev.tohex()}
 ") webserver.content_send("
") - webserver.content_send(string.format("", f.get_fabric_index())) + webserver.content_send(f"") webserver.content_send("

") webserver.content_send("

") @@ -214,128 +246,489 @@ class Matter_UI end - #- ---------------------------------------------------------------------- -# + #----------------------------------------------------------------------- -# + #- Show Javasrcript hints for classes arguments + #----------------------------------------------------------------------- -# + # + # Exmaple: + # var hm = {"relay":0,"shutter+tilt":0,"light2":1,"illuminance":2,"onoff":1,"pressure":2,"light1":1,"humidity":2,"shutter":0,"occupancy":3,"temperature":2,"light3":1,"light0":1}; + # var hl = ["Enter Relay number","Not used","Enter Filter pattern","Enter Switch number"]; + def show_plugins_hints_js(*class_list) + import webserver + import json + import string + + var class_types = [] + for cl: class_list + class_types += string.split(cl, '|') + end + + var hm = {} + var hl = [] + + for typ: class_types + if typ == '' continue end + var cl = self.device.plugins_classes.find(typ) + if cl != nil + var hint = cl.ARG_HINT + if hint != nil + var idx = hl.find(hint) + if idx == nil # not already in list, add it + idx = size(hl) # save index for assignment + hl.push(hint) + end + hm[typ] = idx + end + end + end + + webserver.content_send(f"" + "") + + webserver.content_send(matter._ADD_ENDPOINT_JS) + + end + + #----------------------------------------------------------------------- -# #- Show plugins configuration - #- ---------------------------------------------------------------------- -# + #----------------------------------------------------------------------- -# def show_plugins_configuration() import webserver import string + import introspect webserver.content_send("
 Current Configuration 

") - webserver.content_send("
") - webserver.content_send("

") - - webserver.content_send("
") - webserver.content_send("") - webserver.content_send("") + webserver.content_send("" + "

Local sensors and devices

" + "
Ep.TypeParam
") + webserver.content_send("" + "" + "" + "" + "" + "" + "") # display one line per plug-in + self.device.plugins_config.remove("0") # remove any leftover from ancient configuration var endpoints = self.device.k2l_num(self.device.plugins_config) var i = 0 + var found = false - # special case for root node - if endpoints[0] == 0 - var ep = endpoints[i] - var conf = self.device.plugins_config[str(ep)] - var typ = conf.find('type') - - webserver.content_send(string.format("", i)) - webserver.content_send(string.format("")) - webserver.content_send("") - - i += 1 - end - while i < size(endpoints) var ep = endpoints[i] - var conf = self.device.plugins_config[str(ep)] + var conf = self.device.plugins_config.find(str(ep)) var typ = conf.find('type') if !typ i += 1 continue end + # skip any remote class + if string.find(typ, "http_") == 0 i += 1 continue end + var cl = self.device.plugins_classes.find(typ) var arg = "" if cl != nil arg = cl.ui_conf_to_string(cl, conf) end - # var arg_name = self.device.get_plugin_class_arg(typ) - # var arg = arg_name ? str(conf.find(arg_name, '')) : '' - - webserver.content_send(string.format("", i, ep)) - webserver.content_send(string.format("")) - webserver.content_send(string.format("", - i, webserver.html_escape(arg))) - + found = true + webserver.content_send(f"") + webserver.content_send(format("", + ep, webserver.html_escape(conf.find('name', '')))) + webserver.content_send(f"") + webserver.content_send(format("", + ep, webserver.html_escape(arg), cl ? webserver.html_escape(cl.ARG_HINT) : '')) + webserver.content_send(f"") i += 1 end + webserver.content_send("
#NameTypeParameter
 
{ep:i}{self.plugin_name(conf.find('type', ''))}
") - # add an empty line for adding a configuration - webserver.content_send(string.format("", i)) - webserver.content_send(string.format("")) - webserver.content_send(string.format("", i)) + # if array is empty, still display + if !found + webserver.content_send("

<none>

") + end + webserver.content_send("

") + + # iterate on each remote device + var remotes = [] + for conf: self.device.plugins_config + var url = conf.find("url") + if url != nil + remotes.push(url) + end + end + self.device.sort_distinct(remotes) + # tasmota.log("MTR: remotes: "+str(remotes), 4) + + for remote: remotes + + var remote_html = webserver.html_escape(remote) + var host_device_name = webserver.html_escape( self.device.get_plugin_remote_info(remote).find('name', remote) ) + webserver.content_send(f"🔗 {host_device_name}") + webserver.content_send("") + webserver.content_send("" + "" + "" + "" + "") + + found = false + i = 0 + while i < size(endpoints) + var ep = endpoints[i] + var conf = self.device.plugins_config.find(str(ep)) + var typ = conf.find('type') + if !typ i += 1 continue end + + # skip any non-remote class + if string.find(typ, "http_") != 0 i += 1 continue end + # check if it's the right remote + if conf.find("url") != remote i += 1 continue end + + var cl = self.device.plugins_classes.find(typ) + var arg = "" + if cl != nil + arg = cl.ui_conf_to_string(cl, conf) + end + + found = true + webserver.content_send(f"") + webserver.content_send(format("", + ep, webserver.html_escape(conf.find('name', '')))) + + webserver.content_send(format("", self.plugin_name(conf.find('type', '')))) + webserver.content_send(format("", + ep, webserver.html_escape(arg))) + webserver.content_send(f"") + i += 1 + end + webserver.content_send("
" + "" + "
{ep:i}%s

") + + end # for remote: self.device.get_remotes_list() + - webserver.content_send("

") - webserver.content_send("") - webserver.content_send("

") + if !found + webserver.content_send("

<none>

") + end + + webserver.content_send("

") + + + # Add new endpoint section + self.show_plugins_hints_js(self._CLASSES_TYPES) + + webserver.content_send("

 Add to Configuration 

") + webserver.content_send("

Add local sensor or device

" + "
" + "") + webserver.content_send("" + "" + "" + "" + "") + + webserver.content_send("" + "" + "") + webserver.content_send("" + "
NameTypeParameter
") + + webserver.content_send("
") + webserver.content_send("
") + + # Add remote endpoint + webserver.content_send("

Add Remote Tasmota or OpenBK

" + "
" + "") + webserver.content_send("" + "
http:///
") + + webserver.content_send("
") + webserver.content_send("

") + + # button "Reset and Auto-discover" + webserver.content_send("
" + "

") + + webserver.content_send("

") end + #- ---------------------------------------------------------------------- -# + #- Show pretty name for plugin class + #- ---------------------------------------------------------------------- -# + def plugin_name(cur, *class_list) + if cur == '' return '' end + return self.device.get_plugin_class_displayname(cur) + end + #- ---------------------------------------------------------------------- -# #- Show all possible classes for plugin #- ---------------------------------------------------------------------- -# - def plugin_option(cur, class_list) + def plugin_option(cur, *class_list) import webserver import string - var class_types = class_list ? string.split(class_list, '|') : [] + var class_types = [] + for cl: class_list + class_types += string.split(cl, '|') + end var i = 0 while i < size(class_types) var typ = class_types[i] if typ == '' webserver.content_send("") - elif typ == '-http' - webserver.content_send("") + elif typ == '-virtual' + webserver.content_send("") else var nam = self.device.get_plugin_class_displayname(typ) - webserver.content_send(string.format("", typ, (typ == cur) ? " selected" : "", nam)) + webserver.content_send(format("", typ, (typ == cur) ? " selected" : "", nam)) end i += 1 end end + + ####################################################################### + # Display the advanced configuration page + ####################################################################### + def page_part_mgr_adv() + import webserver + + if !webserver.check_privileged_access() return nil end + + webserver.content_start("Matter Advanced Configuration") #- title of the web page -# + webserver.content_send_style() #- send standard Tasmota styles -# + + if self.matter_enabled() + self.show_passcode_form() + self.show_fabric_info() + end + webserver.content_button(webserver.BUTTON_CONFIGURATION) + webserver.content_stop() #- end of web page -# + end + + ####################################################################### # Display the complete page ####################################################################### def page_part_mgr() import webserver - import string if !webserver.check_privileged_access() return nil end webserver.content_start("Matter") #- title of the web page -# webserver.content_send_style() #- send standard Tasmota styles -# - if self.show_enable() - self.show_passcode_form() + self.show_enable() + if self.matter_enabled() self.show_plugins_configuration() - self.show_fabric_info() end + + webserver.content_send("
") + webserver.content_send("

") + webserver.content_button(webserver.BUTTON_CONFIGURATION) webserver.content_stop() #- end of web page -# end + #---------------------------------------------------------------------- -# + # Generate configuration map from Status 8 and Status 11 + # + # Returns a list of maps: [ {"type":"temperature", "filter":"ESP32#Temperature"} ] + #---------------------------------------------------------------------- -# + def generate_config_from_status(status8, status11) + var config_list = [] + + # count `Power` and `Power` + var power_cnt = 0 + if status11.contains("POWER") + power_cnt = 1 + else + var idx = 1 + while true + if status11.contains("POWER" + str(idx)) + power_cnt = idx + idx += 1 + else + break + end + end + end + # Now `power_cnt` contains the number of Relays including light + + # detect lights + var light1, light2, light3 # contains a relay number of nil + if status11.contains("HSBColor") + light3 = power_cnt + power_cnt -= 1 + elif status11.contains("CT") + light2 = power_cnt + power_cnt -= 1 + elif status11.contains("Dimmer") + light1 = power_cnt + power_cnt -= 1 + end + + # rest is relays + for i: 1..power_cnt + config_list.push({'type': 'light0', 'relay': i}) + end + + # show lights + if light1 != nil + config_list.push({'type': 'light1', 'relay': light1}) + end + if light2 != nil + config_list.push({'type': 'light2', 'relay': light2}) + end + if light3 != nil + config_list.push({'type': 'light3', 'relay': light3}) + end + + + # detect sensors + config_list += self.device.autoconf_sensors_list(status8) + + return config_list + end + + #- ---------------------------------------------------------------------- -# + #- Probe remote device + #- ---------------------------------------------------------------------- -# + def show_remote_autoconf(url) + import webserver + import json + + if url == '' return end + var timeout = matter.Plugin_Bridge_HTTP.PROBE_TIMEOUT + var http_remote = matter.HTTP_remote(nil, url, timeout) + # Status 8 + var status8 = http_remote.call_sync('Status 8', timeout) + if status8 != nil status8 = json.load(status8) end + if status8 != nil status8 = status8.find('StatusSNS') end + # Status 11 + var status11 + if status8 != nil + status11 = http_remote.call_sync('Status 11', timeout) + if status11 != nil status11 = json.load(status11) end + if status11 != nil status11 = status11.find('StatusSTS') end + end + + if status8 != nil && status11 != nil + tasmota.log(format("MTR: probed '%s' status8=%s satus11=%s", url, str(status8), str(status11)), 3) + + var config_list = self.generate_config_from_status(status8, status11) + + self.show_plugins_hints_js(self._CLASSES_TYPES2) + + webserver.content_send("
 Matter Remote Device 

" + "

Add Remote sensor or device

") + + var remote_html = webserver.html_escape(url) + webserver.content_send(f"

🔗 {remote_html}

") + + # Add new endpoint section + webserver.content_send("
" + "" + "" + "" + "" + "" + "") + + webserver.content_send(format("", webserver.html_escape(url))) + + var i = 0 + while i < size(config_list) + var config = config_list[i] + var typ = config.find('type', '') + if typ != '' typ = "http_" + typ end + + var cl = self.device.plugins_classes.find(typ) + var arg = "" + if cl != nil + arg = cl.ui_conf_to_string(cl, config) + end + + webserver.content_send(format("", i)) + webserver.content_send(format("" + "") + i += 1 + end + # empty line for new endpoint + webserver.content_send(format("", i)) + webserver.content_send(format("" + "") + + # end of table + webserver.content_send("
NameTypeParameter
") + webserver.content_send(format("", + i, i, webserver.html_escape(arg), cl ? webserver.html_escape(cl.ARG_HINT) : '')) + webserver.content_send("
") + webserver.content_send(format("", + i, i, '')) + webserver.content_send("
") + + webserver.content_send("
") + webserver.content_send("
") + + webserver.content_send("
") + + else + webserver.content_send(format("

Unable to connect to '%s'

", webserver.html_escape(url))) + end + + + end + ####################################################################### - # Web Controller, called by POST to `/part_wiz` + # Display the page for adding a new endpoint + ####################################################################### + def page_part_mgr_add() + import webserver + + if !webserver.check_privileged_access() return nil end + + webserver.content_start("Matter Create new endpoint") #- title of the web page -# + webserver.content_send_style() #- send standard Tasmota styles -# + + var url = webserver.arg("url") + if self.matter_enabled() + self.show_remote_autoconf(url) + end + webserver.content_button(webserver.BUTTON_CONFIGURATION) + webserver.content_stop() #- end of web page -# + end + + + ####################################################################### + # Web Controller, called by POST to `/matterc` ####################################################################### def page_part_ctl() import webserver @@ -349,11 +742,16 @@ class Matter_UI try + # debug information about parameters + # for i:0..webserver.arg_size()-1 + # tasmota.log(format("MTR: Arg%i '%s' = '%s'", i, webserver.arg_name(i), webserver.arg(i))) + # end + #---------------------------------------------------------------------# # Change Passcode and/or Passcode #---------------------------------------------------------------------# if webserver.has_arg("passcode") || webserver.has_arg("discriminator") - tasmota.log(string.format("MTR: /matterc received '%s' command", 'passcode'), 3) + tasmota.log(format("MTR: /matterc received '%s' command", 'passcode'), 3) if webserver.has_arg("passcode") self.device.root_passcode = int(webserver.arg("passcode")) end @@ -366,29 +764,43 @@ class Matter_UI #- and force restart -# webserver.redirect("/?rst=") - #---------------------------------------------------------------------# - # Enable Matter - #---------------------------------------------------------------------# - elif webserver.has_arg("enable") - tasmota.log(string.format("MTR: /matterc received '%s' command", 'enable'), 3) - tasmota.cmd("SetOption" + str(matter.MATTER_OPTION) + " 1") - #- and force restart -# - webserver.redirect("/?rst=") + elif webserver.has_arg("save") + var matter_enabled_requested = webserver.has_arg("menable") + var matter_commissioning_requested = webserver.has_arg("comm") + var matter_disable_bridge_mode_requested = (webserver.arg("nobridge") == 'on') + if self.device.disable_bridge_mode != matter_disable_bridge_mode_requested + self.device.disable_bridge_mode = matter_disable_bridge_mode_requested + self.device.save_param() + end - #---------------------------------------------------------------------# - # Disable Matter - #---------------------------------------------------------------------# - elif webserver.has_arg("disable") - tasmota.log(string.format("MTR: /matterc received '%s' command", 'disable'), 3) - tasmota.cmd("SetOption" + str(matter.MATTER_OPTION) + " 0") - #- and force restart -# - webserver.redirect("/?rst=") + if matter_enabled_requested != self.matter_enabled() + if matter_enabled_requested + tasmota.log(format("MTR: /matterc received '%s' command", 'enable'), 3) + tasmota.cmd("SetOption" + str(matter.MATTER_OPTION) + " 1") + else + tasmota.log(format("MTR: /matterc received '%s' command", 'disable'), 3) + tasmota.cmd("SetOption" + str(matter.MATTER_OPTION) + " 0") + end + #- and force restart -# + webserver.redirect("/?rst=") + elif matter_commissioning_requested != (self.device.commissioning_open != nil) + if matter_commissioning_requested + self.device.start_root_basic_commissioning() + else + self.device.stop_basic_commissioning() + end + + #- and force restart -# + webserver.redirect("/") + else + webserver.redirect("/") + end #---------------------------------------------------------------------# # Delete Fabric #---------------------------------------------------------------------# elif webserver.has_arg("del_fabric") - tasmota.log(string.format("MTR: /matterc received '%s' command", 'del_fabric'), 3) + tasmota.log(format("MTR: /matterc received '%s' command", 'del_fabric'), 3) var del_fabric = int(webserver.arg("del_fabric")) var idx = 0 var fabrics = self.device.sessions.fabrics @@ -407,7 +819,7 @@ class Matter_UI # Reset to default auto-configuration #---------------------------------------------------------------------# elif webserver.has_arg("auto") - tasmota.log(string.format("MTR: /matterc received '%s' command", 'auto'), 3) + tasmota.log(format("MTR: /matterc received '%s' command", 'auto'), 3) self.device.plugins_persist = false self.device.save_param() #- and force restart -# @@ -416,113 +828,255 @@ class Matter_UI #---------------------------------------------------------------------# # Apply new configuration template #---------------------------------------------------------------------# - elif webserver.has_arg("config") - var config = {} - - tasmota.log(string.format("MTR: /matterc received '%s' command", 'config'), 3) - # iterate by id - var idx = 0 - var idx_str = string.format("%03i", idx) - while webserver.has_arg('ep'+idx_str) - - var ep = webserver.arg('ep'+idx_str) - var ep_int = int(ep) - var typ = webserver.arg('pi'+idx_str) - var arg = webserver.arg('arg'+idx_str) - tasmota.log(string.format("MTR: ep=%i type=%s arg=%s", ep, typ, arg), 3) - - if ep != '' && typ != '' - - # check if type exists - var typ_class = self.device.plugins_classes.find(typ) - if typ_class != nil - var elt = {'type':typ} - typ_class.ui_string_to_conf(typ_class, elt, arg) - # var arg_name = typ_class.ARG - # var arg_type = typ_class.ARG_TYPE - # if arg && arg_name - # elt[arg_name] = arg_type(arg) - # end - config[ep] = elt - - else - tasmota.log(string.format("MTR: unknown type = %s", typ), 2) + elif webserver.has_arg("config") + tasmota.log(format("MTR: /matterc received '%s' command", 'config'), 3) + var needs_saving = false + # iterate by endpoint number + for i:0..webserver.arg_size()-1 + var arg_name = webserver.arg_name(i) + if string.find(arg_name, "arg") == 0 # 'arg' with i being the endpoint + var arg_ep = int(arg_name[3..]) # target endpoint as int + var arg = webserver.arg(i) # text value + + var conf_ep = self.device.plugins_config.find(str(arg_ep)) # find the corresponding configuration map + + if conf_ep != nil # found + var typ_class = self.device.plugins_classes.find(conf_ep.find('type', '')) + if typ_class != nil + tasmota.log(format("MTR: ep=%i arg=%s", arg_ep, arg), 3) + # compute the actual value + var prev_arg = typ_class.ui_conf_to_string(typ_class, conf_ep) + var changed = (prev_arg != arg) + tasmota.log(format("MTR: ep=%i prev_arg='%s' arg='%s' %s", arg_ep, prev_arg, arg, prev_arg != arg ? "changed" : ""), 3) + + if changed + needs_saving = true + typ_class.ui_string_to_conf(typ_class, conf_ep, arg) + var pl = self.device.find_plugin_by_endpoint(arg_ep) + if pl + tasmota.log(format("MTR: apply conf '%s' (%i) to %s", conf_ep, arg_ep, pl), 3) + pl.parse_configuration(conf_ep) + end + end + + end + else + tasmota.log(format("MTR: ep=%i not found", arg_ep), 3) + end + elif string.find(arg_name, "nam") == 0 # 'nam' with i being the endpoint + var nam_ep = int(arg_name[3..]) # target endpoint as int + var nam = webserver.arg(i) # text value + + var conf_ep = self.device.plugins_config.find(str(nam_ep)) # find the corresponding configuration map + + if conf_ep != nil # found + var prev_name = conf_ep.find("name", "") + var changed = (prev_name != nam) + if changed + needs_saving = true + var pl = self.device.find_plugin_by_endpoint(nam_ep) + if pl + # apply or remove + pl.set_name(nam) + if nam + conf_ep['name'] = nam + else + conf_ep.remove('name') + end + tasmota.log(format("MTR: apply name '%s' (%i) to %s", conf_ep, nam_ep, pl), 3) + pl.parse_configuration(conf_ep) + end + end + end end + end + + tasmota.log(format("MTR: config = %s", str(self.device.plugins_config)), 3) + if error + tasmota.log(format("MTR: config error = %s", error), 3) else - tasmota.log("MTR: skipping parameter", 2) + if needs_saving || !self.device.plugins_persist + self.device.plugins_persist = true + self.device.save_param() + end + #- and reload -# + webserver.redirect("/matterc?") end + #---------------------------------------------------------------------# + # Add new endpoint for local sensor or device + #---------------------------------------------------------------------# + elif webserver.has_arg("addep") + var typ = webserver.arg('pi') + var arg = webserver.arg('arg') + var nam = webserver.arg('nam') + tasmota.log(format("MTR: add endpoint typ='%s' arg='%s'", typ, arg), 3) + + # check if type exists + var typ_class = self.device.plugins_classes.find(typ) + if typ_class != nil + var config = {} + if nam config['name'] = nam end + typ_class.ui_string_to_conf(typ_class, config, arg) + self.device.bridge_add_endpoint(typ, config) + end + #- and reload -# + webserver.redirect("/matterc?") - idx += 1 - idx_str = string.format("%03i", idx) - end - - tasmota.log(string.format("MTR: config = %s", str(config)), 3) + #---------------------------------------------------------------------# + # Add new endpoint for remote sensor or device + #---------------------------------------------------------------------# + elif webserver.has_arg("addrem") + var url = webserver.arg('url') + if url == nil || url == '' raise "value_error", "url shouldn't be null" end - # sanity check - if !config.contains("0") error = "Missing endpoint 0" end + # iterate by id + var idx = 0 + var idx_str = str(idx) + while webserver.has_arg('pi'+idx_str) + var typ = webserver.arg('pi'+idx_str) + var arg = webserver.arg('arg'+idx_str) + var nam = webserver.arg('nam'+idx_str) + + if typ != '' + # check if type exists + var typ_class = self.device.plugins_classes.find(typ) + if typ_class != nil + var config = {'url': url, 'type': typ} + if nam + config['name'] = nam + end + typ_class.ui_string_to_conf(typ_class, config, arg) + # check if configuration is already present + var duplicate = false + for c: self.device.plugins_config # iterate on values, not on keys() + # tasmota.log(format("MTR: map_compare '%s' ?= '%s' -> %s", str(c), str(config), str(self.equal_map(c,config))), 3) + if self.equal_map(c,config) duplicate = true break end + end + # not a duplicate, add it + if !duplicate + tasmota.log(format("MTR: remote add url='%s' type='%s' arg='%s'", url, typ, arg), 3) + self.device.bridge_add_endpoint(typ, config) + end + end + end + idx += 1 + idx_str = str(idx) + end + #- and go back to Matter configuration -# + webserver.redirect("/matterc?") - if error - tasmota.log(string.format("MTR: config error = %s", error), 3) else - self.device.plugins_config = config - self.device.plugins_persist = true - self.device.save_param() - #- and force restart -# - webserver.redirect("/?rst=") - end - end + #---------------------------------------------------------------------# + # Check if an endpoint needs to be deleted + #---------------------------------------------------------------------# + var ep_deleted + for i:0..webserver.arg_size()-1 + var arg_name = webserver.arg_name(i) + if string.find(arg_name, "del") == 0 + ep_deleted = int(arg_name[3..]) + break + end + end + # check if we found an endpoint to be deleted + if ep_deleted != nil + self.device.bridge_remove_endpoint(ep_deleted) + webserver.redirect("/matterc?") + end - if error - webserver.content_start("Parameter error") #- title of the web page -# - webserver.content_send_style() #- send standard Tasmota styles -# - webserver.content_send(string.format("

Error:%s

", webserver.html_escape(error))) - webserver.content_button(webserver.BUTTON_CONFIGURATION) #- button back to configuration page -# - webserver.content_stop() #- end of web page -# - end + end + + if error + webserver.content_start("Parameter error") #- title of the web page -# + webserver.content_send_style() #- send standard Tasmota styles -# + webserver.content_send(format("

Error:%s

", webserver.html_escape(error))) + webserver.content_button(webserver.BUTTON_CONFIGURATION) #- button back to configuration page -# + webserver.content_stop() #- end of web page -# + end except .. as e, m - tasmota.log(string.format("BRY: Exception> '%s' - %s", e, m), 2) + tasmota.log(format("BRY: Exception> '%s' - %s", e, m), 2) #- display error page -# webserver.content_start("Parameter error") #- title of the web page -# webserver.content_send_style() #- send standard Tasmota styles -# - webserver.content_send(string.format("

Exception:
'%s'
%s

", e, m)) + webserver.content_send(format("

Exception:
'%s'
%s

", e, m)) webserver.content_button(webserver.BUTTON_CONFIGURATION) #- button back to configuration page -# webserver.content_stop() #- end of web page -# end end - #- display sensor value in the web UI -# - def web_sensor() + ####################################################################### + # Show bridge status + ####################################################################### + def show_bridge_status() import webserver - import string + var bridge_plugin_by_host + + var idx = 0 + while idx < size(self.device.plugins) + var plg = self.device.plugins[idx] - var matter_enabled = tasmota.get_option(matter.MATTER_OPTION) + if isinstance(plg, matter.Plugin_Bridge_HTTP) + if bridge_plugin_by_host == nil bridge_plugin_by_host = {} end + var host = plg.http_remote.addr - if matter_enabled - if self.device.is_root_commissioning_open() - self.show_commissioning_info() + if !bridge_plugin_by_host.contains(host) bridge_plugin_by_host[host] = [] end + bridge_plugin_by_host[host].push(plg) + + end + idx += 1 + end + + if bridge_plugin_by_host == nil return end # no remote device, abort + + # set specific styles + webserver.content_send("
") + webserver.content_send("") + webserver.content_send(matter._STYLESHEET) + + for host: self.device.k2l(bridge_plugin_by_host) + var host_html = webserver.html_escape(host) + var host_device_name = webserver.html_escape( self.device.get_plugin_remote_info(host).find('name', host) ) + webserver.content_send(f"") + var http_remote = bridge_plugin_by_host[host][0].http_remote # get the http_remote object from the first in list + webserver.content_send(http_remote.web_last_seen()) + + for plg: bridge_plugin_by_host[host] + webserver.content_send("") end + end + + + webserver.content_send("
🔗 {host_device_name}
") + plg.web_values() # show values + webserver.content_send("

") + + end + + #- display sensor value in the web UI -# + def web_sensor() + import webserver + + if self.matter_enabled() # mtc0 = close, mtc1 = open commissioning var fabrics_count = self.device.sessions.count_active_fabrics() if fabrics_count == 0 - webserver.content_send(string.format("
%s
", "No active association")) + webserver.content_send(format("
%s
", "Matter: No active association")) else var plural = fabrics_count > 1 - webserver.content_send(string.format("
%s
", str(fabrics_count) + " active association" + (plural ? "s" : ""))) + webserver.content_send(format("
%s
", "Matter: " + str(fabrics_count) + " active association" + (plural ? "s" : ""))) end - webserver.content_send(string.format("") - else - webserver.content_send(" Close Commissioning") + self.show_bridge_status() + + if self.device.is_root_commissioning_open() + self.show_commissioning_info() end + end end @@ -544,6 +1098,8 @@ class Matter_UI #- we need to register a closure, not just a function, that captures the current instance -# webserver.on("/matterc", / -> self.page_part_mgr(), webserver.HTTP_GET) webserver.on("/matterc", / -> self.page_part_ctl(), webserver.HTTP_POST) + webserver.on("/mattera", / -> self.page_part_mgr_adv(), webserver.HTTP_GET) # advanced + webserver.on("/matteradd", / -> self.page_part_mgr_add(), webserver.HTTP_GET) # add endpoint end end matter.UI = Matter_UI diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_0_Inspect.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_0_Inspect.h new file mode 100644 index 000000000000..079f5e775c98 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_0_Inspect.h @@ -0,0 +1,336 @@ +/* Solidification of Matter_0_Inspect.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +/******************************************************************** +** Solidified function: sort +********************************************************************/ +be_local_closure(matter_sort, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_const_int(1), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(stop_iteration), + }), + be_str_weak(sort), + &be_const_str_solidified, + ( &(const binstruction[29]) { /* code */ + 0x60040010, // 0000 GETGBL R1 G16 + 0x6008000C, // 0001 GETGBL R2 G12 + 0x5C0C0000, // 0002 MOVE R3 R0 + 0x7C080200, // 0003 CALL R2 1 + 0x04080500, // 0004 SUB R2 R2 K0 + 0x400A0002, // 0005 CONNECT R2 K0 R2 + 0x7C040200, // 0006 CALL R1 1 + 0xA8020010, // 0007 EXBLK 0 #0019 + 0x5C080200, // 0008 MOVE R2 R1 + 0x7C080000, // 0009 CALL R2 0 + 0x940C0002, // 000A GETIDX R3 R0 R2 + 0x5C100400, // 000B MOVE R4 R2 + 0x24140901, // 000C GT R5 R4 K1 + 0x78160008, // 000D JMPF R5 #0017 + 0x04140900, // 000E SUB R5 R4 K0 + 0x94140005, // 000F GETIDX R5 R0 R5 + 0x24140A03, // 0010 GT R5 R5 R3 + 0x78160004, // 0011 JMPF R5 #0017 + 0x04140900, // 0012 SUB R5 R4 K0 + 0x94140005, // 0013 GETIDX R5 R0 R5 + 0x98000805, // 0014 SETIDX R0 R4 R5 + 0x04100900, // 0015 SUB R4 R4 K0 + 0x7001FFF4, // 0016 JMP #000C + 0x98000803, // 0017 SETIDX R0 R4 R3 + 0x7001FFEE, // 0018 JMP #0008 + 0x58040002, // 0019 LDCONST R1 K2 + 0xAC040200, // 001A CATCH R1 1 0 + 0xB0080000, // 001B RAISE 2 R0 R0 + 0x80040000, // 001C RET 1 R0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: jitter +********************************************************************/ +be_local_closure(matter_jitter, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(crypto), + /* K1 */ be_nested_str_weak(random), + /* K2 */ be_nested_str_weak(get), + /* K3 */ be_const_int(0), + /* K4 */ be_const_int(2147483647), + /* K5 */ be_nested_str_weak(tasmota), + /* K6 */ be_nested_str_weak(millis), + }), + be_str_weak(jitter), + &be_const_str_solidified, + ( &(const binstruction[14]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080301, // 0001 GETMET R2 R1 K1 + 0x54120003, // 0002 LDINT R4 4 + 0x7C080400, // 0003 CALL R2 2 + 0x8C080502, // 0004 GETMET R2 R2 K2 + 0x58100003, // 0005 LDCONST R4 K3 + 0x54160003, // 0006 LDINT R5 4 + 0x7C080600, // 0007 CALL R2 3 + 0x2C080504, // 0008 AND R2 R2 K4 + 0xB80E0A00, // 0009 GETNGBL R3 K5 + 0x8C0C0706, // 000A GETMET R3 R3 K6 + 0x10140400, // 000B MOD R5 R2 R0 + 0x7C0C0400, // 000C CALL R3 2 + 0x80040600, // 000D RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: inspect +********************************************************************/ +be_local_closure(matter_inspect, /* name */ + be_nested_proto( + 14, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[15]) { /* constants */ + /* K0 */ be_nested_str_weak(introspect), + /* K1 */ be_nested_str_weak(members), + /* K2 */ be_nested_str_weak(get), + /* K3 */ be_nested_str_weak(function), + /* K4 */ be_nested_str_weak(push), + /* K5 */ be_nested_str_weak(stop_iteration), + /* K6 */ be_nested_str_weak(matter), + /* K7 */ be_nested_str_weak(sort), + /* K8 */ be_nested_str_weak(_X27_X25s_X27_X3A_X20_X25s), + /* K9 */ be_nested_str_weak(_X7B), + /* K10 */ be_nested_str_weak(concat), + /* K11 */ be_nested_str_weak(_X2C_X20), + /* K12 */ be_nested_str_weak(_X7D), + /* K13 */ be_nested_str_weak(Exception_X3A), + /* K14 */ be_nested_str_weak(_X7C), + }), + be_str_weak(inspect), + &be_const_str_solidified, + ( &(const binstruction[84]) { /* code */ + 0xA8020043, // 0000 EXBLK 0 #0045 + 0xA4060000, // 0001 IMPORT R1 K0 + 0x60080012, // 0002 GETGBL R2 G18 + 0x7C080000, // 0003 CALL R2 0 + 0x600C0010, // 0004 GETGBL R3 G16 + 0x8C100301, // 0005 GETMET R4 R1 K1 + 0x5C180000, // 0006 MOVE R6 R0 + 0x7C100400, // 0007 CALL R4 2 + 0x7C0C0200, // 0008 CALL R3 1 + 0xA802000E, // 0009 EXBLK 0 #0019 + 0x5C100600, // 000A MOVE R4 R3 + 0x7C100000, // 000B CALL R4 0 + 0x8C140302, // 000C GETMET R5 R1 K2 + 0x5C1C0000, // 000D MOVE R7 R0 + 0x5C200800, // 000E MOVE R8 R4 + 0x7C140600, // 000F CALL R5 3 + 0x60180004, // 0010 GETGBL R6 G4 + 0x5C1C0A00, // 0011 MOVE R7 R5 + 0x7C180200, // 0012 CALL R6 1 + 0x20180D03, // 0013 NE R6 R6 K3 + 0x781A0002, // 0014 JMPF R6 #0018 + 0x8C180504, // 0015 GETMET R6 R2 K4 + 0x5C200800, // 0016 MOVE R8 R4 + 0x7C180400, // 0017 CALL R6 2 + 0x7001FFF0, // 0018 JMP #000A + 0x580C0005, // 0019 LDCONST R3 K5 + 0xAC0C0200, // 001A CATCH R3 1 0 + 0xB0080000, // 001B RAISE 2 R0 R0 + 0xB80E0C00, // 001C GETNGBL R3 K6 + 0x8C0C0707, // 001D GETMET R3 R3 K7 + 0x5C140400, // 001E MOVE R5 R2 + 0x7C0C0400, // 001F CALL R3 2 + 0x5C080600, // 0020 MOVE R2 R3 + 0x600C0012, // 0021 GETGBL R3 G18 + 0x7C0C0000, // 0022 CALL R3 0 + 0x60100010, // 0023 GETGBL R4 G16 + 0x5C140400, // 0024 MOVE R5 R2 + 0x7C100200, // 0025 CALL R4 1 + 0xA8020011, // 0026 EXBLK 0 #0039 + 0x5C140800, // 0027 MOVE R5 R4 + 0x7C140000, // 0028 CALL R5 0 + 0x8C180302, // 0029 GETMET R6 R1 K2 + 0x5C200000, // 002A MOVE R8 R0 + 0x5C240A00, // 002B MOVE R9 R5 + 0x7C180600, // 002C CALL R6 3 + 0x8C1C0704, // 002D GETMET R7 R3 K4 + 0x60240018, // 002E GETGBL R9 G24 + 0x58280008, // 002F LDCONST R10 K8 + 0x602C0008, // 0030 GETGBL R11 G8 + 0x5C300A00, // 0031 MOVE R12 R5 + 0x7C2C0200, // 0032 CALL R11 1 + 0x60300008, // 0033 GETGBL R12 G8 + 0x5C340C00, // 0034 MOVE R13 R6 + 0x7C300200, // 0035 CALL R12 1 + 0x7C240600, // 0036 CALL R9 3 + 0x7C1C0400, // 0037 CALL R7 2 + 0x7001FFED, // 0038 JMP #0027 + 0x58100005, // 0039 LDCONST R4 K5 + 0xAC100200, // 003A CATCH R4 1 0 + 0xB0080000, // 003B RAISE 2 R0 R0 + 0x8C10070A, // 003C GETMET R4 R3 K10 + 0x5818000B, // 003D LDCONST R6 K11 + 0x7C100400, // 003E CALL R4 2 + 0x00121204, // 003F ADD R4 K9 R4 + 0x0010090C, // 0040 ADD R4 R4 K12 + 0xA8040001, // 0041 EXBLK 1 1 + 0x80040800, // 0042 RET 1 R4 + 0xA8040001, // 0043 EXBLK 1 1 + 0x7002000D, // 0044 JMP #0053 + 0xAC040002, // 0045 CATCH R1 0 2 + 0x7002000A, // 0046 JMP #0052 + 0x600C0008, // 0047 GETGBL R3 G8 + 0x5C100200, // 0048 MOVE R4 R1 + 0x7C0C0200, // 0049 CALL R3 1 + 0x000E1A03, // 004A ADD R3 K13 R3 + 0x000C070E, // 004B ADD R3 R3 K14 + 0x60100008, // 004C GETGBL R4 G8 + 0x5C140400, // 004D MOVE R5 R2 + 0x7C100200, // 004E CALL R4 1 + 0x000C0604, // 004F ADD R3 R3 R4 + 0x80040600, // 0050 RET 1 R3 + 0x70020000, // 0051 JMP #0053 + 0xB0080000, // 0052 RAISE 2 R0 R0 + 0x80000000, // 0053 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: consolidate_clusters +********************************************************************/ +be_local_closure(matter_consolidate_clusters, /* name */ + be_nested_proto( + 9, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(CLUSTERS), + /* K1 */ be_nested_str_weak(keys), + /* K2 */ be_nested_str_weak(copy), + /* K3 */ be_nested_str_weak(stop_iteration), + /* K4 */ be_nested_str_weak(find), + }), + be_str_weak(consolidate_clusters), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0x60080003, // 0000 GETGBL R2 G3 + 0x5C0C0000, // 0001 MOVE R3 R0 + 0x7C080200, // 0002 CALL R2 1 + 0x88080500, // 0003 GETMBR R2 R2 K0 + 0x600C0013, // 0004 GETGBL R3 G19 + 0x7C0C0000, // 0005 CALL R3 0 + 0x60100010, // 0006 GETGBL R4 G16 + 0x8C140501, // 0007 GETMET R5 R2 K1 + 0x7C140200, // 0008 CALL R5 1 + 0x7C100200, // 0009 CALL R4 1 + 0xA8020006, // 000A EXBLK 0 #0012 + 0x5C140800, // 000B MOVE R5 R4 + 0x7C140000, // 000C CALL R5 0 + 0x94180405, // 000D GETIDX R6 R2 R5 + 0x8C180D02, // 000E GETMET R6 R6 K2 + 0x7C180200, // 000F CALL R6 1 + 0x980C0A06, // 0010 SETIDX R3 R5 R6 + 0x7001FFF8, // 0011 JMP #000B + 0x58100003, // 0012 LDCONST R4 K3 + 0xAC100200, // 0013 CATCH R4 1 0 + 0xB0080000, // 0014 RAISE 2 R0 R0 + 0x60100010, // 0015 GETGBL R4 G16 + 0x8C140301, // 0016 GETMET R5 R1 K1 + 0x7C140200, // 0017 CALL R5 1 + 0x7C100200, // 0018 CALL R4 1 + 0xA802000E, // 0019 EXBLK 0 #0029 + 0x5C140800, // 001A MOVE R5 R4 + 0x7C140000, // 001B CALL R5 0 + 0x8C180704, // 001C GETMET R6 R3 K4 + 0x5C200A00, // 001D MOVE R8 R5 + 0x7C180400, // 001E CALL R6 2 + 0x4C1C0000, // 001F LDNIL R7 + 0x1C1C0C07, // 0020 EQ R7 R6 R7 + 0x781E0002, // 0021 JMPF R7 #0025 + 0x601C0012, // 0022 GETGBL R7 G18 + 0x7C1C0000, // 0023 CALL R7 0 + 0x5C180E00, // 0024 MOVE R6 R7 + 0x941C0205, // 0025 GETIDX R7 R1 R5 + 0x001C0C07, // 0026 ADD R7 R6 R7 + 0x980C0A07, // 0027 SETIDX R3 R5 R7 + 0x7001FFF0, // 0028 JMP #001A + 0x58100003, // 0029 LDCONST R4 K3 + 0xAC100200, // 002A CATCH R4 1 0 + 0xB0080000, // 002B RAISE 2 R0 R0 + 0x80040600, // 002C RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: UC_LIST +********************************************************************/ +be_local_closure(matter_UC_LIST, /* name */ + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 1, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(UPDATE_COMMANDS), + }), + be_str_weak(UC_LIST), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x60080003, // 0000 GETGBL R2 G3 + 0x5C0C0000, // 0001 MOVE R3 R0 + 0x7C080200, // 0002 CALL R2 1 + 0x88080500, // 0003 GETMBR R2 R2 K0 + 0x000C0401, // 0004 ADD R3 R2 R1 + 0x80040600, // 0005 RET 1 R3 + }) + ) +); +/*******************************************************************/ + +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Base38.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Base38.h index 2bef18e6fefc..7ef45645a541 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Base38.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Base38.h @@ -19,7 +19,7 @@ be_local_closure(Matter_Base38_encode, /* name */ 1, /* has sup protos */ ( &(const struct bproto*[ 1]) { be_nested_proto( - 7, /* nstack */ + 6, /* nstack */ 2, /* argc */ 0, /* varg */ 0, /* has upvals */ @@ -27,31 +27,29 @@ be_local_closure(Matter_Base38_encode, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_X2D_X2E), - /* K2 */ be_const_int(0), - /* K3 */ be_nested_str_weak(), - /* K4 */ be_const_int(1), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_X2D_X2E), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(), + /* K3 */ be_const_int(1), }), be_str_weak(b38_enc), &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 + ( &(const binstruction[14]) { /* code */ + 0x58080000, // 0000 LDCONST R2 K0 0x580C0001, // 0001 LDCONST R3 K1 0x58100002, // 0002 LDCONST R4 K2 - 0x58140003, // 0003 LDCONST R5 K3 - 0x14180801, // 0004 LT R6 R4 R1 - 0x781A0007, // 0005 JMPF R6 #000E - 0x541A0025, // 0006 LDINT R6 38 - 0x10180006, // 0007 MOD R6 R0 R6 - 0x94180606, // 0008 GETIDX R6 R3 R6 - 0x00140A06, // 0009 ADD R5 R5 R6 - 0x541A0025, // 000A LDINT R6 38 - 0x0C000006, // 000B DIV R0 R0 R6 - 0x00100904, // 000C ADD R4 R4 K4 - 0x7001FFF5, // 000D JMP #0004 - 0x80040A00, // 000E RET 1 R5 + 0x14140601, // 0003 LT R5 R3 R1 + 0x78160007, // 0004 JMPF R5 #000D + 0x54160025, // 0005 LDINT R5 38 + 0x10140005, // 0006 MOD R5 R0 R5 + 0x94140405, // 0007 GETIDX R5 R2 R5 + 0x00100805, // 0008 ADD R4 R4 R5 + 0x54160025, // 0009 LDINT R5 38 + 0x0C000005, // 000A DIV R0 R0 R5 + 0x000C0703, // 000B ADD R3 R3 K3 + 0x7001FFF5, // 000C JMP #0003 + 0x80040800, // 000D RET 1 R4 }) ), }), diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Commissioning.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Commissioning.h index f3766572192d..d4d7f5a9ef1d 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Commissioning.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Commissioning.h @@ -28,7 +28,7 @@ be_local_closure(Matter_Commisioning_Context_parse_StatusReport, /* name */ /* K5 */ be_nested_str_weak(app_payload_idx), /* K6 */ be_const_int(2147483647), /* K7 */ be_nested_str_weak(tohex), - /* K8 */ be_const_int(2), + /* K8 */ be_const_int(3), }), be_str_weak(parse_StatusReport), &be_const_str_solidified, @@ -66,13 +66,13 @@ be_local_closure(Matter_Commisioning_Context_find_fabric_by_destination_id, /* 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[21]) { /* constants */ + ( &(const bvalue[19]) { /* constants */ /* K0 */ be_nested_str_weak(crypto), /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(log), - /* K3 */ be_nested_str_weak(MTR_X3A_X20SEARCHING_X3A_X20destinationId_X3D), - /* K4 */ be_nested_str_weak(tohex), - /* K5 */ be_const_int(3), + /* K2 */ be_nested_str_weak(loglevel), + /* K3 */ be_nested_str_weak(log), + /* K4 */ be_nested_str_weak(MTR_X3A_X20SEARCHING_X3A_X20destinationId_X3D), + /* K5 */ be_nested_str_weak(tohex), /* K6 */ be_nested_str_weak(device), /* K7 */ be_nested_str_weak(sessions), /* K8 */ be_nested_str_weak(fabrics), @@ -81,94 +81,88 @@ be_local_closure(Matter_Commisioning_Context_find_fabric_by_destination_id, /* /* K11 */ be_nested_str_weak(device_id), /* K12 */ be_nested_str_weak(get_ca_pub), /* K13 */ be_nested_str_weak(get_ipk_group_key), - /* K14 */ be_nested_str_weak(MTR_X3A_X20SIGMA1_X3A_X20destinationMessage_X3D), - /* K15 */ be_nested_str_weak(MTR_X3A_X20SIGMA1_X3A_X20key_ipk_X3D), - /* K16 */ be_nested_str_weak(HMAC_SHA256), - /* K17 */ be_nested_str_weak(update), - /* K18 */ be_nested_str_weak(out), - /* K19 */ be_nested_str_weak(MTR_X3A_X20SIGMA1_X3A_X20candidateDestinationId_X3D), - /* K20 */ be_nested_str_weak(stop_iteration), + /* K14 */ be_nested_str_weak(HMAC_SHA256), + /* K15 */ be_nested_str_weak(update), + /* K16 */ be_nested_str_weak(out), + /* K17 */ be_nested_str_weak(MTR_X3A_X20SIGMA1_X3A_X20candidateDestinationId_X3D), + /* K18 */ be_nested_str_weak(stop_iteration), }), be_str_weak(find_fabric_by_destination_id), &be_const_str_solidified, - ( &(const binstruction[77]) { /* code */ + ( &(const binstruction[73]) { /* code */ 0xA40E0000, // 0000 IMPORT R3 K0 0xB8120200, // 0001 GETNGBL R4 K1 0x8C100902, // 0002 GETMET R4 R4 K2 - 0x8C180304, // 0003 GETMET R6 R1 K4 - 0x7C180200, // 0004 CALL R6 1 - 0x001A0606, // 0005 ADD R6 K3 R6 - 0x581C0005, // 0006 LDCONST R7 K5 - 0x7C100600, // 0007 CALL R4 3 - 0x60100010, // 0008 GETGBL R4 G16 - 0x88140106, // 0009 GETMBR R5 R0 K6 - 0x88140B07, // 000A GETMBR R5 R5 K7 - 0x88140B08, // 000B GETMBR R5 R5 K8 - 0x7C100200, // 000C CALL R4 1 - 0xA8020039, // 000D EXBLK 0 #0048 - 0x5C140800, // 000E MOVE R5 R4 - 0x7C140000, // 000F CALL R5 0 - 0x88180B09, // 0010 GETMBR R6 R5 K9 - 0x4C1C0000, // 0011 LDNIL R7 - 0x1C180C07, // 0012 EQ R6 R6 R7 - 0x741A0007, // 0013 JMPT R6 #001C - 0x88180B0A, // 0014 GETMBR R6 R5 K10 - 0x4C1C0000, // 0015 LDNIL R7 - 0x1C180C07, // 0016 EQ R6 R6 R7 - 0x741A0003, // 0017 JMPT R6 #001C - 0x88180B0B, // 0018 GETMBR R6 R5 K11 - 0x4C1C0000, // 0019 LDNIL R7 - 0x1C180C07, // 001A EQ R6 R6 R7 - 0x781A0000, // 001B JMPF R6 #001D - 0x7001FFF0, // 001C JMP #000E - 0x8C180B0C, // 001D GETMET R6 R5 K12 - 0x7C180200, // 001E CALL R6 1 - 0x00180406, // 001F ADD R6 R2 R6 - 0x881C0B0A, // 0020 GETMBR R7 R5 K10 - 0x00180C07, // 0021 ADD R6 R6 R7 - 0x881C0B0B, // 0022 GETMBR R7 R5 K11 - 0x00180C07, // 0023 ADD R6 R6 R7 - 0x8C1C0B0D, // 0024 GETMET R7 R5 K13 - 0x7C1C0200, // 0025 CALL R7 1 - 0xB8220200, // 0026 GETNGBL R8 K1 - 0x8C201102, // 0027 GETMET R8 R8 K2 - 0x8C280D04, // 0028 GETMET R10 R6 K4 - 0x7C280200, // 0029 CALL R10 1 - 0x002A1C0A, // 002A ADD R10 K14 R10 - 0x582C0005, // 002B LDCONST R11 K5 - 0x7C200600, // 002C CALL R8 3 - 0xB8220200, // 002D GETNGBL R8 K1 - 0x8C201102, // 002E GETMET R8 R8 K2 - 0x8C280F04, // 002F GETMET R10 R7 K4 - 0x7C280200, // 0030 CALL R10 1 - 0x002A1E0A, // 0031 ADD R10 K15 R10 - 0x542E0003, // 0032 LDINT R11 4 - 0x7C200600, // 0033 CALL R8 3 - 0x8C200710, // 0034 GETMET R8 R3 K16 - 0x5C280E00, // 0035 MOVE R10 R7 - 0x7C200400, // 0036 CALL R8 2 - 0x8C241111, // 0037 GETMET R9 R8 K17 - 0x5C2C0C00, // 0038 MOVE R11 R6 - 0x7C240400, // 0039 CALL R9 2 - 0x8C241112, // 003A GETMET R9 R8 K18 - 0x7C240200, // 003B CALL R9 1 - 0xB82A0200, // 003C GETNGBL R10 K1 - 0x8C281502, // 003D GETMET R10 R10 K2 - 0x8C301304, // 003E GETMET R12 R9 K4 - 0x7C300200, // 003F CALL R12 1 - 0x0032260C, // 0040 ADD R12 K19 R12 - 0x58340005, // 0041 LDCONST R13 K5 - 0x7C280600, // 0042 CALL R10 3 - 0x1C281201, // 0043 EQ R10 R9 R1 - 0x782A0001, // 0044 JMPF R10 #0047 - 0xA8040001, // 0045 EXBLK 1 1 - 0x80040A00, // 0046 RET 1 R5 - 0x7001FFC5, // 0047 JMP #000E - 0x58100014, // 0048 LDCONST R4 K20 - 0xAC100200, // 0049 CATCH R4 1 0 - 0xB0080000, // 004A RAISE 2 R0 R0 - 0x4C100000, // 004B LDNIL R4 - 0x80040800, // 004C RET 1 R4 + 0x541A0003, // 0003 LDINT R6 4 + 0x7C100400, // 0004 CALL R4 2 + 0x78120006, // 0005 JMPF R4 #000D + 0xB8120200, // 0006 GETNGBL R4 K1 + 0x8C100903, // 0007 GETMET R4 R4 K3 + 0x8C180305, // 0008 GETMET R6 R1 K5 + 0x7C180200, // 0009 CALL R6 1 + 0x001A0806, // 000A ADD R6 K4 R6 + 0x541E0003, // 000B LDINT R7 4 + 0x7C100600, // 000C CALL R4 3 + 0x60100010, // 000D GETGBL R4 G16 + 0x88140106, // 000E GETMBR R5 R0 K6 + 0x88140B07, // 000F GETMBR R5 R5 K7 + 0x88140B08, // 0010 GETMBR R5 R5 K8 + 0x7C100200, // 0011 CALL R4 1 + 0xA8020030, // 0012 EXBLK 0 #0044 + 0x5C140800, // 0013 MOVE R5 R4 + 0x7C140000, // 0014 CALL R5 0 + 0x88180B09, // 0015 GETMBR R6 R5 K9 + 0x4C1C0000, // 0016 LDNIL R7 + 0x1C180C07, // 0017 EQ R6 R6 R7 + 0x741A0007, // 0018 JMPT R6 #0021 + 0x88180B0A, // 0019 GETMBR R6 R5 K10 + 0x4C1C0000, // 001A LDNIL R7 + 0x1C180C07, // 001B EQ R6 R6 R7 + 0x741A0003, // 001C JMPT R6 #0021 + 0x88180B0B, // 001D GETMBR R6 R5 K11 + 0x4C1C0000, // 001E LDNIL R7 + 0x1C180C07, // 001F EQ R6 R6 R7 + 0x781A0000, // 0020 JMPF R6 #0022 + 0x7001FFF0, // 0021 JMP #0013 + 0x8C180B0C, // 0022 GETMET R6 R5 K12 + 0x7C180200, // 0023 CALL R6 1 + 0x00180406, // 0024 ADD R6 R2 R6 + 0x881C0B0A, // 0025 GETMBR R7 R5 K10 + 0x00180C07, // 0026 ADD R6 R6 R7 + 0x881C0B0B, // 0027 GETMBR R7 R5 K11 + 0x00180C07, // 0028 ADD R6 R6 R7 + 0x8C1C0B0D, // 0029 GETMET R7 R5 K13 + 0x7C1C0200, // 002A CALL R7 1 + 0x8C20070E, // 002B GETMET R8 R3 K14 + 0x5C280E00, // 002C MOVE R10 R7 + 0x7C200400, // 002D CALL R8 2 + 0x8C24110F, // 002E GETMET R9 R8 K15 + 0x5C2C0C00, // 002F MOVE R11 R6 + 0x7C240400, // 0030 CALL R9 2 + 0x8C241110, // 0031 GETMET R9 R8 K16 + 0x7C240200, // 0032 CALL R9 1 + 0xB82A0200, // 0033 GETNGBL R10 K1 + 0x8C281502, // 0034 GETMET R10 R10 K2 + 0x54320003, // 0035 LDINT R12 4 + 0x7C280400, // 0036 CALL R10 2 + 0x782A0006, // 0037 JMPF R10 #003F + 0xB82A0200, // 0038 GETNGBL R10 K1 + 0x8C281503, // 0039 GETMET R10 R10 K3 + 0x8C301305, // 003A GETMET R12 R9 K5 + 0x7C300200, // 003B CALL R12 1 + 0x0032220C, // 003C ADD R12 K17 R12 + 0x54360003, // 003D LDINT R13 4 + 0x7C280600, // 003E CALL R10 3 + 0x1C281201, // 003F EQ R10 R9 R1 + 0x782A0001, // 0040 JMPF R10 #0043 + 0xA8040001, // 0041 EXBLK 1 1 + 0x80040A00, // 0042 RET 1 R5 + 0x7001FFCE, // 0043 JMP #0013 + 0x58100012, // 0044 LDCONST R4 K18 + 0xAC100200, // 0045 CATCH R4 1 0 + 0xB0080000, // 0046 RAISE 2 R0 R0 + 0x4C100000, // 0047 LDNIL R4 + 0x80040800, // 0048 RET 1 R4 }) ) ); @@ -204,7 +198,7 @@ be_local_closure(Matter_Commisioning_Context_every_second, /* name */ ********************************************************************/ be_local_closure(Matter_Commisioning_Context_add_session, /* name */ be_nested_proto( - 14, /* nstack */ + 12, /* nstack */ 6, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -212,43 +206,39 @@ be_local_closure(Matter_Commisioning_Context_add_session, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(log), - /* K3 */ be_nested_str_weak(format), - /* K4 */ be_nested_str_weak(MTR_X3A_X20add_session_X20local_session_id_X3D_X25i_X20initiator_session_id_X3D_X25i), - /* K5 */ be_const_int(3), - /* K6 */ be_nested_str_weak(device), - /* K7 */ be_nested_str_weak(sessions), - /* K8 */ be_nested_str_weak(create_session), - /* K9 */ be_nested_str_weak(set_keys), + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(log), + /* K2 */ be_nested_str_weak(MTR_X3A_X20add_session_X20local_session_id_X3D_X25i_X20initiator_session_id_X3D_X25i), + /* K3 */ be_nested_str_weak(device), + /* K4 */ be_nested_str_weak(sessions), + /* K5 */ be_nested_str_weak(create_session), + /* K6 */ be_nested_str_weak(set_keys), }), be_str_weak(add_session), &be_const_str_solidified, - ( &(const binstruction[22]) { /* code */ - 0xA41A0000, // 0000 IMPORT R6 K0 - 0xB81E0200, // 0001 GETNGBL R7 K1 - 0x8C1C0F02, // 0002 GETMET R7 R7 K2 - 0x8C240D03, // 0003 GETMET R9 R6 K3 - 0x582C0004, // 0004 LDCONST R11 K4 - 0x5C300200, // 0005 MOVE R12 R1 - 0x5C340400, // 0006 MOVE R13 R2 - 0x7C240800, // 0007 CALL R9 4 - 0x58280005, // 0008 LDCONST R10 K5 - 0x7C1C0600, // 0009 CALL R7 3 - 0x881C0106, // 000A GETMBR R7 R0 K6 - 0x881C0F07, // 000B GETMBR R7 R7 K7 - 0x8C1C0F08, // 000C GETMET R7 R7 K8 - 0x5C240200, // 000D MOVE R9 R1 - 0x5C280400, // 000E MOVE R10 R2 - 0x7C1C0600, // 000F CALL R7 3 - 0x8C200F09, // 0010 GETMET R8 R7 K9 - 0x5C280600, // 0011 MOVE R10 R3 - 0x5C2C0800, // 0012 MOVE R11 R4 - 0x5C300A00, // 0013 MOVE R12 R5 - 0x7C200800, // 0014 CALL R8 4 - 0x80000000, // 0015 RET 0 + ( &(const binstruction[21]) { /* code */ + 0xB81A0000, // 0000 GETNGBL R6 K0 + 0x8C180D01, // 0001 GETMET R6 R6 K1 + 0x60200018, // 0002 GETGBL R8 G24 + 0x58240002, // 0003 LDCONST R9 K2 + 0x5C280200, // 0004 MOVE R10 R1 + 0x5C2C0400, // 0005 MOVE R11 R2 + 0x7C200600, // 0006 CALL R8 3 + 0x54260003, // 0007 LDINT R9 4 + 0x7C180600, // 0008 CALL R6 3 + 0x88180103, // 0009 GETMBR R6 R0 K3 + 0x88180D04, // 000A GETMBR R6 R6 K4 + 0x8C180D05, // 000B GETMET R6 R6 K5 + 0x5C200200, // 000C MOVE R8 R1 + 0x5C240400, // 000D MOVE R9 R2 + 0x7C180600, // 000E CALL R6 3 + 0x8C1C0D06, // 000F GETMET R7 R6 K6 + 0x5C240600, // 0010 MOVE R9 R3 + 0x5C280800, // 0011 MOVE R10 R4 + 0x5C2C0A00, // 0012 MOVE R11 R5 + 0x7C1C0800, // 0013 CALL R7 4 + 0x80000000, // 0014 RET 0 }) ) ); @@ -260,7 +250,7 @@ be_local_closure(Matter_Commisioning_Context_add_session, /* name */ ********************************************************************/ be_local_closure(Matter_Commisioning_Context_parse_PBKDFParamRequest, /* name */ be_nested_proto( - 14, /* nstack */ + 12, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -268,19 +258,19 @@ be_local_closure(Matter_Commisioning_Context_parse_PBKDFParamRequest, /* name 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[49]) { /* constants */ + ( &(const bvalue[48]) { /* constants */ /* K0 */ be_nested_str_weak(crypto), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(session), - /* K3 */ be_nested_str_weak(opcode), - /* K4 */ be_nested_str_weak(local_session_id), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(protocol_id), - /* K7 */ be_nested_str_weak(tasmota), - /* K8 */ be_nested_str_weak(log), - /* K9 */ be_nested_str_weak(MTR_X3A_X20invalid_X20PBKDFParamRequest_X20message), - /* K10 */ be_const_int(2), - /* K11 */ be_nested_str_weak(MTR_X3A_X20StatusReport_X28General_X20Code_X3A_X20FAILURE_X2C_X20ProtocolId_X3A_X20SECURE_CHANNEL_X2C_X20ProtocolCode_X3A_X20INVALID_PARAMETER_X29), + /* K1 */ be_nested_str_weak(session), + /* K2 */ be_nested_str_weak(opcode), + /* K3 */ be_nested_str_weak(local_session_id), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(protocol_id), + /* K6 */ be_nested_str_weak(tasmota), + /* K7 */ be_nested_str_weak(log), + /* K8 */ be_nested_str_weak(MTR_X3A_X20invalid_X20PBKDFParamRequest_X20message), + /* K9 */ be_const_int(2), + /* K10 */ be_nested_str_weak(MTR_X3A_X20StatusReport_X28General_X20Code_X3A_X20FAILURE_X2C_X20ProtocolId_X3A_X20SECURE_CHANNEL_X2C_X20ProtocolCode_X3A_X20INVALID_PARAMETER_X29), + /* K11 */ be_const_int(3), /* K12 */ be_nested_str_weak(send_status_report), /* K13 */ be_const_int(1), /* K14 */ be_nested_str_weak(matter), @@ -299,148 +289,146 @@ be_local_closure(Matter_Commisioning_Context_parse_PBKDFParamRequest, /* name /* K27 */ be_nested_str_weak(device), /* K28 */ be_nested_str_weak(sessions), /* K29 */ be_nested_str_weak(gen_local_session_id), - /* K30 */ be_nested_str_weak(format), - /* K31 */ be_nested_str_weak(MTR_X3A_X20_X2BSession_X20_X20_X20_X28_X256i_X29_X20from_X20_X27_X5B_X25s_X5D_X3A_X25i_X27), - /* K32 */ be_nested_str_weak(remote_ip), - /* K33 */ be_nested_str_weak(remote_port), - /* K34 */ be_nested_str_weak(PBKDFParamResponse), - /* K35 */ be_nested_str_weak(initiatorRandom), - /* K36 */ be_nested_str_weak(responderRandom), - /* K37 */ be_nested_str_weak(random), - /* K38 */ be_nested_str_weak(responderSessionId), - /* K39 */ be_nested_str_weak(pbkdf_parameters_salt), - /* K40 */ be_nested_str_weak(commissioning_salt), - /* K41 */ be_nested_str_weak(pbkdf_parameters_iterations), - /* K42 */ be_nested_str_weak(commissioning_iterations), - /* K43 */ be_nested_str_weak(tlv2raw), - /* K44 */ be_nested_str_weak(__Msg2), - /* K45 */ be_nested_str_weak(build_response), - /* K46 */ be_nested_str_weak(encode_frame), - /* K47 */ be_nested_str_weak(responder), - /* K48 */ be_nested_str_weak(send_response_frame), + /* K30 */ be_nested_str_weak(MTR_X3A_X20_X2BSession_X20_X20_X20_X28_X256i_X29_X20from_X20_X27_X5B_X25s_X5D_X3A_X25i_X27), + /* K31 */ be_nested_str_weak(remote_ip), + /* K32 */ be_nested_str_weak(remote_port), + /* K33 */ be_nested_str_weak(PBKDFParamResponse), + /* K34 */ be_nested_str_weak(initiatorRandom), + /* K35 */ be_nested_str_weak(responderRandom), + /* K36 */ be_nested_str_weak(random), + /* K37 */ be_nested_str_weak(responderSessionId), + /* K38 */ be_nested_str_weak(pbkdf_parameters_salt), + /* K39 */ be_nested_str_weak(commissioning_salt), + /* K40 */ be_nested_str_weak(pbkdf_parameters_iterations), + /* K41 */ be_nested_str_weak(commissioning_iterations), + /* K42 */ be_nested_str_weak(tlv2raw), + /* K43 */ be_nested_str_weak(__Msg2), + /* K44 */ be_nested_str_weak(build_response), + /* K45 */ be_nested_str_weak(encode_frame), + /* K46 */ be_nested_str_weak(responder), + /* K47 */ be_nested_str_weak(send_response_frame), }), be_str_weak(parse_PBKDFParamRequest), &be_const_str_solidified, - ( &(const binstruction[119]) { /* code */ + ( &(const binstruction[118]) { /* code */ 0xA40A0000, // 0000 IMPORT R2 K0 - 0xA40E0200, // 0001 IMPORT R3 K1 + 0x880C0301, // 0001 GETMBR R3 R1 K1 0x88100302, // 0002 GETMBR R4 R1 K2 - 0x88140303, // 0003 GETMBR R5 R1 K3 - 0x541A001F, // 0004 LDINT R6 32 - 0x20140A06, // 0005 NE R5 R5 R6 - 0x74160005, // 0006 JMPT R5 #000D - 0x88140304, // 0007 GETMBR R5 R1 K4 - 0x20140B05, // 0008 NE R5 R5 K5 - 0x74160002, // 0009 JMPT R5 #000D - 0x88140306, // 000A GETMBR R5 R1 K6 - 0x20140B05, // 000B NE R5 R5 K5 - 0x78160012, // 000C JMPF R5 #0020 - 0xB8160E00, // 000D GETNGBL R5 K7 - 0x8C140B08, // 000E GETMET R5 R5 K8 + 0x5416001F, // 0003 LDINT R5 32 + 0x20100805, // 0004 NE R4 R4 R5 + 0x74120005, // 0005 JMPT R4 #000C + 0x88100303, // 0006 GETMBR R4 R1 K3 + 0x20100904, // 0007 NE R4 R4 K4 + 0x74120002, // 0008 JMPT R4 #000C + 0x88100305, // 0009 GETMBR R4 R1 K5 + 0x20100904, // 000A NE R4 R4 K4 + 0x78120012, // 000B JMPF R4 #001F + 0xB8120C00, // 000C GETNGBL R4 K6 + 0x8C100907, // 000D GETMET R4 R4 K7 + 0x58180008, // 000E LDCONST R6 K8 0x581C0009, // 000F LDCONST R7 K9 - 0x5820000A, // 0010 LDCONST R8 K10 - 0x7C140600, // 0011 CALL R5 3 - 0xB8160E00, // 0012 GETNGBL R5 K7 - 0x8C140B08, // 0013 GETMET R5 R5 K8 + 0x7C100600, // 0010 CALL R4 3 + 0xB8120C00, // 0011 GETNGBL R4 K6 + 0x8C100907, // 0012 GETMET R4 R4 K7 + 0x5818000A, // 0013 LDCONST R6 K10 0x581C000B, // 0014 LDCONST R7 K11 - 0x5820000A, // 0015 LDCONST R8 K10 - 0x7C140600, // 0016 CALL R5 3 - 0x8C14010C, // 0017 GETMET R5 R0 K12 - 0x5C1C0200, // 0018 MOVE R7 R1 - 0x5820000D, // 0019 LDCONST R8 K13 - 0x58240005, // 001A LDCONST R9 K5 - 0x5828000A, // 001B LDCONST R10 K10 - 0x502C0000, // 001C LDBOOL R11 0 0 - 0x7C140C00, // 001D CALL R5 6 - 0x50140000, // 001E LDBOOL R5 0 0 - 0x80040A00, // 001F RET 1 R5 - 0xB8161C00, // 0020 GETNGBL R5 K14 - 0x8C140B0F, // 0021 GETMET R5 R5 K15 - 0x7C140200, // 0022 CALL R5 1 - 0x8C140B10, // 0023 GETMET R5 R5 K16 - 0x881C0311, // 0024 GETMBR R7 R1 K17 - 0x88200312, // 0025 GETMBR R8 R1 K18 - 0x7C140600, // 0026 CALL R5 3 - 0x88180302, // 0027 GETMBR R6 R1 K2 - 0x8C180D13, // 0028 GETMET R6 R6 K19 - 0x7C180200, // 0029 CALL R6 1 - 0x88180312, // 002A GETMBR R6 R1 K18 - 0x40180D15, // 002B CONNECT R6 R6 K21 - 0x881C0311, // 002C GETMBR R7 R1 K17 - 0x94180E06, // 002D GETIDX R6 R7 R6 - 0x90122806, // 002E SETMBR R4 K20 R6 - 0x88180B16, // 002F GETMBR R6 R5 K22 - 0x20180D05, // 0030 NE R6 R6 K5 - 0x781A0012, // 0031 JMPF R6 #0045 - 0xB81A0E00, // 0032 GETNGBL R6 K7 - 0x8C180D08, // 0033 GETMET R6 R6 K8 - 0x58200017, // 0034 LDCONST R8 K23 - 0x5824000A, // 0035 LDCONST R9 K10 - 0x7C180600, // 0036 CALL R6 3 - 0xB81A0E00, // 0037 GETNGBL R6 K7 - 0x8C180D08, // 0038 GETMET R6 R6 K8 + 0x7C100600, // 0015 CALL R4 3 + 0x8C10010C, // 0016 GETMET R4 R0 K12 + 0x5C180200, // 0017 MOVE R6 R1 + 0x581C000D, // 0018 LDCONST R7 K13 + 0x58200004, // 0019 LDCONST R8 K4 + 0x58240009, // 001A LDCONST R9 K9 + 0x50280000, // 001B LDBOOL R10 0 0 + 0x7C100C00, // 001C CALL R4 6 + 0x50100000, // 001D LDBOOL R4 0 0 + 0x80040800, // 001E RET 1 R4 + 0xB8121C00, // 001F GETNGBL R4 K14 + 0x8C10090F, // 0020 GETMET R4 R4 K15 + 0x7C100200, // 0021 CALL R4 1 + 0x8C100910, // 0022 GETMET R4 R4 K16 + 0x88180311, // 0023 GETMBR R6 R1 K17 + 0x881C0312, // 0024 GETMBR R7 R1 K18 + 0x7C100600, // 0025 CALL R4 3 + 0x88140301, // 0026 GETMBR R5 R1 K1 + 0x8C140B13, // 0027 GETMET R5 R5 K19 + 0x7C140200, // 0028 CALL R5 1 + 0x88140312, // 0029 GETMBR R5 R1 K18 + 0x40140B15, // 002A CONNECT R5 R5 K21 + 0x88180311, // 002B GETMBR R6 R1 K17 + 0x94140C05, // 002C GETIDX R5 R6 R5 + 0x900E2805, // 002D SETMBR R3 K20 R5 + 0x88140916, // 002E GETMBR R5 R4 K22 + 0x20140B04, // 002F NE R5 R5 K4 + 0x78160012, // 0030 JMPF R5 #0044 + 0xB8160C00, // 0031 GETNGBL R5 K6 + 0x8C140B07, // 0032 GETMET R5 R5 K7 + 0x581C0017, // 0033 LDCONST R7 K23 + 0x58200009, // 0034 LDCONST R8 K9 + 0x7C140600, // 0035 CALL R5 3 + 0xB8160C00, // 0036 GETNGBL R5 K6 + 0x8C140B07, // 0037 GETMET R5 R5 K7 + 0x581C000A, // 0038 LDCONST R7 K10 0x5820000B, // 0039 LDCONST R8 K11 - 0x5824000A, // 003A LDCONST R9 K10 - 0x7C180600, // 003B CALL R6 3 - 0x8C18010C, // 003C GETMET R6 R0 K12 - 0x5C200200, // 003D MOVE R8 R1 - 0x5824000D, // 003E LDCONST R9 K13 - 0x58280005, // 003F LDCONST R10 K5 - 0x582C000A, // 0040 LDCONST R11 K10 - 0x50300000, // 0041 LDBOOL R12 0 0 - 0x7C180C00, // 0042 CALL R6 6 - 0x50180000, // 0043 LDBOOL R6 0 0 - 0x80040C00, // 0044 RET 1 R6 - 0x88180B19, // 0045 GETMBR R6 R5 K25 - 0x90123006, // 0046 SETMBR R4 K24 R6 - 0x8818011B, // 0047 GETMBR R6 R0 K27 - 0x88180D1C, // 0048 GETMBR R6 R6 K28 - 0x8C180D1D, // 0049 GETMET R6 R6 K29 - 0x7C180200, // 004A CALL R6 1 - 0x90123406, // 004B SETMBR R4 K26 R6 - 0xB81A0E00, // 004C GETNGBL R6 K7 - 0x8C180D08, // 004D GETMET R6 R6 K8 - 0x8C20071E, // 004E GETMET R8 R3 K30 - 0x5828001F, // 004F LDCONST R10 K31 - 0x882C091A, // 0050 GETMBR R11 R4 K26 - 0x88300320, // 0051 GETMBR R12 R1 K32 - 0x88340321, // 0052 GETMBR R13 R1 K33 - 0x7C200A00, // 0053 CALL R8 5 - 0x5824000A, // 0054 LDCONST R9 K10 - 0x7C180600, // 0055 CALL R6 3 - 0xB81A1C00, // 0056 GETNGBL R6 K14 - 0x8C180D22, // 0057 GETMET R6 R6 K34 - 0x7C180200, // 0058 CALL R6 1 - 0x881C0B23, // 0059 GETMBR R7 R5 K35 - 0x901A4607, // 005A SETMBR R6 K35 R7 - 0x8C1C0525, // 005B GETMET R7 R2 K37 - 0x5426001F, // 005C LDINT R9 32 - 0x7C1C0400, // 005D CALL R7 2 - 0x901A4807, // 005E SETMBR R6 K36 R7 - 0x881C091A, // 005F GETMBR R7 R4 K26 - 0x901A4C07, // 0060 SETMBR R6 K38 R7 - 0x881C011B, // 0061 GETMBR R7 R0 K27 - 0x881C0F28, // 0062 GETMBR R7 R7 K40 - 0x901A4E07, // 0063 SETMBR R6 K39 R7 - 0x881C011B, // 0064 GETMBR R7 R0 K27 - 0x881C0F2A, // 0065 GETMBR R7 R7 K42 - 0x901A5207, // 0066 SETMBR R6 K41 R7 - 0x8C1C0D2B, // 0067 GETMET R7 R6 K43 - 0x7C1C0200, // 0068 CALL R7 1 - 0x90125807, // 0069 SETMBR R4 K44 R7 - 0x8C20032D, // 006A GETMET R8 R1 K45 - 0x542A0020, // 006B LDINT R10 33 - 0x502C0200, // 006C LDBOOL R11 1 0 - 0x7C200600, // 006D CALL R8 3 - 0x8C24112E, // 006E GETMET R9 R8 K46 - 0x5C2C0E00, // 006F MOVE R11 R7 - 0x7C240400, // 0070 CALL R9 2 - 0x8828012F, // 0071 GETMBR R10 R0 K47 - 0x8C281530, // 0072 GETMET R10 R10 K48 - 0x5C301000, // 0073 MOVE R12 R8 - 0x7C280400, // 0074 CALL R10 2 - 0x50280200, // 0075 LDBOOL R10 1 0 - 0x80041400, // 0076 RET 1 R10 + 0x7C140600, // 003A CALL R5 3 + 0x8C14010C, // 003B GETMET R5 R0 K12 + 0x5C1C0200, // 003C MOVE R7 R1 + 0x5820000D, // 003D LDCONST R8 K13 + 0x58240004, // 003E LDCONST R9 K4 + 0x58280009, // 003F LDCONST R10 K9 + 0x502C0000, // 0040 LDBOOL R11 0 0 + 0x7C140C00, // 0041 CALL R5 6 + 0x50140000, // 0042 LDBOOL R5 0 0 + 0x80040A00, // 0043 RET 1 R5 + 0x88140919, // 0044 GETMBR R5 R4 K25 + 0x900E3005, // 0045 SETMBR R3 K24 R5 + 0x8814011B, // 0046 GETMBR R5 R0 K27 + 0x88140B1C, // 0047 GETMBR R5 R5 K28 + 0x8C140B1D, // 0048 GETMET R5 R5 K29 + 0x7C140200, // 0049 CALL R5 1 + 0x900E3405, // 004A SETMBR R3 K26 R5 + 0xB8160C00, // 004B GETNGBL R5 K6 + 0x8C140B07, // 004C GETMET R5 R5 K7 + 0x601C0018, // 004D GETGBL R7 G24 + 0x5820001E, // 004E LDCONST R8 K30 + 0x8824071A, // 004F GETMBR R9 R3 K26 + 0x8828031F, // 0050 GETMBR R10 R1 K31 + 0x882C0320, // 0051 GETMBR R11 R1 K32 + 0x7C1C0800, // 0052 CALL R7 4 + 0x5820000B, // 0053 LDCONST R8 K11 + 0x7C140600, // 0054 CALL R5 3 + 0xB8161C00, // 0055 GETNGBL R5 K14 + 0x8C140B21, // 0056 GETMET R5 R5 K33 + 0x7C140200, // 0057 CALL R5 1 + 0x88180922, // 0058 GETMBR R6 R4 K34 + 0x90164406, // 0059 SETMBR R5 K34 R6 + 0x8C180524, // 005A GETMET R6 R2 K36 + 0x5422001F, // 005B LDINT R8 32 + 0x7C180400, // 005C CALL R6 2 + 0x90164606, // 005D SETMBR R5 K35 R6 + 0x8818071A, // 005E GETMBR R6 R3 K26 + 0x90164A06, // 005F SETMBR R5 K37 R6 + 0x8818011B, // 0060 GETMBR R6 R0 K27 + 0x88180D27, // 0061 GETMBR R6 R6 K39 + 0x90164C06, // 0062 SETMBR R5 K38 R6 + 0x8818011B, // 0063 GETMBR R6 R0 K27 + 0x88180D29, // 0064 GETMBR R6 R6 K41 + 0x90165006, // 0065 SETMBR R5 K40 R6 + 0x8C180B2A, // 0066 GETMET R6 R5 K42 + 0x7C180200, // 0067 CALL R6 1 + 0x900E5606, // 0068 SETMBR R3 K43 R6 + 0x8C1C032C, // 0069 GETMET R7 R1 K44 + 0x54260020, // 006A LDINT R9 33 + 0x50280200, // 006B LDBOOL R10 1 0 + 0x7C1C0600, // 006C CALL R7 3 + 0x8C200F2D, // 006D GETMET R8 R7 K45 + 0x5C280C00, // 006E MOVE R10 R6 + 0x7C200400, // 006F CALL R8 2 + 0x8824012E, // 0070 GETMBR R9 R0 K46 + 0x8C24132F, // 0071 GETMET R9 R9 K47 + 0x5C2C0E00, // 0072 MOVE R11 R7 + 0x7C240400, // 0073 CALL R9 2 + 0x50240200, // 0074 LDBOOL R9 1 0 + 0x80041200, // 0075 RET 1 R9 }) ) ); @@ -508,7 +496,7 @@ be_local_closure(Matter_Commisioning_Context_send_status_report, /* name */ ********************************************************************/ be_local_closure(Matter_Commisioning_Context_parse_Pake1, /* name */ be_nested_proto( - 17, /* nstack */ + 21, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -516,7 +504,7 @@ be_local_closure(Matter_Commisioning_Context_parse_Pake1, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[47]) { /* constants */ + ( &(const bvalue[52]) { /* constants */ /* K0 */ be_nested_str_weak(crypto), /* K1 */ be_nested_str_weak(session), /* K2 */ be_nested_str_weak(opcode), @@ -526,48 +514,53 @@ be_local_closure(Matter_Commisioning_Context_parse_Pake1, /* name */ /* K6 */ be_nested_str_weak(tasmota), /* K7 */ be_nested_str_weak(log), /* K8 */ be_nested_str_weak(MTR_X3A_X20invalid_X20Pake1_X20message), - /* K9 */ be_const_int(2), + /* K9 */ be_const_int(3), /* K10 */ be_nested_str_weak(MTR_X3A_X20StatusReport_X28General_X20Code_X3A_X20FAILURE_X2C_X20ProtocolId_X3A_X20SECURE_CHANNEL_X2C_X20ProtocolCode_X3A_X20INVALID_PARAMETER_X29), /* K11 */ be_nested_str_weak(send_status_report), /* K12 */ be_const_int(1), - /* K13 */ be_nested_str_weak(matter), - /* K14 */ be_nested_str_weak(Pake1), - /* K15 */ be_nested_str_weak(parse), - /* K16 */ be_nested_str_weak(raw), - /* K17 */ be_nested_str_weak(app_payload_idx), - /* K18 */ be_nested_str_weak(pA), - /* K19 */ be_nested_str_weak(SPAKE2P_Matter), - /* K20 */ be_nested_str_weak(device), - /* K21 */ be_nested_str_weak(commissioning_w0), - /* K22 */ be_nested_str_weak(commissioning_L), - /* K23 */ be_nested_str_weak(random), - /* K24 */ be_nested_str_weak(compute_pB), - /* K25 */ be_nested_str_weak(compute_ZV_verifier), - /* K26 */ be_nested_str_weak(SHA256), - /* K27 */ be_nested_str_weak(update), - /* K28 */ be_nested_str_weak(fromstring), - /* K29 */ be_nested_str_weak(Matter_Context_Prefix), - /* K30 */ be_nested_str_weak(__Msg1), - /* K31 */ be_nested_str_weak(__Msg2), - /* K32 */ be_nested_str_weak(out), - /* K33 */ be_nested_str_weak(set_context), - /* K34 */ be_nested_str_weak(compute_TT_hash), - /* K35 */ be_nested_str_weak(Pake2), - /* K36 */ be_nested_str_weak(pB), - /* K37 */ be_nested_str_weak(cB), - /* K38 */ be_nested_str_weak(tlv2raw), - /* K39 */ be_nested_str_weak(__spake_cA), - /* K40 */ be_nested_str_weak(cA), - /* K41 */ be_nested_str_weak(__spake_Ke), - /* K42 */ be_nested_str_weak(Ke), - /* K43 */ be_nested_str_weak(build_response), - /* K44 */ be_nested_str_weak(encode_frame), - /* K45 */ be_nested_str_weak(responder), - /* K46 */ be_nested_str_weak(send_response_frame), + /* K13 */ be_const_int(2), + /* K14 */ be_nested_str_weak(matter), + /* K15 */ be_nested_str_weak(Pake1), + /* K16 */ be_nested_str_weak(parse), + /* K17 */ be_nested_str_weak(raw), + /* K18 */ be_nested_str_weak(app_payload_idx), + /* K19 */ be_nested_str_weak(pA), + /* K20 */ be_nested_str_weak(SPAKE2P_Matter), + /* K21 */ be_nested_str_weak(device), + /* K22 */ be_nested_str_weak(commissioning_w0), + /* K23 */ be_nested_str_weak(commissioning_L), + /* K24 */ be_nested_str_weak(random), + /* K25 */ be_nested_str_weak(compute_pB), + /* K26 */ be_nested_str_weak(compute_ZV_verifier), + /* K27 */ be_nested_str_weak(SHA256), + /* K28 */ be_nested_str_weak(update), + /* K29 */ be_nested_str_weak(fromstring), + /* K30 */ be_nested_str_weak(Matter_Context_Prefix), + /* K31 */ be_nested_str_weak(__Msg1), + /* K32 */ be_nested_str_weak(__Msg2), + /* K33 */ be_nested_str_weak(out), + /* K34 */ be_nested_str_weak(set_context), + /* K35 */ be_nested_str_weak(compute_TT_hash), + /* K36 */ be_nested_str_weak(Pake2), + /* K37 */ be_nested_str_weak(pB), + /* K38 */ be_nested_str_weak(cB), + /* K39 */ be_nested_str_weak(tlv2raw), + /* K40 */ be_nested_str_weak(__spake_cA), + /* K41 */ be_nested_str_weak(cA), + /* K42 */ be_nested_str_weak(__spake_Ke), + /* K43 */ be_nested_str_weak(Ke), + /* K44 */ be_nested_str_weak(build_response), + /* K45 */ be_nested_str_weak(encode_frame), + /* K46 */ be_nested_str_weak(MTR_X3A_X20New_X20Commissioning_X20_X28PASE_X20id_X3D_X25i_X29_X20from_X20_X5B_X25s_X5D_X3A_X25i), + /* K47 */ be_nested_str_weak(__future_local_session_id), + /* K48 */ be_nested_str_weak(_ip), + /* K49 */ be_nested_str_weak(_port), + /* K50 */ be_nested_str_weak(responder), + /* K51 */ be_nested_str_weak(send_response_frame), }), be_str_weak(parse_Pake1), &be_const_str_solidified, - ( &(const binstruction[105]) { /* code */ + ( &(const binstruction[115]) { /* code */ 0xA40A0000, // 0000 IMPORT R2 K0 0x880C0301, // 0001 GETMBR R3 R1 K1 0x88100302, // 0002 GETMBR R4 R1 K2 @@ -594,85 +587,95 @@ be_local_closure(Matter_Commisioning_Context_parse_Pake1, /* name */ 0x5C180200, // 0017 MOVE R6 R1 0x581C000C, // 0018 LDCONST R7 K12 0x58200004, // 0019 LDCONST R8 K4 - 0x58240009, // 001A LDCONST R9 K9 + 0x5824000D, // 001A LDCONST R9 K13 0x50280000, // 001B LDBOOL R10 0 0 0x7C100C00, // 001C CALL R4 6 0x50100000, // 001D LDBOOL R4 0 0 0x80040800, // 001E RET 1 R4 - 0xB8121A00, // 001F GETNGBL R4 K13 - 0x8C10090E, // 0020 GETMET R4 R4 K14 + 0xB8121C00, // 001F GETNGBL R4 K14 + 0x8C10090F, // 0020 GETMET R4 R4 K15 0x7C100200, // 0021 CALL R4 1 - 0x8C10090F, // 0022 GETMET R4 R4 K15 - 0x88180310, // 0023 GETMBR R6 R1 K16 - 0x881C0311, // 0024 GETMBR R7 R1 K17 + 0x8C100910, // 0022 GETMET R4 R4 K16 + 0x88180311, // 0023 GETMBR R6 R1 K17 + 0x881C0312, // 0024 GETMBR R7 R1 K18 0x7C100600, // 0025 CALL R4 3 - 0x88140912, // 0026 GETMBR R5 R4 K18 - 0x8C180513, // 0027 GETMET R6 R2 K19 - 0x88200114, // 0028 GETMBR R8 R0 K20 - 0x88201115, // 0029 GETMBR R8 R8 K21 + 0x88140913, // 0026 GETMBR R5 R4 K19 + 0x8C180514, // 0027 GETMET R6 R2 K20 + 0x88200115, // 0028 GETMBR R8 R0 K21 + 0x88201116, // 0029 GETMBR R8 R8 K22 0x4C240000, // 002A LDNIL R9 - 0x88280114, // 002B GETMBR R10 R0 K20 - 0x88281516, // 002C GETMBR R10 R10 K22 + 0x88280115, // 002B GETMBR R10 R0 K21 + 0x88281517, // 002C GETMBR R10 R10 K23 0x7C180800, // 002D CALL R6 4 - 0x8C1C0517, // 002E GETMET R7 R2 K23 + 0x8C1C0518, // 002E GETMET R7 R2 K24 0x5426001F, // 002F LDINT R9 32 0x7C1C0400, // 0030 CALL R7 2 - 0x8C200D18, // 0031 GETMET R8 R6 K24 + 0x8C200D19, // 0031 GETMET R8 R6 K25 0x5C280E00, // 0032 MOVE R10 R7 0x7C200400, // 0033 CALL R8 2 - 0x8C200D19, // 0034 GETMET R8 R6 K25 + 0x8C200D1A, // 0034 GETMET R8 R6 K26 0x5C280A00, // 0035 MOVE R10 R5 0x7C200400, // 0036 CALL R8 2 - 0x8C20051A, // 0037 GETMET R8 R2 K26 + 0x8C20051B, // 0037 GETMET R8 R2 K27 0x7C200200, // 0038 CALL R8 1 - 0x8C24111B, // 0039 GETMET R9 R8 K27 + 0x8C24111C, // 0039 GETMET R9 R8 K28 0x602C0015, // 003A GETGBL R11 G21 0x7C2C0000, // 003B CALL R11 0 - 0x8C2C171C, // 003C GETMET R11 R11 K28 - 0x8834011D, // 003D GETMBR R13 R0 K29 + 0x8C2C171D, // 003C GETMET R11 R11 K29 + 0x8834011E, // 003D GETMBR R13 R0 K30 0x7C2C0400, // 003E CALL R11 2 0x7C240400, // 003F CALL R9 2 - 0x8C24111B, // 0040 GETMET R9 R8 K27 - 0x882C071E, // 0041 GETMBR R11 R3 K30 + 0x8C24111C, // 0040 GETMET R9 R8 K28 + 0x882C071F, // 0041 GETMBR R11 R3 K31 0x7C240400, // 0042 CALL R9 2 - 0x8C24111B, // 0043 GETMET R9 R8 K27 - 0x882C071F, // 0044 GETMBR R11 R3 K31 + 0x8C24111C, // 0043 GETMET R9 R8 K28 + 0x882C0720, // 0044 GETMBR R11 R3 K32 0x7C240400, // 0045 CALL R9 2 - 0x8C241120, // 0046 GETMET R9 R8 K32 + 0x8C241121, // 0046 GETMET R9 R8 K33 0x7C240200, // 0047 CALL R9 1 - 0x901A2405, // 0048 SETMBR R6 K18 R5 - 0x8C280D21, // 0049 GETMET R10 R6 K33 + 0x901A2605, // 0048 SETMBR R6 K19 R5 + 0x8C280D22, // 0049 GETMET R10 R6 K34 0x5C301200, // 004A MOVE R12 R9 0x7C280400, // 004B CALL R10 2 - 0x8C280D22, // 004C GETMET R10 R6 K34 + 0x8C280D23, // 004C GETMET R10 R6 K35 0x50300200, // 004D LDBOOL R12 1 0 0x7C280400, // 004E CALL R10 2 - 0xB82A1A00, // 004F GETNGBL R10 K13 - 0x8C281523, // 0050 GETMET R10 R10 K35 + 0xB82A1C00, // 004F GETNGBL R10 K14 + 0x8C281524, // 0050 GETMET R10 R10 K36 0x7C280200, // 0051 CALL R10 1 - 0x882C0D24, // 0052 GETMBR R11 R6 K36 - 0x902A480B, // 0053 SETMBR R10 K36 R11 - 0x882C0D25, // 0054 GETMBR R11 R6 K37 - 0x902A4A0B, // 0055 SETMBR R10 K37 R11 - 0x8C2C1526, // 0056 GETMET R11 R10 K38 + 0x882C0D25, // 0052 GETMBR R11 R6 K37 + 0x902A4A0B, // 0053 SETMBR R10 K37 R11 + 0x882C0D26, // 0054 GETMBR R11 R6 K38 + 0x902A4C0B, // 0055 SETMBR R10 K38 R11 + 0x8C2C1527, // 0056 GETMET R11 R10 K39 0x7C2C0200, // 0057 CALL R11 1 - 0x88300D28, // 0058 GETMBR R12 R6 K40 - 0x900E4E0C, // 0059 SETMBR R3 K39 R12 - 0x88300D2A, // 005A GETMBR R12 R6 K42 - 0x900E520C, // 005B SETMBR R3 K41 R12 - 0x8C30032B, // 005C GETMET R12 R1 K43 + 0x88300D29, // 0058 GETMBR R12 R6 K41 + 0x900E500C, // 0059 SETMBR R3 K40 R12 + 0x88300D2B, // 005A GETMBR R12 R6 K43 + 0x900E540C, // 005B SETMBR R3 K42 R12 + 0x8C30032C, // 005C GETMET R12 R1 K44 0x543A0022, // 005D LDINT R14 35 0x503C0200, // 005E LDBOOL R15 1 0 0x7C300600, // 005F CALL R12 3 - 0x8C34192C, // 0060 GETMET R13 R12 K44 + 0x8C34192D, // 0060 GETMET R13 R12 K45 0x5C3C1600, // 0061 MOVE R15 R11 0x7C340400, // 0062 CALL R13 2 - 0x8838012D, // 0063 GETMBR R14 R0 K45 - 0x8C381D2E, // 0064 GETMET R14 R14 K46 - 0x5C401800, // 0065 MOVE R16 R12 - 0x7C380400, // 0066 CALL R14 2 - 0x50380200, // 0067 LDBOOL R14 1 0 - 0x80041C00, // 0068 RET 1 R14 + 0xB83A0C00, // 0063 GETNGBL R14 K6 + 0x8C381D07, // 0064 GETMET R14 R14 K7 + 0x60400018, // 0065 GETGBL R16 G24 + 0x5844002E, // 0066 LDCONST R17 K46 + 0x8848072F, // 0067 GETMBR R18 R3 K47 + 0x884C0730, // 0068 GETMBR R19 R3 K48 + 0x88500731, // 0069 GETMBR R20 R3 K49 + 0x7C400800, // 006A CALL R16 4 + 0x5844000D, // 006B LDCONST R17 K13 + 0x7C380600, // 006C CALL R14 3 + 0x88380132, // 006D GETMBR R14 R0 K50 + 0x8C381D33, // 006E GETMET R14 R14 K51 + 0x5C401800, // 006F MOVE R16 R12 + 0x7C380400, // 0070 CALL R14 2 + 0x50380200, // 0071 LDBOOL R14 1 0 + 0x80041C00, // 0072 RET 1 R14 }) ) ); @@ -734,20 +737,20 @@ be_local_closure(Matter_Commisioning_Context_parse_Pake3, /* name */ /* K6 */ be_nested_str_weak(tasmota), /* K7 */ be_nested_str_weak(log), /* K8 */ be_nested_str_weak(MTR_X3A_X20invalid_X20Pake3_X20message), - /* K9 */ be_const_int(2), + /* K9 */ be_const_int(3), /* K10 */ be_nested_str_weak(MTR_X3A_X20StatusReport_X28General_X20Code_X3A_X20FAILURE_X2C_X20ProtocolId_X3A_X20SECURE_CHANNEL_X2C_X20ProtocolCode_X3A_X20INVALID_PARAMETER_X29), /* K11 */ be_nested_str_weak(send_status_report), /* K12 */ be_const_int(1), - /* K13 */ be_nested_str_weak(matter), - /* K14 */ be_nested_str_weak(Pake3), - /* K15 */ be_nested_str_weak(parse), - /* K16 */ be_nested_str_weak(raw), - /* K17 */ be_nested_str_weak(app_payload_idx), - /* K18 */ be_nested_str_weak(cA), - /* K19 */ be_nested_str_weak(__spake_cA), - /* K20 */ be_nested_str_weak(MTR_X3A_X20invalid_X20cA_X20received), - /* K21 */ be_nested_str_weak(rtc), - /* K22 */ be_nested_str_weak(utc), + /* K13 */ be_const_int(2), + /* K14 */ be_nested_str_weak(matter), + /* K15 */ be_nested_str_weak(Pake3), + /* K16 */ be_nested_str_weak(parse), + /* K17 */ be_nested_str_weak(raw), + /* K18 */ be_nested_str_weak(app_payload_idx), + /* K19 */ be_nested_str_weak(cA), + /* K20 */ be_nested_str_weak(__spake_cA), + /* K21 */ be_nested_str_weak(MTR_X3A_X20invalid_X20cA_X20received), + /* K22 */ be_nested_str_weak(rtc_utc), /* K23 */ be_nested_str_weak(HKDF_SHA256), /* K24 */ be_nested_str_weak(derive), /* K25 */ be_nested_str_weak(__spake_Ke), @@ -759,7 +762,7 @@ be_local_closure(Matter_Commisioning_Context_parse_Pake3, /* name */ }), be_str_weak(parse_Pake3), &be_const_str_solidified, - ( &(const binstruction[106]) { /* code */ + ( &(const binstruction[105]) { /* code */ 0xA40A0000, // 0000 IMPORT R2 K0 0x880C0301, // 0001 GETMBR R3 R1 K1 0x88100302, // 0002 GETMBR R4 R1 K2 @@ -786,25 +789,25 @@ be_local_closure(Matter_Commisioning_Context_parse_Pake3, /* name */ 0x5C180200, // 0017 MOVE R6 R1 0x581C000C, // 0018 LDCONST R7 K12 0x58200004, // 0019 LDCONST R8 K4 - 0x58240009, // 001A LDCONST R9 K9 + 0x5824000D, // 001A LDCONST R9 K13 0x50280000, // 001B LDBOOL R10 0 0 0x7C100C00, // 001C CALL R4 6 0x50100000, // 001D LDBOOL R4 0 0 0x80040800, // 001E RET 1 R4 - 0xB8121A00, // 001F GETNGBL R4 K13 - 0x8C10090E, // 0020 GETMET R4 R4 K14 + 0xB8121C00, // 001F GETNGBL R4 K14 + 0x8C10090F, // 0020 GETMET R4 R4 K15 0x7C100200, // 0021 CALL R4 1 - 0x8C10090F, // 0022 GETMET R4 R4 K15 - 0x88180310, // 0023 GETMBR R6 R1 K16 - 0x881C0311, // 0024 GETMBR R7 R1 K17 + 0x8C100910, // 0022 GETMET R4 R4 K16 + 0x88180311, // 0023 GETMBR R6 R1 K17 + 0x881C0312, // 0024 GETMBR R7 R1 K18 0x7C100600, // 0025 CALL R4 3 - 0x88140912, // 0026 GETMBR R5 R4 K18 - 0x88180713, // 0027 GETMBR R6 R3 K19 + 0x88140913, // 0026 GETMBR R5 R4 K19 + 0x88180714, // 0027 GETMBR R6 R3 K20 0x20180A06, // 0028 NE R6 R5 R6 0x781A0012, // 0029 JMPF R6 #003D 0xB81A0C00, // 002A GETNGBL R6 K6 0x8C180D07, // 002B GETMET R6 R6 K7 - 0x58200014, // 002C LDCONST R8 K20 + 0x58200015, // 002C LDCONST R8 K21 0x58240009, // 002D LDCONST R9 K9 0x7C180600, // 002E CALL R6 3 0xB81A0C00, // 002F GETNGBL R6 K6 @@ -816,56 +819,55 @@ be_local_closure(Matter_Commisioning_Context_parse_Pake3, /* name */ 0x5C200200, // 0035 MOVE R8 R1 0x5824000C, // 0036 LDCONST R9 K12 0x58280004, // 0037 LDCONST R10 K4 - 0x582C0009, // 0038 LDCONST R11 K9 + 0x582C000D, // 0038 LDCONST R11 K13 0x50300000, // 0039 LDBOOL R12 0 0 0x7C180C00, // 003A CALL R6 6 0x50180000, // 003B LDBOOL R6 0 0 0x80040C00, // 003C RET 1 R6 0xB81A0C00, // 003D GETNGBL R6 K6 - 0x8C180D15, // 003E GETMET R6 R6 K21 + 0x8C180D16, // 003E GETMET R6 R6 K22 0x7C180200, // 003F CALL R6 1 - 0x94180D16, // 0040 GETIDX R6 R6 K22 - 0x8C1C0517, // 0041 GETMET R7 R2 K23 - 0x7C1C0200, // 0042 CALL R7 1 - 0x8C1C0F18, // 0043 GETMET R7 R7 K24 - 0x88240719, // 0044 GETMBR R9 R3 K25 - 0x60280015, // 0045 GETGBL R10 G21 - 0x7C280000, // 0046 CALL R10 0 - 0x602C0015, // 0047 GETGBL R11 G21 - 0x7C2C0000, // 0048 CALL R11 0 - 0x8C2C171A, // 0049 GETMET R11 R11 K26 - 0x8834011B, // 004A GETMBR R13 R0 K27 - 0x7C2C0400, // 004B CALL R11 2 - 0x5432002F, // 004C LDINT R12 48 - 0x7C1C0A00, // 004D CALL R7 5 - 0x5422000E, // 004E LDINT R8 15 - 0x40220808, // 004F CONNECT R8 K4 R8 - 0x94200E08, // 0050 GETIDX R8 R7 R8 - 0x5426000F, // 0051 LDINT R9 16 - 0x542A001E, // 0052 LDINT R10 31 - 0x4024120A, // 0053 CONNECT R9 R9 R10 - 0x94240E09, // 0054 GETIDX R9 R7 R9 - 0x542A001F, // 0055 LDINT R10 32 - 0x542E002E, // 0056 LDINT R11 47 - 0x4028140B, // 0057 CONNECT R10 R10 R11 - 0x94280E0A, // 0058 GETIDX R10 R7 R10 - 0x8C2C010B, // 0059 GETMET R11 R0 K11 - 0x5C340200, // 005A MOVE R13 R1 - 0x58380004, // 005B LDCONST R14 K4 - 0x583C0004, // 005C LDCONST R15 K4 - 0x58400004, // 005D LDCONST R16 K4 - 0x50440000, // 005E LDBOOL R17 0 0 - 0x7C2C0C00, // 005F CALL R11 6 - 0x8C2C011C, // 0060 GETMET R11 R0 K28 - 0x8834071D, // 0061 GETMBR R13 R3 K29 - 0x8838071E, // 0062 GETMBR R14 R3 K30 - 0x5C3C1000, // 0063 MOVE R15 R8 - 0x5C401200, // 0064 MOVE R16 R9 - 0x5C441400, // 0065 MOVE R17 R10 - 0x5C480C00, // 0066 MOVE R18 R6 - 0x7C2C0E00, // 0067 CALL R11 7 - 0x502C0200, // 0068 LDBOOL R11 1 0 - 0x80041600, // 0069 RET 1 R11 + 0x8C1C0517, // 0040 GETMET R7 R2 K23 + 0x7C1C0200, // 0041 CALL R7 1 + 0x8C1C0F18, // 0042 GETMET R7 R7 K24 + 0x88240719, // 0043 GETMBR R9 R3 K25 + 0x60280015, // 0044 GETGBL R10 G21 + 0x7C280000, // 0045 CALL R10 0 + 0x602C0015, // 0046 GETGBL R11 G21 + 0x7C2C0000, // 0047 CALL R11 0 + 0x8C2C171A, // 0048 GETMET R11 R11 K26 + 0x8834011B, // 0049 GETMBR R13 R0 K27 + 0x7C2C0400, // 004A CALL R11 2 + 0x5432002F, // 004B LDINT R12 48 + 0x7C1C0A00, // 004C CALL R7 5 + 0x5422000E, // 004D LDINT R8 15 + 0x40220808, // 004E CONNECT R8 K4 R8 + 0x94200E08, // 004F GETIDX R8 R7 R8 + 0x5426000F, // 0050 LDINT R9 16 + 0x542A001E, // 0051 LDINT R10 31 + 0x4024120A, // 0052 CONNECT R9 R9 R10 + 0x94240E09, // 0053 GETIDX R9 R7 R9 + 0x542A001F, // 0054 LDINT R10 32 + 0x542E002E, // 0055 LDINT R11 47 + 0x4028140B, // 0056 CONNECT R10 R10 R11 + 0x94280E0A, // 0057 GETIDX R10 R7 R10 + 0x8C2C010B, // 0058 GETMET R11 R0 K11 + 0x5C340200, // 0059 MOVE R13 R1 + 0x58380004, // 005A LDCONST R14 K4 + 0x583C0004, // 005B LDCONST R15 K4 + 0x58400004, // 005C LDCONST R16 K4 + 0x50440000, // 005D LDBOOL R17 0 0 + 0x7C2C0C00, // 005E CALL R11 6 + 0x8C2C011C, // 005F GETMET R11 R0 K28 + 0x8834071D, // 0060 GETMBR R13 R3 K29 + 0x8838071E, // 0061 GETMBR R14 R3 K30 + 0x5C3C1000, // 0062 MOVE R15 R8 + 0x5C401200, // 0063 MOVE R16 R9 + 0x5C441400, // 0064 MOVE R17 R10 + 0x5C480C00, // 0065 MOVE R18 R6 + 0x7C2C0E00, // 0066 CALL R11 7 + 0x502C0200, // 0067 LDBOOL R11 1 0 + 0x80041600, // 0068 RET 1 R11 }) ) ); @@ -885,7 +887,7 @@ be_local_closure(Matter_Commisioning_Context_parse_Sigma3, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[69]) { /* constants */ + ( &(const bvalue[66]) { /* constants */ /* K0 */ be_nested_str_weak(crypto), /* K1 */ be_nested_str_weak(opcode), /* K2 */ be_nested_str_weak(local_session_id), @@ -894,71 +896,68 @@ be_local_closure(Matter_Commisioning_Context_parse_Sigma3, /* name */ /* K5 */ be_nested_str_weak(tasmota), /* K6 */ be_nested_str_weak(log), /* K7 */ be_nested_str_weak(MTR_X3A_X20StatusReport_X28General_X20Code_X3A_X20FAILURE_X2C_X20ProtocolId_X3A_X20SECURE_CHANNEL_X2C_X20ProtocolCode_X3A_X20INVALID_PARAMETER_X29), - /* K8 */ be_const_int(2), + /* K8 */ be_const_int(3), /* K9 */ be_nested_str_weak(send_status_report), /* K10 */ be_const_int(1), - /* K11 */ be_nested_str_weak(session), - /* K12 */ be_nested_str_weak(matter), - /* K13 */ be_nested_str_weak(Sigma3), - /* K14 */ be_nested_str_weak(parse), - /* K15 */ be_nested_str_weak(raw), - /* K16 */ be_nested_str_weak(app_payload_idx), - /* K17 */ be_nested_str_weak(SHA256), - /* K18 */ be_nested_str_weak(update), - /* K19 */ be_nested_str_weak(__Msg1), - /* K20 */ be_nested_str_weak(__Msg2), - /* K21 */ be_nested_str_weak(out), - /* K22 */ be_nested_str_weak(fromstring), - /* K23 */ be_nested_str_weak(S3K_Info), - /* K24 */ be_nested_str_weak(HKDF_SHA256), - /* K25 */ be_nested_str_weak(derive), - /* K26 */ be_nested_str_weak(shared_secret), - /* K27 */ be_nested_str_weak(get_ipk_group_key), - /* K28 */ be_nested_str_weak(TBEData3Encrypted), - /* K29 */ be_const_int(2147483647), - /* K30 */ be_nested_str_weak(AES_CCM), - /* K31 */ be_nested_str_weak(TBEData3_Nonce), - /* K32 */ be_nested_str_weak(decrypt), - /* K33 */ be_nested_str_weak(tag), - /* K34 */ be_nested_str_weak(MTR_X3A_X20Tag_X20don_X27t_X20match), - /* K35 */ be_nested_str_weak(TLV), - /* K36 */ be_nested_str_weak(findsubval), - /* K37 */ be_const_int(3), - /* K38 */ be_nested_str_weak(MTR_X3A_X20initiatorNOCTLV_X20_X3D_X20), - /* K39 */ be_nested_str_weak(findsub), - /* K40 */ be_nested_str_weak(int), - /* K41 */ be_nested_str_weak(peer_node_id), - /* K42 */ be_nested_str_weak(int64), - /* K43 */ be_nested_str_weak(fromu32), - /* K44 */ be_nested_str_weak(tobytes), - /* K45 */ be_nested_str_weak(MTR_X3A_X20initiatorFabricId_X3D), - /* K46 */ be_nested_str_weak(Matter_TLV_struct), - /* K47 */ be_nested_str_weak(add_TLV), - /* K48 */ be_nested_str_weak(B1), - /* K49 */ be_nested_str_weak(__initiator_pub), - /* K50 */ be_nested_str_weak(__responder_pub), - /* K51 */ be_nested_str_weak(tlv2raw), - /* K52 */ be_nested_str_weak(EC_P256), - /* K53 */ be_nested_str_weak(ecdsa_verify_sha256), - /* K54 */ be_nested_str_weak(MTR_X3A_X20sigma3_tbs_X20does_X20not_X20have_X20a_X20valid_X20signature), - /* K55 */ be_nested_str_weak(MTR_X3A_X20_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X20Invalid_X20signature_X2C_X20trying_X20anyways), - /* K56 */ be_nested_str_weak(MTR_X3A_X20Sigma3_X20verified_X2C_X20computing_X20new_X20keys), - /* K57 */ be_nested_str_weak(Msg3), - /* K58 */ be_nested_str_weak(SEKeys_Info), - /* K59 */ be_nested_str_weak(rtc), - /* K60 */ be_nested_str_weak(utc), - /* K61 */ be_nested_str_weak(close), - /* K62 */ be_nested_str_weak(set_keys), - /* K63 */ be_nested_str_weak(_breadcrumb), - /* K64 */ be_nested_str_weak(counter_snd_next), - /* K65 */ be_nested_str_weak(set_persist), - /* K66 */ be_nested_str_weak(set_no_expiration), - /* K67 */ be_nested_str_weak(persist_to_fabric), - /* K68 */ be_nested_str_weak(save), + /* K11 */ be_const_int(2), + /* K12 */ be_nested_str_weak(session), + /* K13 */ be_nested_str_weak(matter), + /* K14 */ be_nested_str_weak(Sigma3), + /* K15 */ be_nested_str_weak(parse), + /* K16 */ be_nested_str_weak(raw), + /* K17 */ be_nested_str_weak(app_payload_idx), + /* K18 */ be_nested_str_weak(SHA256), + /* K19 */ be_nested_str_weak(update), + /* K20 */ be_nested_str_weak(__Msg1), + /* K21 */ be_nested_str_weak(__Msg2), + /* K22 */ be_nested_str_weak(out), + /* K23 */ be_nested_str_weak(fromstring), + /* K24 */ be_nested_str_weak(S3K_Info), + /* K25 */ be_nested_str_weak(HKDF_SHA256), + /* K26 */ be_nested_str_weak(derive), + /* K27 */ be_nested_str_weak(shared_secret), + /* K28 */ be_nested_str_weak(get_ipk_group_key), + /* K29 */ be_nested_str_weak(TBEData3Encrypted), + /* K30 */ be_const_int(2147483647), + /* K31 */ be_nested_str_weak(AES_CCM), + /* K32 */ be_nested_str_weak(TBEData3_Nonce), + /* K33 */ be_nested_str_weak(decrypt), + /* K34 */ be_nested_str_weak(tag), + /* K35 */ be_nested_str_weak(MTR_X3A_X20Tag_X20don_X27t_X20match), + /* K36 */ be_nested_str_weak(TLV), + /* K37 */ be_nested_str_weak(findsubval), + /* K38 */ be_nested_str_weak(findsub), + /* K39 */ be_nested_str_weak(int), + /* K40 */ be_nested_str_weak(peer_node_id), + /* K41 */ be_nested_str_weak(int64), + /* K42 */ be_nested_str_weak(fromu32), + /* K43 */ be_nested_str_weak(tobytes), + /* K44 */ be_nested_str_weak(Matter_TLV_struct), + /* K45 */ be_nested_str_weak(add_TLV), + /* K46 */ be_nested_str_weak(B1), + /* K47 */ be_nested_str_weak(__initiator_pub), + /* K48 */ be_nested_str_weak(__responder_pub), + /* K49 */ be_nested_str_weak(tlv2raw), + /* K50 */ be_nested_str_weak(EC_P256), + /* K51 */ be_nested_str_weak(ecdsa_verify_sha256), + /* K52 */ be_nested_str_weak(MTR_X3A_X20sigma3_tbs_X20does_X20not_X20have_X20a_X20valid_X20signature), + /* K53 */ be_nested_str_weak(MTR_X3A_X20_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X2A_X20Invalid_X20signature_X2C_X20trying_X20anyways), + /* K54 */ be_nested_str_weak(MTR_X3A_X20Sigma3_X20verified_X2C_X20computing_X20new_X20keys), + /* K55 */ be_nested_str_weak(Msg3), + /* K56 */ be_nested_str_weak(SEKeys_Info), + /* K57 */ be_nested_str_weak(rtc_utc), + /* K58 */ be_nested_str_weak(close), + /* K59 */ be_nested_str_weak(set_keys), + /* K60 */ be_nested_str_weak(_breadcrumb), + /* K61 */ be_nested_str_weak(counter_snd_next), + /* K62 */ be_nested_str_weak(set_persist), + /* K63 */ be_nested_str_weak(set_no_expiration), + /* K64 */ be_nested_str_weak(persist_to_fabric), + /* K65 */ be_nested_str_weak(save), }), be_str_weak(parse_Sigma3), &be_const_str_solidified, - ( &(const binstruction[303]) { /* code */ + ( &(const binstruction[286]) { /* code */ 0xA40A0000, // 0000 IMPORT R2 K0 0x880C0301, // 0001 GETMBR R3 R1 K1 0x54120031, // 0002 LDINT R4 50 @@ -979,39 +978,39 @@ be_local_closure(Matter_Commisioning_Context_parse_Sigma3, /* name */ 0x5C140200, // 0011 MOVE R5 R1 0x5818000A, // 0012 LDCONST R6 K10 0x581C0003, // 0013 LDCONST R7 K3 - 0x58200008, // 0014 LDCONST R8 K8 + 0x5820000B, // 0014 LDCONST R8 K11 0x50240000, // 0015 LDBOOL R9 0 0 0x7C0C0C00, // 0016 CALL R3 6 0x500C0000, // 0017 LDBOOL R3 0 0 0x80040600, // 0018 RET 1 R3 - 0x880C030B, // 0019 GETMBR R3 R1 K11 - 0xB8121800, // 001A GETNGBL R4 K12 - 0x8C10090D, // 001B GETMET R4 R4 K13 + 0x880C030C, // 0019 GETMBR R3 R1 K12 + 0xB8121A00, // 001A GETNGBL R4 K13 + 0x8C10090E, // 001B GETMET R4 R4 K14 0x7C100200, // 001C CALL R4 1 - 0x8C10090E, // 001D GETMET R4 R4 K14 - 0x8818030F, // 001E GETMBR R6 R1 K15 - 0x881C0310, // 001F GETMBR R7 R1 K16 + 0x8C10090F, // 001D GETMET R4 R4 K15 + 0x88180310, // 001E GETMBR R6 R1 K16 + 0x881C0311, // 001F GETMBR R7 R1 K17 0x7C100600, // 0020 CALL R4 3 - 0x8C140511, // 0021 GETMET R5 R2 K17 + 0x8C140512, // 0021 GETMET R5 R2 K18 0x7C140200, // 0022 CALL R5 1 - 0x8C140B12, // 0023 GETMET R5 R5 K18 - 0x881C0713, // 0024 GETMBR R7 R3 K19 + 0x8C140B13, // 0023 GETMET R5 R5 K19 + 0x881C0714, // 0024 GETMBR R7 R3 K20 0x7C140400, // 0025 CALL R5 2 - 0x8C140B12, // 0026 GETMET R5 R5 K18 - 0x881C0714, // 0027 GETMBR R7 R3 K20 + 0x8C140B13, // 0026 GETMET R5 R5 K19 + 0x881C0715, // 0027 GETMBR R7 R3 K21 0x7C140400, // 0028 CALL R5 2 - 0x8C140B15, // 0029 GETMET R5 R5 K21 + 0x8C140B16, // 0029 GETMET R5 R5 K22 0x7C140200, // 002A CALL R5 1 0x60180015, // 002B GETGBL R6 G21 0x7C180000, // 002C CALL R6 0 - 0x8C180D16, // 002D GETMET R6 R6 K22 - 0x88200117, // 002E GETMBR R8 R0 K23 + 0x8C180D17, // 002D GETMET R6 R6 K23 + 0x88200118, // 002E GETMBR R8 R0 K24 0x7C180400, // 002F CALL R6 2 - 0x8C1C0518, // 0030 GETMET R7 R2 K24 + 0x8C1C0519, // 0030 GETMET R7 R2 K25 0x7C1C0200, // 0031 CALL R7 1 - 0x8C1C0F19, // 0032 GETMET R7 R7 K25 - 0x8824071A, // 0033 GETMBR R9 R3 K26 - 0x8C28071B, // 0034 GETMET R10 R3 K27 + 0x8C1C0F1A, // 0032 GETMET R7 R7 K26 + 0x8824071B, // 0033 GETMBR R9 R3 K27 + 0x8C28071C, // 0034 GETMET R10 R3 K28 0x7C280200, // 0035 CALL R10 1 0x00281405, // 0036 ADD R10 R10 R5 0x5C2C0C00, // 0037 MOVE R11 R6 @@ -1019,18 +1018,18 @@ be_local_closure(Matter_Commisioning_Context_parse_Sigma3, /* name */ 0x7C1C0A00, // 0039 CALL R7 5 0x5421FFEE, // 003A LDINT R8 -17 0x40220608, // 003B CONNECT R8 K3 R8 - 0x8824091C, // 003C GETMBR R9 R4 K28 + 0x8824091D, // 003C GETMBR R9 R4 K29 0x94201208, // 003D GETIDX R8 R9 R8 0x5429FFEF, // 003E LDINT R10 -16 - 0x4028151D, // 003F CONNECT R10 R10 K29 - 0x882C091C, // 0040 GETMBR R11 R4 K28 + 0x4028151E, // 003F CONNECT R10 R10 K30 + 0x882C091D, // 0040 GETMBR R11 R4 K29 0x9424160A, // 0041 GETIDX R9 R11 R10 - 0x8C30051E, // 0042 GETMET R12 R2 K30 + 0x8C30051F, // 0042 GETMET R12 R2 K31 0x5C380E00, // 0043 MOVE R14 R7 0x603C0015, // 0044 GETGBL R15 G21 0x7C3C0000, // 0045 CALL R15 0 - 0x8C3C1F16, // 0046 GETMET R15 R15 K22 - 0x8844011F, // 0047 GETMBR R17 R0 K31 + 0x8C3C1F17, // 0046 GETMET R15 R15 K23 + 0x88440120, // 0047 GETMBR R17 R0 K32 0x7C3C0400, // 0048 CALL R15 2 0x60400015, // 0049 GETGBL R16 G21 0x7C400000, // 004A CALL R16 0 @@ -1040,17 +1039,17 @@ be_local_closure(Matter_Commisioning_Context_parse_Sigma3, /* name */ 0x544A000F, // 004E LDINT R18 16 0x7C300C00, // 004F CALL R12 6 0x5C281800, // 0050 MOVE R10 R12 - 0x8C301520, // 0051 GETMET R12 R10 K32 + 0x8C301521, // 0051 GETMET R12 R10 K33 0x5C381000, // 0052 MOVE R14 R8 0x7C300400, // 0053 CALL R12 2 0x5C2C1800, // 0054 MOVE R11 R12 - 0x8C301521, // 0055 GETMET R12 R10 K33 + 0x8C301522, // 0055 GETMET R12 R10 K34 0x7C300200, // 0056 CALL R12 1 0x20341809, // 0057 NE R13 R12 R9 0x78360012, // 0058 JMPF R13 #006C 0xB8360A00, // 0059 GETNGBL R13 K5 0x8C341B06, // 005A GETMET R13 R13 K6 - 0x583C0022, // 005B LDCONST R15 K34 + 0x583C0023, // 005B LDCONST R15 K35 0x58400008, // 005C LDCONST R16 K8 0x7C340600, // 005D CALL R13 3 0xB8360A00, // 005E GETNGBL R13 K5 @@ -1062,206 +1061,189 @@ be_local_closure(Matter_Commisioning_Context_parse_Sigma3, /* name */ 0x5C3C0200, // 0064 MOVE R15 R1 0x5840000A, // 0065 LDCONST R16 K10 0x58440003, // 0066 LDCONST R17 K3 - 0x58480008, // 0067 LDCONST R18 K8 + 0x5848000B, // 0067 LDCONST R18 K11 0x504C0000, // 0068 LDBOOL R19 0 0 0x7C340C00, // 0069 CALL R13 6 0x50340000, // 006A LDBOOL R13 0 0 0x80041A00, // 006B RET 1 R13 - 0xB8361800, // 006C GETNGBL R13 K12 - 0x88341B23, // 006D GETMBR R13 R13 K35 - 0x8C341B0E, // 006E GETMET R13 R13 K14 + 0xB8361A00, // 006C GETNGBL R13 K13 + 0x88341B24, // 006D GETMBR R13 R13 K36 + 0x8C341B0F, // 006E GETMET R13 R13 K15 0x5C3C1600, // 006F MOVE R15 R11 0x7C340400, // 0070 CALL R13 2 - 0x8C381B24, // 0071 GETMET R14 R13 K36 + 0x8C381B25, // 0071 GETMET R14 R13 K37 0x5840000A, // 0072 LDCONST R16 K10 0x7C380400, // 0073 CALL R14 2 - 0x8C3C1B24, // 0074 GETMET R15 R13 K36 - 0x58440008, // 0075 LDCONST R17 K8 + 0x8C3C1B25, // 0074 GETMET R15 R13 K37 + 0x5844000B, // 0075 LDCONST R17 K11 0x7C3C0400, // 0076 CALL R15 2 - 0x8C401B24, // 0077 GETMET R16 R13 K36 - 0x58480025, // 0078 LDCONST R18 K37 + 0x8C401B25, // 0077 GETMET R16 R13 K37 + 0x58480008, // 0078 LDCONST R18 K8 0x7C400400, // 0079 CALL R16 2 - 0xB8461800, // 007A GETNGBL R17 K12 - 0x88442323, // 007B GETMBR R17 R17 K35 - 0x8C44230E, // 007C GETMET R17 R17 K14 + 0xB8461A00, // 007A GETNGBL R17 K13 + 0x88442324, // 007B GETMBR R17 R17 K36 + 0x8C44230F, // 007C GETMET R17 R17 K15 0x5C4C1C00, // 007D MOVE R19 R14 0x7C440400, // 007E CALL R17 2 - 0xB84A0A00, // 007F GETNGBL R18 K5 - 0x8C482506, // 0080 GETMET R18 R18 K6 - 0x60500008, // 0081 GETGBL R20 G8 - 0x5C542200, // 0082 MOVE R21 R17 - 0x7C500200, // 0083 CALL R20 1 - 0x00524C14, // 0084 ADD R20 K38 R20 - 0x58540025, // 0085 LDCONST R21 K37 - 0x7C480600, // 0086 CALL R18 3 - 0x8C482324, // 0087 GETMET R18 R17 K36 - 0x54520008, // 0088 LDINT R20 9 - 0x7C480400, // 0089 CALL R18 2 - 0x8C4C2327, // 008A GETMET R19 R17 K39 - 0x54560005, // 008B LDINT R21 6 - 0x7C4C0400, // 008C CALL R19 2 - 0x8C502724, // 008D GETMET R20 R19 K36 - 0x545A0010, // 008E LDINT R22 17 - 0x7C500400, // 008F CALL R20 2 - 0x60540004, // 0090 GETGBL R21 G4 - 0x5C582800, // 0091 MOVE R22 R20 + 0x8C482325, // 007F GETMET R18 R17 K37 + 0x54520008, // 0080 LDINT R20 9 + 0x7C480400, // 0081 CALL R18 2 + 0x8C4C2326, // 0082 GETMET R19 R17 K38 + 0x54560005, // 0083 LDINT R21 6 + 0x7C4C0400, // 0084 CALL R19 2 + 0x8C502725, // 0085 GETMET R20 R19 K37 + 0x545A0010, // 0086 LDINT R22 17 + 0x7C500400, // 0087 CALL R20 2 + 0x60540004, // 0088 GETGBL R21 G4 + 0x5C582800, // 0089 MOVE R22 R20 + 0x7C540200, // 008A CALL R21 1 + 0x1C542B27, // 008B EQ R21 R21 K39 + 0x78560007, // 008C JMPF R21 #0095 + 0xB8565200, // 008D GETNGBL R21 K41 + 0x8C542B2A, // 008E GETMET R21 R21 K42 + 0x5C5C2800, // 008F MOVE R23 R20 + 0x7C540400, // 0090 CALL R21 2 + 0x8C542B2B, // 0091 GETMET R21 R21 K43 0x7C540200, // 0092 CALL R21 1 - 0x1C542B28, // 0093 EQ R21 R21 K40 - 0x78560007, // 0094 JMPF R21 #009D - 0xB8565400, // 0095 GETNGBL R21 K42 - 0x8C542B2B, // 0096 GETMET R21 R21 K43 - 0x5C5C2800, // 0097 MOVE R23 R20 - 0x7C540400, // 0098 CALL R21 2 - 0x8C542B2C, // 0099 GETMET R21 R21 K44 - 0x7C540200, // 009A CALL R21 1 - 0x900E5215, // 009B SETMBR R3 K41 R21 - 0x70020002, // 009C JMP #00A0 - 0x8C54292C, // 009D GETMET R21 R20 K44 - 0x7C540200, // 009E CALL R21 1 - 0x900E5215, // 009F SETMBR R3 K41 R21 - 0xB8560A00, // 00A0 GETNGBL R21 K5 - 0x8C542B06, // 00A1 GETMET R21 R21 K6 - 0x605C0008, // 00A2 GETGBL R23 G8 - 0x88600729, // 00A3 GETMBR R24 R3 K41 - 0x7C5C0200, // 00A4 CALL R23 1 - 0x005E5A17, // 00A5 ADD R23 K45 R23 - 0x58600025, // 00A6 LDCONST R24 K37 - 0x7C540600, // 00A7 CALL R21 3 - 0xB8561800, // 00A8 GETNGBL R21 K12 - 0x88542B23, // 00A9 GETMBR R21 R21 K35 - 0x8C542B2E, // 00AA GETMET R21 R21 K46 - 0x7C540200, // 00AB CALL R21 1 - 0x8C582B2F, // 00AC GETMET R22 R21 K47 - 0x5860000A, // 00AD LDCONST R24 K10 - 0xB8661800, // 00AE GETNGBL R25 K12 - 0x88643323, // 00AF GETMBR R25 R25 K35 - 0x88643330, // 00B0 GETMBR R25 R25 K48 - 0x5C681C00, // 00B1 MOVE R26 R14 - 0x7C580800, // 00B2 CALL R22 4 - 0x8C582B2F, // 00B3 GETMET R22 R21 K47 - 0x58600008, // 00B4 LDCONST R24 K8 - 0xB8661800, // 00B5 GETNGBL R25 K12 - 0x88643323, // 00B6 GETMBR R25 R25 K35 - 0x88643330, // 00B7 GETMBR R25 R25 K48 - 0x5C681E00, // 00B8 MOVE R26 R15 - 0x7C580800, // 00B9 CALL R22 4 - 0x8C582B2F, // 00BA GETMET R22 R21 K47 - 0x58600025, // 00BB LDCONST R24 K37 - 0xB8661800, // 00BC GETNGBL R25 K12 - 0x88643323, // 00BD GETMBR R25 R25 K35 - 0x88643330, // 00BE GETMBR R25 R25 K48 - 0x88680731, // 00BF GETMBR R26 R3 K49 - 0x7C580800, // 00C0 CALL R22 4 - 0x8C582B2F, // 00C1 GETMET R22 R21 K47 - 0x54620003, // 00C2 LDINT R24 4 - 0xB8661800, // 00C3 GETNGBL R25 K12 - 0x88643323, // 00C4 GETMBR R25 R25 K35 - 0x88643330, // 00C5 GETMBR R25 R25 K48 - 0x88680732, // 00C6 GETMBR R26 R3 K50 - 0x7C580800, // 00C7 CALL R22 4 - 0x8C582B33, // 00C8 GETMET R22 R21 K51 - 0x7C580200, // 00C9 CALL R22 1 - 0x8C5C0534, // 00CA GETMET R23 R2 K52 - 0x7C5C0200, // 00CB CALL R23 1 - 0x8C5C2F35, // 00CC GETMET R23 R23 K53 - 0x5C642400, // 00CD MOVE R25 R18 - 0x5C682C00, // 00CE MOVE R26 R22 - 0x5C6C2000, // 00CF MOVE R27 R16 - 0x7C5C0800, // 00D0 CALL R23 4 - 0x5C602E00, // 00D1 MOVE R24 R23 - 0x7462000A, // 00D2 JMPT R24 #00DE - 0xB8620A00, // 00D3 GETNGBL R24 K5 - 0x8C603106, // 00D4 GETMET R24 R24 K6 - 0x58680036, // 00D5 LDCONST R26 K54 - 0x586C0008, // 00D6 LDCONST R27 K8 - 0x7C600600, // 00D7 CALL R24 3 - 0xB8620A00, // 00D8 GETNGBL R24 K5 - 0x8C603106, // 00D9 GETMET R24 R24 K6 - 0x58680037, // 00DA LDCONST R26 K55 - 0x586C0008, // 00DB LDCONST R27 K8 - 0x7C600600, // 00DC CALL R24 3 - 0x70020004, // 00DD JMP #00E3 - 0xB8620A00, // 00DE GETNGBL R24 K5 - 0x8C603106, // 00DF GETMET R24 R24 K6 - 0x58680038, // 00E0 LDCONST R26 K56 - 0x586C0025, // 00E1 LDCONST R27 K37 - 0x7C600600, // 00E2 CALL R24 3 - 0x8C600511, // 00E3 GETMET R24 R2 K17 - 0x7C600200, // 00E4 CALL R24 1 - 0x8C603112, // 00E5 GETMET R24 R24 K18 - 0x88680713, // 00E6 GETMBR R26 R3 K19 - 0x7C600400, // 00E7 CALL R24 2 - 0x8C603112, // 00E8 GETMET R24 R24 K18 - 0x88680714, // 00E9 GETMBR R26 R3 K20 - 0x7C600400, // 00EA CALL R24 2 - 0x8C603112, // 00EB GETMET R24 R24 K18 - 0x88680939, // 00EC GETMBR R26 R4 K57 - 0x7C600400, // 00ED CALL R24 2 - 0x8C603115, // 00EE GETMET R24 R24 K21 - 0x7C600200, // 00EF CALL R24 1 - 0x5C143000, // 00F0 MOVE R5 R24 - 0x4C600000, // 00F1 LDNIL R24 - 0x900E2618, // 00F2 SETMBR R3 K19 R24 - 0x4C600000, // 00F3 LDNIL R24 - 0x900E2818, // 00F4 SETMBR R3 K20 R24 - 0x8C600518, // 00F5 GETMET R24 R2 K24 - 0x7C600200, // 00F6 CALL R24 1 - 0x8C603119, // 00F7 GETMET R24 R24 K25 - 0x8868071A, // 00F8 GETMBR R26 R3 K26 - 0x8C6C071B, // 00F9 GETMET R27 R3 K27 - 0x7C6C0200, // 00FA CALL R27 1 - 0x006C3605, // 00FB ADD R27 R27 R5 - 0x60700015, // 00FC GETGBL R28 G21 - 0x7C700000, // 00FD CALL R28 0 - 0x8C703916, // 00FE GETMET R28 R28 K22 - 0x8878013A, // 00FF GETMBR R30 R0 K58 - 0x7C700400, // 0100 CALL R28 2 - 0x5476002F, // 0101 LDINT R29 48 - 0x7C600A00, // 0102 CALL R24 5 - 0x5466000E, // 0103 LDINT R25 15 - 0x40660619, // 0104 CONNECT R25 K3 R25 - 0x94643019, // 0105 GETIDX R25 R24 R25 - 0x546A000F, // 0106 LDINT R26 16 - 0x546E001E, // 0107 LDINT R27 31 - 0x4068341B, // 0108 CONNECT R26 R26 R27 - 0x9468301A, // 0109 GETIDX R26 R24 R26 - 0x546E001F, // 010A LDINT R27 32 - 0x5472002E, // 010B LDINT R28 47 - 0x406C361C, // 010C CONNECT R27 R27 R28 - 0x946C301B, // 010D GETIDX R27 R24 R27 - 0xB8720A00, // 010E GETNGBL R28 K5 - 0x8C70393B, // 010F GETMET R28 R28 K59 - 0x7C700200, // 0110 CALL R28 1 - 0x9470393C, // 0111 GETIDX R28 R28 K60 - 0x8C740109, // 0112 GETMET R29 R0 K9 - 0x5C7C0200, // 0113 MOVE R31 R1 - 0x58800003, // 0114 LDCONST R32 K3 - 0x58840003, // 0115 LDCONST R33 K3 - 0x58880003, // 0116 LDCONST R34 K3 - 0x508C0200, // 0117 LDBOOL R35 1 0 - 0x7C740C00, // 0118 CALL R29 6 - 0x8C74073D, // 0119 GETMET R29 R3 K61 - 0x7C740200, // 011A CALL R29 1 - 0x8C74073E, // 011B GETMET R29 R3 K62 - 0x5C7C3200, // 011C MOVE R31 R25 - 0x5C803400, // 011D MOVE R32 R26 - 0x5C843600, // 011E MOVE R33 R27 - 0x5C883800, // 011F MOVE R34 R28 - 0x7C740A00, // 0120 CALL R29 5 - 0x900E7F03, // 0121 SETMBR R3 K63 K3 - 0x8C740740, // 0122 GETMET R29 R3 K64 - 0x7C740200, // 0123 CALL R29 1 - 0x8C740741, // 0124 GETMET R29 R3 K65 - 0x507C0200, // 0125 LDBOOL R31 1 0 - 0x7C740400, // 0126 CALL R29 2 - 0x8C740742, // 0127 GETMET R29 R3 K66 - 0x7C740200, // 0128 CALL R29 1 - 0x8C740743, // 0129 GETMET R29 R3 K67 - 0x7C740200, // 012A CALL R29 1 - 0x8C740744, // 012B GETMET R29 R3 K68 - 0x7C740200, // 012C CALL R29 1 - 0x50740200, // 012D LDBOOL R29 1 0 - 0x80043A00, // 012E RET 1 R29 + 0x900E5015, // 0093 SETMBR R3 K40 R21 + 0x70020002, // 0094 JMP #0098 + 0x8C54292B, // 0095 GETMET R21 R20 K43 + 0x7C540200, // 0096 CALL R21 1 + 0x900E5015, // 0097 SETMBR R3 K40 R21 + 0xB8561A00, // 0098 GETNGBL R21 K13 + 0x88542B24, // 0099 GETMBR R21 R21 K36 + 0x8C542B2C, // 009A GETMET R21 R21 K44 + 0x7C540200, // 009B CALL R21 1 + 0x8C582B2D, // 009C GETMET R22 R21 K45 + 0x5860000A, // 009D LDCONST R24 K10 + 0xB8661A00, // 009E GETNGBL R25 K13 + 0x88643324, // 009F GETMBR R25 R25 K36 + 0x8864332E, // 00A0 GETMBR R25 R25 K46 + 0x5C681C00, // 00A1 MOVE R26 R14 + 0x7C580800, // 00A2 CALL R22 4 + 0x8C582B2D, // 00A3 GETMET R22 R21 K45 + 0x5860000B, // 00A4 LDCONST R24 K11 + 0xB8661A00, // 00A5 GETNGBL R25 K13 + 0x88643324, // 00A6 GETMBR R25 R25 K36 + 0x8864332E, // 00A7 GETMBR R25 R25 K46 + 0x5C681E00, // 00A8 MOVE R26 R15 + 0x7C580800, // 00A9 CALL R22 4 + 0x8C582B2D, // 00AA GETMET R22 R21 K45 + 0x58600008, // 00AB LDCONST R24 K8 + 0xB8661A00, // 00AC GETNGBL R25 K13 + 0x88643324, // 00AD GETMBR R25 R25 K36 + 0x8864332E, // 00AE GETMBR R25 R25 K46 + 0x8868072F, // 00AF GETMBR R26 R3 K47 + 0x7C580800, // 00B0 CALL R22 4 + 0x8C582B2D, // 00B1 GETMET R22 R21 K45 + 0x54620003, // 00B2 LDINT R24 4 + 0xB8661A00, // 00B3 GETNGBL R25 K13 + 0x88643324, // 00B4 GETMBR R25 R25 K36 + 0x8864332E, // 00B5 GETMBR R25 R25 K46 + 0x88680730, // 00B6 GETMBR R26 R3 K48 + 0x7C580800, // 00B7 CALL R22 4 + 0x8C582B31, // 00B8 GETMET R22 R21 K49 + 0x7C580200, // 00B9 CALL R22 1 + 0x8C5C0532, // 00BA GETMET R23 R2 K50 + 0x7C5C0200, // 00BB CALL R23 1 + 0x8C5C2F33, // 00BC GETMET R23 R23 K51 + 0x5C642400, // 00BD MOVE R25 R18 + 0x5C682C00, // 00BE MOVE R26 R22 + 0x5C6C2000, // 00BF MOVE R27 R16 + 0x7C5C0800, // 00C0 CALL R23 4 + 0x5C602E00, // 00C1 MOVE R24 R23 + 0x7462000A, // 00C2 JMPT R24 #00CE + 0xB8620A00, // 00C3 GETNGBL R24 K5 + 0x8C603106, // 00C4 GETMET R24 R24 K6 + 0x58680034, // 00C5 LDCONST R26 K52 + 0x586C000B, // 00C6 LDCONST R27 K11 + 0x7C600600, // 00C7 CALL R24 3 + 0xB8620A00, // 00C8 GETNGBL R24 K5 + 0x8C603106, // 00C9 GETMET R24 R24 K6 + 0x58680035, // 00CA LDCONST R26 K53 + 0x586C000B, // 00CB LDCONST R27 K11 + 0x7C600600, // 00CC CALL R24 3 + 0x70020004, // 00CD JMP #00D3 + 0xB8620A00, // 00CE GETNGBL R24 K5 + 0x8C603106, // 00CF GETMET R24 R24 K6 + 0x58680036, // 00D0 LDCONST R26 K54 + 0x586C0008, // 00D1 LDCONST R27 K8 + 0x7C600600, // 00D2 CALL R24 3 + 0x8C600512, // 00D3 GETMET R24 R2 K18 + 0x7C600200, // 00D4 CALL R24 1 + 0x8C603113, // 00D5 GETMET R24 R24 K19 + 0x88680714, // 00D6 GETMBR R26 R3 K20 + 0x7C600400, // 00D7 CALL R24 2 + 0x8C603113, // 00D8 GETMET R24 R24 K19 + 0x88680715, // 00D9 GETMBR R26 R3 K21 + 0x7C600400, // 00DA CALL R24 2 + 0x8C603113, // 00DB GETMET R24 R24 K19 + 0x88680937, // 00DC GETMBR R26 R4 K55 + 0x7C600400, // 00DD CALL R24 2 + 0x8C603116, // 00DE GETMET R24 R24 K22 + 0x7C600200, // 00DF CALL R24 1 + 0x5C143000, // 00E0 MOVE R5 R24 + 0x4C600000, // 00E1 LDNIL R24 + 0x900E2818, // 00E2 SETMBR R3 K20 R24 + 0x4C600000, // 00E3 LDNIL R24 + 0x900E2A18, // 00E4 SETMBR R3 K21 R24 + 0x8C600519, // 00E5 GETMET R24 R2 K25 + 0x7C600200, // 00E6 CALL R24 1 + 0x8C60311A, // 00E7 GETMET R24 R24 K26 + 0x8868071B, // 00E8 GETMBR R26 R3 K27 + 0x8C6C071C, // 00E9 GETMET R27 R3 K28 + 0x7C6C0200, // 00EA CALL R27 1 + 0x006C3605, // 00EB ADD R27 R27 R5 + 0x60700015, // 00EC GETGBL R28 G21 + 0x7C700000, // 00ED CALL R28 0 + 0x8C703917, // 00EE GETMET R28 R28 K23 + 0x88780138, // 00EF GETMBR R30 R0 K56 + 0x7C700400, // 00F0 CALL R28 2 + 0x5476002F, // 00F1 LDINT R29 48 + 0x7C600A00, // 00F2 CALL R24 5 + 0x5466000E, // 00F3 LDINT R25 15 + 0x40660619, // 00F4 CONNECT R25 K3 R25 + 0x94643019, // 00F5 GETIDX R25 R24 R25 + 0x546A000F, // 00F6 LDINT R26 16 + 0x546E001E, // 00F7 LDINT R27 31 + 0x4068341B, // 00F8 CONNECT R26 R26 R27 + 0x9468301A, // 00F9 GETIDX R26 R24 R26 + 0x546E001F, // 00FA LDINT R27 32 + 0x5472002E, // 00FB LDINT R28 47 + 0x406C361C, // 00FC CONNECT R27 R27 R28 + 0x946C301B, // 00FD GETIDX R27 R24 R27 + 0xB8720A00, // 00FE GETNGBL R28 K5 + 0x8C703939, // 00FF GETMET R28 R28 K57 + 0x7C700200, // 0100 CALL R28 1 + 0x8C740109, // 0101 GETMET R29 R0 K9 + 0x5C7C0200, // 0102 MOVE R31 R1 + 0x58800003, // 0103 LDCONST R32 K3 + 0x58840003, // 0104 LDCONST R33 K3 + 0x58880003, // 0105 LDCONST R34 K3 + 0x508C0200, // 0106 LDBOOL R35 1 0 + 0x7C740C00, // 0107 CALL R29 6 + 0x8C74073A, // 0108 GETMET R29 R3 K58 + 0x7C740200, // 0109 CALL R29 1 + 0x8C74073B, // 010A GETMET R29 R3 K59 + 0x5C7C3200, // 010B MOVE R31 R25 + 0x5C803400, // 010C MOVE R32 R26 + 0x5C843600, // 010D MOVE R33 R27 + 0x5C883800, // 010E MOVE R34 R28 + 0x7C740A00, // 010F CALL R29 5 + 0x900E7903, // 0110 SETMBR R3 K60 K3 + 0x8C74073D, // 0111 GETMET R29 R3 K61 + 0x7C740200, // 0112 CALL R29 1 + 0x8C74073E, // 0113 GETMET R29 R3 K62 + 0x507C0200, // 0114 LDBOOL R31 1 0 + 0x7C740400, // 0115 CALL R29 2 + 0x8C74073F, // 0116 GETMET R29 R3 K63 + 0x7C740200, // 0117 CALL R29 1 + 0x8C740740, // 0118 GETMET R29 R3 K64 + 0x7C740200, // 0119 CALL R29 1 + 0x8C740741, // 011A GETMET R29 R3 K65 + 0x7C740200, // 011B CALL R29 1 + 0x50740200, // 011C LDBOOL R29 1 0 + 0x80043A00, // 011D RET 1 R29 }) ) ); @@ -1273,7 +1255,7 @@ be_local_closure(Matter_Commisioning_Context_parse_Sigma3, /* name */ ********************************************************************/ be_local_closure(Matter_Commisioning_Context_process_incoming, /* name */ be_nested_proto( - 9, /* nstack */ + 7, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1281,7 +1263,7 @@ be_local_closure(Matter_Commisioning_Context_process_incoming, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[20]) { /* constants */ + ( &(const bvalue[14]) { /* constants */ /* K0 */ be_nested_str_weak(device), /* K1 */ be_nested_str_weak(is_commissioning_open), /* K2 */ be_nested_str_weak(opcode), @@ -1289,23 +1271,17 @@ be_local_closure(Matter_Commisioning_Context_process_incoming, /* name */ /* K4 */ be_nested_str_weak(log), /* K5 */ be_nested_str_weak(MTR_X3A_X20commissioning_X20not_X20open), /* K6 */ be_const_int(2), - /* K7 */ be_nested_str_weak(MTR_X3A_X20received_X20message_X20), - /* K8 */ be_nested_str_weak(matter), - /* K9 */ be_nested_str_weak(inspect), - /* K10 */ be_const_int(3), - /* K11 */ be_nested_str_weak(parse_PBKDFParamRequest), - /* K12 */ be_nested_str_weak(parse_Pake1), - /* K13 */ be_nested_str_weak(parse_Pake3), - /* K14 */ be_nested_str_weak(parse_Sigma1), - /* K15 */ be_nested_str_weak(parse_Sigma3), - /* K16 */ be_nested_str_weak(parse_StatusReport), - /* K17 */ be_nested_str_weak(string), - /* K18 */ be_nested_str_weak(format), - /* K19 */ be_nested_str_weak(MTR_X3A_X20_X3E_X3F_X3F_X3F_X3F_X3F_X3F_X3F_X3F_X3F_X20Unknown_X20OpCode_X20_X28secure_X20channel_X29_X20_X2502X), + /* K7 */ be_nested_str_weak(parse_PBKDFParamRequest), + /* K8 */ be_nested_str_weak(parse_Pake1), + /* K9 */ be_nested_str_weak(parse_Pake3), + /* K10 */ be_nested_str_weak(parse_Sigma1), + /* K11 */ be_nested_str_weak(parse_Sigma3), + /* K12 */ be_nested_str_weak(parse_StatusReport), + /* K13 */ be_nested_str_weak(MTR_X3A_X20_X3E_X3F_X3F_X3F_X3F_X3F_X3F_X3F_X3F_X3F_X20Unknown_X20OpCode_X20_X28secure_X20channel_X29_X20_X2502X), }), be_str_weak(process_incoming), &be_const_str_solidified, - ( &(const binstruction[100]) { /* code */ + ( &(const binstruction[90]) { /* code */ 0x88080100, // 0000 GETMBR R2 R0 K0 0x8C080501, // 0001 GETMET R2 R2 K1 0x7C080200, // 0002 CALL R2 1 @@ -1325,87 +1301,77 @@ be_local_closure(Matter_Commisioning_Context_process_incoming, /* name */ 0x7C080600, // 0010 CALL R2 3 0x50080000, // 0011 LDBOOL R2 0 0 0x80040400, // 0012 RET 1 R2 - 0xB80A0600, // 0013 GETNGBL R2 K3 - 0x8C080504, // 0014 GETMET R2 R2 K4 - 0xB8121000, // 0015 GETNGBL R4 K8 - 0x8C100909, // 0016 GETMET R4 R4 K9 - 0x5C180200, // 0017 MOVE R6 R1 - 0x7C100400, // 0018 CALL R4 2 - 0x00120E04, // 0019 ADD R4 K7 R4 - 0x5814000A, // 001A LDCONST R5 K10 - 0x7C080600, // 001B CALL R2 3 - 0x88080302, // 001C GETMBR R2 R1 K2 - 0x540E000F, // 001D LDINT R3 16 - 0x1C080403, // 001E EQ R2 R2 R3 - 0x780A0000, // 001F JMPF R2 #0021 - 0x70020040, // 0020 JMP #0062 + 0x88080302, // 0013 GETMBR R2 R1 K2 + 0x540E000F, // 0014 LDINT R3 16 + 0x1C080403, // 0015 EQ R2 R2 R3 + 0x780A0000, // 0016 JMPF R2 #0018 + 0x7002003F, // 0017 JMP #0058 + 0x88080302, // 0018 GETMBR R2 R1 K2 + 0x540E001F, // 0019 LDINT R3 32 + 0x1C080403, // 001A EQ R2 R2 R3 + 0x780A0004, // 001B JMPF R2 #0021 + 0x8C080107, // 001C GETMET R2 R0 K7 + 0x5C100200, // 001D MOVE R4 R1 + 0x7C080400, // 001E CALL R2 2 + 0x80040400, // 001F RET 1 R2 + 0x70020036, // 0020 JMP #0058 0x88080302, // 0021 GETMBR R2 R1 K2 - 0x540E001F, // 0022 LDINT R3 32 + 0x540E0021, // 0022 LDINT R3 34 0x1C080403, // 0023 EQ R2 R2 R3 0x780A0004, // 0024 JMPF R2 #002A - 0x8C08010B, // 0025 GETMET R2 R0 K11 + 0x8C080108, // 0025 GETMET R2 R0 K8 0x5C100200, // 0026 MOVE R4 R1 0x7C080400, // 0027 CALL R2 2 0x80040400, // 0028 RET 1 R2 - 0x70020037, // 0029 JMP #0062 + 0x7002002D, // 0029 JMP #0058 0x88080302, // 002A GETMBR R2 R1 K2 - 0x540E0021, // 002B LDINT R3 34 + 0x540E0023, // 002B LDINT R3 36 0x1C080403, // 002C EQ R2 R2 R3 0x780A0004, // 002D JMPF R2 #0033 - 0x8C08010C, // 002E GETMET R2 R0 K12 + 0x8C080109, // 002E GETMET R2 R0 K9 0x5C100200, // 002F MOVE R4 R1 0x7C080400, // 0030 CALL R2 2 0x80040400, // 0031 RET 1 R2 - 0x7002002E, // 0032 JMP #0062 + 0x70020024, // 0032 JMP #0058 0x88080302, // 0033 GETMBR R2 R1 K2 - 0x540E0023, // 0034 LDINT R3 36 + 0x540E002F, // 0034 LDINT R3 48 0x1C080403, // 0035 EQ R2 R2 R3 0x780A0004, // 0036 JMPF R2 #003C - 0x8C08010D, // 0037 GETMET R2 R0 K13 + 0x8C08010A, // 0037 GETMET R2 R0 K10 0x5C100200, // 0038 MOVE R4 R1 0x7C080400, // 0039 CALL R2 2 0x80040400, // 003A RET 1 R2 - 0x70020025, // 003B JMP #0062 + 0x7002001B, // 003B JMP #0058 0x88080302, // 003C GETMBR R2 R1 K2 - 0x540E002F, // 003D LDINT R3 48 + 0x540E0031, // 003D LDINT R3 50 0x1C080403, // 003E EQ R2 R2 R3 0x780A0004, // 003F JMPF R2 #0045 - 0x8C08010E, // 0040 GETMET R2 R0 K14 + 0x8C08010B, // 0040 GETMET R2 R0 K11 0x5C100200, // 0041 MOVE R4 R1 0x7C080400, // 0042 CALL R2 2 0x80040400, // 0043 RET 1 R2 - 0x7002001C, // 0044 JMP #0062 + 0x70020012, // 0044 JMP #0058 0x88080302, // 0045 GETMBR R2 R1 K2 - 0x540E0031, // 0046 LDINT R3 50 + 0x540E003F, // 0046 LDINT R3 64 0x1C080403, // 0047 EQ R2 R2 R3 0x780A0004, // 0048 JMPF R2 #004E - 0x8C08010F, // 0049 GETMET R2 R0 K15 + 0x8C08010C, // 0049 GETMET R2 R0 K12 0x5C100200, // 004A MOVE R4 R1 0x7C080400, // 004B CALL R2 2 0x80040400, // 004C RET 1 R2 - 0x70020013, // 004D JMP #0062 - 0x88080302, // 004E GETMBR R2 R1 K2 - 0x540E003F, // 004F LDINT R3 64 - 0x1C080403, // 0050 EQ R2 R2 R3 - 0x780A0004, // 0051 JMPF R2 #0057 - 0x8C080110, // 0052 GETMET R2 R0 K16 - 0x5C100200, // 0053 MOVE R4 R1 - 0x7C080400, // 0054 CALL R2 2 - 0x80040400, // 0055 RET 1 R2 - 0x7002000A, // 0056 JMP #0062 - 0xA40A2200, // 0057 IMPORT R2 K17 - 0xB80E0600, // 0058 GETNGBL R3 K3 - 0x8C0C0704, // 0059 GETMET R3 R3 K4 - 0x8C140512, // 005A GETMET R5 R2 K18 - 0x581C0013, // 005B LDCONST R7 K19 - 0x88200302, // 005C GETMBR R8 R1 K2 - 0x7C140600, // 005D CALL R5 3 - 0x58180006, // 005E LDCONST R6 K6 - 0x7C0C0600, // 005F CALL R3 3 - 0x500C0000, // 0060 LDBOOL R3 0 0 - 0x80040600, // 0061 RET 1 R3 - 0x50080000, // 0062 LDBOOL R2 0 0 - 0x80040400, // 0063 RET 1 R2 + 0x70020009, // 004D JMP #0058 + 0xB80A0600, // 004E GETNGBL R2 K3 + 0x8C080504, // 004F GETMET R2 R2 K4 + 0x60100018, // 0050 GETGBL R4 G24 + 0x5814000D, // 0051 LDCONST R5 K13 + 0x88180302, // 0052 GETMBR R6 R1 K2 + 0x7C100400, // 0053 CALL R4 2 + 0x58140006, // 0054 LDCONST R5 K6 + 0x7C080600, // 0055 CALL R2 3 + 0x50080000, // 0056 LDBOOL R2 0 0 + 0x80040400, // 0057 RET 1 R2 + 0x50080000, // 0058 LDBOOL R2 0 0 + 0x80040400, // 0059 RET 1 R2 }) ) ); @@ -1417,7 +1383,7 @@ be_local_closure(Matter_Commisioning_Context_process_incoming, /* name */ ********************************************************************/ be_local_closure(Matter_Commisioning_Context_parse_Sigma1, /* name */ be_nested_proto( - 37, /* nstack */ + 36, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1425,705 +1391,595 @@ be_local_closure(Matter_Commisioning_Context_parse_Sigma1, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[118]) { /* constants */ + ( &(const bvalue[103]) { /* constants */ /* K0 */ be_nested_str_weak(crypto), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(session), - /* K3 */ be_nested_str_weak(opcode), - /* K4 */ be_nested_str_weak(local_session_id), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(protocol_id), - /* K7 */ be_nested_str_weak(tasmota), - /* K8 */ be_nested_str_weak(log), - /* K9 */ be_nested_str_weak(MTR_X3A_X20StatusReport_X28General_X20Code_X3A_X20FAILURE_X2C_X20ProtocolId_X3A_X20SECURE_CHANNEL_X2C_X20ProtocolCode_X3A_X20INVALID_PARAMETER_X29), - /* K10 */ be_const_int(2), - /* K11 */ be_nested_str_weak(send_status_report), - /* K12 */ be_const_int(1), + /* K1 */ be_nested_str_weak(session), + /* K2 */ be_nested_str_weak(opcode), + /* K3 */ be_nested_str_weak(local_session_id), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(protocol_id), + /* K6 */ be_nested_str_weak(tasmota), + /* K7 */ be_nested_str_weak(log), + /* K8 */ be_nested_str_weak(MTR_X3A_X20StatusReport_X28General_X20Code_X3A_X20FAILURE_X2C_X20ProtocolId_X3A_X20SECURE_CHANNEL_X2C_X20ProtocolCode_X3A_X20INVALID_PARAMETER_X29), + /* K9 */ be_const_int(3), + /* K10 */ be_nested_str_weak(send_status_report), + /* K11 */ be_const_int(1), + /* K12 */ be_const_int(2), /* K13 */ be_nested_str_weak(matter), /* K14 */ be_nested_str_weak(Sigma1), /* K15 */ be_nested_str_weak(parse), /* K16 */ be_nested_str_weak(raw), /* K17 */ be_nested_str_weak(app_payload_idx), - /* K18 */ be_nested_str_weak(format), - /* K19 */ be_nested_str_weak(MTR_X3A_X20sigma1_X3D_X25s), - /* K20 */ be_nested_str_weak(inspect), - /* K21 */ be_nested_str_weak(__initiator_pub), - /* K22 */ be_nested_str_weak(initiatorEphPubKey), - /* K23 */ be_nested_str_weak(resumptionID), - /* K24 */ be_nested_str_weak(initiatorResumeMIC), - /* K25 */ be_nested_str_weak(MTR_X3A_X20is_resumption_X3D_X25i), - /* K26 */ be_nested_str_weak(device), - /* K27 */ be_nested_str_weak(sessions), - /* K28 */ be_nested_str_weak(find_session_by_resumption_id), - /* K29 */ be_nested_str_weak(MTR_X3A_X20session_resumption_X20found_X20session_X3D_X25s_X20session_resumption_X3D_X25s), - /* K30 */ be_nested_str_weak(_fabric), - /* K31 */ be_nested_str_weak(initiatorRandom), - /* K32 */ be_nested_str_weak(fromstring), - /* K33 */ be_nested_str_weak(Sigma1_Resume), - /* K34 */ be_nested_str_weak(HKDF_SHA256), - /* K35 */ be_nested_str_weak(derive), - /* K36 */ be_nested_str_weak(shared_secret), - /* K37 */ be_nested_str_weak(NCASE_SigmaS1), - /* K38 */ be_const_int(2147483647), - /* K39 */ be_nested_str_weak(AES_CCM), - /* K40 */ be_nested_str_weak(decrypt), - /* K41 */ be_nested_str_weak(tag), - /* K42 */ be_nested_str_weak(_source_node_id), - /* K43 */ be_nested_str_weak(source_node_id), - /* K44 */ be_nested_str_weak(set_mode_CASE), - /* K45 */ be_nested_str_weak(__future_initiator_session_id), - /* K46 */ be_nested_str_weak(initiator_session_id), - /* K47 */ be_nested_str_weak(__future_local_session_id), - /* K48 */ be_nested_str_weak(gen_local_session_id), - /* K49 */ be_nested_str_weak(MTR_X3A_X20_X2BSession_X20_X20_X20_X28_X256i_X29_X20from_X20_X27_X5B_X25s_X5D_X3A_X25i_X27), - /* K50 */ be_nested_str_weak(remote_ip), - /* K51 */ be_nested_str_weak(remote_port), - /* K52 */ be_nested_str_weak(resumption_id), - /* K53 */ be_nested_str_weak(random), - /* K54 */ be_nested_str_weak(Sigma2_Resume), - /* K55 */ be_nested_str_weak(NCASE_SigmaS2), - /* K56 */ be_nested_str_weak(Sigma2Resume), - /* K57 */ be_nested_str_weak(responderSessionID), - /* K58 */ be_nested_str_weak(sigma2ResumeMIC), - /* K59 */ be_nested_str_weak(SessionResumptionKeys), - /* K60 */ be_nested_str_weak(rtc), - /* K61 */ be_nested_str_weak(utc), - /* K62 */ be_nested_str_weak(tlv2raw), - /* K63 */ be_nested_str_weak(__Msg1), - /* K64 */ be_nested_str_weak(build_response), - /* K65 */ be_nested_str_weak(encode_frame), - /* K66 */ be_nested_str_weak(responder), - /* K67 */ be_nested_str_weak(send_response_frame), - /* K68 */ be_nested_str_weak(close), - /* K69 */ be_nested_str_weak(set_keys), - /* K70 */ be_nested_str_weak(_breadcrumb), - /* K71 */ be_nested_str_weak(counter_snd_next), - /* K72 */ be_nested_str_weak(set_persist), - /* K73 */ be_nested_str_weak(set_no_expiration), - /* K74 */ be_nested_str_weak(persist_to_fabric), - /* K75 */ be_nested_str_weak(save), - /* K76 */ be_nested_str_weak(find_fabric_by_destination_id), - /* K77 */ be_nested_str_weak(destinationId), - /* K78 */ be_nested_str_weak(MTR_X3A_X20StatusReport_X28GeneralCode_X3A_X20FAILURE_X2C_X20ProtocolId_X3A_X20SECURE_CHANNEL_X2C_X20ProtocolCode_X3A_X20NO_SHARED_TRUST_ROOTS_X29), - /* K79 */ be_nested_str_weak(MTR_X3A_X20fabric_X3D), - /* K80 */ be_nested_str_weak(MTR_X3A_X20no_private_key_X3D), - /* K81 */ be_nested_str_weak(no_private_key), - /* K82 */ be_nested_str_weak(tohex), - /* K83 */ be_nested_str_weak(MTR_X3A_X20noc_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X3D), - /* K84 */ be_nested_str_weak(noc), - /* K85 */ be_nested_str_weak(get_icac), - /* K86 */ be_nested_str_weak(MTR_X3A_X20icac_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X3D), - /* K87 */ be_nested_str_weak(MTR_X3A_X20root_ca_cert_X20_X20_X3D), - /* K88 */ be_nested_str_weak(root_ca_certificate), - /* K89 */ be_nested_str_weak(__responder_priv), - /* K90 */ be_nested_str_weak(__responder_pub), - /* K91 */ be_nested_str_weak(EC_P256), - /* K92 */ be_nested_str_weak(public_key), - /* K93 */ be_nested_str_weak(MTR_X3A_X20ResponderEph_priv_X20_X20_X3D), - /* K94 */ be_nested_str_weak(MTR_X3A_X20ResponderEph_pub_X20_X20_X3D), - /* K95 */ be_nested_str_weak(shared_key), - /* K96 */ be_nested_str_weak(TLV), - /* K97 */ be_nested_str_weak(Matter_TLV_struct), - /* K98 */ be_nested_str_weak(add_TLV), - /* K99 */ be_nested_str_weak(B2), - /* K100 */ be_nested_str_weak(get_noc), - /* K101 */ be_const_int(3), - /* K102 */ be_nested_str_weak(ecdsa_sign_sha256), - /* K103 */ be_nested_str_weak(get_pk), - /* K104 */ be_nested_str_weak(Msg1), - /* K105 */ be_nested_str_weak(SHA256), - /* K106 */ be_nested_str_weak(update), - /* K107 */ be_nested_str_weak(out), - /* K108 */ be_nested_str_weak(S2K_Info), - /* K109 */ be_nested_str_weak(get_ipk_group_key), - /* K110 */ be_nested_str_weak(TBEData2_Nonce), - /* K111 */ be_nested_str_weak(encrypt), - /* K112 */ be_nested_str_weak(Sigma2), - /* K113 */ be_nested_str_weak(responderRandom), - /* K114 */ be_nested_str_weak(responderSessionId), - /* K115 */ be_nested_str_weak(responderEphPubKey), - /* K116 */ be_nested_str_weak(encrypted2), - /* K117 */ be_nested_str_weak(__Msg2), + /* K18 */ be_nested_str_weak(__initiator_pub), + /* K19 */ be_nested_str_weak(initiatorEphPubKey), + /* K20 */ be_nested_str_weak(resumptionID), + /* K21 */ be_nested_str_weak(initiatorResumeMIC), + /* K22 */ be_nested_str_weak(device), + /* K23 */ be_nested_str_weak(sessions), + /* K24 */ be_nested_str_weak(find_session_by_resumption_id), + /* K25 */ be_nested_str_weak(_fabric), + /* K26 */ be_nested_str_weak(initiatorRandom), + /* K27 */ be_nested_str_weak(fromstring), + /* K28 */ be_nested_str_weak(Sigma1_Resume), + /* K29 */ be_nested_str_weak(HKDF_SHA256), + /* K30 */ be_nested_str_weak(derive), + /* K31 */ be_nested_str_weak(shared_secret), + /* K32 */ be_nested_str_weak(NCASE_SigmaS1), + /* K33 */ be_const_int(2147483647), + /* K34 */ be_nested_str_weak(AES_CCM), + /* K35 */ be_nested_str_weak(decrypt), + /* K36 */ be_nested_str_weak(tag), + /* K37 */ be_nested_str_weak(_source_node_id), + /* K38 */ be_nested_str_weak(source_node_id), + /* K39 */ be_nested_str_weak(set_mode_CASE), + /* K40 */ be_nested_str_weak(__future_initiator_session_id), + /* K41 */ be_nested_str_weak(initiator_session_id), + /* K42 */ be_nested_str_weak(__future_local_session_id), + /* K43 */ be_nested_str_weak(gen_local_session_id), + /* K44 */ be_nested_str_weak(MTR_X3A_X20_X2BSession_X20_X20_X20_X28_X256i_X29_X20from_X20_X27_X5B_X25s_X5D_X3A_X25i_X27), + /* K45 */ be_nested_str_weak(remote_ip), + /* K46 */ be_nested_str_weak(remote_port), + /* K47 */ be_nested_str_weak(resumption_id), + /* K48 */ be_nested_str_weak(random), + /* K49 */ be_nested_str_weak(Sigma2_Resume), + /* K50 */ be_nested_str_weak(NCASE_SigmaS2), + /* K51 */ be_nested_str_weak(Sigma2Resume), + /* K52 */ be_nested_str_weak(responderSessionID), + /* K53 */ be_nested_str_weak(sigma2ResumeMIC), + /* K54 */ be_nested_str_weak(SessionResumptionKeys), + /* K55 */ be_nested_str_weak(rtc_utc), + /* K56 */ be_nested_str_weak(tlv2raw), + /* K57 */ be_nested_str_weak(__Msg1), + /* K58 */ be_nested_str_weak(build_response), + /* K59 */ be_nested_str_weak(encode_frame), + /* K60 */ be_nested_str_weak(responder), + /* K61 */ be_nested_str_weak(send_response_frame), + /* K62 */ be_nested_str_weak(close), + /* K63 */ be_nested_str_weak(set_keys), + /* K64 */ be_nested_str_weak(_breadcrumb), + /* K65 */ be_nested_str_weak(counter_snd_next), + /* K66 */ be_nested_str_weak(set_persist), + /* K67 */ be_nested_str_weak(set_no_expiration), + /* K68 */ be_nested_str_weak(persist_to_fabric), + /* K69 */ be_nested_str_weak(save), + /* K70 */ be_nested_str_weak(find_fabric_by_destination_id), + /* K71 */ be_nested_str_weak(destinationId), + /* K72 */ be_nested_str_weak(MTR_X3A_X20StatusReport_X28GeneralCode_X3A_X20FAILURE_X2C_X20ProtocolId_X3A_X20SECURE_CHANNEL_X2C_X20ProtocolCode_X3A_X20NO_SHARED_TRUST_ROOTS_X29), + /* K73 */ be_nested_str_weak(__responder_priv), + /* K74 */ be_nested_str_weak(__responder_pub), + /* K75 */ be_nested_str_weak(EC_P256), + /* K76 */ be_nested_str_weak(public_key), + /* K77 */ be_nested_str_weak(shared_key), + /* K78 */ be_nested_str_weak(TLV), + /* K79 */ be_nested_str_weak(Matter_TLV_struct), + /* K80 */ be_nested_str_weak(add_TLV), + /* K81 */ be_nested_str_weak(B2), + /* K82 */ be_nested_str_weak(get_noc), + /* K83 */ be_nested_str_weak(get_icac), + /* K84 */ be_nested_str_weak(ecdsa_sign_sha256), + /* K85 */ be_nested_str_weak(get_pk), + /* K86 */ be_nested_str_weak(Msg1), + /* K87 */ be_nested_str_weak(SHA256), + /* K88 */ be_nested_str_weak(update), + /* K89 */ be_nested_str_weak(out), + /* K90 */ be_nested_str_weak(S2K_Info), + /* K91 */ be_nested_str_weak(get_ipk_group_key), + /* K92 */ be_nested_str_weak(TBEData2_Nonce), + /* K93 */ be_nested_str_weak(encrypt), + /* K94 */ be_nested_str_weak(Sigma2), + /* K95 */ be_nested_str_weak(responderRandom), + /* K96 */ be_nested_str_weak(responderSessionId), + /* K97 */ be_nested_str_weak(responderEphPubKey), + /* K98 */ be_nested_str_weak(encrypted2), + /* K99 */ be_nested_str_weak(__Msg2), + /* K100 */ be_nested_str_weak(MTR_X3A_X20New_X20Connection_X20_X28CASE_X20id_X3D_X25i_X29_X20from_X20_X5B_X25s_X5D_X3A_X25i), + /* K101 */ be_nested_str_weak(_ip), + /* K102 */ be_nested_str_weak(_port), }), be_str_weak(parse_Sigma1), &be_const_str_solidified, - ( &(const binstruction[576]) { /* code */ + ( &(const binstruction[481]) { /* code */ 0xA40A0000, // 0000 IMPORT R2 K0 - 0xA40E0200, // 0001 IMPORT R3 K1 + 0x880C0301, // 0001 GETMBR R3 R1 K1 0x88100302, // 0002 GETMBR R4 R1 K2 - 0x88140303, // 0003 GETMBR R5 R1 K3 - 0x541A002F, // 0004 LDINT R6 48 - 0x20140A06, // 0005 NE R5 R5 R6 - 0x74160005, // 0006 JMPT R5 #000D - 0x88140304, // 0007 GETMBR R5 R1 K4 - 0x20140B05, // 0008 NE R5 R5 K5 - 0x74160002, // 0009 JMPT R5 #000D - 0x88140306, // 000A GETMBR R5 R1 K6 - 0x20140B05, // 000B NE R5 R5 K5 - 0x7816000D, // 000C JMPF R5 #001B - 0xB8160E00, // 000D GETNGBL R5 K7 - 0x8C140B08, // 000E GETMET R5 R5 K8 + 0x5416002F, // 0003 LDINT R5 48 + 0x20100805, // 0004 NE R4 R4 R5 + 0x74120005, // 0005 JMPT R4 #000C + 0x88100303, // 0006 GETMBR R4 R1 K3 + 0x20100904, // 0007 NE R4 R4 K4 + 0x74120002, // 0008 JMPT R4 #000C + 0x88100305, // 0009 GETMBR R4 R1 K5 + 0x20100904, // 000A NE R4 R4 K4 + 0x7812000D, // 000B JMPF R4 #001A + 0xB8120C00, // 000C GETNGBL R4 K6 + 0x8C100907, // 000D GETMET R4 R4 K7 + 0x58180008, // 000E LDCONST R6 K8 0x581C0009, // 000F LDCONST R7 K9 - 0x5820000A, // 0010 LDCONST R8 K10 - 0x7C140600, // 0011 CALL R5 3 - 0x8C14010B, // 0012 GETMET R5 R0 K11 - 0x5C1C0200, // 0013 MOVE R7 R1 - 0x5820000C, // 0014 LDCONST R8 K12 - 0x58240005, // 0015 LDCONST R9 K5 - 0x5828000A, // 0016 LDCONST R10 K10 - 0x502C0000, // 0017 LDBOOL R11 0 0 - 0x7C140C00, // 0018 CALL R5 6 - 0x50140000, // 0019 LDBOOL R5 0 0 - 0x80040A00, // 001A RET 1 R5 - 0xB8161A00, // 001B GETNGBL R5 K13 - 0x8C140B0E, // 001C GETMET R5 R5 K14 - 0x7C140200, // 001D CALL R5 1 - 0x8C140B0F, // 001E GETMET R5 R5 K15 - 0x881C0310, // 001F GETMBR R7 R1 K16 - 0x88200311, // 0020 GETMBR R8 R1 K17 - 0x7C140600, // 0021 CALL R5 3 - 0xB81A0E00, // 0022 GETNGBL R6 K7 - 0x8C180D08, // 0023 GETMET R6 R6 K8 - 0x8C200712, // 0024 GETMET R8 R3 K18 - 0x58280013, // 0025 LDCONST R10 K19 - 0xB82E1A00, // 0026 GETNGBL R11 K13 - 0x8C2C1714, // 0027 GETMET R11 R11 K20 - 0x5C340A00, // 0028 MOVE R13 R5 - 0x7C2C0400, // 0029 CALL R11 2 - 0x7C200600, // 002A CALL R8 3 - 0x54260003, // 002B LDINT R9 4 - 0x7C180600, // 002C CALL R6 3 - 0x88180B16, // 002D GETMBR R6 R5 K22 - 0x90122A06, // 002E SETMBR R4 K21 R6 - 0x88180B17, // 002F GETMBR R6 R5 K23 - 0x4C1C0000, // 0030 LDNIL R7 - 0x20180C07, // 0031 NE R6 R6 R7 - 0x781A0003, // 0032 JMPF R6 #0037 - 0x88180B18, // 0033 GETMBR R6 R5 K24 - 0x4C1C0000, // 0034 LDNIL R7 - 0x20180C07, // 0035 NE R6 R6 R7 - 0x741A0000, // 0036 JMPT R6 #0038 - 0x50180001, // 0037 LDBOOL R6 0 1 - 0x50180200, // 0038 LDBOOL R6 1 0 - 0xB81E0E00, // 0039 GETNGBL R7 K7 - 0x8C1C0F08, // 003A GETMET R7 R7 K8 - 0x8C240712, // 003B GETMET R9 R3 K18 - 0x582C0019, // 003C LDCONST R11 K25 - 0x781A0001, // 003D JMPF R6 #0040 - 0x5830000C, // 003E LDCONST R12 K12 - 0x70020000, // 003F JMP #0041 - 0x58300005, // 0040 LDCONST R12 K5 - 0x7C240600, // 0041 CALL R9 3 - 0x542A0003, // 0042 LDINT R10 4 - 0x7C1C0600, // 0043 CALL R7 3 - 0x50180000, // 0044 LDBOOL R6 0 0 - 0x4C1C0000, // 0045 LDNIL R7 - 0x781A001C, // 0046 JMPF R6 #0064 - 0x8820011A, // 0047 GETMBR R8 R0 K26 - 0x8820111B, // 0048 GETMBR R8 R8 K27 - 0x8C20111C, // 0049 GETMET R8 R8 K28 - 0x88280B17, // 004A GETMBR R10 R5 K23 - 0x7C200400, // 004B CALL R8 2 - 0x5C1C1000, // 004C MOVE R7 R8 - 0xB8220E00, // 004D GETNGBL R8 K7 - 0x8C201108, // 004E GETMET R8 R8 K8 - 0x8C280712, // 004F GETMET R10 R3 K18 - 0x5830001D, // 0050 LDCONST R12 K29 - 0xB8361A00, // 0051 GETNGBL R13 K13 - 0x8C341B14, // 0052 GETMET R13 R13 K20 - 0x5C3C0800, // 0053 MOVE R15 R4 - 0x7C340400, // 0054 CALL R13 2 - 0xB83A1A00, // 0055 GETNGBL R14 K13 - 0x8C381D14, // 0056 GETMET R14 R14 K20 - 0x5C400E00, // 0057 MOVE R16 R7 - 0x7C380400, // 0058 CALL R14 2 - 0x7C280800, // 0059 CALL R10 4 - 0x542E0003, // 005A LDINT R11 4 - 0x7C200600, // 005B CALL R8 3 - 0x4C200000, // 005C LDNIL R8 - 0x1C200E08, // 005D EQ R8 R7 R8 - 0x74220003, // 005E JMPT R8 #0063 - 0x88200F1E, // 005F GETMBR R8 R7 K30 - 0x4C240000, // 0060 LDNIL R9 - 0x1C201009, // 0061 EQ R8 R8 R9 - 0x78220000, // 0062 JMPF R8 #0064 - 0x50180000, // 0063 LDBOOL R6 0 0 - 0x781A00B6, // 0064 JMPF R6 #011C - 0x88200B1F, // 0065 GETMBR R8 R5 K31 - 0x88240B17, // 0066 GETMBR R9 R5 K23 - 0x00201009, // 0067 ADD R8 R8 R9 - 0x60240015, // 0068 GETGBL R9 G21 - 0x7C240000, // 0069 CALL R9 0 - 0x8C241320, // 006A GETMET R9 R9 K32 - 0x582C0021, // 006B LDCONST R11 K33 - 0x7C240400, // 006C CALL R9 2 - 0x8C280522, // 006D GETMET R10 R2 K34 - 0x7C280200, // 006E CALL R10 1 - 0x8C281523, // 006F GETMET R10 R10 K35 - 0x88300F24, // 0070 GETMBR R12 R7 K36 - 0x5C341000, // 0071 MOVE R13 R8 - 0x5C381200, // 0072 MOVE R14 R9 - 0x543E000F, // 0073 LDINT R15 16 - 0x7C280A00, // 0074 CALL R10 5 - 0x602C0015, // 0075 GETGBL R11 G21 - 0x7C2C0000, // 0076 CALL R11 0 - 0x8C2C1720, // 0077 GETMET R11 R11 K32 - 0x58340025, // 0078 LDCONST R13 K37 - 0x7C2C0400, // 0079 CALL R11 2 - 0x5431FFEE, // 007A LDINT R12 -17 - 0x40320A0C, // 007B CONNECT R12 K5 R12 - 0x88340B18, // 007C GETMBR R13 R5 K24 - 0x94301A0C, // 007D GETIDX R12 R13 R12 - 0x5439FFEF, // 007E LDINT R14 -16 - 0x40381D26, // 007F CONNECT R14 R14 K38 - 0x883C0B18, // 0080 GETMBR R15 R5 K24 - 0x94341E0E, // 0081 GETIDX R13 R15 R14 - 0x8C400527, // 0082 GETMET R16 R2 K39 - 0x5C481400, // 0083 MOVE R18 R10 - 0x5C4C1600, // 0084 MOVE R19 R11 - 0x60500015, // 0085 GETGBL R20 G21 - 0x7C500000, // 0086 CALL R20 0 - 0x6054000C, // 0087 GETGBL R21 G12 - 0x5C581800, // 0088 MOVE R22 R12 - 0x7C540200, // 0089 CALL R21 1 - 0x545A000F, // 008A LDINT R22 16 - 0x7C400C00, // 008B CALL R16 6 - 0x5C382000, // 008C MOVE R14 R16 - 0x8C401D28, // 008D GETMET R16 R14 K40 - 0x5C481800, // 008E MOVE R18 R12 - 0x7C400400, // 008F CALL R16 2 - 0x5C3C2000, // 0090 MOVE R15 R16 - 0x8C401D29, // 0091 GETMET R16 R14 K41 - 0x7C400200, // 0092 CALL R16 1 - 0x1C441A10, // 0093 EQ R17 R13 R16 - 0x78460085, // 0094 JMPF R17 #011B - 0x88440F1E, // 0095 GETMBR R17 R7 K30 - 0x90123C11, // 0096 SETMBR R4 K30 R17 - 0x8844032B, // 0097 GETMBR R17 R1 K43 - 0x90125411, // 0098 SETMBR R4 K42 R17 - 0x8C44092C, // 0099 GETMET R17 R4 K44 - 0x7C440200, // 009A CALL R17 1 - 0x88440B2E, // 009B GETMBR R17 R5 K46 - 0x90125A11, // 009C SETMBR R4 K45 R17 - 0x8844011A, // 009D GETMBR R17 R0 K26 - 0x8844231B, // 009E GETMBR R17 R17 K27 - 0x8C442330, // 009F GETMET R17 R17 K48 - 0x7C440200, // 00A0 CALL R17 1 - 0x90125E11, // 00A1 SETMBR R4 K47 R17 - 0xB8460E00, // 00A2 GETNGBL R17 K7 - 0x8C442308, // 00A3 GETMET R17 R17 K8 - 0x8C4C0712, // 00A4 GETMET R19 R3 K18 - 0x58540031, // 00A5 LDCONST R21 K49 - 0x8858092F, // 00A6 GETMBR R22 R4 K47 - 0x885C0332, // 00A7 GETMBR R23 R1 K50 - 0x88600333, // 00A8 GETMBR R24 R1 K51 - 0x7C4C0A00, // 00A9 CALL R19 5 - 0x5850000A, // 00AA LDCONST R20 K10 - 0x7C440600, // 00AB CALL R17 3 - 0x88440F24, // 00AC GETMBR R17 R7 K36 - 0x90124811, // 00AD SETMBR R4 K36 R17 - 0x8C440535, // 00AE GETMET R17 R2 K53 - 0x544E000F, // 00AF LDINT R19 16 - 0x7C440400, // 00B0 CALL R17 2 - 0x90126811, // 00B1 SETMBR R4 K52 R17 - 0x60440015, // 00B2 GETGBL R17 G21 - 0x7C440000, // 00B3 CALL R17 0 - 0x8C442320, // 00B4 GETMET R17 R17 K32 - 0x584C0036, // 00B5 LDCONST R19 K54 - 0x7C440400, // 00B6 CALL R17 2 - 0x88480B1F, // 00B7 GETMBR R18 R5 K31 - 0x884C0934, // 00B8 GETMBR R19 R4 K52 - 0x00482413, // 00B9 ADD R18 R18 R19 - 0x8C4C0522, // 00BA GETMET R19 R2 K34 - 0x7C4C0200, // 00BB CALL R19 1 - 0x8C4C2723, // 00BC GETMET R19 R19 K35 - 0x88540924, // 00BD GETMBR R21 R4 K36 - 0x5C582400, // 00BE MOVE R22 R18 - 0x5C5C2200, // 00BF MOVE R23 R17 - 0x5462000F, // 00C0 LDINT R24 16 - 0x7C4C0A00, // 00C1 CALL R19 5 - 0x8C500527, // 00C2 GETMET R20 R2 K39 - 0x5C582600, // 00C3 MOVE R22 R19 - 0x605C0015, // 00C4 GETGBL R23 G21 - 0x7C5C0000, // 00C5 CALL R23 0 - 0x8C5C2F20, // 00C6 GETMET R23 R23 K32 - 0x58640037, // 00C7 LDCONST R25 K55 - 0x7C5C0400, // 00C8 CALL R23 2 - 0x60600015, // 00C9 GETGBL R24 G21 - 0x7C600000, // 00CA CALL R24 0 - 0x58640005, // 00CB LDCONST R25 K5 - 0x546A000F, // 00CC LDINT R26 16 - 0x7C500C00, // 00CD CALL R20 6 - 0x8C542929, // 00CE GETMET R21 R20 K41 - 0x7C540200, // 00CF CALL R21 1 - 0xB85A1A00, // 00D0 GETNGBL R22 K13 - 0x8C582D38, // 00D1 GETMET R22 R22 K56 - 0x7C580200, // 00D2 CALL R22 1 - 0x885C0934, // 00D3 GETMBR R23 R4 K52 - 0x905A2E17, // 00D4 SETMBR R22 K23 R23 - 0x885C092F, // 00D5 GETMBR R23 R4 K47 - 0x905A7217, // 00D6 SETMBR R22 K57 R23 - 0x905A7415, // 00D7 SETMBR R22 K58 R21 - 0x8C5C0522, // 00D8 GETMET R23 R2 K34 - 0x7C5C0200, // 00D9 CALL R23 1 - 0x8C5C2F23, // 00DA GETMET R23 R23 K35 - 0x88640924, // 00DB GETMBR R25 R4 K36 - 0x88680B1F, // 00DC GETMBR R26 R5 K31 - 0x886C0934, // 00DD GETMBR R27 R4 K52 - 0x0068341B, // 00DE ADD R26 R26 R27 - 0x606C0015, // 00DF GETGBL R27 G21 - 0x7C6C0000, // 00E0 CALL R27 0 - 0x8C6C3720, // 00E1 GETMET R27 R27 K32 - 0x5874003B, // 00E2 LDCONST R29 K59 - 0x7C6C0400, // 00E3 CALL R27 2 - 0x5472002F, // 00E4 LDINT R28 48 - 0x7C5C0A00, // 00E5 CALL R23 5 - 0x5462000E, // 00E6 LDINT R24 15 - 0x40620A18, // 00E7 CONNECT R24 K5 R24 - 0x94602E18, // 00E8 GETIDX R24 R23 R24 - 0x5466000F, // 00E9 LDINT R25 16 - 0x546A001E, // 00EA LDINT R26 31 - 0x4064321A, // 00EB CONNECT R25 R25 R26 - 0x94642E19, // 00EC GETIDX R25 R23 R25 - 0x546A001F, // 00ED LDINT R26 32 - 0x546E002E, // 00EE LDINT R27 47 - 0x4068341B, // 00EF CONNECT R26 R26 R27 - 0x94682E1A, // 00F0 GETIDX R26 R23 R26 - 0xB86E0E00, // 00F1 GETNGBL R27 K7 - 0x8C6C373C, // 00F2 GETMET R27 R27 K60 - 0x7C6C0200, // 00F3 CALL R27 1 - 0x946C373D, // 00F4 GETIDX R27 R27 K61 - 0x8C702D3E, // 00F5 GETMET R28 R22 K62 - 0x7C700200, // 00F6 CALL R28 1 - 0x4C740000, // 00F7 LDNIL R29 - 0x90127E1D, // 00F8 SETMBR R4 K63 R29 - 0x8C740340, // 00F9 GETMET R29 R1 K64 - 0x547E0032, // 00FA LDINT R31 51 - 0x50800200, // 00FB LDBOOL R32 1 0 - 0x7C740600, // 00FC CALL R29 3 - 0x8C783B41, // 00FD GETMET R30 R29 K65 - 0x5C803800, // 00FE MOVE R32 R28 - 0x7C780400, // 00FF CALL R30 2 - 0x887C0142, // 0100 GETMBR R31 R0 K66 - 0x8C7C3F43, // 0101 GETMET R31 R31 K67 - 0x5C843A00, // 0102 MOVE R33 R29 - 0x7C7C0400, // 0103 CALL R31 2 - 0x8C7C0944, // 0104 GETMET R31 R4 K68 - 0x7C7C0200, // 0105 CALL R31 1 - 0x8C7C0945, // 0106 GETMET R31 R4 K69 - 0x5C843000, // 0107 MOVE R33 R24 - 0x5C883200, // 0108 MOVE R34 R25 - 0x5C8C3400, // 0109 MOVE R35 R26 - 0x5C903600, // 010A MOVE R36 R27 - 0x7C7C0A00, // 010B CALL R31 5 - 0x90128D05, // 010C SETMBR R4 K70 K5 - 0x8C7C0947, // 010D GETMET R31 R4 K71 - 0x7C7C0200, // 010E CALL R31 1 - 0x8C7C0948, // 010F GETMET R31 R4 K72 - 0x50840200, // 0110 LDBOOL R33 1 0 - 0x7C7C0400, // 0111 CALL R31 2 - 0x8C7C0949, // 0112 GETMET R31 R4 K73 - 0x7C7C0200, // 0113 CALL R31 1 - 0x8C7C094A, // 0114 GETMET R31 R4 K74 - 0x7C7C0200, // 0115 CALL R31 1 - 0x8C7C094B, // 0116 GETMET R31 R4 K75 - 0x7C7C0200, // 0117 CALL R31 1 - 0x507C0200, // 0118 LDBOOL R31 1 0 - 0x80043E00, // 0119 RET 1 R31 - 0x70020000, // 011A JMP #011C - 0x50180000, // 011B LDBOOL R6 0 0 - 0x5C200C00, // 011C MOVE R8 R6 - 0x7422011F, // 011D JMPT R8 #023E - 0x8C20014C, // 011E GETMET R8 R0 K76 - 0x88280B4D, // 011F GETMBR R10 R5 K77 - 0x882C0B1F, // 0120 GETMBR R11 R5 K31 - 0x7C200600, // 0121 CALL R8 3 - 0x90123C08, // 0122 SETMBR R4 K30 R8 - 0x4C240000, // 0123 LDNIL R9 - 0x1C240809, // 0124 EQ R9 R4 R9 - 0x74260003, // 0125 JMPT R9 #012A - 0x8824091E, // 0126 GETMBR R9 R4 K30 - 0x4C280000, // 0127 LDNIL R10 - 0x1C24120A, // 0128 EQ R9 R9 R10 - 0x7826000D, // 0129 JMPF R9 #0138 - 0xB8260E00, // 012A GETNGBL R9 K7 - 0x8C241308, // 012B GETMET R9 R9 K8 - 0x582C004E, // 012C LDCONST R11 K78 - 0x5830000A, // 012D LDCONST R12 K10 - 0x7C240600, // 012E CALL R9 3 - 0x8C24010B, // 012F GETMET R9 R0 K11 - 0x5C2C0200, // 0130 MOVE R11 R1 - 0x5830000C, // 0131 LDCONST R12 K12 - 0x58340005, // 0132 LDCONST R13 K5 - 0x5838000C, // 0133 LDCONST R14 K12 - 0x503C0000, // 0134 LDBOOL R15 0 0 - 0x7C240C00, // 0135 CALL R9 6 - 0x50240000, // 0136 LDBOOL R9 0 0 - 0x80041200, // 0137 RET 1 R9 - 0x8824032B, // 0138 GETMBR R9 R1 K43 - 0x90125409, // 0139 SETMBR R4 K42 R9 - 0x8C24092C, // 013A GETMET R9 R4 K44 - 0x7C240200, // 013B CALL R9 1 - 0x88240B2E, // 013C GETMBR R9 R5 K46 - 0x90125A09, // 013D SETMBR R4 K45 R9 - 0x8824011A, // 013E GETMBR R9 R0 K26 - 0x8824131B, // 013F GETMBR R9 R9 K27 - 0x8C241330, // 0140 GETMET R9 R9 K48 + 0x7C100600, // 0010 CALL R4 3 + 0x8C10010A, // 0011 GETMET R4 R0 K10 + 0x5C180200, // 0012 MOVE R6 R1 + 0x581C000B, // 0013 LDCONST R7 K11 + 0x58200004, // 0014 LDCONST R8 K4 + 0x5824000C, // 0015 LDCONST R9 K12 + 0x50280000, // 0016 LDBOOL R10 0 0 + 0x7C100C00, // 0017 CALL R4 6 + 0x50100000, // 0018 LDBOOL R4 0 0 + 0x80040800, // 0019 RET 1 R4 + 0xB8121A00, // 001A GETNGBL R4 K13 + 0x8C10090E, // 001B GETMET R4 R4 K14 + 0x7C100200, // 001C CALL R4 1 + 0x8C10090F, // 001D GETMET R4 R4 K15 + 0x88180310, // 001E GETMBR R6 R1 K16 + 0x881C0311, // 001F GETMBR R7 R1 K17 + 0x7C100600, // 0020 CALL R4 3 + 0x88140913, // 0021 GETMBR R5 R4 K19 + 0x900E2405, // 0022 SETMBR R3 K18 R5 + 0x88140914, // 0023 GETMBR R5 R4 K20 + 0x4C180000, // 0024 LDNIL R6 + 0x20140A06, // 0025 NE R5 R5 R6 + 0x78160003, // 0026 JMPF R5 #002B + 0x88140915, // 0027 GETMBR R5 R4 K21 + 0x4C180000, // 0028 LDNIL R6 + 0x20140A06, // 0029 NE R5 R5 R6 + 0x74160000, // 002A JMPT R5 #002C + 0x50140001, // 002B LDBOOL R5 0 1 + 0x50140200, // 002C LDBOOL R5 1 0 + 0x50140000, // 002D LDBOOL R5 0 0 + 0x4C180000, // 002E LDNIL R6 + 0x7816000D, // 002F JMPF R5 #003E + 0x881C0116, // 0030 GETMBR R7 R0 K22 + 0x881C0F17, // 0031 GETMBR R7 R7 K23 + 0x8C1C0F18, // 0032 GETMET R7 R7 K24 + 0x88240914, // 0033 GETMBR R9 R4 K20 + 0x7C1C0400, // 0034 CALL R7 2 + 0x5C180E00, // 0035 MOVE R6 R7 + 0x4C1C0000, // 0036 LDNIL R7 + 0x1C1C0C07, // 0037 EQ R7 R6 R7 + 0x741E0003, // 0038 JMPT R7 #003D + 0x881C0D19, // 0039 GETMBR R7 R6 K25 + 0x4C200000, // 003A LDNIL R8 + 0x1C1C0E08, // 003B EQ R7 R7 R8 + 0x781E0000, // 003C JMPF R7 #003E + 0x50140000, // 003D LDBOOL R5 0 0 + 0x781600B5, // 003E JMPF R5 #00F5 + 0x881C091A, // 003F GETMBR R7 R4 K26 + 0x88200914, // 0040 GETMBR R8 R4 K20 + 0x001C0E08, // 0041 ADD R7 R7 R8 + 0x60200015, // 0042 GETGBL R8 G21 + 0x7C200000, // 0043 CALL R8 0 + 0x8C20111B, // 0044 GETMET R8 R8 K27 + 0x5828001C, // 0045 LDCONST R10 K28 + 0x7C200400, // 0046 CALL R8 2 + 0x8C24051D, // 0047 GETMET R9 R2 K29 + 0x7C240200, // 0048 CALL R9 1 + 0x8C24131E, // 0049 GETMET R9 R9 K30 + 0x882C0D1F, // 004A GETMBR R11 R6 K31 + 0x5C300E00, // 004B MOVE R12 R7 + 0x5C341000, // 004C MOVE R13 R8 + 0x543A000F, // 004D LDINT R14 16 + 0x7C240A00, // 004E CALL R9 5 + 0x60280015, // 004F GETGBL R10 G21 + 0x7C280000, // 0050 CALL R10 0 + 0x8C28151B, // 0051 GETMET R10 R10 K27 + 0x58300020, // 0052 LDCONST R12 K32 + 0x7C280400, // 0053 CALL R10 2 + 0x542DFFEE, // 0054 LDINT R11 -17 + 0x402E080B, // 0055 CONNECT R11 K4 R11 + 0x88300915, // 0056 GETMBR R12 R4 K21 + 0x942C180B, // 0057 GETIDX R11 R12 R11 + 0x5435FFEF, // 0058 LDINT R13 -16 + 0x40341B21, // 0059 CONNECT R13 R13 K33 + 0x88380915, // 005A GETMBR R14 R4 K21 + 0x94301C0D, // 005B GETIDX R12 R14 R13 + 0x8C3C0522, // 005C GETMET R15 R2 K34 + 0x5C441200, // 005D MOVE R17 R9 + 0x5C481400, // 005E MOVE R18 R10 + 0x604C0015, // 005F GETGBL R19 G21 + 0x7C4C0000, // 0060 CALL R19 0 + 0x6050000C, // 0061 GETGBL R20 G12 + 0x5C541600, // 0062 MOVE R21 R11 + 0x7C500200, // 0063 CALL R20 1 + 0x5456000F, // 0064 LDINT R21 16 + 0x7C3C0C00, // 0065 CALL R15 6 + 0x5C341E00, // 0066 MOVE R13 R15 + 0x8C3C1B23, // 0067 GETMET R15 R13 K35 + 0x5C441600, // 0068 MOVE R17 R11 + 0x7C3C0400, // 0069 CALL R15 2 + 0x5C381E00, // 006A MOVE R14 R15 + 0x8C3C1B24, // 006B GETMET R15 R13 K36 + 0x7C3C0200, // 006C CALL R15 1 + 0x1C40180F, // 006D EQ R16 R12 R15 + 0x78420084, // 006E JMPF R16 #00F4 + 0x88400D19, // 006F GETMBR R16 R6 K25 + 0x900E3210, // 0070 SETMBR R3 K25 R16 + 0x88400326, // 0071 GETMBR R16 R1 K38 + 0x900E4A10, // 0072 SETMBR R3 K37 R16 + 0x8C400727, // 0073 GETMET R16 R3 K39 + 0x7C400200, // 0074 CALL R16 1 + 0x88400929, // 0075 GETMBR R16 R4 K41 + 0x900E5010, // 0076 SETMBR R3 K40 R16 + 0x88400116, // 0077 GETMBR R16 R0 K22 + 0x88402117, // 0078 GETMBR R16 R16 K23 + 0x8C40212B, // 0079 GETMET R16 R16 K43 + 0x7C400200, // 007A CALL R16 1 + 0x900E5410, // 007B SETMBR R3 K42 R16 + 0xB8420C00, // 007C GETNGBL R16 K6 + 0x8C402107, // 007D GETMET R16 R16 K7 + 0x60480018, // 007E GETGBL R18 G24 + 0x584C002C, // 007F LDCONST R19 K44 + 0x8850072A, // 0080 GETMBR R20 R3 K42 + 0x8854032D, // 0081 GETMBR R21 R1 K45 + 0x8858032E, // 0082 GETMBR R22 R1 K46 + 0x7C480800, // 0083 CALL R18 4 + 0x584C0009, // 0084 LDCONST R19 K9 + 0x7C400600, // 0085 CALL R16 3 + 0x88400D1F, // 0086 GETMBR R16 R6 K31 + 0x900E3E10, // 0087 SETMBR R3 K31 R16 + 0x8C400530, // 0088 GETMET R16 R2 K48 + 0x544A000F, // 0089 LDINT R18 16 + 0x7C400400, // 008A CALL R16 2 + 0x900E5E10, // 008B SETMBR R3 K47 R16 + 0x60400015, // 008C GETGBL R16 G21 + 0x7C400000, // 008D CALL R16 0 + 0x8C40211B, // 008E GETMET R16 R16 K27 + 0x58480031, // 008F LDCONST R18 K49 + 0x7C400400, // 0090 CALL R16 2 + 0x8844091A, // 0091 GETMBR R17 R4 K26 + 0x8848072F, // 0092 GETMBR R18 R3 K47 + 0x00442212, // 0093 ADD R17 R17 R18 + 0x8C48051D, // 0094 GETMET R18 R2 K29 + 0x7C480200, // 0095 CALL R18 1 + 0x8C48251E, // 0096 GETMET R18 R18 K30 + 0x8850071F, // 0097 GETMBR R20 R3 K31 + 0x5C542200, // 0098 MOVE R21 R17 + 0x5C582000, // 0099 MOVE R22 R16 + 0x545E000F, // 009A LDINT R23 16 + 0x7C480A00, // 009B CALL R18 5 + 0x8C4C0522, // 009C GETMET R19 R2 K34 + 0x5C542400, // 009D MOVE R21 R18 + 0x60580015, // 009E GETGBL R22 G21 + 0x7C580000, // 009F CALL R22 0 + 0x8C582D1B, // 00A0 GETMET R22 R22 K27 + 0x58600032, // 00A1 LDCONST R24 K50 + 0x7C580400, // 00A2 CALL R22 2 + 0x605C0015, // 00A3 GETGBL R23 G21 + 0x7C5C0000, // 00A4 CALL R23 0 + 0x58600004, // 00A5 LDCONST R24 K4 + 0x5466000F, // 00A6 LDINT R25 16 + 0x7C4C0C00, // 00A7 CALL R19 6 + 0x8C502724, // 00A8 GETMET R20 R19 K36 + 0x7C500200, // 00A9 CALL R20 1 + 0xB8561A00, // 00AA GETNGBL R21 K13 + 0x8C542B33, // 00AB GETMET R21 R21 K51 + 0x7C540200, // 00AC CALL R21 1 + 0x8858072F, // 00AD GETMBR R22 R3 K47 + 0x90562816, // 00AE SETMBR R21 K20 R22 + 0x8858072A, // 00AF GETMBR R22 R3 K42 + 0x90566816, // 00B0 SETMBR R21 K52 R22 + 0x90566A14, // 00B1 SETMBR R21 K53 R20 + 0x8C58051D, // 00B2 GETMET R22 R2 K29 + 0x7C580200, // 00B3 CALL R22 1 + 0x8C582D1E, // 00B4 GETMET R22 R22 K30 + 0x8860071F, // 00B5 GETMBR R24 R3 K31 + 0x8864091A, // 00B6 GETMBR R25 R4 K26 + 0x8868072F, // 00B7 GETMBR R26 R3 K47 + 0x0064321A, // 00B8 ADD R25 R25 R26 + 0x60680015, // 00B9 GETGBL R26 G21 + 0x7C680000, // 00BA CALL R26 0 + 0x8C68351B, // 00BB GETMET R26 R26 K27 + 0x58700036, // 00BC LDCONST R28 K54 + 0x7C680400, // 00BD CALL R26 2 + 0x546E002F, // 00BE LDINT R27 48 + 0x7C580A00, // 00BF CALL R22 5 + 0x545E000E, // 00C0 LDINT R23 15 + 0x405E0817, // 00C1 CONNECT R23 K4 R23 + 0x945C2C17, // 00C2 GETIDX R23 R22 R23 + 0x5462000F, // 00C3 LDINT R24 16 + 0x5466001E, // 00C4 LDINT R25 31 + 0x40603019, // 00C5 CONNECT R24 R24 R25 + 0x94602C18, // 00C6 GETIDX R24 R22 R24 + 0x5466001F, // 00C7 LDINT R25 32 + 0x546A002E, // 00C8 LDINT R26 47 + 0x4064321A, // 00C9 CONNECT R25 R25 R26 + 0x94642C19, // 00CA GETIDX R25 R22 R25 + 0xB86A0C00, // 00CB GETNGBL R26 K6 + 0x8C683537, // 00CC GETMET R26 R26 K55 + 0x7C680200, // 00CD CALL R26 1 + 0x8C6C2B38, // 00CE GETMET R27 R21 K56 + 0x7C6C0200, // 00CF CALL R27 1 + 0x4C700000, // 00D0 LDNIL R28 + 0x900E721C, // 00D1 SETMBR R3 K57 R28 + 0x8C70033A, // 00D2 GETMET R28 R1 K58 + 0x547A0032, // 00D3 LDINT R30 51 + 0x507C0200, // 00D4 LDBOOL R31 1 0 + 0x7C700600, // 00D5 CALL R28 3 + 0x8C74393B, // 00D6 GETMET R29 R28 K59 + 0x5C7C3600, // 00D7 MOVE R31 R27 + 0x7C740400, // 00D8 CALL R29 2 + 0x8878013C, // 00D9 GETMBR R30 R0 K60 + 0x8C783D3D, // 00DA GETMET R30 R30 K61 + 0x5C803800, // 00DB MOVE R32 R28 + 0x7C780400, // 00DC CALL R30 2 + 0x8C78073E, // 00DD GETMET R30 R3 K62 + 0x7C780200, // 00DE CALL R30 1 + 0x8C78073F, // 00DF GETMET R30 R3 K63 + 0x5C802E00, // 00E0 MOVE R32 R23 + 0x5C843000, // 00E1 MOVE R33 R24 + 0x5C883200, // 00E2 MOVE R34 R25 + 0x5C8C3400, // 00E3 MOVE R35 R26 + 0x7C780A00, // 00E4 CALL R30 5 + 0x900E8104, // 00E5 SETMBR R3 K64 K4 + 0x8C780741, // 00E6 GETMET R30 R3 K65 + 0x7C780200, // 00E7 CALL R30 1 + 0x8C780742, // 00E8 GETMET R30 R3 K66 + 0x50800200, // 00E9 LDBOOL R32 1 0 + 0x7C780400, // 00EA CALL R30 2 + 0x8C780743, // 00EB GETMET R30 R3 K67 + 0x7C780200, // 00EC CALL R30 1 + 0x8C780744, // 00ED GETMET R30 R3 K68 + 0x7C780200, // 00EE CALL R30 1 + 0x8C780745, // 00EF GETMET R30 R3 K69 + 0x7C780200, // 00F0 CALL R30 1 + 0x50780200, // 00F1 LDBOOL R30 1 0 + 0x80043C00, // 00F2 RET 1 R30 + 0x70020000, // 00F3 JMP #00F5 + 0x50140000, // 00F4 LDBOOL R5 0 0 + 0x5C1C0A00, // 00F5 MOVE R7 R5 + 0x741E00E7, // 00F6 JMPT R7 #01DF + 0x8C1C0146, // 00F7 GETMET R7 R0 K70 + 0x88240947, // 00F8 GETMBR R9 R4 K71 + 0x8828091A, // 00F9 GETMBR R10 R4 K26 + 0x7C1C0600, // 00FA CALL R7 3 + 0x900E3207, // 00FB SETMBR R3 K25 R7 + 0x4C200000, // 00FC LDNIL R8 + 0x1C200608, // 00FD EQ R8 R3 R8 + 0x74220003, // 00FE JMPT R8 #0103 + 0x88200719, // 00FF GETMBR R8 R3 K25 + 0x4C240000, // 0100 LDNIL R9 + 0x1C201009, // 0101 EQ R8 R8 R9 + 0x7822000D, // 0102 JMPF R8 #0111 + 0xB8220C00, // 0103 GETNGBL R8 K6 + 0x8C201107, // 0104 GETMET R8 R8 K7 + 0x58280048, // 0105 LDCONST R10 K72 + 0x582C0009, // 0106 LDCONST R11 K9 + 0x7C200600, // 0107 CALL R8 3 + 0x8C20010A, // 0108 GETMET R8 R0 K10 + 0x5C280200, // 0109 MOVE R10 R1 + 0x582C000B, // 010A LDCONST R11 K11 + 0x58300004, // 010B LDCONST R12 K4 + 0x5834000B, // 010C LDCONST R13 K11 + 0x50380000, // 010D LDBOOL R14 0 0 + 0x7C200C00, // 010E CALL R8 6 + 0x50200000, // 010F LDBOOL R8 0 0 + 0x80041000, // 0110 RET 1 R8 + 0x88200326, // 0111 GETMBR R8 R1 K38 + 0x900E4A08, // 0112 SETMBR R3 K37 R8 + 0x8C200727, // 0113 GETMET R8 R3 K39 + 0x7C200200, // 0114 CALL R8 1 + 0x88200929, // 0115 GETMBR R8 R4 K41 + 0x900E5008, // 0116 SETMBR R3 K40 R8 + 0x88200116, // 0117 GETMBR R8 R0 K22 + 0x88201117, // 0118 GETMBR R8 R8 K23 + 0x8C20112B, // 0119 GETMET R8 R8 K43 + 0x7C200200, // 011A CALL R8 1 + 0x900E5408, // 011B SETMBR R3 K42 R8 + 0xB8220C00, // 011C GETNGBL R8 K6 + 0x8C201107, // 011D GETMET R8 R8 K7 + 0x60280018, // 011E GETGBL R10 G24 + 0x582C002C, // 011F LDCONST R11 K44 + 0x8830072A, // 0120 GETMBR R12 R3 K42 + 0x8834032D, // 0121 GETMBR R13 R1 K45 + 0x8838032E, // 0122 GETMBR R14 R1 K46 + 0x7C280800, // 0123 CALL R10 4 + 0x582C0009, // 0124 LDCONST R11 K9 + 0x7C200600, // 0125 CALL R8 3 + 0x8C200530, // 0126 GETMET R8 R2 K48 + 0x542A000F, // 0127 LDINT R10 16 + 0x7C200400, // 0128 CALL R8 2 + 0x900E5E08, // 0129 SETMBR R3 K47 R8 + 0x8C200530, // 012A GETMET R8 R2 K48 + 0x542A001F, // 012B LDINT R10 32 + 0x7C200400, // 012C CALL R8 2 + 0x900E9208, // 012D SETMBR R3 K73 R8 + 0x8C20054B, // 012E GETMET R8 R2 K75 + 0x7C200200, // 012F CALL R8 1 + 0x8C20114C, // 0130 GETMET R8 R8 K76 + 0x88280749, // 0131 GETMBR R10 R3 K73 + 0x7C200400, // 0132 CALL R8 2 + 0x900E9408, // 0133 SETMBR R3 K74 R8 + 0x8C200530, // 0134 GETMET R8 R2 K48 + 0x542A001F, // 0135 LDINT R10 32 + 0x7C200400, // 0136 CALL R8 2 + 0x8C24054B, // 0137 GETMET R9 R2 K75 + 0x7C240200, // 0138 CALL R9 1 + 0x8C24134D, // 0139 GETMET R9 R9 K77 + 0x882C0749, // 013A GETMBR R11 R3 K73 + 0x88300913, // 013B GETMBR R12 R4 K19 + 0x7C240600, // 013C CALL R9 3 + 0x900E3E09, // 013D SETMBR R3 K31 R9 + 0xB8261A00, // 013E GETNGBL R9 K13 + 0x8824134E, // 013F GETMBR R9 R9 K78 + 0x8C24134F, // 0140 GETMET R9 R9 K79 0x7C240200, // 0141 CALL R9 1 - 0x90125E09, // 0142 SETMBR R4 K47 R9 - 0xB8260E00, // 0143 GETNGBL R9 K7 - 0x8C241308, // 0144 GETMET R9 R9 K8 - 0x8C2C0712, // 0145 GETMET R11 R3 K18 - 0x58340031, // 0146 LDCONST R13 K49 - 0x8838092F, // 0147 GETMBR R14 R4 K47 - 0x883C0332, // 0148 GETMBR R15 R1 K50 - 0x88400333, // 0149 GETMBR R16 R1 K51 - 0x7C2C0A00, // 014A CALL R11 5 - 0x5830000A, // 014B LDCONST R12 K10 - 0x7C240600, // 014C CALL R9 3 - 0xB8260E00, // 014D GETNGBL R9 K7 - 0x8C241308, // 014E GETMET R9 R9 K8 - 0xB82E1A00, // 014F GETNGBL R11 K13 - 0x8C2C1714, // 0150 GETMET R11 R11 K20 - 0x8834091E, // 0151 GETMBR R13 R4 K30 - 0x7C2C0400, // 0152 CALL R11 2 - 0x002E9E0B, // 0153 ADD R11 K79 R11 - 0x54320003, // 0154 LDINT R12 4 - 0x7C240600, // 0155 CALL R9 3 - 0xB8260E00, // 0156 GETNGBL R9 K7 - 0x8C241308, // 0157 GETMET R9 R9 K8 - 0x882C091E, // 0158 GETMBR R11 R4 K30 - 0x882C1751, // 0159 GETMBR R11 R11 K81 - 0x8C2C1752, // 015A GETMET R11 R11 K82 - 0x7C2C0200, // 015B CALL R11 1 - 0x002EA00B, // 015C ADD R11 K80 R11 - 0x54320003, // 015D LDINT R12 4 - 0x7C240600, // 015E CALL R9 3 - 0xB8260E00, // 015F GETNGBL R9 K7 - 0x8C241308, // 0160 GETMET R9 R9 K8 - 0x882C091E, // 0161 GETMBR R11 R4 K30 - 0x882C1754, // 0162 GETMBR R11 R11 K84 - 0x8C2C1752, // 0163 GETMET R11 R11 K82 - 0x7C2C0200, // 0164 CALL R11 1 - 0x002EA60B, // 0165 ADD R11 K83 R11 - 0x54320003, // 0166 LDINT R12 4 - 0x7C240600, // 0167 CALL R9 3 - 0x8824091E, // 0168 GETMBR R9 R4 K30 - 0x8C241355, // 0169 GETMET R9 R9 K85 - 0x7C240200, // 016A CALL R9 1 - 0x78260009, // 016B JMPF R9 #0176 - 0xB8260E00, // 016C GETNGBL R9 K7 - 0x8C241308, // 016D GETMET R9 R9 K8 - 0x882C091E, // 016E GETMBR R11 R4 K30 - 0x8C2C1755, // 016F GETMET R11 R11 K85 - 0x7C2C0200, // 0170 CALL R11 1 - 0x8C2C1752, // 0171 GETMET R11 R11 K82 - 0x7C2C0200, // 0172 CALL R11 1 - 0x002EAC0B, // 0173 ADD R11 K86 R11 - 0x54320003, // 0174 LDINT R12 4 - 0x7C240600, // 0175 CALL R9 3 - 0xB8260E00, // 0176 GETNGBL R9 K7 - 0x8C241308, // 0177 GETMET R9 R9 K8 - 0x882C091E, // 0178 GETMBR R11 R4 K30 - 0x882C1758, // 0179 GETMBR R11 R11 K88 - 0x8C2C1752, // 017A GETMET R11 R11 K82 - 0x7C2C0200, // 017B CALL R11 1 - 0x002EAE0B, // 017C ADD R11 K87 R11 - 0x54320003, // 017D LDINT R12 4 - 0x7C240600, // 017E CALL R9 3 - 0x8C240535, // 017F GETMET R9 R2 K53 - 0x542E000F, // 0180 LDINT R11 16 - 0x7C240400, // 0181 CALL R9 2 - 0x90126809, // 0182 SETMBR R4 K52 R9 - 0x8C240535, // 0183 GETMET R9 R2 K53 - 0x542E001F, // 0184 LDINT R11 32 - 0x7C240400, // 0185 CALL R9 2 - 0x9012B209, // 0186 SETMBR R4 K89 R9 - 0x8C24055B, // 0187 GETMET R9 R2 K91 - 0x7C240200, // 0188 CALL R9 1 - 0x8C24135C, // 0189 GETMET R9 R9 K92 - 0x882C0959, // 018A GETMBR R11 R4 K89 - 0x7C240400, // 018B CALL R9 2 - 0x9012B409, // 018C SETMBR R4 K90 R9 - 0xB8260E00, // 018D GETNGBL R9 K7 - 0x8C241308, // 018E GETMET R9 R9 K8 - 0x882C0959, // 018F GETMBR R11 R4 K89 - 0x8C2C1752, // 0190 GETMET R11 R11 K82 - 0x7C2C0200, // 0191 CALL R11 1 - 0x002EBA0B, // 0192 ADD R11 K93 R11 - 0x54320003, // 0193 LDINT R12 4 - 0x7C240600, // 0194 CALL R9 3 - 0xB8260E00, // 0195 GETNGBL R9 K7 - 0x8C241308, // 0196 GETMET R9 R9 K8 - 0x882C095A, // 0197 GETMBR R11 R4 K90 - 0x8C2C1752, // 0198 GETMET R11 R11 K82 - 0x7C2C0200, // 0199 CALL R11 1 - 0x002EBC0B, // 019A ADD R11 K94 R11 - 0x54320003, // 019B LDINT R12 4 - 0x7C240600, // 019C CALL R9 3 - 0x8C240535, // 019D GETMET R9 R2 K53 - 0x542E001F, // 019E LDINT R11 32 - 0x7C240400, // 019F CALL R9 2 - 0x8C28055B, // 01A0 GETMET R10 R2 K91 - 0x7C280200, // 01A1 CALL R10 1 - 0x8C28155F, // 01A2 GETMET R10 R10 K95 - 0x88300959, // 01A3 GETMBR R12 R4 K89 - 0x88340B16, // 01A4 GETMBR R13 R5 K22 - 0x7C280600, // 01A5 CALL R10 3 - 0x9012480A, // 01A6 SETMBR R4 K36 R10 - 0xB82A1A00, // 01A7 GETNGBL R10 K13 - 0x88281560, // 01A8 GETMBR R10 R10 K96 - 0x8C281561, // 01A9 GETMET R10 R10 K97 - 0x7C280200, // 01AA CALL R10 1 - 0x8C2C1562, // 01AB GETMET R11 R10 K98 - 0x5834000C, // 01AC LDCONST R13 K12 - 0xB83A1A00, // 01AD GETNGBL R14 K13 - 0x88381D60, // 01AE GETMBR R14 R14 K96 - 0x88381D63, // 01AF GETMBR R14 R14 K99 - 0x8C3C0964, // 01B0 GETMET R15 R4 K100 - 0x7C3C0200, // 01B1 CALL R15 1 - 0x7C2C0800, // 01B2 CALL R11 4 - 0x8C2C1562, // 01B3 GETMET R11 R10 K98 - 0x5834000A, // 01B4 LDCONST R13 K10 - 0xB83A1A00, // 01B5 GETNGBL R14 K13 - 0x88381D60, // 01B6 GETMBR R14 R14 K96 - 0x88381D63, // 01B7 GETMBR R14 R14 K99 - 0x8C3C0955, // 01B8 GETMET R15 R4 K85 - 0x7C3C0200, // 01B9 CALL R15 1 - 0x7C2C0800, // 01BA CALL R11 4 - 0x8C2C1562, // 01BB GETMET R11 R10 K98 - 0x58340065, // 01BC LDCONST R13 K101 - 0xB83A1A00, // 01BD GETNGBL R14 K13 - 0x88381D60, // 01BE GETMBR R14 R14 K96 - 0x88381D63, // 01BF GETMBR R14 R14 K99 - 0x883C095A, // 01C0 GETMBR R15 R4 K90 - 0x7C2C0800, // 01C1 CALL R11 4 - 0x8C2C1562, // 01C2 GETMET R11 R10 K98 - 0x54360003, // 01C3 LDINT R13 4 - 0xB83A1A00, // 01C4 GETNGBL R14 K13 - 0x88381D60, // 01C5 GETMBR R14 R14 K96 - 0x88381D63, // 01C6 GETMBR R14 R14 K99 - 0x883C0B16, // 01C7 GETMBR R15 R5 K22 - 0x7C2C0800, // 01C8 CALL R11 4 - 0x8C2C055B, // 01C9 GETMET R11 R2 K91 - 0x7C2C0200, // 01CA CALL R11 1 - 0x8C2C1766, // 01CB GETMET R11 R11 K102 - 0x8C340967, // 01CC GETMET R13 R4 K103 - 0x7C340200, // 01CD CALL R13 1 - 0x8C38153E, // 01CE GETMET R14 R10 K62 - 0x7C380200, // 01CF CALL R14 1 - 0x7C2C0600, // 01D0 CALL R11 3 - 0xB8321A00, // 01D1 GETNGBL R12 K13 - 0x88301960, // 01D2 GETMBR R12 R12 K96 - 0x8C301961, // 01D3 GETMET R12 R12 K97 - 0x7C300200, // 01D4 CALL R12 1 - 0x8C341962, // 01D5 GETMET R13 R12 K98 - 0x583C000C, // 01D6 LDCONST R15 K12 - 0xB8421A00, // 01D7 GETNGBL R16 K13 - 0x88402160, // 01D8 GETMBR R16 R16 K96 - 0x88402163, // 01D9 GETMBR R16 R16 K99 - 0x8C440964, // 01DA GETMET R17 R4 K100 - 0x7C440200, // 01DB CALL R17 1 - 0x7C340800, // 01DC CALL R13 4 - 0x8C341962, // 01DD GETMET R13 R12 K98 - 0x583C000A, // 01DE LDCONST R15 K10 - 0xB8421A00, // 01DF GETNGBL R16 K13 - 0x88402160, // 01E0 GETMBR R16 R16 K96 - 0x88402163, // 01E1 GETMBR R16 R16 K99 - 0x8C440955, // 01E2 GETMET R17 R4 K85 - 0x7C440200, // 01E3 CALL R17 1 - 0x7C340800, // 01E4 CALL R13 4 - 0x8C341962, // 01E5 GETMET R13 R12 K98 - 0x583C0065, // 01E6 LDCONST R15 K101 - 0xB8421A00, // 01E7 GETNGBL R16 K13 - 0x88402160, // 01E8 GETMBR R16 R16 K96 - 0x88402163, // 01E9 GETMBR R16 R16 K99 - 0x5C441600, // 01EA MOVE R17 R11 - 0x7C340800, // 01EB CALL R13 4 - 0x8C341962, // 01EC GETMET R13 R12 K98 - 0x543E0003, // 01ED LDINT R15 4 - 0xB8421A00, // 01EE GETNGBL R16 K13 - 0x88402160, // 01EF GETMBR R16 R16 K96 - 0x88402163, // 01F0 GETMBR R16 R16 K99 - 0x88440934, // 01F1 GETMBR R17 R4 K52 - 0x7C340800, // 01F2 CALL R13 4 - 0x88340B68, // 01F3 GETMBR R13 R5 K104 - 0x90127E0D, // 01F4 SETMBR R4 K63 R13 - 0x8C340569, // 01F5 GETMET R13 R2 K105 - 0x7C340200, // 01F6 CALL R13 1 - 0x8C341B6A, // 01F7 GETMET R13 R13 K106 - 0x883C093F, // 01F8 GETMBR R15 R4 K63 - 0x7C340400, // 01F9 CALL R13 2 - 0x8C341B6B, // 01FA GETMET R13 R13 K107 - 0x7C340200, // 01FB CALL R13 1 - 0x60380015, // 01FC GETGBL R14 G21 - 0x7C380000, // 01FD CALL R14 0 - 0x8C381D20, // 01FE GETMET R14 R14 K32 - 0x8840016C, // 01FF GETMBR R16 R0 K108 - 0x7C380400, // 0200 CALL R14 2 - 0x8C3C096D, // 0201 GETMET R15 R4 K109 - 0x7C3C0200, // 0202 CALL R15 1 - 0x003C1E09, // 0203 ADD R15 R15 R9 - 0x8840095A, // 0204 GETMBR R16 R4 K90 - 0x003C1E10, // 0205 ADD R15 R15 R16 - 0x003C1E0D, // 0206 ADD R15 R15 R13 - 0x8C400522, // 0207 GETMET R16 R2 K34 - 0x7C400200, // 0208 CALL R16 1 - 0x8C402123, // 0209 GETMET R16 R16 K35 - 0x88480924, // 020A GETMBR R18 R4 K36 - 0x5C4C1E00, // 020B MOVE R19 R15 - 0x5C501C00, // 020C MOVE R20 R14 - 0x5456000F, // 020D LDINT R21 16 - 0x7C400A00, // 020E CALL R16 5 - 0x8C44193E, // 020F GETMET R17 R12 K62 - 0x7C440200, // 0210 CALL R17 1 - 0x8C480527, // 0211 GETMET R18 R2 K39 - 0x5C502000, // 0212 MOVE R20 R16 - 0x60540015, // 0213 GETGBL R21 G21 - 0x7C540000, // 0214 CALL R21 0 - 0x8C542B20, // 0215 GETMET R21 R21 K32 - 0x885C016E, // 0216 GETMBR R23 R0 K110 - 0x7C540400, // 0217 CALL R21 2 - 0x60580015, // 0218 GETGBL R22 G21 - 0x7C580000, // 0219 CALL R22 0 - 0x605C000C, // 021A GETGBL R23 G12 - 0x5C602200, // 021B MOVE R24 R17 - 0x7C5C0200, // 021C CALL R23 1 - 0x5462000F, // 021D LDINT R24 16 - 0x7C480C00, // 021E CALL R18 6 - 0x8C4C256F, // 021F GETMET R19 R18 K111 - 0x5C542200, // 0220 MOVE R21 R17 - 0x7C4C0400, // 0221 CALL R19 2 - 0x8C502529, // 0222 GETMET R20 R18 K41 - 0x7C500200, // 0223 CALL R20 1 - 0x004C2614, // 0224 ADD R19 R19 R20 - 0xB8521A00, // 0225 GETNGBL R20 K13 - 0x8C502970, // 0226 GETMET R20 R20 K112 - 0x7C500200, // 0227 CALL R20 1 - 0x9052E209, // 0228 SETMBR R20 K113 R9 - 0x8854092F, // 0229 GETMBR R21 R4 K47 - 0x9052E415, // 022A SETMBR R20 K114 R21 - 0x8854095A, // 022B GETMBR R21 R4 K90 - 0x9052E615, // 022C SETMBR R20 K115 R21 - 0x9052E813, // 022D SETMBR R20 K116 R19 - 0x8C54293E, // 022E GETMET R21 R20 K62 - 0x7C540200, // 022F CALL R21 1 - 0x9012EA15, // 0230 SETMBR R4 K117 R21 - 0x8C580340, // 0231 GETMET R22 R1 K64 - 0x54620030, // 0232 LDINT R24 49 - 0x50640200, // 0233 LDBOOL R25 1 0 - 0x7C580600, // 0234 CALL R22 3 - 0x8C5C2D41, // 0235 GETMET R23 R22 K65 - 0x5C642A00, // 0236 MOVE R25 R21 - 0x7C5C0400, // 0237 CALL R23 2 - 0x88600142, // 0238 GETMBR R24 R0 K66 - 0x8C603143, // 0239 GETMET R24 R24 K67 - 0x5C682C00, // 023A MOVE R26 R22 - 0x7C600400, // 023B CALL R24 2 - 0x50600200, // 023C LDBOOL R24 1 0 - 0x80043000, // 023D RET 1 R24 - 0x50200200, // 023E LDBOOL R8 1 0 - 0x80041000, // 023F RET 1 R8 + 0x8C281350, // 0142 GETMET R10 R9 K80 + 0x5830000B, // 0143 LDCONST R12 K11 + 0xB8361A00, // 0144 GETNGBL R13 K13 + 0x88341B4E, // 0145 GETMBR R13 R13 K78 + 0x88341B51, // 0146 GETMBR R13 R13 K81 + 0x8C380F52, // 0147 GETMET R14 R7 K82 + 0x7C380200, // 0148 CALL R14 1 + 0x7C280800, // 0149 CALL R10 4 + 0x8C281350, // 014A GETMET R10 R9 K80 + 0x5830000C, // 014B LDCONST R12 K12 + 0xB8361A00, // 014C GETNGBL R13 K13 + 0x88341B4E, // 014D GETMBR R13 R13 K78 + 0x88341B51, // 014E GETMBR R13 R13 K81 + 0x8C380F53, // 014F GETMET R14 R7 K83 + 0x7C380200, // 0150 CALL R14 1 + 0x7C280800, // 0151 CALL R10 4 + 0x8C281350, // 0152 GETMET R10 R9 K80 + 0x58300009, // 0153 LDCONST R12 K9 + 0xB8361A00, // 0154 GETNGBL R13 K13 + 0x88341B4E, // 0155 GETMBR R13 R13 K78 + 0x88341B51, // 0156 GETMBR R13 R13 K81 + 0x8838074A, // 0157 GETMBR R14 R3 K74 + 0x7C280800, // 0158 CALL R10 4 + 0x8C281350, // 0159 GETMET R10 R9 K80 + 0x54320003, // 015A LDINT R12 4 + 0xB8361A00, // 015B GETNGBL R13 K13 + 0x88341B4E, // 015C GETMBR R13 R13 K78 + 0x88341B51, // 015D GETMBR R13 R13 K81 + 0x88380913, // 015E GETMBR R14 R4 K19 + 0x7C280800, // 015F CALL R10 4 + 0x8C28054B, // 0160 GETMET R10 R2 K75 + 0x7C280200, // 0161 CALL R10 1 + 0x8C281554, // 0162 GETMET R10 R10 K84 + 0x8C300F55, // 0163 GETMET R12 R7 K85 + 0x7C300200, // 0164 CALL R12 1 + 0x8C341338, // 0165 GETMET R13 R9 K56 + 0x7C340200, // 0166 CALL R13 1 + 0x7C280600, // 0167 CALL R10 3 + 0xB82E1A00, // 0168 GETNGBL R11 K13 + 0x882C174E, // 0169 GETMBR R11 R11 K78 + 0x8C2C174F, // 016A GETMET R11 R11 K79 + 0x7C2C0200, // 016B CALL R11 1 + 0x8C301750, // 016C GETMET R12 R11 K80 + 0x5838000B, // 016D LDCONST R14 K11 + 0xB83E1A00, // 016E GETNGBL R15 K13 + 0x883C1F4E, // 016F GETMBR R15 R15 K78 + 0x883C1F51, // 0170 GETMBR R15 R15 K81 + 0x8C400F52, // 0171 GETMET R16 R7 K82 + 0x7C400200, // 0172 CALL R16 1 + 0x7C300800, // 0173 CALL R12 4 + 0x8C301750, // 0174 GETMET R12 R11 K80 + 0x5838000C, // 0175 LDCONST R14 K12 + 0xB83E1A00, // 0176 GETNGBL R15 K13 + 0x883C1F4E, // 0177 GETMBR R15 R15 K78 + 0x883C1F51, // 0178 GETMBR R15 R15 K81 + 0x8C400F53, // 0179 GETMET R16 R7 K83 + 0x7C400200, // 017A CALL R16 1 + 0x7C300800, // 017B CALL R12 4 + 0x8C301750, // 017C GETMET R12 R11 K80 + 0x58380009, // 017D LDCONST R14 K9 + 0xB83E1A00, // 017E GETNGBL R15 K13 + 0x883C1F4E, // 017F GETMBR R15 R15 K78 + 0x883C1F51, // 0180 GETMBR R15 R15 K81 + 0x5C401400, // 0181 MOVE R16 R10 + 0x7C300800, // 0182 CALL R12 4 + 0x8C301750, // 0183 GETMET R12 R11 K80 + 0x543A0003, // 0184 LDINT R14 4 + 0xB83E1A00, // 0185 GETNGBL R15 K13 + 0x883C1F4E, // 0186 GETMBR R15 R15 K78 + 0x883C1F51, // 0187 GETMBR R15 R15 K81 + 0x8840072F, // 0188 GETMBR R16 R3 K47 + 0x7C300800, // 0189 CALL R12 4 + 0x88300956, // 018A GETMBR R12 R4 K86 + 0x900E720C, // 018B SETMBR R3 K57 R12 + 0x8C300557, // 018C GETMET R12 R2 K87 + 0x7C300200, // 018D CALL R12 1 + 0x8C301958, // 018E GETMET R12 R12 K88 + 0x88380739, // 018F GETMBR R14 R3 K57 + 0x7C300400, // 0190 CALL R12 2 + 0x8C301959, // 0191 GETMET R12 R12 K89 + 0x7C300200, // 0192 CALL R12 1 + 0x60340015, // 0193 GETGBL R13 G21 + 0x7C340000, // 0194 CALL R13 0 + 0x8C341B1B, // 0195 GETMET R13 R13 K27 + 0x883C015A, // 0196 GETMBR R15 R0 K90 + 0x7C340400, // 0197 CALL R13 2 + 0x8C380F5B, // 0198 GETMET R14 R7 K91 + 0x7C380200, // 0199 CALL R14 1 + 0x00381C08, // 019A ADD R14 R14 R8 + 0x883C074A, // 019B GETMBR R15 R3 K74 + 0x00381C0F, // 019C ADD R14 R14 R15 + 0x00381C0C, // 019D ADD R14 R14 R12 + 0x8C3C051D, // 019E GETMET R15 R2 K29 + 0x7C3C0200, // 019F CALL R15 1 + 0x8C3C1F1E, // 01A0 GETMET R15 R15 K30 + 0x8844071F, // 01A1 GETMBR R17 R3 K31 + 0x5C481C00, // 01A2 MOVE R18 R14 + 0x5C4C1A00, // 01A3 MOVE R19 R13 + 0x5452000F, // 01A4 LDINT R20 16 + 0x7C3C0A00, // 01A5 CALL R15 5 + 0x8C401738, // 01A6 GETMET R16 R11 K56 + 0x7C400200, // 01A7 CALL R16 1 + 0x8C440522, // 01A8 GETMET R17 R2 K34 + 0x5C4C1E00, // 01A9 MOVE R19 R15 + 0x60500015, // 01AA GETGBL R20 G21 + 0x7C500000, // 01AB CALL R20 0 + 0x8C50291B, // 01AC GETMET R20 R20 K27 + 0x8858015C, // 01AD GETMBR R22 R0 K92 + 0x7C500400, // 01AE CALL R20 2 + 0x60540015, // 01AF GETGBL R21 G21 + 0x7C540000, // 01B0 CALL R21 0 + 0x6058000C, // 01B1 GETGBL R22 G12 + 0x5C5C2000, // 01B2 MOVE R23 R16 + 0x7C580200, // 01B3 CALL R22 1 + 0x545E000F, // 01B4 LDINT R23 16 + 0x7C440C00, // 01B5 CALL R17 6 + 0x8C48235D, // 01B6 GETMET R18 R17 K93 + 0x5C502000, // 01B7 MOVE R20 R16 + 0x7C480400, // 01B8 CALL R18 2 + 0x8C4C2324, // 01B9 GETMET R19 R17 K36 + 0x7C4C0200, // 01BA CALL R19 1 + 0x00482413, // 01BB ADD R18 R18 R19 + 0xB84E1A00, // 01BC GETNGBL R19 K13 + 0x8C4C275E, // 01BD GETMET R19 R19 K94 + 0x7C4C0200, // 01BE CALL R19 1 + 0x904EBE08, // 01BF SETMBR R19 K95 R8 + 0x8850072A, // 01C0 GETMBR R20 R3 K42 + 0x904EC014, // 01C1 SETMBR R19 K96 R20 + 0x8850074A, // 01C2 GETMBR R20 R3 K74 + 0x904EC214, // 01C3 SETMBR R19 K97 R20 + 0x904EC412, // 01C4 SETMBR R19 K98 R18 + 0x8C502738, // 01C5 GETMET R20 R19 K56 + 0x7C500200, // 01C6 CALL R20 1 + 0x900EC614, // 01C7 SETMBR R3 K99 R20 + 0x8C54033A, // 01C8 GETMET R21 R1 K58 + 0x545E0030, // 01C9 LDINT R23 49 + 0x50600200, // 01CA LDBOOL R24 1 0 + 0x7C540600, // 01CB CALL R21 3 + 0x8C582B3B, // 01CC GETMET R22 R21 K59 + 0x5C602800, // 01CD MOVE R24 R20 + 0x7C580400, // 01CE CALL R22 2 + 0xB85E0C00, // 01CF GETNGBL R23 K6 + 0x8C5C2F07, // 01D0 GETMET R23 R23 K7 + 0x60640018, // 01D1 GETGBL R25 G24 + 0x58680064, // 01D2 LDCONST R26 K100 + 0x886C072A, // 01D3 GETMBR R27 R3 K42 + 0x88700765, // 01D4 GETMBR R28 R3 K101 + 0x88740766, // 01D5 GETMBR R29 R3 K102 + 0x7C640800, // 01D6 CALL R25 4 + 0x5868000C, // 01D7 LDCONST R26 K12 + 0x7C5C0600, // 01D8 CALL R23 3 + 0x885C013C, // 01D9 GETMBR R23 R0 K60 + 0x8C5C2F3D, // 01DA GETMET R23 R23 K61 + 0x5C642A00, // 01DB MOVE R25 R21 + 0x7C5C0400, // 01DC CALL R23 2 + 0x505C0200, // 01DD LDBOOL R23 1 0 + 0x80042E00, // 01DE RET 1 R23 + 0x501C0200, // 01DF LDBOOL R7 1 0 + 0x80040E00, // 01E0 RET 1 R7 }) ) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Control_Message.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Control_Message.h index 967c09a27c09..a60ffd973474 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Control_Message.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Control_Message.h @@ -11,7 +11,7 @@ extern const bclass be_class_Matter_Control_Message; ********************************************************************/ be_local_closure(Matter_Control_Message_parse_MsgCounterSyncRsp, /* name */ be_nested_proto( - 11, /* nstack */ + 9, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -19,39 +19,36 @@ be_local_closure(Matter_Control_Message_parse_MsgCounterSyncRsp, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(session), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(log), - /* K4 */ be_nested_str_weak(format), - /* K5 */ be_nested_str_weak(MTR_X3A_X20_X3EMCSyncRsp_X20_X2A_X20Not_X20implemented_X20_X25s), - /* K6 */ be_nested_str_weak(raw), - /* K7 */ be_nested_str_weak(app_payload_idx), - /* K8 */ be_const_int(2147483647), - /* K9 */ be_nested_str_weak(tohex), - /* K10 */ be_const_int(2), + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(session), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(log), + /* K3 */ be_nested_str_weak(MTR_X3A_X20_X3EMCSyncRsp_X20_X2A_X20Not_X20implemented_X20_X25s), + /* K4 */ be_nested_str_weak(raw), + /* K5 */ be_nested_str_weak(app_payload_idx), + /* K6 */ be_const_int(2147483647), + /* K7 */ be_nested_str_weak(tohex), + /* K8 */ be_const_int(2), }), be_str_weak(parse_MsgCounterSyncRsp), &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x880C0301, // 0001 GETMBR R3 R1 K1 - 0xB8120400, // 0002 GETNGBL R4 K2 - 0x8C100903, // 0003 GETMET R4 R4 K3 - 0x8C180504, // 0004 GETMET R6 R2 K4 - 0x58200005, // 0005 LDCONST R8 K5 - 0x88240307, // 0006 GETMBR R9 R1 K7 - 0x40241308, // 0007 CONNECT R9 R9 K8 - 0x88280306, // 0008 GETMBR R10 R1 K6 - 0x94241409, // 0009 GETIDX R9 R10 R9 - 0x8C241309, // 000A GETMET R9 R9 K9 - 0x7C240200, // 000B CALL R9 1 - 0x7C180600, // 000C CALL R6 3 - 0x581C000A, // 000D LDCONST R7 K10 - 0x7C100600, // 000E CALL R4 3 - 0x50100000, // 000F LDBOOL R4 0 0 - 0x80040800, // 0010 RET 1 R4 + ( &(const binstruction[16]) { /* code */ + 0x88080300, // 0000 GETMBR R2 R1 K0 + 0xB80E0200, // 0001 GETNGBL R3 K1 + 0x8C0C0702, // 0002 GETMET R3 R3 K2 + 0x60140018, // 0003 GETGBL R5 G24 + 0x58180003, // 0004 LDCONST R6 K3 + 0x881C0305, // 0005 GETMBR R7 R1 K5 + 0x401C0F06, // 0006 CONNECT R7 R7 K6 + 0x88200304, // 0007 GETMBR R8 R1 K4 + 0x941C1007, // 0008 GETIDX R7 R8 R7 + 0x8C1C0F07, // 0009 GETMET R7 R7 K7 + 0x7C1C0200, // 000A CALL R7 1 + 0x7C140400, // 000B CALL R5 2 + 0x58180008, // 000C LDCONST R6 K8 + 0x7C0C0600, // 000D CALL R3 3 + 0x500C0000, // 000E LDBOOL R3 0 0 + 0x80040600, // 000F RET 1 R3 }) ) ); @@ -63,7 +60,7 @@ be_local_closure(Matter_Control_Message_parse_MsgCounterSyncRsp, /* name */ ********************************************************************/ be_local_closure(Matter_Control_Message_parse_MsgCounterSyncReq, /* name */ be_nested_proto( - 11, /* nstack */ + 9, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -71,39 +68,36 @@ be_local_closure(Matter_Control_Message_parse_MsgCounterSyncReq, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(session), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(log), - /* K4 */ be_nested_str_weak(format), - /* K5 */ be_nested_str_weak(MTR_X3A_X20_X3EMCSyncReq_X20_X2A_X20Not_X20implemented_X20_X25s), - /* K6 */ be_nested_str_weak(raw), - /* K7 */ be_nested_str_weak(app_payload_idx), - /* K8 */ be_const_int(2147483647), - /* K9 */ be_nested_str_weak(tohex), - /* K10 */ be_const_int(2), + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(session), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(log), + /* K3 */ be_nested_str_weak(MTR_X3A_X20_X3EMCSyncReq_X20_X2A_X20Not_X20implemented_X20_X25s), + /* K4 */ be_nested_str_weak(raw), + /* K5 */ be_nested_str_weak(app_payload_idx), + /* K6 */ be_const_int(2147483647), + /* K7 */ be_nested_str_weak(tohex), + /* K8 */ be_const_int(2), }), be_str_weak(parse_MsgCounterSyncReq), &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x880C0301, // 0001 GETMBR R3 R1 K1 - 0xB8120400, // 0002 GETNGBL R4 K2 - 0x8C100903, // 0003 GETMET R4 R4 K3 - 0x8C180504, // 0004 GETMET R6 R2 K4 - 0x58200005, // 0005 LDCONST R8 K5 - 0x88240307, // 0006 GETMBR R9 R1 K7 - 0x40241308, // 0007 CONNECT R9 R9 K8 - 0x88280306, // 0008 GETMBR R10 R1 K6 - 0x94241409, // 0009 GETIDX R9 R10 R9 - 0x8C241309, // 000A GETMET R9 R9 K9 - 0x7C240200, // 000B CALL R9 1 - 0x7C180600, // 000C CALL R6 3 - 0x581C000A, // 000D LDCONST R7 K10 - 0x7C100600, // 000E CALL R4 3 - 0x50100000, // 000F LDBOOL R4 0 0 - 0x80040800, // 0010 RET 1 R4 + ( &(const binstruction[16]) { /* code */ + 0x88080300, // 0000 GETMBR R2 R1 K0 + 0xB80E0200, // 0001 GETNGBL R3 K1 + 0x8C0C0702, // 0002 GETMET R3 R3 K2 + 0x60140018, // 0003 GETGBL R5 G24 + 0x58180003, // 0004 LDCONST R6 K3 + 0x881C0305, // 0005 GETMBR R7 R1 K5 + 0x401C0F06, // 0006 CONNECT R7 R7 K6 + 0x88200304, // 0007 GETMBR R8 R1 K4 + 0x941C1007, // 0008 GETIDX R7 R8 R7 + 0x8C1C0F07, // 0009 GETMET R7 R7 K7 + 0x7C1C0200, // 000A CALL R7 1 + 0x7C140400, // 000B CALL R5 2 + 0x58180008, // 000C LDCONST R6 K8 + 0x7C0C0600, // 000D CALL R3 3 + 0x500C0000, // 000E LDBOOL R3 0 0 + 0x80040600, // 000F RET 1 R3 }) ) ); @@ -147,7 +141,7 @@ be_local_closure(Matter_Control_Message_init, /* name */ ********************************************************************/ be_local_closure(Matter_Control_Message_process_incoming_control_message, /* name */ be_nested_proto( - 9, /* nstack */ + 7, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -155,25 +149,24 @@ be_local_closure(Matter_Control_Message_process_incoming_control_message, /* n 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[14]) { /* constants */ + ( &(const bvalue[13]) { /* constants */ /* K0 */ be_nested_str_weak(tasmota), /* K1 */ be_nested_str_weak(log), /* K2 */ be_nested_str_weak(MTR_X3A_X20received_X20control_X20message_X20), /* K3 */ be_nested_str_weak(matter), /* K4 */ be_nested_str_weak(inspect), - /* K5 */ be_const_int(2), + /* K5 */ be_const_int(3), /* K6 */ be_nested_str_weak(opcode), /* K7 */ be_const_int(0), /* K8 */ be_nested_str_weak(parse_MsgCounterSyncReq), /* K9 */ be_const_int(1), /* K10 */ be_nested_str_weak(parse_MsgCounterSyncRsp), - /* K11 */ be_nested_str_weak(string), - /* K12 */ be_nested_str_weak(format), - /* K13 */ be_nested_str_weak(MTR_X3A_X20_X3E_X3F_X3F_X3F_X3F_X3F_X3F_X3F_X3F_X3F_X20Unknown_X20OpCode_X20_X28control_X20message_X29_X20_X2502X), + /* K11 */ be_nested_str_weak(MTR_X3A_X20_X3E_X3F_X3F_X3F_X3F_X3F_X3F_X3F_X3F_X3F_X20Unknown_X20OpCode_X20_X28control_X20message_X29_X20_X2502X), + /* K12 */ be_const_int(2), }), be_str_weak(process_incoming_control_message), &be_const_str_solidified, - ( &(const binstruction[38]) { /* code */ + ( &(const binstruction[37]) { /* code */ 0xB80A0000, // 0000 GETNGBL R2 K0 0x8C080501, // 0001 GETMET R2 R2 K1 0xB8120600, // 0002 GETNGBL R4 K3 @@ -190,7 +183,7 @@ be_local_closure(Matter_Control_Message_process_incoming_control_message, /* n 0x5C100200, // 000D MOVE R4 R1 0x7C080400, // 000E CALL R2 2 0x80040400, // 000F RET 1 R2 - 0x70020012, // 0010 JMP #0024 + 0x70020011, // 0010 JMP #0023 0x88080306, // 0011 GETMBR R2 R1 K6 0x1C080509, // 0012 EQ R2 R2 K9 0x780A0004, // 0013 JMPF R2 #0019 @@ -198,20 +191,19 @@ be_local_closure(Matter_Control_Message_process_incoming_control_message, /* n 0x5C100200, // 0015 MOVE R4 R1 0x7C080400, // 0016 CALL R2 2 0x80040400, // 0017 RET 1 R2 - 0x7002000A, // 0018 JMP #0024 - 0xA40A1600, // 0019 IMPORT R2 K11 - 0xB80E0000, // 001A GETNGBL R3 K0 - 0x8C0C0701, // 001B GETMET R3 R3 K1 - 0x8C14050C, // 001C GETMET R5 R2 K12 - 0x581C000D, // 001D LDCONST R7 K13 - 0x88200306, // 001E GETMBR R8 R1 K6 - 0x7C140600, // 001F CALL R5 3 - 0x58180005, // 0020 LDCONST R6 K5 - 0x7C0C0600, // 0021 CALL R3 3 - 0x500C0000, // 0022 LDBOOL R3 0 0 - 0x80040600, // 0023 RET 1 R3 - 0x50080000, // 0024 LDBOOL R2 0 0 - 0x80040400, // 0025 RET 1 R2 + 0x70020009, // 0018 JMP #0023 + 0xB80A0000, // 0019 GETNGBL R2 K0 + 0x8C080501, // 001A GETMET R2 R2 K1 + 0x60100018, // 001B GETGBL R4 G24 + 0x5814000B, // 001C LDCONST R5 K11 + 0x88180306, // 001D GETMBR R6 R1 K6 + 0x7C100400, // 001E CALL R4 2 + 0x5814000C, // 001F LDCONST R5 K12 + 0x7C080600, // 0020 CALL R2 3 + 0x50080000, // 0021 LDBOOL R2 0 0 + 0x80040400, // 0022 RET 1 R2 + 0x50080000, // 0023 LDBOOL R2 0 0 + 0x80040400, // 0024 RET 1 R2 }) ) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Device.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Device.h index 45b19059875f..c495049d4f0f 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Device.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Device.h @@ -7,76 +7,36 @@ extern const bclass be_class_Matter_Device; /******************************************************************** -** Solidified function: start +** Solidified function: get_plugin_class_displayname ********************************************************************/ -be_local_closure(Matter_Device_start, /* name */ +be_local_closure(Matter_Device_get_plugin_class_displayname, /* name */ be_nested_proto( - 6, /* nstack */ - 1, /* argc */ + 5, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 1]) { - be_nested_proto( - 2, /* nstack */ - 0, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 1]) { /* upvals */ - be_local_const_upval(1, 0), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(_trigger_read_sensors), - }), - be_str_weak(_anonymous_), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x68000000, // 0000 GETUPV R0 U0 - 0x8C000100, // 0001 GETMET R0 R0 K0 - 0x7C000200, // 0002 CALL R0 1 - 0x80000000, // 0003 RET 0 - }) - ), - }), + 0, /* has sup protos */ + NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 9]) { /* constants */ - /* K0 */ be_nested_str_weak(started), - /* K1 */ be_nested_str_weak(autoconf_device), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(add_cron), - /* K4 */ be_nested_str_weak(_X2A_X2F30_X20_X2A_X20_X2A_X20_X2A_X20_X2A_X20_X2A), - /* K5 */ be_nested_str_weak(matter_sensors_30s), - /* K6 */ be_nested_str_weak(_start_udp), - /* K7 */ be_nested_str_weak(UDP_PORT), - /* K8 */ be_nested_str_weak(start_mdns_announce_hostnames), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(plugins_classes), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(DISPLAY_NAME), + /* K3 */ be_nested_str_weak(), }), - be_str_weak(start), + be_str_weak(get_plugin_class_displayname), &be_const_str_solidified, - ( &(const binstruction[20]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x78060000, // 0001 JMPF R1 #0003 - 0x80000200, // 0002 RET 0 - 0x8C040101, // 0003 GETMET R1 R0 K1 - 0x7C040200, // 0004 CALL R1 1 - 0xB8060400, // 0005 GETNGBL R1 K2 - 0x8C040303, // 0006 GETMET R1 R1 K3 - 0x580C0004, // 0007 LDCONST R3 K4 - 0x84100000, // 0008 CLOSURE R4 P0 - 0x58140005, // 0009 LDCONST R5 K5 - 0x7C040800, // 000A CALL R1 4 - 0x8C040106, // 000B GETMET R1 R0 K6 - 0x880C0107, // 000C GETMBR R3 R0 K7 - 0x7C040400, // 000D CALL R1 2 - 0x8C040108, // 000E GETMET R1 R0 K8 - 0x7C040200, // 000F CALL R1 1 - 0x50040200, // 0010 LDBOOL R1 1 0 - 0x90020001, // 0011 SETMBR R0 K0 R1 - 0xA0000000, // 0012 CLOSE R0 - 0x80000000, // 0013 RET 0 + ( &(const binstruction[ 9]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C080400, // 0003 CALL R2 2 + 0x780A0001, // 0004 JMPF R2 #0007 + 0x880C0502, // 0005 GETMBR R3 R2 K2 + 0x70020000, // 0006 JMP #0008 + 0x580C0003, // 0007 LDCONST R3 K3 + 0x80040600, // 0008 RET 1 R3 }) ) ); @@ -84,11 +44,11 @@ be_local_closure(Matter_Device_start, /* name */ /******************************************************************** -** Solidified function: generate_random_passcode +** Solidified function: mdns_remove_PASE ********************************************************************/ -be_local_closure(Matter_Device_generate_random_passcode, /* name */ +be_local_closure(Matter_Device_mdns_remove_PASE, /* name */ be_nested_proto( - 7, /* nstack */ + 10, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -96,54 +56,113 @@ be_local_closure(Matter_Device_generate_random_passcode, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(crypto), - /* K1 */ be_nested_str_weak(random), - /* K2 */ be_nested_str_weak(get), - /* K3 */ be_const_int(0), - /* K4 */ be_const_int(134217727), - /* K5 */ be_const_int(99999998), - /* K6 */ be_nested_str_weak(PASSCODE_INVALID), - /* K7 */ be_nested_str_weak(stop_iteration), + ( &(const bvalue[20]) { /* constants */ + /* K0 */ be_nested_str_weak(mdns), + /* K1 */ be_nested_str_weak(mdns_pase_eth), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(log), + /* K4 */ be_nested_str_weak(MTR_X3A_X20calling_X20mdns_X2Eremove_service_X28_X25s_X2C_X20_X25s_X2C_X20_X25s_X2C_X20_X25s_X29), + /* K5 */ be_nested_str_weak(_matterc), + /* K6 */ be_nested_str_weak(_udp), + /* K7 */ be_nested_str_weak(commissioning_instance_eth), + /* K8 */ be_nested_str_weak(hostname_eth), + /* K9 */ be_const_int(3), + /* K10 */ be_nested_str_weak(MTR_X3A_X20remove_X20mDNS_X20on_X20_X25s_X20_X27_X25s_X27), + /* K11 */ be_nested_str_weak(eth), + /* K12 */ be_nested_str_weak(remove_service), + /* K13 */ be_nested_str_weak(mdns_pase_wifi), + /* K14 */ be_nested_str_weak(commissioning_instance_wifi), + /* K15 */ be_nested_str_weak(hostname_wifi), + /* K16 */ be_nested_str_weak(wifi), + /* K17 */ be_nested_str_weak(MTR_X3A_X20Exception), + /* K18 */ be_nested_str_weak(_X7C), + /* K19 */ be_const_int(2), }), - be_str_weak(generate_random_passcode), + be_str_weak(mdns_remove_PASE), &be_const_str_solidified, - ( &(const binstruction[35]) { /* code */ + ( &(const binstruction[82]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x500C0200, // 0002 LDBOOL R3 1 0 - 0x780E001D, // 0003 JMPF R3 #0022 - 0x8C0C0301, // 0004 GETMET R3 R1 K1 - 0x54160003, // 0005 LDINT R5 4 - 0x7C0C0400, // 0006 CALL R3 2 - 0x8C0C0702, // 0007 GETMET R3 R3 K2 - 0x58140003, // 0008 LDCONST R5 K3 - 0x541A0003, // 0009 LDINT R6 4 - 0x7C0C0600, // 000A CALL R3 3 - 0x2C0C0704, // 000B AND R3 R3 K4 - 0x5C080600, // 000C MOVE R2 R3 - 0x240C0505, // 000D GT R3 R2 K5 - 0x780E0000, // 000E JMPF R3 #0010 - 0x7001FFF1, // 000F JMP #0002 - 0x600C0010, // 0010 GETGBL R3 G16 - 0x88100106, // 0011 GETMBR R4 R0 K6 - 0x7C0C0200, // 0012 CALL R3 1 - 0xA8020005, // 0013 EXBLK 0 #001A - 0x5C100600, // 0014 MOVE R4 R3 - 0x7C100000, // 0015 CALL R4 0 - 0x1C140404, // 0016 EQ R5 R2 R4 - 0x78160000, // 0017 JMPF R5 #0019 - 0x4C080000, // 0018 LDNIL R2 - 0x7001FFF9, // 0019 JMP #0014 - 0x580C0007, // 001A LDCONST R3 K7 - 0xAC0C0200, // 001B CATCH R3 1 0 - 0xB0080000, // 001C RAISE 2 R0 R0 - 0x4C0C0000, // 001D LDNIL R3 - 0x200C0403, // 001E NE R3 R2 R3 - 0x780E0000, // 001F JMPF R3 #0021 - 0x80040400, // 0020 RET 1 R2 - 0x7001FFDF, // 0021 JMP #0002 - 0x80000000, // 0022 RET 0 + 0xA802003D, // 0001 EXBLK 0 #0040 + 0x88080101, // 0002 GETMBR R2 R0 K1 + 0x780A001B, // 0003 JMPF R2 #0020 + 0xB80A0400, // 0004 GETNGBL R2 K2 + 0x8C080503, // 0005 GETMET R2 R2 K3 + 0x60100018, // 0006 GETGBL R4 G24 + 0x58140004, // 0007 LDCONST R5 K4 + 0x58180005, // 0008 LDCONST R6 K5 + 0x581C0006, // 0009 LDCONST R7 K6 + 0x88200107, // 000A GETMBR R8 R0 K7 + 0x88240108, // 000B GETMBR R9 R0 K8 + 0x7C100A00, // 000C CALL R4 5 + 0x58140009, // 000D LDCONST R5 K9 + 0x7C080600, // 000E CALL R2 3 + 0xB80A0400, // 000F GETNGBL R2 K2 + 0x8C080503, // 0010 GETMET R2 R2 K3 + 0x60100018, // 0011 GETGBL R4 G24 + 0x5814000A, // 0012 LDCONST R5 K10 + 0x5818000B, // 0013 LDCONST R6 K11 + 0x881C0107, // 0014 GETMBR R7 R0 K7 + 0x7C100600, // 0015 CALL R4 3 + 0x58140009, // 0016 LDCONST R5 K9 + 0x7C080600, // 0017 CALL R2 3 + 0x50080000, // 0018 LDBOOL R2 0 0 + 0x90020202, // 0019 SETMBR R0 K1 R2 + 0x8C08030C, // 001A GETMET R2 R1 K12 + 0x58100005, // 001B LDCONST R4 K5 + 0x58140006, // 001C LDCONST R5 K6 + 0x88180107, // 001D GETMBR R6 R0 K7 + 0x881C0108, // 001E GETMBR R7 R0 K8 + 0x7C080A00, // 001F CALL R2 5 + 0x8808010D, // 0020 GETMBR R2 R0 K13 + 0x780A001B, // 0021 JMPF R2 #003E + 0xB80A0400, // 0022 GETNGBL R2 K2 + 0x8C080503, // 0023 GETMET R2 R2 K3 + 0x60100018, // 0024 GETGBL R4 G24 + 0x58140004, // 0025 LDCONST R5 K4 + 0x58180005, // 0026 LDCONST R6 K5 + 0x581C0006, // 0027 LDCONST R7 K6 + 0x8820010E, // 0028 GETMBR R8 R0 K14 + 0x8824010F, // 0029 GETMBR R9 R0 K15 + 0x7C100A00, // 002A CALL R4 5 + 0x58140009, // 002B LDCONST R5 K9 + 0x7C080600, // 002C CALL R2 3 + 0xB80A0400, // 002D GETNGBL R2 K2 + 0x8C080503, // 002E GETMET R2 R2 K3 + 0x60100018, // 002F GETGBL R4 G24 + 0x5814000A, // 0030 LDCONST R5 K10 + 0x58180010, // 0031 LDCONST R6 K16 + 0x881C010E, // 0032 GETMBR R7 R0 K14 + 0x7C100600, // 0033 CALL R4 3 + 0x58140009, // 0034 LDCONST R5 K9 + 0x7C080600, // 0035 CALL R2 3 + 0x50080000, // 0036 LDBOOL R2 0 0 + 0x90021A02, // 0037 SETMBR R0 K13 R2 + 0x8C08030C, // 0038 GETMET R2 R1 K12 + 0x58100005, // 0039 LDCONST R4 K5 + 0x58140006, // 003A LDCONST R5 K6 + 0x8818010E, // 003B GETMBR R6 R0 K14 + 0x881C010F, // 003C GETMBR R7 R0 K15 + 0x7C080A00, // 003D CALL R2 5 + 0xA8040001, // 003E EXBLK 1 1 + 0x70020010, // 003F JMP #0051 + 0xAC080002, // 0040 CATCH R2 0 2 + 0x7002000D, // 0041 JMP #0050 + 0xB8120400, // 0042 GETNGBL R4 K2 + 0x8C100903, // 0043 GETMET R4 R4 K3 + 0x60180008, // 0044 GETGBL R6 G8 + 0x5C1C0400, // 0045 MOVE R7 R2 + 0x7C180200, // 0046 CALL R6 1 + 0x001A2206, // 0047 ADD R6 K17 R6 + 0x00180D12, // 0048 ADD R6 R6 K18 + 0x601C0008, // 0049 GETGBL R7 G8 + 0x5C200600, // 004A MOVE R8 R3 + 0x7C1C0200, // 004B CALL R7 1 + 0x00180C07, // 004C ADD R6 R6 R7 + 0x581C0013, // 004D LDCONST R7 K19 + 0x7C100600, // 004E CALL R4 3 + 0x70020000, // 004F JMP #0051 + 0xB0080000, // 0050 RAISE 2 R0 R0 + 0x80000000, // 0051 RET 0 }) ) ); @@ -151,11 +170,11 @@ be_local_closure(Matter_Device_generate_random_passcode, /* name */ /******************************************************************** -** Solidified function: save_param +** Solidified function: compute_qrcode_content ********************************************************************/ -be_local_closure(Matter_Device_save_param, /* name */ +be_local_closure(Matter_Device_compute_qrcode_content, /* name */ be_nested_proto( - 11, /* nstack */ + 8, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -163,102 +182,63 @@ be_local_closure(Matter_Device_save_param, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[26]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(json), - /* K2 */ be_nested_str_weak(format), - /* K3 */ be_nested_str_weak(_X7B_X22distinguish_X22_X3A_X25i_X2C_X22passcode_X22_X3A_X25i_X2C_X22ipv4only_X22_X3A_X25s), - /* K4 */ be_nested_str_weak(root_discriminator), - /* K5 */ be_nested_str_weak(root_passcode), - /* K6 */ be_nested_str_weak(ipv4only), - /* K7 */ be_nested_str_weak(true), - /* K8 */ be_nested_str_weak(false), - /* K9 */ be_nested_str_weak(plugins_persist), - /* K10 */ be_nested_str_weak(_X2C_X22config_X22_X3A), - /* K11 */ be_nested_str_weak(dump), - /* K12 */ be_nested_str_weak(plugins_config), - /* K13 */ be_nested_str_weak(_X7D), - /* K14 */ be_nested_str_weak(FILENAME), - /* K15 */ be_nested_str_weak(w), - /* K16 */ be_nested_str_weak(write), - /* K17 */ be_nested_str_weak(close), - /* K18 */ be_nested_str_weak(tasmota), - /* K19 */ be_nested_str_weak(log), - /* K20 */ be_nested_str_weak(MTR_X3A_X20_X3DSaved_X20_X20_X20_X20_X20parameters_X25s), - /* K21 */ be_nested_str_weak(_X20and_X20condiguration), - /* K22 */ be_nested_str_weak(), - /* K23 */ be_const_int(2), - /* K24 */ be_nested_str_weak(MTR_X3A_X20Session_Store_X3A_X3Asave_X20Exception_X3A), - /* K25 */ be_nested_str_weak(_X7C), + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(resize), + /* K1 */ be_nested_str_weak(setbits), + /* K2 */ be_const_int(3), + /* K3 */ be_nested_str_weak(vendorid), + /* K4 */ be_nested_str_weak(productid), + /* K5 */ be_nested_str_weak(root_discriminator), + /* K6 */ be_nested_str_weak(root_passcode), + /* K7 */ be_const_int(134217727), + /* K8 */ be_nested_str_weak(MT_X3A), + /* K9 */ be_nested_str_weak(matter), + /* K10 */ be_nested_str_weak(Base38), + /* K11 */ be_nested_str_weak(encode), }), - be_str_weak(save_param), + be_str_weak(compute_qrcode_content), &be_const_str_solidified, - ( &(const binstruction[65]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0x8C0C0302, // 0002 GETMET R3 R1 K2 - 0x58140003, // 0003 LDCONST R5 K3 - 0x88180104, // 0004 GETMBR R6 R0 K4 - 0x881C0105, // 0005 GETMBR R7 R0 K5 - 0x88200106, // 0006 GETMBR R8 R0 K6 - 0x78220001, // 0007 JMPF R8 #000A - 0x58200007, // 0008 LDCONST R8 K7 - 0x70020000, // 0009 JMP #000B - 0x58200008, // 000A LDCONST R8 K8 - 0x7C0C0A00, // 000B CALL R3 5 - 0x88100109, // 000C GETMBR R4 R0 K9 - 0x78120004, // 000D JMPF R4 #0013 - 0x000C070A, // 000E ADD R3 R3 K10 - 0x8C10050B, // 000F GETMET R4 R2 K11 - 0x8818010C, // 0010 GETMBR R6 R0 K12 - 0x7C100400, // 0011 CALL R4 2 - 0x000C0604, // 0012 ADD R3 R3 R4 - 0x000C070D, // 0013 ADD R3 R3 K13 - 0xA8020018, // 0014 EXBLK 0 #002E - 0x60100011, // 0015 GETGBL R4 G17 - 0x8814010E, // 0016 GETMBR R5 R0 K14 - 0x5818000F, // 0017 LDCONST R6 K15 - 0x7C100400, // 0018 CALL R4 2 - 0x8C140910, // 0019 GETMET R5 R4 K16 - 0x5C1C0600, // 001A MOVE R7 R3 - 0x7C140400, // 001B CALL R5 2 - 0x8C140911, // 001C GETMET R5 R4 K17 - 0x7C140200, // 001D CALL R5 1 - 0xB8162400, // 001E GETNGBL R5 K18 - 0x8C140B13, // 001F GETMET R5 R5 K19 - 0x8C1C0302, // 0020 GETMET R7 R1 K2 - 0x58240014, // 0021 LDCONST R9 K20 - 0x88280109, // 0022 GETMBR R10 R0 K9 - 0x782A0001, // 0023 JMPF R10 #0026 - 0x58280015, // 0024 LDCONST R10 K21 - 0x70020000, // 0025 JMP #0027 - 0x58280016, // 0026 LDCONST R10 K22 - 0x7C1C0600, // 0027 CALL R7 3 - 0x58200017, // 0028 LDCONST R8 K23 - 0x7C140600, // 0029 CALL R5 3 - 0xA8040001, // 002A EXBLK 1 1 - 0x80040600, // 002B RET 1 R3 - 0xA8040001, // 002C EXBLK 1 1 - 0x70020011, // 002D JMP #0040 - 0xAC100002, // 002E CATCH R4 0 2 - 0x7002000E, // 002F JMP #003F - 0xB81A2400, // 0030 GETNGBL R6 K18 - 0x8C180D13, // 0031 GETMET R6 R6 K19 - 0x60200008, // 0032 GETGBL R8 G8 - 0x5C240800, // 0033 MOVE R9 R4 - 0x7C200200, // 0034 CALL R8 1 - 0x00223008, // 0035 ADD R8 K24 R8 - 0x00201119, // 0036 ADD R8 R8 K25 - 0x60240008, // 0037 GETGBL R9 G8 - 0x5C280A00, // 0038 MOVE R10 R5 - 0x7C240200, // 0039 CALL R9 1 - 0x00201009, // 003A ADD R8 R8 R9 - 0x58240017, // 003B LDCONST R9 K23 - 0x7C180600, // 003C CALL R6 3 - 0x80040600, // 003D RET 1 R3 - 0x70020000, // 003E JMP #0040 - 0xB0080000, // 003F RAISE 2 R0 R0 - 0x80000000, // 0040 RET 0 + ( &(const binstruction[40]) { /* code */ + 0x60040015, // 0000 GETGBL R1 G21 + 0x7C040000, // 0001 CALL R1 0 + 0x8C040300, // 0002 GETMET R1 R1 K0 + 0x540E000A, // 0003 LDINT R3 11 + 0x7C040400, // 0004 CALL R1 2 + 0x8C080301, // 0005 GETMET R2 R1 K1 + 0x58100002, // 0006 LDCONST R4 K2 + 0x5416000F, // 0007 LDINT R5 16 + 0x88180103, // 0008 GETMBR R6 R0 K3 + 0x7C080800, // 0009 CALL R2 4 + 0x8C080301, // 000A GETMET R2 R1 K1 + 0x54120012, // 000B LDINT R4 19 + 0x5416000F, // 000C LDINT R5 16 + 0x88180104, // 000D GETMBR R6 R0 K4 + 0x7C080800, // 000E CALL R2 4 + 0x8C080301, // 000F GETMET R2 R1 K1 + 0x54120024, // 0010 LDINT R4 37 + 0x54160007, // 0011 LDINT R5 8 + 0x541A0003, // 0012 LDINT R6 4 + 0x7C080800, // 0013 CALL R2 4 + 0x8C080301, // 0014 GETMET R2 R1 K1 + 0x5412002C, // 0015 LDINT R4 45 + 0x5416000B, // 0016 LDINT R5 12 + 0x88180105, // 0017 GETMBR R6 R0 K5 + 0x541E0FFE, // 0018 LDINT R7 4095 + 0x2C180C07, // 0019 AND R6 R6 R7 + 0x7C080800, // 001A CALL R2 4 + 0x8C080301, // 001B GETMET R2 R1 K1 + 0x54120038, // 001C LDINT R4 57 + 0x5416001A, // 001D LDINT R5 27 + 0x88180106, // 001E GETMBR R6 R0 K6 + 0x2C180D07, // 001F AND R6 R6 K7 + 0x7C080800, // 0020 CALL R2 4 + 0xB80A1200, // 0021 GETNGBL R2 K9 + 0x8808050A, // 0022 GETMBR R2 R2 K10 + 0x8C08050B, // 0023 GETMET R2 R2 K11 + 0x5C100200, // 0024 MOVE R4 R1 + 0x7C080400, // 0025 CALL R2 2 + 0x000A1002, // 0026 ADD R2 K8 R2 + 0x80040400, // 0027 RET 1 R2 }) ) ); @@ -266,78 +246,35 @@ be_local_closure(Matter_Device_save_param, /* name */ /******************************************************************** -** Solidified function: remove_fabric +** Solidified function: _init_basic_commissioning ********************************************************************/ -be_local_closure(Matter_Device_remove_fabric, /* name */ +be_local_closure(Matter_Device__init_basic_commissioning, /* name */ be_nested_proto( - 9, /* nstack */ - 2, /* argc */ + 3, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[12]) { /* constants */ + ( &(const bvalue[ 4]) { /* constants */ /* K0 */ be_nested_str_weak(sessions), - /* K1 */ be_nested_str_weak(find_children_fabrics), - /* K2 */ be_nested_str_weak(get_fabric_index), - /* K3 */ be_nested_str_weak(find_fabric_by_index), - /* K4 */ be_nested_str_weak(message_handler), - /* K5 */ be_nested_str_weak(im), - /* K6 */ be_nested_str_weak(subs_shop), - /* K7 */ be_nested_str_weak(remove_by_fabric), - /* K8 */ be_nested_str_weak(mdns_remove_op_discovery), - /* K9 */ be_nested_str_weak(remove_fabric), - /* K10 */ be_nested_str_weak(stop_iteration), - /* K11 */ be_nested_str_weak(save_fabrics), + /* K1 */ be_nested_str_weak(count_active_fabrics), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(start_root_basic_commissioning), }), - be_str_weak(remove_fabric), + be_str_weak(_init_basic_commissioning), &be_const_str_solidified, - ( &(const binstruction[43]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x8C100302, // 0002 GETMET R4 R1 K2 - 0x7C100200, // 0003 CALL R4 1 - 0x7C080400, // 0004 CALL R2 2 - 0x4C0C0000, // 0005 LDNIL R3 - 0x1C0C0403, // 0006 EQ R3 R2 R3 - 0x780E0000, // 0007 JMPF R3 #0009 - 0x80000600, // 0008 RET 0 - 0x600C0010, // 0009 GETGBL R3 G16 - 0x5C100400, // 000A MOVE R4 R2 - 0x7C0C0200, // 000B CALL R3 1 - 0xA8020016, // 000C EXBLK 0 #0024 - 0x5C100600, // 000D MOVE R4 R3 - 0x7C100000, // 000E CALL R4 0 - 0x88140100, // 000F GETMBR R5 R0 K0 - 0x8C140B03, // 0010 GETMET R5 R5 K3 - 0x5C1C0800, // 0011 MOVE R7 R4 - 0x7C140400, // 0012 CALL R5 2 - 0x4C180000, // 0013 LDNIL R6 - 0x20180A06, // 0014 NE R6 R5 R6 - 0x781A000C, // 0015 JMPF R6 #0023 - 0x88180104, // 0016 GETMBR R6 R0 K4 - 0x88180D05, // 0017 GETMBR R6 R6 K5 - 0x88180D06, // 0018 GETMBR R6 R6 K6 - 0x8C180D07, // 0019 GETMET R6 R6 K7 - 0x5C200A00, // 001A MOVE R8 R5 - 0x7C180400, // 001B CALL R6 2 - 0x8C180108, // 001C GETMET R6 R0 K8 - 0x5C200A00, // 001D MOVE R8 R5 - 0x7C180400, // 001E CALL R6 2 - 0x88180100, // 001F GETMBR R6 R0 K0 - 0x8C180D09, // 0020 GETMET R6 R6 K9 - 0x5C200A00, // 0021 MOVE R8 R5 - 0x7C180400, // 0022 CALL R6 2 - 0x7001FFE8, // 0023 JMP #000D - 0x580C000A, // 0024 LDCONST R3 K10 - 0xAC0C0200, // 0025 CATCH R3 1 0 - 0xB0080000, // 0026 RAISE 2 R0 R0 - 0x880C0100, // 0027 GETMBR R3 R0 K0 - 0x8C0C070B, // 0028 GETMET R3 R3 K11 - 0x7C0C0200, // 0029 CALL R3 1 - 0x80000000, // 002A RET 0 + ( &(const binstruction[ 8]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x1C040302, // 0003 EQ R1 R1 K2 + 0x78060001, // 0004 JMPF R1 #0007 + 0x8C040103, // 0005 GETMET R1 R0 K3 + 0x7C040200, // 0006 CALL R1 1 + 0x80000000, // 0007 RET 0 }) ) ); @@ -345,86 +282,59 @@ be_local_closure(Matter_Device_remove_fabric, /* name */ /******************************************************************** -** Solidified function: _start_udp +** Solidified function: compute_manual_pairing_code ********************************************************************/ -be_local_closure(Matter_Device__start_udp, /* name */ +be_local_closure(Matter_Device_compute_manual_pairing_code, /* name */ be_nested_proto( - 6, /* nstack */ - 2, /* argc */ + 9, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 1]) { - be_nested_proto( - 8, /* nstack */ - 3, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 1]) { /* upvals */ - be_local_const_upval(1, 0), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(msg_received), - }), - be_str_weak(_X3Clambda_X3E), - &be_const_str_solidified, - ( &(const binstruction[ 7]) { /* code */ - 0x680C0000, // 0000 GETUPV R3 U0 - 0x8C0C0700, // 0001 GETMET R3 R3 K0 - 0x5C140000, // 0002 MOVE R5 R0 - 0x5C180200, // 0003 MOVE R6 R1 - 0x5C1C0400, // 0004 MOVE R7 R2 - 0x7C0C0800, // 0005 CALL R3 4 - 0x80040600, // 0006 RET 1 R3 - }) - ), - }), + 0, /* has sup protos */ + NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 9]) { /* constants */ - /* K0 */ be_nested_str_weak(udp_server), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(log), - /* K3 */ be_nested_str_weak(MTR_X3A_X20starting_X20UDP_X20server_X20on_X20port_X3A_X20), - /* K4 */ be_const_int(2), - /* K5 */ be_nested_str_weak(matter), - /* K6 */ be_nested_str_weak(UDPServer), - /* K7 */ be_nested_str_weak(), - /* K8 */ be_nested_str_weak(start), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(root_discriminator), + /* K1 */ be_nested_str_weak(root_passcode), + /* K2 */ be_nested_str_weak(_X251i_X2505i_X2504i), + /* K3 */ be_nested_str_weak(matter), + /* K4 */ be_nested_str_weak(Verhoeff), + /* K5 */ be_nested_str_weak(checksum), }), - be_str_weak(_start_udp), + be_str_weak(compute_manual_pairing_code), &be_const_str_solidified, - ( &(const binstruction[27]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x780A0000, // 0001 JMPF R2 #0003 - 0x80000400, // 0002 RET 0 - 0x4C080000, // 0003 LDNIL R2 - 0x1C080202, // 0004 EQ R2 R1 R2 - 0x780A0000, // 0005 JMPF R2 #0007 - 0x540615A3, // 0006 LDINT R1 5540 - 0xB80A0200, // 0007 GETNGBL R2 K1 - 0x8C080502, // 0008 GETMET R2 R2 K2 - 0x60100008, // 0009 GETGBL R4 G8 - 0x5C140200, // 000A MOVE R5 R1 - 0x7C100200, // 000B CALL R4 1 - 0x00120604, // 000C ADD R4 K3 R4 - 0x58140004, // 000D LDCONST R5 K4 - 0x7C080600, // 000E CALL R2 3 - 0xB80A0A00, // 000F GETNGBL R2 K5 - 0x8C080506, // 0010 GETMET R2 R2 K6 - 0x58100007, // 0011 LDCONST R4 K7 - 0x5C140200, // 0012 MOVE R5 R1 - 0x7C080600, // 0013 CALL R2 3 - 0x90020002, // 0014 SETMBR R0 K0 R2 - 0x88080100, // 0015 GETMBR R2 R0 K0 - 0x8C080508, // 0016 GETMET R2 R2 K8 - 0x84100000, // 0017 CLOSURE R4 P0 - 0x7C080400, // 0018 CALL R2 2 - 0xA0000000, // 0019 CLOSE R0 - 0x80000000, // 001A RET 0 + ( &(const binstruction[30]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x540A0FFE, // 0001 LDINT R2 4095 + 0x2C040202, // 0002 AND R1 R1 R2 + 0x540A0009, // 0003 LDINT R2 10 + 0x3C040202, // 0004 SHR R1 R1 R2 + 0x88080100, // 0005 GETMBR R2 R0 K0 + 0x540E02FF, // 0006 LDINT R3 768 + 0x2C080403, // 0007 AND R2 R2 R3 + 0x540E0005, // 0008 LDINT R3 6 + 0x38080403, // 0009 SHL R2 R2 R3 + 0x880C0101, // 000A GETMBR R3 R0 K1 + 0x54123FFE, // 000B LDINT R4 16383 + 0x2C0C0604, // 000C AND R3 R3 R4 + 0x30080403, // 000D OR R2 R2 R3 + 0x880C0101, // 000E GETMBR R3 R0 K1 + 0x5412000D, // 000F LDINT R4 14 + 0x3C0C0604, // 0010 SHR R3 R3 R4 + 0x60100018, // 0011 GETGBL R4 G24 + 0x58140002, // 0012 LDCONST R5 K2 + 0x5C180200, // 0013 MOVE R6 R1 + 0x5C1C0400, // 0014 MOVE R7 R2 + 0x5C200600, // 0015 MOVE R8 R3 + 0x7C100800, // 0016 CALL R4 4 + 0xB8160600, // 0017 GETNGBL R5 K3 + 0x88140B04, // 0018 GETMBR R5 R5 K4 + 0x8C140B05, // 0019 GETMET R5 R5 K5 + 0x5C1C0800, // 001A MOVE R7 R4 + 0x7C140400, // 001B CALL R5 2 + 0x00100805, // 001C ADD R4 R4 R5 + 0x80040800, // 001D RET 1 R4 }) ) ); @@ -432,29 +342,55 @@ be_local_closure(Matter_Device__start_udp, /* name */ /******************************************************************** -** Solidified function: every_50ms +** Solidified function: invoke_request ********************************************************************/ -be_local_closure(Matter_Device_every_50ms, /* name */ +be_local_closure(Matter_Device_invoke_request, /* name */ be_nested_proto( - 2, /* nstack */ - 1, /* argc */ + 12, /* nstack */ + 4, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(tick), - /* K1 */ be_const_int(1), + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(endpoint), + /* K2 */ be_nested_str_weak(plugins), + /* K3 */ be_nested_str_weak(invoke_request), + /* K4 */ be_const_int(1), + /* K5 */ be_nested_str_weak(status), + /* K6 */ be_nested_str_weak(matter), + /* K7 */ be_nested_str_weak(UNSUPPORTED_ENDPOINT), }), - be_str_weak(every_50ms), + be_str_weak(invoke_request), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x00040301, // 0001 ADD R1 R1 K1 - 0x90020001, // 0002 SETMBR R0 K0 R1 - 0x80000000, // 0003 RET 0 + ( &(const binstruction[24]) { /* code */ + 0x58100000, // 0000 LDCONST R4 K0 + 0x88140701, // 0001 GETMBR R5 R3 K1 + 0x6018000C, // 0002 GETGBL R6 G12 + 0x881C0102, // 0003 GETMBR R7 R0 K2 + 0x7C180200, // 0004 CALL R6 1 + 0x14180806, // 0005 LT R6 R4 R6 + 0x781A000C, // 0006 JMPF R6 #0014 + 0x88180102, // 0007 GETMBR R6 R0 K2 + 0x94180C04, // 0008 GETIDX R6 R6 R4 + 0x881C0D01, // 0009 GETMBR R7 R6 K1 + 0x1C1C0E05, // 000A EQ R7 R7 R5 + 0x781E0005, // 000B JMPF R7 #0012 + 0x8C1C0D03, // 000C GETMET R7 R6 K3 + 0x5C240200, // 000D MOVE R9 R1 + 0x5C280400, // 000E MOVE R10 R2 + 0x5C2C0600, // 000F MOVE R11 R3 + 0x7C1C0800, // 0010 CALL R7 4 + 0x80040E00, // 0011 RET 1 R7 + 0x00100904, // 0012 ADD R4 R4 K4 + 0x7001FFED, // 0013 JMP #0002 + 0xB81A0C00, // 0014 GETNGBL R6 K6 + 0x88180D07, // 0015 GETMBR R6 R6 K7 + 0x900E0A06, // 0016 SETMBR R3 K5 R6 + 0x80000000, // 0017 RET 0 }) ) ); @@ -500,36 +436,114 @@ be_local_closure(Matter_Device_stop, /* name */ /******************************************************************** -** Solidified function: start_commissioning_complete +** Solidified function: bridge_add_endpoint ********************************************************************/ -be_local_closure(Matter_Device_start_commissioning_complete, /* name */ +be_local_closure(Matter_Device_bridge_add_endpoint, /* name */ be_nested_proto( - 6, /* nstack */ - 2, /* argc */ + 17, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(tasmota), - /* K1 */ be_nested_str_weak(log), - /* K2 */ be_nested_str_weak(MTR_X3A_X20_X2A_X2A_X2A_X20Commissioning_X20complete_X20_X2A_X2A_X2A), - /* K3 */ be_const_int(2), - /* K4 */ be_nested_str_weak(stop_basic_commissioning), + ( &(const bvalue[21]) { /* constants */ + /* K0 */ be_nested_str_weak(plugins_classes), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(log), + /* K4 */ be_nested_str_weak(MTR_X3A_X20unknown_X20class_X20name_X20_X27), + /* K5 */ be_nested_str_weak(_X27_X20skipping), + /* K6 */ be_const_int(3), + /* K7 */ be_nested_str_weak(next_ep), + /* K8 */ be_nested_str_weak(plugins), + /* K9 */ be_nested_str_weak(push), + /* K10 */ be_nested_str_weak(type), + /* K11 */ be_nested_str_weak(keys), + /* K12 */ be_nested_str_weak(stop_iteration), + /* K13 */ be_nested_str_weak(MTR_X3A_X20adding_X20endpoint_X20_X3D_X20_X25i_X20type_X3A_X25s_X25s), + /* K14 */ be_nested_str_weak(conf_to_log), + /* K15 */ be_const_int(2), + /* K16 */ be_nested_str_weak(plugins_config), + /* K17 */ be_nested_str_weak(plugins_persist), + /* K18 */ be_const_int(1), + /* K19 */ be_nested_str_weak(save_param), + /* K20 */ be_nested_str_weak(signal_endpoints_changed), }), - be_str_weak(start_commissioning_complete), + be_str_weak(bridge_add_endpoint), &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0xB80A0000, // 0000 GETNGBL R2 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x58100002, // 0002 LDCONST R4 K2 - 0x58140003, // 0003 LDCONST R5 K3 - 0x7C080600, // 0004 CALL R2 3 - 0x8C080104, // 0005 GETMET R2 R0 K4 - 0x7C080200, // 0006 CALL R2 1 - 0x80000000, // 0007 RET 0 + ( &(const binstruction[70]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x4C100000, // 0004 LDNIL R4 + 0x1C100604, // 0005 EQ R4 R3 R4 + 0x78120009, // 0006 JMPF R4 #0011 + 0xB8120400, // 0007 GETNGBL R4 K2 + 0x8C100903, // 0008 GETMET R4 R4 K3 + 0x60180008, // 0009 GETGBL R6 G8 + 0x5C1C0200, // 000A MOVE R7 R1 + 0x7C180200, // 000B CALL R6 1 + 0x001A0806, // 000C ADD R6 K4 R6 + 0x00180D05, // 000D ADD R6 R6 K5 + 0x581C0006, // 000E LDCONST R7 K6 + 0x7C100600, // 000F CALL R4 3 + 0x80000800, // 0010 RET 0 + 0x88100107, // 0011 GETMBR R4 R0 K7 + 0x60140008, // 0012 GETGBL R5 G8 + 0x5C180800, // 0013 MOVE R6 R4 + 0x7C140200, // 0014 CALL R5 1 + 0x5C180600, // 0015 MOVE R6 R3 + 0x5C1C0000, // 0016 MOVE R7 R0 + 0x5C200800, // 0017 MOVE R8 R4 + 0x5C240400, // 0018 MOVE R9 R2 + 0x7C180600, // 0019 CALL R6 3 + 0x881C0108, // 001A GETMBR R7 R0 K8 + 0x8C1C0F09, // 001B GETMET R7 R7 K9 + 0x5C240C00, // 001C MOVE R9 R6 + 0x7C1C0400, // 001D CALL R7 2 + 0x601C0013, // 001E GETGBL R7 G19 + 0x7C1C0000, // 001F CALL R7 0 + 0x981E1401, // 0020 SETIDX R7 K10 R1 + 0x60200010, // 0021 GETGBL R8 G16 + 0x8C24050B, // 0022 GETMET R9 R2 K11 + 0x7C240200, // 0023 CALL R9 1 + 0x7C200200, // 0024 CALL R8 1 + 0xA8020004, // 0025 EXBLK 0 #002B + 0x5C241000, // 0026 MOVE R9 R8 + 0x7C240000, // 0027 CALL R9 0 + 0x94280409, // 0028 GETIDX R10 R2 R9 + 0x981C120A, // 0029 SETIDX R7 R9 R10 + 0x7001FFFA, // 002A JMP #0026 + 0x5820000C, // 002B LDCONST R8 K12 + 0xAC200200, // 002C CATCH R8 1 0 + 0xB0080000, // 002D RAISE 2 R0 R0 + 0xB8220400, // 002E GETNGBL R8 K2 + 0x8C201103, // 002F GETMET R8 R8 K3 + 0x60280018, // 0030 GETGBL R10 G24 + 0x582C000D, // 0031 LDCONST R11 K13 + 0x5C300800, // 0032 MOVE R12 R4 + 0x5C340200, // 0033 MOVE R13 R1 + 0x8C38010E, // 0034 GETMET R14 R0 K14 + 0x5C400400, // 0035 MOVE R16 R2 + 0x7C380400, // 0036 CALL R14 2 + 0x7C280800, // 0037 CALL R10 4 + 0x582C000F, // 0038 LDCONST R11 K15 + 0x7C200600, // 0039 CALL R8 3 + 0x88200110, // 003A GETMBR R8 R0 K16 + 0x98200A07, // 003B SETIDX R8 R5 R7 + 0x50200200, // 003C LDBOOL R8 1 0 + 0x90022208, // 003D SETMBR R0 K17 R8 + 0x88200107, // 003E GETMBR R8 R0 K7 + 0x00201112, // 003F ADD R8 R8 K18 + 0x90020E08, // 0040 SETMBR R0 K7 R8 + 0x8C200113, // 0041 GETMET R8 R0 K19 + 0x7C200200, // 0042 CALL R8 1 + 0x8C200114, // 0043 GETMET R8 R0 K20 + 0x7C200200, // 0044 CALL R8 1 + 0x80040800, // 0045 RET 1 R4 }) ) ); @@ -537,61 +551,126 @@ be_local_closure(Matter_Device_start_commissioning_complete, /* name */ /******************************************************************** -** Solidified function: register_commands +** Solidified function: mdns_remove_op_discovery ********************************************************************/ -be_local_closure(Matter_Device_register_commands, /* name */ +be_local_closure(Matter_Device_mdns_remove_op_discovery, /* name */ be_nested_proto( - 5, /* nstack */ - 1, /* argc */ + 12, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 1]) { - be_nested_proto( - 10, /* nstack */ - 4, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 1]) { /* upvals */ - be_local_const_upval(1, 0), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(MtrJoin), - }), - be_str_weak(_X3Clambda_X3E), - &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x68100000, // 0000 GETUPV R4 U0 - 0x8C100900, // 0001 GETMET R4 R4 K0 - 0x5C180000, // 0002 MOVE R6 R0 - 0x5C1C0200, // 0003 MOVE R7 R1 - 0x5C200400, // 0004 MOVE R8 R2 - 0x5C240600, // 0005 MOVE R9 R3 - 0x7C100A00, // 0006 CALL R4 5 - 0x80040800, // 0007 RET 1 R4 - }) - ), - }), + 0, /* has sup protos */ + NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(tasmota), - /* K1 */ be_nested_str_weak(add_cmd), - /* K2 */ be_nested_str_weak(MtrJoin), + ( &(const bvalue[23]) { /* constants */ + /* K0 */ be_nested_str_weak(mdns), + /* K1 */ be_nested_str_weak(get_device_id), + /* K2 */ be_nested_str_weak(copy), + /* K3 */ be_nested_str_weak(reverse), + /* K4 */ be_nested_str_weak(get_fabric_compressed), + /* K5 */ be_nested_str_weak(tohex), + /* K6 */ be_nested_str_weak(_X2D), + /* K7 */ be_nested_str_weak(tasmota), + /* K8 */ be_nested_str_weak(eth), + /* K9 */ be_nested_str_weak(find), + /* K10 */ be_nested_str_weak(up), + /* K11 */ be_nested_str_weak(log), + /* K12 */ be_nested_str_weak(MTR_X3A_X20remove_X20mDNS_X20on_X20_X25s_X20_X27_X25s_X27), + /* K13 */ be_const_int(3), + /* K14 */ be_nested_str_weak(remove_service), + /* K15 */ be_nested_str_weak(_matter), + /* K16 */ be_nested_str_weak(_tcp), + /* K17 */ be_nested_str_weak(hostname_eth), + /* K18 */ be_nested_str_weak(wifi), + /* K19 */ be_nested_str_weak(hostname_wifi), + /* K20 */ be_nested_str_weak(MTR_X3A_X20Exception), + /* K21 */ be_nested_str_weak(_X7C), + /* K22 */ be_const_int(2), }), - be_str_weak(register_commands), + be_str_weak(mdns_remove_op_discovery), &be_const_str_solidified, - ( &(const binstruction[ 7]) { /* code */ - 0xB8060000, // 0000 GETNGBL R1 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x580C0002, // 0002 LDCONST R3 K2 - 0x84100000, // 0003 CLOSURE R4 P0 - 0x7C040600, // 0004 CALL R1 3 - 0xA0000000, // 0005 CLOSE R0 - 0x80000000, // 0006 RET 0 + ( &(const binstruction[80]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0xA802003B, // 0001 EXBLK 0 #003E + 0x8C0C0301, // 0002 GETMET R3 R1 K1 + 0x7C0C0200, // 0003 CALL R3 1 + 0x8C0C0702, // 0004 GETMET R3 R3 K2 + 0x7C0C0200, // 0005 CALL R3 1 + 0x8C0C0703, // 0006 GETMET R3 R3 K3 + 0x7C0C0200, // 0007 CALL R3 1 + 0x8C100304, // 0008 GETMET R4 R1 K4 + 0x7C100200, // 0009 CALL R4 1 + 0x8C140905, // 000A GETMET R5 R4 K5 + 0x7C140200, // 000B CALL R5 1 + 0x00140B06, // 000C ADD R5 R5 K6 + 0x8C180705, // 000D GETMET R6 R3 K5 + 0x7C180200, // 000E CALL R6 1 + 0x00140A06, // 000F ADD R5 R5 R6 + 0xB81A0E00, // 0010 GETNGBL R6 K7 + 0x8C180D08, // 0011 GETMET R6 R6 K8 + 0x7C180200, // 0012 CALL R6 1 + 0x8C180D09, // 0013 GETMET R6 R6 K9 + 0x5820000A, // 0014 LDCONST R8 K10 + 0x7C180400, // 0015 CALL R6 2 + 0x781A000E, // 0016 JMPF R6 #0026 + 0xB81A0E00, // 0017 GETNGBL R6 K7 + 0x8C180D0B, // 0018 GETMET R6 R6 K11 + 0x60200018, // 0019 GETGBL R8 G24 + 0x5824000C, // 001A LDCONST R9 K12 + 0x58280008, // 001B LDCONST R10 K8 + 0x5C2C0A00, // 001C MOVE R11 R5 + 0x7C200600, // 001D CALL R8 3 + 0x5824000D, // 001E LDCONST R9 K13 + 0x7C180600, // 001F CALL R6 3 + 0x8C18050E, // 0020 GETMET R6 R2 K14 + 0x5820000F, // 0021 LDCONST R8 K15 + 0x58240010, // 0022 LDCONST R9 K16 + 0x5C280A00, // 0023 MOVE R10 R5 + 0x882C0111, // 0024 GETMBR R11 R0 K17 + 0x7C180A00, // 0025 CALL R6 5 + 0xB81A0E00, // 0026 GETNGBL R6 K7 + 0x8C180D12, // 0027 GETMET R6 R6 K18 + 0x7C180200, // 0028 CALL R6 1 + 0x8C180D09, // 0029 GETMET R6 R6 K9 + 0x5820000A, // 002A LDCONST R8 K10 + 0x7C180400, // 002B CALL R6 2 + 0x781A000E, // 002C JMPF R6 #003C + 0xB81A0E00, // 002D GETNGBL R6 K7 + 0x8C180D0B, // 002E GETMET R6 R6 K11 + 0x60200018, // 002F GETGBL R8 G24 + 0x5824000C, // 0030 LDCONST R9 K12 + 0x58280012, // 0031 LDCONST R10 K18 + 0x5C2C0A00, // 0032 MOVE R11 R5 + 0x7C200600, // 0033 CALL R8 3 + 0x5824000D, // 0034 LDCONST R9 K13 + 0x7C180600, // 0035 CALL R6 3 + 0x8C18050E, // 0036 GETMET R6 R2 K14 + 0x5820000F, // 0037 LDCONST R8 K15 + 0x58240010, // 0038 LDCONST R9 K16 + 0x5C280A00, // 0039 MOVE R10 R5 + 0x882C0113, // 003A GETMBR R11 R0 K19 + 0x7C180A00, // 003B CALL R6 5 + 0xA8040001, // 003C EXBLK 1 1 + 0x70020010, // 003D JMP #004F + 0xAC0C0002, // 003E CATCH R3 0 2 + 0x7002000D, // 003F JMP #004E + 0xB8160E00, // 0040 GETNGBL R5 K7 + 0x8C140B0B, // 0041 GETMET R5 R5 K11 + 0x601C0008, // 0042 GETGBL R7 G8 + 0x5C200600, // 0043 MOVE R8 R3 + 0x7C1C0200, // 0044 CALL R7 1 + 0x001E2807, // 0045 ADD R7 K20 R7 + 0x001C0F15, // 0046 ADD R7 R7 K21 + 0x60200008, // 0047 GETGBL R8 G8 + 0x5C240800, // 0048 MOVE R9 R4 + 0x7C200200, // 0049 CALL R8 1 + 0x001C0E08, // 004A ADD R7 R7 R8 + 0x58200016, // 004B LDCONST R8 K22 + 0x7C140600, // 004C CALL R5 3 + 0x70020000, // 004D JMP #004F + 0xB0080000, // 004E RAISE 2 R0 R0 + 0x80000000, // 004F RET 0 }) ) ); @@ -599,59 +678,32 @@ be_local_closure(Matter_Device_register_commands, /* name */ /******************************************************************** -** Solidified function: start_operational_discovery_deferred +** Solidified function: get_plugin_remote_info ********************************************************************/ -be_local_closure(Matter_Device_start_operational_discovery_deferred, /* name */ +be_local_closure(Matter_Device_get_plugin_remote_info, /* name */ be_nested_proto( 6, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 1]) { - be_nested_proto( - 3, /* nstack */ - 0, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 2]) { /* upvals */ - be_local_const_upval(1, 0), - be_local_const_upval(1, 1), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(start_operational_discovery), - }), - be_str_weak(_X3Clambda_X3E), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x68000000, // 0000 GETUPV R0 U0 - 0x8C000100, // 0001 GETMET R0 R0 K0 - 0x68080001, // 0002 GETUPV R2 U1 - 0x7C000400, // 0003 CALL R0 2 - 0x80040000, // 0004 RET 1 R0 - }) - ), - }), + 0, /* has sup protos */ + NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(tasmota), - /* K1 */ be_nested_str_weak(set_timer), - /* K2 */ be_const_int(0), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(plugins_config_remotes), + /* K1 */ be_nested_str_weak(find), }), - be_str_weak(start_operational_discovery_deferred), + be_str_weak(get_plugin_remote_info), &be_const_str_solidified, ( &(const binstruction[ 7]) { /* code */ - 0xB80A0000, // 0000 GETNGBL R2 K0 + 0x88080100, // 0000 GETMBR R2 R0 K0 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x58100002, // 0002 LDCONST R4 K2 - 0x84140000, // 0003 CLOSURE R5 P0 - 0x7C080600, // 0004 CALL R2 3 - 0xA0000000, // 0005 CLOSE R0 - 0x80000000, // 0006 RET 0 + 0x5C100200, // 0002 MOVE R4 R1 + 0x60140013, // 0003 GETGBL R5 G19 + 0x7C140000, // 0004 CALL R5 0 + 0x7C080600, // 0005 CALL R2 3 + 0x80040400, // 0006 RET 1 R2 }) ) ); @@ -659,20 +711,673 @@ be_local_closure(Matter_Device_start_operational_discovery_deferred, /* name * /******************************************************************** -** Solidified function: register_native_classes +** Solidified function: autoconf_device_map ********************************************************************/ -be_local_closure(Matter_Device_register_native_classes, /* name */ +be_local_closure(Matter_Device_autoconf_device_map, /* name */ be_nested_proto( - 12, /* nstack */ - 3, /* argc */ + 20, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[17]) { /* constants */ - /* K0 */ be_nested_str_weak(introspect), + ( &(const bvalue[36]) { /* constants */ + /* K0 */ be_nested_str_weak(json), + /* K1 */ be_const_int(1), + /* K2 */ be_nested_str_weak(light), + /* K3 */ be_nested_str_weak(get), + /* K4 */ be_nested_str_weak(find), + /* K5 */ be_nested_str_weak(channels), + /* K6 */ be_nested_str_weak(), + /* K7 */ be_const_int(0), + /* K8 */ be_nested_str_weak(type), + /* K9 */ be_nested_str_weak(light1), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str_weak(light2), + /* K12 */ be_nested_str_weak(light3), + /* K13 */ be_nested_str_weak(tasmota), + /* K14 */ be_nested_str_weak(cmd), + /* K15 */ be_nested_str_weak(Status_X2013), + /* K16 */ be_nested_str_weak(log), + /* K17 */ be_nested_str_weak(MTR_X3A_X20Status_X2013_X20_X3D_X20), + /* K18 */ be_const_int(3), + /* K19 */ be_nested_str_weak(contains), + /* K20 */ be_nested_str_weak(StatusSHT), + /* K21 */ be_nested_str_weak(SHT), + /* K22 */ be_nested_str_weak(MTR_X3A_X20_X27_X25s_X27_X20_X3D_X20_X25s), + /* K23 */ be_nested_str_weak(Relay1), + /* K24 */ be_nested_str_weak(Relay2), + /* K25 */ be_nested_str_weak(push), + /* K26 */ be_nested_str_weak(MTR_X3A_X20relay1_X3D_X25s_X20relay2_X3D_X25s), + /* K27 */ be_nested_str_weak(TiltConfig), + /* K28 */ be_nested_str_weak(shutter_X2Btilt), + /* K29 */ be_nested_str_weak(shutter), + /* K30 */ be_nested_str_weak(get_power), + /* K31 */ be_nested_str_weak(relay), + /* K32 */ be_nested_str_weak(load), + /* K33 */ be_nested_str_weak(read_sensors), + /* K34 */ be_nested_str_weak(autoconf_sensors_list), + /* K35 */ be_nested_str_weak(stop_iteration), + }), + be_str_weak(autoconf_device_map), + &be_const_str_solidified, + ( &(const binstruction[198]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x60080013, // 0001 GETGBL R2 G19 + 0x7C080000, // 0002 CALL R2 0 + 0x580C0001, // 0003 LDCONST R3 K1 + 0x50100000, // 0004 LDBOOL R4 0 0 + 0xA4160400, // 0005 IMPORT R5 K2 + 0x8C180B03, // 0006 GETMET R6 R5 K3 + 0x7C180200, // 0007 CALL R6 1 + 0x4C1C0000, // 0008 LDNIL R7 + 0x201C0C07, // 0009 NE R7 R6 R7 + 0x781E0024, // 000A JMPF R7 #0030 + 0x601C000C, // 000B GETGBL R7 G12 + 0x8C200D04, // 000C GETMET R8 R6 K4 + 0x58280005, // 000D LDCONST R10 K5 + 0x582C0006, // 000E LDCONST R11 K6 + 0x7C200600, // 000F CALL R8 3 + 0x7C1C0200, // 0010 CALL R7 1 + 0x24200F07, // 0011 GT R8 R7 K7 + 0x7822001C, // 0012 JMPF R8 #0030 + 0x1C200F01, // 0013 EQ R8 R7 K1 + 0x78220007, // 0014 JMPF R8 #001D + 0x60200008, // 0015 GETGBL R8 G8 + 0x5C240600, // 0016 MOVE R9 R3 + 0x7C200200, // 0017 CALL R8 1 + 0x60240013, // 0018 GETGBL R9 G19 + 0x7C240000, // 0019 CALL R9 0 + 0x98261109, // 001A SETIDX R9 K8 K9 + 0x98081009, // 001B SETIDX R2 R8 R9 + 0x70020010, // 001C JMP #002E + 0x1C200F0A, // 001D EQ R8 R7 K10 + 0x78220007, // 001E JMPF R8 #0027 + 0x60200008, // 001F GETGBL R8 G8 + 0x5C240600, // 0020 MOVE R9 R3 + 0x7C200200, // 0021 CALL R8 1 + 0x60240013, // 0022 GETGBL R9 G19 + 0x7C240000, // 0023 CALL R9 0 + 0x9826110B, // 0024 SETIDX R9 K8 K11 + 0x98081009, // 0025 SETIDX R2 R8 R9 + 0x70020006, // 0026 JMP #002E + 0x60200008, // 0027 GETGBL R8 G8 + 0x5C240600, // 0028 MOVE R9 R3 + 0x7C200200, // 0029 CALL R8 1 + 0x60240013, // 002A GETGBL R9 G19 + 0x7C240000, // 002B CALL R9 0 + 0x9826110C, // 002C SETIDX R9 K8 K12 + 0x98081009, // 002D SETIDX R2 R8 R9 + 0x50100200, // 002E LDBOOL R4 1 0 + 0x000C0701, // 002F ADD R3 R3 K1 + 0xB81E1A00, // 0030 GETNGBL R7 K13 + 0x8C1C0F0E, // 0031 GETMET R7 R7 K14 + 0x5824000F, // 0032 LDCONST R9 K15 + 0x50280200, // 0033 LDBOOL R10 1 0 + 0x7C1C0600, // 0034 CALL R7 3 + 0x60200012, // 0035 GETGBL R8 G18 + 0x7C200000, // 0036 CALL R8 0 + 0xB8261A00, // 0037 GETNGBL R9 K13 + 0x8C241310, // 0038 GETMET R9 R9 K16 + 0x602C0008, // 0039 GETGBL R11 G8 + 0x5C300E00, // 003A MOVE R12 R7 + 0x7C2C0200, // 003B CALL R11 1 + 0x002E220B, // 003C ADD R11 K17 R11 + 0x58300012, // 003D LDCONST R12 K18 + 0x7C240600, // 003E CALL R9 3 + 0x4C240000, // 003F LDNIL R9 + 0x20240E09, // 0040 NE R9 R7 R9 + 0x7826004F, // 0041 JMPF R9 #0092 + 0x8C240F13, // 0042 GETMET R9 R7 K19 + 0x582C0014, // 0043 LDCONST R11 K20 + 0x7C240400, // 0044 CALL R9 2 + 0x7826004B, // 0045 JMPF R9 #0092 + 0x941C0F14, // 0046 GETIDX R7 R7 K20 + 0x58240007, // 0047 LDCONST R9 K7 + 0x50280200, // 0048 LDBOOL R10 1 0 + 0x782A0047, // 0049 JMPF R10 #0092 + 0x60280008, // 004A GETGBL R10 G8 + 0x5C2C1200, // 004B MOVE R11 R9 + 0x7C280200, // 004C CALL R10 1 + 0x002A2A0A, // 004D ADD R10 K21 R10 + 0x8C2C0F13, // 004E GETMET R11 R7 K19 + 0x5C341400, // 004F MOVE R13 R10 + 0x7C2C0400, // 0050 CALL R11 2 + 0x742E0000, // 0051 JMPT R11 #0053 + 0x7002003E, // 0052 JMP #0092 + 0x942C0E0A, // 0053 GETIDX R11 R7 R10 + 0xB8321A00, // 0054 GETNGBL R12 K13 + 0x8C301910, // 0055 GETMET R12 R12 K16 + 0x60380018, // 0056 GETGBL R14 G24 + 0x583C0016, // 0057 LDCONST R15 K22 + 0x5C401400, // 0058 MOVE R16 R10 + 0x60440008, // 0059 GETGBL R17 G8 + 0x5C481600, // 005A MOVE R18 R11 + 0x7C440200, // 005B CALL R17 1 + 0x7C380600, // 005C CALL R14 3 + 0x583C0012, // 005D LDCONST R15 K18 + 0x7C300600, // 005E CALL R12 3 + 0x8C301704, // 005F GETMET R12 R11 K4 + 0x58380017, // 0060 LDCONST R14 K23 + 0x543DFFFE, // 0061 LDINT R15 -1 + 0x7C300600, // 0062 CALL R12 3 + 0x8C341704, // 0063 GETMET R13 R11 K4 + 0x583C0018, // 0064 LDCONST R15 K24 + 0x5441FFFE, // 0065 LDINT R16 -1 + 0x7C340600, // 0066 CALL R13 3 + 0x24381907, // 0067 GT R14 R12 K7 + 0x783A0002, // 0068 JMPF R14 #006C + 0x8C381119, // 0069 GETMET R14 R8 K25 + 0x04401901, // 006A SUB R16 R12 K1 + 0x7C380400, // 006B CALL R14 2 + 0x24381B07, // 006C GT R14 R13 K7 + 0x783A0002, // 006D JMPF R14 #0071 + 0x8C381119, // 006E GETMET R14 R8 K25 + 0x04401B01, // 006F SUB R16 R13 K1 + 0x7C380400, // 0070 CALL R14 2 + 0xB83A1A00, // 0071 GETNGBL R14 K13 + 0x8C381D10, // 0072 GETMET R14 R14 K16 + 0x60400018, // 0073 GETGBL R16 G24 + 0x5844001A, // 0074 LDCONST R17 K26 + 0x5C481800, // 0075 MOVE R18 R12 + 0x5C4C1A00, // 0076 MOVE R19 R13 + 0x7C400600, // 0077 CALL R16 3 + 0x58440012, // 0078 LDCONST R17 K18 + 0x7C380600, // 0079 CALL R14 3 + 0x8C381704, // 007A GETMET R14 R11 K4 + 0x5840001B, // 007B LDCONST R16 K27 + 0x7C380400, // 007C CALL R14 2 + 0x783A0002, // 007D JMPF R14 #0081 + 0x943C1D0A, // 007E GETIDX R15 R14 K10 + 0x243C1F07, // 007F GT R15 R15 K7 + 0x743E0000, // 0080 JMPT R15 #0082 + 0x503C0001, // 0081 LDBOOL R15 0 1 + 0x503C0200, // 0082 LDBOOL R15 1 0 + 0x60400008, // 0083 GETGBL R16 G8 + 0x5C440600, // 0084 MOVE R17 R3 + 0x7C400200, // 0085 CALL R16 1 + 0x60440013, // 0086 GETGBL R17 G19 + 0x7C440000, // 0087 CALL R17 0 + 0x783E0001, // 0088 JMPF R15 #008B + 0x5848001C, // 0089 LDCONST R18 K28 + 0x70020000, // 008A JMP #008C + 0x5848001D, // 008B LDCONST R18 K29 + 0x98461012, // 008C SETIDX R17 K8 R18 + 0x98463A09, // 008D SETIDX R17 K29 R9 + 0x98082011, // 008E SETIDX R2 R16 R17 + 0x000C0701, // 008F ADD R3 R3 K1 + 0x00241301, // 0090 ADD R9 R9 K1 + 0x7001FFB5, // 0091 JMP #0048 + 0x6024000C, // 0092 GETGBL R9 G12 + 0xB82A1A00, // 0093 GETNGBL R10 K13 + 0x8C28151E, // 0094 GETMET R10 R10 K30 + 0x7C280200, // 0095 CALL R10 1 + 0x7C240200, // 0096 CALL R9 1 + 0x58280007, // 0097 LDCONST R10 K7 + 0x78120000, // 0098 JMPF R4 #009A + 0x04241301, // 0099 SUB R9 R9 K1 + 0x142C1409, // 009A LT R11 R10 R9 + 0x782E0011, // 009B JMPF R11 #00AE + 0x8C2C1104, // 009C GETMET R11 R8 K4 + 0x5C341400, // 009D MOVE R13 R10 + 0x7C2C0400, // 009E CALL R11 2 + 0x4C300000, // 009F LDNIL R12 + 0x1C2C160C, // 00A0 EQ R11 R11 R12 + 0x782E0009, // 00A1 JMPF R11 #00AC + 0x602C0008, // 00A2 GETGBL R11 G8 + 0x5C300600, // 00A3 MOVE R12 R3 + 0x7C2C0200, // 00A4 CALL R11 1 + 0x60300013, // 00A5 GETGBL R12 G19 + 0x7C300000, // 00A6 CALL R12 0 + 0x9832111F, // 00A7 SETIDX R12 K8 K31 + 0x00341501, // 00A8 ADD R13 R10 K1 + 0x98323E0D, // 00A9 SETIDX R12 K31 R13 + 0x9808160C, // 00AA SETIDX R2 R11 R12 + 0x000C0701, // 00AB ADD R3 R3 K1 + 0x00281501, // 00AC ADD R10 R10 K1 + 0x7001FFEB, // 00AD JMP #009A + 0x8C2C0320, // 00AE GETMET R11 R1 K32 + 0xB8361A00, // 00AF GETNGBL R13 K13 + 0x8C341B21, // 00B0 GETMET R13 R13 K33 + 0x7C340200, // 00B1 CALL R13 1 + 0x7C2C0400, // 00B2 CALL R11 2 + 0x8C300122, // 00B3 GETMET R12 R0 K34 + 0x5C381600, // 00B4 MOVE R14 R11 + 0x7C300400, // 00B5 CALL R12 2 + 0x60340010, // 00B6 GETGBL R13 G16 + 0x5C381800, // 00B7 MOVE R14 R12 + 0x7C340200, // 00B8 CALL R13 1 + 0xA8020007, // 00B9 EXBLK 0 #00C2 + 0x5C381A00, // 00BA MOVE R14 R13 + 0x7C380000, // 00BB CALL R14 0 + 0x603C0008, // 00BC GETGBL R15 G8 + 0x5C400600, // 00BD MOVE R16 R3 + 0x7C3C0200, // 00BE CALL R15 1 + 0x98081E0E, // 00BF SETIDX R2 R15 R14 + 0x000C0701, // 00C0 ADD R3 R3 K1 + 0x7001FFF7, // 00C1 JMP #00BA + 0x58340023, // 00C2 LDCONST R13 K35 + 0xAC340200, // 00C3 CATCH R13 1 0 + 0xB0080000, // 00C4 RAISE 2 R0 R0 + 0x80040400, // 00C5 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: clean_remotes +********************************************************************/ +be_local_closure(Matter_Device_clean_remotes, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[18]) { /* constants */ + /* K0 */ be_nested_str_weak(introspect), + /* K1 */ be_nested_str_weak(http_remotes), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(stop_iteration), + /* K4 */ be_nested_str_weak(plugins), + /* K5 */ be_nested_str_weak(get), + /* K6 */ be_nested_str_weak(http_remote), + /* K7 */ be_nested_str_weak(find), + /* K8 */ be_const_int(1), + /* K9 */ be_nested_str_weak(keys), + /* K10 */ be_nested_str_weak(push), + /* K11 */ be_nested_str_weak(tasmota), + /* K12 */ be_nested_str_weak(log), + /* K13 */ be_nested_str_weak(MTR_X3A_X20remove_X20unused_X20remote_X3A_X20), + /* K14 */ be_nested_str_weak(addr), + /* K15 */ be_const_int(3), + /* K16 */ be_nested_str_weak(close), + /* K17 */ be_nested_str_weak(remove), + }), + be_str_weak(clean_remotes), + &be_const_str_solidified, + ( &(const binstruction[81]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x88080101, // 0001 GETMBR R2 R0 K1 + 0x780A004C, // 0002 JMPF R2 #0050 + 0x60080013, // 0003 GETGBL R2 G19 + 0x7C080000, // 0004 CALL R2 0 + 0x600C0010, // 0005 GETGBL R3 G16 + 0x88100101, // 0006 GETMBR R4 R0 K1 + 0x7C0C0200, // 0007 CALL R3 1 + 0xA8020003, // 0008 EXBLK 0 #000D + 0x5C100600, // 0009 MOVE R4 R3 + 0x7C100000, // 000A CALL R4 0 + 0x98080902, // 000B SETIDX R2 R4 K2 + 0x7001FFFB, // 000C JMP #0009 + 0x580C0003, // 000D LDCONST R3 K3 + 0xAC0C0200, // 000E CATCH R3 1 0 + 0xB0080000, // 000F RAISE 2 R0 R0 + 0x600C0010, // 0010 GETGBL R3 G16 + 0x88100104, // 0011 GETMBR R4 R0 K4 + 0x7C0C0200, // 0012 CALL R3 1 + 0xA802000F, // 0013 EXBLK 0 #0024 + 0x5C100600, // 0014 MOVE R4 R3 + 0x7C100000, // 0015 CALL R4 0 + 0x8C140305, // 0016 GETMET R5 R1 K5 + 0x5C1C0800, // 0017 MOVE R7 R4 + 0x58200006, // 0018 LDCONST R8 K6 + 0x7C140600, // 0019 CALL R5 3 + 0x4C180000, // 001A LDNIL R6 + 0x20180A06, // 001B NE R6 R5 R6 + 0x781A0005, // 001C JMPF R6 #0023 + 0x8C180507, // 001D GETMET R6 R2 K7 + 0x5C200A00, // 001E MOVE R8 R5 + 0x58240002, // 001F LDCONST R9 K2 + 0x7C180600, // 0020 CALL R6 3 + 0x00180D08, // 0021 ADD R6 R6 K8 + 0x98080A06, // 0022 SETIDX R2 R5 R6 + 0x7001FFEF, // 0023 JMP #0014 + 0x580C0003, // 0024 LDCONST R3 K3 + 0xAC0C0200, // 0025 CATCH R3 1 0 + 0xB0080000, // 0026 RAISE 2 R0 R0 + 0x600C0012, // 0027 GETGBL R3 G18 + 0x7C0C0000, // 0028 CALL R3 0 + 0x60100010, // 0029 GETGBL R4 G16 + 0x8C140509, // 002A GETMET R5 R2 K9 + 0x7C140200, // 002B CALL R5 1 + 0x7C100200, // 002C CALL R4 1 + 0xA8020008, // 002D EXBLK 0 #0037 + 0x5C140800, // 002E MOVE R5 R4 + 0x7C140000, // 002F CALL R5 0 + 0x94180405, // 0030 GETIDX R6 R2 R5 + 0x1C180D02, // 0031 EQ R6 R6 K2 + 0x781A0002, // 0032 JMPF R6 #0036 + 0x8C18070A, // 0033 GETMET R6 R3 K10 + 0x5C200A00, // 0034 MOVE R8 R5 + 0x7C180400, // 0035 CALL R6 2 + 0x7001FFF6, // 0036 JMP #002E + 0x58100003, // 0037 LDCONST R4 K3 + 0xAC100200, // 0038 CATCH R4 1 0 + 0xB0080000, // 0039 RAISE 2 R0 R0 + 0x60100010, // 003A GETGBL R4 G16 + 0x5C140600, // 003B MOVE R5 R3 + 0x7C100200, // 003C CALL R4 1 + 0xA802000E, // 003D EXBLK 0 #004D + 0x5C140800, // 003E MOVE R5 R4 + 0x7C140000, // 003F CALL R5 0 + 0xB81A1600, // 0040 GETNGBL R6 K11 + 0x8C180D0C, // 0041 GETMET R6 R6 K12 + 0x88200B0E, // 0042 GETMBR R8 R5 K14 + 0x00221A08, // 0043 ADD R8 K13 R8 + 0x5824000F, // 0044 LDCONST R9 K15 + 0x7C180600, // 0045 CALL R6 3 + 0x8C180B10, // 0046 GETMET R6 R5 K16 + 0x7C180200, // 0047 CALL R6 1 + 0x88180101, // 0048 GETMBR R6 R0 K1 + 0x8C180D11, // 0049 GETMET R6 R6 K17 + 0x88200B0E, // 004A GETMBR R8 R5 K14 + 0x7C180400, // 004B CALL R6 2 + 0x7001FFF0, // 004C JMP #003E + 0x58100003, // 004D LDCONST R4 K3 + 0xAC100200, // 004E CATCH R4 1 0 + 0xB0080000, // 004F RAISE 2 R0 R0 + 0x80000000, // 0050 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: remove_fabric +********************************************************************/ +be_local_closure(Matter_Device_remove_fabric, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[16]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(log), + /* K2 */ be_nested_str_weak(MTR_X3A_X20removing_X20fabric_X20), + /* K3 */ be_nested_str_weak(get_fabric_id), + /* K4 */ be_nested_str_weak(copy), + /* K5 */ be_nested_str_weak(reverse), + /* K6 */ be_nested_str_weak(tohex), + /* K7 */ be_const_int(2), + /* K8 */ be_nested_str_weak(message_handler), + /* K9 */ be_nested_str_weak(im), + /* K10 */ be_nested_str_weak(subs_shop), + /* K11 */ be_nested_str_weak(remove_by_fabric), + /* K12 */ be_nested_str_weak(mdns_remove_op_discovery), + /* K13 */ be_nested_str_weak(sessions), + /* K14 */ be_nested_str_weak(remove_fabric), + /* K15 */ be_nested_str_weak(save_fabrics), + }), + be_str_weak(remove_fabric), + &be_const_str_solidified, + ( &(const binstruction[33]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x20080202, // 0001 NE R2 R1 R2 + 0x780A0019, // 0002 JMPF R2 #001D + 0xB80A0000, // 0003 GETNGBL R2 K0 + 0x8C080501, // 0004 GETMET R2 R2 K1 + 0x8C100303, // 0005 GETMET R4 R1 K3 + 0x7C100200, // 0006 CALL R4 1 + 0x8C100904, // 0007 GETMET R4 R4 K4 + 0x7C100200, // 0008 CALL R4 1 + 0x8C100905, // 0009 GETMET R4 R4 K5 + 0x7C100200, // 000A CALL R4 1 + 0x8C100906, // 000B GETMET R4 R4 K6 + 0x7C100200, // 000C CALL R4 1 + 0x00120404, // 000D ADD R4 K2 R4 + 0x58140007, // 000E LDCONST R5 K7 + 0x7C080600, // 000F CALL R2 3 + 0x88080108, // 0010 GETMBR R2 R0 K8 + 0x88080509, // 0011 GETMBR R2 R2 K9 + 0x8808050A, // 0012 GETMBR R2 R2 K10 + 0x8C08050B, // 0013 GETMET R2 R2 K11 + 0x5C100200, // 0014 MOVE R4 R1 + 0x7C080400, // 0015 CALL R2 2 + 0x8C08010C, // 0016 GETMET R2 R0 K12 + 0x5C100200, // 0017 MOVE R4 R1 + 0x7C080400, // 0018 CALL R2 2 + 0x8808010D, // 0019 GETMBR R2 R0 K13 + 0x8C08050E, // 001A GETMET R2 R2 K14 + 0x5C100200, // 001B MOVE R4 R1 + 0x7C080400, // 001C CALL R2 2 + 0x8808010D, // 001D GETMBR R2 R0 K13 + 0x8C08050F, // 001E GETMET R2 R2 K15 + 0x7C080200, // 001F CALL R2 1 + 0x80000000, // 0020 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: _mdns_announce_hostname +********************************************************************/ +be_local_closure(Matter_Device__mdns_announce_hostname, /* name */ + be_nested_proto( + 14, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[27]) { /* constants */ + /* K0 */ be_nested_str_weak(mdns), + /* K1 */ be_nested_str_weak(string), + /* K2 */ be_nested_str_weak(start), + /* K3 */ be_nested_str_weak(tasmota), + /* K4 */ be_nested_str_weak(eth), + /* K5 */ be_nested_str_weak(hostname_eth), + /* K6 */ be_nested_str_weak(replace), + /* K7 */ be_nested_str_weak(find), + /* K8 */ be_nested_str_weak(mac), + /* K9 */ be_nested_str_weak(_X3A), + /* K10 */ be_nested_str_weak(), + /* K11 */ be_nested_str_weak(ipv4only), + /* K12 */ be_nested_str_weak(contains), + /* K13 */ be_nested_str_weak(ip6local), + /* K14 */ be_nested_str_weak(add_hostname), + /* K15 */ be_nested_str_weak(ip), + /* K16 */ be_nested_str_weak(ip6), + /* K17 */ be_nested_str_weak(log), + /* K18 */ be_nested_str_weak(MTR_X3A_X20calling_X20mdns_X2Eadd_hostname_X28_X25s_X2C_X20_X25s_X29), + /* K19 */ be_const_int(3), + /* K20 */ be_nested_str_weak(wifi), + /* K21 */ be_nested_str_weak(hostname_wifi), + /* K22 */ be_nested_str_weak(MTR_X3A_X20start_X20mDNS_X20on_X20_X25s_X20host_X20_X27_X25s_X2Elocal_X27), + /* K23 */ be_nested_str_weak(MTR_X3A_X20Exception), + /* K24 */ be_nested_str_weak(_X7C), + /* K25 */ be_const_int(2), + /* K26 */ be_nested_str_weak(mdns_announce_op_discovery_all_fabrics), + }), + be_str_weak(_mdns_announce_hostname), + &be_const_str_solidified, + ( &(const binstruction[148]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0xA40E0200, // 0001 IMPORT R3 K1 + 0x8C100502, // 0002 GETMET R4 R2 K2 + 0x7C100200, // 0003 CALL R4 1 + 0xA802007A, // 0004 EXBLK 0 #0080 + 0x78060034, // 0005 JMPF R1 #003B + 0xB8120600, // 0006 GETNGBL R4 K3 + 0x8C100904, // 0007 GETMET R4 R4 K4 + 0x7C100200, // 0008 CALL R4 1 + 0x8C140706, // 0009 GETMET R5 R3 K6 + 0x8C1C0907, // 000A GETMET R7 R4 K7 + 0x58240008, // 000B LDCONST R9 K8 + 0x7C1C0400, // 000C CALL R7 2 + 0x58200009, // 000D LDCONST R8 K9 + 0x5824000A, // 000E LDCONST R9 K10 + 0x7C140800, // 000F CALL R5 4 + 0x90020A05, // 0010 SETMBR R0 K5 R5 + 0x8814010B, // 0011 GETMBR R5 R0 K11 + 0x78160003, // 0012 JMPF R5 #0017 + 0x8C14090C, // 0013 GETMET R5 R4 K12 + 0x581C000D, // 0014 LDCONST R7 K13 + 0x7C140400, // 0015 CALL R5 2 + 0x7416000F, // 0016 JMPT R5 #0027 + 0x8C14050E, // 0017 GETMET R5 R2 K14 + 0x881C0105, // 0018 GETMBR R7 R0 K5 + 0x8C200907, // 0019 GETMET R8 R4 K7 + 0x5828000D, // 001A LDCONST R10 K13 + 0x582C000A, // 001B LDCONST R11 K10 + 0x7C200600, // 001C CALL R8 3 + 0x8C240907, // 001D GETMET R9 R4 K7 + 0x582C000F, // 001E LDCONST R11 K15 + 0x5830000A, // 001F LDCONST R12 K10 + 0x7C240600, // 0020 CALL R9 3 + 0x8C280907, // 0021 GETMET R10 R4 K7 + 0x58300010, // 0022 LDCONST R12 K16 + 0x5834000A, // 0023 LDCONST R13 K10 + 0x7C280600, // 0024 CALL R10 3 + 0x7C140A00, // 0025 CALL R5 5 + 0x70020012, // 0026 JMP #003A + 0xB8160600, // 0027 GETNGBL R5 K3 + 0x8C140B11, // 0028 GETMET R5 R5 K17 + 0x601C0018, // 0029 GETGBL R7 G24 + 0x58200012, // 002A LDCONST R8 K18 + 0x88240105, // 002B GETMBR R9 R0 K5 + 0x8C280907, // 002C GETMET R10 R4 K7 + 0x5830000F, // 002D LDCONST R12 K15 + 0x5834000A, // 002E LDCONST R13 K10 + 0x7C280600, // 002F CALL R10 3 + 0x7C1C0600, // 0030 CALL R7 3 + 0x58200013, // 0031 LDCONST R8 K19 + 0x7C140600, // 0032 CALL R5 3 + 0x8C14050E, // 0033 GETMET R5 R2 K14 + 0x881C0105, // 0034 GETMBR R7 R0 K5 + 0x8C200907, // 0035 GETMET R8 R4 K7 + 0x5828000F, // 0036 LDCONST R10 K15 + 0x582C000A, // 0037 LDCONST R11 K10 + 0x7C200600, // 0038 CALL R8 3 + 0x7C140600, // 0039 CALL R5 3 + 0x70020033, // 003A JMP #006F + 0xB8120600, // 003B GETNGBL R4 K3 + 0x8C100914, // 003C GETMET R4 R4 K20 + 0x7C100200, // 003D CALL R4 1 + 0x8C140706, // 003E GETMET R5 R3 K6 + 0x8C1C0907, // 003F GETMET R7 R4 K7 + 0x58240008, // 0040 LDCONST R9 K8 + 0x7C1C0400, // 0041 CALL R7 2 + 0x58200009, // 0042 LDCONST R8 K9 + 0x5824000A, // 0043 LDCONST R9 K10 + 0x7C140800, // 0044 CALL R5 4 + 0x90022A05, // 0045 SETMBR R0 K21 R5 + 0x8814010B, // 0046 GETMBR R5 R0 K11 + 0x78160003, // 0047 JMPF R5 #004C + 0x8C14090C, // 0048 GETMET R5 R4 K12 + 0x581C000D, // 0049 LDCONST R7 K13 + 0x7C140400, // 004A CALL R5 2 + 0x7416000F, // 004B JMPT R5 #005C + 0x8C14050E, // 004C GETMET R5 R2 K14 + 0x881C0115, // 004D GETMBR R7 R0 K21 + 0x8C200907, // 004E GETMET R8 R4 K7 + 0x5828000D, // 004F LDCONST R10 K13 + 0x582C000A, // 0050 LDCONST R11 K10 + 0x7C200600, // 0051 CALL R8 3 + 0x8C240907, // 0052 GETMET R9 R4 K7 + 0x582C000F, // 0053 LDCONST R11 K15 + 0x5830000A, // 0054 LDCONST R12 K10 + 0x7C240600, // 0055 CALL R9 3 + 0x8C280907, // 0056 GETMET R10 R4 K7 + 0x58300010, // 0057 LDCONST R12 K16 + 0x5834000A, // 0058 LDCONST R13 K10 + 0x7C280600, // 0059 CALL R10 3 + 0x7C140A00, // 005A CALL R5 5 + 0x70020012, // 005B JMP #006F + 0xB8160600, // 005C GETNGBL R5 K3 + 0x8C140B11, // 005D GETMET R5 R5 K17 + 0x601C0018, // 005E GETGBL R7 G24 + 0x58200012, // 005F LDCONST R8 K18 + 0x88240115, // 0060 GETMBR R9 R0 K21 + 0x8C280907, // 0061 GETMET R10 R4 K7 + 0x5830000F, // 0062 LDCONST R12 K15 + 0x5834000A, // 0063 LDCONST R13 K10 + 0x7C280600, // 0064 CALL R10 3 + 0x7C1C0600, // 0065 CALL R7 3 + 0x58200013, // 0066 LDCONST R8 K19 + 0x7C140600, // 0067 CALL R5 3 + 0x8C14050E, // 0068 GETMET R5 R2 K14 + 0x881C0115, // 0069 GETMBR R7 R0 K21 + 0x8C200907, // 006A GETMET R8 R4 K7 + 0x5828000F, // 006B LDCONST R10 K15 + 0x582C000A, // 006C LDCONST R11 K10 + 0x7C200600, // 006D CALL R8 3 + 0x7C140600, // 006E CALL R5 3 + 0xB8120600, // 006F GETNGBL R4 K3 + 0x8C100911, // 0070 GETMET R4 R4 K17 + 0x60180018, // 0071 GETGBL R6 G24 + 0x581C0016, // 0072 LDCONST R7 K22 + 0x78060001, // 0073 JMPF R1 #0076 + 0x58200004, // 0074 LDCONST R8 K4 + 0x70020000, // 0075 JMP #0077 + 0x58200014, // 0076 LDCONST R8 K20 + 0x78060001, // 0077 JMPF R1 #007A + 0x88240105, // 0078 GETMBR R9 R0 K5 + 0x70020000, // 0079 JMP #007B + 0x88240115, // 007A GETMBR R9 R0 K21 + 0x7C180600, // 007B CALL R6 3 + 0x581C0013, // 007C LDCONST R7 K19 + 0x7C100600, // 007D CALL R4 3 + 0xA8040001, // 007E EXBLK 1 1 + 0x70020010, // 007F JMP #0091 + 0xAC100002, // 0080 CATCH R4 0 2 + 0x7002000D, // 0081 JMP #0090 + 0xB81A0600, // 0082 GETNGBL R6 K3 + 0x8C180D11, // 0083 GETMET R6 R6 K17 + 0x60200008, // 0084 GETGBL R8 G8 + 0x5C240800, // 0085 MOVE R9 R4 + 0x7C200200, // 0086 CALL R8 1 + 0x00222E08, // 0087 ADD R8 K23 R8 + 0x00201118, // 0088 ADD R8 R8 K24 + 0x60240008, // 0089 GETGBL R9 G8 + 0x5C280A00, // 008A MOVE R10 R5 + 0x7C240200, // 008B CALL R9 1 + 0x00201009, // 008C ADD R8 R8 R9 + 0x58240019, // 008D LDCONST R9 K25 + 0x7C180600, // 008E CALL R6 3 + 0x70020000, // 008F JMP #0091 + 0xB0080000, // 0090 RAISE 2 R0 R0 + 0x8C10011A, // 0091 GETMET R4 R0 K26 + 0x7C100200, // 0092 CALL R4 1 + 0x80000000, // 0093 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: register_native_classes +********************************************************************/ +be_local_closure(Matter_Device_register_native_classes, /* name */ + be_nested_proto( + 12, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(introspect), /* K1 */ be_nested_str_weak(string), /* K2 */ be_nested_str_weak(members), /* K3 */ be_nested_str_weak(matter), @@ -683,16 +1388,10 @@ be_local_closure(Matter_Device_register_native_classes, /* name */ /* K8 */ be_const_int(0), /* K9 */ be_nested_str_weak(register_plugin_class), /* K10 */ be_nested_str_weak(stop_iteration), - /* K11 */ be_nested_str_weak(tasmota), - /* K12 */ be_nested_str_weak(log), - /* K13 */ be_nested_str_weak(MTR_X3A_X20registered_X20classes_X20), - /* K14 */ be_nested_str_weak(k2l), - /* K15 */ be_nested_str_weak(plugins_classes), - /* K16 */ be_const_int(3), }), be_str_weak(register_native_classes), &be_const_str_solidified, - ( &(const binstruction[43]) { /* code */ + ( &(const binstruction[33]) { /* code */ 0xA40E0000, // 0000 IMPORT R3 K0 0xA4120200, // 0001 IMPORT R4 K1 0x60140010, // 0002 GETGBL R5 G16 @@ -725,17 +1424,7 @@ be_local_closure(Matter_Device_register_native_classes, /* name */ 0x5814000A, // 001D LDCONST R5 K10 0xAC140200, // 001E CATCH R5 1 0 0xB0080000, // 001F RAISE 2 R0 R0 - 0xB8161600, // 0020 GETNGBL R5 K11 - 0x8C140B0C, // 0021 GETMET R5 R5 K12 - 0x601C0008, // 0022 GETGBL R7 G8 - 0x8C20010E, // 0023 GETMET R8 R0 K14 - 0x8828010F, // 0024 GETMBR R10 R0 K15 - 0x7C200400, // 0025 CALL R8 2 - 0x7C1C0200, // 0026 CALL R7 1 - 0x001E1A07, // 0027 ADD R7 K13 R7 - 0x58200010, // 0028 LDCONST R8 K16 - 0x7C140600, // 0029 CALL R5 3 - 0x80000000, // 002A RET 0 + 0x80000000, // 0020 RET 0 }) ) ); @@ -743,11 +1432,11 @@ be_local_closure(Matter_Device_register_native_classes, /* name */ /******************************************************************** -** Solidified function: stop_basic_commissioning +** Solidified function: mdns_remove_op_discovery_all_fabrics ********************************************************************/ -be_local_closure(Matter_Device_stop_basic_commissioning, /* name */ +be_local_closure(Matter_Device_mdns_remove_op_discovery_all_fabrics, /* name */ be_nested_proto( - 5, /* nstack */ + 6, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -755,49 +1444,39 @@ be_local_closure(Matter_Device_stop_basic_commissioning, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ - /* K0 */ be_nested_str_weak(is_root_commissioning_open), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(publish_result), - /* K3 */ be_nested_str_weak(_X7B_X22Matter_X22_X3A_X7B_X22Commissioning_X22_X3A0_X7D_X7D), - /* K4 */ be_nested_str_weak(Matter), - /* K5 */ be_nested_str_weak(commissioning_open), - /* K6 */ be_nested_str_weak(mdns_remove_PASE), - /* K7 */ be_nested_str_weak(commissioning_iterations), - /* K8 */ be_nested_str_weak(commissioning_discriminator), - /* K9 */ be_nested_str_weak(commissioning_salt), - /* K10 */ be_nested_str_weak(commissioning_w0), - /* K11 */ be_nested_str_weak(commissioning_L), - /* K12 */ be_nested_str_weak(commissioning_admin_fabric), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(sessions), + /* K1 */ be_nested_str_weak(active_fabrics), + /* K2 */ be_nested_str_weak(get_device_id), + /* K3 */ be_nested_str_weak(get_fabric_id), + /* K4 */ be_nested_str_weak(mdns_remove_op_discovery), + /* K5 */ be_nested_str_weak(stop_iteration), }), - be_str_weak(stop_basic_commissioning), + be_str_weak(mdns_remove_op_discovery_all_fabrics), &be_const_str_solidified, - ( &(const binstruction[25]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x78060004, // 0002 JMPF R1 #0008 - 0xB8060200, // 0003 GETNGBL R1 K1 - 0x8C040302, // 0004 GETMET R1 R1 K2 - 0x580C0003, // 0005 LDCONST R3 K3 - 0x58100004, // 0006 LDCONST R4 K4 - 0x7C040600, // 0007 CALL R1 3 - 0x4C040000, // 0008 LDNIL R1 - 0x90020A01, // 0009 SETMBR R0 K5 R1 - 0x8C040106, // 000A GETMET R1 R0 K6 - 0x7C040200, // 000B CALL R1 1 - 0x4C040000, // 000C LDNIL R1 - 0x90020E01, // 000D SETMBR R0 K7 R1 - 0x4C040000, // 000E LDNIL R1 - 0x90021001, // 000F SETMBR R0 K8 R1 - 0x4C040000, // 0010 LDNIL R1 - 0x90021201, // 0011 SETMBR R0 K9 R1 - 0x4C040000, // 0012 LDNIL R1 - 0x90021401, // 0013 SETMBR R0 K10 R1 - 0x4C040000, // 0014 LDNIL R1 - 0x90021601, // 0015 SETMBR R0 K11 R1 - 0x4C040000, // 0016 LDNIL R1 - 0x90021801, // 0017 SETMBR R0 K12 R1 - 0x80000000, // 0018 RET 0 + ( &(const binstruction[22]) { /* code */ + 0x60040010, // 0000 GETGBL R1 G16 + 0x88080100, // 0001 GETMBR R2 R0 K0 + 0x8C080501, // 0002 GETMET R2 R2 K1 + 0x7C080200, // 0003 CALL R2 1 + 0x7C040200, // 0004 CALL R1 1 + 0xA802000B, // 0005 EXBLK 0 #0012 + 0x5C080200, // 0006 MOVE R2 R1 + 0x7C080000, // 0007 CALL R2 0 + 0x8C0C0502, // 0008 GETMET R3 R2 K2 + 0x7C0C0200, // 0009 CALL R3 1 + 0x780E0005, // 000A JMPF R3 #0011 + 0x8C0C0503, // 000B GETMET R3 R2 K3 + 0x7C0C0200, // 000C CALL R3 1 + 0x780E0002, // 000D JMPF R3 #0011 + 0x8C0C0104, // 000E GETMET R3 R0 K4 + 0x5C140400, // 000F MOVE R5 R2 + 0x7C0C0400, // 0010 CALL R3 2 + 0x7001FFF3, // 0011 JMP #0006 + 0x58040005, // 0012 LDCONST R1 K5 + 0xAC040200, // 0013 CATCH R1 1 0 + 0xB0080000, // 0014 RAISE 2 R0 R0 + 0x80000000, // 0015 RET 0 }) ) ); @@ -805,11 +1484,11 @@ be_local_closure(Matter_Device_stop_basic_commissioning, /* name */ /******************************************************************** -** Solidified function: _trigger_read_sensors +** Solidified function: is_root_commissioning_open ********************************************************************/ -be_local_closure(Matter_Device__trigger_read_sensors, /* name */ +be_local_closure(Matter_Device_is_root_commissioning_open, /* name */ be_nested_proto( - 8, /* nstack */ + 3, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -817,59 +1496,24 @@ be_local_closure(Matter_Device__trigger_read_sensors, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ - /* K0 */ be_nested_str_weak(json), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(read_sensors), - /* K3 */ be_nested_str_weak(load), - /* K4 */ be_const_int(0), - /* K5 */ be_nested_str_weak(plugins), - /* K6 */ be_nested_str_weak(parse_sensors), - /* K7 */ be_const_int(1), - /* K8 */ be_nested_str_weak(log), - /* K9 */ be_nested_str_weak(MTR_X3A_X20unable_X20to_X20parse_X20read_sensors_X3A_X20), - /* K10 */ be_const_int(3), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(commissioning_open), + /* K1 */ be_nested_str_weak(commissioning_admin_fabric), }), - be_str_weak(_trigger_read_sensors), + be_str_weak(is_root_commissioning_open), &be_const_str_solidified, - ( &(const binstruction[37]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xB80A0200, // 0001 GETNGBL R2 K1 - 0x8C080502, // 0002 GETMET R2 R2 K2 - 0x7C080200, // 0003 CALL R2 1 - 0x4C0C0000, // 0004 LDNIL R3 - 0x1C0C0403, // 0005 EQ R3 R2 R3 - 0x780E0000, // 0006 JMPF R3 #0008 - 0x80000600, // 0007 RET 0 - 0x8C0C0303, // 0008 GETMET R3 R1 K3 - 0x5C140400, // 0009 MOVE R5 R2 - 0x7C0C0400, // 000A CALL R3 2 - 0x4C100000, // 000B LDNIL R4 - 0x20100604, // 000C NE R4 R3 R4 - 0x7812000D, // 000D JMPF R4 #001C - 0x58100004, // 000E LDCONST R4 K4 - 0x6014000C, // 000F GETGBL R5 G12 - 0x88180105, // 0010 GETMBR R6 R0 K5 - 0x7C140200, // 0011 CALL R5 1 - 0x14140805, // 0012 LT R5 R4 R5 - 0x78160006, // 0013 JMPF R5 #001B - 0x88140105, // 0014 GETMBR R5 R0 K5 - 0x94140A04, // 0015 GETIDX R5 R5 R4 - 0x8C140B06, // 0016 GETMET R5 R5 K6 - 0x5C1C0600, // 0017 MOVE R7 R3 - 0x7C140400, // 0018 CALL R5 2 - 0x00100907, // 0019 ADD R4 R4 K7 - 0x7001FFF3, // 001A JMP #000F - 0x70020007, // 001B JMP #0024 - 0xB8120200, // 001C GETNGBL R4 K1 - 0x8C100908, // 001D GETMET R4 R4 K8 - 0x60180008, // 001E GETGBL R6 G8 - 0x5C1C0400, // 001F MOVE R7 R2 - 0x7C180200, // 0020 CALL R6 1 - 0x001A1206, // 0021 ADD R6 K9 R6 - 0x581C000A, // 0022 LDCONST R7 K10 - 0x7C100600, // 0023 CALL R4 3 - 0x80000000, // 0024 RET 0 + ( &(const binstruction[11]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x20040202, // 0002 NE R1 R1 R2 + 0x78060003, // 0003 JMPF R1 #0008 + 0x88040101, // 0004 GETMBR R1 R0 K1 + 0x4C080000, // 0005 LDNIL R2 + 0x1C040202, // 0006 EQ R1 R1 R2 + 0x74060000, // 0007 JMPT R1 #0009 + 0x50040001, // 0008 LDBOOL R1 0 1 + 0x50040200, // 0009 LDBOOL R1 1 0 + 0x80040200, // 000A RET 1 R1 }) ) ); @@ -877,35 +1521,30 @@ be_local_closure(Matter_Device__trigger_read_sensors, /* name */ /******************************************************************** -** Solidified function: _init_basic_commissioning +** Solidified function: msg_send ********************************************************************/ -be_local_closure(Matter_Device__init_basic_commissioning, /* name */ +be_local_closure(Matter_Device_msg_send, /* name */ be_nested_proto( - 3, /* nstack */ - 1, /* argc */ + 5, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(sessions), - /* K1 */ be_nested_str_weak(count_active_fabrics), - /* K2 */ be_const_int(0), - /* K3 */ be_nested_str_weak(start_root_basic_commissioning), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(udp_server), + /* K1 */ be_nested_str_weak(send_UDP), }), - be_str_weak(_init_basic_commissioning), + be_str_weak(msg_send), &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x1C040302, // 0003 EQ R1 R1 K2 - 0x78060001, // 0004 JMPF R1 #0007 - 0x8C040103, // 0005 GETMET R1 R0 K3 - 0x7C040200, // 0006 CALL R1 1 - 0x80000000, // 0007 RET 0 + ( &(const binstruction[ 5]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C080400, // 0003 CALL R2 2 + 0x80040400, // 0004 RET 1 R2 }) ) ); @@ -913,11 +1552,91 @@ be_local_closure(Matter_Device__init_basic_commissioning, /* name */ /******************************************************************** -** Solidified function: compute_qrcode_content +** Solidified function: process_attribute_read_solo ********************************************************************/ -be_local_closure(Matter_Device_compute_qrcode_content, /* name */ +be_local_closure(Matter_Device_process_attribute_read_solo, /* name */ be_nested_proto( - 8, /* nstack */ + 10, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(endpoint), + /* K1 */ be_nested_str_weak(cluster), + /* K2 */ be_nested_str_weak(attribute), + /* K3 */ be_nested_str_weak(find_plugin_by_endpoint), + /* K4 */ be_nested_str_weak(status), + /* K5 */ be_nested_str_weak(matter), + /* K6 */ be_nested_str_weak(UNSUPPORTED_ENDPOINT), + /* K7 */ be_nested_str_weak(contains_cluster), + /* K8 */ be_nested_str_weak(UNSUPPORTED_CLUSTER), + /* K9 */ be_nested_str_weak(contains_attribute), + /* K10 */ be_nested_str_weak(UNSUPPORTED_ATTRIBUTE), + }), + be_str_weak(process_attribute_read_solo), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0x88080300, // 0000 GETMBR R2 R1 K0 + 0x880C0301, // 0001 GETMBR R3 R1 K1 + 0x88100302, // 0002 GETMBR R4 R1 K2 + 0x4C140000, // 0003 LDNIL R5 + 0x1C140405, // 0004 EQ R5 R2 R5 + 0x74160005, // 0005 JMPT R5 #000C + 0x4C140000, // 0006 LDNIL R5 + 0x1C140605, // 0007 EQ R5 R3 R5 + 0x74160002, // 0008 JMPT R5 #000C + 0x4C140000, // 0009 LDNIL R5 + 0x1C140805, // 000A EQ R5 R4 R5 + 0x78160001, // 000B JMPF R5 #000E + 0x4C140000, // 000C LDNIL R5 + 0x80040A00, // 000D RET 1 R5 + 0x8C140103, // 000E GETMET R5 R0 K3 + 0x5C1C0400, // 000F MOVE R7 R2 + 0x7C140400, // 0010 CALL R5 2 + 0x4C180000, // 0011 LDNIL R6 + 0x1C180A06, // 0012 EQ R6 R5 R6 + 0x781A0004, // 0013 JMPF R6 #0019 + 0xB81A0A00, // 0014 GETNGBL R6 K5 + 0x88180D06, // 0015 GETMBR R6 R6 K6 + 0x90060806, // 0016 SETMBR R1 K4 R6 + 0x4C180000, // 0017 LDNIL R6 + 0x80040C00, // 0018 RET 1 R6 + 0x8C180B07, // 0019 GETMET R6 R5 K7 + 0x5C200600, // 001A MOVE R8 R3 + 0x7C180400, // 001B CALL R6 2 + 0x741A0004, // 001C JMPT R6 #0022 + 0xB81A0A00, // 001D GETNGBL R6 K5 + 0x88180D08, // 001E GETMBR R6 R6 K8 + 0x90060806, // 001F SETMBR R1 K4 R6 + 0x4C180000, // 0020 LDNIL R6 + 0x80040C00, // 0021 RET 1 R6 + 0x8C180B09, // 0022 GETMET R6 R5 K9 + 0x5C200600, // 0023 MOVE R8 R3 + 0x5C240800, // 0024 MOVE R9 R4 + 0x7C180600, // 0025 CALL R6 3 + 0x741A0004, // 0026 JMPT R6 #002C + 0xB81A0A00, // 0027 GETNGBL R6 K5 + 0x88180D0A, // 0028 GETMBR R6 R6 K10 + 0x90060806, // 0029 SETMBR R1 K4 R6 + 0x4C180000, // 002A LDNIL R6 + 0x80040C00, // 002B RET 1 R6 + 0x80040A00, // 002C RET 1 R5 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: autoconf_device +********************************************************************/ +be_local_closure(Matter_Device_autoconf_device, /* name */ + be_nested_proto( + 6, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -925,63 +1644,67 @@ be_local_closure(Matter_Device_compute_qrcode_content, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[12]) { /* constants */ - /* K0 */ be_nested_str_weak(resize), - /* K1 */ be_nested_str_weak(setbits), - /* K2 */ be_const_int(3), - /* K3 */ be_nested_str_weak(vendorid), - /* K4 */ be_nested_str_weak(productid), - /* K5 */ be_nested_str_weak(root_discriminator), - /* K6 */ be_nested_str_weak(root_passcode), - /* K7 */ be_const_int(134217727), - /* K8 */ be_nested_str_weak(MT_X3A), - /* K9 */ be_nested_str_weak(matter), - /* K10 */ be_nested_str_weak(Base38), - /* K11 */ be_nested_str_weak(encode), + ( &(const bvalue[16]) { /* constants */ + /* K0 */ be_nested_str_weak(json), + /* K1 */ be_nested_str_weak(plugins), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(plugins_persist), + /* K4 */ be_nested_str_weak(plugins_config), + /* K5 */ be_nested_str_weak(autoconf_device_map), + /* K6 */ be_nested_str_weak(plugins_config_remotes), + /* K7 */ be_nested_str_weak(adjust_next_ep), + /* K8 */ be_nested_str_weak(tasmota), + /* K9 */ be_nested_str_weak(log), + /* K10 */ be_nested_str_weak(MTR_X3A_X20autoconfig_X20_X3D_X20), + /* K11 */ be_const_int(3), + /* K12 */ be_nested_str_weak(_instantiate_plugins_from_config), + /* K13 */ be_nested_str_weak(sessions), + /* K14 */ be_nested_str_weak(count_active_fabrics), + /* K15 */ be_nested_str_weak(save_param), }), - be_str_weak(compute_qrcode_content), + be_str_weak(autoconf_device), &be_const_str_solidified, ( &(const binstruction[40]) { /* code */ - 0x60040015, // 0000 GETGBL R1 G21 - 0x7C040000, // 0001 CALL R1 0 - 0x8C040300, // 0002 GETMET R1 R1 K0 - 0x540E000A, // 0003 LDINT R3 11 - 0x7C040400, // 0004 CALL R1 2 - 0x8C080301, // 0005 GETMET R2 R1 K1 - 0x58100002, // 0006 LDCONST R4 K2 - 0x5416000F, // 0007 LDINT R5 16 - 0x88180103, // 0008 GETMBR R6 R0 K3 - 0x7C080800, // 0009 CALL R2 4 - 0x8C080301, // 000A GETMET R2 R1 K1 - 0x54120012, // 000B LDINT R4 19 - 0x5416000F, // 000C LDINT R5 16 - 0x88180104, // 000D GETMBR R6 R0 K4 - 0x7C080800, // 000E CALL R2 4 - 0x8C080301, // 000F GETMET R2 R1 K1 - 0x54120024, // 0010 LDINT R4 37 - 0x54160007, // 0011 LDINT R5 8 - 0x541A0003, // 0012 LDINT R6 4 - 0x7C080800, // 0013 CALL R2 4 - 0x8C080301, // 0014 GETMET R2 R1 K1 - 0x5412002C, // 0015 LDINT R4 45 - 0x5416000B, // 0016 LDINT R5 12 - 0x88180105, // 0017 GETMBR R6 R0 K5 - 0x541E0FFE, // 0018 LDINT R7 4095 - 0x2C180C07, // 0019 AND R6 R6 R7 - 0x7C080800, // 001A CALL R2 4 - 0x8C080301, // 001B GETMET R2 R1 K1 - 0x54120038, // 001C LDINT R4 57 - 0x5416001A, // 001D LDINT R5 27 - 0x88180106, // 001E GETMBR R6 R0 K6 - 0x2C180D07, // 001F AND R6 R6 K7 - 0x7C080800, // 0020 CALL R2 4 - 0xB80A1200, // 0021 GETNGBL R2 K9 - 0x8808050A, // 0022 GETMBR R2 R2 K10 - 0x8C08050B, // 0023 GETMET R2 R2 K11 - 0x5C100200, // 0024 MOVE R4 R1 - 0x7C080400, // 0025 CALL R2 2 - 0x000A1002, // 0026 ADD R2 K8 R2 - 0x80040400, // 0027 RET 1 R2 + 0xA4060000, // 0000 IMPORT R1 K0 + 0x6008000C, // 0001 GETGBL R2 G12 + 0x880C0101, // 0002 GETMBR R3 R0 K1 + 0x7C080200, // 0003 CALL R2 1 + 0x24080502, // 0004 GT R2 R2 K2 + 0x780A0000, // 0005 JMPF R2 #0007 + 0x80000400, // 0006 RET 0 + 0x88080103, // 0007 GETMBR R2 R0 K3 + 0x740A000F, // 0008 JMPT R2 #0019 + 0x8C080105, // 0009 GETMET R2 R0 K5 + 0x7C080200, // 000A CALL R2 1 + 0x90020802, // 000B SETMBR R0 K4 R2 + 0x60080013, // 000C GETGBL R2 G19 + 0x7C080000, // 000D CALL R2 0 + 0x90020C02, // 000E SETMBR R0 K6 R2 + 0x8C080107, // 000F GETMET R2 R0 K7 + 0x7C080200, // 0010 CALL R2 1 + 0xB80A1000, // 0011 GETNGBL R2 K8 + 0x8C080509, // 0012 GETMET R2 R2 K9 + 0x60100008, // 0013 GETGBL R4 G8 + 0x88140104, // 0014 GETMBR R5 R0 K4 + 0x7C100200, // 0015 CALL R4 1 + 0x00121404, // 0016 ADD R4 K10 R4 + 0x5814000B, // 0017 LDCONST R5 K11 + 0x7C080600, // 0018 CALL R2 3 + 0x8C08010C, // 0019 GETMET R2 R0 K12 + 0x88100104, // 001A GETMBR R4 R0 K4 + 0x7C080400, // 001B CALL R2 2 + 0x88080103, // 001C GETMBR R2 R0 K3 + 0x740A0008, // 001D JMPT R2 #0027 + 0x8808010D, // 001E GETMBR R2 R0 K13 + 0x8C08050E, // 001F GETMET R2 R2 K14 + 0x7C080200, // 0020 CALL R2 1 + 0x24080502, // 0021 GT R2 R2 K2 + 0x780A0003, // 0022 JMPF R2 #0027 + 0x50080200, // 0023 LDBOOL R2 1 0 + 0x90020602, // 0024 SETMBR R0 K3 R2 + 0x8C08010F, // 0025 GETMET R2 R0 K15 + 0x7C080200, // 0026 CALL R2 1 + 0x80000000, // 0027 RET 0 }) ) ); @@ -989,57 +1712,73 @@ be_local_closure(Matter_Device_compute_qrcode_content, /* name */ /******************************************************************** -** Solidified function: get_active_endpoints +** Solidified function: register_http_remote ********************************************************************/ -be_local_closure(Matter_Device_get_active_endpoints, /* name */ +be_local_closure(Matter_Device_register_http_remote, /* name */ be_nested_proto( 9, /* nstack */ - 2, /* argc */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(plugins), - /* K1 */ be_nested_str_weak(get_endpoint), - /* K2 */ be_const_int(0), - /* K3 */ be_nested_str_weak(find), - /* K4 */ be_nested_str_weak(push), - /* K5 */ be_nested_str_weak(stop_iteration), + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(http_remotes), + /* K1 */ be_nested_str_weak(contains), + /* K2 */ be_nested_str_weak(get_timeout), + /* K3 */ be_nested_str_weak(set_timeout), + /* K4 */ be_nested_str_weak(matter), + /* K5 */ be_nested_str_weak(HTTP_remote), + /* K6 */ be_nested_str_weak(plugins_config_remotes), + /* K7 */ be_nested_str_weak(set_info), }), - be_str_weak(get_active_endpoints), + be_str_weak(register_http_remote), &be_const_str_solidified, - ( &(const binstruction[28]) { /* code */ - 0x60080012, // 0000 GETGBL R2 G18 - 0x7C080000, // 0001 CALL R2 0 - 0x600C0010, // 0002 GETGBL R3 G16 - 0x88100100, // 0003 GETMBR R4 R0 K0 - 0x7C0C0200, // 0004 CALL R3 1 - 0xA8020011, // 0005 EXBLK 0 #0018 - 0x5C100600, // 0006 MOVE R4 R3 - 0x7C100000, // 0007 CALL R4 0 - 0x8C140901, // 0008 GETMET R5 R4 K1 - 0x7C140200, // 0009 CALL R5 1 - 0x78060002, // 000A JMPF R1 #000E - 0x1C180B02, // 000B EQ R6 R5 K2 - 0x781A0000, // 000C JMPF R6 #000E - 0x7001FFF7, // 000D JMP #0006 - 0x8C180503, // 000E GETMET R6 R2 K3 - 0x5C200A00, // 000F MOVE R8 R5 - 0x7C180400, // 0010 CALL R6 2 - 0x4C1C0000, // 0011 LDNIL R7 - 0x1C180C07, // 0012 EQ R6 R6 R7 - 0x781A0002, // 0013 JMPF R6 #0017 - 0x8C180504, // 0014 GETMET R6 R2 K4 - 0x5C200A00, // 0015 MOVE R8 R5 - 0x7C180400, // 0016 CALL R6 2 - 0x7001FFED, // 0017 JMP #0006 - 0x580C0005, // 0018 LDCONST R3 K5 - 0xAC0C0200, // 0019 CATCH R3 1 0 - 0xB0080000, // 001A RAISE 2 R0 R0 - 0x80040400, // 001B RET 1 R2 + ( &(const binstruction[42]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x4C100000, // 0001 LDNIL R4 + 0x1C0C0604, // 0002 EQ R3 R3 R4 + 0x780E0002, // 0003 JMPF R3 #0007 + 0x600C0013, // 0004 GETGBL R3 G19 + 0x7C0C0000, // 0005 CALL R3 0 + 0x90020003, // 0006 SETMBR R0 K0 R3 + 0x4C0C0000, // 0007 LDNIL R3 + 0x88100100, // 0008 GETMBR R4 R0 K0 + 0x8C100901, // 0009 GETMET R4 R4 K1 + 0x5C180200, // 000A MOVE R6 R1 + 0x7C100400, // 000B CALL R4 2 + 0x78120009, // 000C JMPF R4 #0017 + 0x88100100, // 000D GETMBR R4 R0 K0 + 0x940C0801, // 000E GETIDX R3 R4 R1 + 0x8C140702, // 000F GETMET R5 R3 K2 + 0x7C140200, // 0010 CALL R5 1 + 0x14140405, // 0011 LT R5 R2 R5 + 0x78160002, // 0012 JMPF R5 #0016 + 0x8C140703, // 0013 GETMET R5 R3 K3 + 0x5C1C0400, // 0014 MOVE R7 R2 + 0x7C140400, // 0015 CALL R5 2 + 0x70020011, // 0016 JMP #0029 + 0xB8120800, // 0017 GETNGBL R4 K4 + 0x8C100905, // 0018 GETMET R4 R4 K5 + 0x5C180000, // 0019 MOVE R6 R0 + 0x5C1C0200, // 001A MOVE R7 R1 + 0x5C200400, // 001B MOVE R8 R2 + 0x7C100800, // 001C CALL R4 4 + 0x5C0C0800, // 001D MOVE R3 R4 + 0x88100106, // 001E GETMBR R4 R0 K6 + 0x8C100901, // 001F GETMET R4 R4 K1 + 0x5C180200, // 0020 MOVE R6 R1 + 0x7C100400, // 0021 CALL R4 2 + 0x78120003, // 0022 JMPF R4 #0027 + 0x8C100707, // 0023 GETMET R4 R3 K7 + 0x88180106, // 0024 GETMBR R6 R0 K6 + 0x94180C01, // 0025 GETIDX R6 R6 R1 + 0x7C100400, // 0026 CALL R4 2 + 0x88100100, // 0027 GETMBR R4 R0 K0 + 0x98100203, // 0028 SETIDX R4 R1 R3 + 0x80040600, // 0029 RET 1 R3 }) ) ); @@ -1098,55 +1837,869 @@ be_local_closure(Matter_Device_attribute_updated, /* name */ /******************************************************************** -** Solidified function: invoke_request +** Solidified function: every_250ms ********************************************************************/ -be_local_closure(Matter_Device_invoke_request, /* name */ +be_local_closure(Matter_Device_every_250ms, /* name */ be_nested_proto( - 12, /* nstack */ - 4, /* argc */ + 4, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_const_int(0), - /* K1 */ be_nested_str_weak(endpoint), - /* K2 */ be_nested_str_weak(plugins), - /* K3 */ be_nested_str_weak(invoke_request), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(message_handler), + /* K1 */ be_nested_str_weak(every_250ms), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(plugins), /* K4 */ be_const_int(1), - /* K5 */ be_nested_str_weak(status), - /* K6 */ be_nested_str_weak(matter), - /* K7 */ be_nested_str_weak(UNSUPPORTED_ENDPOINT), }), - be_str_weak(invoke_request), + be_str_weak(every_250ms), &be_const_str_solidified, - ( &(const binstruction[24]) { /* code */ - 0x58100000, // 0000 LDCONST R4 K0 - 0x88140701, // 0001 GETMBR R5 R3 K1 - 0x6018000C, // 0002 GETGBL R6 G12 - 0x881C0102, // 0003 GETMBR R7 R0 K2 - 0x7C180200, // 0004 CALL R6 1 - 0x14180806, // 0005 LT R6 R4 R6 - 0x781A000C, // 0006 JMPF R6 #0014 - 0x88180102, // 0007 GETMBR R6 R0 K2 - 0x94180C04, // 0008 GETIDX R6 R6 R4 - 0x881C0D01, // 0009 GETMBR R7 R6 K1 - 0x1C1C0E05, // 000A EQ R7 R7 R5 - 0x781E0005, // 000B JMPF R7 #0012 - 0x8C1C0D03, // 000C GETMET R7 R6 K3 - 0x5C240200, // 000D MOVE R9 R1 - 0x5C280400, // 000E MOVE R10 R2 - 0x5C2C0600, // 000F MOVE R11 R3 - 0x7C1C0800, // 0010 CALL R7 4 - 0x80040E00, // 0011 RET 1 R7 - 0x00100904, // 0012 ADD R4 R4 K4 - 0x7001FFED, // 0013 JMP #0002 - 0xB81A0C00, // 0014 GETNGBL R6 K6 - 0x88180D07, // 0015 GETMBR R6 R6 K7 - 0x900E0A06, // 0016 SETMBR R3 K5 R6 - 0x80000000, // 0017 RET 0 + ( &(const binstruction[16]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x58040002, // 0003 LDCONST R1 K2 + 0x6008000C, // 0004 GETGBL R2 G12 + 0x880C0103, // 0005 GETMBR R3 R0 K3 + 0x7C080200, // 0006 CALL R2 1 + 0x14080202, // 0007 LT R2 R1 R2 + 0x780A0005, // 0008 JMPF R2 #000F + 0x88080103, // 0009 GETMBR R2 R0 K3 + 0x94080401, // 000A GETIDX R2 R2 R1 + 0x8C080501, // 000B GETMET R2 R2 K1 + 0x7C080200, // 000C CALL R2 1 + 0x00040304, // 000D ADD R1 R1 K4 + 0x7001FFF4, // 000E JMP #0004 + 0x80000000, // 000F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_active_endpoints +********************************************************************/ +be_local_closure(Matter_Device_get_active_endpoints, /* name */ + be_nested_proto( + 9, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(plugins), + /* K1 */ be_nested_str_weak(get_endpoint), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(find), + /* K4 */ be_nested_str_weak(push), + /* K5 */ be_nested_str_weak(stop_iteration), + }), + be_str_weak(get_active_endpoints), + &be_const_str_solidified, + ( &(const binstruction[28]) { /* code */ + 0x60080012, // 0000 GETGBL R2 G18 + 0x7C080000, // 0001 CALL R2 0 + 0x600C0010, // 0002 GETGBL R3 G16 + 0x88100100, // 0003 GETMBR R4 R0 K0 + 0x7C0C0200, // 0004 CALL R3 1 + 0xA8020011, // 0005 EXBLK 0 #0018 + 0x5C100600, // 0006 MOVE R4 R3 + 0x7C100000, // 0007 CALL R4 0 + 0x8C140901, // 0008 GETMET R5 R4 K1 + 0x7C140200, // 0009 CALL R5 1 + 0x78060002, // 000A JMPF R1 #000E + 0x1C180B02, // 000B EQ R6 R5 K2 + 0x781A0000, // 000C JMPF R6 #000E + 0x7001FFF7, // 000D JMP #0006 + 0x8C180503, // 000E GETMET R6 R2 K3 + 0x5C200A00, // 000F MOVE R8 R5 + 0x7C180400, // 0010 CALL R6 2 + 0x4C1C0000, // 0011 LDNIL R7 + 0x1C180C07, // 0012 EQ R6 R6 R7 + 0x781A0002, // 0013 JMPF R6 #0017 + 0x8C180504, // 0014 GETMET R6 R2 K4 + 0x5C200A00, // 0015 MOVE R8 R5 + 0x7C180400, // 0016 CALL R6 2 + 0x7001FFED, // 0017 JMP #0006 + 0x580C0005, // 0018 LDCONST R3 K5 + 0xAC0C0200, // 0019 CATCH R3 1 0 + 0xB0080000, // 001A RAISE 2 R0 R0 + 0x80040400, // 001B RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: _start_udp +********************************************************************/ +be_local_closure(Matter_Device__start_udp, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(msg_received), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x680C0000, // 0000 GETUPV R3 U0 + 0x8C0C0700, // 0001 GETMET R3 R3 K0 + 0x5C140000, // 0002 MOVE R5 R0 + 0x5C180200, // 0003 MOVE R6 R1 + 0x5C1C0400, // 0004 MOVE R7 R2 + 0x7C0C0800, // 0005 CALL R3 4 + 0x80040600, // 0006 RET 1 R3 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(udp_server), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(log), + /* K3 */ be_nested_str_weak(MTR_X3A_X20Starting_X20UDP_X20server_X20on_X20port_X3A_X20), + /* K4 */ be_const_int(2), + /* K5 */ be_nested_str_weak(matter), + /* K6 */ be_nested_str_weak(UDPServer), + /* K7 */ be_nested_str_weak(), + /* K8 */ be_nested_str_weak(start), + }), + be_str_weak(_start_udp), + &be_const_str_solidified, + ( &(const binstruction[28]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A0000, // 0001 JMPF R2 #0003 + 0x80000400, // 0002 RET 0 + 0x4C080000, // 0003 LDNIL R2 + 0x1C080202, // 0004 EQ R2 R1 R2 + 0x780A0000, // 0005 JMPF R2 #0007 + 0x540615A3, // 0006 LDINT R1 5540 + 0xB80A0200, // 0007 GETNGBL R2 K1 + 0x8C080502, // 0008 GETMET R2 R2 K2 + 0x60100008, // 0009 GETGBL R4 G8 + 0x5C140200, // 000A MOVE R5 R1 + 0x7C100200, // 000B CALL R4 1 + 0x00120604, // 000C ADD R4 K3 R4 + 0x58140004, // 000D LDCONST R5 K4 + 0x7C080600, // 000E CALL R2 3 + 0xB80A0A00, // 000F GETNGBL R2 K5 + 0x8C080506, // 0010 GETMET R2 R2 K6 + 0x5C100000, // 0011 MOVE R4 R0 + 0x58140007, // 0012 LDCONST R5 K7 + 0x5C180200, // 0013 MOVE R6 R1 + 0x7C080800, // 0014 CALL R2 4 + 0x90020002, // 0015 SETMBR R0 K0 R2 + 0x88080100, // 0016 GETMBR R2 R0 K0 + 0x8C080508, // 0017 GETMET R2 R2 K8 + 0x84100000, // 0018 CLOSURE R4 P0 + 0x7C080400, // 0019 CALL R2 2 + 0xA0000000, // 001A CLOSE R0 + 0x80000000, // 001B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: start_basic_commissioning +********************************************************************/ +be_local_closure(Matter_Device_start_basic_commissioning, /* name */ + be_nested_proto( + 13, /* nstack */ + 8, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 2]) { + be_nested_proto( + 4, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(mdns_announce_PASE), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(remove_rule), + /* K3 */ be_nested_str_weak(Wifi_X23Connected), + }), + be_str_weak(_anonymous_), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x7C000200, // 0002 CALL R0 1 + 0xB8020200, // 0003 GETNGBL R0 K1 + 0x8C000102, // 0004 GETMET R0 R0 K2 + 0x58080003, // 0005 LDCONST R2 K3 + 0x580C0000, // 0006 LDCONST R3 K0 + 0x7C000600, // 0007 CALL R0 3 + 0x80000000, // 0008 RET 0 + }) + ), + be_nested_proto( + 4, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(mdns_announce_PASE), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(remove_rule), + /* K3 */ be_nested_str_weak(Eth_X23Connected), + }), + be_str_weak(_anonymous_), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x7C000200, // 0002 CALL R0 1 + 0xB8020200, // 0003 GETNGBL R0 K1 + 0x8C000102, // 0004 GETMET R0 R0 K2 + 0x58080003, // 0005 LDCONST R2 K3 + 0x580C0000, // 0006 LDCONST R3 K0 + 0x7C000600, // 0007 CALL R0 3 + 0x80000000, // 0008 RET 0 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[16]) { /* constants */ + /* K0 */ be_nested_str_weak(commissioning_open), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(millis), + /* K3 */ be_nested_str_weak(commissioning_iterations), + /* K4 */ be_nested_str_weak(commissioning_discriminator), + /* K5 */ be_nested_str_weak(commissioning_salt), + /* K6 */ be_nested_str_weak(commissioning_w0), + /* K7 */ be_nested_str_weak(commissioning_L), + /* K8 */ be_nested_str_weak(commissioning_admin_fabric), + /* K9 */ be_nested_str_weak(wifi), + /* K10 */ be_nested_str_weak(up), + /* K11 */ be_nested_str_weak(eth), + /* K12 */ be_nested_str_weak(mdns_announce_PASE), + /* K13 */ be_nested_str_weak(add_rule), + /* K14 */ be_nested_str_weak(Wifi_X23Connected), + /* K15 */ be_nested_str_weak(Eth_X23Connected), + }), + be_str_weak(start_basic_commissioning), + &be_const_str_solidified, + ( &(const binstruction[40]) { /* code */ + 0xB8220200, // 0000 GETNGBL R8 K1 + 0x8C201102, // 0001 GETMET R8 R8 K2 + 0x7C200200, // 0002 CALL R8 1 + 0x542603E7, // 0003 LDINT R9 1000 + 0x08240209, // 0004 MUL R9 R1 R9 + 0x00201009, // 0005 ADD R8 R8 R9 + 0x90020008, // 0006 SETMBR R0 K0 R8 + 0x90020602, // 0007 SETMBR R0 K3 R2 + 0x90020803, // 0008 SETMBR R0 K4 R3 + 0x90020A04, // 0009 SETMBR R0 K5 R4 + 0x90020C05, // 000A SETMBR R0 K6 R5 + 0x90020E06, // 000B SETMBR R0 K7 R6 + 0x90021007, // 000C SETMBR R0 K8 R7 + 0xB8220200, // 000D GETNGBL R8 K1 + 0x8C201109, // 000E GETMET R8 R8 K9 + 0x7C200200, // 000F CALL R8 1 + 0x9420110A, // 0010 GETIDX R8 R8 K10 + 0x74220004, // 0011 JMPT R8 #0017 + 0xB8220200, // 0012 GETNGBL R8 K1 + 0x8C20110B, // 0013 GETMET R8 R8 K11 + 0x7C200200, // 0014 CALL R8 1 + 0x9420110A, // 0015 GETIDX R8 R8 K10 + 0x78220002, // 0016 JMPF R8 #001A + 0x8C20010C, // 0017 GETMET R8 R0 K12 + 0x7C200200, // 0018 CALL R8 1 + 0x7002000B, // 0019 JMP #0026 + 0xB8220200, // 001A GETNGBL R8 K1 + 0x8C20110D, // 001B GETMET R8 R8 K13 + 0x5828000E, // 001C LDCONST R10 K14 + 0x842C0000, // 001D CLOSURE R11 P0 + 0x5830000C, // 001E LDCONST R12 K12 + 0x7C200800, // 001F CALL R8 4 + 0xB8220200, // 0020 GETNGBL R8 K1 + 0x8C20110D, // 0021 GETMET R8 R8 K13 + 0x5828000F, // 0022 LDCONST R10 K15 + 0x842C0001, // 0023 CLOSURE R11 P1 + 0x5830000C, // 0024 LDCONST R12 K12 + 0x7C200800, // 0025 CALL R8 4 + 0xA0000000, // 0026 CLOSE R0 + 0x80000000, // 0027 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: bridge_remove_endpoint +********************************************************************/ +be_local_closure(Matter_Device_bridge_remove_endpoint, /* name */ + be_nested_proto( + 11, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[18]) { /* constants */ + /* K0 */ be_nested_str_weak(json), + /* K1 */ be_nested_str_weak(plugins_config), + /* K2 */ be_nested_str_weak(contains), + /* K3 */ be_nested_str_weak(tasmota), + /* K4 */ be_nested_str_weak(log), + /* K5 */ be_nested_str_weak(MTR_X3A_X20Cannot_X20remove_X20an_X20enpoint_X20not_X20configured_X3A_X20), + /* K6 */ be_const_int(3), + /* K7 */ be_nested_str_weak(MTR_X3A_X20deleting_X20endpoint_X20_X3D_X20_X25i), + /* K8 */ be_const_int(2), + /* K9 */ be_nested_str_weak(remove), + /* K10 */ be_nested_str_weak(plugins_persist), + /* K11 */ be_const_int(0), + /* K12 */ be_nested_str_weak(plugins), + /* K13 */ be_nested_str_weak(get_endpoint), + /* K14 */ be_const_int(1), + /* K15 */ be_nested_str_weak(clean_remotes), + /* K16 */ be_nested_str_weak(save_param), + /* K17 */ be_nested_str_weak(signal_endpoints_changed), + }), + be_str_weak(bridge_remove_endpoint), + &be_const_str_solidified, + ( &(const binstruction[58]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0x600C0008, // 0001 GETGBL R3 G8 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C0C0200, // 0003 CALL R3 1 + 0x4C100000, // 0004 LDNIL R4 + 0x4C140000, // 0005 LDNIL R5 + 0x88180101, // 0006 GETMBR R6 R0 K1 + 0x8C180D02, // 0007 GETMET R6 R6 K2 + 0x5C200600, // 0008 MOVE R8 R3 + 0x7C180400, // 0009 CALL R6 2 + 0x741A0005, // 000A JMPT R6 #0011 + 0xB81A0600, // 000B GETNGBL R6 K3 + 0x8C180D04, // 000C GETMET R6 R6 K4 + 0x00220A03, // 000D ADD R8 K5 R3 + 0x58240006, // 000E LDCONST R9 K6 + 0x7C180600, // 000F CALL R6 3 + 0x80000C00, // 0010 RET 0 + 0xB81A0600, // 0011 GETNGBL R6 K3 + 0x8C180D04, // 0012 GETMET R6 R6 K4 + 0x60200018, // 0013 GETGBL R8 G24 + 0x58240007, // 0014 LDCONST R9 K7 + 0x5C280200, // 0015 MOVE R10 R1 + 0x7C200400, // 0016 CALL R8 2 + 0x58240008, // 0017 LDCONST R9 K8 + 0x7C180600, // 0018 CALL R6 3 + 0x88180101, // 0019 GETMBR R6 R0 K1 + 0x8C180D09, // 001A GETMET R6 R6 K9 + 0x5C200600, // 001B MOVE R8 R3 + 0x7C180400, // 001C CALL R6 2 + 0x50180200, // 001D LDBOOL R6 1 0 + 0x90021406, // 001E SETMBR R0 K10 R6 + 0x5818000B, // 001F LDCONST R6 K11 + 0x601C000C, // 0020 GETGBL R7 G12 + 0x8820010C, // 0021 GETMBR R8 R0 K12 + 0x7C1C0200, // 0022 CALL R7 1 + 0x141C0C07, // 0023 LT R7 R6 R7 + 0x781E000D, // 0024 JMPF R7 #0033 + 0x881C010C, // 0025 GETMBR R7 R0 K12 + 0x941C0E06, // 0026 GETIDX R7 R7 R6 + 0x8C1C0F0D, // 0027 GETMET R7 R7 K13 + 0x7C1C0200, // 0028 CALL R7 1 + 0x1C1C0207, // 0029 EQ R7 R1 R7 + 0x781E0005, // 002A JMPF R7 #0031 + 0x881C010C, // 002B GETMBR R7 R0 K12 + 0x8C1C0F09, // 002C GETMET R7 R7 K9 + 0x5C240C00, // 002D MOVE R9 R6 + 0x7C1C0400, // 002E CALL R7 2 + 0x70020002, // 002F JMP #0033 + 0x70020000, // 0030 JMP #0032 + 0x00180D0E, // 0031 ADD R6 R6 K14 + 0x7001FFEC, // 0032 JMP #0020 + 0x8C1C010F, // 0033 GETMET R7 R0 K15 + 0x7C1C0200, // 0034 CALL R7 1 + 0x8C1C0110, // 0035 GETMET R7 R0 K16 + 0x7C1C0200, // 0036 CALL R7 1 + 0x8C1C0111, // 0037 GETMET R7 R0 K17 + 0x7C1C0200, // 0038 CALL R7 1 + 0x80000000, // 0039 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: start +********************************************************************/ +be_local_closure(Matter_Device_start, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 2, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(_trigger_read_sensors), + }), + be_str_weak(_anonymous_), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x7C000200, // 0002 CALL R0 1 + 0x80000000, // 0003 RET 0 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(started), + /* K1 */ be_nested_str_weak(autoconf_device), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(add_cron), + /* K4 */ be_nested_str_weak(_X2A_X2F30_X20_X2A_X20_X2A_X20_X2A_X20_X2A_X20_X2A), + /* K5 */ be_nested_str_weak(matter_sensors_30s), + /* K6 */ be_nested_str_weak(_start_udp), + /* K7 */ be_nested_str_weak(UDP_PORT), + /* K8 */ be_nested_str_weak(start_mdns_announce_hostnames), + }), + be_str_weak(start), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x78060000, // 0001 JMPF R1 #0003 + 0x80000200, // 0002 RET 0 + 0x8C040101, // 0003 GETMET R1 R0 K1 + 0x7C040200, // 0004 CALL R1 1 + 0xB8060400, // 0005 GETNGBL R1 K2 + 0x8C040303, // 0006 GETMET R1 R1 K3 + 0x580C0004, // 0007 LDCONST R3 K4 + 0x84100000, // 0008 CLOSURE R4 P0 + 0x58140005, // 0009 LDCONST R5 K5 + 0x7C040800, // 000A CALL R1 4 + 0x8C040106, // 000B GETMET R1 R0 K6 + 0x880C0107, // 000C GETMBR R3 R0 K7 + 0x7C040400, // 000D CALL R1 2 + 0x8C040108, // 000E GETMET R1 R0 K8 + 0x7C040200, // 000F CALL R1 1 + 0x50040200, // 0010 LDBOOL R1 1 0 + 0x90020001, // 0011 SETMBR R0 K0 R1 + 0xA0000000, // 0012 CLOSE R0 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: stop_basic_commissioning +********************************************************************/ +be_local_closure(Matter_Device_stop_basic_commissioning, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(is_root_commissioning_open), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(publish_result), + /* K3 */ be_nested_str_weak(_X7B_X22Matter_X22_X3A_X7B_X22Commissioning_X22_X3A0_X7D_X7D), + /* K4 */ be_nested_str_weak(Matter), + /* K5 */ be_nested_str_weak(commissioning_open), + /* K6 */ be_nested_str_weak(mdns_remove_PASE), + /* K7 */ be_nested_str_weak(commissioning_iterations), + /* K8 */ be_nested_str_weak(commissioning_discriminator), + /* K9 */ be_nested_str_weak(commissioning_salt), + /* K10 */ be_nested_str_weak(commissioning_w0), + /* K11 */ be_nested_str_weak(commissioning_L), + /* K12 */ be_nested_str_weak(commissioning_admin_fabric), + }), + be_str_weak(stop_basic_commissioning), + &be_const_str_solidified, + ( &(const binstruction[25]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x78060004, // 0002 JMPF R1 #0008 + 0xB8060200, // 0003 GETNGBL R1 K1 + 0x8C040302, // 0004 GETMET R1 R1 K2 + 0x580C0003, // 0005 LDCONST R3 K3 + 0x58100004, // 0006 LDCONST R4 K4 + 0x7C040600, // 0007 CALL R1 3 + 0x4C040000, // 0008 LDNIL R1 + 0x90020A01, // 0009 SETMBR R0 K5 R1 + 0x8C040106, // 000A GETMET R1 R0 K6 + 0x7C040200, // 000B CALL R1 1 + 0x4C040000, // 000C LDNIL R1 + 0x90020E01, // 000D SETMBR R0 K7 R1 + 0x4C040000, // 000E LDNIL R1 + 0x90021001, // 000F SETMBR R0 K8 R1 + 0x4C040000, // 0010 LDNIL R1 + 0x90021201, // 0011 SETMBR R0 K9 R1 + 0x4C040000, // 0012 LDNIL R1 + 0x90021401, // 0013 SETMBR R0 K10 R1 + 0x4C040000, // 0014 LDNIL R1 + 0x90021601, // 0015 SETMBR R0 K11 R1 + 0x4C040000, // 0016 LDNIL R1 + 0x90021801, // 0017 SETMBR R0 K12 R1 + 0x80000000, // 0018 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Device_init, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 2]) { + be_nested_proto( + 4, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(start), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(remove_rule), + /* K3 */ be_nested_str_weak(Wifi_X23Connected), + /* K4 */ be_nested_str_weak(matter_start), + }), + be_str_weak(_anonymous_), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x7C000200, // 0002 CALL R0 1 + 0xB8020200, // 0003 GETNGBL R0 K1 + 0x8C000102, // 0004 GETMET R0 R0 K2 + 0x58080003, // 0005 LDCONST R2 K3 + 0x580C0004, // 0006 LDCONST R3 K4 + 0x7C000600, // 0007 CALL R0 3 + 0x80000000, // 0008 RET 0 + }) + ), + be_nested_proto( + 4, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(start), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(remove_rule), + /* K3 */ be_nested_str_weak(Eth_X23Connected), + /* K4 */ be_nested_str_weak(matter_start), + }), + be_str_weak(_anonymous_), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x7C000200, // 0002 CALL R0 1 + 0xB8020200, // 0003 GETNGBL R0 K1 + 0x8C000102, // 0004 GETMET R0 R0 K2 + 0x58080003, // 0005 LDCONST R2 K3 + 0x580C0004, // 0006 LDCONST R3 K4 + 0x7C000600, // 0007 CALL R0 3 + 0x80000000, // 0008 RET 0 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[46]) { /* constants */ + /* K0 */ be_nested_str_weak(crypto), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(get_option), + /* K3 */ be_nested_str_weak(matter), + /* K4 */ be_nested_str_weak(MATTER_OPTION), + /* K5 */ be_nested_str_weak(UI), + /* K6 */ be_nested_str_weak(profiler), + /* K7 */ be_nested_str_weak(Profiler), + /* K8 */ be_nested_str_weak(started), + /* K9 */ be_nested_str_weak(tick), + /* K10 */ be_const_int(0), + /* K11 */ be_nested_str_weak(plugins), + /* K12 */ be_nested_str_weak(plugins_persist), + /* K13 */ be_nested_str_weak(plugins_classes), + /* K14 */ be_nested_str_weak(plugins_config_remotes), + /* K15 */ be_nested_str_weak(register_native_classes), + /* K16 */ be_nested_str_weak(vendorid), + /* K17 */ be_nested_str_weak(VENDOR_ID), + /* K18 */ be_nested_str_weak(productid), + /* K19 */ be_nested_str_weak(PRODUCT_ID), + /* K20 */ be_nested_str_weak(root_iterations), + /* K21 */ be_nested_str_weak(PBKDF_ITERATIONS), + /* K22 */ be_nested_str_weak(next_ep), + /* K23 */ be_const_int(1), + /* K24 */ be_nested_str_weak(root_salt), + /* K25 */ be_nested_str_weak(random), + /* K26 */ be_nested_str_weak(ipv4only), + /* K27 */ be_nested_str_weak(disable_bridge_mode), + /* K28 */ be_nested_str_weak(load_param), + /* K29 */ be_nested_str_weak(sessions), + /* K30 */ be_nested_str_weak(Session_Store), + /* K31 */ be_nested_str_weak(load_fabrics), + /* K32 */ be_nested_str_weak(message_handler), + /* K33 */ be_nested_str_weak(MessageHandler), + /* K34 */ be_nested_str_weak(ui), + /* K35 */ be_nested_str_weak(wifi), + /* K36 */ be_nested_str_weak(up), + /* K37 */ be_nested_str_weak(eth), + /* K38 */ be_nested_str_weak(start), + /* K39 */ be_nested_str_weak(add_rule), + /* K40 */ be_nested_str_weak(Wifi_X23Connected), + /* K41 */ be_nested_str_weak(matter_start), + /* K42 */ be_nested_str_weak(Eth_X23Connected), + /* K43 */ be_nested_str_weak(_init_basic_commissioning), + /* K44 */ be_nested_str_weak(add_driver), + /* K45 */ be_nested_str_weak(register_commands), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[112]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0xB80A0200, // 0001 GETNGBL R2 K1 + 0x8C080502, // 0002 GETMET R2 R2 K2 + 0xB8120600, // 0003 GETNGBL R4 K3 + 0x88100904, // 0004 GETMBR R4 R4 K4 + 0x7C080400, // 0005 CALL R2 2 + 0x740A0004, // 0006 JMPT R2 #000C + 0xB80A0600, // 0007 GETNGBL R2 K3 + 0x8C080505, // 0008 GETMET R2 R2 K5 + 0x5C100000, // 0009 MOVE R4 R0 + 0x7C080400, // 000A CALL R2 2 + 0x80000400, // 000B RET 0 + 0xB80A0600, // 000C GETNGBL R2 K3 + 0xB80E0600, // 000D GETNGBL R3 K3 + 0x8C0C0707, // 000E GETMET R3 R3 K7 + 0x7C0C0200, // 000F CALL R3 1 + 0x900A0C03, // 0010 SETMBR R2 K6 R3 + 0x50080000, // 0011 LDBOOL R2 0 0 + 0x90021002, // 0012 SETMBR R0 K8 R2 + 0x9002130A, // 0013 SETMBR R0 K9 K10 + 0x60080012, // 0014 GETGBL R2 G18 + 0x7C080000, // 0015 CALL R2 0 + 0x90021602, // 0016 SETMBR R0 K11 R2 + 0x50080000, // 0017 LDBOOL R2 0 0 + 0x90021802, // 0018 SETMBR R0 K12 R2 + 0x60080013, // 0019 GETGBL R2 G19 + 0x7C080000, // 001A CALL R2 0 + 0x90021A02, // 001B SETMBR R0 K13 R2 + 0x60080013, // 001C GETGBL R2 G19 + 0x7C080000, // 001D CALL R2 0 + 0x90021C02, // 001E SETMBR R0 K14 R2 + 0x8C08010F, // 001F GETMET R2 R0 K15 + 0x7C080200, // 0020 CALL R2 1 + 0x88080111, // 0021 GETMBR R2 R0 K17 + 0x90022002, // 0022 SETMBR R0 K16 R2 + 0x88080113, // 0023 GETMBR R2 R0 K19 + 0x90022402, // 0024 SETMBR R0 K18 R2 + 0x88080115, // 0025 GETMBR R2 R0 K21 + 0x90022802, // 0026 SETMBR R0 K20 R2 + 0x90022D17, // 0027 SETMBR R0 K22 K23 + 0x8C080319, // 0028 GETMET R2 R1 K25 + 0x5412000F, // 0029 LDINT R4 16 + 0x7C080400, // 002A CALL R2 2 + 0x90023002, // 002B SETMBR R0 K24 R2 + 0x50080000, // 002C LDBOOL R2 0 0 + 0x90023402, // 002D SETMBR R0 K26 R2 + 0x50080000, // 002E LDBOOL R2 0 0 + 0x90023602, // 002F SETMBR R0 K27 R2 + 0x8C08011C, // 0030 GETMET R2 R0 K28 + 0x7C080200, // 0031 CALL R2 1 + 0xB80A0600, // 0032 GETNGBL R2 K3 + 0x8C08051E, // 0033 GETMET R2 R2 K30 + 0x5C100000, // 0034 MOVE R4 R0 + 0x7C080400, // 0035 CALL R2 2 + 0x90023A02, // 0036 SETMBR R0 K29 R2 + 0x8808011D, // 0037 GETMBR R2 R0 K29 + 0x8C08051F, // 0038 GETMET R2 R2 K31 + 0x7C080200, // 0039 CALL R2 1 + 0xB80A0600, // 003A GETNGBL R2 K3 + 0x8C080521, // 003B GETMET R2 R2 K33 + 0x5C100000, // 003C MOVE R4 R0 + 0x7C080400, // 003D CALL R2 2 + 0x90024002, // 003E SETMBR R0 K32 R2 + 0xB80A0600, // 003F GETNGBL R2 K3 + 0x8C080505, // 0040 GETMET R2 R2 K5 + 0x5C100000, // 0041 MOVE R4 R0 + 0x7C080400, // 0042 CALL R2 2 + 0x90024402, // 0043 SETMBR R0 K34 R2 + 0xB80A0200, // 0044 GETNGBL R2 K1 + 0x8C080523, // 0045 GETMET R2 R2 K35 + 0x7C080200, // 0046 CALL R2 1 + 0x94080524, // 0047 GETIDX R2 R2 K36 + 0x740A0004, // 0048 JMPT R2 #004E + 0xB80A0200, // 0049 GETNGBL R2 K1 + 0x8C080525, // 004A GETMET R2 R2 K37 + 0x7C080200, // 004B CALL R2 1 + 0x94080524, // 004C GETIDX R2 R2 K36 + 0x780A0001, // 004D JMPF R2 #0050 + 0x8C080126, // 004E GETMET R2 R0 K38 + 0x7C080200, // 004F CALL R2 1 + 0xB80A0200, // 0050 GETNGBL R2 K1 + 0x8C080523, // 0051 GETMET R2 R2 K35 + 0x7C080200, // 0052 CALL R2 1 + 0x94080524, // 0053 GETIDX R2 R2 K36 + 0x740A0005, // 0054 JMPT R2 #005B + 0xB80A0200, // 0055 GETNGBL R2 K1 + 0x8C080527, // 0056 GETMET R2 R2 K39 + 0x58100028, // 0057 LDCONST R4 K40 + 0x84140000, // 0058 CLOSURE R5 P0 + 0x58180029, // 0059 LDCONST R6 K41 + 0x7C080800, // 005A CALL R2 4 + 0xB80A0200, // 005B GETNGBL R2 K1 + 0x8C080525, // 005C GETMET R2 R2 K37 + 0x7C080200, // 005D CALL R2 1 + 0x94080524, // 005E GETIDX R2 R2 K36 + 0x740A0005, // 005F JMPT R2 #0066 + 0xB80A0200, // 0060 GETNGBL R2 K1 + 0x8C080527, // 0061 GETMET R2 R2 K39 + 0x5810002A, // 0062 LDCONST R4 K42 + 0x84140001, // 0063 CLOSURE R5 P1 + 0x58180029, // 0064 LDCONST R6 K41 + 0x7C080800, // 0065 CALL R2 4 + 0x8C08012B, // 0066 GETMET R2 R0 K43 + 0x7C080200, // 0067 CALL R2 1 + 0xB80A0200, // 0068 GETNGBL R2 K1 + 0x8C08052C, // 0069 GETMET R2 R2 K44 + 0x5C100000, // 006A MOVE R4 R0 + 0x7C080400, // 006B CALL R2 2 + 0x8C08012D, // 006C GETMET R2 R0 K45 + 0x7C080200, // 006D CALL R2 1 + 0xA0000000, // 006E CLOSE R0 + 0x80000000, // 006F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: adjust_next_ep +********************************************************************/ +be_local_closure(Matter_Device_adjust_next_ep, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(plugins_config), + /* K1 */ be_nested_str_weak(keys), + /* K2 */ be_nested_str_weak(next_ep), + /* K3 */ be_const_int(1), + /* K4 */ be_nested_str_weak(stop_iteration), + }), + be_str_weak(adjust_next_ep), + &be_const_str_solidified, + ( &(const binstruction[21]) { /* code */ + 0x60040010, // 0000 GETGBL R1 G16 + 0x88080100, // 0001 GETMBR R2 R0 K0 + 0x8C080501, // 0002 GETMET R2 R2 K1 + 0x7C080200, // 0003 CALL R2 1 + 0x7C040200, // 0004 CALL R1 1 + 0xA802000A, // 0005 EXBLK 0 #0011 + 0x5C080200, // 0006 MOVE R2 R1 + 0x7C080000, // 0007 CALL R2 0 + 0x600C0009, // 0008 GETGBL R3 G9 + 0x5C100400, // 0009 MOVE R4 R2 + 0x7C0C0200, // 000A CALL R3 1 + 0x88100102, // 000B GETMBR R4 R0 K2 + 0x28100604, // 000C GE R4 R3 R4 + 0x78120001, // 000D JMPF R4 #0010 + 0x00100703, // 000E ADD R4 R3 K3 + 0x90020404, // 000F SETMBR R0 K2 R4 + 0x7001FFF4, // 0010 JMP #0006 + 0x58040004, // 0011 LDCONST R1 K4 + 0xAC040200, // 0012 CATCH R1 1 0 + 0xB0080000, // 0013 RAISE 2 R0 R0 + 0x80000000, // 0014 RET 0 }) ) ); @@ -1154,40 +2707,40 @@ be_local_closure(Matter_Device_invoke_request, /* name */ /******************************************************************** -** Solidified function: event_fabrics_saved +** Solidified function: MtrJoin ********************************************************************/ -be_local_closure(Matter_Device_event_fabrics_saved, /* name */ +be_local_closure(Matter_Device_MtrJoin, /* name */ be_nested_proto( - 3, /* nstack */ - 1, /* argc */ + 8, /* nstack */ + 5, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(sessions), - /* K1 */ be_nested_str_weak(count_active_fabrics), - /* K2 */ be_const_int(0), - /* K3 */ be_nested_str_weak(plugins_persist), - /* K4 */ be_nested_str_weak(save_param), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(start_root_basic_commissioning), + /* K1 */ be_nested_str_weak(stop_basic_commissioning), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(resp_cmnd_done), }), - be_str_weak(event_fabrics_saved), + be_str_weak(MtrJoin), &be_const_str_solidified, - ( &(const binstruction[12]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x24040302, // 0003 GT R1 R1 K2 - 0x78060005, // 0004 JMPF R1 #000B - 0x88040103, // 0005 GETMBR R1 R0 K3 - 0x74060003, // 0006 JMPT R1 #000B - 0x50040200, // 0007 LDBOOL R1 1 0 - 0x90020601, // 0008 SETMBR R0 K3 R1 - 0x8C040104, // 0009 GETMET R1 R0 K4 - 0x7C040200, // 000A CALL R1 1 - 0x80000000, // 000B RET 0 + ( &(const binstruction[13]) { /* code */ + 0x60140009, // 0000 GETGBL R5 G9 + 0x5C180600, // 0001 MOVE R6 R3 + 0x7C140200, // 0002 CALL R5 1 + 0x78160002, // 0003 JMPF R5 #0007 + 0x8C180100, // 0004 GETMET R6 R0 K0 + 0x7C180200, // 0005 CALL R6 1 + 0x70020001, // 0006 JMP #0009 + 0x8C180101, // 0007 GETMET R6 R0 K1 + 0x7C180200, // 0008 CALL R6 1 + 0xB81A0400, // 0009 GETNGBL R6 K2 + 0x8C180D03, // 000A GETMET R6 R6 K3 + 0x7C180200, // 000B CALL R6 1 + 0x80000000, // 000C RET 0 }) ) ); @@ -1195,81 +2748,29 @@ be_local_closure(Matter_Device_event_fabrics_saved, /* name */ /******************************************************************** -** Solidified function: sort_distinct +** Solidified function: every_50ms ********************************************************************/ -be_local_closure(Matter_Device_sort_distinct, /* name */ +be_local_closure(Matter_Device_every_50ms, /* name */ be_nested_proto( - 7, /* nstack */ + 2, /* nstack */ 1, /* argc */ - 4, /* varg */ + 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_const_class(be_class_Matter_Device), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(tick), /* K1 */ be_const_int(1), - /* K2 */ be_const_int(0), - /* K3 */ be_nested_str_weak(stop_iteration), - /* K4 */ be_nested_str_weak(remove), }), - be_str_weak(sort_distinct), + be_str_weak(every_50ms), &be_const_str_solidified, - ( &(const binstruction[53]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0x60080010, // 0001 GETGBL R2 G16 - 0x600C000C, // 0002 GETGBL R3 G12 - 0x5C100000, // 0003 MOVE R4 R0 - 0x7C0C0200, // 0004 CALL R3 1 - 0x040C0701, // 0005 SUB R3 R3 K1 - 0x400E0203, // 0006 CONNECT R3 K1 R3 - 0x7C080200, // 0007 CALL R2 1 - 0xA8020010, // 0008 EXBLK 0 #001A - 0x5C0C0400, // 0009 MOVE R3 R2 - 0x7C0C0000, // 000A CALL R3 0 - 0x94100003, // 000B GETIDX R4 R0 R3 - 0x5C140600, // 000C MOVE R5 R3 - 0x24180B02, // 000D GT R6 R5 K2 - 0x781A0008, // 000E JMPF R6 #0018 - 0x04180B01, // 000F SUB R6 R5 K1 - 0x94180006, // 0010 GETIDX R6 R0 R6 - 0x24180C04, // 0011 GT R6 R6 R4 - 0x781A0004, // 0012 JMPF R6 #0018 - 0x04180B01, // 0013 SUB R6 R5 K1 - 0x94180006, // 0014 GETIDX R6 R0 R6 - 0x98000A06, // 0015 SETIDX R0 R5 R6 - 0x04140B01, // 0016 SUB R5 R5 K1 - 0x7001FFF4, // 0017 JMP #000D - 0x98000A04, // 0018 SETIDX R0 R5 R4 - 0x7001FFEE, // 0019 JMP #0009 - 0x58080003, // 001A LDCONST R2 K3 - 0xAC080200, // 001B CATCH R2 1 0 - 0xB0080000, // 001C RAISE 2 R0 R0 - 0x58080001, // 001D LDCONST R2 K1 - 0x600C000C, // 001E GETGBL R3 G12 - 0x5C100000, // 001F MOVE R4 R0 - 0x7C0C0200, // 0020 CALL R3 1 - 0x180C0701, // 0021 LE R3 R3 K1 - 0x780E0000, // 0022 JMPF R3 #0024 - 0x80040000, // 0023 RET 1 R0 - 0x940C0102, // 0024 GETIDX R3 R0 K2 - 0x6010000C, // 0025 GETGBL R4 G12 - 0x5C140000, // 0026 MOVE R5 R0 - 0x7C100200, // 0027 CALL R4 1 - 0x14100404, // 0028 LT R4 R2 R4 - 0x78120009, // 0029 JMPF R4 #0034 - 0x94100002, // 002A GETIDX R4 R0 R2 - 0x1C100803, // 002B EQ R4 R4 R3 - 0x78120003, // 002C JMPF R4 #0031 - 0x8C100104, // 002D GETMET R4 R0 K4 - 0x5C180400, // 002E MOVE R6 R2 - 0x7C100400, // 002F CALL R4 2 - 0x70020001, // 0030 JMP #0033 - 0x940C0002, // 0031 GETIDX R3 R0 R2 - 0x00080501, // 0032 ADD R2 R2 K1 - 0x7001FFF0, // 0033 JMP #0025 - 0x80040000, // 0034 RET 1 R0 + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x00040301, // 0001 ADD R1 R1 K1 + 0x90020001, // 0002 SETMBR R0 K0 R1 + 0x80000000, // 0003 RET 0 }) ) ); @@ -1359,11 +2860,11 @@ be_local_closure(Matter_Device_k2l_num, /* name */ /******************************************************************** -** Solidified function: mdns_announce_op_discovery +** Solidified function: autoconf_sensors_list ********************************************************************/ -be_local_closure(Matter_Device_mdns_announce_op_discovery, /* name */ +be_local_closure(Matter_Device_autoconf_sensors_list, /* name */ be_nested_proto( - 15, /* nstack */ + 10, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1371,162 +2872,148 @@ be_local_closure(Matter_Device_mdns_announce_op_discovery, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[29]) { /* constants */ - /* K0 */ be_nested_str_weak(mdns), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(get_device_id), - /* K3 */ be_nested_str_weak(copy), - /* K4 */ be_nested_str_weak(reverse), - /* K5 */ be_nested_str_weak(get_fabric_compressed), - /* K6 */ be_nested_str_weak(tohex), - /* K7 */ be_nested_str_weak(_X2D), - /* K8 */ be_nested_str_weak(tasmota), - /* K9 */ be_nested_str_weak(log), - /* K10 */ be_nested_str_weak(MTR_X3A_X20Operational_X20Discovery_X20node_X20_X3D_X20), - /* K11 */ be_const_int(2), - /* K12 */ be_nested_str_weak(eth), - /* K13 */ be_nested_str_weak(find), - /* K14 */ be_nested_str_weak(up), - /* K15 */ be_nested_str_weak(format), - /* K16 */ be_nested_str_weak(MTR_X3A_X20adding_X20mDNS_X20on_X20_X25s_X20_X27_X25s_X27_X20ptr_X20to_X20_X60_X25s_X2Elocal_X60), - /* K17 */ be_nested_str_weak(hostname_eth), - /* K18 */ be_const_int(3), - /* K19 */ be_nested_str_weak(add_service), - /* K20 */ be_nested_str_weak(_matter), - /* K21 */ be_nested_str_weak(_tcp), - /* K22 */ be_nested_str_weak(_I), - /* K23 */ be_nested_str_weak(MTR_X3A_X20adding_X20subtype_X3A_X20), - /* K24 */ be_nested_str_weak(add_subtype), - /* K25 */ be_nested_str_weak(wifi), - /* K26 */ be_nested_str_weak(hostname_wifi), - /* K27 */ be_nested_str_weak(MTR_X3A_X20Exception), - /* K28 */ be_nested_str_weak(_X7C), + ( &(const bvalue[18]) { /* constants */ + /* K0 */ be_nested_str_weak(k2l), + /* K1 */ be_nested_str_weak(contains), + /* K2 */ be_nested_str_weak(Temperature), + /* K3 */ be_nested_str_weak(_X23Temperature), + /* K4 */ be_nested_str_weak(push), + /* K5 */ be_nested_str_weak(type), + /* K6 */ be_nested_str_weak(temperature), + /* K7 */ be_nested_str_weak(filter), + /* K8 */ be_nested_str_weak(stop_iteration), + /* K9 */ be_nested_str_weak(Pressure), + /* K10 */ be_nested_str_weak(_X23Pressure), + /* K11 */ be_nested_str_weak(pressure), + /* K12 */ be_nested_str_weak(Illuminance), + /* K13 */ be_nested_str_weak(_X23Illuminance), + /* K14 */ be_nested_str_weak(illuminance), + /* K15 */ be_nested_str_weak(Humidity), + /* K16 */ be_nested_str_weak(_X23Humidity), + /* K17 */ be_nested_str_weak(humidity), }), - be_str_weak(mdns_announce_op_discovery), + be_str_weak(autoconf_sensors_list), &be_const_str_solidified, - ( &(const binstruction[122]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0xA40E0200, // 0001 IMPORT R3 K1 - 0xA8020064, // 0002 EXBLK 0 #0068 - 0x8C100302, // 0003 GETMET R4 R1 K2 - 0x7C100200, // 0004 CALL R4 1 - 0x8C100903, // 0005 GETMET R4 R4 K3 - 0x7C100200, // 0006 CALL R4 1 - 0x8C100904, // 0007 GETMET R4 R4 K4 - 0x7C100200, // 0008 CALL R4 1 - 0x8C140305, // 0009 GETMET R5 R1 K5 - 0x7C140200, // 000A CALL R5 1 - 0x8C180B06, // 000B GETMET R6 R5 K6 - 0x7C180200, // 000C CALL R6 1 - 0x00180D07, // 000D ADD R6 R6 K7 - 0x8C1C0906, // 000E GETMET R7 R4 K6 - 0x7C1C0200, // 000F CALL R7 1 - 0x00180C07, // 0010 ADD R6 R6 R7 - 0xB81E1000, // 0011 GETNGBL R7 K8 - 0x8C1C0F09, // 0012 GETMET R7 R7 K9 - 0x00261406, // 0013 ADD R9 K10 R6 - 0x5828000B, // 0014 LDCONST R10 K11 - 0x7C1C0600, // 0015 CALL R7 3 - 0xB81E1000, // 0016 GETNGBL R7 K8 - 0x8C1C0F0C, // 0017 GETMET R7 R7 K12 - 0x7C1C0200, // 0018 CALL R7 1 - 0x8C1C0F0D, // 0019 GETMET R7 R7 K13 - 0x5824000E, // 001A LDCONST R9 K14 - 0x7C1C0400, // 001B CALL R7 2 - 0x781E0020, // 001C JMPF R7 #003E - 0xB81E1000, // 001D GETNGBL R7 K8 - 0x8C1C0F09, // 001E GETMET R7 R7 K9 - 0x8C24070F, // 001F GETMET R9 R3 K15 - 0x582C0010, // 0020 LDCONST R11 K16 - 0x5830000C, // 0021 LDCONST R12 K12 - 0x5C340C00, // 0022 MOVE R13 R6 - 0x88380111, // 0023 GETMBR R14 R0 K17 - 0x7C240A00, // 0024 CALL R9 5 - 0x58280012, // 0025 LDCONST R10 K18 - 0x7C1C0600, // 0026 CALL R7 3 - 0x8C1C0513, // 0027 GETMET R7 R2 K19 - 0x58240014, // 0028 LDCONST R9 K20 - 0x58280015, // 0029 LDCONST R10 K21 - 0x542E15A3, // 002A LDINT R11 5540 - 0x4C300000, // 002B LDNIL R12 - 0x5C340C00, // 002C MOVE R13 R6 - 0x88380111, // 002D GETMBR R14 R0 K17 - 0x7C1C0E00, // 002E CALL R7 7 - 0x8C1C0B06, // 002F GETMET R7 R5 K6 - 0x7C1C0200, // 0030 CALL R7 1 - 0x001E2C07, // 0031 ADD R7 K22 R7 - 0xB8221000, // 0032 GETNGBL R8 K8 - 0x8C201109, // 0033 GETMET R8 R8 K9 - 0x002A2E07, // 0034 ADD R10 K23 R7 - 0x582C0012, // 0035 LDCONST R11 K18 - 0x7C200600, // 0036 CALL R8 3 - 0x8C200518, // 0037 GETMET R8 R2 K24 - 0x58280014, // 0038 LDCONST R10 K20 - 0x582C0015, // 0039 LDCONST R11 K21 - 0x5C300C00, // 003A MOVE R12 R6 - 0x88340111, // 003B GETMBR R13 R0 K17 - 0x5C380E00, // 003C MOVE R14 R7 - 0x7C200C00, // 003D CALL R8 6 - 0xB81E1000, // 003E GETNGBL R7 K8 - 0x8C1C0F19, // 003F GETMET R7 R7 K25 - 0x7C1C0200, // 0040 CALL R7 1 - 0x8C1C0F0D, // 0041 GETMET R7 R7 K13 - 0x5824000E, // 0042 LDCONST R9 K14 - 0x7C1C0400, // 0043 CALL R7 2 - 0x781E0020, // 0044 JMPF R7 #0066 - 0xB81E1000, // 0045 GETNGBL R7 K8 - 0x8C1C0F09, // 0046 GETMET R7 R7 K9 - 0x8C24070F, // 0047 GETMET R9 R3 K15 - 0x582C0010, // 0048 LDCONST R11 K16 - 0x58300019, // 0049 LDCONST R12 K25 - 0x5C340C00, // 004A MOVE R13 R6 - 0x8838011A, // 004B GETMBR R14 R0 K26 - 0x7C240A00, // 004C CALL R9 5 - 0x58280012, // 004D LDCONST R10 K18 - 0x7C1C0600, // 004E CALL R7 3 - 0x8C1C0513, // 004F GETMET R7 R2 K19 - 0x58240014, // 0050 LDCONST R9 K20 - 0x58280015, // 0051 LDCONST R10 K21 - 0x542E15A3, // 0052 LDINT R11 5540 - 0x4C300000, // 0053 LDNIL R12 - 0x5C340C00, // 0054 MOVE R13 R6 - 0x8838011A, // 0055 GETMBR R14 R0 K26 - 0x7C1C0E00, // 0056 CALL R7 7 - 0x8C1C0B06, // 0057 GETMET R7 R5 K6 - 0x7C1C0200, // 0058 CALL R7 1 - 0x001E2C07, // 0059 ADD R7 K22 R7 - 0xB8221000, // 005A GETNGBL R8 K8 - 0x8C201109, // 005B GETMET R8 R8 K9 - 0x002A2E07, // 005C ADD R10 K23 R7 - 0x582C0012, // 005D LDCONST R11 K18 - 0x7C200600, // 005E CALL R8 3 - 0x8C200518, // 005F GETMET R8 R2 K24 - 0x58280014, // 0060 LDCONST R10 K20 - 0x582C0015, // 0061 LDCONST R11 K21 - 0x5C300C00, // 0062 MOVE R12 R6 - 0x8834011A, // 0063 GETMBR R13 R0 K26 - 0x5C380E00, // 0064 MOVE R14 R7 - 0x7C200C00, // 0065 CALL R8 6 - 0xA8040001, // 0066 EXBLK 1 1 - 0x70020010, // 0067 JMP #0079 - 0xAC100002, // 0068 CATCH R4 0 2 - 0x7002000D, // 0069 JMP #0078 - 0xB81A1000, // 006A GETNGBL R6 K8 - 0x8C180D09, // 006B GETMET R6 R6 K9 - 0x60200008, // 006C GETGBL R8 G8 - 0x5C240800, // 006D MOVE R9 R4 - 0x7C200200, // 006E CALL R8 1 - 0x00223608, // 006F ADD R8 K27 R8 - 0x0020111C, // 0070 ADD R8 R8 K28 - 0x60240008, // 0071 GETGBL R9 G8 - 0x5C280A00, // 0072 MOVE R10 R5 - 0x7C240200, // 0073 CALL R9 1 - 0x00201009, // 0074 ADD R8 R8 R9 - 0x5824000B, // 0075 LDCONST R9 K11 - 0x7C180600, // 0076 CALL R6 3 - 0x70020000, // 0077 JMP #0079 - 0xB0080000, // 0078 RAISE 2 R0 R0 - 0x80000000, // 0079 RET 0 + ( &(const binstruction[119]) { /* code */ + 0x60080012, // 0000 GETGBL R2 G18 + 0x7C080000, // 0001 CALL R2 0 + 0x600C0010, // 0002 GETGBL R3 G16 + 0x8C100100, // 0003 GETMET R4 R0 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x7C100400, // 0005 CALL R4 2 + 0x7C0C0200, // 0006 CALL R3 1 + 0xA8020013, // 0007 EXBLK 0 #001C + 0x5C100600, // 0008 MOVE R4 R3 + 0x7C100000, // 0009 CALL R4 0 + 0x94140204, // 000A GETIDX R5 R1 R4 + 0x6018000F, // 000B GETGBL R6 G15 + 0x5C1C0A00, // 000C MOVE R7 R5 + 0x60200013, // 000D GETGBL R8 G19 + 0x7C180400, // 000E CALL R6 2 + 0x781A000A, // 000F JMPF R6 #001B + 0x8C180B01, // 0010 GETMET R6 R5 K1 + 0x58200002, // 0011 LDCONST R8 K2 + 0x7C180400, // 0012 CALL R6 2 + 0x781A0006, // 0013 JMPF R6 #001B + 0x00180903, // 0014 ADD R6 R4 K3 + 0x8C1C0504, // 0015 GETMET R7 R2 K4 + 0x60240013, // 0016 GETGBL R9 G19 + 0x7C240000, // 0017 CALL R9 0 + 0x98260B06, // 0018 SETIDX R9 K5 K6 + 0x98260E06, // 0019 SETIDX R9 K7 R6 + 0x7C1C0400, // 001A CALL R7 2 + 0x7001FFEB, // 001B JMP #0008 + 0x580C0008, // 001C LDCONST R3 K8 + 0xAC0C0200, // 001D CATCH R3 1 0 + 0xB0080000, // 001E RAISE 2 R0 R0 + 0x600C0010, // 001F GETGBL R3 G16 + 0x8C100100, // 0020 GETMET R4 R0 K0 + 0x5C180200, // 0021 MOVE R6 R1 + 0x7C100400, // 0022 CALL R4 2 + 0x7C0C0200, // 0023 CALL R3 1 + 0xA8020013, // 0024 EXBLK 0 #0039 + 0x5C100600, // 0025 MOVE R4 R3 + 0x7C100000, // 0026 CALL R4 0 + 0x94140204, // 0027 GETIDX R5 R1 R4 + 0x6018000F, // 0028 GETGBL R6 G15 + 0x5C1C0A00, // 0029 MOVE R7 R5 + 0x60200013, // 002A GETGBL R8 G19 + 0x7C180400, // 002B CALL R6 2 + 0x781A000A, // 002C JMPF R6 #0038 + 0x8C180B01, // 002D GETMET R6 R5 K1 + 0x58200009, // 002E LDCONST R8 K9 + 0x7C180400, // 002F CALL R6 2 + 0x781A0006, // 0030 JMPF R6 #0038 + 0x0018090A, // 0031 ADD R6 R4 K10 + 0x8C1C0504, // 0032 GETMET R7 R2 K4 + 0x60240013, // 0033 GETGBL R9 G19 + 0x7C240000, // 0034 CALL R9 0 + 0x98260B0B, // 0035 SETIDX R9 K5 K11 + 0x98260E06, // 0036 SETIDX R9 K7 R6 + 0x7C1C0400, // 0037 CALL R7 2 + 0x7001FFEB, // 0038 JMP #0025 + 0x580C0008, // 0039 LDCONST R3 K8 + 0xAC0C0200, // 003A CATCH R3 1 0 + 0xB0080000, // 003B RAISE 2 R0 R0 + 0x600C0010, // 003C GETGBL R3 G16 + 0x8C100100, // 003D GETMET R4 R0 K0 + 0x5C180200, // 003E MOVE R6 R1 + 0x7C100400, // 003F CALL R4 2 + 0x7C0C0200, // 0040 CALL R3 1 + 0xA8020013, // 0041 EXBLK 0 #0056 + 0x5C100600, // 0042 MOVE R4 R3 + 0x7C100000, // 0043 CALL R4 0 + 0x94140204, // 0044 GETIDX R5 R1 R4 + 0x6018000F, // 0045 GETGBL R6 G15 + 0x5C1C0A00, // 0046 MOVE R7 R5 + 0x60200013, // 0047 GETGBL R8 G19 + 0x7C180400, // 0048 CALL R6 2 + 0x781A000A, // 0049 JMPF R6 #0055 + 0x8C180B01, // 004A GETMET R6 R5 K1 + 0x5820000C, // 004B LDCONST R8 K12 + 0x7C180400, // 004C CALL R6 2 + 0x781A0006, // 004D JMPF R6 #0055 + 0x0018090D, // 004E ADD R6 R4 K13 + 0x8C1C0504, // 004F GETMET R7 R2 K4 + 0x60240013, // 0050 GETGBL R9 G19 + 0x7C240000, // 0051 CALL R9 0 + 0x98260B0E, // 0052 SETIDX R9 K5 K14 + 0x98260E06, // 0053 SETIDX R9 K7 R6 + 0x7C1C0400, // 0054 CALL R7 2 + 0x7001FFEB, // 0055 JMP #0042 + 0x580C0008, // 0056 LDCONST R3 K8 + 0xAC0C0200, // 0057 CATCH R3 1 0 + 0xB0080000, // 0058 RAISE 2 R0 R0 + 0x600C0010, // 0059 GETGBL R3 G16 + 0x8C100100, // 005A GETMET R4 R0 K0 + 0x5C180200, // 005B MOVE R6 R1 + 0x7C100400, // 005C CALL R4 2 + 0x7C0C0200, // 005D CALL R3 1 + 0xA8020013, // 005E EXBLK 0 #0073 + 0x5C100600, // 005F MOVE R4 R3 + 0x7C100000, // 0060 CALL R4 0 + 0x94140204, // 0061 GETIDX R5 R1 R4 + 0x6018000F, // 0062 GETGBL R6 G15 + 0x5C1C0A00, // 0063 MOVE R7 R5 + 0x60200013, // 0064 GETGBL R8 G19 + 0x7C180400, // 0065 CALL R6 2 + 0x781A000A, // 0066 JMPF R6 #0072 + 0x8C180B01, // 0067 GETMET R6 R5 K1 + 0x5820000F, // 0068 LDCONST R8 K15 + 0x7C180400, // 0069 CALL R6 2 + 0x781A0006, // 006A JMPF R6 #0072 + 0x00180910, // 006B ADD R6 R4 K16 + 0x8C1C0504, // 006C GETMET R7 R2 K4 + 0x60240013, // 006D GETGBL R9 G19 + 0x7C240000, // 006E CALL R9 0 + 0x98260B11, // 006F SETIDX R9 K5 K17 + 0x98260E06, // 0070 SETIDX R9 K7 R6 + 0x7C1C0400, // 0071 CALL R7 2 + 0x7001FFEB, // 0072 JMP #005F + 0x580C0008, // 0073 LDCONST R3 K8 + 0xAC0C0200, // 0074 CATCH R3 1 0 + 0xB0080000, // 0075 RAISE 2 R0 R0 + 0x80040400, // 0076 RET 1 R2 }) ) ); @@ -1534,11 +3021,44 @@ be_local_closure(Matter_Device_mdns_announce_op_discovery, /* name */ /******************************************************************** -** Solidified function: every_second +** Solidified function: msg_received ********************************************************************/ -be_local_closure(Matter_Device_every_second, /* name */ +be_local_closure(Matter_Device_msg_received, /* name */ be_nested_proto( - 4, /* nstack */ + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(message_handler), + /* K1 */ be_nested_str_weak(msg_received), + }), + be_str_weak(msg_received), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x88100100, // 0000 GETMBR R4 R0 K0 + 0x8C100901, // 0001 GETMET R4 R4 K1 + 0x5C180200, // 0002 MOVE R6 R1 + 0x5C1C0400, // 0003 MOVE R7 R2 + 0x5C200600, // 0004 MOVE R8 R3 + 0x7C100800, // 0005 CALL R4 4 + 0x80040800, // 0006 RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_remotes_info +********************************************************************/ +be_local_closure(Matter_Device_update_remotes_info, /* name */ + be_nested_proto( + 7, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1547,34 +3067,49 @@ be_local_closure(Matter_Device_every_second, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(sessions), - /* K1 */ be_nested_str_weak(every_second), - /* K2 */ be_nested_str_weak(message_handler), - /* K3 */ be_nested_str_weak(commissioning_open), - /* K4 */ be_nested_str_weak(tasmota), - /* K5 */ be_nested_str_weak(time_reached), + /* K0 */ be_nested_str_weak(http_remotes), + /* K1 */ be_nested_str_weak(keys), + /* K2 */ be_nested_str_weak(get_info), + /* K3 */ be_const_int(0), + /* K4 */ be_nested_str_weak(stop_iteration), + /* K5 */ be_nested_str_weak(plugins_config_remotes), }), - be_str_weak(every_second), + be_str_weak(update_remotes_info), &be_const_str_solidified, - ( &(const binstruction[18]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x88040102, // 0003 GETMBR R1 R0 K2 - 0x8C040301, // 0004 GETMET R1 R1 K1 - 0x7C040200, // 0005 CALL R1 1 - 0x88040103, // 0006 GETMBR R1 R0 K3 - 0x4C080000, // 0007 LDNIL R2 - 0x20040202, // 0008 NE R1 R1 R2 - 0x78060006, // 0009 JMPF R1 #0011 - 0xB8060800, // 000A GETNGBL R1 K4 - 0x8C040305, // 000B GETMET R1 R1 K5 - 0x880C0103, // 000C GETMBR R3 R0 K3 - 0x7C040400, // 000D CALL R1 2 - 0x78060001, // 000E JMPF R1 #0011 - 0x4C040000, // 000F LDNIL R1 - 0x90020601, // 0010 SETMBR R0 K3 R1 - 0x80000000, // 0011 RET 0 + ( &(const binstruction[33]) { /* code */ + 0x60040013, // 0000 GETGBL R1 G19 + 0x7C040000, // 0001 CALL R1 0 + 0x88080100, // 0002 GETMBR R2 R0 K0 + 0x4C0C0000, // 0003 LDNIL R3 + 0x20080403, // 0004 NE R2 R2 R3 + 0x780A0018, // 0005 JMPF R2 #001F + 0x60080010, // 0006 GETGBL R2 G16 + 0x880C0100, // 0007 GETMBR R3 R0 K0 + 0x8C0C0701, // 0008 GETMET R3 R3 K1 + 0x7C0C0200, // 0009 CALL R3 1 + 0x7C080200, // 000A CALL R2 1 + 0xA802000F, // 000B EXBLK 0 #001C + 0x5C0C0400, // 000C MOVE R3 R2 + 0x7C0C0000, // 000D CALL R3 0 + 0x88100100, // 000E GETMBR R4 R0 K0 + 0x94100803, // 000F GETIDX R4 R4 R3 + 0x8C100902, // 0010 GETMET R4 R4 K2 + 0x7C100200, // 0011 CALL R4 1 + 0x4C140000, // 0012 LDNIL R5 + 0x20140805, // 0013 NE R5 R4 R5 + 0x78160005, // 0014 JMPF R5 #001B + 0x6014000C, // 0015 GETGBL R5 G12 + 0x5C180800, // 0016 MOVE R6 R4 + 0x7C140200, // 0017 CALL R5 1 + 0x24140B03, // 0018 GT R5 R5 K3 + 0x78160000, // 0019 JMPF R5 #001B + 0x98040604, // 001A SETIDX R1 R3 R4 + 0x7001FFEF, // 001B JMP #000C + 0x58080004, // 001C LDCONST R2 K4 + 0xAC080200, // 001D CATCH R2 1 0 + 0xB0080000, // 001E RAISE 2 R0 R0 + 0x90020A01, // 001F SETMBR R0 K5 R1 + 0x80040200, // 0020 RET 1 R1 }) ) ); @@ -1582,36 +3117,71 @@ be_local_closure(Matter_Device_every_second, /* name */ /******************************************************************** -** Solidified function: get_plugin_class_arg +** Solidified function: _trigger_read_sensors ********************************************************************/ -be_local_closure(Matter_Device_get_plugin_class_arg, /* name */ +be_local_closure(Matter_Device__trigger_read_sensors, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 8, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(plugins_classes), - /* K1 */ be_nested_str_weak(find), - /* K2 */ be_nested_str_weak(ARG), - /* K3 */ be_nested_str_weak(), + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(json), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(read_sensors), + /* K3 */ be_nested_str_weak(load), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(plugins), + /* K6 */ be_nested_str_weak(parse_sensors), + /* K7 */ be_const_int(1), + /* K8 */ be_nested_str_weak(log), + /* K9 */ be_nested_str_weak(MTR_X3A_X20unable_X20to_X20parse_X20read_sensors_X3A_X20), + /* K10 */ be_const_int(3), }), - be_str_weak(get_plugin_class_arg), + be_str_weak(_trigger_read_sensors), &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x5C100200, // 0002 MOVE R4 R1 - 0x7C080400, // 0003 CALL R2 2 - 0x780A0001, // 0004 JMPF R2 #0007 - 0x880C0502, // 0005 GETMBR R3 R2 K2 - 0x70020000, // 0006 JMP #0008 - 0x580C0003, // 0007 LDCONST R3 K3 - 0x80040600, // 0008 RET 1 R3 + ( &(const binstruction[37]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0xB80A0200, // 0001 GETNGBL R2 K1 + 0x8C080502, // 0002 GETMET R2 R2 K2 + 0x7C080200, // 0003 CALL R2 1 + 0x4C0C0000, // 0004 LDNIL R3 + 0x1C0C0403, // 0005 EQ R3 R2 R3 + 0x780E0000, // 0006 JMPF R3 #0008 + 0x80000600, // 0007 RET 0 + 0x8C0C0303, // 0008 GETMET R3 R1 K3 + 0x5C140400, // 0009 MOVE R5 R2 + 0x7C0C0400, // 000A CALL R3 2 + 0x4C100000, // 000B LDNIL R4 + 0x20100604, // 000C NE R4 R3 R4 + 0x7812000D, // 000D JMPF R4 #001C + 0x58100004, // 000E LDCONST R4 K4 + 0x6014000C, // 000F GETGBL R5 G12 + 0x88180105, // 0010 GETMBR R6 R0 K5 + 0x7C140200, // 0011 CALL R5 1 + 0x14140805, // 0012 LT R5 R4 R5 + 0x78160006, // 0013 JMPF R5 #001B + 0x88140105, // 0014 GETMBR R5 R0 K5 + 0x94140A04, // 0015 GETIDX R5 R5 R4 + 0x8C140B06, // 0016 GETMET R5 R5 K6 + 0x5C1C0600, // 0017 MOVE R7 R3 + 0x7C140400, // 0018 CALL R5 2 + 0x00100907, // 0019 ADD R4 R4 K7 + 0x7001FFF3, // 001A JMP #000F + 0x70020007, // 001B JMP #0024 + 0xB8120200, // 001C GETNGBL R4 K1 + 0x8C100908, // 001D GETMET R4 R4 K8 + 0x60180008, // 001E GETGBL R6 G8 + 0x5C1C0400, // 001F MOVE R7 R2 + 0x7C180200, // 0020 CALL R6 1 + 0x001A1206, // 0021 ADD R6 K9 R6 + 0x581C000A, // 0022 LDCONST R7 K10 + 0x7C100600, // 0023 CALL R4 3 + 0x80000000, // 0024 RET 0 }) ) ); @@ -1619,36 +3189,79 @@ be_local_closure(Matter_Device_get_plugin_class_arg, /* name */ /******************************************************************** -** Solidified function: is_root_commissioning_open +** Solidified function: k2l ********************************************************************/ -be_local_closure(Matter_Device_is_root_commissioning_open, /* name */ +be_local_closure(Matter_Device_k2l, /* name */ be_nested_proto( - 3, /* nstack */ + 8, /* nstack */ 1, /* argc */ - 2, /* varg */ + 4, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(commissioning_open), - /* K1 */ be_nested_str_weak(commissioning_admin_fabric), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_const_class(be_class_Matter_Device), + /* K1 */ be_nested_str_weak(keys), + /* K2 */ be_nested_str_weak(push), + /* K3 */ be_nested_str_weak(stop_iteration), + /* K4 */ be_const_int(1), + /* K5 */ be_const_int(0), }), - be_str_weak(is_root_commissioning_open), + be_str_weak(k2l), &be_const_str_solidified, - ( &(const binstruction[11]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x20040202, // 0002 NE R1 R1 R2 - 0x78060003, // 0003 JMPF R1 #0008 - 0x88040101, // 0004 GETMBR R1 R0 K1 - 0x4C080000, // 0005 LDNIL R2 - 0x1C040202, // 0006 EQ R1 R1 R2 - 0x74060000, // 0007 JMPT R1 #0009 - 0x50040001, // 0008 LDBOOL R1 0 1 - 0x50040200, // 0009 LDBOOL R1 1 0 - 0x80040200, // 000A RET 1 R1 + ( &(const binstruction[50]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x60080012, // 0001 GETGBL R2 G18 + 0x7C080000, // 0002 CALL R2 0 + 0x4C0C0000, // 0003 LDNIL R3 + 0x1C0C0003, // 0004 EQ R3 R0 R3 + 0x780E0000, // 0005 JMPF R3 #0007 + 0x80040400, // 0006 RET 1 R2 + 0x600C0010, // 0007 GETGBL R3 G16 + 0x8C100101, // 0008 GETMET R4 R0 K1 + 0x7C100200, // 0009 CALL R4 1 + 0x7C0C0200, // 000A CALL R3 1 + 0xA8020005, // 000B EXBLK 0 #0012 + 0x5C100600, // 000C MOVE R4 R3 + 0x7C100000, // 000D CALL R4 0 + 0x8C140502, // 000E GETMET R5 R2 K2 + 0x5C1C0800, // 000F MOVE R7 R4 + 0x7C140400, // 0010 CALL R5 2 + 0x7001FFF9, // 0011 JMP #000C + 0x580C0003, // 0012 LDCONST R3 K3 + 0xAC0C0200, // 0013 CATCH R3 1 0 + 0xB0080000, // 0014 RAISE 2 R0 R0 + 0x600C0010, // 0015 GETGBL R3 G16 + 0x6010000C, // 0016 GETGBL R4 G12 + 0x5C140400, // 0017 MOVE R5 R2 + 0x7C100200, // 0018 CALL R4 1 + 0x04100904, // 0019 SUB R4 R4 K4 + 0x40120804, // 001A CONNECT R4 K4 R4 + 0x7C0C0200, // 001B CALL R3 1 + 0xA8020010, // 001C EXBLK 0 #002E + 0x5C100600, // 001D MOVE R4 R3 + 0x7C100000, // 001E CALL R4 0 + 0x94140404, // 001F GETIDX R5 R2 R4 + 0x5C180800, // 0020 MOVE R6 R4 + 0x241C0D05, // 0021 GT R7 R6 K5 + 0x781E0008, // 0022 JMPF R7 #002C + 0x041C0D04, // 0023 SUB R7 R6 K4 + 0x941C0407, // 0024 GETIDX R7 R2 R7 + 0x241C0E05, // 0025 GT R7 R7 R5 + 0x781E0004, // 0026 JMPF R7 #002C + 0x041C0D04, // 0027 SUB R7 R6 K4 + 0x941C0407, // 0028 GETIDX R7 R2 R7 + 0x98080C07, // 0029 SETIDX R2 R6 R7 + 0x04180D04, // 002A SUB R6 R6 K4 + 0x7001FFF4, // 002B JMP #0021 + 0x98080C05, // 002C SETIDX R2 R6 R5 + 0x7001FFEE, // 002D JMP #001D + 0x580C0003, // 002E LDCONST R3 K3 + 0xAC0C0200, // 002F CATCH R3 1 0 + 0xB0080000, // 0030 RAISE 2 R0 R0 + 0x80040400, // 0031 RET 1 R2 }) ) ); @@ -1656,11 +3269,11 @@ be_local_closure(Matter_Device_is_root_commissioning_open, /* name */ /******************************************************************** -** Solidified function: mdns_announce_PASE +** Solidified function: signal_endpoints_changed ********************************************************************/ -be_local_closure(Matter_Device_mdns_announce_PASE, /* name */ +be_local_closure(Matter_Device_signal_endpoints_changed, /* name */ be_nested_proto( - 16, /* nstack */ + 7, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1668,322 +3281,27 @@ be_local_closure(Matter_Device_mdns_announce_PASE, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[44]) { /* constants */ - /* K0 */ be_nested_str_weak(mdns), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(crypto), - /* K3 */ be_nested_str_weak(VP), - /* K4 */ be_nested_str_weak(vendorid), - /* K5 */ be_nested_str_weak(_X2B), - /* K6 */ be_nested_str_weak(productid), - /* K7 */ be_nested_str_weak(D), - /* K8 */ be_nested_str_weak(commissioning_discriminator), - /* K9 */ be_nested_str_weak(CM), - /* K10 */ be_const_int(1), - /* K11 */ be_nested_str_weak(T), - /* K12 */ be_const_int(0), - /* K13 */ be_nested_str_weak(SII), - /* K14 */ be_nested_str_weak(SAI), - /* K15 */ be_nested_str_weak(commissioning_instance_wifi), - /* K16 */ be_nested_str_weak(random), - /* K17 */ be_nested_str_weak(tohex), - /* K18 */ be_nested_str_weak(commissioning_instance_eth), - /* K19 */ be_nested_str_weak(hostname_eth), - /* K20 */ be_nested_str_weak(tasmota), - /* K21 */ be_nested_str_weak(log), - /* K22 */ be_nested_str_weak(format), - /* K23 */ be_nested_str_weak(MTR_X3A_X20calling_X20mdns_X2Eadd_service_X28_X25s_X2C_X20_X25s_X2C_X20_X25i_X2C_X20_X25s_X2C_X20_X25s_X2C_X20_X25s_X29), - /* K24 */ be_nested_str_weak(_matterc), - /* K25 */ be_nested_str_weak(_udp), - /* K26 */ be_const_int(3), - /* K27 */ be_nested_str_weak(add_service), - /* K28 */ be_nested_str_weak(mdns_pase_eth), - /* K29 */ be_nested_str_weak(MTR_X3A_X20announce_X20mDNS_X20on_X20_X25s_X20_X27_X25s_X27_X20ptr_X20to_X20_X60_X25s_X2Elocal_X60), - /* K30 */ be_nested_str_weak(eth), - /* K31 */ be_const_int(2), - /* K32 */ be_nested_str_weak(_L), - /* K33 */ be_nested_str_weak(MTR_X3A_X20adding_X20subtype_X3A_X20), - /* K34 */ be_nested_str_weak(add_subtype), - /* K35 */ be_nested_str_weak(_S), - /* K36 */ be_nested_str_weak(_V), - /* K37 */ be_nested_str_weak(_CM1), - /* K38 */ be_nested_str_weak(hostname_wifi), - /* K39 */ be_nested_str_weak(mdns_pase_wifi), - /* K40 */ be_nested_str_weak(MTR_X3A_X20starting_X20mDNS_X20on_X20_X25s_X20_X27_X25s_X27_X20ptr_X20to_X20_X60_X25s_X2Elocal_X60), - /* K41 */ be_nested_str_weak(wifi), - /* K42 */ be_nested_str_weak(MTR_X3A_X20Exception), - /* K43 */ be_nested_str_weak(_X7C), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(attribute_updated), + /* K1 */ be_const_int(0), + /* K2 */ be_const_int(3), }), - be_str_weak(mdns_announce_PASE), + be_str_weak(signal_endpoints_changed), &be_const_str_solidified, - ( &(const binstruction[267]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0xA40E0400, // 0002 IMPORT R3 K2 - 0x60100013, // 0003 GETGBL R4 G19 - 0x7C100000, // 0004 CALL R4 0 - 0x60140008, // 0005 GETGBL R5 G8 - 0x88180104, // 0006 GETMBR R6 R0 K4 - 0x7C140200, // 0007 CALL R5 1 - 0x00140B05, // 0008 ADD R5 R5 K5 - 0x60180008, // 0009 GETGBL R6 G8 - 0x881C0106, // 000A GETMBR R7 R0 K6 - 0x7C180200, // 000B CALL R6 1 - 0x00140A06, // 000C ADD R5 R5 R6 - 0x98120605, // 000D SETIDX R4 K3 R5 - 0x88140108, // 000E GETMBR R5 R0 K8 - 0x98120E05, // 000F SETIDX R4 K7 R5 - 0x9812130A, // 0010 SETIDX R4 K9 K10 - 0x9812170C, // 0011 SETIDX R4 K11 K12 - 0x54161387, // 0012 LDINT R5 5000 - 0x98121A05, // 0013 SETIDX R4 K13 R5 - 0x5416012B, // 0014 LDINT R5 300 - 0x98121C05, // 0015 SETIDX R4 K14 R5 - 0x8C140710, // 0016 GETMET R5 R3 K16 - 0x541E0007, // 0017 LDINT R7 8 - 0x7C140400, // 0018 CALL R5 2 - 0x8C140B11, // 0019 GETMET R5 R5 K17 - 0x7C140200, // 001A CALL R5 1 - 0x90021E05, // 001B SETMBR R0 K15 R5 - 0x8C140710, // 001C GETMET R5 R3 K16 - 0x541E0007, // 001D LDINT R7 8 - 0x7C140400, // 001E CALL R5 2 - 0x8C140B11, // 001F GETMET R5 R5 K17 - 0x7C140200, // 0020 CALL R5 1 - 0x90022405, // 0021 SETMBR R0 K18 R5 - 0xA80200D5, // 0022 EXBLK 0 #00F9 - 0x88140113, // 0023 GETMBR R5 R0 K19 - 0x78160067, // 0024 JMPF R5 #008D - 0xB8162800, // 0025 GETNGBL R5 K20 - 0x8C140B15, // 0026 GETMET R5 R5 K21 - 0x8C1C0516, // 0027 GETMET R7 R2 K22 - 0x58240017, // 0028 LDCONST R9 K23 - 0x58280018, // 0029 LDCONST R10 K24 - 0x582C0019, // 002A LDCONST R11 K25 - 0x543215A3, // 002B LDINT R12 5540 - 0x60340008, // 002C GETGBL R13 G8 - 0x5C380800, // 002D MOVE R14 R4 - 0x7C340200, // 002E CALL R13 1 - 0x88380112, // 002F GETMBR R14 R0 K18 - 0x883C0113, // 0030 GETMBR R15 R0 K19 - 0x7C1C1000, // 0031 CALL R7 8 - 0x5820001A, // 0032 LDCONST R8 K26 - 0x7C140600, // 0033 CALL R5 3 - 0x8C14031B, // 0034 GETMET R5 R1 K27 - 0x581C0018, // 0035 LDCONST R7 K24 - 0x58200019, // 0036 LDCONST R8 K25 - 0x542615A3, // 0037 LDINT R9 5540 - 0x5C280800, // 0038 MOVE R10 R4 - 0x882C0112, // 0039 GETMBR R11 R0 K18 - 0x88300113, // 003A GETMBR R12 R0 K19 - 0x7C140E00, // 003B CALL R5 7 - 0x50140200, // 003C LDBOOL R5 1 0 - 0x90023805, // 003D SETMBR R0 K28 R5 - 0xB8162800, // 003E GETNGBL R5 K20 - 0x8C140B15, // 003F GETMET R5 R5 K21 - 0x8C1C0516, // 0040 GETMET R7 R2 K22 - 0x5824001D, // 0041 LDCONST R9 K29 - 0x5828001E, // 0042 LDCONST R10 K30 - 0x882C0112, // 0043 GETMBR R11 R0 K18 - 0x88300113, // 0044 GETMBR R12 R0 K19 - 0x7C1C0A00, // 0045 CALL R7 5 - 0x5820001F, // 0046 LDCONST R8 K31 - 0x7C140600, // 0047 CALL R5 3 - 0x60140008, // 0048 GETGBL R5 G8 - 0x88180108, // 0049 GETMBR R6 R0 K8 - 0x541E0FFE, // 004A LDINT R7 4095 - 0x2C180C07, // 004B AND R6 R6 R7 - 0x7C140200, // 004C CALL R5 1 - 0x00164005, // 004D ADD R5 K32 R5 - 0xB81A2800, // 004E GETNGBL R6 K20 - 0x8C180D15, // 004F GETMET R6 R6 K21 - 0x00224205, // 0050 ADD R8 K33 R5 - 0x5824001F, // 0051 LDCONST R9 K31 - 0x7C180600, // 0052 CALL R6 3 - 0x8C180322, // 0053 GETMET R6 R1 K34 - 0x58200018, // 0054 LDCONST R8 K24 - 0x58240019, // 0055 LDCONST R9 K25 - 0x88280112, // 0056 GETMBR R10 R0 K18 - 0x882C0113, // 0057 GETMBR R11 R0 K19 - 0x5C300A00, // 0058 MOVE R12 R5 - 0x7C180C00, // 0059 CALL R6 6 - 0x60180008, // 005A GETGBL R6 G8 - 0x881C0108, // 005B GETMBR R7 R0 K8 - 0x54220EFF, // 005C LDINT R8 3840 - 0x2C1C0E08, // 005D AND R7 R7 R8 - 0x54220007, // 005E LDINT R8 8 - 0x3C1C0E08, // 005F SHR R7 R7 R8 - 0x7C180200, // 0060 CALL R6 1 - 0x001A4606, // 0061 ADD R6 K35 R6 - 0x5C140C00, // 0062 MOVE R5 R6 - 0xB81A2800, // 0063 GETNGBL R6 K20 - 0x8C180D15, // 0064 GETMET R6 R6 K21 - 0x00224205, // 0065 ADD R8 K33 R5 - 0x5824001F, // 0066 LDCONST R9 K31 - 0x7C180600, // 0067 CALL R6 3 - 0x8C180322, // 0068 GETMET R6 R1 K34 - 0x58200018, // 0069 LDCONST R8 K24 - 0x58240019, // 006A LDCONST R9 K25 - 0x88280112, // 006B GETMBR R10 R0 K18 - 0x882C0113, // 006C GETMBR R11 R0 K19 - 0x5C300A00, // 006D MOVE R12 R5 - 0x7C180C00, // 006E CALL R6 6 - 0x60180008, // 006F GETGBL R6 G8 - 0x881C0104, // 0070 GETMBR R7 R0 K4 - 0x7C180200, // 0071 CALL R6 1 - 0x001A4806, // 0072 ADD R6 K36 R6 - 0x5C140C00, // 0073 MOVE R5 R6 - 0xB81A2800, // 0074 GETNGBL R6 K20 - 0x8C180D15, // 0075 GETMET R6 R6 K21 - 0x00224205, // 0076 ADD R8 K33 R5 - 0x5824001F, // 0077 LDCONST R9 K31 - 0x7C180600, // 0078 CALL R6 3 - 0x8C180322, // 0079 GETMET R6 R1 K34 - 0x58200018, // 007A LDCONST R8 K24 - 0x58240019, // 007B LDCONST R9 K25 - 0x88280112, // 007C GETMBR R10 R0 K18 - 0x882C0113, // 007D GETMBR R11 R0 K19 - 0x5C300A00, // 007E MOVE R12 R5 - 0x7C180C00, // 007F CALL R6 6 - 0x58140025, // 0080 LDCONST R5 K37 - 0xB81A2800, // 0081 GETNGBL R6 K20 - 0x8C180D15, // 0082 GETMET R6 R6 K21 - 0x00224205, // 0083 ADD R8 K33 R5 - 0x5824001F, // 0084 LDCONST R9 K31 - 0x7C180600, // 0085 CALL R6 3 - 0x8C180322, // 0086 GETMET R6 R1 K34 - 0x58200018, // 0087 LDCONST R8 K24 - 0x58240019, // 0088 LDCONST R9 K25 - 0x88280112, // 0089 GETMBR R10 R0 K18 - 0x882C0113, // 008A GETMBR R11 R0 K19 - 0x5C300A00, // 008B MOVE R12 R5 - 0x7C180C00, // 008C CALL R6 6 - 0x88140126, // 008D GETMBR R5 R0 K38 - 0x78160067, // 008E JMPF R5 #00F7 - 0xB8162800, // 008F GETNGBL R5 K20 - 0x8C140B15, // 0090 GETMET R5 R5 K21 - 0x8C1C0516, // 0091 GETMET R7 R2 K22 - 0x58240017, // 0092 LDCONST R9 K23 - 0x58280018, // 0093 LDCONST R10 K24 - 0x582C0019, // 0094 LDCONST R11 K25 - 0x543215A3, // 0095 LDINT R12 5540 - 0x60340008, // 0096 GETGBL R13 G8 - 0x5C380800, // 0097 MOVE R14 R4 - 0x7C340200, // 0098 CALL R13 1 - 0x8838010F, // 0099 GETMBR R14 R0 K15 - 0x883C0126, // 009A GETMBR R15 R0 K38 - 0x7C1C1000, // 009B CALL R7 8 - 0x5820001A, // 009C LDCONST R8 K26 - 0x7C140600, // 009D CALL R5 3 - 0x8C14031B, // 009E GETMET R5 R1 K27 - 0x581C0018, // 009F LDCONST R7 K24 - 0x58200019, // 00A0 LDCONST R8 K25 - 0x542615A3, // 00A1 LDINT R9 5540 - 0x5C280800, // 00A2 MOVE R10 R4 - 0x882C010F, // 00A3 GETMBR R11 R0 K15 - 0x88300126, // 00A4 GETMBR R12 R0 K38 - 0x7C140E00, // 00A5 CALL R5 7 - 0x50140200, // 00A6 LDBOOL R5 1 0 - 0x90024E05, // 00A7 SETMBR R0 K39 R5 - 0xB8162800, // 00A8 GETNGBL R5 K20 - 0x8C140B15, // 00A9 GETMET R5 R5 K21 - 0x8C1C0516, // 00AA GETMET R7 R2 K22 - 0x58240028, // 00AB LDCONST R9 K40 - 0x58280029, // 00AC LDCONST R10 K41 - 0x882C010F, // 00AD GETMBR R11 R0 K15 - 0x88300126, // 00AE GETMBR R12 R0 K38 - 0x7C1C0A00, // 00AF CALL R7 5 - 0x5820001F, // 00B0 LDCONST R8 K31 - 0x7C140600, // 00B1 CALL R5 3 - 0x60140008, // 00B2 GETGBL R5 G8 - 0x88180108, // 00B3 GETMBR R6 R0 K8 - 0x541E0FFE, // 00B4 LDINT R7 4095 - 0x2C180C07, // 00B5 AND R6 R6 R7 - 0x7C140200, // 00B6 CALL R5 1 - 0x00164005, // 00B7 ADD R5 K32 R5 - 0xB81A2800, // 00B8 GETNGBL R6 K20 - 0x8C180D15, // 00B9 GETMET R6 R6 K21 - 0x00224205, // 00BA ADD R8 K33 R5 - 0x5824001F, // 00BB LDCONST R9 K31 - 0x7C180600, // 00BC CALL R6 3 - 0x8C180322, // 00BD GETMET R6 R1 K34 - 0x58200018, // 00BE LDCONST R8 K24 - 0x58240019, // 00BF LDCONST R9 K25 - 0x8828010F, // 00C0 GETMBR R10 R0 K15 - 0x882C0126, // 00C1 GETMBR R11 R0 K38 - 0x5C300A00, // 00C2 MOVE R12 R5 - 0x7C180C00, // 00C3 CALL R6 6 - 0x60180008, // 00C4 GETGBL R6 G8 - 0x881C0108, // 00C5 GETMBR R7 R0 K8 - 0x54220EFF, // 00C6 LDINT R8 3840 - 0x2C1C0E08, // 00C7 AND R7 R7 R8 - 0x54220007, // 00C8 LDINT R8 8 - 0x3C1C0E08, // 00C9 SHR R7 R7 R8 - 0x7C180200, // 00CA CALL R6 1 - 0x001A4606, // 00CB ADD R6 K35 R6 - 0x5C140C00, // 00CC MOVE R5 R6 - 0xB81A2800, // 00CD GETNGBL R6 K20 - 0x8C180D15, // 00CE GETMET R6 R6 K21 - 0x00224205, // 00CF ADD R8 K33 R5 - 0x5824001F, // 00D0 LDCONST R9 K31 - 0x7C180600, // 00D1 CALL R6 3 - 0x8C180322, // 00D2 GETMET R6 R1 K34 - 0x58200018, // 00D3 LDCONST R8 K24 - 0x58240019, // 00D4 LDCONST R9 K25 - 0x8828010F, // 00D5 GETMBR R10 R0 K15 - 0x882C0126, // 00D6 GETMBR R11 R0 K38 - 0x5C300A00, // 00D7 MOVE R12 R5 - 0x7C180C00, // 00D8 CALL R6 6 - 0x60180008, // 00D9 GETGBL R6 G8 - 0x881C0104, // 00DA GETMBR R7 R0 K4 - 0x7C180200, // 00DB CALL R6 1 - 0x001A4806, // 00DC ADD R6 K36 R6 - 0x5C140C00, // 00DD MOVE R5 R6 - 0xB81A2800, // 00DE GETNGBL R6 K20 - 0x8C180D15, // 00DF GETMET R6 R6 K21 - 0x00224205, // 00E0 ADD R8 K33 R5 - 0x5824001F, // 00E1 LDCONST R9 K31 - 0x7C180600, // 00E2 CALL R6 3 - 0x8C180322, // 00E3 GETMET R6 R1 K34 - 0x58200018, // 00E4 LDCONST R8 K24 - 0x58240019, // 00E5 LDCONST R9 K25 - 0x8828010F, // 00E6 GETMBR R10 R0 K15 - 0x882C0126, // 00E7 GETMBR R11 R0 K38 - 0x5C300A00, // 00E8 MOVE R12 R5 - 0x7C180C00, // 00E9 CALL R6 6 - 0x58140025, // 00EA LDCONST R5 K37 - 0xB81A2800, // 00EB GETNGBL R6 K20 - 0x8C180D15, // 00EC GETMET R6 R6 K21 - 0x00224205, // 00ED ADD R8 K33 R5 - 0x5824001F, // 00EE LDCONST R9 K31 - 0x7C180600, // 00EF CALL R6 3 - 0x8C180322, // 00F0 GETMET R6 R1 K34 - 0x58200018, // 00F1 LDCONST R8 K24 - 0x58240019, // 00F2 LDCONST R9 K25 - 0x8828010F, // 00F3 GETMBR R10 R0 K15 - 0x882C0126, // 00F4 GETMBR R11 R0 K38 - 0x5C300A00, // 00F5 MOVE R12 R5 - 0x7C180C00, // 00F6 CALL R6 6 - 0xA8040001, // 00F7 EXBLK 1 1 - 0x70020010, // 00F8 JMP #010A - 0xAC140002, // 00F9 CATCH R5 0 2 - 0x7002000D, // 00FA JMP #0109 - 0xB81E2800, // 00FB GETNGBL R7 K20 - 0x8C1C0F15, // 00FC GETMET R7 R7 K21 - 0x60240008, // 00FD GETGBL R9 G8 - 0x5C280A00, // 00FE MOVE R10 R5 - 0x7C240200, // 00FF CALL R9 1 - 0x00265409, // 0100 ADD R9 K42 R9 - 0x0024132B, // 0101 ADD R9 R9 K43 - 0x60280008, // 0102 GETGBL R10 G8 - 0x5C2C0C00, // 0103 MOVE R11 R6 - 0x7C280200, // 0104 CALL R10 1 - 0x0024120A, // 0105 ADD R9 R9 R10 - 0x5828001F, // 0106 LDCONST R10 K31 - 0x7C1C0600, // 0107 CALL R7 3 - 0x70020000, // 0108 JMP #010A - 0xB0080000, // 0109 RAISE 2 R0 R0 - 0x80000000, // 010A RET 0 + ( &(const binstruction[13]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x580C0001, // 0001 LDCONST R3 K1 + 0x5412001C, // 0002 LDINT R4 29 + 0x58140002, // 0003 LDCONST R5 K2 + 0x50180000, // 0004 LDBOOL R6 0 0 + 0x7C040A00, // 0005 CALL R1 5 + 0x8C040100, // 0006 GETMET R1 R0 K0 + 0x540EFEFF, // 0007 LDINT R3 65280 + 0x5412001C, // 0008 LDINT R4 29 + 0x58140002, // 0009 LDCONST R5 K2 + 0x50180000, // 000A LDBOOL R6 0 0 + 0x7C040A00, // 000B CALL R1 5 + 0x80000000, // 000C RET 0 }) ) ); @@ -1991,418 +3309,81 @@ be_local_closure(Matter_Device_mdns_announce_PASE, /* name */ /******************************************************************** -** Solidified function: autoconf_device_map +** Solidified function: start_root_basic_commissioning ********************************************************************/ -be_local_closure(Matter_Device_autoconf_device_map, /* name */ +be_local_closure(Matter_Device_start_root_basic_commissioning, /* name */ be_nested_proto( - 22, /* nstack */ - 1, /* argc */ + 13, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[53]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(json), - /* K2 */ be_nested_str_weak(0), - /* K3 */ be_nested_str_weak(type), - /* K4 */ be_nested_str_weak(root), - /* K5 */ be_const_int(1), - /* K6 */ be_nested_str_weak(light), - /* K7 */ be_nested_str_weak(get), - /* K8 */ be_nested_str_weak(find), - /* K9 */ be_nested_str_weak(channels), - /* K10 */ be_nested_str_weak(), - /* K11 */ be_const_int(0), - /* K12 */ be_nested_str_weak(light1), - /* K13 */ be_const_int(2), - /* K14 */ be_nested_str_weak(light2), - /* K15 */ be_nested_str_weak(light3), - /* K16 */ be_nested_str_weak(tasmota), - /* K17 */ be_nested_str_weak(cmd), - /* K18 */ be_nested_str_weak(Status_X2013), - /* K19 */ be_nested_str_weak(log), - /* K20 */ be_nested_str_weak(MTR_X3A_X20Status_X2013_X20_X3D_X20), - /* K21 */ be_const_int(3), - /* K22 */ be_nested_str_weak(contains), - /* K23 */ be_nested_str_weak(StatusSHT), - /* K24 */ be_nested_str_weak(SHT), - /* K25 */ be_nested_str_weak(format), - /* K26 */ be_nested_str_weak(MTR_X3A_X20_X27_X25s_X27_X20_X3D_X20_X25s), - /* K27 */ be_nested_str_weak(Relay1), - /* K28 */ be_nested_str_weak(Relay2), - /* K29 */ be_nested_str_weak(push), - /* K30 */ be_nested_str_weak(MTR_X3A_X20relay1_X20_X3D_X20_X25s_X2C_X20relay2_X20_X3D_X20_X25s), - /* K31 */ be_nested_str_weak(TiltConfig), - /* K32 */ be_nested_str_weak(shutter_X2Btilt), - /* K33 */ be_nested_str_weak(shutter), - /* K34 */ be_nested_str_weak(get_power), - /* K35 */ be_nested_str_weak(relay), - /* K36 */ be_nested_str_weak(load), - /* K37 */ be_nested_str_weak(read_sensors), - /* K38 */ be_nested_str_weak(k2l), - /* K39 */ be_nested_str_weak(Temperature), - /* K40 */ be_nested_str_weak(_X23Temperature), - /* K41 */ be_nested_str_weak(temperature), - /* K42 */ be_nested_str_weak(filter), - /* K43 */ be_nested_str_weak(stop_iteration), - /* K44 */ be_nested_str_weak(Pressure), - /* K45 */ be_nested_str_weak(_X23Pressure), - /* K46 */ be_nested_str_weak(pressure), - /* K47 */ be_nested_str_weak(Illuminance), - /* K48 */ be_nested_str_weak(_X23Illuminance), - /* K49 */ be_nested_str_weak(illuminance), - /* K50 */ be_nested_str_weak(Humidity), - /* K51 */ be_nested_str_weak(_X23Humidity), - /* K52 */ be_nested_str_weak(humidity), + ( &(const bvalue[18]) { /* constants */ + /* K0 */ be_nested_str_weak(PASE_TIMEOUT), + /* K1 */ be_nested_str_weak(compute_manual_pairing_code), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(log), + /* K4 */ be_nested_str_weak(MTR_X3A_X20Manual_X20pairing_X20code_X3A_X20_X25s), + /* K5 */ be_const_int(2), + /* K6 */ be_nested_str_weak(compute_qrcode_content), + /* K7 */ be_nested_str_weak(publish_result), + /* K8 */ be_nested_str_weak(_X7B_X22Matter_X22_X3A_X7B_X22Commissioning_X22_X3A1_X2C_X22PairingCode_X22_X3A_X22_X25s_X22_X2C_X22QRCode_X22_X3A_X22_X25s_X22_X7D_X7D), + /* K9 */ be_nested_str_weak(Matter), + /* K10 */ be_nested_str_weak(_compute_pbkdf), + /* K11 */ be_nested_str_weak(root_passcode), + /* K12 */ be_nested_str_weak(root_iterations), + /* K13 */ be_nested_str_weak(root_salt), + /* K14 */ be_nested_str_weak(start_basic_commissioning), + /* K15 */ be_nested_str_weak(root_discriminator), + /* K16 */ be_nested_str_weak(root_w0), + /* K17 */ be_nested_str_weak(root_L), }), - be_str_weak(autoconf_device_map), + be_str_weak(start_root_basic_commissioning), &be_const_str_solidified, - ( &(const binstruction[342]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0x600C0013, // 0002 GETGBL R3 G19 - 0x7C0C0000, // 0003 CALL R3 0 - 0x60100013, // 0004 GETGBL R4 G19 - 0x7C100000, // 0005 CALL R4 0 - 0x98120704, // 0006 SETIDX R4 K3 K4 - 0x980E0404, // 0007 SETIDX R3 K2 R4 - 0x58100005, // 0008 LDCONST R4 K5 - 0x50140000, // 0009 LDBOOL R5 0 0 - 0xA41A0C00, // 000A IMPORT R6 K6 - 0x8C1C0D07, // 000B GETMET R7 R6 K7 - 0x7C1C0200, // 000C CALL R7 1 - 0x4C200000, // 000D LDNIL R8 - 0x20200E08, // 000E NE R8 R7 R8 - 0x78220024, // 000F JMPF R8 #0035 - 0x6020000C, // 0010 GETGBL R8 G12 - 0x8C240F08, // 0011 GETMET R9 R7 K8 - 0x582C0009, // 0012 LDCONST R11 K9 - 0x5830000A, // 0013 LDCONST R12 K10 - 0x7C240600, // 0014 CALL R9 3 - 0x7C200200, // 0015 CALL R8 1 - 0x2424110B, // 0016 GT R9 R8 K11 - 0x7826001C, // 0017 JMPF R9 #0035 - 0x1C241105, // 0018 EQ R9 R8 K5 - 0x78260007, // 0019 JMPF R9 #0022 - 0x60240008, // 001A GETGBL R9 G8 - 0x5C280800, // 001B MOVE R10 R4 - 0x7C240200, // 001C CALL R9 1 - 0x60280013, // 001D GETGBL R10 G19 - 0x7C280000, // 001E CALL R10 0 - 0x982A070C, // 001F SETIDX R10 K3 K12 - 0x980C120A, // 0020 SETIDX R3 R9 R10 - 0x70020010, // 0021 JMP #0033 - 0x1C24110D, // 0022 EQ R9 R8 K13 - 0x78260007, // 0023 JMPF R9 #002C - 0x60240008, // 0024 GETGBL R9 G8 - 0x5C280800, // 0025 MOVE R10 R4 - 0x7C240200, // 0026 CALL R9 1 - 0x60280013, // 0027 GETGBL R10 G19 - 0x7C280000, // 0028 CALL R10 0 - 0x982A070E, // 0029 SETIDX R10 K3 K14 - 0x980C120A, // 002A SETIDX R3 R9 R10 - 0x70020006, // 002B JMP #0033 - 0x60240008, // 002C GETGBL R9 G8 - 0x5C280800, // 002D MOVE R10 R4 - 0x7C240200, // 002E CALL R9 1 - 0x60280013, // 002F GETGBL R10 G19 - 0x7C280000, // 0030 CALL R10 0 - 0x982A070F, // 0031 SETIDX R10 K3 K15 - 0x980C120A, // 0032 SETIDX R3 R9 R10 - 0x50140200, // 0033 LDBOOL R5 1 0 - 0x00100905, // 0034 ADD R4 R4 K5 - 0xB8222000, // 0035 GETNGBL R8 K16 - 0x8C201111, // 0036 GETMET R8 R8 K17 - 0x58280012, // 0037 LDCONST R10 K18 - 0x502C0200, // 0038 LDBOOL R11 1 0 - 0x7C200600, // 0039 CALL R8 3 - 0x60240012, // 003A GETGBL R9 G18 - 0x7C240000, // 003B CALL R9 0 - 0xB82A2000, // 003C GETNGBL R10 K16 - 0x8C281513, // 003D GETMET R10 R10 K19 - 0x60300008, // 003E GETGBL R12 G8 - 0x5C341000, // 003F MOVE R13 R8 - 0x7C300200, // 0040 CALL R12 1 - 0x0032280C, // 0041 ADD R12 K20 R12 - 0x58340015, // 0042 LDCONST R13 K21 - 0x7C280600, // 0043 CALL R10 3 - 0x4C280000, // 0044 LDNIL R10 - 0x2028100A, // 0045 NE R10 R8 R10 - 0x782A0051, // 0046 JMPF R10 #0099 - 0x8C281116, // 0047 GETMET R10 R8 K22 - 0x58300017, // 0048 LDCONST R12 K23 - 0x7C280400, // 0049 CALL R10 2 - 0x782A004D, // 004A JMPF R10 #0099 - 0x94201117, // 004B GETIDX R8 R8 K23 - 0x5828000B, // 004C LDCONST R10 K11 - 0x502C0200, // 004D LDBOOL R11 1 0 - 0x782E0049, // 004E JMPF R11 #0099 - 0x602C0008, // 004F GETGBL R11 G8 - 0x5C301400, // 0050 MOVE R12 R10 - 0x7C2C0200, // 0051 CALL R11 1 - 0x002E300B, // 0052 ADD R11 K24 R11 - 0x8C301116, // 0053 GETMET R12 R8 K22 - 0x5C381600, // 0054 MOVE R14 R11 - 0x7C300400, // 0055 CALL R12 2 - 0x74320000, // 0056 JMPT R12 #0058 - 0x70020040, // 0057 JMP #0099 - 0x9430100B, // 0058 GETIDX R12 R8 R11 - 0xB8362000, // 0059 GETNGBL R13 K16 - 0x8C341B13, // 005A GETMET R13 R13 K19 - 0x8C3C0319, // 005B GETMET R15 R1 K25 - 0x5844001A, // 005C LDCONST R17 K26 - 0x5C481600, // 005D MOVE R18 R11 - 0x604C0008, // 005E GETGBL R19 G8 - 0x5C501800, // 005F MOVE R20 R12 - 0x7C4C0200, // 0060 CALL R19 1 - 0x7C3C0800, // 0061 CALL R15 4 - 0x58400015, // 0062 LDCONST R16 K21 - 0x7C340600, // 0063 CALL R13 3 - 0x8C341908, // 0064 GETMET R13 R12 K8 - 0x583C001B, // 0065 LDCONST R15 K27 - 0x5840000B, // 0066 LDCONST R16 K11 - 0x7C340600, // 0067 CALL R13 3 - 0x04341B05, // 0068 SUB R13 R13 K5 - 0x8C381908, // 0069 GETMET R14 R12 K8 - 0x5840001C, // 006A LDCONST R16 K28 - 0x5844000B, // 006B LDCONST R17 K11 - 0x7C380600, // 006C CALL R14 3 - 0x04381D05, // 006D SUB R14 R14 K5 - 0x283C1B0B, // 006E GE R15 R13 K11 - 0x783E0002, // 006F JMPF R15 #0073 - 0x8C3C131D, // 0070 GETMET R15 R9 K29 - 0x5C441A00, // 0071 MOVE R17 R13 - 0x7C3C0400, // 0072 CALL R15 2 - 0x283C1D0B, // 0073 GE R15 R14 K11 - 0x783E0002, // 0074 JMPF R15 #0078 - 0x8C3C131D, // 0075 GETMET R15 R9 K29 - 0x5C441C00, // 0076 MOVE R17 R14 - 0x7C3C0400, // 0077 CALL R15 2 - 0xB83E2000, // 0078 GETNGBL R15 K16 - 0x8C3C1F13, // 0079 GETMET R15 R15 K19 - 0x8C440319, // 007A GETMET R17 R1 K25 - 0x584C001E, // 007B LDCONST R19 K30 - 0x5C501A00, // 007C MOVE R20 R13 - 0x5C541C00, // 007D MOVE R21 R14 - 0x7C440800, // 007E CALL R17 4 - 0x58480015, // 007F LDCONST R18 K21 - 0x7C3C0600, // 0080 CALL R15 3 - 0x8C3C1908, // 0081 GETMET R15 R12 K8 - 0x5844001F, // 0082 LDCONST R17 K31 - 0x7C3C0400, // 0083 CALL R15 2 - 0x783E0002, // 0084 JMPF R15 #0088 - 0x94401F0D, // 0085 GETIDX R16 R15 K13 - 0x2440210B, // 0086 GT R16 R16 K11 - 0x74420000, // 0087 JMPT R16 #0089 - 0x50400001, // 0088 LDBOOL R16 0 1 - 0x50400200, // 0089 LDBOOL R16 1 0 - 0x60440008, // 008A GETGBL R17 G8 - 0x5C480800, // 008B MOVE R18 R4 - 0x7C440200, // 008C CALL R17 1 - 0x60480013, // 008D GETGBL R18 G19 - 0x7C480000, // 008E CALL R18 0 - 0x78420001, // 008F JMPF R16 #0092 - 0x584C0020, // 0090 LDCONST R19 K32 - 0x70020000, // 0091 JMP #0093 - 0x584C0021, // 0092 LDCONST R19 K33 - 0x984A0613, // 0093 SETIDX R18 K3 R19 - 0x984A420A, // 0094 SETIDX R18 K33 R10 - 0x980C2212, // 0095 SETIDX R3 R17 R18 - 0x00100905, // 0096 ADD R4 R4 K5 - 0x00281505, // 0097 ADD R10 R10 K5 - 0x7001FFB3, // 0098 JMP #004D - 0x6028000C, // 0099 GETGBL R10 G12 - 0xB82E2000, // 009A GETNGBL R11 K16 - 0x8C2C1722, // 009B GETMET R11 R11 K34 - 0x7C2C0200, // 009C CALL R11 1 - 0x7C280200, // 009D CALL R10 1 - 0x582C000B, // 009E LDCONST R11 K11 - 0x78160000, // 009F JMPF R5 #00A1 - 0x04281505, // 00A0 SUB R10 R10 K5 - 0x1430160A, // 00A1 LT R12 R11 R10 - 0x78320010, // 00A2 JMPF R12 #00B4 - 0x8C301308, // 00A3 GETMET R12 R9 K8 - 0x5C381600, // 00A4 MOVE R14 R11 - 0x7C300400, // 00A5 CALL R12 2 - 0x4C340000, // 00A6 LDNIL R13 - 0x1C30180D, // 00A7 EQ R12 R12 R13 - 0x78320008, // 00A8 JMPF R12 #00B2 - 0x60300008, // 00A9 GETGBL R12 G8 - 0x5C340800, // 00AA MOVE R13 R4 - 0x7C300200, // 00AB CALL R12 1 - 0x60340013, // 00AC GETGBL R13 G19 - 0x7C340000, // 00AD CALL R13 0 - 0x98360723, // 00AE SETIDX R13 K3 K35 - 0x9836460B, // 00AF SETIDX R13 K35 R11 - 0x980C180D, // 00B0 SETIDX R3 R12 R13 - 0x00100905, // 00B1 ADD R4 R4 K5 - 0x002C1705, // 00B2 ADD R11 R11 K5 - 0x7001FFEC, // 00B3 JMP #00A1 - 0x8C300524, // 00B4 GETMET R12 R2 K36 - 0xB83A2000, // 00B5 GETNGBL R14 K16 - 0x8C381D25, // 00B6 GETMET R14 R14 K37 - 0x7C380200, // 00B7 CALL R14 1 - 0x7C300400, // 00B8 CALL R12 2 - 0x5412001F, // 00B9 LDINT R4 32 - 0x60340010, // 00BA GETGBL R13 G16 - 0x8C380126, // 00BB GETMET R14 R0 K38 - 0x5C401800, // 00BC MOVE R16 R12 - 0x7C380400, // 00BD CALL R14 2 - 0x7C340200, // 00BE CALL R13 1 - 0xA802001C, // 00BF EXBLK 0 #00DD - 0x5C381A00, // 00C0 MOVE R14 R13 - 0x7C380000, // 00C1 CALL R14 0 - 0x943C180E, // 00C2 GETIDX R15 R12 R14 - 0x6040000F, // 00C3 GETGBL R16 G15 - 0x5C441E00, // 00C4 MOVE R17 R15 - 0x60480013, // 00C5 GETGBL R18 G19 - 0x7C400400, // 00C6 CALL R16 2 - 0x7842000D, // 00C7 JMPF R16 #00D6 - 0x8C401F16, // 00C8 GETMET R16 R15 K22 - 0x58480027, // 00C9 LDCONST R18 K39 - 0x7C400400, // 00CA CALL R16 2 - 0x78420009, // 00CB JMPF R16 #00D6 - 0x00401D28, // 00CC ADD R16 R14 K40 - 0x60440008, // 00CD GETGBL R17 G8 - 0x5C480800, // 00CE MOVE R18 R4 - 0x7C440200, // 00CF CALL R17 1 - 0x60480013, // 00D0 GETGBL R18 G19 - 0x7C480000, // 00D1 CALL R18 0 - 0x984A0729, // 00D2 SETIDX R18 K3 K41 - 0x984A5410, // 00D3 SETIDX R18 K42 R16 - 0x980C2212, // 00D4 SETIDX R3 R17 R18 - 0x00100905, // 00D5 ADD R4 R4 K5 - 0x54420027, // 00D6 LDINT R16 40 - 0x24400810, // 00D7 GT R16 R4 R16 - 0x78420000, // 00D8 JMPF R16 #00DA - 0x70020000, // 00D9 JMP #00DB - 0x7001FFE4, // 00DA JMP #00C0 - 0xA8040001, // 00DB EXBLK 1 1 - 0x70020002, // 00DC JMP #00E0 - 0x5834002B, // 00DD LDCONST R13 K43 - 0xAC340200, // 00DE CATCH R13 1 0 - 0xB0080000, // 00DF RAISE 2 R0 R0 - 0x54120027, // 00E0 LDINT R4 40 - 0x60340010, // 00E1 GETGBL R13 G16 - 0x8C380126, // 00E2 GETMET R14 R0 K38 - 0x5C401800, // 00E3 MOVE R16 R12 - 0x7C380400, // 00E4 CALL R14 2 - 0x7C340200, // 00E5 CALL R13 1 - 0xA802001C, // 00E6 EXBLK 0 #0104 - 0x5C381A00, // 00E7 MOVE R14 R13 - 0x7C380000, // 00E8 CALL R14 0 - 0x943C180E, // 00E9 GETIDX R15 R12 R14 - 0x6040000F, // 00EA GETGBL R16 G15 - 0x5C441E00, // 00EB MOVE R17 R15 - 0x60480013, // 00EC GETGBL R18 G19 - 0x7C400400, // 00ED CALL R16 2 - 0x7842000D, // 00EE JMPF R16 #00FD - 0x8C401F16, // 00EF GETMET R16 R15 K22 - 0x5848002C, // 00F0 LDCONST R18 K44 - 0x7C400400, // 00F1 CALL R16 2 - 0x78420009, // 00F2 JMPF R16 #00FD - 0x00401D2D, // 00F3 ADD R16 R14 K45 - 0x60440008, // 00F4 GETGBL R17 G8 - 0x5C480800, // 00F5 MOVE R18 R4 - 0x7C440200, // 00F6 CALL R17 1 - 0x60480013, // 00F7 GETGBL R18 G19 - 0x7C480000, // 00F8 CALL R18 0 - 0x984A072E, // 00F9 SETIDX R18 K3 K46 - 0x984A5410, // 00FA SETIDX R18 K42 R16 - 0x980C2212, // 00FB SETIDX R3 R17 R18 - 0x00100905, // 00FC ADD R4 R4 K5 - 0x5442002E, // 00FD LDINT R16 47 - 0x24400810, // 00FE GT R16 R4 R16 - 0x78420000, // 00FF JMPF R16 #0101 - 0x70020000, // 0100 JMP #0102 - 0x7001FFE4, // 0101 JMP #00E7 - 0xA8040001, // 0102 EXBLK 1 1 - 0x70020002, // 0103 JMP #0107 - 0x5834002B, // 0104 LDCONST R13 K43 - 0xAC340200, // 0105 CATCH R13 1 0 - 0xB0080000, // 0106 RAISE 2 R0 R0 - 0x5412002F, // 0107 LDINT R4 48 - 0x60340010, // 0108 GETGBL R13 G16 - 0x8C380126, // 0109 GETMET R14 R0 K38 - 0x5C401800, // 010A MOVE R16 R12 - 0x7C380400, // 010B CALL R14 2 - 0x7C340200, // 010C CALL R13 1 - 0xA802001C, // 010D EXBLK 0 #012B - 0x5C381A00, // 010E MOVE R14 R13 - 0x7C380000, // 010F CALL R14 0 - 0x943C180E, // 0110 GETIDX R15 R12 R14 - 0x6040000F, // 0111 GETGBL R16 G15 - 0x5C441E00, // 0112 MOVE R17 R15 - 0x60480013, // 0113 GETGBL R18 G19 - 0x7C400400, // 0114 CALL R16 2 - 0x7842000D, // 0115 JMPF R16 #0124 - 0x8C401F16, // 0116 GETMET R16 R15 K22 - 0x5848002F, // 0117 LDCONST R18 K47 - 0x7C400400, // 0118 CALL R16 2 - 0x78420009, // 0119 JMPF R16 #0124 - 0x00401D30, // 011A ADD R16 R14 K48 - 0x60440008, // 011B GETGBL R17 G8 - 0x5C480800, // 011C MOVE R18 R4 - 0x7C440200, // 011D CALL R17 1 - 0x60480013, // 011E GETGBL R18 G19 - 0x7C480000, // 011F CALL R18 0 - 0x984A0731, // 0120 SETIDX R18 K3 K49 - 0x984A5410, // 0121 SETIDX R18 K42 R16 - 0x980C2212, // 0122 SETIDX R3 R17 R18 - 0x00100905, // 0123 ADD R4 R4 K5 - 0x54420037, // 0124 LDINT R16 56 - 0x24400810, // 0125 GT R16 R4 R16 - 0x78420000, // 0126 JMPF R16 #0128 - 0x70020000, // 0127 JMP #0129 - 0x7001FFE4, // 0128 JMP #010E - 0xA8040001, // 0129 EXBLK 1 1 - 0x70020002, // 012A JMP #012E - 0x5834002B, // 012B LDCONST R13 K43 - 0xAC340200, // 012C CATCH R13 1 0 - 0xB0080000, // 012D RAISE 2 R0 R0 - 0x54120037, // 012E LDINT R4 56 - 0x60340010, // 012F GETGBL R13 G16 - 0x8C380126, // 0130 GETMET R14 R0 K38 - 0x5C401800, // 0131 MOVE R16 R12 - 0x7C380400, // 0132 CALL R14 2 - 0x7C340200, // 0133 CALL R13 1 - 0xA802001C, // 0134 EXBLK 0 #0152 - 0x5C381A00, // 0135 MOVE R14 R13 - 0x7C380000, // 0136 CALL R14 0 - 0x943C180E, // 0137 GETIDX R15 R12 R14 - 0x6040000F, // 0138 GETGBL R16 G15 - 0x5C441E00, // 0139 MOVE R17 R15 - 0x60480013, // 013A GETGBL R18 G19 - 0x7C400400, // 013B CALL R16 2 - 0x7842000D, // 013C JMPF R16 #014B - 0x8C401F16, // 013D GETMET R16 R15 K22 - 0x58480032, // 013E LDCONST R18 K50 - 0x7C400400, // 013F CALL R16 2 - 0x78420009, // 0140 JMPF R16 #014B - 0x00401D33, // 0141 ADD R16 R14 K51 - 0x60440008, // 0142 GETGBL R17 G8 - 0x5C480800, // 0143 MOVE R18 R4 - 0x7C440200, // 0144 CALL R17 1 - 0x60480013, // 0145 GETGBL R18 G19 - 0x7C480000, // 0146 CALL R18 0 - 0x984A0734, // 0147 SETIDX R18 K3 K52 - 0x984A5410, // 0148 SETIDX R18 K42 R16 - 0x980C2212, // 0149 SETIDX R3 R17 R18 - 0x00100905, // 014A ADD R4 R4 K5 - 0x5442003F, // 014B LDINT R16 64 - 0x24400810, // 014C GT R16 R4 R16 - 0x78420000, // 014D JMPF R16 #014F - 0x70020000, // 014E JMP #0150 - 0x7001FFE4, // 014F JMP #0135 - 0xA8040001, // 0150 EXBLK 1 1 - 0x70020002, // 0151 JMP #0155 - 0x5834002B, // 0152 LDCONST R13 K43 - 0xAC340200, // 0153 CATCH R13 1 0 - 0xB0080000, // 0154 RAISE 2 R0 R0 - 0x80040600, // 0155 RET 1 R3 + ( &(const binstruction[40]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x1C080202, // 0001 EQ R2 R1 R2 + 0x780A0000, // 0002 JMPF R2 #0004 + 0x88040100, // 0003 GETMBR R1 R0 K0 + 0x8C080101, // 0004 GETMET R2 R0 K1 + 0x7C080200, // 0005 CALL R2 1 + 0xB80E0400, // 0006 GETNGBL R3 K2 + 0x8C0C0703, // 0007 GETMET R3 R3 K3 + 0x60140018, // 0008 GETGBL R5 G24 + 0x58180004, // 0009 LDCONST R6 K4 + 0x5C1C0400, // 000A MOVE R7 R2 + 0x7C140400, // 000B CALL R5 2 + 0x58180005, // 000C LDCONST R6 K5 + 0x7C0C0600, // 000D CALL R3 3 + 0x8C0C0106, // 000E GETMET R3 R0 K6 + 0x7C0C0200, // 000F CALL R3 1 + 0xB8120400, // 0010 GETNGBL R4 K2 + 0x8C100907, // 0011 GETMET R4 R4 K7 + 0x60180018, // 0012 GETGBL R6 G24 + 0x581C0008, // 0013 LDCONST R7 K8 + 0x5C200400, // 0014 MOVE R8 R2 + 0x5C240600, // 0015 MOVE R9 R3 + 0x7C180600, // 0016 CALL R6 3 + 0x581C0009, // 0017 LDCONST R7 K9 + 0x7C100600, // 0018 CALL R4 3 + 0x8C10010A, // 0019 GETMET R4 R0 K10 + 0x8818010B, // 001A GETMBR R6 R0 K11 + 0x881C010C, // 001B GETMBR R7 R0 K12 + 0x8820010D, // 001C GETMBR R8 R0 K13 + 0x7C100800, // 001D CALL R4 4 + 0x8C10010E, // 001E GETMET R4 R0 K14 + 0x5C180200, // 001F MOVE R6 R1 + 0x881C010C, // 0020 GETMBR R7 R0 K12 + 0x8820010F, // 0021 GETMBR R8 R0 K15 + 0x8824010D, // 0022 GETMBR R9 R0 K13 + 0x88280110, // 0023 GETMBR R10 R0 K16 + 0x882C0111, // 0024 GETMBR R11 R0 K17 + 0x4C300000, // 0025 LDNIL R12 + 0x7C101000, // 0026 CALL R4 8 + 0x80000000, // 0027 RET 0 }) ) ); @@ -2410,9 +3391,9 @@ be_local_closure(Matter_Device_autoconf_device_map, /* name */ /******************************************************************** -** Solidified function: is_commissioning_open +** Solidified function: save_before_restart ********************************************************************/ -be_local_closure(Matter_Device_is_commissioning_open, /* name */ +be_local_closure(Matter_Device_save_before_restart, /* name */ be_nested_proto( 3, /* nstack */ 1, /* argc */ @@ -2422,16 +3403,18 @@ be_local_closure(Matter_Device_is_commissioning_open, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(commissioning_open), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(stop_basic_commissioning), + /* K1 */ be_nested_str_weak(mdns_remove_op_discovery_all_fabrics), }), - be_str_weak(is_commissioning_open), + be_str_weak(save_before_restart), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x20040202, // 0002 NE R1 R1 R2 - 0x80040200, // 0003 RET 1 R1 + ( &(const binstruction[ 5]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x8C040101, // 0002 GETMET R1 R0 K1 + 0x7C040200, // 0003 CALL R1 1 + 0x80000000, // 0004 RET 0 }) ) ); @@ -2439,20 +3422,20 @@ be_local_closure(Matter_Device_is_commissioning_open, /* name */ /******************************************************************** -** Solidified function: init +** Solidified function: register_commands ********************************************************************/ -be_local_closure(Matter_Device_init, /* name */ +be_local_closure(Matter_Device_register_commands, /* name */ be_nested_proto( - 8, /* nstack */ + 5, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 1, /* has sup protos */ - ( &(const struct bproto*[ 2]) { + ( &(const struct bproto*[ 3]) { be_nested_proto( - 4, /* nstack */ - 0, /* argc */ + 10, /* nstack */ + 4, /* argc */ 0, /* varg */ 1, /* has upvals */ ( &(const bupvaldesc[ 1]) { /* upvals */ @@ -2461,30 +3444,52 @@ be_local_closure(Matter_Device_init, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(start), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(remove_rule), - /* K3 */ be_nested_str_weak(Wifi_X23Connected), - /* K4 */ be_nested_str_weak(matter_start), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(MtrJoin), }), - be_str_weak(_anonymous_), + be_str_weak(_X3Clambda_X3E), &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x68000000, // 0000 GETUPV R0 U0 - 0x8C000100, // 0001 GETMET R0 R0 K0 - 0x7C000200, // 0002 CALL R0 1 - 0xB8020200, // 0003 GETNGBL R0 K1 - 0x8C000102, // 0004 GETMET R0 R0 K2 - 0x58080003, // 0005 LDCONST R2 K3 - 0x580C0004, // 0006 LDCONST R3 K4 - 0x7C000600, // 0007 CALL R0 3 - 0x80000000, // 0008 RET 0 + ( &(const binstruction[ 8]) { /* code */ + 0x68100000, // 0000 GETUPV R4 U0 + 0x8C100900, // 0001 GETMET R4 R4 K0 + 0x5C180000, // 0002 MOVE R6 R0 + 0x5C1C0200, // 0003 MOVE R7 R1 + 0x5C200400, // 0004 MOVE R8 R2 + 0x5C240600, // 0005 MOVE R9 R3 + 0x7C100A00, // 0006 CALL R4 5 + 0x80040800, // 0007 RET 1 R4 }) ), be_nested_proto( - 4, /* nstack */ - 0, /* argc */ + 10, /* nstack */ + 4, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(MtrUpdate), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x68100000, // 0000 GETUPV R4 U0 + 0x8C100900, // 0001 GETMET R4 R4 K0 + 0x5C180000, // 0002 MOVE R6 R0 + 0x5C1C0200, // 0003 MOVE R7 R1 + 0x5C200400, // 0004 MOVE R8 R2 + 0x5C240600, // 0005 MOVE R9 R3 + 0x7C100A00, // 0006 CALL R4 5 + 0x80040800, // 0007 RET 1 R4 + }) + ), + be_nested_proto( + 10, /* nstack */ + 4, /* argc */ 0, /* varg */ 1, /* has upvals */ ( &(const bupvaldesc[ 1]) { /* upvals */ @@ -2493,177 +3498,51 @@ be_local_closure(Matter_Device_init, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(start), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(remove_rule), - /* K3 */ be_nested_str_weak(Eth_X23Connected), - /* K4 */ be_nested_str_weak(matter_start), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(MtrInfo), }), - be_str_weak(_anonymous_), + be_str_weak(_X3Clambda_X3E), &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x68000000, // 0000 GETUPV R0 U0 - 0x8C000100, // 0001 GETMET R0 R0 K0 - 0x7C000200, // 0002 CALL R0 1 - 0xB8020200, // 0003 GETNGBL R0 K1 - 0x8C000102, // 0004 GETMET R0 R0 K2 - 0x58080003, // 0005 LDCONST R2 K3 - 0x580C0004, // 0006 LDCONST R3 K4 - 0x7C000600, // 0007 CALL R0 3 - 0x80000000, // 0008 RET 0 + ( &(const binstruction[ 8]) { /* code */ + 0x68100000, // 0000 GETUPV R4 U0 + 0x8C100900, // 0001 GETMET R4 R4 K0 + 0x5C180000, // 0002 MOVE R6 R0 + 0x5C1C0200, // 0003 MOVE R7 R1 + 0x5C200400, // 0004 MOVE R8 R2 + 0x5C240600, // 0005 MOVE R9 R3 + 0x7C100A00, // 0006 CALL R4 5 + 0x80040800, // 0007 RET 1 R4 }) ), }), 1, /* has constants */ - ( &(const bvalue[41]) { /* constants */ - /* K0 */ be_nested_str_weak(crypto), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(get_option), - /* K4 */ be_nested_str_weak(matter), - /* K5 */ be_nested_str_weak(MATTER_OPTION), - /* K6 */ be_nested_str_weak(UI), - /* K7 */ be_nested_str_weak(started), - /* K8 */ be_nested_str_weak(tick), - /* K9 */ be_const_int(0), - /* K10 */ be_nested_str_weak(plugins), - /* K11 */ be_nested_str_weak(plugins_persist), - /* K12 */ be_nested_str_weak(plugins_classes), - /* K13 */ be_nested_str_weak(register_native_classes), - /* K14 */ be_nested_str_weak(vendorid), - /* K15 */ be_nested_str_weak(VENDOR_ID), - /* K16 */ be_nested_str_weak(productid), - /* K17 */ be_nested_str_weak(PRODUCT_ID), - /* K18 */ be_nested_str_weak(root_iterations), - /* K19 */ be_nested_str_weak(PBKDF_ITERATIONS), - /* K20 */ be_nested_str_weak(root_salt), - /* K21 */ be_nested_str_weak(random), - /* K22 */ be_nested_str_weak(ipv4only), - /* K23 */ be_nested_str_weak(load_param), - /* K24 */ be_nested_str_weak(sessions), - /* K25 */ be_nested_str_weak(Session_Store), - /* K26 */ be_nested_str_weak(load_fabrics), - /* K27 */ be_nested_str_weak(message_handler), - /* K28 */ be_nested_str_weak(MessageHandler), - /* K29 */ be_nested_str_weak(ui), - /* K30 */ be_nested_str_weak(wifi), - /* K31 */ be_nested_str_weak(up), - /* K32 */ be_nested_str_weak(eth), - /* K33 */ be_nested_str_weak(start), - /* K34 */ be_nested_str_weak(add_rule), - /* K35 */ be_nested_str_weak(Wifi_X23Connected), - /* K36 */ be_nested_str_weak(matter_start), - /* K37 */ be_nested_str_weak(Eth_X23Connected), - /* K38 */ be_nested_str_weak(_init_basic_commissioning), - /* K39 */ be_nested_str_weak(add_driver), - /* K40 */ be_nested_str_weak(register_commands), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(add_cmd), + /* K2 */ be_nested_str_weak(MtrJoin), + /* K3 */ be_nested_str_weak(MtrUpdate), + /* K4 */ be_nested_str_weak(MtrInfo), }), - be_str_weak(init), + be_str_weak(register_commands), &be_const_str_solidified, - ( &(const binstruction[102]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0xB80E0400, // 0002 GETNGBL R3 K2 - 0x8C0C0703, // 0003 GETMET R3 R3 K3 - 0xB8160800, // 0004 GETNGBL R5 K4 - 0x88140B05, // 0005 GETMBR R5 R5 K5 - 0x7C0C0400, // 0006 CALL R3 2 - 0x740E0004, // 0007 JMPT R3 #000D - 0xB80E0800, // 0008 GETNGBL R3 K4 - 0x8C0C0706, // 0009 GETMET R3 R3 K6 - 0x5C140000, // 000A MOVE R5 R0 - 0x7C0C0400, // 000B CALL R3 2 - 0x80000600, // 000C RET 0 - 0x500C0000, // 000D LDBOOL R3 0 0 - 0x90020E03, // 000E SETMBR R0 K7 R3 - 0x90021109, // 000F SETMBR R0 K8 K9 - 0x600C0012, // 0010 GETGBL R3 G18 - 0x7C0C0000, // 0011 CALL R3 0 - 0x90021403, // 0012 SETMBR R0 K10 R3 - 0x500C0000, // 0013 LDBOOL R3 0 0 - 0x90021603, // 0014 SETMBR R0 K11 R3 - 0x600C0013, // 0015 GETGBL R3 G19 - 0x7C0C0000, // 0016 CALL R3 0 - 0x90021803, // 0017 SETMBR R0 K12 R3 - 0x8C0C010D, // 0018 GETMET R3 R0 K13 - 0x7C0C0200, // 0019 CALL R3 1 - 0x880C010F, // 001A GETMBR R3 R0 K15 - 0x90021C03, // 001B SETMBR R0 K14 R3 - 0x880C0111, // 001C GETMBR R3 R0 K17 - 0x90022003, // 001D SETMBR R0 K16 R3 - 0x880C0113, // 001E GETMBR R3 R0 K19 - 0x90022403, // 001F SETMBR R0 K18 R3 - 0x8C0C0315, // 0020 GETMET R3 R1 K21 - 0x5416000F, // 0021 LDINT R5 16 - 0x7C0C0400, // 0022 CALL R3 2 - 0x90022803, // 0023 SETMBR R0 K20 R3 - 0x500C0000, // 0024 LDBOOL R3 0 0 - 0x90022C03, // 0025 SETMBR R0 K22 R3 - 0x8C0C0117, // 0026 GETMET R3 R0 K23 - 0x7C0C0200, // 0027 CALL R3 1 - 0xB80E0800, // 0028 GETNGBL R3 K4 - 0x8C0C0719, // 0029 GETMET R3 R3 K25 - 0x5C140000, // 002A MOVE R5 R0 - 0x7C0C0400, // 002B CALL R3 2 - 0x90023003, // 002C SETMBR R0 K24 R3 - 0x880C0118, // 002D GETMBR R3 R0 K24 - 0x8C0C071A, // 002E GETMET R3 R3 K26 - 0x7C0C0200, // 002F CALL R3 1 - 0xB80E0800, // 0030 GETNGBL R3 K4 - 0x8C0C071C, // 0031 GETMET R3 R3 K28 - 0x5C140000, // 0032 MOVE R5 R0 - 0x7C0C0400, // 0033 CALL R3 2 - 0x90023603, // 0034 SETMBR R0 K27 R3 - 0xB80E0800, // 0035 GETNGBL R3 K4 - 0x8C0C0706, // 0036 GETMET R3 R3 K6 - 0x5C140000, // 0037 MOVE R5 R0 - 0x7C0C0400, // 0038 CALL R3 2 - 0x90023A03, // 0039 SETMBR R0 K29 R3 - 0xB80E0400, // 003A GETNGBL R3 K2 - 0x8C0C071E, // 003B GETMET R3 R3 K30 - 0x7C0C0200, // 003C CALL R3 1 - 0x940C071F, // 003D GETIDX R3 R3 K31 - 0x740E0004, // 003E JMPT R3 #0044 - 0xB80E0400, // 003F GETNGBL R3 K2 - 0x8C0C0720, // 0040 GETMET R3 R3 K32 - 0x7C0C0200, // 0041 CALL R3 1 - 0x940C071F, // 0042 GETIDX R3 R3 K31 - 0x780E0001, // 0043 JMPF R3 #0046 - 0x8C0C0121, // 0044 GETMET R3 R0 K33 - 0x7C0C0200, // 0045 CALL R3 1 - 0xB80E0400, // 0046 GETNGBL R3 K2 - 0x8C0C071E, // 0047 GETMET R3 R3 K30 - 0x7C0C0200, // 0048 CALL R3 1 - 0x940C071F, // 0049 GETIDX R3 R3 K31 - 0x740E0005, // 004A JMPT R3 #0051 - 0xB80E0400, // 004B GETNGBL R3 K2 - 0x8C0C0722, // 004C GETMET R3 R3 K34 - 0x58140023, // 004D LDCONST R5 K35 - 0x84180000, // 004E CLOSURE R6 P0 - 0x581C0024, // 004F LDCONST R7 K36 - 0x7C0C0800, // 0050 CALL R3 4 - 0xB80E0400, // 0051 GETNGBL R3 K2 - 0x8C0C0720, // 0052 GETMET R3 R3 K32 - 0x7C0C0200, // 0053 CALL R3 1 - 0x940C071F, // 0054 GETIDX R3 R3 K31 - 0x740E0005, // 0055 JMPT R3 #005C - 0xB80E0400, // 0056 GETNGBL R3 K2 - 0x8C0C0722, // 0057 GETMET R3 R3 K34 - 0x58140025, // 0058 LDCONST R5 K37 - 0x84180001, // 0059 CLOSURE R6 P1 - 0x581C0024, // 005A LDCONST R7 K36 - 0x7C0C0800, // 005B CALL R3 4 - 0x8C0C0126, // 005C GETMET R3 R0 K38 - 0x7C0C0200, // 005D CALL R3 1 - 0xB80E0400, // 005E GETNGBL R3 K2 - 0x8C0C0727, // 005F GETMET R3 R3 K39 - 0x5C140000, // 0060 MOVE R5 R0 - 0x7C0C0400, // 0061 CALL R3 2 - 0x8C0C0128, // 0062 GETMET R3 R0 K40 - 0x7C0C0200, // 0063 CALL R3 1 - 0xA0000000, // 0064 CLOSE R0 - 0x80000000, // 0065 RET 0 + ( &(const binstruction[17]) { /* code */ + 0xB8060000, // 0000 GETNGBL R1 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x580C0002, // 0002 LDCONST R3 K2 + 0x84100000, // 0003 CLOSURE R4 P0 + 0x7C040600, // 0004 CALL R1 3 + 0xB8060000, // 0005 GETNGBL R1 K0 + 0x8C040301, // 0006 GETMET R1 R1 K1 + 0x580C0003, // 0007 LDCONST R3 K3 + 0x84100001, // 0008 CLOSURE R4 P1 + 0x7C040600, // 0009 CALL R1 3 + 0xB8060000, // 000A GETNGBL R1 K0 + 0x8C040301, // 000B GETMET R1 R1 K1 + 0x580C0004, // 000C LDCONST R3 K4 + 0x84100002, // 000D CLOSURE R4 P2 + 0x7C040600, // 000E CALL R1 3 + 0xA0000000, // 000F CLOSE R0 + 0x80000000, // 0010 RET 0 }) ) ); @@ -2671,11 +3550,11 @@ be_local_closure(Matter_Device_init, /* name */ /******************************************************************** -** Solidified function: mdns_remove_op_discovery +** Solidified function: MtrInfo_one ********************************************************************/ -be_local_closure(Matter_Device_mdns_remove_op_discovery, /* name */ +be_local_closure(Matter_Device_MtrInfo_one, /* name */ be_nested_proto( - 14, /* nstack */ + 9, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2683,116 +3562,37 @@ be_local_closure(Matter_Device_mdns_remove_op_discovery, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[24]) { /* constants */ - /* K0 */ be_nested_str_weak(mdns), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(get_device_id), - /* K3 */ be_nested_str_weak(copy), - /* K4 */ be_nested_str_weak(reverse), - /* K5 */ be_nested_str_weak(get_fabric_compressed), - /* K6 */ be_nested_str_weak(tohex), - /* K7 */ be_nested_str_weak(_X2D), - /* K8 */ be_nested_str_weak(tasmota), - /* K9 */ be_nested_str_weak(eth), - /* K10 */ be_nested_str_weak(find), - /* K11 */ be_nested_str_weak(up), - /* K12 */ be_nested_str_weak(log), - /* K13 */ be_nested_str_weak(format), - /* K14 */ be_nested_str_weak(MTR_X3A_X20remove_X20mDNS_X20on_X20_X25s_X20_X27_X25s_X27), - /* K15 */ be_const_int(2), - /* K16 */ be_nested_str_weak(remove_service), - /* K17 */ be_nested_str_weak(_matter), - /* K18 */ be_nested_str_weak(_tcp), - /* K19 */ be_nested_str_weak(hostname_eth), - /* K20 */ be_nested_str_weak(wifi), - /* K21 */ be_nested_str_weak(hostname_wifi), - /* K22 */ be_nested_str_weak(MTR_X3A_X20Exception), - /* K23 */ be_nested_str_weak(_X7C), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(find_plugin_by_endpoint), + /* K1 */ be_nested_str_weak(state_json), + /* K2 */ be_nested_str_weak(_X7B_X22MtrInfo_X22_X3A_X25s_X7D), + /* K3 */ be_nested_str_weak(tasmota), + /* K4 */ be_nested_str_weak(publish_result), + /* K5 */ be_nested_str_weak(), }), - be_str_weak(mdns_remove_op_discovery), + be_str_weak(MtrInfo_one), &be_const_str_solidified, - ( &(const binstruction[81]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0xA40E0200, // 0001 IMPORT R3 K1 - 0xA802003B, // 0002 EXBLK 0 #003F - 0x8C100302, // 0003 GETMET R4 R1 K2 - 0x7C100200, // 0004 CALL R4 1 - 0x8C100903, // 0005 GETMET R4 R4 K3 - 0x7C100200, // 0006 CALL R4 1 - 0x8C100904, // 0007 GETMET R4 R4 K4 - 0x7C100200, // 0008 CALL R4 1 - 0x8C140305, // 0009 GETMET R5 R1 K5 - 0x7C140200, // 000A CALL R5 1 - 0x8C180B06, // 000B GETMET R6 R5 K6 - 0x7C180200, // 000C CALL R6 1 - 0x00180D07, // 000D ADD R6 R6 K7 - 0x8C1C0906, // 000E GETMET R7 R4 K6 - 0x7C1C0200, // 000F CALL R7 1 - 0x00180C07, // 0010 ADD R6 R6 R7 - 0xB81E1000, // 0011 GETNGBL R7 K8 - 0x8C1C0F09, // 0012 GETMET R7 R7 K9 - 0x7C1C0200, // 0013 CALL R7 1 - 0x8C1C0F0A, // 0014 GETMET R7 R7 K10 - 0x5824000B, // 0015 LDCONST R9 K11 - 0x7C1C0400, // 0016 CALL R7 2 - 0x781E000E, // 0017 JMPF R7 #0027 - 0xB81E1000, // 0018 GETNGBL R7 K8 - 0x8C1C0F0C, // 0019 GETMET R7 R7 K12 - 0x8C24070D, // 001A GETMET R9 R3 K13 - 0x582C000E, // 001B LDCONST R11 K14 - 0x58300009, // 001C LDCONST R12 K9 - 0x5C340C00, // 001D MOVE R13 R6 - 0x7C240800, // 001E CALL R9 4 - 0x5828000F, // 001F LDCONST R10 K15 - 0x7C1C0600, // 0020 CALL R7 3 - 0x8C1C0510, // 0021 GETMET R7 R2 K16 - 0x58240011, // 0022 LDCONST R9 K17 - 0x58280012, // 0023 LDCONST R10 K18 - 0x5C2C0C00, // 0024 MOVE R11 R6 - 0x88300113, // 0025 GETMBR R12 R0 K19 - 0x7C1C0A00, // 0026 CALL R7 5 - 0xB81E1000, // 0027 GETNGBL R7 K8 - 0x8C1C0F14, // 0028 GETMET R7 R7 K20 - 0x7C1C0200, // 0029 CALL R7 1 - 0x8C1C0F0A, // 002A GETMET R7 R7 K10 - 0x5824000B, // 002B LDCONST R9 K11 - 0x7C1C0400, // 002C CALL R7 2 - 0x781E000E, // 002D JMPF R7 #003D - 0xB81E1000, // 002E GETNGBL R7 K8 - 0x8C1C0F0C, // 002F GETMET R7 R7 K12 - 0x8C24070D, // 0030 GETMET R9 R3 K13 - 0x582C000E, // 0031 LDCONST R11 K14 - 0x58300014, // 0032 LDCONST R12 K20 - 0x5C340C00, // 0033 MOVE R13 R6 - 0x7C240800, // 0034 CALL R9 4 - 0x5828000F, // 0035 LDCONST R10 K15 - 0x7C1C0600, // 0036 CALL R7 3 - 0x8C1C0510, // 0037 GETMET R7 R2 K16 - 0x58240011, // 0038 LDCONST R9 K17 - 0x58280012, // 0039 LDCONST R10 K18 - 0x5C2C0C00, // 003A MOVE R11 R6 - 0x88300115, // 003B GETMBR R12 R0 K21 - 0x7C1C0A00, // 003C CALL R7 5 - 0xA8040001, // 003D EXBLK 1 1 - 0x70020010, // 003E JMP #0050 - 0xAC100002, // 003F CATCH R4 0 2 - 0x7002000D, // 0040 JMP #004F - 0xB81A1000, // 0041 GETNGBL R6 K8 - 0x8C180D0C, // 0042 GETMET R6 R6 K12 - 0x60200008, // 0043 GETGBL R8 G8 - 0x5C240800, // 0044 MOVE R9 R4 - 0x7C200200, // 0045 CALL R8 1 - 0x00222C08, // 0046 ADD R8 K22 R8 - 0x00201117, // 0047 ADD R8 R8 K23 - 0x60240008, // 0048 GETGBL R9 G8 - 0x5C280A00, // 0049 MOVE R10 R5 - 0x7C240200, // 004A CALL R9 1 - 0x00201009, // 004B ADD R8 R8 R9 - 0x5824000F, // 004C LDCONST R9 K15 - 0x7C180600, // 004D CALL R6 3 - 0x70020000, // 004E JMP #0050 - 0xB0080000, // 004F RAISE 2 R0 R0 - 0x80000000, // 0050 RET 0 + ( &(const binstruction[20]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0x4C0C0000, // 0003 LDNIL R3 + 0x1C0C0403, // 0004 EQ R3 R2 R3 + 0x780E0000, // 0005 JMPF R3 #0007 + 0x80000600, // 0006 RET 0 + 0x8C0C0501, // 0007 GETMET R3 R2 K1 + 0x7C0C0200, // 0008 CALL R3 1 + 0x780E0008, // 0009 JMPF R3 #0013 + 0x60100018, // 000A GETGBL R4 G24 + 0x58140002, // 000B LDCONST R5 K2 + 0x5C180600, // 000C MOVE R6 R3 + 0x7C100400, // 000D CALL R4 2 + 0xB8160600, // 000E GETNGBL R5 K3 + 0x8C140B04, // 000F GETMET R5 R5 K4 + 0x5C1C0800, // 0010 MOVE R7 R4 + 0x58200005, // 0011 LDCONST R8 K5 + 0x7C140600, // 0012 CALL R5 3 + 0x80000000, // 0013 RET 0 }) ) ); @@ -2800,11 +3600,11 @@ be_local_closure(Matter_Device_mdns_remove_op_discovery, /* name */ /******************************************************************** -** Solidified function: _mdns_announce_hostname +** Solidified function: find_plugin_by_friendly_name ********************************************************************/ -be_local_closure(Matter_Device__mdns_announce_hostname, /* name */ +be_local_closure(Matter_Device_find_plugin_by_friendly_name, /* name */ be_nested_proto( - 16, /* nstack */ + 7, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2812,211 +3612,50 @@ be_local_closure(Matter_Device__mdns_announce_hostname, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[28]) { /* constants */ - /* K0 */ be_nested_str_weak(mdns), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(start), - /* K3 */ be_nested_str_weak(tasmota), - /* K4 */ be_nested_str_weak(eth), - /* K5 */ be_nested_str_weak(hostname_eth), - /* K6 */ be_nested_str_weak(replace), - /* K7 */ be_nested_str_weak(find), - /* K8 */ be_nested_str_weak(mac), - /* K9 */ be_nested_str_weak(_X3A), - /* K10 */ be_nested_str_weak(), - /* K11 */ be_nested_str_weak(ipv4only), - /* K12 */ be_nested_str_weak(log), - /* K13 */ be_nested_str_weak(format), - /* K14 */ be_nested_str_weak(MTR_X3A_X20calling_X20mdns_X2Eadd_hostname_X28_X25s_X2C_X20_X25s_X2C_X20_X25s_X29), - /* K15 */ be_nested_str_weak(ip6local), - /* K16 */ be_nested_str_weak(ip), - /* K17 */ be_const_int(3), - /* K18 */ be_nested_str_weak(add_hostname), - /* K19 */ be_nested_str_weak(ip6), - /* K20 */ be_nested_str_weak(MTR_X3A_X20calling_X20mdns_X2Eadd_hostname_X28_X25s_X2C_X20_X25s_X29), - /* K21 */ be_nested_str_weak(wifi), - /* K22 */ be_nested_str_weak(hostname_wifi), - /* K23 */ be_nested_str_weak(MTR_X3A_X20start_X20mDNS_X20on_X20_X25s_X20host_X20_X27_X25s_X2Elocal_X27), - /* K24 */ be_const_int(2), - /* K25 */ be_nested_str_weak(MTR_X3A_X20Exception), - /* K26 */ be_nested_str_weak(_X7C), - /* K27 */ be_nested_str_weak(mdns_announce_op_discovery_all_fabrics), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(plugins), + /* K2 */ be_nested_str_weak(get_name), + /* K3 */ be_const_int(1), }), - be_str_weak(_mdns_announce_hostname), + be_str_weak(find_plugin_by_friendly_name), &be_const_str_solidified, - ( &(const binstruction[172]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0xA40E0200, // 0001 IMPORT R3 K1 - 0x8C100502, // 0002 GETMET R4 R2 K2 - 0x7C100200, // 0003 CALL R4 1 - 0xA8020092, // 0004 EXBLK 0 #0098 - 0x78060040, // 0005 JMPF R1 #0047 - 0xB8120600, // 0006 GETNGBL R4 K3 - 0x8C100904, // 0007 GETMET R4 R4 K4 - 0x7C100200, // 0008 CALL R4 1 - 0x8C140706, // 0009 GETMET R5 R3 K6 - 0x8C1C0907, // 000A GETMET R7 R4 K7 - 0x58240008, // 000B LDCONST R9 K8 - 0x7C1C0400, // 000C CALL R7 2 - 0x58200009, // 000D LDCONST R8 K9 - 0x5824000A, // 000E LDCONST R9 K10 - 0x7C140800, // 000F CALL R5 4 - 0x90020A05, // 0010 SETMBR R0 K5 R5 - 0x8814010B, // 0011 GETMBR R5 R0 K11 - 0x7416001F, // 0012 JMPT R5 #0033 - 0xB8160600, // 0013 GETNGBL R5 K3 - 0x8C140B0C, // 0014 GETMET R5 R5 K12 - 0x8C1C070D, // 0015 GETMET R7 R3 K13 - 0x5824000E, // 0016 LDCONST R9 K14 - 0x88280105, // 0017 GETMBR R10 R0 K5 - 0x8C2C0907, // 0018 GETMET R11 R4 K7 - 0x5834000F, // 0019 LDCONST R13 K15 - 0x5838000A, // 001A LDCONST R14 K10 - 0x7C2C0600, // 001B CALL R11 3 - 0x8C300907, // 001C GETMET R12 R4 K7 - 0x58380010, // 001D LDCONST R14 K16 - 0x583C000A, // 001E LDCONST R15 K10 - 0x7C300600, // 001F CALL R12 3 - 0x7C1C0A00, // 0020 CALL R7 5 - 0x58200011, // 0021 LDCONST R8 K17 - 0x7C140600, // 0022 CALL R5 3 - 0x8C140512, // 0023 GETMET R5 R2 K18 - 0x881C0105, // 0024 GETMBR R7 R0 K5 - 0x8C200907, // 0025 GETMET R8 R4 K7 - 0x5828000F, // 0026 LDCONST R10 K15 - 0x582C000A, // 0027 LDCONST R11 K10 - 0x7C200600, // 0028 CALL R8 3 - 0x8C240907, // 0029 GETMET R9 R4 K7 - 0x582C0010, // 002A LDCONST R11 K16 - 0x5830000A, // 002B LDCONST R12 K10 - 0x7C240600, // 002C CALL R9 3 - 0x8C280907, // 002D GETMET R10 R4 K7 - 0x58300013, // 002E LDCONST R12 K19 - 0x5834000A, // 002F LDCONST R13 K10 - 0x7C280600, // 0030 CALL R10 3 - 0x7C140A00, // 0031 CALL R5 5 - 0x70020012, // 0032 JMP #0046 - 0xB8160600, // 0033 GETNGBL R5 K3 - 0x8C140B0C, // 0034 GETMET R5 R5 K12 - 0x8C1C070D, // 0035 GETMET R7 R3 K13 - 0x58240014, // 0036 LDCONST R9 K20 - 0x88280105, // 0037 GETMBR R10 R0 K5 - 0x8C2C0907, // 0038 GETMET R11 R4 K7 - 0x58340010, // 0039 LDCONST R13 K16 - 0x5838000A, // 003A LDCONST R14 K10 - 0x7C2C0600, // 003B CALL R11 3 - 0x7C1C0800, // 003C CALL R7 4 - 0x58200011, // 003D LDCONST R8 K17 - 0x7C140600, // 003E CALL R5 3 - 0x8C140512, // 003F GETMET R5 R2 K18 - 0x881C0105, // 0040 GETMBR R7 R0 K5 - 0x8C200907, // 0041 GETMET R8 R4 K7 - 0x58280010, // 0042 LDCONST R10 K16 - 0x582C000A, // 0043 LDCONST R11 K10 - 0x7C200600, // 0044 CALL R8 3 - 0x7C140600, // 0045 CALL R5 3 - 0x7002003F, // 0046 JMP #0087 - 0xB8120600, // 0047 GETNGBL R4 K3 - 0x8C100915, // 0048 GETMET R4 R4 K21 - 0x7C100200, // 0049 CALL R4 1 - 0x8C140706, // 004A GETMET R5 R3 K6 - 0x8C1C0907, // 004B GETMET R7 R4 K7 - 0x58240008, // 004C LDCONST R9 K8 - 0x7C1C0400, // 004D CALL R7 2 - 0x58200009, // 004E LDCONST R8 K9 - 0x5824000A, // 004F LDCONST R9 K10 - 0x7C140800, // 0050 CALL R5 4 - 0x90022C05, // 0051 SETMBR R0 K22 R5 - 0x8814010B, // 0052 GETMBR R5 R0 K11 - 0x7416001F, // 0053 JMPT R5 #0074 - 0xB8160600, // 0054 GETNGBL R5 K3 - 0x8C140B0C, // 0055 GETMET R5 R5 K12 - 0x8C1C070D, // 0056 GETMET R7 R3 K13 - 0x5824000E, // 0057 LDCONST R9 K14 - 0x88280116, // 0058 GETMBR R10 R0 K22 - 0x8C2C0907, // 0059 GETMET R11 R4 K7 - 0x5834000F, // 005A LDCONST R13 K15 - 0x5838000A, // 005B LDCONST R14 K10 - 0x7C2C0600, // 005C CALL R11 3 - 0x8C300907, // 005D GETMET R12 R4 K7 - 0x58380010, // 005E LDCONST R14 K16 - 0x583C000A, // 005F LDCONST R15 K10 - 0x7C300600, // 0060 CALL R12 3 - 0x7C1C0A00, // 0061 CALL R7 5 - 0x58200011, // 0062 LDCONST R8 K17 - 0x7C140600, // 0063 CALL R5 3 - 0x8C140512, // 0064 GETMET R5 R2 K18 - 0x881C0116, // 0065 GETMBR R7 R0 K22 - 0x8C200907, // 0066 GETMET R8 R4 K7 - 0x5828000F, // 0067 LDCONST R10 K15 - 0x582C000A, // 0068 LDCONST R11 K10 - 0x7C200600, // 0069 CALL R8 3 - 0x8C240907, // 006A GETMET R9 R4 K7 - 0x582C0010, // 006B LDCONST R11 K16 - 0x5830000A, // 006C LDCONST R12 K10 - 0x7C240600, // 006D CALL R9 3 - 0x8C280907, // 006E GETMET R10 R4 K7 - 0x58300013, // 006F LDCONST R12 K19 - 0x5834000A, // 0070 LDCONST R13 K10 - 0x7C280600, // 0071 CALL R10 3 - 0x7C140A00, // 0072 CALL R5 5 - 0x70020012, // 0073 JMP #0087 - 0xB8160600, // 0074 GETNGBL R5 K3 - 0x8C140B0C, // 0075 GETMET R5 R5 K12 - 0x8C1C070D, // 0076 GETMET R7 R3 K13 - 0x58240014, // 0077 LDCONST R9 K20 - 0x88280105, // 0078 GETMBR R10 R0 K5 - 0x8C2C0907, // 0079 GETMET R11 R4 K7 - 0x58340010, // 007A LDCONST R13 K16 - 0x5838000A, // 007B LDCONST R14 K10 - 0x7C2C0600, // 007C CALL R11 3 - 0x7C1C0800, // 007D CALL R7 4 - 0x58200011, // 007E LDCONST R8 K17 - 0x7C140600, // 007F CALL R5 3 - 0x8C140512, // 0080 GETMET R5 R2 K18 - 0x881C0116, // 0081 GETMBR R7 R0 K22 - 0x8C200907, // 0082 GETMET R8 R4 K7 - 0x58280010, // 0083 LDCONST R10 K16 - 0x582C000A, // 0084 LDCONST R11 K10 - 0x7C200600, // 0085 CALL R8 3 - 0x7C140600, // 0086 CALL R5 3 - 0xB8120600, // 0087 GETNGBL R4 K3 - 0x8C10090C, // 0088 GETMET R4 R4 K12 - 0x8C18070D, // 0089 GETMET R6 R3 K13 - 0x58200017, // 008A LDCONST R8 K23 - 0x78060001, // 008B JMPF R1 #008E - 0x58240004, // 008C LDCONST R9 K4 - 0x70020000, // 008D JMP #008F - 0x58240015, // 008E LDCONST R9 K21 - 0x78060001, // 008F JMPF R1 #0092 - 0x88280105, // 0090 GETMBR R10 R0 K5 - 0x70020000, // 0091 JMP #0093 - 0x88280116, // 0092 GETMBR R10 R0 K22 - 0x7C180800, // 0093 CALL R6 4 - 0x581C0018, // 0094 LDCONST R7 K24 - 0x7C100600, // 0095 CALL R4 3 - 0xA8040001, // 0096 EXBLK 1 1 - 0x70020010, // 0097 JMP #00A9 - 0xAC100002, // 0098 CATCH R4 0 2 - 0x7002000D, // 0099 JMP #00A8 - 0xB81A0600, // 009A GETNGBL R6 K3 - 0x8C180D0C, // 009B GETMET R6 R6 K12 - 0x60200008, // 009C GETGBL R8 G8 - 0x5C240800, // 009D MOVE R9 R4 - 0x7C200200, // 009E CALL R8 1 - 0x00223208, // 009F ADD R8 K25 R8 - 0x0020111A, // 00A0 ADD R8 R8 K26 - 0x60240008, // 00A1 GETGBL R9 G8 - 0x5C280A00, // 00A2 MOVE R10 R5 - 0x7C240200, // 00A3 CALL R9 1 - 0x00201009, // 00A4 ADD R8 R8 R9 - 0x58240018, // 00A5 LDCONST R9 K24 - 0x7C180600, // 00A6 CALL R6 3 - 0x70020000, // 00A7 JMP #00A9 - 0xB0080000, // 00A8 RAISE 2 R0 R0 - 0x8C10011B, // 00A9 GETMET R4 R0 K27 - 0x7C100200, // 00AA CALL R4 1 - 0x80000000, // 00AB RET 0 + ( &(const binstruction[35]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x1C080202, // 0001 EQ R2 R1 R2 + 0x740A0004, // 0002 JMPT R2 #0008 + 0x6008000C, // 0003 GETGBL R2 G12 + 0x5C0C0200, // 0004 MOVE R3 R1 + 0x7C080200, // 0005 CALL R2 1 + 0x1C080500, // 0006 EQ R2 R2 K0 + 0x780A0001, // 0007 JMPF R2 #000A + 0x4C080000, // 0008 LDNIL R2 + 0x80040400, // 0009 RET 1 R2 + 0x58080000, // 000A LDCONST R2 K0 + 0x600C000C, // 000B GETGBL R3 G12 + 0x88100101, // 000C GETMBR R4 R0 K1 + 0x7C0C0200, // 000D CALL R3 1 + 0x140C0403, // 000E LT R3 R2 R3 + 0x780E0010, // 000F JMPF R3 #0021 + 0x880C0101, // 0010 GETMBR R3 R0 K1 + 0x940C0602, // 0011 GETIDX R3 R3 R2 + 0x8C100702, // 0012 GETMET R4 R3 K2 + 0x7C100200, // 0013 CALL R4 1 + 0x4C140000, // 0014 LDNIL R5 + 0x20140805, // 0015 NE R5 R4 R5 + 0x78160007, // 0016 JMPF R5 #001F + 0x6014000C, // 0017 GETGBL R5 G12 + 0x5C180800, // 0018 MOVE R6 R4 + 0x7C140200, // 0019 CALL R5 1 + 0x24140B00, // 001A GT R5 R5 K0 + 0x78160002, // 001B JMPF R5 #001F + 0x1C140801, // 001C EQ R5 R4 R1 + 0x78160000, // 001D JMPF R5 #001F + 0x80040600, // 001E RET 1 R3 + 0x00080503, // 001F ADD R2 R2 K3 + 0x7001FFE9, // 0020 JMP #000B + 0x4C0C0000, // 0021 LDNIL R3 + 0x80040600, // 0022 RET 1 R3 }) ) ); @@ -3024,131 +3663,47 @@ be_local_closure(Matter_Device__mdns_announce_hostname, /* name */ /******************************************************************** -** Solidified function: start_mdns_announce_hostnames +** Solidified function: every_second ********************************************************************/ -be_local_closure(Matter_Device_start_mdns_announce_hostnames, /* name */ +be_local_closure(Matter_Device_every_second, /* name */ be_nested_proto( - 6, /* nstack */ + 4, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 2]) { - be_nested_proto( - 4, /* nstack */ - 0, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 1]) { /* upvals */ - be_local_const_upval(1, 0), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_mdns_announce_hostname), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(remove_rule), - /* K3 */ be_nested_str_weak(Wifi_X23Connected), - /* K4 */ be_nested_str_weak(matter_mdns_host), - }), - be_str_weak(_anonymous_), - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x68000000, // 0000 GETUPV R0 U0 - 0x8C000100, // 0001 GETMET R0 R0 K0 - 0x50080000, // 0002 LDBOOL R2 0 0 - 0x7C000400, // 0003 CALL R0 2 - 0xB8020200, // 0004 GETNGBL R0 K1 - 0x8C000102, // 0005 GETMET R0 R0 K2 - 0x58080003, // 0006 LDCONST R2 K3 - 0x580C0004, // 0007 LDCONST R3 K4 - 0x7C000600, // 0008 CALL R0 3 - 0x80000000, // 0009 RET 0 - }) - ), - be_nested_proto( - 4, /* nstack */ - 0, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 1]) { /* upvals */ - be_local_const_upval(1, 0), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_mdns_announce_hostname), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(remove_rule), - /* K3 */ be_nested_str_weak(Eth_X23Connected), - /* K4 */ be_nested_str_weak(matter_mdns_host), - }), - be_str_weak(_anonymous_), - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x68000000, // 0000 GETUPV R0 U0 - 0x8C000100, // 0001 GETMET R0 R0 K0 - 0x50080200, // 0002 LDBOOL R2 1 0 - 0x7C000400, // 0003 CALL R0 2 - 0xB8020200, // 0004 GETNGBL R0 K1 - 0x8C000102, // 0005 GETMET R0 R0 K2 - 0x58080003, // 0006 LDCONST R2 K3 - 0x580C0004, // 0007 LDCONST R3 K4 - 0x7C000600, // 0008 CALL R0 3 - 0x80000000, // 0009 RET 0 - }) - ), - }), + 0, /* has sup protos */ + NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 9]) { /* constants */ - /* K0 */ be_nested_str_weak(tasmota), - /* K1 */ be_nested_str_weak(wifi), - /* K2 */ be_nested_str_weak(up), - /* K3 */ be_nested_str_weak(_mdns_announce_hostname), - /* K4 */ be_nested_str_weak(add_rule), - /* K5 */ be_nested_str_weak(Wifi_X23Connected), - /* K6 */ be_nested_str_weak(matter_mdns_host), - /* K7 */ be_nested_str_weak(eth), - /* K8 */ be_nested_str_weak(Eth_X23Connected), - }), - be_str_weak(start_mdns_announce_hostnames), - &be_const_str_solidified, - ( &(const binstruction[32]) { /* code */ - 0xB8060000, // 0000 GETNGBL R1 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x94040302, // 0003 GETIDX R1 R1 K2 - 0x78060003, // 0004 JMPF R1 #0009 - 0x8C040103, // 0005 GETMET R1 R0 K3 - 0x500C0000, // 0006 LDBOOL R3 0 0 - 0x7C040400, // 0007 CALL R1 2 - 0x70020005, // 0008 JMP #000F - 0xB8060000, // 0009 GETNGBL R1 K0 - 0x8C040304, // 000A GETMET R1 R1 K4 - 0x580C0005, // 000B LDCONST R3 K5 - 0x84100000, // 000C CLOSURE R4 P0 - 0x58140006, // 000D LDCONST R5 K6 - 0x7C040800, // 000E CALL R1 4 - 0xB8060000, // 000F GETNGBL R1 K0 - 0x8C040307, // 0010 GETMET R1 R1 K7 - 0x7C040200, // 0011 CALL R1 1 - 0x94040302, // 0012 GETIDX R1 R1 K2 - 0x78060003, // 0013 JMPF R1 #0018 - 0x8C040103, // 0014 GETMET R1 R0 K3 - 0x500C0200, // 0015 LDBOOL R3 1 0 - 0x7C040400, // 0016 CALL R1 2 - 0x70020005, // 0017 JMP #001E - 0xB8060000, // 0018 GETNGBL R1 K0 - 0x8C040304, // 0019 GETMET R1 R1 K4 - 0x580C0008, // 001A LDCONST R3 K8 - 0x84100001, // 001B CLOSURE R4 P1 - 0x58140006, // 001C LDCONST R5 K6 - 0x7C040800, // 001D CALL R1 4 - 0xA0000000, // 001E CLOSE R0 - 0x80000000, // 001F RET 0 + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(sessions), + /* K1 */ be_nested_str_weak(every_second), + /* K2 */ be_nested_str_weak(message_handler), + /* K3 */ be_nested_str_weak(commissioning_open), + /* K4 */ be_nested_str_weak(tasmota), + /* K5 */ be_nested_str_weak(time_reached), + }), + be_str_weak(every_second), + &be_const_str_solidified, + ( &(const binstruction[18]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x88040102, // 0003 GETMBR R1 R0 K2 + 0x8C040301, // 0004 GETMET R1 R1 K1 + 0x7C040200, // 0005 CALL R1 1 + 0x88040103, // 0006 GETMBR R1 R0 K3 + 0x4C080000, // 0007 LDNIL R2 + 0x20040202, // 0008 NE R1 R1 R2 + 0x78060006, // 0009 JMPF R1 #0011 + 0xB8060800, // 000A GETNGBL R1 K4 + 0x8C040305, // 000B GETMET R1 R1 K5 + 0x880C0103, // 000C GETMBR R3 R0 K3 + 0x7C040400, // 000D CALL R1 2 + 0x78060001, // 000E JMPF R1 #0011 + 0x4C040000, // 000F LDNIL R1 + 0x90020601, // 0010 SETMBR R0 K3 R1 + 0x80000000, // 0011 RET 0 }) ) ); @@ -3156,40 +3711,185 @@ be_local_closure(Matter_Device_start_mdns_announce_hostnames, /* name */ /******************************************************************** -** Solidified function: MtrJoin +** Solidified function: load_param ********************************************************************/ -be_local_closure(Matter_Device_MtrJoin, /* name */ +be_local_closure(Matter_Device_load_param, /* name */ be_nested_proto( - 8, /* nstack */ - 5, /* argc */ + 11, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(start_root_basic_commissioning), - /* K1 */ be_nested_str_weak(stop_basic_commissioning), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(resp_cmnd_done), + ( &(const bvalue[35]) { /* constants */ + /* K0 */ be_nested_str_weak(crypto), + /* K1 */ be_nested_str_weak(FILENAME), + /* K2 */ be_nested_str_weak(read), + /* K3 */ be_nested_str_weak(close), + /* K4 */ be_nested_str_weak(json), + /* K5 */ be_nested_str_weak(load), + /* K6 */ be_nested_str_weak(root_discriminator), + /* K7 */ be_nested_str_weak(find), + /* K8 */ be_nested_str_weak(distinguish), + /* K9 */ be_nested_str_weak(root_passcode), + /* K10 */ be_nested_str_weak(passcode), + /* K11 */ be_nested_str_weak(ipv4only), + /* K12 */ be_nested_str_weak(disable_bridge_mode), + /* K13 */ be_nested_str_weak(next_ep), + /* K14 */ be_nested_str_weak(nextep), + /* K15 */ be_nested_str_weak(plugins_config), + /* K16 */ be_nested_str_weak(config), + /* K17 */ be_nested_str_weak(tasmota), + /* K18 */ be_nested_str_weak(log), + /* K19 */ be_nested_str_weak(MTR_X3A_X20load_config_X20_X3D_X20), + /* K20 */ be_const_int(3), + /* K21 */ be_nested_str_weak(adjust_next_ep), + /* K22 */ be_nested_str_weak(plugins_persist), + /* K23 */ be_nested_str_weak(plugins_config_remotes), + /* K24 */ be_nested_str_weak(remotes), + /* K25 */ be_nested_str_weak(MTR_X3A_X20load_remotes_X20_X3D_X20), + /* K26 */ be_nested_str_weak(io_error), + /* K27 */ be_nested_str_weak(MTR_X3A_X20Session_Store_X3A_X3Aload_X20Exception_X3A), + /* K28 */ be_nested_str_weak(_X7C), + /* K29 */ be_const_int(2), + /* K30 */ be_nested_str_weak(random), + /* K31 */ be_nested_str_weak(get), + /* K32 */ be_const_int(0), + /* K33 */ be_nested_str_weak(generate_random_passcode), + /* K34 */ be_nested_str_weak(save_param), }), - be_str_weak(MtrJoin), + be_str_weak(load_param), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x60140009, // 0000 GETGBL R5 G9 - 0x5C180600, // 0001 MOVE R6 R3 - 0x7C140200, // 0002 CALL R5 1 - 0x78160002, // 0003 JMPF R5 #0007 - 0x8C180100, // 0004 GETMET R6 R0 K0 - 0x7C180200, // 0005 CALL R6 1 - 0x70020001, // 0006 JMP #0009 - 0x8C180101, // 0007 GETMET R6 R0 K1 - 0x7C180200, // 0008 CALL R6 1 - 0xB81A0400, // 0009 GETNGBL R6 K2 - 0x8C180D03, // 000A GETMET R6 R6 K3 - 0x7C180200, // 000B CALL R6 1 - 0x80000000, // 000C RET 0 + ( &(const binstruction[127]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0xA802004D, // 0001 EXBLK 0 #0050 + 0x60080011, // 0002 GETGBL R2 G17 + 0x880C0101, // 0003 GETMBR R3 R0 K1 + 0x7C080200, // 0004 CALL R2 1 + 0x8C0C0502, // 0005 GETMET R3 R2 K2 + 0x7C0C0200, // 0006 CALL R3 1 + 0x8C100503, // 0007 GETMET R4 R2 K3 + 0x7C100200, // 0008 CALL R4 1 + 0xA4120800, // 0009 IMPORT R4 K4 + 0x8C140905, // 000A GETMET R5 R4 K5 + 0x5C1C0600, // 000B MOVE R7 R3 + 0x7C140400, // 000C CALL R5 2 + 0x8C180B07, // 000D GETMET R6 R5 K7 + 0x58200008, // 000E LDCONST R8 K8 + 0x88240106, // 000F GETMBR R9 R0 K6 + 0x7C180600, // 0010 CALL R6 3 + 0x90020C06, // 0011 SETMBR R0 K6 R6 + 0x8C180B07, // 0012 GETMET R6 R5 K7 + 0x5820000A, // 0013 LDCONST R8 K10 + 0x88240109, // 0014 GETMBR R9 R0 K9 + 0x7C180600, // 0015 CALL R6 3 + 0x90021206, // 0016 SETMBR R0 K9 R6 + 0x60180017, // 0017 GETGBL R6 G23 + 0x8C1C0B07, // 0018 GETMET R7 R5 K7 + 0x5824000B, // 0019 LDCONST R9 K11 + 0x50280000, // 001A LDBOOL R10 0 0 + 0x7C1C0600, // 001B CALL R7 3 + 0x7C180200, // 001C CALL R6 1 + 0x90021606, // 001D SETMBR R0 K11 R6 + 0x60180017, // 001E GETGBL R6 G23 + 0x8C1C0B07, // 001F GETMET R7 R5 K7 + 0x5824000C, // 0020 LDCONST R9 K12 + 0x50280000, // 0021 LDBOOL R10 0 0 + 0x7C1C0600, // 0022 CALL R7 3 + 0x7C180200, // 0023 CALL R6 1 + 0x90021806, // 0024 SETMBR R0 K12 R6 + 0x8C180B07, // 0025 GETMET R6 R5 K7 + 0x5820000E, // 0026 LDCONST R8 K14 + 0x8824010D, // 0027 GETMBR R9 R0 K13 + 0x7C180600, // 0028 CALL R6 3 + 0x90021A06, // 0029 SETMBR R0 K13 R6 + 0x8C180B07, // 002A GETMET R6 R5 K7 + 0x58200010, // 002B LDCONST R8 K16 + 0x7C180400, // 002C CALL R6 2 + 0x90021E06, // 002D SETMBR R0 K15 R6 + 0x8818010F, // 002E GETMBR R6 R0 K15 + 0x4C1C0000, // 002F LDNIL R7 + 0x20180C07, // 0030 NE R6 R6 R7 + 0x781A000B, // 0031 JMPF R6 #003E + 0xB81A2200, // 0032 GETNGBL R6 K17 + 0x8C180D12, // 0033 GETMET R6 R6 K18 + 0x60200008, // 0034 GETGBL R8 G8 + 0x8824010F, // 0035 GETMBR R9 R0 K15 + 0x7C200200, // 0036 CALL R8 1 + 0x00222608, // 0037 ADD R8 K19 R8 + 0x58240014, // 0038 LDCONST R9 K20 + 0x7C180600, // 0039 CALL R6 3 + 0x8C180115, // 003A GETMET R6 R0 K21 + 0x7C180200, // 003B CALL R6 1 + 0x50180200, // 003C LDBOOL R6 1 0 + 0x90022C06, // 003D SETMBR R0 K22 R6 + 0x8C180B07, // 003E GETMET R6 R5 K7 + 0x58200018, // 003F LDCONST R8 K24 + 0x60240013, // 0040 GETGBL R9 G19 + 0x7C240000, // 0041 CALL R9 0 + 0x7C180600, // 0042 CALL R6 3 + 0x90022E06, // 0043 SETMBR R0 K23 R6 + 0x88180117, // 0044 GETMBR R6 R0 K23 + 0x781A0007, // 0045 JMPF R6 #004E + 0xB81A2200, // 0046 GETNGBL R6 K17 + 0x8C180D12, // 0047 GETMET R6 R6 K18 + 0x60200008, // 0048 GETGBL R8 G8 + 0x88240117, // 0049 GETMBR R9 R0 K23 + 0x7C200200, // 004A CALL R8 1 + 0x00223208, // 004B ADD R8 K25 R8 + 0x58240014, // 004C LDCONST R9 K20 + 0x7C180600, // 004D CALL R6 3 + 0xA8040001, // 004E EXBLK 1 1 + 0x70020012, // 004F JMP #0063 + 0xAC080002, // 0050 CATCH R2 0 2 + 0x7002000F, // 0051 JMP #0062 + 0x2010051A, // 0052 NE R4 R2 K26 + 0x7812000C, // 0053 JMPF R4 #0061 + 0xB8122200, // 0054 GETNGBL R4 K17 + 0x8C100912, // 0055 GETMET R4 R4 K18 + 0x60180008, // 0056 GETGBL R6 G8 + 0x5C1C0400, // 0057 MOVE R7 R2 + 0x7C180200, // 0058 CALL R6 1 + 0x001A3606, // 0059 ADD R6 K27 R6 + 0x00180D1C, // 005A ADD R6 R6 K28 + 0x601C0008, // 005B GETGBL R7 G8 + 0x5C200600, // 005C MOVE R8 R3 + 0x7C1C0200, // 005D CALL R7 1 + 0x00180C07, // 005E ADD R6 R6 R7 + 0x581C001D, // 005F LDCONST R7 K29 + 0x7C100600, // 0060 CALL R4 3 + 0x70020000, // 0061 JMP #0063 + 0xB0080000, // 0062 RAISE 2 R0 R0 + 0x50080000, // 0063 LDBOOL R2 0 0 + 0x880C0106, // 0064 GETMBR R3 R0 K6 + 0x4C100000, // 0065 LDNIL R4 + 0x1C0C0604, // 0066 EQ R3 R3 R4 + 0x780E000A, // 0067 JMPF R3 #0073 + 0x8C0C031E, // 0068 GETMET R3 R1 K30 + 0x5814001D, // 0069 LDCONST R5 K29 + 0x7C0C0400, // 006A CALL R3 2 + 0x8C0C071F, // 006B GETMET R3 R3 K31 + 0x58140020, // 006C LDCONST R5 K32 + 0x5818001D, // 006D LDCONST R6 K29 + 0x7C0C0600, // 006E CALL R3 3 + 0x54120FFE, // 006F LDINT R4 4095 + 0x2C0C0604, // 0070 AND R3 R3 R4 + 0x90020C03, // 0071 SETMBR R0 K6 R3 + 0x50080200, // 0072 LDBOOL R2 1 0 + 0x880C0109, // 0073 GETMBR R3 R0 K9 + 0x4C100000, // 0074 LDNIL R4 + 0x1C0C0604, // 0075 EQ R3 R3 R4 + 0x780E0003, // 0076 JMPF R3 #007B + 0x8C0C0121, // 0077 GETMET R3 R0 K33 + 0x7C0C0200, // 0078 CALL R3 1 + 0x90021203, // 0079 SETMBR R0 K9 R3 + 0x50080200, // 007A LDBOOL R2 1 0 + 0x780A0001, // 007B JMPF R2 #007E + 0x8C0C0122, // 007C GETMET R3 R0 K34 + 0x7C0C0200, // 007D CALL R3 1 + 0x80000000, // 007E RET 0 }) ) ); @@ -3197,11 +3897,11 @@ be_local_closure(Matter_Device_MtrJoin, /* name */ /******************************************************************** -** Solidified function: _load_plugins_config +** Solidified function: register_plugin_class ********************************************************************/ -be_local_closure(Matter_Device__load_plugins_config, /* name */ +be_local_closure(Matter_Device_register_plugin_class, /* name */ be_nested_proto( - 19, /* nstack */ + 7, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -3209,171 +3909,24 @@ be_local_closure(Matter_Device__load_plugins_config, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[27]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(k2l_num), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(log), - /* K4 */ be_nested_str_weak(MTR_X3A_X20endpoints_X20to_X20be_X20configured_X20), - /* K5 */ be_const_int(3), - /* K6 */ be_nested_str_weak(format), - /* K7 */ be_nested_str_weak(MTR_X3A_X20endpoint_X20_X25i_X20config_X20_X25s), - /* K8 */ be_nested_str_weak(find), - /* K9 */ be_nested_str_weak(type), - /* K10 */ be_nested_str_weak(MTR_X3A_X20no_X20class_X20name_X2C_X20skipping), - /* K11 */ be_nested_str_weak(plugins_classes), - /* K12 */ be_nested_str_weak(MTR_X3A_X20unknown_X20class_X20name_X20_X27), - /* K13 */ be_nested_str_weak(_X27_X20skipping), - /* K14 */ be_const_int(2), - /* K15 */ be_nested_str_weak(plugins), - /* K16 */ be_nested_str_weak(push), - /* K17 */ be_nested_str_weak(), - /* K18 */ be_nested_str_weak(k2l), - /* K19 */ be_nested_str_weak(_X20_X25s_X3A_X25s), - /* K20 */ be_nested_str_weak(stop_iteration), - /* K21 */ be_nested_str_weak(MTR_X3A_X20endpoint_X3A_X25i_X20type_X3A_X25s_X25s), - /* K22 */ be_nested_str_weak(MTR_X3A_X20Exception), - /* K23 */ be_nested_str_weak(_X7C), - /* K24 */ be_nested_str_weak(publish_result), - /* K25 */ be_nested_str_weak(_X7B_X22Matter_X22_X3A_X7B_X22Initialized_X22_X3A1_X7D_X7D), - /* K26 */ be_nested_str_weak(Matter), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(introspect), + /* K1 */ be_nested_str_weak(get), + /* K2 */ be_nested_str_weak(TYPE), + /* K3 */ be_nested_str_weak(plugins_classes), }), - be_str_weak(_load_plugins_config), + be_str_weak(register_plugin_class), &be_const_str_solidified, - ( &(const binstruction[133]) { /* code */ + ( &(const binstruction[ 9]) { /* code */ 0xA40A0000, // 0000 IMPORT R2 K0 - 0x8C0C0101, // 0001 GETMET R3 R0 K1 + 0x8C0C0501, // 0001 GETMET R3 R2 K1 0x5C140200, // 0002 MOVE R5 R1 - 0x7C0C0400, // 0003 CALL R3 2 - 0xB8120400, // 0004 GETNGBL R4 K2 - 0x8C100903, // 0005 GETMET R4 R4 K3 - 0x60180008, // 0006 GETGBL R6 G8 - 0x5C1C0600, // 0007 MOVE R7 R3 - 0x7C180200, // 0008 CALL R6 1 - 0x001A0806, // 0009 ADD R6 K4 R6 - 0x581C0005, // 000A LDCONST R7 K5 - 0x7C100600, // 000B CALL R4 3 - 0x60100010, // 000C GETGBL R4 G16 - 0x5C140600, // 000D MOVE R5 R3 - 0x7C100200, // 000E CALL R4 1 - 0xA802006B, // 000F EXBLK 0 #007C - 0x5C140800, // 0010 MOVE R5 R4 - 0x7C140000, // 0011 CALL R5 0 - 0xA8020056, // 0012 EXBLK 0 #006A - 0x60180008, // 0013 GETGBL R6 G8 - 0x5C1C0A00, // 0014 MOVE R7 R5 - 0x7C180200, // 0015 CALL R6 1 - 0x94180206, // 0016 GETIDX R6 R1 R6 - 0xB81E0400, // 0017 GETNGBL R7 K2 - 0x8C1C0F03, // 0018 GETMET R7 R7 K3 - 0x8C240506, // 0019 GETMET R9 R2 K6 - 0x582C0007, // 001A LDCONST R11 K7 - 0x5C300A00, // 001B MOVE R12 R5 - 0x5C340C00, // 001C MOVE R13 R6 - 0x7C240800, // 001D CALL R9 4 - 0x58280005, // 001E LDCONST R10 K5 - 0x7C1C0600, // 001F CALL R7 3 - 0x8C1C0D08, // 0020 GETMET R7 R6 K8 - 0x58240009, // 0021 LDCONST R9 K9 - 0x7C1C0400, // 0022 CALL R7 2 - 0x4C200000, // 0023 LDNIL R8 - 0x1C200E08, // 0024 EQ R8 R7 R8 - 0x78220006, // 0025 JMPF R8 #002D - 0xB8220400, // 0026 GETNGBL R8 K2 - 0x8C201103, // 0027 GETMET R8 R8 K3 - 0x5828000A, // 0028 LDCONST R10 K10 - 0x582C0005, // 0029 LDCONST R11 K5 - 0x7C200600, // 002A CALL R8 3 - 0xA8040001, // 002B EXBLK 1 1 - 0x7001FFE2, // 002C JMP #0010 - 0x8820010B, // 002D GETMBR R8 R0 K11 - 0x8C201108, // 002E GETMET R8 R8 K8 - 0x5C280E00, // 002F MOVE R10 R7 - 0x7C200400, // 0030 CALL R8 2 - 0x4C240000, // 0031 LDNIL R9 - 0x1C241009, // 0032 EQ R9 R8 R9 - 0x7826000A, // 0033 JMPF R9 #003F - 0xB8260400, // 0034 GETNGBL R9 K2 - 0x8C241303, // 0035 GETMET R9 R9 K3 - 0x602C0008, // 0036 GETGBL R11 G8 - 0x5C300E00, // 0037 MOVE R12 R7 - 0x7C2C0200, // 0038 CALL R11 1 - 0x002E180B, // 0039 ADD R11 K12 R11 - 0x002C170D, // 003A ADD R11 R11 K13 - 0x5830000E, // 003B LDCONST R12 K14 - 0x7C240600, // 003C CALL R9 3 - 0xA8040001, // 003D EXBLK 1 1 - 0x7001FFD0, // 003E JMP #0010 - 0x5C241000, // 003F MOVE R9 R8 - 0x5C280000, // 0040 MOVE R10 R0 - 0x5C2C0A00, // 0041 MOVE R11 R5 - 0x5C300C00, // 0042 MOVE R12 R6 - 0x7C240600, // 0043 CALL R9 3 - 0x8828010F, // 0044 GETMBR R10 R0 K15 - 0x8C281510, // 0045 GETMET R10 R10 K16 - 0x5C301200, // 0046 MOVE R12 R9 - 0x7C280400, // 0047 CALL R10 2 - 0x58280011, // 0048 LDCONST R10 K17 - 0x602C0010, // 0049 GETGBL R11 G16 - 0x8C300112, // 004A GETMET R12 R0 K18 - 0x5C380C00, // 004B MOVE R14 R6 - 0x7C300400, // 004C CALL R12 2 - 0x7C2C0200, // 004D CALL R11 1 - 0xA802000B, // 004E EXBLK 0 #005B - 0x5C301600, // 004F MOVE R12 R11 - 0x7C300000, // 0050 CALL R12 0 - 0x1C341909, // 0051 EQ R13 R12 K9 - 0x78360000, // 0052 JMPF R13 #0054 - 0x7001FFFA, // 0053 JMP #004F - 0x8C340506, // 0054 GETMET R13 R2 K6 - 0x583C0013, // 0055 LDCONST R15 K19 - 0x5C401800, // 0056 MOVE R16 R12 - 0x94440C0C, // 0057 GETIDX R17 R6 R12 - 0x7C340800, // 0058 CALL R13 4 - 0x0028140D, // 0059 ADD R10 R10 R13 - 0x7001FFF3, // 005A JMP #004F - 0x582C0014, // 005B LDCONST R11 K20 - 0xAC2C0200, // 005C CATCH R11 1 0 - 0xB0080000, // 005D RAISE 2 R0 R0 - 0xB82E0400, // 005E GETNGBL R11 K2 - 0x8C2C1703, // 005F GETMET R11 R11 K3 - 0x8C340506, // 0060 GETMET R13 R2 K6 - 0x583C0015, // 0061 LDCONST R15 K21 - 0x5C400A00, // 0062 MOVE R16 R5 - 0x5C440E00, // 0063 MOVE R17 R7 - 0x5C481400, // 0064 MOVE R18 R10 - 0x7C340A00, // 0065 CALL R13 5 - 0x5838000E, // 0066 LDCONST R14 K14 - 0x7C2C0600, // 0067 CALL R11 3 - 0xA8040001, // 0068 EXBLK 1 1 - 0x70020010, // 0069 JMP #007B - 0xAC180002, // 006A CATCH R6 0 2 - 0x7002000D, // 006B JMP #007A - 0xB8220400, // 006C GETNGBL R8 K2 - 0x8C201103, // 006D GETMET R8 R8 K3 - 0x60280008, // 006E GETGBL R10 G8 - 0x5C2C0C00, // 006F MOVE R11 R6 - 0x7C280200, // 0070 CALL R10 1 - 0x002A2C0A, // 0071 ADD R10 K22 R10 - 0x00281517, // 0072 ADD R10 R10 K23 - 0x602C0008, // 0073 GETGBL R11 G8 - 0x5C300E00, // 0074 MOVE R12 R7 - 0x7C2C0200, // 0075 CALL R11 1 - 0x0028140B, // 0076 ADD R10 R10 R11 - 0x582C000E, // 0077 LDCONST R11 K14 - 0x7C200600, // 0078 CALL R8 3 - 0x70020000, // 0079 JMP #007B - 0xB0080000, // 007A RAISE 2 R0 R0 - 0x7001FF93, // 007B JMP #0010 - 0x58100014, // 007C LDCONST R4 K20 - 0xAC100200, // 007D CATCH R4 1 0 - 0xB0080000, // 007E RAISE 2 R0 R0 - 0xB8120400, // 007F GETNGBL R4 K2 - 0x8C100918, // 0080 GETMET R4 R4 K24 - 0x58180019, // 0081 LDCONST R6 K25 - 0x581C001A, // 0082 LDCONST R7 K26 - 0x7C100600, // 0083 CALL R4 3 - 0x80000000, // 0084 RET 0 + 0x58180002, // 0003 LDCONST R6 K2 + 0x7C0C0600, // 0004 CALL R3 3 + 0x780E0001, // 0005 JMPF R3 #0008 + 0x88100103, // 0006 GETMBR R4 R0 K3 + 0x98100601, // 0007 SETIDX R4 R3 R1 + 0x80000000, // 0008 RET 0 }) ) ); @@ -3381,9 +3934,319 @@ be_local_closure(Matter_Device__load_plugins_config, /* name */ /******************************************************************** -** Solidified function: save_before_restart +** Solidified function: process_attribute_expansion ********************************************************************/ -be_local_closure(Matter_Device_save_before_restart, /* name */ +be_local_closure(Matter_Device_process_attribute_expansion, /* name */ + be_nested_proto( + 24, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(keys), + /* K1 */ be_nested_str_weak(push), + /* K2 */ be_nested_str_weak(stop_iteration), + /* K3 */ be_const_int(1), + /* K4 */ be_const_int(0), + }), + be_str_weak(keys_sorted), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0x60040012, // 0000 GETGBL R1 G18 + 0x7C040000, // 0001 CALL R1 0 + 0x60080010, // 0002 GETGBL R2 G16 + 0x8C0C0100, // 0003 GETMET R3 R0 K0 + 0x7C0C0200, // 0004 CALL R3 1 + 0x7C080200, // 0005 CALL R2 1 + 0xA8020005, // 0006 EXBLK 0 #000D + 0x5C0C0400, // 0007 MOVE R3 R2 + 0x7C0C0000, // 0008 CALL R3 0 + 0x8C100301, // 0009 GETMET R4 R1 K1 + 0x5C180600, // 000A MOVE R6 R3 + 0x7C100400, // 000B CALL R4 2 + 0x7001FFF9, // 000C JMP #0007 + 0x58080002, // 000D LDCONST R2 K2 + 0xAC080200, // 000E CATCH R2 1 0 + 0xB0080000, // 000F RAISE 2 R0 R0 + 0x60080010, // 0010 GETGBL R2 G16 + 0x600C000C, // 0011 GETGBL R3 G12 + 0x5C100200, // 0012 MOVE R4 R1 + 0x7C0C0200, // 0013 CALL R3 1 + 0x040C0703, // 0014 SUB R3 R3 K3 + 0x400E0603, // 0015 CONNECT R3 K3 R3 + 0x7C080200, // 0016 CALL R2 1 + 0xA8020010, // 0017 EXBLK 0 #0029 + 0x5C0C0400, // 0018 MOVE R3 R2 + 0x7C0C0000, // 0019 CALL R3 0 + 0x94100203, // 001A GETIDX R4 R1 R3 + 0x5C140600, // 001B MOVE R5 R3 + 0x24180B04, // 001C GT R6 R5 K4 + 0x781A0008, // 001D JMPF R6 #0027 + 0x04180B03, // 001E SUB R6 R5 K3 + 0x94180206, // 001F GETIDX R6 R1 R6 + 0x24180C04, // 0020 GT R6 R6 R4 + 0x781A0004, // 0021 JMPF R6 #0027 + 0x04180B03, // 0022 SUB R6 R5 K3 + 0x94180206, // 0023 GETIDX R6 R1 R6 + 0x98040A06, // 0024 SETIDX R1 R5 R6 + 0x04140B03, // 0025 SUB R5 R5 K3 + 0x7001FFF4, // 0026 JMP #001C + 0x98040A04, // 0027 SETIDX R1 R5 R4 + 0x7001FFEE, // 0028 JMP #0018 + 0x58080002, // 0029 LDCONST R2 K2 + 0xAC080200, // 002A CATCH R2 1 0 + 0xB0080000, // 002B RAISE 2 R0 R0 + 0x80040200, // 002C RET 1 R1 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[16]) { /* constants */ + /* K0 */ be_nested_str_weak(endpoint), + /* K1 */ be_nested_str_weak(cluster), + /* K2 */ be_nested_str_weak(attribute), + /* K3 */ be_nested_str_weak(plugins), + /* K4 */ be_nested_str_weak(get_endpoint), + /* K5 */ be_nested_str_weak(contains), + /* K6 */ be_nested_str_weak(get_cluster_list), + /* K7 */ be_nested_str_weak(get_attribute_list), + /* K8 */ be_nested_str_weak(push), + /* K9 */ be_nested_str_weak(stop_iteration), + /* K10 */ be_nested_str_weak(status), + /* K11 */ be_nested_str_weak(matter), + /* K12 */ be_nested_str_weak(UNSUPPORTED_ENDPOINT), + /* K13 */ be_nested_str_weak(UNSUPPORTED_CLUSTER), + /* K14 */ be_nested_str_weak(UNSUPPORTED_ATTRIBUTE), + /* K15 */ be_nested_str_weak(UNREPORTABLE_ATTRIBUTE), + }), + be_str_weak(process_attribute_expansion), + &be_const_str_solidified, + ( &(const binstruction[203]) { /* code */ + 0x840C0000, // 0000 CLOSURE R3 P0 + 0x88100300, // 0001 GETMBR R4 R1 K0 + 0x88140301, // 0002 GETMBR R5 R1 K1 + 0x88180302, // 0003 GETMBR R6 R1 K2 + 0x501C0000, // 0004 LDBOOL R7 0 0 + 0x50200000, // 0005 LDBOOL R8 0 0 + 0x50240000, // 0006 LDBOOL R9 0 0 + 0x88280300, // 0007 GETMBR R10 R1 K0 + 0x4C2C0000, // 0008 LDNIL R11 + 0x2028140B, // 0009 NE R10 R10 R11 + 0x782A0007, // 000A JMPF R10 #0013 + 0x88280301, // 000B GETMBR R10 R1 K1 + 0x4C2C0000, // 000C LDNIL R11 + 0x2028140B, // 000D NE R10 R10 R11 + 0x782A0003, // 000E JMPF R10 #0013 + 0x88280302, // 000F GETMBR R10 R1 K2 + 0x4C2C0000, // 0010 LDNIL R11 + 0x2028140B, // 0011 NE R10 R10 R11 + 0x742A0000, // 0012 JMPT R10 #0014 + 0x50280001, // 0013 LDBOOL R10 0 1 + 0x50280200, // 0014 LDBOOL R10 1 0 + 0x602C0013, // 0015 GETGBL R11 G19 + 0x7C2C0000, // 0016 CALL R11 0 + 0x60300010, // 0017 GETGBL R12 G16 + 0x88340103, // 0018 GETMBR R13 R0 K3 + 0x7C300200, // 0019 CALL R12 1 + 0xA8020053, // 001A EXBLK 0 #006F + 0x5C341800, // 001B MOVE R13 R12 + 0x7C340000, // 001C CALL R13 0 + 0x8C381B04, // 001D GETMET R14 R13 K4 + 0x7C380200, // 001E CALL R14 1 + 0x4C3C0000, // 001F LDNIL R15 + 0x203C080F, // 0020 NE R15 R4 R15 + 0x783E0002, // 0021 JMPF R15 #0025 + 0x203C1C04, // 0022 NE R15 R14 R4 + 0x783E0000, // 0023 JMPF R15 #0025 + 0x7001FFF5, // 0024 JMP #001B + 0x8C3C1705, // 0025 GETMET R15 R11 K5 + 0x5C441C00, // 0026 MOVE R17 R14 + 0x7C3C0400, // 0027 CALL R15 2 + 0x743E0002, // 0028 JMPT R15 #002C + 0x603C0013, // 0029 GETGBL R15 G19 + 0x7C3C0000, // 002A CALL R15 0 + 0x982C1C0F, // 002B SETIDX R11 R14 R15 + 0x501C0200, // 002C LDBOOL R7 1 0 + 0x8C3C1B06, // 002D GETMET R15 R13 K6 + 0x7C3C0200, // 002E CALL R15 1 + 0x60400010, // 002F GETGBL R16 G16 + 0x5C441E00, // 0030 MOVE R17 R15 + 0x7C400200, // 0031 CALL R16 1 + 0xA8020037, // 0032 EXBLK 0 #006B + 0x5C442000, // 0033 MOVE R17 R16 + 0x7C440000, // 0034 CALL R17 0 + 0x4C480000, // 0035 LDNIL R18 + 0x20480A12, // 0036 NE R18 R5 R18 + 0x784A0002, // 0037 JMPF R18 #003B + 0x20482205, // 0038 NE R18 R17 R5 + 0x784A0000, // 0039 JMPF R18 #003B + 0x7001FFF7, // 003A JMP #0033 + 0x9448160E, // 003B GETIDX R18 R11 R14 + 0x8C482505, // 003C GETMET R18 R18 K5 + 0x5C502200, // 003D MOVE R20 R17 + 0x7C480400, // 003E CALL R18 2 + 0x744A0003, // 003F JMPT R18 #0044 + 0x9448160E, // 0040 GETIDX R18 R11 R14 + 0x604C0013, // 0041 GETGBL R19 G19 + 0x7C4C0000, // 0042 CALL R19 0 + 0x98482213, // 0043 SETIDX R18 R17 R19 + 0x50200200, // 0044 LDBOOL R8 1 0 + 0x8C481B07, // 0045 GETMET R18 R13 K7 + 0x5C502200, // 0046 MOVE R20 R17 + 0x7C480400, // 0047 CALL R18 2 + 0x604C0010, // 0048 GETGBL R19 G16 + 0x5C502400, // 0049 MOVE R20 R18 + 0x7C4C0200, // 004A CALL R19 1 + 0xA802001A, // 004B EXBLK 0 #0067 + 0x5C502600, // 004C MOVE R20 R19 + 0x7C500000, // 004D CALL R20 0 + 0x4C540000, // 004E LDNIL R21 + 0x20540C15, // 004F NE R21 R6 R21 + 0x78560002, // 0050 JMPF R21 #0054 + 0x20542806, // 0051 NE R21 R20 R6 + 0x78560000, // 0052 JMPF R21 #0054 + 0x7001FFF7, // 0053 JMP #004C + 0x9454160E, // 0054 GETIDX R21 R11 R14 + 0x94542A11, // 0055 GETIDX R21 R21 R17 + 0x8C542B05, // 0056 GETMET R21 R21 K5 + 0x5C5C2800, // 0057 MOVE R23 R20 + 0x7C540400, // 0058 CALL R21 2 + 0x74560004, // 0059 JMPT R21 #005F + 0x9454160E, // 005A GETIDX R21 R11 R14 + 0x94542A11, // 005B GETIDX R21 R21 R17 + 0x60580012, // 005C GETGBL R22 G18 + 0x7C580000, // 005D CALL R22 0 + 0x98542816, // 005E SETIDX R21 R20 R22 + 0x50240200, // 005F LDBOOL R9 1 0 + 0x9454160E, // 0060 GETIDX R21 R11 R14 + 0x94542A11, // 0061 GETIDX R21 R21 R17 + 0x94542A14, // 0062 GETIDX R21 R21 R20 + 0x8C542B08, // 0063 GETMET R21 R21 K8 + 0x5C5C1A00, // 0064 MOVE R23 R13 + 0x7C540400, // 0065 CALL R21 2 + 0x7001FFE4, // 0066 JMP #004C + 0x584C0009, // 0067 LDCONST R19 K9 + 0xAC4C0200, // 0068 CATCH R19 1 0 + 0xB0080000, // 0069 RAISE 2 R0 R0 + 0x7001FFC7, // 006A JMP #0033 + 0x58400009, // 006B LDCONST R16 K9 + 0xAC400200, // 006C CATCH R16 1 0 + 0xB0080000, // 006D RAISE 2 R0 R0 + 0x7001FFAB, // 006E JMP #001B + 0x58300009, // 006F LDCONST R12 K9 + 0xAC300200, // 0070 CATCH R12 1 0 + 0xB0080000, // 0071 RAISE 2 R0 R0 + 0x60300010, // 0072 GETGBL R12 G16 + 0x5C340600, // 0073 MOVE R13 R3 + 0x5C381600, // 0074 MOVE R14 R11 + 0x7C340200, // 0075 CALL R13 1 + 0x7C300200, // 0076 CALL R12 1 + 0xA8020033, // 0077 EXBLK 0 #00AC + 0x5C341800, // 0078 MOVE R13 R12 + 0x7C340000, // 0079 CALL R13 0 + 0x60380010, // 007A GETGBL R14 G16 + 0x5C3C0600, // 007B MOVE R15 R3 + 0x9440160D, // 007C GETIDX R16 R11 R13 + 0x7C3C0200, // 007D CALL R15 1 + 0x7C380200, // 007E CALL R14 1 + 0xA8020027, // 007F EXBLK 0 #00A8 + 0x5C3C1C00, // 0080 MOVE R15 R14 + 0x7C3C0000, // 0081 CALL R15 0 + 0x60400010, // 0082 GETGBL R16 G16 + 0x5C440600, // 0083 MOVE R17 R3 + 0x9448160D, // 0084 GETIDX R18 R11 R13 + 0x9448240F, // 0085 GETIDX R18 R18 R15 + 0x7C440200, // 0086 CALL R17 1 + 0x7C400200, // 0087 CALL R16 1 + 0xA802001A, // 0088 EXBLK 0 #00A4 + 0x5C442000, // 0089 MOVE R17 R16 + 0x7C440000, // 008A CALL R17 0 + 0x60480010, // 008B GETGBL R18 G16 + 0x944C160D, // 008C GETIDX R19 R11 R13 + 0x944C260F, // 008D GETIDX R19 R19 R15 + 0x944C2611, // 008E GETIDX R19 R19 R17 + 0x7C480200, // 008F CALL R18 1 + 0xA802000E, // 0090 EXBLK 0 #00A0 + 0x5C4C2400, // 0091 MOVE R19 R18 + 0x7C4C0000, // 0092 CALL R19 0 + 0x9006000D, // 0093 SETMBR R1 K0 R13 + 0x9006020F, // 0094 SETMBR R1 K1 R15 + 0x90060411, // 0095 SETMBR R1 K2 R17 + 0x5C500400, // 0096 MOVE R20 R2 + 0x5C542600, // 0097 MOVE R21 R19 + 0x5C580200, // 0098 MOVE R22 R1 + 0x5C5C1400, // 0099 MOVE R23 R10 + 0x7C500600, // 009A CALL R20 3 + 0x782A0002, // 009B JMPF R10 #009F + 0x78520001, // 009C JMPF R20 #009F + 0xA8040004, // 009D EXBLK 1 4 + 0x80002A00, // 009E RET 0 + 0x7001FFF0, // 009F JMP #0091 + 0x58480009, // 00A0 LDCONST R18 K9 + 0xAC480200, // 00A1 CATCH R18 1 0 + 0xB0080000, // 00A2 RAISE 2 R0 R0 + 0x7001FFE4, // 00A3 JMP #0089 + 0x58400009, // 00A4 LDCONST R16 K9 + 0xAC400200, // 00A5 CATCH R16 1 0 + 0xB0080000, // 00A6 RAISE 2 R0 R0 + 0x7001FFD7, // 00A7 JMP #0080 + 0x58380009, // 00A8 LDCONST R14 K9 + 0xAC380200, // 00A9 CATCH R14 1 0 + 0xB0080000, // 00AA RAISE 2 R0 R0 + 0x7001FFCB, // 00AB JMP #0078 + 0x58300009, // 00AC LDCONST R12 K9 + 0xAC300200, // 00AD CATCH R12 1 0 + 0xB0080000, // 00AE RAISE 2 R0 R0 + 0x782A0019, // 00AF JMPF R10 #00CA + 0x5C300E00, // 00B0 MOVE R12 R7 + 0x74320003, // 00B1 JMPT R12 #00B6 + 0xB8321600, // 00B2 GETNGBL R12 K11 + 0x8830190C, // 00B3 GETMBR R12 R12 K12 + 0x9006140C, // 00B4 SETMBR R1 K10 R12 + 0x7002000E, // 00B5 JMP #00C5 + 0x5C301000, // 00B6 MOVE R12 R8 + 0x74320003, // 00B7 JMPT R12 #00BC + 0xB8321600, // 00B8 GETNGBL R12 K11 + 0x8830190D, // 00B9 GETMBR R12 R12 K13 + 0x9006140C, // 00BA SETMBR R1 K10 R12 + 0x70020008, // 00BB JMP #00C5 + 0x5C301200, // 00BC MOVE R12 R9 + 0x74320003, // 00BD JMPT R12 #00C2 + 0xB8321600, // 00BE GETNGBL R12 K11 + 0x8830190E, // 00BF GETMBR R12 R12 K14 + 0x9006140C, // 00C0 SETMBR R1 K10 R12 + 0x70020002, // 00C1 JMP #00C5 + 0xB8321600, // 00C2 GETNGBL R12 K11 + 0x8830190F, // 00C3 GETMBR R12 R12 K15 + 0x9006140C, // 00C4 SETMBR R1 K10 R12 + 0x5C300400, // 00C5 MOVE R12 R2 + 0x4C340000, // 00C6 LDNIL R13 + 0x5C380200, // 00C7 MOVE R14 R1 + 0x503C0200, // 00C8 LDBOOL R15 1 0 + 0x7C300600, // 00C9 CALL R12 3 + 0x80000000, // 00CA RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: is_commissioning_open +********************************************************************/ +be_local_closure(Matter_Device_is_commissioning_open, /* name */ be_nested_proto( 3, /* nstack */ 1, /* argc */ @@ -3393,18 +4256,76 @@ be_local_closure(Matter_Device_save_before_restart, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(stop_basic_commissioning), - /* K1 */ be_nested_str_weak(mdns_remove_op_discovery_all_fabrics), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(commissioning_open), }), - be_str_weak(save_before_restart), + be_str_weak(is_commissioning_open), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x8C040101, // 0002 GETMET R1 R0 K1 - 0x7C040200, // 0003 CALL R1 1 - 0x80000000, // 0004 RET 0 + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x20040202, // 0002 NE R1 R1 R2 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: start_commissioning_complete_deferred +********************************************************************/ +be_local_closure(Matter_Device_start_commissioning_complete_deferred, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 3, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 2]) { /* upvals */ + be_local_const_upval(1, 0), + be_local_const_upval(1, 1), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(start_commissioning_complete), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x68080001, // 0002 GETUPV R2 U1 + 0x7C000400, // 0003 CALL R0 2 + 0x80040000, // 0004 RET 1 R0 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(set_timer), + /* K2 */ be_const_int(0), + }), + be_str_weak(start_commissioning_complete_deferred), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0xB80A0000, // 0000 GETNGBL R2 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x58100002, // 0002 LDCONST R4 K2 + 0x84140000, // 0003 CLOSURE R5 P0 + 0x7C080600, // 0004 CALL R2 3 + 0xA0000000, // 0005 CLOSE R0 + 0x80000000, // 0006 RET 0 }) ) ); @@ -3412,11 +4333,11 @@ be_local_closure(Matter_Device_save_before_restart, /* name */ /******************************************************************** -** Solidified function: start_root_basic_commissioning +** Solidified function: start_operational_discovery ********************************************************************/ -be_local_closure(Matter_Device_start_root_basic_commissioning, /* name */ +be_local_closure(Matter_Device_start_operational_discovery, /* name */ be_nested_proto( - 14, /* nstack */ + 7, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -3424,83 +4345,29 @@ be_local_closure(Matter_Device_start_root_basic_commissioning, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[23]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(PASE_TIMEOUT), - /* K2 */ be_nested_str_weak(compute_manual_pairing_code), - /* K3 */ be_nested_str_weak(tasmota), - /* K4 */ be_nested_str_weak(log), - /* K5 */ be_nested_str_weak(format), - /* K6 */ be_nested_str_weak(MTR_X3A_X20Manual_X20pairing_X20code_X3A_X20_X25s_X2D_X25s_X2D_X25s), - /* K7 */ be_const_int(0), - /* K8 */ be_const_int(3), - /* K9 */ be_const_int(2147483647), - /* K10 */ be_const_int(2), - /* K11 */ be_nested_str_weak(compute_qrcode_content), - /* K12 */ be_nested_str_weak(publish_result), - /* K13 */ be_nested_str_weak(_X7B_X22Matter_X22_X3A_X7B_X22Commissioning_X22_X3A1_X2C_X22PairingCode_X22_X3A_X22_X25s_X22_X2C_X22QRCode_X22_X3A_X22_X25s_X22_X7D_X7D), - /* K14 */ be_nested_str_weak(Matter), - /* K15 */ be_nested_str_weak(_compute_pbkdf), - /* K16 */ be_nested_str_weak(root_passcode), - /* K17 */ be_nested_str_weak(root_iterations), - /* K18 */ be_nested_str_weak(root_salt), - /* K19 */ be_nested_str_weak(start_basic_commissioning), - /* K20 */ be_nested_str_weak(root_discriminator), - /* K21 */ be_nested_str_weak(root_w0), - /* K22 */ be_nested_str_weak(root_L), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(crypto), + /* K1 */ be_nested_str_weak(mdns), + /* K2 */ be_nested_str_weak(stop_basic_commissioning), + /* K3 */ be_nested_str_weak(root_w0), + /* K4 */ be_nested_str_weak(root_L), + /* K5 */ be_nested_str_weak(mdns_announce_op_discovery), }), - be_str_weak(start_root_basic_commissioning), + be_str_weak(start_operational_discovery), &be_const_str_solidified, - ( &(const binstruction[49]) { /* code */ + ( &(const binstruction[12]) { /* code */ 0xA40A0000, // 0000 IMPORT R2 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x1C0C0203, // 0002 EQ R3 R1 R3 - 0x780E0000, // 0003 JMPF R3 #0005 - 0x88040101, // 0004 GETMBR R1 R0 K1 - 0x8C0C0102, // 0005 GETMET R3 R0 K2 - 0x7C0C0200, // 0006 CALL R3 1 - 0xB8120600, // 0007 GETNGBL R4 K3 - 0x8C100904, // 0008 GETMET R4 R4 K4 - 0x8C180505, // 0009 GETMET R6 R2 K5 - 0x58200006, // 000A LDCONST R8 K6 - 0x40260F08, // 000B CONNECT R9 K7 K8 - 0x94240609, // 000C GETIDX R9 R3 R9 - 0x542A0003, // 000D LDINT R10 4 - 0x542E0005, // 000E LDINT R11 6 - 0x4028140B, // 000F CONNECT R10 R10 R11 - 0x9428060A, // 0010 GETIDX R10 R3 R10 - 0x542E0006, // 0011 LDINT R11 7 - 0x402C1709, // 0012 CONNECT R11 R11 K9 - 0x942C060B, // 0013 GETIDX R11 R3 R11 - 0x7C180A00, // 0014 CALL R6 5 - 0x581C000A, // 0015 LDCONST R7 K10 - 0x7C100600, // 0016 CALL R4 3 - 0x8C10010B, // 0017 GETMET R4 R0 K11 - 0x7C100200, // 0018 CALL R4 1 - 0xB8160600, // 0019 GETNGBL R5 K3 - 0x8C140B0C, // 001A GETMET R5 R5 K12 - 0x8C1C0505, // 001B GETMET R7 R2 K5 - 0x5824000D, // 001C LDCONST R9 K13 - 0x5C280600, // 001D MOVE R10 R3 - 0x5C2C0800, // 001E MOVE R11 R4 - 0x7C1C0800, // 001F CALL R7 4 - 0x5820000E, // 0020 LDCONST R8 K14 - 0x7C140600, // 0021 CALL R5 3 - 0x8C14010F, // 0022 GETMET R5 R0 K15 - 0x881C0110, // 0023 GETMBR R7 R0 K16 - 0x88200111, // 0024 GETMBR R8 R0 K17 - 0x88240112, // 0025 GETMBR R9 R0 K18 - 0x7C140800, // 0026 CALL R5 4 - 0x8C140113, // 0027 GETMET R5 R0 K19 - 0x5C1C0200, // 0028 MOVE R7 R1 - 0x88200111, // 0029 GETMBR R8 R0 K17 - 0x88240114, // 002A GETMBR R9 R0 K20 - 0x88280112, // 002B GETMBR R10 R0 K18 - 0x882C0115, // 002C GETMBR R11 R0 K21 - 0x88300116, // 002D GETMBR R12 R0 K22 - 0x4C340000, // 002E LDNIL R13 - 0x7C141000, // 002F CALL R5 8 - 0x80000000, // 0030 RET 0 + 0xA40E0200, // 0001 IMPORT R3 K1 + 0x8C100102, // 0002 GETMET R4 R0 K2 + 0x7C100200, // 0003 CALL R4 1 + 0x4C100000, // 0004 LDNIL R4 + 0x90020604, // 0005 SETMBR R0 K3 R4 + 0x4C100000, // 0006 LDNIL R4 + 0x90020804, // 0007 SETMBR R0 K4 R4 + 0x8C100105, // 0008 GETMET R4 R0 K5 + 0x5C180200, // 0009 MOVE R6 R1 + 0x7C100400, // 000A CALL R4 2 + 0x80000000, // 000B RET 0 }) ) ); @@ -3508,30 +4375,72 @@ be_local_closure(Matter_Device_start_root_basic_commissioning, /* name */ /******************************************************************** -** Solidified function: received_ack +** Solidified function: MtrInfo ********************************************************************/ -be_local_closure(Matter_Device_received_ack, /* name */ +be_local_closure(Matter_Device_MtrInfo, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 10, /* nstack */ + 5, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(udp_server), - /* K1 */ be_nested_str_weak(received_ack), + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(), + /* K1 */ be_nested_str_weak(plugins), + /* K2 */ be_nested_str_weak(MtrInfo_one), + /* K3 */ be_nested_str_weak(endpoint), + /* K4 */ be_nested_str_weak(stop_iteration), + /* K5 */ be_nested_str_weak(int), + /* K6 */ be_nested_str_weak(find_plugin_by_friendly_name), + /* K7 */ be_nested_str_weak(tasmota), + /* K8 */ be_nested_str_weak(resp_cmnd_done), }), - be_str_weak(received_ack), + be_str_weak(MtrInfo), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x5C100200, // 0002 MOVE R4 R1 - 0x7C080400, // 0003 CALL R2 2 - 0x80040400, // 0004 RET 1 R2 + ( &(const binstruction[40]) { /* code */ + 0x1C140700, // 0000 EQ R5 R3 K0 + 0x7815FFFF, // 0001 JMPF R5 #0002 + 0x1C140700, // 0002 EQ R5 R3 K0 + 0x7816000D, // 0003 JMPF R5 #0012 + 0x60140010, // 0004 GETGBL R5 G16 + 0x88180101, // 0005 GETMBR R6 R0 K1 + 0x7C140200, // 0006 CALL R5 1 + 0xA8020005, // 0007 EXBLK 0 #000E + 0x5C180A00, // 0008 MOVE R6 R5 + 0x7C180000, // 0009 CALL R6 0 + 0x8C1C0102, // 000A GETMET R7 R0 K2 + 0x88240D03, // 000B GETMBR R9 R6 K3 + 0x7C1C0400, // 000C CALL R7 2 + 0x7001FFF9, // 000D JMP #0008 + 0x58140004, // 000E LDCONST R5 K4 + 0xAC140200, // 000F CATCH R5 1 0 + 0xB0080000, // 0010 RAISE 2 R0 R0 + 0x70020011, // 0011 JMP #0024 + 0x60140004, // 0012 GETGBL R5 G4 + 0x5C180800, // 0013 MOVE R6 R4 + 0x7C140200, // 0014 CALL R5 1 + 0x1C140B05, // 0015 EQ R5 R5 K5 + 0x78160003, // 0016 JMPF R5 #001B + 0x8C140102, // 0017 GETMET R5 R0 K2 + 0x5C1C0800, // 0018 MOVE R7 R4 + 0x7C140400, // 0019 CALL R5 2 + 0x70020008, // 001A JMP #0024 + 0x8C140106, // 001B GETMET R5 R0 K6 + 0x5C1C0600, // 001C MOVE R7 R3 + 0x7C140400, // 001D CALL R5 2 + 0x4C180000, // 001E LDNIL R6 + 0x20180A06, // 001F NE R6 R5 R6 + 0x781A0002, // 0020 JMPF R6 #0024 + 0x8C180102, // 0021 GETMET R6 R0 K2 + 0x88200B03, // 0022 GETMBR R8 R5 K3 + 0x7C180400, // 0023 CALL R6 2 + 0xB8160E00, // 0024 GETNGBL R5 K7 + 0x8C140B08, // 0025 GETMET R5 R5 K8 + 0x7C140200, // 0026 CALL R5 1 + 0x80000000, // 0027 RET 0 }) ) ); @@ -3539,75 +4448,171 @@ be_local_closure(Matter_Device_received_ack, /* name */ /******************************************************************** -** Solidified function: _compute_pbkdf +** Solidified function: mdns_announce_op_discovery ********************************************************************/ -be_local_closure(Matter_Device__compute_pbkdf, /* name */ +be_local_closure(Matter_Device_mdns_announce_op_discovery, /* name */ be_nested_proto( 14, /* nstack */ - 4, /* argc */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ - /* K0 */ be_nested_str_weak(crypto), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(add), - /* K3 */ be_nested_str_weak(PBKDF2_HMAC_SHA256), - /* K4 */ be_nested_str_weak(derive), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(root_w0), - /* K7 */ be_nested_str_weak(EC_P256), - /* K8 */ be_nested_str_weak(mod), - /* K9 */ be_nested_str_weak(root_L), - /* K10 */ be_nested_str_weak(public_key), + ( &(const bvalue[27]) { /* constants */ + /* K0 */ be_nested_str_weak(mdns), + /* K1 */ be_nested_str_weak(get_device_id), + /* K2 */ be_nested_str_weak(copy), + /* K3 */ be_nested_str_weak(reverse), + /* K4 */ be_nested_str_weak(get_fabric_compressed), + /* K5 */ be_nested_str_weak(tohex), + /* K6 */ be_nested_str_weak(_X2D), + /* K7 */ be_nested_str_weak(tasmota), + /* K8 */ be_nested_str_weak(log), + /* K9 */ be_nested_str_weak(MTR_X3A_X20Operational_X20Discovery_X20node_X20_X3D_X20), + /* K10 */ be_const_int(3), + /* K11 */ be_nested_str_weak(eth), + /* K12 */ be_nested_str_weak(find), + /* K13 */ be_nested_str_weak(up), + /* K14 */ be_nested_str_weak(MTR_X3A_X20adding_X20mDNS_X20on_X20_X25s_X20_X27_X25s_X27_X20ptr_X20to_X20_X60_X25s_X2Elocal_X60), + /* K15 */ be_nested_str_weak(hostname_eth), + /* K16 */ be_nested_str_weak(add_service), + /* K17 */ be_nested_str_weak(_matter), + /* K18 */ be_nested_str_weak(_tcp), + /* K19 */ be_nested_str_weak(_I), + /* K20 */ be_nested_str_weak(MTR_X3A_X20adding_X20subtype_X3A_X20), + /* K21 */ be_nested_str_weak(add_subtype), + /* K22 */ be_nested_str_weak(wifi), + /* K23 */ be_nested_str_weak(hostname_wifi), + /* K24 */ be_nested_str_weak(MTR_X3A_X20Exception), + /* K25 */ be_nested_str_weak(_X7C), + /* K26 */ be_const_int(2), }), - be_str_weak(_compute_pbkdf), + be_str_weak(mdns_announce_op_discovery), &be_const_str_solidified, - ( &(const binstruction[41]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0xA4160200, // 0001 IMPORT R5 K1 - 0x60180015, // 0002 GETGBL R6 G21 - 0x7C180000, // 0003 CALL R6 0 - 0x8C180D02, // 0004 GETMET R6 R6 K2 - 0x5C200200, // 0005 MOVE R8 R1 - 0x54260003, // 0006 LDINT R9 4 - 0x7C180600, // 0007 CALL R6 3 - 0x8C1C0903, // 0008 GETMET R7 R4 K3 - 0x7C1C0200, // 0009 CALL R7 1 - 0x8C1C0F04, // 000A GETMET R7 R7 K4 - 0x5C240C00, // 000B MOVE R9 R6 - 0x5C280600, // 000C MOVE R10 R3 - 0x5C2C0400, // 000D MOVE R11 R2 - 0x5432004F, // 000E LDINT R12 80 - 0x7C1C0A00, // 000F CALL R7 5 - 0x54220026, // 0010 LDINT R8 39 - 0x40220A08, // 0011 CONNECT R8 K5 R8 - 0x94200E08, // 0012 GETIDX R8 R7 R8 - 0x54260027, // 0013 LDINT R9 40 - 0x542A004E, // 0014 LDINT R10 79 - 0x4024120A, // 0015 CONNECT R9 R9 R10 - 0x94240E09, // 0016 GETIDX R9 R7 R9 - 0x8C280907, // 0017 GETMET R10 R4 K7 - 0x7C280200, // 0018 CALL R10 1 - 0x8C281508, // 0019 GETMET R10 R10 K8 - 0x5C301000, // 001A MOVE R12 R8 - 0x7C280400, // 001B CALL R10 2 - 0x90020C0A, // 001C SETMBR R0 K6 R10 - 0x8C280907, // 001D GETMET R10 R4 K7 - 0x7C280200, // 001E CALL R10 1 - 0x8C281508, // 001F GETMET R10 R10 K8 - 0x5C301200, // 0020 MOVE R12 R9 - 0x7C280400, // 0021 CALL R10 2 - 0x8C2C0907, // 0022 GETMET R11 R4 K7 - 0x7C2C0200, // 0023 CALL R11 1 - 0x8C2C170A, // 0024 GETMET R11 R11 K10 - 0x5C341400, // 0025 MOVE R13 R10 - 0x7C2C0400, // 0026 CALL R11 2 - 0x9002120B, // 0027 SETMBR R0 K9 R11 - 0x80000000, // 0028 RET 0 + ( &(const binstruction[121]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0xA8020064, // 0001 EXBLK 0 #0067 + 0x8C0C0301, // 0002 GETMET R3 R1 K1 + 0x7C0C0200, // 0003 CALL R3 1 + 0x8C0C0702, // 0004 GETMET R3 R3 K2 + 0x7C0C0200, // 0005 CALL R3 1 + 0x8C0C0703, // 0006 GETMET R3 R3 K3 + 0x7C0C0200, // 0007 CALL R3 1 + 0x8C100304, // 0008 GETMET R4 R1 K4 + 0x7C100200, // 0009 CALL R4 1 + 0x8C140905, // 000A GETMET R5 R4 K5 + 0x7C140200, // 000B CALL R5 1 + 0x00140B06, // 000C ADD R5 R5 K6 + 0x8C180705, // 000D GETMET R6 R3 K5 + 0x7C180200, // 000E CALL R6 1 + 0x00140A06, // 000F ADD R5 R5 R6 + 0xB81A0E00, // 0010 GETNGBL R6 K7 + 0x8C180D08, // 0011 GETMET R6 R6 K8 + 0x00221205, // 0012 ADD R8 K9 R5 + 0x5824000A, // 0013 LDCONST R9 K10 + 0x7C180600, // 0014 CALL R6 3 + 0xB81A0E00, // 0015 GETNGBL R6 K7 + 0x8C180D0B, // 0016 GETMET R6 R6 K11 + 0x7C180200, // 0017 CALL R6 1 + 0x8C180D0C, // 0018 GETMET R6 R6 K12 + 0x5820000D, // 0019 LDCONST R8 K13 + 0x7C180400, // 001A CALL R6 2 + 0x781A0020, // 001B JMPF R6 #003D + 0xB81A0E00, // 001C GETNGBL R6 K7 + 0x8C180D08, // 001D GETMET R6 R6 K8 + 0x60200018, // 001E GETGBL R8 G24 + 0x5824000E, // 001F LDCONST R9 K14 + 0x5828000B, // 0020 LDCONST R10 K11 + 0x5C2C0A00, // 0021 MOVE R11 R5 + 0x8830010F, // 0022 GETMBR R12 R0 K15 + 0x7C200800, // 0023 CALL R8 4 + 0x5824000A, // 0024 LDCONST R9 K10 + 0x7C180600, // 0025 CALL R6 3 + 0x8C180510, // 0026 GETMET R6 R2 K16 + 0x58200011, // 0027 LDCONST R8 K17 + 0x58240012, // 0028 LDCONST R9 K18 + 0x542A15A3, // 0029 LDINT R10 5540 + 0x4C2C0000, // 002A LDNIL R11 + 0x5C300A00, // 002B MOVE R12 R5 + 0x8834010F, // 002C GETMBR R13 R0 K15 + 0x7C180E00, // 002D CALL R6 7 + 0x8C180905, // 002E GETMET R6 R4 K5 + 0x7C180200, // 002F CALL R6 1 + 0x001A2606, // 0030 ADD R6 K19 R6 + 0xB81E0E00, // 0031 GETNGBL R7 K7 + 0x8C1C0F08, // 0032 GETMET R7 R7 K8 + 0x00262806, // 0033 ADD R9 K20 R6 + 0x5828000A, // 0034 LDCONST R10 K10 + 0x7C1C0600, // 0035 CALL R7 3 + 0x8C1C0515, // 0036 GETMET R7 R2 K21 + 0x58240011, // 0037 LDCONST R9 K17 + 0x58280012, // 0038 LDCONST R10 K18 + 0x5C2C0A00, // 0039 MOVE R11 R5 + 0x8830010F, // 003A GETMBR R12 R0 K15 + 0x5C340C00, // 003B MOVE R13 R6 + 0x7C1C0C00, // 003C CALL R7 6 + 0xB81A0E00, // 003D GETNGBL R6 K7 + 0x8C180D16, // 003E GETMET R6 R6 K22 + 0x7C180200, // 003F CALL R6 1 + 0x8C180D0C, // 0040 GETMET R6 R6 K12 + 0x5820000D, // 0041 LDCONST R8 K13 + 0x7C180400, // 0042 CALL R6 2 + 0x781A0020, // 0043 JMPF R6 #0065 + 0xB81A0E00, // 0044 GETNGBL R6 K7 + 0x8C180D08, // 0045 GETMET R6 R6 K8 + 0x60200018, // 0046 GETGBL R8 G24 + 0x5824000E, // 0047 LDCONST R9 K14 + 0x58280016, // 0048 LDCONST R10 K22 + 0x5C2C0A00, // 0049 MOVE R11 R5 + 0x88300117, // 004A GETMBR R12 R0 K23 + 0x7C200800, // 004B CALL R8 4 + 0x5824000A, // 004C LDCONST R9 K10 + 0x7C180600, // 004D CALL R6 3 + 0x8C180510, // 004E GETMET R6 R2 K16 + 0x58200011, // 004F LDCONST R8 K17 + 0x58240012, // 0050 LDCONST R9 K18 + 0x542A15A3, // 0051 LDINT R10 5540 + 0x4C2C0000, // 0052 LDNIL R11 + 0x5C300A00, // 0053 MOVE R12 R5 + 0x88340117, // 0054 GETMBR R13 R0 K23 + 0x7C180E00, // 0055 CALL R6 7 + 0x8C180905, // 0056 GETMET R6 R4 K5 + 0x7C180200, // 0057 CALL R6 1 + 0x001A2606, // 0058 ADD R6 K19 R6 + 0xB81E0E00, // 0059 GETNGBL R7 K7 + 0x8C1C0F08, // 005A GETMET R7 R7 K8 + 0x00262806, // 005B ADD R9 K20 R6 + 0x5828000A, // 005C LDCONST R10 K10 + 0x7C1C0600, // 005D CALL R7 3 + 0x8C1C0515, // 005E GETMET R7 R2 K21 + 0x58240011, // 005F LDCONST R9 K17 + 0x58280012, // 0060 LDCONST R10 K18 + 0x5C2C0A00, // 0061 MOVE R11 R5 + 0x88300117, // 0062 GETMBR R12 R0 K23 + 0x5C340C00, // 0063 MOVE R13 R6 + 0x7C1C0C00, // 0064 CALL R7 6 + 0xA8040001, // 0065 EXBLK 1 1 + 0x70020010, // 0066 JMP #0078 + 0xAC0C0002, // 0067 CATCH R3 0 2 + 0x7002000D, // 0068 JMP #0077 + 0xB8160E00, // 0069 GETNGBL R5 K7 + 0x8C140B08, // 006A GETMET R5 R5 K8 + 0x601C0008, // 006B GETGBL R7 G8 + 0x5C200600, // 006C MOVE R8 R3 + 0x7C1C0200, // 006D CALL R7 1 + 0x001E3007, // 006E ADD R7 K24 R7 + 0x001C0F19, // 006F ADD R7 R7 K25 + 0x60200008, // 0070 GETGBL R8 G8 + 0x5C240800, // 0071 MOVE R9 R4 + 0x7C200200, // 0072 CALL R8 1 + 0x001C0E08, // 0073 ADD R7 R7 R8 + 0x5820001A, // 0074 LDCONST R8 K26 + 0x7C140600, // 0075 CALL R5 3 + 0x70020000, // 0076 JMP #0078 + 0xB0080000, // 0077 RAISE 2 R0 R0 + 0x80000000, // 0078 RET 0 }) ) ); @@ -3615,9 +4620,9 @@ be_local_closure(Matter_Device__compute_pbkdf, /* name */ /******************************************************************** -** Solidified function: start_commissioning_complete_deferred +** Solidified function: start_operational_discovery_deferred ********************************************************************/ -be_local_closure(Matter_Device_start_commissioning_complete_deferred, /* name */ +be_local_closure(Matter_Device_start_operational_discovery_deferred, /* name */ be_nested_proto( 6, /* nstack */ 2, /* argc */ @@ -3639,7 +4644,7 @@ be_local_closure(Matter_Device_start_commissioning_complete_deferred, /* name NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(start_commissioning_complete), + /* K0 */ be_nested_str_weak(start_operational_discovery), }), be_str_weak(_X3Clambda_X3E), &be_const_str_solidified, @@ -3658,7 +4663,7 @@ be_local_closure(Matter_Device_start_commissioning_complete_deferred, /* name /* K1 */ be_nested_str_weak(set_timer), /* K2 */ be_const_int(0), }), - be_str_weak(start_commissioning_complete_deferred), + be_str_weak(start_operational_discovery_deferred), &be_const_str_solidified, ( &(const binstruction[ 7]) { /* code */ 0xB80A0000, // 0000 GETNGBL R2 K0 @@ -3675,142 +4680,315 @@ be_local_closure(Matter_Device_start_commissioning_complete_deferred, /* name /******************************************************************** -** Solidified function: start_basic_commissioning +** Solidified function: start_commissioning_complete ********************************************************************/ -be_local_closure(Matter_Device_start_basic_commissioning, /* name */ +be_local_closure(Matter_Device_start_commissioning_complete, /* name */ be_nested_proto( - 13, /* nstack */ - 8, /* argc */ + 11, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 2]) { - be_nested_proto( - 4, /* nstack */ - 0, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 1]) { /* upvals */ - be_local_const_upval(1, 0), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(mdns_announce_PASE), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(remove_rule), - /* K3 */ be_nested_str_weak(Wifi_X23Connected), - }), - be_str_weak(_anonymous_), - &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x68000000, // 0000 GETUPV R0 U0 - 0x8C000100, // 0001 GETMET R0 R0 K0 - 0x7C000200, // 0002 CALL R0 1 - 0xB8020200, // 0003 GETNGBL R0 K1 - 0x8C000102, // 0004 GETMET R0 R0 K2 - 0x58080003, // 0005 LDCONST R2 K3 - 0x580C0000, // 0006 LDCONST R3 K0 - 0x7C000600, // 0007 CALL R0 3 - 0x80000000, // 0008 RET 0 - }) - ), - be_nested_proto( - 4, /* nstack */ - 0, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 1]) { /* upvals */ - be_local_const_upval(1, 0), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(mdns_announce_PASE), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(remove_rule), - /* K3 */ be_nested_str_weak(Eth_X23Connected), - }), - be_str_weak(_anonymous_), - &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x68000000, // 0000 GETUPV R0 U0 - 0x8C000100, // 0001 GETMET R0 R0 K0 - 0x7C000200, // 0002 CALL R0 1 - 0xB8020200, // 0003 GETNGBL R0 K1 - 0x8C000102, // 0004 GETMET R0 R0 K2 - 0x58080003, // 0005 LDCONST R2 K3 - 0x580C0000, // 0006 LDCONST R3 K0 - 0x7C000600, // 0007 CALL R0 3 - 0x80000000, // 0008 RET 0 - }) - ), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(get_fabric), + /* K1 */ be_nested_str_weak(get_fabric_id), + /* K2 */ be_nested_str_weak(copy), + /* K3 */ be_nested_str_weak(reverse), + /* K4 */ be_nested_str_weak(tohex), + /* K5 */ be_nested_str_weak(get_admin_vendor_name), + /* K6 */ be_nested_str_weak(tasmota), + /* K7 */ be_nested_str_weak(log), + /* K8 */ be_nested_str_weak(MTR_X3A_X20_X2D_X2D_X2D_X20Commissioning_X20complete_X20for_X20Fabric_X20_X27_X25s_X27_X20_X28Vendor_X20_X25s_X29_X20_X2D_X2D_X2D), + /* K9 */ be_const_int(2), + /* K10 */ be_nested_str_weak(stop_basic_commissioning), }), + be_str_weak(start_commissioning_complete), + &be_const_str_solidified, + ( &(const binstruction[24]) { /* code */ + 0x8C080300, // 0000 GETMET R2 R1 K0 + 0x7C080200, // 0001 CALL R2 1 + 0x8C0C0501, // 0002 GETMET R3 R2 K1 + 0x7C0C0200, // 0003 CALL R3 1 + 0x8C0C0702, // 0004 GETMET R3 R3 K2 + 0x7C0C0200, // 0005 CALL R3 1 + 0x8C0C0703, // 0006 GETMET R3 R3 K3 + 0x7C0C0200, // 0007 CALL R3 1 + 0x8C0C0704, // 0008 GETMET R3 R3 K4 + 0x7C0C0200, // 0009 CALL R3 1 + 0x8C100505, // 000A GETMET R4 R2 K5 + 0x7C100200, // 000B CALL R4 1 + 0xB8160C00, // 000C GETNGBL R5 K6 + 0x8C140B07, // 000D GETMET R5 R5 K7 + 0x601C0018, // 000E GETGBL R7 G24 + 0x58200008, // 000F LDCONST R8 K8 + 0x5C240600, // 0010 MOVE R9 R3 + 0x5C280800, // 0011 MOVE R10 R4 + 0x7C1C0600, // 0012 CALL R7 3 + 0x58200009, // 0013 LDCONST R8 K9 + 0x7C140600, // 0014 CALL R5 3 + 0x8C14010A, // 0015 GETMET R5 R0 K10 + 0x7C140200, // 0016 CALL R5 1 + 0x80000000, // 0017 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: MtrUpdate +********************************************************************/ +be_local_closure(Matter_Device_MtrUpdate, /* name */ + be_nested_proto( + 18, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[16]) { /* constants */ - /* K0 */ be_nested_str_weak(commissioning_open), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(millis), - /* K3 */ be_nested_str_weak(commissioning_iterations), - /* K4 */ be_nested_str_weak(commissioning_discriminator), - /* K5 */ be_nested_str_weak(commissioning_salt), - /* K6 */ be_nested_str_weak(commissioning_w0), - /* K7 */ be_nested_str_weak(commissioning_L), - /* K8 */ be_nested_str_weak(commissioning_admin_fabric), - /* K9 */ be_nested_str_weak(wifi), - /* K10 */ be_nested_str_weak(up), - /* K11 */ be_nested_str_weak(eth), - /* K12 */ be_nested_str_weak(mdns_announce_PASE), - /* K13 */ be_nested_str_weak(add_rule), - /* K14 */ be_nested_str_weak(Wifi_X23Connected), - /* K15 */ be_nested_str_weak(Eth_X23Connected), + ( &(const bvalue[25]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(resp_cmnd_str), + /* K2 */ be_nested_str_weak(Invalid_X20JSON), + /* K3 */ be_nested_str_weak(find_key_i), + /* K4 */ be_nested_str_weak(Ep), + /* K5 */ be_nested_str_weak(Name), + /* K6 */ be_const_int(0), + /* K7 */ be_nested_str_weak(Invalid_X20_X27Ep_X27_X20attribute), + /* K8 */ be_nested_str_weak(find_plugin_by_endpoint), + /* K9 */ be_nested_str_weak(remove), + /* K10 */ be_nested_str_weak(find_plugin_by_friendly_name), + /* K11 */ be_nested_str_weak(Invalid_X20Device), + /* K12 */ be_nested_str_weak(VIRTUAL), + /* K13 */ be_nested_str_weak(Device_X20is_X20not_X20virtual), + /* K14 */ be_nested_str_weak(consolidate_update_commands), + /* K15 */ be_nested_str_weak(keys), + /* K16 */ be_nested_str_weak(find_list_i), + /* K17 */ be_nested_str_weak(Invalid_X20command_X20_X27_X25s_X27), + /* K18 */ be_nested_str_weak(stop_iteration), + /* K19 */ be_nested_str_weak(update_virtual), + /* K20 */ be_nested_str_weak(state_json), + /* K21 */ be_nested_str_weak(_X7B_X22_X25s_X22_X3A_X25s_X7D), + /* K22 */ be_nested_str_weak(resp_cmnd), + /* K23 */ be_nested_str_weak(resp_cmnd_done), + /* K24 */ be_nested_str_weak(Missing_X20_X27Device_X27_X20attribute), }), - be_str_weak(start_basic_commissioning), + be_str_weak(MtrUpdate), &be_const_str_solidified, - ( &(const binstruction[40]) { /* code */ - 0xB8220200, // 0000 GETNGBL R8 K1 - 0x8C201102, // 0001 GETMET R8 R8 K2 - 0x7C200200, // 0002 CALL R8 1 - 0x542603E7, // 0003 LDINT R9 1000 - 0x08240209, // 0004 MUL R9 R1 R9 - 0x00201009, // 0005 ADD R8 R8 R9 - 0x90020008, // 0006 SETMBR R0 K0 R8 - 0x90020602, // 0007 SETMBR R0 K3 R2 - 0x90020803, // 0008 SETMBR R0 K4 R3 - 0x90020A04, // 0009 SETMBR R0 K5 R4 - 0x90020C05, // 000A SETMBR R0 K6 R5 - 0x90020E06, // 000B SETMBR R0 K7 R6 - 0x90021007, // 000C SETMBR R0 K8 R7 - 0xB8220200, // 000D GETNGBL R8 K1 - 0x8C201109, // 000E GETMET R8 R8 K9 - 0x7C200200, // 000F CALL R8 1 - 0x9420110A, // 0010 GETIDX R8 R8 K10 - 0x74220004, // 0011 JMPT R8 #0017 - 0xB8220200, // 0012 GETNGBL R8 K1 - 0x8C20110B, // 0013 GETMET R8 R8 K11 - 0x7C200200, // 0014 CALL R8 1 - 0x9420110A, // 0015 GETIDX R8 R8 K10 - 0x78220002, // 0016 JMPF R8 #001A - 0x8C20010C, // 0017 GETMET R8 R0 K12 + ( &(const binstruction[126]) { /* code */ + 0x4C140000, // 0000 LDNIL R5 + 0x1C140805, // 0001 EQ R5 R4 R5 + 0x78160004, // 0002 JMPF R5 #0008 + 0xB8160000, // 0003 GETNGBL R5 K0 + 0x8C140B01, // 0004 GETMET R5 R5 K1 + 0x581C0002, // 0005 LDCONST R7 K2 + 0x7C140400, // 0006 CALL R5 2 + 0x80040A00, // 0007 RET 1 R5 + 0xB8160000, // 0008 GETNGBL R5 K0 + 0x8C140B03, // 0009 GETMET R5 R5 K3 + 0x5C1C0800, // 000A MOVE R7 R4 + 0x58200004, // 000B LDCONST R8 K4 + 0x7C140600, // 000C CALL R5 3 + 0xB81A0000, // 000D GETNGBL R6 K0 + 0x8C180D03, // 000E GETMET R6 R6 K3 + 0x5C200800, // 000F MOVE R8 R4 + 0x58240005, // 0010 LDCONST R9 K5 + 0x7C180600, // 0011 CALL R6 3 + 0x74160000, // 0012 JMPT R5 #0014 + 0x781A0064, // 0013 JMPF R6 #0079 + 0x4C1C0000, // 0014 LDNIL R7 + 0x78160010, // 0015 JMPF R5 #0027 + 0x60200009, // 0016 GETGBL R8 G9 + 0x94240805, // 0017 GETIDX R9 R4 R5 0x7C200200, // 0018 CALL R8 1 - 0x7002000B, // 0019 JMP #0026 - 0xB8220200, // 001A GETNGBL R8 K1 - 0x8C20110D, // 001B GETMET R8 R8 K13 - 0x5828000E, // 001C LDCONST R10 K14 - 0x842C0000, // 001D CLOSURE R11 P0 - 0x5830000C, // 001E LDCONST R12 K12 - 0x7C200800, // 001F CALL R8 4 - 0xB8220200, // 0020 GETNGBL R8 K1 - 0x8C20110D, // 0021 GETMET R8 R8 K13 - 0x5828000F, // 0022 LDCONST R10 K15 - 0x842C0001, // 0023 CLOSURE R11 P1 - 0x5830000C, // 0024 LDCONST R12 K12 - 0x7C200800, // 0025 CALL R8 4 - 0xA0000000, // 0026 CLOSE R0 - 0x80000000, // 0027 RET 0 + 0x18241106, // 0019 LE R9 R8 K6 + 0x78260004, // 001A JMPF R9 #0020 + 0xB8260000, // 001B GETNGBL R9 K0 + 0x8C241301, // 001C GETMET R9 R9 K1 + 0x582C0007, // 001D LDCONST R11 K7 + 0x7C240400, // 001E CALL R9 2 + 0x80041200, // 001F RET 1 R9 + 0x8C240108, // 0020 GETMET R9 R0 K8 + 0x5C2C1000, // 0021 MOVE R11 R8 + 0x7C240400, // 0022 CALL R9 2 + 0x5C1C1200, // 0023 MOVE R7 R9 + 0x8C240909, // 0024 GETMET R9 R4 K9 + 0x5C2C0A00, // 0025 MOVE R11 R5 + 0x7C240400, // 0026 CALL R9 2 + 0x781A0009, // 0027 JMPF R6 #0032 + 0x4C200000, // 0028 LDNIL R8 + 0x1C200E08, // 0029 EQ R8 R7 R8 + 0x78220003, // 002A JMPF R8 #002F + 0x8C20010A, // 002B GETMET R8 R0 K10 + 0x94280806, // 002C GETIDX R10 R4 R6 + 0x7C200400, // 002D CALL R8 2 + 0x5C1C1000, // 002E MOVE R7 R8 + 0x8C200909, // 002F GETMET R8 R4 K9 + 0x5C280C00, // 0030 MOVE R10 R6 + 0x7C200400, // 0031 CALL R8 2 + 0x4C200000, // 0032 LDNIL R8 + 0x1C200E08, // 0033 EQ R8 R7 R8 + 0x78220004, // 0034 JMPF R8 #003A + 0xB8220000, // 0035 GETNGBL R8 K0 + 0x8C201101, // 0036 GETMET R8 R8 K1 + 0x5828000B, // 0037 LDCONST R10 K11 + 0x7C200400, // 0038 CALL R8 2 + 0x80041000, // 0039 RET 1 R8 + 0x88200F0C, // 003A GETMBR R8 R7 K12 + 0x74220004, // 003B JMPT R8 #0041 + 0xB8220000, // 003C GETNGBL R8 K0 + 0x8C201101, // 003D GETMET R8 R8 K1 + 0x5828000D, // 003E LDCONST R10 K13 + 0x7C200400, // 003F CALL R8 2 + 0x80041000, // 0040 RET 1 R8 + 0x8C200F0E, // 0041 GETMET R8 R7 K14 + 0x7C200200, // 0042 CALL R8 1 + 0x60240013, // 0043 GETGBL R9 G19 + 0x7C240000, // 0044 CALL R9 0 + 0x60280010, // 0045 GETGBL R10 G16 + 0x8C2C090F, // 0046 GETMET R11 R4 K15 + 0x7C2C0200, // 0047 CALL R11 1 + 0x7C280200, // 0048 CALL R10 1 + 0xA8020016, // 0049 EXBLK 0 #0061 + 0x5C2C1400, // 004A MOVE R11 R10 + 0x7C2C0000, // 004B CALL R11 0 + 0xB8320000, // 004C GETNGBL R12 K0 + 0x8C301910, // 004D GETMET R12 R12 K16 + 0x5C381000, // 004E MOVE R14 R8 + 0x5C3C1600, // 004F MOVE R15 R11 + 0x7C300600, // 0050 CALL R12 3 + 0x4C340000, // 0051 LDNIL R13 + 0x1C34180D, // 0052 EQ R13 R12 R13 + 0x78360008, // 0053 JMPF R13 #005D + 0xB8360000, // 0054 GETNGBL R13 K0 + 0x8C341B01, // 0055 GETMET R13 R13 K1 + 0x603C0018, // 0056 GETGBL R15 G24 + 0x58400011, // 0057 LDCONST R16 K17 + 0x9444080B, // 0058 GETIDX R17 R4 R11 + 0x7C3C0400, // 0059 CALL R15 2 + 0x7C340400, // 005A CALL R13 2 + 0xA8040001, // 005B EXBLK 1 1 + 0x80001A00, // 005C RET 0 + 0x9434100C, // 005D GETIDX R13 R8 R12 + 0x9438080B, // 005E GETIDX R14 R4 R11 + 0x98241A0E, // 005F SETIDX R9 R13 R14 + 0x7001FFE8, // 0060 JMP #004A + 0x58280012, // 0061 LDCONST R10 K18 + 0xAC280200, // 0062 CATCH R10 1 0 + 0xB0080000, // 0063 RAISE 2 R0 R0 + 0x8C280F13, // 0064 GETMET R10 R7 K19 + 0x5C301200, // 0065 MOVE R12 R9 + 0x7C280400, // 0066 CALL R10 2 + 0x8C280F14, // 0067 GETMET R10 R7 K20 + 0x7C280200, // 0068 CALL R10 1 + 0x782A000A, // 0069 JMPF R10 #0075 + 0x602C0018, // 006A GETGBL R11 G24 + 0x58300015, // 006B LDCONST R12 K21 + 0x5C340200, // 006C MOVE R13 R1 + 0x5C381400, // 006D MOVE R14 R10 + 0x7C2C0600, // 006E CALL R11 3 + 0xB8320000, // 006F GETNGBL R12 K0 + 0x8C301916, // 0070 GETMET R12 R12 K22 + 0x5C381600, // 0071 MOVE R14 R11 + 0x7C300400, // 0072 CALL R12 2 + 0x80041800, // 0073 RET 1 R12 + 0x70020003, // 0074 JMP #0079 + 0xB82E0000, // 0075 GETNGBL R11 K0 + 0x8C2C1717, // 0076 GETMET R11 R11 K23 + 0x7C2C0200, // 0077 CALL R11 1 + 0x80041600, // 0078 RET 1 R11 + 0xB81E0000, // 0079 GETNGBL R7 K0 + 0x8C1C0F01, // 007A GETMET R7 R7 K1 + 0x58240018, // 007B LDCONST R9 K24 + 0x7C1C0400, // 007C CALL R7 2 + 0x80000000, // 007D RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: sort_distinct +********************************************************************/ +be_local_closure(Matter_Device_sort_distinct, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 4, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_const_class(be_class_Matter_Device), + /* K1 */ be_const_int(1), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(stop_iteration), + /* K4 */ be_nested_str_weak(remove), + }), + be_str_weak(sort_distinct), + &be_const_str_solidified, + ( &(const binstruction[53]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x60080010, // 0001 GETGBL R2 G16 + 0x600C000C, // 0002 GETGBL R3 G12 + 0x5C100000, // 0003 MOVE R4 R0 + 0x7C0C0200, // 0004 CALL R3 1 + 0x040C0701, // 0005 SUB R3 R3 K1 + 0x400E0203, // 0006 CONNECT R3 K1 R3 + 0x7C080200, // 0007 CALL R2 1 + 0xA8020010, // 0008 EXBLK 0 #001A + 0x5C0C0400, // 0009 MOVE R3 R2 + 0x7C0C0000, // 000A CALL R3 0 + 0x94100003, // 000B GETIDX R4 R0 R3 + 0x5C140600, // 000C MOVE R5 R3 + 0x24180B02, // 000D GT R6 R5 K2 + 0x781A0008, // 000E JMPF R6 #0018 + 0x04180B01, // 000F SUB R6 R5 K1 + 0x94180006, // 0010 GETIDX R6 R0 R6 + 0x24180C04, // 0011 GT R6 R6 R4 + 0x781A0004, // 0012 JMPF R6 #0018 + 0x04180B01, // 0013 SUB R6 R5 K1 + 0x94180006, // 0014 GETIDX R6 R0 R6 + 0x98000A06, // 0015 SETIDX R0 R5 R6 + 0x04140B01, // 0016 SUB R5 R5 K1 + 0x7001FFF4, // 0017 JMP #000D + 0x98000A04, // 0018 SETIDX R0 R5 R4 + 0x7001FFEE, // 0019 JMP #0009 + 0x58080003, // 001A LDCONST R2 K3 + 0xAC080200, // 001B CATCH R2 1 0 + 0xB0080000, // 001C RAISE 2 R0 R0 + 0x58080001, // 001D LDCONST R2 K1 + 0x600C000C, // 001E GETGBL R3 G12 + 0x5C100000, // 001F MOVE R4 R0 + 0x7C0C0200, // 0020 CALL R3 1 + 0x180C0701, // 0021 LE R3 R3 K1 + 0x780E0000, // 0022 JMPF R3 #0024 + 0x80040000, // 0023 RET 1 R0 + 0x940C0102, // 0024 GETIDX R3 R0 K2 + 0x6010000C, // 0025 GETGBL R4 G12 + 0x5C140000, // 0026 MOVE R5 R0 + 0x7C100200, // 0027 CALL R4 1 + 0x14100404, // 0028 LT R4 R2 R4 + 0x78120009, // 0029 JMPF R4 #0034 + 0x94100002, // 002A GETIDX R4 R0 R2 + 0x1C100803, // 002B EQ R4 R4 R3 + 0x78120003, // 002C JMPF R4 #0031 + 0x8C100104, // 002D GETMET R4 R0 K4 + 0x5C180400, // 002E MOVE R6 R2 + 0x7C100400, // 002F CALL R4 2 + 0x70020001, // 0030 JMP #0033 + 0x940C0002, // 0031 GETIDX R3 R0 R2 + 0x00080501, // 0032 ADD R2 R2 K1 + 0x7001FFF0, // 0033 JMP #0025 + 0x80040000, // 0034 RET 1 R0 }) ) ); @@ -3818,51 +4996,53 @@ be_local_closure(Matter_Device_start_basic_commissioning, /* name */ /******************************************************************** -** Solidified function: mdns_announce_op_discovery_all_fabrics +** Solidified function: conf_to_log ********************************************************************/ -be_local_closure(Matter_Device_mdns_announce_op_discovery_all_fabrics, /* name */ +be_local_closure(Matter_Device_conf_to_log, /* name */ be_nested_proto( - 6, /* nstack */ + 9, /* nstack */ 1, /* argc */ - 2, /* varg */ + 4, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(sessions), - /* K1 */ be_nested_str_weak(active_fabrics), - /* K2 */ be_nested_str_weak(get_device_id), - /* K3 */ be_nested_str_weak(get_fabric_id), - /* K4 */ be_nested_str_weak(mdns_announce_op_discovery), + /* K0 */ be_const_class(be_class_Matter_Device), + /* K1 */ be_nested_str_weak(), + /* K2 */ be_nested_str_weak(k2l), + /* K3 */ be_nested_str_weak(type), + /* K4 */ be_nested_str_weak(_X20_X25s_X3A_X25s), /* K5 */ be_nested_str_weak(stop_iteration), }), - be_str_weak(mdns_announce_op_discovery_all_fabrics), + be_str_weak(conf_to_log), &be_const_str_solidified, - ( &(const binstruction[22]) { /* code */ - 0x60040010, // 0000 GETGBL R1 G16 - 0x88080100, // 0001 GETMBR R2 R0 K0 - 0x8C080501, // 0002 GETMET R2 R2 K1 - 0x7C080200, // 0003 CALL R2 1 - 0x7C040200, // 0004 CALL R1 1 - 0xA802000B, // 0005 EXBLK 0 #0012 - 0x5C080200, // 0006 MOVE R2 R1 - 0x7C080000, // 0007 CALL R2 0 - 0x8C0C0502, // 0008 GETMET R3 R2 K2 - 0x7C0C0200, // 0009 CALL R3 1 - 0x780E0005, // 000A JMPF R3 #0011 - 0x8C0C0503, // 000B GETMET R3 R2 K3 - 0x7C0C0200, // 000C CALL R3 1 - 0x780E0002, // 000D JMPF R3 #0011 - 0x8C0C0104, // 000E GETMET R3 R0 K4 - 0x5C140400, // 000F MOVE R5 R2 - 0x7C0C0400, // 0010 CALL R3 2 - 0x7001FFF3, // 0011 JMP #0006 - 0x58040005, // 0012 LDCONST R1 K5 - 0xAC040200, // 0013 CATCH R1 1 0 - 0xB0080000, // 0014 RAISE 2 R0 R0 - 0x80000000, // 0015 RET 0 + ( &(const binstruction[24]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x58080001, // 0001 LDCONST R2 K1 + 0x600C0010, // 0002 GETGBL R3 G16 + 0x8C100302, // 0003 GETMET R4 R1 K2 + 0x5C180000, // 0004 MOVE R6 R0 + 0x7C100400, // 0005 CALL R4 2 + 0x7C0C0200, // 0006 CALL R3 1 + 0xA802000B, // 0007 EXBLK 0 #0014 + 0x5C100600, // 0008 MOVE R4 R3 + 0x7C100000, // 0009 CALL R4 0 + 0x1C140903, // 000A EQ R5 R4 K3 + 0x78160000, // 000B JMPF R5 #000D + 0x7001FFFA, // 000C JMP #0008 + 0x60140018, // 000D GETGBL R5 G24 + 0x58180004, // 000E LDCONST R6 K4 + 0x5C1C0800, // 000F MOVE R7 R4 + 0x94200004, // 0010 GETIDX R8 R0 R4 + 0x7C140600, // 0011 CALL R5 3 + 0x00080405, // 0012 ADD R2 R2 R5 + 0x7001FFF3, // 0013 JMP #0008 + 0x580C0005, // 0014 LDCONST R3 K5 + 0xAC0C0200, // 0015 CATCH R3 1 0 + 0xB0080000, // 0016 RAISE 2 R0 R0 + 0x80040400, // 0017 RET 1 R2 }) ) ); @@ -3870,142 +5050,44 @@ be_local_closure(Matter_Device_mdns_announce_op_discovery_all_fabrics, /* name /******************************************************************** -** Solidified function: load_param +** Solidified function: find_plugin_by_endpoint ********************************************************************/ -be_local_closure(Matter_Device_load_param, /* name */ +be_local_closure(Matter_Device_find_plugin_by_endpoint, /* name */ be_nested_proto( - 12, /* nstack */ - 1, /* argc */ + 6, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[28]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(crypto), - /* K2 */ be_nested_str_weak(FILENAME), - /* K3 */ be_nested_str_weak(read), - /* K4 */ be_nested_str_weak(close), - /* K5 */ be_nested_str_weak(json), - /* K6 */ be_nested_str_weak(load), - /* K7 */ be_nested_str_weak(root_discriminator), - /* K8 */ be_nested_str_weak(find), - /* K9 */ be_nested_str_weak(distinguish), - /* K10 */ be_nested_str_weak(root_passcode), - /* K11 */ be_nested_str_weak(passcode), - /* K12 */ be_nested_str_weak(ipv4only), - /* K13 */ be_nested_str_weak(plugins_config), - /* K14 */ be_nested_str_weak(config), - /* K15 */ be_nested_str_weak(_load_plugins_config), - /* K16 */ be_nested_str_weak(plugins_persist), - /* K17 */ be_nested_str_weak(io_error), - /* K18 */ be_nested_str_weak(tasmota), - /* K19 */ be_nested_str_weak(log), - /* K20 */ be_nested_str_weak(MTR_X3A_X20Session_Store_X3A_X3Aload_X20Exception_X3A), - /* K21 */ be_nested_str_weak(_X7C), - /* K22 */ be_const_int(2), - /* K23 */ be_nested_str_weak(random), - /* K24 */ be_nested_str_weak(get), - /* K25 */ be_const_int(0), - /* K26 */ be_nested_str_weak(generate_random_passcode), - /* K27 */ be_nested_str_weak(save_param), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(plugins), + /* K2 */ be_nested_str_weak(get_endpoint), + /* K3 */ be_const_int(1), }), - be_str_weak(load_param), + be_str_weak(find_plugin_by_endpoint), &be_const_str_solidified, - ( &(const binstruction[91]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0xA8020028, // 0002 EXBLK 0 #002C - 0x600C0011, // 0003 GETGBL R3 G17 - 0x88100102, // 0004 GETMBR R4 R0 K2 - 0x7C0C0200, // 0005 CALL R3 1 - 0x8C100703, // 0006 GETMET R4 R3 K3 - 0x7C100200, // 0007 CALL R4 1 - 0x8C140704, // 0008 GETMET R5 R3 K4 - 0x7C140200, // 0009 CALL R5 1 - 0xA4160A00, // 000A IMPORT R5 K5 - 0x8C180B06, // 000B GETMET R6 R5 K6 - 0x5C200800, // 000C MOVE R8 R4 - 0x7C180400, // 000D CALL R6 2 - 0x8C1C0D08, // 000E GETMET R7 R6 K8 - 0x58240009, // 000F LDCONST R9 K9 - 0x88280107, // 0010 GETMBR R10 R0 K7 - 0x7C1C0600, // 0011 CALL R7 3 - 0x90020E07, // 0012 SETMBR R0 K7 R7 - 0x8C1C0D08, // 0013 GETMET R7 R6 K8 - 0x5824000B, // 0014 LDCONST R9 K11 - 0x8828010A, // 0015 GETMBR R10 R0 K10 - 0x7C1C0600, // 0016 CALL R7 3 - 0x90021407, // 0017 SETMBR R0 K10 R7 - 0x601C0017, // 0018 GETGBL R7 G23 - 0x8C200D08, // 0019 GETMET R8 R6 K8 - 0x5828000C, // 001A LDCONST R10 K12 - 0x502C0000, // 001B LDBOOL R11 0 0 - 0x7C200600, // 001C CALL R8 3 - 0x7C1C0200, // 001D CALL R7 1 - 0x90021807, // 001E SETMBR R0 K12 R7 - 0x8C1C0D08, // 001F GETMET R7 R6 K8 - 0x5824000E, // 0020 LDCONST R9 K14 - 0x7C1C0400, // 0021 CALL R7 2 - 0x90021A07, // 0022 SETMBR R0 K13 R7 - 0x881C010D, // 0023 GETMBR R7 R0 K13 - 0x781E0004, // 0024 JMPF R7 #002A - 0x8C1C010F, // 0025 GETMET R7 R0 K15 - 0x8824010D, // 0026 GETMBR R9 R0 K13 - 0x7C1C0400, // 0027 CALL R7 2 - 0x501C0200, // 0028 LDBOOL R7 1 0 - 0x90022007, // 0029 SETMBR R0 K16 R7 - 0xA8040001, // 002A EXBLK 1 1 - 0x70020012, // 002B JMP #003F - 0xAC0C0002, // 002C CATCH R3 0 2 - 0x7002000F, // 002D JMP #003E - 0x20140711, // 002E NE R5 R3 K17 - 0x7816000C, // 002F JMPF R5 #003D - 0xB8162400, // 0030 GETNGBL R5 K18 - 0x8C140B13, // 0031 GETMET R5 R5 K19 - 0x601C0008, // 0032 GETGBL R7 G8 - 0x5C200600, // 0033 MOVE R8 R3 - 0x7C1C0200, // 0034 CALL R7 1 - 0x001E2807, // 0035 ADD R7 K20 R7 - 0x001C0F15, // 0036 ADD R7 R7 K21 - 0x60200008, // 0037 GETGBL R8 G8 - 0x5C240800, // 0038 MOVE R9 R4 - 0x7C200200, // 0039 CALL R8 1 - 0x001C0E08, // 003A ADD R7 R7 R8 - 0x58200016, // 003B LDCONST R8 K22 - 0x7C140600, // 003C CALL R5 3 - 0x70020000, // 003D JMP #003F - 0xB0080000, // 003E RAISE 2 R0 R0 - 0x500C0000, // 003F LDBOOL R3 0 0 - 0x88100107, // 0040 GETMBR R4 R0 K7 - 0x4C140000, // 0041 LDNIL R5 - 0x1C100805, // 0042 EQ R4 R4 R5 - 0x7812000A, // 0043 JMPF R4 #004F - 0x8C100517, // 0044 GETMET R4 R2 K23 - 0x58180016, // 0045 LDCONST R6 K22 - 0x7C100400, // 0046 CALL R4 2 - 0x8C100918, // 0047 GETMET R4 R4 K24 - 0x58180019, // 0048 LDCONST R6 K25 - 0x581C0016, // 0049 LDCONST R7 K22 - 0x7C100600, // 004A CALL R4 3 - 0x54160FFE, // 004B LDINT R5 4095 - 0x2C100805, // 004C AND R4 R4 R5 - 0x90020E04, // 004D SETMBR R0 K7 R4 - 0x500C0200, // 004E LDBOOL R3 1 0 - 0x8810010A, // 004F GETMBR R4 R0 K10 - 0x4C140000, // 0050 LDNIL R5 - 0x1C100805, // 0051 EQ R4 R4 R5 - 0x78120003, // 0052 JMPF R4 #0057 - 0x8C10011A, // 0053 GETMET R4 R0 K26 - 0x7C100200, // 0054 CALL R4 1 - 0x90021404, // 0055 SETMBR R0 K10 R4 - 0x500C0200, // 0056 LDBOOL R3 1 0 - 0x780E0001, // 0057 JMPF R3 #005A - 0x8C10011B, // 0058 GETMET R4 R0 K27 - 0x7C100200, // 0059 CALL R4 1 - 0x80000000, // 005A RET 0 + ( &(const binstruction[17]) { /* code */ + 0x58080000, // 0000 LDCONST R2 K0 + 0x600C000C, // 0001 GETGBL R3 G12 + 0x88100101, // 0002 GETMBR R4 R0 K1 + 0x7C0C0200, // 0003 CALL R3 1 + 0x140C0403, // 0004 LT R3 R2 R3 + 0x780E0008, // 0005 JMPF R3 #000F + 0x880C0101, // 0006 GETMBR R3 R0 K1 + 0x940C0602, // 0007 GETIDX R3 R3 R2 + 0x8C100702, // 0008 GETMET R4 R3 K2 + 0x7C100200, // 0009 CALL R4 1 + 0x1C100801, // 000A EQ R4 R4 R1 + 0x78120000, // 000B JMPF R4 #000D + 0x80040600, // 000C RET 1 R3 + 0x00080503, // 000D ADD R2 R2 K3 + 0x7001FFF1, // 000E JMP #0001 + 0x4C0C0000, // 000F LDNIL R3 + 0x80040600, // 0010 RET 1 R3 }) ) ); @@ -4013,79 +5095,30 @@ be_local_closure(Matter_Device_load_param, /* name */ /******************************************************************** -** Solidified function: k2l +** Solidified function: received_ack ********************************************************************/ -be_local_closure(Matter_Device_k2l, /* name */ +be_local_closure(Matter_Device_received_ack, /* name */ be_nested_proto( - 8, /* nstack */ - 1, /* argc */ - 4, /* varg */ + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_const_class(be_class_Matter_Device), - /* K1 */ be_nested_str_weak(keys), - /* K2 */ be_nested_str_weak(push), - /* K3 */ be_nested_str_weak(stop_iteration), - /* K4 */ be_const_int(1), - /* K5 */ be_const_int(0), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(udp_server), + /* K1 */ be_nested_str_weak(received_ack), }), - be_str_weak(k2l), + be_str_weak(received_ack), &be_const_str_solidified, - ( &(const binstruction[50]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0x60080012, // 0001 GETGBL R2 G18 - 0x7C080000, // 0002 CALL R2 0 - 0x4C0C0000, // 0003 LDNIL R3 - 0x1C0C0003, // 0004 EQ R3 R0 R3 - 0x780E0000, // 0005 JMPF R3 #0007 - 0x80040400, // 0006 RET 1 R2 - 0x600C0010, // 0007 GETGBL R3 G16 - 0x8C100101, // 0008 GETMET R4 R0 K1 - 0x7C100200, // 0009 CALL R4 1 - 0x7C0C0200, // 000A CALL R3 1 - 0xA8020005, // 000B EXBLK 0 #0012 - 0x5C100600, // 000C MOVE R4 R3 - 0x7C100000, // 000D CALL R4 0 - 0x8C140502, // 000E GETMET R5 R2 K2 - 0x5C1C0800, // 000F MOVE R7 R4 - 0x7C140400, // 0010 CALL R5 2 - 0x7001FFF9, // 0011 JMP #000C - 0x580C0003, // 0012 LDCONST R3 K3 - 0xAC0C0200, // 0013 CATCH R3 1 0 - 0xB0080000, // 0014 RAISE 2 R0 R0 - 0x600C0010, // 0015 GETGBL R3 G16 - 0x6010000C, // 0016 GETGBL R4 G12 - 0x5C140400, // 0017 MOVE R5 R2 - 0x7C100200, // 0018 CALL R4 1 - 0x04100904, // 0019 SUB R4 R4 K4 - 0x40120804, // 001A CONNECT R4 K4 R4 - 0x7C0C0200, // 001B CALL R3 1 - 0xA8020010, // 001C EXBLK 0 #002E - 0x5C100600, // 001D MOVE R4 R3 - 0x7C100000, // 001E CALL R4 0 - 0x94140404, // 001F GETIDX R5 R2 R4 - 0x5C180800, // 0020 MOVE R6 R4 - 0x241C0D05, // 0021 GT R7 R6 K5 - 0x781E0008, // 0022 JMPF R7 #002C - 0x041C0D04, // 0023 SUB R7 R6 K4 - 0x941C0407, // 0024 GETIDX R7 R2 R7 - 0x241C0E05, // 0025 GT R7 R7 R5 - 0x781E0004, // 0026 JMPF R7 #002C - 0x041C0D04, // 0027 SUB R7 R6 K4 - 0x941C0407, // 0028 GETIDX R7 R2 R7 - 0x98080C07, // 0029 SETIDX R2 R6 R7 - 0x04180D04, // 002A SUB R6 R6 K4 - 0x7001FFF4, // 002B JMP #0021 - 0x98080C05, // 002C SETIDX R2 R6 R5 - 0x7001FFEE, // 002D JMP #001D - 0x580C0003, // 002E LDCONST R3 K3 - 0xAC0C0200, // 002F CATCH R3 1 0 - 0xB0080000, // 0030 RAISE 2 R0 R0 - 0x80040400, // 0031 RET 1 R2 + ( &(const binstruction[ 5]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C080400, // 0003 CALL R2 2 + 0x80040400, // 0004 RET 1 R2 }) ) ); @@ -4093,9 +5126,9 @@ be_local_closure(Matter_Device_k2l, /* name */ /******************************************************************** -** Solidified function: autoconf_device +** Solidified function: generate_random_passcode ********************************************************************/ -be_local_closure(Matter_Device_autoconf_device, /* name */ +be_local_closure(Matter_Device_generate_random_passcode, /* name */ be_nested_proto( 7, /* nstack */ 1, /* argc */ @@ -4105,60 +5138,54 @@ be_local_closure(Matter_Device_autoconf_device, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(json), - /* K2 */ be_nested_str_weak(plugins), + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(crypto), + /* K1 */ be_nested_str_weak(random), + /* K2 */ be_nested_str_weak(get), /* K3 */ be_const_int(0), - /* K4 */ be_nested_str_weak(plugins_config), - /* K5 */ be_nested_str_weak(autoconf_device_map), - /* K6 */ be_nested_str_weak(tasmota), - /* K7 */ be_nested_str_weak(log), - /* K8 */ be_nested_str_weak(MTR_X3A_X20autoconfig_X20_X3D_X20), - /* K9 */ be_const_int(3), - /* K10 */ be_nested_str_weak(_load_plugins_config), - /* K11 */ be_nested_str_weak(plugins_persist), - /* K12 */ be_nested_str_weak(sessions), - /* K13 */ be_nested_str_weak(count_active_fabrics), - /* K14 */ be_nested_str_weak(save_param), + /* K4 */ be_const_int(134217727), + /* K5 */ be_const_int(99999998), + /* K6 */ be_nested_str_weak(PASSCODE_INVALID), + /* K7 */ be_nested_str_weak(stop_iteration), }), - be_str_weak(autoconf_device), + be_str_weak(generate_random_passcode), &be_const_str_solidified, - ( &(const binstruction[34]) { /* code */ + ( &(const binstruction[35]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0x600C000C, // 0002 GETGBL R3 G12 - 0x88100102, // 0003 GETMBR R4 R0 K2 - 0x7C0C0200, // 0004 CALL R3 1 - 0x240C0703, // 0005 GT R3 R3 K3 - 0x780E0000, // 0006 JMPF R3 #0008 - 0x80000600, // 0007 RET 0 - 0x8C0C0105, // 0008 GETMET R3 R0 K5 - 0x7C0C0200, // 0009 CALL R3 1 - 0x90020803, // 000A SETMBR R0 K4 R3 - 0xB80E0C00, // 000B GETNGBL R3 K6 - 0x8C0C0707, // 000C GETMET R3 R3 K7 - 0x60140008, // 000D GETGBL R5 G8 - 0x88180104, // 000E GETMBR R6 R0 K4 - 0x7C140200, // 000F CALL R5 1 - 0x00161005, // 0010 ADD R5 K8 R5 - 0x58180009, // 0011 LDCONST R6 K9 - 0x7C0C0600, // 0012 CALL R3 3 - 0x8C0C010A, // 0013 GETMET R3 R0 K10 - 0x88140104, // 0014 GETMBR R5 R0 K4 - 0x7C0C0400, // 0015 CALL R3 2 - 0x880C010B, // 0016 GETMBR R3 R0 K11 - 0x740E0008, // 0017 JMPT R3 #0021 - 0x880C010C, // 0018 GETMBR R3 R0 K12 - 0x8C0C070D, // 0019 GETMET R3 R3 K13 - 0x7C0C0200, // 001A CALL R3 1 - 0x240C0703, // 001B GT R3 R3 K3 - 0x780E0003, // 001C JMPF R3 #0021 - 0x500C0200, // 001D LDBOOL R3 1 0 - 0x90021603, // 001E SETMBR R0 K11 R3 - 0x8C0C010E, // 001F GETMET R3 R0 K14 - 0x7C0C0200, // 0020 CALL R3 1 - 0x80000000, // 0021 RET 0 + 0x4C080000, // 0001 LDNIL R2 + 0x500C0200, // 0002 LDBOOL R3 1 0 + 0x780E001D, // 0003 JMPF R3 #0022 + 0x8C0C0301, // 0004 GETMET R3 R1 K1 + 0x54160003, // 0005 LDINT R5 4 + 0x7C0C0400, // 0006 CALL R3 2 + 0x8C0C0702, // 0007 GETMET R3 R3 K2 + 0x58140003, // 0008 LDCONST R5 K3 + 0x541A0003, // 0009 LDINT R6 4 + 0x7C0C0600, // 000A CALL R3 3 + 0x2C0C0704, // 000B AND R3 R3 K4 + 0x5C080600, // 000C MOVE R2 R3 + 0x240C0505, // 000D GT R3 R2 K5 + 0x780E0000, // 000E JMPF R3 #0010 + 0x7001FFF1, // 000F JMP #0002 + 0x600C0010, // 0010 GETGBL R3 G16 + 0x88100106, // 0011 GETMBR R4 R0 K6 + 0x7C0C0200, // 0012 CALL R3 1 + 0xA8020005, // 0013 EXBLK 0 #001A + 0x5C100600, // 0014 MOVE R4 R3 + 0x7C100000, // 0015 CALL R4 0 + 0x1C140404, // 0016 EQ R5 R2 R4 + 0x78160000, // 0017 JMPF R5 #0019 + 0x4C080000, // 0018 LDNIL R2 + 0x7001FFF9, // 0019 JMP #0014 + 0x580C0007, // 001A LDCONST R3 K7 + 0xAC0C0200, // 001B CATCH R3 1 0 + 0xB0080000, // 001C RAISE 2 R0 R0 + 0x4C0C0000, // 001D LDNIL R3 + 0x200C0403, // 001E NE R3 R2 R3 + 0x780E0000, // 001F JMPF R3 #0021 + 0x80040400, // 0020 RET 1 R2 + 0x7001FFDF, // 0021 JMP #0002 + 0x80000000, // 0022 RET 0 }) ) ); @@ -4166,328 +5193,205 @@ be_local_closure(Matter_Device_autoconf_device, /* name */ /******************************************************************** -** Solidified function: process_attribute_expansion +** Solidified function: _instantiate_plugins_from_config ********************************************************************/ -be_local_closure(Matter_Device_process_attribute_expansion, /* name */ +be_local_closure(Matter_Device__instantiate_plugins_from_config, /* name */ be_nested_proto( - 29, /* nstack */ - 3, /* argc */ + 18, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 1]) { - be_nested_proto( - 7, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(keys), - /* K1 */ be_nested_str_weak(push), - /* K2 */ be_nested_str_weak(stop_iteration), - /* K3 */ be_const_int(1), - /* K4 */ be_const_int(0), - }), - be_str_weak(keys_sorted), - &be_const_str_solidified, - ( &(const binstruction[45]) { /* code */ - 0x60040012, // 0000 GETGBL R1 G18 - 0x7C040000, // 0001 CALL R1 0 - 0x60080010, // 0002 GETGBL R2 G16 - 0x8C0C0100, // 0003 GETMET R3 R0 K0 - 0x7C0C0200, // 0004 CALL R3 1 - 0x7C080200, // 0005 CALL R2 1 - 0xA8020005, // 0006 EXBLK 0 #000D - 0x5C0C0400, // 0007 MOVE R3 R2 - 0x7C0C0000, // 0008 CALL R3 0 - 0x8C100301, // 0009 GETMET R4 R1 K1 - 0x5C180600, // 000A MOVE R6 R3 - 0x7C100400, // 000B CALL R4 2 - 0x7001FFF9, // 000C JMP #0007 - 0x58080002, // 000D LDCONST R2 K2 - 0xAC080200, // 000E CATCH R2 1 0 - 0xB0080000, // 000F RAISE 2 R0 R0 - 0x60080010, // 0010 GETGBL R2 G16 - 0x600C000C, // 0011 GETGBL R3 G12 - 0x5C100200, // 0012 MOVE R4 R1 - 0x7C0C0200, // 0013 CALL R3 1 - 0x040C0703, // 0014 SUB R3 R3 K3 - 0x400E0603, // 0015 CONNECT R3 K3 R3 - 0x7C080200, // 0016 CALL R2 1 - 0xA8020010, // 0017 EXBLK 0 #0029 - 0x5C0C0400, // 0018 MOVE R3 R2 - 0x7C0C0000, // 0019 CALL R3 0 - 0x94100203, // 001A GETIDX R4 R1 R3 - 0x5C140600, // 001B MOVE R5 R3 - 0x24180B04, // 001C GT R6 R5 K4 - 0x781A0008, // 001D JMPF R6 #0027 - 0x04180B03, // 001E SUB R6 R5 K3 - 0x94180206, // 001F GETIDX R6 R1 R6 - 0x24180C04, // 0020 GT R6 R6 R4 - 0x781A0004, // 0021 JMPF R6 #0027 - 0x04180B03, // 0022 SUB R6 R5 K3 - 0x94180206, // 0023 GETIDX R6 R1 R6 - 0x98040A06, // 0024 SETIDX R1 R5 R6 - 0x04140B03, // 0025 SUB R5 R5 K3 - 0x7001FFF4, // 0026 JMP #001C - 0x98040A04, // 0027 SETIDX R1 R5 R4 - 0x7001FFEE, // 0028 JMP #0018 - 0x58080002, // 0029 LDCONST R2 K2 - 0xAC080200, // 002A CATCH R2 1 0 - 0xB0080000, // 002B RAISE 2 R0 R0 - 0x80040200, // 002C RET 1 R1 - }) - ), - }), + 0, /* has sup protos */ + NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[22]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(endpoint), - /* K2 */ be_nested_str_weak(cluster), - /* K3 */ be_nested_str_weak(attribute), - /* K4 */ be_nested_str_weak(plugins), - /* K5 */ be_nested_str_weak(get_endpoint), - /* K6 */ be_nested_str_weak(contains), - /* K7 */ be_nested_str_weak(get_cluster_list), - /* K8 */ be_nested_str_weak(get_attribute_list), - /* K9 */ be_nested_str_weak(push), - /* K10 */ be_nested_str_weak(stop_iteration), - /* K11 */ be_nested_str_weak(tasmota), - /* K12 */ be_nested_str_weak(log), - /* K13 */ be_nested_str_weak(format), - /* K14 */ be_nested_str_weak(MTR_X3A_X20expansion_X20_X5B_X2502X_X5D_X2504X_X2F_X2504X), - /* K15 */ be_const_int(3), - /* K16 */ be_nested_str_weak(status), - /* K17 */ be_nested_str_weak(matter), - /* K18 */ be_nested_str_weak(UNSUPPORTED_ENDPOINT), - /* K19 */ be_nested_str_weak(UNSUPPORTED_CLUSTER), - /* K20 */ be_nested_str_weak(UNSUPPORTED_ATTRIBUTE), - /* K21 */ be_nested_str_weak(UNREPORTABLE_ATTRIBUTE), + ( &(const bvalue[30]) { /* constants */ + /* K0 */ be_nested_str_weak(k2l_num), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(log), + /* K3 */ be_nested_str_weak(MTR_X3A_X20Configuring_X20endpoints), + /* K4 */ be_const_int(2), + /* K5 */ be_nested_str_weak(plugins), + /* K6 */ be_nested_str_weak(push), + /* K7 */ be_nested_str_weak(matter), + /* K8 */ be_nested_str_weak(Plugin_Root), + /* K9 */ be_const_int(0), + /* K10 */ be_nested_str_weak(MTR_X3A_X20_X20_X20endpoint_X20_X3D_X20_X255i_X20type_X3A_X25s_X25s), + /* K11 */ be_nested_str_weak(root), + /* K12 */ be_nested_str_weak(), + /* K13 */ be_nested_str_weak(Plugin_Aggregator), + /* K14 */ be_nested_str_weak(find), + /* K15 */ be_nested_str_weak(type), + /* K16 */ be_nested_str_weak(MTR_X3A_X20no_X20class_X20name_X2C_X20skipping), + /* K17 */ be_const_int(3), + /* K18 */ be_nested_str_weak(MTR_X3A_X20only_X20one_X20root_X20node_X20allowed), + /* K19 */ be_nested_str_weak(plugins_classes), + /* K20 */ be_nested_str_weak(MTR_X3A_X20unknown_X20class_X20name_X20_X27), + /* K21 */ be_nested_str_weak(_X27_X20skipping), + /* K22 */ be_nested_str_weak(conf_to_log), + /* K23 */ be_nested_str_weak(MTR_X3A_X20Exception), + /* K24 */ be_nested_str_weak(_X7C), + /* K25 */ be_nested_str_weak(stop_iteration), + /* K26 */ be_nested_str_weak(aggregator), + /* K27 */ be_nested_str_weak(publish_result), + /* K28 */ be_nested_str_weak(_X7B_X22Matter_X22_X3A_X7B_X22Initialized_X22_X3A1_X7D_X7D), + /* K29 */ be_nested_str_weak(Matter), }), - be_str_weak(process_attribute_expansion), + be_str_weak(_instantiate_plugins_from_config), &be_const_str_solidified, - ( &(const binstruction[216]) { /* code */ - 0x840C0000, // 0000 CLOSURE R3 P0 - 0xA4120000, // 0001 IMPORT R4 K0 - 0x88140301, // 0002 GETMBR R5 R1 K1 - 0x50180000, // 0003 LDBOOL R6 0 0 - 0x881C0302, // 0004 GETMBR R7 R1 K2 - 0x50200000, // 0005 LDBOOL R8 0 0 - 0x88240303, // 0006 GETMBR R9 R1 K3 - 0x50280000, // 0007 LDBOOL R10 0 0 - 0x882C0301, // 0008 GETMBR R11 R1 K1 - 0x4C300000, // 0009 LDNIL R12 - 0x202C160C, // 000A NE R11 R11 R12 - 0x782E0007, // 000B JMPF R11 #0014 - 0x882C0302, // 000C GETMBR R11 R1 K2 - 0x4C300000, // 000D LDNIL R12 - 0x202C160C, // 000E NE R11 R11 R12 - 0x782E0003, // 000F JMPF R11 #0014 - 0x882C0303, // 0010 GETMBR R11 R1 K3 - 0x4C300000, // 0011 LDNIL R12 - 0x202C160C, // 0012 NE R11 R11 R12 - 0x742E0000, // 0013 JMPT R11 #0015 - 0x502C0001, // 0014 LDBOOL R11 0 1 - 0x502C0200, // 0015 LDBOOL R11 1 0 - 0x60300013, // 0016 GETGBL R12 G19 - 0x7C300000, // 0017 CALL R12 0 - 0x60340010, // 0018 GETGBL R13 G16 - 0x88380104, // 0019 GETMBR R14 R0 K4 - 0x7C340200, // 001A CALL R13 1 - 0xA8020055, // 001B EXBLK 0 #0072 - 0x5C381A00, // 001C MOVE R14 R13 - 0x7C380000, // 001D CALL R14 0 - 0x8C3C1D05, // 001E GETMET R15 R14 K5 - 0x7C3C0200, // 001F CALL R15 1 - 0x4C400000, // 0020 LDNIL R16 - 0x20400A10, // 0021 NE R16 R5 R16 - 0x78420002, // 0022 JMPF R16 #0026 - 0x20401E05, // 0023 NE R16 R15 R5 - 0x78420000, // 0024 JMPF R16 #0026 - 0x7001FFF5, // 0025 JMP #001C - 0x8C401906, // 0026 GETMET R16 R12 K6 - 0x5C481E00, // 0027 MOVE R18 R15 - 0x7C400400, // 0028 CALL R16 2 - 0x74420002, // 0029 JMPT R16 #002D - 0x60400013, // 002A GETGBL R16 G19 - 0x7C400000, // 002B CALL R16 0 - 0x98301E10, // 002C SETIDX R12 R15 R16 - 0x50180200, // 002D LDBOOL R6 1 0 - 0x8C401D07, // 002E GETMET R16 R14 K7 - 0x5C481E00, // 002F MOVE R18 R15 - 0x7C400400, // 0030 CALL R16 2 - 0x60440010, // 0031 GETGBL R17 G16 - 0x5C482000, // 0032 MOVE R18 R16 - 0x7C440200, // 0033 CALL R17 1 - 0xA8020038, // 0034 EXBLK 0 #006E - 0x5C482200, // 0035 MOVE R18 R17 - 0x7C480000, // 0036 CALL R18 0 - 0x4C4C0000, // 0037 LDNIL R19 - 0x204C0E13, // 0038 NE R19 R7 R19 - 0x784E0002, // 0039 JMPF R19 #003D - 0x204C2407, // 003A NE R19 R18 R7 - 0x784E0000, // 003B JMPF R19 #003D - 0x7001FFF7, // 003C JMP #0035 - 0x944C180F, // 003D GETIDX R19 R12 R15 - 0x8C4C2706, // 003E GETMET R19 R19 K6 - 0x5C542400, // 003F MOVE R21 R18 - 0x7C4C0400, // 0040 CALL R19 2 - 0x744E0003, // 0041 JMPT R19 #0046 - 0x944C180F, // 0042 GETIDX R19 R12 R15 - 0x60500013, // 0043 GETGBL R20 G19 - 0x7C500000, // 0044 CALL R20 0 - 0x984C2414, // 0045 SETIDX R19 R18 R20 - 0x50200200, // 0046 LDBOOL R8 1 0 - 0x8C4C1D08, // 0047 GETMET R19 R14 K8 - 0x5C541E00, // 0048 MOVE R21 R15 - 0x5C582400, // 0049 MOVE R22 R18 - 0x7C4C0600, // 004A CALL R19 3 - 0x60500010, // 004B GETGBL R20 G16 - 0x5C542600, // 004C MOVE R21 R19 - 0x7C500200, // 004D CALL R20 1 - 0xA802001A, // 004E EXBLK 0 #006A - 0x5C542800, // 004F MOVE R21 R20 - 0x7C540000, // 0050 CALL R21 0 - 0x4C580000, // 0051 LDNIL R22 - 0x20581216, // 0052 NE R22 R9 R22 - 0x785A0002, // 0053 JMPF R22 #0057 - 0x20582A09, // 0054 NE R22 R21 R9 - 0x785A0000, // 0055 JMPF R22 #0057 - 0x7001FFF7, // 0056 JMP #004F - 0x9458180F, // 0057 GETIDX R22 R12 R15 - 0x94582C12, // 0058 GETIDX R22 R22 R18 - 0x8C582D06, // 0059 GETMET R22 R22 K6 - 0x5C602A00, // 005A MOVE R24 R21 - 0x7C580400, // 005B CALL R22 2 - 0x745A0004, // 005C JMPT R22 #0062 - 0x9458180F, // 005D GETIDX R22 R12 R15 - 0x94582C12, // 005E GETIDX R22 R22 R18 - 0x605C0012, // 005F GETGBL R23 G18 - 0x7C5C0000, // 0060 CALL R23 0 - 0x98582A17, // 0061 SETIDX R22 R21 R23 - 0x50280200, // 0062 LDBOOL R10 1 0 - 0x9458180F, // 0063 GETIDX R22 R12 R15 - 0x94582C12, // 0064 GETIDX R22 R22 R18 - 0x94582C15, // 0065 GETIDX R22 R22 R21 - 0x8C582D09, // 0066 GETMET R22 R22 K9 - 0x5C601C00, // 0067 MOVE R24 R14 - 0x7C580400, // 0068 CALL R22 2 - 0x7001FFE4, // 0069 JMP #004F - 0x5850000A, // 006A LDCONST R20 K10 - 0xAC500200, // 006B CATCH R20 1 0 - 0xB0080000, // 006C RAISE 2 R0 R0 - 0x7001FFC6, // 006D JMP #0035 - 0x5844000A, // 006E LDCONST R17 K10 - 0xAC440200, // 006F CATCH R17 1 0 - 0xB0080000, // 0070 RAISE 2 R0 R0 - 0x7001FFA9, // 0071 JMP #001C - 0x5834000A, // 0072 LDCONST R13 K10 - 0xAC340200, // 0073 CATCH R13 1 0 - 0xB0080000, // 0074 RAISE 2 R0 R0 - 0x60340010, // 0075 GETGBL R13 G16 - 0x5C380600, // 0076 MOVE R14 R3 - 0x5C3C1800, // 0077 MOVE R15 R12 - 0x7C380200, // 0078 CALL R14 1 - 0x7C340200, // 0079 CALL R13 1 - 0xA802003D, // 007A EXBLK 0 #00B9 - 0x5C381A00, // 007B MOVE R14 R13 - 0x7C380000, // 007C CALL R14 0 - 0x603C0010, // 007D GETGBL R15 G16 - 0x5C400600, // 007E MOVE R16 R3 - 0x9444180E, // 007F GETIDX R17 R12 R14 - 0x7C400200, // 0080 CALL R16 1 - 0x7C3C0200, // 0081 CALL R15 1 - 0xA8020031, // 0082 EXBLK 0 #00B5 - 0x5C401E00, // 0083 MOVE R16 R15 - 0x7C400000, // 0084 CALL R16 0 - 0x60440010, // 0085 GETGBL R17 G16 - 0x5C480600, // 0086 MOVE R18 R3 - 0x944C180E, // 0087 GETIDX R19 R12 R14 - 0x944C2610, // 0088 GETIDX R19 R19 R16 - 0x7C480200, // 0089 CALL R18 1 - 0x7C440200, // 008A CALL R17 1 - 0xA8020024, // 008B EXBLK 0 #00B1 - 0x5C482200, // 008C MOVE R18 R17 - 0x7C480000, // 008D CALL R18 0 - 0x604C0010, // 008E GETGBL R19 G16 - 0x9450180E, // 008F GETIDX R20 R12 R14 - 0x94502810, // 0090 GETIDX R20 R20 R16 - 0x94502812, // 0091 GETIDX R20 R20 R18 - 0x7C4C0200, // 0092 CALL R19 1 - 0xA8020018, // 0093 EXBLK 0 #00AD - 0x5C502600, // 0094 MOVE R20 R19 - 0x7C500000, // 0095 CALL R20 0 - 0xB8561600, // 0096 GETNGBL R21 K11 - 0x8C542B0C, // 0097 GETMET R21 R21 K12 - 0x8C5C090D, // 0098 GETMET R23 R4 K13 - 0x5864000E, // 0099 LDCONST R25 K14 - 0x5C681C00, // 009A MOVE R26 R14 - 0x5C6C2000, // 009B MOVE R27 R16 - 0x5C702400, // 009C MOVE R28 R18 - 0x7C5C0A00, // 009D CALL R23 5 - 0x5860000F, // 009E LDCONST R24 K15 - 0x7C540600, // 009F CALL R21 3 - 0x9006020E, // 00A0 SETMBR R1 K1 R14 - 0x90060410, // 00A1 SETMBR R1 K2 R16 - 0x90060612, // 00A2 SETMBR R1 K3 R18 - 0x5C540400, // 00A3 MOVE R21 R2 - 0x5C582800, // 00A4 MOVE R22 R20 - 0x5C5C0200, // 00A5 MOVE R23 R1 - 0x5C601600, // 00A6 MOVE R24 R11 - 0x7C540600, // 00A7 CALL R21 3 - 0x782E0002, // 00A8 JMPF R11 #00AC - 0x78560001, // 00A9 JMPF R21 #00AC - 0xA8040004, // 00AA EXBLK 1 4 - 0x80002C00, // 00AB RET 0 - 0x7001FFE6, // 00AC JMP #0094 - 0x584C000A, // 00AD LDCONST R19 K10 - 0xAC4C0200, // 00AE CATCH R19 1 0 - 0xB0080000, // 00AF RAISE 2 R0 R0 - 0x7001FFDA, // 00B0 JMP #008C - 0x5844000A, // 00B1 LDCONST R17 K10 - 0xAC440200, // 00B2 CATCH R17 1 0 - 0xB0080000, // 00B3 RAISE 2 R0 R0 - 0x7001FFCD, // 00B4 JMP #0083 - 0x583C000A, // 00B5 LDCONST R15 K10 - 0xAC3C0200, // 00B6 CATCH R15 1 0 - 0xB0080000, // 00B7 RAISE 2 R0 R0 - 0x7001FFC1, // 00B8 JMP #007B - 0x5834000A, // 00B9 LDCONST R13 K10 - 0xAC340200, // 00BA CATCH R13 1 0 - 0xB0080000, // 00BB RAISE 2 R0 R0 - 0x782E0019, // 00BC JMPF R11 #00D7 - 0x5C340C00, // 00BD MOVE R13 R6 - 0x74360003, // 00BE JMPT R13 #00C3 - 0xB8362200, // 00BF GETNGBL R13 K17 - 0x88341B12, // 00C0 GETMBR R13 R13 K18 - 0x9006200D, // 00C1 SETMBR R1 K16 R13 - 0x7002000E, // 00C2 JMP #00D2 - 0x5C341000, // 00C3 MOVE R13 R8 - 0x74360003, // 00C4 JMPT R13 #00C9 - 0xB8362200, // 00C5 GETNGBL R13 K17 - 0x88341B13, // 00C6 GETMBR R13 R13 K19 - 0x9006200D, // 00C7 SETMBR R1 K16 R13 - 0x70020008, // 00C8 JMP #00D2 - 0x5C341400, // 00C9 MOVE R13 R10 - 0x74360003, // 00CA JMPT R13 #00CF - 0xB8362200, // 00CB GETNGBL R13 K17 - 0x88341B14, // 00CC GETMBR R13 R13 K20 - 0x9006200D, // 00CD SETMBR R1 K16 R13 - 0x70020002, // 00CE JMP #00D2 - 0xB8362200, // 00CF GETNGBL R13 K17 - 0x88341B15, // 00D0 GETMBR R13 R13 K21 - 0x9006200D, // 00D1 SETMBR R1 K16 R13 - 0x5C340400, // 00D2 MOVE R13 R2 - 0x4C380000, // 00D3 LDNIL R14 - 0x5C3C0200, // 00D4 MOVE R15 R1 - 0x50400200, // 00D5 LDBOOL R16 1 0 - 0x7C340600, // 00D6 CALL R13 3 - 0x80000000, // 00D7 RET 0 + ( &(const binstruction[152]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0xB80E0200, // 0003 GETNGBL R3 K1 + 0x8C0C0702, // 0004 GETMET R3 R3 K2 + 0x58140003, // 0005 LDCONST R5 K3 + 0x58180004, // 0006 LDCONST R6 K4 + 0x7C0C0600, // 0007 CALL R3 3 + 0x880C0105, // 0008 GETMBR R3 R0 K5 + 0x8C0C0706, // 0009 GETMET R3 R3 K6 + 0xB8160E00, // 000A GETNGBL R5 K7 + 0x8C140B08, // 000B GETMET R5 R5 K8 + 0x5C1C0000, // 000C MOVE R7 R0 + 0x58200009, // 000D LDCONST R8 K9 + 0x60240013, // 000E GETGBL R9 G19 + 0x7C240000, // 000F CALL R9 0 + 0x7C140800, // 0010 CALL R5 4 + 0x7C0C0400, // 0011 CALL R3 2 + 0xB80E0200, // 0012 GETNGBL R3 K1 + 0x8C0C0702, // 0013 GETMET R3 R3 K2 + 0x60140018, // 0014 GETGBL R5 G24 + 0x5818000A, // 0015 LDCONST R6 K10 + 0x581C0009, // 0016 LDCONST R7 K9 + 0x5820000B, // 0017 LDCONST R8 K11 + 0x5824000C, // 0018 LDCONST R9 K12 + 0x7C140800, // 0019 CALL R5 4 + 0x58180004, // 001A LDCONST R6 K4 + 0x7C0C0600, // 001B CALL R3 3 + 0x880C0105, // 001C GETMBR R3 R0 K5 + 0x8C0C0706, // 001D GETMET R3 R3 K6 + 0xB8160E00, // 001E GETNGBL R5 K7 + 0x8C140B0D, // 001F GETMET R5 R5 K13 + 0x5C1C0000, // 0020 MOVE R7 R0 + 0x5422FEFF, // 0021 LDINT R8 65280 + 0x60240013, // 0022 GETGBL R9 G19 + 0x7C240000, // 0023 CALL R9 0 + 0x7C140800, // 0024 CALL R5 4 + 0x7C0C0400, // 0025 CALL R3 2 + 0x600C0010, // 0026 GETGBL R3 G16 + 0x5C100400, // 0027 MOVE R4 R2 + 0x7C0C0200, // 0028 CALL R3 1 + 0xA802005A, // 0029 EXBLK 0 #0085 + 0x5C100600, // 002A MOVE R4 R3 + 0x7C100000, // 002B CALL R4 0 + 0x1C140909, // 002C EQ R5 R4 K9 + 0x78160000, // 002D JMPF R5 #002F + 0x7001FFFA, // 002E JMP #002A + 0xA8020042, // 002F EXBLK 0 #0073 + 0x60140008, // 0030 GETGBL R5 G8 + 0x5C180800, // 0031 MOVE R6 R4 + 0x7C140200, // 0032 CALL R5 1 + 0x94140205, // 0033 GETIDX R5 R1 R5 + 0x8C180B0E, // 0034 GETMET R6 R5 K14 + 0x5820000F, // 0035 LDCONST R8 K15 + 0x7C180400, // 0036 CALL R6 2 + 0x4C1C0000, // 0037 LDNIL R7 + 0x1C1C0C07, // 0038 EQ R7 R6 R7 + 0x781E0006, // 0039 JMPF R7 #0041 + 0xB81E0200, // 003A GETNGBL R7 K1 + 0x8C1C0F02, // 003B GETMET R7 R7 K2 + 0x58240010, // 003C LDCONST R9 K16 + 0x58280011, // 003D LDCONST R10 K17 + 0x7C1C0600, // 003E CALL R7 3 + 0xA8040001, // 003F EXBLK 1 1 + 0x7001FFE8, // 0040 JMP #002A + 0x1C1C0D0B, // 0041 EQ R7 R6 K11 + 0x781E0006, // 0042 JMPF R7 #004A + 0xB81E0200, // 0043 GETNGBL R7 K1 + 0x8C1C0F02, // 0044 GETMET R7 R7 K2 + 0x58240012, // 0045 LDCONST R9 K18 + 0x58280011, // 0046 LDCONST R10 K17 + 0x7C1C0600, // 0047 CALL R7 3 + 0xA8040001, // 0048 EXBLK 1 1 + 0x7001FFDF, // 0049 JMP #002A + 0x881C0113, // 004A GETMBR R7 R0 K19 + 0x8C1C0F0E, // 004B GETMET R7 R7 K14 + 0x5C240C00, // 004C MOVE R9 R6 + 0x7C1C0400, // 004D CALL R7 2 + 0x4C200000, // 004E LDNIL R8 + 0x1C200E08, // 004F EQ R8 R7 R8 + 0x7822000A, // 0050 JMPF R8 #005C + 0xB8220200, // 0051 GETNGBL R8 K1 + 0x8C201102, // 0052 GETMET R8 R8 K2 + 0x60280008, // 0053 GETGBL R10 G8 + 0x5C2C0C00, // 0054 MOVE R11 R6 + 0x7C280200, // 0055 CALL R10 1 + 0x002A280A, // 0056 ADD R10 K20 R10 + 0x00281515, // 0057 ADD R10 R10 K21 + 0x582C0004, // 0058 LDCONST R11 K4 + 0x7C200600, // 0059 CALL R8 3 + 0xA8040001, // 005A EXBLK 1 1 + 0x7001FFCD, // 005B JMP #002A + 0x5C200E00, // 005C MOVE R8 R7 + 0x5C240000, // 005D MOVE R9 R0 + 0x5C280800, // 005E MOVE R10 R4 + 0x5C2C0A00, // 005F MOVE R11 R5 + 0x7C200600, // 0060 CALL R8 3 + 0x88240105, // 0061 GETMBR R9 R0 K5 + 0x8C241306, // 0062 GETMET R9 R9 K6 + 0x5C2C1000, // 0063 MOVE R11 R8 + 0x7C240400, // 0064 CALL R9 2 + 0xB8260200, // 0065 GETNGBL R9 K1 + 0x8C241302, // 0066 GETMET R9 R9 K2 + 0x602C0018, // 0067 GETGBL R11 G24 + 0x5830000A, // 0068 LDCONST R12 K10 + 0x5C340800, // 0069 MOVE R13 R4 + 0x5C380C00, // 006A MOVE R14 R6 + 0x8C3C0116, // 006B GETMET R15 R0 K22 + 0x5C440A00, // 006C MOVE R17 R5 + 0x7C3C0400, // 006D CALL R15 2 + 0x7C2C0800, // 006E CALL R11 4 + 0x58300004, // 006F LDCONST R12 K4 + 0x7C240600, // 0070 CALL R9 3 + 0xA8040001, // 0071 EXBLK 1 1 + 0x70020010, // 0072 JMP #0084 + 0xAC140002, // 0073 CATCH R5 0 2 + 0x7002000D, // 0074 JMP #0083 + 0xB81E0200, // 0075 GETNGBL R7 K1 + 0x8C1C0F02, // 0076 GETMET R7 R7 K2 + 0x60240008, // 0077 GETGBL R9 G8 + 0x5C280A00, // 0078 MOVE R10 R5 + 0x7C240200, // 0079 CALL R9 1 + 0x00262E09, // 007A ADD R9 K23 R9 + 0x00241318, // 007B ADD R9 R9 K24 + 0x60280008, // 007C GETGBL R10 G8 + 0x5C2C0C00, // 007D MOVE R11 R6 + 0x7C280200, // 007E CALL R10 1 + 0x0024120A, // 007F ADD R9 R9 R10 + 0x58280004, // 0080 LDCONST R10 K4 + 0x7C1C0600, // 0081 CALL R7 3 + 0x70020000, // 0082 JMP #0084 + 0xB0080000, // 0083 RAISE 2 R0 R0 + 0x7001FFA4, // 0084 JMP #002A + 0x580C0019, // 0085 LDCONST R3 K25 + 0xAC0C0200, // 0086 CATCH R3 1 0 + 0xB0080000, // 0087 RAISE 2 R0 R0 + 0xB80E0200, // 0088 GETNGBL R3 K1 + 0x8C0C0702, // 0089 GETMET R3 R3 K2 + 0x60140018, // 008A GETGBL R5 G24 + 0x5818000A, // 008B LDCONST R6 K10 + 0x541EFEFF, // 008C LDINT R7 65280 + 0x5820001A, // 008D LDCONST R8 K26 + 0x5824000C, // 008E LDCONST R9 K12 + 0x7C140800, // 008F CALL R5 4 + 0x58180004, // 0090 LDCONST R6 K4 + 0x7C0C0600, // 0091 CALL R3 3 + 0xB80E0200, // 0092 GETNGBL R3 K1 + 0x8C0C071B, // 0093 GETMET R3 R3 K27 + 0x5814001C, // 0094 LDCONST R5 K28 + 0x5818001D, // 0095 LDCONST R6 K29 + 0x7C0C0600, // 0096 CALL R3 3 + 0x80000000, // 0097 RET 0 }) ) ); @@ -4495,30 +5399,73 @@ be_local_closure(Matter_Device_process_attribute_expansion, /* name */ /******************************************************************** -** Solidified function: msg_send +** Solidified function: _compute_pbkdf ********************************************************************/ -be_local_closure(Matter_Device_msg_send, /* name */ +be_local_closure(Matter_Device__compute_pbkdf, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 13, /* nstack */ + 4, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(udp_server), - /* K1 */ be_nested_str_weak(send_UDP), + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str_weak(crypto), + /* K1 */ be_nested_str_weak(add), + /* K2 */ be_nested_str_weak(PBKDF2_HMAC_SHA256), + /* K3 */ be_nested_str_weak(derive), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(root_w0), + /* K6 */ be_nested_str_weak(EC_P256), + /* K7 */ be_nested_str_weak(mod), + /* K8 */ be_nested_str_weak(root_L), + /* K9 */ be_nested_str_weak(public_key), }), - be_str_weak(msg_send), + be_str_weak(_compute_pbkdf), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x5C100200, // 0002 MOVE R4 R1 - 0x7C080400, // 0003 CALL R2 2 - 0x80040400, // 0004 RET 1 R2 + ( &(const binstruction[40]) { /* code */ + 0xA4120000, // 0000 IMPORT R4 K0 + 0x60140015, // 0001 GETGBL R5 G21 + 0x7C140000, // 0002 CALL R5 0 + 0x8C140B01, // 0003 GETMET R5 R5 K1 + 0x5C1C0200, // 0004 MOVE R7 R1 + 0x54220003, // 0005 LDINT R8 4 + 0x7C140600, // 0006 CALL R5 3 + 0x8C180902, // 0007 GETMET R6 R4 K2 + 0x7C180200, // 0008 CALL R6 1 + 0x8C180D03, // 0009 GETMET R6 R6 K3 + 0x5C200A00, // 000A MOVE R8 R5 + 0x5C240600, // 000B MOVE R9 R3 + 0x5C280400, // 000C MOVE R10 R2 + 0x542E004F, // 000D LDINT R11 80 + 0x7C180A00, // 000E CALL R6 5 + 0x541E0026, // 000F LDINT R7 39 + 0x401E0807, // 0010 CONNECT R7 K4 R7 + 0x941C0C07, // 0011 GETIDX R7 R6 R7 + 0x54220027, // 0012 LDINT R8 40 + 0x5426004E, // 0013 LDINT R9 79 + 0x40201009, // 0014 CONNECT R8 R8 R9 + 0x94200C08, // 0015 GETIDX R8 R6 R8 + 0x8C240906, // 0016 GETMET R9 R4 K6 + 0x7C240200, // 0017 CALL R9 1 + 0x8C241307, // 0018 GETMET R9 R9 K7 + 0x5C2C0E00, // 0019 MOVE R11 R7 + 0x7C240400, // 001A CALL R9 2 + 0x90020A09, // 001B SETMBR R0 K5 R9 + 0x8C240906, // 001C GETMET R9 R4 K6 + 0x7C240200, // 001D CALL R9 1 + 0x8C241307, // 001E GETMET R9 R9 K7 + 0x5C2C1000, // 001F MOVE R11 R8 + 0x7C240400, // 0020 CALL R9 2 + 0x8C280906, // 0021 GETMET R10 R4 K6 + 0x7C280200, // 0022 CALL R10 1 + 0x8C281509, // 0023 GETMET R10 R10 K9 + 0x5C301200, // 0024 MOVE R12 R9 + 0x7C280400, // 0025 CALL R10 2 + 0x9002100A, // 0026 SETMBR R0 K8 R10 + 0x80000000, // 0027 RET 0 }) ) ); @@ -4526,9 +5473,9 @@ be_local_closure(Matter_Device_msg_send, /* name */ /******************************************************************** -** Solidified function: get_plugin_class_displayname +** Solidified function: get_plugin_class_arg ********************************************************************/ -be_local_closure(Matter_Device_get_plugin_class_displayname, /* name */ +be_local_closure(Matter_Device_get_plugin_class_arg, /* name */ be_nested_proto( 5, /* nstack */ 2, /* argc */ @@ -4541,10 +5488,10 @@ be_local_closure(Matter_Device_get_plugin_class_displayname, /* name */ ( &(const bvalue[ 4]) { /* constants */ /* K0 */ be_nested_str_weak(plugins_classes), /* K1 */ be_nested_str_weak(find), - /* K2 */ be_nested_str_weak(NAME), + /* K2 */ be_nested_str_weak(ARG), /* K3 */ be_nested_str_weak(), }), - be_str_weak(get_plugin_class_displayname), + be_str_weak(get_plugin_class_arg), &be_const_str_solidified, ( &(const binstruction[ 9]) { /* code */ 0x88080100, // 0000 GETMBR R2 R0 K0 @@ -4563,9 +5510,9 @@ be_local_closure(Matter_Device_get_plugin_class_displayname, /* name */ /******************************************************************** -** Solidified function: mdns_remove_op_discovery_all_fabrics +** Solidified function: mdns_announce_op_discovery_all_fabrics ********************************************************************/ -be_local_closure(Matter_Device_mdns_remove_op_discovery_all_fabrics, /* name */ +be_local_closure(Matter_Device_mdns_announce_op_discovery_all_fabrics, /* name */ be_nested_proto( 6, /* nstack */ 1, /* argc */ @@ -4580,10 +5527,10 @@ be_local_closure(Matter_Device_mdns_remove_op_discovery_all_fabrics, /* name * /* K1 */ be_nested_str_weak(active_fabrics), /* K2 */ be_nested_str_weak(get_device_id), /* K3 */ be_nested_str_weak(get_fabric_id), - /* K4 */ be_nested_str_weak(mdns_remove_op_discovery), + /* K4 */ be_nested_str_weak(mdns_announce_op_discovery), /* K5 */ be_nested_str_weak(stop_iteration), }), - be_str_weak(mdns_remove_op_discovery_all_fabrics), + be_str_weak(mdns_announce_op_discovery_all_fabrics), &be_const_str_solidified, ( &(const binstruction[22]) { /* code */ 0x60040010, // 0000 GETGBL R1 G16 @@ -4615,94 +5562,11 @@ be_local_closure(Matter_Device_mdns_remove_op_discovery_all_fabrics, /* name * /******************************************************************** -** Solidified function: msg_received -********************************************************************/ -be_local_closure(Matter_Device_msg_received, /* name */ - be_nested_proto( - 9, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(message_handler), - /* K1 */ be_nested_str_weak(msg_received), - }), - be_str_weak(msg_received), - &be_const_str_solidified, - ( &(const binstruction[ 7]) { /* code */ - 0x88100100, // 0000 GETMBR R4 R0 K0 - 0x8C100901, // 0001 GETMET R4 R4 K1 - 0x5C180200, // 0002 MOVE R6 R1 - 0x5C1C0400, // 0003 MOVE R7 R2 - 0x5C200600, // 0004 MOVE R8 R3 - 0x7C100800, // 0005 CALL R4 4 - 0x80040800, // 0006 RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: start_operational_discovery -********************************************************************/ -be_local_closure(Matter_Device_start_operational_discovery, /* name */ - be_nested_proto( - 9, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 9]) { /* constants */ - /* K0 */ be_nested_str_weak(crypto), - /* K1 */ be_nested_str_weak(mdns), - /* K2 */ be_nested_str_weak(string), - /* K3 */ be_nested_str_weak(stop_basic_commissioning), - /* K4 */ be_nested_str_weak(root_w0), - /* K5 */ be_nested_str_weak(root_L), - /* K6 */ be_nested_str_weak(set_expire_in_seconds), - /* K7 */ be_nested_str_weak(mdns_announce_op_discovery), - /* K8 */ be_nested_str_weak(get_fabric), - }), - be_str_weak(start_operational_discovery), - &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0xA40E0200, // 0001 IMPORT R3 K1 - 0xA4120400, // 0002 IMPORT R4 K2 - 0x8C140103, // 0003 GETMET R5 R0 K3 - 0x7C140200, // 0004 CALL R5 1 - 0x4C140000, // 0005 LDNIL R5 - 0x90020805, // 0006 SETMBR R0 K4 R5 - 0x4C140000, // 0007 LDNIL R5 - 0x90020A05, // 0008 SETMBR R0 K5 R5 - 0x8C140306, // 0009 GETMET R5 R1 K6 - 0x541E003B, // 000A LDINT R7 60 - 0x7C140400, // 000B CALL R5 2 - 0x8C140107, // 000C GETMET R5 R0 K7 - 0x8C1C0308, // 000D GETMET R7 R1 K8 - 0x7C1C0200, // 000E CALL R7 1 - 0x7C140400, // 000F CALL R5 2 - 0x80000000, // 0010 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: every_250ms +** Solidified function: event_fabrics_saved ********************************************************************/ -be_local_closure(Matter_Device_every_250ms, /* name */ +be_local_closure(Matter_Device_event_fabrics_saved, /* name */ be_nested_proto( - 4, /* nstack */ + 3, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -4711,31 +5575,27 @@ be_local_closure(Matter_Device_every_250ms, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(message_handler), - /* K1 */ be_nested_str_weak(every_250ms), + /* K0 */ be_nested_str_weak(sessions), + /* K1 */ be_nested_str_weak(count_active_fabrics), /* K2 */ be_const_int(0), - /* K3 */ be_nested_str_weak(plugins), - /* K4 */ be_const_int(1), - }), - be_str_weak(every_250ms), - &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x58040002, // 0003 LDCONST R1 K2 - 0x6008000C, // 0004 GETGBL R2 G12 - 0x880C0103, // 0005 GETMBR R3 R0 K3 - 0x7C080200, // 0006 CALL R2 1 - 0x14080202, // 0007 LT R2 R1 R2 - 0x780A0005, // 0008 JMPF R2 #000F - 0x88080103, // 0009 GETMBR R2 R0 K3 - 0x94080401, // 000A GETIDX R2 R2 R1 - 0x8C080501, // 000B GETMET R2 R2 K1 - 0x7C080200, // 000C CALL R2 1 - 0x00040304, // 000D ADD R1 R1 K4 - 0x7001FFF4, // 000E JMP #0004 - 0x80000000, // 000F RET 0 + /* K3 */ be_nested_str_weak(plugins_persist), + /* K4 */ be_nested_str_weak(save_param), + }), + be_str_weak(event_fabrics_saved), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x24040302, // 0003 GT R1 R1 K2 + 0x78060005, // 0004 JMPF R1 #000B + 0x88040103, // 0005 GETMBR R1 R0 K3 + 0x74060003, // 0006 JMPT R1 #000B + 0x50040200, // 0007 LDBOOL R1 1 0 + 0x90020601, // 0008 SETMBR R0 K3 R1 + 0x8C040104, // 0009 GETMET R1 R0 K4 + 0x7C040200, // 000A CALL R1 1 + 0x80000000, // 000B RET 0 }) ) ); @@ -4743,36 +5603,131 @@ be_local_closure(Matter_Device_every_250ms, /* name */ /******************************************************************** -** Solidified function: register_plugin_class +** Solidified function: start_mdns_announce_hostnames ********************************************************************/ -be_local_closure(Matter_Device_register_plugin_class, /* name */ +be_local_closure(Matter_Device_start_mdns_announce_hostnames, /* name */ be_nested_proto( - 7, /* nstack */ - 2, /* argc */ + 6, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 2]) { + be_nested_proto( + 4, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_mdns_announce_hostname), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(remove_rule), + /* K3 */ be_nested_str_weak(Wifi_X23Connected), + /* K4 */ be_nested_str_weak(matter_mdns_host), + }), + be_str_weak(_anonymous_), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x50080000, // 0002 LDBOOL R2 0 0 + 0x7C000400, // 0003 CALL R0 2 + 0xB8020200, // 0004 GETNGBL R0 K1 + 0x8C000102, // 0005 GETMET R0 R0 K2 + 0x58080003, // 0006 LDCONST R2 K3 + 0x580C0004, // 0007 LDCONST R3 K4 + 0x7C000600, // 0008 CALL R0 3 + 0x80000000, // 0009 RET 0 + }) + ), + be_nested_proto( + 4, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_mdns_announce_hostname), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(remove_rule), + /* K3 */ be_nested_str_weak(Eth_X23Connected), + /* K4 */ be_nested_str_weak(matter_mdns_host), + }), + be_str_weak(_anonymous_), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x50080200, // 0002 LDBOOL R2 1 0 + 0x7C000400, // 0003 CALL R0 2 + 0xB8020200, // 0004 GETNGBL R0 K1 + 0x8C000102, // 0005 GETMET R0 R0 K2 + 0x58080003, // 0006 LDCONST R2 K3 + 0x580C0004, // 0007 LDCONST R3 K4 + 0x7C000600, // 0008 CALL R0 3 + 0x80000000, // 0009 RET 0 + }) + ), + }), 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(introspect), - /* K1 */ be_nested_str_weak(get), - /* K2 */ be_nested_str_weak(TYPE), - /* K3 */ be_nested_str_weak(plugins_classes), + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(wifi), + /* K2 */ be_nested_str_weak(up), + /* K3 */ be_nested_str_weak(_mdns_announce_hostname), + /* K4 */ be_nested_str_weak(add_rule), + /* K5 */ be_nested_str_weak(Wifi_X23Connected), + /* K6 */ be_nested_str_weak(matter_mdns_host), + /* K7 */ be_nested_str_weak(eth), + /* K8 */ be_nested_str_weak(Eth_X23Connected), }), - be_str_weak(register_plugin_class), + be_str_weak(start_mdns_announce_hostnames), &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x8C0C0501, // 0001 GETMET R3 R2 K1 - 0x5C140200, // 0002 MOVE R5 R1 - 0x58180002, // 0003 LDCONST R6 K2 - 0x7C0C0600, // 0004 CALL R3 3 - 0x780E0001, // 0005 JMPF R3 #0008 - 0x88100103, // 0006 GETMBR R4 R0 K3 - 0x98100601, // 0007 SETIDX R4 R3 R1 - 0x80000000, // 0008 RET 0 + ( &(const binstruction[32]) { /* code */ + 0xB8060000, // 0000 GETNGBL R1 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x94040302, // 0003 GETIDX R1 R1 K2 + 0x78060003, // 0004 JMPF R1 #0009 + 0x8C040103, // 0005 GETMET R1 R0 K3 + 0x500C0000, // 0006 LDBOOL R3 0 0 + 0x7C040400, // 0007 CALL R1 2 + 0x70020005, // 0008 JMP #000F + 0xB8060000, // 0009 GETNGBL R1 K0 + 0x8C040304, // 000A GETMET R1 R1 K4 + 0x580C0005, // 000B LDCONST R3 K5 + 0x84100000, // 000C CLOSURE R4 P0 + 0x58140006, // 000D LDCONST R5 K6 + 0x7C040800, // 000E CALL R1 4 + 0xB8060000, // 000F GETNGBL R1 K0 + 0x8C040307, // 0010 GETMET R1 R1 K7 + 0x7C040200, // 0011 CALL R1 1 + 0x94040302, // 0012 GETIDX R1 R1 K2 + 0x78060003, // 0013 JMPF R1 #0018 + 0x8C040103, // 0014 GETMET R1 R0 K3 + 0x500C0200, // 0015 LDBOOL R3 1 0 + 0x7C040400, // 0016 CALL R1 2 + 0x70020005, // 0017 JMP #001E + 0xB8060000, // 0018 GETNGBL R1 K0 + 0x8C040304, // 0019 GETMET R1 R1 K4 + 0x580C0008, // 001A LDCONST R3 K8 + 0x84100001, // 001B CLOSURE R4 P1 + 0x58140006, // 001C LDCONST R5 K6 + 0x7C040800, // 001D CALL R1 4 + 0xA0000000, // 001E CLOSE R0 + 0x80000000, // 001F RET 0 }) ) ); @@ -4780,11 +5735,11 @@ be_local_closure(Matter_Device_register_plugin_class, /* name */ /******************************************************************** -** Solidified function: mdns_remove_PASE +** Solidified function: save_param ********************************************************************/ -be_local_closure(Matter_Device_mdns_remove_PASE, /* name */ +be_local_closure(Matter_Device_save_param, /* name */ be_nested_proto( - 12, /* nstack */ + 10, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -4792,116 +5747,123 @@ be_local_closure(Matter_Device_mdns_remove_PASE, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[22]) { /* constants */ - /* K0 */ be_nested_str_weak(mdns), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(mdns_pase_eth), - /* K3 */ be_nested_str_weak(tasmota), - /* K4 */ be_nested_str_weak(log), - /* K5 */ be_nested_str_weak(format), - /* K6 */ be_nested_str_weak(MTR_X3A_X20calling_X20mdns_X2Eremove_service_X28_X25s_X2C_X20_X25s_X2C_X20_X25s_X2C_X20_X25s_X29), - /* K7 */ be_nested_str_weak(_matterc), - /* K8 */ be_nested_str_weak(_udp), - /* K9 */ be_nested_str_weak(commissioning_instance_eth), - /* K10 */ be_nested_str_weak(hostname_eth), - /* K11 */ be_const_int(3), - /* K12 */ be_nested_str_weak(MTR_X3A_X20remove_X20mDNS_X20on_X20_X25s_X20_X27_X25s_X27), - /* K13 */ be_nested_str_weak(eth), - /* K14 */ be_const_int(2), - /* K15 */ be_nested_str_weak(remove_service), - /* K16 */ be_nested_str_weak(mdns_pase_wifi), - /* K17 */ be_nested_str_weak(commissioning_instance_wifi), - /* K18 */ be_nested_str_weak(hostname_wifi), - /* K19 */ be_nested_str_weak(wifi), - /* K20 */ be_nested_str_weak(MTR_X3A_X20Exception), - /* K21 */ be_nested_str_weak(_X7C), + ( &(const bvalue[30]) { /* constants */ + /* K0 */ be_nested_str_weak(json), + /* K1 */ be_nested_str_weak(update_remotes_info), + /* K2 */ be_nested_str_weak(_X7B_X22distinguish_X22_X3A_X25i_X2C_X22passcode_X22_X3A_X25i_X2C_X22ipv4only_X22_X3A_X25s_X2C_X22disable_bridge_mode_X22_X3A_X25s_X2C_X22nextep_X22_X3A_X25i), + /* K3 */ be_nested_str_weak(root_discriminator), + /* K4 */ be_nested_str_weak(root_passcode), + /* K5 */ be_nested_str_weak(ipv4only), + /* K6 */ be_nested_str_weak(true), + /* K7 */ be_nested_str_weak(false), + /* K8 */ be_nested_str_weak(disable_bridge_mode), + /* K9 */ be_nested_str_weak(next_ep), + /* K10 */ be_nested_str_weak(plugins_persist), + /* K11 */ be_nested_str_weak(_X2C_X22config_X22_X3A), + /* K12 */ be_nested_str_weak(dump), + /* K13 */ be_nested_str_weak(plugins_config), + /* K14 */ be_nested_str_weak(plugins_config_remotes), + /* K15 */ be_const_int(0), + /* K16 */ be_nested_str_weak(_X2C_X22remotes_X22_X3A), + /* K17 */ be_nested_str_weak(_X7D), + /* K18 */ be_nested_str_weak(FILENAME), + /* K19 */ be_nested_str_weak(w), + /* K20 */ be_nested_str_weak(write), + /* K21 */ be_nested_str_weak(close), + /* K22 */ be_nested_str_weak(tasmota), + /* K23 */ be_nested_str_weak(log), + /* K24 */ be_nested_str_weak(MTR_X3A_X20_X3DSaved_X20_X20_X20_X20_X20parameters_X25s), + /* K25 */ be_nested_str_weak(_X20and_X20configuration), + /* K26 */ be_nested_str_weak(), + /* K27 */ be_const_int(2), + /* K28 */ be_nested_str_weak(MTR_X3A_X20Session_Store_X3A_X3Asave_X20Exception_X3A), + /* K29 */ be_nested_str_weak(_X7C), }), - be_str_weak(mdns_remove_PASE), + be_str_weak(save_param), &be_const_str_solidified, - ( &(const binstruction[83]) { /* code */ + ( &(const binstruction[82]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0xA802003D, // 0002 EXBLK 0 #0041 - 0x880C0102, // 0003 GETMBR R3 R0 K2 - 0x780E001B, // 0004 JMPF R3 #0021 - 0xB80E0600, // 0005 GETNGBL R3 K3 - 0x8C0C0704, // 0006 GETMET R3 R3 K4 - 0x8C140505, // 0007 GETMET R5 R2 K5 - 0x581C0006, // 0008 LDCONST R7 K6 - 0x58200007, // 0009 LDCONST R8 K7 - 0x58240008, // 000A LDCONST R9 K8 - 0x88280109, // 000B GETMBR R10 R0 K9 - 0x882C010A, // 000C GETMBR R11 R0 K10 - 0x7C140C00, // 000D CALL R5 6 - 0x5818000B, // 000E LDCONST R6 K11 - 0x7C0C0600, // 000F CALL R3 3 - 0xB80E0600, // 0010 GETNGBL R3 K3 - 0x8C0C0704, // 0011 GETMET R3 R3 K4 - 0x8C140505, // 0012 GETMET R5 R2 K5 - 0x581C000C, // 0013 LDCONST R7 K12 - 0x5820000D, // 0014 LDCONST R8 K13 - 0x88240109, // 0015 GETMBR R9 R0 K9 - 0x7C140800, // 0016 CALL R5 4 - 0x5818000E, // 0017 LDCONST R6 K14 - 0x7C0C0600, // 0018 CALL R3 3 - 0x500C0000, // 0019 LDBOOL R3 0 0 - 0x90020403, // 001A SETMBR R0 K2 R3 - 0x8C0C030F, // 001B GETMET R3 R1 K15 - 0x58140007, // 001C LDCONST R5 K7 - 0x58180008, // 001D LDCONST R6 K8 - 0x881C0109, // 001E GETMBR R7 R0 K9 - 0x8820010A, // 001F GETMBR R8 R0 K10 - 0x7C0C0A00, // 0020 CALL R3 5 - 0x880C0110, // 0021 GETMBR R3 R0 K16 - 0x780E001B, // 0022 JMPF R3 #003F - 0xB80E0600, // 0023 GETNGBL R3 K3 - 0x8C0C0704, // 0024 GETMET R3 R3 K4 - 0x8C140505, // 0025 GETMET R5 R2 K5 - 0x581C0006, // 0026 LDCONST R7 K6 - 0x58200007, // 0027 LDCONST R8 K7 - 0x58240008, // 0028 LDCONST R9 K8 - 0x88280111, // 0029 GETMBR R10 R0 K17 - 0x882C0112, // 002A GETMBR R11 R0 K18 - 0x7C140C00, // 002B CALL R5 6 - 0x5818000B, // 002C LDCONST R6 K11 - 0x7C0C0600, // 002D CALL R3 3 - 0xB80E0600, // 002E GETNGBL R3 K3 - 0x8C0C0704, // 002F GETMET R3 R3 K4 - 0x8C140505, // 0030 GETMET R5 R2 K5 - 0x581C000C, // 0031 LDCONST R7 K12 - 0x58200013, // 0032 LDCONST R8 K19 - 0x88240111, // 0033 GETMBR R9 R0 K17 - 0x7C140800, // 0034 CALL R5 4 - 0x5818000E, // 0035 LDCONST R6 K14 - 0x7C0C0600, // 0036 CALL R3 3 - 0x500C0000, // 0037 LDBOOL R3 0 0 - 0x90022003, // 0038 SETMBR R0 K16 R3 - 0x8C0C030F, // 0039 GETMET R3 R1 K15 - 0x58140007, // 003A LDCONST R5 K7 - 0x58180008, // 003B LDCONST R6 K8 - 0x881C0111, // 003C GETMBR R7 R0 K17 - 0x88200112, // 003D GETMBR R8 R0 K18 - 0x7C0C0A00, // 003E CALL R3 5 - 0xA8040001, // 003F EXBLK 1 1 - 0x70020010, // 0040 JMP #0052 - 0xAC0C0002, // 0041 CATCH R3 0 2 - 0x7002000D, // 0042 JMP #0051 - 0xB8160600, // 0043 GETNGBL R5 K3 - 0x8C140B04, // 0044 GETMET R5 R5 K4 - 0x601C0008, // 0045 GETGBL R7 G8 - 0x5C200600, // 0046 MOVE R8 R3 - 0x7C1C0200, // 0047 CALL R7 1 - 0x001E2807, // 0048 ADD R7 K20 R7 - 0x001C0F15, // 0049 ADD R7 R7 K21 - 0x60200008, // 004A GETGBL R8 G8 - 0x5C240800, // 004B MOVE R9 R4 - 0x7C200200, // 004C CALL R8 1 - 0x001C0E08, // 004D ADD R7 R7 R8 - 0x5820000E, // 004E LDCONST R8 K14 - 0x7C140600, // 004F CALL R5 3 - 0x70020000, // 0050 JMP #0052 - 0xB0080000, // 0051 RAISE 2 R0 R0 - 0x80000000, // 0052 RET 0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x60080018, // 0003 GETGBL R2 G24 + 0x580C0002, // 0004 LDCONST R3 K2 + 0x88100103, // 0005 GETMBR R4 R0 K3 + 0x88140104, // 0006 GETMBR R5 R0 K4 + 0x88180105, // 0007 GETMBR R6 R0 K5 + 0x781A0001, // 0008 JMPF R6 #000B + 0x58180006, // 0009 LDCONST R6 K6 + 0x70020000, // 000A JMP #000C + 0x58180007, // 000B LDCONST R6 K7 + 0x881C0108, // 000C GETMBR R7 R0 K8 + 0x781E0001, // 000D JMPF R7 #0010 + 0x581C0006, // 000E LDCONST R7 K6 + 0x70020000, // 000F JMP #0011 + 0x581C0007, // 0010 LDCONST R7 K7 + 0x88200109, // 0011 GETMBR R8 R0 K9 + 0x7C080C00, // 0012 CALL R2 6 + 0x880C010A, // 0013 GETMBR R3 R0 K10 + 0x780E000E, // 0014 JMPF R3 #0024 + 0x0008050B, // 0015 ADD R2 R2 K11 + 0x8C0C030C, // 0016 GETMET R3 R1 K12 + 0x8814010D, // 0017 GETMBR R5 R0 K13 + 0x7C0C0400, // 0018 CALL R3 2 + 0x00080403, // 0019 ADD R2 R2 R3 + 0x600C000C, // 001A GETGBL R3 G12 + 0x8810010E, // 001B GETMBR R4 R0 K14 + 0x7C0C0200, // 001C CALL R3 1 + 0x240C070F, // 001D GT R3 R3 K15 + 0x780E0004, // 001E JMPF R3 #0024 + 0x00080510, // 001F ADD R2 R2 K16 + 0x8C0C030C, // 0020 GETMET R3 R1 K12 + 0x8814010E, // 0021 GETMBR R5 R0 K14 + 0x7C0C0400, // 0022 CALL R3 2 + 0x00080403, // 0023 ADD R2 R2 R3 + 0x00080511, // 0024 ADD R2 R2 K17 + 0xA8020018, // 0025 EXBLK 0 #003F + 0x600C0011, // 0026 GETGBL R3 G17 + 0x88100112, // 0027 GETMBR R4 R0 K18 + 0x58140013, // 0028 LDCONST R5 K19 + 0x7C0C0400, // 0029 CALL R3 2 + 0x8C100714, // 002A GETMET R4 R3 K20 + 0x5C180400, // 002B MOVE R6 R2 + 0x7C100400, // 002C CALL R4 2 + 0x8C100715, // 002D GETMET R4 R3 K21 + 0x7C100200, // 002E CALL R4 1 + 0xB8122C00, // 002F GETNGBL R4 K22 + 0x8C100917, // 0030 GETMET R4 R4 K23 + 0x60180018, // 0031 GETGBL R6 G24 + 0x581C0018, // 0032 LDCONST R7 K24 + 0x8820010A, // 0033 GETMBR R8 R0 K10 + 0x78220001, // 0034 JMPF R8 #0037 + 0x58200019, // 0035 LDCONST R8 K25 + 0x70020000, // 0036 JMP #0038 + 0x5820001A, // 0037 LDCONST R8 K26 + 0x7C180400, // 0038 CALL R6 2 + 0x581C001B, // 0039 LDCONST R7 K27 + 0x7C100600, // 003A CALL R4 3 + 0xA8040001, // 003B EXBLK 1 1 + 0x80040400, // 003C RET 1 R2 + 0xA8040001, // 003D EXBLK 1 1 + 0x70020011, // 003E JMP #0051 + 0xAC0C0002, // 003F CATCH R3 0 2 + 0x7002000E, // 0040 JMP #0050 + 0xB8162C00, // 0041 GETNGBL R5 K22 + 0x8C140B17, // 0042 GETMET R5 R5 K23 + 0x601C0008, // 0043 GETGBL R7 G8 + 0x5C200600, // 0044 MOVE R8 R3 + 0x7C1C0200, // 0045 CALL R7 1 + 0x001E3807, // 0046 ADD R7 K28 R7 + 0x001C0F1D, // 0047 ADD R7 R7 K29 + 0x60200008, // 0048 GETGBL R8 G8 + 0x5C240800, // 0049 MOVE R9 R4 + 0x7C200200, // 004A CALL R8 1 + 0x001C0E08, // 004B ADD R7 R7 R8 + 0x5820001B, // 004C LDCONST R8 K27 + 0x7C140600, // 004D CALL R5 3 + 0x80040400, // 004E RET 1 R2 + 0x70020000, // 004F JMP #0051 + 0xB0080000, // 0050 RAISE 2 R0 R0 + 0x80000000, // 0051 RET 0 }) ) ); @@ -4909,11 +5871,11 @@ be_local_closure(Matter_Device_mdns_remove_PASE, /* name */ /******************************************************************** -** Solidified function: compute_manual_pairing_code +** Solidified function: mdns_announce_PASE ********************************************************************/ -be_local_closure(Matter_Device_compute_manual_pairing_code, /* name */ +be_local_closure(Matter_Device_mdns_announce_PASE, /* name */ be_nested_proto( - 11, /* nstack */ + 12, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -4921,50 +5883,288 @@ be_local_closure(Matter_Device_compute_manual_pairing_code, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(root_discriminator), - /* K2 */ be_nested_str_weak(root_passcode), - /* K3 */ be_nested_str_weak(format), - /* K4 */ be_nested_str_weak(_X251i_X2505i_X2504i), - /* K5 */ be_nested_str_weak(matter), - /* K6 */ be_nested_str_weak(Verhoeff), - /* K7 */ be_nested_str_weak(checksum), + ( &(const bvalue[41]) { /* constants */ + /* K0 */ be_nested_str_weak(mdns), + /* K1 */ be_nested_str_weak(crypto), + /* K2 */ be_nested_str_weak(VP), + /* K3 */ be_nested_str_weak(vendorid), + /* K4 */ be_nested_str_weak(_X2B), + /* K5 */ be_nested_str_weak(productid), + /* K6 */ be_nested_str_weak(D), + /* K7 */ be_nested_str_weak(commissioning_discriminator), + /* K8 */ be_nested_str_weak(CM), + /* K9 */ be_const_int(1), + /* K10 */ be_nested_str_weak(T), + /* K11 */ be_const_int(0), + /* K12 */ be_nested_str_weak(SII), + /* K13 */ be_nested_str_weak(SAI), + /* K14 */ be_nested_str_weak(commissioning_instance_wifi), + /* K15 */ be_nested_str_weak(random), + /* K16 */ be_nested_str_weak(tohex), + /* K17 */ be_nested_str_weak(commissioning_instance_eth), + /* K18 */ be_nested_str_weak(hostname_eth), + /* K19 */ be_nested_str_weak(add_service), + /* K20 */ be_nested_str_weak(_matterc), + /* K21 */ be_nested_str_weak(_udp), + /* K22 */ be_nested_str_weak(mdns_pase_eth), + /* K23 */ be_nested_str_weak(tasmota), + /* K24 */ be_nested_str_weak(log), + /* K25 */ be_nested_str_weak(MTR_X3A_X20announce_X20mDNS_X20on_X20_X25s_X20_X27_X25s_X27_X20ptr_X20to_X20_X60_X25s_X2Elocal_X60), + /* K26 */ be_nested_str_weak(eth), + /* K27 */ be_const_int(2), + /* K28 */ be_nested_str_weak(_L), + /* K29 */ be_nested_str_weak(MTR_X3A_X20adding_X20subtype_X3A_X20), + /* K30 */ be_const_int(3), + /* K31 */ be_nested_str_weak(add_subtype), + /* K32 */ be_nested_str_weak(_S), + /* K33 */ be_nested_str_weak(_V), + /* K34 */ be_nested_str_weak(_CM1), + /* K35 */ be_nested_str_weak(hostname_wifi), + /* K36 */ be_nested_str_weak(mdns_pase_wifi), + /* K37 */ be_nested_str_weak(MTR_X3A_X20starting_X20mDNS_X20on_X20_X25s_X20_X27_X25s_X27_X20ptr_X20to_X20_X60_X25s_X2Elocal_X60), + /* K38 */ be_nested_str_weak(wifi), + /* K39 */ be_nested_str_weak(MTR_X3A_X20Exception), + /* K40 */ be_nested_str_weak(_X7C), }), - be_str_weak(compute_manual_pairing_code), + be_str_weak(mdns_announce_PASE), &be_const_str_solidified, - ( &(const binstruction[31]) { /* code */ + ( &(const binstruction[236]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 - 0x88080101, // 0001 GETMBR R2 R0 K1 - 0x540E0FFE, // 0002 LDINT R3 4095 - 0x2C080403, // 0003 AND R2 R2 R3 - 0x540E0009, // 0004 LDINT R3 10 - 0x3C080403, // 0005 SHR R2 R2 R3 - 0x880C0101, // 0006 GETMBR R3 R0 K1 - 0x541202FF, // 0007 LDINT R4 768 - 0x2C0C0604, // 0008 AND R3 R3 R4 - 0x54120005, // 0009 LDINT R4 6 - 0x380C0604, // 000A SHL R3 R3 R4 - 0x88100102, // 000B GETMBR R4 R0 K2 - 0x54163FFE, // 000C LDINT R5 16383 - 0x2C100805, // 000D AND R4 R4 R5 - 0x300C0604, // 000E OR R3 R3 R4 - 0x88100102, // 000F GETMBR R4 R0 K2 - 0x5416000D, // 0010 LDINT R5 14 - 0x3C100805, // 0011 SHR R4 R4 R5 - 0x8C140303, // 0012 GETMET R5 R1 K3 - 0x581C0004, // 0013 LDCONST R7 K4 - 0x5C200400, // 0014 MOVE R8 R2 - 0x5C240600, // 0015 MOVE R9 R3 - 0x5C280800, // 0016 MOVE R10 R4 - 0x7C140A00, // 0017 CALL R5 5 - 0xB81A0A00, // 0018 GETNGBL R6 K5 - 0x88180D06, // 0019 GETMBR R6 R6 K6 - 0x8C180D07, // 001A GETMET R6 R6 K7 - 0x5C200A00, // 001B MOVE R8 R5 - 0x7C180400, // 001C CALL R6 2 - 0x00140A06, // 001D ADD R5 R5 R6 - 0x80040A00, // 001E RET 1 R5 + 0xA40A0200, // 0001 IMPORT R2 K1 + 0x600C0013, // 0002 GETGBL R3 G19 + 0x7C0C0000, // 0003 CALL R3 0 + 0x60100008, // 0004 GETGBL R4 G8 + 0x88140103, // 0005 GETMBR R5 R0 K3 + 0x7C100200, // 0006 CALL R4 1 + 0x00100904, // 0007 ADD R4 R4 K4 + 0x60140008, // 0008 GETGBL R5 G8 + 0x88180105, // 0009 GETMBR R6 R0 K5 + 0x7C140200, // 000A CALL R5 1 + 0x00100805, // 000B ADD R4 R4 R5 + 0x980E0404, // 000C SETIDX R3 K2 R4 + 0x88100107, // 000D GETMBR R4 R0 K7 + 0x980E0C04, // 000E SETIDX R3 K6 R4 + 0x980E1109, // 000F SETIDX R3 K8 K9 + 0x980E150B, // 0010 SETIDX R3 K10 K11 + 0x54121387, // 0011 LDINT R4 5000 + 0x980E1804, // 0012 SETIDX R3 K12 R4 + 0x5412012B, // 0013 LDINT R4 300 + 0x980E1A04, // 0014 SETIDX R3 K13 R4 + 0x8C10050F, // 0015 GETMET R4 R2 K15 + 0x541A0007, // 0016 LDINT R6 8 + 0x7C100400, // 0017 CALL R4 2 + 0x8C100910, // 0018 GETMET R4 R4 K16 + 0x7C100200, // 0019 CALL R4 1 + 0x90021C04, // 001A SETMBR R0 K14 R4 + 0x8C10050F, // 001B GETMET R4 R2 K15 + 0x541A0007, // 001C LDINT R6 8 + 0x7C100400, // 001D CALL R4 2 + 0x8C100910, // 001E GETMET R4 R4 K16 + 0x7C100200, // 001F CALL R4 1 + 0x90022204, // 0020 SETMBR R0 K17 R4 + 0xA80200B7, // 0021 EXBLK 0 #00DA + 0x88100112, // 0022 GETMBR R4 R0 K18 + 0x78120058, // 0023 JMPF R4 #007D + 0x8C100313, // 0024 GETMET R4 R1 K19 + 0x58180014, // 0025 LDCONST R6 K20 + 0x581C0015, // 0026 LDCONST R7 K21 + 0x542215A3, // 0027 LDINT R8 5540 + 0x5C240600, // 0028 MOVE R9 R3 + 0x88280111, // 0029 GETMBR R10 R0 K17 + 0x882C0112, // 002A GETMBR R11 R0 K18 + 0x7C100E00, // 002B CALL R4 7 + 0x50100200, // 002C LDBOOL R4 1 0 + 0x90022C04, // 002D SETMBR R0 K22 R4 + 0xB8122E00, // 002E GETNGBL R4 K23 + 0x8C100918, // 002F GETMET R4 R4 K24 + 0x60180018, // 0030 GETGBL R6 G24 + 0x581C0019, // 0031 LDCONST R7 K25 + 0x5820001A, // 0032 LDCONST R8 K26 + 0x88240111, // 0033 GETMBR R9 R0 K17 + 0x88280112, // 0034 GETMBR R10 R0 K18 + 0x7C180800, // 0035 CALL R6 4 + 0x581C001B, // 0036 LDCONST R7 K27 + 0x7C100600, // 0037 CALL R4 3 + 0x60100008, // 0038 GETGBL R4 G8 + 0x88140107, // 0039 GETMBR R5 R0 K7 + 0x541A0FFE, // 003A LDINT R6 4095 + 0x2C140A06, // 003B AND R5 R5 R6 + 0x7C100200, // 003C CALL R4 1 + 0x00123804, // 003D ADD R4 K28 R4 + 0xB8162E00, // 003E GETNGBL R5 K23 + 0x8C140B18, // 003F GETMET R5 R5 K24 + 0x001E3A04, // 0040 ADD R7 K29 R4 + 0x5820001E, // 0041 LDCONST R8 K30 + 0x7C140600, // 0042 CALL R5 3 + 0x8C14031F, // 0043 GETMET R5 R1 K31 + 0x581C0014, // 0044 LDCONST R7 K20 + 0x58200015, // 0045 LDCONST R8 K21 + 0x88240111, // 0046 GETMBR R9 R0 K17 + 0x88280112, // 0047 GETMBR R10 R0 K18 + 0x5C2C0800, // 0048 MOVE R11 R4 + 0x7C140C00, // 0049 CALL R5 6 + 0x60140008, // 004A GETGBL R5 G8 + 0x88180107, // 004B GETMBR R6 R0 K7 + 0x541E0EFF, // 004C LDINT R7 3840 + 0x2C180C07, // 004D AND R6 R6 R7 + 0x541E0007, // 004E LDINT R7 8 + 0x3C180C07, // 004F SHR R6 R6 R7 + 0x7C140200, // 0050 CALL R5 1 + 0x00164005, // 0051 ADD R5 K32 R5 + 0x5C100A00, // 0052 MOVE R4 R5 + 0xB8162E00, // 0053 GETNGBL R5 K23 + 0x8C140B18, // 0054 GETMET R5 R5 K24 + 0x001E3A04, // 0055 ADD R7 K29 R4 + 0x5820001E, // 0056 LDCONST R8 K30 + 0x7C140600, // 0057 CALL R5 3 + 0x8C14031F, // 0058 GETMET R5 R1 K31 + 0x581C0014, // 0059 LDCONST R7 K20 + 0x58200015, // 005A LDCONST R8 K21 + 0x88240111, // 005B GETMBR R9 R0 K17 + 0x88280112, // 005C GETMBR R10 R0 K18 + 0x5C2C0800, // 005D MOVE R11 R4 + 0x7C140C00, // 005E CALL R5 6 + 0x60140008, // 005F GETGBL R5 G8 + 0x88180103, // 0060 GETMBR R6 R0 K3 + 0x7C140200, // 0061 CALL R5 1 + 0x00164205, // 0062 ADD R5 K33 R5 + 0x5C100A00, // 0063 MOVE R4 R5 + 0xB8162E00, // 0064 GETNGBL R5 K23 + 0x8C140B18, // 0065 GETMET R5 R5 K24 + 0x001E3A04, // 0066 ADD R7 K29 R4 + 0x5820001E, // 0067 LDCONST R8 K30 + 0x7C140600, // 0068 CALL R5 3 + 0x8C14031F, // 0069 GETMET R5 R1 K31 + 0x581C0014, // 006A LDCONST R7 K20 + 0x58200015, // 006B LDCONST R8 K21 + 0x88240111, // 006C GETMBR R9 R0 K17 + 0x88280112, // 006D GETMBR R10 R0 K18 + 0x5C2C0800, // 006E MOVE R11 R4 + 0x7C140C00, // 006F CALL R5 6 + 0x58100022, // 0070 LDCONST R4 K34 + 0xB8162E00, // 0071 GETNGBL R5 K23 + 0x8C140B18, // 0072 GETMET R5 R5 K24 + 0x001E3A04, // 0073 ADD R7 K29 R4 + 0x5820001E, // 0074 LDCONST R8 K30 + 0x7C140600, // 0075 CALL R5 3 + 0x8C14031F, // 0076 GETMET R5 R1 K31 + 0x581C0014, // 0077 LDCONST R7 K20 + 0x58200015, // 0078 LDCONST R8 K21 + 0x88240111, // 0079 GETMBR R9 R0 K17 + 0x88280112, // 007A GETMBR R10 R0 K18 + 0x5C2C0800, // 007B MOVE R11 R4 + 0x7C140C00, // 007C CALL R5 6 + 0x88100123, // 007D GETMBR R4 R0 K35 + 0x78120058, // 007E JMPF R4 #00D8 + 0x8C100313, // 007F GETMET R4 R1 K19 + 0x58180014, // 0080 LDCONST R6 K20 + 0x581C0015, // 0081 LDCONST R7 K21 + 0x542215A3, // 0082 LDINT R8 5540 + 0x5C240600, // 0083 MOVE R9 R3 + 0x8828010E, // 0084 GETMBR R10 R0 K14 + 0x882C0123, // 0085 GETMBR R11 R0 K35 + 0x7C100E00, // 0086 CALL R4 7 + 0x50100200, // 0087 LDBOOL R4 1 0 + 0x90024804, // 0088 SETMBR R0 K36 R4 + 0xB8122E00, // 0089 GETNGBL R4 K23 + 0x8C100918, // 008A GETMET R4 R4 K24 + 0x60180018, // 008B GETGBL R6 G24 + 0x581C0025, // 008C LDCONST R7 K37 + 0x58200026, // 008D LDCONST R8 K38 + 0x8824010E, // 008E GETMBR R9 R0 K14 + 0x88280123, // 008F GETMBR R10 R0 K35 + 0x7C180800, // 0090 CALL R6 4 + 0x581C001E, // 0091 LDCONST R7 K30 + 0x7C100600, // 0092 CALL R4 3 + 0x60100008, // 0093 GETGBL R4 G8 + 0x88140107, // 0094 GETMBR R5 R0 K7 + 0x541A0FFE, // 0095 LDINT R6 4095 + 0x2C140A06, // 0096 AND R5 R5 R6 + 0x7C100200, // 0097 CALL R4 1 + 0x00123804, // 0098 ADD R4 K28 R4 + 0xB8162E00, // 0099 GETNGBL R5 K23 + 0x8C140B18, // 009A GETMET R5 R5 K24 + 0x001E3A04, // 009B ADD R7 K29 R4 + 0x5820001E, // 009C LDCONST R8 K30 + 0x7C140600, // 009D CALL R5 3 + 0x8C14031F, // 009E GETMET R5 R1 K31 + 0x581C0014, // 009F LDCONST R7 K20 + 0x58200015, // 00A0 LDCONST R8 K21 + 0x8824010E, // 00A1 GETMBR R9 R0 K14 + 0x88280123, // 00A2 GETMBR R10 R0 K35 + 0x5C2C0800, // 00A3 MOVE R11 R4 + 0x7C140C00, // 00A4 CALL R5 6 + 0x60140008, // 00A5 GETGBL R5 G8 + 0x88180107, // 00A6 GETMBR R6 R0 K7 + 0x541E0EFF, // 00A7 LDINT R7 3840 + 0x2C180C07, // 00A8 AND R6 R6 R7 + 0x541E0007, // 00A9 LDINT R7 8 + 0x3C180C07, // 00AA SHR R6 R6 R7 + 0x7C140200, // 00AB CALL R5 1 + 0x00164005, // 00AC ADD R5 K32 R5 + 0x5C100A00, // 00AD MOVE R4 R5 + 0xB8162E00, // 00AE GETNGBL R5 K23 + 0x8C140B18, // 00AF GETMET R5 R5 K24 + 0x001E3A04, // 00B0 ADD R7 K29 R4 + 0x5820001E, // 00B1 LDCONST R8 K30 + 0x7C140600, // 00B2 CALL R5 3 + 0x8C14031F, // 00B3 GETMET R5 R1 K31 + 0x581C0014, // 00B4 LDCONST R7 K20 + 0x58200015, // 00B5 LDCONST R8 K21 + 0x8824010E, // 00B6 GETMBR R9 R0 K14 + 0x88280123, // 00B7 GETMBR R10 R0 K35 + 0x5C2C0800, // 00B8 MOVE R11 R4 + 0x7C140C00, // 00B9 CALL R5 6 + 0x60140008, // 00BA GETGBL R5 G8 + 0x88180103, // 00BB GETMBR R6 R0 K3 + 0x7C140200, // 00BC CALL R5 1 + 0x00164205, // 00BD ADD R5 K33 R5 + 0x5C100A00, // 00BE MOVE R4 R5 + 0xB8162E00, // 00BF GETNGBL R5 K23 + 0x8C140B18, // 00C0 GETMET R5 R5 K24 + 0x001E3A04, // 00C1 ADD R7 K29 R4 + 0x5820001E, // 00C2 LDCONST R8 K30 + 0x7C140600, // 00C3 CALL R5 3 + 0x8C14031F, // 00C4 GETMET R5 R1 K31 + 0x581C0014, // 00C5 LDCONST R7 K20 + 0x58200015, // 00C6 LDCONST R8 K21 + 0x8824010E, // 00C7 GETMBR R9 R0 K14 + 0x88280123, // 00C8 GETMBR R10 R0 K35 + 0x5C2C0800, // 00C9 MOVE R11 R4 + 0x7C140C00, // 00CA CALL R5 6 + 0x58100022, // 00CB LDCONST R4 K34 + 0xB8162E00, // 00CC GETNGBL R5 K23 + 0x8C140B18, // 00CD GETMET R5 R5 K24 + 0x001E3A04, // 00CE ADD R7 K29 R4 + 0x5820001E, // 00CF LDCONST R8 K30 + 0x7C140600, // 00D0 CALL R5 3 + 0x8C14031F, // 00D1 GETMET R5 R1 K31 + 0x581C0014, // 00D2 LDCONST R7 K20 + 0x58200015, // 00D3 LDCONST R8 K21 + 0x8824010E, // 00D4 GETMBR R9 R0 K14 + 0x88280123, // 00D5 GETMBR R10 R0 K35 + 0x5C2C0800, // 00D6 MOVE R11 R4 + 0x7C140C00, // 00D7 CALL R5 6 + 0xA8040001, // 00D8 EXBLK 1 1 + 0x70020010, // 00D9 JMP #00EB + 0xAC100002, // 00DA CATCH R4 0 2 + 0x7002000D, // 00DB JMP #00EA + 0xB81A2E00, // 00DC GETNGBL R6 K23 + 0x8C180D18, // 00DD GETMET R6 R6 K24 + 0x60200008, // 00DE GETGBL R8 G8 + 0x5C240800, // 00DF MOVE R9 R4 + 0x7C200200, // 00E0 CALL R8 1 + 0x00224E08, // 00E1 ADD R8 K39 R8 + 0x00201128, // 00E2 ADD R8 R8 K40 + 0x60240008, // 00E3 GETGBL R9 G8 + 0x5C280A00, // 00E4 MOVE R10 R5 + 0x7C240200, // 00E5 CALL R9 1 + 0x00201009, // 00E6 ADD R8 R8 R9 + 0x5824001B, // 00E7 LDCONST R9 K27 + 0x7C180600, // 00E8 CALL R6 3 + 0x70020000, // 00E9 JMP #00EB + 0xB0080000, // 00EA RAISE 2 R0 R0 + 0x80000000, // 00EB RET 0 }) ) ); @@ -4975,83 +6175,13 @@ be_local_closure(Matter_Device_compute_manual_pairing_code, /* name */ ** Solidified class: Matter_Device ********************************************************************/ be_local_class(Matter_Device, - 32, + 37, NULL, - be_nested_map(93, + be_nested_map(114, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(message_handler, -1), be_const_var(6) }, - { be_const_key_weak(generate_random_passcode, -1), be_const_closure(Matter_Device_generate_random_passcode_closure) }, - { be_const_key_weak(save_param, -1), be_const_closure(Matter_Device_save_param_closure) }, - { be_const_key_weak(mdns_pase_wifi, -1), be_const_var(24) }, - { be_const_key_weak(remove_fabric, 28), be_const_closure(Matter_Device_remove_fabric_closure) }, - { be_const_key_weak(_start_udp, -1), be_const_closure(Matter_Device__start_udp_closure) }, - { be_const_key_weak(root_iterations, -1), be_const_var(28) }, - { be_const_key_weak(commissioning_discriminator, -1), be_const_var(12) }, - { be_const_key_weak(commissioning_w0, -1), be_const_var(14) }, - { be_const_key_weak(compute_manual_pairing_code, 66), be_const_closure(Matter_Device_compute_manual_pairing_code_closure) }, - { be_const_key_weak(root_discriminator, -1), be_const_var(25) }, - { be_const_key_weak(stop, -1), be_const_closure(Matter_Device_stop_closure) }, - { be_const_key_weak(mdns_remove_PASE, 22), be_const_closure(Matter_Device_mdns_remove_PASE_closure) }, - { be_const_key_weak(plugins_config, -1), be_const_var(4) }, - { be_const_key_weak(start_commissioning_complete, -1), be_const_closure(Matter_Device_start_commissioning_complete_closure) }, - { be_const_key_weak(_trigger_read_sensors, 62), be_const_closure(Matter_Device__trigger_read_sensors_closure) }, - { be_const_key_weak(register_plugin_class, -1), be_const_closure(Matter_Device_register_plugin_class_closure) }, - { be_const_key_weak(root_passcode, 12), be_const_var(26) }, - { be_const_key_weak(every_250ms, 19), be_const_closure(Matter_Device_every_250ms_closure) }, - { be_const_key_weak(commissioning_instance_eth, -1), be_const_var(18) }, - { be_const_key_weak(vendorid, -1), be_const_var(21) }, - { be_const_key_weak(register_native_classes, 89), be_const_closure(Matter_Device_register_native_classes_closure) }, - { be_const_key_weak(start_operational_discovery, 15), be_const_closure(Matter_Device_start_operational_discovery_closure) }, - { be_const_key_weak(_init_basic_commissioning, -1), be_const_closure(Matter_Device__init_basic_commissioning_closure) }, - { be_const_key_weak(compute_qrcode_content, -1), be_const_closure(Matter_Device_compute_qrcode_content_closure) }, - { be_const_key_weak(is_root_commissioning_open, -1), be_const_closure(Matter_Device_is_root_commissioning_open_closure) }, - { be_const_key_weak(commissioning_open, -1), be_const_var(10) }, - { be_const_key_weak(commissioning_instance_wifi, -1), be_const_var(17) }, - { be_const_key_weak(msg_received, -1), be_const_closure(Matter_Device_msg_received_closure) }, - { be_const_key_weak(get_active_endpoints, -1), be_const_closure(Matter_Device_get_active_endpoints_closure) }, - { be_const_key_weak(MtrJoin, -1), be_const_closure(Matter_Device_MtrJoin_closure) }, - { be_const_key_weak(productid, 73), be_const_var(22) }, - { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Device_invoke_request_closure) }, - { be_const_key_weak(get_plugin_class_displayname, 59), be_const_closure(Matter_Device_get_plugin_class_displayname_closure) }, - { be_const_key_weak(event_fabrics_saved, -1), be_const_closure(Matter_Device_event_fabrics_saved_closure) }, - { be_const_key_weak(start, 86), be_const_closure(Matter_Device_start_closure) }, - { be_const_key_weak(k2l_num, -1), be_const_static_closure(Matter_Device_k2l_num_closure) }, - { be_const_key_weak(mdns_announce_op_discovery, -1), be_const_closure(Matter_Device_mdns_announce_op_discovery_closure) }, - { be_const_key_weak(root_salt, -1), be_const_var(29) }, - { be_const_key_weak(every_second, 78), be_const_closure(Matter_Device_every_second_closure) }, - { be_const_key_weak(commissioning_L, -1), be_const_var(15) }, - { be_const_key_weak(hostname_wifi, 18), be_const_var(19) }, - { be_const_key_weak(get_plugin_class_arg, 61), be_const_closure(Matter_Device_get_plugin_class_arg_closure) }, - { be_const_key_weak(started, 84), be_const_var(0) }, - { be_const_key_weak(root_w0, 25), be_const_var(30) }, - { be_const_key_weak(mdns_announce_PASE, -1), be_const_closure(Matter_Device_mdns_announce_PASE_closure) }, - { be_const_key_weak(autoconf_device_map, 82), be_const_closure(Matter_Device_autoconf_device_map_closure) }, - { be_const_key_weak(every_50ms, -1), be_const_closure(Matter_Device_every_50ms_closure) }, - { be_const_key_weak(commissioning_admin_fabric, -1), be_const_var(16) }, - { be_const_key_weak(msg_send, 30), be_const_closure(Matter_Device_msg_send_closure) }, - { be_const_key_weak(commissioning_salt, -1), be_const_var(13) }, - { be_const_key_weak(plugins, -1), be_const_var(1) }, - { be_const_key_weak(PBKDF_ITERATIONS, -1), be_const_int(1000) }, - { be_const_key_weak(_mdns_announce_hostname, 50), be_const_closure(Matter_Device__mdns_announce_hostname_closure) }, - { be_const_key_weak(start_mdns_announce_hostnames, -1), be_const_closure(Matter_Device_start_mdns_announce_hostnames_closure) }, - { be_const_key_weak(attribute_updated, 49), be_const_closure(Matter_Device_attribute_updated_closure) }, { be_const_key_weak(PRODUCT_ID, -1), be_const_int(32768) }, - { be_const_key_weak(root_L, -1), be_const_var(31) }, - { be_const_key_weak(register_commands, 77), be_const_closure(Matter_Device_register_commands_closure) }, - { be_const_key_weak(plugins_persist, -1), be_const_var(2) }, - { be_const_key_weak(init, 57), be_const_closure(Matter_Device_init_closure) }, - { be_const_key_weak(_compute_pbkdf, -1), be_const_closure(Matter_Device__compute_pbkdf_closure) }, - { be_const_key_weak(hostname_eth, -1), be_const_var(20) }, - { be_const_key_weak(received_ack, -1), be_const_closure(Matter_Device_received_ack_closure) }, - { be_const_key_weak(VENDOR_ID, -1), be_const_int(65521) }, - { be_const_key_weak(FILENAME, -1), be_nested_str_weak(_matter_device_X2Ejson) }, - { be_const_key_weak(load_param, -1), be_const_closure(Matter_Device_load_param_closure) }, - { be_const_key_weak(mdns_announce_op_discovery_all_fabrics, -1), be_const_closure(Matter_Device_mdns_announce_op_discovery_all_fabrics_closure) }, - { be_const_key_weak(tick, 70), be_const_var(9) }, - { be_const_key_weak(udp_server, 67), be_const_var(5) }, - { be_const_key_weak(start_basic_commissioning, -1), be_const_closure(Matter_Device_start_basic_commissioning_closure) }, - { be_const_key_weak(k2l, -1), be_const_static_closure(Matter_Device_k2l_closure) }, - { be_const_key_weak(PASSCODE_INVALID, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + { be_const_key_weak(autoconf_device_map, -1), be_const_closure(Matter_Device_autoconf_device_map_closure) }, + { be_const_key_weak(PASSCODE_INVALID, 23), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { be_const_list( * be_nested_list(12, ( (struct bvalue*) &(const bvalue[]) { be_const_int(0), @@ -5067,26 +6197,117 @@ be_local_class(Matter_Device, be_const_int(12345678), be_const_int(87654321), })) ) } )) }, - { be_const_key_weak(start_root_basic_commissioning, -1), be_const_closure(Matter_Device_start_root_basic_commissioning_closure) }, - { be_const_key_weak(autoconf_device, -1), be_const_closure(Matter_Device_autoconf_device_closure) }, - { be_const_key_weak(save_before_restart, 56), be_const_closure(Matter_Device_save_before_restart_closure) }, - { be_const_key_weak(process_attribute_expansion, -1), be_const_closure(Matter_Device_process_attribute_expansion_closure) }, - { be_const_key_weak(_load_plugins_config, -1), be_const_closure(Matter_Device__load_plugins_config_closure) }, - { be_const_key_weak(mdns_pase_eth, -1), be_const_var(23) }, - { be_const_key_weak(PASE_TIMEOUT, 33), be_const_int(600) }, - { be_const_key_weak(is_commissioning_open, 31), be_const_closure(Matter_Device_is_commissioning_open_closure) }, - { be_const_key_weak(mdns_remove_op_discovery_all_fabrics, -1), be_const_closure(Matter_Device_mdns_remove_op_discovery_all_fabrics_closure) }, + { be_const_key_weak(remove_fabric, -1), be_const_closure(Matter_Device_remove_fabric_closure) }, + { be_const_key_weak(is_root_commissioning_open, -1), be_const_closure(Matter_Device_is_root_commissioning_open_closure) }, + { be_const_key_weak(_init_basic_commissioning, 4), be_const_closure(Matter_Device__init_basic_commissioning_closure) }, + { be_const_key_weak(compute_manual_pairing_code, -1), be_const_closure(Matter_Device_compute_manual_pairing_code_closure) }, + { be_const_key_weak(ui, -1), be_const_var(10) }, + { be_const_key_weak(vendorid, 50), be_const_var(23) }, + { be_const_key_weak(root_L, 87), be_const_var(36) }, + { be_const_key_weak(sessions, -1), be_const_var(9) }, + { be_const_key_weak(stop, -1), be_const_closure(Matter_Device_stop_closure) }, + { be_const_key_weak(bridge_add_endpoint, -1), be_const_closure(Matter_Device_bridge_add_endpoint_closure) }, { be_const_key_weak(mdns_remove_op_discovery, -1), be_const_closure(Matter_Device_mdns_remove_op_discovery_closure) }, - { be_const_key_weak(ui, -1), be_const_var(8) }, - { be_const_key_weak(sessions, -1), be_const_var(7) }, - { be_const_key_weak(plugins_classes, -1), be_const_var(3) }, - { be_const_key_weak(sort_distinct, 47), be_const_static_closure(Matter_Device_sort_distinct_closure) }, - { be_const_key_weak(commissioning_iterations, 16), be_const_var(11) }, - { be_const_key_weak(UDP_PORT, -1), be_const_int(5540) }, + { be_const_key_weak(start_mdns_announce_hostnames, 36), be_const_closure(Matter_Device_start_mdns_announce_hostnames_closure) }, + { be_const_key_weak(disable_bridge_mode, 17), be_const_var(31) }, + { be_const_key_weak(get_plugin_class_displayname, 1), be_const_closure(Matter_Device_get_plugin_class_displayname_closure) }, + { be_const_key_weak(http_remotes, -1), be_const_var(27) }, + { be_const_key_weak(clean_remotes, -1), be_const_closure(Matter_Device_clean_remotes_closure) }, + { be_const_key_weak(get_plugin_remote_info, 49), be_const_closure(Matter_Device_get_plugin_remote_info_closure) }, + { be_const_key_weak(_mdns_announce_hostname, -1), be_const_closure(Matter_Device__mdns_announce_hostname_closure) }, + { be_const_key_weak(register_native_classes, 55), be_const_closure(Matter_Device_register_native_classes_closure) }, + { be_const_key_weak(_start_udp, 109), be_const_closure(Matter_Device__start_udp_closure) }, + { be_const_key_weak(get_plugin_class_arg, 33), be_const_closure(Matter_Device_get_plugin_class_arg_closure) }, + { be_const_key_weak(commissioning_admin_fabric, -1), be_const_var(18) }, + { be_const_key_weak(msg_send, -1), be_const_closure(Matter_Device_msg_send_closure) }, + { be_const_key_weak(commissioning_w0, 102), be_const_var(16) }, + { be_const_key_weak(mdns_pase_eth, -1), be_const_var(25) }, + { be_const_key_weak(process_attribute_read_solo, -1), be_const_closure(Matter_Device_process_attribute_read_solo_closure) }, + { be_const_key_weak(invoke_request, 108), be_const_closure(Matter_Device_invoke_request_closure) }, + { be_const_key_weak(adjust_next_ep, 104), be_const_closure(Matter_Device_adjust_next_ep_closure) }, + { be_const_key_weak(attribute_updated, -1), be_const_closure(Matter_Device_attribute_updated_closure) }, + { be_const_key_weak(mdns_remove_PASE, 107), be_const_closure(Matter_Device_mdns_remove_PASE_closure) }, + { be_const_key_weak(_compute_pbkdf, 90), be_const_closure(Matter_Device__compute_pbkdf_closure) }, + { be_const_key_weak(ipv4only, 71), be_const_var(30) }, + { be_const_key_weak(get_active_endpoints, -1), be_const_closure(Matter_Device_get_active_endpoints_closure) }, + { be_const_key_weak(k2l_num, -1), be_const_static_closure(Matter_Device_k2l_num_closure) }, + { be_const_key_weak(autoconf_sensors_list, -1), be_const_closure(Matter_Device_autoconf_sensors_list_closure) }, + { be_const_key_weak(start_basic_commissioning, -1), be_const_closure(Matter_Device_start_basic_commissioning_closure) }, + { be_const_key_weak(bridge_remove_endpoint, 14), be_const_closure(Matter_Device_bridge_remove_endpoint_closure) }, + { be_const_key_weak(msg_received, -1), be_const_closure(Matter_Device_msg_received_closure) }, + { be_const_key_weak(start, -1), be_const_closure(Matter_Device_start_closure) }, { be_const_key_weak(stop_basic_commissioning, -1), be_const_closure(Matter_Device_stop_basic_commissioning_closure) }, - { be_const_key_weak(start_commissioning_complete_deferred, 9), be_const_closure(Matter_Device_start_commissioning_complete_deferred_closure) }, - { be_const_key_weak(ipv4only, 3), be_const_var(27) }, - { be_const_key_weak(start_operational_discovery_deferred, 0), be_const_closure(Matter_Device_start_operational_discovery_deferred_closure) }, + { be_const_key_weak(generate_random_passcode, -1), be_const_closure(Matter_Device_generate_random_passcode_closure) }, + { be_const_key_weak(started, 65), be_const_var(0) }, + { be_const_key_weak(signal_endpoints_changed, -1), be_const_closure(Matter_Device_signal_endpoints_changed_closure) }, + { be_const_key_weak(MtrJoin, 48), be_const_closure(Matter_Device_MtrJoin_closure) }, + { be_const_key_weak(productid, -1), be_const_var(24) }, + { be_const_key_weak(find_plugin_by_endpoint, -1), be_const_closure(Matter_Device_find_plugin_by_endpoint_closure) }, + { be_const_key_weak(PBKDF_ITERATIONS, 3), be_const_int(1000) }, + { be_const_key_weak(hostname_eth, 97), be_const_var(22) }, + { be_const_key_weak(init, 37), be_const_closure(Matter_Device_init_closure) }, + { be_const_key_weak(register_http_remote, 40), be_const_closure(Matter_Device_register_http_remote_closure) }, + { be_const_key_weak(commissioning_salt, 98), be_const_var(15) }, + { be_const_key_weak(mdns_pase_wifi, -1), be_const_var(26) }, + { be_const_key_weak(load_param, -1), be_const_closure(Matter_Device_load_param_closure) }, + { be_const_key_weak(hostname_wifi, 93), be_const_var(21) }, + { be_const_key_weak(compute_qrcode_content, 45), be_const_closure(Matter_Device_compute_qrcode_content_closure) }, + { be_const_key_weak(plugins_config, -1), be_const_var(4) }, + { be_const_key_weak(start_root_basic_commissioning, -1), be_const_closure(Matter_Device_start_root_basic_commissioning_closure) }, + { be_const_key_weak(save_before_restart, -1), be_const_closure(Matter_Device_save_before_restart_closure) }, + { be_const_key_weak(register_commands, 54), be_const_closure(Matter_Device_register_commands_closure) }, + { be_const_key_weak(root_salt, -1), be_const_var(34) }, + { be_const_key_weak(commissioning_iterations, 2), be_const_var(13) }, + { be_const_key_weak(find_plugin_by_friendly_name, -1), be_const_closure(Matter_Device_find_plugin_by_friendly_name_closure) }, + { be_const_key_weak(plugins_persist, -1), be_const_var(2) }, + { be_const_key_weak(udp_server, -1), be_const_var(6) }, + { be_const_key_weak(next_ep, -1), be_const_var(32) }, + { be_const_key_weak(start_operational_discovery_deferred, 72), be_const_closure(Matter_Device_start_operational_discovery_deferred_closure) }, + { be_const_key_weak(every_second, -1), be_const_closure(Matter_Device_every_second_closure) }, + { be_const_key_weak(UDP_PORT, -1), be_const_int(5540) }, + { be_const_key_weak(mdns_announce_op_discovery, 30), be_const_closure(Matter_Device_mdns_announce_op_discovery_closure) }, + { be_const_key_weak(message_handler, -1), be_const_var(8) }, + { be_const_key_weak(process_attribute_expansion, 43), be_const_closure(Matter_Device_process_attribute_expansion_closure) }, + { be_const_key_weak(is_commissioning_open, 62), be_const_closure(Matter_Device_is_commissioning_open_closure) }, + { be_const_key_weak(start_commissioning_complete_deferred, -1), be_const_closure(Matter_Device_start_commissioning_complete_deferred_closure) }, + { be_const_key_weak(plugins_classes, 44), be_const_var(3) }, + { be_const_key_weak(start_operational_discovery, 68), be_const_closure(Matter_Device_start_operational_discovery_closure) }, + { be_const_key_weak(mdns_remove_op_discovery_all_fabrics, 9), be_const_closure(Matter_Device_mdns_remove_op_discovery_all_fabrics_closure) }, + { be_const_key_weak(commissioning_discriminator, -1), be_const_var(14) }, + { be_const_key_weak(FILENAME, -1), be_nested_str_weak(_matter_device_X2Ejson) }, + { be_const_key_weak(root_iterations, 112), be_const_var(33) }, + { be_const_key_weak(commissioning_open, -1), be_const_var(12) }, + { be_const_key_weak(_trigger_read_sensors, 82), be_const_closure(Matter_Device__trigger_read_sensors_closure) }, + { be_const_key_weak(commissioning_instance_wifi, 81), be_const_var(19) }, + { be_const_key_weak(VENDOR_ID, -1), be_const_int(65521) }, + { be_const_key_weak(tick, -1), be_const_var(11) }, + { be_const_key_weak(MtrInfo, -1), be_const_closure(Matter_Device_MtrInfo_closure) }, + { be_const_key_weak(root_discriminator, 67), be_const_var(28) }, + { be_const_key_weak(start_commissioning_complete, 7), be_const_closure(Matter_Device_start_commissioning_complete_closure) }, + { be_const_key_weak(register_plugin_class, 95), be_const_closure(Matter_Device_register_plugin_class_closure) }, + { be_const_key_weak(MtrUpdate, -1), be_const_closure(Matter_Device_MtrUpdate_closure) }, + { be_const_key_weak(sort_distinct, -1), be_const_static_closure(Matter_Device_sort_distinct_closure) }, + { be_const_key_weak(commissioning_instance_eth, -1), be_const_var(20) }, + { be_const_key_weak(conf_to_log, -1), be_const_static_closure(Matter_Device_conf_to_log_closure) }, + { be_const_key_weak(MtrInfo_one, -1), be_const_closure(Matter_Device_MtrInfo_one_closure) }, + { be_const_key_weak(received_ack, -1), be_const_closure(Matter_Device_received_ack_closure) }, + { be_const_key_weak(k2l, -1), be_const_static_closure(Matter_Device_k2l_closure) }, + { be_const_key_weak(update_remotes_info, -1), be_const_closure(Matter_Device_update_remotes_info_closure) }, + { be_const_key_weak(plugins, -1), be_const_var(1) }, + { be_const_key_weak(profiler, -1), be_const_var(7) }, + { be_const_key_weak(_instantiate_plugins_from_config, -1), be_const_closure(Matter_Device__instantiate_plugins_from_config_closure) }, + { be_const_key_weak(every_50ms, 22), be_const_closure(Matter_Device_every_50ms_closure) }, + { be_const_key_weak(commissioning_L, -1), be_const_var(17) }, + { be_const_key_weak(PASE_TIMEOUT, -1), be_const_int(600) }, + { be_const_key_weak(mdns_announce_op_discovery_all_fabrics, -1), be_const_closure(Matter_Device_mdns_announce_op_discovery_all_fabrics_closure) }, + { be_const_key_weak(event_fabrics_saved, -1), be_const_closure(Matter_Device_event_fabrics_saved_closure) }, + { be_const_key_weak(every_250ms, -1), be_const_closure(Matter_Device_every_250ms_closure) }, + { be_const_key_weak(autoconf_device, -1), be_const_closure(Matter_Device_autoconf_device_closure) }, + { be_const_key_weak(root_passcode, -1), be_const_var(29) }, + { be_const_key_weak(save_param, -1), be_const_closure(Matter_Device_save_param_closure) }, + { be_const_key_weak(mdns_announce_PASE, -1), be_const_closure(Matter_Device_mdns_announce_PASE_closure) }, + { be_const_key_weak(plugins_config_remotes, -1), be_const_var(5) }, + { be_const_key_weak(root_w0, -1), be_const_var(35) }, })), be_str_weak(Matter_Device) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Expirable.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Expirable.h index 59867c30773a..4888f31a9cb1 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Expirable.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Expirable.h @@ -129,11 +129,10 @@ be_local_closure(Matter_Expirable_has_expired, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ + ( &(const bvalue[ 3]) { /* constants */ /* K0 */ be_nested_str_weak(tasmota), - /* K1 */ be_nested_str_weak(rtc), - /* K2 */ be_nested_str_weak(utc), - /* K3 */ be_nested_str_weak(_expiration), + /* K1 */ be_nested_str_weak(rtc_utc), + /* K2 */ be_nested_str_weak(_expiration), }), be_str_weak(has_expired), &be_const_str_solidified, @@ -144,12 +143,12 @@ be_local_closure(Matter_Expirable_has_expired, /* name */ 0xB80A0000, // 0003 GETNGBL R2 K0 0x8C080501, // 0004 GETMET R2 R2 K1 0x7C080200, // 0005 CALL R2 1 - 0x94040502, // 0006 GETIDX R1 R2 K2 - 0x88080103, // 0007 GETMBR R2 R0 K3 + 0x5C040400, // 0006 MOVE R1 R2 + 0x88080102, // 0007 GETMBR R2 R0 K2 0x4C0C0000, // 0008 LDNIL R3 0x20080403, // 0009 NE R2 R2 R3 0x780A0002, // 000A JMPF R2 #000E - 0x88080103, // 000B GETMBR R2 R0 K3 + 0x88080102, // 000B GETMBR R2 R0 K2 0x28080202, // 000C GE R2 R1 R2 0x80040400, // 000D RET 1 R2 0x50080000, // 000E LDBOOL R2 0 0 @@ -224,11 +223,10 @@ be_local_closure(Matter_Expirable_set_expire_in_seconds, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ + ( &(const bvalue[ 3]) { /* constants */ /* K0 */ be_nested_str_weak(tasmota), - /* K1 */ be_nested_str_weak(rtc), - /* K2 */ be_nested_str_weak(utc), - /* K3 */ be_nested_str_weak(set_expire_time), + /* K1 */ be_nested_str_weak(rtc_utc), + /* K2 */ be_nested_str_weak(set_expire_time), }), be_str_weak(set_expire_in_seconds), &be_const_str_solidified, @@ -243,8 +241,8 @@ be_local_closure(Matter_Expirable_set_expire_in_seconds, /* name */ 0xB80E0000, // 0007 GETNGBL R3 K0 0x8C0C0701, // 0008 GETMET R3 R3 K1 0x7C0C0200, // 0009 CALL R3 1 - 0x94080702, // 000A GETIDX R2 R3 K2 - 0x8C0C0103, // 000B GETMET R3 R0 K3 + 0x5C080600, // 000A MOVE R2 R3 + 0x8C0C0102, // 000B GETMET R3 R0 K2 0x00140401, // 000C ADD R5 R2 R1 0x7C0C0400, // 000D CALL R3 2 0x80000000, // 000E RET 0 diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Fabric.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Fabric.h index 94d1f1d160ed..046f20836de9 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Fabric.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Fabric.h @@ -7,184 +7,11 @@ extern const bclass be_class_Matter_Fabric; /******************************************************************** -** Solidified function: tojson -********************************************************************/ -be_local_closure(Matter_Fabric_tojson, /* name */ - be_nested_proto( - 18, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[29]) { /* constants */ - /* K0 */ be_nested_str_weak(json), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(introspect), - /* K3 */ be_nested_str_weak(persist_pre), - /* K4 */ be_nested_str_weak(members), - /* K5 */ be_nested_str_weak(get), - /* K6 */ be_nested_str_weak(function), - /* K7 */ be_const_int(0), - /* K8 */ be_nested_str_weak(_), - /* K9 */ be_nested_str_weak(push), - /* K10 */ be_nested_str_weak(stop_iteration), - /* K11 */ be_nested_str_weak(matter), - /* K12 */ be_nested_str_weak(sort), - /* K13 */ be_nested_str_weak(_X24_X24), - /* K14 */ be_nested_str_weak(tob64), - /* K15 */ be_nested_str_weak(format), - /* K16 */ be_nested_str_weak(_X25s_X3A_X25s), - /* K17 */ be_nested_str_weak(dump), - /* K18 */ be_nested_str_weak(_sessions), - /* K19 */ be_nested_str_weak(persistables), - /* K20 */ be_nested_str_weak(tojson), - /* K21 */ be_nested_str_weak(_X5B), - /* K22 */ be_nested_str_weak(concat), - /* K23 */ be_nested_str_weak(_X2C), - /* K24 */ be_nested_str_weak(_X5D), - /* K25 */ be_nested_str_weak(_X22_sessions_X22_X3A), - /* K26 */ be_nested_str_weak(persist_post), - /* K27 */ be_nested_str_weak(_X7B), - /* K28 */ be_nested_str_weak(_X7D), - }), - be_str_weak(tojson), - &be_const_str_solidified, - ( &(const binstruction[120]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0xA40E0400, // 0002 IMPORT R3 K2 - 0x8C100103, // 0003 GETMET R4 R0 K3 - 0x7C100200, // 0004 CALL R4 1 - 0x60100012, // 0005 GETGBL R4 G18 - 0x7C100000, // 0006 CALL R4 0 - 0x60140010, // 0007 GETGBL R5 G16 - 0x8C180704, // 0008 GETMET R6 R3 K4 - 0x5C200000, // 0009 MOVE R8 R0 - 0x7C180400, // 000A CALL R6 2 - 0x7C140200, // 000B CALL R5 1 - 0xA8020011, // 000C EXBLK 0 #001F - 0x5C180A00, // 000D MOVE R6 R5 - 0x7C180000, // 000E CALL R6 0 - 0x8C1C0705, // 000F GETMET R7 R3 K5 - 0x5C240000, // 0010 MOVE R9 R0 - 0x5C280C00, // 0011 MOVE R10 R6 - 0x7C1C0600, // 0012 CALL R7 3 - 0x60200004, // 0013 GETGBL R8 G4 - 0x5C240E00, // 0014 MOVE R9 R7 - 0x7C200200, // 0015 CALL R8 1 - 0x20201106, // 0016 NE R8 R8 K6 - 0x78220005, // 0017 JMPF R8 #001E - 0x94200D07, // 0018 GETIDX R8 R6 K7 - 0x20201108, // 0019 NE R8 R8 K8 - 0x78220002, // 001A JMPF R8 #001E - 0x8C200909, // 001B GETMET R8 R4 K9 - 0x5C280C00, // 001C MOVE R10 R6 - 0x7C200400, // 001D CALL R8 2 - 0x7001FFED, // 001E JMP #000D - 0x5814000A, // 001F LDCONST R5 K10 - 0xAC140200, // 0020 CATCH R5 1 0 - 0xB0080000, // 0021 RAISE 2 R0 R0 - 0xB8161600, // 0022 GETNGBL R5 K11 - 0x8C140B0C, // 0023 GETMET R5 R5 K12 - 0x5C1C0800, // 0024 MOVE R7 R4 - 0x7C140400, // 0025 CALL R5 2 - 0x5C100A00, // 0026 MOVE R4 R5 - 0x60140012, // 0027 GETGBL R5 G18 - 0x7C140000, // 0028 CALL R5 0 - 0x60180010, // 0029 GETGBL R6 G16 - 0x5C1C0800, // 002A MOVE R7 R4 - 0x7C180200, // 002B CALL R6 1 - 0xA8020020, // 002C EXBLK 0 #004E - 0x5C1C0C00, // 002D MOVE R7 R6 - 0x7C1C0000, // 002E CALL R7 0 - 0x8C200705, // 002F GETMET R8 R3 K5 - 0x5C280000, // 0030 MOVE R10 R0 - 0x5C2C0E00, // 0031 MOVE R11 R7 - 0x7C200600, // 0032 CALL R8 3 - 0x4C240000, // 0033 LDNIL R9 - 0x1C241009, // 0034 EQ R9 R8 R9 - 0x78260000, // 0035 JMPF R9 #0037 - 0x7001FFF5, // 0036 JMP #002D - 0x6024000F, // 0037 GETGBL R9 G15 - 0x5C281000, // 0038 MOVE R10 R8 - 0x602C0015, // 0039 GETGBL R11 G21 - 0x7C240400, // 003A CALL R9 2 - 0x78260003, // 003B JMPF R9 #0040 - 0x8C24110E, // 003C GETMET R9 R8 K14 - 0x7C240200, // 003D CALL R9 1 - 0x00261A09, // 003E ADD R9 K13 R9 - 0x5C201200, // 003F MOVE R8 R9 - 0x8C240B09, // 0040 GETMET R9 R5 K9 - 0x8C2C050F, // 0041 GETMET R11 R2 K15 - 0x58340010, // 0042 LDCONST R13 K16 - 0x8C380311, // 0043 GETMET R14 R1 K17 - 0x60400008, // 0044 GETGBL R16 G8 - 0x5C440E00, // 0045 MOVE R17 R7 - 0x7C400200, // 0046 CALL R16 1 - 0x7C380400, // 0047 CALL R14 2 - 0x8C3C0311, // 0048 GETMET R15 R1 K17 - 0x5C441000, // 0049 MOVE R17 R8 - 0x7C3C0400, // 004A CALL R15 2 - 0x7C2C0800, // 004B CALL R11 4 - 0x7C240400, // 004C CALL R9 2 - 0x7001FFDE, // 004D JMP #002D - 0x5818000A, // 004E LDCONST R6 K10 - 0xAC180200, // 004F CATCH R6 1 0 - 0xB0080000, // 0050 RAISE 2 R0 R0 - 0x60180012, // 0051 GETGBL R6 G18 - 0x7C180000, // 0052 CALL R6 0 - 0x601C0010, // 0053 GETGBL R7 G16 - 0x88200112, // 0054 GETMBR R8 R0 K18 - 0x8C201113, // 0055 GETMET R8 R8 K19 - 0x7C200200, // 0056 CALL R8 1 - 0x7C1C0200, // 0057 CALL R7 1 - 0xA8020006, // 0058 EXBLK 0 #0060 - 0x5C200E00, // 0059 MOVE R8 R7 - 0x7C200000, // 005A CALL R8 0 - 0x8C240D09, // 005B GETMET R9 R6 K9 - 0x8C2C1114, // 005C GETMET R11 R8 K20 - 0x7C2C0200, // 005D CALL R11 1 - 0x7C240400, // 005E CALL R9 2 - 0x7001FFF8, // 005F JMP #0059 - 0x581C000A, // 0060 LDCONST R7 K10 - 0xAC1C0200, // 0061 CATCH R7 1 0 - 0xB0080000, // 0062 RAISE 2 R0 R0 - 0x601C000C, // 0063 GETGBL R7 G12 - 0x5C200C00, // 0064 MOVE R8 R6 - 0x7C1C0200, // 0065 CALL R7 1 - 0x241C0F07, // 0066 GT R7 R7 K7 - 0x781E0007, // 0067 JMPF R7 #0070 - 0x8C1C0D16, // 0068 GETMET R7 R6 K22 - 0x58240017, // 0069 LDCONST R9 K23 - 0x7C1C0400, // 006A CALL R7 2 - 0x001E2A07, // 006B ADD R7 K21 R7 - 0x001C0F18, // 006C ADD R7 R7 K24 - 0x8C200B09, // 006D GETMET R8 R5 K9 - 0x002A3207, // 006E ADD R10 K25 R7 - 0x7C200400, // 006F CALL R8 2 - 0x8C1C011A, // 0070 GETMET R7 R0 K26 - 0x7C1C0200, // 0071 CALL R7 1 - 0x8C1C0B16, // 0072 GETMET R7 R5 K22 - 0x58240017, // 0073 LDCONST R9 K23 - 0x7C1C0400, // 0074 CALL R7 2 - 0x001E3607, // 0075 ADD R7 K27 R7 - 0x001C0F1C, // 0076 ADD R7 R7 K28 - 0x80040E00, // 0077 RET 1 R7 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_fabric_index +** Solidified function: counter_group_data_snd_next ********************************************************************/ -be_local_closure(Matter_Fabric_get_fabric_index, /* name */ +be_local_closure(Matter_Fabric_counter_group_data_snd_next, /* name */ be_nested_proto( - 2, /* nstack */ + 7, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -192,14 +19,51 @@ be_local_closure(Matter_Fabric_get_fabric_index, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(fabric_index), + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(_counter_group_data_snd_impl), + /* K1 */ be_nested_str_weak(next), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(log), + /* K4 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Counter_group_data_snd_X3D_X25i), + /* K5 */ be_const_int(3), + /* K6 */ be_nested_str_weak(matter), + /* K7 */ be_nested_str_weak(Counter), + /* K8 */ be_nested_str_weak(is_greater), + /* K9 */ be_nested_str_weak(counter_group_data_snd), + /* K10 */ be_nested_str_weak(_GROUP_SND_INCR), + /* K11 */ be_nested_str_weak(does_persist), + /* K12 */ be_nested_str_weak(save), }), - be_str_weak(get_fabric_index), + be_str_weak(counter_group_data_snd_next), &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ + ( &(const binstruction[27]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0xB80A0400, // 0003 GETNGBL R2 K2 + 0x8C080503, // 0004 GETMET R2 R2 K3 + 0x60100018, // 0005 GETGBL R4 G24 + 0x58140004, // 0006 LDCONST R5 K4 + 0x5C180200, // 0007 MOVE R6 R1 + 0x7C100400, // 0008 CALL R4 2 + 0x58140005, // 0009 LDCONST R5 K5 + 0x7C080600, // 000A CALL R2 3 + 0xB80A0C00, // 000B GETNGBL R2 K6 + 0x88080507, // 000C GETMBR R2 R2 K7 + 0x8C080508, // 000D GETMET R2 R2 K8 + 0x5C100200, // 000E MOVE R4 R1 + 0x88140109, // 000F GETMBR R5 R0 K9 + 0x7C080600, // 0010 CALL R2 3 + 0x780A0007, // 0011 JMPF R2 #001A + 0x8808010A, // 0012 GETMBR R2 R0 K10 + 0x00080202, // 0013 ADD R2 R1 R2 + 0x90021202, // 0014 SETMBR R0 K9 R2 + 0x8C08010B, // 0015 GETMET R2 R0 K11 + 0x7C080200, // 0016 CALL R2 1 + 0x780A0001, // 0017 JMPF R2 #001A + 0x8C08010C, // 0018 GETMET R2 R0 K12 + 0x7C080200, // 0019 CALL R2 1 + 0x80040200, // 001A RET 1 R1 }) ) ); @@ -207,11 +71,11 @@ be_local_closure(Matter_Fabric_get_fabric_index, /* name */ /******************************************************************** -** Solidified function: get_admin_subject +** Solidified function: get_ca_pub ********************************************************************/ -be_local_closure(Matter_Fabric_get_admin_subject, /* name */ +be_local_closure(Matter_Fabric_get_ca_pub, /* name */ be_nested_proto( - 2, /* nstack */ + 6, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -219,72 +83,28 @@ be_local_closure(Matter_Fabric_get_admin_subject, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(admin_subject), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(root_ca_certificate), + /* K1 */ be_nested_str_weak(matter), + /* K2 */ be_nested_str_weak(TLV), + /* K3 */ be_nested_str_weak(parse), + /* K4 */ be_nested_str_weak(findsubval), }), - be_str_weak(get_admin_subject), + be_str_weak(get_ca_pub), &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ + ( &(const binstruction[12]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_old_recent_session -********************************************************************/ -be_local_closure(Matter_Fabric_get_old_recent_session, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(_sessions), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str_weak(last_used), - /* K3 */ be_const_int(1), - }), - be_str_weak(get_old_recent_session), - &be_const_str_solidified, - ( &(const binstruction[30]) { /* code */ - 0x6008000C, // 0000 GETGBL R2 G12 - 0x880C0100, // 0001 GETMBR R3 R0 K0 - 0x7C080200, // 0002 CALL R2 1 - 0x1C080501, // 0003 EQ R2 R2 K1 - 0x780A0001, // 0004 JMPF R2 #0007 - 0x4C080000, // 0005 LDNIL R2 - 0x80040400, // 0006 RET 1 R2 - 0x88080100, // 0007 GETMBR R2 R0 K0 - 0x94080501, // 0008 GETIDX R2 R2 K1 - 0x880C0502, // 0009 GETMBR R3 R2 K2 - 0x58100003, // 000A LDCONST R4 K3 - 0x6014000C, // 000B GETGBL R5 G12 - 0x88180100, // 000C GETMBR R6 R0 K0 - 0x7C140200, // 000D CALL R5 1 - 0x14140805, // 000E LT R5 R4 R5 - 0x7816000C, // 000F JMPF R5 #001D - 0x88140100, // 0010 GETMBR R5 R0 K0 - 0x94140A04, // 0011 GETIDX R5 R5 R4 - 0x88140B02, // 0012 GETMBR R5 R5 K2 - 0x78060001, // 0013 JMPF R1 #0016 - 0x14180A03, // 0014 LT R6 R5 R3 - 0x70020000, // 0015 JMP #0017 - 0x24180A03, // 0016 GT R6 R5 R3 - 0x781A0002, // 0017 JMPF R6 #001B - 0x88180100, // 0018 GETMBR R6 R0 K0 - 0x94080C04, // 0019 GETIDX R2 R6 R4 - 0x5C0C0A00, // 001A MOVE R3 R5 - 0x00100903, // 001B ADD R4 R4 K3 - 0x7001FFED, // 001C JMP #000B - 0x80040400, // 001D RET 1 R2 + 0x78060008, // 0001 JMPF R1 #000B + 0xB80A0200, // 0002 GETNGBL R2 K1 + 0x88080502, // 0003 GETMBR R2 R2 K2 + 0x8C080503, // 0004 GETMET R2 R2 K3 + 0x5C100200, // 0005 MOVE R4 R1 + 0x7C080400, // 0006 CALL R2 2 + 0x8C0C0504, // 0007 GETMET R3 R2 K4 + 0x54160008, // 0008 LDINT R5 9 + 0x7C0C0400, // 0009 CALL R3 2 + 0x80040600, // 000A RET 1 R3 + 0x80000000, // 000B RET 0 }) ) ); @@ -318,127 +138,6 @@ be_local_closure(Matter_Fabric_get_device_id, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: counter_group_ctrl_snd_next -********************************************************************/ -be_local_closure(Matter_Fabric_counter_group_ctrl_snd_next, /* name */ - be_nested_proto( - 9, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(_counter_group_ctrl_snd_impl), - /* K2 */ be_nested_str_weak(next), - /* K3 */ be_nested_str_weak(tasmota), - /* K4 */ be_nested_str_weak(log), - /* K5 */ be_nested_str_weak(format), - /* K6 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Counter_group_ctrl_snd_X3D_X25i), - /* K7 */ be_const_int(3), - /* K8 */ be_nested_str_weak(matter), - /* K9 */ be_nested_str_weak(Counter), - /* K10 */ be_nested_str_weak(is_greater), - /* K11 */ be_nested_str_weak(counter_group_ctrl_snd), - /* K12 */ be_nested_str_weak(_GROUP_SND_INCR), - /* K13 */ be_nested_str_weak(does_persist), - /* K14 */ be_nested_str_weak(save), - }), - be_str_weak(counter_group_ctrl_snd_next), - &be_const_str_solidified, - ( &(const binstruction[28]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x88080101, // 0001 GETMBR R2 R0 K1 - 0x8C080502, // 0002 GETMET R2 R2 K2 - 0x7C080200, // 0003 CALL R2 1 - 0xB80E0600, // 0004 GETNGBL R3 K3 - 0x8C0C0704, // 0005 GETMET R3 R3 K4 - 0x8C140305, // 0006 GETMET R5 R1 K5 - 0x581C0006, // 0007 LDCONST R7 K6 - 0x5C200400, // 0008 MOVE R8 R2 - 0x7C140600, // 0009 CALL R5 3 - 0x58180007, // 000A LDCONST R6 K7 - 0x7C0C0600, // 000B CALL R3 3 - 0xB80E1000, // 000C GETNGBL R3 K8 - 0x880C0709, // 000D GETMBR R3 R3 K9 - 0x8C0C070A, // 000E GETMET R3 R3 K10 - 0x5C140400, // 000F MOVE R5 R2 - 0x8818010B, // 0010 GETMBR R6 R0 K11 - 0x7C0C0600, // 0011 CALL R3 3 - 0x780E0007, // 0012 JMPF R3 #001B - 0x880C010C, // 0013 GETMBR R3 R0 K12 - 0x000C0403, // 0014 ADD R3 R2 R3 - 0x90021603, // 0015 SETMBR R0 K11 R3 - 0x8C0C010D, // 0016 GETMET R3 R0 K13 - 0x7C0C0200, // 0017 CALL R3 1 - 0x780E0001, // 0018 JMPF R3 #001B - 0x8C0C010E, // 0019 GETMET R3 R0 K14 - 0x7C0C0200, // 001A CALL R3 1 - 0x80040400, // 001B RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_fabric_index -********************************************************************/ -be_local_closure(Matter_Fabric_set_fabric_index, /* name */ - be_nested_proto( - 2, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(fabric_index), - }), - be_str_weak(set_fabric_index), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x90020001, // 0000 SETMBR R0 K0 R1 - 0x80000000, // 0001 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_fabric_compressed -********************************************************************/ -be_local_closure(Matter_Fabric_get_fabric_compressed, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(fabric_compressed), - }), - be_str_weak(get_fabric_compressed), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: add_session ********************************************************************/ @@ -452,95 +151,51 @@ be_local_closure(Matter_Fabric_add_session, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ + ( &(const bvalue[ 8]) { /* constants */ /* K0 */ be_nested_str_weak(_sessions), /* K1 */ be_nested_str_weak(find), /* K2 */ be_nested_str_weak(_MAX_CASE), - /* K3 */ be_nested_str_weak(remove), - /* K4 */ be_nested_str_weak(get_oldest_session), - /* K5 */ be_nested_str_weak(push), + /* K3 */ be_nested_str_weak(get_oldest_session), + /* K4 */ be_nested_str_weak(remove), + /* K5 */ be_nested_str_weak(_store), + /* K6 */ be_nested_str_weak(remove_session), + /* K7 */ be_nested_str_weak(push), }), be_str_weak(add_session), &be_const_str_solidified, - ( &(const binstruction[27]) { /* code */ + ( &(const binstruction[32]) { /* code */ 0x88080100, // 0000 GETMBR R2 R0 K0 0x8C080501, // 0001 GETMET R2 R2 K1 0x5C100200, // 0002 MOVE R4 R1 0x7C080400, // 0003 CALL R2 2 0x4C0C0000, // 0004 LDNIL R3 0x1C080403, // 0005 EQ R2 R2 R3 - 0x780A0012, // 0006 JMPF R2 #001A + 0x780A0017, // 0006 JMPF R2 #001F 0x6008000C, // 0007 GETGBL R2 G12 0x880C0100, // 0008 GETMBR R3 R0 K0 0x7C080200, // 0009 CALL R2 1 0x880C0102, // 000A GETMBR R3 R0 K2 0x28080403, // 000B GE R2 R2 R3 - 0x780A0008, // 000C JMPF R2 #0016 - 0x88080100, // 000D GETMBR R2 R0 K0 - 0x8C080503, // 000E GETMET R2 R2 K3 - 0x88100100, // 000F GETMBR R4 R0 K0 - 0x8C100901, // 0010 GETMET R4 R4 K1 - 0x8C180104, // 0011 GETMET R6 R0 K4 - 0x7C180200, // 0012 CALL R6 1 - 0x7C100400, // 0013 CALL R4 2 - 0x7C080400, // 0014 CALL R2 2 - 0x7001FFF0, // 0015 JMP #0007 - 0x88080100, // 0016 GETMBR R2 R0 K0 - 0x8C080505, // 0017 GETMET R2 R2 K5 - 0x5C100200, // 0018 MOVE R4 R1 - 0x7C080400, // 0019 CALL R2 2 - 0x80000000, // 001A RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: log_new_fabric -********************************************************************/ -be_local_closure(Matter_Fabric_log_new_fabric, /* name */ - be_nested_proto( - 9, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(log), - /* K3 */ be_nested_str_weak(format), - /* K4 */ be_nested_str_weak(MTR_X3A_X20_X2BFabric_X20_X20_X20_X20fab_X3D_X27_X25s_X27), - /* K5 */ be_nested_str_weak(get_fabric_id), - /* K6 */ be_nested_str_weak(copy), - /* K7 */ be_nested_str_weak(reverse), - /* K8 */ be_nested_str_weak(tohex), - /* K9 */ be_const_int(2), - }), - be_str_weak(log_new_fabric), - &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xB80A0200, // 0001 GETNGBL R2 K1 - 0x8C080502, // 0002 GETMET R2 R2 K2 - 0x8C100303, // 0003 GETMET R4 R1 K3 - 0x58180004, // 0004 LDCONST R6 K4 - 0x8C1C0105, // 0005 GETMET R7 R0 K5 - 0x7C1C0200, // 0006 CALL R7 1 - 0x8C1C0F06, // 0007 GETMET R7 R7 K6 - 0x7C1C0200, // 0008 CALL R7 1 - 0x8C1C0F07, // 0009 GETMET R7 R7 K7 - 0x7C1C0200, // 000A CALL R7 1 - 0x8C1C0F08, // 000B GETMET R7 R7 K8 - 0x7C1C0200, // 000C CALL R7 1 - 0x7C100600, // 000D CALL R4 3 - 0x58140009, // 000E LDCONST R5 K9 - 0x7C080600, // 000F CALL R2 3 - 0x80000000, // 0010 RET 0 + 0x780A000D, // 000C JMPF R2 #001B + 0x8C080103, // 000D GETMET R2 R0 K3 + 0x7C080200, // 000E CALL R2 1 + 0x880C0100, // 000F GETMBR R3 R0 K0 + 0x8C0C0704, // 0010 GETMET R3 R3 K4 + 0x88140100, // 0011 GETMBR R5 R0 K0 + 0x8C140B01, // 0012 GETMET R5 R5 K1 + 0x5C1C0400, // 0013 MOVE R7 R2 + 0x7C140400, // 0014 CALL R5 2 + 0x7C0C0400, // 0015 CALL R3 2 + 0x880C0105, // 0016 GETMBR R3 R0 K5 + 0x8C0C0706, // 0017 GETMET R3 R3 K6 + 0x5C140400, // 0018 MOVE R5 R2 + 0x7C0C0400, // 0019 CALL R3 2 + 0x7001FFEB, // 001A JMP #0007 + 0x88080100, // 001B GETMBR R2 R0 K0 + 0x8C080507, // 001C GETMET R2 R2 K7 + 0x5C100200, // 001D MOVE R4 R1 + 0x7C080400, // 001E CALL R2 2 + 0x80000000, // 001F RET 0 }) ) ); @@ -548,11 +203,11 @@ be_local_closure(Matter_Fabric_log_new_fabric, /* name */ /******************************************************************** -** Solidified function: before_remove +** Solidified function: get_oldest_session ********************************************************************/ -be_local_closure(Matter_Fabric_before_remove, /* name */ +be_local_closure(Matter_Fabric_get_oldest_session, /* name */ be_nested_proto( - 9, /* nstack */ + 4, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -560,38 +215,16 @@ be_local_closure(Matter_Fabric_before_remove, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(log), - /* K3 */ be_nested_str_weak(format), - /* K4 */ be_nested_str_weak(MTR_X3A_X20_X2DFabric_X20_X20_X20_X20fab_X3D_X27_X25s_X27_X20_X28removed_X29), - /* K5 */ be_nested_str_weak(get_fabric_id), - /* K6 */ be_nested_str_weak(copy), - /* K7 */ be_nested_str_weak(reverse), - /* K8 */ be_nested_str_weak(tohex), - /* K9 */ be_const_int(2), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(get_old_recent_session), }), - be_str_weak(before_remove), + be_str_weak(get_oldest_session), &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xB80A0200, // 0001 GETNGBL R2 K1 - 0x8C080502, // 0002 GETMET R2 R2 K2 - 0x8C100303, // 0003 GETMET R4 R1 K3 - 0x58180004, // 0004 LDCONST R6 K4 - 0x8C1C0105, // 0005 GETMET R7 R0 K5 - 0x7C1C0200, // 0006 CALL R7 1 - 0x8C1C0F06, // 0007 GETMET R7 R7 K6 - 0x7C1C0200, // 0008 CALL R7 1 - 0x8C1C0F07, // 0009 GETMET R7 R7 K7 - 0x7C1C0200, // 000A CALL R7 1 - 0x8C1C0F08, // 000B GETMET R7 R7 K8 - 0x7C1C0200, // 000C CALL R7 1 - 0x7C100600, // 000D CALL R4 3 - 0x58140009, // 000E LDCONST R5 K9 - 0x7C080600, // 000F CALL R2 3 - 0x80000000, // 0010 RET 0 + ( &(const binstruction[ 4]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x500C0200, // 0001 LDBOOL R3 1 0 + 0x7C040400, // 0002 CALL R1 2 + 0x80040200, // 0003 RET 1 R1 }) ) ); @@ -717,11 +350,11 @@ be_local_closure(Matter_Fabric_fromjson, /* name */ /******************************************************************** -** Solidified function: init +** Solidified function: set_fabric_index ********************************************************************/ -be_local_closure(Matter_Fabric_init, /* name */ +be_local_closure(Matter_Fabric_set_fabric_index, /* name */ be_nested_proto( - 5, /* nstack */ + 2, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -729,7 +362,34 @@ be_local_closure(Matter_Fabric_init, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[18]) { /* constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(fabric_index), + }), + be_str_weak(set_fabric_index), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x80000000, // 0001 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Fabric_init, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[17]) { /* constants */ /* K0 */ be_nested_str_weak(crypto), /* K1 */ be_nested_str_weak(_store), /* K2 */ be_nested_str_weak(_sessions), @@ -739,19 +399,18 @@ be_local_closure(Matter_Fabric_init, /* name */ /* K6 */ be_nested_str_weak(), /* K7 */ be_nested_str_weak(created), /* K8 */ be_nested_str_weak(tasmota), - /* K9 */ be_nested_str_weak(rtc), - /* K10 */ be_nested_str_weak(utc), - /* K11 */ be_nested_str_weak(_counter_group_data_snd_impl), - /* K12 */ be_nested_str_weak(Counter), - /* K13 */ be_nested_str_weak(_counter_group_ctrl_snd_impl), - /* K14 */ be_nested_str_weak(counter_group_data_snd), - /* K15 */ be_nested_str_weak(next), - /* K16 */ be_nested_str_weak(_GROUP_SND_INCR), - /* K17 */ be_nested_str_weak(counter_group_ctrl_snd), + /* K9 */ be_nested_str_weak(rtc_utc), + /* K10 */ be_nested_str_weak(_counter_group_data_snd_impl), + /* K11 */ be_nested_str_weak(Counter), + /* K12 */ be_nested_str_weak(_counter_group_ctrl_snd_impl), + /* K13 */ be_nested_str_weak(counter_group_data_snd), + /* K14 */ be_nested_str_weak(next), + /* K15 */ be_nested_str_weak(_GROUP_SND_INCR), + /* K16 */ be_nested_str_weak(counter_group_ctrl_snd), }), be_str_weak(init), &be_const_str_solidified, - ( &(const binstruction[33]) { /* code */ + ( &(const binstruction[32]) { /* code */ 0xA40A0000, // 0000 IMPORT R2 K0 0x90020201, // 0001 SETMBR R0 K1 R1 0xB80E0600, // 0002 GETNGBL R3 K3 @@ -762,29 +421,662 @@ be_local_closure(Matter_Fabric_init, /* name */ 0xB80E1000, // 0007 GETNGBL R3 K8 0x8C0C0709, // 0008 GETMET R3 R3 K9 0x7C0C0200, // 0009 CALL R3 1 - 0x940C070A, // 000A GETIDX R3 R3 K10 - 0x90020E03, // 000B SETMBR R0 K7 R3 - 0xB80E0600, // 000C GETNGBL R3 K3 - 0x8C0C070C, // 000D GETMET R3 R3 K12 - 0x7C0C0200, // 000E CALL R3 1 - 0x90021603, // 000F SETMBR R0 K11 R3 - 0xB80E0600, // 0010 GETNGBL R3 K3 - 0x8C0C070C, // 0011 GETMET R3 R3 K12 - 0x7C0C0200, // 0012 CALL R3 1 - 0x90021A03, // 0013 SETMBR R0 K13 R3 - 0x880C010B, // 0014 GETMBR R3 R0 K11 - 0x8C0C070F, // 0015 GETMET R3 R3 K15 - 0x7C0C0200, // 0016 CALL R3 1 - 0x88100110, // 0017 GETMBR R4 R0 K16 - 0x000C0604, // 0018 ADD R3 R3 R4 - 0x90021C03, // 0019 SETMBR R0 K14 R3 - 0x880C010B, // 001A GETMBR R3 R0 K11 - 0x8C0C070F, // 001B GETMET R3 R3 K15 - 0x7C0C0200, // 001C CALL R3 1 - 0x88100110, // 001D GETMBR R4 R0 K16 - 0x000C0604, // 001E ADD R3 R3 R4 - 0x90022203, // 001F SETMBR R0 K17 R3 - 0x80000000, // 0020 RET 0 + 0x90020E03, // 000A SETMBR R0 K7 R3 + 0xB80E0600, // 000B GETNGBL R3 K3 + 0x8C0C070B, // 000C GETMET R3 R3 K11 + 0x7C0C0200, // 000D CALL R3 1 + 0x90021403, // 000E SETMBR R0 K10 R3 + 0xB80E0600, // 000F GETNGBL R3 K3 + 0x8C0C070B, // 0010 GETMET R3 R3 K11 + 0x7C0C0200, // 0011 CALL R3 1 + 0x90021803, // 0012 SETMBR R0 K12 R3 + 0x880C010A, // 0013 GETMBR R3 R0 K10 + 0x8C0C070E, // 0014 GETMET R3 R3 K14 + 0x7C0C0200, // 0015 CALL R3 1 + 0x8810010F, // 0016 GETMBR R4 R0 K15 + 0x000C0604, // 0017 ADD R3 R3 R4 + 0x90021A03, // 0018 SETMBR R0 K13 R3 + 0x880C010A, // 0019 GETMBR R3 R0 K10 + 0x8C0C070E, // 001A GETMET R3 R3 K14 + 0x7C0C0200, // 001B CALL R3 1 + 0x8810010F, // 001C GETMBR R4 R0 K15 + 0x000C0604, // 001D ADD R3 R3 R4 + 0x90022003, // 001E SETMBR R0 K16 R3 + 0x80000000, // 001F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: fabric_completed +********************************************************************/ +be_local_closure(Matter_Fabric_fabric_completed, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(set_no_expiration), + /* K1 */ be_nested_str_weak(set_persist), + /* K2 */ be_nested_str_weak(assign_fabric_index), + /* K3 */ be_nested_str_weak(_store), + /* K4 */ be_nested_str_weak(add_fabric), + }), + be_str_weak(fabric_completed), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x8C040101, // 0002 GETMET R1 R0 K1 + 0x500C0200, // 0003 LDBOOL R3 1 0 + 0x7C040400, // 0004 CALL R1 2 + 0x8C040102, // 0005 GETMET R1 R0 K2 + 0x7C040200, // 0006 CALL R1 1 + 0x88040103, // 0007 GETMBR R1 R0 K3 + 0x8C040304, // 0008 GETMET R1 R1 K4 + 0x5C0C0000, // 0009 MOVE R3 R0 + 0x7C040400, // 000A CALL R1 2 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: counter_group_ctrl_snd_next +********************************************************************/ +be_local_closure(Matter_Fabric_counter_group_ctrl_snd_next, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(_counter_group_ctrl_snd_impl), + /* K1 */ be_nested_str_weak(next), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(log), + /* K4 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Counter_group_ctrl_snd_X3D_X25i), + /* K5 */ be_const_int(3), + /* K6 */ be_nested_str_weak(matter), + /* K7 */ be_nested_str_weak(Counter), + /* K8 */ be_nested_str_weak(is_greater), + /* K9 */ be_nested_str_weak(counter_group_ctrl_snd), + /* K10 */ be_nested_str_weak(_GROUP_SND_INCR), + /* K11 */ be_nested_str_weak(does_persist), + /* K12 */ be_nested_str_weak(save), + }), + be_str_weak(counter_group_ctrl_snd_next), + &be_const_str_solidified, + ( &(const binstruction[27]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0xB80A0400, // 0003 GETNGBL R2 K2 + 0x8C080503, // 0004 GETMET R2 R2 K3 + 0x60100018, // 0005 GETGBL R4 G24 + 0x58140004, // 0006 LDCONST R5 K4 + 0x5C180200, // 0007 MOVE R6 R1 + 0x7C100400, // 0008 CALL R4 2 + 0x58140005, // 0009 LDCONST R5 K5 + 0x7C080600, // 000A CALL R2 3 + 0xB80A0C00, // 000B GETNGBL R2 K6 + 0x88080507, // 000C GETMBR R2 R2 K7 + 0x8C080508, // 000D GETMET R2 R2 K8 + 0x5C100200, // 000E MOVE R4 R1 + 0x88140109, // 000F GETMBR R5 R0 K9 + 0x7C080600, // 0010 CALL R2 3 + 0x780A0007, // 0011 JMPF R2 #001A + 0x8808010A, // 0012 GETMBR R2 R0 K10 + 0x00080202, // 0013 ADD R2 R1 R2 + 0x90021202, // 0014 SETMBR R0 K9 R2 + 0x8C08010B, // 0015 GETMET R2 R0 K11 + 0x7C080200, // 0016 CALL R2 1 + 0x780A0001, // 0017 JMPF R2 #001A + 0x8C08010C, // 0018 GETMET R2 R0 K12 + 0x7C080200, // 0019 CALL R2 1 + 0x80040200, // 001A RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_ipk_epoch_key +********************************************************************/ +be_local_closure(Matter_Fabric_get_ipk_epoch_key, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(ipk_epoch_key), + }), + be_str_weak(get_ipk_epoch_key), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: tojson +********************************************************************/ +be_local_closure(Matter_Fabric_tojson, /* name */ + be_nested_proto( + 16, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[27]) { /* constants */ + /* K0 */ be_nested_str_weak(json), + /* K1 */ be_nested_str_weak(introspect), + /* K2 */ be_nested_str_weak(persist_pre), + /* K3 */ be_nested_str_weak(members), + /* K4 */ be_nested_str_weak(get), + /* K5 */ be_nested_str_weak(function), + /* K6 */ be_const_int(0), + /* K7 */ be_nested_str_weak(_), + /* K8 */ be_nested_str_weak(push), + /* K9 */ be_nested_str_weak(stop_iteration), + /* K10 */ be_nested_str_weak(matter), + /* K11 */ be_nested_str_weak(sort), + /* K12 */ be_nested_str_weak(_X24_X24), + /* K13 */ be_nested_str_weak(tob64), + /* K14 */ be_nested_str_weak(_X25s_X3A_X25s), + /* K15 */ be_nested_str_weak(dump), + /* K16 */ be_nested_str_weak(_sessions), + /* K17 */ be_nested_str_weak(persistables), + /* K18 */ be_nested_str_weak(tojson), + /* K19 */ be_nested_str_weak(_X5B), + /* K20 */ be_nested_str_weak(concat), + /* K21 */ be_nested_str_weak(_X2C), + /* K22 */ be_nested_str_weak(_X5D), + /* K23 */ be_nested_str_weak(_X22_sessions_X22_X3A), + /* K24 */ be_nested_str_weak(persist_post), + /* K25 */ be_nested_str_weak(_X7B), + /* K26 */ be_nested_str_weak(_X7D), + }), + be_str_weak(tojson), + &be_const_str_solidified, + ( &(const binstruction[119]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0xA40A0200, // 0001 IMPORT R2 K1 + 0x8C0C0102, // 0002 GETMET R3 R0 K2 + 0x7C0C0200, // 0003 CALL R3 1 + 0x600C0012, // 0004 GETGBL R3 G18 + 0x7C0C0000, // 0005 CALL R3 0 + 0x60100010, // 0006 GETGBL R4 G16 + 0x8C140503, // 0007 GETMET R5 R2 K3 + 0x5C1C0000, // 0008 MOVE R7 R0 + 0x7C140400, // 0009 CALL R5 2 + 0x7C100200, // 000A CALL R4 1 + 0xA8020011, // 000B EXBLK 0 #001E + 0x5C140800, // 000C MOVE R5 R4 + 0x7C140000, // 000D CALL R5 0 + 0x8C180504, // 000E GETMET R6 R2 K4 + 0x5C200000, // 000F MOVE R8 R0 + 0x5C240A00, // 0010 MOVE R9 R5 + 0x7C180600, // 0011 CALL R6 3 + 0x601C0004, // 0012 GETGBL R7 G4 + 0x5C200C00, // 0013 MOVE R8 R6 + 0x7C1C0200, // 0014 CALL R7 1 + 0x201C0F05, // 0015 NE R7 R7 K5 + 0x781E0005, // 0016 JMPF R7 #001D + 0x941C0B06, // 0017 GETIDX R7 R5 K6 + 0x201C0F07, // 0018 NE R7 R7 K7 + 0x781E0002, // 0019 JMPF R7 #001D + 0x8C1C0708, // 001A GETMET R7 R3 K8 + 0x5C240A00, // 001B MOVE R9 R5 + 0x7C1C0400, // 001C CALL R7 2 + 0x7001FFED, // 001D JMP #000C + 0x58100009, // 001E LDCONST R4 K9 + 0xAC100200, // 001F CATCH R4 1 0 + 0xB0080000, // 0020 RAISE 2 R0 R0 + 0xB8121400, // 0021 GETNGBL R4 K10 + 0x8C10090B, // 0022 GETMET R4 R4 K11 + 0x5C180600, // 0023 MOVE R6 R3 + 0x7C100400, // 0024 CALL R4 2 + 0x5C0C0800, // 0025 MOVE R3 R4 + 0x60100012, // 0026 GETGBL R4 G18 + 0x7C100000, // 0027 CALL R4 0 + 0x60140010, // 0028 GETGBL R5 G16 + 0x5C180600, // 0029 MOVE R6 R3 + 0x7C140200, // 002A CALL R5 1 + 0xA8020020, // 002B EXBLK 0 #004D + 0x5C180A00, // 002C MOVE R6 R5 + 0x7C180000, // 002D CALL R6 0 + 0x8C1C0504, // 002E GETMET R7 R2 K4 + 0x5C240000, // 002F MOVE R9 R0 + 0x5C280C00, // 0030 MOVE R10 R6 + 0x7C1C0600, // 0031 CALL R7 3 + 0x4C200000, // 0032 LDNIL R8 + 0x1C200E08, // 0033 EQ R8 R7 R8 + 0x78220000, // 0034 JMPF R8 #0036 + 0x7001FFF5, // 0035 JMP #002C + 0x6020000F, // 0036 GETGBL R8 G15 + 0x5C240E00, // 0037 MOVE R9 R7 + 0x60280015, // 0038 GETGBL R10 G21 + 0x7C200400, // 0039 CALL R8 2 + 0x78220003, // 003A JMPF R8 #003F + 0x8C200F0D, // 003B GETMET R8 R7 K13 + 0x7C200200, // 003C CALL R8 1 + 0x00221808, // 003D ADD R8 K12 R8 + 0x5C1C1000, // 003E MOVE R7 R8 + 0x8C200908, // 003F GETMET R8 R4 K8 + 0x60280018, // 0040 GETGBL R10 G24 + 0x582C000E, // 0041 LDCONST R11 K14 + 0x8C30030F, // 0042 GETMET R12 R1 K15 + 0x60380008, // 0043 GETGBL R14 G8 + 0x5C3C0C00, // 0044 MOVE R15 R6 + 0x7C380200, // 0045 CALL R14 1 + 0x7C300400, // 0046 CALL R12 2 + 0x8C34030F, // 0047 GETMET R13 R1 K15 + 0x5C3C0E00, // 0048 MOVE R15 R7 + 0x7C340400, // 0049 CALL R13 2 + 0x7C280600, // 004A CALL R10 3 + 0x7C200400, // 004B CALL R8 2 + 0x7001FFDE, // 004C JMP #002C + 0x58140009, // 004D LDCONST R5 K9 + 0xAC140200, // 004E CATCH R5 1 0 + 0xB0080000, // 004F RAISE 2 R0 R0 + 0x60140012, // 0050 GETGBL R5 G18 + 0x7C140000, // 0051 CALL R5 0 + 0x60180010, // 0052 GETGBL R6 G16 + 0x881C0110, // 0053 GETMBR R7 R0 K16 + 0x8C1C0F11, // 0054 GETMET R7 R7 K17 + 0x7C1C0200, // 0055 CALL R7 1 + 0x7C180200, // 0056 CALL R6 1 + 0xA8020006, // 0057 EXBLK 0 #005F + 0x5C1C0C00, // 0058 MOVE R7 R6 + 0x7C1C0000, // 0059 CALL R7 0 + 0x8C200B08, // 005A GETMET R8 R5 K8 + 0x8C280F12, // 005B GETMET R10 R7 K18 + 0x7C280200, // 005C CALL R10 1 + 0x7C200400, // 005D CALL R8 2 + 0x7001FFF8, // 005E JMP #0058 + 0x58180009, // 005F LDCONST R6 K9 + 0xAC180200, // 0060 CATCH R6 1 0 + 0xB0080000, // 0061 RAISE 2 R0 R0 + 0x6018000C, // 0062 GETGBL R6 G12 + 0x5C1C0A00, // 0063 MOVE R7 R5 + 0x7C180200, // 0064 CALL R6 1 + 0x24180D06, // 0065 GT R6 R6 K6 + 0x781A0007, // 0066 JMPF R6 #006F + 0x8C180B14, // 0067 GETMET R6 R5 K20 + 0x58200015, // 0068 LDCONST R8 K21 + 0x7C180400, // 0069 CALL R6 2 + 0x001A2606, // 006A ADD R6 K19 R6 + 0x00180D16, // 006B ADD R6 R6 K22 + 0x8C1C0908, // 006C GETMET R7 R4 K8 + 0x00262E06, // 006D ADD R9 K23 R6 + 0x7C1C0400, // 006E CALL R7 2 + 0x8C180118, // 006F GETMET R6 R0 K24 + 0x7C180200, // 0070 CALL R6 1 + 0x8C180914, // 0071 GETMET R6 R4 K20 + 0x58200015, // 0072 LDCONST R8 K21 + 0x7C180400, // 0073 CALL R6 2 + 0x001A3206, // 0074 ADD R6 K25 R6 + 0x00180D1A, // 0075 ADD R6 R6 K26 + 0x80040C00, // 0076 RET 1 R6 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: assign_fabric_index +********************************************************************/ +be_local_closure(Matter_Fabric_assign_fabric_index, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(get_fabric_index), + /* K1 */ be_nested_str_weak(set_fabric_index), + /* K2 */ be_nested_str_weak(_store), + /* K3 */ be_nested_str_weak(next_fabric_idx), + }), + be_str_weak(assign_fabric_index), + &be_const_str_solidified, + ( &(const binstruction[11]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x4C080000, // 0002 LDNIL R2 + 0x1C040202, // 0003 EQ R1 R1 R2 + 0x78060004, // 0004 JMPF R1 #000A + 0x8C040101, // 0005 GETMET R1 R0 K1 + 0x880C0102, // 0006 GETMBR R3 R0 K2 + 0x8C0C0703, // 0007 GETMET R3 R3 K3 + 0x7C0C0200, // 0008 CALL R3 1 + 0x7C040400, // 0009 CALL R1 2 + 0x80000000, // 000A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_admin_subject +********************************************************************/ +be_local_closure(Matter_Fabric_get_admin_subject, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(admin_subject), + }), + be_str_weak(get_admin_subject), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_fabric_compressed +********************************************************************/ +be_local_closure(Matter_Fabric_get_fabric_compressed, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(fabric_compressed), + }), + be_str_weak(get_fabric_compressed), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: fabric_candidate +********************************************************************/ +be_local_closure(Matter_Fabric_fabric_candidate, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(set_expire_in_seconds), + /* K1 */ be_nested_str_weak(assign_fabric_index), + /* K2 */ be_nested_str_weak(_store), + /* K3 */ be_nested_str_weak(add_fabric), + }), + be_str_weak(fabric_candidate), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x540E0077, // 0001 LDINT R3 120 + 0x7C040400, // 0002 CALL R1 2 + 0x8C040101, // 0003 GETMET R1 R0 K1 + 0x7C040200, // 0004 CALL R1 1 + 0x88040102, // 0005 GETMBR R1 R0 K2 + 0x8C040303, // 0006 GETMET R1 R1 K3 + 0x5C0C0000, // 0007 MOVE R3 R0 + 0x7C040400, // 0008 CALL R1 2 + 0x80000000, // 0009 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_fabric_label +********************************************************************/ +be_local_closure(Matter_Fabric_get_fabric_label, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(fabric_label), + }), + be_str_weak(get_fabric_label), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_noc_icac +********************************************************************/ +be_local_closure(Matter_Fabric_set_noc_icac, /* name */ + be_nested_proto( + 3, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(noc), + /* K1 */ be_nested_str_weak(icac), + }), + be_str_weak(set_noc_icac), + &be_const_str_solidified, + ( &(const binstruction[ 3]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x90020202, // 0001 SETMBR R0 K1 R2 + 0x80000000, // 0002 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_newest_session +********************************************************************/ +be_local_closure(Matter_Fabric_get_newest_session, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(get_old_recent_session), + }), + be_str_weak(get_newest_session), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x500C0000, // 0001 LDBOOL R3 0 0 + 0x7C040400, // 0002 CALL R1 2 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: before_remove +********************************************************************/ +be_local_closure(Matter_Fabric_before_remove, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(log), + /* K2 */ be_nested_str_weak(MTR_X3A_X20_X2DFabric_X20_X20_X20_X20fab_X3D_X27_X25s_X27_X20_X28removed_X29), + /* K3 */ be_nested_str_weak(get_fabric_id), + /* K4 */ be_nested_str_weak(copy), + /* K5 */ be_nested_str_weak(reverse), + /* K6 */ be_nested_str_weak(tohex), + /* K7 */ be_const_int(3), + }), + be_str_weak(before_remove), + &be_const_str_solidified, + ( &(const binstruction[16]) { /* code */ + 0xB8060000, // 0000 GETNGBL R1 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x600C0018, // 0002 GETGBL R3 G24 + 0x58100002, // 0003 LDCONST R4 K2 + 0x8C140103, // 0004 GETMET R5 R0 K3 + 0x7C140200, // 0005 CALL R5 1 + 0x8C140B04, // 0006 GETMET R5 R5 K4 + 0x7C140200, // 0007 CALL R5 1 + 0x8C140B05, // 0008 GETMET R5 R5 K5 + 0x7C140200, // 0009 CALL R5 1 + 0x8C140B06, // 000A GETMET R5 R5 K6 + 0x7C140200, // 000B CALL R5 1 + 0x7C0C0400, // 000C CALL R3 2 + 0x58100007, // 000D LDCONST R4 K7 + 0x7C040600, // 000E CALL R1 3 + 0x80000000, // 000F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_fabric_device +********************************************************************/ +be_local_closure(Matter_Fabric_set_fabric_device, /* name */ + be_nested_proto( + 7, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(fabric_id), + /* K1 */ be_nested_str_weak(device_id), + /* K2 */ be_nested_str_weak(fabric_compressed), + /* K3 */ be_nested_str_weak(fabric_parent), + /* K4 */ be_nested_str_weak(get_fabric_index), + }), + be_str_weak(set_fabric_device), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x90020202, // 0001 SETMBR R0 K1 R2 + 0x90020403, // 0002 SETMBR R0 K2 R3 + 0x4C140000, // 0003 LDNIL R5 + 0x20140805, // 0004 NE R5 R4 R5 + 0x78160002, // 0005 JMPF R5 #0009 + 0x8C140904, // 0006 GETMET R5 R4 K4 + 0x7C140200, // 0007 CALL R5 1 + 0x70020000, // 0008 JMP #000A + 0x4C140000, // 0009 LDNIL R5 + 0x90020605, // 000A SETMBR R0 K3 R5 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_ipk_epoch_key +********************************************************************/ +be_local_closure(Matter_Fabric_set_ipk_epoch_key, /* name */ + be_nested_proto( + 2, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(ipk_epoch_key), + }), + be_str_weak(set_ipk_epoch_key), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x80000000, // 0001 RET 0 }) ) ); @@ -834,13 +1126,109 @@ be_local_closure(Matter_Fabric_get_ipk_group_key, /* name */ 0x8C0C0704, // 000F GETMET R3 R3 K4 0x88140105, // 0010 GETMBR R5 R0 K5 0x7C0C0400, // 0011 CALL R3 2 - 0x8C100506, // 0012 GETMET R4 R2 K6 - 0x88180100, // 0013 GETMBR R6 R0 K0 - 0x881C0101, // 0014 GETMBR R7 R0 K1 - 0x5C200600, // 0015 MOVE R8 R3 - 0x5426000F, // 0016 LDINT R9 16 - 0x7C100A00, // 0017 CALL R4 5 - 0x80040800, // 0018 RET 1 R4 + 0x8C100506, // 0012 GETMET R4 R2 K6 + 0x88180100, // 0013 GETMBR R6 R0 K0 + 0x881C0101, // 0014 GETMBR R7 R0 K1 + 0x5C200600, // 0015 MOVE R8 R3 + 0x5426000F, // 0016 LDINT R9 16 + 0x7C100A00, // 0017 CALL R4 5 + 0x80040800, // 0018 RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: hydrate_post +********************************************************************/ +be_local_closure(Matter_Fabric_hydrate_post, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(_counter_group_data_snd_impl), + /* K1 */ be_nested_str_weak(reset), + /* K2 */ be_nested_str_weak(counter_group_data_snd), + /* K3 */ be_nested_str_weak(_counter_group_ctrl_snd_impl), + /* K4 */ be_nested_str_weak(counter_group_ctrl_snd), + /* K5 */ be_nested_str_weak(val), + }), + be_str_weak(hydrate_post), + &be_const_str_solidified, + ( &(const binstruction[17]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x880C0102, // 0002 GETMBR R3 R0 K2 + 0x7C040400, // 0003 CALL R1 2 + 0x88040103, // 0004 GETMBR R1 R0 K3 + 0x8C040301, // 0005 GETMET R1 R1 K1 + 0x880C0104, // 0006 GETMBR R3 R0 K4 + 0x7C040400, // 0007 CALL R1 2 + 0x88040100, // 0008 GETMBR R1 R0 K0 + 0x8C040305, // 0009 GETMET R1 R1 K5 + 0x7C040200, // 000A CALL R1 1 + 0x90020401, // 000B SETMBR R0 K2 R1 + 0x88040103, // 000C GETMBR R1 R0 K3 + 0x8C040305, // 000D GETMET R1 R1 K5 + 0x7C040200, // 000E CALL R1 1 + 0x90020801, // 000F SETMBR R0 K4 R1 + 0x80000000, // 0010 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_admin_vendor_name +********************************************************************/ +be_local_closure(Matter_Fabric_get_admin_vendor_name, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(admin_vendor), + /* K1 */ be_nested_str_weak(), + /* K2 */ be_nested_str_weak(matter), + /* K3 */ be_nested_str_weak(get_vendor_name), + /* K4 */ be_nested_str_weak(0x_X2504X), + }), + be_str_weak(get_admin_vendor_name), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x1C080202, // 0002 EQ R2 R1 R2 + 0x780A0000, // 0003 JMPF R2 #0005 + 0x80060200, // 0004 RET 1 K1 + 0xB80A0400, // 0005 GETNGBL R2 K2 + 0x8C080503, // 0006 GETMET R2 R2 K3 + 0x5C100200, // 0007 MOVE R4 R1 + 0x7C080400, // 0008 CALL R2 2 + 0x4C0C0000, // 0009 LDNIL R3 + 0x200C0403, // 000A NE R3 R2 R3 + 0x780E0001, // 000B JMPF R3 #000E + 0x80040400, // 000C RET 1 R2 + 0x70020004, // 000D JMP #0013 + 0x600C0018, // 000E GETGBL R3 G24 + 0x58100004, // 000F LDCONST R4 K4 + 0x5C140200, // 0010 MOVE R5 R1 + 0x7C0C0400, // 0011 CALL R3 2 + 0x80040600, // 0012 RET 1 R3 + 0x80000000, // 0013 RET 0 }) ) ); @@ -848,12 +1236,12 @@ be_local_closure(Matter_Fabric_get_ipk_group_key, /* name */ /******************************************************************** -** Solidified function: get_ipk_epoch_key +** Solidified function: set_pk ********************************************************************/ -be_local_closure(Matter_Fabric_get_ipk_epoch_key, /* name */ +be_local_closure(Matter_Fabric_set_pk, /* name */ be_nested_proto( 2, /* nstack */ - 1, /* argc */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -861,13 +1249,13 @@ be_local_closure(Matter_Fabric_get_ipk_epoch_key, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(ipk_epoch_key), + /* K0 */ be_nested_str_weak(no_private_key), }), - be_str_weak(get_ipk_epoch_key), + be_str_weak(set_pk), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x80000000, // 0001 RET 0 }) ) ); @@ -875,11 +1263,11 @@ be_local_closure(Matter_Fabric_get_ipk_epoch_key, /* name */ /******************************************************************** -** Solidified function: get_oldest_session +** Solidified function: get_icac ********************************************************************/ -be_local_closure(Matter_Fabric_get_oldest_session, /* name */ +be_local_closure(Matter_Fabric_get_icac, /* name */ be_nested_proto( - 4, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -888,15 +1276,13 @@ be_local_closure(Matter_Fabric_get_oldest_session, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(get_old_recent_session), + /* K0 */ be_nested_str_weak(icac), }), - be_str_weak(get_oldest_session), + be_str_weak(get_icac), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x500C0200, // 0001 LDBOOL R3 1 0 - 0x7C040400, // 0002 CALL R1 2 - 0x80040200, // 0003 RET 1 R1 + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -904,26 +1290,28 @@ be_local_closure(Matter_Fabric_get_oldest_session, /* name */ /******************************************************************** -** Solidified function: get_fabric_label +** Solidified function: set_admin_subject_vendor ********************************************************************/ -be_local_closure(Matter_Fabric_get_fabric_label, /* name */ +be_local_closure(Matter_Fabric_set_admin_subject_vendor, /* name */ be_nested_proto( - 2, /* nstack */ - 1, /* argc */ + 3, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(fabric_label), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(admin_subject), + /* K1 */ be_nested_str_weak(admin_vendor), }), - be_str_weak(get_fabric_label), + be_str_weak(set_admin_subject_vendor), &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 + ( &(const binstruction[ 3]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x90020202, // 0001 SETMBR R0 K1 R2 + 0x80000000, // 0002 RET 0 }) ) ); @@ -931,11 +1319,11 @@ be_local_closure(Matter_Fabric_get_fabric_label, /* name */ /******************************************************************** -** Solidified function: get_newest_session +** Solidified function: log_new_fabric ********************************************************************/ -be_local_closure(Matter_Fabric_get_newest_session, /* name */ +be_local_closure(Matter_Fabric_log_new_fabric, /* name */ be_nested_proto( - 4, /* nstack */ + 8, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -943,16 +1331,38 @@ be_local_closure(Matter_Fabric_get_newest_session, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(get_old_recent_session), + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(log), + /* K2 */ be_nested_str_weak(MTR_X3A_X20_X2BFabric_X20_X20_X20_X20fab_X3D_X27_X25s_X27_X20vendorid_X3D_X25s), + /* K3 */ be_nested_str_weak(get_fabric_id), + /* K4 */ be_nested_str_weak(copy), + /* K5 */ be_nested_str_weak(reverse), + /* K6 */ be_nested_str_weak(tohex), + /* K7 */ be_nested_str_weak(get_admin_vendor_name), + /* K8 */ be_const_int(3), }), - be_str_weak(get_newest_session), + be_str_weak(log_new_fabric), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x500C0000, // 0001 LDBOOL R3 0 0 - 0x7C040400, // 0002 CALL R1 2 - 0x80040200, // 0003 RET 1 R1 + ( &(const binstruction[18]) { /* code */ + 0xB8060000, // 0000 GETNGBL R1 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x600C0018, // 0002 GETGBL R3 G24 + 0x58100002, // 0003 LDCONST R4 K2 + 0x8C140103, // 0004 GETMET R5 R0 K3 + 0x7C140200, // 0005 CALL R5 1 + 0x8C140B04, // 0006 GETMET R5 R5 K4 + 0x7C140200, // 0007 CALL R5 1 + 0x8C140B05, // 0008 GETMET R5 R5 K5 + 0x7C140200, // 0009 CALL R5 1 + 0x8C140B06, // 000A GETMET R5 R5 K6 + 0x7C140200, // 000B CALL R5 1 + 0x8C180107, // 000C GETMET R6 R0 K7 + 0x7C180200, // 000D CALL R6 1 + 0x7C0C0600, // 000E CALL R3 3 + 0x58100008, // 000F LDCONST R4 K8 + 0x7C040600, // 0010 CALL R1 3 + 0x80000000, // 0011 RET 0 }) ) ); @@ -960,9 +1370,9 @@ be_local_closure(Matter_Fabric_get_newest_session, /* name */ /******************************************************************** -** Solidified function: get_ca +** Solidified function: get_pk ********************************************************************/ -be_local_closure(Matter_Fabric_get_ca, /* name */ +be_local_closure(Matter_Fabric_get_pk, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -973,9 +1383,9 @@ be_local_closure(Matter_Fabric_get_ca, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(root_ca_certificate), + /* K0 */ be_nested_str_weak(no_private_key), }), - be_str_weak(get_ca), + be_str_weak(get_pk), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -987,9 +1397,9 @@ be_local_closure(Matter_Fabric_get_ca, /* name */ /******************************************************************** -** Solidified function: get_icac +** Solidified function: get_admin_vendor ********************************************************************/ -be_local_closure(Matter_Fabric_get_icac, /* name */ +be_local_closure(Matter_Fabric_get_admin_vendor, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -1000,9 +1410,9 @@ be_local_closure(Matter_Fabric_get_icac, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(icac), + /* K0 */ be_nested_str_weak(admin_vendor), }), - be_str_weak(get_icac), + be_str_weak(get_admin_vendor), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -1014,9 +1424,9 @@ be_local_closure(Matter_Fabric_get_icac, /* name */ /******************************************************************** -** Solidified function: get_noc +** Solidified function: get_fabric_id ********************************************************************/ -be_local_closure(Matter_Fabric_get_noc, /* name */ +be_local_closure(Matter_Fabric_get_fabric_id, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -1027,9 +1437,9 @@ be_local_closure(Matter_Fabric_get_noc, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(noc), + /* K0 */ be_nested_str_weak(fabric_id), }), - be_str_weak(get_noc), + be_str_weak(get_fabric_id), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -1041,12 +1451,12 @@ be_local_closure(Matter_Fabric_get_noc, /* name */ /******************************************************************** -** Solidified function: get_fabric_id +** Solidified function: set_ca ********************************************************************/ -be_local_closure(Matter_Fabric_get_fabric_id, /* name */ +be_local_closure(Matter_Fabric_set_ca, /* name */ be_nested_proto( 2, /* nstack */ - 1, /* argc */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -1054,13 +1464,13 @@ be_local_closure(Matter_Fabric_get_fabric_id, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(fabric_id), + /* K0 */ be_nested_str_weak(root_ca_certificate), }), - be_str_weak(get_fabric_id), + be_str_weak(set_ca), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x80000000, // 0001 RET 0 }) ) ); @@ -1068,9 +1478,9 @@ be_local_closure(Matter_Fabric_get_fabric_id, /* name */ /******************************************************************** -** Solidified function: get_admin_vendor +** Solidified function: get_noc ********************************************************************/ -be_local_closure(Matter_Fabric_get_admin_vendor, /* name */ +be_local_closure(Matter_Fabric_get_noc, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -1081,9 +1491,9 @@ be_local_closure(Matter_Fabric_get_admin_vendor, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(admin_vendor), + /* K0 */ be_nested_str_weak(noc), }), - be_str_weak(get_admin_vendor), + be_str_weak(get_noc), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -1095,11 +1505,11 @@ be_local_closure(Matter_Fabric_get_admin_vendor, /* name */ /******************************************************************** -** Solidified function: hydrate_post +** Solidified function: get_fabric_index ********************************************************************/ -be_local_closure(Matter_Fabric_hydrate_post, /* name */ +be_local_closure(Matter_Fabric_get_fabric_index, /* name */ be_nested_proto( - 4, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1107,34 +1517,14 @@ be_local_closure(Matter_Fabric_hydrate_post, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(_counter_group_data_snd_impl), - /* K1 */ be_nested_str_weak(reset), - /* K2 */ be_nested_str_weak(counter_group_data_snd), - /* K3 */ be_nested_str_weak(_counter_group_ctrl_snd_impl), - /* K4 */ be_nested_str_weak(counter_group_ctrl_snd), - /* K5 */ be_nested_str_weak(val), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(fabric_index), }), - be_str_weak(hydrate_post), + be_str_weak(get_fabric_index), &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ + ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x880C0102, // 0002 GETMBR R3 R0 K2 - 0x7C040400, // 0003 CALL R1 2 - 0x88040103, // 0004 GETMBR R1 R0 K3 - 0x8C040301, // 0005 GETMET R1 R1 K1 - 0x880C0104, // 0006 GETMBR R3 R0 K4 - 0x7C040400, // 0007 CALL R1 2 - 0x88040100, // 0008 GETMBR R1 R0 K0 - 0x8C040305, // 0009 GETMET R1 R1 K5 - 0x7C040200, // 000A CALL R1 1 - 0x90020401, // 000B SETMBR R0 K2 R1 - 0x88040103, // 000C GETMBR R1 R0 K3 - 0x8C040305, // 000D GETMET R1 R1 K5 - 0x7C040200, // 000E CALL R1 1 - 0x90020801, // 000F SETMBR R0 K4 R1 - 0x80000000, // 0010 RET 0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -1142,11 +1532,11 @@ be_local_closure(Matter_Fabric_hydrate_post, /* name */ /******************************************************************** -** Solidified function: counter_group_data_snd_next +** Solidified function: get_ca ********************************************************************/ -be_local_closure(Matter_Fabric_counter_group_data_snd_next, /* name */ +be_local_closure(Matter_Fabric_get_ca, /* name */ be_nested_proto( - 9, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1154,54 +1544,14 @@ be_local_closure(Matter_Fabric_counter_group_data_snd_next, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(_counter_group_data_snd_impl), - /* K2 */ be_nested_str_weak(next), - /* K3 */ be_nested_str_weak(tasmota), - /* K4 */ be_nested_str_weak(log), - /* K5 */ be_nested_str_weak(format), - /* K6 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Counter_group_data_snd_X3D_X25i), - /* K7 */ be_const_int(3), - /* K8 */ be_nested_str_weak(matter), - /* K9 */ be_nested_str_weak(Counter), - /* K10 */ be_nested_str_weak(is_greater), - /* K11 */ be_nested_str_weak(counter_group_data_snd), - /* K12 */ be_nested_str_weak(_GROUP_SND_INCR), - /* K13 */ be_nested_str_weak(does_persist), - /* K14 */ be_nested_str_weak(save), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(root_ca_certificate), }), - be_str_weak(counter_group_data_snd_next), + be_str_weak(get_ca), &be_const_str_solidified, - ( &(const binstruction[28]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x88080101, // 0001 GETMBR R2 R0 K1 - 0x8C080502, // 0002 GETMET R2 R2 K2 - 0x7C080200, // 0003 CALL R2 1 - 0xB80E0600, // 0004 GETNGBL R3 K3 - 0x8C0C0704, // 0005 GETMET R3 R3 K4 - 0x8C140305, // 0006 GETMET R5 R1 K5 - 0x581C0006, // 0007 LDCONST R7 K6 - 0x5C200400, // 0008 MOVE R8 R2 - 0x7C140600, // 0009 CALL R5 3 - 0x58180007, // 000A LDCONST R6 K7 - 0x7C0C0600, // 000B CALL R3 3 - 0xB80E1000, // 000C GETNGBL R3 K8 - 0x880C0709, // 000D GETMBR R3 R3 K9 - 0x8C0C070A, // 000E GETMET R3 R3 K10 - 0x5C140400, // 000F MOVE R5 R2 - 0x8818010B, // 0010 GETMBR R6 R0 K11 - 0x7C0C0600, // 0011 CALL R3 3 - 0x780E0007, // 0012 JMPF R3 #001B - 0x880C010C, // 0013 GETMBR R3 R0 K12 - 0x000C0403, // 0014 ADD R3 R2 R3 - 0x90021603, // 0015 SETMBR R0 K11 R3 - 0x8C0C010D, // 0016 GETMET R3 R0 K13 - 0x7C0C0200, // 0017 CALL R3 1 - 0x780E0001, // 0018 JMPF R3 #001B - 0x8C0C010E, // 0019 GETMET R3 R0 K14 - 0x7C0C0200, // 001A CALL R3 1 - 0x80040400, // 001B RET 1 R2 + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -1209,40 +1559,57 @@ be_local_closure(Matter_Fabric_counter_group_data_snd_next, /* name */ /******************************************************************** -** Solidified function: get_ca_pub +** Solidified function: get_old_recent_session ********************************************************************/ -be_local_closure(Matter_Fabric_get_ca_pub, /* name */ +be_local_closure(Matter_Fabric_get_old_recent_session, /* name */ be_nested_proto( - 6, /* nstack */ - 1, /* argc */ + 7, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(root_ca_certificate), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(parse), - /* K4 */ be_nested_str_weak(findsubval), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(_sessions), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(last_used), + /* K3 */ be_const_int(1), }), - be_str_weak(get_ca_pub), + be_str_weak(get_old_recent_session), &be_const_str_solidified, - ( &(const binstruction[12]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x78060008, // 0001 JMPF R1 #000B - 0xB80A0200, // 0002 GETNGBL R2 K1 - 0x88080502, // 0003 GETMBR R2 R2 K2 - 0x8C080503, // 0004 GETMET R2 R2 K3 - 0x5C100200, // 0005 MOVE R4 R1 - 0x7C080400, // 0006 CALL R2 2 - 0x8C0C0504, // 0007 GETMET R3 R2 K4 - 0x54160008, // 0008 LDINT R5 9 - 0x7C0C0400, // 0009 CALL R3 2 - 0x80040600, // 000A RET 1 R3 - 0x80000000, // 000B RET 0 + ( &(const binstruction[30]) { /* code */ + 0x6008000C, // 0000 GETGBL R2 G12 + 0x880C0100, // 0001 GETMBR R3 R0 K0 + 0x7C080200, // 0002 CALL R2 1 + 0x1C080501, // 0003 EQ R2 R2 K1 + 0x780A0001, // 0004 JMPF R2 #0007 + 0x4C080000, // 0005 LDNIL R2 + 0x80040400, // 0006 RET 1 R2 + 0x88080100, // 0007 GETMBR R2 R0 K0 + 0x94080501, // 0008 GETIDX R2 R2 K1 + 0x880C0502, // 0009 GETMBR R3 R2 K2 + 0x58100003, // 000A LDCONST R4 K3 + 0x6014000C, // 000B GETGBL R5 G12 + 0x88180100, // 000C GETMBR R6 R0 K0 + 0x7C140200, // 000D CALL R5 1 + 0x14140805, // 000E LT R5 R4 R5 + 0x7816000C, // 000F JMPF R5 #001D + 0x88140100, // 0010 GETMBR R5 R0 K0 + 0x94140A04, // 0011 GETIDX R5 R5 R4 + 0x88140B02, // 0012 GETMBR R5 R5 K2 + 0x78060001, // 0013 JMPF R1 #0016 + 0x14180A03, // 0014 LT R6 R5 R3 + 0x70020000, // 0015 JMP #0017 + 0x24180A03, // 0016 GT R6 R5 R3 + 0x781A0002, // 0017 JMPF R6 #001B + 0x88180100, // 0018 GETMBR R6 R0 K0 + 0x94080C04, // 0019 GETIDX R2 R6 R4 + 0x5C0C0A00, // 001A MOVE R3 R5 + 0x00100903, // 001B ADD R4 R4 K3 + 0x7001FFED, // 001C JMP #000B + 0x80040400, // 001D RET 1 R2 }) ) ); @@ -1256,57 +1623,68 @@ extern const bclass be_class_Matter_Expirable; be_local_class(Matter_Fabric, 20, &be_class_Matter_Expirable, - be_nested_map(49, + be_nested_map(60, ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(fabric_index, -1), be_const_var(2) }, + { be_const_key_weak(fromjson, -1), be_const_static_closure(Matter_Fabric_fromjson_closure) }, + { be_const_key_weak(root_ca_certificate, -1), be_const_var(6) }, + { be_const_key_weak(ipk_epoch_key, -1), be_const_var(9) }, + { be_const_key_weak(get_ca, 34), be_const_closure(Matter_Fabric_get_ca_closure) }, + { be_const_key_weak(noc, -1), be_const_var(7) }, + { be_const_key_weak(get_device_id, -1), be_const_closure(Matter_Fabric_get_device_id_closure) }, + { be_const_key_weak(add_session, -1), be_const_closure(Matter_Fabric_add_session_closure) }, + { be_const_key_weak(get_oldest_session, 50), be_const_closure(Matter_Fabric_get_oldest_session_closure) }, + { be_const_key_weak(fabric_parent, -1), be_const_var(3) }, { be_const_key_weak(no_private_key, -1), be_const_var(5) }, - { be_const_key_weak(tojson, 8), be_const_closure(Matter_Fabric_tojson_closure) }, - { be_const_key_weak(counter_group_data_snd, -1), be_const_var(14) }, + { be_const_key_weak(admin_vendor, 1), be_const_var(19) }, + { be_const_key_weak(fabric_id, -1), be_const_var(10) }, + { be_const_key_weak(device_id, -1), be_const_var(12) }, + { be_const_key_weak(set_fabric_index, -1), be_const_closure(Matter_Fabric_set_fabric_index_closure) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_Fabric_init_closure) }, + { be_const_key_weak(counter_group_ctrl_snd, -1), be_const_var(15) }, { be_const_key_weak(fabric_label, -1), be_const_var(13) }, - { be_const_key_weak(_sessions, 34), be_const_var(4) }, + { be_const_key_weak(fabric_completed, -1), be_const_closure(Matter_Fabric_fabric_completed_closure) }, { be_const_key_weak(created, -1), be_const_var(1) }, - { be_const_key_weak(_GROUP_SND_INCR, -1), be_const_int(32) }, + { be_const_key_weak(fabric_compressed, -1), be_const_var(11) }, + { be_const_key_weak(icac, -1), be_const_var(8) }, + { be_const_key_weak(_counter_group_data_snd_impl, 2), be_const_var(16) }, + { be_const_key_weak(_store, 57), be_const_var(0) }, + { be_const_key_weak(get_ca_pub, 32), be_const_closure(Matter_Fabric_get_ca_pub_closure) }, + { be_const_key_weak(_GROUP_KEY, 16), be_nested_str_weak(GroupKey_X20v1_X2E0) }, + { be_const_key_weak(tojson, -1), be_const_closure(Matter_Fabric_tojson_closure) }, + { be_const_key_weak(assign_fabric_index, -1), be_const_closure(Matter_Fabric_assign_fabric_index_closure) }, { be_const_key_weak(get_admin_subject, -1), be_const_closure(Matter_Fabric_get_admin_subject_closure) }, - { be_const_key_weak(add_session, -1), be_const_closure(Matter_Fabric_add_session_closure) }, - { be_const_key_weak(get_old_recent_session, -1), be_const_closure(Matter_Fabric_get_old_recent_session_closure) }, - { be_const_key_weak(counter_group_data_snd_next, -1), be_const_closure(Matter_Fabric_counter_group_data_snd_next_closure) }, - { be_const_key_weak(ipk_epoch_key, -1), be_const_var(9) }, - { be_const_key_weak(get_device_id, -1), be_const_closure(Matter_Fabric_get_device_id_closure) }, - { be_const_key_weak(counter_group_ctrl_snd_next, -1), be_const_closure(Matter_Fabric_counter_group_ctrl_snd_next_closure) }, - { be_const_key_weak(_counter_group_ctrl_snd_impl, -1), be_const_var(17) }, - { be_const_key_weak(admin_subject, 3), be_const_var(18) }, - { be_const_key_weak(set_fabric_index, -1), be_const_closure(Matter_Fabric_set_fabric_index_closure) }, - { be_const_key_weak(get_fabric_compressed, 32), be_const_closure(Matter_Fabric_get_fabric_compressed_closure) }, - { be_const_key_weak(fabric_index, -1), be_const_var(2) }, - { be_const_key_weak(counter_group_ctrl_snd, 21), be_const_var(15) }, + { be_const_key_weak(_MAX_CASE, -1), be_const_int(5) }, + { be_const_key_weak(fabric_candidate, -1), be_const_closure(Matter_Fabric_fabric_candidate_closure) }, + { be_const_key_weak(_GROUP_SND_INCR, 36), be_const_int(32) }, + { be_const_key_weak(get_fabric_label, 55), be_const_closure(Matter_Fabric_get_fabric_label_closure) }, + { be_const_key_weak(set_noc_icac, -1), be_const_closure(Matter_Fabric_set_noc_icac_closure) }, + { be_const_key_weak(get_noc, 52), be_const_closure(Matter_Fabric_get_noc_closure) }, + { be_const_key_weak(before_remove, -1), be_const_closure(Matter_Fabric_before_remove_closure) }, + { be_const_key_weak(get_admin_vendor_name, -1), be_const_closure(Matter_Fabric_get_admin_vendor_name_closure) }, + { be_const_key_weak(set_ca, -1), be_const_closure(Matter_Fabric_set_ca_closure) }, + { be_const_key_weak(get_ipk_group_key, -1), be_const_closure(Matter_Fabric_get_ipk_group_key_closure) }, + { be_const_key_weak(hydrate_post, -1), be_const_closure(Matter_Fabric_hydrate_post_closure) }, + { be_const_key_weak(set_ipk_epoch_key, 31), be_const_closure(Matter_Fabric_set_ipk_epoch_key_closure) }, + { be_const_key_weak(set_pk, -1), be_const_closure(Matter_Fabric_set_pk_closure) }, + { be_const_key_weak(set_admin_subject_vendor, -1), be_const_closure(Matter_Fabric_set_admin_subject_vendor_closure) }, + { be_const_key_weak(get_fabric_compressed, 42), be_const_closure(Matter_Fabric_get_fabric_compressed_closure) }, { be_const_key_weak(log_new_fabric, -1), be_const_closure(Matter_Fabric_log_new_fabric_closure) }, - { be_const_key_weak(init, -1), be_const_closure(Matter_Fabric_init_closure) }, + { be_const_key_weak(get_pk, -1), be_const_closure(Matter_Fabric_get_pk_closure) }, + { be_const_key_weak(get_admin_vendor, -1), be_const_closure(Matter_Fabric_get_admin_vendor_closure) }, { be_const_key_weak(get_fabric_id, -1), be_const_closure(Matter_Fabric_get_fabric_id_closure) }, - { be_const_key_weak(_store, 15), be_const_var(0) }, - { be_const_key_weak(admin_vendor, 20), be_const_var(19) }, - { be_const_key_weak(device_id, 40), be_const_var(12) }, - { be_const_key_weak(before_remove, 28), be_const_closure(Matter_Fabric_before_remove_closure) }, - { be_const_key_weak(fromjson, -1), be_const_static_closure(Matter_Fabric_fromjson_closure) }, - { be_const_key_weak(get_noc, 39), be_const_closure(Matter_Fabric_get_noc_closure) }, - { be_const_key_weak(get_fabric_index, 38), be_const_closure(Matter_Fabric_get_fabric_index_closure) }, - { be_const_key_weak(_MAX_CASE, -1), be_const_int(5) }, + { be_const_key_weak(get_icac, 37), be_const_closure(Matter_Fabric_get_icac_closure) }, + { be_const_key_weak(_counter_group_ctrl_snd_impl, -1), be_const_var(17) }, + { be_const_key_weak(set_fabric_device, -1), be_const_closure(Matter_Fabric_set_fabric_device_closure) }, + { be_const_key_weak(admin_subject, 5), be_const_var(18) }, + { be_const_key_weak(counter_group_data_snd, -1), be_const_var(14) }, + { be_const_key_weak(get_newest_session, 29), be_const_closure(Matter_Fabric_get_newest_session_closure) }, + { be_const_key_weak(get_fabric_index, -1), be_const_closure(Matter_Fabric_get_fabric_index_closure) }, { be_const_key_weak(get_ipk_epoch_key, -1), be_const_closure(Matter_Fabric_get_ipk_epoch_key_closure) }, - { be_const_key_weak(_GROUP_KEY, -1), be_nested_str_weak(GroupKey_X20v1_X2E0) }, - { be_const_key_weak(_counter_group_data_snd_impl, -1), be_const_var(16) }, - { be_const_key_weak(fabric_parent, -1), be_const_var(3) }, - { be_const_key_weak(fabric_id, -1), be_const_var(10) }, - { be_const_key_weak(icac, 35), be_const_var(8) }, - { be_const_key_weak(get_ca, -1), be_const_closure(Matter_Fabric_get_ca_closure) }, - { be_const_key_weak(get_ipk_group_key, 6), be_const_closure(Matter_Fabric_get_ipk_group_key_closure) }, - { be_const_key_weak(get_fabric_label, -1), be_const_closure(Matter_Fabric_get_fabric_label_closure) }, - { be_const_key_weak(get_oldest_session, -1), be_const_closure(Matter_Fabric_get_oldest_session_closure) }, - { be_const_key_weak(get_newest_session, 22), be_const_closure(Matter_Fabric_get_newest_session_closure) }, - { be_const_key_weak(get_admin_vendor, -1), be_const_closure(Matter_Fabric_get_admin_vendor_closure) }, - { be_const_key_weak(noc, -1), be_const_var(7) }, - { be_const_key_weak(hydrate_post, -1), be_const_closure(Matter_Fabric_hydrate_post_closure) }, - { be_const_key_weak(get_icac, 10), be_const_closure(Matter_Fabric_get_icac_closure) }, - { be_const_key_weak(fabric_compressed, -1), be_const_var(11) }, - { be_const_key_weak(get_ca_pub, -1), be_const_closure(Matter_Fabric_get_ca_pub_closure) }, - { be_const_key_weak(root_ca_certificate, -1), be_const_var(6) }, + { be_const_key_weak(counter_group_data_snd_next, 4), be_const_closure(Matter_Fabric_counter_group_data_snd_next_closure) }, + { be_const_key_weak(counter_group_ctrl_snd_next, -1), be_const_closure(Matter_Fabric_counter_group_ctrl_snd_next_closure) }, + { be_const_key_weak(get_old_recent_session, -1), be_const_closure(Matter_Fabric_get_old_recent_session_closure) }, + { be_const_key_weak(_sessions, 0), be_const_var(4) }, })), be_str_weak(Matter_Fabric) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_HTTP_async.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_HTTP_async.h new file mode 100644 index 000000000000..49b05e0a900b --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_HTTP_async.h @@ -0,0 +1,1144 @@ +/* Solidification of Matter_HTTP_async.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_HTTP_async; + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_HTTP_async_init, /* name */ + be_nested_proto( + 11, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(compile_re), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x60140003, // 0000 GETGBL R5 G3 + 0x5C180000, // 0001 MOVE R6 R0 + 0x7C140200, // 0002 CALL R5 1 + 0x8C140B00, // 0003 GETMET R5 R5 K0 + 0x5C1C0200, // 0004 MOVE R7 R1 + 0x5C200400, // 0005 MOVE R8 R2 + 0x5C240600, // 0006 MOVE R9 R3 + 0x5C280800, // 0007 MOVE R10 R4 + 0x7C140A00, // 0008 CALL R5 5 + 0x8C140101, // 0009 GETMET R5 R0 K1 + 0x7C140200, // 000A CALL R5 1 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_http_failed +********************************************************************/ +be_local_closure(Matter_HTTP_async_event_http_failed, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(event_http_failed), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: compile_re +********************************************************************/ +be_local_closure(Matter_HTTP_async_compile_re, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(re), + /* K1 */ be_nested_str_weak(global), + /* K2 */ be_nested_str_weak(contains), + /* K3 */ be_nested_str_weak(_re_http_status), + /* K4 */ be_nested_str_weak(compile), + /* K5 */ be_nested_str_weak(HTTP_STATUS_REGEX), + /* K6 */ be_nested_str_weak(_re_http_header), + /* K7 */ be_nested_str_weak(HTTP_HEADER_REGEX), + /* K8 */ be_nested_str_weak(_re_http_body), + /* K9 */ be_nested_str_weak(HTTP_BODY_REGEX), + /* K10 */ be_nested_str_weak(_re_http_chunk), + /* K11 */ be_nested_str_weak(HTTP_CHUNK_REGEX), + }), + be_str_weak(compile_re), + &be_const_str_solidified, + ( &(const binstruction[27]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0xB80A0200, // 0001 GETNGBL R2 K1 + 0x8C080502, // 0002 GETMET R2 R2 K2 + 0x58100003, // 0003 LDCONST R4 K3 + 0x7C080400, // 0004 CALL R2 2 + 0x740A0013, // 0005 JMPT R2 #001A + 0xB80A0200, // 0006 GETNGBL R2 K1 + 0x8C0C0304, // 0007 GETMET R3 R1 K4 + 0x88140105, // 0008 GETMBR R5 R0 K5 + 0x7C0C0400, // 0009 CALL R3 2 + 0x900A0603, // 000A SETMBR R2 K3 R3 + 0xB80A0200, // 000B GETNGBL R2 K1 + 0x8C0C0304, // 000C GETMET R3 R1 K4 + 0x88140107, // 000D GETMBR R5 R0 K7 + 0x7C0C0400, // 000E CALL R3 2 + 0x900A0C03, // 000F SETMBR R2 K6 R3 + 0xB80A0200, // 0010 GETNGBL R2 K1 + 0x8C0C0304, // 0011 GETMET R3 R1 K4 + 0x88140109, // 0012 GETMBR R5 R0 K9 + 0x7C0C0400, // 0013 CALL R3 2 + 0x900A1003, // 0014 SETMBR R2 K8 R3 + 0xB80A0200, // 0015 GETNGBL R2 K1 + 0x8C0C0304, // 0016 GETMET R3 R1 K4 + 0x8814010B, // 0017 GETMBR R5 R0 K11 + 0x7C0C0400, // 0018 CALL R3 2 + 0x900A1403, // 0019 SETMBR R2 K10 R3 + 0x80000000, // 001A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_http_response +********************************************************************/ +be_local_closure(Matter_HTTP_async_parse_http_response, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(phase), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(parse_http_status_line), + /* K3 */ be_const_int(1), + /* K4 */ be_nested_str_weak(parse_http_headers), + /* K5 */ be_const_int(2), + /* K6 */ be_nested_str_weak(parse_http_payload), + }), + be_str_weak(parse_http_response), + &be_const_str_solidified, + ( &(const binstruction[18]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x1C040301, // 0001 EQ R1 R1 K1 + 0x78060002, // 0002 JMPF R1 #0006 + 0x8C040102, // 0003 GETMET R1 R0 K2 + 0x7C040200, // 0004 CALL R1 1 + 0x7002000A, // 0005 JMP #0011 + 0x88040100, // 0006 GETMBR R1 R0 K0 + 0x1C040303, // 0007 EQ R1 R1 K3 + 0x78060002, // 0008 JMPF R1 #000C + 0x8C040104, // 0009 GETMET R1 R0 K4 + 0x7C040200, // 000A CALL R1 1 + 0x70020004, // 000B JMP #0011 + 0x88040100, // 000C GETMBR R1 R0 K0 + 0x1C040305, // 000D EQ R1 R1 K5 + 0x78060001, // 000E JMPF R1 #0011 + 0x8C040106, // 000F GETMET R1 R0 K6 + 0x7C040200, // 0010 CALL R1 1 + 0x80000000, // 0011 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_available +********************************************************************/ +be_local_closure(Matter_HTTP_async_event_available, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(receive), + }), + be_str_weak(event_available), + &be_const_str_solidified, + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80000000, // 0002 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: receive +********************************************************************/ +be_local_closure(Matter_HTTP_async_receive, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[15]) { /* constants */ + /* K0 */ be_nested_str_weak(tcp_connected), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(millis), + /* K3 */ be_nested_str_weak(time_start), + /* K4 */ be_nested_str_weak(timeout), + /* K5 */ be_nested_str_weak(status), + /* K6 */ be_nested_str_weak(close), + /* K7 */ be_nested_str_weak(http_status), + /* K8 */ be_nested_str_weak(event_http_timeout), + /* K9 */ be_nested_str_weak(tcp), + /* K10 */ be_nested_str_weak(available), + /* K11 */ be_const_int(0), + /* K12 */ be_nested_str_weak(read), + /* K13 */ be_nested_str_weak(response), + /* K14 */ be_nested_str_weak(parse_http_response), + }), + be_str_weak(receive), + &be_const_str_solidified, + ( &(const binstruction[48]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x50080200, // 0001 LDBOOL R2 1 0 + 0x20040202, // 0002 NE R1 R1 R2 + 0x78060000, // 0003 JMPF R1 #0005 + 0x80000200, // 0004 RET 0 + 0xB8060200, // 0005 GETNGBL R1 K1 + 0x8C040302, // 0006 GETMET R1 R1 K2 + 0x7C040200, // 0007 CALL R1 1 + 0x88080103, // 0008 GETMBR R2 R0 K3 + 0x04040202, // 0009 SUB R1 R1 R2 + 0x88080104, // 000A GETMBR R2 R0 K4 + 0x24040202, // 000B GT R1 R1 R2 + 0x78060008, // 000C JMPF R1 #0016 + 0x5405FFFC, // 000D LDINT R1 -3 + 0x90020A01, // 000E SETMBR R0 K5 R1 + 0x8C040106, // 000F GETMET R1 R0 K6 + 0x7C040200, // 0010 CALL R1 1 + 0x5405FFFD, // 0011 LDINT R1 -2 + 0x90020E01, // 0012 SETMBR R0 K7 R1 + 0x8C040108, // 0013 GETMET R1 R0 K8 + 0x7C040200, // 0014 CALL R1 1 + 0x70020018, // 0015 JMP #002F + 0x88040109, // 0016 GETMBR R1 R0 K9 + 0x8C04030A, // 0017 GETMET R1 R1 K10 + 0x7C040200, // 0018 CALL R1 1 + 0x5808000B, // 0019 LDCONST R2 K11 + 0x240C030B, // 001A GT R3 R1 K11 + 0x780E000E, // 001B JMPF R3 #002B + 0x880C0109, // 001C GETMBR R3 R0 K9 + 0x8C0C070C, // 001D GETMET R3 R3 K12 + 0x7C0C0200, // 001E CALL R3 1 + 0x8810010D, // 001F GETMBR R4 R0 K13 + 0x00100803, // 0020 ADD R4 R4 R3 + 0x90021A04, // 0021 SETMBR R0 K13 R4 + 0x6010000C, // 0022 GETGBL R4 G12 + 0x5C140600, // 0023 MOVE R5 R3 + 0x7C100200, // 0024 CALL R4 1 + 0x00080404, // 0025 ADD R2 R2 R4 + 0x88100109, // 0026 GETMBR R4 R0 K9 + 0x8C10090A, // 0027 GETMET R4 R4 K10 + 0x7C100200, // 0028 CALL R4 1 + 0x5C040800, // 0029 MOVE R1 R4 + 0x7001FFEE, // 002A JMP #001A + 0x240C050B, // 002B GT R3 R2 K11 + 0x780E0001, // 002C JMPF R3 #002F + 0x8C0C010E, // 002D GETMET R3 R0 K14 + 0x7C0C0200, // 002E CALL R3 1 + 0x80000000, // 002F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: reset +********************************************************************/ +be_local_closure(Matter_HTTP_async_reset, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(reset), + /* K1 */ be_nested_str_weak(cmd), + /* K2 */ be_nested_str_weak(response), + /* K3 */ be_nested_str_weak(response_offset), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(payload), + /* K6 */ be_nested_str_weak(), + /* K7 */ be_nested_str_weak(phase), + /* K8 */ be_nested_str_weak(http_status), + /* K9 */ be_nested_str_weak(is_chunked), + /* K10 */ be_nested_str_weak(chunk_size), + }), + be_str_weak(reset), + &be_const_str_solidified, + ( &(const binstruction[18]) { /* code */ + 0x60040003, // 0000 GETGBL R1 G3 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x8C040300, // 0003 GETMET R1 R1 K0 + 0x7C040200, // 0004 CALL R1 1 + 0x4C040000, // 0005 LDNIL R1 + 0x90020201, // 0006 SETMBR R0 K1 R1 + 0x4C040000, // 0007 LDNIL R1 + 0x90020401, // 0008 SETMBR R0 K2 R1 + 0x90020704, // 0009 SETMBR R0 K3 K4 + 0x90020B06, // 000A SETMBR R0 K5 K6 + 0x90020F04, // 000B SETMBR R0 K7 K4 + 0x90021104, // 000C SETMBR R0 K8 K4 + 0x50040000, // 000D LDBOOL R1 0 0 + 0x90021201, // 000E SETMBR R0 K9 R1 + 0x4C040000, // 000F LDNIL R1 + 0x90021401, // 0010 SETMBR R0 K10 R1 + 0x80000000, // 0011 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_http_status_code +********************************************************************/ +be_local_closure(Matter_HTTP_async_event_http_status_code, /* name */ + be_nested_proto( + 3, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(status_code), + }), + be_str_weak(event_http_status_code), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x80000000, // 0001 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_http_payload +********************************************************************/ +be_local_closure(Matter_HTTP_async_parse_http_payload, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[16]) { /* constants */ + /* K0 */ be_nested_str_weak(is_chunked), + /* K1 */ be_nested_str_weak(chunk_size), + /* K2 */ be_nested_str_weak(global), + /* K3 */ be_nested_str_weak(_re_http_chunk), + /* K4 */ be_nested_str_weak(match2), + /* K5 */ be_nested_str_weak(response), + /* K6 */ be_nested_str_weak(response_offset), + /* K7 */ be_const_int(0), + /* K8 */ be_nested_str_weak(0x), + /* K9 */ be_const_int(1), + /* K10 */ be_nested_str_weak(status), + /* K11 */ be_const_int(2), + /* K12 */ be_nested_str_weak(), + /* K13 */ be_nested_str_weak(close), + /* K14 */ be_nested_str_weak(payload), + /* K15 */ be_const_int(2147483647), + }), + be_str_weak(parse_http_payload), + &be_const_str_solidified, + ( &(const binstruction[82]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x78060045, // 0001 JMPF R1 #0048 + 0x50040200, // 0002 LDBOOL R1 1 0 + 0x78060042, // 0003 JMPF R1 #0047 + 0x88040101, // 0004 GETMBR R1 R0 K1 + 0x4C080000, // 0005 LDNIL R2 + 0x1C040202, // 0006 EQ R1 R1 R2 + 0x78060018, // 0007 JMPF R1 #0021 + 0xB8060400, // 0008 GETNGBL R1 K2 + 0x88040303, // 0009 GETMBR R1 R1 K3 + 0x8C040304, // 000A GETMET R1 R1 K4 + 0x880C0105, // 000B GETMBR R3 R0 K5 + 0x88100106, // 000C GETMBR R4 R0 K6 + 0x7C040600, // 000D CALL R1 3 + 0x78060011, // 000E JMPF R1 #0021 + 0x88080106, // 000F GETMBR R2 R0 K6 + 0x940C0307, // 0010 GETIDX R3 R1 K7 + 0x00080403, // 0011 ADD R2 R2 R3 + 0x90020C02, // 0012 SETMBR R0 K6 R2 + 0x60080009, // 0013 GETGBL R2 G9 + 0x940C0309, // 0014 GETIDX R3 R1 K9 + 0x000E1003, // 0015 ADD R3 K8 R3 + 0x7C080200, // 0016 CALL R2 1 + 0x90020202, // 0017 SETMBR R0 K1 R2 + 0x88080101, // 0018 GETMBR R2 R0 K1 + 0x1C080507, // 0019 EQ R2 R2 K7 + 0x780A0005, // 001A JMPF R2 #0021 + 0x9002150B, // 001B SETMBR R0 K10 K11 + 0x90020B0C, // 001C SETMBR R0 K5 K12 + 0x90020D07, // 001D SETMBR R0 K6 K7 + 0x8C08010D, // 001E GETMET R2 R0 K13 + 0x7C080200, // 001F CALL R2 1 + 0x80000400, // 0020 RET 0 + 0x88040101, // 0021 GETMBR R1 R0 K1 + 0x4C080000, // 0022 LDNIL R2 + 0x20040202, // 0023 NE R1 R1 R2 + 0x7806001F, // 0024 JMPF R1 #0045 + 0x88040101, // 0025 GETMBR R1 R0 K1 + 0x6008000C, // 0026 GETGBL R2 G12 + 0x880C0105, // 0027 GETMBR R3 R0 K5 + 0x7C080200, // 0028 CALL R2 1 + 0x880C0106, // 0029 GETMBR R3 R0 K6 + 0x04080403, // 002A SUB R2 R2 R3 + 0x18040202, // 002B LE R1 R1 R2 + 0x78060015, // 002C JMPF R1 #0043 + 0x88080106, // 002D GETMBR R2 R0 K6 + 0x880C0106, // 002E GETMBR R3 R0 K6 + 0x88100101, // 002F GETMBR R4 R0 K1 + 0x000C0604, // 0030 ADD R3 R3 R4 + 0x040C0709, // 0031 SUB R3 R3 K9 + 0x40080403, // 0032 CONNECT R2 R2 R3 + 0x880C0105, // 0033 GETMBR R3 R0 K5 + 0x8804010E, // 0034 GETMBR R1 R0 K14 + 0x94080602, // 0035 GETIDX R2 R3 R2 + 0x00040202, // 0036 ADD R1 R1 R2 + 0x90021C01, // 0037 SETMBR R0 K14 R1 + 0x88040106, // 0038 GETMBR R1 R0 K6 + 0x88080101, // 0039 GETMBR R2 R0 K1 + 0x00040202, // 003A ADD R1 R1 R2 + 0x4004030F, // 003B CONNECT R1 R1 K15 + 0x88080105, // 003C GETMBR R2 R0 K5 + 0x94040401, // 003D GETIDX R1 R2 R1 + 0x90020A01, // 003E SETMBR R0 K5 R1 + 0x90020D07, // 003F SETMBR R0 K6 K7 + 0x4C040000, // 0040 LDNIL R1 + 0x90020201, // 0041 SETMBR R0 K1 R1 + 0x70020000, // 0042 JMP #0044 + 0x80000200, // 0043 RET 0 + 0x70020000, // 0044 JMP #0046 + 0x80000200, // 0045 RET 0 + 0x7001FFBA, // 0046 JMP #0002 + 0x70020008, // 0047 JMP #0051 + 0x88080106, // 0048 GETMBR R2 R0 K6 + 0x4008050F, // 0049 CONNECT R2 R2 K15 + 0x880C0105, // 004A GETMBR R3 R0 K5 + 0x8804010E, // 004B GETMBR R1 R0 K14 + 0x94080602, // 004C GETIDX R2 R3 R2 + 0x00040202, // 004D ADD R1 R1 R2 + 0x90021C01, // 004E SETMBR R0 K14 R1 + 0x90020B0C, // 004F SETMBR R0 K5 K12 + 0x90020D07, // 0050 SETMBR R0 K6 K7 + 0x80000000, // 0051 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: send_http +********************************************************************/ +be_local_closure(Matter_HTTP_async_send_http, /* name */ + be_nested_proto( + 8, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[17]) { /* constants */ + /* K0 */ be_nested_str_weak(string), + /* K1 */ be_nested_str_weak(response), + /* K2 */ be_nested_str_weak(), + /* K3 */ be_nested_str_weak(addr), + /* K4 */ be_nested_str_weak(find), + /* K5 */ be_nested_str_weak(_X3A), + /* K6 */ be_const_int(0), + /* K7 */ be_nested_str_weak(_X5B), + /* K8 */ be_nested_str_weak(_X5D), + /* K9 */ be_nested_str_weak(HTTP_GET), + /* K10 */ be_nested_str_weak(cmd), + /* K11 */ be_nested_str_weak(port), + /* K12 */ be_nested_str_weak(write), + /* K13 */ be_nested_str_weak(close), + /* K14 */ be_nested_str_weak(status), + /* K15 */ be_nested_str_weak(http_status), + /* K16 */ be_nested_str_weak(event_http_failed), + }), + be_str_weak(send_http), + &be_const_str_solidified, + ( &(const binstruction[35]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x90020302, // 0001 SETMBR R0 K1 K2 + 0x88080103, // 0002 GETMBR R2 R0 K3 + 0x8C0C0304, // 0003 GETMET R3 R1 K4 + 0x5C140400, // 0004 MOVE R5 R2 + 0x58180005, // 0005 LDCONST R6 K5 + 0x7C0C0600, // 0006 CALL R3 3 + 0x280C0706, // 0007 GE R3 R3 K6 + 0x780E0002, // 0008 JMPF R3 #000C + 0x000E0E02, // 0009 ADD R3 K7 R2 + 0x000C0708, // 000A ADD R3 R3 K8 + 0x5C080600, // 000B MOVE R2 R3 + 0x600C0018, // 000C GETGBL R3 G24 + 0x88100109, // 000D GETMBR R4 R0 K9 + 0x8814010A, // 000E GETMBR R5 R0 K10 + 0x5C180400, // 000F MOVE R6 R2 + 0x881C010B, // 0010 GETMBR R7 R0 K11 + 0x7C0C0800, // 0011 CALL R3 4 + 0x8C10010C, // 0012 GETMET R4 R0 K12 + 0x5C180600, // 0013 MOVE R6 R3 + 0x7C100400, // 0014 CALL R4 2 + 0x6014000C, // 0015 GETGBL R5 G12 + 0x5C180600, // 0016 MOVE R6 R3 + 0x7C140200, // 0017 CALL R5 1 + 0x20140805, // 0018 NE R5 R4 R5 + 0x78160007, // 0019 JMPF R5 #0022 + 0x8C14010D, // 001A GETMET R5 R0 K13 + 0x7C140200, // 001B CALL R5 1 + 0x5415FFFB, // 001C LDINT R5 -4 + 0x90021C05, // 001D SETMBR R0 K14 R5 + 0x5415FFFE, // 001E LDINT R5 -1 + 0x90021E05, // 001F SETMBR R0 K15 R5 + 0x8C140110, // 0020 GETMET R5 R0 K16 + 0x7C140200, // 0021 CALL R5 1 + 0x80000000, // 0022 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: begin_sync +********************************************************************/ +be_local_closure(Matter_HTTP_async_begin_sync, /* name */ + be_nested_proto( + 10, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str_weak(timeout), + /* K1 */ be_nested_str_weak(set_timeout), + /* K2 */ be_nested_str_weak(SPINLOCK), + /* K3 */ be_nested_str_weak(begin), + /* K4 */ be_nested_str_weak(http_status), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(loop), + /* K7 */ be_nested_str_weak(tasmota), + /* K8 */ be_nested_str_weak(delay), + /* K9 */ be_nested_str_weak(payload), + }), + be_str_weak(begin_sync), + &be_const_str_solidified, + ( &(const binstruction[33]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x4C100000, // 0001 LDNIL R4 + 0x20100404, // 0002 NE R4 R2 R4 + 0x78120002, // 0003 JMPF R4 #0007 + 0x8C100101, // 0004 GETMET R4 R0 K1 + 0x5C180400, // 0005 MOVE R6 R2 + 0x7C100400, // 0006 CALL R4 2 + 0x4C100000, // 0007 LDNIL R4 + 0x88140102, // 0008 GETMBR R5 R0 K2 + 0x8C180103, // 0009 GETMET R6 R0 K3 + 0x5C200200, // 000A MOVE R8 R1 + 0x7C180400, // 000B CALL R6 2 + 0x781A0009, // 000C JMPF R6 #0017 + 0x881C0104, // 000D GETMBR R7 R0 K4 + 0x1C1C0F05, // 000E EQ R7 R7 K5 + 0x781E0006, // 000F JMPF R7 #0017 + 0x8C1C0106, // 0010 GETMET R7 R0 K6 + 0x7C1C0200, // 0011 CALL R7 1 + 0xB81E0E00, // 0012 GETNGBL R7 K7 + 0x8C1C0F08, // 0013 GETMET R7 R7 K8 + 0x5C240A00, // 0014 MOVE R9 R5 + 0x7C1C0400, // 0015 CALL R7 2 + 0x7001FFF5, // 0016 JMP #000D + 0x8C1C0101, // 0017 GETMET R7 R0 K1 + 0x5C240600, // 0018 MOVE R9 R3 + 0x7C1C0400, // 0019 CALL R7 2 + 0x881C0104, // 001A GETMBR R7 R0 K4 + 0x241C0F05, // 001B GT R7 R7 K5 + 0x781E0001, // 001C JMPF R7 #001F + 0x881C0109, // 001D GETMBR R7 R0 K9 + 0x70020000, // 001E JMP #0020 + 0x4C1C0000, // 001F LDNIL R7 + 0x80040E00, // 0020 RET 1 R7 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_http_finished +********************************************************************/ +be_local_closure(Matter_HTTP_async_event_http_finished, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(event_http_finished), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_timeout +********************************************************************/ +be_local_closure(Matter_HTTP_async_event_timeout, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(http_status), + /* K1 */ be_nested_str_weak(event_http_timeout), + }), + be_str_weak(event_timeout), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x5405FFFD, // 0000 LDINT R1 -2 + 0x90020001, // 0001 SETMBR R0 K0 R1 + 0x8C040101, // 0002 GETMET R1 R0 K1 + 0x7C040200, // 0003 CALL R1 1 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_established +********************************************************************/ +be_local_closure(Matter_HTTP_async_event_established, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(send_http), + }), + be_str_weak(event_established), + &be_const_str_solidified, + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80000000, // 0002 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_refused +********************************************************************/ +be_local_closure(Matter_HTTP_async_event_refused, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(http_status), + /* K1 */ be_nested_str_weak(event_http_failed), + }), + be_str_weak(event_refused), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x5405FFFE, // 0000 LDINT R1 -1 + 0x90020001, // 0001 SETMBR R0 K0 R1 + 0x8C040101, // 0002 GETMET R1 R0 K1 + 0x7C040200, // 0003 CALL R1 1 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_closed +********************************************************************/ +be_local_closure(Matter_HTTP_async_event_closed, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(http_status), + /* K1 */ be_const_int(0), + /* K2 */ be_const_int(1), + /* K3 */ be_nested_str_weak(event_http_finished), + }), + be_str_weak(event_closed), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x1C040301, // 0001 EQ R1 R1 K1 + 0x78060002, // 0002 JMPF R1 #0006 + 0x90020102, // 0003 SETMBR R0 K0 K2 + 0x8C040103, // 0004 GETMET R1 R0 K3 + 0x7C040200, // 0005 CALL R1 1 + 0x80000000, // 0006 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_http_status_line +********************************************************************/ +be_local_closure(Matter_HTTP_async_parse_http_status_line, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(global), + /* K1 */ be_nested_str_weak(_re_http_status), + /* K2 */ be_nested_str_weak(match2), + /* K3 */ be_nested_str_weak(response), + /* K4 */ be_nested_str_weak(response_offset), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(status_code), + /* K7 */ be_const_int(1), + /* K8 */ be_nested_str_weak(phase), + /* K9 */ be_nested_str_weak(parse_http_headers), + /* K10 */ be_nested_str_weak(close), + /* K11 */ be_nested_str_weak(status), + }), + be_str_weak(parse_http_status_line), + &be_const_str_solidified, + ( &(const binstruction[28]) { /* code */ + 0xB8060000, // 0000 GETNGBL R1 K0 + 0x88040301, // 0001 GETMBR R1 R1 K1 + 0x8C040302, // 0002 GETMET R1 R1 K2 + 0x880C0103, // 0003 GETMBR R3 R0 K3 + 0x88100104, // 0004 GETMBR R4 R0 K4 + 0x7C040600, // 0005 CALL R1 3 + 0x78060009, // 0006 JMPF R1 #0011 + 0x94080305, // 0007 GETIDX R2 R1 K5 + 0x90020802, // 0008 SETMBR R0 K4 R2 + 0x60080009, // 0009 GETGBL R2 G9 + 0x940C0307, // 000A GETIDX R3 R1 K7 + 0x7C080200, // 000B CALL R2 1 + 0x90020C02, // 000C SETMBR R0 K6 R2 + 0x90021107, // 000D SETMBR R0 K8 K7 + 0x8C080109, // 000E GETMET R2 R0 K9 + 0x7C080200, // 000F CALL R2 1 + 0x70020009, // 0010 JMP #001B + 0x6008000C, // 0011 GETGBL R2 G12 + 0x880C0103, // 0012 GETMBR R3 R0 K3 + 0x7C080200, // 0013 CALL R2 1 + 0x540E0063, // 0014 LDINT R3 100 + 0x24080403, // 0015 GT R2 R2 R3 + 0x780A0003, // 0016 JMPF R2 #001B + 0x8C08010A, // 0017 GETMET R2 R0 K10 + 0x7C080200, // 0018 CALL R2 1 + 0x5409FFFB, // 0019 LDINT R2 -4 + 0x90021602, // 001A SETMBR R0 K11 R2 + 0x80000000, // 001B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_http_headers +********************************************************************/ +be_local_closure(Matter_HTTP_async_parse_http_headers, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[17]) { /* constants */ + /* K0 */ be_nested_str_weak(global), + /* K1 */ be_nested_str_weak(_re_http_header), + /* K2 */ be_nested_str_weak(match2), + /* K3 */ be_nested_str_weak(response), + /* K4 */ be_nested_str_weak(response_offset), + /* K5 */ be_nested_str_weak(event_http_header), + /* K6 */ be_const_int(1), + /* K7 */ be_const_int(2), + /* K8 */ be_const_int(0), + /* K9 */ be_nested_str_weak(_re_http_body), + /* K10 */ be_nested_str_weak(event_http_headers_end), + /* K11 */ be_nested_str_weak(phase), + /* K12 */ be_nested_str_weak(parse_http_payload), + /* K13 */ be_nested_str_weak(close), + /* K14 */ be_nested_str_weak(status), + /* K15 */ be_nested_str_weak(http_status), + /* K16 */ be_nested_str_weak(event_http_failed), + }), + be_str_weak(parse_http_headers), + &be_const_str_solidified, + ( &(const binstruction[47]) { /* code */ + 0x50040200, // 0000 LDBOOL R1 1 0 + 0x7806002B, // 0001 JMPF R1 #002E + 0xB8060000, // 0002 GETNGBL R1 K0 + 0x88040301, // 0003 GETMBR R1 R1 K1 + 0x8C040302, // 0004 GETMET R1 R1 K2 + 0x880C0103, // 0005 GETMBR R3 R0 K3 + 0x88100104, // 0006 GETMBR R4 R0 K4 + 0x7C040600, // 0007 CALL R1 3 + 0x78060008, // 0008 JMPF R1 #0012 + 0x8C080105, // 0009 GETMET R2 R0 K5 + 0x94100306, // 000A GETIDX R4 R1 K6 + 0x94140307, // 000B GETIDX R5 R1 K7 + 0x7C080600, // 000C CALL R2 3 + 0x88080104, // 000D GETMBR R2 R0 K4 + 0x940C0308, // 000E GETIDX R3 R1 K8 + 0x00080403, // 000F ADD R2 R2 R3 + 0x90020802, // 0010 SETMBR R0 K4 R2 + 0x7002001A, // 0011 JMP #002D + 0xB80A0000, // 0012 GETNGBL R2 K0 + 0x88080509, // 0013 GETMBR R2 R2 K9 + 0x8C080502, // 0014 GETMET R2 R2 K2 + 0x88100103, // 0015 GETMBR R4 R0 K3 + 0x88140104, // 0016 GETMBR R5 R0 K4 + 0x7C080600, // 0017 CALL R2 3 + 0x780A0004, // 0018 JMPF R2 #001E + 0x8C0C010A, // 0019 GETMET R3 R0 K10 + 0x7C0C0200, // 001A CALL R3 1 + 0x90021707, // 001B SETMBR R0 K11 K7 + 0x8C0C010C, // 001C GETMET R3 R0 K12 + 0x7C0C0200, // 001D CALL R3 1 + 0x600C000C, // 001E GETGBL R3 G12 + 0x88100103, // 001F GETMBR R4 R0 K3 + 0x7C0C0200, // 0020 CALL R3 1 + 0x541203FF, // 0021 LDINT R4 1024 + 0x240C0604, // 0022 GT R3 R3 R4 + 0x780E0007, // 0023 JMPF R3 #002C + 0x8C0C010D, // 0024 GETMET R3 R0 K13 + 0x7C0C0200, // 0025 CALL R3 1 + 0x540DFFFB, // 0026 LDINT R3 -4 + 0x90021C03, // 0027 SETMBR R0 K14 R3 + 0x540DFFFE, // 0028 LDINT R3 -1 + 0x90021E03, // 0029 SETMBR R0 K15 R3 + 0x8C0C0110, // 002A GETMET R3 R0 K16 + 0x7C0C0200, // 002B CALL R3 1 + 0x80000600, // 002C RET 0 + 0x7001FFD1, // 002D JMP #0000 + 0x80000000, // 002E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_http_timeout +********************************************************************/ +be_local_closure(Matter_HTTP_async_event_http_timeout, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(event_http_timeout), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_http_headers_end +********************************************************************/ +be_local_closure(Matter_HTTP_async_event_http_headers_end, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(response_offset), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(response), + /* K3 */ be_const_int(2147483647), + }), + be_str_weak(event_http_headers_end), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x24040301, // 0001 GT R1 R1 K1 + 0x78060005, // 0002 JMPF R1 #0009 + 0x88040100, // 0003 GETMBR R1 R0 K0 + 0x40040303, // 0004 CONNECT R1 R1 K3 + 0x88080102, // 0005 GETMBR R2 R0 K2 + 0x94040401, // 0006 GETIDX R1 R2 R1 + 0x90020401, // 0007 SETMBR R0 K2 R1 + 0x90020101, // 0008 SETMBR R0 K0 K1 + 0x80000000, // 0009 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_http_header +********************************************************************/ +be_local_closure(Matter_HTTP_async_event_http_header, /* name */ + be_nested_proto( + 7, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(string), + /* K1 */ be_nested_str_weak(tolower), + /* K2 */ be_nested_str_weak(transfer_X2Dencoding), + /* K3 */ be_nested_str_weak(chunked), + /* K4 */ be_nested_str_weak(is_chunked), + }), + be_str_weak(event_http_header), + &be_const_str_solidified, + ( &(const binstruction[19]) { /* code */ + 0xA40E0000, // 0000 IMPORT R3 K0 + 0x8C100701, // 0001 GETMET R4 R3 K1 + 0x5C180200, // 0002 MOVE R6 R1 + 0x7C100400, // 0003 CALL R4 2 + 0x5C040800, // 0004 MOVE R1 R4 + 0x8C100701, // 0005 GETMET R4 R3 K1 + 0x5C180400, // 0006 MOVE R6 R2 + 0x7C100400, // 0007 CALL R4 2 + 0x5C080800, // 0008 MOVE R2 R4 + 0x1C100302, // 0009 EQ R4 R1 K2 + 0x78120006, // 000A JMPF R4 #0012 + 0x8C100701, // 000B GETMET R4 R3 K1 + 0x5C180400, // 000C MOVE R6 R2 + 0x7C100400, // 000D CALL R4 2 + 0x1C100903, // 000E EQ R4 R4 K3 + 0x78120001, // 000F JMPF R4 #0012 + 0x50100200, // 0010 LDBOOL R4 1 0 + 0x90020804, // 0011 SETMBR R0 K4 R4 + 0x80000000, // 0012 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: begin +********************************************************************/ +be_local_closure(Matter_HTTP_async_begin, /* name */ + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(begin), + /* K1 */ be_nested_str_weak(cmd), + }), + be_str_weak(begin), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x60080003, // 0000 GETGBL R2 G3 + 0x5C0C0000, // 0001 MOVE R3 R0 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080500, // 0003 GETMET R2 R2 K0 + 0x7C080200, // 0004 CALL R2 1 + 0x90020201, // 0005 SETMBR R0 K1 R1 + 0x80040400, // 0006 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_HTTP_async +********************************************************************/ +extern const bclass be_class_Matter_TCP_async; +be_local_class(Matter_HTTP_async, + 9, + &be_class_Matter_TCP_async, + be_nested_map(37, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(init, 2), be_const_closure(Matter_HTTP_async_init_closure) }, + { be_const_key_weak(response, 28), be_const_var(1) }, + { be_const_key_weak(http_status, -1), be_const_var(5) }, + { be_const_key_weak(HTTP_STATUS_REGEX, 14), be_nested_str_weak(HTTP_X2F1_X5C_X2E_X5B0_X2D1_X5D_X20_X28_X5Cd_X2B_X29_X20_X2E_X2A_X3F_X0D_X0A) }, + { be_const_key_weak(HTTP_GET, 8), be_nested_str_weak(GET_X20_X25s_X20HTTP_X2F1_X2E1_X0D_X0AHost_X20_X25s_X3A_X25s_X0D_X0AConnection_X3A_X20close_X0D_X0A_X0D_X0A) }, + { be_const_key_weak(response_offset, -1), be_const_var(2) }, + { be_const_key_weak(compile_re, -1), be_const_closure(Matter_HTTP_async_compile_re_closure) }, + { be_const_key_weak(event_http_header, -1), be_const_closure(Matter_HTTP_async_event_http_header_closure) }, + { be_const_key_weak(event_http_status_code, -1), be_const_closure(Matter_HTTP_async_event_http_status_code_closure) }, + { be_const_key_weak(payload, -1), be_const_var(4) }, + { be_const_key_weak(event_available, -1), be_const_closure(Matter_HTTP_async_event_available_closure) }, + { be_const_key_weak(chunk_size, 16), be_const_var(8) }, + { be_const_key_weak(event_http_timeout, -1), be_const_closure(Matter_HTTP_async_event_http_timeout_closure) }, + { be_const_key_weak(parse_http_payload, -1), be_const_closure(Matter_HTTP_async_parse_http_payload_closure) }, + { be_const_key_weak(parse_http_status_line, 29), be_const_closure(Matter_HTTP_async_parse_http_status_line_closure) }, + { be_const_key_weak(begin_sync, -1), be_const_closure(Matter_HTTP_async_begin_sync_closure) }, + { be_const_key_weak(cmd, -1), be_const_var(0) }, + { be_const_key_weak(event_http_failed, 13), be_const_closure(Matter_HTTP_async_event_http_failed_closure) }, + { be_const_key_weak(SPINLOCK, -1), be_const_int(5) }, + { be_const_key_weak(reset, 31), be_const_closure(Matter_HTTP_async_reset_closure) }, + { be_const_key_weak(send_http, -1), be_const_closure(Matter_HTTP_async_send_http_closure) }, + { be_const_key_weak(parse_http_response, 15), be_const_closure(Matter_HTTP_async_parse_http_response_closure) }, + { be_const_key_weak(event_http_finished, -1), be_const_closure(Matter_HTTP_async_event_http_finished_closure) }, + { be_const_key_weak(HTTP_BODY_REGEX, -1), be_nested_str_weak(_X0D_X0A) }, + { be_const_key_weak(event_refused, -1), be_const_closure(Matter_HTTP_async_event_refused_closure) }, + { be_const_key_weak(HTTP_HEADER_REGEX, -1), be_nested_str_weak(_X28_X5BA_X2DZa_X2Dz0_X2D9_X2D_X5D_X2B_X29_X3A_X20_X28_X2E_X2A_X3F_X29_X0D_X0A) }, + { be_const_key_weak(is_chunked, 25), be_const_var(7) }, + { be_const_key_weak(event_established, 24), be_const_closure(Matter_HTTP_async_event_established_closure) }, + { be_const_key_weak(HTTP_CHUNK_REGEX, -1), be_nested_str_weak(_X0D_X0A_X28_X5BA_X2DFa_X2Df0_X2D9_X5D_X2B_X29_X5B_X20_X09_X5D_X2A_X2E_X2A_X3F_X0D_X0A) }, + { be_const_key_weak(receive, -1), be_const_closure(Matter_HTTP_async_receive_closure) }, + { be_const_key_weak(event_closed, -1), be_const_closure(Matter_HTTP_async_event_closed_closure) }, + { be_const_key_weak(phase, -1), be_const_var(6) }, + { be_const_key_weak(parse_http_headers, -1), be_const_closure(Matter_HTTP_async_parse_http_headers_closure) }, + { be_const_key_weak(event_timeout, 12), be_const_closure(Matter_HTTP_async_event_timeout_closure) }, + { be_const_key_weak(event_http_headers_end, -1), be_const_closure(Matter_HTTP_async_event_http_headers_end_closure) }, + { be_const_key_weak(status_code, 7), be_const_var(3) }, + { be_const_key_weak(begin, -1), be_const_closure(Matter_HTTP_async_begin_closure) }, + })), + be_str_weak(Matter_HTTP_async) +); +/*******************************************************************/ + +void be_load_Matter_HTTP_async_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_HTTP_async); + be_setglobal(vm, "Matter_HTTP_async"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_HTTP_remote.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_HTTP_remote.h new file mode 100644 index 000000000000..ee1c0bc37ce4 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_HTTP_remote.h @@ -0,0 +1,1325 @@ +/* Solidification of Matter_HTTP_remote.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_HTTP_remote; + +/******************************************************************** +** Solidified function: device_is_alive +********************************************************************/ +be_local_closure(Matter_HTTP_remote_device_is_alive, /* name */ + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(reachable), + /* K1 */ be_nested_str_weak(reachable_utc), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(rtc_utc), + }), + be_str_weak(device_is_alive), + &be_const_str_solidified, + ( &(const binstruction[11]) { /* code */ + 0x78060006, // 0000 JMPF R1 #0008 + 0x50080200, // 0001 LDBOOL R2 1 0 + 0x90020002, // 0002 SETMBR R0 K0 R2 + 0xB80A0400, // 0003 GETNGBL R2 K2 + 0x8C080503, // 0004 GETMET R2 R2 K3 + 0x7C080200, // 0005 CALL R2 1 + 0x90020202, // 0006 SETMBR R0 K1 R2 + 0x70020001, // 0007 JMP #000A + 0x50080000, // 0008 LDBOOL R2 0 0 + 0x90020002, // 0009 SETMBR R0 K0 R2 + 0x80000000, // 000A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_update +********************************************************************/ +be_local_closure(Matter_HTTP_remote_parse_update, /* name */ + be_nested_proto( + 12, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[28]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(DeviceName), + /* K3 */ be_nested_str_weak(Tasmota), + /* K4 */ be_nested_str_weak(info), + /* K5 */ be_nested_str_weak(name), + /* K6 */ be_nested_str_weak(remove), + /* K7 */ be_nested_str_weak(tasmota), + /* K8 */ be_nested_str_weak(log), + /* K9 */ be_nested_str_weak(MTR_X3A_X20update_X20_X27_X25s_X27_X20name_X3D_X27_X25s_X27), + /* K10 */ be_nested_str_weak(addr), + /* K11 */ be_const_int(3), + /* K12 */ be_nested_str_weak(change_schedule), + /* K13 */ be_nested_str_weak(UPDATE_CMD0), + /* K14 */ be_nested_str_weak(UPDATE_TIME2), + /* K15 */ be_const_int(2), + /* K16 */ be_nested_str_weak(Version), + /* K17 */ be_nested_str_weak(Hardware), + /* K18 */ be_nested_str_weak(version), + /* K19 */ be_nested_str_weak(MTR_X3A_X20update_X20_X27_X25s_X27_X20version_X3D_X27_X25s_X27), + /* K20 */ be_nested_str_weak(hardware), + /* K21 */ be_nested_str_weak(MTR_X3A_X20update_X20_X27_X25s_X27_X20hardware_X3D_X27_X25s_X27), + /* K22 */ be_nested_str_weak(UPDATE_CMD2), + /* K23 */ be_nested_str_weak(Mac), + /* K24 */ be_nested_str_weak(mac), + /* K25 */ be_nested_str_weak(MTR_X3A_X20update_X20_X27_X25s_X27_X20mac_X3D_X27_X25s_X27), + /* K26 */ be_nested_str_weak(UPDATE_CMD5), + /* K27 */ be_nested_str_weak(info_changed), + }), + be_str_weak(parse_update), + &be_const_str_solidified, + ( &(const binstruction[145]) { /* code */ + 0x500C0000, // 0000 LDBOOL R3 0 0 + 0x1C100500, // 0001 EQ R4 R2 K0 + 0x78120024, // 0002 JMPF R4 #0028 + 0x8C100301, // 0003 GETMET R4 R1 K1 + 0x58180002, // 0004 LDCONST R6 K2 + 0x7C100400, // 0005 CALL R4 2 + 0x1C140903, // 0006 EQ R5 R4 K3 + 0x78160000, // 0007 JMPF R5 #0009 + 0x4C100000, // 0008 LDNIL R4 + 0x88140104, // 0009 GETMBR R5 R0 K4 + 0x8C140B01, // 000A GETMET R5 R5 K1 + 0x581C0005, // 000B LDCONST R7 K5 + 0x7C140400, // 000C CALL R5 2 + 0x20140A04, // 000D NE R5 R5 R4 + 0x78160013, // 000E JMPF R5 #0023 + 0x4C140000, // 000F LDNIL R5 + 0x20140805, // 0010 NE R5 R4 R5 + 0x78160002, // 0011 JMPF R5 #0015 + 0x88140104, // 0012 GETMBR R5 R0 K4 + 0x98160A04, // 0013 SETIDX R5 K5 R4 + 0x70020003, // 0014 JMP #0019 + 0x88140104, // 0015 GETMBR R5 R0 K4 + 0x8C140B06, // 0016 GETMET R5 R5 K6 + 0x581C0005, // 0017 LDCONST R7 K5 + 0x7C140400, // 0018 CALL R5 2 + 0xB8160E00, // 0019 GETNGBL R5 K7 + 0x8C140B08, // 001A GETMET R5 R5 K8 + 0x601C0018, // 001B GETGBL R7 G24 + 0x58200009, // 001C LDCONST R8 K9 + 0x8824010A, // 001D GETMBR R9 R0 K10 + 0x5C280800, // 001E MOVE R10 R4 + 0x7C1C0600, // 001F CALL R7 3 + 0x5820000B, // 0020 LDCONST R8 K11 + 0x7C140600, // 0021 CALL R5 3 + 0x500C0200, // 0022 LDBOOL R3 1 0 + 0x8C14010C, // 0023 GETMET R5 R0 K12 + 0x881C010D, // 0024 GETMBR R7 R0 K13 + 0x8820010E, // 0025 GETMBR R8 R0 K14 + 0x7C140600, // 0026 CALL R5 3 + 0x70020064, // 0027 JMP #008D + 0x1C10050F, // 0028 EQ R4 R2 K15 + 0x7812003E, // 0029 JMPF R4 #0069 + 0x8C100301, // 002A GETMET R4 R1 K1 + 0x58180010, // 002B LDCONST R6 K16 + 0x7C100400, // 002C CALL R4 2 + 0x8C140301, // 002D GETMET R5 R1 K1 + 0x581C0011, // 002E LDCONST R7 K17 + 0x7C140400, // 002F CALL R5 2 + 0x88180104, // 0030 GETMBR R6 R0 K4 + 0x8C180D01, // 0031 GETMET R6 R6 K1 + 0x58200012, // 0032 LDCONST R8 K18 + 0x7C180400, // 0033 CALL R6 2 + 0x20180C04, // 0034 NE R6 R6 R4 + 0x781A0013, // 0035 JMPF R6 #004A + 0x4C180000, // 0036 LDNIL R6 + 0x20180806, // 0037 NE R6 R4 R6 + 0x781A0002, // 0038 JMPF R6 #003C + 0x88180104, // 0039 GETMBR R6 R0 K4 + 0x981A2404, // 003A SETIDX R6 K18 R4 + 0x70020003, // 003B JMP #0040 + 0x88180104, // 003C GETMBR R6 R0 K4 + 0x8C180D06, // 003D GETMET R6 R6 K6 + 0x58200012, // 003E LDCONST R8 K18 + 0x7C180400, // 003F CALL R6 2 + 0xB81A0E00, // 0040 GETNGBL R6 K7 + 0x8C180D08, // 0041 GETMET R6 R6 K8 + 0x60200018, // 0042 GETGBL R8 G24 + 0x58240013, // 0043 LDCONST R9 K19 + 0x8828010A, // 0044 GETMBR R10 R0 K10 + 0x5C2C0800, // 0045 MOVE R11 R4 + 0x7C200600, // 0046 CALL R8 3 + 0x5824000B, // 0047 LDCONST R9 K11 + 0x7C180600, // 0048 CALL R6 3 + 0x500C0200, // 0049 LDBOOL R3 1 0 + 0x88180104, // 004A GETMBR R6 R0 K4 + 0x8C180D01, // 004B GETMET R6 R6 K1 + 0x58200014, // 004C LDCONST R8 K20 + 0x7C180400, // 004D CALL R6 2 + 0x20180C05, // 004E NE R6 R6 R5 + 0x781A0013, // 004F JMPF R6 #0064 + 0x4C180000, // 0050 LDNIL R6 + 0x20180A06, // 0051 NE R6 R5 R6 + 0x781A0002, // 0052 JMPF R6 #0056 + 0x88180104, // 0053 GETMBR R6 R0 K4 + 0x981A2805, // 0054 SETIDX R6 K20 R5 + 0x70020003, // 0055 JMP #005A + 0x88180104, // 0056 GETMBR R6 R0 K4 + 0x8C180D06, // 0057 GETMET R6 R6 K6 + 0x58200014, // 0058 LDCONST R8 K20 + 0x7C180400, // 0059 CALL R6 2 + 0xB81A0E00, // 005A GETNGBL R6 K7 + 0x8C180D08, // 005B GETMET R6 R6 K8 + 0x60200018, // 005C GETGBL R8 G24 + 0x58240015, // 005D LDCONST R9 K21 + 0x8828010A, // 005E GETMBR R10 R0 K10 + 0x5C2C0A00, // 005F MOVE R11 R5 + 0x7C200600, // 0060 CALL R8 3 + 0x5824000B, // 0061 LDCONST R9 K11 + 0x7C180600, // 0062 CALL R6 3 + 0x500C0200, // 0063 LDBOOL R3 1 0 + 0x8C18010C, // 0064 GETMET R6 R0 K12 + 0x88200116, // 0065 GETMBR R8 R0 K22 + 0x8824010E, // 0066 GETMBR R9 R0 K14 + 0x7C180600, // 0067 CALL R6 3 + 0x70020023, // 0068 JMP #008D + 0x54120004, // 0069 LDINT R4 5 + 0x1C100404, // 006A EQ R4 R2 R4 + 0x78120020, // 006B JMPF R4 #008D + 0x8C100301, // 006C GETMET R4 R1 K1 + 0x58180017, // 006D LDCONST R6 K23 + 0x7C100400, // 006E CALL R4 2 + 0x88140104, // 006F GETMBR R5 R0 K4 + 0x8C140B01, // 0070 GETMET R5 R5 K1 + 0x581C0018, // 0071 LDCONST R7 K24 + 0x7C140400, // 0072 CALL R5 2 + 0x20140A04, // 0073 NE R5 R5 R4 + 0x78160013, // 0074 JMPF R5 #0089 + 0x4C140000, // 0075 LDNIL R5 + 0x20140805, // 0076 NE R5 R4 R5 + 0x78160002, // 0077 JMPF R5 #007B + 0x88140104, // 0078 GETMBR R5 R0 K4 + 0x98163004, // 0079 SETIDX R5 K24 R4 + 0x70020003, // 007A JMP #007F + 0x88140104, // 007B GETMBR R5 R0 K4 + 0x8C140B06, // 007C GETMET R5 R5 K6 + 0x581C0018, // 007D LDCONST R7 K24 + 0x7C140400, // 007E CALL R5 2 + 0xB8160E00, // 007F GETNGBL R5 K7 + 0x8C140B08, // 0080 GETMET R5 R5 K8 + 0x601C0018, // 0081 GETGBL R7 G24 + 0x58200019, // 0082 LDCONST R8 K25 + 0x8824010A, // 0083 GETMBR R9 R0 K10 + 0x5C280800, // 0084 MOVE R10 R4 + 0x7C1C0600, // 0085 CALL R7 3 + 0x5820000B, // 0086 LDCONST R8 K11 + 0x7C140600, // 0087 CALL R5 3 + 0x500C0200, // 0088 LDBOOL R3 1 0 + 0x8C14010C, // 0089 GETMET R5 R0 K12 + 0x881C011A, // 008A GETMBR R7 R0 K26 + 0x8820010E, // 008B GETMBR R8 R0 K14 + 0x7C140600, // 008C CALL R5 3 + 0x780E0001, // 008D JMPF R3 #0090 + 0x8C10011B, // 008E GETMET R4 R0 K27 + 0x7C100200, // 008F CALL R4 1 + 0x80000000, // 0090 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: call_sync +********************************************************************/ +be_local_closure(Matter_HTTP_remote_call_sync, /* name */ + be_nested_proto( + 16, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[24]) { /* constants */ + /* K0 */ be_nested_str_weak(string), + /* K1 */ be_nested_str_weak(webserver), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(wifi), + /* K4 */ be_nested_str_weak(up), + /* K5 */ be_nested_str_weak(eth), + /* K6 */ be_nested_str_weak(current_cmd), + /* K7 */ be_nested_str_weak(_X2Fcm_X3Fcmnd_X3D), + /* K8 */ be_nested_str_weak(tr), + /* K9 */ be_nested_str_weak(_X20), + /* K10 */ be_nested_str_weak(_X2B), + /* K11 */ be_nested_str_weak(log), + /* K12 */ be_nested_str_weak(MTR_X3A_X20HTTP_X20sync_X20request_X20_X27http_X3A_X2F_X2F_X25s_X3A_X25i_X25s_X27), + /* K13 */ be_nested_str_weak(addr), + /* K14 */ be_nested_str_weak(port), + /* K15 */ be_const_int(3), + /* K16 */ be_nested_str_weak(begin_sync), + /* K17 */ be_nested_str_weak(nil), + /* K18 */ be_const_int(0), + /* K19 */ be_nested_str_weak(_X2E_X2E_X2E), + /* K20 */ be_nested_str_weak(MTR_X3A_X20HTTP_X20sync_X2Dresp_X20_X20in_X20_X25i_X20ms_X20from_X20_X25s_X3A_X20_X5B_X25i_X5D_X20_X27_X25s_X27), + /* K21 */ be_nested_str_weak(millis), + /* K22 */ be_nested_str_weak(time_start), + /* K23 */ be_nested_str_weak(payload), + }), + be_str_weak(call_sync), + &be_const_str_solidified, + ( &(const binstruction[72]) { /* code */ + 0xA40E0000, // 0000 IMPORT R3 K0 + 0xA4120200, // 0001 IMPORT R4 K1 + 0xB8160400, // 0002 GETNGBL R5 K2 + 0x8C140B03, // 0003 GETMET R5 R5 K3 + 0x7C140200, // 0004 CALL R5 1 + 0x94140B04, // 0005 GETIDX R5 R5 K4 + 0x74160006, // 0006 JMPT R5 #000E + 0xB8160400, // 0007 GETNGBL R5 K2 + 0x8C140B05, // 0008 GETMET R5 R5 K5 + 0x7C140200, // 0009 CALL R5 1 + 0x94140B04, // 000A GETIDX R5 R5 K4 + 0x74160001, // 000B JMPT R5 #000E + 0x4C140000, // 000C LDNIL R5 + 0x80040A00, // 000D RET 1 R5 + 0x4C140000, // 000E LDNIL R5 + 0x90020C05, // 000F SETMBR R0 K6 R5 + 0x8C140708, // 0010 GETMET R5 R3 K8 + 0x5C1C0200, // 0011 MOVE R7 R1 + 0x58200009, // 0012 LDCONST R8 K9 + 0x5824000A, // 0013 LDCONST R9 K10 + 0x7C140800, // 0014 CALL R5 4 + 0x00160E05, // 0015 ADD R5 K7 R5 + 0xB81A0400, // 0016 GETNGBL R6 K2 + 0x8C180D0B, // 0017 GETMET R6 R6 K11 + 0x60200018, // 0018 GETGBL R8 G24 + 0x5824000C, // 0019 LDCONST R9 K12 + 0x8828010D, // 001A GETMBR R10 R0 K13 + 0x882C010E, // 001B GETMBR R11 R0 K14 + 0x5C300A00, // 001C MOVE R12 R5 + 0x7C200800, // 001D CALL R8 4 + 0x5824000F, // 001E LDCONST R9 K15 + 0x7C180600, // 001F CALL R6 3 + 0x60180003, // 0020 GETGBL R6 G3 + 0x5C1C0000, // 0021 MOVE R7 R0 + 0x7C180200, // 0022 CALL R6 1 + 0x8C180D10, // 0023 GETMET R6 R6 K16 + 0x5C200A00, // 0024 MOVE R8 R5 + 0x5C240400, // 0025 MOVE R9 R2 + 0x7C180600, // 0026 CALL R6 3 + 0x781A0001, // 0027 JMPF R6 #002A + 0x5C1C0C00, // 0028 MOVE R7 R6 + 0x70020000, // 0029 JMP #002B + 0x581C0011, // 002A LDCONST R7 K17 + 0x6020000C, // 002B GETGBL R8 G12 + 0x5C240E00, // 002C MOVE R9 R7 + 0x7C200200, // 002D CALL R8 1 + 0x5426001D, // 002E LDINT R9 30 + 0x24201009, // 002F GT R8 R8 R9 + 0x78220004, // 0030 JMPF R8 #0036 + 0x5422001C, // 0031 LDINT R8 29 + 0x40222408, // 0032 CONNECT R8 K18 R8 + 0x94200E08, // 0033 GETIDX R8 R7 R8 + 0x00201113, // 0034 ADD R8 R8 K19 + 0x5C1C1000, // 0035 MOVE R7 R8 + 0xB8220400, // 0036 GETNGBL R8 K2 + 0x8C20110B, // 0037 GETMET R8 R8 K11 + 0x60280018, // 0038 GETGBL R10 G24 + 0x582C0014, // 0039 LDCONST R11 K20 + 0xB8320400, // 003A GETNGBL R12 K2 + 0x8C301915, // 003B GETMET R12 R12 K21 + 0x7C300200, // 003C CALL R12 1 + 0x88340116, // 003D GETMBR R13 R0 K22 + 0x0430180D, // 003E SUB R12 R12 R13 + 0x8834010D, // 003F GETMBR R13 R0 K13 + 0x6038000C, // 0040 GETGBL R14 G12 + 0x883C0117, // 0041 GETMBR R15 R0 K23 + 0x7C380200, // 0042 CALL R14 1 + 0x5C3C0E00, // 0043 MOVE R15 R7 + 0x7C280A00, // 0044 CALL R10 5 + 0x582C000F, // 0045 LDCONST R11 K15 + 0x7C200600, // 0046 CALL R8 3 + 0x80040C00, // 0047 RET 1 R6 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_http_finished +********************************************************************/ +be_local_closure(Matter_HTTP_remote_event_http_finished, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(current_cmd), + /* K1 */ be_nested_str_weak(payload), + /* K2 */ be_nested_str_weak(nil), + /* K3 */ be_const_int(0), + /* K4 */ be_nested_str_weak(_X2E_X2E_X2E), + /* K5 */ be_nested_str_weak(tasmota), + /* K6 */ be_nested_str_weak(log), + /* K7 */ be_nested_str_weak(MTR_X3A_X20HTTP_X20async_X2Dresp_X20in_X20_X25i_X20ms_X20from_X20_X25s_X3A_X20_X5B_X25i_X5D_X20_X27_X25s_X27), + /* K8 */ be_nested_str_weak(millis), + /* K9 */ be_nested_str_weak(time_start), + /* K10 */ be_nested_str_weak(addr), + /* K11 */ be_const_int(3), + /* K12 */ be_nested_str_weak(dispatch_cb), + /* K13 */ be_nested_str_weak(http_status), + }), + be_str_weak(event_http_finished), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x78060000, // 0003 JMPF R1 #0005 + 0x80000200, // 0004 RET 0 + 0x88040101, // 0005 GETMBR R1 R0 K1 + 0x4C080000, // 0006 LDNIL R2 + 0x20040202, // 0007 NE R1 R1 R2 + 0x78060001, // 0008 JMPF R1 #000B + 0x88040101, // 0009 GETMBR R1 R0 K1 + 0x70020000, // 000A JMP #000C + 0x58040002, // 000B LDCONST R1 K2 + 0x6008000C, // 000C GETGBL R2 G12 + 0x5C0C0200, // 000D MOVE R3 R1 + 0x7C080200, // 000E CALL R2 1 + 0x540E001D, // 000F LDINT R3 30 + 0x24080403, // 0010 GT R2 R2 R3 + 0x780A0004, // 0011 JMPF R2 #0017 + 0x540A001C, // 0012 LDINT R2 29 + 0x400A0602, // 0013 CONNECT R2 K3 R2 + 0x94080202, // 0014 GETIDX R2 R1 R2 + 0x00080504, // 0015 ADD R2 R2 K4 + 0x5C040400, // 0016 MOVE R1 R2 + 0xB80A0A00, // 0017 GETNGBL R2 K5 + 0x8C080506, // 0018 GETMET R2 R2 K6 + 0x60100018, // 0019 GETGBL R4 G24 + 0x58140007, // 001A LDCONST R5 K7 + 0xB81A0A00, // 001B GETNGBL R6 K5 + 0x8C180D08, // 001C GETMET R6 R6 K8 + 0x7C180200, // 001D CALL R6 1 + 0x881C0109, // 001E GETMBR R7 R0 K9 + 0x04180C07, // 001F SUB R6 R6 R7 + 0x881C010A, // 0020 GETMBR R7 R0 K10 + 0x6020000C, // 0021 GETGBL R8 G12 + 0x88240101, // 0022 GETMBR R9 R0 K1 + 0x7C200200, // 0023 CALL R8 1 + 0x5C240200, // 0024 MOVE R9 R1 + 0x7C100A00, // 0025 CALL R4 5 + 0x5814000B, // 0026 LDCONST R5 K11 + 0x7C080600, // 0027 CALL R2 3 + 0x8C08010C, // 0028 GETMET R2 R0 K12 + 0x8810010D, // 0029 GETMBR R4 R0 K13 + 0x88140101, // 002A GETMBR R5 R0 K1 + 0x7C080600, // 002B CALL R2 3 + 0x80000000, // 002C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_last_seen +********************************************************************/ +be_local_closure(Matter_HTTP_remote_web_last_seen, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(reachable_utc), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(rtc_utc), + /* K4 */ be_nested_str_weak(matter), + /* K5 */ be_nested_str_weak(seconds_to_dhm), + }), + be_str_weak(web_last_seen), + &be_const_str_solidified, + ( &(const binstruction[17]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x5409FFFE, // 0001 LDINT R2 -1 + 0x880C0101, // 0002 GETMBR R3 R0 K1 + 0x4C100000, // 0003 LDNIL R4 + 0x200C0604, // 0004 NE R3 R3 R4 + 0x780E0005, // 0005 JMPF R3 #000C + 0xB80E0400, // 0006 GETNGBL R3 K2 + 0x8C0C0703, // 0007 GETMET R3 R3 K3 + 0x7C0C0200, // 0008 CALL R3 1 + 0x88100101, // 0009 GETMBR R4 R0 K1 + 0x040C0604, // 000A SUB R3 R3 R4 + 0x5C080600, // 000B MOVE R2 R3 + 0xB80E0800, // 000C GETNGBL R3 K4 + 0x8C0C0705, // 000D GETMET R3 R3 K5 + 0x5C140400, // 000E MOVE R5 R2 + 0x7C0C0400, // 000F CALL R3 2 + 0x80040600, // 0010 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_http_failed +********************************************************************/ +be_local_closure(Matter_HTTP_remote_event_http_failed, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(current_cmd), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(log), + /* K3 */ be_nested_str_weak(MTR_X3A_X20HTTP_X20failed), + /* K4 */ be_const_int(3), + /* K5 */ be_nested_str_weak(dispatch_cb), + /* K6 */ be_nested_str_weak(http_status), + }), + be_str_weak(event_http_failed), + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x78060000, // 0003 JMPF R1 #0005 + 0x80000200, // 0004 RET 0 + 0xB8060200, // 0005 GETNGBL R1 K1 + 0x8C040302, // 0006 GETMET R1 R1 K2 + 0x580C0003, // 0007 LDCONST R3 K3 + 0x58100004, // 0008 LDCONST R4 K4 + 0x7C040600, // 0009 CALL R1 3 + 0x8C040105, // 000A GETMET R1 R0 K5 + 0x880C0106, // 000B GETMBR R3 R0 K6 + 0x4C100000, // 000C LDNIL R4 + 0x7C040600, // 000D CALL R1 3 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_status_response +********************************************************************/ +be_local_closure(Matter_HTTP_remote_parse_status_response, /* name */ + be_nested_proto( + 11, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(device_is_alive), + /* K2 */ be_nested_str_weak(json), + /* K3 */ be_nested_str_weak(load), + /* K4 */ be_nested_str_weak(contains), + /* K5 */ be_nested_str_weak(Status), + /* K6 */ be_nested_str_weak(StatusFWR), + /* K7 */ be_const_int(2), + /* K8 */ be_nested_str_weak(StatusNET), + /* K9 */ be_nested_str_weak(parse_update), + }), + be_str_weak(parse_status_response), + &be_const_str_solidified, + ( &(const binstruction[39]) { /* code */ + 0x4C100000, // 0000 LDNIL R4 + 0x20100204, // 0001 NE R4 R1 R4 + 0x78120022, // 0002 JMPF R4 #0026 + 0x24100300, // 0003 GT R4 R1 K0 + 0x78120020, // 0004 JMPF R4 #0026 + 0x8C100101, // 0005 GETMET R4 R0 K1 + 0x50180200, // 0006 LDBOOL R6 1 0 + 0x7C100400, // 0007 CALL R4 2 + 0xA4120400, // 0008 IMPORT R4 K2 + 0x8C140903, // 0009 GETMET R5 R4 K3 + 0x5C1C0400, // 000A MOVE R7 R2 + 0x7C140400, // 000B CALL R5 2 + 0x4C180000, // 000C LDNIL R6 + 0x78160017, // 000D JMPF R5 #0026 + 0x8C1C0B04, // 000E GETMET R7 R5 K4 + 0x58240005, // 000F LDCONST R9 K5 + 0x7C1C0400, // 0010 CALL R7 2 + 0x781E0002, // 0011 JMPF R7 #0015 + 0x94140B05, // 0012 GETIDX R5 R5 K5 + 0x58180000, // 0013 LDCONST R6 K0 + 0x7002000C, // 0014 JMP #0022 + 0x8C1C0B04, // 0015 GETMET R7 R5 K4 + 0x58240006, // 0016 LDCONST R9 K6 + 0x7C1C0400, // 0017 CALL R7 2 + 0x781E0002, // 0018 JMPF R7 #001C + 0x94140B06, // 0019 GETIDX R5 R5 K6 + 0x58180007, // 001A LDCONST R6 K7 + 0x70020005, // 001B JMP #0022 + 0x8C1C0B04, // 001C GETMET R7 R5 K4 + 0x58240008, // 001D LDCONST R9 K8 + 0x7C1C0400, // 001E CALL R7 2 + 0x781E0001, // 001F JMPF R7 #0022 + 0x94140B08, // 0020 GETIDX R5 R5 K8 + 0x541A0004, // 0021 LDINT R6 5 + 0x8C1C0109, // 0022 GETMET R7 R0 K9 + 0x5C240A00, // 0023 MOVE R9 R5 + 0x5C280C00, // 0024 MOVE R10 R6 + 0x7C1C0600, // 0025 CALL R7 3 + 0x80000000, // 0026 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_info +********************************************************************/ +be_local_closure(Matter_HTTP_remote_get_info, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(info), + }), + be_str_weak(get_info), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_http_timeout +********************************************************************/ +be_local_closure(Matter_HTTP_remote_event_http_timeout, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str_weak(current_cmd), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(log), + /* K3 */ be_nested_str_weak(MTR_X3A_X20HTTP_X20timeout_X20http_status_X3D_X25i_X20phase_X3D_X25i_X20tcp_status_X3D_X25i_X20size_payload_X3D_X25i), + /* K4 */ be_nested_str_weak(http_status), + /* K5 */ be_nested_str_weak(phase), + /* K6 */ be_nested_str_weak(status), + /* K7 */ be_nested_str_weak(payload), + /* K8 */ be_const_int(3), + /* K9 */ be_nested_str_weak(dispatch_cb), + }), + be_str_weak(event_http_timeout), + &be_const_str_solidified, + ( &(const binstruction[23]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x78060000, // 0003 JMPF R1 #0005 + 0x80000200, // 0004 RET 0 + 0xB8060200, // 0005 GETNGBL R1 K1 + 0x8C040302, // 0006 GETMET R1 R1 K2 + 0x600C0018, // 0007 GETGBL R3 G24 + 0x58100003, // 0008 LDCONST R4 K3 + 0x88140104, // 0009 GETMBR R5 R0 K4 + 0x88180105, // 000A GETMBR R6 R0 K5 + 0x881C0106, // 000B GETMBR R7 R0 K6 + 0x6020000C, // 000C GETGBL R8 G12 + 0x88240107, // 000D GETMBR R9 R0 K7 + 0x7C200200, // 000E CALL R8 1 + 0x7C0C0A00, // 000F CALL R3 5 + 0x58100008, // 0010 LDCONST R4 K8 + 0x7C040600, // 0011 CALL R1 3 + 0x8C040109, // 0012 GETMET R1 R0 K9 + 0x880C0104, // 0013 GETMBR R3 R0 K4 + 0x4C100000, // 0014 LDNIL R4 + 0x7C040600, // 0015 CALL R1 3 + 0x80000000, // 0016 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: info_changed +********************************************************************/ +be_local_closure(Matter_HTTP_remote_info_changed, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(device), + /* K1 */ be_nested_str_weak(save_param), + }), + be_str_weak(info_changed), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80000000, // 0003 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: scheduler +********************************************************************/ +be_local_closure(Matter_HTTP_remote_scheduler, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str_weak(probe_next_timestamp_map), + /* K1 */ be_nested_str_weak(keys), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(stop_iteration), + /* K4 */ be_nested_str_weak(tasmota), + /* K5 */ be_nested_str_weak(time_reached), + /* K6 */ be_nested_str_weak(tcp_connected), + /* K7 */ be_nested_str_weak(millis), + /* K8 */ be_nested_str_weak(probe_update_time_map), + /* K9 */ be_nested_str_weak(probe_async), + }), + be_str_weak(scheduler), + &be_const_str_solidified, + ( &(const binstruction[66]) { /* code */ + 0x4C040000, // 0000 LDNIL R1 + 0x60080010, // 0001 GETGBL R2 G16 + 0x880C0100, // 0002 GETMBR R3 R0 K0 + 0x8C0C0701, // 0003 GETMET R3 R3 K1 + 0x7C0C0200, // 0004 CALL R3 1 + 0x7C080200, // 0005 CALL R2 1 + 0xA802000A, // 0006 EXBLK 0 #0012 + 0x5C0C0400, // 0007 MOVE R3 R2 + 0x7C0C0000, // 0008 CALL R3 0 + 0x88100100, // 0009 GETMBR R4 R0 K0 + 0x94100803, // 000A GETIDX R4 R4 R3 + 0x1C100902, // 000B EQ R4 R4 K2 + 0x78120001, // 000C JMPF R4 #000F + 0x5C040600, // 000D MOVE R1 R3 + 0x70020000, // 000E JMP #0010 + 0x7001FFF6, // 000F JMP #0007 + 0xA8040001, // 0010 EXBLK 1 1 + 0x70020002, // 0011 JMP #0015 + 0x58080003, // 0012 LDCONST R2 K3 + 0xAC080200, // 0013 CATCH R2 1 0 + 0xB0080000, // 0014 RAISE 2 R0 R0 + 0x4C080000, // 0015 LDNIL R2 + 0x1C080202, // 0016 EQ R2 R1 R2 + 0x780A0015, // 0017 JMPF R2 #002E + 0x60080010, // 0018 GETGBL R2 G16 + 0x880C0100, // 0019 GETMBR R3 R0 K0 + 0x8C0C0701, // 001A GETMET R3 R3 K1 + 0x7C0C0200, // 001B CALL R3 1 + 0x7C080200, // 001C CALL R2 1 + 0xA802000C, // 001D EXBLK 0 #002B + 0x5C0C0400, // 001E MOVE R3 R2 + 0x7C0C0000, // 001F CALL R3 0 + 0xB8120800, // 0020 GETNGBL R4 K4 + 0x8C100905, // 0021 GETMET R4 R4 K5 + 0x88180100, // 0022 GETMBR R6 R0 K0 + 0x94180C03, // 0023 GETIDX R6 R6 R3 + 0x7C100400, // 0024 CALL R4 2 + 0x78120001, // 0025 JMPF R4 #0028 + 0x5C040600, // 0026 MOVE R1 R3 + 0x70020000, // 0027 JMP #0029 + 0x7001FFF4, // 0028 JMP #001E + 0xA8040001, // 0029 EXBLK 1 1 + 0x70020002, // 002A JMP #002E + 0x58080003, // 002B LDCONST R2 K3 + 0xAC080200, // 002C CATCH R2 1 0 + 0xB0080000, // 002D RAISE 2 R0 R0 + 0x4C080000, // 002E LDNIL R2 + 0x1C080202, // 002F EQ R2 R1 R2 + 0x780A0000, // 0030 JMPF R2 #0032 + 0x80000400, // 0031 RET 0 + 0x88080106, // 0032 GETMBR R2 R0 K6 + 0x780A0002, // 0033 JMPF R2 #0037 + 0x88080100, // 0034 GETMBR R2 R0 K0 + 0x98080302, // 0035 SETIDX R2 R1 K2 + 0x80000400, // 0036 RET 0 + 0x88080100, // 0037 GETMBR R2 R0 K0 + 0xB80E0800, // 0038 GETNGBL R3 K4 + 0x8C0C0707, // 0039 GETMET R3 R3 K7 + 0x88140108, // 003A GETMBR R5 R0 K8 + 0x94140A01, // 003B GETIDX R5 R5 R1 + 0x7C0C0400, // 003C CALL R3 2 + 0x98080203, // 003D SETIDX R2 R1 R3 + 0x8C080109, // 003E GETMET R2 R0 K9 + 0x5C100200, // 003F MOVE R4 R1 + 0x7C080400, // 0040 CALL R2 2 + 0x80000000, // 0041 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: add_schedule +********************************************************************/ +be_local_closure(Matter_HTTP_remote_add_schedule, /* name */ + be_nested_proto( + 8, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(probe_update_time_map), + /* K1 */ be_nested_str_weak(contains), + /* K2 */ be_nested_str_weak(probe_next_timestamp_map), + /* K3 */ be_nested_str_weak(matter), + /* K4 */ be_nested_str_weak(jitter), + /* K5 */ be_nested_str_weak(add_async_cb), + }), + be_str_weak(add_schedule), + &be_const_str_solidified, + ( &(const binstruction[25]) { /* code */ + 0x88100100, // 0000 GETMBR R4 R0 K0 + 0x8C100901, // 0001 GETMET R4 R4 K1 + 0x5C180200, // 0002 MOVE R6 R1 + 0x7C100400, // 0003 CALL R4 2 + 0x78120003, // 0004 JMPF R4 #0009 + 0x88100100, // 0005 GETMBR R4 R0 K0 + 0x94100801, // 0006 GETIDX R4 R4 R1 + 0x14100404, // 0007 LT R4 R2 R4 + 0x78120007, // 0008 JMPF R4 #0011 + 0x88100100, // 0009 GETMBR R4 R0 K0 + 0x98100202, // 000A SETIDX R4 R1 R2 + 0x88100102, // 000B GETMBR R4 R0 K2 + 0xB8160600, // 000C GETNGBL R5 K3 + 0x8C140B04, // 000D GETMET R5 R5 K4 + 0x5C1C0400, // 000E MOVE R7 R2 + 0x7C140400, // 000F CALL R5 2 + 0x98100205, // 0010 SETIDX R4 R1 R5 + 0x4C100000, // 0011 LDNIL R4 + 0x20100604, // 0012 NE R4 R3 R4 + 0x78120003, // 0013 JMPF R4 #0018 + 0x8C100105, // 0014 GETMET R4 R0 K5 + 0x5C180600, // 0015 MOVE R6 R3 + 0x5C1C0200, // 0016 MOVE R7 R1 + 0x7C100600, // 0017 CALL R4 3 + 0x80000000, // 0018 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: probe_async +********************************************************************/ +be_local_closure(Matter_HTTP_remote_probe_async, /* name */ + be_nested_proto( + 12, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[17]) { /* constants */ + /* K0 */ be_nested_str_weak(string), + /* K1 */ be_nested_str_weak(webserver), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(wifi), + /* K4 */ be_nested_str_weak(up), + /* K5 */ be_nested_str_weak(eth), + /* K6 */ be_nested_str_weak(current_cmd), + /* K7 */ be_nested_str_weak(_X2Fcm_X3Fcmnd_X3D), + /* K8 */ be_nested_str_weak(tr), + /* K9 */ be_nested_str_weak(_X20), + /* K10 */ be_nested_str_weak(_X2B), + /* K11 */ be_nested_str_weak(log), + /* K12 */ be_nested_str_weak(MTR_X3A_X20HTTP_X20async_X20request_X20_X27http_X3A_X2F_X2F_X25s_X3A_X25i_X25s_X27), + /* K13 */ be_nested_str_weak(addr), + /* K14 */ be_nested_str_weak(port), + /* K15 */ be_const_int(3), + /* K16 */ be_nested_str_weak(begin), + }), + be_str_weak(probe_async), + &be_const_str_solidified, + ( &(const binstruction[35]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0xA40E0200, // 0001 IMPORT R3 K1 + 0xB8120400, // 0002 GETNGBL R4 K2 + 0x8C100903, // 0003 GETMET R4 R4 K3 + 0x7C100200, // 0004 CALL R4 1 + 0x94100904, // 0005 GETIDX R4 R4 K4 + 0x74120006, // 0006 JMPT R4 #000E + 0xB8120400, // 0007 GETNGBL R4 K2 + 0x8C100905, // 0008 GETMET R4 R4 K5 + 0x7C100200, // 0009 CALL R4 1 + 0x94100904, // 000A GETIDX R4 R4 K4 + 0x74120001, // 000B JMPT R4 #000E + 0x4C100000, // 000C LDNIL R4 + 0x80040800, // 000D RET 1 R4 + 0x90020C01, // 000E SETMBR R0 K6 R1 + 0x8C100508, // 000F GETMET R4 R2 K8 + 0x5C180200, // 0010 MOVE R6 R1 + 0x581C0009, // 0011 LDCONST R7 K9 + 0x5820000A, // 0012 LDCONST R8 K10 + 0x7C100800, // 0013 CALL R4 4 + 0x00120E04, // 0014 ADD R4 K7 R4 + 0xB8160400, // 0015 GETNGBL R5 K2 + 0x8C140B0B, // 0016 GETMET R5 R5 K11 + 0x601C0018, // 0017 GETGBL R7 G24 + 0x5820000C, // 0018 LDCONST R8 K12 + 0x8824010D, // 0019 GETMBR R9 R0 K13 + 0x8828010E, // 001A GETMBR R10 R0 K14 + 0x5C2C0800, // 001B MOVE R11 R4 + 0x7C1C0800, // 001C CALL R7 4 + 0x5820000F, // 001D LDCONST R8 K15 + 0x7C140600, // 001E CALL R5 3 + 0x8C140110, // 001F GETMET R5 R0 K16 + 0x5C1C0800, // 0020 MOVE R7 R4 + 0x7C140400, // 0021 CALL R5 2 + 0x80000000, // 0022 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: add_async_cb +********************************************************************/ +be_local_closure(Matter_HTTP_remote_add_async_cb, /* name */ + be_nested_proto( + 4, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(async_cb_map), + }), + be_str_weak(add_async_cb), + &be_const_str_solidified, + ( &(const binstruction[ 3]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x980C0202, // 0001 SETIDX R3 R1 R2 + 0x80000000, // 0002 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_info +********************************************************************/ +be_local_closure(Matter_HTTP_remote_set_info, /* name */ + be_nested_proto( + 2, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(info), + }), + be_str_weak(set_info), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x80000000, // 0001 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: dispatch_cb +********************************************************************/ +be_local_closure(Matter_HTTP_remote_dispatch_cb, /* name */ + be_nested_proto( + 11, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(async_cb_map), + /* K2 */ be_nested_str_weak(keys), + /* K3 */ be_nested_str_weak(current_cmd), + /* K4 */ be_nested_str_weak(stop_iteration), + }), + be_str_weak(dispatch_cb), + &be_const_str_solidified, + ( &(const binstruction[27]) { /* code */ + 0x580C0000, // 0000 LDCONST R3 K0 + 0x60100010, // 0001 GETGBL R4 G16 + 0x88140101, // 0002 GETMBR R5 R0 K1 + 0x8C140B02, // 0003 GETMET R5 R5 K2 + 0x7C140200, // 0004 CALL R5 1 + 0x7C100200, // 0005 CALL R4 1 + 0xA802000F, // 0006 EXBLK 0 #0017 + 0x5C140800, // 0007 MOVE R5 R4 + 0x7C140000, // 0008 CALL R5 0 + 0x88180101, // 0009 GETMBR R6 R0 K1 + 0x94180C05, // 000A GETIDX R6 R6 R5 + 0x881C0103, // 000B GETMBR R7 R0 K3 + 0x1C1C0C07, // 000C EQ R7 R6 R7 + 0x741E0002, // 000D JMPT R7 #0011 + 0x4C1C0000, // 000E LDNIL R7 + 0x1C1C0C07, // 000F EQ R7 R6 R7 + 0x781E0004, // 0010 JMPF R7 #0016 + 0x5C1C0A00, // 0011 MOVE R7 R5 + 0x5C200200, // 0012 MOVE R8 R1 + 0x5C240400, // 0013 MOVE R9 R2 + 0x88280103, // 0014 GETMBR R10 R0 K3 + 0x7C1C0600, // 0015 CALL R7 3 + 0x7001FFEF, // 0016 JMP #0007 + 0x58100004, // 0017 LDCONST R4 K4 + 0xAC100200, // 0018 CATCH R4 1 0 + 0xB0080000, // 0019 RAISE 2 R0 R0 + 0x80000000, // 001A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: change_schedule +********************************************************************/ +be_local_closure(Matter_HTTP_remote_change_schedule, /* name */ + be_nested_proto( + 7, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(probe_update_time_map), + /* K1 */ be_nested_str_weak(contains), + /* K2 */ be_nested_str_weak(probe_next_timestamp_map), + /* K3 */ be_nested_str_weak(matter), + /* K4 */ be_nested_str_weak(jitter), + }), + be_str_weak(change_schedule), + &be_const_str_solidified, + ( &(const binstruction[14]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x780E0007, // 0004 JMPF R3 #000D + 0x880C0100, // 0005 GETMBR R3 R0 K0 + 0x980C0202, // 0006 SETIDX R3 R1 R2 + 0x880C0102, // 0007 GETMBR R3 R0 K2 + 0xB8120600, // 0008 GETNGBL R4 K3 + 0x8C100904, // 0009 GETMET R4 R4 K4 + 0x5C180400, // 000A MOVE R6 R2 + 0x7C100400, // 000B CALL R4 2 + 0x980C0204, // 000C SETIDX R3 R1 R4 + 0x80000000, // 000D RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_HTTP_remote_init, /* name */ + be_nested_proto( + 11, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 3]) { + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(parse_status_response), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x680C0000, // 0000 GETUPV R3 U0 + 0x8C0C0700, // 0001 GETMET R3 R3 K0 + 0x5C140000, // 0002 MOVE R5 R0 + 0x5C180200, // 0003 MOVE R6 R1 + 0x5C1C0400, // 0004 MOVE R7 R2 + 0x7C0C0800, // 0005 CALL R3 4 + 0x80040600, // 0006 RET 1 R3 + }) + ), + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(parse_status_response), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x680C0000, // 0000 GETUPV R3 U0 + 0x8C0C0700, // 0001 GETMET R3 R3 K0 + 0x5C140000, // 0002 MOVE R5 R0 + 0x5C180200, // 0003 MOVE R6 R1 + 0x5C1C0400, // 0004 MOVE R7 R2 + 0x7C0C0800, // 0005 CALL R3 4 + 0x80040600, // 0006 RET 1 R3 + }) + ), + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(parse_status_response), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x680C0000, // 0000 GETUPV R3 U0 + 0x8C0C0700, // 0001 GETMET R3 R3 K0 + 0x5C140000, // 0002 MOVE R5 R0 + 0x5C180200, // 0003 MOVE R6 R1 + 0x5C1C0400, // 0004 MOVE R7 R2 + 0x7C0C0800, // 0005 CALL R3 4 + 0x80040600, // 0006 RET 1 R3 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(device), + /* K1 */ be_nested_str_weak(probe_update_time_map), + /* K2 */ be_nested_str_weak(probe_next_timestamp_map), + /* K3 */ be_nested_str_weak(async_cb_map), + /* K4 */ be_nested_str_weak(current_cmd), + /* K5 */ be_nested_str_weak(reachable), + /* K6 */ be_nested_str_weak(init), + /* K7 */ be_nested_str_weak(info), + /* K8 */ be_nested_str_weak(add_schedule), + /* K9 */ be_nested_str_weak(UPDATE_CMD0), + /* K10 */ be_nested_str_weak(UPDATE_TIME), + /* K11 */ be_nested_str_weak(UPDATE_CMD2), + /* K12 */ be_nested_str_weak(UPDATE_CMD5), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x60140013, // 0001 GETGBL R5 G19 + 0x7C140000, // 0002 CALL R5 0 + 0x90020205, // 0003 SETMBR R0 K1 R5 + 0x60140013, // 0004 GETGBL R5 G19 + 0x7C140000, // 0005 CALL R5 0 + 0x90020405, // 0006 SETMBR R0 K2 R5 + 0x60140013, // 0007 GETGBL R5 G19 + 0x7C140000, // 0008 CALL R5 0 + 0x90020605, // 0009 SETMBR R0 K3 R5 + 0x4C140000, // 000A LDNIL R5 + 0x90020805, // 000B SETMBR R0 K4 R5 + 0x50140000, // 000C LDBOOL R5 0 0 + 0x90020A05, // 000D SETMBR R0 K5 R5 + 0x60140003, // 000E GETGBL R5 G3 + 0x5C180000, // 000F MOVE R6 R0 + 0x7C140200, // 0010 CALL R5 1 + 0x8C140B06, // 0011 GETMET R5 R5 K6 + 0x5C1C0400, // 0012 MOVE R7 R2 + 0x5422004F, // 0013 LDINT R8 80 + 0x5C240600, // 0014 MOVE R9 R3 + 0x5C280800, // 0015 MOVE R10 R4 + 0x7C140A00, // 0016 CALL R5 5 + 0x60140013, // 0017 GETGBL R5 G19 + 0x7C140000, // 0018 CALL R5 0 + 0x90020E05, // 0019 SETMBR R0 K7 R5 + 0x88140100, // 001A GETMBR R5 R0 K0 + 0x7816000E, // 001B JMPF R5 #002B + 0x8C140108, // 001C GETMET R5 R0 K8 + 0x881C0109, // 001D GETMBR R7 R0 K9 + 0x8820010A, // 001E GETMBR R8 R0 K10 + 0x84240000, // 001F CLOSURE R9 P0 + 0x7C140800, // 0020 CALL R5 4 + 0x8C140108, // 0021 GETMET R5 R0 K8 + 0x881C010B, // 0022 GETMBR R7 R0 K11 + 0x8820010A, // 0023 GETMBR R8 R0 K10 + 0x84240001, // 0024 CLOSURE R9 P1 + 0x7C140800, // 0025 CALL R5 4 + 0x8C140108, // 0026 GETMET R5 R0 K8 + 0x881C010C, // 0027 GETMBR R7 R0 K12 + 0x8820010A, // 0028 GETMBR R8 R0 K10 + 0x84240002, // 0029 CLOSURE R9 P2 + 0x7C140800, // 002A CALL R5 4 + 0xA0000000, // 002B CLOSE R0 + 0x80000000, // 002C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_HTTP_remote +********************************************************************/ +extern const bclass be_class_Matter_HTTP_async; +be_local_class(Matter_HTTP_remote, + 8, + &be_class_Matter_HTTP_async, + be_nested_map(31, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(device_is_alive, -1), be_const_closure(Matter_HTTP_remote_device_is_alive_closure) }, + { be_const_key_weak(reachable, 21), be_const_var(5) }, + { be_const_key_weak(parse_update, -1), be_const_closure(Matter_HTTP_remote_parse_update_closure) }, + { be_const_key_weak(UPDATE_TIME, 7), be_const_int(5000) }, + { be_const_key_weak(web_last_seen, 30), be_const_closure(Matter_HTTP_remote_web_last_seen_closure) }, + { be_const_key_weak(call_sync, 4), be_const_closure(Matter_HTTP_remote_call_sync_closure) }, + { be_const_key_weak(change_schedule, 19), be_const_closure(Matter_HTTP_remote_change_schedule_closure) }, + { be_const_key_weak(device, -1), be_const_var(0) }, + { be_const_key_weak(UPDATE_CMD5, -1), be_nested_str_weak(Status_X205) }, + { be_const_key_weak(get_info, 17), be_const_closure(Matter_HTTP_remote_get_info_closure) }, + { be_const_key_weak(info, -1), be_const_var(7) }, + { be_const_key_weak(event_http_timeout, -1), be_const_closure(Matter_HTTP_remote_event_http_timeout_closure) }, + { be_const_key_weak(info_changed, -1), be_const_closure(Matter_HTTP_remote_info_changed_closure) }, + { be_const_key_weak(add_schedule, -1), be_const_closure(Matter_HTTP_remote_add_schedule_closure) }, + { be_const_key_weak(UPDATE_TIME2, -1), be_const_int(300000) }, + { be_const_key_weak(scheduler, -1), be_const_closure(Matter_HTTP_remote_scheduler_closure) }, + { be_const_key_weak(parse_status_response, 13), be_const_closure(Matter_HTTP_remote_parse_status_response_closure) }, + { be_const_key_weak(probe_async, 18), be_const_closure(Matter_HTTP_remote_probe_async_closure) }, + { be_const_key_weak(probe_update_time_map, -1), be_const_var(1) }, + { be_const_key_weak(reachable_utc, -1), be_const_var(6) }, + { be_const_key_weak(probe_next_timestamp_map, -1), be_const_var(2) }, + { be_const_key_weak(async_cb_map, -1), be_const_var(3) }, + { be_const_key_weak(current_cmd, -1), be_const_var(4) }, + { be_const_key_weak(set_info, -1), be_const_closure(Matter_HTTP_remote_set_info_closure) }, + { be_const_key_weak(dispatch_cb, -1), be_const_closure(Matter_HTTP_remote_dispatch_cb_closure) }, + { be_const_key_weak(UPDATE_CMD2, -1), be_nested_str_weak(Status_X202) }, + { be_const_key_weak(UPDATE_CMD0, -1), be_nested_str_weak(Status) }, + { be_const_key_weak(event_http_failed, 3), be_const_closure(Matter_HTTP_remote_event_http_failed_closure) }, + { be_const_key_weak(add_async_cb, 6), be_const_closure(Matter_HTTP_remote_add_async_cb_closure) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_HTTP_remote_init_closure) }, + { be_const_key_weak(event_http_finished, -1), be_const_closure(Matter_HTTP_remote_event_http_finished_closure) }, + })), + be_str_weak(Matter_HTTP_remote) +); +/*******************************************************************/ + +void be_load_Matter_HTTP_remote_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_HTTP_remote); + be_setglobal(vm, "Matter_HTTP_remote"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM.h index df537be23cdb..54294c9d1144 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM.h @@ -7,55 +7,1189 @@ extern const bclass be_class_Matter_IM; /******************************************************************** -** Solidified function: expire_sendqueue +** Solidified function: every_250ms +********************************************************************/ +be_local_closure(Matter_IM_every_250ms, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(subs_shop), + /* K1 */ be_nested_str_weak(every_250ms), + }), + be_str_weak(every_250ms), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80000000, // 0003 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: process_incoming_ack +********************************************************************/ +be_local_closure(Matter_IM_process_incoming_ack, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(find_sendqueue_by_exchangeid), + /* K1 */ be_nested_str_weak(exchange_id), + /* K2 */ be_nested_str_weak(ack_received), + }), + be_str_weak(process_incoming_ack), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x88100301, // 0001 GETMBR R4 R1 K1 + 0x7C080400, // 0002 CALL R2 2 + 0x780A0003, // 0003 JMPF R2 #0008 + 0x8C0C0502, // 0004 GETMET R3 R2 K2 + 0x5C140200, // 0005 MOVE R5 R1 + 0x7C0C0400, // 0006 CALL R3 2 + 0x80040600, // 0007 RET 1 R3 + 0x500C0000, // 0008 LDBOOL R3 0 0 + 0x80040600, // 0009 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: subscribe_response +********************************************************************/ +be_local_closure(Matter_IM_subscribe_response, /* name */ + be_nested_proto( + 6, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(SubscribeResponseMessage), + /* K2 */ be_nested_str_weak(from_TLV), + }), + be_str_weak(subscribe_response), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0xB80E0000, // 0000 GETNGBL R3 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x7C0C0200, // 0002 CALL R3 1 + 0x8C0C0702, // 0003 GETMET R3 R3 K2 + 0x5C140400, // 0004 MOVE R5 R2 + 0x7C0C0400, // 0005 CALL R3 2 + 0x50100000, // 0006 LDBOOL R4 0 0 + 0x80040800, // 0007 RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: process_write_response +********************************************************************/ +be_local_closure(Matter_IM_process_write_response, /* name */ + be_nested_proto( + 6, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(WriteResponseMessage), + /* K2 */ be_nested_str_weak(from_TLV), + }), + be_str_weak(process_write_response), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0xB80E0000, // 0000 GETNGBL R3 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x7C0C0200, // 0002 CALL R3 1 + 0x8C0C0702, // 0003 GETMET R3 R3 K2 + 0x5C140400, // 0004 MOVE R5 R2 + 0x7C0C0400, // 0005 CALL R3 2 + 0x50100000, // 0006 LDBOOL R4 0 0 + 0x80040800, // 0007 RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: process_status_response +********************************************************************/ +be_local_closure(Matter_IM_process_status_response, /* name */ + be_nested_proto( + 11, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[16]) { /* constants */ + /* K0 */ be_nested_str_weak(findsubval), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(find_sendqueue_by_exchangeid), + /* K3 */ be_nested_str_weak(exchange_id), + /* K4 */ be_nested_str_weak(matter), + /* K5 */ be_nested_str_weak(SUCCESS), + /* K6 */ be_nested_str_weak(status_ok_received), + /* K7 */ be_nested_str_weak(tasmota), + /* K8 */ be_nested_str_weak(log), + /* K9 */ be_nested_str_weak(MTR_X3A_X20_X3EOK_X20_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20exch_X3D_X25i_X20not_X20found), + /* K10 */ be_nested_str_weak(session), + /* K11 */ be_nested_str_weak(local_session_id), + /* K12 */ be_nested_str_weak(MTR_X3A_X20_X3EStatus_X20_X20_X20_X20ERROR_X20_X3D_X200x_X2502X), + /* K13 */ be_const_int(3), + /* K14 */ be_nested_str_weak(status_error_received), + /* K15 */ be_nested_str_weak(remove_sendqueue_by_exchangeid), + }), + be_str_weak(process_status_response), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0x8C0C0500, // 0000 GETMET R3 R2 K0 + 0x58140001, // 0001 LDCONST R5 K1 + 0x541A00FE, // 0002 LDINT R6 255 + 0x7C0C0600, // 0003 CALL R3 3 + 0x8C100102, // 0004 GETMET R4 R0 K2 + 0x88180303, // 0005 GETMBR R6 R1 K3 + 0x7C100400, // 0006 CALL R4 2 + 0xB8160800, // 0007 GETNGBL R5 K4 + 0x88140B05, // 0008 GETMBR R5 R5 K5 + 0x1C140605, // 0009 EQ R5 R3 R5 + 0x78160010, // 000A JMPF R5 #001C + 0x78120004, // 000B JMPF R4 #0011 + 0x8C140906, // 000C GETMET R5 R4 K6 + 0x5C1C0200, // 000D MOVE R7 R1 + 0x7C140400, // 000E CALL R5 2 + 0x80040A00, // 000F RET 1 R5 + 0x70020009, // 0010 JMP #001B + 0xB8160E00, // 0011 GETNGBL R5 K7 + 0x8C140B08, // 0012 GETMET R5 R5 K8 + 0x601C0018, // 0013 GETGBL R7 G24 + 0x58200009, // 0014 LDCONST R8 K9 + 0x8824030A, // 0015 GETMBR R9 R1 K10 + 0x8824130B, // 0016 GETMBR R9 R9 K11 + 0x88280303, // 0017 GETMBR R10 R1 K3 + 0x7C1C0600, // 0018 CALL R7 3 + 0x54220003, // 0019 LDINT R8 4 + 0x7C140600, // 001A CALL R5 3 + 0x7002000E, // 001B JMP #002B + 0xB8160E00, // 001C GETNGBL R5 K7 + 0x8C140B08, // 001D GETMET R5 R5 K8 + 0x601C0018, // 001E GETGBL R7 G24 + 0x5820000C, // 001F LDCONST R8 K12 + 0x5C240600, // 0020 MOVE R9 R3 + 0x7C1C0400, // 0021 CALL R7 2 + 0x5820000D, // 0022 LDCONST R8 K13 + 0x7C140600, // 0023 CALL R5 3 + 0x78120005, // 0024 JMPF R4 #002B + 0x8C14090E, // 0025 GETMET R5 R4 K14 + 0x5C1C0200, // 0026 MOVE R7 R1 + 0x7C140400, // 0027 CALL R5 2 + 0x8C14010F, // 0028 GETMET R5 R0 K15 + 0x881C0303, // 0029 GETMBR R7 R1 K3 + 0x7C140400, // 002A CALL R5 2 + 0x50140000, // 002B LDBOOL R5 0 0 + 0x80040A00, // 002C RET 1 R5 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: process_timed_request +********************************************************************/ +be_local_closure(Matter_IM_process_timed_request, /* name */ + be_nested_proto( + 10, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TimedRequestMessage), + /* K2 */ be_nested_str_weak(from_TLV), + /* K3 */ be_nested_str_weak(tasmota), + /* K4 */ be_nested_str_weak(log), + /* K5 */ be_nested_str_weak(MTR_X3A_X20_X3ECommand_X20_X20_X20_X28_X256i_X29_X20TimedRequest_X3D_X25i), + /* K6 */ be_nested_str_weak(session), + /* K7 */ be_nested_str_weak(local_session_id), + /* K8 */ be_nested_str_weak(timeout), + /* K9 */ be_const_int(3), + /* K10 */ be_nested_str_weak(send_status), + /* K11 */ be_nested_str_weak(SUCCESS), + }), + be_str_weak(process_timed_request), + &be_const_str_solidified, + ( &(const binstruction[23]) { /* code */ + 0xB80E0000, // 0000 GETNGBL R3 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x7C0C0200, // 0002 CALL R3 1 + 0x8C0C0702, // 0003 GETMET R3 R3 K2 + 0x5C140400, // 0004 MOVE R5 R2 + 0x7C0C0400, // 0005 CALL R3 2 + 0xB8120600, // 0006 GETNGBL R4 K3 + 0x8C100904, // 0007 GETMET R4 R4 K4 + 0x60180018, // 0008 GETGBL R6 G24 + 0x581C0005, // 0009 LDCONST R7 K5 + 0x88200306, // 000A GETMBR R8 R1 K6 + 0x88201107, // 000B GETMBR R8 R8 K7 + 0x88240708, // 000C GETMBR R9 R3 K8 + 0x7C180600, // 000D CALL R6 3 + 0x581C0009, // 000E LDCONST R7 K9 + 0x7C100600, // 000F CALL R4 3 + 0x8C10010A, // 0010 GETMET R4 R0 K10 + 0x5C180200, // 0011 MOVE R6 R1 + 0xB81E0000, // 0012 GETNGBL R7 K0 + 0x881C0F0B, // 0013 GETMBR R7 R7 K11 + 0x7C100600, // 0014 CALL R4 3 + 0x50100200, // 0015 LDBOOL R4 1 0 + 0x80040800, // 0016 RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: attributedata2raw +********************************************************************/ +be_local_closure(Matter_IM_attributedata2raw, /* name */ + be_nested_proto( + 11, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(add), + /* K1 */ be_const_int(355795236), + /* K2 */ be_const_int(1), + /* K3 */ be_nested_str_weak(path2raw), + /* K4 */ be_nested_str_weak(tag_sub), + /* K5 */ be_const_int(2), + /* K6 */ be_nested_str_weak(tlv2raw), + }), + be_str_weak(attributedata2raw), + &be_const_str_solidified, + ( &(const binstruction[23]) { /* code */ + 0x8C140300, // 0000 GETMET R5 R1 K0 + 0x581C0001, // 0001 LDCONST R7 K1 + 0x5421FFFB, // 0002 LDINT R8 -4 + 0x7C140600, // 0003 CALL R5 3 + 0x8C140300, // 0004 GETMET R5 R1 K0 + 0x581C0002, // 0005 LDCONST R7 K2 + 0x5421FFFD, // 0006 LDINT R8 -2 + 0x7C140600, // 0007 CALL R5 3 + 0x8C140103, // 0008 GETMET R5 R0 K3 + 0x5C1C0200, // 0009 MOVE R7 R1 + 0x5C200400, // 000A MOVE R8 R2 + 0x58240002, // 000B LDCONST R9 K2 + 0x5C280800, // 000C MOVE R10 R4 + 0x7C140A00, // 000D CALL R5 5 + 0x900E0905, // 000E SETMBR R3 K4 K5 + 0x8C140706, // 000F GETMET R5 R3 K6 + 0x5C1C0200, // 0010 MOVE R7 R1 + 0x7C140400, // 0011 CALL R5 2 + 0x8C140300, // 0012 GETMET R5 R1 K0 + 0x541E1817, // 0013 LDINT R7 6168 + 0x5421FFFD, // 0014 LDINT R8 -2 + 0x7C140600, // 0015 CALL R5 3 + 0x80000000, // 0016 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: process_invoke_request_solo +********************************************************************/ +be_local_closure(Matter_IM_process_invoke_request_solo, /* name */ + be_nested_proto( + 15, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[42]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(profiler), + /* K2 */ be_nested_str_weak(log), + /* K3 */ be_nested_str_weak(invoke_request_solo_start), + /* K4 */ be_nested_str_weak(msg), + /* K5 */ be_nested_str_weak(status), + /* K6 */ be_nested_str_weak(UNSUPPORTED_COMMAND), + /* K7 */ be_nested_str_weak(get_command_name), + /* K8 */ be_nested_str_weak(cluster), + /* K9 */ be_nested_str_weak(command), + /* K10 */ be_nested_str_weak(device), + /* K11 */ be_nested_str_weak(invoke_request), + /* K12 */ be_nested_str_weak(session), + /* K13 */ be_nested_str_weak(command_fields), + /* K14 */ be_nested_str_weak(COMMAND_X20DONE), + /* K15 */ be_nested_str_weak(_X28), + /* K16 */ be_nested_str_weak(_X29_X20), + /* K17 */ be_nested_str_weak(), + /* K18 */ be_nested_str_weak(tasmota), + /* K19 */ be_nested_str_weak(loglevel), + /* K20 */ be_const_int(3), + /* K21 */ be_nested_str_weak(MTR_X3A_X20_X3ECommand1_X20_X20_X28_X256i_X29_X20_X25s_X20_X25s_X20_X25s), + /* K22 */ be_nested_str_weak(local_session_id), + /* K23 */ be_nested_str_weak(add), + /* K24 */ be_const_int(354943030), + /* K25 */ be_const_int(1), + /* K26 */ be_nested_str_weak(SUCCESS), + /* K27 */ be_nested_str_weak(invokeresponse2raw), + /* K28 */ be_nested_str_weak(MTR_X3A_X20_X3CReplied_X20_X20_X20_X28_X256i_X29_X20OK_X20exch_X3D_X25i), + /* K29 */ be_nested_str_weak(exchange_id), + /* K30 */ be_nested_str_weak(MTR_X3A_X20_X3CReplied_X20_X20_X20_X28_X256i_X29_X20_X25s_X20_X25s), + /* K31 */ be_nested_str_weak(MTR_X3A_X20_X3CReplied_X20_X20_X20_X28_X256i_X29_X20Status_X3D0x_X2502X_X20exch_X3D_X25i), + /* K32 */ be_nested_str_weak(MTR_X3A_X20_Ignore_X20_X20_X20_X20_X28_X256i_X29_X20exch_X3D_X25i), + /* K33 */ be_const_int(405077761), + /* K34 */ be_nested_str_weak(build_response), + /* K35 */ be_nested_str_weak(message_handler), + /* K36 */ be_nested_str_weak(raw), + /* K37 */ be_nested_str_weak(clear), + /* K38 */ be_nested_str_weak(encode_frame), + /* K39 */ be_nested_str_weak(encrypt), + /* K40 */ be_nested_str_weak(send_response_frame), + /* K41 */ be_nested_str_weak(RESPONSE_X20SENT), + }), + be_str_weak(process_invoke_request_solo), + &be_const_str_solidified, + ( &(const binstruction[208]) { /* code */ + 0xB80E0000, // 0000 GETNGBL R3 K0 + 0x880C0701, // 0001 GETMBR R3 R3 K1 + 0x8C0C0702, // 0002 GETMET R3 R3 K2 + 0x58140003, // 0003 LDCONST R5 K3 + 0x7C0C0400, // 0004 CALL R3 2 + 0x900A0801, // 0005 SETMBR R2 K4 R1 + 0xB80E0000, // 0006 GETNGBL R3 K0 + 0x880C0706, // 0007 GETMBR R3 R3 K6 + 0x900A0A03, // 0008 SETMBR R2 K5 R3 + 0xB80E0000, // 0009 GETNGBL R3 K0 + 0x8C0C0707, // 000A GETMET R3 R3 K7 + 0x88140508, // 000B GETMBR R5 R2 K8 + 0x88180509, // 000C GETMBR R6 R2 K9 + 0x7C0C0600, // 000D CALL R3 3 + 0x60100008, // 000E GETGBL R4 G8 + 0x5C140400, // 000F MOVE R5 R2 + 0x7C100200, // 0010 CALL R4 1 + 0x8814010A, // 0011 GETMBR R5 R0 K10 + 0x8C140B0B, // 0012 GETMET R5 R5 K11 + 0x881C030C, // 0013 GETMBR R7 R1 K12 + 0x8820050D, // 0014 GETMBR R8 R2 K13 + 0x5C240400, // 0015 MOVE R9 R2 + 0x7C140800, // 0016 CALL R5 4 + 0xB81A0000, // 0017 GETNGBL R6 K0 + 0x88180D01, // 0018 GETMBR R6 R6 K1 + 0x8C180D02, // 0019 GETMET R6 R6 K2 + 0x5820000E, // 001A LDCONST R8 K14 + 0x7C180400, // 001B CALL R6 2 + 0x88180502, // 001C GETMBR R6 R2 K2 + 0x4C1C0000, // 001D LDNIL R7 + 0x20180C07, // 001E NE R6 R6 R7 + 0x781A0005, // 001F JMPF R6 #0026 + 0x60180008, // 0020 GETGBL R6 G8 + 0x881C0502, // 0021 GETMBR R7 R2 K2 + 0x7C180200, // 0022 CALL R6 1 + 0x001A1E06, // 0023 ADD R6 K15 R6 + 0x00180D10, // 0024 ADD R6 R6 K16 + 0x70020000, // 0025 JMP #0027 + 0x58180011, // 0026 LDCONST R6 K17 + 0xB81E2400, // 0027 GETNGBL R7 K18 + 0x8C1C0F13, // 0028 GETMET R7 R7 K19 + 0x58240014, // 0029 LDCONST R9 K20 + 0x7C1C0400, // 002A CALL R7 2 + 0x781E000E, // 002B JMPF R7 #003B + 0xB81E2400, // 002C GETNGBL R7 K18 + 0x8C1C0F02, // 002D GETMET R7 R7 K2 + 0x60240018, // 002E GETGBL R9 G24 + 0x58280015, // 002F LDCONST R10 K21 + 0x882C030C, // 0030 GETMBR R11 R1 K12 + 0x882C1716, // 0031 GETMBR R11 R11 K22 + 0x5C300800, // 0032 MOVE R12 R4 + 0x780E0001, // 0033 JMPF R3 #0036 + 0x5C340600, // 0034 MOVE R13 R3 + 0x70020000, // 0035 JMP #0037 + 0x58340011, // 0036 LDCONST R13 K17 + 0x5C380C00, // 0037 MOVE R14 R6 + 0x7C240A00, // 0038 CALL R9 5 + 0x58280014, // 0039 LDCONST R10 K20 + 0x7C1C0600, // 003A CALL R7 3 + 0x4C1C0000, // 003B LDNIL R7 + 0x900A0407, // 003C SETMBR R2 K2 R7 + 0x601C0015, // 003D GETGBL R7 G21 + 0x5422002F, // 003E LDINT R8 48 + 0x7C1C0200, // 003F CALL R7 1 + 0x8C200F17, // 0040 GETMET R8 R7 K23 + 0x58280018, // 0041 LDCONST R10 K24 + 0x542DFFFB, // 0042 LDINT R11 -4 + 0x7C200600, // 0043 CALL R8 3 + 0x8C200F17, // 0044 GETMET R8 R7 K23 + 0x58280019, // 0045 LDCONST R10 K25 + 0x582C0019, // 0046 LDCONST R11 K25 + 0x7C200600, // 0047 CALL R8 3 + 0x50200200, // 0048 LDBOOL R8 1 0 + 0x1C200A08, // 0049 EQ R8 R5 R8 + 0x74220004, // 004A JMPT R8 #0050 + 0x88200505, // 004B GETMBR R8 R2 K5 + 0xB8260000, // 004C GETNGBL R9 K0 + 0x8824131A, // 004D GETMBR R9 R9 K26 + 0x1C201009, // 004E EQ R8 R8 R9 + 0x78220017, // 004F JMPF R8 #0068 + 0xB8220000, // 0050 GETNGBL R8 K0 + 0x8820111A, // 0051 GETMBR R8 R8 K26 + 0x900A0A08, // 0052 SETMBR R2 K5 R8 + 0x8C20011B, // 0053 GETMET R8 R0 K27 + 0x5C280E00, // 0054 MOVE R10 R7 + 0x5C2C0400, // 0055 MOVE R11 R2 + 0x4C300000, // 0056 LDNIL R12 + 0x7C200800, // 0057 CALL R8 4 + 0xB8222400, // 0058 GETNGBL R8 K18 + 0x8C201113, // 0059 GETMET R8 R8 K19 + 0x58280014, // 005A LDCONST R10 K20 + 0x7C200400, // 005B CALL R8 2 + 0x78220009, // 005C JMPF R8 #0067 + 0xB8222400, // 005D GETNGBL R8 K18 + 0x8C201102, // 005E GETMET R8 R8 K2 + 0x60280018, // 005F GETGBL R10 G24 + 0x582C001C, // 0060 LDCONST R11 K28 + 0x8830030C, // 0061 GETMBR R12 R1 K12 + 0x88301916, // 0062 GETMBR R12 R12 K22 + 0x8834031D, // 0063 GETMBR R13 R1 K29 + 0x7C280600, // 0064 CALL R10 3 + 0x582C0014, // 0065 LDCONST R11 K20 + 0x7C200600, // 0066 CALL R8 3 + 0x70020046, // 0067 JMP #00AF + 0x4C200000, // 0068 LDNIL R8 + 0x20200A08, // 0069 NE R8 R5 R8 + 0x78220018, // 006A JMPF R8 #0084 + 0x8C20011B, // 006B GETMET R8 R0 K27 + 0x5C280E00, // 006C MOVE R10 R7 + 0x5C2C0400, // 006D MOVE R11 R2 + 0x5C300A00, // 006E MOVE R12 R5 + 0x7C200800, // 006F CALL R8 4 + 0x5C200600, // 0070 MOVE R8 R3 + 0x74220000, // 0071 JMPT R8 #0073 + 0x580C0011, // 0072 LDCONST R3 K17 + 0xB8222400, // 0073 GETNGBL R8 K18 + 0x8C201113, // 0074 GETMET R8 R8 K19 + 0x58280014, // 0075 LDCONST R10 K20 + 0x7C200400, // 0076 CALL R8 2 + 0x7822000A, // 0077 JMPF R8 #0083 + 0xB8222400, // 0078 GETNGBL R8 K18 + 0x8C201102, // 0079 GETMET R8 R8 K2 + 0x60280018, // 007A GETGBL R10 G24 + 0x582C001E, // 007B LDCONST R11 K30 + 0x8830030C, // 007C GETMBR R12 R1 K12 + 0x88301916, // 007D GETMBR R12 R12 K22 + 0x5C340400, // 007E MOVE R13 R2 + 0x5C380600, // 007F MOVE R14 R3 + 0x7C280800, // 0080 CALL R10 4 + 0x582C0014, // 0081 LDCONST R11 K20 + 0x7C200600, // 0082 CALL R8 3 + 0x7002002A, // 0083 JMP #00AF + 0x88200505, // 0084 GETMBR R8 R2 K5 + 0x4C240000, // 0085 LDNIL R9 + 0x20201009, // 0086 NE R8 R8 R9 + 0x78220015, // 0087 JMPF R8 #009E + 0x8C20011B, // 0088 GETMET R8 R0 K27 + 0x5C280E00, // 0089 MOVE R10 R7 + 0x5C2C0400, // 008A MOVE R11 R2 + 0x4C300000, // 008B LDNIL R12 + 0x7C200800, // 008C CALL R8 4 + 0xB8222400, // 008D GETNGBL R8 K18 + 0x8C201113, // 008E GETMET R8 R8 K19 + 0x58280014, // 008F LDCONST R10 K20 + 0x7C200400, // 0090 CALL R8 2 + 0x7822000A, // 0091 JMPF R8 #009D + 0xB8222400, // 0092 GETNGBL R8 K18 + 0x8C201102, // 0093 GETMET R8 R8 K2 + 0x60280018, // 0094 GETGBL R10 G24 + 0x582C001F, // 0095 LDCONST R11 K31 + 0x8830030C, // 0096 GETMBR R12 R1 K12 + 0x88301916, // 0097 GETMBR R12 R12 K22 + 0x88340505, // 0098 GETMBR R13 R2 K5 + 0x8838031D, // 0099 GETMBR R14 R1 K29 + 0x7C280800, // 009A CALL R10 4 + 0x582C0014, // 009B LDCONST R11 K20 + 0x7C200600, // 009C CALL R8 3 + 0x70020010, // 009D JMP #00AF + 0xB8222400, // 009E GETNGBL R8 K18 + 0x8C201113, // 009F GETMET R8 R8 K19 + 0x58280014, // 00A0 LDCONST R10 K20 + 0x7C200400, // 00A1 CALL R8 2 + 0x78220009, // 00A2 JMPF R8 #00AD + 0xB8222400, // 00A3 GETNGBL R8 K18 + 0x8C201102, // 00A4 GETMET R8 R8 K2 + 0x60280018, // 00A5 GETGBL R10 G24 + 0x582C0020, // 00A6 LDCONST R11 K32 + 0x8830030C, // 00A7 GETMBR R12 R1 K12 + 0x88301916, // 00A8 GETMBR R12 R12 K22 + 0x8834031D, // 00A9 GETMBR R13 R1 K29 + 0x7C280600, // 00AA CALL R10 3 + 0x582C0014, // 00AB LDCONST R11 K20 + 0x7C200600, // 00AC CALL R8 3 + 0x50200000, // 00AD LDBOOL R8 0 0 + 0x80041000, // 00AE RET 1 R8 + 0x8C200F17, // 00AF GETMET R8 R7 K23 + 0x58280021, // 00B0 LDCONST R10 K33 + 0x542DFFFB, // 00B1 LDINT R11 -4 + 0x7C200600, // 00B2 CALL R8 3 + 0x8C200F17, // 00B3 GETMET R8 R7 K23 + 0x542A0017, // 00B4 LDINT R10 24 + 0x582C0019, // 00B5 LDCONST R11 K25 + 0x7C200600, // 00B6 CALL R8 3 + 0x8C200322, // 00B7 GETMET R8 R1 K34 + 0x542A0008, // 00B8 LDINT R10 9 + 0x502C0200, // 00B9 LDBOOL R11 1 0 + 0x7C200600, // 00BA CALL R8 3 + 0x8824010A, // 00BB GETMBR R9 R0 K10 + 0x88241323, // 00BC GETMBR R9 R9 K35 + 0x88280324, // 00BD GETMBR R10 R1 K36 + 0x8C2C1525, // 00BE GETMET R11 R10 K37 + 0x7C2C0200, // 00BF CALL R11 1 + 0x8C2C1126, // 00C0 GETMET R11 R8 K38 + 0x5C340E00, // 00C1 MOVE R13 R7 + 0x5C381400, // 00C2 MOVE R14 R10 + 0x7C2C0600, // 00C3 CALL R11 3 + 0x8C2C1127, // 00C4 GETMET R11 R8 K39 + 0x7C2C0200, // 00C5 CALL R11 1 + 0x8C2C1328, // 00C6 GETMET R11 R9 K40 + 0x5C341000, // 00C7 MOVE R13 R8 + 0x7C2C0400, // 00C8 CALL R11 2 + 0xB82E0000, // 00C9 GETNGBL R11 K0 + 0x882C1701, // 00CA GETMBR R11 R11 K1 + 0x8C2C1702, // 00CB GETMET R11 R11 K2 + 0x58340029, // 00CC LDCONST R13 K41 + 0x7C2C0400, // 00CD CALL R11 2 + 0x502C0200, // 00CE LDBOOL R11 1 0 + 0x80041600, // 00CF RET 1 R11 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: invokeresponse2raw +********************************************************************/ +be_local_closure(Matter_IM_invokeresponse2raw, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(add), + /* K1 */ be_const_int(1), + /* K2 */ be_nested_str_weak(endpoint), + /* K3 */ be_const_int(2), + /* K4 */ be_nested_str_weak(cluster), + /* K5 */ be_nested_str_weak(command), + /* K6 */ be_nested_str_weak(status), + /* K7 */ be_nested_str_weak(matter), + /* K8 */ be_nested_str_weak(SUCCESS), + /* K9 */ be_nested_str_weak(tag_sub), + /* K10 */ be_nested_str_weak(tlv2raw), + }), + be_str_weak(invokeresponse2raw), + &be_const_str_solidified, + ( &(const binstruction[148]) { /* code */ + 0x8C100300, // 0000 GETMET R4 R1 K0 + 0x541A0014, // 0001 LDINT R6 21 + 0x581C0001, // 0002 LDCONST R7 K1 + 0x7C100600, // 0003 CALL R4 3 + 0x4C100000, // 0004 LDNIL R4 + 0x1C100604, // 0005 EQ R4 R3 R4 + 0x78120004, // 0006 JMPF R4 #000C + 0x8C100300, // 0007 GETMET R4 R1 K0 + 0x541A3500, // 0008 LDINT R6 13569 + 0x541DFFFD, // 0009 LDINT R7 -2 + 0x7C100600, // 000A CALL R4 3 + 0x70020003, // 000B JMP #0010 + 0x8C100300, // 000C GETMET R4 R1 K0 + 0x541A34FF, // 000D LDINT R6 13568 + 0x541DFFFD, // 000E LDINT R7 -2 + 0x7C100600, // 000F CALL R4 3 + 0x8C100300, // 0010 GETMET R4 R1 K0 + 0x541A36FF, // 0011 LDINT R6 14080 + 0x541DFFFD, // 0012 LDINT R7 -2 + 0x7C100600, // 0013 CALL R4 3 + 0x88100502, // 0014 GETMBR R4 R2 K2 + 0x541600FE, // 0015 LDINT R5 255 + 0x18100805, // 0016 LE R4 R4 R5 + 0x78120008, // 0017 JMPF R4 #0021 + 0x8C100300, // 0018 GETMET R4 R1 K0 + 0x541A23FF, // 0019 LDINT R6 9216 + 0x541DFFFD, // 001A LDINT R7 -2 + 0x7C100600, // 001B CALL R4 3 + 0x8C100300, // 001C GETMET R4 R1 K0 + 0x88180502, // 001D GETMBR R6 R2 K2 + 0x581C0001, // 001E LDCONST R7 K1 + 0x7C100600, // 001F CALL R4 3 + 0x70020007, // 0020 JMP #0029 + 0x8C100300, // 0021 GETMET R4 R1 K0 + 0x541A24FF, // 0022 LDINT R6 9472 + 0x541DFFFD, // 0023 LDINT R7 -2 + 0x7C100600, // 0024 CALL R4 3 + 0x8C100300, // 0025 GETMET R4 R1 K0 + 0x88180502, // 0026 GETMBR R6 R2 K2 + 0x581C0003, // 0027 LDCONST R7 K3 + 0x7C100600, // 0028 CALL R4 3 + 0x88100504, // 0029 GETMBR R4 R2 K4 + 0x541600FE, // 002A LDINT R5 255 + 0x18100805, // 002B LE R4 R4 R5 + 0x78120008, // 002C JMPF R4 #0036 + 0x8C100300, // 002D GETMET R4 R1 K0 + 0x541A2400, // 002E LDINT R6 9217 + 0x541DFFFD, // 002F LDINT R7 -2 + 0x7C100600, // 0030 CALL R4 3 + 0x8C100300, // 0031 GETMET R4 R1 K0 + 0x88180504, // 0032 GETMBR R6 R2 K4 + 0x581C0001, // 0033 LDCONST R7 K1 + 0x7C100600, // 0034 CALL R4 3 + 0x70020014, // 0035 JMP #004B + 0x88100504, // 0036 GETMBR R4 R2 K4 + 0x5416FFFE, // 0037 LDINT R5 65535 + 0x18100805, // 0038 LE R4 R4 R5 + 0x78120008, // 0039 JMPF R4 #0043 + 0x8C100300, // 003A GETMET R4 R1 K0 + 0x541A2500, // 003B LDINT R6 9473 + 0x541DFFFD, // 003C LDINT R7 -2 + 0x7C100600, // 003D CALL R4 3 + 0x8C100300, // 003E GETMET R4 R1 K0 + 0x88180504, // 003F GETMBR R6 R2 K4 + 0x581C0003, // 0040 LDCONST R7 K3 + 0x7C100600, // 0041 CALL R4 3 + 0x70020007, // 0042 JMP #004B + 0x8C100300, // 0043 GETMET R4 R1 K0 + 0x541A2600, // 0044 LDINT R6 9729 + 0x541DFFFD, // 0045 LDINT R7 -2 + 0x7C100600, // 0046 CALL R4 3 + 0x8C100300, // 0047 GETMET R4 R1 K0 + 0x88180504, // 0048 GETMBR R6 R2 K4 + 0x541E0003, // 0049 LDINT R7 4 + 0x7C100600, // 004A CALL R4 3 + 0x88100505, // 004B GETMBR R4 R2 K5 + 0x541600FE, // 004C LDINT R5 255 + 0x18100805, // 004D LE R4 R4 R5 + 0x78120008, // 004E JMPF R4 #0058 + 0x8C100300, // 004F GETMET R4 R1 K0 + 0x541A2401, // 0050 LDINT R6 9218 + 0x541DFFFD, // 0051 LDINT R7 -2 + 0x7C100600, // 0052 CALL R4 3 + 0x8C100300, // 0053 GETMET R4 R1 K0 + 0x88180505, // 0054 GETMBR R6 R2 K5 + 0x581C0001, // 0055 LDCONST R7 K1 + 0x7C100600, // 0056 CALL R4 3 + 0x70020014, // 0057 JMP #006D + 0x88100505, // 0058 GETMBR R4 R2 K5 + 0x5416FFFE, // 0059 LDINT R5 65535 + 0x18100805, // 005A LE R4 R4 R5 + 0x78120008, // 005B JMPF R4 #0065 + 0x8C100300, // 005C GETMET R4 R1 K0 + 0x541A2501, // 005D LDINT R6 9474 + 0x541DFFFD, // 005E LDINT R7 -2 + 0x7C100600, // 005F CALL R4 3 + 0x8C100300, // 0060 GETMET R4 R1 K0 + 0x88180505, // 0061 GETMBR R6 R2 K5 + 0x581C0003, // 0062 LDCONST R7 K3 + 0x7C100600, // 0063 CALL R4 3 + 0x70020007, // 0064 JMP #006D + 0x8C100300, // 0065 GETMET R4 R1 K0 + 0x541A2601, // 0066 LDINT R6 9730 + 0x541DFFFD, // 0067 LDINT R7 -2 + 0x7C100600, // 0068 CALL R4 3 + 0x8C100300, // 0069 GETMET R4 R1 K0 + 0x88180505, // 006A GETMBR R6 R2 K5 + 0x541E0003, // 006B LDINT R7 4 + 0x7C100600, // 006C CALL R4 3 + 0x8C100300, // 006D GETMET R4 R1 K0 + 0x541A0017, // 006E LDINT R6 24 + 0x581C0001, // 006F LDCONST R7 K1 + 0x7C100600, // 0070 CALL R4 3 + 0x4C100000, // 0071 LDNIL R4 + 0x1C100604, // 0072 EQ R4 R3 R4 + 0x78120016, // 0073 JMPF R4 #008B + 0x88100506, // 0074 GETMBR R4 R2 K6 + 0x4C140000, // 0075 LDNIL R5 + 0x1C140805, // 0076 EQ R5 R4 R5 + 0x78160001, // 0077 JMPF R5 #007A + 0xB8160E00, // 0078 GETNGBL R5 K7 + 0x88100B08, // 0079 GETMBR R4 R5 K8 + 0x8C140300, // 007A GETMET R5 R1 K0 + 0x541E3500, // 007B LDINT R7 13569 + 0x5421FFFD, // 007C LDINT R8 -2 + 0x7C140600, // 007D CALL R5 3 + 0x8C140300, // 007E GETMET R5 R1 K0 + 0x541E23FF, // 007F LDINT R7 9216 + 0x5421FFFD, // 0080 LDINT R8 -2 + 0x7C140600, // 0081 CALL R5 3 + 0x8C140300, // 0082 GETMET R5 R1 K0 + 0x881C0506, // 0083 GETMBR R7 R2 K6 + 0x58200001, // 0084 LDCONST R8 K1 + 0x7C140600, // 0085 CALL R5 3 + 0x8C140300, // 0086 GETMET R5 R1 K0 + 0x541E0017, // 0087 LDINT R7 24 + 0x58200001, // 0088 LDCONST R8 K1 + 0x7C140600, // 0089 CALL R5 3 + 0x70020003, // 008A JMP #008F + 0x900E1301, // 008B SETMBR R3 K9 K1 + 0x8C10070A, // 008C GETMET R4 R3 K10 + 0x5C180200, // 008D MOVE R6 R1 + 0x7C100400, // 008E CALL R4 2 + 0x8C100300, // 008F GETMET R4 R1 K0 + 0x541A1817, // 0090 LDINT R6 6168 + 0x541DFFFD, // 0091 LDINT R7 -2 + 0x7C100600, // 0092 CALL R4 3 + 0x80000000, // 0093 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: send_ack_now +********************************************************************/ +be_local_closure(Matter_IM_send_ack_now, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(session), + /* K1 */ be_nested_str_weak(_message_handler), + /* K2 */ be_nested_str_weak(send_encrypted_ack), + }), + be_str_weak(send_ack_now), + &be_const_str_solidified, + ( &(const binstruction[11]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x1C080202, // 0001 EQ R2 R1 R2 + 0x780A0000, // 0002 JMPF R2 #0004 + 0x80000400, // 0003 RET 0 + 0x88080300, // 0004 GETMBR R2 R1 K0 + 0x88080501, // 0005 GETMBR R2 R2 K1 + 0x8C080502, // 0006 GETMET R2 R2 K2 + 0x5C100200, // 0007 MOVE R4 R1 + 0x50140000, // 0008 LDBOOL R5 0 0 + 0x7C080600, // 0009 CALL R2 3 + 0x80000000, // 000A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: process_invoke_request +********************************************************************/ +be_local_closure(Matter_IM_process_invoke_request, /* name */ + be_nested_proto( + 20, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[43]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(profiler), + /* K2 */ be_nested_str_weak(log), + /* K3 */ be_nested_str_weak(invoke_request_start), + /* K4 */ be_nested_str_weak(Path), + /* K5 */ be_nested_str_weak(msg), + /* K6 */ be_nested_str_weak(InvokeRequestMessage), + /* K7 */ be_nested_str_weak(from_TLV), + /* K8 */ be_nested_str_weak(invoke_requests), + /* K9 */ be_nested_str_weak(InvokeResponseMessage), + /* K10 */ be_nested_str_weak(suppress_response), + /* K11 */ be_nested_str_weak(invoke_responses), + /* K12 */ be_nested_str_weak(endpoint), + /* K13 */ be_nested_str_weak(command_path), + /* K14 */ be_nested_str_weak(cluster), + /* K15 */ be_nested_str_weak(command), + /* K16 */ be_nested_str_weak(status), + /* K17 */ be_nested_str_weak(UNSUPPORTED_COMMAND), + /* K18 */ be_nested_str_weak(get_command_name), + /* K19 */ be_nested_str_weak(device), + /* K20 */ be_nested_str_weak(invoke_request), + /* K21 */ be_nested_str_weak(session), + /* K22 */ be_nested_str_weak(command_fields), + /* K23 */ be_nested_str_weak(COMMAND_X20DONE), + /* K24 */ be_nested_str_weak(_X28), + /* K25 */ be_nested_str_weak(_X29_X20), + /* K26 */ be_nested_str_weak(), + /* K27 */ be_nested_str_weak(tasmota), + /* K28 */ be_nested_str_weak(MTR_X3A_X20_X3ECommand_X20_X20_X20_X28_X256i_X29_X20_X25s_X20_X25s_X20_X25s), + /* K29 */ be_nested_str_weak(local_session_id), + /* K30 */ be_const_int(3), + /* K31 */ be_nested_str_weak(SUCCESS), + /* K32 */ be_nested_str_weak(invokeresponse2raw), + /* K33 */ be_nested_str_weak(push), + /* K34 */ be_nested_str_weak(loglevel), + /* K35 */ be_nested_str_weak(MTR_X3A_X20_X3CReplied_X20_X20_X20_X28_X256i_X29_X20OK_X20exch_X3D_X25i), + /* K36 */ be_nested_str_weak(exchange_id), + /* K37 */ be_nested_str_weak(MTR_X3A_X20_X3CReplied_X20_X20_X20_X28_X256i_X29_X20_X25s_X20_X25s), + /* K38 */ be_nested_str_weak(MTR_X3A_X20_X3CReplied_X20_X20_X20_X28_X256i_X29_X20Status_X3D0x_X2502X_X20exch_X3D_X25i), + /* K39 */ be_nested_str_weak(MTR_X3A_X20_Ignore_X20_X20_X20_X20_X28_X256i_X29_X20exch_X3D_X25i), + /* K40 */ be_nested_str_weak(stop_iteration), + /* K41 */ be_const_int(0), + /* K42 */ be_nested_str_weak(send_invoke_response), + }), + be_str_weak(process_invoke_request), + &be_const_str_solidified, + ( &(const binstruction[233]) { /* code */ + 0xB80E0000, // 0000 GETNGBL R3 K0 + 0x880C0701, // 0001 GETMBR R3 R3 K1 + 0x8C0C0702, // 0002 GETMET R3 R3 K2 + 0x58140003, // 0003 LDCONST R5 K3 + 0x7C0C0400, // 0004 CALL R3 2 + 0xB80E0000, // 0005 GETNGBL R3 K0 + 0x8C0C0704, // 0006 GETMET R3 R3 K4 + 0x7C0C0200, // 0007 CALL R3 1 + 0x900E0A01, // 0008 SETMBR R3 K5 R1 + 0xB8120000, // 0009 GETNGBL R4 K0 + 0x8C100906, // 000A GETMET R4 R4 K6 + 0x7C100200, // 000B CALL R4 1 + 0x8C100907, // 000C GETMET R4 R4 K7 + 0x5C180400, // 000D MOVE R6 R2 + 0x7C100400, // 000E CALL R4 2 + 0x88140908, // 000F GETMBR R5 R4 K8 + 0x4C180000, // 0010 LDNIL R6 + 0x20140A06, // 0011 NE R5 R5 R6 + 0x781600D4, // 0012 JMPF R5 #00E8 + 0xB8160000, // 0013 GETNGBL R5 K0 + 0x8C140B09, // 0014 GETMET R5 R5 K9 + 0x7C140200, // 0015 CALL R5 1 + 0x50180000, // 0016 LDBOOL R6 0 0 + 0x90161406, // 0017 SETMBR R5 K10 R6 + 0x60180012, // 0018 GETGBL R6 G18 + 0x7C180000, // 0019 CALL R6 0 + 0x90161606, // 001A SETMBR R5 K11 R6 + 0x60180010, // 001B GETGBL R6 G16 + 0x881C0908, // 001C GETMBR R7 R4 K8 + 0x7C180200, // 001D CALL R6 1 + 0xA80200B7, // 001E EXBLK 0 #00D7 + 0x5C1C0C00, // 001F MOVE R7 R6 + 0x7C1C0000, // 0020 CALL R7 0 + 0x88200F0D, // 0021 GETMBR R8 R7 K13 + 0x8820110C, // 0022 GETMBR R8 R8 K12 + 0x900E1808, // 0023 SETMBR R3 K12 R8 + 0x88200F0D, // 0024 GETMBR R8 R7 K13 + 0x8820110E, // 0025 GETMBR R8 R8 K14 + 0x900E1C08, // 0026 SETMBR R3 K14 R8 + 0x88200F0D, // 0027 GETMBR R8 R7 K13 + 0x8820110F, // 0028 GETMBR R8 R8 K15 + 0x900E1E08, // 0029 SETMBR R3 K15 R8 + 0xB8220000, // 002A GETNGBL R8 K0 + 0x88201111, // 002B GETMBR R8 R8 K17 + 0x900E2008, // 002C SETMBR R3 K16 R8 + 0xB8220000, // 002D GETNGBL R8 K0 + 0x8C201112, // 002E GETMET R8 R8 K18 + 0x8828070E, // 002F GETMBR R10 R3 K14 + 0x882C070F, // 0030 GETMBR R11 R3 K15 + 0x7C200600, // 0031 CALL R8 3 + 0x60240008, // 0032 GETGBL R9 G8 + 0x5C280600, // 0033 MOVE R10 R3 + 0x7C240200, // 0034 CALL R9 1 + 0x88280113, // 0035 GETMBR R10 R0 K19 + 0x8C281514, // 0036 GETMET R10 R10 K20 + 0x88300315, // 0037 GETMBR R12 R1 K21 + 0x88340F16, // 0038 GETMBR R13 R7 K22 + 0x5C380600, // 0039 MOVE R14 R3 + 0x7C280800, // 003A CALL R10 4 + 0xB82E0000, // 003B GETNGBL R11 K0 + 0x882C1701, // 003C GETMBR R11 R11 K1 + 0x8C2C1702, // 003D GETMET R11 R11 K2 + 0x58340017, // 003E LDCONST R13 K23 + 0x7C2C0400, // 003F CALL R11 2 + 0x882C0702, // 0040 GETMBR R11 R3 K2 + 0x4C300000, // 0041 LDNIL R12 + 0x202C160C, // 0042 NE R11 R11 R12 + 0x782E0005, // 0043 JMPF R11 #004A + 0x602C0008, // 0044 GETGBL R11 G8 + 0x88300702, // 0045 GETMBR R12 R3 K2 + 0x7C2C0200, // 0046 CALL R11 1 + 0x002E300B, // 0047 ADD R11 K24 R11 + 0x002C1719, // 0048 ADD R11 R11 K25 + 0x70020000, // 0049 JMP #004B + 0x582C001A, // 004A LDCONST R11 K26 + 0xB8323600, // 004B GETNGBL R12 K27 + 0x8C301902, // 004C GETMET R12 R12 K2 + 0x60380018, // 004D GETGBL R14 G24 + 0x583C001C, // 004E LDCONST R15 K28 + 0x88400315, // 004F GETMBR R16 R1 K21 + 0x8840211D, // 0050 GETMBR R16 R16 K29 + 0x5C441200, // 0051 MOVE R17 R9 + 0x78220001, // 0052 JMPF R8 #0055 + 0x5C481000, // 0053 MOVE R18 R8 + 0x70020000, // 0054 JMP #0056 + 0x5848001A, // 0055 LDCONST R18 K26 + 0x5C4C1600, // 0056 MOVE R19 R11 + 0x7C380A00, // 0057 CALL R14 5 + 0x583C001E, // 0058 LDCONST R15 K30 + 0x7C300600, // 0059 CALL R12 3 + 0x4C300000, // 005A LDNIL R12 + 0x900E040C, // 005B SETMBR R3 K2 R12 + 0x60300015, // 005C GETGBL R12 G21 + 0x5436001F, // 005D LDINT R13 32 + 0x7C300200, // 005E CALL R12 1 + 0x50340200, // 005F LDBOOL R13 1 0 + 0x1C34140D, // 0060 EQ R13 R10 R13 + 0x74360004, // 0061 JMPT R13 #0067 + 0x88340710, // 0062 GETMBR R13 R3 K16 + 0xB83A0000, // 0063 GETNGBL R14 K0 + 0x88381D1F, // 0064 GETMBR R14 R14 K31 + 0x1C341A0E, // 0065 EQ R13 R13 R14 + 0x7836001B, // 0066 JMPF R13 #0083 + 0xB8360000, // 0067 GETNGBL R13 K0 + 0x88341B1F, // 0068 GETMBR R13 R13 K31 + 0x900E200D, // 0069 SETMBR R3 K16 R13 + 0x8C340120, // 006A GETMET R13 R0 K32 + 0x5C3C1800, // 006B MOVE R15 R12 + 0x5C400600, // 006C MOVE R16 R3 + 0x4C440000, // 006D LDNIL R17 + 0x7C340800, // 006E CALL R13 4 + 0x88340B0B, // 006F GETMBR R13 R5 K11 + 0x8C341B21, // 0070 GETMET R13 R13 K33 + 0x5C3C1800, // 0071 MOVE R15 R12 + 0x7C340400, // 0072 CALL R13 2 + 0xB8363600, // 0073 GETNGBL R13 K27 + 0x8C341B22, // 0074 GETMET R13 R13 K34 + 0x583C001E, // 0075 LDCONST R15 K30 + 0x7C340400, // 0076 CALL R13 2 + 0x78360009, // 0077 JMPF R13 #0082 + 0xB8363600, // 0078 GETNGBL R13 K27 + 0x8C341B02, // 0079 GETMET R13 R13 K2 + 0x603C0018, // 007A GETGBL R15 G24 + 0x58400023, // 007B LDCONST R16 K35 + 0x88440315, // 007C GETMBR R17 R1 K21 + 0x8844231D, // 007D GETMBR R17 R17 K29 + 0x88480324, // 007E GETMBR R18 R1 K36 + 0x7C3C0600, // 007F CALL R15 3 + 0x5840001E, // 0080 LDCONST R16 K30 + 0x7C340600, // 0081 CALL R13 3 + 0x70020052, // 0082 JMP #00D6 + 0x4C340000, // 0083 LDNIL R13 + 0x2034140D, // 0084 NE R13 R10 R13 + 0x78360022, // 0085 JMPF R13 #00A9 + 0x8C340120, // 0086 GETMET R13 R0 K32 + 0x5C3C1800, // 0087 MOVE R15 R12 + 0x5C400600, // 0088 MOVE R16 R3 + 0x5C441400, // 0089 MOVE R17 R10 + 0x7C340800, // 008A CALL R13 4 + 0x88340B0B, // 008B GETMBR R13 R5 K11 + 0x8C341B21, // 008C GETMET R13 R13 K33 + 0x5C3C1800, // 008D MOVE R15 R12 + 0x7C340400, // 008E CALL R13 2 + 0xB8360000, // 008F GETNGBL R13 K0 + 0x8C341B12, // 0090 GETMET R13 R13 K18 + 0x883C070E, // 0091 GETMBR R15 R3 K14 + 0x8840070F, // 0092 GETMBR R16 R3 K15 + 0x7C340600, // 0093 CALL R13 3 + 0x5C201A00, // 0094 MOVE R8 R13 + 0x5C341000, // 0095 MOVE R13 R8 + 0x74360000, // 0096 JMPT R13 #0098 + 0x5820001A, // 0097 LDCONST R8 K26 + 0xB8363600, // 0098 GETNGBL R13 K27 + 0x8C341B22, // 0099 GETMET R13 R13 K34 + 0x583C001E, // 009A LDCONST R15 K30 + 0x7C340400, // 009B CALL R13 2 + 0x7836000A, // 009C JMPF R13 #00A8 + 0xB8363600, // 009D GETNGBL R13 K27 + 0x8C341B02, // 009E GETMET R13 R13 K2 + 0x603C0018, // 009F GETGBL R15 G24 + 0x58400025, // 00A0 LDCONST R16 K37 + 0x88440315, // 00A1 GETMBR R17 R1 K21 + 0x8844231D, // 00A2 GETMBR R17 R17 K29 + 0x5C480600, // 00A3 MOVE R18 R3 + 0x5C4C1000, // 00A4 MOVE R19 R8 + 0x7C3C0800, // 00A5 CALL R15 4 + 0x5840001E, // 00A6 LDCONST R16 K30 + 0x7C340600, // 00A7 CALL R13 3 + 0x7002002C, // 00A8 JMP #00D6 + 0x88340710, // 00A9 GETMBR R13 R3 K16 + 0x4C380000, // 00AA LDNIL R14 + 0x20341A0E, // 00AB NE R13 R13 R14 + 0x78360019, // 00AC JMPF R13 #00C7 + 0x8C340120, // 00AD GETMET R13 R0 K32 + 0x5C3C1800, // 00AE MOVE R15 R12 + 0x5C400600, // 00AF MOVE R16 R3 + 0x4C440000, // 00B0 LDNIL R17 + 0x7C340800, // 00B1 CALL R13 4 + 0x88340B0B, // 00B2 GETMBR R13 R5 K11 + 0x8C341B21, // 00B3 GETMET R13 R13 K33 + 0x5C3C1800, // 00B4 MOVE R15 R12 + 0x7C340400, // 00B5 CALL R13 2 + 0xB8363600, // 00B6 GETNGBL R13 K27 + 0x8C341B22, // 00B7 GETMET R13 R13 K34 + 0x583C001E, // 00B8 LDCONST R15 K30 + 0x7C340400, // 00B9 CALL R13 2 + 0x7836000A, // 00BA JMPF R13 #00C6 + 0xB8363600, // 00BB GETNGBL R13 K27 + 0x8C341B02, // 00BC GETMET R13 R13 K2 + 0x603C0018, // 00BD GETGBL R15 G24 + 0x58400026, // 00BE LDCONST R16 K38 + 0x88440315, // 00BF GETMBR R17 R1 K21 + 0x8844231D, // 00C0 GETMBR R17 R17 K29 + 0x88480710, // 00C1 GETMBR R18 R3 K16 + 0x884C0324, // 00C2 GETMBR R19 R1 K36 + 0x7C3C0800, // 00C3 CALL R15 4 + 0x5840001E, // 00C4 LDCONST R16 K30 + 0x7C340600, // 00C5 CALL R13 3 + 0x7002000E, // 00C6 JMP #00D6 + 0xB8363600, // 00C7 GETNGBL R13 K27 + 0x8C341B22, // 00C8 GETMET R13 R13 K34 + 0x583C001E, // 00C9 LDCONST R15 K30 + 0x7C340400, // 00CA CALL R13 2 + 0x78360009, // 00CB JMPF R13 #00D6 + 0xB8363600, // 00CC GETNGBL R13 K27 + 0x8C341B02, // 00CD GETMET R13 R13 K2 + 0x603C0018, // 00CE GETGBL R15 G24 + 0x58400027, // 00CF LDCONST R16 K39 + 0x88440315, // 00D0 GETMBR R17 R1 K21 + 0x8844231D, // 00D1 GETMBR R17 R17 K29 + 0x88480324, // 00D2 GETMBR R18 R1 K36 + 0x7C3C0600, // 00D3 CALL R15 3 + 0x5840001E, // 00D4 LDCONST R16 K30 + 0x7C340600, // 00D5 CALL R13 3 + 0x7001FF47, // 00D6 JMP #001F + 0x58180028, // 00D7 LDCONST R6 K40 + 0xAC180200, // 00D8 CATCH R6 1 0 + 0xB0080000, // 00D9 RAISE 2 R0 R0 + 0x6018000C, // 00DA GETGBL R6 G12 + 0x881C0B0B, // 00DB GETMBR R7 R5 K11 + 0x7C180200, // 00DC CALL R6 1 + 0x24180D29, // 00DD GT R6 R6 K41 + 0x781A0004, // 00DE JMPF R6 #00E4 + 0x8C18012A, // 00DF GETMET R6 R0 K42 + 0x5C200200, // 00E0 MOVE R8 R1 + 0x5C240A00, // 00E1 MOVE R9 R5 + 0x7C180600, // 00E2 CALL R6 3 + 0x70020001, // 00E3 JMP #00E6 + 0x50180000, // 00E4 LDBOOL R6 0 0 + 0x80040C00, // 00E5 RET 1 R6 + 0x50180200, // 00E6 LDBOOL R6 1 0 + 0x80040C00, // 00E7 RET 1 R6 + 0x80000000, // 00E8 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: process_read_request ********************************************************************/ -be_local_closure(Matter_IM_expire_sendqueue, /* name */ +be_local_closure(Matter_IM_process_read_request, /* name */ be_nested_proto( - 6, /* nstack */ - 1, /* argc */ + 9, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_const_int(0), - /* K1 */ be_nested_str_weak(send_queue), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(time_reached), - /* K4 */ be_nested_str_weak(expiration), - /* K5 */ be_nested_str_weak(reached_timeout), - /* K6 */ be_nested_str_weak(remove), - /* K7 */ be_const_int(1), + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(profiler), + /* K2 */ be_nested_str_weak(log), + /* K3 */ be_nested_str_weak(read_request_start), + /* K4 */ be_nested_str_weak(ReadRequestMessage), + /* K5 */ be_nested_str_weak(from_TLV), + /* K6 */ be_nested_str_weak(attributes_requests), + /* K7 */ be_nested_str_weak(_inner_process_read_request), + /* K8 */ be_nested_str_weak(session), + /* K9 */ be_nested_str_weak(send_report_data), }), - be_str_weak(expire_sendqueue), + be_str_weak(process_read_request), &be_const_str_solidified, - ( &(const binstruction[24]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0x6008000C, // 0001 GETGBL R2 G12 - 0x880C0101, // 0002 GETMBR R3 R0 K1 - 0x7C080200, // 0003 CALL R2 1 - 0x14080202, // 0004 LT R2 R1 R2 - 0x780A000F, // 0005 JMPF R2 #0016 - 0x88080101, // 0006 GETMBR R2 R0 K1 - 0x94080401, // 0007 GETIDX R2 R2 R1 - 0xB80E0400, // 0008 GETNGBL R3 K2 - 0x8C0C0703, // 0009 GETMET R3 R3 K3 - 0x88140504, // 000A GETMBR R5 R2 K4 - 0x7C0C0400, // 000B CALL R3 2 - 0x780E0006, // 000C JMPF R3 #0014 - 0x8C0C0505, // 000D GETMET R3 R2 K5 - 0x7C0C0200, // 000E CALL R3 1 - 0x880C0101, // 000F GETMBR R3 R0 K1 - 0x8C0C0706, // 0010 GETMET R3 R3 K6 - 0x5C140200, // 0011 MOVE R5 R1 - 0x7C0C0400, // 0012 CALL R3 2 - 0x70020000, // 0013 JMP #0015 - 0x00040307, // 0014 ADD R1 R1 K7 - 0x7001FFEA, // 0015 JMP #0001 - 0x4C080000, // 0016 LDNIL R2 - 0x80040400, // 0017 RET 1 R2 + ( &(const binstruction[26]) { /* code */ + 0xB80E0000, // 0000 GETNGBL R3 K0 + 0x880C0701, // 0001 GETMBR R3 R3 K1 + 0x8C0C0702, // 0002 GETMET R3 R3 K2 + 0x58140003, // 0003 LDCONST R5 K3 + 0x7C0C0400, // 0004 CALL R3 2 + 0xB80E0000, // 0005 GETNGBL R3 K0 + 0x8C0C0704, // 0006 GETMET R3 R3 K4 + 0x7C0C0200, // 0007 CALL R3 1 + 0x8C0C0705, // 0008 GETMET R3 R3 K5 + 0x5C140400, // 0009 MOVE R5 R2 + 0x7C0C0400, // 000A CALL R3 2 + 0x88100706, // 000B GETMBR R4 R3 K6 + 0x4C140000, // 000C LDNIL R5 + 0x20100805, // 000D NE R4 R4 R5 + 0x78120008, // 000E JMPF R4 #0018 + 0x8C100107, // 000F GETMET R4 R0 K7 + 0x88180308, // 0010 GETMBR R6 R1 K8 + 0x5C1C0600, // 0011 MOVE R7 R3 + 0x5C200200, // 0012 MOVE R8 R1 + 0x7C100800, // 0013 CALL R4 4 + 0x8C140109, // 0014 GETMET R5 R0 K9 + 0x5C1C0200, // 0015 MOVE R7 R1 + 0x5C200800, // 0016 MOVE R8 R4 + 0x7C140600, // 0017 CALL R5 3 + 0x50100200, // 0018 LDBOOL R4 1 0 + 0x80040800, // 0019 RET 1 R4 }) ) ); @@ -63,11 +1197,11 @@ be_local_closure(Matter_IM_expire_sendqueue, /* name */ /******************************************************************** -** Solidified function: process_invoke_request +** Solidified function: send_invoke_response ********************************************************************/ -be_local_closure(Matter_IM_process_invoke_request, /* name */ +be_local_closure(Matter_IM_send_invoke_response, /* name */ be_nested_proto( - 21, /* nstack */ + 9, /* nstack */ 3, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -75,325 +1209,24 @@ be_local_closure(Matter_IM_process_invoke_request, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[44]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(Path), - /* K3 */ be_nested_str_weak(InvokeRequestMessage), - /* K4 */ be_nested_str_weak(from_TLV), - /* K5 */ be_nested_str_weak(invoke_requests), - /* K6 */ be_nested_str_weak(InvokeResponseMessage), - /* K7 */ be_nested_str_weak(suppress_response), - /* K8 */ be_nested_str_weak(invoke_responses), - /* K9 */ be_nested_str_weak(endpoint), - /* K10 */ be_nested_str_weak(command_path), - /* K11 */ be_nested_str_weak(cluster), - /* K12 */ be_nested_str_weak(command), - /* K13 */ be_nested_str_weak(status), - /* K14 */ be_nested_str_weak(UNSUPPORTED_COMMAND), - /* K15 */ be_nested_str_weak(get_command_name), - /* K16 */ be_nested_str_weak(device), - /* K17 */ be_nested_str_weak(invoke_request), - /* K18 */ be_nested_str_weak(session), - /* K19 */ be_nested_str_weak(command_fields), - /* K20 */ be_nested_str_weak(log), - /* K21 */ be_nested_str_weak(_X28), - /* K22 */ be_nested_str_weak(_X29_X20), - /* K23 */ be_nested_str_weak(), - /* K24 */ be_nested_str_weak(tasmota), - /* K25 */ be_nested_str_weak(format), - /* K26 */ be_nested_str_weak(MTR_X3A_X20_X3ECommand_X20_X20_X20_X28_X256i_X29_X20_X25s_X20_X25s_X20_X25s), - /* K27 */ be_nested_str_weak(local_session_id), - /* K28 */ be_const_int(2), - /* K29 */ be_nested_str_weak(InvokeResponseIB), - /* K30 */ be_nested_str_weak(SUCCESS), - /* K31 */ be_nested_str_weak(CommandStatusIB), - /* K32 */ be_nested_str_weak(CommandPathIB), - /* K33 */ be_nested_str_weak(StatusIB), - /* K34 */ be_nested_str_weak(push), - /* K35 */ be_nested_str_weak(MTR_X3A_X20_X3CReplied_X20_X20_X20_X28_X256i_X29_X20OK_X20exch_X3D_X25i), - /* K36 */ be_nested_str_weak(exchange_id), - /* K37 */ be_nested_str_weak(CommandDataIB), - /* K38 */ be_nested_str_weak(MTR_X3A_X20_X3CReplied_X20_X20_X20_X28_X256i_X29_X20_X25s_X20_X25s), - /* K39 */ be_nested_str_weak(MTR_X3A_X20_X3CReplied_X20_X20_X20_X28_X256i_X29_X20Status_X3D0x_X2502X_X20exch_X3D_X25i), - /* K40 */ be_nested_str_weak(MTR_X3A_X20_Ignore_X20_X20_X20_X20_X28_X256i_X29_X20exch_X3D_X25i), - /* K41 */ be_nested_str_weak(stop_iteration), - /* K42 */ be_const_int(0), - /* K43 */ be_nested_str_weak(send_invoke_response), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(send_queue), + /* K1 */ be_nested_str_weak(push), + /* K2 */ be_nested_str_weak(matter), + /* K3 */ be_nested_str_weak(IM_InvokeResponse), }), - be_str_weak(process_invoke_request), + be_str_weak(send_invoke_response), &be_const_str_solidified, - ( &(const binstruction[270]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x8C100902, // 0002 GETMET R4 R4 K2 - 0x7C100200, // 0003 CALL R4 1 - 0xB8160200, // 0004 GETNGBL R5 K1 - 0x8C140B03, // 0005 GETMET R5 R5 K3 - 0x7C140200, // 0006 CALL R5 1 - 0x8C140B04, // 0007 GETMET R5 R5 K4 - 0x5C1C0400, // 0008 MOVE R7 R2 - 0x7C140400, // 0009 CALL R5 2 - 0x88180B05, // 000A GETMBR R6 R5 K5 - 0x4C1C0000, // 000B LDNIL R7 - 0x20180C07, // 000C NE R6 R6 R7 - 0x781A00FE, // 000D JMPF R6 #010D - 0xB81A0200, // 000E GETNGBL R6 K1 - 0x8C180D06, // 000F GETMET R6 R6 K6 - 0x7C180200, // 0010 CALL R6 1 - 0x501C0000, // 0011 LDBOOL R7 0 0 - 0x901A0E07, // 0012 SETMBR R6 K7 R7 - 0x601C0012, // 0013 GETGBL R7 G18 - 0x7C1C0000, // 0014 CALL R7 0 - 0x901A1007, // 0015 SETMBR R6 K8 R7 - 0x601C0010, // 0016 GETGBL R7 G16 - 0x88200B05, // 0017 GETMBR R8 R5 K5 - 0x7C1C0200, // 0018 CALL R7 1 - 0xA80200E1, // 0019 EXBLK 0 #00FC - 0x5C200E00, // 001A MOVE R8 R7 - 0x7C200000, // 001B CALL R8 0 - 0x8824110A, // 001C GETMBR R9 R8 K10 - 0x88241309, // 001D GETMBR R9 R9 K9 - 0x90121209, // 001E SETMBR R4 K9 R9 - 0x8824110A, // 001F GETMBR R9 R8 K10 - 0x8824130B, // 0020 GETMBR R9 R9 K11 - 0x90121609, // 0021 SETMBR R4 K11 R9 - 0x8824110A, // 0022 GETMBR R9 R8 K10 - 0x8824130C, // 0023 GETMBR R9 R9 K12 - 0x90121809, // 0024 SETMBR R4 K12 R9 - 0xB8260200, // 0025 GETNGBL R9 K1 - 0x8824130E, // 0026 GETMBR R9 R9 K14 - 0x90121A09, // 0027 SETMBR R4 K13 R9 - 0xB8260200, // 0028 GETNGBL R9 K1 - 0x8C24130F, // 0029 GETMET R9 R9 K15 - 0x882C090B, // 002A GETMBR R11 R4 K11 - 0x8830090C, // 002B GETMBR R12 R4 K12 - 0x7C240600, // 002C CALL R9 3 - 0x88280110, // 002D GETMBR R10 R0 K16 - 0x8C281511, // 002E GETMET R10 R10 K17 - 0x88300312, // 002F GETMBR R12 R1 K18 - 0x88341113, // 0030 GETMBR R13 R8 K19 - 0x5C380800, // 0031 MOVE R14 R4 - 0x7C280800, // 0032 CALL R10 4 - 0x882C0914, // 0033 GETMBR R11 R4 K20 - 0x4C300000, // 0034 LDNIL R12 - 0x202C160C, // 0035 NE R11 R11 R12 - 0x782E0005, // 0036 JMPF R11 #003D - 0x602C0008, // 0037 GETGBL R11 G8 - 0x88300914, // 0038 GETMBR R12 R4 K20 - 0x7C2C0200, // 0039 CALL R11 1 - 0x002E2A0B, // 003A ADD R11 K21 R11 - 0x002C1716, // 003B ADD R11 R11 K22 - 0x70020000, // 003C JMP #003E - 0x582C0017, // 003D LDCONST R11 K23 - 0xB8323000, // 003E GETNGBL R12 K24 - 0x8C301914, // 003F GETMET R12 R12 K20 - 0x8C380719, // 0040 GETMET R14 R3 K25 - 0x5840001A, // 0041 LDCONST R16 K26 - 0x88440312, // 0042 GETMBR R17 R1 K18 - 0x8844231B, // 0043 GETMBR R17 R17 K27 - 0x60480008, // 0044 GETGBL R18 G8 - 0x5C4C0800, // 0045 MOVE R19 R4 - 0x7C480200, // 0046 CALL R18 1 - 0x78260001, // 0047 JMPF R9 #004A - 0x5C4C1200, // 0048 MOVE R19 R9 - 0x70020000, // 0049 JMP #004B - 0x584C0017, // 004A LDCONST R19 K23 - 0x5C501600, // 004B MOVE R20 R11 - 0x7C380C00, // 004C CALL R14 6 - 0x583C001C, // 004D LDCONST R15 K28 - 0x7C300600, // 004E CALL R12 3 - 0x4C300000, // 004F LDNIL R12 - 0x9012280C, // 0050 SETMBR R4 K20 R12 - 0xB8320200, // 0051 GETNGBL R12 K1 - 0x8C30191D, // 0052 GETMET R12 R12 K29 - 0x7C300200, // 0053 CALL R12 1 - 0x50340200, // 0054 LDBOOL R13 1 0 - 0x1C34140D, // 0055 EQ R13 R10 R13 - 0x74360004, // 0056 JMPT R13 #005C - 0x8834090D, // 0057 GETMBR R13 R4 K13 - 0xB83A0200, // 0058 GETNGBL R14 K1 - 0x88381D1E, // 0059 GETMBR R14 R14 K30 - 0x1C341A0E, // 005A EQ R13 R13 R14 - 0x7836002D, // 005B JMPF R13 #008A - 0xB8360200, // 005C GETNGBL R13 K1 - 0x8C341B1F, // 005D GETMET R13 R13 K31 - 0x7C340200, // 005E CALL R13 1 - 0x90321A0D, // 005F SETMBR R12 K13 R13 - 0x8834190D, // 0060 GETMBR R13 R12 K13 - 0xB83A0200, // 0061 GETNGBL R14 K1 - 0x8C381D20, // 0062 GETMET R14 R14 K32 - 0x7C380200, // 0063 CALL R14 1 - 0x9036140E, // 0064 SETMBR R13 K10 R14 - 0x8834190D, // 0065 GETMBR R13 R12 K13 - 0x88341B0A, // 0066 GETMBR R13 R13 K10 - 0x88380909, // 0067 GETMBR R14 R4 K9 - 0x9036120E, // 0068 SETMBR R13 K9 R14 - 0x8834190D, // 0069 GETMBR R13 R12 K13 - 0x88341B0A, // 006A GETMBR R13 R13 K10 - 0x8838090B, // 006B GETMBR R14 R4 K11 - 0x9036160E, // 006C SETMBR R13 K11 R14 - 0x8834190D, // 006D GETMBR R13 R12 K13 - 0x88341B0A, // 006E GETMBR R13 R13 K10 - 0x8838090C, // 006F GETMBR R14 R4 K12 - 0x9036180E, // 0070 SETMBR R13 K12 R14 - 0x8834190D, // 0071 GETMBR R13 R12 K13 - 0xB83A0200, // 0072 GETNGBL R14 K1 - 0x8C381D21, // 0073 GETMET R14 R14 K33 - 0x7C380200, // 0074 CALL R14 1 - 0x90361A0E, // 0075 SETMBR R13 K13 R14 - 0x8834190D, // 0076 GETMBR R13 R12 K13 - 0x88341B0D, // 0077 GETMBR R13 R13 K13 - 0xB83A0200, // 0078 GETNGBL R14 K1 - 0x88381D1E, // 0079 GETMBR R14 R14 K30 - 0x90361A0E, // 007A SETMBR R13 K13 R14 - 0x88340D08, // 007B GETMBR R13 R6 K8 - 0x8C341B22, // 007C GETMET R13 R13 K34 - 0x5C3C1800, // 007D MOVE R15 R12 - 0x7C340400, // 007E CALL R13 2 - 0xB8363000, // 007F GETNGBL R13 K24 - 0x8C341B14, // 0080 GETMET R13 R13 K20 - 0x8C3C0719, // 0081 GETMET R15 R3 K25 - 0x58440023, // 0082 LDCONST R17 K35 - 0x88480312, // 0083 GETMBR R18 R1 K18 - 0x8848251B, // 0084 GETMBR R18 R18 K27 - 0x884C0324, // 0085 GETMBR R19 R1 K36 - 0x7C3C0800, // 0086 CALL R15 4 - 0x5840001C, // 0087 LDCONST R16 K28 - 0x7C340600, // 0088 CALL R13 3 - 0x70020070, // 0089 JMP #00FB - 0x4C340000, // 008A LDNIL R13 - 0x2034140D, // 008B NE R13 R10 R13 - 0x78360031, // 008C JMPF R13 #00BF - 0xB8360200, // 008D GETNGBL R13 K1 - 0x8C341B25, // 008E GETMET R13 R13 K37 - 0x7C340200, // 008F CALL R13 1 - 0x9032180D, // 0090 SETMBR R12 K12 R13 - 0x8834190C, // 0091 GETMBR R13 R12 K12 - 0xB83A0200, // 0092 GETNGBL R14 K1 - 0x8C381D20, // 0093 GETMET R14 R14 K32 - 0x7C380200, // 0094 CALL R14 1 - 0x9036140E, // 0095 SETMBR R13 K10 R14 - 0x8834190C, // 0096 GETMBR R13 R12 K12 - 0x88341B0A, // 0097 GETMBR R13 R13 K10 - 0x88380909, // 0098 GETMBR R14 R4 K9 - 0x9036120E, // 0099 SETMBR R13 K9 R14 - 0x8834190C, // 009A GETMBR R13 R12 K12 - 0x88341B0A, // 009B GETMBR R13 R13 K10 - 0x8838090B, // 009C GETMBR R14 R4 K11 - 0x9036160E, // 009D SETMBR R13 K11 R14 - 0x8834190C, // 009E GETMBR R13 R12 K12 - 0x88341B0A, // 009F GETMBR R13 R13 K10 - 0x8838090C, // 00A0 GETMBR R14 R4 K12 - 0x9036180E, // 00A1 SETMBR R13 K12 R14 - 0x8834190C, // 00A2 GETMBR R13 R12 K12 - 0x9036260A, // 00A3 SETMBR R13 K19 R10 - 0x88340D08, // 00A4 GETMBR R13 R6 K8 - 0x8C341B22, // 00A5 GETMET R13 R13 K34 - 0x5C3C1800, // 00A6 MOVE R15 R12 - 0x7C340400, // 00A7 CALL R13 2 - 0xB8360200, // 00A8 GETNGBL R13 K1 - 0x8C341B0F, // 00A9 GETMET R13 R13 K15 - 0x883C090B, // 00AA GETMBR R15 R4 K11 - 0x8840090C, // 00AB GETMBR R16 R4 K12 - 0x7C340600, // 00AC CALL R13 3 - 0x5C241A00, // 00AD MOVE R9 R13 - 0xB8363000, // 00AE GETNGBL R13 K24 - 0x8C341B14, // 00AF GETMET R13 R13 K20 - 0x8C3C0719, // 00B0 GETMET R15 R3 K25 - 0x58440026, // 00B1 LDCONST R17 K38 - 0x88480312, // 00B2 GETMBR R18 R1 K18 - 0x8848251B, // 00B3 GETMBR R18 R18 K27 - 0x604C0008, // 00B4 GETGBL R19 G8 - 0x5C500800, // 00B5 MOVE R20 R4 - 0x7C4C0200, // 00B6 CALL R19 1 - 0x78260001, // 00B7 JMPF R9 #00BA - 0x5C501200, // 00B8 MOVE R20 R9 - 0x70020000, // 00B9 JMP #00BB - 0x58500017, // 00BA LDCONST R20 K23 - 0x7C3C0A00, // 00BB CALL R15 5 - 0x5840001C, // 00BC LDCONST R16 K28 - 0x7C340600, // 00BD CALL R13 3 - 0x7002003B, // 00BE JMP #00FB - 0x8834090D, // 00BF GETMBR R13 R4 K13 - 0x4C380000, // 00C0 LDNIL R14 - 0x20341A0E, // 00C1 NE R13 R13 R14 - 0x7836002D, // 00C2 JMPF R13 #00F1 - 0xB8360200, // 00C3 GETNGBL R13 K1 - 0x8C341B1F, // 00C4 GETMET R13 R13 K31 - 0x7C340200, // 00C5 CALL R13 1 - 0x90321A0D, // 00C6 SETMBR R12 K13 R13 - 0x8834190D, // 00C7 GETMBR R13 R12 K13 - 0xB83A0200, // 00C8 GETNGBL R14 K1 - 0x8C381D20, // 00C9 GETMET R14 R14 K32 - 0x7C380200, // 00CA CALL R14 1 - 0x9036140E, // 00CB SETMBR R13 K10 R14 - 0x8834190D, // 00CC GETMBR R13 R12 K13 - 0x88341B0A, // 00CD GETMBR R13 R13 K10 - 0x88380909, // 00CE GETMBR R14 R4 K9 - 0x9036120E, // 00CF SETMBR R13 K9 R14 - 0x8834190D, // 00D0 GETMBR R13 R12 K13 - 0x88341B0A, // 00D1 GETMBR R13 R13 K10 - 0x8838090B, // 00D2 GETMBR R14 R4 K11 - 0x9036160E, // 00D3 SETMBR R13 K11 R14 - 0x8834190D, // 00D4 GETMBR R13 R12 K13 - 0x88341B0A, // 00D5 GETMBR R13 R13 K10 - 0x8838090C, // 00D6 GETMBR R14 R4 K12 - 0x9036180E, // 00D7 SETMBR R13 K12 R14 - 0x8834190D, // 00D8 GETMBR R13 R12 K13 - 0xB83A0200, // 00D9 GETNGBL R14 K1 - 0x8C381D21, // 00DA GETMET R14 R14 K33 - 0x7C380200, // 00DB CALL R14 1 - 0x90361A0E, // 00DC SETMBR R13 K13 R14 - 0x8834190D, // 00DD GETMBR R13 R12 K13 - 0x88341B0D, // 00DE GETMBR R13 R13 K13 - 0x8838090D, // 00DF GETMBR R14 R4 K13 - 0x90361A0E, // 00E0 SETMBR R13 K13 R14 - 0x88340D08, // 00E1 GETMBR R13 R6 K8 - 0x8C341B22, // 00E2 GETMET R13 R13 K34 - 0x5C3C1800, // 00E3 MOVE R15 R12 - 0x7C340400, // 00E4 CALL R13 2 - 0xB8363000, // 00E5 GETNGBL R13 K24 - 0x8C341B14, // 00E6 GETMET R13 R13 K20 - 0x8C3C0719, // 00E7 GETMET R15 R3 K25 - 0x58440027, // 00E8 LDCONST R17 K39 - 0x88480312, // 00E9 GETMBR R18 R1 K18 - 0x8848251B, // 00EA GETMBR R18 R18 K27 - 0x884C090D, // 00EB GETMBR R19 R4 K13 - 0x88500324, // 00EC GETMBR R20 R1 K36 - 0x7C3C0A00, // 00ED CALL R15 5 - 0x5840001C, // 00EE LDCONST R16 K28 - 0x7C340600, // 00EF CALL R13 3 - 0x70020009, // 00F0 JMP #00FB - 0xB8363000, // 00F1 GETNGBL R13 K24 - 0x8C341B14, // 00F2 GETMET R13 R13 K20 - 0x8C3C0719, // 00F3 GETMET R15 R3 K25 - 0x58440028, // 00F4 LDCONST R17 K40 - 0x88480312, // 00F5 GETMBR R18 R1 K18 - 0x8848251B, // 00F6 GETMBR R18 R18 K27 - 0x884C0324, // 00F7 GETMBR R19 R1 K36 - 0x7C3C0800, // 00F8 CALL R15 4 - 0x5840001C, // 00F9 LDCONST R16 K28 - 0x7C340600, // 00FA CALL R13 3 - 0x7001FF1D, // 00FB JMP #001A - 0x581C0029, // 00FC LDCONST R7 K41 - 0xAC1C0200, // 00FD CATCH R7 1 0 - 0xB0080000, // 00FE RAISE 2 R0 R0 - 0x601C000C, // 00FF GETGBL R7 G12 - 0x88200D08, // 0100 GETMBR R8 R6 K8 - 0x7C1C0200, // 0101 CALL R7 1 - 0x241C0F2A, // 0102 GT R7 R7 K42 - 0x781E0004, // 0103 JMPF R7 #0109 - 0x8C1C012B, // 0104 GETMET R7 R0 K43 - 0x5C240200, // 0105 MOVE R9 R1 - 0x5C280C00, // 0106 MOVE R10 R6 - 0x7C1C0600, // 0107 CALL R7 3 - 0x70020001, // 0108 JMP #010B - 0x501C0000, // 0109 LDBOOL R7 0 0 - 0x80040E00, // 010A RET 1 R7 - 0x501C0200, // 010B LDBOOL R7 1 0 - 0x80040E00, // 010C RET 1 R7 - 0x80000000, // 010D RET 0 + ( &(const binstruction[ 9]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0xB8160400, // 0002 GETNGBL R5 K2 + 0x8C140B03, // 0003 GETMET R5 R5 K3 + 0x5C1C0200, // 0004 MOVE R7 R1 + 0x5C200400, // 0005 MOVE R8 R2 + 0x7C140600, // 0006 CALL R5 3 + 0x7C0C0400, // 0007 CALL R3 2 + 0x80000000, // 0008 RET 0 }) ) ); @@ -401,11 +1234,11 @@ be_local_closure(Matter_IM_process_invoke_request, /* name */ /******************************************************************** -** Solidified function: subscribe_request +** Solidified function: send_write_response ********************************************************************/ -be_local_closure(Matter_IM_subscribe_request, /* name */ +be_local_closure(Matter_IM_send_write_response, /* name */ be_nested_proto( - 19, /* nstack */ + 9, /* nstack */ 3, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -413,120 +1246,24 @@ be_local_closure(Matter_IM_subscribe_request, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[31]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(SubscribeRequestMessage), - /* K3 */ be_nested_str_weak(from_TLV), - /* K4 */ be_nested_str_weak(keep_subscriptions), - /* K5 */ be_nested_str_weak(subs_shop), - /* K6 */ be_nested_str_weak(remove_by_session), - /* K7 */ be_nested_str_weak(session), - /* K8 */ be_nested_str_weak(new_subscription), - /* K9 */ be_nested_str_weak(Path), - /* K10 */ be_nested_str_weak(attributes_requests), - /* K11 */ be_nested_str_weak(endpoint), - /* K12 */ be_nested_str_weak(cluster), - /* K13 */ be_nested_str_weak(attribute), - /* K14 */ be_nested_str_weak(push), - /* K15 */ be_nested_str_weak(stop_iteration), - /* K16 */ be_nested_str_weak(tasmota), - /* K17 */ be_nested_str_weak(log), - /* K18 */ be_nested_str_weak(format), - /* K19 */ be_nested_str_weak(MTR_X3A_X20_X3ESubscribe_X20_X28_X256i_X29_X20_X25s_X20_X28min_X3D_X25i_X2C_X20max_X3D_X25i_X2C_X20keep_X3D_X25i_X29_X20sub_X3D_X25i), - /* K20 */ be_nested_str_weak(local_session_id), - /* K21 */ be_nested_str_weak(concat), - /* K22 */ be_nested_str_weak(_X20), - /* K23 */ be_nested_str_weak(min_interval), - /* K24 */ be_nested_str_weak(max_interval), - /* K25 */ be_const_int(1), - /* K26 */ be_const_int(0), - /* K27 */ be_nested_str_weak(subscription_id), - /* K28 */ be_const_int(2), - /* K29 */ be_nested_str_weak(_inner_process_read_request), - /* K30 */ be_nested_str_weak(send_subscribe_response), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(send_queue), + /* K1 */ be_nested_str_weak(push), + /* K2 */ be_nested_str_weak(matter), + /* K3 */ be_nested_str_weak(IM_WriteResponse), }), - be_str_weak(subscribe_request), + be_str_weak(send_write_response), &be_const_str_solidified, - ( &(const binstruction[78]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x8C100902, // 0002 GETMET R4 R4 K2 - 0x7C100200, // 0003 CALL R4 1 - 0x8C100903, // 0004 GETMET R4 R4 K3 - 0x5C180400, // 0005 MOVE R6 R2 - 0x7C100400, // 0006 CALL R4 2 - 0x88140904, // 0007 GETMBR R5 R4 K4 - 0x74160003, // 0008 JMPT R5 #000D - 0x88140105, // 0009 GETMBR R5 R0 K5 - 0x8C140B06, // 000A GETMET R5 R5 K6 - 0x881C0307, // 000B GETMBR R7 R1 K7 - 0x7C140400, // 000C CALL R5 2 - 0x88140105, // 000D GETMBR R5 R0 K5 - 0x8C140B08, // 000E GETMET R5 R5 K8 - 0x881C0307, // 000F GETMBR R7 R1 K7 - 0x5C200800, // 0010 MOVE R8 R4 - 0x7C140600, // 0011 CALL R5 3 - 0x60180012, // 0012 GETGBL R6 G18 - 0x7C180000, // 0013 CALL R6 0 - 0xB81E0200, // 0014 GETNGBL R7 K1 - 0x8C1C0F09, // 0015 GETMET R7 R7 K9 - 0x7C1C0200, // 0016 CALL R7 1 - 0x60200010, // 0017 GETGBL R8 G16 - 0x8824090A, // 0018 GETMBR R9 R4 K10 - 0x7C200200, // 0019 CALL R8 1 - 0xA802000D, // 001A EXBLK 0 #0029 - 0x5C241000, // 001B MOVE R9 R8 - 0x7C240000, // 001C CALL R9 0 - 0x8828130B, // 001D GETMBR R10 R9 K11 - 0x901E160A, // 001E SETMBR R7 K11 R10 - 0x8828130C, // 001F GETMBR R10 R9 K12 - 0x901E180A, // 0020 SETMBR R7 K12 R10 - 0x8828130D, // 0021 GETMBR R10 R9 K13 - 0x901E1A0A, // 0022 SETMBR R7 K13 R10 - 0x8C280D0E, // 0023 GETMET R10 R6 K14 - 0x60300008, // 0024 GETGBL R12 G8 - 0x5C340E00, // 0025 MOVE R13 R7 - 0x7C300200, // 0026 CALL R12 1 - 0x7C280400, // 0027 CALL R10 2 - 0x7001FFF1, // 0028 JMP #001B - 0x5820000F, // 0029 LDCONST R8 K15 - 0xAC200200, // 002A CATCH R8 1 0 - 0xB0080000, // 002B RAISE 2 R0 R0 - 0xB8222000, // 002C GETNGBL R8 K16 - 0x8C201111, // 002D GETMET R8 R8 K17 - 0x8C280712, // 002E GETMET R10 R3 K18 - 0x58300013, // 002F LDCONST R12 K19 - 0x88340307, // 0030 GETMBR R13 R1 K7 - 0x88341B14, // 0031 GETMBR R13 R13 K20 - 0x8C380D15, // 0032 GETMET R14 R6 K21 - 0x58400016, // 0033 LDCONST R16 K22 - 0x7C380400, // 0034 CALL R14 2 - 0x883C0B17, // 0035 GETMBR R15 R5 K23 - 0x88400B18, // 0036 GETMBR R16 R5 K24 - 0x88440904, // 0037 GETMBR R17 R4 K4 - 0x78460001, // 0038 JMPF R17 #003B - 0x58440019, // 0039 LDCONST R17 K25 - 0x70020000, // 003A JMP #003C - 0x5844001A, // 003B LDCONST R17 K26 - 0x88480B1B, // 003C GETMBR R18 R5 K27 - 0x7C281000, // 003D CALL R10 8 - 0x582C001C, // 003E LDCONST R11 K28 - 0x7C200600, // 003F CALL R8 3 - 0x8C20011D, // 0040 GETMET R8 R0 K29 - 0x88280307, // 0041 GETMBR R10 R1 K7 - 0x5C2C0800, // 0042 MOVE R11 R4 - 0x50300200, // 0043 LDBOOL R12 1 0 - 0x7C200800, // 0044 CALL R8 4 - 0x88240B1B, // 0045 GETMBR R9 R5 K27 - 0x90223609, // 0046 SETMBR R8 K27 R9 - 0x8C24011E, // 0047 GETMET R9 R0 K30 - 0x5C2C0200, // 0048 MOVE R11 R1 - 0x5C301000, // 0049 MOVE R12 R8 - 0x5C340A00, // 004A MOVE R13 R5 - 0x7C240800, // 004B CALL R9 4 - 0x50240200, // 004C LDBOOL R9 1 0 - 0x80041200, // 004D RET 1 R9 + ( &(const binstruction[ 9]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0xB8160400, // 0002 GETNGBL R5 K2 + 0x8C140B03, // 0003 GETMET R5 R5 K3 + 0x5C1C0200, // 0004 MOVE R7 R1 + 0x5C200400, // 0005 MOVE R8 R2 + 0x7C140600, // 0006 CALL R5 3 + 0x7C0C0400, // 0007 CALL R3 2 + 0x80000000, // 0008 RET 0 }) ) ); @@ -538,7 +1275,7 @@ be_local_closure(Matter_IM_subscribe_request, /* name */ ********************************************************************/ be_local_closure(Matter_IM_process_write_request, /* name */ be_nested_proto( - 20, /* nstack */ + 19, /* nstack */ 3, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -546,7 +1283,7 @@ be_local_closure(Matter_IM_process_write_request, /* name */ 1, /* has sup protos */ ( &(const struct bproto*[ 2]) { be_nested_proto( - 19, /* nstack */ + 17, /* nstack */ 5, /* argc */ 0, /* varg */ 1, /* has upvals */ @@ -557,133 +1294,137 @@ be_local_closure(Matter_IM_process_write_request, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[26]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(get_attribute_name), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_nested_str_weak(_X20_X28), - /* K6 */ be_nested_str_weak(_X29), - /* K7 */ be_nested_str_weak(), - /* K8 */ be_nested_str_weak(status), - /* K9 */ be_nested_str_weak(UNSUPPORTED_WRITE), - /* K10 */ be_nested_str_weak(write_attribute), - /* K11 */ be_nested_str_weak(session), - /* K12 */ be_nested_str_weak(SUCCESS), - /* K13 */ be_nested_str_weak(AttributeStatusIB), - /* K14 */ be_nested_str_weak(path), - /* K15 */ be_nested_str_weak(AttributePathIB), - /* K16 */ be_nested_str_weak(StatusIB), - /* K17 */ be_nested_str_weak(endpoint), - /* K18 */ be_nested_str_weak(write_responses), - /* K19 */ be_nested_str_weak(push), - /* K20 */ be_nested_str_weak(tasmota), - /* K21 */ be_nested_str_weak(log), - /* K22 */ be_nested_str_weak(format), - /* K23 */ be_nested_str_weak(MTR_X3A_X20Write_Attr_X20_X25s_X25s_X20_X2D_X20STATUS_X3A_X200x_X2502X_X20_X25s), - /* K24 */ be_const_int(2), + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(get_attribute_name), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(_X20_X28), + /* K5 */ be_nested_str_weak(_X29), + /* K6 */ be_nested_str_weak(), + /* K7 */ be_nested_str_weak(status), + /* K8 */ be_nested_str_weak(UNSUPPORTED_WRITE), + /* K9 */ be_nested_str_weak(write_attribute), + /* K10 */ be_nested_str_weak(session), + /* K11 */ be_nested_str_weak(SUCCESS), + /* K12 */ be_nested_str_weak(AttributeStatusIB), + /* K13 */ be_nested_str_weak(path), + /* K14 */ be_nested_str_weak(AttributePathIB), + /* K15 */ be_nested_str_weak(StatusIB), + /* K16 */ be_nested_str_weak(endpoint), + /* K17 */ be_nested_str_weak(write_responses), + /* K18 */ be_nested_str_weak(push), + /* K19 */ be_nested_str_weak(tasmota), + /* K20 */ be_nested_str_weak(log), + /* K21 */ be_nested_str_weak(MTR_X3A_X20Write_Attr_X20_X25s_X25s_X20_X2D_X20STATUS_X3A_X200x_X2502X_X20_X25s), + /* K22 */ be_const_int(0), + /* K23 */ be_const_int(2), + /* K24 */ be_const_int(3), /* K25 */ be_nested_str_weak(MTR_X3A_X20Write_Attr_X20_X25s_X25s_X20_X2D_X20IGNORED), }), be_str_weak(write_single_attribute), &be_const_str_solidified, - ( &(const binstruction[97]) { /* code */ - 0xA4160000, // 0000 IMPORT R5 K0 - 0xB81A0200, // 0001 GETNGBL R6 K1 - 0x8C180D02, // 0002 GETMET R6 R6 K2 + ( &(const binstruction[101]) { /* code */ + 0xB8160000, // 0000 GETNGBL R5 K0 + 0x8C140B01, // 0001 GETMET R5 R5 K1 + 0x881C0502, // 0002 GETMBR R7 R2 K2 0x88200503, // 0003 GETMBR R8 R2 K3 - 0x88240504, // 0004 GETMBR R9 R2 K4 - 0x7C180600, // 0005 CALL R6 3 - 0x781A0002, // 0006 JMPF R6 #000A - 0x001E0A06, // 0007 ADD R7 K5 R6 - 0x001C0F06, // 0008 ADD R7 R7 K6 - 0x70020000, // 0009 JMP #000B - 0x581C0007, // 000A LDCONST R7 K7 - 0x5C180E00, // 000B MOVE R6 R7 - 0xB81E0200, // 000C GETNGBL R7 K1 - 0x881C0F09, // 000D GETMBR R7 R7 K9 - 0x900A1007, // 000E SETMBR R2 K8 R7 - 0x4C1C0000, // 000F LDNIL R7 - 0x201C0207, // 0010 NE R7 R1 R7 - 0x781E0006, // 0011 JMPF R7 #0019 - 0x8C1C030A, // 0012 GETMET R7 R1 K10 - 0x68240000, // 0013 GETUPV R9 U0 - 0x8824130B, // 0014 GETMBR R9 R9 K11 - 0x5C280400, // 0015 MOVE R10 R2 - 0x5C2C0600, // 0016 MOVE R11 R3 - 0x7C1C0800, // 0017 CALL R7 4 - 0x70020000, // 0018 JMP #001A - 0x4C1C0000, // 0019 LDNIL R7 - 0x781E0002, // 001A JMPF R7 #001E - 0xB8220200, // 001B GETNGBL R8 K1 - 0x8820110C, // 001C GETMBR R8 R8 K12 - 0x900A1008, // 001D SETMBR R2 K8 R8 - 0x88200508, // 001E GETMBR R8 R2 K8 - 0x4C240000, // 001F LDNIL R9 - 0x20201009, // 0020 NE R8 R8 R9 - 0x78220032, // 0021 JMPF R8 #0055 - 0x78120030, // 0022 JMPF R4 #0054 - 0xB8220200, // 0023 GETNGBL R8 K1 - 0x8C20110D, // 0024 GETMET R8 R8 K13 - 0x7C200200, // 0025 CALL R8 1 - 0xB8260200, // 0026 GETNGBL R9 K1 - 0x8C24130F, // 0027 GETMET R9 R9 K15 - 0x7C240200, // 0028 CALL R9 1 - 0x90221C09, // 0029 SETMBR R8 K14 R9 - 0xB8260200, // 002A GETNGBL R9 K1 - 0x8C241310, // 002B GETMET R9 R9 K16 - 0x7C240200, // 002C CALL R9 1 - 0x90221009, // 002D SETMBR R8 K8 R9 - 0x8824110E, // 002E GETMBR R9 R8 K14 - 0x88280511, // 002F GETMBR R10 R2 K17 - 0x9026220A, // 0030 SETMBR R9 K17 R10 - 0x8824110E, // 0031 GETMBR R9 R8 K14 - 0x88280503, // 0032 GETMBR R10 R2 K3 - 0x9026060A, // 0033 SETMBR R9 K3 R10 - 0x8824110E, // 0034 GETMBR R9 R8 K14 - 0x88280504, // 0035 GETMBR R10 R2 K4 - 0x9026080A, // 0036 SETMBR R9 K4 R10 - 0x88241108, // 0037 GETMBR R9 R8 K8 - 0x88280508, // 0038 GETMBR R10 R2 K8 - 0x9026100A, // 0039 SETMBR R9 K8 R10 - 0x88240112, // 003A GETMBR R9 R0 K18 - 0x8C241313, // 003B GETMET R9 R9 K19 - 0x5C2C1000, // 003C MOVE R11 R8 - 0x7C240400, // 003D CALL R9 2 - 0xB8262800, // 003E GETNGBL R9 K20 - 0x8C241315, // 003F GETMET R9 R9 K21 - 0x8C2C0B16, // 0040 GETMET R11 R5 K22 - 0x58340017, // 0041 LDCONST R13 K23 - 0x60380008, // 0042 GETGBL R14 G8 - 0x5C3C0400, // 0043 MOVE R15 R2 - 0x7C380200, // 0044 CALL R14 1 - 0x5C3C0C00, // 0045 MOVE R15 R6 - 0x88400508, // 0046 GETMBR R16 R2 K8 - 0x88440508, // 0047 GETMBR R17 R2 K8 - 0xB84A0200, // 0048 GETNGBL R18 K1 - 0x8848250C, // 0049 GETMBR R18 R18 K12 - 0x1C442212, // 004A EQ R17 R17 R18 - 0x78460001, // 004B JMPF R17 #004E - 0x5844000C, // 004C LDCONST R17 K12 - 0x70020000, // 004D JMP #004F - 0x58440007, // 004E LDCONST R17 K7 - 0x7C2C0C00, // 004F CALL R11 6 - 0x58300018, // 0050 LDCONST R12 K24 - 0x7C240600, // 0051 CALL R9 3 - 0x50240200, // 0052 LDBOOL R9 1 0 - 0x80041200, // 0053 RET 1 R9 - 0x7002000A, // 0054 JMP #0060 - 0xB8222800, // 0055 GETNGBL R8 K20 - 0x8C201115, // 0056 GETMET R8 R8 K21 - 0x8C280B16, // 0057 GETMET R10 R5 K22 - 0x58300019, // 0058 LDCONST R12 K25 - 0x60340008, // 0059 GETGBL R13 G8 - 0x5C380400, // 005A MOVE R14 R2 - 0x7C340200, // 005B CALL R13 1 - 0x5C380C00, // 005C MOVE R14 R6 - 0x7C280800, // 005D CALL R10 4 - 0x582C0018, // 005E LDCONST R11 K24 - 0x7C200600, // 005F CALL R8 3 - 0x80000000, // 0060 RET 0 + 0x7C140600, // 0004 CALL R5 3 + 0x78160002, // 0005 JMPF R5 #0009 + 0x001A0805, // 0006 ADD R6 K4 R5 + 0x00180D05, // 0007 ADD R6 R6 K5 + 0x70020000, // 0008 JMP #000A + 0x58180006, // 0009 LDCONST R6 K6 + 0x5C140C00, // 000A MOVE R5 R6 + 0xB81A0000, // 000B GETNGBL R6 K0 + 0x88180D08, // 000C GETMBR R6 R6 K8 + 0x900A0E06, // 000D SETMBR R2 K7 R6 + 0x4C180000, // 000E LDNIL R6 + 0x20180206, // 000F NE R6 R1 R6 + 0x781A0006, // 0010 JMPF R6 #0018 + 0x8C180309, // 0011 GETMET R6 R1 K9 + 0x68200000, // 0012 GETUPV R8 U0 + 0x8820110A, // 0013 GETMBR R8 R8 K10 + 0x5C240400, // 0014 MOVE R9 R2 + 0x5C280600, // 0015 MOVE R10 R3 + 0x7C180800, // 0016 CALL R6 4 + 0x70020000, // 0017 JMP #0019 + 0x4C180000, // 0018 LDNIL R6 + 0x781A0002, // 0019 JMPF R6 #001D + 0xB81E0000, // 001A GETNGBL R7 K0 + 0x881C0F0B, // 001B GETMBR R7 R7 K11 + 0x900A0E07, // 001C SETMBR R2 K7 R7 + 0x881C0507, // 001D GETMBR R7 R2 K7 + 0x4C200000, // 001E LDNIL R8 + 0x201C0E08, // 001F NE R7 R7 R8 + 0x781E0037, // 0020 JMPF R7 #0059 + 0x78120035, // 0021 JMPF R4 #0058 + 0xB81E0000, // 0022 GETNGBL R7 K0 + 0x8C1C0F0C, // 0023 GETMET R7 R7 K12 + 0x7C1C0200, // 0024 CALL R7 1 + 0xB8220000, // 0025 GETNGBL R8 K0 + 0x8C20110E, // 0026 GETMET R8 R8 K14 + 0x7C200200, // 0027 CALL R8 1 + 0x901E1A08, // 0028 SETMBR R7 K13 R8 + 0xB8220000, // 0029 GETNGBL R8 K0 + 0x8C20110F, // 002A GETMET R8 R8 K15 + 0x7C200200, // 002B CALL R8 1 + 0x901E0E08, // 002C SETMBR R7 K7 R8 + 0x88200F0D, // 002D GETMBR R8 R7 K13 + 0x88240510, // 002E GETMBR R9 R2 K16 + 0x90222009, // 002F SETMBR R8 K16 R9 + 0x88200F0D, // 0030 GETMBR R8 R7 K13 + 0x88240502, // 0031 GETMBR R9 R2 K2 + 0x90220409, // 0032 SETMBR R8 K2 R9 + 0x88200F0D, // 0033 GETMBR R8 R7 K13 + 0x88240503, // 0034 GETMBR R9 R2 K3 + 0x90220609, // 0035 SETMBR R8 K3 R9 + 0x88200F07, // 0036 GETMBR R8 R7 K7 + 0x88240507, // 0037 GETMBR R9 R2 K7 + 0x90220E09, // 0038 SETMBR R8 K7 R9 + 0x88200111, // 0039 GETMBR R8 R0 K17 + 0x8C201112, // 003A GETMET R8 R8 K18 + 0x5C280E00, // 003B MOVE R10 R7 + 0x7C200400, // 003C CALL R8 2 + 0xB8222600, // 003D GETNGBL R8 K19 + 0x8C201114, // 003E GETMET R8 R8 K20 + 0x60280018, // 003F GETGBL R10 G24 + 0x582C0015, // 0040 LDCONST R11 K21 + 0x60300008, // 0041 GETGBL R12 G8 + 0x5C340400, // 0042 MOVE R13 R2 + 0x7C300200, // 0043 CALL R12 1 + 0x5C340A00, // 0044 MOVE R13 R5 + 0x88380507, // 0045 GETMBR R14 R2 K7 + 0x883C0507, // 0046 GETMBR R15 R2 K7 + 0xB8420000, // 0047 GETNGBL R16 K0 + 0x8840210B, // 0048 GETMBR R16 R16 K11 + 0x1C3C1E10, // 0049 EQ R15 R15 R16 + 0x783E0001, // 004A JMPF R15 #004D + 0x583C000B, // 004B LDCONST R15 K11 + 0x70020000, // 004C JMP #004E + 0x583C0006, // 004D LDCONST R15 K6 + 0x7C280A00, // 004E CALL R10 5 + 0x882C0510, // 004F GETMBR R11 R2 K16 + 0x202C1716, // 0050 NE R11 R11 K22 + 0x782E0001, // 0051 JMPF R11 #0054 + 0x582C0017, // 0052 LDCONST R11 K23 + 0x70020000, // 0053 JMP #0055 + 0x582C0018, // 0054 LDCONST R11 K24 + 0x7C200600, // 0055 CALL R8 3 + 0x50200200, // 0056 LDBOOL R8 1 0 + 0x80041000, // 0057 RET 1 R8 + 0x7002000A, // 0058 JMP #0064 + 0xB81E2600, // 0059 GETNGBL R7 K19 + 0x8C1C0F14, // 005A GETMET R7 R7 K20 + 0x60240018, // 005B GETGBL R9 G24 + 0x58280019, // 005C LDCONST R10 K25 + 0x602C0008, // 005D GETGBL R11 G8 + 0x5C300400, // 005E MOVE R12 R2 + 0x7C2C0200, // 005F CALL R11 1 + 0x5C300A00, // 0060 MOVE R12 R5 + 0x7C240600, // 0061 CALL R9 3 + 0x58280018, // 0062 LDCONST R10 K24 + 0x7C1C0600, // 0063 CALL R7 3 + 0x80000000, // 0064 RET 0 }) ), be_nested_proto( @@ -692,9 +1433,9 @@ be_local_closure(Matter_IM_process_write_request, /* name */ 0, /* varg */ 1, /* has upvals */ ( &(const bupvaldesc[ 3]) { /* upvals */ - be_local_const_upval(1, 7), - be_local_const_upval(1, 9), - be_local_const_upval(1, 13), + be_local_const_upval(1, 6), + be_local_const_upval(1, 8), + be_local_const_upval(1, 12), }), 0, /* has sup protos */ NULL, /* no sub protos */ @@ -716,14 +1457,14 @@ be_local_closure(Matter_IM_process_write_request, /* name */ }), 1, /* has constants */ ( &(const bvalue[30]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(WriteRequestMessage), - /* K3 */ be_nested_str_weak(from_TLV), - /* K4 */ be_nested_str_weak(suppress_response), - /* K5 */ be_nested_str_weak(device), - /* K6 */ be_nested_str_weak(get_active_endpoints), - /* K7 */ be_nested_str_weak(Path), + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(WriteRequestMessage), + /* K2 */ be_nested_str_weak(from_TLV), + /* K3 */ be_nested_str_weak(suppress_response), + /* K4 */ be_nested_str_weak(device), + /* K5 */ be_nested_str_weak(get_active_endpoints), + /* K6 */ be_nested_str_weak(Path), + /* K7 */ be_nested_str_weak(msg), /* K8 */ be_nested_str_weak(write_requests), /* K9 */ be_nested_str_weak(WriteResponseMessage), /* K10 */ be_nested_str_weak(write_responses), @@ -742,7 +1483,7 @@ be_local_closure(Matter_IM_process_write_request, /* name */ /* K23 */ be_nested_str_weak(_X20_X28), /* K24 */ be_nested_str_weak(_X29), /* K25 */ be_nested_str_weak(), - /* K26 */ be_const_int(2), + /* K26 */ be_const_int(3), /* K27 */ be_nested_str_weak(process_attribute_expansion), /* K28 */ be_nested_str_weak(stop_iteration), /* K29 */ be_nested_str_weak(send_write_response), @@ -750,110 +1491,110 @@ be_local_closure(Matter_IM_process_write_request, /* name */ be_str_weak(process_write_request), &be_const_str_solidified, ( &(const binstruction[104]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x8C100902, // 0002 GETMET R4 R4 K2 - 0x7C100200, // 0003 CALL R4 1 - 0x8C100903, // 0004 GETMET R4 R4 K3 - 0x5C180400, // 0005 MOVE R6 R2 - 0x7C100400, // 0006 CALL R4 2 - 0x88140904, // 0007 GETMBR R5 R4 K4 - 0x88180105, // 0008 GETMBR R6 R0 K5 - 0x8C180D06, // 0009 GETMET R6 R6 K6 - 0x7C180200, // 000A CALL R6 1 - 0x841C0000, // 000B CLOSURE R7 P0 - 0xB8220200, // 000C GETNGBL R8 K1 - 0x8C201107, // 000D GETMET R8 R8 K7 - 0x7C200200, // 000E CALL R8 1 - 0x88240908, // 000F GETMBR R9 R4 K8 - 0x4C280000, // 0010 LDNIL R10 - 0x2024120A, // 0011 NE R9 R9 R10 - 0x78260051, // 0012 JMPF R9 #0065 - 0xB8260200, // 0013 GETNGBL R9 K1 - 0x8C241309, // 0014 GETMET R9 R9 K9 - 0x7C240200, // 0015 CALL R9 1 - 0x60280012, // 0016 GETGBL R10 G18 - 0x7C280000, // 0017 CALL R10 0 - 0x9026140A, // 0018 SETMBR R9 K10 R10 - 0x60280010, // 0019 GETGBL R10 G16 - 0x882C0908, // 001A GETMBR R11 R4 K8 - 0x7C280200, // 001B CALL R10 1 + 0xB80E0000, // 0000 GETNGBL R3 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x7C0C0200, // 0002 CALL R3 1 + 0x8C0C0702, // 0003 GETMET R3 R3 K2 + 0x5C140400, // 0004 MOVE R5 R2 + 0x7C0C0400, // 0005 CALL R3 2 + 0x88100703, // 0006 GETMBR R4 R3 K3 + 0x88140104, // 0007 GETMBR R5 R0 K4 + 0x8C140B05, // 0008 GETMET R5 R5 K5 + 0x7C140200, // 0009 CALL R5 1 + 0x84180000, // 000A CLOSURE R6 P0 + 0xB81E0000, // 000B GETNGBL R7 K0 + 0x8C1C0F06, // 000C GETMET R7 R7 K6 + 0x7C1C0200, // 000D CALL R7 1 + 0x901E0E01, // 000E SETMBR R7 K7 R1 + 0x88200708, // 000F GETMBR R8 R3 K8 + 0x4C240000, // 0010 LDNIL R9 + 0x20201009, // 0011 NE R8 R8 R9 + 0x78220051, // 0012 JMPF R8 #0065 + 0xB8220000, // 0013 GETNGBL R8 K0 + 0x8C201109, // 0014 GETMET R8 R8 K9 + 0x7C200200, // 0015 CALL R8 1 + 0x60240012, // 0016 GETGBL R9 G18 + 0x7C240000, // 0017 CALL R9 0 + 0x90221409, // 0018 SETMBR R8 K10 R9 + 0x60240010, // 0019 GETGBL R9 G16 + 0x88280708, // 001A GETMBR R10 R3 K8 + 0x7C240200, // 001B CALL R9 1 0xA802003D, // 001C EXBLK 0 #005B - 0x5C2C1400, // 001D MOVE R11 R10 - 0x7C2C0000, // 001E CALL R11 0 - 0x8830170B, // 001F GETMBR R12 R11 K11 - 0x8834170C, // 0020 GETMBR R13 R11 K12 - 0x8838190D, // 0021 GETMBR R14 R12 K13 - 0x90221A0E, // 0022 SETMBR R8 K13 R14 - 0x8838190E, // 0023 GETMBR R14 R12 K14 - 0x90221C0E, // 0024 SETMBR R8 K14 R14 - 0x8838190F, // 0025 GETMBR R14 R12 K15 - 0x90221E0E, // 0026 SETMBR R8 K15 R14 - 0xB83A0200, // 0027 GETNGBL R14 K1 - 0x88381D11, // 0028 GETMBR R14 R14 K17 - 0x9022200E, // 0029 SETMBR R8 K16 R14 - 0x8838110E, // 002A GETMBR R14 R8 K14 - 0x4C3C0000, // 002B LDNIL R15 - 0x1C381C0F, // 002C EQ R14 R14 R15 - 0x743A0003, // 002D JMPT R14 #0032 - 0x8838110F, // 002E GETMBR R14 R8 K15 - 0x4C3C0000, // 002F LDNIL R15 - 0x1C381C0F, // 0030 EQ R14 R14 R15 - 0x783A000A, // 0031 JMPF R14 #003D - 0xB83A0200, // 0032 GETNGBL R14 K1 - 0x88381D12, // 0033 GETMBR R14 R14 K18 - 0x9022200E, // 0034 SETMBR R8 K16 R14 - 0x5C380E00, // 0035 MOVE R14 R7 - 0x5C3C1200, // 0036 MOVE R15 R9 - 0x4C400000, // 0037 LDNIL R16 - 0x5C441000, // 0038 MOVE R17 R8 - 0x4C480000, // 0039 LDNIL R18 - 0x504C0200, // 003A LDBOOL R19 1 0 - 0x7C380A00, // 003B CALL R14 5 + 0x5C281200, // 001D MOVE R10 R9 + 0x7C280000, // 001E CALL R10 0 + 0x882C150B, // 001F GETMBR R11 R10 K11 + 0x8830150C, // 0020 GETMBR R12 R10 K12 + 0x8834170D, // 0021 GETMBR R13 R11 K13 + 0x901E1A0D, // 0022 SETMBR R7 K13 R13 + 0x8834170E, // 0023 GETMBR R13 R11 K14 + 0x901E1C0D, // 0024 SETMBR R7 K14 R13 + 0x8834170F, // 0025 GETMBR R13 R11 K15 + 0x901E1E0D, // 0026 SETMBR R7 K15 R13 + 0xB8360000, // 0027 GETNGBL R13 K0 + 0x88341B11, // 0028 GETMBR R13 R13 K17 + 0x901E200D, // 0029 SETMBR R7 K16 R13 + 0x88340F0E, // 002A GETMBR R13 R7 K14 + 0x4C380000, // 002B LDNIL R14 + 0x1C341A0E, // 002C EQ R13 R13 R14 + 0x74360003, // 002D JMPT R13 #0032 + 0x88340F0F, // 002E GETMBR R13 R7 K15 + 0x4C380000, // 002F LDNIL R14 + 0x1C341A0E, // 0030 EQ R13 R13 R14 + 0x7836000A, // 0031 JMPF R13 #003D + 0xB8360000, // 0032 GETNGBL R13 K0 + 0x88341B12, // 0033 GETMBR R13 R13 K18 + 0x901E200D, // 0034 SETMBR R7 K16 R13 + 0x5C340C00, // 0035 MOVE R13 R6 + 0x5C381000, // 0036 MOVE R14 R8 + 0x4C3C0000, // 0037 LDNIL R15 + 0x5C400E00, // 0038 MOVE R16 R7 + 0x4C440000, // 0039 LDNIL R17 + 0x50480200, // 003A LDBOOL R18 1 0 + 0x7C340A00, // 003B CALL R13 5 0x7001FFDF, // 003C JMP #001D - 0x8838110D, // 003D GETMBR R14 R8 K13 - 0x4C3C0000, // 003E LDNIL R15 - 0x1C381C0F, // 003F EQ R14 R14 R15 - 0x783A0012, // 0040 JMPF R14 #0054 - 0xB83A0200, // 0041 GETNGBL R14 K1 - 0x8C381D13, // 0042 GETMET R14 R14 K19 - 0x8840110E, // 0043 GETMBR R16 R8 K14 - 0x8844110F, // 0044 GETMBR R17 R8 K15 - 0x7C380600, // 0045 CALL R14 3 - 0xB83E2800, // 0046 GETNGBL R15 K20 - 0x8C3C1F15, // 0047 GETMET R15 R15 K21 - 0x60440008, // 0048 GETGBL R17 G8 - 0x5C481000, // 0049 MOVE R18 R8 - 0x7C440200, // 004A CALL R17 1 - 0x00462C11, // 004B ADD R17 K22 R17 - 0x783A0002, // 004C JMPF R14 #0050 - 0x004A2E0E, // 004D ADD R18 K23 R14 - 0x00482518, // 004E ADD R18 R18 K24 + 0x88340F0D, // 003D GETMBR R13 R7 K13 + 0x4C380000, // 003E LDNIL R14 + 0x1C341A0E, // 003F EQ R13 R13 R14 + 0x78360012, // 0040 JMPF R13 #0054 + 0xB8360000, // 0041 GETNGBL R13 K0 + 0x8C341B13, // 0042 GETMET R13 R13 K19 + 0x883C0F0E, // 0043 GETMBR R15 R7 K14 + 0x88400F0F, // 0044 GETMBR R16 R7 K15 + 0x7C340600, // 0045 CALL R13 3 + 0xB83A2800, // 0046 GETNGBL R14 K20 + 0x8C381D15, // 0047 GETMET R14 R14 K21 + 0x60400008, // 0048 GETGBL R16 G8 + 0x5C440E00, // 0049 MOVE R17 R7 + 0x7C400200, // 004A CALL R16 1 + 0x00422C10, // 004B ADD R16 K22 R16 + 0x78360002, // 004C JMPF R13 #0050 + 0x00462E0D, // 004D ADD R17 K23 R13 + 0x00442318, // 004E ADD R17 R17 K24 0x70020000, // 004F JMP #0051 - 0x58480019, // 0050 LDCONST R18 K25 - 0x00442212, // 0051 ADD R17 R17 R18 - 0x5848001A, // 0052 LDCONST R18 K26 - 0x7C3C0600, // 0053 CALL R15 3 - 0x88380105, // 0054 GETMBR R14 R0 K5 - 0x8C381D1B, // 0055 GETMET R14 R14 K27 - 0x5C401000, // 0056 MOVE R16 R8 - 0x84440001, // 0057 CLOSURE R17 P1 - 0x7C380600, // 0058 CALL R14 3 - 0xA0280000, // 0059 CLOSE R10 + 0x58440019, // 0050 LDCONST R17 K25 + 0x00402011, // 0051 ADD R16 R16 R17 + 0x5844001A, // 0052 LDCONST R17 K26 + 0x7C380600, // 0053 CALL R14 3 + 0x88340104, // 0054 GETMBR R13 R0 K4 + 0x8C341B1B, // 0055 GETMET R13 R13 K27 + 0x5C3C0E00, // 0056 MOVE R15 R7 + 0x84400001, // 0057 CLOSURE R16 P1 + 0x7C340600, // 0058 CALL R13 3 + 0xA0240000, // 0059 CLOSE R9 0x7001FFC1, // 005A JMP #001D - 0x5828001C, // 005B LDCONST R10 K28 - 0xAC280200, // 005C CATCH R10 1 0 + 0x5824001C, // 005B LDCONST R9 K28 + 0xAC240200, // 005C CATCH R9 1 0 0xB0080000, // 005D RAISE 2 R0 R0 - 0x5C280A00, // 005E MOVE R10 R5 - 0x742A0003, // 005F JMPT R10 #0064 - 0x8C28011D, // 0060 GETMET R10 R0 K29 - 0x5C300200, // 0061 MOVE R12 R1 - 0x5C341200, // 0062 MOVE R13 R9 - 0x7C280600, // 0063 CALL R10 3 - 0xA0240000, // 0064 CLOSE R9 - 0x50240200, // 0065 LDBOOL R9 1 0 + 0x5C240800, // 005E MOVE R9 R4 + 0x74260003, // 005F JMPT R9 #0064 + 0x8C24011D, // 0060 GETMET R9 R0 K29 + 0x5C2C0200, // 0061 MOVE R11 R1 + 0x5C301000, // 0062 MOVE R12 R8 + 0x7C240600, // 0063 CALL R9 3 + 0xA0200000, // 0064 CLOSE R8 + 0x50200200, // 0065 LDBOOL R8 1 0 0xA0000000, // 0066 CLOSE R0 - 0x80041200, // 0067 RET 1 R9 + 0x80041000, // 0067 RET 1 R8 }) ) ); @@ -861,36 +1602,252 @@ be_local_closure(Matter_IM_process_write_request, /* name */ /******************************************************************** -** Solidified function: send_write_response +** Solidified function: path2raw ********************************************************************/ -be_local_closure(Matter_IM_send_write_response, /* name */ +be_local_closure(Matter_IM_path2raw, /* name */ be_nested_proto( 9, /* nstack */ - 3, /* argc */ + 5, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(send_queue), - /* K1 */ be_nested_str_weak(push), - /* K2 */ be_nested_str_weak(matter), - /* K3 */ be_nested_str_weak(IM_WriteResponse), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(add), + /* K1 */ be_const_int(1), + /* K2 */ be_nested_str_weak(endpoint), + /* K3 */ be_const_int(2), + /* K4 */ be_nested_str_weak(cluster), + /* K5 */ be_nested_str_weak(attribute), }), - be_str_weak(send_write_response), + be_str_weak(path2raw), &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x8C0C0701, // 0001 GETMET R3 R3 K1 - 0xB8160400, // 0002 GETNGBL R5 K2 - 0x8C140B03, // 0003 GETMET R5 R5 K3 - 0x5C1C0200, // 0004 MOVE R7 R1 - 0x5C200400, // 0005 MOVE R8 R2 - 0x7C140600, // 0006 CALL R5 3 - 0x7C0C0400, // 0007 CALL R3 2 - 0x80000000, // 0008 RET 0 + ( &(const binstruction[107]) { /* code */ + 0x8C140300, // 0000 GETMET R5 R1 K0 + 0x541E0036, // 0001 LDINT R7 55 + 0x58200001, // 0002 LDCONST R8 K1 + 0x7C140600, // 0003 CALL R5 3 + 0x8C140300, // 0004 GETMET R5 R1 K0 + 0x5C1C0600, // 0005 MOVE R7 R3 + 0x58200001, // 0006 LDCONST R8 K1 + 0x7C140600, // 0007 CALL R5 3 + 0x88140502, // 0008 GETMBR R5 R2 K2 + 0x541A00FE, // 0009 LDINT R6 255 + 0x18140A06, // 000A LE R5 R5 R6 + 0x78160008, // 000B JMPF R5 #0015 + 0x8C140300, // 000C GETMET R5 R1 K0 + 0x541E2401, // 000D LDINT R7 9218 + 0x5421FFFD, // 000E LDINT R8 -2 + 0x7C140600, // 000F CALL R5 3 + 0x8C140300, // 0010 GETMET R5 R1 K0 + 0x881C0502, // 0011 GETMBR R7 R2 K2 + 0x58200001, // 0012 LDCONST R8 K1 + 0x7C140600, // 0013 CALL R5 3 + 0x70020007, // 0014 JMP #001D + 0x8C140300, // 0015 GETMET R5 R1 K0 + 0x541E2501, // 0016 LDINT R7 9474 + 0x5421FFFD, // 0017 LDINT R8 -2 + 0x7C140600, // 0018 CALL R5 3 + 0x8C140300, // 0019 GETMET R5 R1 K0 + 0x881C0502, // 001A GETMBR R7 R2 K2 + 0x58200003, // 001B LDCONST R8 K3 + 0x7C140600, // 001C CALL R5 3 + 0x88140504, // 001D GETMBR R5 R2 K4 + 0x541A00FE, // 001E LDINT R6 255 + 0x18140A06, // 001F LE R5 R5 R6 + 0x78160008, // 0020 JMPF R5 #002A + 0x8C140300, // 0021 GETMET R5 R1 K0 + 0x541E2402, // 0022 LDINT R7 9219 + 0x5421FFFD, // 0023 LDINT R8 -2 + 0x7C140600, // 0024 CALL R5 3 + 0x8C140300, // 0025 GETMET R5 R1 K0 + 0x881C0504, // 0026 GETMBR R7 R2 K4 + 0x58200001, // 0027 LDCONST R8 K1 + 0x7C140600, // 0028 CALL R5 3 + 0x70020014, // 0029 JMP #003F + 0x88140504, // 002A GETMBR R5 R2 K4 + 0x541AFFFE, // 002B LDINT R6 65535 + 0x18140A06, // 002C LE R5 R5 R6 + 0x78160008, // 002D JMPF R5 #0037 + 0x8C140300, // 002E GETMET R5 R1 K0 + 0x541E2502, // 002F LDINT R7 9475 + 0x5421FFFD, // 0030 LDINT R8 -2 + 0x7C140600, // 0031 CALL R5 3 + 0x8C140300, // 0032 GETMET R5 R1 K0 + 0x881C0504, // 0033 GETMBR R7 R2 K4 + 0x58200003, // 0034 LDCONST R8 K3 + 0x7C140600, // 0035 CALL R5 3 + 0x70020007, // 0036 JMP #003F + 0x8C140300, // 0037 GETMET R5 R1 K0 + 0x541E2602, // 0038 LDINT R7 9731 + 0x5421FFFD, // 0039 LDINT R8 -2 + 0x7C140600, // 003A CALL R5 3 + 0x8C140300, // 003B GETMET R5 R1 K0 + 0x881C0504, // 003C GETMBR R7 R2 K4 + 0x54220003, // 003D LDINT R8 4 + 0x7C140600, // 003E CALL R5 3 + 0x88140505, // 003F GETMBR R5 R2 K5 + 0x541A00FE, // 0040 LDINT R6 255 + 0x18140A06, // 0041 LE R5 R5 R6 + 0x78160008, // 0042 JMPF R5 #004C + 0x8C140300, // 0043 GETMET R5 R1 K0 + 0x541E2403, // 0044 LDINT R7 9220 + 0x5421FFFD, // 0045 LDINT R8 -2 + 0x7C140600, // 0046 CALL R5 3 + 0x8C140300, // 0047 GETMET R5 R1 K0 + 0x881C0505, // 0048 GETMBR R7 R2 K5 + 0x58200001, // 0049 LDCONST R8 K1 + 0x7C140600, // 004A CALL R5 3 + 0x70020014, // 004B JMP #0061 + 0x88140505, // 004C GETMBR R5 R2 K5 + 0x541AFFFE, // 004D LDINT R6 65535 + 0x18140A06, // 004E LE R5 R5 R6 + 0x78160008, // 004F JMPF R5 #0059 + 0x8C140300, // 0050 GETMET R5 R1 K0 + 0x541E2503, // 0051 LDINT R7 9476 + 0x5421FFFD, // 0052 LDINT R8 -2 + 0x7C140600, // 0053 CALL R5 3 + 0x8C140300, // 0054 GETMET R5 R1 K0 + 0x881C0505, // 0055 GETMBR R7 R2 K5 + 0x58200003, // 0056 LDCONST R8 K3 + 0x7C140600, // 0057 CALL R5 3 + 0x70020007, // 0058 JMP #0061 + 0x8C140300, // 0059 GETMET R5 R1 K0 + 0x541E2603, // 005A LDINT R7 9732 + 0x5421FFFD, // 005B LDINT R8 -2 + 0x7C140600, // 005C CALL R5 3 + 0x8C140300, // 005D GETMET R5 R1 K0 + 0x881C0505, // 005E GETMBR R7 R2 K5 + 0x54220003, // 005F LDINT R8 4 + 0x7C140600, // 0060 CALL R5 3 + 0x78120003, // 0061 JMPF R4 #0066 + 0x8C140300, // 0062 GETMET R5 R1 K0 + 0x541E3404, // 0063 LDINT R7 13317 + 0x5421FFFD, // 0064 LDINT R8 -2 + 0x7C140600, // 0065 CALL R5 3 + 0x8C140300, // 0066 GETMET R5 R1 K0 + 0x541E0017, // 0067 LDINT R7 24 + 0x58200001, // 0068 LDCONST R8 K1 + 0x7C140600, // 0069 CALL R5 3 + 0x80000000, // 006A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: send_subscribe_update +********************************************************************/ +be_local_closure(Matter_IM_send_subscribe_update, /* name */ + be_nested_proto( + 11, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[25]) { /* constants */ + /* K0 */ be_nested_str_weak(session), + /* K1 */ be_nested_str_weak(matter), + /* K2 */ be_nested_str_weak(ReadRequestMessage), + /* K3 */ be_nested_str_weak(fabric_filtered), + /* K4 */ be_nested_str_weak(attributes_requests), + /* K5 */ be_nested_str_weak(updates), + /* K6 */ be_nested_str_weak(AttributePathIB), + /* K7 */ be_nested_str_weak(endpoint), + /* K8 */ be_nested_str_weak(cluster), + /* K9 */ be_nested_str_weak(attribute), + /* K10 */ be_nested_str_weak(push), + /* K11 */ be_nested_str_weak(stop_iteration), + /* K12 */ be_nested_str_weak(tasmota), + /* K13 */ be_nested_str_weak(log), + /* K14 */ be_nested_str_weak(MTR_X3A_X20_X3CSub_Data_X20_X20_X28_X256i_X29_X20sub_X3D_X25i), + /* K15 */ be_nested_str_weak(local_session_id), + /* K16 */ be_nested_str_weak(subscription_id), + /* K17 */ be_const_int(3), + /* K18 */ be_nested_str_weak(is_keep_alive), + /* K19 */ be_nested_str_weak(_inner_process_read_request), + /* K20 */ be_nested_str_weak(suppress_response), + /* K21 */ be_nested_str_weak(IM_ReportDataSubscribed), + /* K22 */ be_nested_str_weak(_message_handler), + /* K23 */ be_nested_str_weak(send_queue), + /* K24 */ be_nested_str_weak(send_enqueued), + }), + be_str_weak(send_subscribe_update), + &be_const_str_solidified, + ( &(const binstruction[67]) { /* code */ + 0x88080300, // 0000 GETMBR R2 R1 K0 + 0xB80E0200, // 0001 GETNGBL R3 K1 + 0x8C0C0702, // 0002 GETMET R3 R3 K2 + 0x7C0C0200, // 0003 CALL R3 1 + 0x50100000, // 0004 LDBOOL R4 0 0 + 0x900E0604, // 0005 SETMBR R3 K3 R4 + 0x60100012, // 0006 GETGBL R4 G18 + 0x7C100000, // 0007 CALL R4 0 + 0x900E0804, // 0008 SETMBR R3 K4 R4 + 0x60100010, // 0009 GETGBL R4 G16 + 0x88140305, // 000A GETMBR R5 R1 K5 + 0x7C100200, // 000B CALL R4 1 + 0xA802000F, // 000C EXBLK 0 #001D + 0x5C140800, // 000D MOVE R5 R4 + 0x7C140000, // 000E CALL R5 0 + 0xB81A0200, // 000F GETNGBL R6 K1 + 0x8C180D06, // 0010 GETMET R6 R6 K6 + 0x7C180200, // 0011 CALL R6 1 + 0x881C0B07, // 0012 GETMBR R7 R5 K7 + 0x901A0E07, // 0013 SETMBR R6 K7 R7 + 0x881C0B08, // 0014 GETMBR R7 R5 K8 + 0x901A1007, // 0015 SETMBR R6 K8 R7 + 0x881C0B09, // 0016 GETMBR R7 R5 K9 + 0x901A1207, // 0017 SETMBR R6 K9 R7 + 0x881C0704, // 0018 GETMBR R7 R3 K4 + 0x8C1C0F0A, // 0019 GETMET R7 R7 K10 + 0x5C240C00, // 001A MOVE R9 R6 + 0x7C1C0400, // 001B CALL R7 2 + 0x7001FFEF, // 001C JMP #000D + 0x5810000B, // 001D LDCONST R4 K11 + 0xAC100200, // 001E CATCH R4 1 0 + 0xB0080000, // 001F RAISE 2 R0 R0 + 0xB8121800, // 0020 GETNGBL R4 K12 + 0x8C10090D, // 0021 GETMET R4 R4 K13 + 0x60180018, // 0022 GETGBL R6 G24 + 0x581C000E, // 0023 LDCONST R7 K14 + 0x8820050F, // 0024 GETMBR R8 R2 K15 + 0x88240310, // 0025 GETMBR R9 R1 K16 + 0x7C180600, // 0026 CALL R6 3 + 0x581C0011, // 0027 LDCONST R7 K17 + 0x7C100600, // 0028 CALL R4 3 + 0x50100000, // 0029 LDBOOL R4 0 0 + 0x90062404, // 002A SETMBR R1 K18 R4 + 0x8C100113, // 002B GETMET R4 R0 K19 + 0x5C180400, // 002C MOVE R6 R2 + 0x5C1C0600, // 002D MOVE R7 R3 + 0x4C200000, // 002E LDNIL R8 + 0x7C100800, // 002F CALL R4 4 + 0x50140000, // 0030 LDBOOL R5 0 0 + 0x90122805, // 0031 SETMBR R4 K20 R5 + 0x88140310, // 0032 GETMBR R5 R1 K16 + 0x90122005, // 0033 SETMBR R4 K16 R5 + 0xB8160200, // 0034 GETNGBL R5 K1 + 0x8C140B15, // 0035 GETMET R5 R5 K21 + 0x881C0516, // 0036 GETMBR R7 R2 K22 + 0x5C200400, // 0037 MOVE R8 R2 + 0x5C240800, // 0038 MOVE R9 R4 + 0x5C280200, // 0039 MOVE R10 R1 + 0x7C140A00, // 003A CALL R5 5 + 0x88180117, // 003B GETMBR R6 R0 K23 + 0x8C180D0A, // 003C GETMET R6 R6 K10 + 0x5C200A00, // 003D MOVE R8 R5 + 0x7C180400, // 003E CALL R6 2 + 0x8C180118, // 003F GETMET R6 R0 K24 + 0x88200516, // 0040 GETMBR R8 R2 K22 + 0x7C180400, // 0041 CALL R6 2 + 0x80000000, // 0042 RET 0 }) ) ); @@ -938,74 +1895,12 @@ be_local_closure(Matter_IM_remove_sendqueue_by_exchangeid, /* name */ 0x780E0004, // 000F JMPF R3 #0015 0x880C0101, // 0010 GETMBR R3 R0 K1 0x8C0C0703, // 0011 GETMET R3 R3 K3 - 0x5C140400, // 0012 MOVE R5 R2 - 0x7C0C0400, // 0013 CALL R3 2 - 0x70020000, // 0014 JMP #0016 - 0x00080504, // 0015 ADD R2 R2 K4 - 0x7001FFED, // 0016 JMP #0005 - 0x80000000, // 0017 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: every_second -********************************************************************/ -be_local_closure(Matter_IM_every_second, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(expire_sendqueue), - }), - be_str_weak(every_second), - &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x80000000, // 0002 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: send_ack_now -********************************************************************/ -be_local_closure(Matter_IM_send_ack_now, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(session), - /* K1 */ be_nested_str_weak(_message_handler), - /* K2 */ be_nested_str_weak(send_encrypted_ack), - }), - be_str_weak(send_ack_now), - &be_const_str_solidified, - ( &(const binstruction[ 7]) { /* code */ - 0x88080300, // 0000 GETMBR R2 R1 K0 - 0x88080501, // 0001 GETMBR R2 R2 K1 - 0x8C080502, // 0002 GETMET R2 R2 K2 - 0x5C100200, // 0003 MOVE R4 R1 - 0x50140000, // 0004 LDBOOL R5 0 0 - 0x7C080600, // 0005 CALL R2 3 - 0x80000000, // 0006 RET 0 + 0x5C140400, // 0012 MOVE R5 R2 + 0x7C0C0400, // 0013 CALL R3 2 + 0x70020000, // 0014 JMP #0016 + 0x00080504, // 0015 ADD R2 R2 K4 + 0x7001FFED, // 0016 JMP #0005 + 0x80000000, // 0017 RET 0 }) ) ); @@ -1013,29 +1908,181 @@ be_local_closure(Matter_IM_send_ack_now, /* name */ /******************************************************************** -** Solidified function: every_250ms +** Solidified function: process_incoming ********************************************************************/ -be_local_closure(Matter_IM_every_250ms, /* name */ +be_local_closure(Matter_IM_process_incoming, /* name */ be_nested_proto( - 3, /* nstack */ - 1, /* argc */ + 8, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(subs_shop), - /* K1 */ be_nested_str_weak(every_250ms), + ( &(const bvalue[25]) { /* constants */ + /* K0 */ be_nested_str_weak(opcode), + /* K1 */ be_const_int(2), + /* K2 */ be_nested_str_weak(read_request_solo), + /* K3 */ be_nested_str_weak(from_raw), + /* K4 */ be_nested_str_weak(raw), + /* K5 */ be_nested_str_weak(app_payload_idx), + /* K6 */ be_nested_str_weak(process_read_request_solo), + /* K7 */ be_nested_str_weak(invoke_request_solo), + /* K8 */ be_nested_str_weak(process_invoke_request_solo), + /* K9 */ be_nested_str_weak(matter), + /* K10 */ be_nested_str_weak(TLV), + /* K11 */ be_nested_str_weak(parse), + /* K12 */ be_const_int(1), + /* K13 */ be_nested_str_weak(process_status_response), + /* K14 */ be_nested_str_weak(process_read_request), + /* K15 */ be_const_int(3), + /* K16 */ be_nested_str_weak(send_ack_now), + /* K17 */ be_nested_str_weak(subscribe_request), + /* K18 */ be_nested_str_weak(subscribe_response), + /* K19 */ be_nested_str_weak(report_data), + /* K20 */ be_nested_str_weak(process_write_request), + /* K21 */ be_nested_str_weak(process_write_response), + /* K22 */ be_nested_str_weak(process_invoke_request), + /* K23 */ be_nested_str_weak(process_invoke_response), + /* K24 */ be_nested_str_weak(process_timed_request), }), - be_str_weak(every_250ms), + be_str_weak(process_incoming), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x80000000, // 0003 RET 0 + ( &(const binstruction[133]) { /* code */ + 0x88080300, // 0000 GETMBR R2 R1 K0 + 0x1C0C0501, // 0001 EQ R3 R2 K1 + 0x780E000D, // 0002 JMPF R3 #0011 + 0x880C0102, // 0003 GETMBR R3 R0 K2 + 0x8C0C0703, // 0004 GETMET R3 R3 K3 + 0x88140304, // 0005 GETMBR R5 R1 K4 + 0x88180305, // 0006 GETMBR R6 R1 K5 + 0x7C0C0600, // 0007 CALL R3 3 + 0x4C100000, // 0008 LDNIL R4 + 0x20100604, // 0009 NE R4 R3 R4 + 0x78120004, // 000A JMPF R4 #0010 + 0x8C100106, // 000B GETMET R4 R0 K6 + 0x5C180200, // 000C MOVE R6 R1 + 0x5C1C0600, // 000D MOVE R7 R3 + 0x7C100600, // 000E CALL R4 3 + 0x80040800, // 000F RET 1 R4 + 0x7002000F, // 0010 JMP #0021 + 0x540E0007, // 0011 LDINT R3 8 + 0x1C0C0403, // 0012 EQ R3 R2 R3 + 0x780E000C, // 0013 JMPF R3 #0021 + 0x880C0107, // 0014 GETMBR R3 R0 K7 + 0x8C0C0703, // 0015 GETMET R3 R3 K3 + 0x88140304, // 0016 GETMBR R5 R1 K4 + 0x88180305, // 0017 GETMBR R6 R1 K5 + 0x7C0C0600, // 0018 CALL R3 3 + 0x4C100000, // 0019 LDNIL R4 + 0x20100604, // 001A NE R4 R3 R4 + 0x78120004, // 001B JMPF R4 #0021 + 0x8C100108, // 001C GETMET R4 R0 K8 + 0x5C180200, // 001D MOVE R6 R1 + 0x5C1C0600, // 001E MOVE R7 R3 + 0x7C100600, // 001F CALL R4 3 + 0x80040800, // 0020 RET 1 R4 + 0xB80E1200, // 0021 GETNGBL R3 K9 + 0x880C070A, // 0022 GETMBR R3 R3 K10 + 0x8C0C070B, // 0023 GETMET R3 R3 K11 + 0x88140304, // 0024 GETMBR R5 R1 K4 + 0x88180305, // 0025 GETMBR R6 R1 K5 + 0x7C0C0600, // 0026 CALL R3 3 + 0x1C10050C, // 0027 EQ R4 R2 K12 + 0x78120005, // 0028 JMPF R4 #002F + 0x8C10010D, // 0029 GETMET R4 R0 K13 + 0x5C180200, // 002A MOVE R6 R1 + 0x5C1C0600, // 002B MOVE R7 R3 + 0x7C100600, // 002C CALL R4 3 + 0x80040800, // 002D RET 1 R4 + 0x70020053, // 002E JMP #0083 + 0x1C100501, // 002F EQ R4 R2 K1 + 0x78120005, // 0030 JMPF R4 #0037 + 0x8C10010E, // 0031 GETMET R4 R0 K14 + 0x5C180200, // 0032 MOVE R6 R1 + 0x5C1C0600, // 0033 MOVE R7 R3 + 0x7C100600, // 0034 CALL R4 3 + 0x80040800, // 0035 RET 1 R4 + 0x7002004B, // 0036 JMP #0083 + 0x1C10050F, // 0037 EQ R4 R2 K15 + 0x78120008, // 0038 JMPF R4 #0042 + 0x8C100110, // 0039 GETMET R4 R0 K16 + 0x5C180200, // 003A MOVE R6 R1 + 0x7C100400, // 003B CALL R4 2 + 0x8C100111, // 003C GETMET R4 R0 K17 + 0x5C180200, // 003D MOVE R6 R1 + 0x5C1C0600, // 003E MOVE R7 R3 + 0x7C100600, // 003F CALL R4 3 + 0x80040800, // 0040 RET 1 R4 + 0x70020040, // 0041 JMP #0083 + 0x54120003, // 0042 LDINT R4 4 + 0x1C100404, // 0043 EQ R4 R2 R4 + 0x78120005, // 0044 JMPF R4 #004B + 0x8C100112, // 0045 GETMET R4 R0 K18 + 0x5C180200, // 0046 MOVE R6 R1 + 0x5C1C0600, // 0047 MOVE R7 R3 + 0x7C100600, // 0048 CALL R4 3 + 0x80040800, // 0049 RET 1 R4 + 0x70020037, // 004A JMP #0083 + 0x54120004, // 004B LDINT R4 5 + 0x1C100404, // 004C EQ R4 R2 R4 + 0x78120005, // 004D JMPF R4 #0054 + 0x8C100113, // 004E GETMET R4 R0 K19 + 0x5C180200, // 004F MOVE R6 R1 + 0x5C1C0600, // 0050 MOVE R7 R3 + 0x7C100600, // 0051 CALL R4 3 + 0x80040800, // 0052 RET 1 R4 + 0x7002002E, // 0053 JMP #0083 + 0x54120005, // 0054 LDINT R4 6 + 0x1C100404, // 0055 EQ R4 R2 R4 + 0x78120008, // 0056 JMPF R4 #0060 + 0x8C100110, // 0057 GETMET R4 R0 K16 + 0x5C180200, // 0058 MOVE R6 R1 + 0x7C100400, // 0059 CALL R4 2 + 0x8C100114, // 005A GETMET R4 R0 K20 + 0x5C180200, // 005B MOVE R6 R1 + 0x5C1C0600, // 005C MOVE R7 R3 + 0x7C100600, // 005D CALL R4 3 + 0x80040800, // 005E RET 1 R4 + 0x70020022, // 005F JMP #0083 + 0x54120006, // 0060 LDINT R4 7 + 0x1C100404, // 0061 EQ R4 R2 R4 + 0x78120005, // 0062 JMPF R4 #0069 + 0x8C100115, // 0063 GETMET R4 R0 K21 + 0x5C180200, // 0064 MOVE R6 R1 + 0x5C1C0600, // 0065 MOVE R7 R3 + 0x7C100600, // 0066 CALL R4 3 + 0x80040800, // 0067 RET 1 R4 + 0x70020019, // 0068 JMP #0083 + 0x54120007, // 0069 LDINT R4 8 + 0x1C100404, // 006A EQ R4 R2 R4 + 0x78120005, // 006B JMPF R4 #0072 + 0x8C100116, // 006C GETMET R4 R0 K22 + 0x5C180200, // 006D MOVE R6 R1 + 0x5C1C0600, // 006E MOVE R7 R3 + 0x7C100600, // 006F CALL R4 3 + 0x80040800, // 0070 RET 1 R4 + 0x70020010, // 0071 JMP #0083 + 0x54120008, // 0072 LDINT R4 9 + 0x1C100404, // 0073 EQ R4 R2 R4 + 0x78120005, // 0074 JMPF R4 #007B + 0x8C100117, // 0075 GETMET R4 R0 K23 + 0x5C180200, // 0076 MOVE R6 R1 + 0x5C1C0600, // 0077 MOVE R7 R3 + 0x7C100600, // 0078 CALL R4 3 + 0x80040800, // 0079 RET 1 R4 + 0x70020007, // 007A JMP #0083 + 0x54120009, // 007B LDINT R4 10 + 0x1C100404, // 007C EQ R4 R2 R4 + 0x78120004, // 007D JMPF R4 #0083 + 0x8C100118, // 007E GETMET R4 R0 K24 + 0x5C180200, // 007F MOVE R6 R1 + 0x5C1C0600, // 0080 MOVE R7 R3 + 0x7C100600, // 0081 CALL R4 3 + 0x80040800, // 0082 RET 1 R4 + 0x50100000, // 0083 LDBOOL R4 0 0 + 0x80040800, // 0084 RET 1 R4 }) ) ); @@ -1043,37 +2090,34 @@ be_local_closure(Matter_IM_every_250ms, /* name */ /******************************************************************** -** Solidified function: send_subscribe_response +** Solidified function: process_invoke_response ********************************************************************/ -be_local_closure(Matter_IM_send_subscribe_response, /* name */ +be_local_closure(Matter_IM_process_invoke_response, /* name */ be_nested_proto( - 11, /* nstack */ - 4, /* argc */ + 6, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(send_queue), - /* K1 */ be_nested_str_weak(push), - /* K2 */ be_nested_str_weak(matter), - /* K3 */ be_nested_str_weak(IM_SubscribeResponse), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(InvokeResponseMessage), + /* K2 */ be_nested_str_weak(from_TLV), }), - be_str_weak(send_subscribe_response), + be_str_weak(process_invoke_response), &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x88100100, // 0000 GETMBR R4 R0 K0 - 0x8C100901, // 0001 GETMET R4 R4 K1 - 0xB81A0400, // 0002 GETNGBL R6 K2 - 0x8C180D03, // 0003 GETMET R6 R6 K3 - 0x5C200200, // 0004 MOVE R8 R1 - 0x5C240400, // 0005 MOVE R9 R2 - 0x5C280600, // 0006 MOVE R10 R3 - 0x7C180800, // 0007 CALL R6 4 - 0x7C100400, // 0008 CALL R4 2 - 0x80000000, // 0009 RET 0 + ( &(const binstruction[ 8]) { /* code */ + 0xB80E0000, // 0000 GETNGBL R3 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x7C0C0200, // 0002 CALL R3 1 + 0x8C0C0702, // 0003 GETMET R3 R3 K2 + 0x5C140400, // 0004 MOVE R5 R2 + 0x7C0C0400, // 0005 CALL R3 2 + 0x50100000, // 0006 LDBOOL R4 0 0 + 0x80040800, // 0007 RET 1 R4 }) ) ); @@ -1081,36 +2125,27 @@ be_local_closure(Matter_IM_send_subscribe_response, /* name */ /******************************************************************** -** Solidified function: send_invoke_response +** Solidified function: every_second ********************************************************************/ -be_local_closure(Matter_IM_send_invoke_response, /* name */ +be_local_closure(Matter_IM_every_second, /* name */ be_nested_proto( - 9, /* nstack */ - 3, /* argc */ + 3, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(send_queue), - /* K1 */ be_nested_str_weak(push), - /* K2 */ be_nested_str_weak(matter), - /* K3 */ be_nested_str_weak(IM_InvokeResponse), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(expire_sendqueue), }), - be_str_weak(send_invoke_response), + be_str_weak(every_second), &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x8C0C0701, // 0001 GETMET R3 R3 K1 - 0xB8160400, // 0002 GETNGBL R5 K2 - 0x8C140B03, // 0003 GETMET R5 R5 K3 - 0x5C1C0200, // 0004 MOVE R7 R1 - 0x5C200400, // 0005 MOVE R8 R2 - 0x7C140600, // 0006 CALL R5 3 - 0x7C0C0400, // 0007 CALL R3 2 - 0x80000000, // 0008 RET 0 + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80000000, // 0002 RET 0 }) ) ); @@ -1154,485 +2189,304 @@ be_local_closure(Matter_IM_send_status, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: subscribe_response -********************************************************************/ -be_local_closure(Matter_IM_subscribe_response, /* name */ - be_nested_proto( - 9, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(SubscribeResponseMessage), - /* K3 */ be_nested_str_weak(from_TLV), - /* K4 */ be_nested_str_weak(tasmota), - /* K5 */ be_nested_str_weak(log), - /* K6 */ be_nested_str_weak(MTR_X3A_X20received_X20SubscribeResponsetMessage_X3D), - /* K7 */ be_const_int(2), - }), - be_str_weak(subscribe_response), - &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x8C100902, // 0002 GETMET R4 R4 K2 - 0x7C100200, // 0003 CALL R4 1 - 0x8C100903, // 0004 GETMET R4 R4 K3 - 0x5C180400, // 0005 MOVE R6 R2 - 0x7C100400, // 0006 CALL R4 2 - 0xB8160800, // 0007 GETNGBL R5 K4 - 0x8C140B05, // 0008 GETMET R5 R5 K5 - 0x601C0008, // 0009 GETGBL R7 G8 - 0x5C200800, // 000A MOVE R8 R4 - 0x7C1C0200, // 000B CALL R7 1 - 0x001E0C07, // 000C ADD R7 K6 R7 - 0x58200007, // 000D LDCONST R8 K7 - 0x7C140600, // 000E CALL R5 3 - 0x50140000, // 000F LDBOOL R5 0 0 - 0x80040A00, // 0010 RET 1 R5 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: process_incoming -********************************************************************/ -be_local_closure(Matter_IM_process_incoming, /* name */ - be_nested_proto( - 9, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[21]) { /* constants */ - /* K0 */ be_nested_str_weak(matter), - /* K1 */ be_nested_str_weak(TLV), - /* K2 */ be_nested_str_weak(parse), - /* K3 */ be_nested_str_weak(raw), - /* K4 */ be_nested_str_weak(app_payload_idx), - /* K5 */ be_nested_str_weak(findsubval), - /* K6 */ be_nested_str_weak(opcode), - /* K7 */ be_const_int(1), - /* K8 */ be_nested_str_weak(process_status_response), - /* K9 */ be_const_int(2), - /* K10 */ be_nested_str_weak(send_ack_now), - /* K11 */ be_nested_str_weak(process_read_request), - /* K12 */ be_const_int(3), - /* K13 */ be_nested_str_weak(subscribe_request), - /* K14 */ be_nested_str_weak(subscribe_response), - /* K15 */ be_nested_str_weak(report_data), - /* K16 */ be_nested_str_weak(process_write_request), - /* K17 */ be_nested_str_weak(process_write_response), - /* K18 */ be_nested_str_weak(process_invoke_request), - /* K19 */ be_nested_str_weak(process_invoke_response), - /* K20 */ be_nested_str_weak(process_timed_request), - }), - be_str_weak(process_incoming), - &be_const_str_solidified, - ( &(const binstruction[110]) { /* code */ - 0xB80A0000, // 0000 GETNGBL R2 K0 - 0x88080501, // 0001 GETMBR R2 R2 K1 - 0x8C080502, // 0002 GETMET R2 R2 K2 - 0x88100303, // 0003 GETMBR R4 R1 K3 - 0x88140304, // 0004 GETMBR R5 R1 K4 - 0x7C080600, // 0005 CALL R2 3 - 0x8C0C0505, // 0006 GETMET R3 R2 K5 - 0x541600FE, // 0007 LDINT R5 255 - 0x7C0C0400, // 0008 CALL R3 2 - 0x88100306, // 0009 GETMBR R4 R1 K6 - 0x1C140907, // 000A EQ R5 R4 K7 - 0x78160005, // 000B JMPF R5 #0012 - 0x8C140108, // 000C GETMET R5 R0 K8 - 0x5C1C0200, // 000D MOVE R7 R1 - 0x5C200400, // 000E MOVE R8 R2 - 0x7C140600, // 000F CALL R5 3 - 0x80040A00, // 0010 RET 1 R5 - 0x70020059, // 0011 JMP #006C - 0x1C140909, // 0012 EQ R5 R4 K9 - 0x78160008, // 0013 JMPF R5 #001D - 0x8C14010A, // 0014 GETMET R5 R0 K10 - 0x5C1C0200, // 0015 MOVE R7 R1 - 0x7C140400, // 0016 CALL R5 2 - 0x8C14010B, // 0017 GETMET R5 R0 K11 - 0x5C1C0200, // 0018 MOVE R7 R1 - 0x5C200400, // 0019 MOVE R8 R2 - 0x7C140600, // 001A CALL R5 3 - 0x80040A00, // 001B RET 1 R5 - 0x7002004E, // 001C JMP #006C - 0x1C14090C, // 001D EQ R5 R4 K12 - 0x78160008, // 001E JMPF R5 #0028 - 0x8C14010A, // 001F GETMET R5 R0 K10 - 0x5C1C0200, // 0020 MOVE R7 R1 - 0x7C140400, // 0021 CALL R5 2 - 0x8C14010D, // 0022 GETMET R5 R0 K13 - 0x5C1C0200, // 0023 MOVE R7 R1 - 0x5C200400, // 0024 MOVE R8 R2 - 0x7C140600, // 0025 CALL R5 3 - 0x80040A00, // 0026 RET 1 R5 - 0x70020043, // 0027 JMP #006C - 0x54160003, // 0028 LDINT R5 4 - 0x1C140805, // 0029 EQ R5 R4 R5 - 0x78160005, // 002A JMPF R5 #0031 - 0x8C14010E, // 002B GETMET R5 R0 K14 - 0x5C1C0200, // 002C MOVE R7 R1 - 0x5C200400, // 002D MOVE R8 R2 - 0x7C140600, // 002E CALL R5 3 - 0x80040A00, // 002F RET 1 R5 - 0x7002003A, // 0030 JMP #006C - 0x54160004, // 0031 LDINT R5 5 - 0x1C140805, // 0032 EQ R5 R4 R5 - 0x78160005, // 0033 JMPF R5 #003A - 0x8C14010F, // 0034 GETMET R5 R0 K15 - 0x5C1C0200, // 0035 MOVE R7 R1 - 0x5C200400, // 0036 MOVE R8 R2 - 0x7C140600, // 0037 CALL R5 3 - 0x80040A00, // 0038 RET 1 R5 - 0x70020031, // 0039 JMP #006C - 0x54160005, // 003A LDINT R5 6 - 0x1C140805, // 003B EQ R5 R4 R5 - 0x78160008, // 003C JMPF R5 #0046 - 0x8C14010A, // 003D GETMET R5 R0 K10 - 0x5C1C0200, // 003E MOVE R7 R1 - 0x7C140400, // 003F CALL R5 2 - 0x8C140110, // 0040 GETMET R5 R0 K16 - 0x5C1C0200, // 0041 MOVE R7 R1 - 0x5C200400, // 0042 MOVE R8 R2 - 0x7C140600, // 0043 CALL R5 3 - 0x80040A00, // 0044 RET 1 R5 - 0x70020025, // 0045 JMP #006C - 0x54160006, // 0046 LDINT R5 7 - 0x1C140805, // 0047 EQ R5 R4 R5 - 0x78160005, // 0048 JMPF R5 #004F - 0x8C140111, // 0049 GETMET R5 R0 K17 - 0x5C1C0200, // 004A MOVE R7 R1 - 0x5C200400, // 004B MOVE R8 R2 - 0x7C140600, // 004C CALL R5 3 - 0x80040A00, // 004D RET 1 R5 - 0x7002001C, // 004E JMP #006C - 0x54160007, // 004F LDINT R5 8 - 0x1C140805, // 0050 EQ R5 R4 R5 - 0x78160008, // 0051 JMPF R5 #005B - 0x8C14010A, // 0052 GETMET R5 R0 K10 - 0x5C1C0200, // 0053 MOVE R7 R1 - 0x7C140400, // 0054 CALL R5 2 - 0x8C140112, // 0055 GETMET R5 R0 K18 - 0x5C1C0200, // 0056 MOVE R7 R1 - 0x5C200400, // 0057 MOVE R8 R2 - 0x7C140600, // 0058 CALL R5 3 - 0x80040A00, // 0059 RET 1 R5 - 0x70020010, // 005A JMP #006C - 0x54160008, // 005B LDINT R5 9 - 0x1C140805, // 005C EQ R5 R4 R5 - 0x78160005, // 005D JMPF R5 #0064 - 0x8C140113, // 005E GETMET R5 R0 K19 - 0x5C1C0200, // 005F MOVE R7 R1 - 0x5C200400, // 0060 MOVE R8 R2 - 0x7C140600, // 0061 CALL R5 3 - 0x80040A00, // 0062 RET 1 R5 - 0x70020007, // 0063 JMP #006C - 0x54160009, // 0064 LDINT R5 10 - 0x1C140805, // 0065 EQ R5 R4 R5 - 0x78160004, // 0066 JMPF R5 #006C - 0x8C140114, // 0067 GETMET R5 R0 K20 - 0x5C1C0200, // 0068 MOVE R7 R1 - 0x5C200400, // 0069 MOVE R8 R2 - 0x7C140600, // 006A CALL R5 3 - 0x80040A00, // 006B RET 1 R5 - 0x50140000, // 006C LDBOOL R5 0 0 - 0x80040A00, // 006D RET 1 R5 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: _inner_process_read_request ********************************************************************/ be_local_closure(Matter_IM__inner_process_read_request, /* name */ be_nested_proto( - 20, /* nstack */ - 4, /* argc */ + 19, /* nstack */ + 5, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 1, /* has sup protos */ ( &(const struct bproto*[ 2]) { be_nested_proto( - 25, /* nstack */ + 20, /* nstack */ 4, /* argc */ 0, /* varg */ 1, /* has upvals */ - ( &(const bupvaldesc[ 2]) { /* upvals */ + ( &(const bupvaldesc[ 3]) { /* upvals */ be_local_const_upval(1, 1), - be_local_const_upval(1, 3), + be_local_const_upval(1, 0), + be_local_const_upval(1, 4), }), 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[40]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(get_attribute_name), - /* K4 */ be_nested_str_weak(cluster), - /* K5 */ be_nested_str_weak(attribute), - /* K6 */ be_nested_str_weak(_X20_X28), - /* K7 */ be_nested_str_weak(_X29), - /* K8 */ be_nested_str_weak(), - /* K9 */ be_nested_str_weak(read_attribute), - /* K10 */ be_nested_str_weak(AttributeReportIB), - /* K11 */ be_nested_str_weak(attribute_data), - /* K12 */ be_nested_str_weak(AttributeDataIB), - /* K13 */ be_nested_str_weak(data_version), - /* K14 */ be_const_int(1), - /* K15 */ be_nested_str_weak(path), - /* K16 */ be_nested_str_weak(AttributePathIB), - /* K17 */ be_nested_str_weak(endpoint), - /* K18 */ be_nested_str_weak(data), - /* K19 */ be_nested_str_weak(to_TLV), - /* K20 */ be_nested_str_weak(encode_len), - /* K21 */ be_nested_str_weak(tlv2raw), - /* K22 */ be_nested_str_weak(tasmota), - /* K23 */ be_nested_str_weak(log), - /* K24 */ be_nested_str_weak(format), - /* K25 */ be_nested_str_weak(MTR_X3A_X20_X3ERead_Attr_X20_X28_X256i_X29_X20_X25s_X25s_X20_X2D_X20_X25s), - /* K26 */ be_nested_str_weak(local_session_id), - /* K27 */ be_const_int(2), - /* K28 */ be_nested_str_weak(status), - /* K29 */ be_nested_str_weak(attribute_status), - /* K30 */ be_nested_str_weak(AttributeStatusIB), - /* K31 */ be_nested_str_weak(StatusIB), - /* K32 */ be_nested_str_weak(MTR_X3A_X20_X3ERead_Attr_X20_X28_X256i_X29_X20_X25s_X25s_X20_X2D_X20STATUS_X3A_X200x_X2502X_X20_X25s), - /* K33 */ be_nested_str_weak(UNSUPPORTED_ATTRIBUTE), - /* K34 */ be_nested_str_weak(MTR_X3A_X20_X3ERead_Attr_X20_X28_X256i_X29_X20_X25s_X25s_X20_X2D_X20IGNORED), - /* K35 */ be_nested_str_weak(attribute_reports), - /* K36 */ be_const_int(0), - /* K37 */ be_nested_str_weak(push), - /* K38 */ be_nested_str_weak(IM_ReportData), - /* K39 */ be_nested_str_weak(MAX_MESSAGE), + ( &(const bvalue[35]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(get_attribute_name), + /* K3 */ be_nested_str_weak(cluster), + /* K4 */ be_nested_str_weak(attribute), + /* K5 */ be_nested_str_weak(_X20_X28), + /* K6 */ be_nested_str_weak(_X29), + /* K7 */ be_nested_str_weak(), + /* K8 */ be_nested_str_weak(read_attribute), + /* K9 */ be_nested_str_weak(tlv_solo), + /* K10 */ be_nested_str_weak(to_str_val), + /* K11 */ be_nested_str_weak(is_list), + /* K12 */ be_nested_str_weak(is_array), + /* K13 */ be_nested_str_weak(encode_len), + /* K14 */ be_nested_str_weak(IM_ReportData), + /* K15 */ be_nested_str_weak(MAX_MESSAGE), + /* K16 */ be_nested_str_weak(Matter_TLV_array), + /* K17 */ be_nested_str_weak(attributedata2raw), + /* K18 */ be_nested_str_weak(push), + /* K19 */ be_nested_str_weak(val), + /* K20 */ be_nested_str_weak(stop_iteration), + /* K21 */ be_nested_str_weak(tasmota), + /* K22 */ be_nested_str_weak(log), + /* K23 */ be_nested_str_weak(MTR_X3A_X20_X3ERead_Attr_X20_X28_X256i_X29_X20_X25s_X25s_X20_X2D_X20_X25s), + /* K24 */ be_nested_str_weak(local_session_id), + /* K25 */ be_const_int(3), + /* K26 */ be_nested_str_weak(status), + /* K27 */ be_nested_str_weak(attributestatus2raw), + /* K28 */ be_nested_str_weak(loglevel), + /* K29 */ be_nested_str_weak(MTR_X3A_X20_X3ERead_Attr_X20_X28_X256i_X29_X20_X25s_X25s_X20_X2D_X20STATUS_X3A_X200x_X2502X_X20_X25s), + /* K30 */ be_nested_str_weak(UNSUPPORTED_ATTRIBUTE), + /* K31 */ be_nested_str_weak(MTR_X3A_X20_X3ERead_Attr_X20_X28_X256i_X29_X20_X25s_X25s_X20_X2D_X20IGNORED), + /* K32 */ be_const_int(0), + /* K33 */ be_nested_str_weak(attribute_reports), + /* K34 */ be_const_int(1), }), be_str_weak(read_single_attribute), &be_const_str_solidified, - ( &(const binstruction[206]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0xB8160200, // 0001 GETNGBL R5 K1 - 0x88140B02, // 0002 GETMBR R5 R5 K2 - 0xB81A0200, // 0003 GETNGBL R6 K1 - 0x8C180D03, // 0004 GETMET R6 R6 K3 + ( &(const binstruction[233]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0xB8160000, // 0002 GETNGBL R5 K0 + 0x8C140B02, // 0003 GETMET R5 R5 K2 + 0x881C0503, // 0004 GETMBR R7 R2 K3 0x88200504, // 0005 GETMBR R8 R2 K4 - 0x88240505, // 0006 GETMBR R9 R2 K5 - 0x7C180600, // 0007 CALL R6 3 - 0x781A0002, // 0008 JMPF R6 #000C - 0x001E0C06, // 0009 ADD R7 K6 R6 - 0x001C0F07, // 000A ADD R7 R7 K7 - 0x70020000, // 000B JMP #000D - 0x581C0008, // 000C LDCONST R7 K8 - 0x5C180E00, // 000D MOVE R6 R7 - 0x4C1C0000, // 000E LDNIL R7 - 0x201C0207, // 000F NE R7 R1 R7 - 0x781E0004, // 0010 JMPF R7 #0016 - 0x8C1C0309, // 0011 GETMET R7 R1 K9 - 0x68240000, // 0012 GETUPV R9 U0 - 0x5C280400, // 0013 MOVE R10 R2 - 0x7C1C0600, // 0014 CALL R7 3 - 0x70020000, // 0015 JMP #0017 - 0x4C1C0000, // 0016 LDNIL R7 - 0x50200200, // 0017 LDBOOL R8 1 0 - 0x4C240000, // 0018 LDNIL R9 - 0x4C280000, // 0019 LDNIL R10 - 0x20280E0A, // 001A NE R10 R7 R10 - 0x782A003A, // 001B JMPF R10 #0057 - 0x60280008, // 001C GETGBL R10 G8 - 0x5C2C0E00, // 001D MOVE R11 R7 - 0x7C280200, // 001E CALL R10 1 - 0xB82E0200, // 001F GETNGBL R11 K1 - 0x8C2C170A, // 0020 GETMET R11 R11 K10 - 0x7C2C0200, // 0021 CALL R11 1 - 0xB8320200, // 0022 GETNGBL R12 K1 - 0x8C30190C, // 0023 GETMET R12 R12 K12 - 0x7C300200, // 0024 CALL R12 1 - 0x902E160C, // 0025 SETMBR R11 K11 R12 - 0x8830170B, // 0026 GETMBR R12 R11 K11 - 0x90321B0E, // 0027 SETMBR R12 K13 K14 - 0x8830170B, // 0028 GETMBR R12 R11 K11 - 0xB8360200, // 0029 GETNGBL R13 K1 - 0x8C341B10, // 002A GETMET R13 R13 K16 - 0x7C340200, // 002B CALL R13 1 - 0x90321E0D, // 002C SETMBR R12 K15 R13 - 0x8830170B, // 002D GETMBR R12 R11 K11 - 0x8830190F, // 002E GETMBR R12 R12 K15 - 0x88340511, // 002F GETMBR R13 R2 K17 - 0x9032220D, // 0030 SETMBR R12 K17 R13 - 0x8830170B, // 0031 GETMBR R12 R11 K11 - 0x8830190F, // 0032 GETMBR R12 R12 K15 - 0x88340504, // 0033 GETMBR R13 R2 K4 - 0x9032080D, // 0034 SETMBR R12 K4 R13 - 0x8830170B, // 0035 GETMBR R12 R11 K11 - 0x8830190F, // 0036 GETMBR R12 R12 K15 - 0x88340505, // 0037 GETMBR R13 R2 K5 - 0x90320A0D, // 0038 SETMBR R12 K5 R13 - 0x8830170B, // 0039 GETMBR R12 R11 K11 - 0x90322407, // 003A SETMBR R12 K18 R7 - 0x8C301713, // 003B GETMET R12 R11 K19 - 0x7C300200, // 003C CALL R12 1 - 0x8C341914, // 003D GETMET R13 R12 K20 - 0x7C340200, // 003E CALL R13 1 - 0x60380015, // 003F GETGBL R14 G21 - 0x5C3C1A00, // 0040 MOVE R15 R13 - 0x7C380200, // 0041 CALL R14 1 - 0x8C3C1915, // 0042 GETMET R15 R12 K21 - 0x5C441C00, // 0043 MOVE R17 R14 - 0x7C3C0400, // 0044 CALL R15 2 - 0x5C241E00, // 0045 MOVE R9 R15 - 0x683C0001, // 0046 GETUPV R15 U1 - 0x743E000D, // 0047 JMPT R15 #0056 - 0xB83E2C00, // 0048 GETNGBL R15 K22 - 0x8C3C1F17, // 0049 GETMET R15 R15 K23 - 0x8C440918, // 004A GETMET R17 R4 K24 - 0x584C0019, // 004B LDCONST R19 K25 - 0x68500000, // 004C GETUPV R20 U0 - 0x8850291A, // 004D GETMBR R20 R20 K26 - 0x60540008, // 004E GETGBL R21 G8 - 0x5C580400, // 004F MOVE R22 R2 - 0x7C540200, // 0050 CALL R21 1 - 0x5C580C00, // 0051 MOVE R22 R6 - 0x5C5C1400, // 0052 MOVE R23 R10 - 0x7C440C00, // 0053 CALL R17 6 - 0x5848001B, // 0054 LDCONST R18 K27 - 0x7C3C0600, // 0055 CALL R15 3 - 0x70020055, // 0056 JMP #00AD - 0x8828051C, // 0057 GETMBR R10 R2 K28 - 0x4C2C0000, // 0058 LDNIL R11 - 0x2028140B, // 0059 NE R10 R10 R11 - 0x782A0043, // 005A JMPF R10 #009F - 0x780E0041, // 005B JMPF R3 #009E - 0xB82A0200, // 005C GETNGBL R10 K1 - 0x8C28150A, // 005D GETMET R10 R10 K10 - 0x7C280200, // 005E CALL R10 1 - 0xB82E0200, // 005F GETNGBL R11 K1 - 0x8C2C171E, // 0060 GETMET R11 R11 K30 - 0x7C2C0200, // 0061 CALL R11 1 - 0x902A3A0B, // 0062 SETMBR R10 K29 R11 - 0x882C151D, // 0063 GETMBR R11 R10 K29 - 0xB8320200, // 0064 GETNGBL R12 K1 - 0x8C301910, // 0065 GETMET R12 R12 K16 - 0x7C300200, // 0066 CALL R12 1 - 0x902E1E0C, // 0067 SETMBR R11 K15 R12 - 0x882C151D, // 0068 GETMBR R11 R10 K29 - 0xB8320200, // 0069 GETNGBL R12 K1 - 0x8C30191F, // 006A GETMET R12 R12 K31 - 0x7C300200, // 006B CALL R12 1 - 0x902E380C, // 006C SETMBR R11 K28 R12 - 0x882C151D, // 006D GETMBR R11 R10 K29 - 0x882C170F, // 006E GETMBR R11 R11 K15 - 0x88300511, // 006F GETMBR R12 R2 K17 - 0x902E220C, // 0070 SETMBR R11 K17 R12 - 0x882C151D, // 0071 GETMBR R11 R10 K29 - 0x882C170F, // 0072 GETMBR R11 R11 K15 - 0x88300504, // 0073 GETMBR R12 R2 K4 - 0x902E080C, // 0074 SETMBR R11 K4 R12 - 0x882C151D, // 0075 GETMBR R11 R10 K29 - 0x882C170F, // 0076 GETMBR R11 R11 K15 - 0x88300505, // 0077 GETMBR R12 R2 K5 - 0x902E0A0C, // 0078 SETMBR R11 K5 R12 - 0x882C151D, // 0079 GETMBR R11 R10 K29 - 0x882C171C, // 007A GETMBR R11 R11 K28 - 0x8830051C, // 007B GETMBR R12 R2 K28 - 0x902E380C, // 007C SETMBR R11 K28 R12 - 0x8C2C1513, // 007D GETMET R11 R10 K19 - 0x7C2C0200, // 007E CALL R11 1 - 0x8C301714, // 007F GETMET R12 R11 K20 - 0x7C300200, // 0080 CALL R12 1 - 0x60340015, // 0081 GETGBL R13 G21 - 0x5C381800, // 0082 MOVE R14 R12 - 0x7C340200, // 0083 CALL R13 1 - 0x8C381715, // 0084 GETMET R14 R11 K21 - 0x5C401A00, // 0085 MOVE R16 R13 - 0x7C380400, // 0086 CALL R14 2 - 0x5C241C00, // 0087 MOVE R9 R14 - 0xB83A2C00, // 0088 GETNGBL R14 K22 - 0x8C381D17, // 0089 GETMET R14 R14 K23 - 0x8C400918, // 008A GETMET R16 R4 K24 - 0x58480020, // 008B LDCONST R18 K32 - 0x684C0000, // 008C GETUPV R19 U0 - 0x884C271A, // 008D GETMBR R19 R19 K26 - 0x60500008, // 008E GETGBL R20 G8 - 0x5C540400, // 008F MOVE R21 R2 - 0x7C500200, // 0090 CALL R20 1 - 0x5C540C00, // 0091 MOVE R21 R6 - 0x8858051C, // 0092 GETMBR R22 R2 K28 - 0x885C051C, // 0093 GETMBR R23 R2 K28 - 0xB8620200, // 0094 GETNGBL R24 K1 - 0x88603121, // 0095 GETMBR R24 R24 K33 - 0x1C5C2E18, // 0096 EQ R23 R23 R24 - 0x785E0001, // 0097 JMPF R23 #009A - 0x585C0021, // 0098 LDCONST R23 K33 - 0x70020000, // 0099 JMP #009B - 0x585C0008, // 009A LDCONST R23 K8 - 0x7C400E00, // 009B CALL R16 7 - 0x5844001B, // 009C LDCONST R17 K27 - 0x7C380600, // 009D CALL R14 3 - 0x7002000D, // 009E JMP #00AD - 0xB82A2C00, // 009F GETNGBL R10 K22 - 0x8C281517, // 00A0 GETMET R10 R10 K23 - 0x8C300918, // 00A1 GETMET R12 R4 K24 - 0x58380022, // 00A2 LDCONST R14 K34 - 0x683C0000, // 00A3 GETUPV R15 U0 - 0x883C1F1A, // 00A4 GETMBR R15 R15 K26 - 0x60400008, // 00A5 GETGBL R16 G8 - 0x5C440400, // 00A6 MOVE R17 R2 - 0x7C400200, // 00A7 CALL R16 1 - 0x5C440C00, // 00A8 MOVE R17 R6 - 0x7C300A00, // 00A9 CALL R12 5 - 0x5834001B, // 00AA LDCONST R13 K27 - 0x7C280600, // 00AB CALL R10 3 - 0x50200000, // 00AC LDBOOL R8 0 0 - 0x7826001E, // 00AD JMPF R9 #00CD - 0x6028000C, // 00AE GETGBL R10 G12 - 0x882C0123, // 00AF GETMBR R11 R0 K35 - 0x7C280200, // 00B0 CALL R10 1 - 0x1C281524, // 00B1 EQ R10 R10 K36 - 0x782A0004, // 00B2 JMPF R10 #00B8 - 0x88280123, // 00B3 GETMBR R10 R0 K35 - 0x8C281525, // 00B4 GETMET R10 R10 K37 - 0x5C301200, // 00B5 MOVE R12 R9 - 0x7C280400, // 00B6 CALL R10 2 - 0x70020014, // 00B7 JMP #00CD - 0x5429FFFE, // 00B8 LDINT R10 -1 - 0x882C0123, // 00B9 GETMBR R11 R0 K35 - 0x9428160A, // 00BA GETIDX R10 R11 R10 - 0x6030000C, // 00BB GETGBL R12 G12 - 0x5C341400, // 00BC MOVE R13 R10 - 0x7C300200, // 00BD CALL R12 1 - 0x6034000C, // 00BE GETGBL R13 G12 - 0x5C381200, // 00BF MOVE R14 R9 - 0x7C340200, // 00C0 CALL R13 1 - 0x0030180D, // 00C1 ADD R12 R12 R13 - 0xB8360200, // 00C2 GETNGBL R13 K1 - 0x88341B26, // 00C3 GETMBR R13 R13 K38 - 0x88341B27, // 00C4 GETMBR R13 R13 K39 - 0x1830180D, // 00C5 LE R12 R12 R13 - 0x78320001, // 00C6 JMPF R12 #00C9 - 0x40301409, // 00C7 CONNECT R12 R10 R9 - 0x70020003, // 00C8 JMP #00CD - 0x882C0123, // 00C9 GETMBR R11 R0 K35 - 0x8C2C1725, // 00CA GETMET R11 R11 K37 - 0x5C341200, // 00CB MOVE R13 R9 - 0x7C2C0400, // 00CC CALL R11 2 - 0x80041000, // 00CD RET 1 R8 + 0x7C140600, // 0006 CALL R5 3 + 0x78160002, // 0007 JMPF R5 #000B + 0x001A0A05, // 0008 ADD R6 K5 R5 + 0x00180D06, // 0009 ADD R6 R6 K6 + 0x70020000, // 000A JMP #000C + 0x58180007, // 000B LDCONST R6 K7 + 0x5C140C00, // 000C MOVE R5 R6 + 0x4C180000, // 000D LDNIL R6 + 0x20180206, // 000E NE R6 R1 R6 + 0x781A0006, // 000F JMPF R6 #0017 + 0x8C180308, // 0010 GETMET R6 R1 K8 + 0x68200000, // 0011 GETUPV R8 U0 + 0x5C240400, // 0012 MOVE R9 R2 + 0x68280001, // 0013 GETUPV R10 U1 + 0x88281509, // 0014 GETMBR R10 R10 K9 + 0x7C180800, // 0015 CALL R6 4 + 0x70020000, // 0016 JMP #0018 + 0x4C180000, // 0017 LDNIL R6 + 0x501C0200, // 0018 LDBOOL R7 1 0 + 0x4C200000, // 0019 LDNIL R8 + 0x4C240000, // 001A LDNIL R9 + 0x20240C09, // 001B NE R9 R6 R9 + 0x78260054, // 001C JMPF R9 #0072 + 0x58240007, // 001D LDCONST R9 K7 + 0x68280002, // 001E GETUPV R10 U2 + 0x742A0002, // 001F JMPT R10 #0023 + 0x8C280D0A, // 0020 GETMET R10 R6 K10 + 0x7C280200, // 0021 CALL R10 1 + 0x5C241400, // 0022 MOVE R9 R10 + 0x88280D0B, // 0023 GETMBR R10 R6 K11 + 0x742A0001, // 0024 JMPT R10 #0027 + 0x88280D0C, // 0025 GETMBR R10 R6 K12 + 0x782A0031, // 0026 JMPF R10 #0059 + 0x8C280D0D, // 0027 GETMET R10 R6 K13 + 0x7C280200, // 0028 CALL R10 1 + 0xB82E0000, // 0029 GETNGBL R11 K0 + 0x882C170E, // 002A GETMBR R11 R11 K14 + 0x882C170F, // 002B GETMBR R11 R11 K15 + 0x2428140B, // 002C GT R10 R10 R11 + 0x782A002A, // 002D JMPF R10 #0059 + 0x60280012, // 002E GETGBL R10 G18 + 0x7C280000, // 002F CALL R10 0 + 0x5C201400, // 0030 MOVE R8 R10 + 0x60280015, // 0031 GETGBL R10 G21 + 0x542E002F, // 0032 LDINT R11 48 + 0x7C280200, // 0033 CALL R10 1 + 0x8C2C0910, // 0034 GETMET R11 R4 K16 + 0x7C2C0200, // 0035 CALL R11 1 + 0x68300001, // 0036 GETUPV R12 U1 + 0x8C301911, // 0037 GETMET R12 R12 K17 + 0x5C381400, // 0038 MOVE R14 R10 + 0x5C3C0400, // 0039 MOVE R15 R2 + 0x5C401600, // 003A MOVE R16 R11 + 0x50440000, // 003B LDBOOL R17 0 0 + 0x7C300A00, // 003C CALL R12 5 + 0x8C301112, // 003D GETMET R12 R8 K18 + 0x5C381400, // 003E MOVE R14 R10 + 0x7C300400, // 003F CALL R12 2 + 0x60300010, // 0040 GETGBL R12 G16 + 0x88340D13, // 0041 GETMBR R13 R6 K19 + 0x7C300200, // 0042 CALL R12 1 + 0xA8020010, // 0043 EXBLK 0 #0055 + 0x5C341800, // 0044 MOVE R13 R12 + 0x7C340000, // 0045 CALL R13 0 + 0x60380015, // 0046 GETGBL R14 G21 + 0x543E002F, // 0047 LDINT R15 48 + 0x7C380200, // 0048 CALL R14 1 + 0x5C281C00, // 0049 MOVE R10 R14 + 0x68380001, // 004A GETUPV R14 U1 + 0x8C381D11, // 004B GETMET R14 R14 K17 + 0x5C401400, // 004C MOVE R16 R10 + 0x5C440400, // 004D MOVE R17 R2 + 0x5C481A00, // 004E MOVE R18 R13 + 0x504C0200, // 004F LDBOOL R19 1 0 + 0x7C380A00, // 0050 CALL R14 5 + 0x8C381112, // 0051 GETMET R14 R8 K18 + 0x5C401400, // 0052 MOVE R16 R10 + 0x7C380400, // 0053 CALL R14 2 + 0x7001FFEE, // 0054 JMP #0044 + 0x58300014, // 0055 LDCONST R12 K20 + 0xAC300200, // 0056 CATCH R12 1 0 + 0xB0080000, // 0057 RAISE 2 R0 R0 + 0x70020009, // 0058 JMP #0063 + 0x60280015, // 0059 GETGBL R10 G21 + 0x542E002F, // 005A LDINT R11 48 + 0x7C280200, // 005B CALL R10 1 + 0x5C201400, // 005C MOVE R8 R10 + 0x68280001, // 005D GETUPV R10 U1 + 0x8C281511, // 005E GETMET R10 R10 K17 + 0x5C301000, // 005F MOVE R12 R8 + 0x5C340400, // 0060 MOVE R13 R2 + 0x5C380C00, // 0061 MOVE R14 R6 + 0x7C280800, // 0062 CALL R10 4 + 0x68280002, // 0063 GETUPV R10 U2 + 0x742A000B, // 0064 JMPT R10 #0071 + 0xB82A2A00, // 0065 GETNGBL R10 K21 + 0x8C281516, // 0066 GETMET R10 R10 K22 + 0x60300018, // 0067 GETGBL R12 G24 + 0x58340017, // 0068 LDCONST R13 K23 + 0x68380000, // 0069 GETUPV R14 U0 + 0x88381D18, // 006A GETMBR R14 R14 K24 + 0x5C3C0400, // 006B MOVE R15 R2 + 0x5C400A00, // 006C MOVE R16 R5 + 0x5C441200, // 006D MOVE R17 R9 + 0x7C300A00, // 006E CALL R12 5 + 0x58340019, // 006F LDCONST R13 K25 + 0x7C280600, // 0070 CALL R10 3 + 0x70020038, // 0071 JMP #00AB + 0x8824051A, // 0072 GETMBR R9 R2 K26 + 0x4C280000, // 0073 LDNIL R10 + 0x2024120A, // 0074 NE R9 R9 R10 + 0x78260026, // 0075 JMPF R9 #009D + 0x780E0024, // 0076 JMPF R3 #009C + 0x60240015, // 0077 GETGBL R9 G21 + 0x542A002F, // 0078 LDINT R10 48 + 0x7C240200, // 0079 CALL R9 1 + 0x5C201200, // 007A MOVE R8 R9 + 0x68240001, // 007B GETUPV R9 U1 + 0x8C24131B, // 007C GETMET R9 R9 K27 + 0x5C2C1000, // 007D MOVE R11 R8 + 0x5C300400, // 007E MOVE R12 R2 + 0x8834051A, // 007F GETMBR R13 R2 K26 + 0x7C240800, // 0080 CALL R9 4 + 0xB8262A00, // 0081 GETNGBL R9 K21 + 0x8C24131C, // 0082 GETMET R9 R9 K28 + 0x582C0019, // 0083 LDCONST R11 K25 + 0x7C240400, // 0084 CALL R9 2 + 0x78260015, // 0085 JMPF R9 #009C + 0xB8262A00, // 0086 GETNGBL R9 K21 + 0x8C241316, // 0087 GETMET R9 R9 K22 + 0x602C0018, // 0088 GETGBL R11 G24 + 0x5830001D, // 0089 LDCONST R12 K29 + 0x68340000, // 008A GETUPV R13 U0 + 0x88341B18, // 008B GETMBR R13 R13 K24 + 0x60380008, // 008C GETGBL R14 G8 + 0x5C3C0400, // 008D MOVE R15 R2 + 0x7C380200, // 008E CALL R14 1 + 0x5C3C0A00, // 008F MOVE R15 R5 + 0x8840051A, // 0090 GETMBR R16 R2 K26 + 0x8844051A, // 0091 GETMBR R17 R2 K26 + 0xB84A0000, // 0092 GETNGBL R18 K0 + 0x8848251E, // 0093 GETMBR R18 R18 K30 + 0x1C442212, // 0094 EQ R17 R17 R18 + 0x78460001, // 0095 JMPF R17 #0098 + 0x5844001E, // 0096 LDCONST R17 K30 + 0x70020000, // 0097 JMP #0099 + 0x58440007, // 0098 LDCONST R17 K7 + 0x7C2C0C00, // 0099 CALL R11 6 + 0x58300019, // 009A LDCONST R12 K25 + 0x7C240600, // 009B CALL R9 3 + 0x7002000D, // 009C JMP #00AB + 0xB8262A00, // 009D GETNGBL R9 K21 + 0x8C241316, // 009E GETMET R9 R9 K22 + 0x602C0018, // 009F GETGBL R11 G24 + 0x5830001F, // 00A0 LDCONST R12 K31 + 0x68340000, // 00A1 GETUPV R13 U0 + 0x88341B18, // 00A2 GETMBR R13 R13 K24 + 0x60380008, // 00A3 GETGBL R14 G8 + 0x5C3C0400, // 00A4 MOVE R15 R2 + 0x7C380200, // 00A5 CALL R14 1 + 0x5C3C0A00, // 00A6 MOVE R15 R5 + 0x7C2C0800, // 00A7 CALL R11 4 + 0x58300019, // 00A8 LDCONST R12 K25 + 0x7C240600, // 00A9 CALL R9 3 + 0x501C0000, // 00AA LDBOOL R7 0 0 + 0x6024000F, // 00AB GETGBL R9 G15 + 0x5C281000, // 00AC MOVE R10 R8 + 0x602C0012, // 00AD GETGBL R11 G18 + 0x7C240400, // 00AE CALL R9 2 + 0x78260001, // 00AF JMPF R9 #00B2 + 0x58240020, // 00B0 LDCONST R9 K32 + 0x70020000, // 00B1 JMP #00B3 + 0x4C240000, // 00B2 LDNIL R9 + 0x4C280000, // 00B3 LDNIL R10 + 0x2028100A, // 00B4 NE R10 R8 R10 + 0x782A0031, // 00B5 JMPF R10 #00E8 + 0x4C280000, // 00B6 LDNIL R10 + 0x1C28120A, // 00B7 EQ R10 R9 R10 + 0x782A0001, // 00B8 JMPF R10 #00BB + 0x5C281000, // 00B9 MOVE R10 R8 + 0x70020000, // 00BA JMP #00BC + 0x94281009, // 00BB GETIDX R10 R8 R9 + 0x602C000C, // 00BC GETGBL R11 G12 + 0x88300121, // 00BD GETMBR R12 R0 K33 + 0x7C2C0200, // 00BE CALL R11 1 + 0x1C2C1720, // 00BF EQ R11 R11 K32 + 0x782E0004, // 00C0 JMPF R11 #00C6 + 0x882C0121, // 00C1 GETMBR R11 R0 K33 + 0x8C2C1712, // 00C2 GETMET R11 R11 K18 + 0x5C341400, // 00C3 MOVE R13 R10 + 0x7C2C0400, // 00C4 CALL R11 2 + 0x70020014, // 00C5 JMP #00DB + 0x542DFFFE, // 00C6 LDINT R11 -1 + 0x88300121, // 00C7 GETMBR R12 R0 K33 + 0x942C180B, // 00C8 GETIDX R11 R12 R11 + 0x6034000C, // 00C9 GETGBL R13 G12 + 0x5C381600, // 00CA MOVE R14 R11 + 0x7C340200, // 00CB CALL R13 1 + 0x6038000C, // 00CC GETGBL R14 G12 + 0x5C3C1400, // 00CD MOVE R15 R10 + 0x7C380200, // 00CE CALL R14 1 + 0x00341A0E, // 00CF ADD R13 R13 R14 + 0xB83A0000, // 00D0 GETNGBL R14 K0 + 0x88381D0E, // 00D1 GETMBR R14 R14 K14 + 0x88381D0F, // 00D2 GETMBR R14 R14 K15 + 0x18341A0E, // 00D3 LE R13 R13 R14 + 0x78360001, // 00D4 JMPF R13 #00D7 + 0x4034160A, // 00D5 CONNECT R13 R11 R10 + 0x70020003, // 00D6 JMP #00DB + 0x88300121, // 00D7 GETMBR R12 R0 K33 + 0x8C301912, // 00D8 GETMET R12 R12 K18 + 0x5C381400, // 00D9 MOVE R14 R10 + 0x7C300400, // 00DA CALL R12 2 + 0x4C2C0000, // 00DB LDNIL R11 + 0x1C2C120B, // 00DC EQ R11 R9 R11 + 0x782E0001, // 00DD JMPF R11 #00E0 + 0x4C200000, // 00DE LDNIL R8 + 0x70020006, // 00DF JMP #00E7 + 0x00241322, // 00E0 ADD R9 R9 K34 + 0x602C000C, // 00E1 GETGBL R11 G12 + 0x5C301000, // 00E2 MOVE R12 R8 + 0x7C2C0200, // 00E3 CALL R11 1 + 0x282C120B, // 00E4 GE R11 R9 R11 + 0x782E0000, // 00E5 JMPF R11 #00E7 + 0x4C200000, // 00E6 LDNIL R8 + 0x7001FFCA, // 00E7 JMP #00B3 + 0x80040E00, // 00E8 RET 1 R7 }) ), be_nested_proto( @@ -1663,44 +2517,44 @@ be_local_closure(Matter_IM__inner_process_read_request, /* name */ }), 1, /* has constants */ ( &(const bvalue[25]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(device), - /* K2 */ be_nested_str_weak(get_active_endpoints), - /* K3 */ be_nested_str_weak(matter), - /* K4 */ be_nested_str_weak(Path), + /* K0 */ be_nested_str_weak(device), + /* K1 */ be_nested_str_weak(get_active_endpoints), + /* K2 */ be_nested_str_weak(matter), + /* K3 */ be_nested_str_weak(Path), + /* K4 */ be_nested_str_weak(msg), /* K5 */ be_nested_str_weak(ReportDataMessage), /* K6 */ be_nested_str_weak(attribute_reports), /* K7 */ be_nested_str_weak(attributes_requests), /* K8 */ be_nested_str_weak(endpoint), /* K9 */ be_nested_str_weak(cluster), /* K10 */ be_nested_str_weak(attribute), - /* K11 */ be_nested_str_weak(status), - /* K12 */ be_nested_str_weak(UNSUPPORTED_ATTRIBUTE), - /* K13 */ be_nested_str_weak(get_attribute_name), - /* K14 */ be_nested_str_weak(tasmota), - /* K15 */ be_nested_str_weak(log), - /* K16 */ be_nested_str_weak(format), + /* K11 */ be_nested_str_weak(fabric_filtered), + /* K12 */ be_nested_str_weak(status), + /* K13 */ be_nested_str_weak(UNSUPPORTED_ATTRIBUTE), + /* K14 */ be_nested_str_weak(get_attribute_name), + /* K15 */ be_nested_str_weak(tasmota), + /* K16 */ be_nested_str_weak(log), /* K17 */ be_nested_str_weak(MTR_X3A_X20_X3ERead_Attr_X20_X28_X256i_X29_X20_X25s), /* K18 */ be_nested_str_weak(local_session_id), /* K19 */ be_nested_str_weak(_X20_X28), /* K20 */ be_nested_str_weak(_X29), /* K21 */ be_nested_str_weak(), - /* K22 */ be_const_int(2), + /* K22 */ be_const_int(3), /* K23 */ be_nested_str_weak(process_attribute_expansion), /* K24 */ be_nested_str_weak(stop_iteration), }), be_str_weak(_inner_process_read_request), &be_const_str_solidified, - ( &(const binstruction[94]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0x84140000, // 0001 CLOSURE R5 P0 - 0x88180101, // 0002 GETMBR R6 R0 K1 - 0x8C180D02, // 0003 GETMET R6 R6 K2 - 0x7C180200, // 0004 CALL R6 1 - 0xB81E0600, // 0005 GETNGBL R7 K3 - 0x8C1C0F04, // 0006 GETMET R7 R7 K4 - 0x7C1C0200, // 0007 CALL R7 1 - 0xB8220600, // 0008 GETNGBL R8 K3 + ( &(const binstruction[96]) { /* code */ + 0x84140000, // 0000 CLOSURE R5 P0 + 0x88180100, // 0001 GETMBR R6 R0 K0 + 0x8C180D01, // 0002 GETMET R6 R6 K1 + 0x7C180200, // 0003 CALL R6 1 + 0xB81E0400, // 0004 GETNGBL R7 K2 + 0x8C1C0F03, // 0005 GETMET R7 R7 K3 + 0x7C1C0200, // 0006 CALL R7 1 + 0x901E0803, // 0007 SETMBR R7 K4 R3 + 0xB8220400, // 0008 GETNGBL R8 K2 0x8C201105, // 0009 GETMET R8 R8 K5 0x7C200200, // 000A CALL R8 1 0x60240012, // 000B GETGBL R9 G18 @@ -1709,7 +2563,7 @@ be_local_closure(Matter_IM__inner_process_read_request, /* name */ 0x60240010, // 000E GETGBL R9 G16 0x88280507, // 000F GETMBR R10 R2 K7 0x7C240200, // 0010 CALL R9 1 - 0xA8020046, // 0011 EXBLK 0 #0059 + 0xA8020048, // 0011 EXBLK 0 #005B 0x5C281200, // 0012 MOVE R10 R9 0x7C280000, // 0013 CALL R10 0 0x882C1508, // 0014 GETMBR R11 R10 K8 @@ -1718,74 +2572,76 @@ be_local_closure(Matter_IM__inner_process_read_request, /* name */ 0x901E120B, // 0017 SETMBR R7 K9 R11 0x882C150A, // 0018 GETMBR R11 R10 K10 0x901E140B, // 0019 SETMBR R7 K10 R11 - 0xB82E0600, // 001A GETNGBL R11 K3 - 0x882C170C, // 001B GETMBR R11 R11 K12 - 0x901E160B, // 001C SETMBR R7 K11 R11 - 0x882C0F08, // 001D GETMBR R11 R7 K8 - 0x4C300000, // 001E LDNIL R12 - 0x1C2C160C, // 001F EQ R11 R11 R12 - 0x742E0007, // 0020 JMPT R11 #0029 - 0x882C0F09, // 0021 GETMBR R11 R7 K9 - 0x4C300000, // 0022 LDNIL R12 - 0x1C2C160C, // 0023 EQ R11 R11 R12 - 0x742E0003, // 0024 JMPT R11 #0029 - 0x882C0F0A, // 0025 GETMBR R11 R7 K10 - 0x4C300000, // 0026 LDNIL R12 - 0x1C2C160C, // 0027 EQ R11 R11 R12 - 0x782E0029, // 0028 JMPF R11 #0053 - 0x882C0F09, // 0029 GETMBR R11 R7 K9 - 0x4C300000, // 002A LDNIL R12 - 0x202C160C, // 002B NE R11 R11 R12 - 0x782E001A, // 002C JMPF R11 #0048 - 0x882C0F0A, // 002D GETMBR R11 R7 K10 - 0x4C300000, // 002E LDNIL R12 - 0x202C160C, // 002F NE R11 R11 R12 - 0x782E0016, // 0030 JMPF R11 #0048 - 0xB82E0600, // 0031 GETNGBL R11 K3 - 0x8C2C170D, // 0032 GETMET R11 R11 K13 - 0x88340F09, // 0033 GETMBR R13 R7 K9 - 0x88380F0A, // 0034 GETMBR R14 R7 K10 - 0x7C2C0600, // 0035 CALL R11 3 - 0xB8321C00, // 0036 GETNGBL R12 K14 - 0x8C30190F, // 0037 GETMET R12 R12 K15 - 0x8C380910, // 0038 GETMET R14 R4 K16 - 0x58400011, // 0039 LDCONST R16 K17 - 0x88440312, // 003A GETMBR R17 R1 K18 - 0x60480008, // 003B GETGBL R18 G8 - 0x5C4C0E00, // 003C MOVE R19 R7 - 0x7C480200, // 003D CALL R18 1 - 0x782E0002, // 003E JMPF R11 #0042 - 0x004E260B, // 003F ADD R19 K19 R11 - 0x004C2714, // 0040 ADD R19 R19 K20 - 0x70020000, // 0041 JMP #0043 - 0x584C0015, // 0042 LDCONST R19 K21 - 0x00482413, // 0043 ADD R18 R18 R19 - 0x7C380800, // 0044 CALL R14 4 - 0x583C0016, // 0045 LDCONST R15 K22 - 0x7C300600, // 0046 CALL R12 3 - 0x7002000A, // 0047 JMP #0053 - 0xB82E1C00, // 0048 GETNGBL R11 K14 - 0x8C2C170F, // 0049 GETMET R11 R11 K15 - 0x8C340910, // 004A GETMET R13 R4 K16 - 0x583C0011, // 004B LDCONST R15 K17 - 0x88400312, // 004C GETMBR R16 R1 K18 - 0x60440008, // 004D GETGBL R17 G8 - 0x5C480E00, // 004E MOVE R18 R7 - 0x7C440200, // 004F CALL R17 1 - 0x7C340800, // 0050 CALL R13 4 - 0x58380016, // 0051 LDCONST R14 K22 - 0x7C2C0600, // 0052 CALL R11 3 - 0x882C0101, // 0053 GETMBR R11 R0 K1 - 0x8C2C1717, // 0054 GETMET R11 R11 K23 - 0x5C340E00, // 0055 MOVE R13 R7 - 0x84380001, // 0056 CLOSURE R14 P1 - 0x7C2C0600, // 0057 CALL R11 3 - 0x7001FFB8, // 0058 JMP #0012 - 0x58240018, // 0059 LDCONST R9 K24 - 0xAC240200, // 005A CATCH R9 1 0 - 0xB0080000, // 005B RAISE 2 R0 R0 - 0xA0000000, // 005C CLOSE R0 - 0x80041000, // 005D RET 1 R8 + 0x882C050B, // 001A GETMBR R11 R2 K11 + 0x901E160B, // 001B SETMBR R7 K11 R11 + 0xB82E0400, // 001C GETNGBL R11 K2 + 0x882C170D, // 001D GETMBR R11 R11 K13 + 0x901E180B, // 001E SETMBR R7 K12 R11 + 0x882C0F08, // 001F GETMBR R11 R7 K8 + 0x4C300000, // 0020 LDNIL R12 + 0x1C2C160C, // 0021 EQ R11 R11 R12 + 0x742E0007, // 0022 JMPT R11 #002B + 0x882C0F09, // 0023 GETMBR R11 R7 K9 + 0x4C300000, // 0024 LDNIL R12 + 0x1C2C160C, // 0025 EQ R11 R11 R12 + 0x742E0003, // 0026 JMPT R11 #002B + 0x882C0F0A, // 0027 GETMBR R11 R7 K10 + 0x4C300000, // 0028 LDNIL R12 + 0x1C2C160C, // 0029 EQ R11 R11 R12 + 0x782E0029, // 002A JMPF R11 #0055 + 0x882C0F09, // 002B GETMBR R11 R7 K9 + 0x4C300000, // 002C LDNIL R12 + 0x202C160C, // 002D NE R11 R11 R12 + 0x782E001A, // 002E JMPF R11 #004A + 0x882C0F0A, // 002F GETMBR R11 R7 K10 + 0x4C300000, // 0030 LDNIL R12 + 0x202C160C, // 0031 NE R11 R11 R12 + 0x782E0016, // 0032 JMPF R11 #004A + 0xB82E0400, // 0033 GETNGBL R11 K2 + 0x8C2C170E, // 0034 GETMET R11 R11 K14 + 0x88340F09, // 0035 GETMBR R13 R7 K9 + 0x88380F0A, // 0036 GETMBR R14 R7 K10 + 0x7C2C0600, // 0037 CALL R11 3 + 0xB8321E00, // 0038 GETNGBL R12 K15 + 0x8C301910, // 0039 GETMET R12 R12 K16 + 0x60380018, // 003A GETGBL R14 G24 + 0x583C0011, // 003B LDCONST R15 K17 + 0x88400312, // 003C GETMBR R16 R1 K18 + 0x60440008, // 003D GETGBL R17 G8 + 0x5C480E00, // 003E MOVE R18 R7 + 0x7C440200, // 003F CALL R17 1 + 0x782E0002, // 0040 JMPF R11 #0044 + 0x004A260B, // 0041 ADD R18 K19 R11 + 0x00482514, // 0042 ADD R18 R18 K20 + 0x70020000, // 0043 JMP #0045 + 0x58480015, // 0044 LDCONST R18 K21 + 0x00442212, // 0045 ADD R17 R17 R18 + 0x7C380600, // 0046 CALL R14 3 + 0x583C0016, // 0047 LDCONST R15 K22 + 0x7C300600, // 0048 CALL R12 3 + 0x7002000A, // 0049 JMP #0055 + 0xB82E1E00, // 004A GETNGBL R11 K15 + 0x8C2C1710, // 004B GETMET R11 R11 K16 + 0x60340018, // 004C GETGBL R13 G24 + 0x58380011, // 004D LDCONST R14 K17 + 0x883C0312, // 004E GETMBR R15 R1 K18 + 0x60400008, // 004F GETGBL R16 G8 + 0x5C440E00, // 0050 MOVE R17 R7 + 0x7C400200, // 0051 CALL R16 1 + 0x7C340600, // 0052 CALL R13 3 + 0x58380016, // 0053 LDCONST R14 K22 + 0x7C2C0600, // 0054 CALL R11 3 + 0x882C0100, // 0055 GETMBR R11 R0 K0 + 0x8C2C1717, // 0056 GETMET R11 R11 K23 + 0x5C340E00, // 0057 MOVE R13 R7 + 0x84380001, // 0058 CLOSURE R14 P1 + 0x7C2C0600, // 0059 CALL R11 3 + 0x7001FFB6, // 005A JMP #0012 + 0x58240018, // 005B LDCONST R9 K24 + 0xAC240200, // 005C CATCH R9 1 0 + 0xB0080000, // 005D RAISE 2 R0 R0 + 0xA0000000, // 005E CLOSE R0 + 0x80041000, // 005F RET 1 R8 }) ) ); @@ -1793,49 +2649,34 @@ be_local_closure(Matter_IM__inner_process_read_request, /* name */ /******************************************************************** -** Solidified function: find_sendqueue_by_exchangeid +** Solidified function: report_data ********************************************************************/ -be_local_closure(Matter_IM_find_sendqueue_by_exchangeid, /* name */ +be_local_closure(Matter_IM_report_data, /* name */ be_nested_proto( 6, /* nstack */ - 2, /* argc */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_const_int(0), - /* K1 */ be_nested_str_weak(send_queue), - /* K2 */ be_nested_str_weak(get_exchangeid), - /* K3 */ be_const_int(1), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(ReportDataMessage), + /* K2 */ be_nested_str_weak(from_TLV), }), - be_str_weak(find_sendqueue_by_exchangeid), + be_str_weak(report_data), &be_const_str_solidified, - ( &(const binstruction[22]) { /* code */ - 0x4C080000, // 0000 LDNIL R2 - 0x1C080202, // 0001 EQ R2 R1 R2 - 0x780A0001, // 0002 JMPF R2 #0005 - 0x4C080000, // 0003 LDNIL R2 - 0x80040400, // 0004 RET 1 R2 - 0x58080000, // 0005 LDCONST R2 K0 - 0x600C000C, // 0006 GETGBL R3 G12 - 0x88100101, // 0007 GETMBR R4 R0 K1 - 0x7C0C0200, // 0008 CALL R3 1 - 0x140C0403, // 0009 LT R3 R2 R3 - 0x780E0008, // 000A JMPF R3 #0014 - 0x880C0101, // 000B GETMBR R3 R0 K1 - 0x940C0602, // 000C GETIDX R3 R3 R2 - 0x8C100702, // 000D GETMET R4 R3 K2 - 0x7C100200, // 000E CALL R4 1 - 0x1C100801, // 000F EQ R4 R4 R1 - 0x78120000, // 0010 JMPF R4 #0012 - 0x80040600, // 0011 RET 1 R3 - 0x00080503, // 0012 ADD R2 R2 K3 - 0x7001FFF1, // 0013 JMP #0006 - 0x4C0C0000, // 0014 LDNIL R3 - 0x80040600, // 0015 RET 1 R3 + ( &(const binstruction[ 8]) { /* code */ + 0xB80E0000, // 0000 GETNGBL R3 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x7C0C0200, // 0002 CALL R3 1 + 0x8C0C0702, // 0003 GETMET R3 R3 K2 + 0x5C140400, // 0004 MOVE R5 R2 + 0x7C0C0400, // 0005 CALL R3 2 + 0x50100000, // 0006 LDBOOL R4 0 0 + 0x80040800, // 0007 RET 1 R4 }) ) ); @@ -1843,59 +2684,76 @@ be_local_closure(Matter_IM_find_sendqueue_by_exchangeid, /* name */ /******************************************************************** -** Solidified function: process_incoming_ack +** Solidified function: attributestatus2raw ********************************************************************/ -be_local_closure(Matter_IM_process_incoming_ack, /* name */ +be_local_closure(Matter_IM_attributestatus2raw, /* name */ be_nested_proto( - 11, /* nstack */ - 2, /* argc */ + 9, /* nstack */ + 4, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(find_sendqueue_by_exchangeid), - /* K2 */ be_nested_str_weak(exchange_id), - /* K3 */ be_nested_str_weak(tasmota), - /* K4 */ be_nested_str_weak(log), - /* K5 */ be_nested_str_weak(format), - /* K6 */ be_nested_str_weak(MTR_X3A_X20process_incoming_ack_X20exch_X3D_X25i_X20message_X3D_X25i), - /* K7 */ be_const_int(1), - /* K8 */ be_const_int(0), - /* K9 */ be_const_int(3), - /* K10 */ be_nested_str_weak(ack_received), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(add), + /* K1 */ be_const_int(1), + /* K2 */ be_nested_str_weak(path2raw), + /* K3 */ be_const_int(0), + /* K4 */ be_nested_str_weak(status), + /* K5 */ be_const_int(2), }), - be_str_weak(process_incoming_ack), + be_str_weak(attributestatus2raw), &be_const_str_solidified, - ( &(const binstruction[25]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x8C0C0101, // 0001 GETMET R3 R0 K1 - 0x88140302, // 0002 GETMBR R5 R1 K2 - 0x7C0C0400, // 0003 CALL R3 2 - 0xB8120600, // 0004 GETNGBL R4 K3 - 0x8C100904, // 0005 GETMET R4 R4 K4 - 0x8C180505, // 0006 GETMET R6 R2 K5 - 0x58200006, // 0007 LDCONST R8 K6 - 0x88240302, // 0008 GETMBR R9 R1 K2 - 0x4C280000, // 0009 LDNIL R10 - 0x2028060A, // 000A NE R10 R3 R10 - 0x782A0001, // 000B JMPF R10 #000E - 0x58280007, // 000C LDCONST R10 K7 - 0x70020000, // 000D JMP #000F - 0x58280008, // 000E LDCONST R10 K8 - 0x7C180800, // 000F CALL R6 4 - 0x581C0009, // 0010 LDCONST R7 K9 - 0x7C100600, // 0011 CALL R4 3 - 0x780E0003, // 0012 JMPF R3 #0017 - 0x8C10070A, // 0013 GETMET R4 R3 K10 - 0x5C180200, // 0014 MOVE R6 R1 - 0x7C100400, // 0015 CALL R4 2 - 0x80040800, // 0016 RET 1 R4 - 0x50100000, // 0017 LDBOOL R4 0 0 - 0x80040800, // 0018 RET 1 R4 + ( &(const binstruction[47]) { /* code */ + 0x8C100300, // 0000 GETMET R4 R1 K0 + 0x541A0014, // 0001 LDINT R6 21 + 0x581C0001, // 0002 LDCONST R7 K1 + 0x7C100600, // 0003 CALL R4 3 + 0x8C100300, // 0004 GETMET R4 R1 K0 + 0x541A34FF, // 0005 LDINT R6 13568 + 0x541DFFFD, // 0006 LDINT R7 -2 + 0x7C100600, // 0007 CALL R4 3 + 0x8C100102, // 0008 GETMET R4 R0 K2 + 0x5C180200, // 0009 MOVE R6 R1 + 0x5C1C0400, // 000A MOVE R7 R2 + 0x58200003, // 000B LDCONST R8 K3 + 0x7C100800, // 000C CALL R4 4 + 0x8C100300, // 000D GETMET R4 R1 K0 + 0x541A3500, // 000E LDINT R6 13569 + 0x541DFFFD, // 000F LDINT R7 -2 + 0x7C100600, // 0010 CALL R4 3 + 0x88100504, // 0011 GETMBR R4 R2 K4 + 0x541600FE, // 0012 LDINT R5 255 + 0x18100805, // 0013 LE R4 R4 R5 + 0x78120008, // 0014 JMPF R4 #001E + 0x8C100300, // 0015 GETMET R4 R1 K0 + 0x541A23FF, // 0016 LDINT R6 9216 + 0x541DFFFD, // 0017 LDINT R7 -2 + 0x7C100600, // 0018 CALL R4 3 + 0x8C100300, // 0019 GETMET R4 R1 K0 + 0x88180504, // 001A GETMBR R6 R2 K4 + 0x581C0001, // 001B LDCONST R7 K1 + 0x7C100600, // 001C CALL R4 3 + 0x70020007, // 001D JMP #0026 + 0x8C100300, // 001E GETMET R4 R1 K0 + 0x541A24FF, // 001F LDINT R6 9472 + 0x541DFFFD, // 0020 LDINT R7 -2 + 0x7C100600, // 0021 CALL R4 3 + 0x8C100300, // 0022 GETMET R4 R1 K0 + 0x88180504, // 0023 GETMBR R6 R2 K4 + 0x581C0005, // 0024 LDCONST R7 K5 + 0x7C100600, // 0025 CALL R4 3 + 0x8C100300, // 0026 GETMET R4 R1 K0 + 0x541A1817, // 0027 LDINT R6 6168 + 0x541DFFFD, // 0028 LDINT R7 -2 + 0x7C100600, // 0029 CALL R4 3 + 0x8C100300, // 002A GETMET R4 R1 K0 + 0x541A0017, // 002B LDINT R6 24 + 0x581C0001, // 002C LDCONST R7 K1 + 0x7C100600, // 002D CALL R4 3 + 0x80000000, // 002E RET 0 }) ) ); @@ -1903,50 +2761,37 @@ be_local_closure(Matter_IM_process_incoming_ack, /* name */ /******************************************************************** -** Solidified function: process_read_request +** Solidified function: send_subscribe_response ********************************************************************/ -be_local_closure(Matter_IM_process_read_request, /* name */ +be_local_closure(Matter_IM_send_subscribe_response, /* name */ be_nested_proto( - 9, /* nstack */ - 3, /* argc */ + 11, /* nstack */ + 4, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str_weak(matter), - /* K1 */ be_nested_str_weak(ReadRequestMessage), - /* K2 */ be_nested_str_weak(from_TLV), - /* K3 */ be_nested_str_weak(attributes_requests), - /* K4 */ be_nested_str_weak(_inner_process_read_request), - /* K5 */ be_nested_str_weak(session), - /* K6 */ be_nested_str_weak(send_report_data), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(send_queue), + /* K1 */ be_nested_str_weak(push), + /* K2 */ be_nested_str_weak(matter), + /* K3 */ be_nested_str_weak(IM_SubscribeResponse), }), - be_str_weak(process_read_request), + be_str_weak(send_subscribe_response), &be_const_str_solidified, - ( &(const binstruction[20]) { /* code */ - 0xB80E0000, // 0000 GETNGBL R3 K0 - 0x8C0C0701, // 0001 GETMET R3 R3 K1 - 0x7C0C0200, // 0002 CALL R3 1 - 0x8C0C0702, // 0003 GETMET R3 R3 K2 - 0x5C140400, // 0004 MOVE R5 R2 - 0x7C0C0400, // 0005 CALL R3 2 - 0x88100703, // 0006 GETMBR R4 R3 K3 - 0x4C140000, // 0007 LDNIL R5 - 0x20100805, // 0008 NE R4 R4 R5 - 0x78120007, // 0009 JMPF R4 #0012 - 0x8C100104, // 000A GETMET R4 R0 K4 - 0x88180305, // 000B GETMBR R6 R1 K5 - 0x5C1C0600, // 000C MOVE R7 R3 - 0x7C100600, // 000D CALL R4 3 - 0x8C140106, // 000E GETMET R5 R0 K6 - 0x5C1C0200, // 000F MOVE R7 R1 - 0x5C200800, // 0010 MOVE R8 R4 - 0x7C140600, // 0011 CALL R5 3 - 0x50100200, // 0012 LDBOOL R4 1 0 - 0x80040800, // 0013 RET 1 R4 + ( &(const binstruction[10]) { /* code */ + 0x88100100, // 0000 GETMBR R4 R0 K0 + 0x8C100901, // 0001 GETMET R4 R4 K1 + 0xB81A0400, // 0002 GETNGBL R6 K2 + 0x8C180D03, // 0003 GETMET R6 R6 K3 + 0x5C200200, // 0004 MOVE R8 R1 + 0x5C240400, // 0005 MOVE R9 R2 + 0x5C280600, // 0006 MOVE R10 R3 + 0x7C180800, // 0007 CALL R6 4 + 0x7C100400, // 0008 CALL R4 2 + 0x80000000, // 0009 RET 0 }) ) ); @@ -1991,88 +2836,49 @@ be_local_closure(Matter_IM_send_report_data, /* name */ /******************************************************************** -** Solidified function: process_status_response +** Solidified function: find_sendqueue_by_exchangeid ********************************************************************/ -be_local_closure(Matter_IM_process_status_response, /* name */ +be_local_closure(Matter_IM_find_sendqueue_by_exchangeid, /* name */ be_nested_proto( - 13, /* nstack */ - 3, /* argc */ + 6, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[19]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(findsubval), - /* K2 */ be_const_int(0), - /* K3 */ be_nested_str_weak(find_sendqueue_by_exchangeid), - /* K4 */ be_nested_str_weak(exchange_id), - /* K5 */ be_nested_str_weak(matter), - /* K6 */ be_nested_str_weak(SUCCESS), - /* K7 */ be_nested_str_weak(status_ok_received), - /* K8 */ be_nested_str_weak(tasmota), - /* K9 */ be_nested_str_weak(log), - /* K10 */ be_nested_str_weak(format), - /* K11 */ be_nested_str_weak(MTR_X3A_X20_X3EOK_X20_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20exch_X3D_X25i_X20not_X20found), - /* K12 */ be_nested_str_weak(session), - /* K13 */ be_nested_str_weak(local_session_id), - /* K14 */ be_const_int(3), - /* K15 */ be_nested_str_weak(MTR_X3A_X20_X3EStatus_X20_X20_X20_X20ERROR_X20_X3D_X200x_X2502X), - /* K16 */ be_const_int(2), - /* K17 */ be_nested_str_weak(status_error_received), - /* K18 */ be_nested_str_weak(remove_sendqueue_by_exchangeid), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(send_queue), + /* K2 */ be_nested_str_weak(get_exchangeid), + /* K3 */ be_const_int(1), }), - be_str_weak(process_status_response), + be_str_weak(find_sendqueue_by_exchangeid), &be_const_str_solidified, - ( &(const binstruction[46]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0x8C100501, // 0001 GETMET R4 R2 K1 - 0x58180002, // 0002 LDCONST R6 K2 - 0x541E00FE, // 0003 LDINT R7 255 - 0x7C100600, // 0004 CALL R4 3 - 0x8C140103, // 0005 GETMET R5 R0 K3 - 0x881C0304, // 0006 GETMBR R7 R1 K4 - 0x7C140400, // 0007 CALL R5 2 - 0xB81A0A00, // 0008 GETNGBL R6 K5 - 0x88180D06, // 0009 GETMBR R6 R6 K6 - 0x1C180806, // 000A EQ R6 R4 R6 - 0x781A0010, // 000B JMPF R6 #001D - 0x78160004, // 000C JMPF R5 #0012 - 0x8C180B07, // 000D GETMET R6 R5 K7 - 0x5C200200, // 000E MOVE R8 R1 - 0x7C180400, // 000F CALL R6 2 - 0x80040C00, // 0010 RET 1 R6 - 0x70020009, // 0011 JMP #001C - 0xB81A1000, // 0012 GETNGBL R6 K8 - 0x8C180D09, // 0013 GETMET R6 R6 K9 - 0x8C20070A, // 0014 GETMET R8 R3 K10 - 0x5828000B, // 0015 LDCONST R10 K11 - 0x882C030C, // 0016 GETMBR R11 R1 K12 - 0x882C170D, // 0017 GETMBR R11 R11 K13 - 0x88300304, // 0018 GETMBR R12 R1 K4 - 0x7C200800, // 0019 CALL R8 4 - 0x5824000E, // 001A LDCONST R9 K14 - 0x7C180600, // 001B CALL R6 3 - 0x7002000E, // 001C JMP #002C - 0xB81A1000, // 001D GETNGBL R6 K8 - 0x8C180D09, // 001E GETMET R6 R6 K9 - 0x8C20070A, // 001F GETMET R8 R3 K10 - 0x5828000F, // 0020 LDCONST R10 K15 - 0x5C2C0800, // 0021 MOVE R11 R4 - 0x7C200600, // 0022 CALL R8 3 - 0x58240010, // 0023 LDCONST R9 K16 - 0x7C180600, // 0024 CALL R6 3 - 0x78160005, // 0025 JMPF R5 #002C - 0x8C180B11, // 0026 GETMET R6 R5 K17 - 0x5C200200, // 0027 MOVE R8 R1 - 0x7C180400, // 0028 CALL R6 2 - 0x8C180112, // 0029 GETMET R6 R0 K18 - 0x88200304, // 002A GETMBR R8 R1 K4 - 0x7C180400, // 002B CALL R6 2 - 0x50180000, // 002C LDBOOL R6 0 0 - 0x80040C00, // 002D RET 1 R6 + ( &(const binstruction[22]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x1C080202, // 0001 EQ R2 R1 R2 + 0x780A0001, // 0002 JMPF R2 #0005 + 0x4C080000, // 0003 LDNIL R2 + 0x80040400, // 0004 RET 1 R2 + 0x58080000, // 0005 LDCONST R2 K0 + 0x600C000C, // 0006 GETGBL R3 G12 + 0x88100101, // 0007 GETMBR R4 R0 K1 + 0x7C0C0200, // 0008 CALL R3 1 + 0x140C0403, // 0009 LT R3 R2 R3 + 0x780E0008, // 000A JMPF R3 #0014 + 0x880C0101, // 000B GETMBR R3 R0 K1 + 0x940C0602, // 000C GETIDX R3 R3 R2 + 0x8C100702, // 000D GETMET R4 R3 K2 + 0x7C100200, // 000E CALL R4 1 + 0x1C100801, // 000F EQ R4 R4 R1 + 0x78120000, // 0010 JMPF R4 #0012 + 0x80040600, // 0011 RET 1 R3 + 0x00080503, // 0012 ADD R2 R2 K3 + 0x7001FFF1, // 0013 JMP #0006 + 0x4C0C0000, // 0014 LDNIL R3 + 0x80040600, // 0015 RET 1 R3 }) ) ); @@ -2080,11 +2886,11 @@ be_local_closure(Matter_IM_process_status_response, /* name */ /******************************************************************** -** Solidified function: process_write_response +** Solidified function: process_read_request_solo ********************************************************************/ -be_local_closure(Matter_IM_process_write_response, /* name */ +be_local_closure(Matter_IM_process_read_request_solo, /* name */ be_nested_proto( - 9, /* nstack */ + 20, /* nstack */ 3, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2092,154 +2898,317 @@ be_local_closure(Matter_IM_process_write_response, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(string), + ( &(const bvalue[55]) { /* constants */ + /* K0 */ be_nested_str_weak(status), /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(WriteResponseMessage), - /* K3 */ be_nested_str_weak(from_TLV), - /* K4 */ be_nested_str_weak(tasmota), - /* K5 */ be_nested_str_weak(log), - /* K6 */ be_nested_str_weak(MTR_X3A_X20received_X20WriteResponseMessage_X3D), - /* K7 */ be_const_int(2), - }), - be_str_weak(process_write_response), - &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x8C100902, // 0002 GETMET R4 R4 K2 - 0x7C100200, // 0003 CALL R4 1 - 0x8C100903, // 0004 GETMET R4 R4 K3 - 0x5C180400, // 0005 MOVE R6 R2 - 0x7C100400, // 0006 CALL R4 2 - 0xB8160800, // 0007 GETNGBL R5 K4 - 0x8C140B05, // 0008 GETMET R5 R5 K5 - 0x601C0008, // 0009 GETGBL R7 G8 - 0x5C200800, // 000A MOVE R8 R4 - 0x7C1C0200, // 000B CALL R7 1 - 0x001E0C07, // 000C ADD R7 K6 R7 - 0x58200007, // 000D LDCONST R8 K7 - 0x7C140600, // 000E CALL R5 3 - 0x50140000, // 000F LDBOOL R5 0 0 - 0x80040A00, // 0010 RET 1 R5 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: send_subscribe_update -********************************************************************/ -be_local_closure(Matter_IM_send_subscribe_update, /* name */ - be_nested_proto( - 12, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[27]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(session), - /* K2 */ be_nested_str_weak(matter), - /* K3 */ be_nested_str_weak(ReadRequestMessage), - /* K4 */ be_nested_str_weak(fabric_filtered), - /* K5 */ be_nested_str_weak(attributes_requests), - /* K6 */ be_nested_str_weak(updates), - /* K7 */ be_nested_str_weak(AttributePathIB), - /* K8 */ be_nested_str_weak(endpoint), - /* K9 */ be_nested_str_weak(cluster), - /* K10 */ be_nested_str_weak(attribute), - /* K11 */ be_nested_str_weak(push), - /* K12 */ be_nested_str_weak(stop_iteration), - /* K13 */ be_nested_str_weak(tasmota), - /* K14 */ be_nested_str_weak(log), - /* K15 */ be_nested_str_weak(format), - /* K16 */ be_nested_str_weak(MTR_X3A_X20_X3CSub_Data_X20_X20_X28_X256i_X29_X20sub_X3D_X25i), - /* K17 */ be_nested_str_weak(local_session_id), - /* K18 */ be_nested_str_weak(subscription_id), - /* K19 */ be_const_int(2), - /* K20 */ be_nested_str_weak(is_keep_alive), - /* K21 */ be_nested_str_weak(_inner_process_read_request), - /* K22 */ be_nested_str_weak(suppress_response), - /* K23 */ be_nested_str_weak(IM_ReportDataSubscribed), - /* K24 */ be_nested_str_weak(_message_handler), - /* K25 */ be_nested_str_weak(send_queue), - /* K26 */ be_nested_str_weak(send_enqueued), + /* K2 */ be_nested_str_weak(INVALID_ACTION), + /* K3 */ be_nested_str_weak(msg), + /* K4 */ be_nested_str_weak(device), + /* K5 */ be_nested_str_weak(process_attribute_read_solo), + /* K6 */ be_nested_str_weak(UNSUPPORTED_ATTRIBUTE), + /* K7 */ be_nested_str_weak(read_attribute), + /* K8 */ be_nested_str_weak(session), + /* K9 */ be_nested_str_weak(tlv_solo), + /* K10 */ be_nested_str_weak(profiler), + /* K11 */ be_nested_str_weak(log), + /* K12 */ be_nested_str_weak(read_request_solo_X20read_X20done), + /* K13 */ be_nested_str_weak(is_list), + /* K14 */ be_nested_str_weak(is_array), + /* K15 */ be_nested_str_weak(encode_len), + /* K16 */ be_nested_str_weak(IM_ReportData), + /* K17 */ be_nested_str_weak(MAX_MESSAGE), + /* K18 */ be_nested_str_weak(tasmota), + /* K19 */ be_nested_str_weak(MTR_X3A_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Response_X20to_X20big_X2C_X20revert_X20to_X20non_X2Dsolo), + /* K20 */ be_const_int(3), + /* K21 */ be_nested_str_weak(TLV), + /* K22 */ be_nested_str_weak(parse), + /* K23 */ be_nested_str_weak(raw), + /* K24 */ be_nested_str_weak(app_payload_idx), + /* K25 */ be_nested_str_weak(process_read_request), + /* K26 */ be_nested_str_weak(add), + /* K27 */ be_const_int(1), + /* K28 */ be_nested_str_weak(attributedata2raw), + /* K29 */ be_const_int(405077761), + /* K30 */ be_nested_str_weak(attributestatus2raw), + /* K31 */ be_nested_str_weak(MTR_X3A_X20_X3ERead_Attr_X20_X28_X256i_X29_X20_X25s_X20_X2D_X20IGNORED), + /* K32 */ be_nested_str_weak(local_session_id), + /* K33 */ be_nested_str_weak(build_response), + /* K34 */ be_nested_str_weak(message_handler), + /* K35 */ be_nested_str_weak(clear), + /* K36 */ be_nested_str_weak(encode_frame), + /* K37 */ be_nested_str_weak(encrypt), + /* K38 */ be_nested_str_weak(loglevel), + /* K39 */ be_nested_str_weak(MTR_X3A_X20_X3Csnd_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20id_X3D_X25i_X20exch_X3D_X25i_X20rack_X3D_X25s), + /* K40 */ be_nested_str_weak(message_counter), + /* K41 */ be_nested_str_weak(exchange_id), + /* K42 */ be_nested_str_weak(ack_message_counter), + /* K43 */ be_nested_str_weak(send_response_frame), + /* K44 */ be_nested_str_weak(RESPONSE_X20SENT), + /* K45 */ be_nested_str_weak(get_attribute_name), + /* K46 */ be_nested_str_weak(cluster), + /* K47 */ be_nested_str_weak(attribute), + /* K48 */ be_nested_str_weak(_X20_X28), + /* K49 */ be_nested_str_weak(_X29), + /* K50 */ be_nested_str_weak(), + /* K51 */ be_nested_str_weak(to_str_val), + /* K52 */ be_nested_str_weak(MTR_X3A_X20_X3ERead_Attr1_X28_X256i_X29_X20_X25s_X25s_X20_X2D_X20_X25s), + /* K53 */ be_nested_str_weak(MTR_X3A_X20_X3ERead_Attr1_X28_X256i_X29_X20_X25s_X25s_X20_X2D_X20STATUS_X3A_X200x_X2502X_X20_X25s), + /* K54 */ be_nested_str_weak(MTR_X3A_X20_X3ERead_Attr1_X28_X256i_X29_X20_X25s_X25s_X20_X2D_X20IGNORED), }), - be_str_weak(send_subscribe_update), + be_str_weak(process_read_request_solo), &be_const_str_solidified, - ( &(const binstruction[67]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x880C0301, // 0001 GETMBR R3 R1 K1 - 0xB8120400, // 0002 GETNGBL R4 K2 - 0x8C100903, // 0003 GETMET R4 R4 K3 - 0x7C100200, // 0004 CALL R4 1 - 0x50140000, // 0005 LDBOOL R5 0 0 - 0x90120805, // 0006 SETMBR R4 K4 R5 - 0x60140012, // 0007 GETGBL R5 G18 - 0x7C140000, // 0008 CALL R5 0 - 0x90120A05, // 0009 SETMBR R4 K5 R5 - 0x60140010, // 000A GETGBL R5 G16 - 0x88180306, // 000B GETMBR R6 R1 K6 - 0x7C140200, // 000C CALL R5 1 - 0xA802000F, // 000D EXBLK 0 #001E - 0x5C180A00, // 000E MOVE R6 R5 - 0x7C180000, // 000F CALL R6 0 - 0xB81E0400, // 0010 GETNGBL R7 K2 - 0x8C1C0F07, // 0011 GETMET R7 R7 K7 - 0x7C1C0200, // 0012 CALL R7 1 - 0x88200D08, // 0013 GETMBR R8 R6 K8 - 0x901E1008, // 0014 SETMBR R7 K8 R8 - 0x88200D09, // 0015 GETMBR R8 R6 K9 - 0x901E1208, // 0016 SETMBR R7 K9 R8 - 0x88200D0A, // 0017 GETMBR R8 R6 K10 - 0x901E1408, // 0018 SETMBR R7 K10 R8 - 0x88200905, // 0019 GETMBR R8 R4 K5 - 0x8C20110B, // 001A GETMET R8 R8 K11 - 0x5C280E00, // 001B MOVE R10 R7 - 0x7C200400, // 001C CALL R8 2 - 0x7001FFEF, // 001D JMP #000E - 0x5814000C, // 001E LDCONST R5 K12 - 0xAC140200, // 001F CATCH R5 1 0 - 0xB0080000, // 0020 RAISE 2 R0 R0 - 0xB8161A00, // 0021 GETNGBL R5 K13 - 0x8C140B0E, // 0022 GETMET R5 R5 K14 - 0x8C1C050F, // 0023 GETMET R7 R2 K15 - 0x58240010, // 0024 LDCONST R9 K16 - 0x88280711, // 0025 GETMBR R10 R3 K17 - 0x882C0312, // 0026 GETMBR R11 R1 K18 - 0x7C1C0800, // 0027 CALL R7 4 - 0x58200013, // 0028 LDCONST R8 K19 - 0x7C140600, // 0029 CALL R5 3 - 0x50140000, // 002A LDBOOL R5 0 0 - 0x90062805, // 002B SETMBR R1 K20 R5 - 0x8C140115, // 002C GETMET R5 R0 K21 - 0x5C1C0600, // 002D MOVE R7 R3 - 0x5C200800, // 002E MOVE R8 R4 - 0x7C140600, // 002F CALL R5 3 - 0x50180000, // 0030 LDBOOL R6 0 0 - 0x90162C06, // 0031 SETMBR R5 K22 R6 - 0x88180312, // 0032 GETMBR R6 R1 K18 - 0x90162406, // 0033 SETMBR R5 K18 R6 - 0xB81A0400, // 0034 GETNGBL R6 K2 - 0x8C180D17, // 0035 GETMET R6 R6 K23 - 0x88200718, // 0036 GETMBR R8 R3 K24 - 0x5C240600, // 0037 MOVE R9 R3 - 0x5C280A00, // 0038 MOVE R10 R5 - 0x5C2C0200, // 0039 MOVE R11 R1 - 0x7C180A00, // 003A CALL R6 5 - 0x881C0119, // 003B GETMBR R7 R0 K25 - 0x8C1C0F0B, // 003C GETMET R7 R7 K11 - 0x5C240C00, // 003D MOVE R9 R6 - 0x7C1C0400, // 003E CALL R7 2 - 0x8C1C011A, // 003F GETMET R7 R0 K26 - 0x88240718, // 0040 GETMBR R9 R3 K24 - 0x7C1C0400, // 0041 CALL R7 2 - 0x80000000, // 0042 RET 0 + ( &(const binstruction[251]) { /* code */ + 0xB80E0200, // 0000 GETNGBL R3 K1 + 0x880C0702, // 0001 GETMBR R3 R3 K2 + 0x900A0003, // 0002 SETMBR R2 K0 R3 + 0x900A0601, // 0003 SETMBR R2 K3 R1 + 0x880C0104, // 0004 GETMBR R3 R0 K4 + 0x8C0C0705, // 0005 GETMET R3 R3 K5 + 0x5C140400, // 0006 MOVE R5 R2 + 0x7C0C0400, // 0007 CALL R3 2 + 0x4C100000, // 0008 LDNIL R4 + 0x4C140000, // 0009 LDNIL R5 + 0x4C180000, // 000A LDNIL R6 + 0x20180606, // 000B NE R6 R3 R6 + 0x781A0008, // 000C JMPF R6 #0016 + 0xB81A0200, // 000D GETNGBL R6 K1 + 0x88180D06, // 000E GETMBR R6 R6 K6 + 0x900A0006, // 000F SETMBR R2 K0 R6 + 0x8C180707, // 0010 GETMET R6 R3 K7 + 0x88200308, // 0011 GETMBR R8 R1 K8 + 0x5C240400, // 0012 MOVE R9 R2 + 0x88280109, // 0013 GETMBR R10 R0 K9 + 0x7C180800, // 0014 CALL R6 4 + 0x5C100C00, // 0015 MOVE R4 R6 + 0xB81A0200, // 0016 GETNGBL R6 K1 + 0x88180D0A, // 0017 GETMBR R6 R6 K10 + 0x8C180D0B, // 0018 GETMET R6 R6 K11 + 0x5820000C, // 0019 LDCONST R8 K12 + 0x7C180400, // 001A CALL R6 2 + 0x4C180000, // 001B LDNIL R6 + 0x20180806, // 001C NE R6 R4 R6 + 0x781A0037, // 001D JMPF R6 #0056 + 0x8818090D, // 001E GETMBR R6 R4 K13 + 0x741A0001, // 001F JMPT R6 #0022 + 0x8818090E, // 0020 GETMBR R6 R4 K14 + 0x781A0019, // 0021 JMPF R6 #003C + 0x8C18090F, // 0022 GETMET R6 R4 K15 + 0x7C180200, // 0023 CALL R6 1 + 0xB81E0200, // 0024 GETNGBL R7 K1 + 0x881C0F10, // 0025 GETMBR R7 R7 K16 + 0x881C0F11, // 0026 GETMBR R7 R7 K17 + 0x24180C07, // 0027 GT R6 R6 R7 + 0x781A0012, // 0028 JMPF R6 #003C + 0x4C100000, // 0029 LDNIL R4 + 0xB81A2400, // 002A GETNGBL R6 K18 + 0x8C180D0B, // 002B GETMET R6 R6 K11 + 0x60200018, // 002C GETGBL R8 G24 + 0x58240013, // 002D LDCONST R9 K19 + 0x7C200200, // 002E CALL R8 1 + 0x58240014, // 002F LDCONST R9 K20 + 0x7C180600, // 0030 CALL R6 3 + 0xB81A0200, // 0031 GETNGBL R6 K1 + 0x88180D15, // 0032 GETMBR R6 R6 K21 + 0x8C180D16, // 0033 GETMET R6 R6 K22 + 0x88200317, // 0034 GETMBR R8 R1 K23 + 0x88240318, // 0035 GETMBR R9 R1 K24 + 0x7C180600, // 0036 CALL R6 3 + 0x8C1C0119, // 0037 GETMET R7 R0 K25 + 0x5C240200, // 0038 MOVE R9 R1 + 0x5C280C00, // 0039 MOVE R10 R6 + 0x7C1C0600, // 003A CALL R7 3 + 0x80040E00, // 003B RET 1 R7 + 0x60180015, // 003C GETGBL R6 G21 + 0x541E002F, // 003D LDINT R7 48 + 0x7C180200, // 003E CALL R6 1 + 0x5C140C00, // 003F MOVE R5 R6 + 0x8C180B1A, // 0040 GETMET R6 R5 K26 + 0x54220014, // 0041 LDINT R8 21 + 0x5824001B, // 0042 LDCONST R9 K27 + 0x7C180600, // 0043 CALL R6 3 + 0x8C180B1A, // 0044 GETMET R6 R5 K26 + 0x54223600, // 0045 LDINT R8 13825 + 0x5425FFFD, // 0046 LDINT R9 -2 + 0x7C180600, // 0047 CALL R6 3 + 0x8C18011C, // 0048 GETMET R6 R0 K28 + 0x5C200A00, // 0049 MOVE R8 R5 + 0x5C240400, // 004A MOVE R9 R2 + 0x5C280800, // 004B MOVE R10 R4 + 0x7C180800, // 004C CALL R6 4 + 0x8C180B1A, // 004D GETMET R6 R5 K26 + 0x5820001D, // 004E LDCONST R8 K29 + 0x5425FFFB, // 004F LDINT R9 -4 + 0x7C180600, // 0050 CALL R6 3 + 0x8C180B1A, // 0051 GETMET R6 R5 K26 + 0x54220017, // 0052 LDINT R8 24 + 0x5824001B, // 0053 LDCONST R9 K27 + 0x7C180600, // 0054 CALL R6 3 + 0x70020029, // 0055 JMP #0080 + 0x88180500, // 0056 GETMBR R6 R2 K0 + 0x4C1C0000, // 0057 LDNIL R7 + 0x20180C07, // 0058 NE R6 R6 R7 + 0x781A0019, // 0059 JMPF R6 #0074 + 0x60180015, // 005A GETGBL R6 G21 + 0x541E002F, // 005B LDINT R7 48 + 0x7C180200, // 005C CALL R6 1 + 0x5C140C00, // 005D MOVE R5 R6 + 0x8C180B1A, // 005E GETMET R6 R5 K26 + 0x54220014, // 005F LDINT R8 21 + 0x5824001B, // 0060 LDCONST R9 K27 + 0x7C180600, // 0061 CALL R6 3 + 0x8C180B1A, // 0062 GETMET R6 R5 K26 + 0x54223600, // 0063 LDINT R8 13825 + 0x5425FFFD, // 0064 LDINT R9 -2 + 0x7C180600, // 0065 CALL R6 3 + 0x8C18011E, // 0066 GETMET R6 R0 K30 + 0x5C200A00, // 0067 MOVE R8 R5 + 0x5C240400, // 0068 MOVE R9 R2 + 0x88280500, // 0069 GETMBR R10 R2 K0 + 0x7C180800, // 006A CALL R6 4 + 0x8C180B1A, // 006B GETMET R6 R5 K26 + 0x5820001D, // 006C LDCONST R8 K29 + 0x5425FFFB, // 006D LDINT R9 -4 + 0x7C180600, // 006E CALL R6 3 + 0x8C180B1A, // 006F GETMET R6 R5 K26 + 0x54220017, // 0070 LDINT R8 24 + 0x5824001B, // 0071 LDCONST R9 K27 + 0x7C180600, // 0072 CALL R6 3 + 0x7002000B, // 0073 JMP #0080 + 0xB81A2400, // 0074 GETNGBL R6 K18 + 0x8C180D0B, // 0075 GETMET R6 R6 K11 + 0x60200018, // 0076 GETGBL R8 G24 + 0x5824001F, // 0077 LDCONST R9 K31 + 0x88280308, // 0078 GETMBR R10 R1 K8 + 0x88281520, // 0079 GETMBR R10 R10 K32 + 0x5C2C0400, // 007A MOVE R11 R2 + 0x7C200600, // 007B CALL R8 3 + 0x58240014, // 007C LDCONST R9 K20 + 0x7C180600, // 007D CALL R6 3 + 0x50180000, // 007E LDBOOL R6 0 0 + 0x80040C00, // 007F RET 1 R6 + 0x8C180321, // 0080 GETMET R6 R1 K33 + 0x54220004, // 0081 LDINT R8 5 + 0x50240200, // 0082 LDBOOL R9 1 0 + 0x7C180600, // 0083 CALL R6 3 + 0x881C0104, // 0084 GETMBR R7 R0 K4 + 0x881C0F22, // 0085 GETMBR R7 R7 K34 + 0x88200317, // 0086 GETMBR R8 R1 K23 + 0x8C241123, // 0087 GETMET R9 R8 K35 + 0x7C240200, // 0088 CALL R9 1 + 0x8C240D24, // 0089 GETMET R9 R6 K36 + 0x5C2C0A00, // 008A MOVE R11 R5 + 0x5C301000, // 008B MOVE R12 R8 + 0x7C240600, // 008C CALL R9 3 + 0x8C240D25, // 008D GETMET R9 R6 K37 + 0x7C240200, // 008E CALL R9 1 + 0xB8262400, // 008F GETNGBL R9 K18 + 0x8C241326, // 0090 GETMET R9 R9 K38 + 0x542E0003, // 0091 LDINT R11 4 + 0x7C240400, // 0092 CALL R9 2 + 0x7826000B, // 0093 JMPF R9 #00A0 + 0xB8262400, // 0094 GETNGBL R9 K18 + 0x8C24130B, // 0095 GETMET R9 R9 K11 + 0x602C0018, // 0096 GETGBL R11 G24 + 0x58300027, // 0097 LDCONST R12 K39 + 0x88340D08, // 0098 GETMBR R13 R6 K8 + 0x88341B20, // 0099 GETMBR R13 R13 K32 + 0x88380D28, // 009A GETMBR R14 R6 K40 + 0x883C0D29, // 009B GETMBR R15 R6 K41 + 0x88400D2A, // 009C GETMBR R16 R6 K42 + 0x7C2C0A00, // 009D CALL R11 5 + 0x54320003, // 009E LDINT R12 4 + 0x7C240600, // 009F CALL R9 3 + 0x8C240F2B, // 00A0 GETMET R9 R7 K43 + 0x5C2C0C00, // 00A1 MOVE R11 R6 + 0x7C240400, // 00A2 CALL R9 2 + 0xB8260200, // 00A3 GETNGBL R9 K1 + 0x8824130A, // 00A4 GETMBR R9 R9 K10 + 0x8C24130B, // 00A5 GETMET R9 R9 K11 + 0x582C002C, // 00A6 LDCONST R11 K44 + 0x7C240400, // 00A7 CALL R9 2 + 0xB8260200, // 00A8 GETNGBL R9 K1 + 0x8C24132D, // 00A9 GETMET R9 R9 K45 + 0x882C052E, // 00AA GETMBR R11 R2 K46 + 0x8830052F, // 00AB GETMBR R12 R2 K47 + 0x7C240600, // 00AC CALL R9 3 + 0x78260002, // 00AD JMPF R9 #00B1 + 0x002A6009, // 00AE ADD R10 K48 R9 + 0x00281531, // 00AF ADD R10 R10 K49 + 0x70020000, // 00B0 JMP #00B2 + 0x58280032, // 00B1 LDCONST R10 K50 + 0x5C241400, // 00B2 MOVE R9 R10 + 0x4C280000, // 00B3 LDNIL R10 + 0x2028080A, // 00B4 NE R10 R4 R10 + 0x782A0013, // 00B5 JMPF R10 #00CA + 0x8C280933, // 00B6 GETMET R10 R4 K51 + 0x7C280200, // 00B7 CALL R10 1 + 0xB82E2400, // 00B8 GETNGBL R11 K18 + 0x8C2C1726, // 00B9 GETMET R11 R11 K38 + 0x58340014, // 00BA LDCONST R13 K20 + 0x7C2C0400, // 00BB CALL R11 2 + 0x782E000B, // 00BC JMPF R11 #00C9 + 0xB82E2400, // 00BD GETNGBL R11 K18 + 0x8C2C170B, // 00BE GETMET R11 R11 K11 + 0x60340018, // 00BF GETGBL R13 G24 + 0x58380034, // 00C0 LDCONST R14 K52 + 0x883C0308, // 00C1 GETMBR R15 R1 K8 + 0x883C1F20, // 00C2 GETMBR R15 R15 K32 + 0x5C400400, // 00C3 MOVE R16 R2 + 0x5C441200, // 00C4 MOVE R17 R9 + 0x5C481400, // 00C5 MOVE R18 R10 + 0x7C340A00, // 00C6 CALL R13 5 + 0x58380014, // 00C7 LDCONST R14 K20 + 0x7C2C0600, // 00C8 CALL R11 3 + 0x7002002E, // 00C9 JMP #00F9 + 0x88280500, // 00CA GETMBR R10 R2 K0 + 0x4C2C0000, // 00CB LDNIL R11 + 0x2028140B, // 00CC NE R10 R10 R11 + 0x782A001A, // 00CD JMPF R10 #00E9 + 0x88280500, // 00CE GETMBR R10 R2 K0 + 0xB82E0200, // 00CF GETNGBL R11 K1 + 0x882C1706, // 00D0 GETMBR R11 R11 K6 + 0x1C28140B, // 00D1 EQ R10 R10 R11 + 0x782A0001, // 00D2 JMPF R10 #00D5 + 0x58280006, // 00D3 LDCONST R10 K6 + 0x70020000, // 00D4 JMP #00D6 + 0x58280032, // 00D5 LDCONST R10 K50 + 0xB82E2400, // 00D6 GETNGBL R11 K18 + 0x8C2C1726, // 00D7 GETMET R11 R11 K38 + 0x58340014, // 00D8 LDCONST R13 K20 + 0x7C2C0400, // 00D9 CALL R11 2 + 0x782E000C, // 00DA JMPF R11 #00E8 + 0xB82E2400, // 00DB GETNGBL R11 K18 + 0x8C2C170B, // 00DC GETMET R11 R11 K11 + 0x60340018, // 00DD GETGBL R13 G24 + 0x58380035, // 00DE LDCONST R14 K53 + 0x883C0308, // 00DF GETMBR R15 R1 K8 + 0x883C1F20, // 00E0 GETMBR R15 R15 K32 + 0x5C400400, // 00E1 MOVE R16 R2 + 0x5C441200, // 00E2 MOVE R17 R9 + 0x88480500, // 00E3 GETMBR R18 R2 K0 + 0x5C4C1400, // 00E4 MOVE R19 R10 + 0x7C340C00, // 00E5 CALL R13 6 + 0x58380014, // 00E6 LDCONST R14 K20 + 0x7C2C0600, // 00E7 CALL R11 3 + 0x7002000F, // 00E8 JMP #00F9 + 0xB82A2400, // 00E9 GETNGBL R10 K18 + 0x8C281526, // 00EA GETMET R10 R10 K38 + 0x58300014, // 00EB LDCONST R12 K20 + 0x7C280400, // 00EC CALL R10 2 + 0x782A000A, // 00ED JMPF R10 #00F9 + 0xB82A2400, // 00EE GETNGBL R10 K18 + 0x8C28150B, // 00EF GETMET R10 R10 K11 + 0x60300018, // 00F0 GETGBL R12 G24 + 0x58340036, // 00F1 LDCONST R13 K54 + 0x88380308, // 00F2 GETMBR R14 R1 K8 + 0x88381D20, // 00F3 GETMBR R14 R14 K32 + 0x5C3C0400, // 00F4 MOVE R15 R2 + 0x5C401200, // 00F5 MOVE R16 R9 + 0x7C300800, // 00F6 CALL R12 4 + 0x58340014, // 00F7 LDCONST R13 K20 + 0x7C280600, // 00F8 CALL R10 3 + 0x50280200, // 00F9 LDBOOL R10 1 0 + 0x80041400, // 00FA RET 1 R10 }) ) ); @@ -2259,7 +3228,7 @@ be_local_closure(Matter_IM_send_enqueued, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ + ( &(const bvalue[12]) { /* constants */ /* K0 */ be_const_int(0), /* K1 */ be_nested_str_weak(send_queue), /* K2 */ be_nested_str_weak(finish), @@ -2270,9 +3239,8 @@ be_local_closure(Matter_IM_send_enqueued, /* name */ /* K7 */ be_nested_str_weak(MTR_X3A_X20remove_X20IM_X20message_X20exch_X3D), /* K8 */ be_nested_str_weak(resp), /* K9 */ be_nested_str_weak(exchange_id), - /* K10 */ be_const_int(3), - /* K11 */ be_nested_str_weak(remove), - /* K12 */ be_const_int(1), + /* K10 */ be_nested_str_weak(remove), + /* K11 */ be_const_int(1), }), be_str_weak(send_enqueued), &be_const_str_solidified, @@ -2301,14 +3269,14 @@ be_local_closure(Matter_IM_send_enqueued, /* name */ 0x881C0F09, // 0015 GETMBR R7 R7 K9 0x7C180200, // 0016 CALL R6 1 0x001A0E06, // 0017 ADD R6 K7 R6 - 0x581C000A, // 0018 LDCONST R7 K10 + 0x541E0003, // 0018 LDINT R7 4 0x7C100600, // 0019 CALL R4 3 0x88100101, // 001A GETMBR R4 R0 K1 - 0x8C10090B, // 001B GETMET R4 R4 K11 + 0x8C10090A, // 001B GETMET R4 R4 K10 0x5C180400, // 001C MOVE R6 R2 0x7C100400, // 001D CALL R4 2 0x70020000, // 001E JMP #0020 - 0x0008050C, // 001F ADD R2 R2 K12 + 0x0008050B, // 001F ADD R2 R2 K11 0x7001FFDF, // 0020 JMP #0001 0x80000000, // 0021 RET 0 }) @@ -2318,61 +3286,58 @@ be_local_closure(Matter_IM_send_enqueued, /* name */ /******************************************************************** -** Solidified function: process_timed_request +** Solidified function: init ********************************************************************/ -be_local_closure(Matter_IM_process_timed_request, /* name */ +be_local_closure(Matter_IM_init, /* name */ be_nested_proto( - 12, /* nstack */ - 3, /* argc */ + 5, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[14]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TimedRequestMessage), - /* K3 */ be_nested_str_weak(from_TLV), - /* K4 */ be_nested_str_weak(tasmota), - /* K5 */ be_nested_str_weak(log), - /* K6 */ be_nested_str_weak(format), - /* K7 */ be_nested_str_weak(MTR_X3A_X20_X3ECommand_X20_X20_X20_X28_X256i_X29_X20TimedRequest_X3D_X25i), - /* K8 */ be_nested_str_weak(session), - /* K9 */ be_nested_str_weak(local_session_id), - /* K10 */ be_nested_str_weak(timeout), - /* K11 */ be_const_int(2), - /* K12 */ be_nested_str_weak(send_status), - /* K13 */ be_nested_str_weak(SUCCESS), + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(device), + /* K1 */ be_nested_str_weak(send_queue), + /* K2 */ be_nested_str_weak(subs_shop), + /* K3 */ be_nested_str_weak(matter), + /* K4 */ be_nested_str_weak(IM_Subscription_Shop), + /* K5 */ be_nested_str_weak(read_request_solo), + /* K6 */ be_nested_str_weak(ReadRequestMessage_solo), + /* K7 */ be_nested_str_weak(invoke_request_solo), + /* K8 */ be_nested_str_weak(InvokeRequestMessage_solo), + /* K9 */ be_nested_str_weak(tlv_solo), + /* K10 */ be_nested_str_weak(TLV), + /* K11 */ be_nested_str_weak(Matter_TLV_item), }), - be_str_weak(process_timed_request), + be_str_weak(init), &be_const_str_solidified, - ( &(const binstruction[24]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x8C100902, // 0002 GETMET R4 R4 K2 - 0x7C100200, // 0003 CALL R4 1 - 0x8C100903, // 0004 GETMET R4 R4 K3 - 0x5C180400, // 0005 MOVE R6 R2 - 0x7C100400, // 0006 CALL R4 2 - 0xB8160800, // 0007 GETNGBL R5 K4 - 0x8C140B05, // 0008 GETMET R5 R5 K5 - 0x8C1C0706, // 0009 GETMET R7 R3 K6 - 0x58240007, // 000A LDCONST R9 K7 - 0x88280308, // 000B GETMBR R10 R1 K8 - 0x88281509, // 000C GETMBR R10 R10 K9 - 0x882C090A, // 000D GETMBR R11 R4 K10 - 0x7C1C0800, // 000E CALL R7 4 - 0x5820000B, // 000F LDCONST R8 K11 - 0x7C140600, // 0010 CALL R5 3 - 0x8C14010C, // 0011 GETMET R5 R0 K12 - 0x5C1C0200, // 0012 MOVE R7 R1 - 0xB8220200, // 0013 GETNGBL R8 K1 - 0x8820110D, // 0014 GETMBR R8 R8 K13 - 0x7C140600, // 0015 CALL R5 3 - 0x50140200, // 0016 LDBOOL R5 1 0 - 0x80040A00, // 0017 RET 1 R5 + ( &(const binstruction[23]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x60080012, // 0001 GETGBL R2 G18 + 0x7C080000, // 0002 CALL R2 0 + 0x90020202, // 0003 SETMBR R0 K1 R2 + 0xB80A0600, // 0004 GETNGBL R2 K3 + 0x8C080504, // 0005 GETMET R2 R2 K4 + 0x5C100000, // 0006 MOVE R4 R0 + 0x7C080400, // 0007 CALL R2 2 + 0x90020402, // 0008 SETMBR R0 K2 R2 + 0xB80A0600, // 0009 GETNGBL R2 K3 + 0x8C080506, // 000A GETMET R2 R2 K6 + 0x7C080200, // 000B CALL R2 1 + 0x90020A02, // 000C SETMBR R0 K5 R2 + 0xB80A0600, // 000D GETNGBL R2 K3 + 0x8C080508, // 000E GETMET R2 R2 K8 + 0x7C080200, // 000F CALL R2 1 + 0x90020E02, // 0010 SETMBR R0 K7 R2 + 0xB80A0600, // 0011 GETNGBL R2 K3 + 0x8808050A, // 0012 GETMBR R2 R2 K10 + 0x8C08050B, // 0013 GETMET R2 R2 K11 + 0x7C080200, // 0014 CALL R2 1 + 0x90021202, // 0015 SETMBR R0 K9 R2 + 0x80000000, // 0016 RET 0 }) ) ); @@ -2380,12 +3345,12 @@ be_local_closure(Matter_IM_process_timed_request, /* name */ /******************************************************************** -** Solidified function: report_data +** Solidified function: expire_sendqueue ********************************************************************/ -be_local_closure(Matter_IM_report_data, /* name */ +be_local_closure(Matter_IM_expire_sendqueue, /* name */ be_nested_proto( - 9, /* nstack */ - 3, /* argc */ + 6, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -2393,35 +3358,42 @@ be_local_closure(Matter_IM_report_data, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(ReportDataMessage), - /* K3 */ be_nested_str_weak(from_TLV), - /* K4 */ be_nested_str_weak(tasmota), - /* K5 */ be_nested_str_weak(log), - /* K6 */ be_nested_str_weak(MTR_X3A_X20received_X20ReportDataMessage_X3D), - /* K7 */ be_const_int(2), + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(send_queue), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(time_reached), + /* K4 */ be_nested_str_weak(expiration), + /* K5 */ be_nested_str_weak(reached_timeout), + /* K6 */ be_nested_str_weak(remove), + /* K7 */ be_const_int(1), }), - be_str_weak(report_data), + be_str_weak(expire_sendqueue), &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x8C100902, // 0002 GETMET R4 R4 K2 - 0x7C100200, // 0003 CALL R4 1 - 0x8C100903, // 0004 GETMET R4 R4 K3 - 0x5C180400, // 0005 MOVE R6 R2 - 0x7C100400, // 0006 CALL R4 2 - 0xB8160800, // 0007 GETNGBL R5 K4 - 0x8C140B05, // 0008 GETMET R5 R5 K5 - 0x601C0008, // 0009 GETGBL R7 G8 - 0x5C200800, // 000A MOVE R8 R4 - 0x7C1C0200, // 000B CALL R7 1 - 0x001E0C07, // 000C ADD R7 K6 R7 - 0x58200007, // 000D LDCONST R8 K7 - 0x7C140600, // 000E CALL R5 3 - 0x50140000, // 000F LDBOOL R5 0 0 - 0x80040A00, // 0010 RET 1 R5 + ( &(const binstruction[24]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x6008000C, // 0001 GETGBL R2 G12 + 0x880C0101, // 0002 GETMBR R3 R0 K1 + 0x7C080200, // 0003 CALL R2 1 + 0x14080202, // 0004 LT R2 R1 R2 + 0x780A000F, // 0005 JMPF R2 #0016 + 0x88080101, // 0006 GETMBR R2 R0 K1 + 0x94080401, // 0007 GETIDX R2 R2 R1 + 0xB80E0400, // 0008 GETNGBL R3 K2 + 0x8C0C0703, // 0009 GETMET R3 R3 K3 + 0x88140504, // 000A GETMBR R5 R2 K4 + 0x7C0C0400, // 000B CALL R3 2 + 0x780E0006, // 000C JMPF R3 #0014 + 0x8C0C0505, // 000D GETMET R3 R2 K5 + 0x7C0C0200, // 000E CALL R3 1 + 0x880C0101, // 000F GETMBR R3 R0 K1 + 0x8C0C0706, // 0010 GETMET R3 R3 K6 + 0x5C140200, // 0011 MOVE R5 R1 + 0x7C0C0400, // 0012 CALL R3 2 + 0x70020000, // 0013 JMP #0015 + 0x00040307, // 0014 ADD R1 R1 K7 + 0x7001FFEA, // 0015 JMP #0001 + 0x4C080000, // 0016 LDNIL R2 + 0x80040400, // 0017 RET 1 R2 }) ) ); @@ -2429,11 +3401,11 @@ be_local_closure(Matter_IM_report_data, /* name */ /******************************************************************** -** Solidified function: process_invoke_response +** Solidified function: subscribe_request ********************************************************************/ -be_local_closure(Matter_IM_process_invoke_response, /* name */ +be_local_closure(Matter_IM_subscribe_request, /* name */ be_nested_proto( - 9, /* nstack */ + 18, /* nstack */ 3, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2441,75 +3413,143 @@ be_local_closure(Matter_IM_process_invoke_response, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(InvokeResponseMessage), - /* K3 */ be_nested_str_weak(from_TLV), - /* K4 */ be_nested_str_weak(tasmota), - /* K5 */ be_nested_str_weak(log), - /* K6 */ be_nested_str_weak(MTR_X3A_X20received_X20InvokeResponseMessage_X3D), - /* K7 */ be_const_int(2), - }), - be_str_weak(process_invoke_response), - &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x8C100902, // 0002 GETMET R4 R4 K2 - 0x7C100200, // 0003 CALL R4 1 - 0x8C100903, // 0004 GETMET R4 R4 K3 - 0x5C180400, // 0005 MOVE R6 R2 - 0x7C100400, // 0006 CALL R4 2 - 0xB8160800, // 0007 GETNGBL R5 K4 - 0x8C140B05, // 0008 GETMET R5 R5 K5 - 0x601C0008, // 0009 GETGBL R7 G8 - 0x5C200800, // 000A MOVE R8 R4 - 0x7C1C0200, // 000B CALL R7 1 - 0x001E0C07, // 000C ADD R7 K6 R7 - 0x58200007, // 000D LDCONST R8 K7 - 0x7C140600, // 000E CALL R5 3 - 0x50140000, // 000F LDBOOL R5 0 0 - 0x80040A00, // 0010 RET 1 R5 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Matter_IM_init, /* name */ - be_nested_proto( - 5, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(device), - /* K1 */ be_nested_str_weak(send_queue), - /* K2 */ be_nested_str_weak(subs_shop), - /* K3 */ be_nested_str_weak(matter), - /* K4 */ be_nested_str_weak(IM_Subscription_Shop), + ( &(const bvalue[33]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(SubscribeRequestMessage), + /* K2 */ be_nested_str_weak(from_TLV), + /* K3 */ be_nested_str_weak(keep_subscriptions), + /* K4 */ be_nested_str_weak(subs_shop), + /* K5 */ be_nested_str_weak(remove_by_session), + /* K6 */ be_nested_str_weak(session), + /* K7 */ be_nested_str_weak(new_subscription), + /* K8 */ be_nested_str_weak(Path), + /* K9 */ be_nested_str_weak(msg), + /* K10 */ be_nested_str_weak(attributes_requests), + /* K11 */ be_nested_str_weak(endpoint), + /* K12 */ be_nested_str_weak(cluster), + /* K13 */ be_nested_str_weak(attribute), + /* K14 */ be_nested_str_weak(push), + /* K15 */ be_nested_str_weak(stop_iteration), + /* K16 */ be_nested_str_weak(tasmota), + /* K17 */ be_nested_str_weak(log), + /* K18 */ be_nested_str_weak(MTR_X3A_X20_X3ESubscribe_X20_X28_X256i_X29_X20_X25s_X20_X28min_X3D_X25i_X2C_X20max_X3D_X25i_X2C_X20keep_X3D_X25i_X29_X20sub_X3D_X25i_X20fabric_filtered_X3D_X25s), + /* K19 */ be_nested_str_weak(local_session_id), + /* K20 */ be_nested_str_weak(concat), + /* K21 */ be_nested_str_weak(_X20), + /* K22 */ be_nested_str_weak(min_interval), + /* K23 */ be_nested_str_weak(max_interval), + /* K24 */ be_const_int(1), + /* K25 */ be_const_int(0), + /* K26 */ be_nested_str_weak(subscription_id), + /* K27 */ be_nested_str_weak(fabric_filtered), + /* K28 */ be_const_int(3), + /* K29 */ be_nested_str_weak(event_requests), + /* K30 */ be_nested_str_weak(MTR_X3A_X20_X3ESubscribe_X20_X28_X25_X256i_X29_X20event_requests_size_X3D_X25s), + /* K31 */ be_nested_str_weak(_inner_process_read_request), + /* K32 */ be_nested_str_weak(send_subscribe_response), }), - be_str_weak(init), + be_str_weak(subscribe_request), &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x90020001, // 0000 SETMBR R0 K0 R1 - 0x60080012, // 0001 GETGBL R2 G18 - 0x7C080000, // 0002 CALL R2 0 - 0x90020202, // 0003 SETMBR R0 K1 R2 - 0xB80A0600, // 0004 GETNGBL R2 K3 - 0x8C080504, // 0005 GETMET R2 R2 K4 - 0x5C100000, // 0006 MOVE R4 R0 - 0x7C080400, // 0007 CALL R2 2 - 0x90020402, // 0008 SETMBR R0 K2 R2 - 0x80000000, // 0009 RET 0 + ( &(const binstruction[99]) { /* code */ + 0xB80E0000, // 0000 GETNGBL R3 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x7C0C0200, // 0002 CALL R3 1 + 0x8C0C0702, // 0003 GETMET R3 R3 K2 + 0x5C140400, // 0004 MOVE R5 R2 + 0x7C0C0400, // 0005 CALL R3 2 + 0x88100703, // 0006 GETMBR R4 R3 K3 + 0x74120003, // 0007 JMPT R4 #000C + 0x88100104, // 0008 GETMBR R4 R0 K4 + 0x8C100905, // 0009 GETMET R4 R4 K5 + 0x88180306, // 000A GETMBR R6 R1 K6 + 0x7C100400, // 000B CALL R4 2 + 0x88100104, // 000C GETMBR R4 R0 K4 + 0x8C100907, // 000D GETMET R4 R4 K7 + 0x88180306, // 000E GETMBR R6 R1 K6 + 0x5C1C0600, // 000F MOVE R7 R3 + 0x7C100600, // 0010 CALL R4 3 + 0x60140012, // 0011 GETGBL R5 G18 + 0x7C140000, // 0012 CALL R5 0 + 0xB81A0000, // 0013 GETNGBL R6 K0 + 0x8C180D08, // 0014 GETMET R6 R6 K8 + 0x7C180200, // 0015 CALL R6 1 + 0x901A1201, // 0016 SETMBR R6 K9 R1 + 0x601C0010, // 0017 GETGBL R7 G16 + 0x8820070A, // 0018 GETMBR R8 R3 K10 + 0x7C1C0200, // 0019 CALL R7 1 + 0xA802000D, // 001A EXBLK 0 #0029 + 0x5C200E00, // 001B MOVE R8 R7 + 0x7C200000, // 001C CALL R8 0 + 0x8824110B, // 001D GETMBR R9 R8 K11 + 0x901A1609, // 001E SETMBR R6 K11 R9 + 0x8824110C, // 001F GETMBR R9 R8 K12 + 0x901A1809, // 0020 SETMBR R6 K12 R9 + 0x8824110D, // 0021 GETMBR R9 R8 K13 + 0x901A1A09, // 0022 SETMBR R6 K13 R9 + 0x8C240B0E, // 0023 GETMET R9 R5 K14 + 0x602C0008, // 0024 GETGBL R11 G8 + 0x5C300C00, // 0025 MOVE R12 R6 + 0x7C2C0200, // 0026 CALL R11 1 + 0x7C240400, // 0027 CALL R9 2 + 0x7001FFF1, // 0028 JMP #001B + 0x581C000F, // 0029 LDCONST R7 K15 + 0xAC1C0200, // 002A CATCH R7 1 0 + 0xB0080000, // 002B RAISE 2 R0 R0 + 0xB81E2000, // 002C GETNGBL R7 K16 + 0x8C1C0F11, // 002D GETMET R7 R7 K17 + 0x60240018, // 002E GETGBL R9 G24 + 0x58280012, // 002F LDCONST R10 K18 + 0x882C0306, // 0030 GETMBR R11 R1 K6 + 0x882C1713, // 0031 GETMBR R11 R11 K19 + 0x8C300B14, // 0032 GETMET R12 R5 K20 + 0x58380015, // 0033 LDCONST R14 K21 + 0x7C300400, // 0034 CALL R12 2 + 0x88340916, // 0035 GETMBR R13 R4 K22 + 0x88380917, // 0036 GETMBR R14 R4 K23 + 0x883C0703, // 0037 GETMBR R15 R3 K3 + 0x783E0001, // 0038 JMPF R15 #003B + 0x583C0018, // 0039 LDCONST R15 K24 + 0x70020000, // 003A JMP #003C + 0x583C0019, // 003B LDCONST R15 K25 + 0x8840091A, // 003C GETMBR R16 R4 K26 + 0x8844071B, // 003D GETMBR R17 R3 K27 + 0x7C241000, // 003E CALL R9 8 + 0x5828001C, // 003F LDCONST R10 K28 + 0x7C1C0600, // 0040 CALL R7 3 + 0x881C071D, // 0041 GETMBR R7 R3 K29 + 0x4C200000, // 0042 LDNIL R8 + 0x201C0E08, // 0043 NE R7 R7 R8 + 0x781E000E, // 0044 JMPF R7 #0054 + 0x601C000C, // 0045 GETGBL R7 G12 + 0x8820071D, // 0046 GETMBR R8 R3 K29 + 0x7C1C0200, // 0047 CALL R7 1 + 0x241C0F19, // 0048 GT R7 R7 K25 + 0x781E0009, // 0049 JMPF R7 #0054 + 0xB81E2000, // 004A GETNGBL R7 K16 + 0x8C1C0F11, // 004B GETMET R7 R7 K17 + 0x60240018, // 004C GETGBL R9 G24 + 0x5828001E, // 004D LDCONST R10 K30 + 0x602C000C, // 004E GETGBL R11 G12 + 0x8830071D, // 004F GETMBR R12 R3 K29 + 0x7C2C0200, // 0050 CALL R11 1 + 0x7C240400, // 0051 CALL R9 2 + 0x5828001C, // 0052 LDCONST R10 K28 + 0x7C1C0600, // 0053 CALL R7 3 + 0x8C1C011F, // 0054 GETMET R7 R0 K31 + 0x88240306, // 0055 GETMBR R9 R1 K6 + 0x5C280600, // 0056 MOVE R10 R3 + 0x5C2C0200, // 0057 MOVE R11 R1 + 0x50300200, // 0058 LDBOOL R12 1 0 + 0x7C1C0A00, // 0059 CALL R7 5 + 0x8820091A, // 005A GETMBR R8 R4 K26 + 0x901E3408, // 005B SETMBR R7 K26 R8 + 0x8C200120, // 005C GETMET R8 R0 K32 + 0x5C280200, // 005D MOVE R10 R1 + 0x5C2C0E00, // 005E MOVE R11 R7 + 0x5C300800, // 005F MOVE R12 R4 + 0x7C200800, // 0060 CALL R8 4 + 0x50200200, // 0061 LDBOOL R8 1 0 + 0x80041000, // 0062 RET 1 R8 }) ) ); @@ -2521,7 +3561,7 @@ be_local_closure(Matter_IM_init, /* name */ ********************************************************************/ be_local_closure(Matter_IM_send_subscribe_heartbeat, /* name */ be_nested_proto( - 11, /* nstack */ + 10, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2529,64 +3569,61 @@ be_local_closure(Matter_IM_send_subscribe_heartbeat, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[18]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(session), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(log), - /* K4 */ be_nested_str_weak(format), - /* K5 */ be_nested_str_weak(MTR_X3A_X20_X3CSub_Alive_X20_X28_X256i_X29_X20sub_X3D_X25i), - /* K6 */ be_nested_str_weak(local_session_id), - /* K7 */ be_nested_str_weak(subscription_id), - /* K8 */ be_const_int(2), - /* K9 */ be_nested_str_weak(is_keep_alive), - /* K10 */ be_nested_str_weak(matter), - /* K11 */ be_nested_str_weak(ReportDataMessage), - /* K12 */ be_nested_str_weak(suppress_response), - /* K13 */ be_nested_str_weak(IM_SubscribedHeartbeat), - /* K14 */ be_nested_str_weak(_message_handler), - /* K15 */ be_nested_str_weak(send_queue), - /* K16 */ be_nested_str_weak(push), - /* K17 */ be_nested_str_weak(send_enqueued), + ( &(const bvalue[16]) { /* constants */ + /* K0 */ be_nested_str_weak(session), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(log), + /* K3 */ be_nested_str_weak(MTR_X3A_X20_X3CSub_Alive_X20_X28_X256i_X29_X20sub_X3D_X25i), + /* K4 */ be_nested_str_weak(local_session_id), + /* K5 */ be_nested_str_weak(subscription_id), + /* K6 */ be_const_int(3), + /* K7 */ be_nested_str_weak(is_keep_alive), + /* K8 */ be_nested_str_weak(matter), + /* K9 */ be_nested_str_weak(ReportDataMessage), + /* K10 */ be_nested_str_weak(suppress_response), + /* K11 */ be_nested_str_weak(IM_SubscribedHeartbeat), + /* K12 */ be_nested_str_weak(_message_handler), + /* K13 */ be_nested_str_weak(send_queue), + /* K14 */ be_nested_str_weak(push), + /* K15 */ be_nested_str_weak(send_enqueued), }), be_str_weak(send_subscribe_heartbeat), &be_const_str_solidified, - ( &(const binstruction[35]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x880C0301, // 0001 GETMBR R3 R1 K1 - 0xB8120400, // 0002 GETNGBL R4 K2 - 0x8C100903, // 0003 GETMET R4 R4 K3 - 0x8C180504, // 0004 GETMET R6 R2 K4 - 0x58200005, // 0005 LDCONST R8 K5 - 0x88240706, // 0006 GETMBR R9 R3 K6 - 0x88280307, // 0007 GETMBR R10 R1 K7 - 0x7C180800, // 0008 CALL R6 4 - 0x581C0008, // 0009 LDCONST R7 K8 - 0x7C100600, // 000A CALL R4 3 - 0x50100200, // 000B LDBOOL R4 1 0 - 0x90061204, // 000C SETMBR R1 K9 R4 - 0xB8121400, // 000D GETNGBL R4 K10 - 0x8C10090B, // 000E GETMET R4 R4 K11 - 0x7C100200, // 000F CALL R4 1 - 0x50140200, // 0010 LDBOOL R5 1 0 - 0x90121805, // 0011 SETMBR R4 K12 R5 - 0x88140307, // 0012 GETMBR R5 R1 K7 - 0x90120E05, // 0013 SETMBR R4 K7 R5 - 0xB8161400, // 0014 GETNGBL R5 K10 - 0x8C140B0D, // 0015 GETMET R5 R5 K13 - 0x881C070E, // 0016 GETMBR R7 R3 K14 + ( &(const binstruction[34]) { /* code */ + 0x88080300, // 0000 GETMBR R2 R1 K0 + 0xB80E0200, // 0001 GETNGBL R3 K1 + 0x8C0C0702, // 0002 GETMET R3 R3 K2 + 0x60140018, // 0003 GETGBL R5 G24 + 0x58180003, // 0004 LDCONST R6 K3 + 0x881C0504, // 0005 GETMBR R7 R2 K4 + 0x88200305, // 0006 GETMBR R8 R1 K5 + 0x7C140600, // 0007 CALL R5 3 + 0x58180006, // 0008 LDCONST R6 K6 + 0x7C0C0600, // 0009 CALL R3 3 + 0x500C0200, // 000A LDBOOL R3 1 0 + 0x90060E03, // 000B SETMBR R1 K7 R3 + 0xB80E1000, // 000C GETNGBL R3 K8 + 0x8C0C0709, // 000D GETMET R3 R3 K9 + 0x7C0C0200, // 000E CALL R3 1 + 0x50100200, // 000F LDBOOL R4 1 0 + 0x900E1404, // 0010 SETMBR R3 K10 R4 + 0x88100305, // 0011 GETMBR R4 R1 K5 + 0x900E0A04, // 0012 SETMBR R3 K5 R4 + 0xB8121000, // 0013 GETNGBL R4 K8 + 0x8C10090B, // 0014 GETMET R4 R4 K11 + 0x8818050C, // 0015 GETMBR R6 R2 K12 + 0x5C1C0400, // 0016 MOVE R7 R2 0x5C200600, // 0017 MOVE R8 R3 - 0x5C240800, // 0018 MOVE R9 R4 - 0x5C280200, // 0019 MOVE R10 R1 - 0x7C140A00, // 001A CALL R5 5 - 0x8818010F, // 001B GETMBR R6 R0 K15 - 0x8C180D10, // 001C GETMET R6 R6 K16 - 0x5C200A00, // 001D MOVE R8 R5 - 0x7C180400, // 001E CALL R6 2 - 0x8C180111, // 001F GETMET R6 R0 K17 - 0x8820070E, // 0020 GETMBR R8 R3 K14 - 0x7C180400, // 0021 CALL R6 2 - 0x80000000, // 0022 RET 0 + 0x5C240200, // 0018 MOVE R9 R1 + 0x7C100A00, // 0019 CALL R4 5 + 0x8814010D, // 001A GETMBR R5 R0 K13 + 0x8C140B0E, // 001B GETMET R5 R5 K14 + 0x5C1C0800, // 001C MOVE R7 R4 + 0x7C140400, // 001D CALL R5 2 + 0x8C14010F, // 001E GETMET R5 R0 K15 + 0x881C050C, // 001F GETMBR R7 R2 K12 + 0x7C140400, // 0020 CALL R5 2 + 0x80000000, // 0021 RET 0 }) ) ); @@ -2597,41 +3634,50 @@ be_local_closure(Matter_IM_send_subscribe_heartbeat, /* name */ ** Solidified class: Matter_IM ********************************************************************/ be_local_class(Matter_IM, - 3, + 6, NULL, - be_nested_map(31, + be_nested_map(40, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(send_subscribe_heartbeat, -1), be_const_closure(Matter_IM_send_subscribe_heartbeat_closure) }, - { be_const_key_weak(subs_shop, 23), be_const_var(1) }, - { be_const_key_weak(send_queue, 30), be_const_var(2) }, - { be_const_key_weak(process_invoke_request, -1), be_const_closure(Matter_IM_process_invoke_request_closure) }, - { be_const_key_weak(subscribe_request, -1), be_const_closure(Matter_IM_subscribe_request_closure) }, - { be_const_key_weak(process_write_request, 11), be_const_closure(Matter_IM_process_write_request_closure) }, - { be_const_key_weak(send_write_response, -1), be_const_closure(Matter_IM_send_write_response_closure) }, - { be_const_key_weak(remove_sendqueue_by_exchangeid, -1), be_const_closure(Matter_IM_remove_sendqueue_by_exchangeid_closure) }, - { be_const_key_weak(every_second, -1), be_const_closure(Matter_IM_every_second_closure) }, - { be_const_key_weak(send_ack_now, -1), be_const_closure(Matter_IM_send_ack_now_closure) }, { be_const_key_weak(every_250ms, -1), be_const_closure(Matter_IM_every_250ms_closure) }, + { be_const_key_weak(process_incoming_ack, -1), be_const_closure(Matter_IM_process_incoming_ack_closure) }, + { be_const_key_weak(send_ack_now, -1), be_const_closure(Matter_IM_send_ack_now_closure) }, + { be_const_key_weak(subscribe_response, -1), be_const_closure(Matter_IM_subscribe_response_closure) }, + { be_const_key_weak(process_write_response, -1), be_const_closure(Matter_IM_process_write_response_closure) }, + { be_const_key_weak(process_status_response, -1), be_const_closure(Matter_IM_process_status_response_closure) }, + { be_const_key_weak(send_subscribe_heartbeat, -1), be_const_closure(Matter_IM_send_subscribe_heartbeat_closure) }, + { be_const_key_weak(attributedata2raw, 12), be_const_closure(Matter_IM_attributedata2raw_closure) }, + { be_const_key_weak(subscribe_request, 37), be_const_closure(Matter_IM_subscribe_request_closure) }, + { be_const_key_weak(send_subscribe_update, -1), be_const_closure(Matter_IM_send_subscribe_update_closure) }, + { be_const_key_weak(invokeresponse2raw, 2), be_const_closure(Matter_IM_invokeresponse2raw_closure) }, + { be_const_key_weak(read_request_solo, 38), be_const_var(3) }, + { be_const_key_weak(process_incoming, -1), be_const_closure(Matter_IM_process_incoming_closure) }, + { be_const_key_weak(process_invoke_request_solo, 8), be_const_closure(Matter_IM_process_invoke_request_solo_closure) }, { be_const_key_weak(send_invoke_response, -1), be_const_closure(Matter_IM_send_invoke_response_closure) }, - { be_const_key_weak(process_invoke_response, 21), be_const_closure(Matter_IM_process_invoke_response_closure) }, + { be_const_key_weak(send_write_response, 6), be_const_closure(Matter_IM_send_write_response_closure) }, + { be_const_key_weak(process_write_request, -1), be_const_closure(Matter_IM_process_write_request_closure) }, + { be_const_key_weak(every_second, -1), be_const_closure(Matter_IM_every_second_closure) }, + { be_const_key_weak(path2raw, -1), be_const_closure(Matter_IM_path2raw_closure) }, + { be_const_key_weak(invoke_request_solo, -1), be_const_var(4) }, { be_const_key_weak(_inner_process_read_request, -1), be_const_closure(Matter_IM__inner_process_read_request_closure) }, - { be_const_key_weak(subscribe_response, 22), be_const_closure(Matter_IM_subscribe_response_closure) }, - { be_const_key_weak(process_incoming, -1), be_const_closure(Matter_IM_process_incoming_closure) }, - { be_const_key_weak(send_subscribe_response, 18), be_const_closure(Matter_IM_send_subscribe_response_closure) }, + { be_const_key_weak(tlv_solo, -1), be_const_var(5) }, + { be_const_key_weak(remove_sendqueue_by_exchangeid, -1), be_const_closure(Matter_IM_remove_sendqueue_by_exchangeid_closure) }, { be_const_key_weak(find_sendqueue_by_exchangeid, -1), be_const_closure(Matter_IM_find_sendqueue_by_exchangeid_closure) }, - { be_const_key_weak(process_incoming_ack, 13), be_const_closure(Matter_IM_process_incoming_ack_closure) }, - { be_const_key_weak(process_read_request, -1), be_const_closure(Matter_IM_process_read_request_closure) }, { be_const_key_weak(send_report_data, -1), be_const_closure(Matter_IM_send_report_data_closure) }, - { be_const_key_weak(process_timed_request, -1), be_const_closure(Matter_IM_process_timed_request_closure) }, - { be_const_key_weak(process_status_response, -1), be_const_closure(Matter_IM_process_status_response_closure) }, - { be_const_key_weak(send_subscribe_update, 28), be_const_closure(Matter_IM_send_subscribe_update_closure) }, - { be_const_key_weak(send_enqueued, -1), be_const_closure(Matter_IM_send_enqueued_closure) }, - { be_const_key_weak(process_write_response, 12), be_const_closure(Matter_IM_process_write_response_closure) }, - { be_const_key_weak(report_data, 0), be_const_closure(Matter_IM_report_data_closure) }, - { be_const_key_weak(device, -1), be_const_var(0) }, + { be_const_key_weak(process_invoke_request, 17), be_const_closure(Matter_IM_process_invoke_request_closure) }, { be_const_key_weak(send_status, -1), be_const_closure(Matter_IM_send_status_closure) }, + { be_const_key_weak(subs_shop, 20), be_const_var(1) }, + { be_const_key_weak(process_timed_request, 32), be_const_closure(Matter_IM_process_timed_request_closure) }, + { be_const_key_weak(attributestatus2raw, 23), be_const_closure(Matter_IM_attributestatus2raw_closure) }, + { be_const_key_weak(send_subscribe_response, -1), be_const_closure(Matter_IM_send_subscribe_response_closure) }, + { be_const_key_weak(process_invoke_response, 24), be_const_closure(Matter_IM_process_invoke_response_closure) }, + { be_const_key_weak(report_data, 9), be_const_closure(Matter_IM_report_data_closure) }, + { be_const_key_weak(process_read_request_solo, -1), be_const_closure(Matter_IM_process_read_request_solo_closure) }, + { be_const_key_weak(send_enqueued, -1), be_const_closure(Matter_IM_send_enqueued_closure) }, { be_const_key_weak(init, -1), be_const_closure(Matter_IM_init_closure) }, { be_const_key_weak(expire_sendqueue, -1), be_const_closure(Matter_IM_expire_sendqueue_closure) }, + { be_const_key_weak(process_read_request, -1), be_const_closure(Matter_IM_process_read_request_closure) }, + { be_const_key_weak(device, -1), be_const_var(0) }, + { be_const_key_weak(send_queue, -1), be_const_var(2) }, })), be_str_weak(Matter_IM) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Data.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Data.h index aecff66c6ecb..1ffcdfd5e112 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Data.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Data.h @@ -307,7 +307,7 @@ be_local_closure(Matter_AttributePathIB_to_TLV, /* name */ ********************************************************************/ be_local_closure(Matter_AttributePathIB_tostring, /* name */ be_nested_proto( - 7, /* nstack */ + 6, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -315,89 +315,86 @@ be_local_closure(Matter_AttributePathIB_tostring, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[16]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(), - /* K2 */ be_nested_str_weak(node), - /* K3 */ be_nested_str_weak(format), - /* K4 */ be_nested_str_weak(node_X3D_X25s_X20), - /* K5 */ be_nested_str_weak(endpoint), - /* K6 */ be_nested_str_weak(_X5B_X2502X_X5D), - /* K7 */ be_nested_str_weak(_X5B_X2A_X2A_X5D), - /* K8 */ be_nested_str_weak(cluster), - /* K9 */ be_nested_str_weak(_X2504X_X2F), - /* K10 */ be_nested_str_weak(_X2A_X2A_X2A_X2A_X2F), - /* K11 */ be_nested_str_weak(attribute), - /* K12 */ be_nested_str_weak(_X2504X), - /* K13 */ be_nested_str_weak(_X2A_X2A_X2A_X2A), - /* K14 */ be_nested_str_weak(Exception_X3E_X20), - /* K15 */ be_nested_str_weak(_X2C_X20), + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(), + /* K1 */ be_nested_str_weak(node), + /* K2 */ be_nested_str_weak(node_X3D_X25s_X20), + /* K3 */ be_nested_str_weak(endpoint), + /* K4 */ be_nested_str_weak(_X5B_X2502X_X5D), + /* K5 */ be_nested_str_weak(_X5B_X2A_X2A_X5D), + /* K6 */ be_nested_str_weak(cluster), + /* K7 */ be_nested_str_weak(_X2504X_X2F), + /* K8 */ be_nested_str_weak(_X2A_X2A_X2A_X2A_X2F), + /* K9 */ be_nested_str_weak(attribute), + /* K10 */ be_nested_str_weak(_X2504X), + /* K11 */ be_nested_str_weak(_X2A_X2A_X2A_X2A), + /* K12 */ be_nested_str_weak(Exception_X3E_X20), + /* K13 */ be_nested_str_weak(_X2C_X20), }), be_str_weak(tostring), &be_const_str_solidified, - ( &(const binstruction[62]) { /* code */ - 0xA802002D, // 0000 EXBLK 0 #002F - 0xA4060000, // 0001 IMPORT R1 K0 - 0x58080001, // 0002 LDCONST R2 K1 - 0x880C0102, // 0003 GETMBR R3 R0 K2 - 0x780E0004, // 0004 JMPF R3 #000A - 0x8C0C0303, // 0005 GETMET R3 R1 K3 - 0x58140004, // 0006 LDCONST R5 K4 - 0x88180102, // 0007 GETMBR R6 R0 K2 - 0x7C0C0600, // 0008 CALL R3 3 - 0x00080403, // 0009 ADD R2 R2 R3 - 0x880C0105, // 000A GETMBR R3 R0 K5 - 0x4C100000, // 000B LDNIL R4 - 0x200C0604, // 000C NE R3 R3 R4 - 0x780E0004, // 000D JMPF R3 #0013 - 0x8C0C0303, // 000E GETMET R3 R1 K3 - 0x58140006, // 000F LDCONST R5 K6 - 0x88180105, // 0010 GETMBR R6 R0 K5 - 0x7C0C0600, // 0011 CALL R3 3 - 0x70020000, // 0012 JMP #0014 - 0x580C0007, // 0013 LDCONST R3 K7 - 0x00080403, // 0014 ADD R2 R2 R3 - 0x880C0108, // 0015 GETMBR R3 R0 K8 - 0x4C100000, // 0016 LDNIL R4 - 0x200C0604, // 0017 NE R3 R3 R4 - 0x780E0004, // 0018 JMPF R3 #001E - 0x8C0C0303, // 0019 GETMET R3 R1 K3 - 0x58140009, // 001A LDCONST R5 K9 - 0x88180108, // 001B GETMBR R6 R0 K8 - 0x7C0C0600, // 001C CALL R3 3 - 0x70020000, // 001D JMP #001F - 0x580C000A, // 001E LDCONST R3 K10 - 0x00080403, // 001F ADD R2 R2 R3 - 0x880C010B, // 0020 GETMBR R3 R0 K11 - 0x4C100000, // 0021 LDNIL R4 - 0x200C0604, // 0022 NE R3 R3 R4 - 0x780E0004, // 0023 JMPF R3 #0029 - 0x8C0C0303, // 0024 GETMET R3 R1 K3 - 0x5814000C, // 0025 LDCONST R5 K12 - 0x8818010B, // 0026 GETMBR R6 R0 K11 - 0x7C0C0600, // 0027 CALL R3 3 - 0x70020000, // 0028 JMP #002A - 0x580C000D, // 0029 LDCONST R3 K13 - 0x00080403, // 002A ADD R2 R2 R3 - 0xA8040001, // 002B EXBLK 1 1 - 0x80040400, // 002C RET 1 R2 - 0xA8040001, // 002D EXBLK 1 1 - 0x7002000D, // 002E JMP #003D - 0xAC040002, // 002F CATCH R1 0 2 - 0x7002000A, // 0030 JMP #003C - 0x600C0008, // 0031 GETGBL R3 G8 - 0x5C100200, // 0032 MOVE R4 R1 - 0x7C0C0200, // 0033 CALL R3 1 - 0x000E1C03, // 0034 ADD R3 K14 R3 - 0x000C070F, // 0035 ADD R3 R3 K15 - 0x60100008, // 0036 GETGBL R4 G8 - 0x5C140400, // 0037 MOVE R5 R2 - 0x7C100200, // 0038 CALL R4 1 - 0x000C0604, // 0039 ADD R3 R3 R4 - 0x80040600, // 003A RET 1 R3 - 0x70020000, // 003B JMP #003D - 0xB0080000, // 003C RAISE 2 R0 R0 - 0x80000000, // 003D RET 0 + ( &(const binstruction[61]) { /* code */ + 0xA802002C, // 0000 EXBLK 0 #002E + 0x58040000, // 0001 LDCONST R1 K0 + 0x88080101, // 0002 GETMBR R2 R0 K1 + 0x780A0004, // 0003 JMPF R2 #0009 + 0x60080018, // 0004 GETGBL R2 G24 + 0x580C0002, // 0005 LDCONST R3 K2 + 0x88100101, // 0006 GETMBR R4 R0 K1 + 0x7C080400, // 0007 CALL R2 2 + 0x00040202, // 0008 ADD R1 R1 R2 + 0x88080103, // 0009 GETMBR R2 R0 K3 + 0x4C0C0000, // 000A LDNIL R3 + 0x20080403, // 000B NE R2 R2 R3 + 0x780A0004, // 000C JMPF R2 #0012 + 0x60080018, // 000D GETGBL R2 G24 + 0x580C0004, // 000E LDCONST R3 K4 + 0x88100103, // 000F GETMBR R4 R0 K3 + 0x7C080400, // 0010 CALL R2 2 + 0x70020000, // 0011 JMP #0013 + 0x58080005, // 0012 LDCONST R2 K5 + 0x00040202, // 0013 ADD R1 R1 R2 + 0x88080106, // 0014 GETMBR R2 R0 K6 + 0x4C0C0000, // 0015 LDNIL R3 + 0x20080403, // 0016 NE R2 R2 R3 + 0x780A0004, // 0017 JMPF R2 #001D + 0x60080018, // 0018 GETGBL R2 G24 + 0x580C0007, // 0019 LDCONST R3 K7 + 0x88100106, // 001A GETMBR R4 R0 K6 + 0x7C080400, // 001B CALL R2 2 + 0x70020000, // 001C JMP #001E + 0x58080008, // 001D LDCONST R2 K8 + 0x00040202, // 001E ADD R1 R1 R2 + 0x88080109, // 001F GETMBR R2 R0 K9 + 0x4C0C0000, // 0020 LDNIL R3 + 0x20080403, // 0021 NE R2 R2 R3 + 0x780A0004, // 0022 JMPF R2 #0028 + 0x60080018, // 0023 GETGBL R2 G24 + 0x580C000A, // 0024 LDCONST R3 K10 + 0x88100109, // 0025 GETMBR R4 R0 K9 + 0x7C080400, // 0026 CALL R2 2 + 0x70020000, // 0027 JMP #0029 + 0x5808000B, // 0028 LDCONST R2 K11 + 0x00040202, // 0029 ADD R1 R1 R2 + 0xA8040001, // 002A EXBLK 1 1 + 0x80040200, // 002B RET 1 R1 + 0xA8040001, // 002C EXBLK 1 1 + 0x7002000D, // 002D JMP #003C + 0xAC040002, // 002E CATCH R1 0 2 + 0x7002000A, // 002F JMP #003B + 0x600C0008, // 0030 GETGBL R3 G8 + 0x5C100200, // 0031 MOVE R4 R1 + 0x7C0C0200, // 0032 CALL R3 1 + 0x000E1803, // 0033 ADD R3 K12 R3 + 0x000C070D, // 0034 ADD R3 R3 K13 + 0x60100008, // 0035 GETGBL R4 G8 + 0x5C140400, // 0036 MOVE R5 R2 + 0x7C100200, // 0037 CALL R4 1 + 0x000C0604, // 0038 ADD R3 R3 R4 + 0x80040600, // 0039 RET 1 R3 + 0x70020000, // 003A JMP #003C + 0xB0080000, // 003B RAISE 2 R0 R0 + 0x80000000, // 003C RET 0 }) ) ); @@ -2825,6 +2822,194 @@ void be_load_Matter_ReadRequestMessage_class(bvm *vm) { be_pop(vm, 1); } +extern const bclass be_class_Matter_ReadRequestMessage_solo; + +/******************************************************************** +** Solidified function: from_raw +********************************************************************/ +be_local_closure(Matter_ReadRequestMessage_solo_from_raw, /* name */ + be_nested_proto( + 11, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str_weak(reset), + /* K1 */ be_nested_str_weak(get), + /* K2 */ be_const_int(355860503), + /* K3 */ be_const_int(1), + /* K4 */ be_const_int(2), + /* K5 */ be_const_int(3), + /* K6 */ be_nested_str_weak(endpoint), + /* K7 */ be_nested_str_weak(cluster), + /* K8 */ be_nested_str_weak(attribute), + /* K9 */ be_nested_str_weak(fabric_filtered), + }), + be_str_weak(from_raw), + &be_const_str_solidified, + ( &(const binstruction[131]) { /* code */ + 0x8C0C0100, // 0000 GETMET R3 R0 K0 + 0x7C0C0200, // 0001 CALL R3 1 + 0x600C000C, // 0002 GETGBL R3 G12 + 0x5C100200, // 0003 MOVE R4 R1 + 0x7C0C0200, // 0004 CALL R3 1 + 0x4C100000, // 0005 LDNIL R4 + 0x8C140301, // 0006 GETMET R5 R1 K1 + 0x5C1C0400, // 0007 MOVE R7 R2 + 0x5421FFFB, // 0008 LDINT R8 -4 + 0x7C140600, // 0009 CALL R5 3 + 0x20140B02, // 000A NE R5 R5 K2 + 0x78160001, // 000B JMPF R5 #000E + 0x4C140000, // 000C LDNIL R5 + 0x80040A00, // 000D RET 1 R5 + 0x54160003, // 000E LDINT R5 4 + 0x00080405, // 000F ADD R2 R2 R5 + 0x14140403, // 0010 LT R5 R2 R3 + 0x7816002D, // 0011 JMPF R5 #0040 + 0x8C140301, // 0012 GETMET R5 R1 K1 + 0x001C0503, // 0013 ADD R7 R2 K3 + 0x58200003, // 0014 LDCONST R8 K3 + 0x7C140600, // 0015 CALL R5 3 + 0x8C180301, // 0016 GETMET R6 R1 K1 + 0x5C200400, // 0017 MOVE R8 R2 + 0x58240003, // 0018 LDCONST R9 K3 + 0x7C180600, // 0019 CALL R6 3 + 0x541E0023, // 001A LDINT R7 36 + 0x1C1C0C07, // 001B EQ R7 R6 R7 + 0x781E0006, // 001C JMPF R7 #0024 + 0x8C1C0301, // 001D GETMET R7 R1 K1 + 0x00240504, // 001E ADD R9 R2 K4 + 0x58280003, // 001F LDCONST R10 K3 + 0x7C1C0600, // 0020 CALL R7 3 + 0x5C100E00, // 0021 MOVE R4 R7 + 0x00080505, // 0022 ADD R2 R2 K5 + 0x7002000B, // 0023 JMP #0030 + 0x541E0024, // 0024 LDINT R7 37 + 0x1C1C0C07, // 0025 EQ R7 R6 R7 + 0x781E0007, // 0026 JMPF R7 #002F + 0x8C1C0301, // 0027 GETMET R7 R1 K1 + 0x00240504, // 0028 ADD R9 R2 K4 + 0x58280004, // 0029 LDCONST R10 K4 + 0x7C1C0600, // 002A CALL R7 3 + 0x5C100E00, // 002B MOVE R4 R7 + 0x541E0003, // 002C LDINT R7 4 + 0x00080407, // 002D ADD R2 R2 R7 + 0x70020000, // 002E JMP #0030 + 0x7002000F, // 002F JMP #0040 + 0x1C1C0B04, // 0030 EQ R7 R5 K4 + 0x781E0001, // 0031 JMPF R7 #0034 + 0x90020C04, // 0032 SETMBR R0 K6 R4 + 0x7002000A, // 0033 JMP #003F + 0x1C1C0B05, // 0034 EQ R7 R5 K5 + 0x781E0001, // 0035 JMPF R7 #0038 + 0x90020E04, // 0036 SETMBR R0 K7 R4 + 0x70020006, // 0037 JMP #003F + 0x541E0003, // 0038 LDINT R7 4 + 0x1C1C0A07, // 0039 EQ R7 R5 R7 + 0x781E0001, // 003A JMPF R7 #003D + 0x90021004, // 003B SETMBR R0 K8 R4 + 0x70020001, // 003C JMP #003F + 0x4C1C0000, // 003D LDNIL R7 + 0x80040E00, // 003E RET 1 R7 + 0x7001FFCF, // 003F JMP #0010 + 0x8C140301, // 0040 GETMET R5 R1 K1 + 0x5C1C0400, // 0041 MOVE R7 R2 + 0x5421FFFD, // 0042 LDINT R8 -2 + 0x7C140600, // 0043 CALL R5 3 + 0x5C100A00, // 0044 MOVE R4 R5 + 0x54161817, // 0045 LDINT R5 6168 + 0x20140805, // 0046 NE R5 R4 R5 + 0x78160001, // 0047 JMPF R5 #004A + 0x4C140000, // 0048 LDNIL R5 + 0x80040A00, // 0049 RET 1 R5 + 0x00080504, // 004A ADD R2 R2 K4 + 0x8C140301, // 004B GETMET R5 R1 K1 + 0x5C1C0400, // 004C MOVE R7 R2 + 0x5421FFFD, // 004D LDINT R8 -2 + 0x7C140600, // 004E CALL R5 3 + 0x5C100A00, // 004F MOVE R4 R5 + 0x54162802, // 0050 LDINT R5 10243 + 0x1C140805, // 0051 EQ R5 R4 R5 + 0x78160003, // 0052 JMPF R5 #0057 + 0x50140000, // 0053 LDBOOL R5 0 0 + 0x90021205, // 0054 SETMBR R0 K9 R5 + 0x00080504, // 0055 ADD R2 R2 K4 + 0x70020005, // 0056 JMP #005D + 0x54162902, // 0057 LDINT R5 10499 + 0x1C140805, // 0058 EQ R5 R4 R5 + 0x78160002, // 0059 JMPF R5 #005D + 0x50140200, // 005A LDBOOL R5 1 0 + 0x90021205, // 005B SETMBR R0 K9 R5 + 0x00080504, // 005C ADD R2 R2 K4 + 0x8C140301, // 005D GETMET R5 R1 K1 + 0x5C1C0400, // 005E MOVE R7 R2 + 0x5421FFFD, // 005F LDINT R8 -2 + 0x7C140600, // 0060 CALL R5 3 + 0x5C100A00, // 0061 MOVE R4 R5 + 0x541624FE, // 0062 LDINT R5 9471 + 0x1C140805, // 0063 EQ R5 R4 R5 + 0x78160000, // 0064 JMPF R5 #0066 + 0x00080505, // 0065 ADD R2 R2 K5 + 0x8C140301, // 0066 GETMET R5 R1 K1 + 0x5C1C0400, // 0067 MOVE R7 R2 + 0x58200003, // 0068 LDCONST R8 K3 + 0x7C140600, // 0069 CALL R5 3 + 0x541A0017, // 006A LDINT R6 24 + 0x20140A06, // 006B NE R5 R5 R6 + 0x78160001, // 006C JMPF R5 #006F + 0x4C140000, // 006D LDNIL R5 + 0x80040A00, // 006E RET 1 R5 + 0x00080503, // 006F ADD R2 R2 K3 + 0x88140106, // 0070 GETMBR R5 R0 K6 + 0x4C180000, // 0071 LDNIL R6 + 0x1C140A06, // 0072 EQ R5 R5 R6 + 0x7416000B, // 0073 JMPT R5 #0080 + 0x88140107, // 0074 GETMBR R5 R0 K7 + 0x4C180000, // 0075 LDNIL R6 + 0x1C140A06, // 0076 EQ R5 R5 R6 + 0x74160007, // 0077 JMPT R5 #0080 + 0x88140108, // 0078 GETMBR R5 R0 K8 + 0x4C180000, // 0079 LDNIL R6 + 0x1C140A06, // 007A EQ R5 R5 R6 + 0x74160003, // 007B JMPT R5 #0080 + 0x88140109, // 007C GETMBR R5 R0 K9 + 0x4C180000, // 007D LDNIL R6 + 0x1C140A06, // 007E EQ R5 R5 R6 + 0x78160001, // 007F JMPF R5 #0082 + 0x4C140000, // 0080 LDNIL R5 + 0x80040A00, // 0081 RET 1 R5 + 0x80040000, // 0082 RET 1 R0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_ReadRequestMessage_solo +********************************************************************/ +extern const bclass be_class_Matter_Path; +be_local_class(Matter_ReadRequestMessage_solo, + 0, + &be_class_Matter_Path, + be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(from_raw, -1), be_const_closure(Matter_ReadRequestMessage_solo_from_raw_closure) }, + })), + be_str_weak(Matter_ReadRequestMessage_solo) +); +/*******************************************************************/ + +void be_load_Matter_ReadRequestMessage_solo_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_ReadRequestMessage_solo); + be_setglobal(vm, "Matter_ReadRequestMessage_solo"); + be_pop(vm, 1); +} + extern const bclass be_class_Matter_ReportDataMessage; /******************************************************************** @@ -3889,6 +4074,281 @@ void be_load_Matter_InvokeRequestMessage_class(bvm *vm) { be_pop(vm, 1); } +extern const bclass be_class_Matter_InvokeRequestMessage_solo; + +/******************************************************************** +** Solidified function: reset +********************************************************************/ +be_local_closure(Matter_InvokeRequestMessage_solo_reset, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(reset), + /* K1 */ be_nested_str_weak(SuppressResponse), + /* K2 */ be_nested_str_weak(TimedRequest), + /* K3 */ be_nested_str_weak(command_fields), + }), + be_str_weak(reset), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x4C040000, // 0000 LDNIL R1 + 0x60080003, // 0001 GETGBL R2 G3 + 0x5C0C0000, // 0002 MOVE R3 R0 + 0x7C080200, // 0003 CALL R2 1 + 0x8C080500, // 0004 GETMET R2 R2 K0 + 0x7C080200, // 0005 CALL R2 1 + 0x90020201, // 0006 SETMBR R0 K1 R1 + 0x90020401, // 0007 SETMBR R0 K2 R1 + 0x90020601, // 0008 SETMBR R0 K3 R1 + 0x80000000, // 0009 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: from_raw +********************************************************************/ +be_local_closure(Matter_InvokeRequestMessage_solo_from_raw, /* name */ + be_nested_proto( + 11, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[16]) { /* constants */ + /* K0 */ be_nested_str_weak(reset), + /* K1 */ be_nested_str_weak(get), + /* K2 */ be_const_int(1), + /* K3 */ be_nested_str_weak(SuppressResponse), + /* K4 */ be_const_int(2), + /* K5 */ be_const_int(3), + /* K6 */ be_const_int(0), + /* K7 */ be_nested_str_weak(endpoint), + /* K8 */ be_nested_str_weak(cluster), + /* K9 */ be_nested_str_weak(command), + /* K10 */ be_nested_str_weak(command_fields), + /* K11 */ be_nested_str_weak(matter), + /* K12 */ be_nested_str_weak(TLV), + /* K13 */ be_nested_str_weak(parse), + /* K14 */ be_nested_str_weak(next_idx), + /* K15 */ be_const_int(620691736), + }), + be_str_weak(from_raw), + &be_const_str_solidified, + ( &(const binstruction[170]) { /* code */ + 0x8C0C0100, // 0000 GETMET R3 R0 K0 + 0x7C0C0200, // 0001 CALL R3 1 + 0x600C000C, // 0002 GETGBL R3 G12 + 0x5C100200, // 0003 MOVE R4 R1 + 0x7C0C0200, // 0004 CALL R3 1 + 0x4C100000, // 0005 LDNIL R4 + 0x8C140301, // 0006 GETMET R5 R1 K1 + 0x5C1C0400, // 0007 MOVE R7 R2 + 0x58200002, // 0008 LDCONST R8 K2 + 0x7C140600, // 0009 CALL R5 3 + 0x541A0014, // 000A LDINT R6 21 + 0x20140A06, // 000B NE R5 R5 R6 + 0x78160001, // 000C JMPF R5 #000F + 0x4C140000, // 000D LDNIL R5 + 0x80040A00, // 000E RET 1 R5 + 0x00080502, // 000F ADD R2 R2 K2 + 0x8C140301, // 0010 GETMET R5 R1 K1 + 0x5C1C0400, // 0011 MOVE R7 R2 + 0x5421FFFD, // 0012 LDINT R8 -2 + 0x7C140600, // 0013 CALL R5 3 + 0x5C100A00, // 0014 MOVE R4 R5 + 0x541627FF, // 0015 LDINT R5 10240 + 0x1C140805, // 0016 EQ R5 R4 R5 + 0x74160002, // 0017 JMPT R5 #001B + 0x541628FF, // 0018 LDINT R5 10496 + 0x1C140805, // 0019 EQ R5 R4 R5 + 0x78160003, // 001A JMPF R5 #001F + 0x541628FF, // 001B LDINT R5 10496 + 0x1C140805, // 001C EQ R5 R4 R5 + 0x90020605, // 001D SETMBR R0 K3 R5 + 0x00080504, // 001E ADD R2 R2 K4 + 0x8C140301, // 001F GETMET R5 R1 K1 + 0x5C1C0400, // 0020 MOVE R7 R2 + 0x5421FFFD, // 0021 LDINT R8 -2 + 0x7C140600, // 0022 CALL R5 3 + 0x5C100A00, // 0023 MOVE R4 R5 + 0x54162800, // 0024 LDINT R5 10241 + 0x1C140805, // 0025 EQ R5 R4 R5 + 0x74160002, // 0026 JMPT R5 #002A + 0x54162900, // 0027 LDINT R5 10497 + 0x1C140805, // 0028 EQ R5 R4 R5 + 0x78160003, // 0029 JMPF R5 #002E + 0x54162900, // 002A LDINT R5 10497 + 0x1C140805, // 002B EQ R5 R4 R5 + 0x90020605, // 002C SETMBR R0 K3 R5 + 0x00080504, // 002D ADD R2 R2 K4 + 0x8C140301, // 002E GETMET R5 R1 K1 + 0x5C1C0400, // 002F MOVE R7 R2 + 0x5421FFFD, // 0030 LDINT R8 -2 + 0x7C140600, // 0031 CALL R5 3 + 0x541A3601, // 0032 LDINT R6 13826 + 0x20140A06, // 0033 NE R5 R5 R6 + 0x78160001, // 0034 JMPF R5 #0037 + 0x4C140000, // 0035 LDNIL R5 + 0x80040A00, // 0036 RET 1 R5 + 0x00080504, // 0037 ADD R2 R2 K4 + 0x8C140301, // 0038 GETMET R5 R1 K1 + 0x5C1C0400, // 0039 MOVE R7 R2 + 0x58200002, // 003A LDCONST R8 K2 + 0x7C140600, // 003B CALL R5 3 + 0x541A0014, // 003C LDINT R6 21 + 0x20140A06, // 003D NE R5 R5 R6 + 0x78160001, // 003E JMPF R5 #0041 + 0x4C140000, // 003F LDNIL R5 + 0x80040A00, // 0040 RET 1 R5 + 0x00080502, // 0041 ADD R2 R2 K2 + 0x8C140301, // 0042 GETMET R5 R1 K1 + 0x5C1C0400, // 0043 MOVE R7 R2 + 0x5421FFFD, // 0044 LDINT R8 -2 + 0x7C140600, // 0045 CALL R5 3 + 0x541A36FF, // 0046 LDINT R6 14080 + 0x20140A06, // 0047 NE R5 R5 R6 + 0x78160001, // 0048 JMPF R5 #004B + 0x4C140000, // 0049 LDNIL R5 + 0x80040A00, // 004A RET 1 R5 + 0x00080504, // 004B ADD R2 R2 K4 + 0x14140403, // 004C LT R5 R2 R3 + 0x7816002C, // 004D JMPF R5 #007B + 0x8C140301, // 004E GETMET R5 R1 K1 + 0x001C0502, // 004F ADD R7 R2 K2 + 0x58200002, // 0050 LDCONST R8 K2 + 0x7C140600, // 0051 CALL R5 3 + 0x8C180301, // 0052 GETMET R6 R1 K1 + 0x5C200400, // 0053 MOVE R8 R2 + 0x58240002, // 0054 LDCONST R9 K2 + 0x7C180600, // 0055 CALL R6 3 + 0x541E0023, // 0056 LDINT R7 36 + 0x1C1C0C07, // 0057 EQ R7 R6 R7 + 0x781E0006, // 0058 JMPF R7 #0060 + 0x8C1C0301, // 0059 GETMET R7 R1 K1 + 0x00240504, // 005A ADD R9 R2 K4 + 0x58280002, // 005B LDCONST R10 K2 + 0x7C1C0600, // 005C CALL R7 3 + 0x5C100E00, // 005D MOVE R4 R7 + 0x00080505, // 005E ADD R2 R2 K5 + 0x7002000B, // 005F JMP #006C + 0x541E0024, // 0060 LDINT R7 37 + 0x1C1C0C07, // 0061 EQ R7 R6 R7 + 0x781E0007, // 0062 JMPF R7 #006B + 0x8C1C0301, // 0063 GETMET R7 R1 K1 + 0x00240504, // 0064 ADD R9 R2 K4 + 0x58280004, // 0065 LDCONST R10 K4 + 0x7C1C0600, // 0066 CALL R7 3 + 0x5C100E00, // 0067 MOVE R4 R7 + 0x541E0003, // 0068 LDINT R7 4 + 0x00080407, // 0069 ADD R2 R2 R7 + 0x70020000, // 006A JMP #006C + 0x7002000E, // 006B JMP #007B + 0x1C1C0B06, // 006C EQ R7 R5 K6 + 0x781E0001, // 006D JMPF R7 #0070 + 0x90020E04, // 006E SETMBR R0 K7 R4 + 0x70020009, // 006F JMP #007A + 0x1C1C0B02, // 0070 EQ R7 R5 K2 + 0x781E0001, // 0071 JMPF R7 #0074 + 0x90021004, // 0072 SETMBR R0 K8 R4 + 0x70020005, // 0073 JMP #007A + 0x1C1C0B04, // 0074 EQ R7 R5 K4 + 0x781E0001, // 0075 JMPF R7 #0078 + 0x90021204, // 0076 SETMBR R0 K9 R4 + 0x70020001, // 0077 JMP #007A + 0x4C1C0000, // 0078 LDNIL R7 + 0x80040E00, // 0079 RET 1 R7 + 0x7001FFD0, // 007A JMP #004C + 0x8C140301, // 007B GETMET R5 R1 K1 + 0x5C1C0400, // 007C MOVE R7 R2 + 0x58200002, // 007D LDCONST R8 K2 + 0x7C140600, // 007E CALL R5 3 + 0x541A0017, // 007F LDINT R6 24 + 0x20140A06, // 0080 NE R5 R5 R6 + 0x78160001, // 0081 JMPF R5 #0084 + 0x4C140000, // 0082 LDNIL R5 + 0x80040A00, // 0083 RET 1 R5 + 0x00080502, // 0084 ADD R2 R2 K2 + 0x8C140301, // 0085 GETMET R5 R1 K1 + 0x5C1C0400, // 0086 MOVE R7 R2 + 0x5421FFFD, // 0087 LDINT R8 -2 + 0x7C140600, // 0088 CALL R5 3 + 0x541A3500, // 0089 LDINT R6 13569 + 0x20140A06, // 008A NE R5 R5 R6 + 0x78160001, // 008B JMPF R5 #008E + 0x4C140000, // 008C LDNIL R5 + 0x80040A00, // 008D RET 1 R5 + 0xB8161600, // 008E GETNGBL R5 K11 + 0x88140B0C, // 008F GETMBR R5 R5 K12 + 0x8C140B0D, // 0090 GETMET R5 R5 K13 + 0x5C1C0200, // 0091 MOVE R7 R1 + 0x5C200400, // 0092 MOVE R8 R2 + 0x7C140600, // 0093 CALL R5 3 + 0x90021405, // 0094 SETMBR R0 K10 R5 + 0x8814010A, // 0095 GETMBR R5 R0 K10 + 0x88080B0E, // 0096 GETMBR R2 R5 K14 + 0x8C180301, // 0097 GETMET R6 R1 K1 + 0x5C200400, // 0098 MOVE R8 R2 + 0x5425FFFD, // 0099 LDINT R9 -2 + 0x7C180600, // 009A CALL R6 3 + 0x541E1817, // 009B LDINT R7 6168 + 0x20180C07, // 009C NE R6 R6 R7 + 0x781A0001, // 009D JMPF R6 #00A0 + 0x4C180000, // 009E LDNIL R6 + 0x80040C00, // 009F RET 1 R6 + 0x00080504, // 00A0 ADD R2 R2 K4 + 0x8C140301, // 00A1 GETMET R5 R1 K1 + 0x5C1C0400, // 00A2 MOVE R7 R2 + 0x5421FFFB, // 00A3 LDINT R8 -4 + 0x7C140600, // 00A4 CALL R5 3 + 0x20140B0F, // 00A5 NE R5 R5 K15 + 0x78160001, // 00A6 JMPF R5 #00A9 + 0x4C140000, // 00A7 LDNIL R5 + 0x80040A00, // 00A8 RET 1 R5 + 0x80040000, // 00A9 RET 1 R0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_InvokeRequestMessage_solo +********************************************************************/ +extern const bclass be_class_Matter_Path; +be_local_class(Matter_InvokeRequestMessage_solo, + 3, + &be_class_Matter_Path, + be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(SuppressResponse, 4), be_const_var(0) }, + { be_const_key_weak(command_fields, 3), be_const_var(2) }, + { be_const_key_weak(reset, -1), be_const_closure(Matter_InvokeRequestMessage_solo_reset_closure) }, + { be_const_key_weak(from_raw, -1), be_const_closure(Matter_InvokeRequestMessage_solo_from_raw_closure) }, + { be_const_key_weak(TimedRequest, -1), be_const_var(1) }, + })), + be_str_weak(Matter_InvokeRequestMessage_solo) +); +/*******************************************************************/ + +void be_load_Matter_InvokeRequestMessage_solo_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_InvokeRequestMessage_solo); + be_setglobal(vm, "Matter_InvokeRequestMessage_solo"); + be_pop(vm, 1); +} + extern const bclass be_class_Matter_InvokeResponseMessage; /******************************************************************** diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Message.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Message.h index b1b6f21da38a..61bae0147a62 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Message.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Message.h @@ -7,23 +7,59 @@ extern const bclass be_class_Matter_IM_Message; /******************************************************************** -** Solidified function: status_error_received +** Solidified function: init ********************************************************************/ -be_local_closure(Matter_IM_Message_status_error_received, /* name */ +be_local_closure(Matter_IM_Message_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(reset), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x8C100100, // 0000 GETMET R4 R0 K0 + 0x5C180200, // 0001 MOVE R6 R1 + 0x5C1C0400, // 0002 MOVE R7 R2 + 0x5C200600, // 0003 MOVE R8 R3 + 0x7C100800, // 0004 CALL R4 4 + 0x80000000, // 0005 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_exchangeid +********************************************************************/ +be_local_closure(Matter_IM_Message_get_exchangeid, /* name */ be_nested_proto( 2, /* nstack */ - 2, /* argc */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(status_error_received), + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(resp), + /* K1 */ be_nested_str_weak(exchange_id), + }), + be_str_weak(get_exchangeid), &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 + ( &(const binstruction[ 3]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x88040301, // 0001 GETMBR R1 R1 K1 + 0x80040200, // 0002 RET 1 R1 }) ) ); @@ -43,67 +79,70 @@ be_local_closure(Matter_IM_Message_send_im, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[21]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(ready), - /* K2 */ be_nested_str_weak(resp), - /* K3 */ be_nested_str_weak(encode_frame), - /* K4 */ be_nested_str_weak(data), - /* K5 */ be_nested_str_weak(to_TLV), - /* K6 */ be_nested_str_weak(tlv2raw), - /* K7 */ be_nested_str_weak(encrypt), - /* K8 */ be_nested_str_weak(tasmota), + ( &(const bvalue[19]) { /* constants */ + /* K0 */ be_nested_str_weak(ready), + /* K1 */ be_nested_str_weak(resp), + /* K2 */ be_nested_str_weak(data), + /* K3 */ be_nested_str_weak(to_TLV), + /* K4 */ be_nested_str_weak(tlv2raw), + /* K5 */ be_nested_str_weak(encode_frame), + /* K6 */ be_nested_str_weak(encrypt), + /* K7 */ be_nested_str_weak(tasmota), + /* K8 */ be_nested_str_weak(loglevel), /* K9 */ be_nested_str_weak(log), - /* K10 */ be_nested_str_weak(format), - /* K11 */ be_nested_str_weak(MTR_X3A_X20_X3Csnd_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20id_X3D_X25i_X20exch_X3D_X25i_X20rack_X3D_X25s), - /* K12 */ be_nested_str_weak(session), - /* K13 */ be_nested_str_weak(local_session_id), - /* K14 */ be_nested_str_weak(message_counter), - /* K15 */ be_nested_str_weak(exchange_id), - /* K16 */ be_nested_str_weak(ack_message_counter), - /* K17 */ be_const_int(3), - /* K18 */ be_nested_str_weak(send_response_frame), - /* K19 */ be_nested_str_weak(last_counter), - /* K20 */ be_nested_str_weak(finish), + /* K10 */ be_nested_str_weak(MTR_X3A_X20_X3Csnd_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20id_X3D_X25i_X20exch_X3D_X25i_X20rack_X3D_X25s), + /* K11 */ be_nested_str_weak(session), + /* K12 */ be_nested_str_weak(local_session_id), + /* K13 */ be_nested_str_weak(message_counter), + /* K14 */ be_nested_str_weak(exchange_id), + /* K15 */ be_nested_str_weak(ack_message_counter), + /* K16 */ be_nested_str_weak(send_response_frame), + /* K17 */ be_nested_str_weak(last_counter), + /* K18 */ be_nested_str_weak(finish), }), be_str_weak(send_im), &be_const_str_solidified, - ( &(const binstruction[35]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x880C0101, // 0001 GETMBR R3 R0 K1 - 0x740E0001, // 0002 JMPT R3 #0005 - 0x500C0000, // 0003 LDBOOL R3 0 0 - 0x80040600, // 0004 RET 1 R3 + ( &(const binstruction[40]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x740A0001, // 0001 JMPT R2 #0004 + 0x50080000, // 0002 LDBOOL R2 0 0 + 0x80040400, // 0003 RET 1 R2 + 0x88080101, // 0004 GETMBR R2 R0 K1 0x880C0102, // 0005 GETMBR R3 R0 K2 - 0x8C100703, // 0006 GETMET R4 R3 K3 - 0x88180104, // 0007 GETMBR R6 R0 K4 - 0x8C180D05, // 0008 GETMET R6 R6 K5 - 0x7C180200, // 0009 CALL R6 1 - 0x8C180D06, // 000A GETMET R6 R6 K6 - 0x7C180200, // 000B CALL R6 1 - 0x7C100400, // 000C CALL R4 2 - 0x8C100707, // 000D GETMET R4 R3 K7 - 0x7C100200, // 000E CALL R4 1 - 0xB8121000, // 000F GETNGBL R4 K8 - 0x8C100909, // 0010 GETMET R4 R4 K9 - 0x8C18050A, // 0011 GETMET R6 R2 K10 - 0x5820000B, // 0012 LDCONST R8 K11 - 0x8824070C, // 0013 GETMBR R9 R3 K12 - 0x8824130D, // 0014 GETMBR R9 R9 K13 - 0x8828070E, // 0015 GETMBR R10 R3 K14 - 0x882C070F, // 0016 GETMBR R11 R3 K15 - 0x88300710, // 0017 GETMBR R12 R3 K16 - 0x7C180C00, // 0018 CALL R6 6 - 0x581C0011, // 0019 LDCONST R7 K17 - 0x7C100600, // 001A CALL R4 3 - 0x8C100312, // 001B GETMET R4 R1 K18 - 0x5C180600, // 001C MOVE R6 R3 - 0x7C100400, // 001D CALL R4 2 - 0x8810070E, // 001E GETMBR R4 R3 K14 - 0x90022604, // 001F SETMBR R0 K19 R4 - 0x50100200, // 0020 LDBOOL R4 1 0 - 0x90022804, // 0021 SETMBR R0 K20 R4 - 0x80000000, // 0022 RET 0 + 0x8C0C0703, // 0006 GETMET R3 R3 K3 + 0x7C0C0200, // 0007 CALL R3 1 + 0x8C100704, // 0008 GETMET R4 R3 K4 + 0x7C100200, // 0009 CALL R4 1 + 0x8C140505, // 000A GETMET R5 R2 K5 + 0x5C1C0800, // 000B MOVE R7 R4 + 0x7C140400, // 000C CALL R5 2 + 0x8C140506, // 000D GETMET R5 R2 K6 + 0x7C140200, // 000E CALL R5 1 + 0xB8160E00, // 000F GETNGBL R5 K7 + 0x8C140B08, // 0010 GETMET R5 R5 K8 + 0x541E0003, // 0011 LDINT R7 4 + 0x7C140400, // 0012 CALL R5 2 + 0x7816000B, // 0013 JMPF R5 #0020 + 0xB8160E00, // 0014 GETNGBL R5 K7 + 0x8C140B09, // 0015 GETMET R5 R5 K9 + 0x601C0018, // 0016 GETGBL R7 G24 + 0x5820000A, // 0017 LDCONST R8 K10 + 0x8824050B, // 0018 GETMBR R9 R2 K11 + 0x8824130C, // 0019 GETMBR R9 R9 K12 + 0x8828050D, // 001A GETMBR R10 R2 K13 + 0x882C050E, // 001B GETMBR R11 R2 K14 + 0x8830050F, // 001C GETMBR R12 R2 K15 + 0x7C1C0A00, // 001D CALL R7 5 + 0x54220003, // 001E LDINT R8 4 + 0x7C140600, // 001F CALL R5 3 + 0x8C140310, // 0020 GETMET R5 R1 K16 + 0x5C1C0400, // 0021 MOVE R7 R2 + 0x7C140400, // 0022 CALL R5 2 + 0x8814050D, // 0023 GETMBR R5 R2 K13 + 0x90022205, // 0024 SETMBR R0 K17 R5 + 0x50140200, // 0025 LDBOOL R5 1 0 + 0x90022405, // 0026 SETMBR R0 K18 R5 + 0x80000000, // 0027 RET 0 }) ) ); @@ -111,28 +150,23 @@ be_local_closure(Matter_IM_Message_send_im, /* name */ /******************************************************************** -** Solidified function: get_exchangeid +** Solidified function: status_error_received ********************************************************************/ -be_local_closure(Matter_IM_Message_get_exchangeid, /* name */ +be_local_closure(Matter_IM_Message_status_error_received, /* name */ be_nested_proto( 2, /* nstack */ - 1, /* argc */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(resp), - /* K1 */ be_nested_str_weak(exchange_id), - }), - be_str_weak(get_exchangeid), + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(status_error_received), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x80040200, // 0002 RET 1 R1 + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 }) ) ); @@ -140,9 +174,9 @@ be_local_closure(Matter_IM_Message_get_exchangeid, /* name */ /******************************************************************** -** Solidified function: init +** Solidified function: reset ********************************************************************/ -be_local_closure(Matter_IM_Message_init, /* name */ +be_local_closure(Matter_IM_Message_reset, /* name */ be_nested_proto( 8, /* nstack */ 4, /* argc */ @@ -152,7 +186,7 @@ be_local_closure(Matter_IM_Message_init, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ + ( &(const bvalue[11]) { /* constants */ /* K0 */ be_nested_str_weak(resp), /* K1 */ be_nested_str_weak(build_response), /* K2 */ be_nested_str_weak(ready), @@ -163,10 +197,11 @@ be_local_closure(Matter_IM_Message_init, /* name */ /* K7 */ be_nested_str_weak(last_counter), /* K8 */ be_const_int(0), /* K9 */ be_nested_str_weak(finish), + /* K10 */ be_nested_str_weak(data), }), - be_str_weak(init), + be_str_weak(reset), &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ + ( &(const binstruction[19]) { /* code */ 0x8C100301, // 0000 GETMET R4 R1 K1 0x5C180400, // 0001 MOVE R6 R2 0x5C1C0600, // 0002 MOVE R7 R3 @@ -183,7 +218,9 @@ be_local_closure(Matter_IM_Message_init, /* name */ 0x90020F08, // 000D SETMBR R0 K7 K8 0x50100000, // 000E LDBOOL R4 0 0 0x90021204, // 000F SETMBR R0 K9 R4 - 0x80000000, // 0010 RET 0 + 0x4C100000, // 0010 LDNIL R4 + 0x90021404, // 0011 SETMBR R0 K10 R4 + 0x80000000, // 0012 RET 0 }) ) ); @@ -191,35 +228,23 @@ be_local_closure(Matter_IM_Message_init, /* name */ /******************************************************************** -** Solidified function: ack_received +** Solidified function: reached_timeout ********************************************************************/ -be_local_closure(Matter_IM_Message_ack_received, /* name */ +be_local_closure(Matter_IM_Message_reached_timeout, /* name */ be_nested_proto( - 4, /* nstack */ - 2, /* argc */ + 1, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(expiration), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(millis), - /* K3 */ be_nested_str_weak(MSG_TIMEOUT), - }), - be_str_weak(ack_received), + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(reached_timeout), &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0xB80A0200, // 0000 GETNGBL R2 K1 - 0x8C080502, // 0001 GETMET R2 R2 K2 - 0x7C080200, // 0002 CALL R2 1 - 0x880C0103, // 0003 GETMBR R3 R0 K3 - 0x00080403, // 0004 ADD R2 R2 R3 - 0x90020002, // 0005 SETMBR R0 K0 R2 - 0x50080000, // 0006 LDBOOL R2 0 0 - 0x80040400, // 0007 RET 1 R2 + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 }) ) ); @@ -227,23 +252,51 @@ be_local_closure(Matter_IM_Message_ack_received, /* name */ /******************************************************************** -** Solidified function: reached_timeout +** Solidified function: status_ok_received ********************************************************************/ -be_local_closure(Matter_IM_Message_reached_timeout, /* name */ +be_local_closure(Matter_IM_Message_status_ok_received, /* name */ be_nested_proto( - 1, /* nstack */ - 1, /* argc */ + 7, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(reached_timeout), + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(expiration), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(millis), + /* K3 */ be_nested_str_weak(MSG_TIMEOUT), + /* K4 */ be_nested_str_weak(resp), + /* K5 */ be_nested_str_weak(build_response), + /* K6 */ be_nested_str_weak(opcode), + /* K7 */ be_nested_str_weak(x_flag_r), + /* K8 */ be_nested_str_weak(ready), + }), + be_str_weak(status_ok_received), &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 + ( &(const binstruction[19]) { /* code */ + 0xB80A0200, // 0000 GETNGBL R2 K1 + 0x8C080502, // 0001 GETMET R2 R2 K2 + 0x7C080200, // 0002 CALL R2 1 + 0x880C0103, // 0003 GETMBR R3 R0 K3 + 0x00080403, // 0004 ADD R2 R2 R3 + 0x90020002, // 0005 SETMBR R0 K0 R2 + 0x78060007, // 0006 JMPF R1 #000F + 0x8C080305, // 0007 GETMET R2 R1 K5 + 0x88100104, // 0008 GETMBR R4 R0 K4 + 0x88100906, // 0009 GETMBR R4 R4 K6 + 0x88140104, // 000A GETMBR R5 R0 K4 + 0x88140B07, // 000B GETMBR R5 R5 K7 + 0x88180104, // 000C GETMBR R6 R0 K4 + 0x7C080800, // 000D CALL R2 4 + 0x90020802, // 000E SETMBR R0 K4 R2 + 0x50080200, // 000F LDBOOL R2 1 0 + 0x90021002, // 0010 SETMBR R0 K8 R2 + 0x50080200, // 0011 LDBOOL R2 1 0 + 0x80040400, // 0012 RET 1 R2 }) ) ); @@ -251,11 +304,11 @@ be_local_closure(Matter_IM_Message_reached_timeout, /* name */ /******************************************************************** -** Solidified function: status_ok_received +** Solidified function: ack_received ********************************************************************/ -be_local_closure(Matter_IM_Message_status_ok_received, /* name */ +be_local_closure(Matter_IM_Message_ack_received, /* name */ be_nested_proto( - 8, /* nstack */ + 4, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -263,41 +316,23 @@ be_local_closure(Matter_IM_Message_status_ok_received, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(expiration), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(millis), - /* K4 */ be_nested_str_weak(MSG_TIMEOUT), - /* K5 */ be_nested_str_weak(resp), - /* K6 */ be_nested_str_weak(build_response), - /* K7 */ be_nested_str_weak(opcode), - /* K8 */ be_nested_str_weak(x_flag_r), - /* K9 */ be_nested_str_weak(ready), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(expiration), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(millis), + /* K3 */ be_nested_str_weak(MSG_TIMEOUT), }), - be_str_weak(status_ok_received), + be_str_weak(ack_received), &be_const_str_solidified, - ( &(const binstruction[20]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0xB80E0400, // 0001 GETNGBL R3 K2 - 0x8C0C0703, // 0002 GETMET R3 R3 K3 - 0x7C0C0200, // 0003 CALL R3 1 - 0x88100104, // 0004 GETMBR R4 R0 K4 - 0x000C0604, // 0005 ADD R3 R3 R4 - 0x90020203, // 0006 SETMBR R0 K1 R3 - 0x78060007, // 0007 JMPF R1 #0010 - 0x8C0C0306, // 0008 GETMET R3 R1 K6 - 0x88140105, // 0009 GETMBR R5 R0 K5 - 0x88140B07, // 000A GETMBR R5 R5 K7 - 0x88180105, // 000B GETMBR R6 R0 K5 - 0x88180D08, // 000C GETMBR R6 R6 K8 - 0x881C0105, // 000D GETMBR R7 R0 K5 - 0x7C0C0800, // 000E CALL R3 4 - 0x90020A03, // 000F SETMBR R0 K5 R3 - 0x500C0200, // 0010 LDBOOL R3 1 0 - 0x90021203, // 0011 SETMBR R0 K9 R3 - 0x500C0200, // 0012 LDBOOL R3 1 0 - 0x80040600, // 0013 RET 1 R3 + ( &(const binstruction[ 8]) { /* code */ + 0xB80A0200, // 0000 GETNGBL R2 K1 + 0x8C080502, // 0001 GETMET R2 R2 K2 + 0x7C080200, // 0002 CALL R2 1 + 0x880C0103, // 0003 GETMBR R3 R0 K3 + 0x00080403, // 0004 ADD R2 R2 R3 + 0x90020002, // 0005 SETMBR R0 K0 R2 + 0x50080000, // 0006 LDBOOL R2 0 0 + 0x80040400, // 0007 RET 1 R2 }) ) ); @@ -310,22 +345,23 @@ be_local_closure(Matter_IM_Message_status_ok_received, /* name */ be_local_class(Matter_IM_Message, 6, NULL, - be_nested_map(14, + be_nested_map(15, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(MSG_TIMEOUT, -1), be_const_int(5000) }, - { be_const_key_weak(data, -1), be_const_var(4) }, + { be_const_key_weak(init, 11), be_const_closure(Matter_IM_Message_init_closure) }, + { be_const_key_weak(get_exchangeid, 10), be_const_closure(Matter_IM_Message_get_exchangeid_closure) }, + { be_const_key_weak(reset, -1), be_const_closure(Matter_IM_Message_reset_closure) }, { be_const_key_weak(send_im, -1), be_const_closure(Matter_IM_Message_send_im_closure) }, - { be_const_key_weak(status_ok_received, -1), be_const_closure(Matter_IM_Message_status_ok_received_closure) }, - { be_const_key_weak(get_exchangeid, 0), be_const_closure(Matter_IM_Message_get_exchangeid_closure) }, - { be_const_key_weak(init, -1), be_const_closure(Matter_IM_Message_init_closure) }, - { be_const_key_weak(expiration, -1), be_const_var(0) }, - { be_const_key_weak(resp, -1), be_const_var(1) }, - { be_const_key_weak(finish, 13), be_const_var(3) }, - { be_const_key_weak(last_counter, 6), be_const_var(5) }, - { be_const_key_weak(ack_received, 9), be_const_closure(Matter_IM_Message_ack_received_closure) }, + { be_const_key_weak(status_error_received, -1), be_const_closure(Matter_IM_Message_status_error_received_closure) }, + { be_const_key_weak(finish, -1), be_const_var(3) }, + { be_const_key_weak(status_ok_received, 2), be_const_closure(Matter_IM_Message_status_ok_received_closure) }, + { be_const_key_weak(last_counter, -1), be_const_var(5) }, { be_const_key_weak(reached_timeout, -1), be_const_closure(Matter_IM_Message_reached_timeout_closure) }, - { be_const_key_weak(status_error_received, 3), be_const_closure(Matter_IM_Message_status_error_received_closure) }, - { be_const_key_weak(ready, -1), be_const_var(2) }, + { be_const_key_weak(resp, -1), be_const_var(1) }, + { be_const_key_weak(data, -1), be_const_var(4) }, + { be_const_key_weak(expiration, -1), be_const_var(0) }, + { be_const_key_weak(ready, 6), be_const_var(2) }, + { be_const_key_weak(MSG_TIMEOUT, 5), be_const_int(5000) }, + { be_const_key_weak(ack_received, -1), be_const_closure(Matter_IM_Message_ack_received_closure) }, })), be_str_weak(Matter_IM_Message) ); @@ -529,7 +565,7 @@ extern const bclass be_class_Matter_IM_ReportData; ********************************************************************/ be_local_closure(Matter_IM_ReportData_send_im, /* name */ be_nested_proto( - 19, /* nstack */ + 12, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -537,151 +573,95 @@ be_local_closure(Matter_IM_ReportData_send_im, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[31]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(ready), - /* K2 */ be_nested_str_weak(resp), - /* K3 */ be_nested_str_weak(data), - /* K4 */ be_nested_str_weak(more_chunked_messages), - /* K5 */ be_const_int(1), - /* K6 */ be_nested_str_weak(attribute_reports), - /* K7 */ be_const_int(2147483647), - /* K8 */ be_const_int(0), - /* K9 */ be_nested_str_weak(tasmota), - /* K10 */ be_nested_str_weak(log), - /* K11 */ be_nested_str_weak(format), - /* K12 */ be_nested_str_weak(MTR_X3A_X20_X2ERead_Attr_X20next_chunk_X20exch_X3D_X25i), - /* K13 */ be_nested_str_weak(get_exchangeid), - /* K14 */ be_const_int(3), - /* K15 */ be_nested_str_weak(MTR_X3A_X20_X2ERead_Attr_X20first_chunk_X20exch_X3D_X25i), - /* K16 */ be_nested_str_weak(to_TLV), - /* K17 */ be_nested_str_weak(tlv2raw), - /* K18 */ be_nested_str_weak(MAX_MESSAGE), - /* K19 */ be_nested_str_weak(encode_frame), - /* K20 */ be_nested_str_weak(encrypt), - /* K21 */ be_nested_str_weak(MTR_X3A_X20_X3Csnd_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20id_X3D_X25i_X20exch_X3D_X25i_X20rack_X3D_X25s), - /* K22 */ be_nested_str_weak(session), - /* K23 */ be_nested_str_weak(local_session_id), - /* K24 */ be_nested_str_weak(message_counter), - /* K25 */ be_nested_str_weak(exchange_id), - /* K26 */ be_nested_str_weak(ack_message_counter), - /* K27 */ be_nested_str_weak(send_response_frame), - /* K28 */ be_nested_str_weak(last_counter), - /* K29 */ be_nested_str_weak(MTR_X3A_X20to_be_sent_later_X20size_X3D_X25i_X20exch_X3D_X25i), - /* K30 */ be_nested_str_weak(finish), + ( &(const bvalue[17]) { /* constants */ + /* K0 */ be_nested_str_weak(ready), + /* K1 */ be_nested_str_weak(resp), + /* K2 */ be_nested_str_weak(data), + /* K3 */ be_nested_str_weak(more_chunked_messages), + /* K4 */ be_const_int(1), + /* K5 */ be_nested_str_weak(attribute_reports), + /* K6 */ be_const_int(2147483647), + /* K7 */ be_const_int(0), + /* K8 */ be_nested_str_weak(to_TLV), + /* K9 */ be_nested_str_weak(tlv2raw), + /* K10 */ be_nested_str_weak(MAX_MESSAGE), + /* K11 */ be_nested_str_weak(encode_frame), + /* K12 */ be_nested_str_weak(encrypt), + /* K13 */ be_nested_str_weak(send_response_frame), + /* K14 */ be_nested_str_weak(last_counter), + /* K15 */ be_nested_str_weak(message_counter), + /* K16 */ be_nested_str_weak(finish), }), be_str_weak(send_im), &be_const_str_solidified, - ( &(const binstruction[109]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x880C0101, // 0001 GETMBR R3 R0 K1 - 0x740E0001, // 0002 JMPT R3 #0005 - 0x500C0000, // 0003 LDBOOL R3 0 0 - 0x80040600, // 0004 RET 1 R3 + ( &(const binstruction[67]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x740A0001, // 0001 JMPT R2 #0004 + 0x50080000, // 0002 LDBOOL R2 0 0 + 0x80040400, // 0003 RET 1 R2 + 0x88080101, // 0004 GETMBR R2 R0 K1 0x880C0102, // 0005 GETMBR R3 R0 K2 - 0x88100103, // 0006 GETMBR R4 R0 K3 - 0x88140904, // 0007 GETMBR R5 R4 K4 - 0x58180005, // 0008 LDCONST R6 K5 - 0x4C1C0000, // 0009 LDNIL R7 - 0x88200906, // 000A GETMBR R8 R4 K6 - 0x4C240000, // 000B LDNIL R9 - 0x20201009, // 000C NE R8 R8 R9 - 0x7822000D, // 000D JMPF R8 #001C - 0x40200D07, // 000E CONNECT R8 R6 K7 - 0x88240906, // 000F GETMBR R9 R4 K6 - 0x941C1208, // 0010 GETIDX R7 R9 R8 - 0x04280D05, // 0011 SUB R10 R6 K5 - 0x402A100A, // 0012 CONNECT R10 K8 R10 - 0x882C0906, // 0013 GETMBR R11 R4 K6 - 0x9428160A, // 0014 GETIDX R10 R11 R10 - 0x90120C0A, // 0015 SETMBR R4 K6 R10 - 0x6028000C, // 0016 GETGBL R10 G12 - 0x5C2C0E00, // 0017 MOVE R11 R7 - 0x7C280200, // 0018 CALL R10 1 - 0x24281508, // 0019 GT R10 R10 K8 - 0x9012080A, // 001A SETMBR R4 K4 R10 - 0x70020001, // 001B JMP #001E - 0x50200000, // 001C LDBOOL R8 0 0 - 0x90120808, // 001D SETMBR R4 K4 R8 - 0x78160008, // 001E JMPF R5 #0028 - 0xB8221200, // 001F GETNGBL R8 K9 - 0x8C20110A, // 0020 GETMET R8 R8 K10 - 0x8C28050B, // 0021 GETMET R10 R2 K11 - 0x5830000C, // 0022 LDCONST R12 K12 - 0x8C34010D, // 0023 GETMET R13 R0 K13 - 0x7C340200, // 0024 CALL R13 1 - 0x7C280600, // 0025 CALL R10 3 - 0x582C000E, // 0026 LDCONST R11 K14 - 0x7C200600, // 0027 CALL R8 3 - 0x88200904, // 0028 GETMBR R8 R4 K4 - 0x7822000A, // 0029 JMPF R8 #0035 - 0x5C200A00, // 002A MOVE R8 R5 - 0x74220008, // 002B JMPT R8 #0035 - 0xB8221200, // 002C GETNGBL R8 K9 - 0x8C20110A, // 002D GETMET R8 R8 K10 - 0x8C28050B, // 002E GETMET R10 R2 K11 - 0x5830000F, // 002F LDCONST R12 K15 - 0x8C34010D, // 0030 GETMET R13 R0 K13 - 0x7C340200, // 0031 CALL R13 1 - 0x7C280600, // 0032 CALL R10 3 - 0x582C000E, // 0033 LDCONST R11 K14 - 0x7C200600, // 0034 CALL R8 3 - 0x88200103, // 0035 GETMBR R8 R0 K3 - 0x8C201110, // 0036 GETMET R8 R8 K16 - 0x7C200200, // 0037 CALL R8 1 - 0x8C241111, // 0038 GETMET R9 R8 K17 - 0x602C0015, // 0039 GETGBL R11 G21 - 0x88300112, // 003A GETMBR R12 R0 K18 - 0x7C2C0200, // 003B CALL R11 1 - 0x7C240400, // 003C CALL R9 2 - 0x8C280713, // 003D GETMET R10 R3 K19 - 0x5C301200, // 003E MOVE R12 R9 - 0x7C280400, // 003F CALL R10 2 - 0x8C280714, // 0040 GETMET R10 R3 K20 - 0x7C280200, // 0041 CALL R10 1 - 0xB82A1200, // 0042 GETNGBL R10 K9 - 0x8C28150A, // 0043 GETMET R10 R10 K10 - 0x8C30050B, // 0044 GETMET R12 R2 K11 - 0x58380015, // 0045 LDCONST R14 K21 - 0x883C0716, // 0046 GETMBR R15 R3 K22 - 0x883C1F17, // 0047 GETMBR R15 R15 K23 - 0x88400718, // 0048 GETMBR R16 R3 K24 - 0x88440719, // 0049 GETMBR R17 R3 K25 - 0x8848071A, // 004A GETMBR R18 R3 K26 - 0x7C300C00, // 004B CALL R12 6 - 0x5834000E, // 004C LDCONST R13 K14 - 0x7C280600, // 004D CALL R10 3 - 0x8C28031B, // 004E GETMET R10 R1 K27 - 0x5C300600, // 004F MOVE R12 R3 - 0x7C280400, // 0050 CALL R10 2 - 0x88280718, // 0051 GETMBR R10 R3 K24 - 0x9002380A, // 0052 SETMBR R0 K28 R10 - 0x4C280000, // 0053 LDNIL R10 - 0x20280E0A, // 0054 NE R10 R7 R10 - 0x782A0013, // 0055 JMPF R10 #006A - 0x6028000C, // 0056 GETGBL R10 G12 - 0x5C2C0E00, // 0057 MOVE R11 R7 - 0x7C280200, // 0058 CALL R10 1 - 0x24281508, // 0059 GT R10 R10 K8 - 0x782A000E, // 005A JMPF R10 #006A - 0x90120C07, // 005B SETMBR R4 K6 R7 - 0xB82A1200, // 005C GETNGBL R10 K9 - 0x8C28150A, // 005D GETMET R10 R10 K10 - 0x8C30050B, // 005E GETMET R12 R2 K11 - 0x5838001D, // 005F LDCONST R14 K29 - 0x603C000C, // 0060 GETGBL R15 G12 - 0x88400906, // 0061 GETMBR R16 R4 K6 - 0x7C3C0200, // 0062 CALL R15 1 - 0x88400719, // 0063 GETMBR R16 R3 K25 - 0x7C300800, // 0064 CALL R12 4 - 0x5834000E, // 0065 LDCONST R13 K14 - 0x7C280600, // 0066 CALL R10 3 - 0x50280000, // 0067 LDBOOL R10 0 0 - 0x9002020A, // 0068 SETMBR R0 K1 R10 - 0x70020001, // 0069 JMP #006C - 0x50280200, // 006A LDBOOL R10 1 0 - 0x90023C0A, // 006B SETMBR R0 K30 R10 - 0x80000000, // 006C RET 0 + 0x88100703, // 0006 GETMBR R4 R3 K3 + 0x58140004, // 0007 LDCONST R5 K4 + 0x4C180000, // 0008 LDNIL R6 + 0x881C0705, // 0009 GETMBR R7 R3 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E000D, // 000C JMPF R7 #001B + 0x401C0B06, // 000D CONNECT R7 R5 K6 + 0x88200705, // 000E GETMBR R8 R3 K5 + 0x94181007, // 000F GETIDX R6 R8 R7 + 0x04240B04, // 0010 SUB R9 R5 K4 + 0x40260E09, // 0011 CONNECT R9 K7 R9 + 0x88280705, // 0012 GETMBR R10 R3 K5 + 0x94241409, // 0013 GETIDX R9 R10 R9 + 0x900E0A09, // 0014 SETMBR R3 K5 R9 + 0x6024000C, // 0015 GETGBL R9 G12 + 0x5C280C00, // 0016 MOVE R10 R6 + 0x7C240200, // 0017 CALL R9 1 + 0x24241307, // 0018 GT R9 R9 K7 + 0x900E0609, // 0019 SETMBR R3 K3 R9 + 0x70020001, // 001A JMP #001D + 0x501C0000, // 001B LDBOOL R7 0 0 + 0x900E0607, // 001C SETMBR R3 K3 R7 + 0x7811FFFF, // 001D JMPF R4 #001E + 0x881C0703, // 001E GETMBR R7 R3 K3 + 0x781E0001, // 001F JMPF R7 #0022 + 0x5C1C0800, // 0020 MOVE R7 R4 + 0x741DFFFF, // 0021 JMPT R7 #0022 + 0x881C0102, // 0022 GETMBR R7 R0 K2 + 0x8C1C0F08, // 0023 GETMET R7 R7 K8 + 0x7C1C0200, // 0024 CALL R7 1 + 0x8C200F09, // 0025 GETMET R8 R7 K9 + 0x60280015, // 0026 GETGBL R10 G21 + 0x882C010A, // 0027 GETMBR R11 R0 K10 + 0x7C280200, // 0028 CALL R10 1 + 0x7C200400, // 0029 CALL R8 2 + 0x8C24050B, // 002A GETMET R9 R2 K11 + 0x5C2C1000, // 002B MOVE R11 R8 + 0x7C240400, // 002C CALL R9 2 + 0x8C24050C, // 002D GETMET R9 R2 K12 + 0x7C240200, // 002E CALL R9 1 + 0x8C24030D, // 002F GETMET R9 R1 K13 + 0x5C2C0400, // 0030 MOVE R11 R2 + 0x7C240400, // 0031 CALL R9 2 + 0x8824050F, // 0032 GETMBR R9 R2 K15 + 0x90021C09, // 0033 SETMBR R0 K14 R9 + 0x4C240000, // 0034 LDNIL R9 + 0x20240C09, // 0035 NE R9 R6 R9 + 0x78260008, // 0036 JMPF R9 #0040 + 0x6024000C, // 0037 GETGBL R9 G12 + 0x5C280C00, // 0038 MOVE R10 R6 + 0x7C240200, // 0039 CALL R9 1 + 0x24241307, // 003A GT R9 R9 K7 + 0x78260003, // 003B JMPF R9 #0040 + 0x900E0A06, // 003C SETMBR R3 K5 R6 + 0x50240000, // 003D LDBOOL R9 0 0 + 0x90020009, // 003E SETMBR R0 K0 R9 + 0x70020001, // 003F JMP #0042 + 0x50240200, // 0040 LDBOOL R9 1 0 + 0x90022009, // 0041 SETMBR R0 K16 R9 + 0x80000000, // 0042 RET 0 }) ) ); @@ -803,7 +783,7 @@ be_local_closure(Matter_IM_ReportDataSubscribed_ack_received, /* name */ ********************************************************************/ be_local_closure(Matter_IM_ReportDataSubscribed_send_im, /* name */ be_nested_proto( - 12, /* nstack */ + 10, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -811,104 +791,106 @@ be_local_closure(Matter_IM_ReportDataSubscribed_send_im, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[23]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(ready), - /* K2 */ be_nested_str_weak(data), - /* K3 */ be_nested_str_weak(attribute_reports), - /* K4 */ be_const_int(0), - /* K5 */ be_nested_str_weak(report_data_phase), - /* K6 */ be_nested_str_weak(send_im), - /* K7 */ be_nested_str_weak(finish), - /* K8 */ be_nested_str_weak(resp), - /* K9 */ be_nested_str_weak(build_standalone_ack), - /* K10 */ be_nested_str_weak(encode_frame), - /* K11 */ be_nested_str_weak(encrypt), - /* K12 */ be_nested_str_weak(tasmota), + ( &(const bvalue[21]) { /* constants */ + /* K0 */ be_nested_str_weak(ready), + /* K1 */ be_nested_str_weak(data), + /* K2 */ be_nested_str_weak(attribute_reports), + /* K3 */ be_const_int(0), + /* K4 */ be_nested_str_weak(report_data_phase), + /* K5 */ be_nested_str_weak(send_im), + /* K6 */ be_nested_str_weak(finish), + /* K7 */ be_nested_str_weak(resp), + /* K8 */ be_nested_str_weak(build_standalone_ack), + /* K9 */ be_nested_str_weak(encode_frame), + /* K10 */ be_nested_str_weak(encrypt), + /* K11 */ be_nested_str_weak(tasmota), + /* K12 */ be_nested_str_weak(loglevel), /* K13 */ be_nested_str_weak(log), - /* K14 */ be_nested_str_weak(format), - /* K15 */ be_nested_str_weak(MTR_X3A_X20_X3CAck_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20ack_X3D_X25i_X20id_X3D_X25i), - /* K16 */ be_nested_str_weak(session), - /* K17 */ be_nested_str_weak(local_session_id), - /* K18 */ be_nested_str_weak(ack_message_counter), - /* K19 */ be_nested_str_weak(message_counter), - /* K20 */ be_const_int(3), - /* K21 */ be_nested_str_weak(send_response_frame), - /* K22 */ be_nested_str_weak(last_counter), + /* K14 */ be_nested_str_weak(MTR_X3A_X20_X3CAck_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20ack_X3D_X25i_X20id_X3D_X25i), + /* K15 */ be_nested_str_weak(session), + /* K16 */ be_nested_str_weak(local_session_id), + /* K17 */ be_nested_str_weak(ack_message_counter), + /* K18 */ be_nested_str_weak(message_counter), + /* K19 */ be_nested_str_weak(send_response_frame), + /* K20 */ be_nested_str_weak(last_counter), }), be_str_weak(send_im), &be_const_str_solidified, - ( &(const binstruction[70]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x880C0101, // 0001 GETMBR R3 R0 K1 - 0x740E0001, // 0002 JMPT R3 #0005 - 0x500C0000, // 0003 LDBOOL R3 0 0 - 0x80040600, // 0004 RET 1 R3 - 0x600C000C, // 0005 GETGBL R3 G12 - 0x88100102, // 0006 GETMBR R4 R0 K2 - 0x88100903, // 0007 GETMBR R4 R4 K3 - 0x7C0C0200, // 0008 CALL R3 1 - 0x240C0704, // 0009 GT R3 R3 K4 - 0x780E002C, // 000A JMPF R3 #0038 - 0x880C0105, // 000B GETMBR R3 R0 K5 - 0x780E000F, // 000C JMPF R3 #001D - 0x600C0003, // 000D GETGBL R3 G3 - 0x5C100000, // 000E MOVE R4 R0 - 0x7C0C0200, // 000F CALL R3 1 - 0x8C0C0706, // 0010 GETMET R3 R3 K6 - 0x5C140200, // 0011 MOVE R5 R1 - 0x7C0C0400, // 0012 CALL R3 2 - 0x880C0107, // 0013 GETMBR R3 R0 K7 - 0x740E0000, // 0014 JMPT R3 #0016 - 0x80000600, // 0015 RET 0 - 0x500C0000, // 0016 LDBOOL R3 0 0 - 0x90020A03, // 0017 SETMBR R0 K5 R3 - 0x500C0000, // 0018 LDBOOL R3 0 0 - 0x90020203, // 0019 SETMBR R0 K1 R3 - 0x500C0000, // 001A LDBOOL R3 0 0 - 0x90020E03, // 001B SETMBR R0 K7 R3 - 0x70020019, // 001C JMP #0037 - 0x880C0108, // 001D GETMBR R3 R0 K8 - 0x8C0C0709, // 001E GETMET R3 R3 K9 - 0x50140000, // 001F LDBOOL R5 0 0 - 0x7C0C0400, // 0020 CALL R3 2 - 0x8C10070A, // 0021 GETMET R4 R3 K10 - 0x7C100200, // 0022 CALL R4 1 - 0x8C10070B, // 0023 GETMET R4 R3 K11 - 0x7C100200, // 0024 CALL R4 1 - 0xB8121800, // 0025 GETNGBL R4 K12 - 0x8C10090D, // 0026 GETMET R4 R4 K13 - 0x8C18050E, // 0027 GETMET R6 R2 K14 - 0x5820000F, // 0028 LDCONST R8 K15 - 0x88240710, // 0029 GETMBR R9 R3 K16 - 0x88241311, // 002A GETMBR R9 R9 K17 - 0x88280712, // 002B GETMBR R10 R3 K18 - 0x882C0713, // 002C GETMBR R11 R3 K19 - 0x7C180A00, // 002D CALL R6 5 - 0x581C0014, // 002E LDCONST R7 K20 - 0x7C100600, // 002F CALL R4 3 - 0x8C100315, // 0030 GETMET R4 R1 K21 - 0x5C180600, // 0031 MOVE R6 R3 - 0x7C100400, // 0032 CALL R4 2 - 0x88100713, // 0033 GETMBR R4 R3 K19 - 0x90022C04, // 0034 SETMBR R0 K22 R4 - 0x50100200, // 0035 LDBOOL R4 1 0 - 0x90020E04, // 0036 SETMBR R0 K7 R4 - 0x7002000C, // 0037 JMP #0045 - 0x880C0105, // 0038 GETMBR R3 R0 K5 - 0x780E0008, // 0039 JMPF R3 #0043 - 0x600C0003, // 003A GETGBL R3 G3 - 0x5C100000, // 003B MOVE R4 R0 - 0x7C0C0200, // 003C CALL R3 1 - 0x8C0C0706, // 003D GETMET R3 R3 K6 - 0x5C140200, // 003E MOVE R5 R1 - 0x7C0C0400, // 003F CALL R3 2 - 0x500C0000, // 0040 LDBOOL R3 0 0 - 0x90020A03, // 0041 SETMBR R0 K5 R3 - 0x70020001, // 0042 JMP #0045 - 0x500C0200, // 0043 LDBOOL R3 1 0 - 0x90020E03, // 0044 SETMBR R0 K7 R3 - 0x80000000, // 0045 RET 0 + ( &(const binstruction[74]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x740A0001, // 0001 JMPT R2 #0004 + 0x50080000, // 0002 LDBOOL R2 0 0 + 0x80040400, // 0003 RET 1 R2 + 0x6008000C, // 0004 GETGBL R2 G12 + 0x880C0101, // 0005 GETMBR R3 R0 K1 + 0x880C0702, // 0006 GETMBR R3 R3 K2 + 0x7C080200, // 0007 CALL R2 1 + 0x24080503, // 0008 GT R2 R2 K3 + 0x780A0031, // 0009 JMPF R2 #003C + 0x88080104, // 000A GETMBR R2 R0 K4 + 0x780A000F, // 000B JMPF R2 #001C + 0x60080003, // 000C GETGBL R2 G3 + 0x5C0C0000, // 000D MOVE R3 R0 + 0x7C080200, // 000E CALL R2 1 + 0x8C080505, // 000F GETMET R2 R2 K5 + 0x5C100200, // 0010 MOVE R4 R1 + 0x7C080400, // 0011 CALL R2 2 + 0x88080106, // 0012 GETMBR R2 R0 K6 + 0x740A0000, // 0013 JMPT R2 #0015 + 0x80000400, // 0014 RET 0 + 0x50080000, // 0015 LDBOOL R2 0 0 + 0x90020802, // 0016 SETMBR R0 K4 R2 + 0x50080000, // 0017 LDBOOL R2 0 0 + 0x90020002, // 0018 SETMBR R0 K0 R2 + 0x50080000, // 0019 LDBOOL R2 0 0 + 0x90020C02, // 001A SETMBR R0 K6 R2 + 0x7002001E, // 001B JMP #003B + 0x88080107, // 001C GETMBR R2 R0 K7 + 0x8C080508, // 001D GETMET R2 R2 K8 + 0x50100000, // 001E LDBOOL R4 0 0 + 0x7C080400, // 001F CALL R2 2 + 0x8C0C0509, // 0020 GETMET R3 R2 K9 + 0x7C0C0200, // 0021 CALL R3 1 + 0x8C0C050A, // 0022 GETMET R3 R2 K10 + 0x7C0C0200, // 0023 CALL R3 1 + 0xB80E1600, // 0024 GETNGBL R3 K11 + 0x8C0C070C, // 0025 GETMET R3 R3 K12 + 0x54160003, // 0026 LDINT R5 4 + 0x7C0C0400, // 0027 CALL R3 2 + 0x780E000A, // 0028 JMPF R3 #0034 + 0xB80E1600, // 0029 GETNGBL R3 K11 + 0x8C0C070D, // 002A GETMET R3 R3 K13 + 0x60140018, // 002B GETGBL R5 G24 + 0x5818000E, // 002C LDCONST R6 K14 + 0x881C050F, // 002D GETMBR R7 R2 K15 + 0x881C0F10, // 002E GETMBR R7 R7 K16 + 0x88200511, // 002F GETMBR R8 R2 K17 + 0x88240512, // 0030 GETMBR R9 R2 K18 + 0x7C140800, // 0031 CALL R5 4 + 0x541A0003, // 0032 LDINT R6 4 + 0x7C0C0600, // 0033 CALL R3 3 + 0x8C0C0313, // 0034 GETMET R3 R1 K19 + 0x5C140400, // 0035 MOVE R5 R2 + 0x7C0C0400, // 0036 CALL R3 2 + 0x880C0512, // 0037 GETMBR R3 R2 K18 + 0x90022803, // 0038 SETMBR R0 K20 R3 + 0x500C0200, // 0039 LDBOOL R3 1 0 + 0x90020C03, // 003A SETMBR R0 K6 R3 + 0x7002000C, // 003B JMP #0049 + 0x88080104, // 003C GETMBR R2 R0 K4 + 0x780A0008, // 003D JMPF R2 #0047 + 0x60080003, // 003E GETGBL R2 G3 + 0x5C0C0000, // 003F MOVE R3 R0 + 0x7C080200, // 0040 CALL R2 1 + 0x8C080505, // 0041 GETMET R2 R2 K5 + 0x5C100200, // 0042 MOVE R4 R1 + 0x7C080400, // 0043 CALL R2 2 + 0x50080000, // 0044 LDBOOL R2 0 0 + 0x90020802, // 0045 SETMBR R0 K4 R2 + 0x70020001, // 0046 JMP #0049 + 0x50080200, // 0047 LDBOOL R2 1 0 + 0x90020C02, // 0048 SETMBR R0 K6 R2 + 0x80000000, // 0049 RET 0 }) ) ); @@ -1401,7 +1383,7 @@ be_local_closure(Matter_IM_SubscribeResponse_init, /* name */ ********************************************************************/ be_local_closure(Matter_IM_SubscribeResponse_status_ok_received, /* name */ be_nested_proto( - 10, /* nstack */ + 8, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1409,41 +1391,44 @@ be_local_closure(Matter_IM_SubscribeResponse_status_ok_received, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(log), - /* K3 */ be_nested_str_weak(format), + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(loglevel), + /* K2 */ be_const_int(3), + /* K3 */ be_nested_str_weak(log), /* K4 */ be_nested_str_weak(MTR_X3A_X20_X3ESub_OK_X20_X20_X20_X20_X28_X256i_X29_X20sub_X3D_X25i), /* K5 */ be_nested_str_weak(session), /* K6 */ be_nested_str_weak(local_session_id), /* K7 */ be_nested_str_weak(sub), /* K8 */ be_nested_str_weak(subscription_id), - /* K9 */ be_const_int(2), - /* K10 */ be_nested_str_weak(status_ok_received), + /* K9 */ be_nested_str_weak(status_ok_received), }), be_str_weak(status_ok_received), &be_const_str_solidified, - ( &(const binstruction[19]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0xB80E0200, // 0001 GETNGBL R3 K1 - 0x8C0C0702, // 0002 GETMET R3 R3 K2 - 0x8C140503, // 0003 GETMET R5 R2 K3 - 0x581C0004, // 0004 LDCONST R7 K4 - 0x88200305, // 0005 GETMBR R8 R1 K5 - 0x88201106, // 0006 GETMBR R8 R8 K6 - 0x88240107, // 0007 GETMBR R9 R0 K7 - 0x88241308, // 0008 GETMBR R9 R9 K8 - 0x7C140800, // 0009 CALL R5 4 - 0x58180009, // 000A LDCONST R6 K9 - 0x7C0C0600, // 000B CALL R3 3 - 0x600C0003, // 000C GETGBL R3 G3 - 0x5C100000, // 000D MOVE R4 R0 - 0x7C0C0200, // 000E CALL R3 1 - 0x8C0C070A, // 000F GETMET R3 R3 K10 - 0x5C140200, // 0010 MOVE R5 R1 - 0x7C0C0400, // 0011 CALL R3 2 - 0x80040600, // 0012 RET 1 R3 + ( &(const binstruction[23]) { /* code */ + 0xB80A0000, // 0000 GETNGBL R2 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x58100002, // 0002 LDCONST R4 K2 + 0x7C080400, // 0003 CALL R2 2 + 0x780A000A, // 0004 JMPF R2 #0010 + 0xB80A0000, // 0005 GETNGBL R2 K0 + 0x8C080503, // 0006 GETMET R2 R2 K3 + 0x60100018, // 0007 GETGBL R4 G24 + 0x58140004, // 0008 LDCONST R5 K4 + 0x88180305, // 0009 GETMBR R6 R1 K5 + 0x88180D06, // 000A GETMBR R6 R6 K6 + 0x881C0107, // 000B GETMBR R7 R0 K7 + 0x881C0F08, // 000C GETMBR R7 R7 K8 + 0x7C100600, // 000D CALL R4 3 + 0x58140002, // 000E LDCONST R5 K2 + 0x7C080600, // 000F CALL R2 3 + 0x60080003, // 0010 GETGBL R2 G3 + 0x5C0C0000, // 0011 MOVE R3 R0 + 0x7C080200, // 0012 CALL R2 1 + 0x8C080509, // 0013 GETMET R2 R2 K9 + 0x5C100200, // 0014 MOVE R4 R1 + 0x7C080400, // 0015 CALL R2 2 + 0x80040400, // 0016 RET 1 R2 }) ) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Subscription.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Subscription.h index e2f48b099501..63b370196c75 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Subscription.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_IM_Subscription.h @@ -190,7 +190,7 @@ be_local_closure(Matter_IM_Subscription_remove_self, /* name */ /* K1 */ be_nested_str_weak(log), /* K2 */ be_nested_str_weak(MTR_X3A_X20_X2DSub_Del_X20_X20_X20_X28_X20_X20_X20_X20_X20_X20_X29_X20sub_X3D), /* K3 */ be_nested_str_weak(subscription_id), - /* K4 */ be_const_int(2), + /* K4 */ be_const_int(3), /* K5 */ be_nested_str_weak(subs_shop), /* K6 */ be_nested_str_weak(remove_sub), }), @@ -323,7 +323,7 @@ be_local_closure(Matter_IM_Subscription_attribute_updated_ctx, /* name */ ********************************************************************/ be_local_closure(Matter_IM_Subscription_re_arm, /* name */ be_nested_proto( - 9, /* nstack */ + 7, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -331,57 +331,54 @@ be_local_closure(Matter_IM_Subscription_re_arm, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[16]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(wait_status), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(millis), - /* K4 */ be_nested_str_weak(expiration), - /* K5 */ be_nested_str_weak(max_interval), - /* K6 */ be_nested_str_weak(MAX_INTERVAL_MARGIN), - /* K7 */ be_nested_str_weak(not_before), - /* K8 */ be_nested_str_weak(min_interval), - /* K9 */ be_const_int(1), - /* K10 */ be_nested_str_weak(is_keep_alive), - /* K11 */ be_nested_str_weak(log), - /* K12 */ be_nested_str_weak(format), - /* K13 */ be_nested_str_weak(MTR_X3A_X20_X2ESub_Done_X20_X20_X28_X20_X20_X20_X20_X20_X20_X29_X20sub_X3D_X25i), - /* K14 */ be_nested_str_weak(subscription_id), - /* K15 */ be_const_int(2), + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(wait_status), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(millis), + /* K3 */ be_nested_str_weak(expiration), + /* K4 */ be_nested_str_weak(max_interval), + /* K5 */ be_nested_str_weak(MAX_INTERVAL_MARGIN), + /* K6 */ be_nested_str_weak(not_before), + /* K7 */ be_nested_str_weak(min_interval), + /* K8 */ be_const_int(1), + /* K9 */ be_nested_str_weak(is_keep_alive), + /* K10 */ be_nested_str_weak(log), + /* K11 */ be_nested_str_weak(MTR_X3A_X20_X2ESub_Done_X20_X20_X28_X20_X20_X20_X20_X20_X20_X29_X20sub_X3D_X25i), + /* K12 */ be_nested_str_weak(subscription_id), + /* K13 */ be_const_int(3), }), be_str_weak(re_arm), &be_const_str_solidified, - ( &(const binstruction[30]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x50080000, // 0001 LDBOOL R2 0 0 - 0x90020202, // 0002 SETMBR R0 K1 R2 - 0xB80A0400, // 0003 GETNGBL R2 K2 - 0x8C080503, // 0004 GETMET R2 R2 K3 - 0x7C080200, // 0005 CALL R2 1 + ( &(const binstruction[29]) { /* code */ + 0x50040000, // 0000 LDBOOL R1 0 0 + 0x90020001, // 0001 SETMBR R0 K0 R1 + 0xB8060200, // 0002 GETNGBL R1 K1 + 0x8C040302, // 0003 GETMET R1 R1 K2 + 0x7C040200, // 0004 CALL R1 1 + 0x88080104, // 0005 GETMBR R2 R0 K4 0x880C0105, // 0006 GETMBR R3 R0 K5 - 0x88100106, // 0007 GETMBR R4 R0 K6 - 0x040C0604, // 0008 SUB R3 R3 R4 - 0x541203E7, // 0009 LDINT R4 1000 - 0x080C0604, // 000A MUL R3 R3 R4 - 0x000C0403, // 000B ADD R3 R2 R3 - 0x90020803, // 000C SETMBR R0 K4 R3 - 0x880C0108, // 000D GETMBR R3 R0 K8 - 0x541203E7, // 000E LDINT R4 1000 - 0x080C0604, // 000F MUL R3 R3 R4 - 0x000C0403, // 0010 ADD R3 R2 R3 - 0x040C0709, // 0011 SUB R3 R3 K9 - 0x90020E03, // 0012 SETMBR R0 K7 R3 - 0x880C010A, // 0013 GETMBR R3 R0 K10 - 0x740E0007, // 0014 JMPT R3 #001D - 0xB80E0400, // 0015 GETNGBL R3 K2 - 0x8C0C070B, // 0016 GETMET R3 R3 K11 - 0x8C14030C, // 0017 GETMET R5 R1 K12 - 0x581C000D, // 0018 LDCONST R7 K13 - 0x8820010E, // 0019 GETMBR R8 R0 K14 - 0x7C140600, // 001A CALL R5 3 - 0x5818000F, // 001B LDCONST R6 K15 - 0x7C0C0600, // 001C CALL R3 3 - 0x80000000, // 001D RET 0 + 0x04080403, // 0007 SUB R2 R2 R3 + 0x540E03E7, // 0008 LDINT R3 1000 + 0x08080403, // 0009 MUL R2 R2 R3 + 0x00080202, // 000A ADD R2 R1 R2 + 0x90020602, // 000B SETMBR R0 K3 R2 + 0x88080107, // 000C GETMBR R2 R0 K7 + 0x540E03E7, // 000D LDINT R3 1000 + 0x08080403, // 000E MUL R2 R2 R3 + 0x00080202, // 000F ADD R2 R1 R2 + 0x04080508, // 0010 SUB R2 R2 K8 + 0x90020C02, // 0011 SETMBR R0 K6 R2 + 0x88080109, // 0012 GETMBR R2 R0 K9 + 0x740A0007, // 0013 JMPT R2 #001C + 0xB80A0200, // 0014 GETNGBL R2 K1 + 0x8C08050A, // 0015 GETMET R2 R2 K10 + 0x60100018, // 0016 GETGBL R4 G24 + 0x5814000B, // 0017 LDCONST R5 K11 + 0x8818010C, // 0018 GETMBR R6 R0 K12 + 0x7C100400, // 0019 CALL R4 2 + 0x5814000D, // 001A LDCONST R5 K13 + 0x7C080600, // 001B CALL R2 3 + 0x80000000, // 001C RET 0 }) ) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Message.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Message.h index 55aa4510bd16..08f9cf707057 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Message.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Message.h @@ -12,16 +12,16 @@ extern const bclass be_class_Matter_Frame; be_local_closure(Matter_Frame_encode_frame, /* name */ be_nested_proto( 7, /* nstack */ - 2, /* argc */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[30]) { /* constants */ - /* K0 */ be_nested_str_weak(flags), - /* K1 */ be_const_int(0), + ( &(const bvalue[29]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(flags), /* K2 */ be_nested_str_weak(flag_s), /* K3 */ be_nested_str_weak(flag_dsiz), /* K4 */ be_const_int(3), @@ -48,158 +48,166 @@ be_local_closure(Matter_Frame_encode_frame, /* name */ /* K25 */ be_nested_str_weak(protocol_id), /* K26 */ be_nested_str_weak(ack_message_counter), /* K27 */ be_nested_str_weak(app_payload_idx), - /* K28 */ be_nested_str_weak(debug), - /* K29 */ be_nested_str_weak(raw), + /* K28 */ be_nested_str_weak(raw), }), be_str_weak(encode_frame), &be_const_str_solidified, - ( &(const binstruction[146]) { /* code */ - 0x60080015, // 0000 GETGBL R2 G21 - 0x7C080000, // 0001 CALL R2 0 - 0x880C0100, // 0002 GETMBR R3 R0 K0 - 0x4C100000, // 0003 LDNIL R4 - 0x1C0C0604, // 0004 EQ R3 R3 R4 - 0x780E000D, // 0005 JMPF R3 #0014 - 0x90020101, // 0006 SETMBR R0 K0 K1 - 0x880C0102, // 0007 GETMBR R3 R0 K2 - 0x780E0003, // 0008 JMPF R3 #000D - 0x880C0100, // 0009 GETMBR R3 R0 K0 - 0x54120003, // 000A LDINT R4 4 - 0x300C0604, // 000B OR R3 R3 R4 - 0x90020003, // 000C SETMBR R0 K0 R3 - 0x880C0103, // 000D GETMBR R3 R0 K3 - 0x780E0004, // 000E JMPF R3 #0014 - 0x880C0100, // 000F GETMBR R3 R0 K0 - 0x88100103, // 0010 GETMBR R4 R0 K3 - 0x2C100904, // 0011 AND R4 R4 K4 - 0x300C0604, // 0012 OR R3 R3 R4 - 0x90020003, // 0013 SETMBR R0 K0 R3 - 0x8C0C0505, // 0014 GETMET R3 R2 K5 - 0x88140100, // 0015 GETMBR R5 R0 K0 - 0x58180006, // 0016 LDCONST R6 K6 - 0x7C0C0600, // 0017 CALL R3 3 - 0x8C0C0505, // 0018 GETMET R3 R2 K5 - 0x88140107, // 0019 GETMBR R5 R0 K7 - 0x78160001, // 001A JMPF R5 #001D - 0x88140107, // 001B GETMBR R5 R0 K7 - 0x70020000, // 001C JMP #001E - 0x58140001, // 001D LDCONST R5 K1 - 0x58180008, // 001E LDCONST R6 K8 - 0x7C0C0600, // 001F CALL R3 3 - 0x880C0109, // 0020 GETMBR R3 R0 K9 - 0x4C100000, // 0021 LDNIL R4 - 0x1C0C0604, // 0022 EQ R3 R3 R4 - 0x780E0013, // 0023 JMPF R3 #0038 - 0x90021301, // 0024 SETMBR R0 K9 K1 - 0x880C010A, // 0025 GETMBR R3 R0 K10 - 0x780E0003, // 0026 JMPF R3 #002B - 0x880C0109, // 0027 GETMBR R3 R0 K9 - 0x5412007F, // 0028 LDINT R4 128 - 0x300C0604, // 0029 OR R3 R3 R4 - 0x90021203, // 002A SETMBR R0 K9 R3 - 0x880C010B, // 002B GETMBR R3 R0 K11 - 0x780E0003, // 002C JMPF R3 #0031 - 0x880C0109, // 002D GETMBR R3 R0 K9 - 0x5412003F, // 002E LDINT R4 64 - 0x300C0604, // 002F OR R3 R3 R4 - 0x90021203, // 0030 SETMBR R0 K9 R3 - 0x880C010C, // 0031 GETMBR R3 R0 K12 - 0x780E0004, // 0032 JMPF R3 #0038 + ( &(const binstruction[155]) { /* code */ + 0x4C0C0000, // 0000 LDNIL R3 + 0x1C0C0403, // 0001 EQ R3 R2 R3 + 0x780E000A, // 0002 JMPF R3 #000E + 0x600C0015, // 0003 GETGBL R3 G21 + 0x5412000F, // 0004 LDINT R4 16 + 0x78060003, // 0005 JMPF R1 #000A + 0x6014000C, // 0006 GETGBL R5 G12 + 0x5C180200, // 0007 MOVE R6 R1 + 0x7C140200, // 0008 CALL R5 1 + 0x70020000, // 0009 JMP #000B + 0x58140000, // 000A LDCONST R5 K0 + 0x00100805, // 000B ADD R4 R4 R5 + 0x7C0C0200, // 000C CALL R3 1 + 0x5C080600, // 000D MOVE R2 R3 + 0x880C0101, // 000E GETMBR R3 R0 K1 + 0x4C100000, // 000F LDNIL R4 + 0x1C0C0604, // 0010 EQ R3 R3 R4 + 0x780E000D, // 0011 JMPF R3 #0020 + 0x90020300, // 0012 SETMBR R0 K1 K0 + 0x880C0102, // 0013 GETMBR R3 R0 K2 + 0x780E0003, // 0014 JMPF R3 #0019 + 0x880C0101, // 0015 GETMBR R3 R0 K1 + 0x54120003, // 0016 LDINT R4 4 + 0x300C0604, // 0017 OR R3 R3 R4 + 0x90020203, // 0018 SETMBR R0 K1 R3 + 0x880C0103, // 0019 GETMBR R3 R0 K3 + 0x780E0004, // 001A JMPF R3 #0020 + 0x880C0101, // 001B GETMBR R3 R0 K1 + 0x88100103, // 001C GETMBR R4 R0 K3 + 0x2C100904, // 001D AND R4 R4 K4 + 0x300C0604, // 001E OR R3 R3 R4 + 0x90020203, // 001F SETMBR R0 K1 R3 + 0x8C0C0505, // 0020 GETMET R3 R2 K5 + 0x88140101, // 0021 GETMBR R5 R0 K1 + 0x58180006, // 0022 LDCONST R6 K6 + 0x7C0C0600, // 0023 CALL R3 3 + 0x8C0C0505, // 0024 GETMET R3 R2 K5 + 0x88140107, // 0025 GETMBR R5 R0 K7 + 0x78160001, // 0026 JMPF R5 #0029 + 0x88140107, // 0027 GETMBR R5 R0 K7 + 0x70020000, // 0028 JMP #002A + 0x58140000, // 0029 LDCONST R5 K0 + 0x58180008, // 002A LDCONST R6 K8 + 0x7C0C0600, // 002B CALL R3 3 + 0x880C0109, // 002C GETMBR R3 R0 K9 + 0x4C100000, // 002D LDNIL R4 + 0x1C0C0604, // 002E EQ R3 R3 R4 + 0x780E0013, // 002F JMPF R3 #0044 + 0x90021300, // 0030 SETMBR R0 K9 K0 + 0x880C010A, // 0031 GETMBR R3 R0 K10 + 0x780E0003, // 0032 JMPF R3 #0037 0x880C0109, // 0033 GETMBR R3 R0 K9 - 0x8810010C, // 0034 GETMBR R4 R0 K12 - 0x2C100904, // 0035 AND R4 R4 K4 - 0x300C0604, // 0036 OR R3 R3 R4 - 0x90021203, // 0037 SETMBR R0 K9 R3 - 0x8C0C0505, // 0038 GETMET R3 R2 K5 - 0x88140109, // 0039 GETMBR R5 R0 K9 - 0x58180006, // 003A LDCONST R6 K6 - 0x7C0C0600, // 003B CALL R3 3 - 0x8C0C0505, // 003C GETMET R3 R2 K5 - 0x8814010D, // 003D GETMBR R5 R0 K13 - 0x541A0003, // 003E LDINT R6 4 - 0x7C0C0600, // 003F CALL R3 3 - 0x880C0102, // 0040 GETMBR R3 R0 K2 - 0x780E0001, // 0041 JMPF R3 #0044 - 0x880C010E, // 0042 GETMBR R3 R0 K14 - 0x400C0403, // 0043 CONNECT R3 R2 R3 - 0x880C0103, // 0044 GETMBR R3 R0 K3 - 0x1C0C0706, // 0045 EQ R3 R3 K6 - 0x780E0001, // 0046 JMPF R3 #0049 - 0x880C010F, // 0047 GETMBR R3 R0 K15 - 0x400C0403, // 0048 CONNECT R3 R2 R3 - 0x880C0103, // 0049 GETMBR R3 R0 K3 - 0x1C0C0708, // 004A EQ R3 R3 K8 - 0x780E0003, // 004B JMPF R3 #0050 - 0x8C0C0505, // 004C GETMET R3 R2 K5 - 0x88140110, // 004D GETMBR R5 R0 K16 - 0x58180008, // 004E LDCONST R6 K8 - 0x7C0C0600, // 004F CALL R3 3 - 0x600C000C, // 0050 GETGBL R3 G12 - 0x5C100400, // 0051 MOVE R4 R2 - 0x7C0C0200, // 0052 CALL R3 1 - 0x90022203, // 0053 SETMBR R0 K17 R3 - 0x880C0112, // 0054 GETMBR R3 R0 K18 - 0x4C100000, // 0055 LDNIL R4 - 0x1C0C0604, // 0056 EQ R3 R3 R4 - 0x780E0016, // 0057 JMPF R3 #006F - 0x90022501, // 0058 SETMBR R0 K18 K1 - 0x880C0113, // 0059 GETMBR R3 R0 K19 - 0x780E0003, // 005A JMPF R3 #005F - 0x880C0112, // 005B GETMBR R3 R0 K18 - 0x5412000F, // 005C LDINT R4 16 - 0x300C0604, // 005D OR R3 R3 R4 - 0x90022403, // 005E SETMBR R0 K18 R3 - 0x880C0114, // 005F GETMBR R3 R0 K20 - 0x780E0003, // 0060 JMPF R3 #0065 - 0x880C0112, // 0061 GETMBR R3 R0 K18 - 0x54120003, // 0062 LDINT R4 4 - 0x300C0604, // 0063 OR R3 R3 R4 - 0x90022403, // 0064 SETMBR R0 K18 R3 - 0x880C0115, // 0065 GETMBR R3 R0 K21 - 0x780E0002, // 0066 JMPF R3 #006A + 0x5412007F, // 0034 LDINT R4 128 + 0x300C0604, // 0035 OR R3 R3 R4 + 0x90021203, // 0036 SETMBR R0 K9 R3 + 0x880C010B, // 0037 GETMBR R3 R0 K11 + 0x780E0003, // 0038 JMPF R3 #003D + 0x880C0109, // 0039 GETMBR R3 R0 K9 + 0x5412003F, // 003A LDINT R4 64 + 0x300C0604, // 003B OR R3 R3 R4 + 0x90021203, // 003C SETMBR R0 K9 R3 + 0x880C010C, // 003D GETMBR R3 R0 K12 + 0x780E0004, // 003E JMPF R3 #0044 + 0x880C0109, // 003F GETMBR R3 R0 K9 + 0x8810010C, // 0040 GETMBR R4 R0 K12 + 0x2C100904, // 0041 AND R4 R4 K4 + 0x300C0604, // 0042 OR R3 R3 R4 + 0x90021203, // 0043 SETMBR R0 K9 R3 + 0x8C0C0505, // 0044 GETMET R3 R2 K5 + 0x88140109, // 0045 GETMBR R5 R0 K9 + 0x58180006, // 0046 LDCONST R6 K6 + 0x7C0C0600, // 0047 CALL R3 3 + 0x8C0C0505, // 0048 GETMET R3 R2 K5 + 0x8814010D, // 0049 GETMBR R5 R0 K13 + 0x541A0003, // 004A LDINT R6 4 + 0x7C0C0600, // 004B CALL R3 3 + 0x880C0102, // 004C GETMBR R3 R0 K2 + 0x780E0001, // 004D JMPF R3 #0050 + 0x880C010E, // 004E GETMBR R3 R0 K14 + 0x400C0403, // 004F CONNECT R3 R2 R3 + 0x880C0103, // 0050 GETMBR R3 R0 K3 + 0x1C0C0706, // 0051 EQ R3 R3 K6 + 0x780E0001, // 0052 JMPF R3 #0055 + 0x880C010F, // 0053 GETMBR R3 R0 K15 + 0x400C0403, // 0054 CONNECT R3 R2 R3 + 0x880C0103, // 0055 GETMBR R3 R0 K3 + 0x1C0C0708, // 0056 EQ R3 R3 K8 + 0x780E0003, // 0057 JMPF R3 #005C + 0x8C0C0505, // 0058 GETMET R3 R2 K5 + 0x88140110, // 0059 GETMBR R5 R0 K16 + 0x58180008, // 005A LDCONST R6 K8 + 0x7C0C0600, // 005B CALL R3 3 + 0x600C000C, // 005C GETGBL R3 G12 + 0x5C100400, // 005D MOVE R4 R2 + 0x7C0C0200, // 005E CALL R3 1 + 0x90022203, // 005F SETMBR R0 K17 R3 + 0x880C0112, // 0060 GETMBR R3 R0 K18 + 0x4C100000, // 0061 LDNIL R4 + 0x1C0C0604, // 0062 EQ R3 R3 R4 + 0x780E0016, // 0063 JMPF R3 #007B + 0x90022500, // 0064 SETMBR R0 K18 K0 + 0x880C0113, // 0065 GETMBR R3 R0 K19 + 0x780E0003, // 0066 JMPF R3 #006B 0x880C0112, // 0067 GETMBR R3 R0 K18 - 0x300C0708, // 0068 OR R3 R3 K8 - 0x90022403, // 0069 SETMBR R0 K18 R3 - 0x880C0116, // 006A GETMBR R3 R0 K22 - 0x780E0002, // 006B JMPF R3 #006F - 0x880C0112, // 006C GETMBR R3 R0 K18 - 0x300C0706, // 006D OR R3 R3 K6 - 0x90022403, // 006E SETMBR R0 K18 R3 - 0x8C0C0505, // 006F GETMET R3 R2 K5 - 0x88140112, // 0070 GETMBR R5 R0 K18 - 0x58180006, // 0071 LDCONST R6 K6 - 0x7C0C0600, // 0072 CALL R3 3 - 0x8C0C0505, // 0073 GETMET R3 R2 K5 - 0x88140117, // 0074 GETMBR R5 R0 K23 - 0x58180006, // 0075 LDCONST R6 K6 - 0x7C0C0600, // 0076 CALL R3 3 - 0x8C0C0505, // 0077 GETMET R3 R2 K5 - 0x88140118, // 0078 GETMBR R5 R0 K24 - 0x541AFFFE, // 0079 LDINT R6 65535 - 0x2C140A06, // 007A AND R5 R5 R6 - 0x58180008, // 007B LDCONST R6 K8 - 0x7C0C0600, // 007C CALL R3 3 - 0x8C0C0505, // 007D GETMET R3 R2 K5 - 0x88140119, // 007E GETMBR R5 R0 K25 - 0x58180008, // 007F LDCONST R6 K8 - 0x7C0C0600, // 0080 CALL R3 3 - 0x880C0115, // 0081 GETMBR R3 R0 K21 - 0x780E0003, // 0082 JMPF R3 #0087 + 0x5412000F, // 0068 LDINT R4 16 + 0x300C0604, // 0069 OR R3 R3 R4 + 0x90022403, // 006A SETMBR R0 K18 R3 + 0x880C0114, // 006B GETMBR R3 R0 K20 + 0x780E0003, // 006C JMPF R3 #0071 + 0x880C0112, // 006D GETMBR R3 R0 K18 + 0x54120003, // 006E LDINT R4 4 + 0x300C0604, // 006F OR R3 R3 R4 + 0x90022403, // 0070 SETMBR R0 K18 R3 + 0x880C0115, // 0071 GETMBR R3 R0 K21 + 0x780E0002, // 0072 JMPF R3 #0076 + 0x880C0112, // 0073 GETMBR R3 R0 K18 + 0x300C0708, // 0074 OR R3 R3 K8 + 0x90022403, // 0075 SETMBR R0 K18 R3 + 0x880C0116, // 0076 GETMBR R3 R0 K22 + 0x780E0002, // 0077 JMPF R3 #007B + 0x880C0112, // 0078 GETMBR R3 R0 K18 + 0x300C0706, // 0079 OR R3 R3 K6 + 0x90022403, // 007A SETMBR R0 K18 R3 + 0x8C0C0505, // 007B GETMET R3 R2 K5 + 0x88140112, // 007C GETMBR R5 R0 K18 + 0x58180006, // 007D LDCONST R6 K6 + 0x7C0C0600, // 007E CALL R3 3 + 0x8C0C0505, // 007F GETMET R3 R2 K5 + 0x88140117, // 0080 GETMBR R5 R0 K23 + 0x58180006, // 0081 LDCONST R6 K6 + 0x7C0C0600, // 0082 CALL R3 3 0x8C0C0505, // 0083 GETMET R3 R2 K5 - 0x8814011A, // 0084 GETMBR R5 R0 K26 - 0x541A0003, // 0085 LDINT R6 4 - 0x7C0C0600, // 0086 CALL R3 3 - 0x600C000C, // 0087 GETGBL R3 G12 - 0x5C100400, // 0088 MOVE R4 R2 - 0x7C0C0200, // 0089 CALL R3 1 - 0x90023603, // 008A SETMBR R0 K27 R3 - 0x78060000, // 008B JMPF R1 #008D - 0x400C0401, // 008C CONNECT R3 R2 R1 - 0x8C0C011C, // 008D GETMET R3 R0 K28 - 0x5C140400, // 008E MOVE R5 R2 - 0x7C0C0400, // 008F CALL R3 2 - 0x90023A02, // 0090 SETMBR R0 K29 R2 - 0x80040400, // 0091 RET 1 R2 + 0x88140118, // 0084 GETMBR R5 R0 K24 + 0x541AFFFE, // 0085 LDINT R6 65535 + 0x2C140A06, // 0086 AND R5 R5 R6 + 0x58180008, // 0087 LDCONST R6 K8 + 0x7C0C0600, // 0088 CALL R3 3 + 0x8C0C0505, // 0089 GETMET R3 R2 K5 + 0x88140119, // 008A GETMBR R5 R0 K25 + 0x58180008, // 008B LDCONST R6 K8 + 0x7C0C0600, // 008C CALL R3 3 + 0x880C0115, // 008D GETMBR R3 R0 K21 + 0x780E0003, // 008E JMPF R3 #0093 + 0x8C0C0505, // 008F GETMET R3 R2 K5 + 0x8814011A, // 0090 GETMBR R5 R0 K26 + 0x541A0003, // 0091 LDINT R6 4 + 0x7C0C0600, // 0092 CALL R3 3 + 0x600C000C, // 0093 GETGBL R3 G12 + 0x5C100400, // 0094 MOVE R4 R2 + 0x7C0C0200, // 0095 CALL R3 1 + 0x90023603, // 0096 SETMBR R0 K27 R3 + 0x78060000, // 0097 JMPF R1 #0099 + 0x400C0401, // 0098 CONNECT R3 R2 R1 + 0x90023802, // 0099 SETMBR R0 K28 R2 + 0x80040400, // 009A RET 1 R2 }) ) ); @@ -211,7 +219,7 @@ be_local_closure(Matter_Frame_encode_frame, /* name */ ********************************************************************/ be_local_closure(Matter_Frame_encrypt, /* name */ be_nested_proto( - 15, /* nstack */ + 23, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -219,85 +227,92 @@ be_local_closure(Matter_Frame_encrypt, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[17]) { /* constants */ + ( &(const bvalue[18]) { /* constants */ /* K0 */ be_nested_str_weak(crypto), /* K1 */ be_nested_str_weak(raw), /* K2 */ be_nested_str_weak(session), - /* K3 */ be_nested_str_weak(get_r2i), - /* K4 */ be_const_int(0), - /* K5 */ be_nested_str_weak(payload_idx), - /* K6 */ be_const_int(1), - /* K7 */ be_const_int(2147483647), + /* K3 */ be_nested_str_weak(payload_idx), + /* K4 */ be_nested_str_weak(get_r2i), + /* K5 */ be_nested_str_weak(message_handler), + /* K6 */ be_nested_str_weak(_n_bytes), + /* K7 */ be_nested_str_weak(clear), /* K8 */ be_nested_str_weak(add), /* K9 */ be_nested_str_weak(flags), - /* K10 */ be_nested_str_weak(message_counter), - /* K11 */ be_nested_str_weak(is_CASE), - /* K12 */ be_nested_str_weak(get_device_id), - /* K13 */ be_nested_str_weak(resize), - /* K14 */ be_nested_str_weak(AES_CCM), - /* K15 */ be_nested_str_weak(encrypt), - /* K16 */ be_nested_str_weak(tag), + /* K10 */ be_const_int(1), + /* K11 */ be_nested_str_weak(message_counter), + /* K12 */ be_nested_str_weak(is_CASE), + /* K13 */ be_nested_str_weak(get_device_id), + /* K14 */ be_nested_str_weak(resize), + /* K15 */ be_nested_str_weak(AES_CCM), + /* K16 */ be_nested_str_weak(encrypt1), + /* K17 */ be_const_int(0), }), be_str_weak(encrypt), &be_const_str_solidified, - ( &(const binstruction[57]) { /* code */ + ( &(const binstruction[63]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 0x88080101, // 0001 GETMBR R2 R0 K1 0x880C0102, // 0002 GETMBR R3 R0 K2 - 0x8C100703, // 0003 GETMET R4 R3 K3 - 0x7C100200, // 0004 CALL R4 1 - 0x88140105, // 0005 GETMBR R5 R0 K5 - 0x04140B06, // 0006 SUB R5 R5 K6 - 0x40160805, // 0007 CONNECT R5 K4 R5 - 0x94140405, // 0008 GETIDX R5 R2 R5 - 0x88180105, // 0009 GETMBR R6 R0 K5 - 0x40180D07, // 000A CONNECT R6 R6 K7 - 0x94180406, // 000B GETIDX R6 R2 R6 - 0x601C0015, // 000C GETGBL R7 G21 - 0x7C1C0000, // 000D CALL R7 0 - 0x8C200F08, // 000E GETMET R8 R7 K8 - 0x88280109, // 000F GETMBR R10 R0 K9 - 0x582C0006, // 0010 LDCONST R11 K6 - 0x7C200600, // 0011 CALL R8 3 - 0x8C200F08, // 0012 GETMET R8 R7 K8 - 0x8828010A, // 0013 GETMBR R10 R0 K10 - 0x542E0003, // 0014 LDINT R11 4 - 0x7C200600, // 0015 CALL R8 3 - 0x8C20070B, // 0016 GETMET R8 R3 K11 + 0x88100103, // 0003 GETMBR R4 R0 K3 + 0x5416000F, // 0004 LDINT R5 16 + 0x8C180704, // 0005 GETMET R6 R3 K4 + 0x7C180200, // 0006 CALL R6 1 + 0x881C0105, // 0007 GETMBR R7 R0 K5 + 0x881C0F06, // 0008 GETMBR R7 R7 K6 + 0x8C200F07, // 0009 GETMET R8 R7 K7 + 0x7C200200, // 000A CALL R8 1 + 0x8C200F08, // 000B GETMET R8 R7 K8 + 0x88280109, // 000C GETMBR R10 R0 K9 + 0x582C000A, // 000D LDCONST R11 K10 + 0x7C200600, // 000E CALL R8 3 + 0x8C200F08, // 000F GETMET R8 R7 K8 + 0x8828010B, // 0010 GETMBR R10 R0 K11 + 0x542E0003, // 0011 LDINT R11 4 + 0x7C200600, // 0012 CALL R8 3 + 0x8C20070C, // 0013 GETMET R8 R3 K12 + 0x7C200200, // 0014 CALL R8 1 + 0x78220005, // 0015 JMPF R8 #001C + 0x8C20070D, // 0016 GETMET R8 R3 K13 0x7C200200, // 0017 CALL R8 1 - 0x78220005, // 0018 JMPF R8 #001F - 0x8C20070C, // 0019 GETMET R8 R3 K12 + 0x78220002, // 0018 JMPF R8 #001C + 0x8C20070D, // 0019 GETMET R8 R3 K13 0x7C200200, // 001A CALL R8 1 - 0x78220002, // 001B JMPF R8 #001F - 0x8C20070C, // 001C GETMET R8 R3 K12 - 0x7C200200, // 001D CALL R8 1 - 0x40200E08, // 001E CONNECT R8 R7 R8 - 0x8C200F0D, // 001F GETMET R8 R7 K13 - 0x542A000C, // 0020 LDINT R10 13 - 0x7C200400, // 0021 CALL R8 2 - 0x8C20030E, // 0022 GETMET R8 R1 K14 - 0x5C280800, // 0023 MOVE R10 R4 - 0x5C2C0E00, // 0024 MOVE R11 R7 - 0x5C300A00, // 0025 MOVE R12 R5 - 0x6034000C, // 0026 GETGBL R13 G12 - 0x5C380C00, // 0027 MOVE R14 R6 - 0x7C340200, // 0028 CALL R13 1 - 0x543A000F, // 0029 LDINT R14 16 - 0x7C200C00, // 002A CALL R8 6 - 0x8C24110F, // 002B GETMET R9 R8 K15 - 0x5C2C0C00, // 002C MOVE R11 R6 - 0x7C240400, // 002D CALL R9 2 - 0x8C281110, // 002E GETMET R10 R8 K16 - 0x7C280200, // 002F CALL R10 1 - 0x882C0101, // 0030 GETMBR R11 R0 K1 - 0x8C2C170D, // 0031 GETMET R11 R11 K13 - 0x88340105, // 0032 GETMBR R13 R0 K5 - 0x7C2C0400, // 0033 CALL R11 2 - 0x882C0101, // 0034 GETMBR R11 R0 K1 - 0x402C1609, // 0035 CONNECT R11 R11 R9 - 0x882C0101, // 0036 GETMBR R11 R0 K1 - 0x402C160A, // 0037 CONNECT R11 R11 R10 - 0x80000000, // 0038 RET 0 + 0x40200E08, // 001B CONNECT R8 R7 R8 + 0x8C200F0E, // 001C GETMET R8 R7 K14 + 0x542A000C, // 001D LDINT R10 13 + 0x7C200400, // 001E CALL R8 2 + 0x8C20050E, // 001F GETMET R8 R2 K14 + 0x6028000C, // 0020 GETGBL R10 G12 + 0x5C2C0400, // 0021 MOVE R11 R2 + 0x7C280200, // 0022 CALL R10 1 + 0x00281405, // 0023 ADD R10 R10 R5 + 0x7C200400, // 0024 CALL R8 2 + 0x8820030F, // 0025 GETMBR R8 R1 K15 + 0x8C201110, // 0026 GETMET R8 R8 K16 + 0x5C280C00, // 0027 MOVE R10 R6 + 0x5C2C0E00, // 0028 MOVE R11 R7 + 0x58300011, // 0029 LDCONST R12 K17 + 0x6034000C, // 002A GETGBL R13 G12 + 0x5C380E00, // 002B MOVE R14 R7 + 0x7C340200, // 002C CALL R13 1 + 0x5C380400, // 002D MOVE R14 R2 + 0x583C0011, // 002E LDCONST R15 K17 + 0x5C400800, // 002F MOVE R16 R4 + 0x5C440400, // 0030 MOVE R17 R2 + 0x5C480800, // 0031 MOVE R18 R4 + 0x604C000C, // 0032 GETGBL R19 G12 + 0x5C500400, // 0033 MOVE R20 R2 + 0x7C4C0200, // 0034 CALL R19 1 + 0x044C2604, // 0035 SUB R19 R19 R4 + 0x044C2605, // 0036 SUB R19 R19 R5 + 0x5C500400, // 0037 MOVE R20 R2 + 0x6054000C, // 0038 GETGBL R21 G12 + 0x5C580400, // 0039 MOVE R22 R2 + 0x7C540200, // 003A CALL R21 1 + 0x04542A05, // 003B SUB R21 R21 R5 + 0x5C580A00, // 003C MOVE R22 R5 + 0x7C201C00, // 003D CALL R8 14 + 0x80000000, // 003E RET 0 }) ) ); @@ -309,7 +324,7 @@ be_local_closure(Matter_Frame_encrypt, /* name */ ********************************************************************/ be_local_closure(Matter_Frame_debug, /* name */ be_nested_proto( - 8, /* nstack */ + 6, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -317,20 +332,16 @@ be_local_closure(Matter_Frame_debug, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 9]) { /* constants */ + ( &(const bvalue[ 5]) { /* constants */ /* K0 */ be_nested_str_weak(matter), /* K1 */ be_nested_str_weak(Frame), /* K2 */ be_nested_str_weak(message_handler), /* K3 */ be_nested_str_weak(decode_header), /* K4 */ be_nested_str_weak(decode_payload), - /* K5 */ be_nested_str_weak(tasmota), - /* K6 */ be_nested_str_weak(log), - /* K7 */ be_nested_str_weak(MTR_X3A_X20sending_X20decode_X3A_X20), - /* K8 */ be_nested_str_weak(inspect), }), be_str_weak(debug), &be_const_str_solidified, - ( &(const binstruction[19]) { /* code */ + ( &(const binstruction[10]) { /* code */ 0x80000400, // 0000 RET 0 0xB80A0000, // 0001 GETNGBL R2 K0 0x8C080501, // 0002 GETMET R2 R2 K1 @@ -341,15 +352,6 @@ be_local_closure(Matter_Frame_debug, /* name */ 0x7C0C0200, // 0007 CALL R3 1 0x8C0C0504, // 0008 GETMET R3 R2 K4 0x7C0C0200, // 0009 CALL R3 1 - 0xB80E0A00, // 000A GETNGBL R3 K5 - 0x8C0C0706, // 000B GETMET R3 R3 K6 - 0xB8160000, // 000C GETNGBL R5 K0 - 0x8C140B08, // 000D GETMET R5 R5 K8 - 0x5C1C0400, // 000E MOVE R7 R2 - 0x7C140400, // 000F CALL R5 2 - 0x00160E05, // 0010 ADD R5 K7 R5 - 0x541A0003, // 0011 LDINT R6 4 - 0x7C0C0600, // 0012 CALL R3 3 }) ) ); @@ -361,7 +363,7 @@ be_local_closure(Matter_Frame_debug, /* name */ ********************************************************************/ be_local_closure(Matter_Frame_build_standalone_ack, /* name */ be_nested_proto( - 6, /* nstack */ + 5, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -369,79 +371,77 @@ be_local_closure(Matter_Frame_build_standalone_ack, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[22]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(message_handler), - /* K2 */ be_nested_str_weak(remote_ip), - /* K3 */ be_nested_str_weak(remote_port), - /* K4 */ be_nested_str_weak(flag_s), - /* K5 */ be_nested_str_weak(flag_dsiz), - /* K6 */ be_const_int(1), - /* K7 */ be_nested_str_weak(dest_node_id_8), - /* K8 */ be_nested_str_weak(source_node_id), - /* K9 */ be_const_int(0), - /* K10 */ be_nested_str_weak(session), - /* K11 */ be_nested_str_weak(message_counter), - /* K12 */ be_nested_str_weak(counter_snd_next), - /* K13 */ be_nested_str_weak(local_session_id), - /* K14 */ be_nested_str_weak(initiator_session_id), - /* K15 */ be_nested_str_weak(x_flag_i), - /* K16 */ be_nested_str_weak(opcode), - /* K17 */ be_nested_str_weak(exchange_id), - /* K18 */ be_nested_str_weak(protocol_id), - /* K19 */ be_nested_str_weak(x_flag_a), - /* K20 */ be_nested_str_weak(ack_message_counter), - /* K21 */ be_nested_str_weak(x_flag_r), + ( &(const bvalue[21]) { /* constants */ + /* K0 */ be_nested_str_weak(message_handler), + /* K1 */ be_nested_str_weak(remote_ip), + /* K2 */ be_nested_str_weak(remote_port), + /* K3 */ be_nested_str_weak(flag_s), + /* K4 */ be_nested_str_weak(flag_dsiz), + /* K5 */ be_const_int(1), + /* K6 */ be_nested_str_weak(dest_node_id_8), + /* K7 */ be_nested_str_weak(source_node_id), + /* K8 */ be_const_int(0), + /* K9 */ be_nested_str_weak(session), + /* K10 */ be_nested_str_weak(message_counter), + /* K11 */ be_nested_str_weak(counter_snd_next), + /* K12 */ be_nested_str_weak(local_session_id), + /* K13 */ be_nested_str_weak(initiator_session_id), + /* K14 */ be_nested_str_weak(x_flag_i), + /* K15 */ be_nested_str_weak(opcode), + /* K16 */ be_nested_str_weak(exchange_id), + /* K17 */ be_nested_str_weak(protocol_id), + /* K18 */ be_nested_str_weak(x_flag_a), + /* K19 */ be_nested_str_weak(ack_message_counter), + /* K20 */ be_nested_str_weak(x_flag_r), }), be_str_weak(build_standalone_ack), &be_const_str_solidified, - ( &(const binstruction[46]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x600C0006, // 0001 GETGBL R3 G6 - 0x5C100000, // 0002 MOVE R4 R0 - 0x7C0C0200, // 0003 CALL R3 1 - 0x88100101, // 0004 GETMBR R4 R0 K1 - 0x7C0C0200, // 0005 CALL R3 1 - 0x88100102, // 0006 GETMBR R4 R0 K2 - 0x900E0404, // 0007 SETMBR R3 K2 R4 - 0x88100103, // 0008 GETMBR R4 R0 K3 - 0x900E0604, // 0009 SETMBR R3 K3 R4 - 0x88100104, // 000A GETMBR R4 R0 K4 - 0x78120003, // 000B JMPF R4 #0010 - 0x900E0B06, // 000C SETMBR R3 K5 K6 - 0x88100108, // 000D GETMBR R4 R0 K8 - 0x900E0E04, // 000E SETMBR R3 K7 R4 - 0x70020000, // 000F JMP #0011 - 0x900E0B09, // 0010 SETMBR R3 K5 K9 - 0x8810010A, // 0011 GETMBR R4 R0 K10 - 0x900E1404, // 0012 SETMBR R3 K10 R4 - 0x8810010A, // 0013 GETMBR R4 R0 K10 - 0x8C10090C, // 0014 GETMET R4 R4 K12 - 0x7C100200, // 0015 CALL R4 1 - 0x900E1604, // 0016 SETMBR R3 K11 R4 - 0x8810010A, // 0017 GETMBR R4 R0 K10 - 0x8810090E, // 0018 GETMBR R4 R4 K14 - 0x900E1A04, // 0019 SETMBR R3 K13 R4 - 0x8810010F, // 001A GETMBR R4 R0 K15 - 0x78120001, // 001B JMPF R4 #001E - 0x58100009, // 001C LDCONST R4 K9 - 0x70020000, // 001D JMP #001F - 0x58100006, // 001E LDCONST R4 K6 - 0x900E1E04, // 001F SETMBR R3 K15 R4 - 0x5412000F, // 0020 LDINT R4 16 - 0x900E2004, // 0021 SETMBR R3 K16 R4 - 0x88100111, // 0022 GETMBR R4 R0 K17 - 0x900E2204, // 0023 SETMBR R3 K17 R4 - 0x900E2509, // 0024 SETMBR R3 K18 K9 - 0x900E2706, // 0025 SETMBR R3 K19 K6 - 0x8810010B, // 0026 GETMBR R4 R0 K11 - 0x900E2804, // 0027 SETMBR R3 K20 R4 - 0x78060001, // 0028 JMPF R1 #002B - 0x58100006, // 0029 LDCONST R4 K6 - 0x70020000, // 002A JMP #002C - 0x58100009, // 002B LDCONST R4 K9 - 0x900E2A04, // 002C SETMBR R3 K21 R4 - 0x80040600, // 002D RET 1 R3 + ( &(const binstruction[45]) { /* code */ + 0x60080006, // 0000 GETGBL R2 G6 + 0x5C0C0000, // 0001 MOVE R3 R0 + 0x7C080200, // 0002 CALL R2 1 + 0x880C0100, // 0003 GETMBR R3 R0 K0 + 0x7C080200, // 0004 CALL R2 1 + 0x880C0101, // 0005 GETMBR R3 R0 K1 + 0x900A0203, // 0006 SETMBR R2 K1 R3 + 0x880C0102, // 0007 GETMBR R3 R0 K2 + 0x900A0403, // 0008 SETMBR R2 K2 R3 + 0x880C0103, // 0009 GETMBR R3 R0 K3 + 0x780E0003, // 000A JMPF R3 #000F + 0x900A0905, // 000B SETMBR R2 K4 K5 + 0x880C0107, // 000C GETMBR R3 R0 K7 + 0x900A0C03, // 000D SETMBR R2 K6 R3 + 0x70020000, // 000E JMP #0010 + 0x900A0908, // 000F SETMBR R2 K4 K8 + 0x880C0109, // 0010 GETMBR R3 R0 K9 + 0x900A1203, // 0011 SETMBR R2 K9 R3 + 0x880C0109, // 0012 GETMBR R3 R0 K9 + 0x8C0C070B, // 0013 GETMET R3 R3 K11 + 0x7C0C0200, // 0014 CALL R3 1 + 0x900A1403, // 0015 SETMBR R2 K10 R3 + 0x880C0109, // 0016 GETMBR R3 R0 K9 + 0x880C070D, // 0017 GETMBR R3 R3 K13 + 0x900A1803, // 0018 SETMBR R2 K12 R3 + 0x880C010E, // 0019 GETMBR R3 R0 K14 + 0x780E0001, // 001A JMPF R3 #001D + 0x580C0008, // 001B LDCONST R3 K8 + 0x70020000, // 001C JMP #001E + 0x580C0005, // 001D LDCONST R3 K5 + 0x900A1C03, // 001E SETMBR R2 K14 R3 + 0x540E000F, // 001F LDINT R3 16 + 0x900A1E03, // 0020 SETMBR R2 K15 R3 + 0x880C0110, // 0021 GETMBR R3 R0 K16 + 0x900A2003, // 0022 SETMBR R2 K16 R3 + 0x900A2308, // 0023 SETMBR R2 K17 K8 + 0x900A2505, // 0024 SETMBR R2 K18 K5 + 0x880C010A, // 0025 GETMBR R3 R0 K10 + 0x900A2603, // 0026 SETMBR R2 K19 R3 + 0x78060001, // 0027 JMPF R1 #002A + 0x580C0005, // 0028 LDCONST R3 K5 + 0x70020000, // 0029 JMP #002B + 0x580C0008, // 002A LDCONST R3 K8 + 0x900A2803, // 002B SETMBR R2 K20 R3 + 0x80040400, // 002C RET 1 R2 }) ) ); @@ -453,7 +453,7 @@ be_local_closure(Matter_Frame_build_standalone_ack, /* name */ ********************************************************************/ be_local_closure(Matter_Frame_build_response, /* name */ be_nested_proto( - 13, /* nstack */ + 11, /* nstack */ 4, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -461,135 +461,132 @@ be_local_closure(Matter_Frame_build_response, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[32]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(message_handler), - /* K2 */ be_nested_str_weak(remote_ip), - /* K3 */ be_nested_str_weak(remote_port), - /* K4 */ be_nested_str_weak(flag_s), - /* K5 */ be_nested_str_weak(flag_dsiz), - /* K6 */ be_const_int(1), - /* K7 */ be_nested_str_weak(dest_node_id_8), - /* K8 */ be_nested_str_weak(source_node_id), - /* K9 */ be_const_int(0), - /* K10 */ be_nested_str_weak(session), - /* K11 */ be_nested_str_weak(local_session_id), - /* K12 */ be_nested_str_weak(initiator_session_id), - /* K13 */ be_nested_str_weak(message_counter), - /* K14 */ be_nested_str_weak(counter_snd_next), - /* K15 */ be_nested_str_weak(_counter_insecure_snd), - /* K16 */ be_nested_str_weak(next), - /* K17 */ be_nested_str_weak(x_flag_i), - /* K18 */ be_nested_str_weak(opcode), - /* K19 */ be_nested_str_weak(exchange_id), - /* K20 */ be_nested_str_weak(protocol_id), - /* K21 */ be_nested_str_weak(x_flag_r), - /* K22 */ be_nested_str_weak(x_flag_a), - /* K23 */ be_nested_str_weak(ack_message_counter), - /* K24 */ be_nested_str_weak(matter), - /* K25 */ be_nested_str_weak(get_opcode_name), - /* K26 */ be_nested_str_weak(format), - /* K27 */ be_nested_str_weak(0x_X2502X), - /* K28 */ be_nested_str_weak(tasmota), - /* K29 */ be_nested_str_weak(log), - /* K30 */ be_nested_str_weak(MTR_X3A_X20_X3CReplied_X20_X20_X20_X28_X256i_X29_X20_X25s), - /* K31 */ be_const_int(2), + ( &(const bvalue[30]) { /* constants */ + /* K0 */ be_nested_str_weak(message_handler), + /* K1 */ be_nested_str_weak(remote_ip), + /* K2 */ be_nested_str_weak(remote_port), + /* K3 */ be_nested_str_weak(flag_s), + /* K4 */ be_nested_str_weak(flag_dsiz), + /* K5 */ be_const_int(1), + /* K6 */ be_nested_str_weak(dest_node_id_8), + /* K7 */ be_nested_str_weak(source_node_id), + /* K8 */ be_const_int(0), + /* K9 */ be_nested_str_weak(session), + /* K10 */ be_nested_str_weak(local_session_id), + /* K11 */ be_nested_str_weak(initiator_session_id), + /* K12 */ be_nested_str_weak(message_counter), + /* K13 */ be_nested_str_weak(counter_snd_next), + /* K14 */ be_nested_str_weak(_counter_insecure_snd), + /* K15 */ be_nested_str_weak(next), + /* K16 */ be_nested_str_weak(x_flag_i), + /* K17 */ be_nested_str_weak(opcode), + /* K18 */ be_nested_str_weak(exchange_id), + /* K19 */ be_nested_str_weak(protocol_id), + /* K20 */ be_nested_str_weak(x_flag_r), + /* K21 */ be_nested_str_weak(x_flag_a), + /* K22 */ be_nested_str_weak(ack_message_counter), + /* K23 */ be_nested_str_weak(matter), + /* K24 */ be_nested_str_weak(get_opcode_name), + /* K25 */ be_nested_str_weak(0x_X2502X), + /* K26 */ be_nested_str_weak(tasmota), + /* K27 */ be_nested_str_weak(log), + /* K28 */ be_nested_str_weak(MTR_X3A_X20_X3CReplied_X20_X20_X20_X28_X256i_X29_X20_X25s), + /* K29 */ be_const_int(3), }), be_str_weak(build_response), &be_const_str_solidified, - ( &(const binstruction[92]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0x4C140000, // 0001 LDNIL R5 - 0x1C140605, // 0002 EQ R5 R3 R5 - 0x78160005, // 0003 JMPF R5 #000A - 0x60140006, // 0004 GETGBL R5 G6 - 0x5C180000, // 0005 MOVE R6 R0 - 0x7C140200, // 0006 CALL R5 1 - 0x88180101, // 0007 GETMBR R6 R0 K1 - 0x7C140200, // 0008 CALL R5 1 - 0x5C0C0A00, // 0009 MOVE R3 R5 - 0x88140102, // 000A GETMBR R5 R0 K2 - 0x900E0405, // 000B SETMBR R3 K2 R5 - 0x88140103, // 000C GETMBR R5 R0 K3 - 0x900E0605, // 000D SETMBR R3 K3 R5 - 0x88140104, // 000E GETMBR R5 R0 K4 - 0x78160003, // 000F JMPF R5 #0014 - 0x900E0B06, // 0010 SETMBR R3 K5 K6 - 0x88140108, // 0011 GETMBR R5 R0 K8 - 0x900E0E05, // 0012 SETMBR R3 K7 R5 - 0x70020000, // 0013 JMP #0015 - 0x900E0B09, // 0014 SETMBR R3 K5 K9 - 0x8814010A, // 0015 GETMBR R5 R0 K10 - 0x900E1405, // 0016 SETMBR R3 K10 R5 - 0x8814010B, // 0017 GETMBR R5 R0 K11 - 0x20140B09, // 0018 NE R5 R5 K9 - 0x7816000D, // 0019 JMPF R5 #0028 - 0x8814010A, // 001A GETMBR R5 R0 K10 - 0x7816000B, // 001B JMPF R5 #0028 - 0x8814010A, // 001C GETMBR R5 R0 K10 - 0x88140B0C, // 001D GETMBR R5 R5 K12 - 0x20140B09, // 001E NE R5 R5 K9 - 0x78160007, // 001F JMPF R5 #0028 - 0x8814010A, // 0020 GETMBR R5 R0 K10 - 0x8C140B0E, // 0021 GETMET R5 R5 K14 - 0x7C140200, // 0022 CALL R5 1 - 0x900E1A05, // 0023 SETMBR R3 K13 R5 - 0x8814010A, // 0024 GETMBR R5 R0 K10 - 0x88140B0C, // 0025 GETMBR R5 R5 K12 - 0x900E1605, // 0026 SETMBR R3 K11 R5 - 0x70020005, // 0027 JMP #002E - 0x8814010A, // 0028 GETMBR R5 R0 K10 - 0x88140B0F, // 0029 GETMBR R5 R5 K15 - 0x8C140B10, // 002A GETMET R5 R5 K16 - 0x7C140200, // 002B CALL R5 1 - 0x900E1A05, // 002C SETMBR R3 K13 R5 - 0x900E1709, // 002D SETMBR R3 K11 K9 - 0x88140111, // 002E GETMBR R5 R0 K17 - 0x78160001, // 002F JMPF R5 #0032 - 0x58140009, // 0030 LDCONST R5 K9 - 0x70020000, // 0031 JMP #0033 - 0x58140006, // 0032 LDCONST R5 K6 - 0x900E2205, // 0033 SETMBR R3 K17 R5 - 0x900E2401, // 0034 SETMBR R3 K18 R1 - 0x88140113, // 0035 GETMBR R5 R0 K19 - 0x900E2605, // 0036 SETMBR R3 K19 R5 - 0x88140114, // 0037 GETMBR R5 R0 K20 - 0x900E2805, // 0038 SETMBR R3 K20 R5 - 0x88140115, // 0039 GETMBR R5 R0 K21 - 0x78160002, // 003A JMPF R5 #003E - 0x900E2D06, // 003B SETMBR R3 K22 K6 - 0x8814010D, // 003C GETMBR R5 R0 K13 - 0x900E2E05, // 003D SETMBR R3 K23 R5 - 0x780A0001, // 003E JMPF R2 #0041 - 0x58140006, // 003F LDCONST R5 K6 - 0x70020000, // 0040 JMP #0042 - 0x58140009, // 0041 LDCONST R5 K9 - 0x900E2A05, // 0042 SETMBR R3 K21 R5 - 0x8814070B, // 0043 GETMBR R5 R3 K11 - 0x1C140B09, // 0044 EQ R5 R5 K9 - 0x78160014, // 0045 JMPF R5 #005B - 0xB8163000, // 0046 GETNGBL R5 K24 - 0x8C140B19, // 0047 GETMET R5 R5 K25 - 0x881C0712, // 0048 GETMBR R7 R3 K18 - 0x7C140400, // 0049 CALL R5 2 - 0x5C180A00, // 004A MOVE R6 R5 - 0x741A0004, // 004B JMPT R6 #0051 - 0x8C18091A, // 004C GETMET R6 R4 K26 - 0x5820001B, // 004D LDCONST R8 K27 - 0x88240712, // 004E GETMBR R9 R3 K18 - 0x7C180600, // 004F CALL R6 3 - 0x5C140C00, // 0050 MOVE R5 R6 - 0xB81A3800, // 0051 GETNGBL R6 K28 - 0x8C180D1D, // 0052 GETMET R6 R6 K29 - 0x8C20091A, // 0053 GETMET R8 R4 K26 - 0x5828001E, // 0054 LDCONST R10 K30 - 0x882C070A, // 0055 GETMBR R11 R3 K10 - 0x882C170B, // 0056 GETMBR R11 R11 K11 - 0x5C300A00, // 0057 MOVE R12 R5 - 0x7C200800, // 0058 CALL R8 4 - 0x5824001F, // 0059 LDCONST R9 K31 - 0x7C180600, // 005A CALL R6 3 - 0x80040600, // 005B RET 1 R3 + ( &(const binstruction[91]) { /* code */ + 0x4C100000, // 0000 LDNIL R4 + 0x1C100604, // 0001 EQ R4 R3 R4 + 0x78120005, // 0002 JMPF R4 #0009 + 0x60100006, // 0003 GETGBL R4 G6 + 0x5C140000, // 0004 MOVE R5 R0 + 0x7C100200, // 0005 CALL R4 1 + 0x88140100, // 0006 GETMBR R5 R0 K0 + 0x7C100200, // 0007 CALL R4 1 + 0x5C0C0800, // 0008 MOVE R3 R4 + 0x88100101, // 0009 GETMBR R4 R0 K1 + 0x900E0204, // 000A SETMBR R3 K1 R4 + 0x88100102, // 000B GETMBR R4 R0 K2 + 0x900E0404, // 000C SETMBR R3 K2 R4 + 0x88100103, // 000D GETMBR R4 R0 K3 + 0x78120003, // 000E JMPF R4 #0013 + 0x900E0905, // 000F SETMBR R3 K4 K5 + 0x88100107, // 0010 GETMBR R4 R0 K7 + 0x900E0C04, // 0011 SETMBR R3 K6 R4 + 0x70020000, // 0012 JMP #0014 + 0x900E0908, // 0013 SETMBR R3 K4 K8 + 0x88100109, // 0014 GETMBR R4 R0 K9 + 0x900E1204, // 0015 SETMBR R3 K9 R4 + 0x8810010A, // 0016 GETMBR R4 R0 K10 + 0x20100908, // 0017 NE R4 R4 K8 + 0x7812000D, // 0018 JMPF R4 #0027 + 0x88100109, // 0019 GETMBR R4 R0 K9 + 0x7812000B, // 001A JMPF R4 #0027 + 0x88100109, // 001B GETMBR R4 R0 K9 + 0x8810090B, // 001C GETMBR R4 R4 K11 + 0x20100908, // 001D NE R4 R4 K8 + 0x78120007, // 001E JMPF R4 #0027 + 0x88100109, // 001F GETMBR R4 R0 K9 + 0x8C10090D, // 0020 GETMET R4 R4 K13 + 0x7C100200, // 0021 CALL R4 1 + 0x900E1804, // 0022 SETMBR R3 K12 R4 + 0x88100109, // 0023 GETMBR R4 R0 K9 + 0x8810090B, // 0024 GETMBR R4 R4 K11 + 0x900E1404, // 0025 SETMBR R3 K10 R4 + 0x70020005, // 0026 JMP #002D + 0x88100109, // 0027 GETMBR R4 R0 K9 + 0x8810090E, // 0028 GETMBR R4 R4 K14 + 0x8C10090F, // 0029 GETMET R4 R4 K15 + 0x7C100200, // 002A CALL R4 1 + 0x900E1804, // 002B SETMBR R3 K12 R4 + 0x900E1508, // 002C SETMBR R3 K10 K8 + 0x88100110, // 002D GETMBR R4 R0 K16 + 0x78120001, // 002E JMPF R4 #0031 + 0x58100008, // 002F LDCONST R4 K8 + 0x70020000, // 0030 JMP #0032 + 0x58100005, // 0031 LDCONST R4 K5 + 0x900E2004, // 0032 SETMBR R3 K16 R4 + 0x900E2201, // 0033 SETMBR R3 K17 R1 + 0x88100112, // 0034 GETMBR R4 R0 K18 + 0x900E2404, // 0035 SETMBR R3 K18 R4 + 0x88100113, // 0036 GETMBR R4 R0 K19 + 0x900E2604, // 0037 SETMBR R3 K19 R4 + 0x88100114, // 0038 GETMBR R4 R0 K20 + 0x78120002, // 0039 JMPF R4 #003D + 0x900E2B05, // 003A SETMBR R3 K21 K5 + 0x8810010C, // 003B GETMBR R4 R0 K12 + 0x900E2C04, // 003C SETMBR R3 K22 R4 + 0x780A0001, // 003D JMPF R2 #0040 + 0x58100005, // 003E LDCONST R4 K5 + 0x70020000, // 003F JMP #0041 + 0x58100008, // 0040 LDCONST R4 K8 + 0x900E2804, // 0041 SETMBR R3 K20 R4 + 0x8810070A, // 0042 GETMBR R4 R3 K10 + 0x1C100908, // 0043 EQ R4 R4 K8 + 0x78120014, // 0044 JMPF R4 #005A + 0xB8122E00, // 0045 GETNGBL R4 K23 + 0x8C100918, // 0046 GETMET R4 R4 K24 + 0x88180711, // 0047 GETMBR R6 R3 K17 + 0x7C100400, // 0048 CALL R4 2 + 0x5C140800, // 0049 MOVE R5 R4 + 0x74160004, // 004A JMPT R5 #0050 + 0x60140018, // 004B GETGBL R5 G24 + 0x58180019, // 004C LDCONST R6 K25 + 0x881C0711, // 004D GETMBR R7 R3 K17 + 0x7C140400, // 004E CALL R5 2 + 0x5C100A00, // 004F MOVE R4 R5 + 0xB8163400, // 0050 GETNGBL R5 K26 + 0x8C140B1B, // 0051 GETMET R5 R5 K27 + 0x601C0018, // 0052 GETGBL R7 G24 + 0x5820001C, // 0053 LDCONST R8 K28 + 0x88240709, // 0054 GETMBR R9 R3 K9 + 0x8824130A, // 0055 GETMBR R9 R9 K10 + 0x5C280800, // 0056 MOVE R10 R4 + 0x7C1C0600, // 0057 CALL R7 3 + 0x5820001D, // 0058 LDCONST R8 K29 + 0x7C140600, // 0059 CALL R5 3 + 0x80040600, // 005A RET 1 R3 }) ) ); @@ -601,7 +598,7 @@ be_local_closure(Matter_Frame_build_response, /* name */ ********************************************************************/ be_local_closure(Matter_Frame_initiate_response, /* name */ be_nested_proto( - 10, /* nstack */ + 9, /* nstack */ 5, /* argc */ 4, /* varg */ 0, /* has upvals */ @@ -609,82 +606,80 @@ be_local_closure(Matter_Frame_initiate_response, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[24]) { /* constants */ + ( &(const bvalue[23]) { /* constants */ /* K0 */ be_const_class(be_class_Matter_Frame), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(matter), - /* K3 */ be_nested_str_weak(Frame), - /* K4 */ be_nested_str_weak(remote_ip), - /* K5 */ be_nested_str_weak(_ip), - /* K6 */ be_nested_str_weak(remote_port), - /* K7 */ be_nested_str_weak(_port), - /* K8 */ be_nested_str_weak(flag_dsiz), - /* K9 */ be_const_int(0), - /* K10 */ be_nested_str_weak(session), - /* K11 */ be_nested_str_weak(initiator_session_id), - /* K12 */ be_nested_str_weak(message_counter), - /* K13 */ be_nested_str_weak(counter_snd_next), - /* K14 */ be_nested_str_weak(local_session_id), - /* K15 */ be_nested_str_weak(_counter_insecure_snd), - /* K16 */ be_nested_str_weak(next), - /* K17 */ be_nested_str_weak(x_flag_i), - /* K18 */ be_const_int(1), - /* K19 */ be_nested_str_weak(opcode), - /* K20 */ be_nested_str_weak(_exchange_id), - /* K21 */ be_nested_str_weak(exchange_id), - /* K22 */ be_nested_str_weak(protocol_id), - /* K23 */ be_nested_str_weak(x_flag_r), + /* K1 */ be_nested_str_weak(matter), + /* K2 */ be_nested_str_weak(Frame), + /* K3 */ be_nested_str_weak(remote_ip), + /* K4 */ be_nested_str_weak(_ip), + /* K5 */ be_nested_str_weak(remote_port), + /* K6 */ be_nested_str_weak(_port), + /* K7 */ be_nested_str_weak(flag_dsiz), + /* K8 */ be_const_int(0), + /* K9 */ be_nested_str_weak(session), + /* K10 */ be_nested_str_weak(initiator_session_id), + /* K11 */ be_nested_str_weak(message_counter), + /* K12 */ be_nested_str_weak(counter_snd_next), + /* K13 */ be_nested_str_weak(local_session_id), + /* K14 */ be_nested_str_weak(_counter_insecure_snd), + /* K15 */ be_nested_str_weak(next), + /* K16 */ be_nested_str_weak(x_flag_i), + /* K17 */ be_const_int(1), + /* K18 */ be_nested_str_weak(opcode), + /* K19 */ be_nested_str_weak(_exchange_id), + /* K20 */ be_nested_str_weak(exchange_id), + /* K21 */ be_nested_str_weak(protocol_id), + /* K22 */ be_nested_str_weak(x_flag_r), }), be_str_weak(initiate_response), &be_const_str_solidified, - ( &(const binstruction[47]) { /* code */ + ( &(const binstruction[46]) { /* code */ 0x58140000, // 0000 LDCONST R5 K0 - 0xA41A0200, // 0001 IMPORT R6 K1 - 0x4C1C0000, // 0002 LDNIL R7 - 0x1C1C0807, // 0003 EQ R7 R4 R7 - 0x781E0004, // 0004 JMPF R7 #000A - 0xB81E0400, // 0005 GETNGBL R7 K2 - 0x8C1C0F03, // 0006 GETMET R7 R7 K3 - 0x5C240000, // 0007 MOVE R9 R0 - 0x7C1C0400, // 0008 CALL R7 2 - 0x5C100E00, // 0009 MOVE R4 R7 - 0x881C0305, // 000A GETMBR R7 R1 K5 - 0x90120807, // 000B SETMBR R4 K4 R7 - 0x881C0307, // 000C GETMBR R7 R1 K7 - 0x90120C07, // 000D SETMBR R4 K6 R7 - 0x90121109, // 000E SETMBR R4 K8 K9 - 0x90121401, // 000F SETMBR R4 K10 R1 - 0x78060008, // 0010 JMPF R1 #001A - 0x881C030B, // 0011 GETMBR R7 R1 K11 - 0x201C0F09, // 0012 NE R7 R7 K9 - 0x781E0005, // 0013 JMPF R7 #001A - 0x8C1C030D, // 0014 GETMET R7 R1 K13 - 0x7C1C0200, // 0015 CALL R7 1 - 0x90121807, // 0016 SETMBR R4 K12 R7 - 0x881C030B, // 0017 GETMBR R7 R1 K11 - 0x90121C07, // 0018 SETMBR R4 K14 R7 - 0x70020004, // 0019 JMP #001F - 0x881C030F, // 001A GETMBR R7 R1 K15 - 0x8C1C0F10, // 001B GETMET R7 R7 K16 - 0x7C1C0200, // 001C CALL R7 1 - 0x90121807, // 001D SETMBR R4 K12 R7 - 0x90121D09, // 001E SETMBR R4 K14 K9 - 0x90122312, // 001F SETMBR R4 K17 K18 - 0x90122602, // 0020 SETMBR R4 K19 R2 - 0x881C0314, // 0021 GETMBR R7 R1 K20 - 0x001C0F12, // 0022 ADD R7 R7 K18 - 0x90062807, // 0023 SETMBR R1 K20 R7 - 0x881C0314, // 0024 GETMBR R7 R1 K20 - 0x5422FFFF, // 0025 LDINT R8 65536 - 0x301C0E08, // 0026 OR R7 R7 R8 - 0x90122A07, // 0027 SETMBR R4 K21 R7 - 0x90122D12, // 0028 SETMBR R4 K22 K18 - 0x780E0001, // 0029 JMPF R3 #002C - 0x581C0012, // 002A LDCONST R7 K18 - 0x70020000, // 002B JMP #002D - 0x581C0009, // 002C LDCONST R7 K9 - 0x90122E07, // 002D SETMBR R4 K23 R7 - 0x80040800, // 002E RET 1 R4 + 0x4C180000, // 0001 LDNIL R6 + 0x1C180806, // 0002 EQ R6 R4 R6 + 0x781A0004, // 0003 JMPF R6 #0009 + 0xB81A0200, // 0004 GETNGBL R6 K1 + 0x8C180D02, // 0005 GETMET R6 R6 K2 + 0x5C200000, // 0006 MOVE R8 R0 + 0x7C180400, // 0007 CALL R6 2 + 0x5C100C00, // 0008 MOVE R4 R6 + 0x88180304, // 0009 GETMBR R6 R1 K4 + 0x90120606, // 000A SETMBR R4 K3 R6 + 0x88180306, // 000B GETMBR R6 R1 K6 + 0x90120A06, // 000C SETMBR R4 K5 R6 + 0x90120F08, // 000D SETMBR R4 K7 K8 + 0x90121201, // 000E SETMBR R4 K9 R1 + 0x78060008, // 000F JMPF R1 #0019 + 0x8818030A, // 0010 GETMBR R6 R1 K10 + 0x20180D08, // 0011 NE R6 R6 K8 + 0x781A0005, // 0012 JMPF R6 #0019 + 0x8C18030C, // 0013 GETMET R6 R1 K12 + 0x7C180200, // 0014 CALL R6 1 + 0x90121606, // 0015 SETMBR R4 K11 R6 + 0x8818030A, // 0016 GETMBR R6 R1 K10 + 0x90121A06, // 0017 SETMBR R4 K13 R6 + 0x70020004, // 0018 JMP #001E + 0x8818030E, // 0019 GETMBR R6 R1 K14 + 0x8C180D0F, // 001A GETMET R6 R6 K15 + 0x7C180200, // 001B CALL R6 1 + 0x90121606, // 001C SETMBR R4 K11 R6 + 0x90121B08, // 001D SETMBR R4 K13 K8 + 0x90122111, // 001E SETMBR R4 K16 K17 + 0x90122402, // 001F SETMBR R4 K18 R2 + 0x88180313, // 0020 GETMBR R6 R1 K19 + 0x00180D11, // 0021 ADD R6 R6 K17 + 0x90062606, // 0022 SETMBR R1 K19 R6 + 0x88180313, // 0023 GETMBR R6 R1 K19 + 0x541EFFFF, // 0024 LDINT R7 65536 + 0x30180C07, // 0025 OR R6 R6 R7 + 0x90122806, // 0026 SETMBR R4 K20 R6 + 0x90122B11, // 0027 SETMBR R4 K21 K17 + 0x780E0001, // 0028 JMPF R3 #002B + 0x58180011, // 0029 LDCONST R6 K17 + 0x70020000, // 002A JMP #002C + 0x58180008, // 002B LDCONST R6 K8 + 0x90122C06, // 002C SETMBR R4 K22 R6 + 0x80040800, // 002D RET 1 R4 }) ) ); @@ -1031,7 +1026,7 @@ be_local_closure(Matter_Frame_decode_payload, /* name */ ********************************************************************/ be_local_closure(Matter_Frame_decrypt, /* name */ be_nested_proto( - 16, /* nstack */ + 23, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1039,11 +1034,11 @@ be_local_closure(Matter_Frame_decrypt, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[28]) { /* constants */ + ( &(const bvalue[30]) { /* constants */ /* K0 */ be_nested_str_weak(crypto), /* K1 */ be_nested_str_weak(session), /* K2 */ be_nested_str_weak(raw), - /* K3 */ be_const_int(2147483647), + /* K3 */ be_nested_str_weak(payload_idx), /* K4 */ be_nested_str_weak(get_i2r), /* K5 */ be_nested_str_weak(sec_p), /* K6 */ be_nested_str_weak(tasmota), @@ -1051,133 +1046,145 @@ be_local_closure(Matter_Frame_decrypt, /* name */ /* K8 */ be_nested_str_weak(MTR_X3A_X20_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X3E_X20Compute_X20Privacy_X20TODO), /* K9 */ be_const_int(2), /* K10 */ be_nested_str_weak(get_i2r_privacy), - /* K11 */ be_nested_str_weak(add), - /* K12 */ be_nested_str_weak(local_session_id), - /* K13 */ be_nested_str_weak(payload_idx), + /* K11 */ be_const_int(2147483647), + /* K12 */ be_nested_str_weak(add), + /* K13 */ be_nested_str_weak(local_session_id), /* K14 */ be_const_int(1), /* K15 */ be_nested_str_weak(AES_CTR), /* K16 */ be_nested_str_weak(decrypt), /* K17 */ be_const_int(0), /* K18 */ be_const_int(3), - /* K19 */ be_nested_str_weak(self), - /* K20 */ be_nested_str_weak(flags), - /* K21 */ be_nested_str_weak(message_counter), - /* K22 */ be_nested_str_weak(source_node_id), - /* K23 */ be_nested_str_weak(peer_node_id), - /* K24 */ be_nested_str_weak(resize), - /* K25 */ be_nested_str_weak(AES_CCM), - /* K26 */ be_nested_str_weak(tag), - /* K27 */ be_nested_str_weak(MTR_X3A_X20rejected_X20packet_X20due_X20to_X20invalid_X20MIC), + /* K19 */ be_nested_str_weak(message_handler), + /* K20 */ be_nested_str_weak(_n_bytes), + /* K21 */ be_nested_str_weak(clear), + /* K22 */ be_nested_str_weak(flags), + /* K23 */ be_nested_str_weak(message_counter), + /* K24 */ be_nested_str_weak(source_node_id), + /* K25 */ be_nested_str_weak(peer_node_id), + /* K26 */ be_nested_str_weak(resize), + /* K27 */ be_nested_str_weak(AES_CCM), + /* K28 */ be_nested_str_weak(decrypt1), + /* K29 */ be_nested_str_weak(MTR_X3A_X20rejected_X20packet_X20due_X20to_X20invalid_X20MIC), }), be_str_weak(decrypt), &be_const_str_solidified, - ( &(const binstruction[106]) { /* code */ + ( &(const binstruction[116]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 0x88080101, // 0001 GETMBR R2 R0 K1 0x880C0102, // 0002 GETMBR R3 R0 K2 - 0x5411FFEF, // 0003 LDINT R4 -16 - 0x40100903, // 0004 CONNECT R4 R4 K3 - 0x94100604, // 0005 GETIDX R4 R3 R4 - 0x8C140504, // 0006 GETMET R5 R2 K4 - 0x7C140200, // 0007 CALL R5 1 - 0x88180105, // 0008 GETMBR R6 R0 K5 - 0x781A002A, // 0009 JMPF R6 #0035 - 0xB81A0C00, // 000A GETNGBL R6 K6 - 0x8C180D07, // 000B GETMET R6 R6 K7 - 0x58200008, // 000C LDCONST R8 K8 - 0x58240009, // 000D LDCONST R9 K9 - 0x7C180600, // 000E CALL R6 3 - 0x8C18050A, // 000F GETMET R6 R2 K10 - 0x7C180200, // 0010 CALL R6 1 - 0x601C0015, // 0011 GETGBL R7 G21 - 0x7C1C0000, // 0012 CALL R7 0 - 0x8C1C0F0B, // 0013 GETMET R7 R7 K11 - 0x8824010C, // 0014 GETMBR R9 R0 K12 - 0x5429FFFD, // 0015 LDINT R10 -2 - 0x7C1C0600, // 0016 CALL R7 3 - 0x54220004, // 0017 LDINT R8 5 - 0x5426000E, // 0018 LDINT R9 15 - 0x40201009, // 0019 CONNECT R8 R8 R9 - 0x94200808, // 001A GETIDX R8 R4 R8 - 0x001C0E08, // 001B ADD R7 R7 R8 - 0x54220003, // 001C LDINT R8 4 - 0x8824010D, // 001D GETMBR R9 R0 K13 - 0x0424130E, // 001E SUB R9 R9 K14 - 0x40201009, // 001F CONNECT R8 R8 R9 - 0x88240102, // 0020 GETMBR R9 R0 K2 - 0x94201208, // 0021 GETIDX R8 R9 R8 - 0x8C28030F, // 0022 GETMET R10 R1 K15 - 0x5C300C00, // 0023 MOVE R12 R6 - 0x7C280400, // 0024 CALL R10 2 - 0x8C281510, // 0025 GETMET R10 R10 K16 - 0x5C301000, // 0026 MOVE R12 R8 - 0x5C340E00, // 0027 MOVE R13 R7 - 0x58380009, // 0028 LDCONST R14 K9 - 0x7C280800, // 0029 CALL R10 4 - 0x5C241400, // 002A MOVE R9 R10 - 0x402A2312, // 002B CONNECT R10 K17 K18 - 0x882C0102, // 002C GETMBR R11 R0 K2 - 0x9428160A, // 002D GETIDX R10 R11 R10 - 0x00281409, // 002E ADD R10 R10 R9 - 0x882C0113, // 002F GETMBR R11 R0 K19 - 0x882C170D, // 0030 GETMBR R11 R11 K13 - 0x402C1703, // 0031 CONNECT R11 R11 K3 - 0x942C100B, // 0032 GETIDX R11 R8 R11 - 0x0028140B, // 0033 ADD R10 R10 R11 - 0x9002040A, // 0034 SETMBR R0 K2 R10 - 0x8818010D, // 0035 GETMBR R6 R0 K13 - 0x04180D0E, // 0036 SUB R6 R6 K14 - 0x401A2206, // 0037 CONNECT R6 K17 R6 - 0x94180606, // 0038 GETIDX R6 R3 R6 - 0x881C010D, // 0039 GETMBR R7 R0 K13 - 0x5421FFEE, // 003A LDINT R8 -17 - 0x401C0E08, // 003B CONNECT R7 R7 R8 - 0x941C0607, // 003C GETIDX R7 R3 R7 - 0x60200015, // 003D GETGBL R8 G21 - 0x7C200000, // 003E CALL R8 0 - 0x8C24110B, // 003F GETMET R9 R8 K11 - 0x882C0114, // 0040 GETMBR R11 R0 K20 - 0x5830000E, // 0041 LDCONST R12 K14 - 0x7C240600, // 0042 CALL R9 3 - 0x8C24110B, // 0043 GETMET R9 R8 K11 - 0x882C0115, // 0044 GETMBR R11 R0 K21 - 0x54320003, // 0045 LDINT R12 4 - 0x7C240600, // 0046 CALL R9 3 - 0x88240116, // 0047 GETMBR R9 R0 K22 - 0x78260001, // 0048 JMPF R9 #004B - 0x40241103, // 0049 CONNECT R9 R8 K3 - 0x70020006, // 004A JMP #0052 - 0x88240517, // 004B GETMBR R9 R2 K23 - 0x78260001, // 004C JMPF R9 #004F - 0x88240517, // 004D GETMBR R9 R2 K23 - 0x40241009, // 004E CONNECT R9 R8 R9 - 0x8C241118, // 004F GETMET R9 R8 K24 - 0x542E000C, // 0050 LDINT R11 13 - 0x7C240400, // 0051 CALL R9 2 - 0x8C240319, // 0052 GETMET R9 R1 K25 - 0x5C2C0A00, // 0053 MOVE R11 R5 - 0x5C301000, // 0054 MOVE R12 R8 - 0x5C340C00, // 0055 MOVE R13 R6 - 0x6038000C, // 0056 GETGBL R14 G12 - 0x5C3C0E00, // 0057 MOVE R15 R7 - 0x7C380200, // 0058 CALL R14 1 - 0x543E000F, // 0059 LDINT R15 16 - 0x7C240C00, // 005A CALL R9 6 - 0x8C281310, // 005B GETMET R10 R9 K16 - 0x5C300E00, // 005C MOVE R12 R7 - 0x7C280400, // 005D CALL R10 2 - 0x8C2C131A, // 005E GETMET R11 R9 K26 - 0x7C2C0200, // 005F CALL R11 1 - 0x20301604, // 0060 NE R12 R11 R4 - 0x78320006, // 0061 JMPF R12 #0069 - 0xB8320C00, // 0062 GETNGBL R12 K6 - 0x8C301907, // 0063 GETMET R12 R12 K7 - 0x5838001B, // 0064 LDCONST R14 K27 - 0x583C0009, // 0065 LDCONST R15 K9 - 0x7C300600, // 0066 CALL R12 3 - 0x4C300000, // 0067 LDNIL R12 - 0x80041800, // 0068 RET 1 R12 - 0x80041400, // 0069 RET 1 R10 + 0x88100103, // 0003 GETMBR R4 R0 K3 + 0x5416000F, // 0004 LDINT R5 16 + 0x8C180504, // 0005 GETMET R6 R2 K4 + 0x7C180200, // 0006 CALL R6 1 + 0x881C0105, // 0007 GETMBR R7 R0 K5 + 0x781E002C, // 0008 JMPF R7 #0036 + 0xB81E0C00, // 0009 GETNGBL R7 K6 + 0x8C1C0F07, // 000A GETMET R7 R7 K7 + 0x58240008, // 000B LDCONST R9 K8 + 0x58280009, // 000C LDCONST R10 K9 + 0x7C1C0600, // 000D CALL R7 3 + 0x8C1C050A, // 000E GETMET R7 R2 K10 + 0x7C1C0200, // 000F CALL R7 1 + 0x5421FFEF, // 0010 LDINT R8 -16 + 0x4020110B, // 0011 CONNECT R8 R8 K11 + 0x94200608, // 0012 GETIDX R8 R3 R8 + 0x60240015, // 0013 GETGBL R9 G21 + 0x7C240000, // 0014 CALL R9 0 + 0x8C24130C, // 0015 GETMET R9 R9 K12 + 0x882C010D, // 0016 GETMBR R11 R0 K13 + 0x5431FFFD, // 0017 LDINT R12 -2 + 0x7C240600, // 0018 CALL R9 3 + 0x542A0004, // 0019 LDINT R10 5 + 0x542E000E, // 001A LDINT R11 15 + 0x4028140B, // 001B CONNECT R10 R10 R11 + 0x9428100A, // 001C GETIDX R10 R8 R10 + 0x0024120A, // 001D ADD R9 R9 R10 + 0x542A0003, // 001E LDINT R10 4 + 0x882C0103, // 001F GETMBR R11 R0 K3 + 0x042C170E, // 0020 SUB R11 R11 K14 + 0x4028140B, // 0021 CONNECT R10 R10 R11 + 0x882C0102, // 0022 GETMBR R11 R0 K2 + 0x9428160A, // 0023 GETIDX R10 R11 R10 + 0x8C30030F, // 0024 GETMET R12 R1 K15 + 0x5C380E00, // 0025 MOVE R14 R7 + 0x7C300400, // 0026 CALL R12 2 + 0x8C301910, // 0027 GETMET R12 R12 K16 + 0x5C381400, // 0028 MOVE R14 R10 + 0x5C3C1200, // 0029 MOVE R15 R9 + 0x58400009, // 002A LDCONST R16 K9 + 0x7C300800, // 002B CALL R12 4 + 0x5C2C1800, // 002C MOVE R11 R12 + 0x40322312, // 002D CONNECT R12 K17 K18 + 0x88340102, // 002E GETMBR R13 R0 K2 + 0x94301A0C, // 002F GETIDX R12 R13 R12 + 0x0030180B, // 0030 ADD R12 R12 R11 + 0x88340103, // 0031 GETMBR R13 R0 K3 + 0x40341B0B, // 0032 CONNECT R13 R13 K11 + 0x9434140D, // 0033 GETIDX R13 R10 R13 + 0x0030180D, // 0034 ADD R12 R12 R13 + 0x9002040C, // 0035 SETMBR R0 K2 R12 + 0x881C0113, // 0036 GETMBR R7 R0 K19 + 0x881C0F14, // 0037 GETMBR R7 R7 K20 + 0x8C200F15, // 0038 GETMET R8 R7 K21 + 0x7C200200, // 0039 CALL R8 1 + 0x8C200F0C, // 003A GETMET R8 R7 K12 + 0x88280116, // 003B GETMBR R10 R0 K22 + 0x582C000E, // 003C LDCONST R11 K14 + 0x7C200600, // 003D CALL R8 3 + 0x8C200F0C, // 003E GETMET R8 R7 K12 + 0x88280117, // 003F GETMBR R10 R0 K23 + 0x542E0003, // 0040 LDINT R11 4 + 0x7C200600, // 0041 CALL R8 3 + 0x88200118, // 0042 GETMBR R8 R0 K24 + 0x78220001, // 0043 JMPF R8 #0046 + 0x40200F0B, // 0044 CONNECT R8 R7 K11 + 0x70020006, // 0045 JMP #004D + 0x88200519, // 0046 GETMBR R8 R2 K25 + 0x78220001, // 0047 JMPF R8 #004A + 0x88200519, // 0048 GETMBR R8 R2 K25 + 0x40200E08, // 0049 CONNECT R8 R7 R8 + 0x8C200F1A, // 004A GETMET R8 R7 K26 + 0x542A000C, // 004B LDINT R10 13 + 0x7C200400, // 004C CALL R8 2 + 0x8820031B, // 004D GETMBR R8 R1 K27 + 0x8C20111C, // 004E GETMET R8 R8 K28 + 0x5C280C00, // 004F MOVE R10 R6 + 0x5C2C0E00, // 0050 MOVE R11 R7 + 0x58300011, // 0051 LDCONST R12 K17 + 0x6034000C, // 0052 GETGBL R13 G12 + 0x5C380E00, // 0053 MOVE R14 R7 + 0x7C340200, // 0054 CALL R13 1 + 0x5C380600, // 0055 MOVE R14 R3 + 0x583C0011, // 0056 LDCONST R15 K17 + 0x5C400800, // 0057 MOVE R16 R4 + 0x5C440600, // 0058 MOVE R17 R3 + 0x5C480800, // 0059 MOVE R18 R4 + 0x604C000C, // 005A GETGBL R19 G12 + 0x5C500600, // 005B MOVE R20 R3 + 0x7C4C0200, // 005C CALL R19 1 + 0x044C2604, // 005D SUB R19 R19 R4 + 0x044C2605, // 005E SUB R19 R19 R5 + 0x5C500600, // 005F MOVE R20 R3 + 0x6054000C, // 0060 GETGBL R21 G12 + 0x5C580600, // 0061 MOVE R22 R3 + 0x7C540200, // 0062 CALL R21 1 + 0x04542A05, // 0063 SUB R21 R21 R5 + 0x5C580A00, // 0064 MOVE R22 R5 + 0x7C201C00, // 0065 CALL R8 14 + 0x78220006, // 0066 JMPF R8 #006E + 0x8C24071A, // 0067 GETMET R9 R3 K26 + 0x602C000C, // 0068 GETGBL R11 G12 + 0x5C300600, // 0069 MOVE R12 R3 + 0x7C2C0200, // 006A CALL R11 1 + 0x042C1605, // 006B SUB R11 R11 R5 + 0x7C240400, // 006C CALL R9 2 + 0x70020004, // 006D JMP #0073 + 0xB8260C00, // 006E GETNGBL R9 K6 + 0x8C241307, // 006F GETMET R9 R9 K7 + 0x582C001D, // 0070 LDCONST R11 K29 + 0x58300012, // 0071 LDCONST R12 K18 + 0x7C240600, // 0072 CALL R9 3 + 0x80041000, // 0073 RET 1 R8 }) ) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_MessageHandler.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_MessageHandler.h index a94a7c160857..3dd9400121bb 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_MessageHandler.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_MessageHandler.h @@ -7,9 +7,9 @@ extern const bclass be_class_Matter_MessageHandler; /******************************************************************** -** Solidified function: send_response_frame +** Solidified function: init ********************************************************************/ -be_local_closure(Matter_MessageHandler_send_response_frame, /* name */ +be_local_closure(Matter_MessageHandler_init, /* name */ be_nested_proto( 5, /* nstack */ 2, /* argc */ @@ -19,18 +19,41 @@ be_local_closure(Matter_MessageHandler_send_response_frame, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ + ( &(const bvalue[ 9]) { /* constants */ /* K0 */ be_nested_str_weak(device), - /* K1 */ be_nested_str_weak(msg_send), + /* K1 */ be_nested_str_weak(commissioning), + /* K2 */ be_nested_str_weak(matter), + /* K3 */ be_nested_str_weak(Commisioning_Context), + /* K4 */ be_nested_str_weak(im), + /* K5 */ be_nested_str_weak(IM), + /* K6 */ be_nested_str_weak(control_message), + /* K7 */ be_nested_str_weak(Control_Message), + /* K8 */ be_nested_str_weak(_n_bytes), }), - be_str_weak(send_response_frame), + be_str_weak(init), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x5C100200, // 0002 MOVE R4 R1 - 0x7C080400, // 0003 CALL R2 2 - 0x80000000, // 0004 RET 0 + ( &(const binstruction[21]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0xB80A0400, // 0001 GETNGBL R2 K2 + 0x8C080503, // 0002 GETMET R2 R2 K3 + 0x5C100000, // 0003 MOVE R4 R0 + 0x7C080400, // 0004 CALL R2 2 + 0x90020202, // 0005 SETMBR R0 K1 R2 + 0xB80A0400, // 0006 GETNGBL R2 K2 + 0x8C080505, // 0007 GETMET R2 R2 K5 + 0x5C100200, // 0008 MOVE R4 R1 + 0x7C080400, // 0009 CALL R2 2 + 0x90020802, // 000A SETMBR R0 K4 R2 + 0xB80A0400, // 000B GETNGBL R2 K2 + 0x8C080507, // 000C GETMET R2 R2 K7 + 0x5C100000, // 000D MOVE R4 R0 + 0x7C080400, // 000E CALL R2 2 + 0x90020C02, // 000F SETMBR R0 K6 R2 + 0x60080015, // 0010 GETGBL R2 G21 + 0x540E000F, // 0011 LDINT R3 16 + 0x7C080200, // 0012 CALL R2 1 + 0x90021002, // 0013 SETMBR R0 K8 R2 + 0x80000000, // 0014 RET 0 }) ) ); @@ -42,7 +65,7 @@ be_local_closure(Matter_MessageHandler_send_response_frame, /* name */ ********************************************************************/ be_local_closure(Matter_MessageHandler_send_encrypted_ack, /* name */ be_nested_proto( - 14, /* nstack */ + 12, /* nstack */ 3, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -50,57 +73,59 @@ be_local_closure(Matter_MessageHandler_send_encrypted_ack, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[17]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(x_flag_r), - /* K2 */ be_nested_str_weak(build_standalone_ack), - /* K3 */ be_nested_str_weak(encode_frame), - /* K4 */ be_nested_str_weak(encrypt), - /* K5 */ be_nested_str_weak(tasmota), + ( &(const bvalue[15]) { /* constants */ + /* K0 */ be_nested_str_weak(x_flag_r), + /* K1 */ be_nested_str_weak(build_standalone_ack), + /* K2 */ be_nested_str_weak(encode_frame), + /* K3 */ be_nested_str_weak(encrypt), + /* K4 */ be_nested_str_weak(tasmota), + /* K5 */ be_nested_str_weak(loglevel), /* K6 */ be_nested_str_weak(log), - /* K7 */ be_nested_str_weak(format), - /* K8 */ be_nested_str_weak(MTR_X3A_X20_X3CAck_X2A_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20ack_X3D_X25i_X20id_X3D_X25i_X20_X25s), - /* K9 */ be_nested_str_weak(session), - /* K10 */ be_nested_str_weak(local_session_id), - /* K11 */ be_nested_str_weak(ack_message_counter), - /* K12 */ be_nested_str_weak(message_counter), - /* K13 */ be_nested_str_weak(_X7Breliable_X7D), - /* K14 */ be_nested_str_weak(), - /* K15 */ be_const_int(3), - /* K16 */ be_nested_str_weak(send_response_frame), + /* K7 */ be_nested_str_weak(MTR_X3A_X20_X3CAck_X2A_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20ack_X3D_X25i_X20id_X3D_X25i_X20_X25s), + /* K8 */ be_nested_str_weak(session), + /* K9 */ be_nested_str_weak(local_session_id), + /* K10 */ be_nested_str_weak(ack_message_counter), + /* K11 */ be_nested_str_weak(message_counter), + /* K12 */ be_nested_str_weak(_X7Breliable_X7D), + /* K13 */ be_nested_str_weak(), + /* K14 */ be_nested_str_weak(send_response_frame), }), be_str_weak(send_encrypted_ack), &be_const_str_solidified, - ( &(const binstruction[29]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0x88100301, // 0001 GETMBR R4 R1 K1 - 0x78120018, // 0002 JMPF R4 #001C - 0x8C100302, // 0003 GETMET R4 R1 K2 - 0x5C180400, // 0004 MOVE R6 R2 - 0x7C100400, // 0005 CALL R4 2 - 0x8C140903, // 0006 GETMET R5 R4 K3 - 0x7C140200, // 0007 CALL R5 1 - 0x8C140904, // 0008 GETMET R5 R4 K4 - 0x7C140200, // 0009 CALL R5 1 - 0xB8160A00, // 000A GETNGBL R5 K5 - 0x8C140B06, // 000B GETMET R5 R5 K6 - 0x8C1C0707, // 000C GETMET R7 R3 K7 - 0x58240008, // 000D LDCONST R9 K8 - 0x88280909, // 000E GETMBR R10 R4 K9 - 0x8828150A, // 000F GETMBR R10 R10 K10 - 0x882C090B, // 0010 GETMBR R11 R4 K11 - 0x8830090C, // 0011 GETMBR R12 R4 K12 - 0x780A0001, // 0012 JMPF R2 #0015 - 0x5834000D, // 0013 LDCONST R13 K13 - 0x70020000, // 0014 JMP #0016 - 0x5834000E, // 0015 LDCONST R13 K14 - 0x7C1C0C00, // 0016 CALL R7 6 - 0x5820000F, // 0017 LDCONST R8 K15 - 0x7C140600, // 0018 CALL R5 3 - 0x8C140110, // 0019 GETMET R5 R0 K16 - 0x5C1C0800, // 001A MOVE R7 R4 - 0x7C140400, // 001B CALL R5 2 - 0x80000000, // 001C RET 0 + ( &(const binstruction[33]) { /* code */ + 0x880C0300, // 0000 GETMBR R3 R1 K0 + 0x780E001D, // 0001 JMPF R3 #0020 + 0x8C0C0301, // 0002 GETMET R3 R1 K1 + 0x5C140400, // 0003 MOVE R5 R2 + 0x7C0C0400, // 0004 CALL R3 2 + 0x8C100702, // 0005 GETMET R4 R3 K2 + 0x7C100200, // 0006 CALL R4 1 + 0x8C100703, // 0007 GETMET R4 R3 K3 + 0x7C100200, // 0008 CALL R4 1 + 0xB8120800, // 0009 GETNGBL R4 K4 + 0x8C100905, // 000A GETMET R4 R4 K5 + 0x541A0003, // 000B LDINT R6 4 + 0x7C100400, // 000C CALL R4 2 + 0x7812000E, // 000D JMPF R4 #001D + 0xB8120800, // 000E GETNGBL R4 K4 + 0x8C100906, // 000F GETMET R4 R4 K6 + 0x60180018, // 0010 GETGBL R6 G24 + 0x581C0007, // 0011 LDCONST R7 K7 + 0x88200708, // 0012 GETMBR R8 R3 K8 + 0x88201109, // 0013 GETMBR R8 R8 K9 + 0x8824070A, // 0014 GETMBR R9 R3 K10 + 0x8828070B, // 0015 GETMBR R10 R3 K11 + 0x780A0001, // 0016 JMPF R2 #0019 + 0x582C000C, // 0017 LDCONST R11 K12 + 0x70020000, // 0018 JMP #001A + 0x582C000D, // 0019 LDCONST R11 K13 + 0x7C180A00, // 001A CALL R6 5 + 0x541E0003, // 001B LDINT R7 4 + 0x7C100600, // 001C CALL R4 3 + 0x8C10010E, // 001D GETMET R4 R0 K14 + 0x5C180600, // 001E MOVE R6 R3 + 0x7C100400, // 001F CALL R4 2 + 0x80000000, // 0020 RET 0 }) ) ); @@ -108,33 +133,458 @@ be_local_closure(Matter_MessageHandler_send_encrypted_ack, /* name */ /******************************************************************** -** Solidified function: every_second +** Solidified function: msg_received ********************************************************************/ -be_local_closure(Matter_MessageHandler_every_second, /* name */ +be_local_closure(Matter_MessageHandler_msg_received, /* name */ be_nested_proto( - 3, /* nstack */ - 1, /* argc */ + 19, /* nstack */ + 4, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(commissioning), - /* K1 */ be_nested_str_weak(every_second), - /* K2 */ be_nested_str_weak(im), + ( &(const bvalue[70]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(profiler), + /* K2 */ be_nested_str_weak(log), + /* K3 */ be_nested_str_weak(msg_received), + /* K4 */ be_nested_str_weak(Frame), + /* K5 */ be_nested_str_weak(decode_header), + /* K6 */ be_nested_str_weak(sec_p), + /* K7 */ be_nested_str_weak(device), + /* K8 */ be_nested_str_weak(sessions), + /* K9 */ be_nested_str_weak(find_session_source_id_unsecure), + /* K10 */ be_nested_str_weak(source_node_id), + /* K11 */ be_nested_str_weak(control_message), + /* K12 */ be_nested_str_weak(process_incoming_control_message), + /* K13 */ be_nested_str_weak(local_session_id), + /* K14 */ be_const_int(0), + /* K15 */ be_nested_str_weak(sec_sesstype), + /* K16 */ be_nested_str_weak(_ip), + /* K17 */ be_nested_str_weak(_port), + /* K18 */ be_nested_str_weak(_message_handler), + /* K19 */ be_nested_str_weak(session), + /* K20 */ be_nested_str_weak(_counter_insecure_rcv), + /* K21 */ be_nested_str_weak(validate), + /* K22 */ be_nested_str_weak(message_counter), + /* K23 */ be_nested_str_weak(tasmota), + /* K24 */ be_nested_str_weak(loglevel), + /* K25 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Duplicate_X20unencrypted_X20message_X20_X3D_X20_X25i_X20ref_X20_X3D_X20_X25i), + /* K26 */ be_nested_str_weak(val), + /* K27 */ be_nested_str_weak(send_simple_ack), + /* K28 */ be_nested_str_weak(decode_payload), + /* K29 */ be_nested_str_weak(received_ack), + /* K30 */ be_nested_str_weak(opcode), + /* K31 */ be_nested_str_weak(get_opcode_name), + /* K32 */ be_nested_str_weak(0x_X2502X), + /* K33 */ be_const_int(3), + /* K34 */ be_nested_str_weak(MTR_X3A_X20_X3EReceived_X20_X20_X28_X256i_X29_X20_X25s_X20rid_X3D_X25i_X20exch_X3D_X25i_X20from_X20_X5B_X25s_X5D_X3A_X25i), + /* K35 */ be_nested_str_weak(exchange_id), + /* K36 */ be_nested_str_weak(MTR_X3A_X20_X3Ercv_X20Ack_X20_X20_X20_X28_X256i_X29_X20rid_X3D_X25i_X20exch_X3D_X25i_X20ack_X3D_X25s_X20_X25sfrom_X20_X5B_X25s_X5D_X3A_X25i), + /* K37 */ be_nested_str_weak(x_flag_r), + /* K38 */ be_nested_str_weak(_X7Breliable_X7D_X20), + /* K39 */ be_nested_str_weak(), + /* K40 */ be_nested_str_weak(ack_message_counter), + /* K41 */ be_nested_str_weak(commissioning), + /* K42 */ be_nested_str_weak(process_incoming), + /* K43 */ be_nested_str_weak(MTR_X3A_X20decode_X20header_X3A_X20local_session_id_X3D_X25i_X20message_counter_X3D_X25i), + /* K44 */ be_nested_str_weak(get_session_by_local_session_id), + /* K45 */ be_nested_str_weak(MTR_X3A_X20unknown_X20local_session_id_X3D), + /* K46 */ be_nested_str_weak(counter_rcv_validate), + /* K47 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Duplicate_X20encrypted_X20message_X20_X3D_X20), + /* K48 */ be_nested_str_weak(_X20counter_X3D), + /* K49 */ be_nested_str_weak(counter_rcv), + /* K50 */ be_nested_str_weak(send_encrypted_ack), + /* K51 */ be_nested_str_weak(decrypt), + /* K52 */ be_nested_str_weak(msg_received_header_frame_decrypted), + /* K53 */ be_nested_str_weak(MTR_X3A_X20_X3E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Decrypted_X20message_X3A_X20protocol_id_X3A), + /* K54 */ be_nested_str_weak(protocol_id), + /* K55 */ be_nested_str_weak(_X20opcode_X3D), + /* K56 */ be_nested_str_weak(_X20exchange_id_X3D), + /* K57 */ be_nested_str_weak(im), + /* K58 */ be_nested_str_weak(process_incoming_ack), + /* K59 */ be_nested_str_weak(send_enqueued), + /* K60 */ be_const_int(1), + /* K61 */ be_nested_str_weak(process_IM_start), + /* K62 */ be_nested_str_weak(process_IM_end), + /* K63 */ be_nested_str_weak(MTR_X3A_X20ignoring_X20unhandled_X20protocol_id_X3A), + /* K64 */ be_nested_str_weak(MTR_X3A_X20MessageHandler_X3A_X3Amsg_received_X20exception_X3A_X20), + /* K65 */ be_nested_str_weak(_X3B), + /* K66 */ be_const_int(2), + /* K67 */ be_nested_str_weak(_debug_present), + /* K68 */ be_nested_str_weak(debug), + /* K69 */ be_nested_str_weak(traceback), }), - be_str_weak(every_second), + be_str_weak(msg_received), &be_const_str_solidified, - ( &(const binstruction[ 7]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x88040102, // 0003 GETMBR R1 R0 K2 - 0x8C040301, // 0004 GETMET R1 R1 K1 - 0x7C040200, // 0005 CALL R1 1 - 0x80000000, // 0006 RET 0 + ( &(const binstruction[365]) { /* code */ + 0x50100000, // 0000 LDBOOL R4 0 0 + 0xB8160000, // 0001 GETNGBL R5 K0 + 0x88140B01, // 0002 GETMBR R5 R5 K1 + 0x8C140B02, // 0003 GETMET R5 R5 K2 + 0x581C0003, // 0004 LDCONST R7 K3 + 0x7C140400, // 0005 CALL R5 2 + 0xA802014B, // 0006 EXBLK 0 #0153 + 0xB8160000, // 0007 GETNGBL R5 K0 + 0x8C140B04, // 0008 GETMET R5 R5 K4 + 0x5C1C0000, // 0009 MOVE R7 R0 + 0x5C200200, // 000A MOVE R8 R1 + 0x5C240400, // 000B MOVE R9 R2 + 0x5C280600, // 000C MOVE R10 R3 + 0x7C140A00, // 000D CALL R5 5 + 0x8C180B05, // 000E GETMET R6 R5 K5 + 0x7C180200, // 000F CALL R6 1 + 0x5C1C0C00, // 0010 MOVE R7 R6 + 0x741E0002, // 0011 JMPT R7 #0015 + 0x501C0000, // 0012 LDBOOL R7 0 0 + 0xA8040001, // 0013 EXBLK 1 1 + 0x80040E00, // 0014 RET 1 R7 + 0x881C0B06, // 0015 GETMBR R7 R5 K6 + 0x781E000C, // 0016 JMPF R7 #0024 + 0x881C0107, // 0017 GETMBR R7 R0 K7 + 0x881C0F08, // 0018 GETMBR R7 R7 K8 + 0x8C1C0F09, // 0019 GETMET R7 R7 K9 + 0x88240B0A, // 001A GETMBR R9 R5 K10 + 0x542A0059, // 001B LDINT R10 90 + 0x7C1C0600, // 001C CALL R7 3 + 0x8820010B, // 001D GETMBR R8 R0 K11 + 0x8C20110C, // 001E GETMET R8 R8 K12 + 0x5C280A00, // 001F MOVE R10 R5 + 0x7C200400, // 0020 CALL R8 2 + 0xA8040001, // 0021 EXBLK 1 1 + 0x80041000, // 0022 RET 1 R8 + 0x7002012A, // 0023 JMP #014F + 0x881C0B0D, // 0024 GETMBR R7 R5 K13 + 0x1C1C0F0E, // 0025 EQ R7 R7 K14 + 0x781E007F, // 0026 JMPF R7 #00A7 + 0x881C0B0F, // 0027 GETMBR R7 R5 K15 + 0x1C1C0F0E, // 0028 EQ R7 R7 K14 + 0x781E007C, // 0029 JMPF R7 #00A7 + 0x881C0107, // 002A GETMBR R7 R0 K7 + 0x881C0F08, // 002B GETMBR R7 R7 K8 + 0x8C1C0F09, // 002C GETMET R7 R7 K9 + 0x88240B0A, // 002D GETMBR R9 R5 K10 + 0x542A0059, // 002E LDINT R10 90 + 0x7C1C0600, // 002F CALL R7 3 + 0x780A0000, // 0030 JMPF R2 #0032 + 0x901E2002, // 0031 SETMBR R7 K16 R2 + 0x780E0000, // 0032 JMPF R3 #0034 + 0x901E2203, // 0033 SETMBR R7 K17 R3 + 0x901E2400, // 0034 SETMBR R7 K18 R0 + 0x90162607, // 0035 SETMBR R5 K19 R7 + 0x88200F14, // 0036 GETMBR R8 R7 K20 + 0x8C201115, // 0037 GETMET R8 R8 K21 + 0x88280B16, // 0038 GETMBR R10 R5 K22 + 0x502C0000, // 0039 LDBOOL R11 0 0 + 0x7C200600, // 003A CALL R8 3 + 0x74220016, // 003B JMPT R8 #0053 + 0xB8222E00, // 003C GETNGBL R8 K23 + 0x8C201118, // 003D GETMET R8 R8 K24 + 0x542A0003, // 003E LDINT R10 4 + 0x7C200400, // 003F CALL R8 2 + 0x7822000A, // 0040 JMPF R8 #004C + 0xB8222E00, // 0041 GETNGBL R8 K23 + 0x8C201102, // 0042 GETMET R8 R8 K2 + 0x60280018, // 0043 GETGBL R10 G24 + 0x582C0019, // 0044 LDCONST R11 K25 + 0x88300B16, // 0045 GETMBR R12 R5 K22 + 0x88340F14, // 0046 GETMBR R13 R7 K20 + 0x8C341B1A, // 0047 GETMET R13 R13 K26 + 0x7C340200, // 0048 CALL R13 1 + 0x7C280600, // 0049 CALL R10 3 + 0x542E0003, // 004A LDINT R11 4 + 0x7C200600, // 004B CALL R8 3 + 0x8C20011B, // 004C GETMET R8 R0 K27 + 0x5C280A00, // 004D MOVE R10 R5 + 0x502C0000, // 004E LDBOOL R11 0 0 + 0x7C200600, // 004F CALL R8 3 + 0x50200000, // 0050 LDBOOL R8 0 0 + 0xA8040001, // 0051 EXBLK 1 1 + 0x80041000, // 0052 RET 1 R8 + 0x8C200B1C, // 0053 GETMET R8 R5 K28 + 0x7C200200, // 0054 CALL R8 1 + 0x74220002, // 0055 JMPT R8 #0059 + 0x50200000, // 0056 LDBOOL R8 0 0 + 0xA8040001, // 0057 EXBLK 1 1 + 0x80041000, // 0058 RET 1 R8 + 0x88200107, // 0059 GETMBR R8 R0 K7 + 0x8C20111D, // 005A GETMET R8 R8 K29 + 0x5C280A00, // 005B MOVE R10 R5 + 0x7C200400, // 005C CALL R8 2 + 0x88200B1E, // 005D GETMBR R8 R5 K30 + 0x5426000F, // 005E LDINT R9 16 + 0x20201009, // 005F NE R8 R8 R9 + 0x7822001D, // 0060 JMPF R8 #007F + 0xB8220000, // 0061 GETNGBL R8 K0 + 0x8C20111F, // 0062 GETMET R8 R8 K31 + 0x88280B1E, // 0063 GETMBR R10 R5 K30 + 0x7C200400, // 0064 CALL R8 2 + 0x5C241000, // 0065 MOVE R9 R8 + 0x74260004, // 0066 JMPT R9 #006C + 0x60240018, // 0067 GETGBL R9 G24 + 0x58280020, // 0068 LDCONST R10 K32 + 0x882C0B1E, // 0069 GETMBR R11 R5 K30 + 0x7C240400, // 006A CALL R9 2 + 0x5C201200, // 006B MOVE R8 R9 + 0xB8262E00, // 006C GETNGBL R9 K23 + 0x8C241318, // 006D GETMET R9 R9 K24 + 0x582C0021, // 006E LDCONST R11 K33 + 0x7C240400, // 006F CALL R9 2 + 0x7826000C, // 0070 JMPF R9 #007E + 0xB8262E00, // 0071 GETNGBL R9 K23 + 0x8C241302, // 0072 GETMET R9 R9 K2 + 0x602C0018, // 0073 GETGBL R11 G24 + 0x58300022, // 0074 LDCONST R12 K34 + 0x88340F0D, // 0075 GETMBR R13 R7 K13 + 0x5C381000, // 0076 MOVE R14 R8 + 0x883C0B16, // 0077 GETMBR R15 R5 K22 + 0x88400B23, // 0078 GETMBR R16 R5 K35 + 0x5C440400, // 0079 MOVE R17 R2 + 0x5C480600, // 007A MOVE R18 R3 + 0x7C2C0E00, // 007B CALL R11 7 + 0x58300021, // 007C LDCONST R12 K33 + 0x7C240600, // 007D CALL R9 3 + 0x70020018, // 007E JMP #0098 + 0xB8222E00, // 007F GETNGBL R8 K23 + 0x8C201118, // 0080 GETMET R8 R8 K24 + 0x542A0003, // 0081 LDINT R10 4 + 0x7C200400, // 0082 CALL R8 2 + 0x78220013, // 0083 JMPF R8 #0098 + 0xB8222E00, // 0084 GETNGBL R8 K23 + 0x8C201102, // 0085 GETMET R8 R8 K2 + 0x60280018, // 0086 GETGBL R10 G24 + 0x582C0024, // 0087 LDCONST R11 K36 + 0x88300F0D, // 0088 GETMBR R12 R7 K13 + 0x88340B16, // 0089 GETMBR R13 R5 K22 + 0x88380B25, // 008A GETMBR R14 R5 K37 + 0x783A0001, // 008B JMPF R14 #008E + 0x58380026, // 008C LDCONST R14 K38 + 0x70020000, // 008D JMP #008F + 0x58380027, // 008E LDCONST R14 K39 + 0x883C0B23, // 008F GETMBR R15 R5 K35 + 0x60400008, // 0090 GETGBL R16 G8 + 0x88440B28, // 0091 GETMBR R17 R5 K40 + 0x7C400200, // 0092 CALL R16 1 + 0x5C440400, // 0093 MOVE R17 R2 + 0x5C480600, // 0094 MOVE R18 R3 + 0x7C281000, // 0095 CALL R10 8 + 0x542E0003, // 0096 LDINT R11 4 + 0x7C200600, // 0097 CALL R8 3 + 0x88200129, // 0098 GETMBR R8 R0 K41 + 0x8C20112A, // 0099 GETMET R8 R8 K42 + 0x5C280A00, // 009A MOVE R10 R5 + 0x7C200400, // 009B CALL R8 2 + 0x5C101000, // 009C MOVE R4 R8 + 0x5C200800, // 009D MOVE R8 R4 + 0x74220003, // 009E JMPT R8 #00A3 + 0x8C20011B, // 009F GETMET R8 R0 K27 + 0x5C280A00, // 00A0 MOVE R10 R5 + 0x502C0000, // 00A1 LDBOOL R11 0 0 + 0x7C200600, // 00A2 CALL R8 3 + 0x50200200, // 00A3 LDBOOL R8 1 0 + 0xA8040001, // 00A4 EXBLK 1 1 + 0x80041000, // 00A5 RET 1 R8 + 0x700200A7, // 00A6 JMP #014F + 0xB81E2E00, // 00A7 GETNGBL R7 K23 + 0x8C1C0F18, // 00A8 GETMET R7 R7 K24 + 0x54260003, // 00A9 LDINT R9 4 + 0x7C1C0400, // 00AA CALL R7 2 + 0x781E0008, // 00AB JMPF R7 #00B5 + 0xB81E2E00, // 00AC GETNGBL R7 K23 + 0x8C1C0F02, // 00AD GETMET R7 R7 K2 + 0x60240018, // 00AE GETGBL R9 G24 + 0x5828002B, // 00AF LDCONST R10 K43 + 0x882C0B0D, // 00B0 GETMBR R11 R5 K13 + 0x88300B16, // 00B1 GETMBR R12 R5 K22 + 0x7C240600, // 00B2 CALL R9 3 + 0x542A0003, // 00B3 LDINT R10 4 + 0x7C1C0600, // 00B4 CALL R7 3 + 0x881C0107, // 00B5 GETMBR R7 R0 K7 + 0x881C0F08, // 00B6 GETMBR R7 R7 K8 + 0x8C1C0F2C, // 00B7 GETMET R7 R7 K44 + 0x88240B0D, // 00B8 GETMBR R9 R5 K13 + 0x7C1C0400, // 00B9 CALL R7 2 + 0x4C200000, // 00BA LDNIL R8 + 0x1C200E08, // 00BB EQ R8 R7 R8 + 0x7822000A, // 00BC JMPF R8 #00C8 + 0xB8222E00, // 00BD GETNGBL R8 K23 + 0x8C201102, // 00BE GETMET R8 R8 K2 + 0x60280008, // 00BF GETGBL R10 G8 + 0x882C0B0D, // 00C0 GETMBR R11 R5 K13 + 0x7C280200, // 00C1 CALL R10 1 + 0x002A5A0A, // 00C2 ADD R10 K45 R10 + 0x582C0021, // 00C3 LDCONST R11 K33 + 0x7C200600, // 00C4 CALL R8 3 + 0x50200000, // 00C5 LDBOOL R8 0 0 + 0xA8040001, // 00C6 EXBLK 1 1 + 0x80041000, // 00C7 RET 1 R8 + 0x780A0000, // 00C8 JMPF R2 #00CA + 0x901E2002, // 00C9 SETMBR R7 K16 R2 + 0x780E0000, // 00CA JMPF R3 #00CC + 0x901E2203, // 00CB SETMBR R7 K17 R3 + 0x901E2400, // 00CC SETMBR R7 K18 R0 + 0x90162607, // 00CD SETMBR R5 K19 R7 + 0x8C200F2E, // 00CE GETMET R8 R7 K46 + 0x88280B16, // 00CF GETMBR R10 R5 K22 + 0x502C0200, // 00D0 LDBOOL R11 1 0 + 0x7C200600, // 00D1 CALL R8 3 + 0x74220018, // 00D2 JMPT R8 #00EC + 0xB8222E00, // 00D3 GETNGBL R8 K23 + 0x8C201118, // 00D4 GETMET R8 R8 K24 + 0x58280021, // 00D5 LDCONST R10 K33 + 0x7C200400, // 00D6 CALL R8 2 + 0x7822000C, // 00D7 JMPF R8 #00E5 + 0xB8222E00, // 00D8 GETNGBL R8 K23 + 0x8C201102, // 00D9 GETMET R8 R8 K2 + 0x60280008, // 00DA GETGBL R10 G8 + 0x882C0B16, // 00DB GETMBR R11 R5 K22 + 0x7C280200, // 00DC CALL R10 1 + 0x002A5E0A, // 00DD ADD R10 K47 R10 + 0x00281530, // 00DE ADD R10 R10 K48 + 0x602C0008, // 00DF GETGBL R11 G8 + 0x88300F31, // 00E0 GETMBR R12 R7 K49 + 0x7C2C0200, // 00E1 CALL R11 1 + 0x0028140B, // 00E2 ADD R10 R10 R11 + 0x582C0021, // 00E3 LDCONST R11 K33 + 0x7C200600, // 00E4 CALL R8 3 + 0x8C200132, // 00E5 GETMET R8 R0 K50 + 0x5C280A00, // 00E6 MOVE R10 R5 + 0x502C0000, // 00E7 LDBOOL R11 0 0 + 0x7C200600, // 00E8 CALL R8 3 + 0x50200000, // 00E9 LDBOOL R8 0 0 + 0xA8040001, // 00EA EXBLK 1 1 + 0x80041000, // 00EB RET 1 R8 + 0x8C200B33, // 00EC GETMET R8 R5 K51 + 0x7C200200, // 00ED CALL R8 1 + 0xB8260000, // 00EE GETNGBL R9 K0 + 0x88241301, // 00EF GETMBR R9 R9 K1 + 0x8C241302, // 00F0 GETMET R9 R9 K2 + 0x582C0034, // 00F1 LDCONST R11 K52 + 0x7C240400, // 00F2 CALL R9 2 + 0x5C241000, // 00F3 MOVE R9 R8 + 0x74260002, // 00F4 JMPT R9 #00F8 + 0x50240000, // 00F5 LDBOOL R9 0 0 + 0xA8040001, // 00F6 EXBLK 1 1 + 0x80041200, // 00F7 RET 1 R9 + 0x8C240B1C, // 00F8 GETMET R9 R5 K28 + 0x7C240200, // 00F9 CALL R9 1 + 0xB8262E00, // 00FA GETNGBL R9 K23 + 0x8C241318, // 00FB GETMET R9 R9 K24 + 0x542E0003, // 00FC LDINT R11 4 + 0x7C240400, // 00FD CALL R9 2 + 0x78260013, // 00FE JMPF R9 #0113 + 0xB8262E00, // 00FF GETNGBL R9 K23 + 0x8C241302, // 0100 GETMET R9 R9 K2 + 0x602C0008, // 0101 GETGBL R11 G8 + 0x88300B36, // 0102 GETMBR R12 R5 K54 + 0x7C2C0200, // 0103 CALL R11 1 + 0x002E6A0B, // 0104 ADD R11 K53 R11 + 0x002C1737, // 0105 ADD R11 R11 K55 + 0x60300008, // 0106 GETGBL R12 G8 + 0x88340B1E, // 0107 GETMBR R13 R5 K30 + 0x7C300200, // 0108 CALL R12 1 + 0x002C160C, // 0109 ADD R11 R11 R12 + 0x002C1738, // 010A ADD R11 R11 K56 + 0x60300008, // 010B GETGBL R12 G8 + 0x88340B23, // 010C GETMBR R13 R5 K35 + 0x543AFFFE, // 010D LDINT R14 65535 + 0x2C341A0E, // 010E AND R13 R13 R14 + 0x7C300200, // 010F CALL R12 1 + 0x002C160C, // 0110 ADD R11 R11 R12 + 0x54320003, // 0111 LDINT R12 4 + 0x7C240600, // 0112 CALL R9 3 + 0x88240107, // 0113 GETMBR R9 R0 K7 + 0x8C24131D, // 0114 GETMET R9 R9 K29 + 0x5C2C0A00, // 0115 MOVE R11 R5 + 0x7C240400, // 0116 CALL R9 2 + 0x88240B36, // 0117 GETMBR R9 R5 K54 + 0x1C28130E, // 0118 EQ R10 R9 K14 + 0x782A000F, // 0119 JMPF R10 #012A + 0x88280B1E, // 011A GETMBR R10 R5 K30 + 0x542E000F, // 011B LDINT R11 16 + 0x1C28140B, // 011C EQ R10 R10 R11 + 0x782A0009, // 011D JMPF R10 #0128 + 0x88280139, // 011E GETMBR R10 R0 K57 + 0x8C28153A, // 011F GETMET R10 R10 K58 + 0x5C300A00, // 0120 MOVE R12 R5 + 0x7C280400, // 0121 CALL R10 2 + 0x5C101400, // 0122 MOVE R4 R10 + 0x78120003, // 0123 JMPF R4 #0128 + 0x88280139, // 0124 GETMBR R10 R0 K57 + 0x8C28153B, // 0125 GETMET R10 R10 K59 + 0x5C300000, // 0126 MOVE R12 R0 + 0x7C280400, // 0127 CALL R10 2 + 0x50100200, // 0128 LDBOOL R4 1 0 + 0x70020024, // 0129 JMP #014F + 0x1C28133C, // 012A EQ R10 R9 K60 + 0x782A001A, // 012B JMPF R10 #0147 + 0xB82A0000, // 012C GETNGBL R10 K0 + 0x88281501, // 012D GETMBR R10 R10 K1 + 0x8C281502, // 012E GETMET R10 R10 K2 + 0x5830003D, // 012F LDCONST R12 K61 + 0x7C280400, // 0130 CALL R10 2 + 0x88280139, // 0131 GETMBR R10 R0 K57 + 0x8C28152A, // 0132 GETMET R10 R10 K42 + 0x5C300A00, // 0133 MOVE R12 R5 + 0x7C280400, // 0134 CALL R10 2 + 0x5C101400, // 0135 MOVE R4 R10 + 0xB82A0000, // 0136 GETNGBL R10 K0 + 0x88281501, // 0137 GETMBR R10 R10 K1 + 0x8C281502, // 0138 GETMET R10 R10 K2 + 0x5830003E, // 0139 LDCONST R12 K62 + 0x7C280400, // 013A CALL R10 2 + 0x78120004, // 013B JMPF R4 #0141 + 0x88280139, // 013C GETMBR R10 R0 K57 + 0x8C28153B, // 013D GETMET R10 R10 K59 + 0x5C300000, // 013E MOVE R12 R0 + 0x7C280400, // 013F CALL R10 2 + 0x70020003, // 0140 JMP #0145 + 0x8C280132, // 0141 GETMET R10 R0 K50 + 0x5C300A00, // 0142 MOVE R12 R5 + 0x50340200, // 0143 LDBOOL R13 1 0 + 0x7C280600, // 0144 CALL R10 3 + 0x50100200, // 0145 LDBOOL R4 1 0 + 0x70020007, // 0146 JMP #014F + 0xB82A2E00, // 0147 GETNGBL R10 K23 + 0x8C281502, // 0148 GETMET R10 R10 K2 + 0x60300008, // 0149 GETGBL R12 G8 + 0x5C341200, // 014A MOVE R13 R9 + 0x7C300200, // 014B CALL R12 1 + 0x00327E0C, // 014C ADD R12 K63 R12 + 0x58340021, // 014D LDCONST R13 K33 + 0x7C280600, // 014E CALL R10 3 + 0xA8040001, // 014F EXBLK 1 1 + 0x80040800, // 0150 RET 1 R4 + 0xA8040001, // 0151 EXBLK 1 1 + 0x70020018, // 0152 JMP #016C + 0xAC140002, // 0153 CATCH R5 0 2 + 0x70020015, // 0154 JMP #016B + 0xB81E2E00, // 0155 GETNGBL R7 K23 + 0x8C1C0F02, // 0156 GETMET R7 R7 K2 + 0x60240008, // 0157 GETGBL R9 G8 + 0x5C280A00, // 0158 MOVE R10 R5 + 0x7C240200, // 0159 CALL R9 1 + 0x00268009, // 015A ADD R9 K64 R9 + 0x00241341, // 015B ADD R9 R9 K65 + 0x60280008, // 015C GETGBL R10 G8 + 0x5C2C0C00, // 015D MOVE R11 R6 + 0x7C280200, // 015E CALL R10 1 + 0x0024120A, // 015F ADD R9 R9 R10 + 0x58280042, // 0160 LDCONST R10 K66 + 0x7C1C0600, // 0161 CALL R7 3 + 0xB81E2E00, // 0162 GETNGBL R7 K23 + 0x881C0F43, // 0163 GETMBR R7 R7 K67 + 0x781E0002, // 0164 JMPF R7 #0168 + 0xA41E8800, // 0165 IMPORT R7 K68 + 0x8C200F45, // 0166 GETMET R8 R7 K69 + 0x7C200200, // 0167 CALL R8 1 + 0x501C0000, // 0168 LDBOOL R7 0 0 + 0x80040E00, // 0169 RET 1 R7 + 0x70020000, // 016A JMP #016C + 0xB0080000, // 016B RAISE 2 R0 R0 + 0x80000000, // 016C RET 0 }) ) ); @@ -142,66 +592,39 @@ be_local_closure(Matter_MessageHandler_every_second, /* name */ /******************************************************************** -** Solidified function: send_simple_ack +** Solidified function: send_response_frame ********************************************************************/ -be_local_closure(Matter_MessageHandler_send_simple_ack, /* name */ +be_local_closure(Matter_MessageHandler_send_response_frame, /* name */ be_nested_proto( - 14, /* nstack */ - 3, /* argc */ + 5, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[16]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(x_flag_r), - /* K2 */ be_nested_str_weak(build_standalone_ack), - /* K3 */ be_nested_str_weak(encode_frame), - /* K4 */ be_nested_str_weak(tasmota), - /* K5 */ be_nested_str_weak(log), - /* K6 */ be_nested_str_weak(format), - /* K7 */ be_nested_str_weak(MTR_X3A_X20_X3CAck_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20ack_X3D_X25i_X20id_X3D_X25i_X20_X25s), - /* K8 */ be_nested_str_weak(session), - /* K9 */ be_nested_str_weak(local_session_id), - /* K10 */ be_nested_str_weak(ack_message_counter), - /* K11 */ be_nested_str_weak(message_counter), - /* K12 */ be_nested_str_weak(_X7Breliable_X7D), - /* K13 */ be_nested_str_weak(), - /* K14 */ be_const_int(3), - /* K15 */ be_nested_str_weak(send_response_frame), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(profiler), + /* K2 */ be_nested_str_weak(log), + /* K3 */ be_nested_str_weak(send_response_frame), + /* K4 */ be_nested_str_weak(device), + /* K5 */ be_nested_str_weak(msg_send), }), - be_str_weak(send_simple_ack), + be_str_weak(send_response_frame), &be_const_str_solidified, - ( &(const binstruction[27]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0x88100301, // 0001 GETMBR R4 R1 K1 - 0x78120016, // 0002 JMPF R4 #001A - 0x8C100302, // 0003 GETMET R4 R1 K2 - 0x5C180400, // 0004 MOVE R6 R2 - 0x7C100400, // 0005 CALL R4 2 - 0x8C140903, // 0006 GETMET R5 R4 K3 - 0x7C140200, // 0007 CALL R5 1 - 0xB8160800, // 0008 GETNGBL R5 K4 - 0x8C140B05, // 0009 GETMET R5 R5 K5 - 0x8C1C0706, // 000A GETMET R7 R3 K6 - 0x58240007, // 000B LDCONST R9 K7 - 0x88280908, // 000C GETMBR R10 R4 K8 - 0x88281509, // 000D GETMBR R10 R10 K9 - 0x882C090A, // 000E GETMBR R11 R4 K10 - 0x8830090B, // 000F GETMBR R12 R4 K11 - 0x780A0001, // 0010 JMPF R2 #0013 - 0x5834000C, // 0011 LDCONST R13 K12 - 0x70020000, // 0012 JMP #0014 - 0x5834000D, // 0013 LDCONST R13 K13 - 0x7C1C0C00, // 0014 CALL R7 6 - 0x5820000E, // 0015 LDCONST R8 K14 - 0x7C140600, // 0016 CALL R5 3 - 0x8C14010F, // 0017 GETMET R5 R0 K15 - 0x5C1C0800, // 0018 MOVE R7 R4 - 0x7C140400, // 0019 CALL R5 2 - 0x80000000, // 001A RET 0 + ( &(const binstruction[10]) { /* code */ + 0xB80A0000, // 0000 GETNGBL R2 K0 + 0x88080501, // 0001 GETMBR R2 R2 K1 + 0x8C080502, // 0002 GETMET R2 R2 K2 + 0x58100003, // 0003 LDCONST R4 K3 + 0x7C080400, // 0004 CALL R2 2 + 0x88080104, // 0005 GETMBR R2 R0 K4 + 0x8C080505, // 0006 GETMET R2 R2 K5 + 0x5C100200, // 0007 MOVE R4 R1 + 0x7C080400, // 0008 CALL R2 2 + 0x80000000, // 0009 RET 0 }) ) ); @@ -209,489 +632,68 @@ be_local_closure(Matter_MessageHandler_send_simple_ack, /* name */ /******************************************************************** -** Solidified function: msg_received +** Solidified function: send_simple_ack ********************************************************************/ -be_local_closure(Matter_MessageHandler_msg_received, /* name */ +be_local_closure(Matter_MessageHandler_send_simple_ack, /* name */ be_nested_proto( - 24, /* nstack */ - 4, /* argc */ + 12, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[75]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(Frame), - /* K3 */ be_nested_str_weak(decode_header), - /* K4 */ be_nested_str_weak(sec_p), - /* K5 */ be_nested_str_weak(tasmota), - /* K6 */ be_nested_str_weak(log), - /* K7 */ be_nested_str_weak(MTR_X3A_X20CONTROL_X20MESSAGE_X3D), - /* K8 */ be_nested_str_weak(inspect), - /* K9 */ be_nested_str_weak(device), - /* K10 */ be_nested_str_weak(sessions), - /* K11 */ be_nested_str_weak(find_session_source_id_unsecure), - /* K12 */ be_nested_str_weak(source_node_id), - /* K13 */ be_nested_str_weak(MTR_X3A_X20find_X20session_X20by_X20source_node_id_X20_X3D_X20), - /* K14 */ be_nested_str_weak(_X20session_id_X20_X3D_X20), - /* K15 */ be_nested_str_weak(local_session_id), - /* K16 */ be_nested_str_weak(control_message), - /* K17 */ be_nested_str_weak(process_incoming_control_message), - /* K18 */ be_const_int(0), - /* K19 */ be_nested_str_weak(sec_sesstype), - /* K20 */ be_nested_str_weak(_ip), - /* K21 */ be_nested_str_weak(_port), - /* K22 */ be_nested_str_weak(_message_handler), - /* K23 */ be_nested_str_weak(session), - /* K24 */ be_nested_str_weak(_counter_insecure_rcv), - /* K25 */ be_nested_str_weak(validate), - /* K26 */ be_nested_str_weak(message_counter), - /* K27 */ be_nested_str_weak(format), - /* K28 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Duplicate_X20unencrypted_X20message_X20_X3D_X20_X25i_X20ref_X20_X3D_X20_X25i), - /* K29 */ be_nested_str_weak(val), - /* K30 */ be_const_int(3), - /* K31 */ be_nested_str_weak(send_simple_ack), - /* K32 */ be_nested_str_weak(decode_payload), - /* K33 */ be_nested_str_weak(received_ack), - /* K34 */ be_nested_str_weak(opcode), - /* K35 */ be_nested_str_weak(get_opcode_name), - /* K36 */ be_nested_str_weak(0x_X2502X), - /* K37 */ be_nested_str_weak(MTR_X3A_X20_X3EReceived_X20_X20_X28_X256i_X29_X20_X25s_X20rid_X3D_X25i_X20exch_X3D_X25i_X20from_X20_X5B_X25s_X5D_X3A_X25i), - /* K38 */ be_nested_str_weak(exchange_id), - /* K39 */ be_const_int(2), - /* K40 */ be_nested_str_weak(MTR_X3A_X20_X3Ercv_X20Ack_X20_X20_X20_X28_X256i_X29_X20rid_X3D_X25i_X20exch_X3D_X25i_X20ack_X3D_X25s_X20_X25sfrom_X20_X5B_X25s_X5D_X3A_X25i), - /* K41 */ be_nested_str_weak(x_flag_r), - /* K42 */ be_nested_str_weak(_X7Breliable_X7D_X20), - /* K43 */ be_nested_str_weak(), - /* K44 */ be_nested_str_weak(ack_message_counter), - /* K45 */ be_nested_str_weak(commissioning), - /* K46 */ be_nested_str_weak(process_incoming), - /* K47 */ be_nested_str_weak(MTR_X3A_X20decode_X20header_X3A_X20local_session_id_X3D_X25i_X20message_counter_X3D_X25i), - /* K48 */ be_nested_str_weak(get_session_by_local_session_id), - /* K49 */ be_nested_str_weak(MTR_X3A_X20unknown_X20local_session_id_X3D), - /* K50 */ be_nested_str_weak(counter_rcv_validate), - /* K51 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Duplicate_X20encrypted_X20message_X20_X3D_X20), - /* K52 */ be_nested_str_weak(_X20counter_X3D), - /* K53 */ be_nested_str_weak(counter_rcv), - /* K54 */ be_nested_str_weak(send_encrypted_ack), - /* K55 */ be_nested_str_weak(decrypt), - /* K56 */ be_nested_str_weak(raw), - /* K57 */ be_nested_str_weak(payload_idx), - /* K58 */ be_const_int(1), - /* K59 */ be_nested_str_weak(MTR_X3A_X20idx_X3D_X25i_X20clear_X3D_X25s), - /* K60 */ be_nested_str_weak(tohex), - /* K61 */ be_nested_str_weak(MTR_X3A_X20_X3E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Decrypted_X20message_X3A_X20protocol_id_X3A), - /* K62 */ be_nested_str_weak(protocol_id), - /* K63 */ be_nested_str_weak(_X20opcode_X3D), - /* K64 */ be_nested_str_weak(_X20exchange_id_X3D), - /* K65 */ be_nested_str_weak(MTR_X3A_X20_X3Ercv_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20_X5B_X2502X_X2F_X2502X_X5D_X20rid_X3D_X25i_X20exch_X3D_X25i_X20ack_X3D_X25s_X20_X25sfrom_X20_X5B_X25s_X5D_X3A_X25i), - /* K66 */ be_nested_str_weak(im), - /* K67 */ be_nested_str_weak(process_incoming_ack), - /* K68 */ be_nested_str_weak(send_enqueued), - /* K69 */ be_nested_str_weak(MTR_X3A_X20ignoring_X20unhandled_X20protocol_id_X3A), - /* K70 */ be_nested_str_weak(MTR_X3A_X20MessageHandler_X3A_X3Amsg_received_X20exception_X3A_X20), - /* K71 */ be_nested_str_weak(_X3B), - /* K72 */ be_nested_str_weak(_debug_present), - /* K73 */ be_nested_str_weak(debug), - /* K74 */ be_nested_str_weak(traceback), + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(x_flag_r), + /* K1 */ be_nested_str_weak(build_standalone_ack), + /* K2 */ be_nested_str_weak(encode_frame), + /* K3 */ be_nested_str_weak(tasmota), + /* K4 */ be_nested_str_weak(loglevel), + /* K5 */ be_nested_str_weak(log), + /* K6 */ be_nested_str_weak(MTR_X3A_X20_X3CAck_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20ack_X3D_X25i_X20id_X3D_X25i_X20_X25s), + /* K7 */ be_nested_str_weak(session), + /* K8 */ be_nested_str_weak(local_session_id), + /* K9 */ be_nested_str_weak(ack_message_counter), + /* K10 */ be_nested_str_weak(message_counter), + /* K11 */ be_nested_str_weak(_X7Breliable_X7D), + /* K12 */ be_nested_str_weak(), + /* K13 */ be_nested_str_weak(send_response_frame), }), - be_str_weak(msg_received), + be_str_weak(send_simple_ack), &be_const_str_solidified, - ( &(const binstruction[391]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0x50140000, // 0001 LDBOOL R5 0 0 - 0xA802016A, // 0002 EXBLK 0 #016E - 0xB81A0200, // 0003 GETNGBL R6 K1 - 0x8C180D02, // 0004 GETMET R6 R6 K2 - 0x5C200000, // 0005 MOVE R8 R0 - 0x5C240200, // 0006 MOVE R9 R1 - 0x5C280400, // 0007 MOVE R10 R2 - 0x5C2C0600, // 0008 MOVE R11 R3 - 0x7C180A00, // 0009 CALL R6 5 - 0x8C1C0D03, // 000A GETMET R7 R6 K3 - 0x7C1C0200, // 000B CALL R7 1 - 0x5C200E00, // 000C MOVE R8 R7 - 0x74220002, // 000D JMPT R8 #0011 - 0x50200000, // 000E LDBOOL R8 0 0 - 0xA8040001, // 000F EXBLK 1 1 - 0x80041000, // 0010 RET 1 R8 - 0x88200D04, // 0011 GETMBR R8 R6 K4 - 0x78220022, // 0012 JMPF R8 #0036 - 0xB8220A00, // 0013 GETNGBL R8 K5 - 0x8C201106, // 0014 GETMET R8 R8 K6 - 0xB82A0200, // 0015 GETNGBL R10 K1 - 0x8C281508, // 0016 GETMET R10 R10 K8 - 0x5C300C00, // 0017 MOVE R12 R6 - 0x7C280400, // 0018 CALL R10 2 - 0x002A0E0A, // 0019 ADD R10 K7 R10 - 0x542E0003, // 001A LDINT R11 4 - 0x7C200600, // 001B CALL R8 3 - 0x88200109, // 001C GETMBR R8 R0 K9 - 0x8820110A, // 001D GETMBR R8 R8 K10 - 0x8C20110B, // 001E GETMET R8 R8 K11 - 0x88280D0C, // 001F GETMBR R10 R6 K12 - 0x542E0059, // 0020 LDINT R11 90 - 0x7C200600, // 0021 CALL R8 3 - 0xB8260A00, // 0022 GETNGBL R9 K5 - 0x8C241306, // 0023 GETMET R9 R9 K6 - 0x602C0008, // 0024 GETGBL R11 G8 - 0x88300D0C, // 0025 GETMBR R12 R6 K12 - 0x7C2C0200, // 0026 CALL R11 1 - 0x002E1A0B, // 0027 ADD R11 K13 R11 - 0x002C170E, // 0028 ADD R11 R11 K14 - 0x60300008, // 0029 GETGBL R12 G8 - 0x8834110F, // 002A GETMBR R13 R8 K15 - 0x7C300200, // 002B CALL R12 1 - 0x002C160C, // 002C ADD R11 R11 R12 - 0x54320003, // 002D LDINT R12 4 - 0x7C240600, // 002E CALL R9 3 - 0x88240110, // 002F GETMBR R9 R0 K16 - 0x8C241311, // 0030 GETMET R9 R9 K17 - 0x5C2C0C00, // 0031 MOVE R11 R6 - 0x7C240400, // 0032 CALL R9 2 - 0xA8040001, // 0033 EXBLK 1 1 - 0x80041200, // 0034 RET 1 R9 - 0x70020133, // 0035 JMP #016A - 0x88200D0F, // 0036 GETMBR R8 R6 K15 - 0x1C201112, // 0037 EQ R8 R8 K18 - 0x7822007D, // 0038 JMPF R8 #00B7 - 0x88200D13, // 0039 GETMBR R8 R6 K19 - 0x1C201112, // 003A EQ R8 R8 K18 - 0x7822007A, // 003B JMPF R8 #00B7 - 0x88200109, // 003C GETMBR R8 R0 K9 - 0x8820110A, // 003D GETMBR R8 R8 K10 - 0x8C20110B, // 003E GETMET R8 R8 K11 - 0x88280D0C, // 003F GETMBR R10 R6 K12 - 0x542E0059, // 0040 LDINT R11 90 - 0x7C200600, // 0041 CALL R8 3 - 0xB8260A00, // 0042 GETNGBL R9 K5 - 0x8C241306, // 0043 GETMET R9 R9 K6 - 0x602C0008, // 0044 GETGBL R11 G8 - 0x88300D0C, // 0045 GETMBR R12 R6 K12 - 0x7C2C0200, // 0046 CALL R11 1 - 0x002E1A0B, // 0047 ADD R11 K13 R11 - 0x002C170E, // 0048 ADD R11 R11 K14 - 0x60300008, // 0049 GETGBL R12 G8 - 0x8834110F, // 004A GETMBR R13 R8 K15 - 0x7C300200, // 004B CALL R12 1 - 0x002C160C, // 004C ADD R11 R11 R12 - 0x54320003, // 004D LDINT R12 4 - 0x7C240600, // 004E CALL R9 3 - 0x780A0000, // 004F JMPF R2 #0051 - 0x90222802, // 0050 SETMBR R8 K20 R2 - 0x780E0000, // 0051 JMPF R3 #0053 - 0x90222A03, // 0052 SETMBR R8 K21 R3 - 0x90222C00, // 0053 SETMBR R8 K22 R0 - 0x901A2E08, // 0054 SETMBR R6 K23 R8 - 0x88241118, // 0055 GETMBR R9 R8 K24 - 0x8C241319, // 0056 GETMET R9 R9 K25 - 0x882C0D1A, // 0057 GETMBR R11 R6 K26 - 0x50300000, // 0058 LDBOOL R12 0 0 - 0x7C240600, // 0059 CALL R9 3 - 0x74260011, // 005A JMPT R9 #006D - 0xB8260A00, // 005B GETNGBL R9 K5 - 0x8C241306, // 005C GETMET R9 R9 K6 - 0x8C2C091B, // 005D GETMET R11 R4 K27 - 0x5834001C, // 005E LDCONST R13 K28 - 0x88380D1A, // 005F GETMBR R14 R6 K26 - 0x883C1118, // 0060 GETMBR R15 R8 K24 - 0x8C3C1F1D, // 0061 GETMET R15 R15 K29 - 0x7C3C0200, // 0062 CALL R15 1 - 0x7C2C0800, // 0063 CALL R11 4 - 0x5830001E, // 0064 LDCONST R12 K30 - 0x7C240600, // 0065 CALL R9 3 - 0x8C24011F, // 0066 GETMET R9 R0 K31 - 0x5C2C0C00, // 0067 MOVE R11 R6 - 0x50300000, // 0068 LDBOOL R12 0 0 - 0x7C240600, // 0069 CALL R9 3 - 0x50240000, // 006A LDBOOL R9 0 0 - 0xA8040001, // 006B EXBLK 1 1 - 0x80041200, // 006C RET 1 R9 - 0x8C240D20, // 006D GETMET R9 R6 K32 - 0x7C240200, // 006E CALL R9 1 - 0x74260002, // 006F JMPT R9 #0073 - 0x50240000, // 0070 LDBOOL R9 0 0 - 0xA8040001, // 0071 EXBLK 1 1 - 0x80041200, // 0072 RET 1 R9 - 0x88240109, // 0073 GETMBR R9 R0 K9 - 0x8C241321, // 0074 GETMET R9 R9 K33 - 0x5C2C0C00, // 0075 MOVE R11 R6 - 0x7C240400, // 0076 CALL R9 2 - 0x88240D22, // 0077 GETMBR R9 R6 K34 - 0x542A000F, // 0078 LDINT R10 16 - 0x2024120A, // 0079 NE R9 R9 R10 - 0x78260018, // 007A JMPF R9 #0094 - 0xB8260200, // 007B GETNGBL R9 K1 - 0x8C241323, // 007C GETMET R9 R9 K35 - 0x882C0D22, // 007D GETMBR R11 R6 K34 - 0x7C240400, // 007E CALL R9 2 - 0x5C281200, // 007F MOVE R10 R9 - 0x742A0004, // 0080 JMPT R10 #0086 - 0x8C28091B, // 0081 GETMET R10 R4 K27 - 0x58300024, // 0082 LDCONST R12 K36 - 0x88340D22, // 0083 GETMBR R13 R6 K34 - 0x7C280600, // 0084 CALL R10 3 - 0x5C241400, // 0085 MOVE R9 R10 - 0xB82A0A00, // 0086 GETNGBL R10 K5 - 0x8C281506, // 0087 GETMET R10 R10 K6 - 0x8C30091B, // 0088 GETMET R12 R4 K27 - 0x58380025, // 0089 LDCONST R14 K37 - 0x883C110F, // 008A GETMBR R15 R8 K15 - 0x5C401200, // 008B MOVE R16 R9 - 0x88440D1A, // 008C GETMBR R17 R6 K26 - 0x88480D26, // 008D GETMBR R18 R6 K38 - 0x5C4C0400, // 008E MOVE R19 R2 - 0x5C500600, // 008F MOVE R20 R3 - 0x7C301000, // 0090 CALL R12 8 - 0x58340027, // 0091 LDCONST R13 K39 - 0x7C280600, // 0092 CALL R10 3 - 0x70020013, // 0093 JMP #00A8 - 0xB8260A00, // 0094 GETNGBL R9 K5 - 0x8C241306, // 0095 GETMET R9 R9 K6 - 0x8C2C091B, // 0096 GETMET R11 R4 K27 - 0x58340028, // 0097 LDCONST R13 K40 - 0x8838110F, // 0098 GETMBR R14 R8 K15 - 0x883C0D1A, // 0099 GETMBR R15 R6 K26 - 0x88400D29, // 009A GETMBR R16 R6 K41 - 0x78420001, // 009B JMPF R16 #009E - 0x5840002A, // 009C LDCONST R16 K42 - 0x70020000, // 009D JMP #009F - 0x5840002B, // 009E LDCONST R16 K43 - 0x88440D26, // 009F GETMBR R17 R6 K38 - 0x60480008, // 00A0 GETGBL R18 G8 - 0x884C0D2C, // 00A1 GETMBR R19 R6 K44 - 0x7C480200, // 00A2 CALL R18 1 - 0x5C4C0400, // 00A3 MOVE R19 R2 - 0x5C500600, // 00A4 MOVE R20 R3 - 0x7C2C1200, // 00A5 CALL R11 9 - 0x5830001E, // 00A6 LDCONST R12 K30 - 0x7C240600, // 00A7 CALL R9 3 - 0x8824012D, // 00A8 GETMBR R9 R0 K45 - 0x8C24132E, // 00A9 GETMET R9 R9 K46 - 0x5C2C0C00, // 00AA MOVE R11 R6 - 0x7C240400, // 00AB CALL R9 2 - 0x5C141200, // 00AC MOVE R5 R9 - 0x5C240A00, // 00AD MOVE R9 R5 - 0x74260003, // 00AE JMPT R9 #00B3 - 0x8C24011F, // 00AF GETMET R9 R0 K31 - 0x5C2C0C00, // 00B0 MOVE R11 R6 - 0x50300000, // 00B1 LDBOOL R12 0 0 - 0x7C240600, // 00B2 CALL R9 3 - 0x50240200, // 00B3 LDBOOL R9 1 0 - 0xA8040001, // 00B4 EXBLK 1 1 - 0x80041200, // 00B5 RET 1 R9 - 0x700200B2, // 00B6 JMP #016A - 0xB8220A00, // 00B7 GETNGBL R8 K5 - 0x8C201106, // 00B8 GETMET R8 R8 K6 - 0x8C28091B, // 00B9 GETMET R10 R4 K27 - 0x5830002F, // 00BA LDCONST R12 K47 - 0x88340D0F, // 00BB GETMBR R13 R6 K15 - 0x88380D1A, // 00BC GETMBR R14 R6 K26 - 0x7C280800, // 00BD CALL R10 4 - 0x582C001E, // 00BE LDCONST R11 K30 - 0x7C200600, // 00BF CALL R8 3 - 0x88200109, // 00C0 GETMBR R8 R0 K9 - 0x8820110A, // 00C1 GETMBR R8 R8 K10 - 0x8C201130, // 00C2 GETMET R8 R8 K48 - 0x88280D0F, // 00C3 GETMBR R10 R6 K15 - 0x7C200400, // 00C4 CALL R8 2 - 0x4C240000, // 00C5 LDNIL R9 - 0x1C241009, // 00C6 EQ R9 R8 R9 - 0x7826000A, // 00C7 JMPF R9 #00D3 - 0xB8260A00, // 00C8 GETNGBL R9 K5 - 0x8C241306, // 00C9 GETMET R9 R9 K6 - 0x602C0008, // 00CA GETGBL R11 G8 - 0x88300D0F, // 00CB GETMBR R12 R6 K15 - 0x7C2C0200, // 00CC CALL R11 1 - 0x002E620B, // 00CD ADD R11 K49 R11 - 0x58300027, // 00CE LDCONST R12 K39 - 0x7C240600, // 00CF CALL R9 3 - 0x50240000, // 00D0 LDBOOL R9 0 0 - 0xA8040001, // 00D1 EXBLK 1 1 - 0x80041200, // 00D2 RET 1 R9 - 0x780A0000, // 00D3 JMPF R2 #00D5 - 0x90222802, // 00D4 SETMBR R8 K20 R2 - 0x780E0000, // 00D5 JMPF R3 #00D7 - 0x90222A03, // 00D6 SETMBR R8 K21 R3 - 0x90222C00, // 00D7 SETMBR R8 K22 R0 - 0x901A2E08, // 00D8 SETMBR R6 K23 R8 - 0x8C241132, // 00D9 GETMET R9 R8 K50 - 0x882C0D1A, // 00DA GETMBR R11 R6 K26 - 0x50300200, // 00DB LDBOOL R12 1 0 - 0x7C240600, // 00DC CALL R9 3 - 0x74260013, // 00DD JMPT R9 #00F2 - 0xB8260A00, // 00DE GETNGBL R9 K5 - 0x8C241306, // 00DF GETMET R9 R9 K6 - 0x602C0008, // 00E0 GETGBL R11 G8 - 0x88300D1A, // 00E1 GETMBR R12 R6 K26 - 0x7C2C0200, // 00E2 CALL R11 1 - 0x002E660B, // 00E3 ADD R11 K51 R11 - 0x002C1734, // 00E4 ADD R11 R11 K52 - 0x60300008, // 00E5 GETGBL R12 G8 - 0x88341135, // 00E6 GETMBR R13 R8 K53 - 0x7C300200, // 00E7 CALL R12 1 - 0x002C160C, // 00E8 ADD R11 R11 R12 - 0x5830001E, // 00E9 LDCONST R12 K30 - 0x7C240600, // 00EA CALL R9 3 - 0x8C240136, // 00EB GETMET R9 R0 K54 - 0x5C2C0C00, // 00EC MOVE R11 R6 - 0x50300000, // 00ED LDBOOL R12 0 0 - 0x7C240600, // 00EE CALL R9 3 - 0x50240000, // 00EF LDBOOL R9 0 0 - 0xA8040001, // 00F0 EXBLK 1 1 - 0x80041200, // 00F1 RET 1 R9 - 0x8C240D37, // 00F2 GETMET R9 R6 K55 - 0x7C240200, // 00F3 CALL R9 1 - 0x5C281200, // 00F4 MOVE R10 R9 - 0x742A0002, // 00F5 JMPT R10 #00F9 - 0x50280000, // 00F6 LDBOOL R10 0 0 - 0xA8040001, // 00F7 EXBLK 1 1 - 0x80041400, // 00F8 RET 1 R10 - 0x88280D39, // 00F9 GETMBR R10 R6 K57 - 0x0428153A, // 00FA SUB R10 R10 K58 - 0x402A240A, // 00FB CONNECT R10 K18 R10 - 0x882C0D38, // 00FC GETMBR R11 R6 K56 - 0x9428160A, // 00FD GETIDX R10 R11 R10 - 0x901A700A, // 00FE SETMBR R6 K56 R10 - 0x88280D38, // 00FF GETMBR R10 R6 K56 - 0x40281409, // 0100 CONNECT R10 R10 R9 - 0xB82A0A00, // 0101 GETNGBL R10 K5 - 0x8C281506, // 0102 GETMET R10 R10 K6 - 0x8C30091B, // 0103 GETMET R12 R4 K27 - 0x5838003B, // 0104 LDCONST R14 K59 - 0x883C0D39, // 0105 GETMBR R15 R6 K57 - 0x88400D38, // 0106 GETMBR R16 R6 K56 - 0x8C40213C, // 0107 GETMET R16 R16 K60 - 0x7C400200, // 0108 CALL R16 1 - 0x7C300800, // 0109 CALL R12 4 - 0x54360003, // 010A LDINT R13 4 - 0x7C280600, // 010B CALL R10 3 - 0x8C280D20, // 010C GETMET R10 R6 K32 - 0x7C280200, // 010D CALL R10 1 - 0xB82A0A00, // 010E GETNGBL R10 K5 - 0x8C281506, // 010F GETMET R10 R10 K6 - 0x60300008, // 0110 GETGBL R12 G8 - 0x88340D3E, // 0111 GETMBR R13 R6 K62 - 0x7C300200, // 0112 CALL R12 1 - 0x00327A0C, // 0113 ADD R12 K61 R12 - 0x0030193F, // 0114 ADD R12 R12 K63 - 0x60340008, // 0115 GETGBL R13 G8 - 0x88380D22, // 0116 GETMBR R14 R6 K34 - 0x7C340200, // 0117 CALL R13 1 - 0x0030180D, // 0118 ADD R12 R12 R13 - 0x00301940, // 0119 ADD R12 R12 K64 - 0x60340008, // 011A GETGBL R13 G8 - 0x88380D26, // 011B GETMBR R14 R6 K38 - 0x543EFFFE, // 011C LDINT R15 65535 - 0x2C381C0F, // 011D AND R14 R14 R15 - 0x7C340200, // 011E CALL R13 1 - 0x0030180D, // 011F ADD R12 R12 R13 - 0x5834001E, // 0120 LDCONST R13 K30 - 0x7C280600, // 0121 CALL R10 3 - 0xB82A0A00, // 0122 GETNGBL R10 K5 - 0x8C281506, // 0123 GETMET R10 R10 K6 - 0x8C30091B, // 0124 GETMET R12 R4 K27 - 0x58380041, // 0125 LDCONST R14 K65 - 0x883C110F, // 0126 GETMBR R15 R8 K15 - 0x88400D3E, // 0127 GETMBR R16 R6 K62 - 0x88440D22, // 0128 GETMBR R17 R6 K34 - 0x88480D1A, // 0129 GETMBR R18 R6 K26 - 0x884C0D26, // 012A GETMBR R19 R6 K38 - 0x60500008, // 012B GETGBL R20 G8 - 0x88540D2C, // 012C GETMBR R21 R6 K44 - 0x7C500200, // 012D CALL R20 1 - 0x88540D29, // 012E GETMBR R21 R6 K41 - 0x78560001, // 012F JMPF R21 #0132 - 0x5854002A, // 0130 LDCONST R21 K42 - 0x70020000, // 0131 JMP #0133 - 0x5854002B, // 0132 LDCONST R21 K43 - 0x5C580400, // 0133 MOVE R22 R2 - 0x5C5C0600, // 0134 MOVE R23 R3 - 0x7C301600, // 0135 CALL R12 11 - 0x5834001E, // 0136 LDCONST R13 K30 - 0x7C280600, // 0137 CALL R10 3 - 0x88280109, // 0138 GETMBR R10 R0 K9 - 0x8C281521, // 0139 GETMET R10 R10 K33 - 0x5C300C00, // 013A MOVE R12 R6 - 0x7C280400, // 013B CALL R10 2 - 0x88280D3E, // 013C GETMBR R10 R6 K62 - 0x1C2C1512, // 013D EQ R11 R10 K18 - 0x782E000F, // 013E JMPF R11 #014F - 0x882C0D22, // 013F GETMBR R11 R6 K34 - 0x5432000F, // 0140 LDINT R12 16 - 0x1C2C160C, // 0141 EQ R11 R11 R12 - 0x782E0009, // 0142 JMPF R11 #014D - 0x882C0142, // 0143 GETMBR R11 R0 K66 - 0x8C2C1743, // 0144 GETMET R11 R11 K67 - 0x5C340C00, // 0145 MOVE R13 R6 - 0x7C2C0400, // 0146 CALL R11 2 - 0x5C141600, // 0147 MOVE R5 R11 - 0x78160003, // 0148 JMPF R5 #014D - 0x882C0142, // 0149 GETMBR R11 R0 K66 - 0x8C2C1744, // 014A GETMET R11 R11 K68 - 0x5C340000, // 014B MOVE R13 R0 - 0x7C2C0400, // 014C CALL R11 2 - 0x50140200, // 014D LDBOOL R5 1 0 - 0x7002001A, // 014E JMP #016A - 0x1C2C153A, // 014F EQ R11 R10 K58 - 0x782E0010, // 0150 JMPF R11 #0162 - 0x882C0142, // 0151 GETMBR R11 R0 K66 - 0x8C2C172E, // 0152 GETMET R11 R11 K46 - 0x5C340C00, // 0153 MOVE R13 R6 - 0x7C2C0400, // 0154 CALL R11 2 - 0x5C141600, // 0155 MOVE R5 R11 - 0x78160004, // 0156 JMPF R5 #015C - 0x882C0142, // 0157 GETMBR R11 R0 K66 - 0x8C2C1744, // 0158 GETMET R11 R11 K68 - 0x5C340000, // 0159 MOVE R13 R0 - 0x7C2C0400, // 015A CALL R11 2 - 0x70020003, // 015B JMP #0160 - 0x8C2C0136, // 015C GETMET R11 R0 K54 - 0x5C340C00, // 015D MOVE R13 R6 - 0x50380200, // 015E LDBOOL R14 1 0 - 0x7C2C0600, // 015F CALL R11 3 - 0x50140200, // 0160 LDBOOL R5 1 0 - 0x70020007, // 0161 JMP #016A - 0xB82E0A00, // 0162 GETNGBL R11 K5 - 0x8C2C1706, // 0163 GETMET R11 R11 K6 - 0x60340008, // 0164 GETGBL R13 G8 - 0x5C381400, // 0165 MOVE R14 R10 - 0x7C340200, // 0166 CALL R13 1 - 0x00368A0D, // 0167 ADD R13 K69 R13 - 0x5838001E, // 0168 LDCONST R14 K30 - 0x7C2C0600, // 0169 CALL R11 3 - 0xA8040001, // 016A EXBLK 1 1 - 0x80040A00, // 016B RET 1 R5 - 0xA8040001, // 016C EXBLK 1 1 - 0x70020017, // 016D JMP #0186 - 0xAC180002, // 016E CATCH R6 0 2 - 0x70020014, // 016F JMP #0185 - 0xB8220A00, // 0170 GETNGBL R8 K5 - 0x8C201106, // 0171 GETMET R8 R8 K6 - 0x60280008, // 0172 GETGBL R10 G8 - 0x5C2C0C00, // 0173 MOVE R11 R6 - 0x7C280200, // 0174 CALL R10 1 - 0x002A8C0A, // 0175 ADD R10 K70 R10 - 0x00281547, // 0176 ADD R10 R10 K71 - 0x602C0008, // 0177 GETGBL R11 G8 - 0x5C300E00, // 0178 MOVE R12 R7 - 0x7C2C0200, // 0179 CALL R11 1 - 0x0028140B, // 017A ADD R10 R10 R11 - 0x7C200400, // 017B CALL R8 2 - 0xB8220A00, // 017C GETNGBL R8 K5 - 0x88201148, // 017D GETMBR R8 R8 K72 - 0x78220002, // 017E JMPF R8 #0182 - 0xA4229200, // 017F IMPORT R8 K73 - 0x8C24114A, // 0180 GETMET R9 R8 K74 - 0x7C240200, // 0181 CALL R9 1 - 0x50200000, // 0182 LDBOOL R8 0 0 - 0x80041000, // 0183 RET 1 R8 - 0x70020000, // 0184 JMP #0186 - 0xB0080000, // 0185 RAISE 2 R0 R0 - 0x80000000, // 0186 RET 0 + ( &(const binstruction[31]) { /* code */ + 0x880C0300, // 0000 GETMBR R3 R1 K0 + 0x780E001B, // 0001 JMPF R3 #001E + 0x8C0C0301, // 0002 GETMET R3 R1 K1 + 0x5C140400, // 0003 MOVE R5 R2 + 0x7C0C0400, // 0004 CALL R3 2 + 0x8C100702, // 0005 GETMET R4 R3 K2 + 0x7C100200, // 0006 CALL R4 1 + 0xB8120600, // 0007 GETNGBL R4 K3 + 0x8C100904, // 0008 GETMET R4 R4 K4 + 0x541A0003, // 0009 LDINT R6 4 + 0x7C100400, // 000A CALL R4 2 + 0x7812000E, // 000B JMPF R4 #001B + 0xB8120600, // 000C GETNGBL R4 K3 + 0x8C100905, // 000D GETMET R4 R4 K5 + 0x60180018, // 000E GETGBL R6 G24 + 0x581C0006, // 000F LDCONST R7 K6 + 0x88200707, // 0010 GETMBR R8 R3 K7 + 0x88201108, // 0011 GETMBR R8 R8 K8 + 0x88240709, // 0012 GETMBR R9 R3 K9 + 0x8828070A, // 0013 GETMBR R10 R3 K10 + 0x780A0001, // 0014 JMPF R2 #0017 + 0x582C000B, // 0015 LDCONST R11 K11 + 0x70020000, // 0016 JMP #0018 + 0x582C000C, // 0017 LDCONST R11 K12 + 0x7C180A00, // 0018 CALL R6 5 + 0x541E0003, // 0019 LDINT R7 4 + 0x7C100600, // 001A CALL R4 3 + 0x8C10010D, // 001B GETMET R4 R0 K13 + 0x5C180600, // 001C MOVE R6 R3 + 0x7C100400, // 001D CALL R4 2 + 0x80000000, // 001E RET 0 }) ) ); @@ -729,48 +731,33 @@ be_local_closure(Matter_MessageHandler_every_250ms, /* name */ /******************************************************************** -** Solidified function: init +** Solidified function: every_second ********************************************************************/ -be_local_closure(Matter_MessageHandler_init, /* name */ +be_local_closure(Matter_MessageHandler_every_second, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 3, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(device), - /* K1 */ be_nested_str_weak(commissioning), - /* K2 */ be_nested_str_weak(matter), - /* K3 */ be_nested_str_weak(Commisioning_Context), - /* K4 */ be_nested_str_weak(im), - /* K5 */ be_nested_str_weak(IM), - /* K6 */ be_nested_str_weak(control_message), - /* K7 */ be_nested_str_weak(Control_Message), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(commissioning), + /* K1 */ be_nested_str_weak(every_second), + /* K2 */ be_nested_str_weak(im), }), - be_str_weak(init), + be_str_weak(every_second), &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0x90020001, // 0000 SETMBR R0 K0 R1 - 0xB80A0400, // 0001 GETNGBL R2 K2 - 0x8C080503, // 0002 GETMET R2 R2 K3 - 0x5C100000, // 0003 MOVE R4 R0 - 0x7C080400, // 0004 CALL R2 2 - 0x90020202, // 0005 SETMBR R0 K1 R2 - 0xB80A0400, // 0006 GETNGBL R2 K2 - 0x8C080505, // 0007 GETMET R2 R2 K5 - 0x5C100200, // 0008 MOVE R4 R1 - 0x7C080400, // 0009 CALL R2 2 - 0x90020802, // 000A SETMBR R0 K4 R2 - 0xB80A0400, // 000B GETNGBL R2 K2 - 0x8C080507, // 000C GETMET R2 R2 K7 - 0x5C100000, // 000D MOVE R4 R0 - 0x7C080400, // 000E CALL R2 2 - 0x90020C02, // 000F SETMBR R0 K6 R2 - 0x80000000, // 0010 RET 0 + ( &(const binstruction[ 7]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x88040102, // 0003 GETMBR R1 R0 K2 + 0x8C040301, // 0004 GETMET R1 R1 K1 + 0x7C040200, // 0005 CALL R1 1 + 0x80000000, // 0006 RET 0 }) ) ); @@ -781,21 +768,22 @@ be_local_closure(Matter_MessageHandler_init, /* name */ ** Solidified class: Matter_MessageHandler ********************************************************************/ be_local_class(Matter_MessageHandler, - 4, + 5, NULL, - be_nested_map(11, + be_nested_map(12, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(im, 3), be_const_var(2) }, - { be_const_key_weak(init, -1), be_const_closure(Matter_MessageHandler_init_closure) }, + { be_const_key_weak(commissioning, -1), be_const_var(1) }, + { be_const_key_weak(_n_bytes, 7), be_const_var(4) }, { be_const_key_weak(send_encrypted_ack, -1), be_const_closure(Matter_MessageHandler_send_encrypted_ack_closure) }, + { be_const_key_weak(init, 5), be_const_closure(Matter_MessageHandler_init_closure) }, + { be_const_key_weak(msg_received, -1), be_const_closure(Matter_MessageHandler_msg_received_closure) }, + { be_const_key_weak(im, 11), be_const_var(2) }, { be_const_key_weak(every_second, -1), be_const_closure(Matter_MessageHandler_every_second_closure) }, { be_const_key_weak(every_250ms, -1), be_const_closure(Matter_MessageHandler_every_250ms_closure) }, - { be_const_key_weak(device, -1), be_const_var(0) }, - { be_const_key_weak(msg_received, -1), be_const_closure(Matter_MessageHandler_msg_received_closure) }, - { be_const_key_weak(control_message, 4), be_const_var(3) }, - { be_const_key_weak(commissioning, -1), be_const_var(1) }, { be_const_key_weak(send_simple_ack, 1), be_const_closure(Matter_MessageHandler_send_simple_ack_closure) }, - { be_const_key_weak(send_response_frame, 0), be_const_closure(Matter_MessageHandler_send_response_frame_closure) }, + { be_const_key_weak(send_response_frame, 6), be_const_closure(Matter_MessageHandler_send_response_frame_closure) }, + { be_const_key_weak(control_message, -1), be_const_var(3) }, + { be_const_key_weak(device, -1), be_const_var(0) }, })), be_str_weak(Matter_MessageHandler) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Path.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Path.h index 1916265ee613..bab7d9909e67 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Path.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Path.h @@ -11,7 +11,7 @@ extern const bclass be_class_Matter_Path; ********************************************************************/ be_local_closure(Matter_Path_tostring, /* name */ be_nested_proto( - 7, /* nstack */ + 6, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -20,100 +20,144 @@ be_local_closure(Matter_Path_tostring, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[15]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(), - /* K2 */ be_nested_str_weak(endpoint), - /* K3 */ be_nested_str_weak(format), - /* K4 */ be_nested_str_weak(_X5B_X2502X_X5D), - /* K5 */ be_nested_str_weak(_X5B_X2A_X2A_X5D), - /* K6 */ be_nested_str_weak(cluster), - /* K7 */ be_nested_str_weak(_X2504X_X2F), - /* K8 */ be_nested_str_weak(_X2A_X2A_X2A_X2A_X2F), - /* K9 */ be_nested_str_weak(attribute), - /* K10 */ be_nested_str_weak(_X2504X), - /* K11 */ be_nested_str_weak(command), + /* K0 */ be_nested_str_weak(), + /* K1 */ be_nested_str_weak(endpoint), + /* K2 */ be_nested_str_weak(_X5B_X2502X_X5D), + /* K3 */ be_nested_str_weak(_X5B_X2A_X2A_X5D), + /* K4 */ be_nested_str_weak(cluster), + /* K5 */ be_nested_str_weak(_X2504X_X2F), + /* K6 */ be_nested_str_weak(_X2A_X2A_X2A_X2A_X2F), + /* K7 */ be_nested_str_weak(attribute), + /* K8 */ be_nested_str_weak(_X2504X), + /* K9 */ be_nested_str_weak(command), + /* K10 */ be_nested_str_weak(fabric_filtered), + /* K11 */ be_nested_str_weak(_X21), /* K12 */ be_nested_str_weak(_X2A_X2A_X2A_X2A), /* K13 */ be_nested_str_weak(Exception_X3E_X20), /* K14 */ be_nested_str_weak(_X2C_X20), }), be_str_weak(tostring), &be_const_str_solidified, - ( &(const binstruction[75]) { /* code */ - 0xA802003A, // 0000 EXBLK 0 #003C - 0xA4060000, // 0001 IMPORT R1 K0 - 0x58080001, // 0002 LDCONST R2 K1 - 0x880C0102, // 0003 GETMBR R3 R0 K2 - 0x4C100000, // 0004 LDNIL R4 - 0x200C0604, // 0005 NE R3 R3 R4 - 0x780E0004, // 0006 JMPF R3 #000C - 0x8C0C0303, // 0007 GETMET R3 R1 K3 - 0x58140004, // 0008 LDCONST R5 K4 - 0x88180102, // 0009 GETMBR R6 R0 K2 - 0x7C0C0600, // 000A CALL R3 3 - 0x70020000, // 000B JMP #000D - 0x580C0005, // 000C LDCONST R3 K5 - 0x00080403, // 000D ADD R2 R2 R3 - 0x880C0106, // 000E GETMBR R3 R0 K6 - 0x4C100000, // 000F LDNIL R4 - 0x200C0604, // 0010 NE R3 R3 R4 - 0x780E0004, // 0011 JMPF R3 #0017 - 0x8C0C0303, // 0012 GETMET R3 R1 K3 - 0x58140007, // 0013 LDCONST R5 K7 - 0x88180106, // 0014 GETMBR R6 R0 K6 - 0x7C0C0600, // 0015 CALL R3 3 - 0x70020000, // 0016 JMP #0018 - 0x580C0008, // 0017 LDCONST R3 K8 - 0x00080403, // 0018 ADD R2 R2 R3 - 0x880C0109, // 0019 GETMBR R3 R0 K9 - 0x4C100000, // 001A LDNIL R4 - 0x200C0604, // 001B NE R3 R3 R4 - 0x780E0004, // 001C JMPF R3 #0022 - 0x8C0C0303, // 001D GETMET R3 R1 K3 - 0x5814000A, // 001E LDCONST R5 K10 - 0x88180109, // 001F GETMBR R6 R0 K9 - 0x7C0C0600, // 0020 CALL R3 3 - 0x70020000, // 0021 JMP #0023 - 0x580C0001, // 0022 LDCONST R3 K1 - 0x00080403, // 0023 ADD R2 R2 R3 - 0x880C010B, // 0024 GETMBR R3 R0 K11 - 0x4C100000, // 0025 LDNIL R4 - 0x200C0604, // 0026 NE R3 R3 R4 - 0x780E0004, // 0027 JMPF R3 #002D - 0x8C0C0303, // 0028 GETMET R3 R1 K3 - 0x5814000A, // 0029 LDCONST R5 K10 - 0x8818010B, // 002A GETMBR R6 R0 K11 - 0x7C0C0600, // 002B CALL R3 3 - 0x70020000, // 002C JMP #002E - 0x580C0001, // 002D LDCONST R3 K1 - 0x00080403, // 002E ADD R2 R2 R3 - 0x880C0109, // 002F GETMBR R3 R0 K9 - 0x4C100000, // 0030 LDNIL R4 - 0x1C0C0604, // 0031 EQ R3 R3 R4 - 0x780E0004, // 0032 JMPF R3 #0038 - 0x880C010B, // 0033 GETMBR R3 R0 K11 - 0x4C100000, // 0034 LDNIL R4 - 0x1C0C0604, // 0035 EQ R3 R3 R4 - 0x780E0000, // 0036 JMPF R3 #0038 - 0x0008050C, // 0037 ADD R2 R2 K12 - 0xA8040001, // 0038 EXBLK 1 1 - 0x80040400, // 0039 RET 1 R2 + ( &(const binstruction[77]) { /* code */ + 0xA802003C, // 0000 EXBLK 0 #003E + 0x58040000, // 0001 LDCONST R1 K0 + 0x88080101, // 0002 GETMBR R2 R0 K1 + 0x4C0C0000, // 0003 LDNIL R3 + 0x20080403, // 0004 NE R2 R2 R3 + 0x780A0004, // 0005 JMPF R2 #000B + 0x60080018, // 0006 GETGBL R2 G24 + 0x580C0002, // 0007 LDCONST R3 K2 + 0x88100101, // 0008 GETMBR R4 R0 K1 + 0x7C080400, // 0009 CALL R2 2 + 0x70020000, // 000A JMP #000C + 0x58080003, // 000B LDCONST R2 K3 + 0x00040202, // 000C ADD R1 R1 R2 + 0x88080104, // 000D GETMBR R2 R0 K4 + 0x4C0C0000, // 000E LDNIL R3 + 0x20080403, // 000F NE R2 R2 R3 + 0x780A0004, // 0010 JMPF R2 #0016 + 0x60080018, // 0011 GETGBL R2 G24 + 0x580C0005, // 0012 LDCONST R3 K5 + 0x88100104, // 0013 GETMBR R4 R0 K4 + 0x7C080400, // 0014 CALL R2 2 + 0x70020000, // 0015 JMP #0017 + 0x58080006, // 0016 LDCONST R2 K6 + 0x00040202, // 0017 ADD R1 R1 R2 + 0x88080107, // 0018 GETMBR R2 R0 K7 + 0x4C0C0000, // 0019 LDNIL R3 + 0x20080403, // 001A NE R2 R2 R3 + 0x780A0004, // 001B JMPF R2 #0021 + 0x60080018, // 001C GETGBL R2 G24 + 0x580C0008, // 001D LDCONST R3 K8 + 0x88100107, // 001E GETMBR R4 R0 K7 + 0x7C080400, // 001F CALL R2 2 + 0x70020000, // 0020 JMP #0022 + 0x58080000, // 0021 LDCONST R2 K0 + 0x00040202, // 0022 ADD R1 R1 R2 + 0x88080109, // 0023 GETMBR R2 R0 K9 + 0x4C0C0000, // 0024 LDNIL R3 + 0x20080403, // 0025 NE R2 R2 R3 + 0x780A0004, // 0026 JMPF R2 #002C + 0x60080018, // 0027 GETGBL R2 G24 + 0x580C0008, // 0028 LDCONST R3 K8 + 0x88100109, // 0029 GETMBR R4 R0 K9 + 0x7C080400, // 002A CALL R2 2 + 0x70020000, // 002B JMP #002D + 0x58080000, // 002C LDCONST R2 K0 + 0x00040202, // 002D ADD R1 R1 R2 + 0x8808010A, // 002E GETMBR R2 R0 K10 + 0x780A0000, // 002F JMPF R2 #0031 + 0x0004030B, // 0030 ADD R1 R1 K11 + 0x88080107, // 0031 GETMBR R2 R0 K7 + 0x4C0C0000, // 0032 LDNIL R3 + 0x1C080403, // 0033 EQ R2 R2 R3 + 0x780A0004, // 0034 JMPF R2 #003A + 0x88080109, // 0035 GETMBR R2 R0 K9 + 0x4C0C0000, // 0036 LDNIL R3 + 0x1C080403, // 0037 EQ R2 R2 R3 + 0x780A0000, // 0038 JMPF R2 #003A + 0x0004030C, // 0039 ADD R1 R1 K12 0xA8040001, // 003A EXBLK 1 1 - 0x7002000D, // 003B JMP #004A - 0xAC040002, // 003C CATCH R1 0 2 - 0x7002000A, // 003D JMP #0049 - 0x600C0008, // 003E GETGBL R3 G8 - 0x5C100200, // 003F MOVE R4 R1 - 0x7C0C0200, // 0040 CALL R3 1 - 0x000E1A03, // 0041 ADD R3 K13 R3 - 0x000C070E, // 0042 ADD R3 R3 K14 - 0x60100008, // 0043 GETGBL R4 G8 - 0x5C140400, // 0044 MOVE R5 R2 - 0x7C100200, // 0045 CALL R4 1 - 0x000C0604, // 0046 ADD R3 R3 R4 - 0x80040600, // 0047 RET 1 R3 - 0x70020000, // 0048 JMP #004A - 0xB0080000, // 0049 RAISE 2 R0 R0 - 0x80000000, // 004A RET 0 + 0x80040200, // 003B RET 1 R1 + 0xA8040001, // 003C EXBLK 1 1 + 0x7002000D, // 003D JMP #004C + 0xAC040002, // 003E CATCH R1 0 2 + 0x7002000A, // 003F JMP #004B + 0x600C0008, // 0040 GETGBL R3 G8 + 0x5C100200, // 0041 MOVE R4 R1 + 0x7C0C0200, // 0042 CALL R3 1 + 0x000E1A03, // 0043 ADD R3 K13 R3 + 0x000C070E, // 0044 ADD R3 R3 K14 + 0x60100008, // 0045 GETGBL R4 G8 + 0x5C140400, // 0046 MOVE R5 R2 + 0x7C100200, // 0047 CALL R4 1 + 0x000C0604, // 0048 ADD R3 R3 R4 + 0x80040600, // 0049 RET 1 R3 + 0x70020000, // 004A JMP #004C + 0xB0080000, // 004B RAISE 2 R0 R0 + 0x80000000, // 004C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: reset +********************************************************************/ +be_local_closure(Matter_Path_reset, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(endpoint), + /* K1 */ be_nested_str_weak(cluster), + /* K2 */ be_nested_str_weak(attribute), + /* K3 */ be_nested_str_weak(fabric_filtered), + /* K4 */ be_nested_str_weak(command), + /* K5 */ be_nested_str_weak(status), + /* K6 */ be_nested_str_weak(log), + /* K7 */ be_nested_str_weak(msg), + }), + be_str_weak(reset), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x4C040000, // 0000 LDNIL R1 + 0x90020001, // 0001 SETMBR R0 K0 R1 + 0x90020201, // 0002 SETMBR R0 K1 R1 + 0x90020401, // 0003 SETMBR R0 K2 R1 + 0x90020601, // 0004 SETMBR R0 K3 R1 + 0x90020801, // 0005 SETMBR R0 K4 R1 + 0x90020A01, // 0006 SETMBR R0 K5 R1 + 0x90020C01, // 0007 SETMBR R0 K6 R1 + 0x90020E01, // 0008 SETMBR R0 K7 R1 + 0x80000000, // 0009 RET 0 }) ) ); @@ -124,17 +168,20 @@ be_local_closure(Matter_Path_tostring, /* name */ ** Solidified class: Matter_Path ********************************************************************/ be_local_class(Matter_Path, - 6, + 8, NULL, - be_nested_map(7, + be_nested_map(10, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(log, 4), be_const_var(5) }, - { be_const_key_weak(command, 2), be_const_var(3) }, - { be_const_key_weak(status, -1), be_const_var(4) }, - { be_const_key_weak(tostring, -1), be_const_closure(Matter_Path_tostring_closure) }, - { be_const_key_weak(cluster, 5), be_const_var(1) }, - { be_const_key_weak(endpoint, -1), be_const_var(0) }, { be_const_key_weak(attribute, -1), be_const_var(2) }, + { be_const_key_weak(log, 0), be_const_var(6) }, + { be_const_key_weak(fabric_filtered, 6), be_const_var(3) }, + { be_const_key_weak(command, -1), be_const_var(4) }, + { be_const_key_weak(msg, -1), be_const_var(7) }, + { be_const_key_weak(tostring, -1), be_const_closure(Matter_Path_tostring_closure) }, + { be_const_key_weak(reset, -1), be_const_closure(Matter_Path_reset_closure) }, + { be_const_key_weak(cluster, -1), be_const_var(1) }, + { be_const_key_weak(endpoint, 3), be_const_var(0) }, + { be_const_key_weak(status, -1), be_const_var(5) }, })), be_str_weak(Matter_Path) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin.h deleted file mode 100644 index 147b3a143ed9..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin.h +++ /dev/null @@ -1,967 +0,0 @@ -/* Solidification of Matter_Plugin.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin; - -/******************************************************************** -** Solidified function: -********************************************************************/ -be_local_closure(Matter_Plugin__X3Clambda_X3E, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(_X3Clambda_X3E), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x60040008, // 0000 GETGBL R1 G8 - 0x5C080000, // 0001 MOVE R2 R0 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_attribute_list -********************************************************************/ -be_local_closure(Matter_Plugin_get_attribute_list, /* name */ - be_nested_proto( - 7, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(clusters), - /* K1 */ be_nested_str_weak(find), - }), - be_str_weak(get_attribute_list), - &be_const_str_solidified, - ( &(const binstruction[ 7]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x8C0C0701, // 0001 GETMET R3 R3 K1 - 0x5C140400, // 0002 MOVE R5 R2 - 0x60180012, // 0003 GETGBL R6 G18 - 0x7C180000, // 0004 CALL R6 0 - 0x7C0C0600, // 0005 CALL R3 3 - 0x80040600, // 0006 RET 1 R3 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: has -********************************************************************/ -be_local_closure(Matter_Plugin_has, /* name */ - be_nested_proto( - 6, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(clusters), - /* K1 */ be_nested_str_weak(contains), - /* K2 */ be_nested_str_weak(endpoints), - /* K3 */ be_nested_str_weak(find), - }), - be_str_weak(has), - &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x8C0C0701, // 0001 GETMET R3 R3 K1 - 0x5C140200, // 0002 MOVE R5 R1 - 0x7C0C0400, // 0003 CALL R3 2 - 0x780E0006, // 0004 JMPF R3 #000C - 0x880C0102, // 0005 GETMBR R3 R0 K2 - 0x8C0C0703, // 0006 GETMET R3 R3 K3 - 0x5C140400, // 0007 MOVE R5 R2 - 0x7C0C0400, // 0008 CALL R3 2 - 0x4C100000, // 0009 LDNIL R4 - 0x200C0604, // 000A NE R3 R3 R4 - 0x740E0000, // 000B JMPT R3 #000D - 0x500C0001, // 000C LDBOOL R3 0 1 - 0x500C0200, // 000D LDBOOL R3 1 0 - 0x80040600, // 000E RET 1 R3 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: consolidate_clusters -********************************************************************/ -be_local_closure(Matter_Plugin_consolidate_clusters, /* name */ - be_nested_proto( - 12, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 1]) { - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(real_super), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x60040003, // 0000 GETGBL R1 G3 - 0x5C080000, // 0001 MOVE R2 R0 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 - }) - ), - }), - 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(CLUSTERS), - /* K1 */ be_nested_str_weak(keys), - /* K2 */ be_nested_str_weak(contains), - /* K3 */ be_nested_str_weak(find), - /* K4 */ be_nested_str_weak(push), - /* K5 */ be_nested_str_weak(stop_iteration), - }), - be_str_weak(consolidate_clusters), - &be_const_str_solidified, - ( &(const binstruction[53]) { /* code */ - 0x84040000, // 0000 CLOSURE R1 P0 - 0x60080013, // 0001 GETGBL R2 G19 - 0x7C080000, // 0002 CALL R2 0 - 0x5C0C0000, // 0003 MOVE R3 R0 - 0x4C100000, // 0004 LDNIL R4 - 0x20100604, // 0005 NE R4 R3 R4 - 0x7812002C, // 0006 JMPF R4 #0034 - 0x88100700, // 0007 GETMBR R4 R3 K0 - 0x60140010, // 0008 GETGBL R5 G16 - 0x8C180901, // 0009 GETMET R6 R4 K1 - 0x7C180200, // 000A CALL R6 1 - 0x7C140200, // 000B CALL R5 1 - 0xA802001E, // 000C EXBLK 0 #002C - 0x5C180A00, // 000D MOVE R6 R5 - 0x7C180000, // 000E CALL R6 0 - 0x8C1C0502, // 000F GETMET R7 R2 K2 - 0x5C240C00, // 0010 MOVE R9 R6 - 0x7C1C0400, // 0011 CALL R7 2 - 0x741E0002, // 0012 JMPT R7 #0016 - 0x601C0012, // 0013 GETGBL R7 G18 - 0x7C1C0000, // 0014 CALL R7 0 - 0x98080C07, // 0015 SETIDX R2 R6 R7 - 0x601C0010, // 0016 GETGBL R7 G16 - 0x94200806, // 0017 GETIDX R8 R4 R6 - 0x7C1C0200, // 0018 CALL R7 1 - 0xA802000D, // 0019 EXBLK 0 #0028 - 0x5C200E00, // 001A MOVE R8 R7 - 0x7C200000, // 001B CALL R8 0 - 0x94240406, // 001C GETIDX R9 R2 R6 - 0x8C241303, // 001D GETMET R9 R9 K3 - 0x5C2C1000, // 001E MOVE R11 R8 - 0x7C240400, // 001F CALL R9 2 - 0x4C280000, // 0020 LDNIL R10 - 0x1C24120A, // 0021 EQ R9 R9 R10 - 0x78260003, // 0022 JMPF R9 #0027 - 0x94240406, // 0023 GETIDX R9 R2 R6 - 0x8C241304, // 0024 GETMET R9 R9 K4 - 0x5C2C1000, // 0025 MOVE R11 R8 - 0x7C240400, // 0026 CALL R9 2 - 0x7001FFF1, // 0027 JMP #001A - 0x581C0005, // 0028 LDCONST R7 K5 - 0xAC1C0200, // 0029 CATCH R7 1 0 - 0xB0080000, // 002A RAISE 2 R0 R0 - 0x7001FFE0, // 002B JMP #000D - 0x58140005, // 002C LDCONST R5 K5 - 0xAC140200, // 002D CATCH R5 1 0 - 0xB0080000, // 002E RAISE 2 R0 R0 - 0x5C140200, // 002F MOVE R5 R1 - 0x5C180600, // 0030 MOVE R6 R3 - 0x7C140200, // 0031 CALL R5 1 - 0x5C0C0A00, // 0032 MOVE R3 R5 - 0x7001FFCF, // 0033 JMP #0004 - 0x80040400, // 0034 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_endpoint -********************************************************************/ -be_local_closure(Matter_Plugin_get_endpoint, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(endpoint), - }), - be_str_weak(get_endpoint), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: timed_request -********************************************************************/ -be_local_closure(Matter_Plugin_timed_request, /* name */ - be_nested_proto( - 5, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(timed_request), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x4C100000, // 0000 LDNIL R4 - 0x80040800, // 0001 RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: subscribe_event -********************************************************************/ -be_local_closure(Matter_Plugin_subscribe_event, /* name */ - be_nested_proto( - 6, /* nstack */ - 5, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(subscribe_event), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x4C140000, // 0000 LDNIL R5 - 0x80040A00, // 0001 RET 1 R5 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: update_shadow_lazy -********************************************************************/ -be_local_closure(Matter_Plugin_update_shadow_lazy, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(tick), - /* K1 */ be_nested_str_weak(device), - /* K2 */ be_nested_str_weak(update_shadow), - }), - be_str_weak(update_shadow_lazy), - &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88080101, // 0001 GETMBR R2 R0 K1 - 0x88080500, // 0002 GETMBR R2 R2 K0 - 0x20040202, // 0003 NE R1 R1 R2 - 0x78060001, // 0004 JMPF R1 #0007 - 0x8C040102, // 0005 GETMET R1 R0 K2 - 0x7C040200, // 0006 CALL R1 1 - 0x80000000, // 0007 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: attribute_updated -********************************************************************/ -be_local_closure(Matter_Plugin_attribute_updated, /* name */ - be_nested_proto( - 10, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(device), - /* K1 */ be_nested_str_weak(attribute_updated), - /* K2 */ be_nested_str_weak(endpoint), - }), - be_str_weak(attribute_updated), - &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x88100100, // 0000 GETMBR R4 R0 K0 - 0x8C100901, // 0001 GETMET R4 R4 K1 - 0x88180102, // 0002 GETMBR R6 R0 K2 - 0x5C1C0200, // 0003 MOVE R7 R1 - 0x5C200400, // 0004 MOVE R8 R2 - 0x5C240600, // 0005 MOVE R9 R3 - 0x7C100A00, // 0006 CALL R4 5 - 0x80000000, // 0007 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_cluster_list -********************************************************************/ -be_local_closure(Matter_Plugin_get_cluster_list, /* name */ - be_nested_proto( - 8, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(clusters), - /* K1 */ be_nested_str_weak(keys), - /* K2 */ be_nested_str_weak(push), - /* K3 */ be_nested_str_weak(stop_iteration), - }), - be_str_weak(get_cluster_list), - &be_const_str_solidified, - ( &(const binstruction[18]) { /* code */ - 0x60080012, // 0000 GETGBL R2 G18 - 0x7C080000, // 0001 CALL R2 0 - 0x600C0010, // 0002 GETGBL R3 G16 - 0x88100100, // 0003 GETMBR R4 R0 K0 - 0x8C100901, // 0004 GETMET R4 R4 K1 - 0x7C100200, // 0005 CALL R4 1 - 0x7C0C0200, // 0006 CALL R3 1 - 0xA8020005, // 0007 EXBLK 0 #000E - 0x5C100600, // 0008 MOVE R4 R3 - 0x7C100000, // 0009 CALL R4 0 - 0x8C140502, // 000A GETMET R5 R2 K2 - 0x5C1C0800, // 000B MOVE R7 R4 - 0x7C140400, // 000C CALL R5 2 - 0x7001FFF9, // 000D JMP #0008 - 0x580C0003, // 000E LDCONST R3 K3 - 0xAC0C0200, // 000F CATCH R3 1 0 - 0xB0080000, // 0010 RAISE 2 R0 R0 - 0x80040400, // 0011 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_read_attribute, /* name */ - be_nested_proto( - 16, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[18]) { /* constants */ - /* K0 */ be_nested_str_weak(matter), - /* K1 */ be_nested_str_weak(TLV), - /* K2 */ be_nested_str_weak(cluster), - /* K3 */ be_nested_str_weak(attribute), - /* K4 */ be_const_int(0), - /* K5 */ be_nested_str_weak(Matter_TLV_array), - /* K6 */ be_nested_str_weak(get_types), - /* K7 */ be_nested_str_weak(keys), - /* K8 */ be_nested_str_weak(add_struct), - /* K9 */ be_nested_str_weak(add_TLV), - /* K10 */ be_nested_str_weak(U2), - /* K11 */ be_const_int(1), - /* K12 */ be_nested_str_weak(stop_iteration), - /* K13 */ be_nested_str_weak(get_cluster_list), - /* K14 */ be_nested_str_weak(U4), - /* K15 */ be_const_int(2), - /* K16 */ be_const_int(3), - /* K17 */ be_nested_str_weak(create_TLV), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[93]) { /* code */ - 0xB80E0000, // 0000 GETNGBL R3 K0 - 0x880C0701, // 0001 GETMBR R3 R3 K1 - 0x88100502, // 0002 GETMBR R4 R2 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x541A001C, // 0004 LDINT R6 29 - 0x1C180806, // 0005 EQ R6 R4 R6 - 0x781A0052, // 0006 JMPF R6 #005A - 0x1C180B04, // 0007 EQ R6 R5 K4 - 0x781A001C, // 0008 JMPF R6 #0026 - 0x8C180705, // 0009 GETMET R6 R3 K5 - 0x7C180200, // 000A CALL R6 1 - 0x8C1C0106, // 000B GETMET R7 R0 K6 - 0x7C1C0200, // 000C CALL R7 1 - 0x60200010, // 000D GETGBL R8 G16 - 0x8C240F07, // 000E GETMET R9 R7 K7 - 0x7C240200, // 000F CALL R9 1 - 0x7C200200, // 0010 CALL R8 1 - 0xA802000E, // 0011 EXBLK 0 #0021 - 0x5C241000, // 0012 MOVE R9 R8 - 0x7C240000, // 0013 CALL R9 0 - 0x8C280D08, // 0014 GETMET R10 R6 K8 - 0x7C280200, // 0015 CALL R10 1 - 0x8C2C1509, // 0016 GETMET R11 R10 K9 - 0x58340004, // 0017 LDCONST R13 K4 - 0x8838070A, // 0018 GETMBR R14 R3 K10 - 0x5C3C1200, // 0019 MOVE R15 R9 - 0x7C2C0800, // 001A CALL R11 4 - 0x8C2C1509, // 001B GETMET R11 R10 K9 - 0x5834000B, // 001C LDCONST R13 K11 - 0x8838070A, // 001D GETMBR R14 R3 K10 - 0x943C0E09, // 001E GETIDX R15 R7 R9 - 0x7C2C0800, // 001F CALL R11 4 - 0x7001FFF0, // 0020 JMP #0012 - 0x5820000C, // 0021 LDCONST R8 K12 - 0xAC200200, // 0022 CATCH R8 1 0 - 0xB0080000, // 0023 RAISE 2 R0 R0 - 0x80040C00, // 0024 RET 1 R6 - 0x70020032, // 0025 JMP #0059 - 0x1C180B0B, // 0026 EQ R6 R5 K11 - 0x781A0013, // 0027 JMPF R6 #003C - 0x8C180705, // 0028 GETMET R6 R3 K5 - 0x7C180200, // 0029 CALL R6 1 - 0x601C0010, // 002A GETGBL R7 G16 - 0x8C20010D, // 002B GETMET R8 R0 K13 - 0x7C200200, // 002C CALL R8 1 - 0x7C1C0200, // 002D CALL R7 1 - 0xA8020007, // 002E EXBLK 0 #0037 - 0x5C200E00, // 002F MOVE R8 R7 - 0x7C200000, // 0030 CALL R8 0 - 0x8C240D09, // 0031 GETMET R9 R6 K9 - 0x4C2C0000, // 0032 LDNIL R11 - 0x8830070E, // 0033 GETMBR R12 R3 K14 - 0x5C341000, // 0034 MOVE R13 R8 - 0x7C240800, // 0035 CALL R9 4 - 0x7001FFF7, // 0036 JMP #002F - 0x581C000C, // 0037 LDCONST R7 K12 - 0xAC1C0200, // 0038 CATCH R7 1 0 - 0xB0080000, // 0039 RAISE 2 R0 R0 - 0x80040C00, // 003A RET 1 R6 - 0x7002001C, // 003B JMP #0059 - 0x1C180B0F, // 003C EQ R6 R5 K15 - 0x781A0003, // 003D JMPF R6 #0042 - 0x8C180705, // 003E GETMET R6 R3 K5 - 0x7C180200, // 003F CALL R6 1 - 0x80040C00, // 0040 RET 1 R6 - 0x70020016, // 0041 JMP #0059 - 0x1C180B10, // 0042 EQ R6 R5 K16 - 0x781A0003, // 0043 JMPF R6 #0048 - 0x8C180705, // 0044 GETMET R6 R3 K5 - 0x7C180200, // 0045 CALL R6 1 - 0x80040C00, // 0046 RET 1 R6 - 0x70020010, // 0047 JMP #0059 - 0x541AFFFB, // 0048 LDINT R6 65532 - 0x1C180A06, // 0049 EQ R6 R5 R6 - 0x781A0005, // 004A JMPF R6 #0051 - 0x8C180711, // 004B GETMET R6 R3 K17 - 0x8820070E, // 004C GETMBR R8 R3 K14 - 0x58240004, // 004D LDCONST R9 K4 - 0x7C180600, // 004E CALL R6 3 - 0x80040C00, // 004F RET 1 R6 - 0x70020007, // 0050 JMP #0059 - 0x541AFFFC, // 0051 LDINT R6 65533 - 0x1C180A06, // 0052 EQ R6 R5 R6 - 0x781A0004, // 0053 JMPF R6 #0059 - 0x8C180711, // 0054 GETMET R6 R3 K17 - 0x8820070E, // 0055 GETMBR R8 R3 K14 - 0x5824000B, // 0056 LDCONST R9 K11 - 0x7C180600, // 0057 CALL R6 3 - 0x80040C00, // 0058 RET 1 R6 - 0x70020001, // 0059 JMP #005C - 0x4C180000, // 005A LDNIL R6 - 0x80040C00, // 005B RET 1 R6 - 0x80000000, // 005C RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: write_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_write_attribute, /* name */ - be_nested_proto( - 5, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(write_attribute), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x4C100000, // 0000 LDNIL R4 - 0x80040800, // 0001 RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: subscribe_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_subscribe_attribute, /* name */ - be_nested_proto( - 6, /* nstack */ - 5, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(subscribe_attribute), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x4C140000, // 0000 LDNIL R5 - 0x80040A00, // 0001 RET 1 R5 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: update_shadow -********************************************************************/ -be_local_closure(Matter_Plugin_update_shadow, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(tick), - /* K1 */ be_nested_str_weak(device), - }), - be_str_weak(update_shadow), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040101, // 0000 GETMBR R1 R0 K1 - 0x88040300, // 0001 GETMBR R1 R1 K0 - 0x90020001, // 0002 SETMBR R0 K0 R1 - 0x80000000, // 0003 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Matter_Plugin_init, /* name */ - be_nested_proto( - 6, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(device), - /* K1 */ be_nested_str_weak(endpoint), - /* K2 */ be_nested_str_weak(clusters), - /* K3 */ be_nested_str_weak(consolidate_clusters), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x90020001, // 0000 SETMBR R0 K0 R1 - 0x90020202, // 0001 SETMBR R0 K1 R2 - 0x8C100103, // 0002 GETMET R4 R0 K3 - 0x7C100200, // 0003 CALL R4 1 - 0x90020404, // 0004 SETMBR R0 K2 R4 - 0x80000000, // 0005 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: read_event -********************************************************************/ -be_local_closure(Matter_Plugin_read_event, /* name */ - be_nested_proto( - 6, /* nstack */ - 5, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(read_event), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x4C140000, // 0000 LDNIL R5 - 0x80040A00, // 0001 RET 1 R5 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_types -********************************************************************/ -be_local_closure(Matter_Plugin_get_types, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(TYPES), - }), - be_str_weak(get_types), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: ui_string_to_conf -********************************************************************/ -be_local_closure(Matter_Plugin_ui_string_to_conf, /* name */ - be_nested_proto( - 8, /* nstack */ - 3, /* argc */ - 4, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_const_class(be_class_Matter_Plugin), - /* K1 */ be_nested_str_weak(ARG), - /* K2 */ be_nested_str_weak(ARG_TYPE), - }), - be_str_weak(ui_string_to_conf), - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x580C0000, // 0000 LDCONST R3 K0 - 0x88100101, // 0001 GETMBR R4 R0 K1 - 0x88140102, // 0002 GETMBR R5 R0 K2 - 0x780A0004, // 0003 JMPF R2 #0009 - 0x78120003, // 0004 JMPF R4 #0009 - 0x5C180A00, // 0005 MOVE R6 R5 - 0x5C1C0400, // 0006 MOVE R7 R2 - 0x7C180200, // 0007 CALL R6 1 - 0x98040806, // 0008 SETIDX R1 R4 R6 - 0x80040200, // 0009 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: invoke_request -********************************************************************/ -be_local_closure(Matter_Plugin_invoke_request, /* name */ - be_nested_proto( - 5, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(invoke_request), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x4C100000, // 0000 LDNIL R4 - 0x80040800, // 0001 RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: parse_sensors -********************************************************************/ -be_local_closure(Matter_Plugin_parse_sensors, /* name */ - be_nested_proto( - 2, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(parse_sensors), - &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: every_250ms -********************************************************************/ -be_local_closure(Matter_Plugin_every_250ms, /* name */ - be_nested_proto( - 6, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ - /* K0 */ be_nested_str_weak(update_next), - /* K1 */ be_nested_str_weak(crypto), - /* K2 */ be_nested_str_weak(random), - /* K3 */ be_nested_str_weak(get), - /* K4 */ be_const_int(0), - /* K5 */ be_const_int(2147483647), - /* K6 */ be_nested_str_weak(tasmota), - /* K7 */ be_nested_str_weak(millis), - /* K8 */ be_nested_str_weak(UPDATE_TIME), - /* K9 */ be_nested_str_weak(time_reached), - /* K10 */ be_nested_str_weak(update_shadow_lazy), - }), - be_str_weak(every_250ms), - &be_const_str_solidified, - ( &(const binstruction[33]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x1C040202, // 0002 EQ R1 R1 R2 - 0x7806000F, // 0003 JMPF R1 #0014 - 0xA4060200, // 0004 IMPORT R1 K1 - 0x8C080302, // 0005 GETMET R2 R1 K2 - 0x54120003, // 0006 LDINT R4 4 - 0x7C080400, // 0007 CALL R2 2 - 0x8C080503, // 0008 GETMET R2 R2 K3 - 0x58100004, // 0009 LDCONST R4 K4 - 0x54160003, // 000A LDINT R5 4 - 0x7C080600, // 000B CALL R2 3 - 0x2C080505, // 000C AND R2 R2 K5 - 0xB80E0C00, // 000D GETNGBL R3 K6 - 0x8C0C0707, // 000E GETMET R3 R3 K7 - 0x88140108, // 000F GETMBR R5 R0 K8 - 0x10140405, // 0010 MOD R5 R2 R5 - 0x7C0C0400, // 0011 CALL R3 2 - 0x90020003, // 0012 SETMBR R0 K0 R3 - 0x7002000B, // 0013 JMP #0020 - 0xB8060C00, // 0014 GETNGBL R1 K6 - 0x8C040309, // 0015 GETMET R1 R1 K9 - 0x880C0100, // 0016 GETMBR R3 R0 K0 - 0x7C040400, // 0017 CALL R1 2 - 0x78060006, // 0018 JMPF R1 #0020 - 0x8C04010A, // 0019 GETMET R1 R0 K10 - 0x7C040200, // 001A CALL R1 1 - 0xB8060C00, // 001B GETNGBL R1 K6 - 0x8C040307, // 001C GETMET R1 R1 K7 - 0x880C0108, // 001D GETMBR R3 R0 K8 - 0x7C040400, // 001E CALL R1 2 - 0x90020001, // 001F SETMBR R0 K0 R1 - 0x80000000, // 0020 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: ui_conf_to_string -********************************************************************/ -be_local_closure(Matter_Plugin_ui_conf_to_string, /* name */ - be_nested_proto( - 9, /* nstack */ - 2, /* argc */ - 4, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_const_class(be_class_Matter_Plugin), - /* K1 */ be_nested_str_weak(ARG), - /* K2 */ be_nested_str_weak(find), - /* K3 */ be_nested_str_weak(), - }), - be_str_weak(ui_conf_to_string), - &be_const_str_solidified, - ( &(const binstruction[12]) { /* code */ - 0x58080000, // 0000 LDCONST R2 K0 - 0x880C0101, // 0001 GETMBR R3 R0 K1 - 0x780E0006, // 0002 JMPF R3 #000A - 0x60100008, // 0003 GETGBL R4 G8 - 0x8C140302, // 0004 GETMET R5 R1 K2 - 0x5C1C0600, // 0005 MOVE R7 R3 - 0x58200003, // 0006 LDCONST R8 K3 - 0x7C140600, // 0007 CALL R5 3 - 0x7C100200, // 0008 CALL R4 1 - 0x70020000, // 0009 JMP #000B - 0x58100003, // 000A LDCONST R4 K3 - 0x80040800, // 000B RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin -********************************************************************/ -be_local_class(Matter_Plugin, - 5, - NULL, - be_nested_map(32, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(ARG_TYPE, 5), be_const_static_closure(Matter_Plugin__X3Clambda_X3E_closure) }, - { be_const_key_weak(get_attribute_list, -1), be_const_closure(Matter_Plugin_get_attribute_list_closure) }, - { be_const_key_weak(ui_conf_to_string, 11), be_const_static_closure(Matter_Plugin_ui_conf_to_string_closure) }, - { be_const_key_weak(has, -1), be_const_closure(Matter_Plugin_has_closure) }, - { be_const_key_weak(tick, -1), be_const_var(4) }, - { be_const_key_weak(every_250ms, -1), be_const_closure(Matter_Plugin_every_250ms_closure) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak() }, - { be_const_key_weak(ARG, 16), be_nested_str_weak() }, - { be_const_key_weak(UPDATE_TIME, -1), be_const_int(5000) }, - { be_const_key_weak(get_endpoint, -1), be_const_closure(Matter_Plugin_get_endpoint_closure) }, - { be_const_key_weak(timed_request, -1), be_const_closure(Matter_Plugin_timed_request_closure) }, - { be_const_key_weak(clusters, 17), be_const_var(3) }, - { be_const_key_weak(subscribe_event, 30), be_const_closure(Matter_Plugin_subscribe_event_closure) }, - { be_const_key_weak(TYPE, -1), be_nested_str_weak() }, - { be_const_key_weak(parse_sensors, 29), be_const_closure(Matter_Plugin_parse_sensors_closure) }, - { be_const_key_weak(attribute_updated, -1), be_const_closure(Matter_Plugin_attribute_updated_closure) }, - { be_const_key_weak(get_cluster_list, -1), be_const_closure(Matter_Plugin_get_cluster_list_closure) }, - { be_const_key_weak(ui_string_to_conf, 22), be_const_static_closure(Matter_Plugin_ui_string_to_conf_closure) }, - { be_const_key_weak(device, -1), be_const_var(1) }, - { be_const_key_weak(write_attribute, 23), be_const_closure(Matter_Plugin_write_attribute_closure) }, - { be_const_key_weak(subscribe_attribute, -1), be_const_closure(Matter_Plugin_subscribe_attribute_closure) }, - { be_const_key_weak(update_shadow, -1), be_const_closure(Matter_Plugin_update_shadow_closure) }, - { be_const_key_weak(read_event, 24), be_const_closure(Matter_Plugin_read_event_closure) }, - { be_const_key_weak(init, 18), be_const_closure(Matter_Plugin_init_closure) }, - { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(29, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(6, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(2), - be_const_int(3), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(get_types, -1), be_const_closure(Matter_Plugin_get_types_closure) }, - { be_const_key_weak(read_attribute, 2), be_const_closure(Matter_Plugin_read_attribute_closure) }, - { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_invoke_request_closure) }, - { be_const_key_weak(update_next, 14), be_const_var(0) }, - { be_const_key_weak(endpoint, 31), be_const_var(2) }, - { be_const_key_weak(update_shadow_lazy, -1), be_const_closure(Matter_Plugin_update_shadow_lazy_closure) }, - { be_const_key_weak(consolidate_clusters, -1), be_const_closure(Matter_Plugin_consolidate_clusters_closure) }, - })), - be_str_weak(Matter_Plugin) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin); - be_setglobal(vm, "Matter_Plugin"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_0.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_0.h new file mode 100644 index 000000000000..6e5811686e53 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_0.h @@ -0,0 +1,1367 @@ +/* Solidification of Matter_Plugin_0.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin; + +/******************************************************************** +** Solidified function: ack_request +********************************************************************/ +be_local_closure(Matter_Plugin_ack_request, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(msg), + /* K1 */ be_nested_str_weak(device), + /* K2 */ be_nested_str_weak(message_handler), + /* K3 */ be_nested_str_weak(im), + /* K4 */ be_nested_str_weak(send_ack_now), + }), + be_str_weak(ack_request), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x88080300, // 0000 GETMBR R2 R1 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x200C0403, // 0002 NE R3 R2 R3 + 0x780E0005, // 0003 JMPF R3 #000A + 0x880C0101, // 0004 GETMBR R3 R0 K1 + 0x880C0702, // 0005 GETMBR R3 R3 K2 + 0x880C0703, // 0006 GETMBR R3 R3 K3 + 0x8C0C0704, // 0007 GETMET R3 R3 K4 + 0x5C140400, // 0008 MOVE R5 R2 + 0x7C0C0400, // 0009 CALL R3 2 + 0x4C0C0000, // 000A LDNIL R3 + 0x90060003, // 000B SETMBR R1 K0 R3 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: consolidate_clusters +********************************************************************/ +be_local_closure(Matter_Plugin_consolidate_clusters, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(CLUSTERS), + }), + be_str_weak(consolidate_clusters), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_shadow +********************************************************************/ +be_local_closure(Matter_Plugin_update_shadow, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(tick), + /* K1 */ be_nested_str_weak(device), + }), + be_str_weak(update_shadow), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040101, // 0000 GETMBR R1 R0 K1 + 0x88040300, // 0001 GETMBR R1 R1 K0 + 0x90020001, // 0002 SETMBR R0 K0 R1 + 0x80000000, // 0003 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_sensors +********************************************************************/ +be_local_closure(Matter_Plugin_parse_sensors, /* name */ + be_nested_proto( + 2, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(parse_sensors), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: consolidate_update_commands +********************************************************************/ +be_local_closure(Matter_Plugin_consolidate_update_commands, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(UPDATE_COMMANDS), + }), + be_str_weak(consolidate_update_commands), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: publish_command +********************************************************************/ +be_local_closure(Matter_Plugin_publish_command, /* name */ + be_nested_proto( + 16, /* nstack */ + 7, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(json), + /* K1 */ be_nested_str_weak(_X25s_X3A_X25s), + /* K2 */ be_nested_str_weak(dump), + /* K3 */ be_nested_str_weak(_X25s_X2C_X25s_X3A_X25s), + /* K4 */ be_nested_str_weak(matter), + /* K5 */ be_nested_str_weak(publish_command), + /* K6 */ be_nested_str_weak(MtrReceived), + /* K7 */ be_nested_str_weak(endpoint), + /* K8 */ be_nested_str_weak(node_label), + }), + be_str_weak(publish_command), + &be_const_str_solidified, + ( &(const binstruction[46]) { /* code */ + 0xA41E0000, // 0000 IMPORT R7 K0 + 0x60200018, // 0001 GETGBL R8 G24 + 0x58240001, // 0002 LDCONST R9 K1 + 0x8C280F02, // 0003 GETMET R10 R7 K2 + 0x5C300200, // 0004 MOVE R12 R1 + 0x7C280400, // 0005 CALL R10 2 + 0x8C2C0F02, // 0006 GETMET R11 R7 K2 + 0x5C340400, // 0007 MOVE R13 R2 + 0x7C2C0400, // 0008 CALL R11 2 + 0x7C200600, // 0009 CALL R8 3 + 0x4C240000, // 000A LDNIL R9 + 0x20240609, // 000B NE R9 R3 R9 + 0x7826000A, // 000C JMPF R9 #0018 + 0x60240018, // 000D GETGBL R9 G24 + 0x58280003, // 000E LDCONST R10 K3 + 0x5C2C1000, // 000F MOVE R11 R8 + 0x8C300F02, // 0010 GETMET R12 R7 K2 + 0x5C380600, // 0011 MOVE R14 R3 + 0x7C300400, // 0012 CALL R12 2 + 0x8C340F02, // 0013 GETMET R13 R7 K2 + 0x5C3C0800, // 0014 MOVE R15 R4 + 0x7C340400, // 0015 CALL R13 2 + 0x7C240800, // 0016 CALL R9 4 + 0x5C201200, // 0017 MOVE R8 R9 + 0x4C240000, // 0018 LDNIL R9 + 0x20240A09, // 0019 NE R9 R5 R9 + 0x7826000A, // 001A JMPF R9 #0026 + 0x60240018, // 001B GETGBL R9 G24 + 0x58280003, // 001C LDCONST R10 K3 + 0x5C2C1000, // 001D MOVE R11 R8 + 0x8C300F02, // 001E GETMET R12 R7 K2 + 0x5C380A00, // 001F MOVE R14 R5 + 0x7C300400, // 0020 CALL R12 2 + 0x8C340F02, // 0021 GETMET R13 R7 K2 + 0x5C3C0C00, // 0022 MOVE R15 R6 + 0x7C340400, // 0023 CALL R13 2 + 0x7C240800, // 0024 CALL R9 4 + 0x5C201200, // 0025 MOVE R8 R9 + 0xB8260800, // 0026 GETNGBL R9 K4 + 0x8C241305, // 0027 GETMET R9 R9 K5 + 0x582C0006, // 0028 LDCONST R11 K6 + 0x88300107, // 0029 GETMBR R12 R0 K7 + 0x88340108, // 002A GETMBR R13 R0 K8 + 0x5C381000, // 002B MOVE R14 R8 + 0x7C240A00, // 002C CALL R9 5 + 0x80000000, // 002D RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: subscribe_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_subscribe_attribute, /* name */ + be_nested_proto( + 6, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(subscribe_attribute), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x4C140000, // 0000 LDNIL R5 + 0x80040A00, // 0001 RET 1 R5 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_read_attribute, /* name */ + be_nested_proto( + 17, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[20]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(Matter_TLV_array), + /* K6 */ be_nested_str_weak(TYPES), + /* K7 */ be_nested_str_weak(keys), + /* K8 */ be_nested_str_weak(add_struct), + /* K9 */ be_nested_str_weak(add_TLV), + /* K10 */ be_nested_str_weak(U2), + /* K11 */ be_const_int(1), + /* K12 */ be_nested_str_weak(stop_iteration), + /* K13 */ be_nested_str_weak(get_cluster_list), + /* K14 */ be_nested_str_weak(U4), + /* K15 */ be_const_int(2), + /* K16 */ be_const_int(3), + /* K17 */ be_nested_str_weak(set), + /* K18 */ be_nested_str_weak(BOOL), + /* K19 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[114]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E001C, // 0004 LDINT R7 29 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0051, // 0006 JMPF R7 #0059 + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E001B, // 0008 JMPF R7 #0025 + 0x8C1C0905, // 0009 GETMET R7 R4 K5 + 0x7C1C0200, // 000A CALL R7 1 + 0x88200106, // 000B GETMBR R8 R0 K6 + 0x60240010, // 000C GETGBL R9 G16 + 0x8C281107, // 000D GETMET R10 R8 K7 + 0x7C280200, // 000E CALL R10 1 + 0x7C240200, // 000F CALL R9 1 + 0xA802000E, // 0010 EXBLK 0 #0020 + 0x5C281200, // 0011 MOVE R10 R9 + 0x7C280000, // 0012 CALL R10 0 + 0x8C2C0F08, // 0013 GETMET R11 R7 K8 + 0x7C2C0200, // 0014 CALL R11 1 + 0x8C301709, // 0015 GETMET R12 R11 K9 + 0x58380004, // 0016 LDCONST R14 K4 + 0x883C090A, // 0017 GETMBR R15 R4 K10 + 0x5C401400, // 0018 MOVE R16 R10 + 0x7C300800, // 0019 CALL R12 4 + 0x8C301709, // 001A GETMET R12 R11 K9 + 0x5838000B, // 001B LDCONST R14 K11 + 0x883C090A, // 001C GETMBR R15 R4 K10 + 0x9440100A, // 001D GETIDX R16 R8 R10 + 0x7C300800, // 001E CALL R12 4 + 0x7001FFF0, // 001F JMP #0011 + 0x5824000C, // 0020 LDCONST R9 K12 + 0xAC240200, // 0021 CATCH R9 1 0 + 0xB0080000, // 0022 RAISE 2 R0 R0 + 0x80040E00, // 0023 RET 1 R7 + 0x70020032, // 0024 JMP #0058 + 0x1C1C0D0B, // 0025 EQ R7 R6 K11 + 0x781E0013, // 0026 JMPF R7 #003B + 0x8C1C0905, // 0027 GETMET R7 R4 K5 + 0x7C1C0200, // 0028 CALL R7 1 + 0x60200010, // 0029 GETGBL R8 G16 + 0x8C24010D, // 002A GETMET R9 R0 K13 + 0x7C240200, // 002B CALL R9 1 + 0x7C200200, // 002C CALL R8 1 + 0xA8020007, // 002D EXBLK 0 #0036 + 0x5C241000, // 002E MOVE R9 R8 + 0x7C240000, // 002F CALL R9 0 + 0x8C280F09, // 0030 GETMET R10 R7 K9 + 0x4C300000, // 0031 LDNIL R12 + 0x8834090E, // 0032 GETMBR R13 R4 K14 + 0x5C381200, // 0033 MOVE R14 R9 + 0x7C280800, // 0034 CALL R10 4 + 0x7001FFF7, // 0035 JMP #002E + 0x5820000C, // 0036 LDCONST R8 K12 + 0xAC200200, // 0037 CATCH R8 1 0 + 0xB0080000, // 0038 RAISE 2 R0 R0 + 0x80040E00, // 0039 RET 1 R7 + 0x7002001C, // 003A JMP #0058 + 0x1C1C0D0F, // 003B EQ R7 R6 K15 + 0x781E0003, // 003C JMPF R7 #0041 + 0x8C1C0905, // 003D GETMET R7 R4 K5 + 0x7C1C0200, // 003E CALL R7 1 + 0x80040E00, // 003F RET 1 R7 + 0x70020016, // 0040 JMP #0058 + 0x1C1C0D10, // 0041 EQ R7 R6 K16 + 0x781E0003, // 0042 JMPF R7 #0047 + 0x8C1C0905, // 0043 GETMET R7 R4 K5 + 0x7C1C0200, // 0044 CALL R7 1 + 0x80040E00, // 0045 RET 1 R7 + 0x70020010, // 0046 JMP #0058 + 0x541EFFFB, // 0047 LDINT R7 65532 + 0x1C1C0C07, // 0048 EQ R7 R6 R7 + 0x781E0005, // 0049 JMPF R7 #0050 + 0x8C1C0711, // 004A GETMET R7 R3 K17 + 0x8824090E, // 004B GETMBR R9 R4 K14 + 0x58280004, // 004C LDCONST R10 K4 + 0x7C1C0600, // 004D CALL R7 3 + 0x80040E00, // 004E RET 1 R7 + 0x70020007, // 004F JMP #0058 + 0x541EFFFC, // 0050 LDINT R7 65533 + 0x1C1C0C07, // 0051 EQ R7 R6 R7 + 0x781E0004, // 0052 JMPF R7 #0058 + 0x8C1C0711, // 0053 GETMET R7 R3 K17 + 0x8824090E, // 0054 GETMBR R9 R4 K14 + 0x5828000B, // 0055 LDCONST R10 K11 + 0x7C1C0600, // 0056 CALL R7 3 + 0x80040E00, // 0057 RET 1 R7 + 0x70020017, // 0058 JMP #0071 + 0x541E0038, // 0059 LDINT R7 57 + 0x1C1C0A07, // 005A EQ R7 R5 R7 + 0x781E0012, // 005B JMPF R7 #006F + 0x541E0010, // 005C LDINT R7 17 + 0x1C1C0C07, // 005D EQ R7 R6 R7 + 0x781E0005, // 005E JMPF R7 #0065 + 0x8C1C0711, // 005F GETMET R7 R3 K17 + 0x88240912, // 0060 GETMBR R9 R4 K18 + 0x5828000B, // 0061 LDCONST R10 K11 + 0x7C1C0600, // 0062 CALL R7 3 + 0x80040E00, // 0063 RET 1 R7 + 0x70020008, // 0064 JMP #006E + 0x601C0003, // 0065 GETGBL R7 G3 + 0x5C200000, // 0066 MOVE R8 R0 + 0x7C1C0200, // 0067 CALL R7 1 + 0x8C1C0F13, // 0068 GETMET R7 R7 K19 + 0x5C240200, // 0069 MOVE R9 R1 + 0x5C280400, // 006A MOVE R10 R2 + 0x5C2C0600, // 006B MOVE R11 R3 + 0x7C1C0800, // 006C CALL R7 4 + 0x80040E00, // 006D RET 1 R7 + 0x70020001, // 006E JMP #0071 + 0x4C1C0000, // 006F LDNIL R7 + 0x80040E00, // 0070 RET 1 R7 + 0x80000000, // 0071 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: timed_request +********************************************************************/ +be_local_closure(Matter_Plugin_timed_request, /* name */ + be_nested_proto( + 5, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(timed_request), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x4C100000, // 0000 LDNIL R4 + 0x80040800, // 0001 RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_name +********************************************************************/ +be_local_closure(Matter_Plugin_set_name, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(node_label), + /* K1 */ be_nested_str_weak(attribute_updated), + }), + be_str_weak(set_name), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x20080202, // 0001 NE R2 R1 R2 + 0x780A0003, // 0002 JMPF R2 #0007 + 0x8C080101, // 0003 GETMET R2 R0 K1 + 0x54120038, // 0004 LDINT R4 57 + 0x54160004, // 0005 LDINT R5 5 + 0x7C080600, // 0006 CALL R2 3 + 0x90020001, // 0007 SETMBR R0 K0 R1 + 0x80000000, // 0008 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: is_local_device +********************************************************************/ +be_local_closure(Matter_Plugin_is_local_device, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(is_local_device), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x50040200, // 0000 LDBOOL R1 1 0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_name +********************************************************************/ +be_local_closure(Matter_Plugin_get_name, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(node_label), + }), + be_str_weak(get_name), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_init, /* name */ + be_nested_proto( + 8, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(device), + /* K1 */ be_nested_str_weak(endpoint), + /* K2 */ be_nested_str_weak(clusters), + /* K3 */ be_nested_str_weak(consolidate_clusters), + /* K4 */ be_nested_str_weak(parse_configuration), + /* K5 */ be_nested_str_weak(node_label), + /* K6 */ be_nested_str_weak(find), + /* K7 */ be_nested_str_weak(name), + /* K8 */ be_nested_str_weak(), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[14]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x90020202, // 0001 SETMBR R0 K1 R2 + 0x8C100103, // 0002 GETMET R4 R0 K3 + 0x7C100200, // 0003 CALL R4 1 + 0x90020404, // 0004 SETMBR R0 K2 R4 + 0x8C100104, // 0005 GETMET R4 R0 K4 + 0x5C180600, // 0006 MOVE R6 R3 + 0x7C100400, // 0007 CALL R4 2 + 0x8C100706, // 0008 GETMET R4 R3 K6 + 0x58180007, // 0009 LDCONST R6 K7 + 0x581C0008, // 000A LDCONST R7 K8 + 0x7C100600, // 000B CALL R4 3 + 0x90020A04, // 000C SETMBR R0 K5 R4 + 0x80000000, // 000D RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_shadow_lazy +********************************************************************/ +be_local_closure(Matter_Plugin_update_shadow_lazy, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(tick), + /* K1 */ be_nested_str_weak(device), + /* K2 */ be_nested_str_weak(update_shadow), + }), + be_str_weak(update_shadow_lazy), + &be_const_str_solidified, + ( &(const binstruction[11]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x88080101, // 0001 GETMBR R2 R0 K1 + 0x88080500, // 0002 GETMBR R2 R2 K0 + 0x20040202, // 0003 NE R1 R1 R2 + 0x78060004, // 0004 JMPF R1 #000A + 0x8C040102, // 0005 GETMET R1 R0 K2 + 0x7C040200, // 0006 CALL R1 1 + 0x88040101, // 0007 GETMBR R1 R0 K1 + 0x88040300, // 0008 GETMBR R1 R1 K0 + 0x90020001, // 0009 SETMBR R0 K0 R1 + 0x80000000, // 000A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: invoke_request +********************************************************************/ +be_local_closure(Matter_Plugin_invoke_request, /* name */ + be_nested_proto( + 5, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(invoke_request), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x4C100000, // 0000 LDNIL R4 + 0x80040800, // 0001 RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: ui_string_to_conf +********************************************************************/ +be_local_closure(Matter_Plugin_ui_string_to_conf, /* name */ + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 4, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_const_class(be_class_Matter_Plugin), + /* K1 */ be_nested_str_weak(ARG), + /* K2 */ be_nested_str_weak(ARG_TYPE), + }), + be_str_weak(ui_string_to_conf), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x580C0000, // 0000 LDCONST R3 K0 + 0x88100101, // 0001 GETMBR R4 R0 K1 + 0x88140102, // 0002 GETMBR R5 R0 K2 + 0x780A0004, // 0003 JMPF R2 #0009 + 0x78120003, // 0004 JMPF R4 #0009 + 0x5C180A00, // 0005 MOVE R6 R5 + 0x5C1C0400, // 0006 MOVE R7 R2 + 0x7C180200, // 0007 CALL R6 1 + 0x98040806, // 0008 SETIDX R1 R4 R6 + 0x80040200, // 0009 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_endpoint +********************************************************************/ +be_local_closure(Matter_Plugin_get_endpoint, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(endpoint), + }), + be_str_weak(get_endpoint), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_attribute_list +********************************************************************/ +be_local_closure(Matter_Plugin_get_attribute_list, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(clusters), + /* K1 */ be_nested_str_weak(find), + }), + be_str_weak(get_attribute_list), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x60140012, // 0003 GETGBL R5 G18 + 0x7C140000, // 0004 CALL R5 0 + 0x7C080600, // 0005 CALL R2 3 + 0x80040400, // 0006 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: append_state_json +********************************************************************/ +be_local_closure(Matter_Plugin_append_state_json, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(), + }), + be_str_weak(append_state_json), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80060000, // 0000 RET 1 K0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_event +********************************************************************/ +be_local_closure(Matter_Plugin_read_event, /* name */ + be_nested_proto( + 6, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(read_event), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x4C140000, // 0000 LDNIL R5 + 0x80040A00, // 0001 RET 1 R5 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_configuration +********************************************************************/ +be_local_closure(Matter_Plugin_parse_configuration, /* name */ + be_nested_proto( + 2, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(parse_configuration), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: state_json +********************************************************************/ +be_local_closure(Matter_Plugin_state_json, /* name */ + be_nested_proto( + 9, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(json), + /* K1 */ be_nested_str_weak(node_label), + /* K2 */ be_nested_str_weak(_X2C_X22Name_X22_X3A_X25s), + /* K3 */ be_nested_str_weak(dump), + /* K4 */ be_nested_str_weak(), + /* K5 */ be_nested_str_weak(append_state_json), + /* K6 */ be_nested_str_weak(_X7B_X22Ep_X22_X3A_X25i_X25s_X25s_X7D), + /* K7 */ be_nested_str_weak(endpoint), + }), + be_str_weak(state_json), + &be_const_str_solidified, + ( &(const binstruction[25]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x88080101, // 0001 GETMBR R2 R0 K1 + 0x780A0006, // 0002 JMPF R2 #000A + 0x60080018, // 0003 GETGBL R2 G24 + 0x580C0002, // 0004 LDCONST R3 K2 + 0x8C100303, // 0005 GETMET R4 R1 K3 + 0x88180101, // 0006 GETMBR R6 R0 K1 + 0x7C100400, // 0007 CALL R4 2 + 0x7C080400, // 0008 CALL R2 2 + 0x70020000, // 0009 JMP #000B + 0x58080004, // 000A LDCONST R2 K4 + 0x8C0C0105, // 000B GETMET R3 R0 K5 + 0x7C0C0200, // 000C CALL R3 1 + 0x780E0007, // 000D JMPF R3 #0016 + 0x60100018, // 000E GETGBL R4 G24 + 0x58140006, // 000F LDCONST R5 K6 + 0x88180107, // 0010 GETMBR R6 R0 K7 + 0x5C1C0400, // 0011 MOVE R7 R2 + 0x5C200600, // 0012 MOVE R8 R3 + 0x7C100800, // 0013 CALL R4 4 + 0x80040800, // 0014 RET 1 R4 + 0x70020001, // 0015 JMP #0018 + 0x4C100000, // 0016 LDNIL R4 + 0x80040800, // 0017 RET 1 R4 + 0x80000000, // 0018 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: subscribe_event +********************************************************************/ +be_local_closure(Matter_Plugin_subscribe_event, /* name */ + be_nested_proto( + 6, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(subscribe_event), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x4C140000, // 0000 LDNIL R5 + 0x80040A00, // 0001 RET 1 R5 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: has +********************************************************************/ +be_local_closure(Matter_Plugin_has, /* name */ + be_nested_proto( + 6, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(clusters), + /* K1 */ be_nested_str_weak(contains), + /* K2 */ be_nested_str_weak(endpoints), + /* K3 */ be_nested_str_weak(find), + }), + be_str_weak(has), + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x780E0006, // 0004 JMPF R3 #000C + 0x880C0102, // 0005 GETMBR R3 R0 K2 + 0x8C0C0703, // 0006 GETMET R3 R3 K3 + 0x5C140400, // 0007 MOVE R5 R2 + 0x7C0C0400, // 0008 CALL R3 2 + 0x4C100000, // 0009 LDNIL R4 + 0x200C0604, // 000A NE R3 R3 R4 + 0x740E0000, // 000B JMPT R3 #000D + 0x500C0001, // 000C LDBOOL R3 0 1 + 0x500C0200, // 000D LDBOOL R3 1 0 + 0x80040600, // 000E RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: every_250ms +********************************************************************/ +be_local_closure(Matter_Plugin_every_250ms, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str_weak(update_next), + /* K1 */ be_nested_str_weak(matter), + /* K2 */ be_nested_str_weak(jitter), + /* K3 */ be_nested_str_weak(UPDATE_TIME), + /* K4 */ be_nested_str_weak(tasmota), + /* K5 */ be_nested_str_weak(time_reached), + /* K6 */ be_nested_str_weak(tick), + /* K7 */ be_nested_str_weak(device), + /* K8 */ be_nested_str_weak(update_shadow), + /* K9 */ be_nested_str_weak(millis), + }), + be_str_weak(every_250ms), + &be_const_str_solidified, + ( &(const binstruction[28]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x78060005, // 0003 JMPF R1 #000A + 0xB8060200, // 0004 GETNGBL R1 K1 + 0x8C040302, // 0005 GETMET R1 R1 K2 + 0x880C0103, // 0006 GETMBR R3 R0 K3 + 0x7C040400, // 0007 CALL R1 2 + 0x90020001, // 0008 SETMBR R0 K0 R1 + 0x70020010, // 0009 JMP #001B + 0xB8060800, // 000A GETNGBL R1 K4 + 0x8C040305, // 000B GETMET R1 R1 K5 + 0x880C0100, // 000C GETMBR R3 R0 K0 + 0x7C040400, // 000D CALL R1 2 + 0x7806000B, // 000E JMPF R1 #001B + 0x88040106, // 000F GETMBR R1 R0 K6 + 0x88080107, // 0010 GETMBR R2 R0 K7 + 0x88080506, // 0011 GETMBR R2 R2 K6 + 0x20040202, // 0012 NE R1 R1 R2 + 0x78060001, // 0013 JMPF R1 #0016 + 0x8C040108, // 0014 GETMET R1 R0 K8 + 0x7C040200, // 0015 CALL R1 1 + 0xB8060800, // 0016 GETNGBL R1 K4 + 0x8C040309, // 0017 GETMET R1 R1 K9 + 0x880C0103, // 0018 GETMBR R3 R0 K3 + 0x7C040400, // 0019 CALL R1 2 + 0x90020001, // 001A SETMBR R0 K0 R1 + 0x80000000, // 001B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: contains_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_contains_attribute, /* name */ + be_nested_proto( + 7, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(clusters), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_const_int(0), + /* K3 */ be_const_int(1), + }), + be_str_weak(contains_attribute), + &be_const_str_solidified, + ( &(const binstruction[22]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x4C100000, // 0004 LDNIL R4 + 0x20100604, // 0005 NE R4 R3 R4 + 0x7812000C, // 0006 JMPF R4 #0014 + 0x58100002, // 0007 LDCONST R4 K2 + 0x6014000C, // 0008 GETGBL R5 G12 + 0x5C180600, // 0009 MOVE R6 R3 + 0x7C140200, // 000A CALL R5 1 + 0x14140805, // 000B LT R5 R4 R5 + 0x78160006, // 000C JMPF R5 #0014 + 0x94140604, // 000D GETIDX R5 R3 R4 + 0x1C140A02, // 000E EQ R5 R5 R2 + 0x78160001, // 000F JMPF R5 #0012 + 0x50140200, // 0010 LDBOOL R5 1 0 + 0x80040A00, // 0011 RET 1 R5 + 0x00100903, // 0012 ADD R4 R4 K3 + 0x7001FFF3, // 0013 JMP #0008 + 0x50100000, // 0014 LDBOOL R4 0 0 + 0x80040800, // 0015 RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: write_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_write_attribute, /* name */ + be_nested_proto( + 5, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(write_attribute), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x4C100000, // 0000 LDNIL R4 + 0x80040800, // 0001 RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: attribute_updated +********************************************************************/ +be_local_closure(Matter_Plugin_attribute_updated, /* name */ + be_nested_proto( + 10, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(device), + /* K1 */ be_nested_str_weak(attribute_updated), + /* K2 */ be_nested_str_weak(endpoint), + }), + be_str_weak(attribute_updated), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x88100100, // 0000 GETMBR R4 R0 K0 + 0x8C100901, // 0001 GETMET R4 R4 K1 + 0x88180102, // 0002 GETMBR R6 R0 K2 + 0x5C1C0200, // 0003 MOVE R7 R1 + 0x5C200400, // 0004 MOVE R8 R2 + 0x5C240600, // 0005 MOVE R9 R3 + 0x7C100A00, // 0006 CALL R4 5 + 0x80000000, // 0007 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: +********************************************************************/ +be_local_closure(Matter_Plugin__X3Clambda_X3E, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x60040008, // 0000 GETGBL R1 G8 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_virtual +********************************************************************/ +be_local_closure(Matter_Plugin_update_virtual, /* name */ + be_nested_proto( + 2, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(update_virtual), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_cluster_list +********************************************************************/ +be_local_closure(Matter_Plugin_get_cluster_list, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(clusters), + /* K1 */ be_nested_str_weak(keys), + /* K2 */ be_nested_str_weak(push), + /* K3 */ be_nested_str_weak(stop_iteration), + }), + be_str_weak(get_cluster_list), + &be_const_str_solidified, + ( &(const binstruction[18]) { /* code */ + 0x60040012, // 0000 GETGBL R1 G18 + 0x7C040000, // 0001 CALL R1 0 + 0x60080010, // 0002 GETGBL R2 G16 + 0x880C0100, // 0003 GETMBR R3 R0 K0 + 0x8C0C0701, // 0004 GETMET R3 R3 K1 + 0x7C0C0200, // 0005 CALL R3 1 + 0x7C080200, // 0006 CALL R2 1 + 0xA8020005, // 0007 EXBLK 0 #000E + 0x5C0C0400, // 0008 MOVE R3 R2 + 0x7C0C0000, // 0009 CALL R3 0 + 0x8C100302, // 000A GETMET R4 R1 K2 + 0x5C180600, // 000B MOVE R6 R3 + 0x7C100400, // 000C CALL R4 2 + 0x7001FFF9, // 000D JMP #0008 + 0x58080003, // 000E LDCONST R2 K3 + 0xAC080200, // 000F CATCH R2 1 0 + 0xB0080000, // 0010 RAISE 2 R0 R0 + 0x80040200, // 0011 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: ui_conf_to_string +********************************************************************/ +be_local_closure(Matter_Plugin_ui_conf_to_string, /* name */ + be_nested_proto( + 9, /* nstack */ + 2, /* argc */ + 4, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_const_class(be_class_Matter_Plugin), + /* K1 */ be_nested_str_weak(ARG), + /* K2 */ be_nested_str_weak(find), + /* K3 */ be_nested_str_weak(), + }), + be_str_weak(ui_conf_to_string), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x58080000, // 0000 LDCONST R2 K0 + 0x880C0101, // 0001 GETMBR R3 R0 K1 + 0x780E0006, // 0002 JMPF R3 #000A + 0x60100008, // 0003 GETGBL R4 G8 + 0x8C140302, // 0004 GETMET R5 R1 K2 + 0x5C1C0600, // 0005 MOVE R7 R3 + 0x58200003, // 0006 LDCONST R8 K3 + 0x7C140600, // 0007 CALL R5 3 + 0x7C100200, // 0008 CALL R4 1 + 0x70020000, // 0009 JMP #000B + 0x58100003, // 000A LDCONST R4 K3 + 0x80040800, // 000B RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: contains_cluster +********************************************************************/ +be_local_closure(Matter_Plugin_contains_cluster, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(clusters), + /* K1 */ be_nested_str_weak(contains), + }), + be_str_weak(contains_cluster), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C080400, // 0003 CALL R2 2 + 0x80040400, // 0004 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin +********************************************************************/ +be_local_class(Matter_Plugin, + 6, + NULL, + be_nested_map(47, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(ack_request, -1), be_const_closure(Matter_Plugin_ack_request_closure) }, + { be_const_key_weak(parse_sensors, -1), be_const_closure(Matter_Plugin_parse_sensors_closure) }, + { be_const_key_weak(ui_conf_to_string, 45), be_const_static_closure(Matter_Plugin_ui_conf_to_string_closure) }, + { be_const_key_weak(clusters, 27), be_const_var(3) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(_Not_X20used_) }, + { be_const_key_weak(subscribe_attribute, -1), be_const_closure(Matter_Plugin_subscribe_attribute_closure) }, + { be_const_key_weak(timed_request, -1), be_const_closure(Matter_Plugin_timed_request_closure) }, + { be_const_key_weak(endpoint, -1), be_const_var(2) }, + { be_const_key_weak(DISPLAY_NAME, 1), be_nested_str_weak() }, + { be_const_key_weak(update_shadow, 2), be_const_closure(Matter_Plugin_update_shadow_closure) }, + { be_const_key_weak(ARG_TYPE, -1), be_const_static_closure(Matter_Plugin__X3Clambda_X3E_closure) }, + { be_const_key_weak(publish_command, -1), be_const_closure(Matter_Plugin_publish_command_closure) }, + { be_const_key_weak(consolidate_clusters, 5), be_const_closure(Matter_Plugin_consolidate_clusters_closure) }, + { be_const_key_weak(set_name, 42), be_const_closure(Matter_Plugin_set_name_closure) }, + { be_const_key_weak(write_attribute, 23), be_const_closure(Matter_Plugin_write_attribute_closure) }, + { be_const_key_weak(VIRTUAL, 6), be_const_bool(0) }, + { be_const_key_weak(node_label, 34), be_const_var(5) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(2, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(29, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(1, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(update_shadow_lazy, -1), be_const_closure(Matter_Plugin_update_shadow_lazy_closure) }, + { be_const_key_weak(update_next, 40), be_const_var(0) }, + { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_invoke_request_closure) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_init_closure) }, + { be_const_key_weak(ARG, 14), be_nested_str_weak() }, + { be_const_key_weak(get_endpoint, 17), be_const_closure(Matter_Plugin_get_endpoint_closure) }, + { be_const_key_weak(get_name, 20), be_const_closure(Matter_Plugin_get_name_closure) }, + { be_const_key_weak(ui_string_to_conf, 10), be_const_static_closure(Matter_Plugin_ui_string_to_conf_closure) }, + { be_const_key_weak(tick, 18), be_const_var(4) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak() }, + { be_const_key_weak(append_state_json, -1), be_const_closure(Matter_Plugin_append_state_json_closure) }, + { be_const_key_weak(read_event, -1), be_const_closure(Matter_Plugin_read_event_closure) }, + { be_const_key_weak(device, -1), be_const_var(1) }, + { be_const_key_weak(parse_configuration, -1), be_const_closure(Matter_Plugin_parse_configuration_closure) }, + { be_const_key_weak(state_json, -1), be_const_closure(Matter_Plugin_state_json_closure) }, + { be_const_key_weak(subscribe_event, -1), be_const_closure(Matter_Plugin_subscribe_event_closure) }, + { be_const_key_weak(get_attribute_list, -1), be_const_closure(Matter_Plugin_get_attribute_list_closure) }, + { be_const_key_weak(read_attribute, 26), be_const_closure(Matter_Plugin_read_attribute_closure) }, + { be_const_key_weak(has, -1), be_const_closure(Matter_Plugin_has_closure) }, + { be_const_key_weak(UPDATE_TIME, -1), be_const_int(5000) }, + { be_const_key_weak(every_250ms, -1), be_const_closure(Matter_Plugin_every_250ms_closure) }, + { be_const_key_weak(contains_attribute, -1), be_const_closure(Matter_Plugin_contains_attribute_closure) }, + { be_const_key_weak(is_local_device, 13), be_const_closure(Matter_Plugin_is_local_device_closure) }, + { be_const_key_weak(attribute_updated, -1), be_const_closure(Matter_Plugin_attribute_updated_closure) }, + { be_const_key_weak(UPDATE_COMMANDS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(0, + ( (struct bvalue*) &(const bvalue[]) { + })) ) } )) }, + { be_const_key_weak(update_virtual, -1), be_const_closure(Matter_Plugin_update_virtual_closure) }, + { be_const_key_weak(get_cluster_list, -1), be_const_closure(Matter_Plugin_get_cluster_list_closure) }, + { be_const_key_weak(consolidate_update_commands, -1), be_const_closure(Matter_Plugin_consolidate_update_commands_closure) }, + { be_const_key_weak(contains_cluster, -1), be_const_closure(Matter_Plugin_contains_cluster_closure) }, + })), + be_str_weak(Matter_Plugin) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin); + be_setglobal(vm, "Matter_Plugin"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_1_Device.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_1_Device.h new file mode 100644 index 000000000000..b43be5a8307c --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_1_Device.h @@ -0,0 +1,654 @@ +/* Solidification of Matter_Plugin_1_Device.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Device; + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Device_read_attribute, /* name */ + be_nested_proto( + 17, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[37]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(3), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(U2), + /* K8 */ be_const_int(1), + /* K9 */ be_nested_str_weak(U1), + /* K10 */ be_nested_str_weak(U4), + /* K11 */ be_nested_str_weak(Matter_TLV_array), + /* K12 */ be_nested_str_weak(TYPES), + /* K13 */ be_nested_str_weak(keys), + /* K14 */ be_nested_str_weak(add_struct), + /* K15 */ be_nested_str_weak(add_TLV), + /* K16 */ be_nested_str_weak(stop_iteration), + /* K17 */ be_nested_str_weak(NON_BRIDGE_VENDOR), + /* K18 */ be_nested_str_weak(find), + /* K19 */ be_nested_str_weak(get_admin_vendor), + /* K20 */ be_nested_str_weak(device), + /* K21 */ be_nested_str_weak(disable_bridge_mode), + /* K22 */ be_nested_str_weak(read_attribute), + /* K23 */ be_nested_str_weak(string), + /* K24 */ be_nested_str_weak(UTF1), + /* K25 */ be_nested_str_weak(tasmota), + /* K26 */ be_nested_str_weak(cmd), + /* K27 */ be_nested_str_weak(DeviceName), + /* K28 */ be_nested_str_weak(get_name), + /* K29 */ be_nested_str_weak(Status_X202), + /* K30 */ be_nested_str_weak(StatusFWR), + /* K31 */ be_nested_str_weak(Version), + /* K32 */ be_nested_str_weak(_X28), + /* K33 */ be_nested_str_weak(wifi), + /* K34 */ be_nested_str_weak(mac), + /* K35 */ be_nested_str_weak(), + /* K36 */ be_nested_str_weak(BOOL), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[264]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x1C1C0B04, // 0004 EQ R7 R5 K4 + 0x781E0021, // 0005 JMPF R7 #0028 + 0x1C1C0D05, // 0006 EQ R7 R6 K5 + 0x781E0005, // 0007 JMPF R7 #000E + 0x8C1C0706, // 0008 GETMET R7 R3 K6 + 0x88240907, // 0009 GETMBR R9 R4 K7 + 0x58280005, // 000A LDCONST R10 K5 + 0x7C1C0600, // 000B CALL R7 3 + 0x80040E00, // 000C RET 1 R7 + 0x70020018, // 000D JMP #0027 + 0x1C1C0D08, // 000E EQ R7 R6 K8 + 0x781E0005, // 000F JMPF R7 #0016 + 0x8C1C0706, // 0010 GETMET R7 R3 K6 + 0x88240909, // 0011 GETMBR R9 R4 K9 + 0x58280005, // 0012 LDCONST R10 K5 + 0x7C1C0600, // 0013 CALL R7 3 + 0x80040E00, // 0014 RET 1 R7 + 0x70020010, // 0015 JMP #0027 + 0x541EFFFB, // 0016 LDINT R7 65532 + 0x1C1C0C07, // 0017 EQ R7 R6 R7 + 0x781E0005, // 0018 JMPF R7 #001F + 0x8C1C0706, // 0019 GETMET R7 R3 K6 + 0x8824090A, // 001A GETMBR R9 R4 K10 + 0x58280005, // 001B LDCONST R10 K5 + 0x7C1C0600, // 001C CALL R7 3 + 0x80040E00, // 001D RET 1 R7 + 0x70020007, // 001E JMP #0027 + 0x541EFFFC, // 001F LDINT R7 65533 + 0x1C1C0C07, // 0020 EQ R7 R6 R7 + 0x781E0004, // 0021 JMPF R7 #0027 + 0x8C1C0706, // 0022 GETMET R7 R3 K6 + 0x8824090A, // 0023 GETMBR R9 R4 K10 + 0x542A0003, // 0024 LDINT R10 4 + 0x7C1C0600, // 0025 CALL R7 3 + 0x80040E00, // 0026 RET 1 R7 + 0x700200DE, // 0027 JMP #0107 + 0x541E0003, // 0028 LDINT R7 4 + 0x1C1C0A07, // 0029 EQ R7 R5 R7 + 0x781E0016, // 002A JMPF R7 #0042 + 0x1C1C0D05, // 002B EQ R7 R6 K5 + 0x781E0002, // 002C JMPF R7 #0030 + 0x4C1C0000, // 002D LDNIL R7 + 0x80040E00, // 002E RET 1 R7 + 0x70020010, // 002F JMP #0041 + 0x541EFFFB, // 0030 LDINT R7 65532 + 0x1C1C0C07, // 0031 EQ R7 R6 R7 + 0x781E0005, // 0032 JMPF R7 #0039 + 0x8C1C0706, // 0033 GETMET R7 R3 K6 + 0x8824090A, // 0034 GETMBR R9 R4 K10 + 0x58280005, // 0035 LDCONST R10 K5 + 0x7C1C0600, // 0036 CALL R7 3 + 0x80040E00, // 0037 RET 1 R7 + 0x70020007, // 0038 JMP #0041 + 0x541EFFFC, // 0039 LDINT R7 65533 + 0x1C1C0C07, // 003A EQ R7 R6 R7 + 0x781E0004, // 003B JMPF R7 #0041 + 0x8C1C0706, // 003C GETMET R7 R3 K6 + 0x8824090A, // 003D GETMBR R9 R4 K10 + 0x542A0003, // 003E LDINT R10 4 + 0x7C1C0600, // 003F CALL R7 3 + 0x80040E00, // 0040 RET 1 R7 + 0x700200C4, // 0041 JMP #0107 + 0x541E0004, // 0042 LDINT R7 5 + 0x1C1C0A07, // 0043 EQ R7 R5 R7 + 0x781E0011, // 0044 JMPF R7 #0057 + 0x541EFFFB, // 0045 LDINT R7 65532 + 0x1C1C0C07, // 0046 EQ R7 R6 R7 + 0x781E0005, // 0047 JMPF R7 #004E + 0x8C1C0706, // 0048 GETMET R7 R3 K6 + 0x8824090A, // 0049 GETMBR R9 R4 K10 + 0x58280005, // 004A LDCONST R10 K5 + 0x7C1C0600, // 004B CALL R7 3 + 0x80040E00, // 004C RET 1 R7 + 0x70020007, // 004D JMP #0056 + 0x541EFFFC, // 004E LDINT R7 65533 + 0x1C1C0C07, // 004F EQ R7 R6 R7 + 0x781E0004, // 0050 JMPF R7 #0056 + 0x8C1C0706, // 0051 GETMET R7 R3 K6 + 0x8824090A, // 0052 GETMBR R9 R4 K10 + 0x542A0003, // 0053 LDINT R10 4 + 0x7C1C0600, // 0054 CALL R7 3 + 0x80040E00, // 0055 RET 1 R7 + 0x700200AF, // 0056 JMP #0107 + 0x541E001C, // 0057 LDINT R7 29 + 0x1C1C0A07, // 0058 EQ R7 R5 R7 + 0x781E003E, // 0059 JMPF R7 #0099 + 0x1C1C0D05, // 005A EQ R7 R6 K5 + 0x781E0032, // 005B JMPF R7 #008F + 0x8C1C090B, // 005C GETMET R7 R4 K11 + 0x7C1C0200, // 005D CALL R7 1 + 0x8820010C, // 005E GETMBR R8 R0 K12 + 0x60240010, // 005F GETGBL R9 G16 + 0x8C28110D, // 0060 GETMET R10 R8 K13 + 0x7C280200, // 0061 CALL R10 1 + 0x7C240200, // 0062 CALL R9 1 + 0xA802000E, // 0063 EXBLK 0 #0073 + 0x5C281200, // 0064 MOVE R10 R9 + 0x7C280000, // 0065 CALL R10 0 + 0x8C2C0F0E, // 0066 GETMET R11 R7 K14 + 0x7C2C0200, // 0067 CALL R11 1 + 0x8C30170F, // 0068 GETMET R12 R11 K15 + 0x58380005, // 0069 LDCONST R14 K5 + 0x883C0907, // 006A GETMBR R15 R4 K7 + 0x5C401400, // 006B MOVE R16 R10 + 0x7C300800, // 006C CALL R12 4 + 0x8C30170F, // 006D GETMET R12 R11 K15 + 0x58380008, // 006E LDCONST R14 K8 + 0x883C0907, // 006F GETMBR R15 R4 K7 + 0x9440100A, // 0070 GETIDX R16 R8 R10 + 0x7C300800, // 0071 CALL R12 4 + 0x7001FFF0, // 0072 JMP #0064 + 0x58240010, // 0073 LDCONST R9 K16 + 0xAC240200, // 0074 CATCH R9 1 0 + 0xB0080000, // 0075 RAISE 2 R0 R0 + 0x88240111, // 0076 GETMBR R9 R0 K17 + 0x8C241312, // 0077 GETMET R9 R9 K18 + 0x8C2C0313, // 0078 GETMET R11 R1 K19 + 0x7C2C0200, // 0079 CALL R11 1 + 0x7C240400, // 007A CALL R9 2 + 0x4C280000, // 007B LDNIL R10 + 0x1C24120A, // 007C EQ R9 R9 R10 + 0x7826000E, // 007D JMPF R9 #008D + 0x88240114, // 007E GETMBR R9 R0 K20 + 0x88241315, // 007F GETMBR R9 R9 K21 + 0x7426000B, // 0080 JMPT R9 #008D + 0x8C240F0E, // 0081 GETMET R9 R7 K14 + 0x7C240200, // 0082 CALL R9 1 + 0x8C28130F, // 0083 GETMET R10 R9 K15 + 0x58300005, // 0084 LDCONST R12 K5 + 0x88340907, // 0085 GETMBR R13 R4 K7 + 0x543A0012, // 0086 LDINT R14 19 + 0x7C280800, // 0087 CALL R10 4 + 0x8C28130F, // 0088 GETMET R10 R9 K15 + 0x58300008, // 0089 LDCONST R12 K8 + 0x88340907, // 008A GETMBR R13 R4 K7 + 0x58380008, // 008B LDCONST R14 K8 + 0x7C280800, // 008C CALL R10 4 + 0x80040E00, // 008D RET 1 R7 + 0x70020008, // 008E JMP #0098 + 0x601C0003, // 008F GETGBL R7 G3 + 0x5C200000, // 0090 MOVE R8 R0 + 0x7C1C0200, // 0091 CALL R7 1 + 0x8C1C0F16, // 0092 GETMET R7 R7 K22 + 0x5C240200, // 0093 MOVE R9 R1 + 0x5C280400, // 0094 MOVE R10 R2 + 0x5C2C0600, // 0095 MOVE R11 R3 + 0x7C1C0800, // 0096 CALL R7 4 + 0x80040E00, // 0097 RET 1 R7 + 0x7002006D, // 0098 JMP #0107 + 0x541E0038, // 0099 LDINT R7 57 + 0x1C1C0A07, // 009A EQ R7 R5 R7 + 0x781E0061, // 009B JMPF R7 #00FE + 0xA41E2E00, // 009C IMPORT R7 K23 + 0x1C200D04, // 009D EQ R8 R6 K4 + 0x7822000A, // 009E JMPF R8 #00AA + 0x8C200706, // 009F GETMET R8 R3 K6 + 0x88280918, // 00A0 GETMBR R10 R4 K24 + 0xB82E3200, // 00A1 GETNGBL R11 K25 + 0x8C2C171A, // 00A2 GETMET R11 R11 K26 + 0x5834001B, // 00A3 LDCONST R13 K27 + 0x50380200, // 00A4 LDBOOL R14 1 0 + 0x7C2C0600, // 00A5 CALL R11 3 + 0x942C171B, // 00A6 GETIDX R11 R11 K27 + 0x7C200600, // 00A7 CALL R8 3 + 0x80041000, // 00A8 RET 1 R8 + 0x70020052, // 00A9 JMP #00FD + 0x54220004, // 00AA LDINT R8 5 + 0x1C200C08, // 00AB EQ R8 R6 R8 + 0x78220006, // 00AC JMPF R8 #00B4 + 0x8C200706, // 00AD GETMET R8 R3 K6 + 0x88280918, // 00AE GETMBR R10 R4 K24 + 0x8C2C011C, // 00AF GETMET R11 R0 K28 + 0x7C2C0200, // 00B0 CALL R11 1 + 0x7C200600, // 00B1 CALL R8 3 + 0x80041000, // 00B2 RET 1 R8 + 0x70020048, // 00B3 JMP #00FD + 0x54220009, // 00B4 LDINT R8 10 + 0x1C200C08, // 00B5 EQ R8 R6 R8 + 0x78220015, // 00B6 JMPF R8 #00CD + 0xB8223200, // 00B7 GETNGBL R8 K25 + 0x8C20111A, // 00B8 GETMET R8 R8 K26 + 0x5828001D, // 00B9 LDCONST R10 K29 + 0x502C0200, // 00BA LDBOOL R11 1 0 + 0x7C200600, // 00BB CALL R8 3 + 0x9420111E, // 00BC GETIDX R8 R8 K30 + 0x9420111F, // 00BD GETIDX R8 R8 K31 + 0x8C240F12, // 00BE GETMET R9 R7 K18 + 0x5C2C1000, // 00BF MOVE R11 R8 + 0x58300020, // 00C0 LDCONST R12 K32 + 0x7C240600, // 00C1 CALL R9 3 + 0x24281305, // 00C2 GT R10 R9 K5 + 0x782A0002, // 00C3 JMPF R10 #00C7 + 0x04281308, // 00C4 SUB R10 R9 K8 + 0x402A0A0A, // 00C5 CONNECT R10 K5 R10 + 0x9420100A, // 00C6 GETIDX R8 R8 R10 + 0x8C280706, // 00C7 GETMET R10 R3 K6 + 0x88300918, // 00C8 GETMBR R12 R4 K24 + 0x5C341000, // 00C9 MOVE R13 R8 + 0x7C280600, // 00CA CALL R10 3 + 0x80041400, // 00CB RET 1 R10 + 0x7002002F, // 00CC JMP #00FD + 0x5422000E, // 00CD LDINT R8 15 + 0x1C200C08, // 00CE EQ R8 R6 R8 + 0x7822000B, // 00CF JMPF R8 #00DC + 0x8C200706, // 00D0 GETMET R8 R3 K6 + 0x88280918, // 00D1 GETMBR R10 R4 K24 + 0xB82E3200, // 00D2 GETNGBL R11 K25 + 0x8C2C1721, // 00D3 GETMET R11 R11 K33 + 0x7C2C0200, // 00D4 CALL R11 1 + 0x8C2C1712, // 00D5 GETMET R11 R11 K18 + 0x58340022, // 00D6 LDCONST R13 K34 + 0x58380023, // 00D7 LDCONST R14 K35 + 0x7C2C0600, // 00D8 CALL R11 3 + 0x7C200600, // 00D9 CALL R8 3 + 0x80041000, // 00DA RET 1 R8 + 0x70020020, // 00DB JMP #00FD + 0x54220010, // 00DC LDINT R8 17 + 0x1C200C08, // 00DD EQ R8 R6 R8 + 0x78220005, // 00DE JMPF R8 #00E5 + 0x8C200706, // 00DF GETMET R8 R3 K6 + 0x88280924, // 00E0 GETMBR R10 R4 K36 + 0x582C0008, // 00E1 LDCONST R11 K8 + 0x7C200600, // 00E2 CALL R8 3 + 0x80041000, // 00E3 RET 1 R8 + 0x70020017, // 00E4 JMP #00FD + 0x54220011, // 00E5 LDINT R8 18 + 0x1C200C08, // 00E6 EQ R8 R6 R8 + 0x7822000B, // 00E7 JMPF R8 #00F4 + 0x8C200706, // 00E8 GETMET R8 R3 K6 + 0x88280918, // 00E9 GETMBR R10 R4 K24 + 0xB82E3200, // 00EA GETNGBL R11 K25 + 0x8C2C1721, // 00EB GETMET R11 R11 K33 + 0x7C2C0200, // 00EC CALL R11 1 + 0x8C2C1712, // 00ED GETMET R11 R11 K18 + 0x58340022, // 00EE LDCONST R13 K34 + 0x58380023, // 00EF LDCONST R14 K35 + 0x7C2C0600, // 00F0 CALL R11 3 + 0x7C200600, // 00F1 CALL R8 3 + 0x80041000, // 00F2 RET 1 R8 + 0x70020008, // 00F3 JMP #00FD + 0x60200003, // 00F4 GETGBL R8 G3 + 0x5C240000, // 00F5 MOVE R9 R0 + 0x7C200200, // 00F6 CALL R8 1 + 0x8C201116, // 00F7 GETMET R8 R8 K22 + 0x5C280200, // 00F8 MOVE R10 R1 + 0x5C2C0400, // 00F9 MOVE R11 R2 + 0x5C300600, // 00FA MOVE R12 R3 + 0x7C200800, // 00FB CALL R8 4 + 0x80041000, // 00FC RET 1 R8 + 0x70020008, // 00FD JMP #0107 + 0x601C0003, // 00FE GETGBL R7 G3 + 0x5C200000, // 00FF MOVE R8 R0 + 0x7C1C0200, // 0100 CALL R7 1 + 0x8C1C0F16, // 0101 GETMET R7 R7 K22 + 0x5C240200, // 0102 MOVE R9 R1 + 0x5C280400, // 0103 MOVE R10 R2 + 0x5C2C0600, // 0104 MOVE R11 R3 + 0x7C1C0800, // 0105 CALL R7 4 + 0x80040E00, // 0106 RET 1 R7 + 0x80000000, // 0107 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: append_state_json +********************************************************************/ +be_local_closure(Matter_Plugin_Device_append_state_json, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 12, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 2]) { /* upvals */ + be_local_const_upval(1, 0), + be_local_const_upval(1, 2), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(introspect), + /* K1 */ be_nested_str_weak(json), + /* K2 */ be_nested_str_weak(get), + /* K3 */ be_nested_str_weak(bool), + /* K4 */ be_nested_str_weak(_X2C_X22_X25s_X22_X3A_X25s), + /* K5 */ be_nested_str_weak(dump), + }), + be_str_weak(_stats_json_inner), + &be_const_str_solidified, + ( &(const binstruction[31]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0xA40E0200, // 0001 IMPORT R3 K1 + 0x4C100000, // 0002 LDNIL R4 + 0x8C140502, // 0003 GETMET R5 R2 K2 + 0x681C0000, // 0004 GETUPV R7 U0 + 0x5C200000, // 0005 MOVE R8 R0 + 0x7C140600, // 0006 CALL R5 3 + 0x5C100A00, // 0007 MOVE R4 R5 + 0x4C180000, // 0008 LDNIL R6 + 0x20140A06, // 0009 NE R5 R5 R6 + 0x78160012, // 000A JMPF R5 #001E + 0x60140004, // 000B GETGBL R5 G4 + 0x5C180800, // 000C MOVE R6 R4 + 0x7C140200, // 000D CALL R5 1 + 0x1C140B03, // 000E EQ R5 R5 K3 + 0x78160003, // 000F JMPF R5 #0014 + 0x60140009, // 0010 GETGBL R5 G9 + 0x5C180800, // 0011 MOVE R6 R4 + 0x7C140200, // 0012 CALL R5 1 + 0x5C100A00, // 0013 MOVE R4 R5 + 0x60180018, // 0014 GETGBL R6 G24 + 0x581C0004, // 0015 LDCONST R7 K4 + 0x5C200200, // 0016 MOVE R8 R1 + 0x8C240705, // 0017 GETMET R9 R3 K5 + 0x5C2C0800, // 0018 MOVE R11 R4 + 0x7C240400, // 0019 CALL R9 2 + 0x7C180600, // 001A CALL R6 3 + 0x68140001, // 001B GETUPV R5 U1 + 0x00140A06, // 001C ADD R5 R5 R6 + 0x6C140001, // 001D SETUPV R5 U1 + 0x80000000, // 001E RET 0 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[22]) { /* constants */ + /* K0 */ be_nested_str_weak(introspect), + /* K1 */ be_nested_str_weak(), + /* K2 */ be_nested_str_weak(shadow_onoff), + /* K3 */ be_nested_str_weak(Power), + /* K4 */ be_nested_str_weak(shadow_bri), + /* K5 */ be_nested_str_weak(Bri), + /* K6 */ be_nested_str_weak(shadow_ct), + /* K7 */ be_nested_str_weak(CT), + /* K8 */ be_nested_str_weak(shadow_hue), + /* K9 */ be_nested_str_weak(Hue), + /* K10 */ be_nested_str_weak(shadow_sat), + /* K11 */ be_nested_str_weak(Sat), + /* K12 */ be_nested_str_weak(shadow_shutter_pos), + /* K13 */ be_nested_str_weak(ShutterPos), + /* K14 */ be_nested_str_weak(shadow_shutter_target), + /* K15 */ be_nested_str_weak(ShutterTarget), + /* K16 */ be_nested_str_weak(shadow_shutter_tilt), + /* K17 */ be_nested_str_weak(ShutterTilt), + /* K18 */ be_nested_str_weak(shadow_contact), + /* K19 */ be_nested_str_weak(Contact), + /* K20 */ be_nested_str_weak(shadow_occupancy), + /* K21 */ be_nested_str_weak(Occupancy), + }), + be_str_weak(append_state_json), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x58080001, // 0001 LDCONST R2 K1 + 0x840C0000, // 0002 CLOSURE R3 P0 + 0x5C100600, // 0003 MOVE R4 R3 + 0x58140002, // 0004 LDCONST R5 K2 + 0x58180003, // 0005 LDCONST R6 K3 + 0x7C100400, // 0006 CALL R4 2 + 0x5C100600, // 0007 MOVE R4 R3 + 0x58140004, // 0008 LDCONST R5 K4 + 0x58180005, // 0009 LDCONST R6 K5 + 0x7C100400, // 000A CALL R4 2 + 0x5C100600, // 000B MOVE R4 R3 + 0x58140006, // 000C LDCONST R5 K6 + 0x58180007, // 000D LDCONST R6 K7 + 0x7C100400, // 000E CALL R4 2 + 0x5C100600, // 000F MOVE R4 R3 + 0x58140008, // 0010 LDCONST R5 K8 + 0x58180009, // 0011 LDCONST R6 K9 + 0x7C100400, // 0012 CALL R4 2 + 0x5C100600, // 0013 MOVE R4 R3 + 0x5814000A, // 0014 LDCONST R5 K10 + 0x5818000B, // 0015 LDCONST R6 K11 + 0x7C100400, // 0016 CALL R4 2 + 0x5C100600, // 0017 MOVE R4 R3 + 0x5814000C, // 0018 LDCONST R5 K12 + 0x5818000D, // 0019 LDCONST R6 K13 + 0x7C100400, // 001A CALL R4 2 + 0x5C100600, // 001B MOVE R4 R3 + 0x5814000E, // 001C LDCONST R5 K14 + 0x5818000F, // 001D LDCONST R6 K15 + 0x7C100400, // 001E CALL R4 2 + 0x5C100600, // 001F MOVE R4 R3 + 0x58140010, // 0020 LDCONST R5 K16 + 0x58180011, // 0021 LDCONST R6 K17 + 0x7C100400, // 0022 CALL R4 2 + 0x5C100600, // 0023 MOVE R4 R3 + 0x58140012, // 0024 LDCONST R5 K18 + 0x58180013, // 0025 LDCONST R6 K19 + 0x7C100400, // 0026 CALL R4 2 + 0x5C100600, // 0027 MOVE R4 R3 + 0x58140014, // 0028 LDCONST R5 K20 + 0x58180015, // 0029 LDCONST R6 K21 + 0x7C100400, // 002A CALL R4 2 + 0xA0000000, // 002B CLOSE R0 + 0x80040400, // 002C RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: invoke_request +********************************************************************/ +be_local_closure(Matter_Plugin_Device_invoke_request, /* name */ + be_nested_proto( + 13, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(command), + /* K4 */ be_const_int(3), + /* K5 */ be_const_int(0), + /* K6 */ be_const_int(1), + /* K7 */ be_nested_str_weak(Matter_TLV_struct), + /* K8 */ be_nested_str_weak(add_TLV), + /* K9 */ be_nested_str_weak(U2), + /* K10 */ be_nested_str_weak(invoke_request), + }), + be_str_weak(invoke_request), + &be_const_str_solidified, + ( &(const binstruction[51]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140702, // 0002 GETMBR R5 R3 K2 + 0x88180703, // 0003 GETMBR R6 R3 K3 + 0x1C1C0B04, // 0004 EQ R7 R5 K4 + 0x781E0016, // 0005 JMPF R7 #001D + 0x1C1C0D05, // 0006 EQ R7 R6 K5 + 0x781E0002, // 0007 JMPF R7 #000B + 0x501C0200, // 0008 LDBOOL R7 1 0 + 0x80040E00, // 0009 RET 1 R7 + 0x70020010, // 000A JMP #001C + 0x1C1C0D06, // 000B EQ R7 R6 K6 + 0x781E0009, // 000C JMPF R7 #0017 + 0x8C1C0907, // 000D GETMET R7 R4 K7 + 0x7C1C0200, // 000E CALL R7 1 + 0x8C200F08, // 000F GETMET R8 R7 K8 + 0x58280005, // 0010 LDCONST R10 K5 + 0x882C0909, // 0011 GETMBR R11 R4 K9 + 0x58300005, // 0012 LDCONST R12 K5 + 0x7C200800, // 0013 CALL R8 4 + 0x900E0705, // 0014 SETMBR R3 K3 K5 + 0x80040E00, // 0015 RET 1 R7 + 0x70020004, // 0016 JMP #001C + 0x541E003F, // 0017 LDINT R7 64 + 0x1C1C0C07, // 0018 EQ R7 R6 R7 + 0x781E0001, // 0019 JMPF R7 #001C + 0x501C0200, // 001A LDBOOL R7 1 0 + 0x80040E00, // 001B RET 1 R7 + 0x70020014, // 001C JMP #0032 + 0x541E0003, // 001D LDINT R7 4 + 0x1C1C0A07, // 001E EQ R7 R5 R7 + 0x781E0002, // 001F JMPF R7 #0023 + 0x501C0200, // 0020 LDBOOL R7 1 0 + 0x80040E00, // 0021 RET 1 R7 + 0x7002000E, // 0022 JMP #0032 + 0x541E0004, // 0023 LDINT R7 5 + 0x1C1C0A07, // 0024 EQ R7 R5 R7 + 0x781E0002, // 0025 JMPF R7 #0029 + 0x501C0200, // 0026 LDBOOL R7 1 0 + 0x80040E00, // 0027 RET 1 R7 + 0x70020008, // 0028 JMP #0032 + 0x601C0003, // 0029 GETGBL R7 G3 + 0x5C200000, // 002A MOVE R8 R0 + 0x7C1C0200, // 002B CALL R7 1 + 0x8C1C0F0A, // 002C GETMET R7 R7 K10 + 0x5C240200, // 002D MOVE R9 R1 + 0x5C280400, // 002E MOVE R10 R2 + 0x5C2C0600, // 002F MOVE R11 R3 + 0x7C1C0800, // 0030 CALL R7 4 + 0x80040E00, // 0031 RET 1 R7 + 0x80000000, // 0032 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Device +********************************************************************/ +extern const bclass be_class_Matter_Plugin; +be_local_class(Matter_Plugin_Device, + 0, + &be_class_Matter_Plugin, + be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Device_read_attribute_closure) }, + { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Device_invoke_request_closure) }, + { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(19, -1), be_const_int(1) }, + })) ) } )) }, + { be_const_key_weak(append_state_json, -1), be_const_closure(Matter_Plugin_Device_append_state_json_closure) }, + { be_const_key_weak(CLUSTERS, 3), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(NON_BRIDGE_VENDOR, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(2, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(4631), + be_const_int(4993), + })) ) } )) }, + })), + be_str_weak(Matter_Plugin_Device) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Device_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Device); + be_setglobal(vm, "Matter_Plugin_Device"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_1_Root.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_1_Root.h new file mode 100644 index 000000000000..b435e2ca6fbe --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_1_Root.h @@ -0,0 +1,2213 @@ +/* Solidification of Matter_Plugin_1_Root.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Root; + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Root_read_attribute, /* name */ + be_nested_proto( + 25, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[92]) { /* constants */ + /* K0 */ be_nested_str_weak(string), + /* K1 */ be_nested_str_weak(matter), + /* K2 */ be_nested_str_weak(TLV), + /* K3 */ be_nested_str_weak(cluster), + /* K4 */ be_nested_str_weak(attribute), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(U8), + /* K8 */ be_nested_str_weak(_breadcrumb), + /* K9 */ be_const_int(1), + /* K10 */ be_nested_str_weak(Matter_TLV_struct), + /* K11 */ be_nested_str_weak(add_TLV), + /* K12 */ be_nested_str_weak(U2), + /* K13 */ be_const_int(2), + /* K14 */ be_nested_str_weak(U1), + /* K15 */ be_const_int(3), + /* K16 */ be_nested_str_weak(BOOL), + /* K17 */ be_nested_str_weak(Matter_TLV_array), + /* K18 */ be_nested_str_weak(tasmota), + /* K19 */ be_nested_str_weak(eth), + /* K20 */ be_nested_str_weak(up), + /* K21 */ be_nested_str_weak(add_struct), + /* K22 */ be_nested_str_weak(UTF1), + /* K23 */ be_nested_str_weak(ethernet), + /* K24 */ be_nested_str_weak(NULL), + /* K25 */ be_nested_str_weak(fromhex), + /* K26 */ be_nested_str_weak(replace), + /* K27 */ be_nested_str_weak(find), + /* K28 */ be_nested_str_weak(mac), + /* K29 */ be_nested_str_weak(), + /* K30 */ be_nested_str_weak(_X3A), + /* K31 */ be_nested_str_weak(B1), + /* K32 */ be_nested_str_weak(add_array), + /* K33 */ be_nested_str_weak(get_ip_bytes), + /* K34 */ be_nested_str_weak(ip), + /* K35 */ be_nested_str_weak(ip6local), + /* K36 */ be_nested_str_weak(ip6), + /* K37 */ be_nested_str_weak(wifi), + /* K38 */ be_nested_str_weak(cmd), + /* K39 */ be_nested_str_weak(Status_X201), + /* K40 */ be_nested_str_weak(StatusPRM), + /* K41 */ be_nested_str_weak(BootCount), + /* K42 */ be_nested_str_weak(U4), + /* K43 */ be_nested_str_weak(Status_X2011), + /* K44 */ be_nested_str_weak(StatusSTS), + /* K45 */ be_nested_str_weak(UptimeSec), + /* K46 */ be_nested_str_weak(int64), + /* K47 */ be_nested_str_weak(rtc_utc), + /* K48 */ be_const_int(1000000), + /* K49 */ be_nested_str_weak(rtc), + /* K50 */ be_nested_str_weak(local), + /* K51 */ be_nested_str_weak(ack_request), + /* K52 */ be_nested_str_weak(fabric_filtered), + /* K53 */ be_nested_str_weak(get_fabric), + /* K54 */ be_nested_str_weak(device), + /* K55 */ be_nested_str_weak(sessions), + /* K56 */ be_nested_str_weak(active_fabrics), + /* K57 */ be_nested_str_weak(B2), + /* K58 */ be_nested_str_weak(get_noc), + /* K59 */ be_nested_str_weak(get_icac), + /* K60 */ be_nested_str_weak(get_fabric_index), + /* K61 */ be_nested_str_weak(stop_iteration), + /* K62 */ be_nested_str_weak(parse), + /* K63 */ be_nested_str_weak(get_ca), + /* K64 */ be_nested_str_weak(findsubval), + /* K65 */ be_nested_str_weak(get_admin_vendor), + /* K66 */ be_nested_str_weak(get_fabric_id), + /* K67 */ be_nested_str_weak(get_device_id), + /* K68 */ be_nested_str_weak(get_fabric_label), + /* K69 */ be_nested_str_weak(Fabric), + /* K70 */ be_nested_str_weak(_MAX_CASE), + /* K71 */ be_nested_str_weak(count_active_fabrics), + /* K72 */ be_nested_str_weak(_fabric), + /* K73 */ be_nested_str_weak(is_commissioning_open), + /* K74 */ be_nested_str_weak(is_root_commissioning_open), + /* K75 */ be_nested_str_weak(commissioning_admin_fabric), + /* K76 */ be_nested_str_weak(Tasmota), + /* K77 */ be_nested_str_weak(vendorid), + /* K78 */ be_nested_str_weak(DeviceName), + /* K79 */ be_nested_str_weak(FriendlyName), + /* K80 */ be_nested_str_weak(FriendlyName1), + /* K81 */ be_nested_str_weak(XX), + /* K82 */ be_nested_str_weak(Status_X202), + /* K83 */ be_nested_str_weak(StatusFWR), + /* K84 */ be_nested_str_weak(Hardware), + /* K85 */ be_nested_str_weak(Version), + /* K86 */ be_nested_str_weak(_X28), + /* K87 */ be_nested_str_weak(locale), + /* K88 */ be_nested_str_weak(create_TLV), + /* K89 */ be_nested_str_weak(get_active_endpoints), + /* K90 */ be_nested_str_weak(disable_bridge_mode), + /* K91 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[937]) { /* code */ + 0xA4120000, // 0000 IMPORT R4 K0 + 0xB8160200, // 0001 GETNGBL R5 K1 + 0x88140B02, // 0002 GETMBR R5 R5 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x881C0504, // 0004 GETMBR R7 R2 K4 + 0x5422002F, // 0005 LDINT R8 48 + 0x1C200C08, // 0006 EQ R8 R6 R8 + 0x78220030, // 0007 JMPF R8 #0039 + 0x1C200F05, // 0008 EQ R8 R7 K5 + 0x78220005, // 0009 JMPF R8 #0010 + 0x8C200706, // 000A GETMET R8 R3 K6 + 0x88280B07, // 000B GETMBR R10 R5 K7 + 0x882C0308, // 000C GETMBR R11 R1 K8 + 0x7C200600, // 000D CALL R8 3 + 0x80041000, // 000E RET 1 R8 + 0x70020027, // 000F JMP #0038 + 0x1C200F09, // 0010 EQ R8 R7 K9 + 0x7822000D, // 0011 JMPF R8 #0020 + 0x8C200B0A, // 0012 GETMET R8 R5 K10 + 0x7C200200, // 0013 CALL R8 1 + 0x8C24110B, // 0014 GETMET R9 R8 K11 + 0x582C0005, // 0015 LDCONST R11 K5 + 0x88300B0C, // 0016 GETMBR R12 R5 K12 + 0x5436003B, // 0017 LDINT R13 60 + 0x7C240800, // 0018 CALL R9 4 + 0x8C24110B, // 0019 GETMET R9 R8 K11 + 0x582C0009, // 001A LDCONST R11 K9 + 0x88300B0C, // 001B GETMBR R12 R5 K12 + 0x54360383, // 001C LDINT R13 900 + 0x7C240800, // 001D CALL R9 4 + 0x80041000, // 001E RET 1 R8 + 0x70020017, // 001F JMP #0038 + 0x1C200F0D, // 0020 EQ R8 R7 K13 + 0x78220005, // 0021 JMPF R8 #0028 + 0x8C200706, // 0022 GETMET R8 R3 K6 + 0x88280B0E, // 0023 GETMBR R10 R5 K14 + 0x582C000D, // 0024 LDCONST R11 K13 + 0x7C200600, // 0025 CALL R8 3 + 0x80041000, // 0026 RET 1 R8 + 0x7002000F, // 0027 JMP #0038 + 0x1C200F0F, // 0028 EQ R8 R7 K15 + 0x78220005, // 0029 JMPF R8 #0030 + 0x8C200706, // 002A GETMET R8 R3 K6 + 0x88280B0E, // 002B GETMBR R10 R5 K14 + 0x582C000D, // 002C LDCONST R11 K13 + 0x7C200600, // 002D CALL R8 3 + 0x80041000, // 002E RET 1 R8 + 0x70020007, // 002F JMP #0038 + 0x54220003, // 0030 LDINT R8 4 + 0x1C200E08, // 0031 EQ R8 R7 R8 + 0x78220004, // 0032 JMPF R8 #0038 + 0x8C200706, // 0033 GETMET R8 R3 K6 + 0x88280B10, // 0034 GETMBR R10 R5 K16 + 0x502C0000, // 0035 LDBOOL R11 0 0 + 0x7C200600, // 0036 CALL R8 3 + 0x80041000, // 0037 RET 1 R8 + 0x7002036E, // 0038 JMP #03A8 + 0x54220031, // 0039 LDINT R8 50 + 0x1C200C08, // 003A EQ R8 R6 R8 + 0x78220000, // 003B JMPF R8 #003D + 0x7002036A, // 003C JMP #03A8 + 0x54220032, // 003D LDINT R8 51 + 0x1C200C08, // 003E EQ R8 R6 R8 + 0x782200DC, // 003F JMPF R8 #011D + 0x1C200F05, // 0040 EQ R8 R7 K5 + 0x782200B5, // 0041 JMPF R8 #00F8 + 0x8C200B11, // 0042 GETMET R8 R5 K17 + 0x7C200200, // 0043 CALL R8 1 + 0xB8262400, // 0044 GETNGBL R9 K18 + 0x8C241313, // 0045 GETMET R9 R9 K19 + 0x7C240200, // 0046 CALL R9 1 + 0x94281314, // 0047 GETIDX R10 R9 K20 + 0x782A0053, // 0048 JMPF R10 #009D + 0x8C281115, // 0049 GETMET R10 R8 K21 + 0x4C300000, // 004A LDNIL R12 + 0x7C280400, // 004B CALL R10 2 + 0x8C2C150B, // 004C GETMET R11 R10 K11 + 0x58340005, // 004D LDCONST R13 K5 + 0x88380B16, // 004E GETMBR R14 R5 K22 + 0x583C0017, // 004F LDCONST R15 K23 + 0x7C2C0800, // 0050 CALL R11 4 + 0x8C2C150B, // 0051 GETMET R11 R10 K11 + 0x58340009, // 0052 LDCONST R13 K9 + 0x88380B10, // 0053 GETMBR R14 R5 K16 + 0x583C0009, // 0054 LDCONST R15 K9 + 0x7C2C0800, // 0055 CALL R11 4 + 0x8C2C150B, // 0056 GETMET R11 R10 K11 + 0x5834000D, // 0057 LDCONST R13 K13 + 0x88380B10, // 0058 GETMBR R14 R5 K16 + 0x583C0009, // 0059 LDCONST R15 K9 + 0x7C2C0800, // 005A CALL R11 4 + 0x8C2C150B, // 005B GETMET R11 R10 K11 + 0x5834000F, // 005C LDCONST R13 K15 + 0x88380B18, // 005D GETMBR R14 R5 K24 + 0x4C3C0000, // 005E LDNIL R15 + 0x7C2C0800, // 005F CALL R11 4 + 0x602C0015, // 0060 GETGBL R11 G21 + 0x7C2C0000, // 0061 CALL R11 0 + 0x8C2C1719, // 0062 GETMET R11 R11 K25 + 0x8C34091A, // 0063 GETMET R13 R4 K26 + 0x8C3C131B, // 0064 GETMET R15 R9 K27 + 0x5844001C, // 0065 LDCONST R17 K28 + 0x5848001D, // 0066 LDCONST R18 K29 + 0x7C3C0600, // 0067 CALL R15 3 + 0x5840001E, // 0068 LDCONST R16 K30 + 0x5844001D, // 0069 LDCONST R17 K29 + 0x7C340800, // 006A CALL R13 4 + 0x7C2C0400, // 006B CALL R11 2 + 0x8C30150B, // 006C GETMET R12 R10 K11 + 0x543A0003, // 006D LDINT R14 4 + 0x883C0B1F, // 006E GETMBR R15 R5 K31 + 0x5C401600, // 006F MOVE R16 R11 + 0x7C300800, // 0070 CALL R12 4 + 0x8C301520, // 0071 GETMET R12 R10 K32 + 0x543A0004, // 0072 LDINT R14 5 + 0x7C300400, // 0073 CALL R12 2 + 0x8C34190B, // 0074 GETMET R13 R12 K11 + 0x4C3C0000, // 0075 LDNIL R15 + 0x88400B1F, // 0076 GETMBR R16 R5 K31 + 0xB8460200, // 0077 GETNGBL R17 K1 + 0x8C442321, // 0078 GETMET R17 R17 K33 + 0x8C4C131B, // 0079 GETMET R19 R9 K27 + 0x58540022, // 007A LDCONST R21 K34 + 0x5858001D, // 007B LDCONST R22 K29 + 0x7C4C0600, // 007C CALL R19 3 + 0x7C440400, // 007D CALL R17 2 + 0x7C340800, // 007E CALL R13 4 + 0x8C341520, // 007F GETMET R13 R10 K32 + 0x543E0005, // 0080 LDINT R15 6 + 0x7C340400, // 0081 CALL R13 2 + 0x8C381B0B, // 0082 GETMET R14 R13 K11 + 0x4C400000, // 0083 LDNIL R16 + 0x88440B1F, // 0084 GETMBR R17 R5 K31 + 0xB84A0200, // 0085 GETNGBL R18 K1 + 0x8C482521, // 0086 GETMET R18 R18 K33 + 0x8C50131B, // 0087 GETMET R20 R9 K27 + 0x58580023, // 0088 LDCONST R22 K35 + 0x585C001D, // 0089 LDCONST R23 K29 + 0x7C500600, // 008A CALL R20 3 + 0x7C480400, // 008B CALL R18 2 + 0x7C380800, // 008C CALL R14 4 + 0x8C381B0B, // 008D GETMET R14 R13 K11 + 0x4C400000, // 008E LDNIL R16 + 0x88440B1F, // 008F GETMBR R17 R5 K31 + 0xB84A0200, // 0090 GETNGBL R18 K1 + 0x8C482521, // 0091 GETMET R18 R18 K33 + 0x8C50131B, // 0092 GETMET R20 R9 K27 + 0x58580024, // 0093 LDCONST R22 K36 + 0x585C001D, // 0094 LDCONST R23 K29 + 0x7C500600, // 0095 CALL R20 3 + 0x7C480400, // 0096 CALL R18 2 + 0x7C380800, // 0097 CALL R14 4 + 0x8C38150B, // 0098 GETMET R14 R10 K11 + 0x54420006, // 0099 LDINT R16 7 + 0x88440B0E, // 009A GETMBR R17 R5 K14 + 0x5848000D, // 009B LDCONST R18 K13 + 0x7C380800, // 009C CALL R14 4 + 0xB82A2400, // 009D GETNGBL R10 K18 + 0x8C281525, // 009E GETMET R10 R10 K37 + 0x7C280200, // 009F CALL R10 1 + 0x942C1514, // 00A0 GETIDX R11 R10 K20 + 0x782E0053, // 00A1 JMPF R11 #00F6 + 0x8C2C1115, // 00A2 GETMET R11 R8 K21 + 0x4C340000, // 00A3 LDNIL R13 + 0x7C2C0400, // 00A4 CALL R11 2 + 0x8C30170B, // 00A5 GETMET R12 R11 K11 + 0x58380005, // 00A6 LDCONST R14 K5 + 0x883C0B16, // 00A7 GETMBR R15 R5 K22 + 0x58400025, // 00A8 LDCONST R16 K37 + 0x7C300800, // 00A9 CALL R12 4 + 0x8C30170B, // 00AA GETMET R12 R11 K11 + 0x58380009, // 00AB LDCONST R14 K9 + 0x883C0B10, // 00AC GETMBR R15 R5 K16 + 0x58400009, // 00AD LDCONST R16 K9 + 0x7C300800, // 00AE CALL R12 4 + 0x8C30170B, // 00AF GETMET R12 R11 K11 + 0x5838000D, // 00B0 LDCONST R14 K13 + 0x883C0B10, // 00B1 GETMBR R15 R5 K16 + 0x58400009, // 00B2 LDCONST R16 K9 + 0x7C300800, // 00B3 CALL R12 4 + 0x8C30170B, // 00B4 GETMET R12 R11 K11 + 0x5838000F, // 00B5 LDCONST R14 K15 + 0x883C0B18, // 00B6 GETMBR R15 R5 K24 + 0x4C400000, // 00B7 LDNIL R16 + 0x7C300800, // 00B8 CALL R12 4 + 0x60300015, // 00B9 GETGBL R12 G21 + 0x7C300000, // 00BA CALL R12 0 + 0x8C301919, // 00BB GETMET R12 R12 K25 + 0x8C38091A, // 00BC GETMET R14 R4 K26 + 0x8C40151B, // 00BD GETMET R16 R10 K27 + 0x5848001C, // 00BE LDCONST R18 K28 + 0x584C001D, // 00BF LDCONST R19 K29 + 0x7C400600, // 00C0 CALL R16 3 + 0x5844001E, // 00C1 LDCONST R17 K30 + 0x5848001D, // 00C2 LDCONST R18 K29 + 0x7C380800, // 00C3 CALL R14 4 + 0x7C300400, // 00C4 CALL R12 2 + 0x8C34170B, // 00C5 GETMET R13 R11 K11 + 0x543E0003, // 00C6 LDINT R15 4 + 0x88400B1F, // 00C7 GETMBR R16 R5 K31 + 0x5C441800, // 00C8 MOVE R17 R12 + 0x7C340800, // 00C9 CALL R13 4 + 0x8C341720, // 00CA GETMET R13 R11 K32 + 0x543E0004, // 00CB LDINT R15 5 + 0x7C340400, // 00CC CALL R13 2 + 0x8C381B0B, // 00CD GETMET R14 R13 K11 + 0x4C400000, // 00CE LDNIL R16 + 0x88440B1F, // 00CF GETMBR R17 R5 K31 + 0xB84A0200, // 00D0 GETNGBL R18 K1 + 0x8C482521, // 00D1 GETMET R18 R18 K33 + 0x8C50151B, // 00D2 GETMET R20 R10 K27 + 0x58580022, // 00D3 LDCONST R22 K34 + 0x585C001D, // 00D4 LDCONST R23 K29 + 0x7C500600, // 00D5 CALL R20 3 + 0x7C480400, // 00D6 CALL R18 2 + 0x7C380800, // 00D7 CALL R14 4 + 0x8C381720, // 00D8 GETMET R14 R11 K32 + 0x54420005, // 00D9 LDINT R16 6 + 0x7C380400, // 00DA CALL R14 2 + 0x8C3C1D0B, // 00DB GETMET R15 R14 K11 + 0x4C440000, // 00DC LDNIL R17 + 0x88480B1F, // 00DD GETMBR R18 R5 K31 + 0xB84E0200, // 00DE GETNGBL R19 K1 + 0x8C4C2721, // 00DF GETMET R19 R19 K33 + 0x8C54151B, // 00E0 GETMET R21 R10 K27 + 0x585C0023, // 00E1 LDCONST R23 K35 + 0x5860001D, // 00E2 LDCONST R24 K29 + 0x7C540600, // 00E3 CALL R21 3 + 0x7C4C0400, // 00E4 CALL R19 2 + 0x7C3C0800, // 00E5 CALL R15 4 + 0x8C3C1D0B, // 00E6 GETMET R15 R14 K11 + 0x4C440000, // 00E7 LDNIL R17 + 0x88480B1F, // 00E8 GETMBR R18 R5 K31 + 0xB84E0200, // 00E9 GETNGBL R19 K1 + 0x8C4C2721, // 00EA GETMET R19 R19 K33 + 0x8C54151B, // 00EB GETMET R21 R10 K27 + 0x585C0024, // 00EC LDCONST R23 K36 + 0x5860001D, // 00ED LDCONST R24 K29 + 0x7C540600, // 00EE CALL R21 3 + 0x7C4C0400, // 00EF CALL R19 2 + 0x7C3C0800, // 00F0 CALL R15 4 + 0x8C3C170B, // 00F1 GETMET R15 R11 K11 + 0x54460006, // 00F2 LDINT R17 7 + 0x88480B0E, // 00F3 GETMBR R18 R5 K14 + 0x584C0009, // 00F4 LDCONST R19 K9 + 0x7C3C0800, // 00F5 CALL R15 4 + 0x80041000, // 00F6 RET 1 R8 + 0x70020023, // 00F7 JMP #011C + 0x1C200F09, // 00F8 EQ R8 R7 K9 + 0x7822000B, // 00F9 JMPF R8 #0106 + 0x8C200706, // 00FA GETMET R8 R3 K6 + 0x88280B0C, // 00FB GETMBR R10 R5 K12 + 0xB82E2400, // 00FC GETNGBL R11 K18 + 0x8C2C1726, // 00FD GETMET R11 R11 K38 + 0x58340027, // 00FE LDCONST R13 K39 + 0x50380200, // 00FF LDBOOL R14 1 0 + 0x7C2C0600, // 0100 CALL R11 3 + 0x942C1728, // 0101 GETIDX R11 R11 K40 + 0x942C1729, // 0102 GETIDX R11 R11 K41 + 0x7C200600, // 0103 CALL R8 3 + 0x80041000, // 0104 RET 1 R8 + 0x70020015, // 0105 JMP #011C + 0x1C200F0D, // 0106 EQ R8 R7 K13 + 0x7822000B, // 0107 JMPF R8 #0114 + 0x8C200706, // 0108 GETMET R8 R3 K6 + 0x88280B2A, // 0109 GETMBR R10 R5 K42 + 0xB82E2400, // 010A GETNGBL R11 K18 + 0x8C2C1726, // 010B GETMET R11 R11 K38 + 0x5834002B, // 010C LDCONST R13 K43 + 0x50380200, // 010D LDBOOL R14 1 0 + 0x7C2C0600, // 010E CALL R11 3 + 0x942C172C, // 010F GETIDX R11 R11 K44 + 0x942C172D, // 0110 GETIDX R11 R11 K45 + 0x7C200600, // 0111 CALL R8 3 + 0x80041000, // 0112 RET 1 R8 + 0x70020007, // 0113 JMP #011C + 0x54220007, // 0114 LDINT R8 8 + 0x1C200E08, // 0115 EQ R8 R7 R8 + 0x78220004, // 0116 JMPF R8 #011C + 0x8C200706, // 0117 GETMET R8 R3 K6 + 0x88280B10, // 0118 GETMBR R10 R5 K16 + 0x502C0000, // 0119 LDBOOL R11 0 0 + 0x7C200600, // 011A CALL R8 3 + 0x80041000, // 011B RET 1 R8 + 0x7002028A, // 011C JMP #03A8 + 0x54220033, // 011D LDINT R8 52 + 0x1C200C08, // 011E EQ R8 R6 R8 + 0x78220000, // 011F JMPF R8 #0121 + 0x70020286, // 0120 JMP #03A8 + 0x54220037, // 0121 LDINT R8 56 + 0x1C200C08, // 0122 EQ R8 R6 R8 + 0x7822002B, // 0123 JMPF R8 #0150 + 0x1C200F05, // 0124 EQ R8 R7 K5 + 0x7822000E, // 0125 JMPF R8 #0135 + 0xB8225C00, // 0126 GETNGBL R8 K46 + 0xB8262400, // 0127 GETNGBL R9 K18 + 0x8C24132F, // 0128 GETMET R9 R9 K47 + 0x7C240200, // 0129 CALL R9 1 + 0x7C200200, // 012A CALL R8 1 + 0xB8265C00, // 012B GETNGBL R9 K46 + 0x58280030, // 012C LDCONST R10 K48 + 0x7C240200, // 012D CALL R9 1 + 0x08201009, // 012E MUL R8 R8 R9 + 0x8C240706, // 012F GETMET R9 R3 K6 + 0x882C0B07, // 0130 GETMBR R11 R5 K7 + 0x5C301000, // 0131 MOVE R12 R8 + 0x7C240600, // 0132 CALL R9 3 + 0x80041200, // 0133 RET 1 R9 + 0x70020019, // 0134 JMP #014F + 0x1C200F09, // 0135 EQ R8 R7 K9 + 0x78220005, // 0136 JMPF R8 #013D + 0x8C200706, // 0137 GETMET R8 R3 K6 + 0x88280B0E, // 0138 GETMBR R10 R5 K14 + 0x582C000F, // 0139 LDCONST R11 K15 + 0x7C200600, // 013A CALL R8 3 + 0x80041000, // 013B RET 1 R8 + 0x70020011, // 013C JMP #014F + 0x54220006, // 013D LDINT R8 7 + 0x1C200E08, // 013E EQ R8 R7 R8 + 0x7822000E, // 013F JMPF R8 #014F + 0xB8225C00, // 0140 GETNGBL R8 K46 + 0xB8262400, // 0141 GETNGBL R9 K18 + 0x8C241331, // 0142 GETMET R9 R9 K49 + 0x7C240200, // 0143 CALL R9 1 + 0x94241332, // 0144 GETIDX R9 R9 K50 + 0x7C200200, // 0145 CALL R8 1 + 0xB8265C00, // 0146 GETNGBL R9 K46 + 0x58280030, // 0147 LDCONST R10 K48 + 0x7C240200, // 0148 CALL R9 1 + 0x08201009, // 0149 MUL R8 R8 R9 + 0x8C240706, // 014A GETMET R9 R3 K6 + 0x882C0B07, // 014B GETMBR R11 R5 K7 + 0x5C301000, // 014C MOVE R12 R8 + 0x7C240600, // 014D CALL R9 3 + 0x80041200, // 014E RET 1 R9 + 0x70020257, // 014F JMP #03A8 + 0x5422003D, // 0150 LDINT R8 62 + 0x1C200C08, // 0151 EQ R8 R6 R8 + 0x782200AD, // 0152 JMPF R8 #0201 + 0x8C200133, // 0153 GETMET R8 R0 K51 + 0x5C280400, // 0154 MOVE R10 R2 + 0x7C200400, // 0155 CALL R8 2 + 0x1C200F05, // 0156 EQ R8 R7 K5 + 0x78220032, // 0157 JMPF R8 #018B + 0x8C200B11, // 0158 GETMET R8 R5 K17 + 0x7C200200, // 0159 CALL R8 1 + 0x88240534, // 015A GETMBR R9 R2 K52 + 0x78260005, // 015B JMPF R9 #0162 + 0x60240012, // 015C GETGBL R9 G18 + 0x7C240000, // 015D CALL R9 0 + 0x8C280335, // 015E GETMET R10 R1 K53 + 0x7C280200, // 015F CALL R10 1 + 0x4028120A, // 0160 CONNECT R10 R9 R10 + 0x70020003, // 0161 JMP #0166 + 0x88240136, // 0162 GETMBR R9 R0 K54 + 0x88241337, // 0163 GETMBR R9 R9 K55 + 0x8C241338, // 0164 GETMET R9 R9 K56 + 0x7C240200, // 0165 CALL R9 1 + 0x60280010, // 0166 GETGBL R10 G16 + 0x5C2C1200, // 0167 MOVE R11 R9 + 0x7C280200, // 0168 CALL R10 1 + 0xA802001B, // 0169 EXBLK 0 #0186 + 0x5C2C1400, // 016A MOVE R11 R10 + 0x7C2C0000, // 016B CALL R11 0 + 0x4C300000, // 016C LDNIL R12 + 0x1C30160C, // 016D EQ R12 R11 R12 + 0x78320000, // 016E JMPF R12 #0170 + 0x7001FFF9, // 016F JMP #016A + 0x8C301115, // 0170 GETMET R12 R8 K21 + 0x4C380000, // 0171 LDNIL R14 + 0x7C300400, // 0172 CALL R12 2 + 0x8C34190B, // 0173 GETMET R13 R12 K11 + 0x583C0009, // 0174 LDCONST R15 K9 + 0x88400B39, // 0175 GETMBR R16 R5 K57 + 0x8C44173A, // 0176 GETMET R17 R11 K58 + 0x7C440200, // 0177 CALL R17 1 + 0x7C340800, // 0178 CALL R13 4 + 0x8C34190B, // 0179 GETMET R13 R12 K11 + 0x583C000D, // 017A LDCONST R15 K13 + 0x88400B39, // 017B GETMBR R16 R5 K57 + 0x8C44173B, // 017C GETMET R17 R11 K59 + 0x7C440200, // 017D CALL R17 1 + 0x7C340800, // 017E CALL R13 4 + 0x8C34190B, // 017F GETMET R13 R12 K11 + 0x543E00FD, // 0180 LDINT R15 254 + 0x88400B0C, // 0181 GETMBR R16 R5 K12 + 0x8C44173C, // 0182 GETMET R17 R11 K60 + 0x7C440200, // 0183 CALL R17 1 + 0x7C340800, // 0184 CALL R13 4 + 0x7001FFE3, // 0185 JMP #016A + 0x5828003D, // 0186 LDCONST R10 K61 + 0xAC280200, // 0187 CATCH R10 1 0 + 0xB0080000, // 0188 RAISE 2 R0 R0 + 0x80041000, // 0189 RET 1 R8 + 0x70020074, // 018A JMP #0200 + 0x1C200F09, // 018B EQ R8 R7 K9 + 0x78220049, // 018C JMPF R8 #01D7 + 0x8C200B11, // 018D GETMET R8 R5 K17 + 0x7C200200, // 018E CALL R8 1 + 0x88240534, // 018F GETMBR R9 R2 K52 + 0x78260005, // 0190 JMPF R9 #0197 + 0x60240012, // 0191 GETGBL R9 G18 + 0x7C240000, // 0192 CALL R9 0 + 0x8C280335, // 0193 GETMET R10 R1 K53 + 0x7C280200, // 0194 CALL R10 1 + 0x4028120A, // 0195 CONNECT R10 R9 R10 + 0x70020003, // 0196 JMP #019B + 0x88240136, // 0197 GETMBR R9 R0 K54 + 0x88241337, // 0198 GETMBR R9 R9 K55 + 0x8C241338, // 0199 GETMET R9 R9 K56 + 0x7C240200, // 019A CALL R9 1 + 0x60280010, // 019B GETGBL R10 G16 + 0x5C2C1200, // 019C MOVE R11 R9 + 0x7C280200, // 019D CALL R10 1 + 0xA8020032, // 019E EXBLK 0 #01D2 + 0x5C2C1400, // 019F MOVE R11 R10 + 0x7C2C0000, // 01A0 CALL R11 0 + 0x4C300000, // 01A1 LDNIL R12 + 0x1C30160C, // 01A2 EQ R12 R11 R12 + 0x78320000, // 01A3 JMPF R12 #01A5 + 0x7001FFF9, // 01A4 JMP #019F + 0x8C300B3E, // 01A5 GETMET R12 R5 K62 + 0x8C38173F, // 01A6 GETMET R14 R11 K63 + 0x7C380200, // 01A7 CALL R14 1 + 0x7C300400, // 01A8 CALL R12 2 + 0x8C341115, // 01A9 GETMET R13 R8 K21 + 0x4C3C0000, // 01AA LDNIL R15 + 0x7C340400, // 01AB CALL R13 2 + 0x8C381B0B, // 01AC GETMET R14 R13 K11 + 0x58400009, // 01AD LDCONST R16 K9 + 0x88440B39, // 01AE GETMBR R17 R5 K57 + 0x8C481940, // 01AF GETMET R18 R12 K64 + 0x54520008, // 01B0 LDINT R20 9 + 0x7C480400, // 01B1 CALL R18 2 + 0x7C380800, // 01B2 CALL R14 4 + 0x8C381B0B, // 01B3 GETMET R14 R13 K11 + 0x5840000D, // 01B4 LDCONST R16 K13 + 0x88440B0C, // 01B5 GETMBR R17 R5 K12 + 0x8C481741, // 01B6 GETMET R18 R11 K65 + 0x7C480200, // 01B7 CALL R18 1 + 0x7C380800, // 01B8 CALL R14 4 + 0x8C381B0B, // 01B9 GETMET R14 R13 K11 + 0x5840000F, // 01BA LDCONST R16 K15 + 0x88440B07, // 01BB GETMBR R17 R5 K7 + 0x8C481742, // 01BC GETMET R18 R11 K66 + 0x7C480200, // 01BD CALL R18 1 + 0x7C380800, // 01BE CALL R14 4 + 0x8C381B0B, // 01BF GETMET R14 R13 K11 + 0x54420003, // 01C0 LDINT R16 4 + 0x88440B07, // 01C1 GETMBR R17 R5 K7 + 0x8C481743, // 01C2 GETMET R18 R11 K67 + 0x7C480200, // 01C3 CALL R18 1 + 0x7C380800, // 01C4 CALL R14 4 + 0x8C381B0B, // 01C5 GETMET R14 R13 K11 + 0x54420004, // 01C6 LDINT R16 5 + 0x88440B16, // 01C7 GETMBR R17 R5 K22 + 0x8C481744, // 01C8 GETMET R18 R11 K68 + 0x7C480200, // 01C9 CALL R18 1 + 0x7C380800, // 01CA CALL R14 4 + 0x8C381B0B, // 01CB GETMET R14 R13 K11 + 0x544200FD, // 01CC LDINT R16 254 + 0x88440B0C, // 01CD GETMBR R17 R5 K12 + 0x8C48173C, // 01CE GETMET R18 R11 K60 + 0x7C480200, // 01CF CALL R18 1 + 0x7C380800, // 01D0 CALL R14 4 + 0x7001FFCC, // 01D1 JMP #019F + 0x5828003D, // 01D2 LDCONST R10 K61 + 0xAC280200, // 01D3 CATCH R10 1 0 + 0xB0080000, // 01D4 RAISE 2 R0 R0 + 0x80041000, // 01D5 RET 1 R8 + 0x70020028, // 01D6 JMP #0200 + 0x1C200F0D, // 01D7 EQ R8 R7 K13 + 0x78220007, // 01D8 JMPF R8 #01E1 + 0x8C200706, // 01D9 GETMET R8 R3 K6 + 0x88280B0E, // 01DA GETMBR R10 R5 K14 + 0xB82E0200, // 01DB GETNGBL R11 K1 + 0x882C1745, // 01DC GETMBR R11 R11 K69 + 0x882C1746, // 01DD GETMBR R11 R11 K70 + 0x7C200600, // 01DE CALL R8 3 + 0x80041000, // 01DF RET 1 R8 + 0x7002001E, // 01E0 JMP #0200 + 0x1C200F0F, // 01E1 EQ R8 R7 K15 + 0x78220009, // 01E2 JMPF R8 #01ED + 0x88200136, // 01E3 GETMBR R8 R0 K54 + 0x88201137, // 01E4 GETMBR R8 R8 K55 + 0x8C201147, // 01E5 GETMET R8 R8 K71 + 0x7C200200, // 01E6 CALL R8 1 + 0x8C240706, // 01E7 GETMET R9 R3 K6 + 0x882C0B0E, // 01E8 GETMBR R11 R5 K14 + 0x5C301000, // 01E9 MOVE R12 R8 + 0x7C240600, // 01EA CALL R9 3 + 0x80041200, // 01EB RET 1 R9 + 0x70020012, // 01EC JMP #0200 + 0x54220003, // 01ED LDINT R8 4 + 0x1C200E08, // 01EE EQ R8 R7 R8 + 0x78220000, // 01EF JMPF R8 #01F1 + 0x7002000E, // 01F0 JMP #0200 + 0x54220004, // 01F1 LDINT R8 5 + 0x1C200E08, // 01F2 EQ R8 R7 R8 + 0x7822000B, // 01F3 JMPF R8 #0200 + 0x88200348, // 01F4 GETMBR R8 R1 K72 + 0x8C20113C, // 01F5 GETMET R8 R8 K60 + 0x7C200200, // 01F6 CALL R8 1 + 0x4C240000, // 01F7 LDNIL R9 + 0x1C241009, // 01F8 EQ R9 R8 R9 + 0x78260000, // 01F9 JMPF R9 #01FB + 0x58200005, // 01FA LDCONST R8 K5 + 0x8C240706, // 01FB GETMET R9 R3 K6 + 0x882C0B0E, // 01FC GETMBR R11 R5 K14 + 0x5C301000, // 01FD MOVE R12 R8 + 0x7C240600, // 01FE CALL R9 3 + 0x80041200, // 01FF RET 1 R9 + 0x700201A6, // 0200 JMP #03A8 + 0x5422003B, // 0201 LDINT R8 60 + 0x1C200C08, // 0202 EQ R8 R6 R8 + 0x7822003C, // 0203 JMPF R8 #0241 + 0x1C200F05, // 0204 EQ R8 R7 K5 + 0x78220012, // 0205 JMPF R8 #0219 + 0x88200136, // 0206 GETMBR R8 R0 K54 + 0x8C201149, // 0207 GETMET R8 R8 K73 + 0x7C200200, // 0208 CALL R8 1 + 0x88240136, // 0209 GETMBR R9 R0 K54 + 0x8C24134A, // 020A GETMET R9 R9 K74 + 0x7C240200, // 020B CALL R9 1 + 0x78220004, // 020C JMPF R8 #0212 + 0x78260001, // 020D JMPF R9 #0210 + 0x5828000D, // 020E LDCONST R10 K13 + 0x70020000, // 020F JMP #0211 + 0x58280009, // 0210 LDCONST R10 K9 + 0x70020000, // 0211 JMP #0213 + 0x58280005, // 0212 LDCONST R10 K5 + 0x8C2C0706, // 0213 GETMET R11 R3 K6 + 0x88340B0E, // 0214 GETMBR R13 R5 K14 + 0x5C381400, // 0215 MOVE R14 R10 + 0x7C2C0600, // 0216 CALL R11 3 + 0x80041600, // 0217 RET 1 R11 + 0x70020026, // 0218 JMP #0240 + 0x1C200F09, // 0219 EQ R8 R7 K9 + 0x78220011, // 021A JMPF R8 #022D + 0x88200136, // 021B GETMBR R8 R0 K54 + 0x8820114B, // 021C GETMBR R8 R8 K75 + 0x4C240000, // 021D LDNIL R9 + 0x20241009, // 021E NE R9 R8 R9 + 0x78260006, // 021F JMPF R9 #0227 + 0x8C240706, // 0220 GETMET R9 R3 K6 + 0x882C0B0C, // 0221 GETMBR R11 R5 K12 + 0x8C30113C, // 0222 GETMET R12 R8 K60 + 0x7C300200, // 0223 CALL R12 1 + 0x7C240600, // 0224 CALL R9 3 + 0x80041200, // 0225 RET 1 R9 + 0x70020004, // 0226 JMP #022C + 0x8C240706, // 0227 GETMET R9 R3 K6 + 0x882C0B18, // 0228 GETMBR R11 R5 K24 + 0x4C300000, // 0229 LDNIL R12 + 0x7C240600, // 022A CALL R9 3 + 0x80041200, // 022B RET 1 R9 + 0x70020012, // 022C JMP #0240 + 0x1C200F0D, // 022D EQ R8 R7 K13 + 0x78220010, // 022E JMPF R8 #0240 + 0x88200136, // 022F GETMBR R8 R0 K54 + 0x8820114B, // 0230 GETMBR R8 R8 K75 + 0x4C240000, // 0231 LDNIL R9 + 0x20241009, // 0232 NE R9 R8 R9 + 0x78260006, // 0233 JMPF R9 #023B + 0x8C240706, // 0234 GETMET R9 R3 K6 + 0x882C0B0C, // 0235 GETMBR R11 R5 K12 + 0x8C301141, // 0236 GETMET R12 R8 K65 + 0x7C300200, // 0237 CALL R12 1 + 0x7C240600, // 0238 CALL R9 3 + 0x80041200, // 0239 RET 1 R9 + 0x70020004, // 023A JMP #0240 + 0x8C240706, // 023B GETMET R9 R3 K6 + 0x882C0B18, // 023C GETMBR R11 R5 K24 + 0x4C300000, // 023D LDNIL R12 + 0x7C240600, // 023E CALL R9 3 + 0x80041200, // 023F RET 1 R9 + 0x70020166, // 0240 JMP #03A8 + 0x54220027, // 0241 LDINT R8 40 + 0x1C200C08, // 0242 EQ R8 R6 R8 + 0x782200BA, // 0243 JMPF R8 #02FF + 0x8C200133, // 0244 GETMET R8 R0 K51 + 0x5C280400, // 0245 MOVE R10 R2 + 0x7C200400, // 0246 CALL R8 2 + 0x1C200F05, // 0247 EQ R8 R7 K5 + 0x78220005, // 0248 JMPF R8 #024F + 0x8C200706, // 0249 GETMET R8 R3 K6 + 0x88280B0C, // 024A GETMBR R10 R5 K12 + 0x582C0009, // 024B LDCONST R11 K9 + 0x7C200600, // 024C CALL R8 3 + 0x80041000, // 024D RET 1 R8 + 0x700200AE, // 024E JMP #02FE + 0x1C200F09, // 024F EQ R8 R7 K9 + 0x78220005, // 0250 JMPF R8 #0257 + 0x8C200706, // 0251 GETMET R8 R3 K6 + 0x88280B16, // 0252 GETMBR R10 R5 K22 + 0x582C004C, // 0253 LDCONST R11 K76 + 0x7C200600, // 0254 CALL R8 3 + 0x80041000, // 0255 RET 1 R8 + 0x700200A6, // 0256 JMP #02FE + 0x1C200F0D, // 0257 EQ R8 R7 K13 + 0x78220006, // 0258 JMPF R8 #0260 + 0x8C200706, // 0259 GETMET R8 R3 K6 + 0x88280B0C, // 025A GETMBR R10 R5 K12 + 0x882C0136, // 025B GETMBR R11 R0 K54 + 0x882C174D, // 025C GETMBR R11 R11 K77 + 0x7C200600, // 025D CALL R8 3 + 0x80041000, // 025E RET 1 R8 + 0x7002009D, // 025F JMP #02FE + 0x1C200F0F, // 0260 EQ R8 R7 K15 + 0x7822000A, // 0261 JMPF R8 #026D + 0x8C200706, // 0262 GETMET R8 R3 K6 + 0x88280B16, // 0263 GETMBR R10 R5 K22 + 0xB82E2400, // 0264 GETNGBL R11 K18 + 0x8C2C1726, // 0265 GETMET R11 R11 K38 + 0x5834004E, // 0266 LDCONST R13 K78 + 0x50380200, // 0267 LDBOOL R14 1 0 + 0x7C2C0600, // 0268 CALL R11 3 + 0x942C174E, // 0269 GETIDX R11 R11 K78 + 0x7C200600, // 026A CALL R8 3 + 0x80041000, // 026B RET 1 R8 + 0x70020090, // 026C JMP #02FE + 0x54220003, // 026D LDINT R8 4 + 0x1C200E08, // 026E EQ R8 R7 R8 + 0x78220005, // 026F JMPF R8 #0276 + 0x8C200706, // 0270 GETMET R8 R3 K6 + 0x88280B0C, // 0271 GETMBR R10 R5 K12 + 0x542E7FFF, // 0272 LDINT R11 32768 + 0x7C200600, // 0273 CALL R8 3 + 0x80041000, // 0274 RET 1 R8 + 0x70020087, // 0275 JMP #02FE + 0x54220004, // 0276 LDINT R8 5 + 0x1C200E08, // 0277 EQ R8 R7 R8 + 0x7822000A, // 0278 JMPF R8 #0284 + 0x8C200706, // 0279 GETMET R8 R3 K6 + 0x88280B16, // 027A GETMBR R10 R5 K22 + 0xB82E2400, // 027B GETNGBL R11 K18 + 0x8C2C1726, // 027C GETMET R11 R11 K38 + 0x5834004F, // 027D LDCONST R13 K79 + 0x50380200, // 027E LDBOOL R14 1 0 + 0x7C2C0600, // 027F CALL R11 3 + 0x942C1750, // 0280 GETIDX R11 R11 K80 + 0x7C200600, // 0281 CALL R8 3 + 0x80041000, // 0282 RET 1 R8 + 0x70020079, // 0283 JMP #02FE + 0x54220005, // 0284 LDINT R8 6 + 0x1C200E08, // 0285 EQ R8 R7 R8 + 0x78220005, // 0286 JMPF R8 #028D + 0x8C200706, // 0287 GETMET R8 R3 K6 + 0x88280B16, // 0288 GETMBR R10 R5 K22 + 0x582C0051, // 0289 LDCONST R11 K81 + 0x7C200600, // 028A CALL R8 3 + 0x80041000, // 028B RET 1 R8 + 0x70020070, // 028C JMP #02FE + 0x54220006, // 028D LDINT R8 7 + 0x1C200E08, // 028E EQ R8 R7 R8 + 0x78220005, // 028F JMPF R8 #0296 + 0x8C200706, // 0290 GETMET R8 R3 K6 + 0x88280B0C, // 0291 GETMBR R10 R5 K12 + 0x582C0005, // 0292 LDCONST R11 K5 + 0x7C200600, // 0293 CALL R8 3 + 0x80041000, // 0294 RET 1 R8 + 0x70020067, // 0295 JMP #02FE + 0x54220007, // 0296 LDINT R8 8 + 0x1C200E08, // 0297 EQ R8 R7 R8 + 0x7822000B, // 0298 JMPF R8 #02A5 + 0x8C200706, // 0299 GETMET R8 R3 K6 + 0x88280B16, // 029A GETMBR R10 R5 K22 + 0xB82E2400, // 029B GETNGBL R11 K18 + 0x8C2C1726, // 029C GETMET R11 R11 K38 + 0x58340052, // 029D LDCONST R13 K82 + 0x50380200, // 029E LDBOOL R14 1 0 + 0x7C2C0600, // 029F CALL R11 3 + 0x942C1753, // 02A0 GETIDX R11 R11 K83 + 0x942C1754, // 02A1 GETIDX R11 R11 K84 + 0x7C200600, // 02A2 CALL R8 3 + 0x80041000, // 02A3 RET 1 R8 + 0x70020058, // 02A4 JMP #02FE + 0x54220008, // 02A5 LDINT R8 9 + 0x1C200E08, // 02A6 EQ R8 R7 R8 + 0x78220005, // 02A7 JMPF R8 #02AE + 0x8C200706, // 02A8 GETMET R8 R3 K6 + 0x88280B0C, // 02A9 GETMBR R10 R5 K12 + 0x582C0009, // 02AA LDCONST R11 K9 + 0x7C200600, // 02AB CALL R8 3 + 0x80041000, // 02AC RET 1 R8 + 0x7002004F, // 02AD JMP #02FE + 0x54220009, // 02AE LDINT R8 10 + 0x1C200E08, // 02AF EQ R8 R7 R8 + 0x78220015, // 02B0 JMPF R8 #02C7 + 0xB8222400, // 02B1 GETNGBL R8 K18 + 0x8C201126, // 02B2 GETMET R8 R8 K38 + 0x58280052, // 02B3 LDCONST R10 K82 + 0x502C0200, // 02B4 LDBOOL R11 1 0 + 0x7C200600, // 02B5 CALL R8 3 + 0x94201153, // 02B6 GETIDX R8 R8 K83 + 0x94201155, // 02B7 GETIDX R8 R8 K85 + 0x8C24091B, // 02B8 GETMET R9 R4 K27 + 0x5C2C1000, // 02B9 MOVE R11 R8 + 0x58300056, // 02BA LDCONST R12 K86 + 0x7C240600, // 02BB CALL R9 3 + 0x24281305, // 02BC GT R10 R9 K5 + 0x782A0002, // 02BD JMPF R10 #02C1 + 0x04281309, // 02BE SUB R10 R9 K9 + 0x402A0A0A, // 02BF CONNECT R10 K5 R10 + 0x9420100A, // 02C0 GETIDX R8 R8 R10 + 0x8C280706, // 02C1 GETMET R10 R3 K6 + 0x88300B16, // 02C2 GETMBR R12 R5 K22 + 0x5C341000, // 02C3 MOVE R13 R8 + 0x7C280600, // 02C4 CALL R10 3 + 0x80041400, // 02C5 RET 1 R10 + 0x70020036, // 02C6 JMP #02FE + 0x5422000E, // 02C7 LDINT R8 15 + 0x1C200E08, // 02C8 EQ R8 R7 R8 + 0x7822000B, // 02C9 JMPF R8 #02D6 + 0x8C200706, // 02CA GETMET R8 R3 K6 + 0x88280B16, // 02CB GETMBR R10 R5 K22 + 0xB82E2400, // 02CC GETNGBL R11 K18 + 0x8C2C1725, // 02CD GETMET R11 R11 K37 + 0x7C2C0200, // 02CE CALL R11 1 + 0x8C2C171B, // 02CF GETMET R11 R11 K27 + 0x5834001C, // 02D0 LDCONST R13 K28 + 0x5838001D, // 02D1 LDCONST R14 K29 + 0x7C2C0600, // 02D2 CALL R11 3 + 0x7C200600, // 02D3 CALL R8 3 + 0x80041000, // 02D4 RET 1 R8 + 0x70020027, // 02D5 JMP #02FE + 0x54220010, // 02D6 LDINT R8 17 + 0x1C200E08, // 02D7 EQ R8 R7 R8 + 0x78220005, // 02D8 JMPF R8 #02DF + 0x8C200706, // 02D9 GETMET R8 R3 K6 + 0x88280B10, // 02DA GETMBR R10 R5 K16 + 0x582C0009, // 02DB LDCONST R11 K9 + 0x7C200600, // 02DC CALL R8 3 + 0x80041000, // 02DD RET 1 R8 + 0x7002001E, // 02DE JMP #02FE + 0x54220011, // 02DF LDINT R8 18 + 0x1C200E08, // 02E0 EQ R8 R7 R8 + 0x7822000B, // 02E1 JMPF R8 #02EE + 0x8C200706, // 02E2 GETMET R8 R3 K6 + 0x88280B16, // 02E3 GETMBR R10 R5 K22 + 0xB82E2400, // 02E4 GETNGBL R11 K18 + 0x8C2C1725, // 02E5 GETMET R11 R11 K37 + 0x7C2C0200, // 02E6 CALL R11 1 + 0x8C2C171B, // 02E7 GETMET R11 R11 K27 + 0x5834001C, // 02E8 LDCONST R13 K28 + 0x5838001D, // 02E9 LDCONST R14 K29 + 0x7C2C0600, // 02EA CALL R11 3 + 0x7C200600, // 02EB CALL R8 3 + 0x80041000, // 02EC RET 1 R8 + 0x7002000F, // 02ED JMP #02FE + 0x54220012, // 02EE LDINT R8 19 + 0x1C200E08, // 02EF EQ R8 R7 R8 + 0x7822000C, // 02F0 JMPF R8 #02FE + 0x8C200B0A, // 02F1 GETMET R8 R5 K10 + 0x7C200200, // 02F2 CALL R8 1 + 0x8C24110B, // 02F3 GETMET R9 R8 K11 + 0x582C0005, // 02F4 LDCONST R11 K5 + 0x88300B0C, // 02F5 GETMBR R12 R5 K12 + 0x5834000F, // 02F6 LDCONST R13 K15 + 0x7C240800, // 02F7 CALL R9 4 + 0x8C24110B, // 02F8 GETMET R9 R8 K11 + 0x582C0009, // 02F9 LDCONST R11 K9 + 0x88300B0C, // 02FA GETMBR R12 R5 K12 + 0x5834000F, // 02FB LDCONST R13 K15 + 0x7C240800, // 02FC CALL R9 4 + 0x80041000, // 02FD RET 1 R8 + 0x700200A8, // 02FE JMP #03A8 + 0x5422003E, // 02FF LDINT R8 63 + 0x1C200C08, // 0300 EQ R8 R6 R8 + 0x78220000, // 0301 JMPF R8 #0303 + 0x700200A4, // 0302 JMP #03A8 + 0x54220029, // 0303 LDINT R8 42 + 0x1C200C08, // 0304 EQ R8 R6 R8 + 0x7822001D, // 0305 JMPF R8 #0324 + 0x1C200F05, // 0306 EQ R8 R7 K5 + 0x78220003, // 0307 JMPF R8 #030C + 0x8C200B11, // 0308 GETMET R8 R5 K17 + 0x7C200200, // 0309 CALL R8 1 + 0x80041000, // 030A RET 1 R8 + 0x70020016, // 030B JMP #0323 + 0x1C200F09, // 030C EQ R8 R7 K9 + 0x78220005, // 030D JMPF R8 #0314 + 0x8C200706, // 030E GETMET R8 R3 K6 + 0x88280B10, // 030F GETMBR R10 R5 K16 + 0x582C0005, // 0310 LDCONST R11 K5 + 0x7C200600, // 0311 CALL R8 3 + 0x80041000, // 0312 RET 1 R8 + 0x7002000E, // 0313 JMP #0323 + 0x1C200F0D, // 0314 EQ R8 R7 K13 + 0x78220005, // 0315 JMPF R8 #031C + 0x8C200706, // 0316 GETMET R8 R3 K6 + 0x88280B0E, // 0317 GETMBR R10 R5 K14 + 0x582C0009, // 0318 LDCONST R11 K9 + 0x7C200600, // 0319 CALL R8 3 + 0x80041000, // 031A RET 1 R8 + 0x70020006, // 031B JMP #0323 + 0x1C200F0F, // 031C EQ R8 R7 K15 + 0x78220004, // 031D JMPF R8 #0323 + 0x8C200706, // 031E GETMET R8 R3 K6 + 0x88280B18, // 031F GETMBR R10 R5 K24 + 0x4C2C0000, // 0320 LDNIL R11 + 0x7C200600, // 0321 CALL R8 3 + 0x80041000, // 0322 RET 1 R8 + 0x70020083, // 0323 JMP #03A8 + 0x5422002A, // 0324 LDINT R8 43 + 0x1C200C08, // 0325 EQ R8 R6 R8 + 0x78220016, // 0326 JMPF R8 #033E + 0x1C200F05, // 0327 EQ R8 R7 K5 + 0x78220007, // 0328 JMPF R8 #0331 + 0x8C200706, // 0329 GETMET R8 R3 K6 + 0x88280B16, // 032A GETMBR R10 R5 K22 + 0xB82E2400, // 032B GETNGBL R11 K18 + 0x8C2C1757, // 032C GETMET R11 R11 K87 + 0x7C2C0200, // 032D CALL R11 1 + 0x7C200600, // 032E CALL R8 3 + 0x80041000, // 032F RET 1 R8 + 0x7002000B, // 0330 JMP #033D + 0x1C200F09, // 0331 EQ R8 R7 K9 + 0x78220009, // 0332 JMPF R8 #033D + 0x8C200B11, // 0333 GETMET R8 R5 K17 + 0x7C200200, // 0334 CALL R8 1 + 0x8C24110B, // 0335 GETMET R9 R8 K11 + 0x4C2C0000, // 0336 LDNIL R11 + 0x88300B16, // 0337 GETMBR R12 R5 K22 + 0xB8362400, // 0338 GETNGBL R13 K18 + 0x8C341B57, // 0339 GETMET R13 R13 K87 + 0x7C340200, // 033A CALL R13 1 + 0x7C240800, // 033B CALL R9 4 + 0x80041000, // 033C RET 1 R8 + 0x70020069, // 033D JMP #03A8 + 0x5422002B, // 033E LDINT R8 44 + 0x1C200C08, // 033F EQ R8 R6 R8 + 0x7822001C, // 0340 JMPF R8 #035E + 0x1C200F05, // 0341 EQ R8 R7 K5 + 0x78220005, // 0342 JMPF R8 #0349 + 0x8C200706, // 0343 GETMET R8 R3 K6 + 0x88280B0E, // 0344 GETMBR R10 R5 K14 + 0x582C0009, // 0345 LDCONST R11 K9 + 0x7C200600, // 0346 CALL R8 3 + 0x80041000, // 0347 RET 1 R8 + 0x70020013, // 0348 JMP #035D + 0x1C200F09, // 0349 EQ R8 R7 K9 + 0x78220005, // 034A JMPF R8 #0351 + 0x8C200706, // 034B GETMET R8 R3 K6 + 0x88280B0E, // 034C GETMBR R10 R5 K14 + 0x542E0003, // 034D LDINT R11 4 + 0x7C200600, // 034E CALL R8 3 + 0x80041000, // 034F RET 1 R8 + 0x7002000B, // 0350 JMP #035D + 0x1C200F0D, // 0351 EQ R8 R7 K13 + 0x78220009, // 0352 JMPF R8 #035D + 0x8C200B11, // 0353 GETMET R8 R5 K17 + 0x7C200200, // 0354 CALL R8 1 + 0x8C24110B, // 0355 GETMET R9 R8 K11 + 0x4C2C0000, // 0356 LDNIL R11 + 0x8C300B58, // 0357 GETMET R12 R5 K88 + 0x88380B0E, // 0358 GETMBR R14 R5 K14 + 0x543E0003, // 0359 LDINT R15 4 + 0x7C300600, // 035A CALL R12 3 + 0x7C240600, // 035B CALL R9 3 + 0x80041000, // 035C RET 1 R8 + 0x70020049, // 035D JMP #03A8 + 0x54220030, // 035E LDINT R8 49 + 0x1C200C08, // 035F EQ R8 R6 R8 + 0x78220010, // 0360 JMPF R8 #0372 + 0x1C200F0F, // 0361 EQ R8 R7 K15 + 0x78220005, // 0362 JMPF R8 #0369 + 0x8C200706, // 0363 GETMET R8 R3 K6 + 0x88280B0E, // 0364 GETMBR R10 R5 K14 + 0x542E001D, // 0365 LDINT R11 30 + 0x7C200600, // 0366 CALL R8 3 + 0x80041000, // 0367 RET 1 R8 + 0x70020007, // 0368 JMP #0371 + 0x5422FFFB, // 0369 LDINT R8 65532 + 0x1C200E08, // 036A EQ R8 R7 R8 + 0x78220004, // 036B JMPF R8 #0371 + 0x8C200706, // 036C GETMET R8 R3 K6 + 0x88280B2A, // 036D GETMBR R10 R5 K42 + 0x542E0003, // 036E LDINT R11 4 + 0x7C200600, // 036F CALL R8 3 + 0x80041000, // 0370 RET 1 R8 + 0x70020035, // 0371 JMP #03A8 + 0x5422001C, // 0372 LDINT R8 29 + 0x1C200C08, // 0373 EQ R8 R6 R8 + 0x78220029, // 0374 JMPF R8 #039F + 0x1C200F0F, // 0375 EQ R8 R7 K15 + 0x7822001D, // 0376 JMPF R8 #0395 + 0x8C200B11, // 0377 GETMET R8 R5 K17 + 0x7C200200, // 0378 CALL R8 1 + 0x88240136, // 0379 GETMBR R9 R0 K54 + 0x8C241359, // 037A GETMET R9 R9 K89 + 0x502C0200, // 037B LDBOOL R11 1 0 + 0x7C240400, // 037C CALL R9 2 + 0x88280136, // 037D GETMBR R10 R0 K54 + 0x8828155A, // 037E GETMBR R10 R10 K90 + 0x602C0010, // 037F GETGBL R11 G16 + 0x5C301200, // 0380 MOVE R12 R9 + 0x7C2C0200, // 0381 CALL R11 1 + 0xA802000C, // 0382 EXBLK 0 #0390 + 0x5C301600, // 0383 MOVE R12 R11 + 0x7C300000, // 0384 CALL R12 0 + 0x5C341400, // 0385 MOVE R13 R10 + 0x78360002, // 0386 JMPF R13 #038A + 0x5436FEFF, // 0387 LDINT R13 65280 + 0x1434180D, // 0388 LT R13 R12 R13 + 0x78360004, // 0389 JMPF R13 #038F + 0x8C34110B, // 038A GETMET R13 R8 K11 + 0x4C3C0000, // 038B LDNIL R15 + 0x88400B0C, // 038C GETMBR R16 R5 K12 + 0x5C441800, // 038D MOVE R17 R12 + 0x7C340800, // 038E CALL R13 4 + 0x7001FFF2, // 038F JMP #0383 + 0x582C003D, // 0390 LDCONST R11 K61 + 0xAC2C0200, // 0391 CATCH R11 1 0 + 0xB0080000, // 0392 RAISE 2 R0 R0 + 0x80041000, // 0393 RET 1 R8 + 0x70020008, // 0394 JMP #039E + 0x60200003, // 0395 GETGBL R8 G3 + 0x5C240000, // 0396 MOVE R9 R0 + 0x7C200200, // 0397 CALL R8 1 + 0x8C20115B, // 0398 GETMET R8 R8 K91 + 0x5C280200, // 0399 MOVE R10 R1 + 0x5C2C0400, // 039A MOVE R11 R2 + 0x5C300600, // 039B MOVE R12 R3 + 0x7C200800, // 039C CALL R8 4 + 0x80041000, // 039D RET 1 R8 + 0x70020008, // 039E JMP #03A8 + 0x60200003, // 039F GETGBL R8 G3 + 0x5C240000, // 03A0 MOVE R9 R0 + 0x7C200200, // 03A1 CALL R8 1 + 0x8C20115B, // 03A2 GETMET R8 R8 K91 + 0x5C280200, // 03A3 MOVE R10 R1 + 0x5C2C0400, // 03A4 MOVE R11 R2 + 0x5C300600, // 03A5 MOVE R12 R3 + 0x7C200800, // 03A6 CALL R8 4 + 0x80041000, // 03A7 RET 1 R8 + 0x80000000, // 03A8 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: write_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Root_write_attribute, /* name */ + be_nested_proto( + 11, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(int), + /* K6 */ be_nested_str_weak(int64), + /* K7 */ be_nested_str_weak(_breadcrumb), + /* K8 */ be_nested_str_weak(attribute_updated), + /* K9 */ be_nested_str_weak(status), + /* K10 */ be_nested_str_weak(CONSTRAINT_ERROR), + /* K11 */ be_const_int(1), + /* K12 */ be_nested_str_weak(INVALID_ACTION), + }), + be_str_weak(write_attribute), + &be_const_str_solidified, + ( &(const binstruction[100]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E002F, // 0004 LDINT R7 48 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0019, // 0006 JMPF R7 #0021 + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E0016, // 0008 JMPF R7 #0020 + 0x601C0004, // 0009 GETGBL R7 G4 + 0x5C200600, // 000A MOVE R8 R3 + 0x7C1C0200, // 000B CALL R7 1 + 0x1C1C0F05, // 000C EQ R7 R7 K5 + 0x741E0004, // 000D JMPT R7 #0013 + 0x601C000F, // 000E GETGBL R7 G15 + 0x5C200600, // 000F MOVE R8 R3 + 0xB8260C00, // 0010 GETNGBL R9 K6 + 0x7C1C0400, // 0011 CALL R7 2 + 0x781E0007, // 0012 JMPF R7 #001B + 0x90060E03, // 0013 SETMBR R1 K7 R3 + 0x8C1C0108, // 0014 GETMET R7 R0 K8 + 0x88240502, // 0015 GETMBR R9 R2 K2 + 0x88280503, // 0016 GETMBR R10 R2 K3 + 0x7C1C0600, // 0017 CALL R7 3 + 0x501C0200, // 0018 LDBOOL R7 1 0 + 0x80040E00, // 0019 RET 1 R7 + 0x70020004, // 001A JMP #0020 + 0xB81E0000, // 001B GETNGBL R7 K0 + 0x881C0F0A, // 001C GETMBR R7 R7 K10 + 0x900A1207, // 001D SETMBR R2 K9 R7 + 0x501C0000, // 001E LDBOOL R7 0 0 + 0x80040E00, // 001F RET 1 R7 + 0x70020041, // 0020 JMP #0063 + 0x541E001E, // 0021 LDINT R7 31 + 0x1C1C0A07, // 0022 EQ R7 R5 R7 + 0x781E0004, // 0023 JMPF R7 #0029 + 0x1C1C0D04, // 0024 EQ R7 R6 K4 + 0x781E0001, // 0025 JMPF R7 #0028 + 0x501C0200, // 0026 LDBOOL R7 1 0 + 0x80040E00, // 0027 RET 1 R7 + 0x70020039, // 0028 JMP #0063 + 0x541E0027, // 0029 LDINT R7 40 + 0x1C1C0A07, // 002A EQ R7 R5 R7 + 0x781E000B, // 002B JMPF R7 #0038 + 0x541E0004, // 002C LDINT R7 5 + 0x1C1C0C07, // 002D EQ R7 R6 R7 + 0x781E0002, // 002E JMPF R7 #0032 + 0x501C0200, // 002F LDBOOL R7 1 0 + 0x80040E00, // 0030 RET 1 R7 + 0x70020004, // 0031 JMP #0037 + 0x541E0005, // 0032 LDINT R7 6 + 0x1C1C0C07, // 0033 EQ R7 R6 R7 + 0x781E0001, // 0034 JMPF R7 #0037 + 0x501C0200, // 0035 LDBOOL R7 1 0 + 0x80040E00, // 0036 RET 1 R7 + 0x7002002A, // 0037 JMP #0063 + 0x541E0029, // 0038 LDINT R7 42 + 0x1C1C0A07, // 0039 EQ R7 R5 R7 + 0x781E0004, // 003A JMPF R7 #0040 + 0x1C1C0D04, // 003B EQ R7 R6 K4 + 0x781E0001, // 003C JMPF R7 #003F + 0x501C0200, // 003D LDBOOL R7 1 0 + 0x80040E00, // 003E RET 1 R7 + 0x70020022, // 003F JMP #0063 + 0x541E002A, // 0040 LDINT R7 43 + 0x1C1C0A07, // 0041 EQ R7 R5 R7 + 0x781E0007, // 0042 JMPF R7 #004B + 0x1C1C0D04, // 0043 EQ R7 R6 K4 + 0x781E0004, // 0044 JMPF R7 #004A + 0xB81E0000, // 0045 GETNGBL R7 K0 + 0x881C0F0A, // 0046 GETMBR R7 R7 K10 + 0x900A1207, // 0047 SETMBR R2 K9 R7 + 0x501C0000, // 0048 LDBOOL R7 0 0 + 0x80040E00, // 0049 RET 1 R7 + 0x70020017, // 004A JMP #0063 + 0x541E002B, // 004B LDINT R7 44 + 0x1C1C0A07, // 004C EQ R7 R5 R7 + 0x781E0009, // 004D JMPF R7 #0058 + 0x1C1C0D04, // 004E EQ R7 R6 K4 + 0x781E0002, // 004F JMPF R7 #0053 + 0x501C0200, // 0050 LDBOOL R7 1 0 + 0x80040E00, // 0051 RET 1 R7 + 0x70020003, // 0052 JMP #0057 + 0x1C1C0D0B, // 0053 EQ R7 R6 K11 + 0x781E0001, // 0054 JMPF R7 #0057 + 0x501C0200, // 0055 LDBOOL R7 1 0 + 0x80040E00, // 0056 RET 1 R7 + 0x7002000A, // 0057 JMP #0063 + 0x541E0030, // 0058 LDINT R7 49 + 0x1C1C0A07, // 0059 EQ R7 R5 R7 + 0x781E0007, // 005A JMPF R7 #0063 + 0x541E0003, // 005B LDINT R7 4 + 0x1C1C0C07, // 005C EQ R7 R6 R7 + 0x781E0004, // 005D JMPF R7 #0063 + 0xB81E0000, // 005E GETNGBL R7 K0 + 0x881C0F0C, // 005F GETMBR R7 R7 K12 + 0x900A1207, // 0060 SETMBR R2 K9 R7 + 0x501C0000, // 0061 LDBOOL R7 0 0 + 0x80040E00, // 0062 RET 1 R7 + 0x80000000, // 0063 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: invoke_request +********************************************************************/ +be_local_closure(Matter_Plugin_Root_invoke_request, /* name */ + be_nested_proto( + 30, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 3, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 2]) { /* upvals */ + be_local_const_upval(1, 0), + be_local_const_upval(1, 10), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(device), + /* K1 */ be_nested_str_weak(remove_fabric), + }), + be_str_weak(_anonymous_), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x88000100, // 0001 GETMBR R0 R0 K0 + 0x8C000101, // 0002 GETMET R0 R0 K1 + 0x68080001, // 0003 GETUPV R2 U1 + 0x7C000400, // 0004 CALL R0 2 + 0x80000000, // 0005 RET 0 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[100]) { /* constants */ + /* K0 */ be_nested_str_weak(crypto), + /* K1 */ be_nested_str_weak(matter), + /* K2 */ be_nested_str_weak(TLV), + /* K3 */ be_nested_str_weak(cluster), + /* K4 */ be_nested_str_weak(command), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(findsubval), + /* K7 */ be_const_int(1), + /* K8 */ be_nested_str_weak(_breadcrumb), + /* K9 */ be_nested_str_weak(Matter_TLV_struct), + /* K10 */ be_nested_str_weak(add_TLV), + /* K11 */ be_nested_str_weak(U1), + /* K12 */ be_nested_str_weak(UTF1), + /* K13 */ be_nested_str_weak(), + /* K14 */ be_const_int(2), + /* K15 */ be_nested_str_weak(XX), + /* K16 */ be_const_int(3), + /* K17 */ be_nested_str_weak(ack_request), + /* K18 */ be_nested_str_weak(_fabric), + /* K19 */ be_nested_str_weak(fabric_completed), + /* K20 */ be_nested_str_weak(set_no_expiration), + /* K21 */ be_nested_str_weak(save), + /* K22 */ be_nested_str_weak(device), + /* K23 */ be_nested_str_weak(start_commissioning_complete_deferred), + /* K24 */ be_nested_str_weak(context_error), + /* K25 */ be_nested_str_weak(CommissioningComplete_X3A_X20no_X20fabric_X20attached), + /* K26 */ be_nested_str_weak(status), + /* K27 */ be_nested_str_weak(UNSUPPORTED_COMMAND), + /* K28 */ be_nested_str_weak(B2), + /* K29 */ be_nested_str_weak(DAC_Cert_FFF1_8000), + /* K30 */ be_nested_str_weak(PAI_Cert_FFF1), + /* K31 */ be_nested_str_weak(CD_FFF1_8000), + /* K32 */ be_nested_str_weak(B1), + /* K33 */ be_nested_str_weak(U4), + /* K34 */ be_nested_str_weak(tasmota), + /* K35 */ be_nested_str_weak(rtc_utc), + /* K36 */ be_nested_str_weak(tlv2raw), + /* K37 */ be_nested_str_weak(get_ac), + /* K38 */ be_nested_str_weak(EC_P256), + /* K39 */ be_nested_str_weak(ecdsa_sign_sha256), + /* K40 */ be_nested_str_weak(DAC_Priv_FFF1_8000), + /* K41 */ be_nested_str_weak(gen_CSR), + /* K42 */ be_nested_str_weak(set_temp_ca), + /* K43 */ be_nested_str_weak(SUCCESS), + /* K44 */ be_nested_str_weak(log), + /* K45 */ be_nested_str_weak(MTR_X3A_X20AddNoc_X20Args_X3D), + /* K46 */ be_nested_str_weak(get_temp_ca), + /* K47 */ be_nested_str_weak(MTR_X3A_X20Error_X3A_X20AdNOC_X20without_X20CA), + /* K48 */ be_nested_str_weak(sessions), + /* K49 */ be_nested_str_weak(create_fabric), + /* K50 */ be_nested_str_weak(set_ca), + /* K51 */ be_nested_str_weak(set_noc_icac), + /* K52 */ be_nested_str_weak(set_ipk_epoch_key), + /* K53 */ be_nested_str_weak(set_admin_subject_vendor), + /* K54 */ be_nested_str_weak(set_pk), + /* K55 */ be_nested_str_weak(get_pk), + /* K56 */ be_nested_str_weak(parse), + /* K57 */ be_nested_str_weak(findsub), + /* K58 */ be_nested_str_weak(MTR_X3A_X20Error_X3A_X20no_X20fabricid_X20nor_X20deviceid_X20in_X20NOC_X20certificate), + /* K59 */ be_nested_str_weak(int), + /* K60 */ be_nested_str_weak(int64), + /* K61 */ be_nested_str_weak(fromu32), + /* K62 */ be_nested_str_weak(tobytes), + /* K63 */ be_nested_str_weak(get_temp_ca_pub), + /* K64 */ be_const_int(2147483647), + /* K65 */ be_nested_str_weak(fromstring), + /* K66 */ be_nested_str_weak(CompressedFabric), + /* K67 */ be_nested_str_weak(HKDF_SHA256), + /* K68 */ be_nested_str_weak(copy), + /* K69 */ be_nested_str_weak(reverse), + /* K70 */ be_nested_str_weak(derive), + /* K71 */ be_nested_str_weak(commissioning_admin_fabric), + /* K72 */ be_nested_str_weak(set_fabric_device), + /* K73 */ be_nested_str_weak(fabric_candidate), + /* K74 */ be_nested_str_weak(start_operational_discovery_deferred), + /* K75 */ be_nested_str_weak(is_PASE), + /* K76 */ be_nested_str_weak(set_expire_in_seconds), + /* K77 */ be_nested_str_weak(log_new_fabric), + /* K78 */ be_nested_str_weak(set_fabric_label), + /* K79 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Update_X20fabric_X20_X27_X25s_X27_X20label_X3D_X27_X25s_X27), + /* K80 */ be_nested_str_weak(get_fabric_id), + /* K81 */ be_nested_str_weak(tohex), + /* K82 */ be_nested_str_weak(fabric_index_X3A), + /* K83 */ be_nested_str_weak(active_fabrics), + /* K84 */ be_nested_str_weak(get_fabric_index), + /* K85 */ be_nested_str_weak(set_timer), + /* K86 */ be_nested_str_weak(stop_iteration), + /* K87 */ be_nested_str_weak(MTR_X3A_X20RemoveFabric_X20fabric_X28), + /* K88 */ be_nested_str_weak(_X29_X20not_X20found), + /* K89 */ be_nested_str_weak(INVALID_ACTION), + /* K90 */ be_nested_str_weak(MTR_X3A_X20OpenCommissioningWindow_X28timeout_X3D_X25i_X2C_X20passcode_X3D_X25s_X2C_X20discriminator_X3D_X25i_X2C_X20iterations_X3D_X25i_X2C_X20salt_X3D_X25s_X29), + /* K91 */ be_nested_str_weak(INVALID_DATA_TYPE), + /* K92 */ be_nested_str_weak(MTR_X3A_X20wrong_X20size_X20for_X20PAKE_X20parameters), + /* K93 */ be_nested_str_weak(CONSTRAINT_ERROR), + /* K94 */ be_nested_str_weak(start_basic_commissioning), + /* K95 */ be_nested_str_weak(get_fabric), + /* K96 */ be_nested_str_weak(MTR_X3A_X20OpenBasicCommissioningWindow_X20commissioning_timeout_X3D), + /* K97 */ be_nested_str_weak(start_root_basic_commissioning), + /* K98 */ be_nested_str_weak(stop_basic_commissioning), + /* K99 */ be_nested_str_weak(invoke_request), + }), + be_str_weak(invoke_request), + &be_const_str_solidified, + ( &(const binstruction[713]) { /* code */ + 0xA4120000, // 0000 IMPORT R4 K0 + 0xB8160200, // 0001 GETNGBL R5 K1 + 0x88140B02, // 0002 GETMBR R5 R5 K2 + 0x88180703, // 0003 GETMBR R6 R3 K3 + 0x881C0704, // 0004 GETMBR R7 R3 K4 + 0x5422002F, // 0005 LDINT R8 48 + 0x1C200C08, // 0006 EQ R8 R6 R8 + 0x7822005C, // 0007 JMPF R8 #0065 + 0x1C200F05, // 0008 EQ R8 R7 K5 + 0x78220017, // 0009 JMPF R8 #0022 + 0x8C200506, // 000A GETMET R8 R2 K6 + 0x58280005, // 000B LDCONST R10 K5 + 0x542E0383, // 000C LDINT R11 900 + 0x7C200600, // 000D CALL R8 3 + 0x8C240506, // 000E GETMET R9 R2 K6 + 0x582C0007, // 000F LDCONST R11 K7 + 0x58300005, // 0010 LDCONST R12 K5 + 0x7C240600, // 0011 CALL R9 3 + 0x90061009, // 0012 SETMBR R1 K8 R9 + 0x8C280B09, // 0013 GETMET R10 R5 K9 + 0x7C280200, // 0014 CALL R10 1 + 0x8C2C150A, // 0015 GETMET R11 R10 K10 + 0x58340005, // 0016 LDCONST R13 K5 + 0x88380B0B, // 0017 GETMBR R14 R5 K11 + 0x583C0005, // 0018 LDCONST R15 K5 + 0x7C2C0800, // 0019 CALL R11 4 + 0x8C2C150A, // 001A GETMET R11 R10 K10 + 0x58340007, // 001B LDCONST R13 K7 + 0x88380B0C, // 001C GETMBR R14 R5 K12 + 0x583C000D, // 001D LDCONST R15 K13 + 0x7C2C0800, // 001E CALL R11 4 + 0x900E0907, // 001F SETMBR R3 K4 K7 + 0x80041400, // 0020 RET 1 R10 + 0x70020041, // 0021 JMP #0064 + 0x1C200F0E, // 0022 EQ R8 R7 K14 + 0x7822001A, // 0023 JMPF R8 #003F + 0x8C200506, // 0024 GETMET R8 R2 K6 + 0x58280005, // 0025 LDCONST R10 K5 + 0x7C200400, // 0026 CALL R8 2 + 0x8C240506, // 0027 GETMET R9 R2 K6 + 0x582C0007, // 0028 LDCONST R11 K7 + 0x5830000F, // 0029 LDCONST R12 K15 + 0x7C240600, // 002A CALL R9 3 + 0x8C280506, // 002B GETMET R10 R2 K6 + 0x5830000E, // 002C LDCONST R12 K14 + 0x58340005, // 002D LDCONST R13 K5 + 0x7C280600, // 002E CALL R10 3 + 0x9006100A, // 002F SETMBR R1 K8 R10 + 0x8C2C0B09, // 0030 GETMET R11 R5 K9 + 0x7C2C0200, // 0031 CALL R11 1 + 0x8C30170A, // 0032 GETMET R12 R11 K10 + 0x58380005, // 0033 LDCONST R14 K5 + 0x883C0B0B, // 0034 GETMBR R15 R5 K11 + 0x58400005, // 0035 LDCONST R16 K5 + 0x7C300800, // 0036 CALL R12 4 + 0x8C30170A, // 0037 GETMET R12 R11 K10 + 0x58380007, // 0038 LDCONST R14 K7 + 0x883C0B0C, // 0039 GETMBR R15 R5 K12 + 0x5840000D, // 003A LDCONST R16 K13 + 0x7C300800, // 003B CALL R12 4 + 0x900E0910, // 003C SETMBR R3 K4 K16 + 0x80041600, // 003D RET 1 R11 + 0x70020024, // 003E JMP #0064 + 0x54220003, // 003F LDINT R8 4 + 0x1C200E08, // 0040 EQ R8 R7 R8 + 0x78220021, // 0041 JMPF R8 #0064 + 0x8C200111, // 0042 GETMET R8 R0 K17 + 0x5C280600, // 0043 MOVE R10 R3 + 0x7C200400, // 0044 CALL R8 2 + 0x88200312, // 0045 GETMBR R8 R1 K18 + 0x7822001B, // 0046 JMPF R8 #0063 + 0x90061105, // 0047 SETMBR R1 K8 K5 + 0x88200312, // 0048 GETMBR R8 R1 K18 + 0x8C201113, // 0049 GETMET R8 R8 K19 + 0x7C200200, // 004A CALL R8 1 + 0x8C200314, // 004B GETMET R8 R1 K20 + 0x7C200200, // 004C CALL R8 1 + 0x8C200315, // 004D GETMET R8 R1 K21 + 0x7C200200, // 004E CALL R8 1 + 0x8C200B09, // 004F GETMET R8 R5 K9 + 0x7C200200, // 0050 CALL R8 1 + 0x8C24110A, // 0051 GETMET R9 R8 K10 + 0x582C0005, // 0052 LDCONST R11 K5 + 0x88300B0B, // 0053 GETMBR R12 R5 K11 + 0x58340005, // 0054 LDCONST R13 K5 + 0x7C240800, // 0055 CALL R9 4 + 0x8C24110A, // 0056 GETMET R9 R8 K10 + 0x582C0007, // 0057 LDCONST R11 K7 + 0x88300B0C, // 0058 GETMBR R12 R5 K12 + 0x5834000D, // 0059 LDCONST R13 K13 + 0x7C240800, // 005A CALL R9 4 + 0x54260004, // 005B LDINT R9 5 + 0x900E0809, // 005C SETMBR R3 K4 R9 + 0x88240116, // 005D GETMBR R9 R0 K22 + 0x8C241317, // 005E GETMET R9 R9 K23 + 0x5C2C0200, // 005F MOVE R11 R1 + 0x7C240400, // 0060 CALL R9 2 + 0x80041000, // 0061 RET 1 R8 + 0x70020000, // 0062 JMP #0064 + 0xB0063119, // 0063 RAISE 1 K24 K25 + 0x70020261, // 0064 JMP #02C7 + 0x5422003D, // 0065 LDINT R8 62 + 0x1C200C08, // 0066 EQ R8 R6 R8 + 0x782201C2, // 0067 JMPF R8 #022B + 0x1C200F0E, // 0068 EQ R8 R7 K14 + 0x7822001D, // 0069 JMPF R8 #0088 + 0x8C200506, // 006A GETMET R8 R2 K6 + 0x58280005, // 006B LDCONST R10 K5 + 0x7C200400, // 006C CALL R8 2 + 0x20241107, // 006D NE R9 R8 K7 + 0x78260006, // 006E JMPF R9 #0076 + 0x2024110E, // 006F NE R9 R8 K14 + 0x78260004, // 0070 JMPF R9 #0076 + 0xB8260200, // 0071 GETNGBL R9 K1 + 0x8824131B, // 0072 GETMBR R9 R9 K27 + 0x900E3409, // 0073 SETMBR R3 K26 R9 + 0x4C240000, // 0074 LDNIL R9 + 0x80041200, // 0075 RET 1 R9 + 0x8C240B09, // 0076 GETMET R9 R5 K9 + 0x7C240200, // 0077 CALL R9 1 + 0x8C28130A, // 0078 GETMET R10 R9 K10 + 0x58300005, // 0079 LDCONST R12 K5 + 0x88340B1C, // 007A GETMBR R13 R5 K28 + 0x1C381107, // 007B EQ R14 R8 K7 + 0x783A0003, // 007C JMPF R14 #0081 + 0xB83A0200, // 007D GETNGBL R14 K1 + 0x8C381D1D, // 007E GETMET R14 R14 K29 + 0x7C380200, // 007F CALL R14 1 + 0x70020002, // 0080 JMP #0084 + 0xB83A0200, // 0081 GETNGBL R14 K1 + 0x8C381D1E, // 0082 GETMET R14 R14 K30 + 0x7C380200, // 0083 CALL R14 1 + 0x7C280800, // 0084 CALL R10 4 + 0x900E0910, // 0085 SETMBR R3 K4 K16 + 0x80041200, // 0086 RET 1 R9 + 0x700201A1, // 0087 JMP #022A + 0x1C200F05, // 0088 EQ R8 R7 K5 + 0x7822003C, // 0089 JMPF R8 #00C7 + 0x8C200506, // 008A GETMET R8 R2 K6 + 0x58280005, // 008B LDCONST R10 K5 + 0x7C200400, // 008C CALL R8 2 + 0x6024000C, // 008D GETGBL R9 G12 + 0x5C281000, // 008E MOVE R10 R8 + 0x7C240200, // 008F CALL R9 1 + 0x542A001F, // 0090 LDINT R10 32 + 0x2024120A, // 0091 NE R9 R9 R10 + 0x78260001, // 0092 JMPF R9 #0095 + 0x4C240000, // 0093 LDNIL R9 + 0x80041200, // 0094 RET 1 R9 + 0x900E0907, // 0095 SETMBR R3 K4 K7 + 0x8C240B09, // 0096 GETMET R9 R5 K9 + 0x7C240200, // 0097 CALL R9 1 + 0x8C28130A, // 0098 GETMET R10 R9 K10 + 0x58300007, // 0099 LDCONST R12 K7 + 0x88340B1C, // 009A GETMBR R13 R5 K28 + 0xB83A0200, // 009B GETNGBL R14 K1 + 0x8C381D1F, // 009C GETMET R14 R14 K31 + 0x7C380200, // 009D CALL R14 1 + 0x7C280800, // 009E CALL R10 4 + 0x8C28130A, // 009F GETMET R10 R9 K10 + 0x5830000E, // 00A0 LDCONST R12 K14 + 0x88340B20, // 00A1 GETMBR R13 R5 K32 + 0x5C381000, // 00A2 MOVE R14 R8 + 0x7C280800, // 00A3 CALL R10 4 + 0x8C28130A, // 00A4 GETMET R10 R9 K10 + 0x58300010, // 00A5 LDCONST R12 K16 + 0x88340B21, // 00A6 GETMBR R13 R5 K33 + 0xB83A4400, // 00A7 GETNGBL R14 K34 + 0x8C381D23, // 00A8 GETMET R14 R14 K35 + 0x7C380200, // 00A9 CALL R14 1 + 0x7C280800, // 00AA CALL R10 4 + 0x8C281324, // 00AB GETMET R10 R9 K36 + 0x7C280200, // 00AC CALL R10 1 + 0x8C2C0325, // 00AD GETMET R11 R1 K37 + 0x7C2C0200, // 00AE CALL R11 1 + 0x0030140B, // 00AF ADD R12 R10 R11 + 0x8C340926, // 00B0 GETMET R13 R4 K38 + 0x7C340200, // 00B1 CALL R13 1 + 0x8C341B27, // 00B2 GETMET R13 R13 K39 + 0xB83E0200, // 00B3 GETNGBL R15 K1 + 0x8C3C1F28, // 00B4 GETMET R15 R15 K40 + 0x7C3C0200, // 00B5 CALL R15 1 + 0x5C401800, // 00B6 MOVE R16 R12 + 0x7C340600, // 00B7 CALL R13 3 + 0x8C380B09, // 00B8 GETMET R14 R5 K9 + 0x7C380200, // 00B9 CALL R14 1 + 0x8C3C1D0A, // 00BA GETMET R15 R14 K10 + 0x58440005, // 00BB LDCONST R17 K5 + 0x88480B1C, // 00BC GETMBR R18 R5 K28 + 0x5C4C1400, // 00BD MOVE R19 R10 + 0x7C3C0800, // 00BE CALL R15 4 + 0x8C3C1D0A, // 00BF GETMET R15 R14 K10 + 0x58440007, // 00C0 LDCONST R17 K7 + 0x88480B20, // 00C1 GETMBR R18 R5 K32 + 0x5C4C1A00, // 00C2 MOVE R19 R13 + 0x7C3C0800, // 00C3 CALL R15 4 + 0x900E0907, // 00C4 SETMBR R3 K4 K7 + 0x80041C00, // 00C5 RET 1 R14 + 0x70020162, // 00C6 JMP #022A + 0x54220003, // 00C7 LDINT R8 4 + 0x1C200E08, // 00C8 EQ R8 R7 R8 + 0x7822003C, // 00C9 JMPF R8 #0107 + 0x8C200111, // 00CA GETMET R8 R0 K17 + 0x5C280600, // 00CB MOVE R10 R3 + 0x7C200400, // 00CC CALL R8 2 + 0x8C200506, // 00CD GETMET R8 R2 K6 + 0x58280005, // 00CE LDCONST R10 K5 + 0x7C200400, // 00CF CALL R8 2 + 0x6024000C, // 00D0 GETGBL R9 G12 + 0x5C281000, // 00D1 MOVE R10 R8 + 0x7C240200, // 00D2 CALL R9 1 + 0x542A001F, // 00D3 LDINT R10 32 + 0x2024120A, // 00D4 NE R9 R9 R10 + 0x78260001, // 00D5 JMPF R9 #00D8 + 0x4C240000, // 00D6 LDNIL R9 + 0x80041200, // 00D7 RET 1 R9 + 0x8C240506, // 00D8 GETMET R9 R2 K6 + 0x582C0007, // 00D9 LDCONST R11 K7 + 0x50300000, // 00DA LDBOOL R12 0 0 + 0x7C240600, // 00DB CALL R9 3 + 0x8C280329, // 00DC GETMET R10 R1 K41 + 0x7C280200, // 00DD CALL R10 1 + 0x8C2C0B09, // 00DE GETMET R11 R5 K9 + 0x7C2C0200, // 00DF CALL R11 1 + 0x8C30170A, // 00E0 GETMET R12 R11 K10 + 0x58380007, // 00E1 LDCONST R14 K7 + 0x883C0B1C, // 00E2 GETMBR R15 R5 K28 + 0x5C401400, // 00E3 MOVE R16 R10 + 0x7C300800, // 00E4 CALL R12 4 + 0x8C30170A, // 00E5 GETMET R12 R11 K10 + 0x5838000E, // 00E6 LDCONST R14 K14 + 0x883C0B20, // 00E7 GETMBR R15 R5 K32 + 0x5C401000, // 00E8 MOVE R16 R8 + 0x7C300800, // 00E9 CALL R12 4 + 0x8C301724, // 00EA GETMET R12 R11 K36 + 0x7C300200, // 00EB CALL R12 1 + 0x8C340325, // 00EC GETMET R13 R1 K37 + 0x7C340200, // 00ED CALL R13 1 + 0x0034180D, // 00EE ADD R13 R12 R13 + 0x8C380926, // 00EF GETMET R14 R4 K38 + 0x7C380200, // 00F0 CALL R14 1 + 0x8C381D27, // 00F1 GETMET R14 R14 K39 + 0xB8420200, // 00F2 GETNGBL R16 K1 + 0x8C402128, // 00F3 GETMET R16 R16 K40 + 0x7C400200, // 00F4 CALL R16 1 + 0x5C441A00, // 00F5 MOVE R17 R13 + 0x7C380600, // 00F6 CALL R14 3 + 0x8C3C0B09, // 00F7 GETMET R15 R5 K9 + 0x7C3C0200, // 00F8 CALL R15 1 + 0x8C401F0A, // 00F9 GETMET R16 R15 K10 + 0x58480005, // 00FA LDCONST R18 K5 + 0x884C0B1C, // 00FB GETMBR R19 R5 K28 + 0x5C501800, // 00FC MOVE R20 R12 + 0x7C400800, // 00FD CALL R16 4 + 0x8C401F0A, // 00FE GETMET R16 R15 K10 + 0x58480007, // 00FF LDCONST R18 K7 + 0x884C0B20, // 0100 GETMBR R19 R5 K32 + 0x5C501C00, // 0101 MOVE R20 R14 + 0x7C400800, // 0102 CALL R16 4 + 0x54420004, // 0103 LDINT R16 5 + 0x900E0810, // 0104 SETMBR R3 K4 R16 + 0x80041E00, // 0105 RET 1 R15 + 0x70020122, // 0106 JMP #022A + 0x5422000A, // 0107 LDINT R8 11 + 0x1C200E08, // 0108 EQ R8 R7 R8 + 0x7822000B, // 0109 JMPF R8 #0116 + 0x8C200506, // 010A GETMET R8 R2 K6 + 0x58280005, // 010B LDCONST R10 K5 + 0x7C200400, // 010C CALL R8 2 + 0x8C24032A, // 010D GETMET R9 R1 K42 + 0x5C2C1000, // 010E MOVE R11 R8 + 0x7C240400, // 010F CALL R9 2 + 0xB8260200, // 0110 GETNGBL R9 K1 + 0x8824132B, // 0111 GETMBR R9 R9 K43 + 0x900E3409, // 0112 SETMBR R3 K26 R9 + 0x4C240000, // 0113 LDNIL R9 + 0x80041200, // 0114 RET 1 R9 + 0x70020113, // 0115 JMP #022A + 0x54220005, // 0116 LDINT R8 6 + 0x1C200E08, // 0117 EQ R8 R7 R8 + 0x782200B9, // 0118 JMPF R8 #01D3 + 0xB8224400, // 0119 GETNGBL R8 K34 + 0x8C20112C, // 011A GETMET R8 R8 K44 + 0x60280008, // 011B GETGBL R10 G8 + 0x5C2C0400, // 011C MOVE R11 R2 + 0x7C280200, // 011D CALL R10 1 + 0x002A5A0A, // 011E ADD R10 K45 R10 + 0x542E0003, // 011F LDINT R11 4 + 0x7C200600, // 0120 CALL R8 3 + 0x8C200506, // 0121 GETMET R8 R2 K6 + 0x58280005, // 0122 LDCONST R10 K5 + 0x7C200400, // 0123 CALL R8 2 + 0x8C240506, // 0124 GETMET R9 R2 K6 + 0x582C0007, // 0125 LDCONST R11 K7 + 0x7C240400, // 0126 CALL R9 2 + 0x6028000C, // 0127 GETGBL R10 G12 + 0x5C2C1200, // 0128 MOVE R11 R9 + 0x7C280200, // 0129 CALL R10 1 + 0x1C281505, // 012A EQ R10 R10 K5 + 0x782A0000, // 012B JMPF R10 #012D + 0x4C240000, // 012C LDNIL R9 + 0x8C280506, // 012D GETMET R10 R2 K6 + 0x5830000E, // 012E LDCONST R12 K14 + 0x7C280400, // 012F CALL R10 2 + 0x8C2C0506, // 0130 GETMET R11 R2 K6 + 0x58340010, // 0131 LDCONST R13 K16 + 0x7C2C0400, // 0132 CALL R11 2 + 0x8C300506, // 0133 GETMET R12 R2 K6 + 0x543A0003, // 0134 LDINT R14 4 + 0x7C300400, // 0135 CALL R12 2 + 0x8C34032E, // 0136 GETMET R13 R1 K46 + 0x7C340200, // 0137 CALL R13 1 + 0x4C380000, // 0138 LDNIL R14 + 0x1C341A0E, // 0139 EQ R13 R13 R14 + 0x78360006, // 013A JMPF R13 #0142 + 0xB8364400, // 013B GETNGBL R13 K34 + 0x8C341B2C, // 013C GETMET R13 R13 K44 + 0x583C002F, // 013D LDCONST R15 K47 + 0x5840000E, // 013E LDCONST R16 K14 + 0x7C340600, // 013F CALL R13 3 + 0x4C340000, // 0140 LDNIL R13 + 0x80041A00, // 0141 RET 1 R13 + 0x88340116, // 0142 GETMBR R13 R0 K22 + 0x88341B30, // 0143 GETMBR R13 R13 K48 + 0x8C341B31, // 0144 GETMET R13 R13 K49 + 0x7C340200, // 0145 CALL R13 1 + 0x8C381B32, // 0146 GETMET R14 R13 K50 + 0x8C40032E, // 0147 GETMET R16 R1 K46 + 0x7C400200, // 0148 CALL R16 1 + 0x7C380400, // 0149 CALL R14 2 + 0x8C381B33, // 014A GETMET R14 R13 K51 + 0x5C401000, // 014B MOVE R16 R8 + 0x5C441200, // 014C MOVE R17 R9 + 0x7C380600, // 014D CALL R14 3 + 0x8C381B34, // 014E GETMET R14 R13 K52 + 0x5C401400, // 014F MOVE R16 R10 + 0x7C380400, // 0150 CALL R14 2 + 0x8C381B35, // 0151 GETMET R14 R13 K53 + 0x5C401600, // 0152 MOVE R16 R11 + 0x5C441800, // 0153 MOVE R17 R12 + 0x7C380600, // 0154 CALL R14 3 + 0x8C381B36, // 0155 GETMET R14 R13 K54 + 0x8C400337, // 0156 GETMET R16 R1 K55 + 0x7C400200, // 0157 CALL R16 1 + 0x7C380400, // 0158 CALL R14 2 + 0xB83A0200, // 0159 GETNGBL R14 K1 + 0x88381D02, // 015A GETMBR R14 R14 K2 + 0x8C381D38, // 015B GETMET R14 R14 K56 + 0x5C401000, // 015C MOVE R16 R8 + 0x7C380400, // 015D CALL R14 2 + 0x8C3C1D39, // 015E GETMET R15 R14 K57 + 0x54460005, // 015F LDINT R17 6 + 0x7C3C0400, // 0160 CALL R15 2 + 0x8C401F06, // 0161 GETMET R16 R15 K6 + 0x544A0014, // 0162 LDINT R18 21 + 0x7C400400, // 0163 CALL R16 2 + 0x8C441F06, // 0164 GETMET R17 R15 K6 + 0x544E0010, // 0165 LDINT R19 17 + 0x7C440400, // 0166 CALL R17 2 + 0x5C482000, // 0167 MOVE R18 R16 + 0x784A0001, // 0168 JMPF R18 #016B + 0x5C482200, // 0169 MOVE R18 R17 + 0x744A0006, // 016A JMPT R18 #0172 + 0xB84A4400, // 016B GETNGBL R18 K34 + 0x8C48252C, // 016C GETMET R18 R18 K44 + 0x5850003A, // 016D LDCONST R20 K58 + 0x5854000E, // 016E LDCONST R21 K14 + 0x7C480600, // 016F CALL R18 3 + 0x50480000, // 0170 LDBOOL R18 0 0 + 0x80042400, // 0171 RET 1 R18 + 0x60480004, // 0172 GETGBL R18 G4 + 0x5C4C2000, // 0173 MOVE R19 R16 + 0x7C480200, // 0174 CALL R18 1 + 0x1C48253B, // 0175 EQ R18 R18 K59 + 0x784A0007, // 0176 JMPF R18 #017F + 0xB84A7800, // 0177 GETNGBL R18 K60 + 0x8C48253D, // 0178 GETMET R18 R18 K61 + 0x5C502000, // 0179 MOVE R20 R16 + 0x7C480400, // 017A CALL R18 2 + 0x8C48253E, // 017B GETMET R18 R18 K62 + 0x7C480200, // 017C CALL R18 1 + 0x5C402400, // 017D MOVE R16 R18 + 0x70020002, // 017E JMP #0182 + 0x8C48213E, // 017F GETMET R18 R16 K62 + 0x7C480200, // 0180 CALL R18 1 + 0x5C402400, // 0181 MOVE R16 R18 + 0x60480004, // 0182 GETGBL R18 G4 + 0x5C4C2200, // 0183 MOVE R19 R17 + 0x7C480200, // 0184 CALL R18 1 + 0x1C48253B, // 0185 EQ R18 R18 K59 + 0x784A0007, // 0186 JMPF R18 #018F + 0xB84A7800, // 0187 GETNGBL R18 K60 + 0x8C48253D, // 0188 GETMET R18 R18 K61 + 0x5C502200, // 0189 MOVE R20 R17 + 0x7C480400, // 018A CALL R18 2 + 0x8C48253E, // 018B GETMET R18 R18 K62 + 0x7C480200, // 018C CALL R18 1 + 0x5C442400, // 018D MOVE R17 R18 + 0x70020002, // 018E JMP #0192 + 0x8C48233E, // 018F GETMET R18 R17 K62 + 0x7C480200, // 0190 CALL R18 1 + 0x5C442400, // 0191 MOVE R17 R18 + 0x8C48033F, // 0192 GETMET R18 R1 K63 + 0x7C480200, // 0193 CALL R18 1 + 0x404E0F40, // 0194 CONNECT R19 K7 K64 + 0x94482413, // 0195 GETIDX R18 R18 R19 + 0x60500015, // 0196 GETGBL R20 G21 + 0x7C500000, // 0197 CALL R20 0 + 0x8C502941, // 0198 GETMET R20 R20 K65 + 0x58580042, // 0199 LDCONST R22 K66 + 0x7C500400, // 019A CALL R20 2 + 0x5C4C2800, // 019B MOVE R19 R20 + 0x8C500943, // 019C GETMET R20 R4 K67 + 0x7C500200, // 019D CALL R20 1 + 0x8C542144, // 019E GETMET R21 R16 K68 + 0x7C540200, // 019F CALL R21 1 + 0x8C542B45, // 01A0 GETMET R21 R21 K69 + 0x7C540200, // 01A1 CALL R21 1 + 0x8C582946, // 01A2 GETMET R22 R20 K70 + 0x5C602400, // 01A3 MOVE R24 R18 + 0x5C642A00, // 01A4 MOVE R25 R21 + 0x5C682600, // 01A5 MOVE R26 R19 + 0x546E0007, // 01A6 LDINT R27 8 + 0x7C580A00, // 01A7 CALL R22 5 + 0x885C0312, // 01A8 GETMBR R23 R1 K18 + 0x785E0001, // 01A9 JMPF R23 #01AC + 0x885C0312, // 01AA GETMBR R23 R1 K18 + 0x70020001, // 01AB JMP #01AE + 0x885C0116, // 01AC GETMBR R23 R0 K22 + 0x885C2F47, // 01AD GETMBR R23 R23 K71 + 0x8C601B48, // 01AE GETMET R24 R13 K72 + 0x5C682000, // 01AF MOVE R26 R16 + 0x5C6C2200, // 01B0 MOVE R27 R17 + 0x5C702C00, // 01B1 MOVE R28 R22 + 0x5C742E00, // 01B2 MOVE R29 R23 + 0x7C600A00, // 01B3 CALL R24 5 + 0x8C601B49, // 01B4 GETMET R24 R13 K73 + 0x7C600200, // 01B5 CALL R24 1 + 0x88600116, // 01B6 GETMBR R24 R0 K22 + 0x8C60314A, // 01B7 GETMET R24 R24 K74 + 0x5C681A00, // 01B8 MOVE R26 R13 + 0x7C600400, // 01B9 CALL R24 2 + 0x8C60034B, // 01BA GETMET R24 R1 K75 + 0x7C600200, // 01BB CALL R24 1 + 0x78620002, // 01BC JMPF R24 #01C0 + 0x8C60034C, // 01BD GETMET R24 R1 K76 + 0x546A003B, // 01BE LDINT R26 60 + 0x7C600400, // 01BF CALL R24 2 + 0x8C601B4D, // 01C0 GETMET R24 R13 K77 + 0x7C600200, // 01C1 CALL R24 1 + 0x8C600B09, // 01C2 GETMET R24 R5 K9 + 0x7C600200, // 01C3 CALL R24 1 + 0x8C64310A, // 01C4 GETMET R25 R24 K10 + 0x586C0005, // 01C5 LDCONST R27 K5 + 0x88700B0B, // 01C6 GETMBR R28 R5 K11 + 0xB8760200, // 01C7 GETNGBL R29 K1 + 0x88743B2B, // 01C8 GETMBR R29 R29 K43 + 0x7C640800, // 01C9 CALL R25 4 + 0x8C64310A, // 01CA GETMET R25 R24 K10 + 0x586C0007, // 01CB LDCONST R27 K7 + 0x88700B0B, // 01CC GETMBR R28 R5 K11 + 0x58740007, // 01CD LDCONST R29 K7 + 0x7C640800, // 01CE CALL R25 4 + 0x54660007, // 01CF LDINT R25 8 + 0x900E0819, // 01D0 SETMBR R3 K4 R25 + 0x80043000, // 01D1 RET 1 R24 + 0x70020056, // 01D2 JMP #022A + 0x54220008, // 01D3 LDINT R8 9 + 0x1C200E08, // 01D4 EQ R8 R7 R8 + 0x7822001E, // 01D5 JMPF R8 #01F5 + 0x8C200506, // 01D6 GETMET R8 R2 K6 + 0x58280005, // 01D7 LDCONST R10 K5 + 0x7C200400, // 01D8 CALL R8 2 + 0x8C24034E, // 01D9 GETMET R9 R1 K78 + 0x5C2C1000, // 01DA MOVE R11 R8 + 0x7C240400, // 01DB CALL R9 2 + 0xB8264400, // 01DC GETNGBL R9 K34 + 0x8C24132C, // 01DD GETMET R9 R9 K44 + 0x602C0018, // 01DE GETGBL R11 G24 + 0x5830004F, // 01DF LDCONST R12 K79 + 0x88340312, // 01E0 GETMBR R13 R1 K18 + 0x8C341B50, // 01E1 GETMET R13 R13 K80 + 0x7C340200, // 01E2 CALL R13 1 + 0x8C341B44, // 01E3 GETMET R13 R13 K68 + 0x7C340200, // 01E4 CALL R13 1 + 0x8C341B45, // 01E5 GETMET R13 R13 K69 + 0x7C340200, // 01E6 CALL R13 1 + 0x8C341B51, // 01E7 GETMET R13 R13 K81 + 0x7C340200, // 01E8 CALL R13 1 + 0x60380008, // 01E9 GETGBL R14 G8 + 0x5C3C1000, // 01EA MOVE R15 R8 + 0x7C380200, // 01EB CALL R14 1 + 0x7C2C0600, // 01EC CALL R11 3 + 0x58300010, // 01ED LDCONST R12 K16 + 0x7C240600, // 01EE CALL R9 3 + 0xB8260200, // 01EF GETNGBL R9 K1 + 0x8824132B, // 01F0 GETMBR R9 R9 K43 + 0x900E3409, // 01F1 SETMBR R3 K26 R9 + 0x4C240000, // 01F2 LDNIL R9 + 0x80041200, // 01F3 RET 1 R9 + 0x70020034, // 01F4 JMP #022A + 0x54220009, // 01F5 LDINT R8 10 + 0x1C200E08, // 01F6 EQ R8 R7 R8 + 0x78220031, // 01F7 JMPF R8 #022A + 0x8C200506, // 01F8 GETMET R8 R2 K6 + 0x58280005, // 01F9 LDCONST R10 K5 + 0x7C200400, // 01FA CALL R8 2 + 0x60240008, // 01FB GETGBL R9 G8 + 0x5C281000, // 01FC MOVE R10 R8 + 0x7C240200, // 01FD CALL R9 1 + 0x0026A409, // 01FE ADD R9 K82 R9 + 0x900E5809, // 01FF SETMBR R3 K44 R9 + 0x60240010, // 0200 GETGBL R9 G16 + 0x88280116, // 0201 GETMBR R10 R0 K22 + 0x88281530, // 0202 GETMBR R10 R10 K48 + 0x8C281553, // 0203 GETMET R10 R10 K83 + 0x7C280200, // 0204 CALL R10 1 + 0x7C240200, // 0205 CALL R9 1 + 0xA8020010, // 0206 EXBLK 0 #0218 + 0x5C281200, // 0207 MOVE R10 R9 + 0x7C280000, // 0208 CALL R10 0 + 0x8C2C1554, // 0209 GETMET R11 R10 K84 + 0x7C2C0200, // 020A CALL R11 1 + 0x1C2C1608, // 020B EQ R11 R11 R8 + 0x782E0008, // 020C JMPF R11 #0216 + 0xB82E4400, // 020D GETNGBL R11 K34 + 0x8C2C1755, // 020E GETMET R11 R11 K85 + 0x543607CF, // 020F LDINT R13 2000 + 0x84380000, // 0210 CLOSURE R14 P0 + 0x7C2C0600, // 0211 CALL R11 3 + 0x502C0200, // 0212 LDBOOL R11 1 0 + 0xA0000000, // 0213 CLOSE R0 + 0xA8040001, // 0214 EXBLK 1 1 + 0x80041600, // 0215 RET 1 R11 + 0xA0240000, // 0216 CLOSE R9 + 0x7001FFEE, // 0217 JMP #0207 + 0x58240056, // 0218 LDCONST R9 K86 + 0xAC240200, // 0219 CATCH R9 1 0 + 0xB0080000, // 021A RAISE 2 R0 R0 + 0xB8264400, // 021B GETNGBL R9 K34 + 0x8C24132C, // 021C GETMET R9 R9 K44 + 0x602C0008, // 021D GETGBL R11 G8 + 0x5C301000, // 021E MOVE R12 R8 + 0x7C2C0200, // 021F CALL R11 1 + 0x002EAE0B, // 0220 ADD R11 K87 R11 + 0x002C1758, // 0221 ADD R11 R11 K88 + 0x5830000E, // 0222 LDCONST R12 K14 + 0x7C240600, // 0223 CALL R9 3 + 0xB8260200, // 0224 GETNGBL R9 K1 + 0x88241359, // 0225 GETMBR R9 R9 K89 + 0x900E3409, // 0226 SETMBR R3 K26 R9 + 0x4C240000, // 0227 LDNIL R9 + 0xA0000000, // 0228 CLOSE R0 + 0x80041200, // 0229 RET 1 R9 + 0x7002009B, // 022A JMP #02C7 + 0x5422003B, // 022B LDINT R8 60 + 0x1C200C08, // 022C EQ R8 R6 R8 + 0x78220085, // 022D JMPF R8 #02B4 + 0x1C200F05, // 022E EQ R8 R7 K5 + 0x78220065, // 022F JMPF R8 #0296 + 0x8C200506, // 0230 GETMET R8 R2 K6 + 0x58280005, // 0231 LDCONST R10 K5 + 0x7C200400, // 0232 CALL R8 2 + 0x8C240506, // 0233 GETMET R9 R2 K6 + 0x582C0007, // 0234 LDCONST R11 K7 + 0x7C240400, // 0235 CALL R9 2 + 0x8C280506, // 0236 GETMET R10 R2 K6 + 0x5830000E, // 0237 LDCONST R12 K14 + 0x7C280400, // 0238 CALL R10 2 + 0x8C2C0506, // 0239 GETMET R11 R2 K6 + 0x58340010, // 023A LDCONST R13 K16 + 0x7C2C0400, // 023B CALL R11 2 + 0x8C300506, // 023C GETMET R12 R2 K6 + 0x543A0003, // 023D LDINT R14 4 + 0x7C300400, // 023E CALL R12 2 + 0xB8364400, // 023F GETNGBL R13 K34 + 0x8C341B2C, // 0240 GETMET R13 R13 K44 + 0x603C0018, // 0241 GETGBL R15 G24 + 0x5840005A, // 0242 LDCONST R16 K90 + 0x5C441000, // 0243 MOVE R17 R8 + 0x8C481351, // 0244 GETMET R18 R9 K81 + 0x7C480200, // 0245 CALL R18 1 + 0x5C4C1400, // 0246 MOVE R19 R10 + 0x5C501600, // 0247 MOVE R20 R11 + 0x8C541951, // 0248 GETMET R21 R12 K81 + 0x7C540200, // 0249 CALL R21 1 + 0x7C3C0C00, // 024A CALL R15 6 + 0x54420003, // 024B LDINT R16 4 + 0x7C340600, // 024C CALL R13 3 + 0x4C340000, // 024D LDNIL R13 + 0x1C34100D, // 024E EQ R13 R8 R13 + 0x7436000B, // 024F JMPT R13 #025C + 0x4C340000, // 0250 LDNIL R13 + 0x1C34120D, // 0251 EQ R13 R9 R13 + 0x74360008, // 0252 JMPT R13 #025C + 0x4C340000, // 0253 LDNIL R13 + 0x1C34140D, // 0254 EQ R13 R10 R13 + 0x74360005, // 0255 JMPT R13 #025C + 0x4C340000, // 0256 LDNIL R13 + 0x1C34160D, // 0257 EQ R13 R11 R13 + 0x74360002, // 0258 JMPT R13 #025C + 0x4C340000, // 0259 LDNIL R13 + 0x1C34180D, // 025A EQ R13 R12 R13 + 0x78360005, // 025B JMPF R13 #0262 + 0xB8360200, // 025C GETNGBL R13 K1 + 0x88341B5B, // 025D GETMBR R13 R13 K91 + 0x900E340D, // 025E SETMBR R3 K26 R13 + 0x4C340000, // 025F LDNIL R13 + 0xA0000000, // 0260 CLOSE R0 + 0x80041A00, // 0261 RET 1 R13 + 0x6034000C, // 0262 GETGBL R13 G12 + 0x5C381200, // 0263 MOVE R14 R9 + 0x7C340200, // 0264 CALL R13 1 + 0x543A001F, // 0265 LDINT R14 32 + 0x543E0040, // 0266 LDINT R15 65 + 0x00381C0F, // 0267 ADD R14 R14 R15 + 0x20341A0E, // 0268 NE R13 R13 R14 + 0x7436000B, // 0269 JMPT R13 #0276 + 0x6034000C, // 026A GETGBL R13 G12 + 0x5C381800, // 026B MOVE R14 R12 + 0x7C340200, // 026C CALL R13 1 + 0x543A000F, // 026D LDINT R14 16 + 0x14341A0E, // 026E LT R13 R13 R14 + 0x74360005, // 026F JMPT R13 #0276 + 0x6034000C, // 0270 GETGBL R13 G12 + 0x5C381800, // 0271 MOVE R14 R12 + 0x7C340200, // 0272 CALL R13 1 + 0x543A001F, // 0273 LDINT R14 32 + 0x24341A0E, // 0274 GT R13 R13 R14 + 0x7836000A, // 0275 JMPF R13 #0281 + 0xB8364400, // 0276 GETNGBL R13 K34 + 0x8C341B2C, // 0277 GETMET R13 R13 K44 + 0x583C005C, // 0278 LDCONST R15 K92 + 0x5840000E, // 0279 LDCONST R16 K14 + 0x7C340600, // 027A CALL R13 3 + 0xB8360200, // 027B GETNGBL R13 K1 + 0x88341B5D, // 027C GETMBR R13 R13 K93 + 0x900E340D, // 027D SETMBR R3 K26 R13 + 0x4C340000, // 027E LDNIL R13 + 0xA0000000, // 027F CLOSE R0 + 0x80041A00, // 0280 RET 1 R13 + 0x5436001E, // 0281 LDINT R13 31 + 0x40360A0D, // 0282 CONNECT R13 K5 R13 + 0x9434120D, // 0283 GETIDX R13 R9 R13 + 0x543A001F, // 0284 LDINT R14 32 + 0x40381D40, // 0285 CONNECT R14 R14 K64 + 0x9438120E, // 0286 GETIDX R14 R9 R14 + 0x883C0116, // 0287 GETMBR R15 R0 K22 + 0x8C3C1F5E, // 0288 GETMET R15 R15 K94 + 0x5C441000, // 0289 MOVE R17 R8 + 0x5C481600, // 028A MOVE R18 R11 + 0x5C4C1400, // 028B MOVE R19 R10 + 0x5C501800, // 028C MOVE R20 R12 + 0x5C541A00, // 028D MOVE R21 R13 + 0x5C581C00, // 028E MOVE R22 R14 + 0x8C5C035F, // 028F GETMET R23 R1 K95 + 0x7C5C0200, // 0290 CALL R23 1 + 0x7C3C1000, // 0291 CALL R15 8 + 0x503C0200, // 0292 LDBOOL R15 1 0 + 0xA0000000, // 0293 CLOSE R0 + 0x80041E00, // 0294 RET 1 R15 + 0x7002001C, // 0295 JMP #02B3 + 0x1C200F07, // 0296 EQ R8 R7 K7 + 0x78220012, // 0297 JMPF R8 #02AB + 0x8C200506, // 0298 GETMET R8 R2 K6 + 0x58280005, // 0299 LDCONST R10 K5 + 0x7C200400, // 029A CALL R8 2 + 0xB8264400, // 029B GETNGBL R9 K34 + 0x8C24132C, // 029C GETMET R9 R9 K44 + 0x602C0008, // 029D GETGBL R11 G8 + 0x5C301000, // 029E MOVE R12 R8 + 0x7C2C0200, // 029F CALL R11 1 + 0x002EC00B, // 02A0 ADD R11 K96 R11 + 0x58300010, // 02A1 LDCONST R12 K16 + 0x7C240600, // 02A2 CALL R9 3 + 0x88240116, // 02A3 GETMBR R9 R0 K22 + 0x8C241361, // 02A4 GETMET R9 R9 K97 + 0x5C2C1000, // 02A5 MOVE R11 R8 + 0x7C240400, // 02A6 CALL R9 2 + 0x50240200, // 02A7 LDBOOL R9 1 0 + 0xA0000000, // 02A8 CLOSE R0 + 0x80041200, // 02A9 RET 1 R9 + 0x70020007, // 02AA JMP #02B3 + 0x1C200F0E, // 02AB EQ R8 R7 K14 + 0x78220005, // 02AC JMPF R8 #02B3 + 0x88200116, // 02AD GETMBR R8 R0 K22 + 0x8C201162, // 02AE GETMET R8 R8 K98 + 0x7C200200, // 02AF CALL R8 1 + 0x50200200, // 02B0 LDBOOL R8 1 0 + 0xA0000000, // 02B1 CLOSE R0 + 0x80041000, // 02B2 RET 1 R8 + 0x70020012, // 02B3 JMP #02C7 + 0x54220029, // 02B4 LDINT R8 42 + 0x1C200C08, // 02B5 EQ R8 R6 R8 + 0x78220005, // 02B6 JMPF R8 #02BD + 0x1C200F05, // 02B7 EQ R8 R7 K5 + 0x78220002, // 02B8 JMPF R8 #02BC + 0x50200200, // 02B9 LDBOOL R8 1 0 + 0xA0000000, // 02BA CLOSE R0 + 0x80041000, // 02BB RET 1 R8 + 0x70020009, // 02BC JMP #02C7 + 0x60200003, // 02BD GETGBL R8 G3 + 0x5C240000, // 02BE MOVE R9 R0 + 0x7C200200, // 02BF CALL R8 1 + 0x8C201163, // 02C0 GETMET R8 R8 K99 + 0x5C280200, // 02C1 MOVE R10 R1 + 0x5C2C0400, // 02C2 MOVE R11 R2 + 0x5C300600, // 02C3 MOVE R12 R3 + 0x7C200800, // 02C4 CALL R8 4 + 0xA0000000, // 02C5 CLOSE R0 + 0x80041000, // 02C6 RET 1 R8 + 0xA0000000, // 02C7 CLOSE R0 + 0x80000000, // 02C8 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Root +********************************************************************/ +extern const bclass be_class_Matter_Plugin; +be_local_class(Matter_Plugin_Root, + 0, + &be_class_Matter_Plugin, + be_nested_map(7, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(read_attribute, 1), be_const_closure(Matter_Plugin_Root_read_attribute_closure) }, + { be_const_key_weak(invoke_request, 6), be_const_closure(Matter_Plugin_Root_invoke_request_closure) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(root) }, + { be_const_key_weak(TYPES, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(22, -1), be_const_int(1) }, + })) ) } )) }, + { be_const_key_weak(write_attribute, -1), be_const_closure(Matter_Plugin_Root_write_attribute_closure) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Root_X20node) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(15, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(60, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + })) ) } )) }, + { be_const_key_int(31, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(2), + be_const_int(3), + be_const_int(4), + })) ) } )) }, + { be_const_key_int(62, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + })) ) } )) }, + { be_const_key_int(48, 9), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(5, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + })) ) } )) }, + { be_const_key_int(49, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(3), + be_const_int(4), + be_const_int(65532), + })) ) } )) }, + { be_const_key_int(50, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(0, + ( (struct bvalue*) &(const bvalue[]) { + })) ) } )) }, + { be_const_key_int(51, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(8), + })) ) } )) }, + { be_const_key_int(52, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(0, + ( (struct bvalue*) &(const bvalue[]) { + })) ) } )) }, + { be_const_key_int(29, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(63, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(0, + ( (struct bvalue*) &(const bvalue[]) { + })) ) } )) }, + { be_const_key_int(40, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(15, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(6), + be_const_int(7), + be_const_int(8), + be_const_int(9), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + be_const_int(19), + })) ) } )) }, + { be_const_key_int(56, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(7), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(1, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + })) ) } )) }, + { be_const_key_int(43, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(2, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + })) ) } )) }, + { be_const_key_int(44, 8), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + })) ) } )) }, + })) ) } )) }, + })), + be_str_weak(Matter_Plugin_Root) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Root_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Root); + be_setglobal(vm, "Matter_Plugin_Root"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Aggregator.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Aggregator.h new file mode 100644 index 000000000000..af4ea7333136 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Aggregator.h @@ -0,0 +1,128 @@ +/* Solidification of Matter_Plugin_2_Aggregator.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Aggregator; + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Aggregator_read_attribute, /* name */ + be_nested_proto( + 16, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(3), + /* K5 */ be_nested_str_weak(Matter_TLV_array), + /* K6 */ be_nested_str_weak(device), + /* K7 */ be_nested_str_weak(get_active_endpoints), + /* K8 */ be_nested_str_weak(add_TLV), + /* K9 */ be_nested_str_weak(U2), + /* K10 */ be_nested_str_weak(stop_iteration), + /* K11 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[55]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E001C, // 0004 LDINT R7 29 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0025, // 0006 JMPF R7 #002D + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E0019, // 0008 JMPF R7 #0023 + 0x8C1C0905, // 0009 GETMET R7 R4 K5 + 0x7C1C0200, // 000A CALL R7 1 + 0x88200106, // 000B GETMBR R8 R0 K6 + 0x8C201107, // 000C GETMET R8 R8 K7 + 0x50280200, // 000D LDBOOL R10 1 0 + 0x7C200400, // 000E CALL R8 2 + 0x60240010, // 000F GETGBL R9 G16 + 0x5C281000, // 0010 MOVE R10 R8 + 0x7C240200, // 0011 CALL R9 1 + 0xA802000A, // 0012 EXBLK 0 #001E + 0x5C281200, // 0013 MOVE R10 R9 + 0x7C280000, // 0014 CALL R10 0 + 0x542EFEFF, // 0015 LDINT R11 65280 + 0x142C140B, // 0016 LT R11 R10 R11 + 0x782E0004, // 0017 JMPF R11 #001D + 0x8C2C0F08, // 0018 GETMET R11 R7 K8 + 0x4C340000, // 0019 LDNIL R13 + 0x88380909, // 001A GETMBR R14 R4 K9 + 0x5C3C1400, // 001B MOVE R15 R10 + 0x7C2C0800, // 001C CALL R11 4 + 0x7001FFF4, // 001D JMP #0013 + 0x5824000A, // 001E LDCONST R9 K10 + 0xAC240200, // 001F CATCH R9 1 0 + 0xB0080000, // 0020 RAISE 2 R0 R0 + 0x80040E00, // 0021 RET 1 R7 + 0x70020008, // 0022 JMP #002C + 0x601C0003, // 0023 GETGBL R7 G3 + 0x5C200000, // 0024 MOVE R8 R0 + 0x7C1C0200, // 0025 CALL R7 1 + 0x8C1C0F0B, // 0026 GETMET R7 R7 K11 + 0x5C240200, // 0027 MOVE R9 R1 + 0x5C280400, // 0028 MOVE R10 R2 + 0x5C2C0600, // 0029 MOVE R11 R3 + 0x7C1C0800, // 002A CALL R7 4 + 0x80040E00, // 002B RET 1 R7 + 0x70020008, // 002C JMP #0036 + 0x601C0003, // 002D GETGBL R7 G3 + 0x5C200000, // 002E MOVE R8 R0 + 0x7C1C0200, // 002F CALL R7 1 + 0x8C1C0F0B, // 0030 GETMET R7 R7 K11 + 0x5C240200, // 0031 MOVE R9 R1 + 0x5C280400, // 0032 MOVE R10 R2 + 0x5C2C0600, // 0033 MOVE R11 R3 + 0x7C1C0800, // 0034 CALL R7 4 + 0x80040E00, // 0035 RET 1 R7 + 0x80000000, // 0036 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Aggregator +********************************************************************/ +extern const bclass be_class_Matter_Plugin; +be_local_class(Matter_Plugin_Aggregator, + 0, + &be_class_Matter_Plugin, + be_nested_map(4, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(14, -1), be_const_int(1) }, + })) ) } )) }, + { be_const_key_weak(TYPE, 3), be_nested_str_weak(aggregator) }, + { be_const_key_weak(read_attribute, 0), be_const_closure(Matter_Plugin_Aggregator_read_attribute_closure) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Aggregator) }, + })), + be_str_weak(Matter_Plugin_Aggregator) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Aggregator_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Aggregator); + be_setglobal(vm, "Matter_Plugin_Aggregator"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Bridge_HTTP.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Bridge_HTTP.h new file mode 100644 index 000000000000..418f03eae293 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Bridge_HTTP.h @@ -0,0 +1,945 @@ +/* Solidification of Matter_Plugin_2_Bridge_HTTP.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_GetOptionReader; + +/******************************************************************** +** Solidified function: getoption +********************************************************************/ +be_local_closure(GetOptionReader_getoption, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(flag), + /* K1 */ be_nested_str_weak(getbits), + /* K2 */ be_const_int(1), + /* K3 */ be_nested_str_weak(flag2), + /* K4 */ be_nested_str_weak(get), + /* K5 */ be_nested_str_weak(flag3), + /* K6 */ be_nested_str_weak(flag4), + /* K7 */ be_nested_str_weak(flag5), + /* K8 */ be_nested_str_weak(flag6), + }), + be_str_weak(getoption), + &be_const_str_solidified, + ( &(const binstruction[65]) { /* code */ + 0x540A001F, // 0000 LDINT R2 32 + 0x14080202, // 0001 LT R2 R1 R2 + 0x780A0006, // 0002 JMPF R2 #000A + 0x88080100, // 0003 GETMBR R2 R0 K0 + 0x8C080501, // 0004 GETMET R2 R2 K1 + 0x5C100200, // 0005 MOVE R4 R1 + 0x58140002, // 0006 LDCONST R5 K2 + 0x7C080600, // 0007 CALL R2 3 + 0x80040400, // 0008 RET 1 R2 + 0x70020035, // 0009 JMP #0040 + 0x540A0031, // 000A LDINT R2 50 + 0x14080202, // 000B LT R2 R1 R2 + 0x780A0007, // 000C JMPF R2 #0015 + 0x88080103, // 000D GETMBR R2 R0 K3 + 0x8C080504, // 000E GETMET R2 R2 K4 + 0x5412001F, // 000F LDINT R4 32 + 0x04100204, // 0010 SUB R4 R1 R4 + 0x58140002, // 0011 LDCONST R5 K2 + 0x7C080600, // 0012 CALL R2 3 + 0x80040400, // 0013 RET 1 R2 + 0x7002002A, // 0014 JMP #0040 + 0x540A0051, // 0015 LDINT R2 82 + 0x14080202, // 0016 LT R2 R1 R2 + 0x780A0007, // 0017 JMPF R2 #0020 + 0x88080105, // 0018 GETMBR R2 R0 K5 + 0x8C080501, // 0019 GETMET R2 R2 K1 + 0x54120031, // 001A LDINT R4 50 + 0x04100204, // 001B SUB R4 R1 R4 + 0x58140002, // 001C LDCONST R5 K2 + 0x7C080600, // 001D CALL R2 3 + 0x80040400, // 001E RET 1 R2 + 0x7002001F, // 001F JMP #0040 + 0x540A0071, // 0020 LDINT R2 114 + 0x14080202, // 0021 LT R2 R1 R2 + 0x780A0007, // 0022 JMPF R2 #002B + 0x88080106, // 0023 GETMBR R2 R0 K6 + 0x8C080501, // 0024 GETMET R2 R2 K1 + 0x54120051, // 0025 LDINT R4 82 + 0x04100204, // 0026 SUB R4 R1 R4 + 0x58140002, // 0027 LDCONST R5 K2 + 0x7C080600, // 0028 CALL R2 3 + 0x80040400, // 0029 RET 1 R2 + 0x70020014, // 002A JMP #0040 + 0x540A0091, // 002B LDINT R2 146 + 0x14080202, // 002C LT R2 R1 R2 + 0x780A0007, // 002D JMPF R2 #0036 + 0x88080107, // 002E GETMBR R2 R0 K7 + 0x8C080501, // 002F GETMET R2 R2 K1 + 0x54120071, // 0030 LDINT R4 114 + 0x04100204, // 0031 SUB R4 R1 R4 + 0x58140002, // 0032 LDCONST R5 K2 + 0x7C080600, // 0033 CALL R2 3 + 0x80040400, // 0034 RET 1 R2 + 0x70020009, // 0035 JMP #0040 + 0x540A00B1, // 0036 LDINT R2 178 + 0x14080202, // 0037 LT R2 R1 R2 + 0x780A0006, // 0038 JMPF R2 #0040 + 0x88080108, // 0039 GETMBR R2 R0 K8 + 0x8C080501, // 003A GETMET R2 R2 K1 + 0x54120091, // 003B LDINT R4 146 + 0x04100204, // 003C SUB R4 R1 R4 + 0x58140002, // 003D LDCONST R5 K2 + 0x7C080600, // 003E CALL R2 3 + 0x80040400, // 003F RET 1 R2 + 0x80000000, // 0040 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(GetOptionReader_init, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[15]) { /* constants */ + /* K0 */ be_nested_str_weak(value_error), + /* K1 */ be_nested_str_weak(invalid_X20json), + /* K2 */ be_nested_str_weak(SetOption), + /* K3 */ be_nested_str_weak(flag), + /* K4 */ be_nested_str_weak(fromhex), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(reverse), + /* K7 */ be_nested_str_weak(flag2), + /* K8 */ be_const_int(1), + /* K9 */ be_nested_str_weak(flag3), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str_weak(flag4), + /* K12 */ be_const_int(3), + /* K13 */ be_nested_str_weak(flag5), + /* K14 */ be_nested_str_weak(flag6), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[54]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x1C080202, // 0001 EQ R2 R1 R2 + 0x780A0000, // 0002 JMPF R2 #0004 + 0xB0060101, // 0003 RAISE 1 K0 K1 + 0x94080302, // 0004 GETIDX R2 R1 K2 + 0x600C0015, // 0005 GETGBL R3 G21 + 0x7C0C0000, // 0006 CALL R3 0 + 0x8C0C0704, // 0007 GETMET R3 R3 K4 + 0x94140505, // 0008 GETIDX R5 R2 K5 + 0x7C0C0400, // 0009 CALL R3 2 + 0x8C0C0706, // 000A GETMET R3 R3 K6 + 0x7C0C0200, // 000B CALL R3 1 + 0x90020603, // 000C SETMBR R0 K3 R3 + 0x600C0015, // 000D GETGBL R3 G21 + 0x7C0C0000, // 000E CALL R3 0 + 0x8C0C0704, // 000F GETMET R3 R3 K4 + 0x94140508, // 0010 GETIDX R5 R2 K8 + 0x7C0C0400, // 0011 CALL R3 2 + 0x90020E03, // 0012 SETMBR R0 K7 R3 + 0x600C0015, // 0013 GETGBL R3 G21 + 0x7C0C0000, // 0014 CALL R3 0 + 0x8C0C0704, // 0015 GETMET R3 R3 K4 + 0x9414050A, // 0016 GETIDX R5 R2 K10 + 0x7C0C0400, // 0017 CALL R3 2 + 0x8C0C0706, // 0018 GETMET R3 R3 K6 + 0x7C0C0200, // 0019 CALL R3 1 + 0x90021203, // 001A SETMBR R0 K9 R3 + 0x600C0015, // 001B GETGBL R3 G21 + 0x7C0C0000, // 001C CALL R3 0 + 0x8C0C0704, // 001D GETMET R3 R3 K4 + 0x9414050C, // 001E GETIDX R5 R2 K12 + 0x7C0C0400, // 001F CALL R3 2 + 0x8C0C0706, // 0020 GETMET R3 R3 K6 + 0x7C0C0200, // 0021 CALL R3 1 + 0x90021603, // 0022 SETMBR R0 K11 R3 + 0x600C0015, // 0023 GETGBL R3 G21 + 0x7C0C0000, // 0024 CALL R3 0 + 0x8C0C0704, // 0025 GETMET R3 R3 K4 + 0x54160003, // 0026 LDINT R5 4 + 0x94140405, // 0027 GETIDX R5 R2 R5 + 0x7C0C0400, // 0028 CALL R3 2 + 0x8C0C0706, // 0029 GETMET R3 R3 K6 + 0x7C0C0200, // 002A CALL R3 1 + 0x90021A03, // 002B SETMBR R0 K13 R3 + 0x600C0015, // 002C GETGBL R3 G21 + 0x7C0C0000, // 002D CALL R3 0 + 0x8C0C0704, // 002E GETMET R3 R3 K4 + 0x54160004, // 002F LDINT R5 5 + 0x94140405, // 0030 GETIDX R5 R2 R5 + 0x7C0C0400, // 0031 CALL R3 2 + 0x8C0C0706, // 0032 GETMET R3 R3 K6 + 0x7C0C0200, // 0033 CALL R3 1 + 0x90021C03, // 0034 SETMBR R0 K14 R3 + 0x80000000, // 0035 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: GetOptionReader +********************************************************************/ +be_local_class(GetOptionReader, + 6, + NULL, + be_nested_map(8, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(flag2, -1), be_const_var(1) }, + { be_const_key_weak(flag4, -1), be_const_var(3) }, + { be_const_key_weak(getoption, -1), be_const_closure(GetOptionReader_getoption_closure) }, + { be_const_key_weak(init, 5), be_const_closure(GetOptionReader_init_closure) }, + { be_const_key_weak(flag3, -1), be_const_var(2) }, + { be_const_key_weak(flag6, -1), be_const_var(5) }, + { be_const_key_weak(flag5, -1), be_const_var(4) }, + { be_const_key_weak(flag, 0), be_const_var(0) }, + })), + be_str_weak(GetOptionReader) +); +/*******************************************************************/ + +void be_load_GetOptionReader_class(bvm *vm) { + be_pushntvclass(vm, &be_class_GetOptionReader); + be_setglobal(vm, "GetOptionReader"); + be_pop(vm, 1); +} + +extern const bclass be_class_Matter_Plugin_Bridge_HTTP; + +/******************************************************************** +** Solidified function: call_remote_sync +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_HTTP_call_remote_sync, /* name */ + be_nested_proto( + 10, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(json), + /* K1 */ be_const_int(2), + /* K2 */ be_nested_str_weak(_X20), + /* K3 */ be_const_int(0), + /* K4 */ be_nested_str_weak(http_remote), + /* K5 */ be_nested_str_weak(call_sync), + /* K6 */ be_nested_str_weak(SYNC_TIMEOUT), + /* K7 */ be_nested_str_weak(device_is_alive), + /* K8 */ be_nested_str_weak(load), + /* K9 */ be_const_int(1), + /* K10 */ be_nested_str_weak(tasmota), + /* K11 */ be_nested_str_weak(log), + /* K12 */ be_nested_str_weak(MTR_X3A_X20HTTP_X20GET_X20retrying), + /* K13 */ be_const_int(3), + }), + be_str_weak(call_remote_sync), + &be_const_str_solidified, + ( &(const binstruction[42]) { /* code */ + 0xA40E0000, // 0000 IMPORT R3 K0 + 0x58100001, // 0001 LDCONST R4 K1 + 0x4C140000, // 0002 LDNIL R5 + 0x20140405, // 0003 NE R5 R2 R5 + 0x78160005, // 0004 JMPF R5 #000B + 0x00140302, // 0005 ADD R5 R1 K2 + 0x60180008, // 0006 GETGBL R6 G8 + 0x5C1C0400, // 0007 MOVE R7 R2 + 0x7C180200, // 0008 CALL R6 1 + 0x00140A06, // 0009 ADD R5 R5 R6 + 0x5C040A00, // 000A MOVE R1 R5 + 0x24140903, // 000B GT R5 R4 K3 + 0x78160016, // 000C JMPF R5 #0024 + 0x88140104, // 000D GETMBR R5 R0 K4 + 0x8C140B05, // 000E GETMET R5 R5 K5 + 0x5C1C0200, // 000F MOVE R7 R1 + 0x88200106, // 0010 GETMBR R8 R0 K6 + 0x7C140600, // 0011 CALL R5 3 + 0x4C180000, // 0012 LDNIL R6 + 0x20180A06, // 0013 NE R6 R5 R6 + 0x781A0007, // 0014 JMPF R6 #001D + 0x88180104, // 0015 GETMBR R6 R0 K4 + 0x8C180D07, // 0016 GETMET R6 R6 K7 + 0x50200200, // 0017 LDBOOL R8 1 0 + 0x7C180400, // 0018 CALL R6 2 + 0x8C180708, // 0019 GETMET R6 R3 K8 + 0x5C200A00, // 001A MOVE R8 R5 + 0x7C180400, // 001B CALL R6 2 + 0x80040C00, // 001C RET 1 R6 + 0x04100909, // 001D SUB R4 R4 K9 + 0xB81A1400, // 001E GETNGBL R6 K10 + 0x8C180D0B, // 001F GETMET R6 R6 K11 + 0x5820000C, // 0020 LDCONST R8 K12 + 0x5824000D, // 0021 LDCONST R9 K13 + 0x7C180600, // 0022 CALL R6 3 + 0x7001FFE6, // 0023 JMP #000B + 0x88140104, // 0024 GETMBR R5 R0 K4 + 0x8C140B07, // 0025 GETMET R5 R5 K7 + 0x501C0000, // 0026 LDBOOL R7 0 0 + 0x7C140400, // 0027 CALL R5 2 + 0x4C140000, // 0028 LDNIL R5 + 0x80040A00, // 0029 RET 1 R5 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_value_onoff +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_HTTP_web_value_onoff, /* name */ + be_nested_proto( + 3, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(_X3Cb_X3EOn_X3C_X2Fb_X3E), + /* K1 */ be_nested_str_weak(Off), + /* K2 */ be_nested_str_weak(), + }), + be_str_weak(web_value_onoff), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x20080202, // 0001 NE R2 R1 R2 + 0x780A0004, // 0002 JMPF R2 #0008 + 0x78060001, // 0003 JMPF R1 #0006 + 0x58080000, // 0004 LDCONST R2 K0 + 0x70020000, // 0005 JMP #0007 + 0x58080001, // 0006 LDCONST R2 K1 + 0x70020000, // 0007 JMP #0009 + 0x58080002, // 0008 LDCONST R2 K2 + 0x80040400, // 0009 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_http_response +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_HTTP_parse_http_response, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(http_remote), + /* K2 */ be_nested_str_weak(device_is_alive), + /* K3 */ be_nested_str_weak(device), + /* K4 */ be_nested_str_weak(tick), + /* K5 */ be_nested_str_weak(json), + /* K6 */ be_nested_str_weak(load), + /* K7 */ be_nested_str_weak(contains), + /* K8 */ be_nested_str_weak(StatusSNS), + /* K9 */ be_nested_str_weak(StatusSTS), + /* K10 */ be_nested_str_weak(StatusSHT), + /* K11 */ be_nested_str_weak(parse_update), + }), + be_str_weak(parse_http_response), + &be_const_str_solidified, + ( &(const binstruction[39]) { /* code */ + 0x24100300, // 0000 GT R4 R1 K0 + 0x78120023, // 0001 JMPF R4 #0026 + 0x88100101, // 0002 GETMBR R4 R0 K1 + 0x8C100902, // 0003 GETMET R4 R4 K2 + 0x50180200, // 0004 LDBOOL R6 1 0 + 0x7C100400, // 0005 CALL R4 2 + 0x88100103, // 0006 GETMBR R4 R0 K3 + 0x88100904, // 0007 GETMBR R4 R4 K4 + 0xA4160A00, // 0008 IMPORT R5 K5 + 0x8C180B06, // 0009 GETMET R6 R5 K6 + 0x5C200400, // 000A MOVE R8 R2 + 0x7C180400, // 000B CALL R6 2 + 0x4C1C0000, // 000C LDNIL R7 + 0x781A0017, // 000D JMPF R6 #0026 + 0x8C200D07, // 000E GETMET R8 R6 K7 + 0x58280008, // 000F LDCONST R10 K8 + 0x7C200400, // 0010 CALL R8 2 + 0x78220002, // 0011 JMPF R8 #0015 + 0x94180D08, // 0012 GETIDX R6 R6 K8 + 0x541E0007, // 0013 LDINT R7 8 + 0x7002000C, // 0014 JMP #0022 + 0x8C200D07, // 0015 GETMET R8 R6 K7 + 0x58280009, // 0016 LDCONST R10 K9 + 0x7C200400, // 0017 CALL R8 2 + 0x78220002, // 0018 JMPF R8 #001C + 0x94180D09, // 0019 GETIDX R6 R6 K9 + 0x541E000A, // 001A LDINT R7 11 + 0x70020005, // 001B JMP #0022 + 0x8C200D07, // 001C GETMET R8 R6 K7 + 0x5828000A, // 001D LDCONST R10 K10 + 0x7C200400, // 001E CALL R8 2 + 0x78220001, // 001F JMPF R8 #0022 + 0x94180D09, // 0020 GETIDX R6 R6 K9 + 0x541E000C, // 0021 LDINT R7 13 + 0x8C20010B, // 0022 GETMET R8 R0 K11 + 0x5C280C00, // 0023 MOVE R10 R6 + 0x5C2C0E00, // 0024 MOVE R11 R7 + 0x7C200600, // 0025 CALL R8 3 + 0x80000000, // 0026 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_HTTP_web_values, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(web_values_prefix), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(_X26lt_X3B_X2D_X2D_X20_X28), + /* K4 */ be_nested_str_weak(DISPLAY_NAME), + /* K5 */ be_nested_str_weak(_X29_X20_X2D_X2D_X26gt_X3B), + }), + be_str_weak(web_values), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x88100104, // 0004 GETMBR R4 R0 K4 + 0x00120604, // 0005 ADD R4 K3 R4 + 0x00100905, // 0006 ADD R4 R4 K5 + 0x7C080400, // 0007 CALL R2 2 + 0x80000000, // 0008 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: is_local_device +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_HTTP_is_local_device, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(is_local_device), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x50040000, // 0000 LDBOOL R1 0 0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_HTTP_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(ARG_HTTP), + /* K3 */ be_nested_str_weak(http_remote), + /* K4 */ be_nested_str_weak(device), + /* K5 */ be_nested_str_weak(register_http_remote), + /* K6 */ be_nested_str_weak(PROBE_TIMEOUT), + /* K7 */ be_nested_str_weak(register_cmd_cb), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x8C100701, // 0008 GETMET R4 R3 K1 + 0x88180102, // 0009 GETMBR R6 R0 K2 + 0x7C100400, // 000A CALL R4 2 + 0x88140104, // 000B GETMBR R5 R0 K4 + 0x8C140B05, // 000C GETMET R5 R5 K5 + 0x5C1C0800, // 000D MOVE R7 R4 + 0x88200106, // 000E GETMBR R8 R0 K6 + 0x7C140600, // 000F CALL R5 3 + 0x90020605, // 0010 SETMBR R0 K3 R5 + 0x8C140107, // 0011 GETMET R5 R0 K7 + 0x7C140200, // 0012 CALL R5 1 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_update +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_HTTP_parse_update, /* name */ + be_nested_proto( + 3, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(parse_update), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_HTTP_read_attribute, /* name */ + be_nested_proto( + 14, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[21]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(string), + /* K5 */ be_const_int(3), + /* K6 */ be_nested_str_weak(http_remote), + /* K7 */ be_nested_str_weak(get_info), + /* K8 */ be_nested_str_weak(find), + /* K9 */ be_nested_str_weak(name), + /* K10 */ be_nested_str_weak(set), + /* K11 */ be_nested_str_weak(UTF1), + /* K12 */ be_nested_str_weak(NULL), + /* K13 */ be_nested_str_weak(version), + /* K14 */ be_nested_str_weak(_X28), + /* K15 */ be_const_int(0), + /* K16 */ be_const_int(1), + /* K17 */ be_nested_str_weak(mac), + /* K18 */ be_nested_str_weak(BOOL), + /* K19 */ be_nested_str_weak(reachable), + /* K20 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[115]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0038, // 0004 LDINT R7 57 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0061, // 0006 JMPF R7 #0069 + 0xA41E0800, // 0007 IMPORT R7 K4 + 0x1C200D05, // 0008 EQ R8 R6 K5 + 0x78220012, // 0009 JMPF R8 #001D + 0x88200106, // 000A GETMBR R8 R0 K6 + 0x8C201107, // 000B GETMET R8 R8 K7 + 0x7C200200, // 000C CALL R8 1 + 0x8C201108, // 000D GETMET R8 R8 K8 + 0x58280009, // 000E LDCONST R10 K9 + 0x7C200400, // 000F CALL R8 2 + 0x78220005, // 0010 JMPF R8 #0017 + 0x8C24070A, // 0011 GETMET R9 R3 K10 + 0x882C090B, // 0012 GETMBR R11 R4 K11 + 0x5C301000, // 0013 MOVE R12 R8 + 0x7C240600, // 0014 CALL R9 3 + 0x80041200, // 0015 RET 1 R9 + 0x70020004, // 0016 JMP #001C + 0x8C24070A, // 0017 GETMET R9 R3 K10 + 0x882C090C, // 0018 GETMBR R11 R4 K12 + 0x4C300000, // 0019 LDNIL R12 + 0x7C240600, // 001A CALL R9 3 + 0x80041200, // 001B RET 1 R9 + 0x7002004A, // 001C JMP #0068 + 0x54220009, // 001D LDINT R8 10 + 0x1C200C08, // 001E EQ R8 R6 R8 + 0x7822001B, // 001F JMPF R8 #003C + 0x88200106, // 0020 GETMBR R8 R0 K6 + 0x8C201107, // 0021 GETMET R8 R8 K7 + 0x7C200200, // 0022 CALL R8 1 + 0x8C201108, // 0023 GETMET R8 R8 K8 + 0x5828000D, // 0024 LDCONST R10 K13 + 0x7C200400, // 0025 CALL R8 2 + 0x7822000E, // 0026 JMPF R8 #0036 + 0x8C240F08, // 0027 GETMET R9 R7 K8 + 0x5C2C1000, // 0028 MOVE R11 R8 + 0x5830000E, // 0029 LDCONST R12 K14 + 0x7C240600, // 002A CALL R9 3 + 0x2428130F, // 002B GT R10 R9 K15 + 0x782A0002, // 002C JMPF R10 #0030 + 0x04281310, // 002D SUB R10 R9 K16 + 0x402A1E0A, // 002E CONNECT R10 K15 R10 + 0x9420100A, // 002F GETIDX R8 R8 R10 + 0x8C28070A, // 0030 GETMET R10 R3 K10 + 0x8830090B, // 0031 GETMBR R12 R4 K11 + 0x5C341000, // 0032 MOVE R13 R8 + 0x7C280600, // 0033 CALL R10 3 + 0x80041400, // 0034 RET 1 R10 + 0x70020004, // 0035 JMP #003B + 0x8C24070A, // 0036 GETMET R9 R3 K10 + 0x882C090C, // 0037 GETMBR R11 R4 K12 + 0x4C300000, // 0038 LDNIL R12 + 0x7C240600, // 0039 CALL R9 3 + 0x80041200, // 003A RET 1 R9 + 0x7002002B, // 003B JMP #0068 + 0x5422000E, // 003C LDINT R8 15 + 0x1C200C08, // 003D EQ R8 R6 R8 + 0x74220002, // 003E JMPT R8 #0042 + 0x54220011, // 003F LDINT R8 18 + 0x1C200C08, // 0040 EQ R8 R6 R8 + 0x78220012, // 0041 JMPF R8 #0055 + 0x88200106, // 0042 GETMBR R8 R0 K6 + 0x8C201107, // 0043 GETMET R8 R8 K7 + 0x7C200200, // 0044 CALL R8 1 + 0x8C201108, // 0045 GETMET R8 R8 K8 + 0x58280011, // 0046 LDCONST R10 K17 + 0x7C200400, // 0047 CALL R8 2 + 0x78220005, // 0048 JMPF R8 #004F + 0x8C24070A, // 0049 GETMET R9 R3 K10 + 0x882C090B, // 004A GETMBR R11 R4 K11 + 0x5C301000, // 004B MOVE R12 R8 + 0x7C240600, // 004C CALL R9 3 + 0x80041200, // 004D RET 1 R9 + 0x70020004, // 004E JMP #0054 + 0x8C24070A, // 004F GETMET R9 R3 K10 + 0x882C090C, // 0050 GETMBR R11 R4 K12 + 0x4C300000, // 0051 LDNIL R12 + 0x7C240600, // 0052 CALL R9 3 + 0x80041200, // 0053 RET 1 R9 + 0x70020012, // 0054 JMP #0068 + 0x54220010, // 0055 LDINT R8 17 + 0x1C200C08, // 0056 EQ R8 R6 R8 + 0x78220006, // 0057 JMPF R8 #005F + 0x8C20070A, // 0058 GETMET R8 R3 K10 + 0x88280912, // 0059 GETMBR R10 R4 K18 + 0x882C0106, // 005A GETMBR R11 R0 K6 + 0x882C1713, // 005B GETMBR R11 R11 K19 + 0x7C200600, // 005C CALL R8 3 + 0x80041000, // 005D RET 1 R8 + 0x70020008, // 005E JMP #0068 + 0x60200003, // 005F GETGBL R8 G3 + 0x5C240000, // 0060 MOVE R9 R0 + 0x7C200200, // 0061 CALL R8 1 + 0x8C201114, // 0062 GETMET R8 R8 K20 + 0x5C280200, // 0063 MOVE R10 R1 + 0x5C2C0400, // 0064 MOVE R11 R2 + 0x5C300600, // 0065 MOVE R12 R3 + 0x7C200800, // 0066 CALL R8 4 + 0x80041000, // 0067 RET 1 R8 + 0x70020008, // 0068 JMP #0072 + 0x601C0003, // 0069 GETGBL R7 G3 + 0x5C200000, // 006A MOVE R8 R0 + 0x7C1C0200, // 006B CALL R7 1 + 0x8C1C0F14, // 006C GETMET R7 R7 K20 + 0x5C240200, // 006D MOVE R9 R1 + 0x5C280400, // 006E MOVE R10 R2 + 0x5C2C0600, // 006F MOVE R11 R3 + 0x7C1C0800, // 0070 CALL R7 4 + 0x80040E00, // 0071 RET 1 R7 + 0x80000000, // 0072 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values_prefix +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_HTTP_web_values_prefix, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(get_name), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(PREFIX), + /* K4 */ be_nested_str_weak(html_escape), + /* K5 */ be_nested_str_weak(), + }), + be_str_weak(web_values_prefix), + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C0C0302, // 0003 GETMET R3 R1 K2 + 0x60140018, // 0004 GETGBL R5 G24 + 0x88180103, // 0005 GETMBR R6 R0 K3 + 0x780A0003, // 0006 JMPF R2 #000B + 0x8C1C0304, // 0007 GETMET R7 R1 K4 + 0x5C240400, // 0008 MOVE R9 R2 + 0x7C1C0400, // 0009 CALL R7 2 + 0x70020000, // 000A JMP #000C + 0x581C0005, // 000B LDCONST R7 K5 + 0x7C140400, // 000C CALL R5 2 + 0x7C0C0400, // 000D CALL R3 2 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: register_cmd_cb +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_HTTP_register_cmd_cb, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(parse_http_response), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x680C0000, // 0000 GETUPV R3 U0 + 0x8C0C0700, // 0001 GETMET R3 R3 K0 + 0x5C140000, // 0002 MOVE R5 R0 + 0x5C180200, // 0003 MOVE R6 R1 + 0x5C1C0400, // 0004 MOVE R7 R2 + 0x7C0C0800, // 0005 CALL R3 4 + 0x80040600, // 0006 RET 1 R3 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(http_remote), + /* K1 */ be_nested_str_weak(add_schedule), + /* K2 */ be_nested_str_weak(UPDATE_CMD), + /* K3 */ be_nested_str_weak(UPDATE_TIME), + }), + be_str_weak(register_cmd_cb), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x880C0102, // 0002 GETMBR R3 R0 K2 + 0x88100103, // 0003 GETMBR R4 R0 K3 + 0x84140000, // 0004 CLOSURE R5 P0 + 0x7C040800, // 0005 CALL R1 4 + 0xA0000000, // 0006 CLOSE R0 + 0x80000000, // 0007 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_shadow +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_HTTP_update_shadow, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(tick), + /* K1 */ be_nested_str_weak(device), + /* K2 */ be_nested_str_weak(call_remote_sync), + /* K3 */ be_nested_str_weak(UPDATE_CMD), + /* K4 */ be_nested_str_weak(parse_http_response), + /* K5 */ be_const_int(1), + }), + be_str_weak(update_shadow), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x88040101, // 0000 GETMBR R1 R0 K1 + 0x88040300, // 0001 GETMBR R1 R1 K0 + 0x90020001, // 0002 SETMBR R0 K0 R1 + 0x8C040102, // 0003 GETMET R1 R0 K2 + 0x880C0103, // 0004 GETMBR R3 R0 K3 + 0x7C040400, // 0005 CALL R1 2 + 0x78060004, // 0006 JMPF R1 #000C + 0x8C080104, // 0007 GETMET R2 R0 K4 + 0x58100005, // 0008 LDCONST R4 K5 + 0x5C140200, // 0009 MOVE R5 R1 + 0x88180103, // 000A GETMBR R6 R0 K3 + 0x7C080800, // 000B CALL R2 4 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: every_250ms +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_HTTP_every_250ms, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(http_remote), + /* K1 */ be_nested_str_weak(scheduler), + }), + be_str_weak(every_250ms), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80000000, // 0003 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_HTTP +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Device; +be_local_class(Matter_Plugin_Bridge_HTTP, + 1, + &be_class_Matter_Plugin_Device, + be_nested_map(23, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(UPDATE_CMD, -1), be_nested_str_weak(Status_X2011) }, + { be_const_key_weak(every_250ms, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_every_250ms_closure) }, + { be_const_key_weak(ARG, -1), be_nested_str_weak() }, + { be_const_key_weak(call_remote_sync, 22), be_const_closure(Matter_Plugin_Bridge_HTTP_call_remote_sync_closure) }, + { be_const_key_weak(web_value_onoff, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_web_value_onoff_closure) }, + { be_const_key_weak(update_shadow, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_update_shadow_closure) }, + { be_const_key_weak(UPDATE_TIME, -1), be_const_int(3000) }, + { be_const_key_weak(GetOptionReader, 5), be_const_class(be_class_GetOptionReader) }, + { be_const_key_weak(parse_http_response, 21), be_const_closure(Matter_Plugin_Bridge_HTTP_parse_http_response_closure) }, + { be_const_key_weak(parse_update, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_parse_update_closure) }, + { be_const_key_weak(SYNC_TIMEOUT, 18), be_const_int(500) }, + { be_const_key_weak(is_local_device, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_is_local_device_closure) }, + { be_const_key_weak(PREFIX, 17), be_nested_str_weak(_X7C_X20_X3Ci_X3E_X25s_X3C_X2Fi_X3E_X20) }, + { be_const_key_weak(http_remote, 1), be_const_var(0) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_init_closure) }, + { be_const_key_weak(ARG_HTTP, -1), be_nested_str_weak(url) }, + { be_const_key_weak(DISPLAY_NAME, 9), be_nested_str_weak() }, + { be_const_key_weak(web_values_prefix, 19), be_const_closure(Matter_Plugin_Bridge_HTTP_web_values_prefix_closure) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_read_attribute_closure) }, + { be_const_key_weak(PROBE_TIMEOUT, -1), be_const_int(1700) }, + { be_const_key_weak(register_cmd_cb, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_register_cmd_cb_closure) }, + { be_const_key_weak(web_values, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_web_values_closure) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak() }, + })), + be_str_weak(Matter_Plugin_Bridge_HTTP) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_HTTP_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_HTTP); + be_setglobal(vm, "Matter_Plugin_Bridge_HTTP"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Light0.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Light0.h new file mode 100644 index 000000000000..bd25d7a01735 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Light0.h @@ -0,0 +1,511 @@ +/* Solidification of Matter_Plugin_2_Light0.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Light0; + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Light0_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(BOOL), + /* K8 */ be_nested_str_weak(shadow_onoff), + /* K9 */ be_nested_str_weak(U4), + /* K10 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0005, // 0004 LDINT R7 6 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E001B, // 0006 JMPF R7 #0023 + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x1C1C0D05, // 0009 EQ R7 R6 K5 + 0x781E0005, // 000A JMPF R7 #0011 + 0x8C1C0706, // 000B GETMET R7 R3 K6 + 0x88240907, // 000C GETMBR R9 R4 K7 + 0x88280108, // 000D GETMBR R10 R0 K8 + 0x7C1C0600, // 000E CALL R7 3 + 0x80040E00, // 000F RET 1 R7 + 0x70020010, // 0010 JMP #0022 + 0x541EFFFB, // 0011 LDINT R7 65532 + 0x1C1C0C07, // 0012 EQ R7 R6 R7 + 0x781E0005, // 0013 JMPF R7 #001A + 0x8C1C0706, // 0014 GETMET R7 R3 K6 + 0x88240909, // 0015 GETMBR R9 R4 K9 + 0x58280005, // 0016 LDCONST R10 K5 + 0x7C1C0600, // 0017 CALL R7 3 + 0x80040E00, // 0018 RET 1 R7 + 0x70020007, // 0019 JMP #0022 + 0x541EFFFC, // 001A LDINT R7 65533 + 0x1C1C0C07, // 001B EQ R7 R6 R7 + 0x781E0004, // 001C JMPF R7 #0022 + 0x8C1C0706, // 001D GETMET R7 R3 K6 + 0x88240909, // 001E GETMBR R9 R4 K9 + 0x542A0003, // 001F LDINT R10 4 + 0x7C1C0600, // 0020 CALL R7 3 + 0x80040E00, // 0021 RET 1 R7 + 0x70020008, // 0022 JMP #002C + 0x601C0003, // 0023 GETGBL R7 G3 + 0x5C200000, // 0024 MOVE R8 R0 + 0x7C1C0200, // 0025 CALL R7 1 + 0x8C1C0F0A, // 0026 GETMET R7 R7 K10 + 0x5C240200, // 0027 MOVE R9 R1 + 0x5C280400, // 0028 MOVE R10 R2 + 0x5C2C0600, // 0029 MOVE R11 R3 + 0x7C1C0800, // 002A CALL R7 4 + 0x80040E00, // 002B RET 1 R7 + 0x80000000, // 002C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_onoff +********************************************************************/ +be_local_closure(Matter_Plugin_Light0_set_onoff, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(VIRTUAL), + /* K1 */ be_nested_str_weak(light), + /* K2 */ be_nested_str_weak(set), + /* K3 */ be_nested_str_weak(power), + /* K4 */ be_nested_str_weak(update_shadow), + /* K5 */ be_nested_str_weak(shadow_onoff), + /* K6 */ be_nested_str_weak(attribute_updated), + /* K7 */ be_const_int(0), + }), + be_str_weak(set_onoff), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x740A0008, // 0001 JMPT R2 #000B + 0xA40A0200, // 0002 IMPORT R2 K1 + 0x8C0C0502, // 0003 GETMET R3 R2 K2 + 0x60140013, // 0004 GETGBL R5 G19 + 0x7C140000, // 0005 CALL R5 0 + 0x98160601, // 0006 SETIDX R5 K3 R1 + 0x7C0C0400, // 0007 CALL R3 2 + 0x8C0C0104, // 0008 GETMET R3 R0 K4 + 0x7C0C0200, // 0009 CALL R3 1 + 0x70020007, // 000A JMP #0013 + 0x88080105, // 000B GETMBR R2 R0 K5 + 0x20080202, // 000C NE R2 R1 R2 + 0x780A0004, // 000D JMPF R2 #0013 + 0x8C080106, // 000E GETMET R2 R0 K6 + 0x54120005, // 000F LDINT R4 6 + 0x58140007, // 0010 LDCONST R5 K7 + 0x7C080600, // 0011 CALL R2 3 + 0x90020A01, // 0012 SETMBR R0 K5 R1 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_virtual +********************************************************************/ +be_local_closure(Matter_Plugin_Light0_update_virtual, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(find), + /* K1 */ be_nested_str_weak(Power), + /* K2 */ be_nested_str_weak(set_onoff), + /* K3 */ be_nested_str_weak(update_virtual), + }), + be_str_weak(update_virtual), + &be_const_str_solidified, + ( &(const binstruction[18]) { /* code */ + 0x8C080300, // 0000 GETMET R2 R1 K0 + 0x58100001, // 0001 LDCONST R4 K1 + 0x7C080400, // 0002 CALL R2 2 + 0x4C0C0000, // 0003 LDNIL R3 + 0x200C0403, // 0004 NE R3 R2 R3 + 0x780E0004, // 0005 JMPF R3 #000B + 0x8C0C0102, // 0006 GETMET R3 R0 K2 + 0x60140017, // 0007 GETGBL R5 G23 + 0x5C180400, // 0008 MOVE R6 R2 + 0x7C140200, // 0009 CALL R5 1 + 0x7C0C0400, // 000A CALL R3 2 + 0x600C0003, // 000B GETGBL R3 G3 + 0x5C100000, // 000C MOVE R4 R0 + 0x7C0C0200, // 000D CALL R3 1 + 0x8C0C0703, // 000E GETMET R3 R3 K3 + 0x5C140200, // 000F MOVE R5 R1 + 0x7C0C0400, // 0010 CALL R3 2 + 0x80000000, // 0011 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_Light0_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(shadow_onoff), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[11]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x50100000, // 0008 LDBOOL R4 0 0 + 0x90020204, // 0009 SETMBR R0 K1 R4 + 0x80000000, // 000A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_shadow +********************************************************************/ +be_local_closure(Matter_Plugin_Light0_update_shadow, /* name */ + be_nested_proto( + 8, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(VIRTUAL), + /* K1 */ be_nested_str_weak(light), + /* K2 */ be_nested_str_weak(get), + /* K3 */ be_nested_str_weak(find), + /* K4 */ be_nested_str_weak(power), + /* K5 */ be_nested_str_weak(shadow_onoff), + /* K6 */ be_nested_str_weak(attribute_updated), + /* K7 */ be_const_int(0), + /* K8 */ be_nested_str_weak(update_shadow), + }), + be_str_weak(update_shadow), + &be_const_str_solidified, + ( &(const binstruction[26]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x74060011, // 0001 JMPT R1 #0014 + 0xA4060200, // 0002 IMPORT R1 K1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x7C080200, // 0004 CALL R2 1 + 0x4C0C0000, // 0005 LDNIL R3 + 0x200C0403, // 0006 NE R3 R2 R3 + 0x780E000B, // 0007 JMPF R3 #0014 + 0x8C0C0503, // 0008 GETMET R3 R2 K3 + 0x58140004, // 0009 LDCONST R5 K4 + 0x4C180000, // 000A LDNIL R6 + 0x7C0C0600, // 000B CALL R3 3 + 0x88100105, // 000C GETMBR R4 R0 K5 + 0x20100604, // 000D NE R4 R3 R4 + 0x78120004, // 000E JMPF R4 #0014 + 0x8C100106, // 000F GETMET R4 R0 K6 + 0x541A0005, // 0010 LDINT R6 6 + 0x581C0007, // 0011 LDCONST R7 K7 + 0x7C100600, // 0012 CALL R4 3 + 0x90020A03, // 0013 SETMBR R0 K5 R3 + 0x60040003, // 0014 GETGBL R1 G3 + 0x5C080000, // 0015 MOVE R2 R0 + 0x7C040200, // 0016 CALL R1 1 + 0x8C040308, // 0017 GETMET R1 R1 K8 + 0x7C040200, // 0018 CALL R1 1 + 0x80000000, // 0019 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: invoke_request +********************************************************************/ +be_local_closure(Matter_Plugin_Light0_invoke_request, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(light), + /* K1 */ be_nested_str_weak(matter), + /* K2 */ be_nested_str_weak(TLV), + /* K3 */ be_nested_str_weak(cluster), + /* K4 */ be_nested_str_weak(command), + /* K5 */ be_nested_str_weak(update_shadow_lazy), + /* K6 */ be_const_int(0), + /* K7 */ be_nested_str_weak(set_onoff), + /* K8 */ be_nested_str_weak(publish_command), + /* K9 */ be_nested_str_weak(Power), + /* K10 */ be_const_int(1), + /* K11 */ be_const_int(2), + /* K12 */ be_nested_str_weak(shadow_onoff), + }), + be_str_weak(invoke_request), + &be_const_str_solidified, + ( &(const binstruction[53]) { /* code */ + 0xA4120000, // 0000 IMPORT R4 K0 + 0xB8160200, // 0001 GETNGBL R5 K1 + 0x88140B02, // 0002 GETMBR R5 R5 K2 + 0x88180703, // 0003 GETMBR R6 R3 K3 + 0x881C0704, // 0004 GETMBR R7 R3 K4 + 0x54220005, // 0005 LDINT R8 6 + 0x1C200C08, // 0006 EQ R8 R6 R8 + 0x7822002B, // 0007 JMPF R8 #0034 + 0x8C200105, // 0008 GETMET R8 R0 K5 + 0x7C200200, // 0009 CALL R8 1 + 0x1C200F06, // 000A EQ R8 R7 K6 + 0x78220009, // 000B JMPF R8 #0016 + 0x8C200107, // 000C GETMET R8 R0 K7 + 0x50280000, // 000D LDBOOL R10 0 0 + 0x7C200400, // 000E CALL R8 2 + 0x8C200108, // 000F GETMET R8 R0 K8 + 0x58280009, // 0010 LDCONST R10 K9 + 0x582C0006, // 0011 LDCONST R11 K6 + 0x7C200600, // 0012 CALL R8 3 + 0x50200200, // 0013 LDBOOL R8 1 0 + 0x80041000, // 0014 RET 1 R8 + 0x7002001D, // 0015 JMP #0034 + 0x1C200F0A, // 0016 EQ R8 R7 K10 + 0x78220009, // 0017 JMPF R8 #0022 + 0x8C200107, // 0018 GETMET R8 R0 K7 + 0x50280200, // 0019 LDBOOL R10 1 0 + 0x7C200400, // 001A CALL R8 2 + 0x8C200108, // 001B GETMET R8 R0 K8 + 0x58280009, // 001C LDCONST R10 K9 + 0x582C000A, // 001D LDCONST R11 K10 + 0x7C200600, // 001E CALL R8 3 + 0x50200200, // 001F LDBOOL R8 1 0 + 0x80041000, // 0020 RET 1 R8 + 0x70020011, // 0021 JMP #0034 + 0x1C200F0B, // 0022 EQ R8 R7 K11 + 0x7822000F, // 0023 JMPF R8 #0034 + 0x8C200107, // 0024 GETMET R8 R0 K7 + 0x8828010C, // 0025 GETMBR R10 R0 K12 + 0x782A0000, // 0026 JMPF R10 #0028 + 0x50280001, // 0027 LDBOOL R10 0 1 + 0x50280200, // 0028 LDBOOL R10 1 0 + 0x7C200400, // 0029 CALL R8 2 + 0x8C200108, // 002A GETMET R8 R0 K8 + 0x58280009, // 002B LDCONST R10 K9 + 0x882C010C, // 002C GETMBR R11 R0 K12 + 0x782E0001, // 002D JMPF R11 #0030 + 0x582C000A, // 002E LDCONST R11 K10 + 0x70020000, // 002F JMP #0031 + 0x582C0006, // 0030 LDCONST R11 K6 + 0x7C200600, // 0031 CALL R8 3 + 0x50200200, // 0032 LDBOOL R8 1 0 + 0x80041000, // 0033 RET 1 R8 + 0x80000000, // 0034 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: find_val_i +********************************************************************/ +be_local_closure(Matter_Plugin_Light0_find_val_i, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 4, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_const_class(be_class_Matter_Plugin_Light0), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(find_key_i), + /* K3 */ be_nested_str_weak(find), + }), + be_str_weak(find_val_i), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x58080000, // 0000 LDCONST R2 K0 + 0xB80E0200, // 0001 GETNGBL R3 K1 + 0x8C0C0702, // 0002 GETMET R3 R3 K2 + 0x5C140000, // 0003 MOVE R5 R0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x7C0C0600, // 0005 CALL R3 3 + 0x8C100103, // 0006 GETMET R4 R0 K3 + 0x5C180600, // 0007 MOVE R6 R3 + 0x7C100400, // 0008 CALL R4 2 + 0x80040800, // 0009 RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Light0 +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Device; +be_local_class(Matter_Plugin_Light0, + 1, + &be_class_Matter_Plugin_Device, + be_nested_map(14, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(read_attribute, 9), be_const_closure(Matter_Plugin_Light0_read_attribute_closure) }, + { be_const_key_weak(UPDATE_TIME, 4), be_const_int(250) }, + { be_const_key_weak(update_virtual, 1), be_const_closure(Matter_Plugin_Light0_update_virtual_closure) }, + { be_const_key_weak(UPDATE_COMMANDS, 13), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(1, + ( (struct bvalue*) &(const bvalue[]) { + be_nested_str_weak(Power), + })) ) } )) }, + { be_const_key_weak(find_val_i, -1), be_const_static_closure(Matter_Plugin_Light0_find_val_i_closure) }, + { be_const_key_weak(init, 11), be_const_closure(Matter_Plugin_Light0_init_closure) }, + { be_const_key_weak(set_onoff, 12), be_const_closure(Matter_Plugin_Light0_set_onoff_closure) }, + { be_const_key_weak(update_shadow, 8), be_const_closure(Matter_Plugin_Light0_update_shadow_closure) }, + { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Light0_invoke_request_closure) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(256, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Light_X200_X20On) }, + { be_const_key_weak(shadow_onoff, -1), be_const_var(0) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(light0) }, + })), + be_str_weak(Matter_Plugin_Light0) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Light0_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Light0); + be_setglobal(vm, "Matter_Plugin_Light0"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_OnOff.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_OnOff.h new file mode 100644 index 000000000000..b003d1004d6d --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_OnOff.h @@ -0,0 +1,546 @@ +/* Solidification of Matter_Plugin_2_OnOff.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_OnOff; + +/******************************************************************** +** Solidified function: set_onoff +********************************************************************/ +be_local_closure(Matter_Plugin_OnOff_set_onoff, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(VIRTUAL), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(set_power), + /* K3 */ be_nested_str_weak(tasmota_relay_index), + /* K4 */ be_const_int(1), + /* K5 */ be_nested_str_weak(update_shadow), + /* K6 */ be_nested_str_weak(shadow_onoff), + /* K7 */ be_nested_str_weak(attribute_updated), + /* K8 */ be_const_int(0), + }), + be_str_weak(set_onoff), + &be_const_str_solidified, + ( &(const binstruction[22]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x740A000A, // 0001 JMPT R2 #000D + 0xB80A0200, // 0002 GETNGBL R2 K1 + 0x8C080502, // 0003 GETMET R2 R2 K2 + 0x88100103, // 0004 GETMBR R4 R0 K3 + 0x04100904, // 0005 SUB R4 R4 K4 + 0x60140017, // 0006 GETGBL R5 G23 + 0x5C180200, // 0007 MOVE R6 R1 + 0x7C140200, // 0008 CALL R5 1 + 0x7C080600, // 0009 CALL R2 3 + 0x8C080105, // 000A GETMET R2 R0 K5 + 0x7C080200, // 000B CALL R2 1 + 0x70020007, // 000C JMP #0015 + 0x88080106, // 000D GETMBR R2 R0 K6 + 0x20080202, // 000E NE R2 R1 R2 + 0x780A0004, // 000F JMPF R2 #0015 + 0x8C080107, // 0010 GETMET R2 R0 K7 + 0x54120005, // 0011 LDINT R4 6 + 0x58140008, // 0012 LDCONST R5 K8 + 0x7C080600, // 0013 CALL R2 3 + 0x90020C01, // 0014 SETMBR R0 K6 R1 + 0x80000000, // 0015 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_configuration +********************************************************************/ +be_local_closure(Matter_Plugin_OnOff_parse_configuration, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota_relay_index), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(ARG), + /* K3 */ be_const_int(1), + /* K4 */ be_const_int(0), + }), + be_str_weak(parse_configuration), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x60080009, // 0000 GETGBL R2 G9 + 0x8C0C0301, // 0001 GETMET R3 R1 K1 + 0x88140102, // 0002 GETMBR R5 R0 K2 + 0x58180003, // 0003 LDCONST R6 K3 + 0x7C0C0600, // 0004 CALL R3 3 + 0x7C080200, // 0005 CALL R2 1 + 0x90020002, // 0006 SETMBR R0 K0 R2 + 0x88080100, // 0007 GETMBR R2 R0 K0 + 0x18080504, // 0008 LE R2 R2 K4 + 0x780A0000, // 0009 JMPF R2 #000B + 0x90020103, // 000A SETMBR R0 K0 K3 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_shadow +********************************************************************/ +be_local_closure(Matter_Plugin_OnOff_update_shadow, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(VIRTUAL), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(get_power), + /* K3 */ be_nested_str_weak(tasmota_relay_index), + /* K4 */ be_const_int(1), + /* K5 */ be_nested_str_weak(shadow_onoff), + /* K6 */ be_nested_str_weak(attribute_updated), + /* K7 */ be_const_int(0), + /* K8 */ be_nested_str_weak(update_shadow), + }), + be_str_weak(update_shadow), + &be_const_str_solidified, + ( &(const binstruction[27]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x74060012, // 0001 JMPT R1 #0015 + 0xB8060200, // 0002 GETNGBL R1 K1 + 0x8C040302, // 0003 GETMET R1 R1 K2 + 0x880C0103, // 0004 GETMBR R3 R0 K3 + 0x040C0704, // 0005 SUB R3 R3 K4 + 0x7C040400, // 0006 CALL R1 2 + 0x4C080000, // 0007 LDNIL R2 + 0x20080202, // 0008 NE R2 R1 R2 + 0x780A000A, // 0009 JMPF R2 #0015 + 0x88080105, // 000A GETMBR R2 R0 K5 + 0x600C0017, // 000B GETGBL R3 G23 + 0x5C100200, // 000C MOVE R4 R1 + 0x7C0C0200, // 000D CALL R3 1 + 0x20080403, // 000E NE R2 R2 R3 + 0x780A0003, // 000F JMPF R2 #0014 + 0x8C080106, // 0010 GETMET R2 R0 K6 + 0x54120005, // 0011 LDINT R4 6 + 0x58140007, // 0012 LDCONST R5 K7 + 0x7C080600, // 0013 CALL R2 3 + 0x90020A01, // 0014 SETMBR R0 K5 R1 + 0x60040003, // 0015 GETGBL R1 G3 + 0x5C080000, // 0016 MOVE R2 R0 + 0x7C040200, // 0017 CALL R1 1 + 0x8C040308, // 0018 GETMET R1 R1 K8 + 0x7C040200, // 0019 CALL R1 1 + 0x80000000, // 001A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: invoke_request +********************************************************************/ +be_local_closure(Matter_Plugin_OnOff_invoke_request, /* name */ + be_nested_proto( + 11, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(command), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(set_onoff), + /* K7 */ be_nested_str_weak(publish_command), + /* K8 */ be_nested_str_weak(Power), + /* K9 */ be_const_int(1), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str_weak(shadow_onoff), + }), + be_str_weak(invoke_request), + &be_const_str_solidified, + ( &(const binstruction[52]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140702, // 0002 GETMBR R5 R3 K2 + 0x88180703, // 0003 GETMBR R6 R3 K3 + 0x541E0005, // 0004 LDINT R7 6 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E002B, // 0006 JMPF R7 #0033 + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x1C1C0D05, // 0009 EQ R7 R6 K5 + 0x781E0009, // 000A JMPF R7 #0015 + 0x8C1C0106, // 000B GETMET R7 R0 K6 + 0x50240000, // 000C LDBOOL R9 0 0 + 0x7C1C0400, // 000D CALL R7 2 + 0x8C1C0107, // 000E GETMET R7 R0 K7 + 0x58240008, // 000F LDCONST R9 K8 + 0x58280005, // 0010 LDCONST R10 K5 + 0x7C1C0600, // 0011 CALL R7 3 + 0x501C0200, // 0012 LDBOOL R7 1 0 + 0x80040E00, // 0013 RET 1 R7 + 0x7002001D, // 0014 JMP #0033 + 0x1C1C0D09, // 0015 EQ R7 R6 K9 + 0x781E0009, // 0016 JMPF R7 #0021 + 0x8C1C0106, // 0017 GETMET R7 R0 K6 + 0x50240200, // 0018 LDBOOL R9 1 0 + 0x7C1C0400, // 0019 CALL R7 2 + 0x8C1C0107, // 001A GETMET R7 R0 K7 + 0x58240008, // 001B LDCONST R9 K8 + 0x58280009, // 001C LDCONST R10 K9 + 0x7C1C0600, // 001D CALL R7 3 + 0x501C0200, // 001E LDBOOL R7 1 0 + 0x80040E00, // 001F RET 1 R7 + 0x70020011, // 0020 JMP #0033 + 0x1C1C0D0A, // 0021 EQ R7 R6 K10 + 0x781E000F, // 0022 JMPF R7 #0033 + 0x8C1C0106, // 0023 GETMET R7 R0 K6 + 0x8824010B, // 0024 GETMBR R9 R0 K11 + 0x78260000, // 0025 JMPF R9 #0027 + 0x50240001, // 0026 LDBOOL R9 0 1 + 0x50240200, // 0027 LDBOOL R9 1 0 + 0x7C1C0400, // 0028 CALL R7 2 + 0x8C1C0107, // 0029 GETMET R7 R0 K7 + 0x58240008, // 002A LDCONST R9 K8 + 0x8828010B, // 002B GETMBR R10 R0 K11 + 0x782A0001, // 002C JMPF R10 #002F + 0x58280009, // 002D LDCONST R10 K9 + 0x70020000, // 002E JMP #0030 + 0x58280005, // 002F LDCONST R10 K5 + 0x7C1C0600, // 0030 CALL R7 3 + 0x501C0200, // 0031 LDBOOL R7 1 0 + 0x80040E00, // 0032 RET 1 R7 + 0x80000000, // 0033 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_virtual +********************************************************************/ +be_local_closure(Matter_Plugin_OnOff_update_virtual, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(find), + /* K1 */ be_nested_str_weak(Power), + /* K2 */ be_nested_str_weak(set_onoff), + /* K3 */ be_nested_str_weak(update_virtual), + }), + be_str_weak(update_virtual), + &be_const_str_solidified, + ( &(const binstruction[18]) { /* code */ + 0x8C080300, // 0000 GETMET R2 R1 K0 + 0x58100001, // 0001 LDCONST R4 K1 + 0x7C080400, // 0002 CALL R2 2 + 0x4C0C0000, // 0003 LDNIL R3 + 0x200C0403, // 0004 NE R3 R2 R3 + 0x780E0004, // 0005 JMPF R3 #000B + 0x8C0C0102, // 0006 GETMET R3 R0 K2 + 0x60140017, // 0007 GETGBL R5 G23 + 0x5C180400, // 0008 MOVE R6 R2 + 0x7C140200, // 0009 CALL R5 1 + 0x7C0C0400, // 000A CALL R3 2 + 0x600C0003, // 000B GETGBL R3 G3 + 0x5C100000, // 000C MOVE R4 R0 + 0x7C0C0200, // 000D CALL R3 1 + 0x8C0C0703, // 000E GETMET R3 R3 K3 + 0x5C140200, // 000F MOVE R5 R1 + 0x7C0C0400, // 0010 CALL R3 2 + 0x80000000, // 0011 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_OnOff_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(shadow_onoff), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[11]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x50100000, // 0008 LDBOOL R4 0 0 + 0x90020204, // 0009 SETMBR R0 K1 R4 + 0x80000000, // 000A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: +********************************************************************/ +be_local_closure(Matter_Plugin_OnOff__X3Clambda_X3E, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x60040009, // 0000 GETGBL R1 G9 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_OnOff_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(BOOL), + /* K8 */ be_nested_str_weak(shadow_onoff), + /* K9 */ be_nested_str_weak(U4), + /* K10 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0005, // 0004 LDINT R7 6 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E001B, // 0006 JMPF R7 #0023 + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x1C1C0D05, // 0009 EQ R7 R6 K5 + 0x781E0005, // 000A JMPF R7 #0011 + 0x8C1C0706, // 000B GETMET R7 R3 K6 + 0x88240907, // 000C GETMBR R9 R4 K7 + 0x88280108, // 000D GETMBR R10 R0 K8 + 0x7C1C0600, // 000E CALL R7 3 + 0x80040E00, // 000F RET 1 R7 + 0x70020010, // 0010 JMP #0022 + 0x541EFFFB, // 0011 LDINT R7 65532 + 0x1C1C0C07, // 0012 EQ R7 R6 R7 + 0x781E0005, // 0013 JMPF R7 #001A + 0x8C1C0706, // 0014 GETMET R7 R3 K6 + 0x88240909, // 0015 GETMBR R9 R4 K9 + 0x58280005, // 0016 LDCONST R10 K5 + 0x7C1C0600, // 0017 CALL R7 3 + 0x80040E00, // 0018 RET 1 R7 + 0x70020007, // 0019 JMP #0022 + 0x541EFFFC, // 001A LDINT R7 65533 + 0x1C1C0C07, // 001B EQ R7 R6 R7 + 0x781E0004, // 001C JMPF R7 #0022 + 0x8C1C0706, // 001D GETMET R7 R3 K6 + 0x88240909, // 001E GETMBR R9 R4 K9 + 0x542A0003, // 001F LDINT R10 4 + 0x7C1C0600, // 0020 CALL R7 3 + 0x80040E00, // 0021 RET 1 R7 + 0x70020008, // 0022 JMP #002C + 0x601C0003, // 0023 GETGBL R7 G3 + 0x5C200000, // 0024 MOVE R8 R0 + 0x7C1C0200, // 0025 CALL R7 1 + 0x8C1C0F0A, // 0026 GETMET R7 R7 K10 + 0x5C240200, // 0027 MOVE R9 R1 + 0x5C280400, // 0028 MOVE R10 R2 + 0x5C2C0600, // 0029 MOVE R11 R3 + 0x7C1C0800, // 002A CALL R7 4 + 0x80040E00, // 002B RET 1 R7 + 0x80000000, // 002C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_OnOff +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Device; +be_local_class(Matter_Plugin_OnOff, + 1, + &be_class_Matter_Plugin_Device, + be_nested_map(17, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(update_virtual, -1), be_const_closure(Matter_Plugin_OnOff_update_virtual_closure) }, + { be_const_key_weak(UPDATE_COMMANDS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(1, + ( (struct bvalue*) &(const bvalue[]) { + be_nested_str_weak(Power), + })) ) } )) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(Relay_X3Cx_X3E_X20number) }, + { be_const_key_weak(set_onoff, -1), be_const_closure(Matter_Plugin_OnOff_set_onoff_closure) }, + { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(266, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(parse_configuration, -1), be_const_closure(Matter_Plugin_OnOff_parse_configuration_closure) }, + { be_const_key_weak(update_shadow, -1), be_const_closure(Matter_Plugin_OnOff_update_shadow_closure) }, + { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_OnOff_invoke_request_closure) }, + { be_const_key_weak(ARG, 0), be_nested_str_weak(relay) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Relay) }, + { be_const_key_weak(UPDATE_TIME, 12), be_const_int(250) }, + { be_const_key_weak(read_attribute, 13), be_const_closure(Matter_Plugin_OnOff_read_attribute_closure) }, + { be_const_key_weak(ARG_TYPE, 10), be_const_static_closure(Matter_Plugin_OnOff__X3Clambda_X3E_closure) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(relay) }, + { be_const_key_weak(init, 1), be_const_closure(Matter_Plugin_OnOff_init_closure) }, + { be_const_key_weak(tasmota_relay_index, -1), be_const_var(0) }, + })), + be_str_weak(Matter_Plugin_OnOff) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_OnOff_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_OnOff); + be_setglobal(vm, "Matter_Plugin_OnOff"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Sensor.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Sensor.h new file mode 100644 index 000000000000..adb3bf9c8d32 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Sensor.h @@ -0,0 +1,282 @@ +/* Solidification of Matter_Plugin_2_Sensor.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Sensor; + +/******************************************************************** +** Solidified function: update_virtual +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_update_virtual, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(find), + /* K1 */ be_nested_str_weak(JSON_NAME), + /* K2 */ be_nested_str_weak(bool), + /* K3 */ be_nested_str_weak(shadow_value), + /* K4 */ be_nested_str_weak(value_changed), + /* K5 */ be_nested_str_weak(update_virtual), + }), + be_str_weak(update_virtual), + &be_const_str_solidified, + ( &(const binstruction[28]) { /* code */ + 0x8C080300, // 0000 GETMET R2 R1 K0 + 0x88100101, // 0001 GETMBR R4 R0 K1 + 0x7C080400, // 0002 CALL R2 2 + 0x4C0C0000, // 0003 LDNIL R3 + 0x200C0403, // 0004 NE R3 R2 R3 + 0x780E000E, // 0005 JMPF R3 #0015 + 0x600C0004, // 0006 GETGBL R3 G4 + 0x5C100400, // 0007 MOVE R4 R2 + 0x7C0C0200, // 0008 CALL R3 1 + 0x1C0C0702, // 0009 EQ R3 R3 K2 + 0x780E0003, // 000A JMPF R3 #000F + 0x600C0009, // 000B GETGBL R3 G9 + 0x5C100400, // 000C MOVE R4 R2 + 0x7C0C0200, // 000D CALL R3 1 + 0x5C080600, // 000E MOVE R2 R3 + 0x880C0103, // 000F GETMBR R3 R0 K3 + 0x200C0602, // 0010 NE R3 R3 R2 + 0x780E0002, // 0011 JMPF R3 #0015 + 0x8C0C0104, // 0012 GETMET R3 R0 K4 + 0x7C0C0200, // 0013 CALL R3 1 + 0x90020602, // 0014 SETMBR R0 K3 R2 + 0x600C0003, // 0015 GETGBL R3 G3 + 0x5C100000, // 0016 MOVE R4 R0 + 0x7C0C0200, // 0017 CALL R3 1 + 0x8C0C0705, // 0018 GETMET R3 R3 K5 + 0x5C140200, // 0019 MOVE R5 R1 + 0x7C0C0400, // 001A CALL R3 2 + 0x80000000, // 001B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_sensors +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_parse_sensors, /* name */ + be_nested_proto( + 8, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota_sensor_matcher), + /* K1 */ be_nested_str_weak(pre_value), + /* K2 */ be_nested_str_weak(match), + /* K3 */ be_nested_str_weak(shadow_value), + /* K4 */ be_nested_str_weak(value_changed), + }), + be_str_weak(parse_sensors), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A0010, // 0001 JMPF R2 #0013 + 0x8C080101, // 0002 GETMET R2 R0 K1 + 0x6010000A, // 0003 GETGBL R4 G10 + 0x88140100, // 0004 GETMBR R5 R0 K0 + 0x8C140B02, // 0005 GETMET R5 R5 K2 + 0x5C1C0200, // 0006 MOVE R7 R1 + 0x7C140400, // 0007 CALL R5 2 + 0x7C100200, // 0008 CALL R4 1 + 0x7C080400, // 0009 CALL R2 2 + 0x4C0C0000, // 000A LDNIL R3 + 0x200C0403, // 000B NE R3 R2 R3 + 0x780E0005, // 000C JMPF R3 #0013 + 0x880C0103, // 000D GETMBR R3 R0 K3 + 0x200C0403, // 000E NE R3 R2 R3 + 0x780E0002, // 000F JMPF R3 #0013 + 0x8C0C0104, // 0010 GETMET R3 R0 K4 + 0x7C0C0200, // 0011 CALL R3 1 + 0x90020602, // 0012 SETMBR R0 K3 R2 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_configuration +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_parse_configuration, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota_sensor_filter), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(ARG), + /* K3 */ be_nested_str_weak(tasmota_sensor_matcher), + /* K4 */ be_nested_str_weak(tasmota), + /* K5 */ be_nested_str_weak(Rule_Matcher), + /* K6 */ be_nested_str_weak(parse), + }), + be_str_weak(parse_configuration), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x8C080301, // 0000 GETMET R2 R1 K1 + 0x88100102, // 0001 GETMBR R4 R0 K2 + 0x7C080400, // 0002 CALL R2 2 + 0x90020002, // 0003 SETMBR R0 K0 R2 + 0x88080100, // 0004 GETMBR R2 R0 K0 + 0x780A0005, // 0005 JMPF R2 #000C + 0xB80A0800, // 0006 GETNGBL R2 K4 + 0x88080505, // 0007 GETMBR R2 R2 K5 + 0x8C080506, // 0008 GETMET R2 R2 K6 + 0x88100100, // 0009 GETMBR R4 R0 K0 + 0x7C080400, // 000A CALL R2 2 + 0x90020602, // 000B SETMBR R0 K3 R2 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pre_value +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_pre_value, /* name */ + be_nested_proto( + 2, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(pre_value), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80040200, // 0000 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: append_state_json +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_append_state_json, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(shadow_value), + /* K1 */ be_nested_str_weak(null), + /* K2 */ be_nested_str_weak(_X2C_X22_X25s_X22_X3A_X25s), + /* K3 */ be_nested_str_weak(JSON_NAME), + }), + be_str_weak(append_state_json), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x20040202, // 0002 NE R1 R1 R2 + 0x78060001, // 0003 JMPF R1 #0006 + 0x88040100, // 0004 GETMBR R1 R0 K0 + 0x70020000, // 0005 JMP #0007 + 0x58040001, // 0006 LDCONST R1 K1 + 0x60080018, // 0007 GETGBL R2 G24 + 0x580C0002, // 0008 LDCONST R3 K2 + 0x88100103, // 0009 GETMBR R4 R0 K3 + 0x5C140200, // 000A MOVE R5 R1 + 0x7C080600, // 000B CALL R2 3 + 0x80040400, // 000C RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: value_changed +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_value_changed, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(value_changed), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Sensor +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Device; +be_local_class(Matter_Plugin_Sensor, + 3, + &be_class_Matter_Plugin_Device, + be_nested_map(13, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(ARG, 1), be_nested_str_weak(filter) }, + { be_const_key_weak(value_changed, -1), be_const_closure(Matter_Plugin_Sensor_value_changed_closure) }, + { be_const_key_weak(update_virtual, -1), be_const_closure(Matter_Plugin_Sensor_update_virtual_closure) }, + { be_const_key_weak(ARG_HINT, 8), be_nested_str_weak(Filter_X20pattern) }, + { be_const_key_weak(tasmota_sensor_matcher, -1), be_const_var(1) }, + { be_const_key_weak(parse_sensors, -1), be_const_closure(Matter_Plugin_Sensor_parse_sensors_closure) }, + { be_const_key_weak(JSON_NAME, -1), be_nested_str_weak() }, + { be_const_key_weak(parse_configuration, -1), be_const_closure(Matter_Plugin_Sensor_parse_configuration_closure) }, + { be_const_key_weak(pre_value, 12), be_const_closure(Matter_Plugin_Sensor_pre_value_closure) }, + { be_const_key_weak(append_state_json, -1), be_const_closure(Matter_Plugin_Sensor_append_state_json_closure) }, + { be_const_key_weak(shadow_value, 9), be_const_var(2) }, + { be_const_key_weak(UPDATE_TIME, -1), be_const_int(5000) }, + { be_const_key_weak(tasmota_sensor_filter, -1), be_const_var(0) }, + })), + be_str_weak(Matter_Plugin_Sensor) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Sensor_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor); + be_setglobal(vm, "Matter_Plugin_Sensor"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Shutter.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Shutter.h similarity index 54% rename from lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Shutter.h rename to lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Shutter.h index 2fd38c7dadfc..30f6d83489fe 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Shutter.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_2_Shutter.h @@ -1,4 +1,4 @@ -/* Solidification of Matter_Plugin_Shutter.h */ +/* Solidification of Matter_Plugin_2_Shutter.h */ /********************************************************************\ * Generated code, don't edit * \********************************************************************/ @@ -7,88 +7,40 @@ extern const bclass be_class_Matter_Plugin_Shutter; /******************************************************************** -** Solidified function: update_inverted +** Solidified function: parse_configuration ********************************************************************/ -be_local_closure(Matter_Plugin_Shutter_update_inverted, /* name */ +be_local_closure(Matter_Plugin_Shutter_parse_configuration, /* name */ be_nested_proto( - 7, /* nstack */ - 1, /* argc */ + 5, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[14]) { /* constants */ - /* K0 */ be_nested_str_weak(shadow_shutter_inverted), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(cmd), - /* K3 */ be_nested_str_weak(Status_X2013), - /* K4 */ be_nested_str_weak(contains), - /* K5 */ be_nested_str_weak(StatusSHT), - /* K6 */ be_nested_str_weak(find), - /* K7 */ be_nested_str_weak(SHT), - /* K8 */ be_nested_str_weak(tasmota_shutter_index), - /* K9 */ be_nested_str_weak(Opt), - /* K10 */ be_nested_str_weak(log), - /* K11 */ be_nested_str_weak(MTR_X3A_X20opt_X3A_X20), - /* K12 */ be_const_int(1), - /* K13 */ be_nested_str_weak(MTR_X3A_X20Inverted_X20flag_X3A_X20), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota_shutter_index), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(ARG), + /* K3 */ be_const_int(0), + /* K4 */ be_nested_str_weak(shadow_shutter_inverted), }), - be_str_weak(update_inverted), + be_str_weak(parse_configuration), &be_const_str_solidified, - ( &(const binstruction[51]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x5409FFFE, // 0001 LDINT R2 -1 - 0x1C040202, // 0002 EQ R1 R1 R2 - 0x7806002D, // 0003 JMPF R1 #0032 - 0xB8060200, // 0004 GETNGBL R1 K1 - 0x8C040302, // 0005 GETMET R1 R1 K2 - 0x580C0003, // 0006 LDCONST R3 K3 - 0x50100200, // 0007 LDBOOL R4 1 0 - 0x7C040600, // 0008 CALL R1 3 - 0x8C080304, // 0009 GETMET R2 R1 K4 - 0x58100005, // 000A LDCONST R4 K5 - 0x7C080400, // 000B CALL R2 2 - 0x780A0024, // 000C JMPF R2 #0032 - 0x94040305, // 000D GETIDX R1 R1 K5 - 0x8C080306, // 000E GETMET R2 R1 K6 - 0x60100008, // 000F GETGBL R4 G8 - 0x88140108, // 0010 GETMBR R5 R0 K8 - 0x7C100200, // 0011 CALL R4 1 - 0x00120E04, // 0012 ADD R4 K7 R4 - 0x60140013, // 0013 GETGBL R5 G19 - 0x7C140000, // 0014 CALL R5 0 - 0x7C080600, // 0015 CALL R2 3 - 0x8C080506, // 0016 GETMET R2 R2 K6 - 0x58100009, // 0017 LDCONST R4 K9 - 0x7C080400, // 0018 CALL R2 2 - 0xB80E0200, // 0019 GETNGBL R3 K1 - 0x8C0C070A, // 001A GETMET R3 R3 K10 - 0x60140008, // 001B GETGBL R5 G8 - 0x5C180400, // 001C MOVE R6 R2 - 0x7C140200, // 001D CALL R5 1 - 0x00161605, // 001E ADD R5 K11 R5 - 0x7C0C0400, // 001F CALL R3 2 - 0x4C0C0000, // 0020 LDNIL R3 - 0x200C0403, // 0021 NE R3 R2 R3 - 0x780E000E, // 0022 JMPF R3 #0032 - 0x600C0009, // 0023 GETGBL R3 G9 - 0x6010000C, // 0024 GETGBL R4 G12 - 0x5C140400, // 0025 MOVE R5 R2 - 0x7C100200, // 0026 CALL R4 1 - 0x0410090C, // 0027 SUB R4 R4 K12 - 0x94100404, // 0028 GETIDX R4 R2 R4 - 0x7C0C0200, // 0029 CALL R3 1 - 0x90020003, // 002A SETMBR R0 K0 R3 - 0xB80E0200, // 002B GETNGBL R3 K1 - 0x8C0C070A, // 002C GETMET R3 R3 K10 - 0x60140008, // 002D GETGBL R5 G8 - 0x88180100, // 002E GETMBR R6 R0 K0 - 0x7C140200, // 002F CALL R5 1 - 0x00161A05, // 0030 ADD R5 K13 R5 - 0x7C0C0400, // 0031 CALL R3 2 - 0x80000000, // 0032 RET 0 + ( &(const binstruction[12]) { /* code */ + 0x8C080301, // 0000 GETMET R2 R1 K1 + 0x88100102, // 0001 GETMBR R4 R0 K2 + 0x7C080400, // 0002 CALL R2 2 + 0x90020002, // 0003 SETMBR R0 K0 R2 + 0x88080100, // 0004 GETMBR R2 R0 K0 + 0x4C0C0000, // 0005 LDNIL R3 + 0x1C080403, // 0006 EQ R2 R2 R3 + 0x780A0000, // 0007 JMPF R2 #0009 + 0x90020103, // 0008 SETMBR R0 K0 K3 + 0x5409FFFE, // 0009 LDINT R2 -1 + 0x90020802, // 000A SETMBR R0 K4 R2 + 0x80000000, // 000B RET 0 }) ) ); @@ -265,187 +217,186 @@ be_local_closure(Matter_Plugin_Shutter_invoke_request, /* name */ be_local_closure(Matter_Plugin_Shutter_read_attribute, /* name */ be_nested_proto( 13, /* nstack */ - 3, /* argc */ + 4, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[19]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_nested_str_weak(update_shadow_lazy), - /* K6 */ be_nested_str_weak(update_inverted), - /* K7 */ be_const_int(0), - /* K8 */ be_nested_str_weak(create_TLV), - /* K9 */ be_nested_str_weak(U1), - /* K10 */ be_nested_str_weak(U2), - /* K11 */ be_const_int(1), - /* K12 */ be_nested_str_weak(shadow_shutter_inverted), - /* K13 */ be_nested_str_weak(shadow_shutter_pos), - /* K14 */ be_nested_str_weak(shadow_shutter_direction), - /* K15 */ be_const_int(2), - /* K16 */ be_nested_str_weak(shadow_shutter_target), - /* K17 */ be_nested_str_weak(U4), - /* K18 */ be_nested_str_weak(read_attribute), + ( &(const bvalue[18]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_nested_str_weak(update_inverted), + /* K6 */ be_const_int(0), + /* K7 */ be_nested_str_weak(set), + /* K8 */ be_nested_str_weak(U1), + /* K9 */ be_nested_str_weak(U2), + /* K10 */ be_const_int(1), + /* K11 */ be_nested_str_weak(shadow_shutter_inverted), + /* K12 */ be_nested_str_weak(shadow_shutter_pos), + /* K13 */ be_nested_str_weak(shadow_shutter_direction), + /* K14 */ be_const_int(2), + /* K15 */ be_nested_str_weak(shadow_shutter_target), + /* K16 */ be_nested_str_weak(U4), + /* K17 */ be_nested_str_weak(read_attribute), }), be_str_weak(read_attribute), &be_const_str_solidified, ( &(const binstruction[152]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x4C1C0000, // 0005 LDNIL R7 - 0x54220101, // 0006 LDINT R8 258 - 0x1C200A08, // 0007 EQ R8 R5 R8 - 0x78220085, // 0008 JMPF R8 #008F - 0x8C200105, // 0009 GETMET R8 R0 K5 - 0x7C200200, // 000A CALL R8 1 - 0x8C200106, // 000B GETMET R8 R0 K6 - 0x7C200200, // 000C CALL R8 1 - 0x1C200D07, // 000D EQ R8 R6 K7 - 0x78220005, // 000E JMPF R8 #0015 - 0x8C200908, // 000F GETMET R8 R4 K8 - 0x88280909, // 0010 GETMBR R10 R4 K9 - 0x542E00FE, // 0011 LDINT R11 255 - 0x7C200600, // 0012 CALL R8 3 - 0x80041000, // 0013 RET 1 R8 - 0x70020078, // 0014 JMP #008E - 0x54220004, // 0015 LDINT R8 5 - 0x1C200C08, // 0016 EQ R8 R6 R8 - 0x78220005, // 0017 JMPF R8 #001E - 0x8C200908, // 0018 GETMET R8 R4 K8 - 0x8828090A, // 0019 GETMBR R10 R4 K10 - 0x582C0007, // 001A LDCONST R11 K7 - 0x7C200600, // 001B CALL R8 3 - 0x80041000, // 001C RET 1 R8 - 0x7002006F, // 001D JMP #008E - 0x54220006, // 001E LDINT R8 7 - 0x1C200C08, // 001F EQ R8 R6 R8 - 0x78220006, // 0020 JMPF R8 #0028 - 0x8C200908, // 0021 GETMET R8 R4 K8 - 0x88280909, // 0022 GETMBR R10 R4 K9 - 0x542E0007, // 0023 LDINT R11 8 - 0x002E160B, // 0024 ADD R11 K11 R11 - 0x7C200600, // 0025 CALL R8 3 - 0x80041000, // 0026 RET 1 R8 - 0x70020065, // 0027 JMP #008E - 0x5422000C, // 0028 LDINT R8 13 - 0x1C200C08, // 0029 EQ R8 R6 R8 - 0x78220005, // 002A JMPF R8 #0031 - 0x8C200908, // 002B GETMET R8 R4 K8 - 0x88280909, // 002C GETMBR R10 R4 K9 - 0x542E00FE, // 002D LDINT R11 255 - 0x7C200600, // 002E CALL R8 3 - 0x80041000, // 002F RET 1 R8 - 0x7002005C, // 0030 JMP #008E - 0x5422000D, // 0031 LDINT R8 14 - 0x1C200C08, // 0032 EQ R8 R6 R8 - 0x78220013, // 0033 JMPF R8 #0048 - 0x8820010C, // 0034 GETMBR R8 R0 K12 - 0x1C201107, // 0035 EQ R8 R8 K7 - 0x78220006, // 0036 JMPF R8 #003E - 0x54220063, // 0037 LDINT R8 100 - 0x8824010D, // 0038 GETMBR R9 R0 K13 - 0x04201009, // 0039 SUB R8 R8 R9 - 0x54260063, // 003A LDINT R9 100 - 0x08201009, // 003B MUL R8 R8 R9 - 0x5C1C1000, // 003C MOVE R7 R8 - 0x70020003, // 003D JMP #0042 - 0x8820010D, // 003E GETMBR R8 R0 K13 - 0x54260063, // 003F LDINT R9 100 - 0x08201009, // 0040 MUL R8 R8 R9 - 0x5C1C1000, // 0041 MOVE R7 R8 - 0x8C200908, // 0042 GETMET R8 R4 K8 - 0x8828090A, // 0043 GETMBR R10 R4 K10 - 0x5C2C0E00, // 0044 MOVE R11 R7 - 0x7C200600, // 0045 CALL R8 3 - 0x80041000, // 0046 RET 1 R8 - 0x70020045, // 0047 JMP #008E - 0x54220009, // 0048 LDINT R8 10 - 0x1C200C08, // 0049 EQ R8 R6 R8 - 0x78220010, // 004A JMPF R8 #005C - 0x8820010E, // 004B GETMBR R8 R0 K14 - 0x1C201107, // 004C EQ R8 R8 K7 - 0x78220001, // 004D JMPF R8 #0050 - 0x58200007, // 004E LDCONST R8 K7 - 0x70020005, // 004F JMP #0056 - 0x8820010E, // 0050 GETMBR R8 R0 K14 - 0x24201107, // 0051 GT R8 R8 K7 - 0x78220001, // 0052 JMPF R8 #0055 - 0x5820000B, // 0053 LDCONST R8 K11 - 0x70020000, // 0054 JMP #0056 - 0x5820000F, // 0055 LDCONST R8 K15 - 0x8C240908, // 0056 GETMET R9 R4 K8 - 0x882C0909, // 0057 GETMBR R11 R4 K9 - 0x5C301000, // 0058 MOVE R12 R8 - 0x7C240600, // 0059 CALL R9 3 - 0x80041200, // 005A RET 1 R9 - 0x70020031, // 005B JMP #008E - 0x5422000A, // 005C LDINT R8 11 - 0x1C200C08, // 005D EQ R8 R6 R8 - 0x78220013, // 005E JMPF R8 #0073 - 0x8820010C, // 005F GETMBR R8 R0 K12 - 0x1C201107, // 0060 EQ R8 R8 K7 - 0x78220006, // 0061 JMPF R8 #0069 - 0x54220063, // 0062 LDINT R8 100 - 0x88240110, // 0063 GETMBR R9 R0 K16 - 0x04201009, // 0064 SUB R8 R8 R9 - 0x54260063, // 0065 LDINT R9 100 - 0x08201009, // 0066 MUL R8 R8 R9 - 0x5C1C1000, // 0067 MOVE R7 R8 - 0x70020003, // 0068 JMP #006D - 0x88200110, // 0069 GETMBR R8 R0 K16 - 0x54260063, // 006A LDINT R9 100 - 0x08201009, // 006B MUL R8 R8 R9 - 0x5C1C1000, // 006C MOVE R7 R8 - 0x8C200908, // 006D GETMET R8 R4 K8 - 0x8828090A, // 006E GETMBR R10 R4 K10 - 0x5C2C0E00, // 006F MOVE R11 R7 - 0x7C200600, // 0070 CALL R8 3 - 0x80041000, // 0071 RET 1 R8 - 0x7002001A, // 0072 JMP #008E - 0x54220016, // 0073 LDINT R8 23 - 0x1C200C08, // 0074 EQ R8 R6 R8 - 0x78220005, // 0075 JMPF R8 #007C - 0x8C200908, // 0076 GETMET R8 R4 K8 - 0x88280909, // 0077 GETMBR R10 R4 K9 - 0x582C0007, // 0078 LDCONST R11 K7 - 0x7C200600, // 0079 CALL R8 3 - 0x80041000, // 007A RET 1 R8 - 0x70020011, // 007B JMP #008E - 0x5422FFFB, // 007C LDINT R8 65532 - 0x1C200C08, // 007D EQ R8 R6 R8 - 0x78220006, // 007E JMPF R8 #0086 - 0x8C200908, // 007F GETMET R8 R4 K8 - 0x88280911, // 0080 GETMBR R10 R4 K17 - 0x542E0003, // 0081 LDINT R11 4 - 0x002E160B, // 0082 ADD R11 K11 R11 - 0x7C200600, // 0083 CALL R8 3 - 0x80041000, // 0084 RET 1 R8 - 0x70020007, // 0085 JMP #008E - 0x5422FFFC, // 0086 LDINT R8 65533 - 0x1C200C08, // 0087 EQ R8 R6 R8 - 0x78220004, // 0088 JMPF R8 #008E - 0x8C200908, // 0089 GETMET R8 R4 K8 - 0x88280911, // 008A GETMBR R10 R4 K17 - 0x542E0004, // 008B LDINT R11 5 - 0x7C200600, // 008C CALL R8 3 - 0x80041000, // 008D RET 1 R8 - 0x70020007, // 008E JMP #0097 - 0x60200003, // 008F GETGBL R8 G3 - 0x5C240000, // 0090 MOVE R9 R0 - 0x7C200200, // 0091 CALL R8 1 - 0x8C201112, // 0092 GETMET R8 R8 K18 - 0x5C280200, // 0093 MOVE R10 R1 - 0x5C2C0400, // 0094 MOVE R11 R2 - 0x7C200600, // 0095 CALL R8 3 + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x4C1C0000, // 0004 LDNIL R7 + 0x54220101, // 0005 LDINT R8 258 + 0x1C200A08, // 0006 EQ R8 R5 R8 + 0x78220085, // 0007 JMPF R8 #008E + 0x8C200104, // 0008 GETMET R8 R0 K4 + 0x7C200200, // 0009 CALL R8 1 + 0x8C200105, // 000A GETMET R8 R0 K5 + 0x7C200200, // 000B CALL R8 1 + 0x1C200D06, // 000C EQ R8 R6 K6 + 0x78220005, // 000D JMPF R8 #0014 + 0x8C200707, // 000E GETMET R8 R3 K7 + 0x88280908, // 000F GETMBR R10 R4 K8 + 0x542E00FE, // 0010 LDINT R11 255 + 0x7C200600, // 0011 CALL R8 3 + 0x80041000, // 0012 RET 1 R8 + 0x70020078, // 0013 JMP #008D + 0x54220004, // 0014 LDINT R8 5 + 0x1C200C08, // 0015 EQ R8 R6 R8 + 0x78220005, // 0016 JMPF R8 #001D + 0x8C200707, // 0017 GETMET R8 R3 K7 + 0x88280909, // 0018 GETMBR R10 R4 K9 + 0x582C0006, // 0019 LDCONST R11 K6 + 0x7C200600, // 001A CALL R8 3 + 0x80041000, // 001B RET 1 R8 + 0x7002006F, // 001C JMP #008D + 0x54220006, // 001D LDINT R8 7 + 0x1C200C08, // 001E EQ R8 R6 R8 + 0x78220006, // 001F JMPF R8 #0027 + 0x8C200707, // 0020 GETMET R8 R3 K7 + 0x88280908, // 0021 GETMBR R10 R4 K8 + 0x542E0007, // 0022 LDINT R11 8 + 0x002E140B, // 0023 ADD R11 K10 R11 + 0x7C200600, // 0024 CALL R8 3 + 0x80041000, // 0025 RET 1 R8 + 0x70020065, // 0026 JMP #008D + 0x5422000C, // 0027 LDINT R8 13 + 0x1C200C08, // 0028 EQ R8 R6 R8 + 0x78220005, // 0029 JMPF R8 #0030 + 0x8C200707, // 002A GETMET R8 R3 K7 + 0x88280908, // 002B GETMBR R10 R4 K8 + 0x542E00FE, // 002C LDINT R11 255 + 0x7C200600, // 002D CALL R8 3 + 0x80041000, // 002E RET 1 R8 + 0x7002005C, // 002F JMP #008D + 0x5422000D, // 0030 LDINT R8 14 + 0x1C200C08, // 0031 EQ R8 R6 R8 + 0x78220013, // 0032 JMPF R8 #0047 + 0x8820010B, // 0033 GETMBR R8 R0 K11 + 0x1C201106, // 0034 EQ R8 R8 K6 + 0x78220006, // 0035 JMPF R8 #003D + 0x54220063, // 0036 LDINT R8 100 + 0x8824010C, // 0037 GETMBR R9 R0 K12 + 0x04201009, // 0038 SUB R8 R8 R9 + 0x54260063, // 0039 LDINT R9 100 + 0x08201009, // 003A MUL R8 R8 R9 + 0x5C1C1000, // 003B MOVE R7 R8 + 0x70020003, // 003C JMP #0041 + 0x8820010C, // 003D GETMBR R8 R0 K12 + 0x54260063, // 003E LDINT R9 100 + 0x08201009, // 003F MUL R8 R8 R9 + 0x5C1C1000, // 0040 MOVE R7 R8 + 0x8C200707, // 0041 GETMET R8 R3 K7 + 0x88280909, // 0042 GETMBR R10 R4 K9 + 0x5C2C0E00, // 0043 MOVE R11 R7 + 0x7C200600, // 0044 CALL R8 3 + 0x80041000, // 0045 RET 1 R8 + 0x70020045, // 0046 JMP #008D + 0x54220009, // 0047 LDINT R8 10 + 0x1C200C08, // 0048 EQ R8 R6 R8 + 0x78220010, // 0049 JMPF R8 #005B + 0x8820010D, // 004A GETMBR R8 R0 K13 + 0x1C201106, // 004B EQ R8 R8 K6 + 0x78220001, // 004C JMPF R8 #004F + 0x58200006, // 004D LDCONST R8 K6 + 0x70020005, // 004E JMP #0055 + 0x8820010D, // 004F GETMBR R8 R0 K13 + 0x24201106, // 0050 GT R8 R8 K6 + 0x78220001, // 0051 JMPF R8 #0054 + 0x5820000A, // 0052 LDCONST R8 K10 + 0x70020000, // 0053 JMP #0055 + 0x5820000E, // 0054 LDCONST R8 K14 + 0x8C240707, // 0055 GETMET R9 R3 K7 + 0x882C0908, // 0056 GETMBR R11 R4 K8 + 0x5C301000, // 0057 MOVE R12 R8 + 0x7C240600, // 0058 CALL R9 3 + 0x80041200, // 0059 RET 1 R9 + 0x70020031, // 005A JMP #008D + 0x5422000A, // 005B LDINT R8 11 + 0x1C200C08, // 005C EQ R8 R6 R8 + 0x78220013, // 005D JMPF R8 #0072 + 0x8820010B, // 005E GETMBR R8 R0 K11 + 0x1C201106, // 005F EQ R8 R8 K6 + 0x78220006, // 0060 JMPF R8 #0068 + 0x54220063, // 0061 LDINT R8 100 + 0x8824010F, // 0062 GETMBR R9 R0 K15 + 0x04201009, // 0063 SUB R8 R8 R9 + 0x54260063, // 0064 LDINT R9 100 + 0x08201009, // 0065 MUL R8 R8 R9 + 0x5C1C1000, // 0066 MOVE R7 R8 + 0x70020003, // 0067 JMP #006C + 0x8820010F, // 0068 GETMBR R8 R0 K15 + 0x54260063, // 0069 LDINT R9 100 + 0x08201009, // 006A MUL R8 R8 R9 + 0x5C1C1000, // 006B MOVE R7 R8 + 0x8C200707, // 006C GETMET R8 R3 K7 + 0x88280909, // 006D GETMBR R10 R4 K9 + 0x5C2C0E00, // 006E MOVE R11 R7 + 0x7C200600, // 006F CALL R8 3 + 0x80041000, // 0070 RET 1 R8 + 0x7002001A, // 0071 JMP #008D + 0x54220016, // 0072 LDINT R8 23 + 0x1C200C08, // 0073 EQ R8 R6 R8 + 0x78220005, // 0074 JMPF R8 #007B + 0x8C200707, // 0075 GETMET R8 R3 K7 + 0x88280908, // 0076 GETMBR R10 R4 K8 + 0x582C0006, // 0077 LDCONST R11 K6 + 0x7C200600, // 0078 CALL R8 3 + 0x80041000, // 0079 RET 1 R8 + 0x70020011, // 007A JMP #008D + 0x5422FFFB, // 007B LDINT R8 65532 + 0x1C200C08, // 007C EQ R8 R6 R8 + 0x78220006, // 007D JMPF R8 #0085 + 0x8C200707, // 007E GETMET R8 R3 K7 + 0x88280910, // 007F GETMBR R10 R4 K16 + 0x542E0003, // 0080 LDINT R11 4 + 0x002E140B, // 0081 ADD R11 K10 R11 + 0x7C200600, // 0082 CALL R8 3 + 0x80041000, // 0083 RET 1 R8 + 0x70020007, // 0084 JMP #008D + 0x5422FFFC, // 0085 LDINT R8 65533 + 0x1C200C08, // 0086 EQ R8 R6 R8 + 0x78220004, // 0087 JMPF R8 #008D + 0x8C200707, // 0088 GETMET R8 R3 K7 + 0x88280910, // 0089 GETMBR R10 R4 K16 + 0x542E0004, // 008A LDINT R11 5 + 0x7C200600, // 008B CALL R8 3 + 0x80041000, // 008C RET 1 R8 + 0x70020008, // 008D JMP #0097 + 0x60200003, // 008E GETGBL R8 G3 + 0x5C240000, // 008F MOVE R9 R0 + 0x7C200200, // 0090 CALL R8 1 + 0x8C201111, // 0091 GETMET R8 R8 K17 + 0x5C280200, // 0092 MOVE R10 R1 + 0x5C2C0400, // 0093 MOVE R11 R2 + 0x5C300600, // 0094 MOVE R12 R3 + 0x7C200800, // 0095 CALL R8 4 0x80041000, // 0096 RET 1 R8 0x80000000, // 0097 RET 0 }) @@ -486,7 +437,7 @@ be_local_closure(Matter_Plugin_Shutter__X3Clambda_X3E, /* name */ ********************************************************************/ be_local_closure(Matter_Plugin_Shutter_parse_sensors, /* name */ be_nested_proto( - 12, /* nstack */ + 11, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -494,78 +445,76 @@ be_local_closure(Matter_Plugin_Shutter_parse_sensors, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(Shutter), - /* K2 */ be_nested_str_weak(tasmota_shutter_index), - /* K3 */ be_const_int(1), - /* K4 */ be_nested_str_weak(contains), - /* K5 */ be_nested_str_weak(find), - /* K6 */ be_nested_str_weak(Position), - /* K7 */ be_nested_str_weak(shadow_shutter_pos), - /* K8 */ be_nested_str_weak(attribute_updated), - /* K9 */ be_nested_str_weak(Direction), - /* K10 */ be_nested_str_weak(shadow_shutter_direction), - /* K11 */ be_nested_str_weak(Target), - /* K12 */ be_nested_str_weak(shadow_shutter_target), + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(Shutter), + /* K1 */ be_nested_str_weak(tasmota_shutter_index), + /* K2 */ be_const_int(1), + /* K3 */ be_nested_str_weak(contains), + /* K4 */ be_nested_str_weak(find), + /* K5 */ be_nested_str_weak(Position), + /* K6 */ be_nested_str_weak(shadow_shutter_pos), + /* K7 */ be_nested_str_weak(attribute_updated), + /* K8 */ be_nested_str_weak(Direction), + /* K9 */ be_nested_str_weak(shadow_shutter_direction), + /* K10 */ be_nested_str_weak(Target), + /* K11 */ be_nested_str_weak(shadow_shutter_target), }), be_str_weak(parse_sensors), &be_const_str_solidified, - ( &(const binstruction[54]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x600C0008, // 0001 GETGBL R3 G8 - 0x88100102, // 0002 GETMBR R4 R0 K2 - 0x00100903, // 0003 ADD R4 R4 K3 - 0x7C0C0200, // 0004 CALL R3 1 - 0x000E0203, // 0005 ADD R3 K1 R3 - 0x8C100304, // 0006 GETMET R4 R1 K4 - 0x5C180600, // 0007 MOVE R6 R3 - 0x7C100400, // 0008 CALL R4 2 - 0x7812002A, // 0009 JMPF R4 #0035 - 0x94100203, // 000A GETIDX R4 R1 R3 - 0x8C140905, // 000B GETMET R5 R4 K5 - 0x581C0006, // 000C LDCONST R7 K6 - 0x7C140400, // 000D CALL R5 2 - 0x4C180000, // 000E LDNIL R6 - 0x20180A06, // 000F NE R6 R5 R6 - 0x781A0007, // 0010 JMPF R6 #0019 - 0x88180107, // 0011 GETMBR R6 R0 K7 - 0x20180A06, // 0012 NE R6 R5 R6 - 0x781A0003, // 0013 JMPF R6 #0018 - 0x8C180108, // 0014 GETMET R6 R0 K8 - 0x54220101, // 0015 LDINT R8 258 - 0x5426000D, // 0016 LDINT R9 14 - 0x7C180600, // 0017 CALL R6 3 - 0x90020E05, // 0018 SETMBR R0 K7 R5 - 0x8C180905, // 0019 GETMET R6 R4 K5 - 0x58200009, // 001A LDCONST R8 K9 - 0x7C180400, // 001B CALL R6 2 - 0x4C1C0000, // 001C LDNIL R7 - 0x201C0C07, // 001D NE R7 R6 R7 - 0x781E0007, // 001E JMPF R7 #0027 - 0x881C010A, // 001F GETMBR R7 R0 K10 - 0x201C0C07, // 0020 NE R7 R6 R7 - 0x781E0003, // 0021 JMPF R7 #0026 - 0x8C1C0108, // 0022 GETMET R7 R0 K8 - 0x54260101, // 0023 LDINT R9 258 - 0x542A0009, // 0024 LDINT R10 10 - 0x7C1C0600, // 0025 CALL R7 3 - 0x90021406, // 0026 SETMBR R0 K10 R6 - 0x8C1C0905, // 0027 GETMET R7 R4 K5 - 0x5824000B, // 0028 LDCONST R9 K11 - 0x7C1C0400, // 0029 CALL R7 2 - 0x4C200000, // 002A LDNIL R8 - 0x20200E08, // 002B NE R8 R7 R8 - 0x78220007, // 002C JMPF R8 #0035 - 0x8820010C, // 002D GETMBR R8 R0 K12 - 0x20200E08, // 002E NE R8 R7 R8 - 0x78220003, // 002F JMPF R8 #0034 - 0x8C200108, // 0030 GETMET R8 R0 K8 - 0x542A0101, // 0031 LDINT R10 258 - 0x542E000A, // 0032 LDINT R11 11 - 0x7C200600, // 0033 CALL R8 3 - 0x90021807, // 0034 SETMBR R0 K12 R7 - 0x80000000, // 0035 RET 0 + ( &(const binstruction[53]) { /* code */ + 0x60080008, // 0000 GETGBL R2 G8 + 0x880C0101, // 0001 GETMBR R3 R0 K1 + 0x000C0702, // 0002 ADD R3 R3 K2 + 0x7C080200, // 0003 CALL R2 1 + 0x000A0002, // 0004 ADD R2 K0 R2 + 0x8C0C0303, // 0005 GETMET R3 R1 K3 + 0x5C140400, // 0006 MOVE R5 R2 + 0x7C0C0400, // 0007 CALL R3 2 + 0x780E002A, // 0008 JMPF R3 #0034 + 0x940C0202, // 0009 GETIDX R3 R1 R2 + 0x8C100704, // 000A GETMET R4 R3 K4 + 0x58180005, // 000B LDCONST R6 K5 + 0x7C100400, // 000C CALL R4 2 + 0x4C140000, // 000D LDNIL R5 + 0x20140805, // 000E NE R5 R4 R5 + 0x78160007, // 000F JMPF R5 #0018 + 0x88140106, // 0010 GETMBR R5 R0 K6 + 0x20140805, // 0011 NE R5 R4 R5 + 0x78160003, // 0012 JMPF R5 #0017 + 0x8C140107, // 0013 GETMET R5 R0 K7 + 0x541E0101, // 0014 LDINT R7 258 + 0x5422000D, // 0015 LDINT R8 14 + 0x7C140600, // 0016 CALL R5 3 + 0x90020C04, // 0017 SETMBR R0 K6 R4 + 0x8C140704, // 0018 GETMET R5 R3 K4 + 0x581C0008, // 0019 LDCONST R7 K8 + 0x7C140400, // 001A CALL R5 2 + 0x4C180000, // 001B LDNIL R6 + 0x20180A06, // 001C NE R6 R5 R6 + 0x781A0007, // 001D JMPF R6 #0026 + 0x88180109, // 001E GETMBR R6 R0 K9 + 0x20180A06, // 001F NE R6 R5 R6 + 0x781A0003, // 0020 JMPF R6 #0025 + 0x8C180107, // 0021 GETMET R6 R0 K7 + 0x54220101, // 0022 LDINT R8 258 + 0x54260009, // 0023 LDINT R9 10 + 0x7C180600, // 0024 CALL R6 3 + 0x90021205, // 0025 SETMBR R0 K9 R5 + 0x8C180704, // 0026 GETMET R6 R3 K4 + 0x5820000A, // 0027 LDCONST R8 K10 + 0x7C180400, // 0028 CALL R6 2 + 0x4C1C0000, // 0029 LDNIL R7 + 0x201C0C07, // 002A NE R7 R6 R7 + 0x781E0007, // 002B JMPF R7 #0034 + 0x881C010B, // 002C GETMBR R7 R0 K11 + 0x201C0C07, // 002D NE R7 R6 R7 + 0x781E0003, // 002E JMPF R7 #0033 + 0x8C1C0107, // 002F GETMET R7 R0 K7 + 0x54260101, // 0030 LDINT R9 258 + 0x542A000A, // 0031 LDINT R10 11 + 0x7C1C0600, // 0032 CALL R7 3 + 0x90021606, // 0033 SETMBR R0 K11 R6 + 0x80000000, // 0034 RET 0 }) ) ); @@ -573,49 +522,71 @@ be_local_closure(Matter_Plugin_Shutter_parse_sensors, /* name */ /******************************************************************** -** Solidified function: init +** Solidified function: update_inverted ********************************************************************/ -be_local_closure(Matter_Plugin_Shutter_init, /* name */ +be_local_closure(Matter_Plugin_Shutter_update_inverted, /* name */ be_nested_proto( - 9, /* nstack */ - 4, /* argc */ + 6, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(init), - /* K1 */ be_nested_str_weak(tasmota_shutter_index), - /* K2 */ be_nested_str_weak(find), - /* K3 */ be_nested_str_weak(ARG), - /* K4 */ be_const_int(0), - /* K5 */ be_nested_str_weak(shadow_shutter_inverted), + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(shadow_shutter_inverted), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(cmd), + /* K3 */ be_nested_str_weak(Status_X2013), + /* K4 */ be_nested_str_weak(contains), + /* K5 */ be_nested_str_weak(StatusSHT), + /* K6 */ be_nested_str_weak(find), + /* K7 */ be_nested_str_weak(SHT), + /* K8 */ be_nested_str_weak(tasmota_shutter_index), + /* K9 */ be_nested_str_weak(Opt), + /* K10 */ be_const_int(1), }), - be_str_weak(init), + be_str_weak(update_inverted), &be_const_str_solidified, - ( &(const binstruction[20]) { /* code */ - 0x60100003, // 0000 GETGBL R4 G3 - 0x5C140000, // 0001 MOVE R5 R0 - 0x7C100200, // 0002 CALL R4 1 - 0x8C100900, // 0003 GETMET R4 R4 K0 - 0x5C180200, // 0004 MOVE R6 R1 - 0x5C1C0400, // 0005 MOVE R7 R2 - 0x5C200600, // 0006 MOVE R8 R3 - 0x7C100800, // 0007 CALL R4 4 - 0x8C100702, // 0008 GETMET R4 R3 K2 - 0x88180103, // 0009 GETMBR R6 R0 K3 - 0x7C100400, // 000A CALL R4 2 - 0x90020204, // 000B SETMBR R0 K1 R4 - 0x88100101, // 000C GETMBR R4 R0 K1 - 0x4C140000, // 000D LDNIL R5 - 0x1C100805, // 000E EQ R4 R4 R5 - 0x78120000, // 000F JMPF R4 #0011 - 0x90020304, // 0010 SETMBR R0 K1 K4 - 0x5411FFFE, // 0011 LDINT R4 -1 - 0x90020A04, // 0012 SETMBR R0 K5 R4 - 0x80000000, // 0013 RET 0 + ( &(const binstruction[37]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x5409FFFE, // 0001 LDINT R2 -1 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x7806001F, // 0003 JMPF R1 #0024 + 0xB8060200, // 0004 GETNGBL R1 K1 + 0x8C040302, // 0005 GETMET R1 R1 K2 + 0x580C0003, // 0006 LDCONST R3 K3 + 0x50100200, // 0007 LDBOOL R4 1 0 + 0x7C040600, // 0008 CALL R1 3 + 0x8C080304, // 0009 GETMET R2 R1 K4 + 0x58100005, // 000A LDCONST R4 K5 + 0x7C080400, // 000B CALL R2 2 + 0x780A0016, // 000C JMPF R2 #0024 + 0x94040305, // 000D GETIDX R1 R1 K5 + 0x8C080306, // 000E GETMET R2 R1 K6 + 0x60100008, // 000F GETGBL R4 G8 + 0x88140108, // 0010 GETMBR R5 R0 K8 + 0x7C100200, // 0011 CALL R4 1 + 0x00120E04, // 0012 ADD R4 K7 R4 + 0x60140013, // 0013 GETGBL R5 G19 + 0x7C140000, // 0014 CALL R5 0 + 0x7C080600, // 0015 CALL R2 3 + 0x8C080506, // 0016 GETMET R2 R2 K6 + 0x58100009, // 0017 LDCONST R4 K9 + 0x7C080400, // 0018 CALL R2 2 + 0x4C0C0000, // 0019 LDNIL R3 + 0x200C0403, // 001A NE R3 R2 R3 + 0x780E0007, // 001B JMPF R3 #0024 + 0x600C0009, // 001C GETGBL R3 G9 + 0x6010000C, // 001D GETGBL R4 G12 + 0x5C140400, // 001E MOVE R5 R2 + 0x7C100200, // 001F CALL R4 1 + 0x0410090A, // 0020 SUB R4 R4 K10 + 0x94100404, // 0021 GETIDX R4 R2 R4 + 0x7C0C0200, // 0022 CALL R3 1 + 0x90020003, // 0023 SETMBR R0 K0 R3 + 0x80000000, // 0024 RET 0 }) ) ); @@ -680,20 +651,20 @@ be_local_closure(Matter_Plugin_Shutter_update_shadow, /* name */ ********************************************************************/ extern const bclass be_class_Matter_Plugin_Device; be_local_class(Matter_Plugin_Shutter, - 6, + 5, &be_class_Matter_Plugin_Device, be_nested_map(18, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(shadow_shutter_direction, -1), be_const_var(4) }, + { be_const_key_weak(shadow_shutter_inverted, -1), be_const_var(4) }, { be_const_key_weak(TYPE, -1), be_nested_str_weak(shutter) }, { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { be_const_map( * be_nested_map(1, ( (struct bmapnode*) &(const bmapnode[]) { { be_const_key_int(514, -1), be_const_int(2) }, })) ) } )) }, - { be_const_key_weak(update_shadow, -1), be_const_closure(Matter_Plugin_Shutter_update_shadow_closure) }, + { be_const_key_weak(shadow_shutter_target, -1), be_const_var(2) }, { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, + be_const_map( * be_nested_map(6, ( (struct bmapnode*) &(const bmapnode[]) { { be_const_key_int(258, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { be_const_list( * be_nested_list(10, @@ -709,20 +680,68 @@ be_local_class(Matter_Plugin_Shutter, be_const_int(65532), be_const_int(65533), })) ) } )) }, + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), })) ) } )) }, - { be_const_key_weak(invoke_request, 14), be_const_closure(Matter_Plugin_Shutter_invoke_request_closure) }, - { be_const_key_weak(read_attribute, 13), be_const_closure(Matter_Plugin_Shutter_read_attribute_closure) }, - { be_const_key_weak(shadow_shutter_inverted, 3), be_const_var(5) }, + { be_const_key_int(29, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(invoke_request, 3), be_const_closure(Matter_Plugin_Shutter_invoke_request_closure) }, + { be_const_key_weak(read_attribute, 11), be_const_closure(Matter_Plugin_Shutter_read_attribute_closure) }, + { be_const_key_weak(parse_configuration, 14), be_const_closure(Matter_Plugin_Shutter_parse_configuration_closure) }, { be_const_key_weak(shadow_shutter_pos, -1), be_const_var(1) }, - { be_const_key_weak(ARG, -1), be_nested_str_weak(shutter) }, + { be_const_key_weak(ARG, 13), be_nested_str_weak(shutter) }, { be_const_key_weak(ARG_TYPE, -1), be_const_static_closure(Matter_Plugin_Shutter__X3Clambda_X3E_closure) }, - { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Shutter_init_closure) }, - { be_const_key_weak(update_inverted, 16), be_const_closure(Matter_Plugin_Shutter_update_inverted_closure) }, { be_const_key_weak(parse_sensors, -1), be_const_closure(Matter_Plugin_Shutter_parse_sensors_closure) }, - { be_const_key_weak(shadow_shutter_target, -1), be_const_var(2) }, - { be_const_key_weak(tasmota_shutter_index, 11), be_const_var(0) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak(Shutter) }, - { be_const_key_weak(shadow_shutter_tilt, 0), be_const_var(3) }, + { be_const_key_weak(update_inverted, -1), be_const_closure(Matter_Plugin_Shutter_update_inverted_closure) }, + { be_const_key_weak(ARG_HINT, 16), be_nested_str_weak(Relay_X3Cx_X3E_X20number) }, + { be_const_key_weak(update_shadow, 0), be_const_closure(Matter_Plugin_Shutter_update_shadow_closure) }, + { be_const_key_weak(tasmota_shutter_index, -1), be_const_var(0) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Shutter) }, + { be_const_key_weak(shadow_shutter_direction, -1), be_const_var(3) }, })), be_str_weak(Matter_Plugin_Shutter) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Bridge_Light0.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Bridge_Light0.h new file mode 100644 index 000000000000..c0eb08bcdbdc --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Bridge_Light0.h @@ -0,0 +1,570 @@ +/* Solidification of Matter_Plugin_3_Bridge_Light0.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Bridge_Light0; + +/******************************************************************** +** Solidified function: set_onoff +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light0_set_onoff, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(call_remote_sync), + /* K1 */ be_nested_str_weak(Power), + /* K2 */ be_nested_str_weak(tasmota_relay_index), + /* K3 */ be_nested_str_weak(1), + /* K4 */ be_nested_str_weak(0), + /* K5 */ be_nested_str_weak(parse_update), + }), + be_str_weak(set_onoff), + &be_const_str_solidified, + ( &(const binstruction[18]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x60100008, // 0001 GETGBL R4 G8 + 0x88140102, // 0002 GETMBR R5 R0 K2 + 0x7C100200, // 0003 CALL R4 1 + 0x00120204, // 0004 ADD R4 K1 R4 + 0x78060001, // 0005 JMPF R1 #0008 + 0x58140003, // 0006 LDCONST R5 K3 + 0x70020000, // 0007 JMP #0009 + 0x58140004, // 0008 LDCONST R5 K4 + 0x7C080600, // 0009 CALL R2 3 + 0x4C0C0000, // 000A LDNIL R3 + 0x200C0403, // 000B NE R3 R2 R3 + 0x780E0003, // 000C JMPF R3 #0011 + 0x8C0C0105, // 000D GETMET R3 R0 K5 + 0x5C140400, // 000E MOVE R5 R2 + 0x541A000A, // 000F LDINT R6 11 + 0x7C0C0600, // 0010 CALL R3 3 + 0x80000000, // 0011 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light0_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(shadow_onoff), + /* K2 */ be_nested_str_weak(tasmota_relay_index), + /* K3 */ be_nested_str_weak(find), + /* K4 */ be_nested_str_weak(ARG), + /* K5 */ be_const_int(1), + /* K6 */ be_const_int(0), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[22]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x50100000, // 0008 LDBOOL R4 0 0 + 0x90020204, // 0009 SETMBR R0 K1 R4 + 0x60100009, // 000A GETGBL R4 G9 + 0x8C140703, // 000B GETMET R5 R3 K3 + 0x881C0104, // 000C GETMBR R7 R0 K4 + 0x58200005, // 000D LDCONST R8 K5 + 0x7C140600, // 000E CALL R5 3 + 0x7C100200, // 000F CALL R4 1 + 0x90020404, // 0010 SETMBR R0 K2 R4 + 0x88100102, // 0011 GETMBR R4 R0 K2 + 0x18100906, // 0012 LE R4 R4 K6 + 0x78120000, // 0013 JMPF R4 #0015 + 0x90020505, // 0014 SETMBR R0 K2 K5 + 0x80000000, // 0015 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light0_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(BOOL), + /* K8 */ be_nested_str_weak(shadow_onoff), + /* K9 */ be_nested_str_weak(U4), + /* K10 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0005, // 0004 LDINT R7 6 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E001B, // 0006 JMPF R7 #0023 + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x1C1C0D05, // 0009 EQ R7 R6 K5 + 0x781E0005, // 000A JMPF R7 #0011 + 0x8C1C0706, // 000B GETMET R7 R3 K6 + 0x88240907, // 000C GETMBR R9 R4 K7 + 0x88280108, // 000D GETMBR R10 R0 K8 + 0x7C1C0600, // 000E CALL R7 3 + 0x80040E00, // 000F RET 1 R7 + 0x70020010, // 0010 JMP #0022 + 0x541EFFFB, // 0011 LDINT R7 65532 + 0x1C1C0C07, // 0012 EQ R7 R6 R7 + 0x781E0005, // 0013 JMPF R7 #001A + 0x8C1C0706, // 0014 GETMET R7 R3 K6 + 0x88240909, // 0015 GETMBR R9 R4 K9 + 0x58280005, // 0016 LDCONST R10 K5 + 0x7C1C0600, // 0017 CALL R7 3 + 0x80040E00, // 0018 RET 1 R7 + 0x70020007, // 0019 JMP #0022 + 0x541EFFFC, // 001A LDINT R7 65533 + 0x1C1C0C07, // 001B EQ R7 R6 R7 + 0x781E0004, // 001C JMPF R7 #0022 + 0x8C1C0706, // 001D GETMET R7 R3 K6 + 0x88240909, // 001E GETMBR R9 R4 K9 + 0x542A0003, // 001F LDINT R10 4 + 0x7C1C0600, // 0020 CALL R7 3 + 0x80040E00, // 0021 RET 1 R7 + 0x70020008, // 0022 JMP #002C + 0x601C0003, // 0023 GETGBL R7 G3 + 0x5C200000, // 0024 MOVE R8 R0 + 0x7C1C0200, // 0025 CALL R7 1 + 0x8C1C0F0A, // 0026 GETMET R7 R7 K10 + 0x5C240200, // 0027 MOVE R9 R1 + 0x5C280400, // 0028 MOVE R10 R2 + 0x5C2C0600, // 0029 MOVE R11 R3 + 0x7C1C0800, // 002A CALL R7 4 + 0x80040E00, // 002B RET 1 R7 + 0x80000000, // 002C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light0__X3Clambda_X3E, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x60040009, // 0000 GETGBL R1 G9 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_update +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light0_parse_update, /* name */ + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota_relay_index), + /* K1 */ be_const_int(1), + /* K2 */ be_nested_str_weak(contains), + /* K3 */ be_nested_str_weak(POWER), + /* K4 */ be_nested_str_weak(find), + /* K5 */ be_nested_str_weak(ON), + /* K6 */ be_nested_str_weak(shadow_onoff), + /* K7 */ be_nested_str_weak(attribute_updated), + /* K8 */ be_const_int(0), + }), + be_str_weak(parse_update), + &be_const_str_solidified, + ( &(const binstruction[41]) { /* code */ + 0x540E000A, // 0000 LDINT R3 11 + 0x1C0C0403, // 0001 EQ R3 R2 R3 + 0x780E0024, // 0002 JMPF R3 #0028 + 0x500C0000, // 0003 LDBOOL R3 0 0 + 0x88100100, // 0004 GETMBR R4 R0 K0 + 0x1C100901, // 0005 EQ R4 R4 K1 + 0x78120009, // 0006 JMPF R4 #0011 + 0x8C100302, // 0007 GETMET R4 R1 K2 + 0x58180003, // 0008 LDCONST R6 K3 + 0x7C100400, // 0009 CALL R4 2 + 0x78120005, // 000A JMPF R4 #0011 + 0x8C100304, // 000B GETMET R4 R1 K4 + 0x58180003, // 000C LDCONST R6 K3 + 0x7C100400, // 000D CALL R4 2 + 0x1C100905, // 000E EQ R4 R4 K5 + 0x5C0C0800, // 000F MOVE R3 R4 + 0x70020007, // 0010 JMP #0019 + 0x8C100304, // 0011 GETMET R4 R1 K4 + 0x60180008, // 0012 GETGBL R6 G8 + 0x881C0100, // 0013 GETMBR R7 R0 K0 + 0x7C180200, // 0014 CALL R6 1 + 0x001A0606, // 0015 ADD R6 K3 R6 + 0x7C100400, // 0016 CALL R4 2 + 0x1C100905, // 0017 EQ R4 R4 K5 + 0x5C0C0800, // 0018 MOVE R3 R4 + 0x88100106, // 0019 GETMBR R4 R0 K6 + 0x4C140000, // 001A LDNIL R5 + 0x20100805, // 001B NE R4 R4 R5 + 0x78120009, // 001C JMPF R4 #0027 + 0x88100106, // 001D GETMBR R4 R0 K6 + 0x60140017, // 001E GETGBL R5 G23 + 0x5C180600, // 001F MOVE R6 R3 + 0x7C140200, // 0020 CALL R5 1 + 0x20100805, // 0021 NE R4 R4 R5 + 0x78120003, // 0022 JMPF R4 #0027 + 0x8C100107, // 0023 GETMET R4 R0 K7 + 0x541A0005, // 0024 LDINT R6 6 + 0x581C0008, // 0025 LDCONST R7 K8 + 0x7C100600, // 0026 CALL R4 3 + 0x90020C03, // 0027 SETMBR R0 K6 R3 + 0x80000000, // 0028 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: invoke_request +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light0_invoke_request, /* name */ + be_nested_proto( + 11, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(command), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(set_onoff), + /* K6 */ be_nested_str_weak(publish_command), + /* K7 */ be_nested_str_weak(Power), + /* K8 */ be_const_int(1), + /* K9 */ be_const_int(2), + /* K10 */ be_nested_str_weak(shadow_onoff), + }), + be_str_weak(invoke_request), + &be_const_str_solidified, + ( &(const binstruction[50]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140702, // 0002 GETMBR R5 R3 K2 + 0x88180703, // 0003 GETMBR R6 R3 K3 + 0x541E0005, // 0004 LDINT R7 6 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0029, // 0006 JMPF R7 #0031 + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E0009, // 0008 JMPF R7 #0013 + 0x8C1C0105, // 0009 GETMET R7 R0 K5 + 0x50240000, // 000A LDBOOL R9 0 0 + 0x7C1C0400, // 000B CALL R7 2 + 0x8C1C0106, // 000C GETMET R7 R0 K6 + 0x58240007, // 000D LDCONST R9 K7 + 0x58280004, // 000E LDCONST R10 K4 + 0x7C1C0600, // 000F CALL R7 3 + 0x501C0200, // 0010 LDBOOL R7 1 0 + 0x80040E00, // 0011 RET 1 R7 + 0x7002001D, // 0012 JMP #0031 + 0x1C1C0D08, // 0013 EQ R7 R6 K8 + 0x781E0009, // 0014 JMPF R7 #001F + 0x8C1C0105, // 0015 GETMET R7 R0 K5 + 0x50240200, // 0016 LDBOOL R9 1 0 + 0x7C1C0400, // 0017 CALL R7 2 + 0x8C1C0106, // 0018 GETMET R7 R0 K6 + 0x58240007, // 0019 LDCONST R9 K7 + 0x58280008, // 001A LDCONST R10 K8 + 0x7C1C0600, // 001B CALL R7 3 + 0x501C0200, // 001C LDBOOL R7 1 0 + 0x80040E00, // 001D RET 1 R7 + 0x70020011, // 001E JMP #0031 + 0x1C1C0D09, // 001F EQ R7 R6 K9 + 0x781E000F, // 0020 JMPF R7 #0031 + 0x8C1C0105, // 0021 GETMET R7 R0 K5 + 0x8824010A, // 0022 GETMBR R9 R0 K10 + 0x78260000, // 0023 JMPF R9 #0025 + 0x50240001, // 0024 LDBOOL R9 0 1 + 0x50240200, // 0025 LDBOOL R9 1 0 + 0x7C1C0400, // 0026 CALL R7 2 + 0x8C1C0106, // 0027 GETMET R7 R0 K6 + 0x58240007, // 0028 LDCONST R9 K7 + 0x8828010A, // 0029 GETMBR R10 R0 K10 + 0x782A0001, // 002A JMPF R10 #002D + 0x58280008, // 002B LDCONST R10 K8 + 0x70020000, // 002C JMP #002E + 0x58280004, // 002D LDCONST R10 K4 + 0x7C1C0600, // 002E CALL R7 3 + 0x501C0200, // 002F LDBOOL R7 1 0 + 0x80040E00, // 0030 RET 1 R7 + 0x80000000, // 0031 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light0_web_values, /* name */ + be_nested_proto( + 9, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(web_values_prefix), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(_X25s), + /* K4 */ be_nested_str_weak(web_value_onoff), + /* K5 */ be_nested_str_weak(shadow_onoff), + }), + be_str_weak(web_values), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x60100018, // 0004 GETGBL R4 G24 + 0x58140003, // 0005 LDCONST R5 K3 + 0x8C180104, // 0006 GETMET R6 R0 K4 + 0x88200105, // 0007 GETMBR R8 R0 K5 + 0x7C180400, // 0008 CALL R6 2 + 0x7C100400, // 0009 CALL R4 2 + 0x7C080400, // 000A CALL R2 2 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values_prefix +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light0_web_values_prefix, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(get_name), + /* K2 */ be_nested_str_weak(Power), + /* K3 */ be_nested_str_weak(tasmota_relay_index), + /* K4 */ be_nested_str_weak(content_send), + /* K5 */ be_nested_str_weak(PREFIX), + /* K6 */ be_nested_str_weak(html_escape), + /* K7 */ be_nested_str_weak(), + }), + be_str_weak(web_values_prefix), + &be_const_str_solidified, + ( &(const binstruction[22]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x5C0C0400, // 0003 MOVE R3 R2 + 0x740E0004, // 0004 JMPT R3 #000A + 0x600C0008, // 0005 GETGBL R3 G8 + 0x88100103, // 0006 GETMBR R4 R0 K3 + 0x7C0C0200, // 0007 CALL R3 1 + 0x000E0403, // 0008 ADD R3 K2 R3 + 0x5C080600, // 0009 MOVE R2 R3 + 0x8C0C0304, // 000A GETMET R3 R1 K4 + 0x60140018, // 000B GETGBL R5 G24 + 0x88180105, // 000C GETMBR R6 R0 K5 + 0x780A0003, // 000D JMPF R2 #0012 + 0x8C1C0306, // 000E GETMET R7 R1 K6 + 0x5C240400, // 000F MOVE R9 R2 + 0x7C1C0400, // 0010 CALL R7 2 + 0x70020000, // 0011 JMP #0013 + 0x581C0007, // 0012 LDCONST R7 K7 + 0x7C140400, // 0013 CALL R5 2 + 0x7C0C0400, // 0014 CALL R3 2 + 0x80000000, // 0015 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_Light0 +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Bridge_HTTP; +be_local_class(Matter_Plugin_Bridge_Light0, + 2, + &be_class_Matter_Plugin_Bridge_HTTP, + be_nested_map(16, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(shadow_onoff, 5), be_const_var(1) }, + { be_const_key_weak(tasmota_relay_index, 4), be_const_var(0) }, + { be_const_key_weak(set_onoff, -1), be_const_closure(Matter_Plugin_Bridge_Light0_set_onoff_closure) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Bridge_Light0_init_closure) }, + { be_const_key_weak(web_values_prefix, 9), be_const_closure(Matter_Plugin_Bridge_Light0_web_values_prefix_closure) }, + { be_const_key_weak(web_values, 15), be_const_closure(Matter_Plugin_Bridge_Light0_web_values_closure) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(http_light0) }, + { be_const_key_weak(ARG, -1), be_nested_str_weak(relay) }, + { be_const_key_weak(parse_update, -1), be_const_closure(Matter_Plugin_Bridge_Light0_parse_update_closure) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(Power_X3Cx_X3E_X20number) }, + { be_const_key_weak(read_attribute, 12), be_const_closure(Matter_Plugin_Bridge_Light0_read_attribute_closure) }, + { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Bridge_Light0_invoke_request_closure) }, + { be_const_key_weak(CLUSTERS, 14), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(DISPLAY_NAME, 6), be_nested_str_weak(Light_X200_X20On) }, + { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(256, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(ARG_TYPE, -1), be_const_static_closure(Matter_Plugin_Bridge_Light0__X3Clambda_X3E_closure) }, + })), + be_str_weak(Matter_Plugin_Bridge_Light0) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_Light0_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_Light0); + be_setglobal(vm, "Matter_Plugin_Bridge_Light0"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Bridge_Sensor.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Bridge_Sensor.h new file mode 100644 index 000000000000..4079b20bdf10 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Bridge_Sensor.h @@ -0,0 +1,316 @@ +/* Solidification of Matter_Plugin_3_Bridge_Sensor.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Bridge_Sensor; + +/******************************************************************** +** Solidified function: parse_configuration +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_parse_configuration, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota_sensor_filter), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(ARG), + /* K3 */ be_nested_str_weak(tasmota_sensor_matcher), + /* K4 */ be_nested_str_weak(tasmota), + /* K5 */ be_nested_str_weak(Rule_Matcher), + /* K6 */ be_nested_str_weak(parse), + /* K7 */ be_nested_str_weak(temp_unit), + /* K8 */ be_nested_str_weak(TEMP_C), + /* K9 */ be_nested_str_weak(pressure_unit), + /* K10 */ be_nested_str_weak(PRESSURE_HPA), + }), + be_str_weak(parse_configuration), + &be_const_str_solidified, + ( &(const binstruction[17]) { /* code */ + 0x8C080301, // 0000 GETMET R2 R1 K1 + 0x88100102, // 0001 GETMBR R4 R0 K2 + 0x7C080400, // 0002 CALL R2 2 + 0x90020002, // 0003 SETMBR R0 K0 R2 + 0x88080100, // 0004 GETMBR R2 R0 K0 + 0x780A0005, // 0005 JMPF R2 #000C + 0xB80A0800, // 0006 GETNGBL R2 K4 + 0x88080505, // 0007 GETMBR R2 R2 K5 + 0x8C080506, // 0008 GETMET R2 R2 K6 + 0x88100100, // 0009 GETMBR R4 R0 K0 + 0x7C080400, // 000A CALL R2 2 + 0x90020602, // 000B SETMBR R0 K3 R2 + 0x88080108, // 000C GETMBR R2 R0 K8 + 0x90020E02, // 000D SETMBR R0 K7 R2 + 0x8808010A, // 000E GETMBR R2 R0 K10 + 0x90021202, // 000F SETMBR R0 K9 R2 + 0x80000000, // 0010 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: value_changed +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_value_changed, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(value_changed), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values_prefix +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_web_values_prefix, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(get_name), + /* K2 */ be_nested_str_weak(filter_name_html), + /* K3 */ be_nested_str_weak(content_send), + /* K4 */ be_nested_str_weak(PREFIX), + /* K5 */ be_nested_str_weak(html_escape), + /* K6 */ be_nested_str_weak(), + }), + be_str_weak(web_values_prefix), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x5C0C0400, // 0003 MOVE R3 R2 + 0x740E0002, // 0004 JMPT R3 #0008 + 0x8C0C0102, // 0005 GETMET R3 R0 K2 + 0x7C0C0200, // 0006 CALL R3 1 + 0x5C080600, // 0007 MOVE R2 R3 + 0x8C0C0303, // 0008 GETMET R3 R1 K3 + 0x60140018, // 0009 GETGBL R5 G24 + 0x88180104, // 000A GETMBR R6 R0 K4 + 0x780A0003, // 000B JMPF R2 #0010 + 0x8C1C0305, // 000C GETMET R7 R1 K5 + 0x5C240400, // 000D MOVE R9 R2 + 0x7C1C0400, // 000E CALL R7 2 + 0x70020000, // 000F JMP #0011 + 0x581C0006, // 0010 LDCONST R7 K6 + 0x7C140400, // 0011 CALL R5 2 + 0x7C0C0400, // 0012 CALL R3 2 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_update +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_parse_update, /* name */ + be_nested_proto( + 9, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str_weak(contains), + /* K1 */ be_nested_str_weak(TempUnit), + /* K2 */ be_nested_str_weak(temp_unit), + /* K3 */ be_nested_str_weak(PressureUnit), + /* K4 */ be_nested_str_weak(pressure_unit), + /* K5 */ be_nested_str_weak(tasmota_sensor_matcher), + /* K6 */ be_nested_str_weak(pre_value), + /* K7 */ be_nested_str_weak(match), + /* K8 */ be_nested_str_weak(shadow_value), + /* K9 */ be_nested_str_weak(value_changed), + }), + be_str_weak(parse_update), + &be_const_str_solidified, + ( &(const binstruction[35]) { /* code */ + 0x540E0007, // 0000 LDINT R3 8 + 0x1C0C0403, // 0001 EQ R3 R2 R3 + 0x780E001E, // 0002 JMPF R3 #0022 + 0x8C0C0300, // 0003 GETMET R3 R1 K0 + 0x58140001, // 0004 LDCONST R5 K1 + 0x7C0C0400, // 0005 CALL R3 2 + 0x780E0001, // 0006 JMPF R3 #0009 + 0x940C0301, // 0007 GETIDX R3 R1 K1 + 0x90020403, // 0008 SETMBR R0 K2 R3 + 0x8C0C0300, // 0009 GETMET R3 R1 K0 + 0x58140003, // 000A LDCONST R5 K3 + 0x7C0C0400, // 000B CALL R3 2 + 0x780E0001, // 000C JMPF R3 #000F + 0x940C0303, // 000D GETIDX R3 R1 K3 + 0x90020803, // 000E SETMBR R0 K4 R3 + 0x880C0105, // 000F GETMBR R3 R0 K5 + 0x780E0010, // 0010 JMPF R3 #0022 + 0x8C0C0106, // 0011 GETMET R3 R0 K6 + 0x6014000A, // 0012 GETGBL R5 G10 + 0x88180105, // 0013 GETMBR R6 R0 K5 + 0x8C180D07, // 0014 GETMET R6 R6 K7 + 0x5C200200, // 0015 MOVE R8 R1 + 0x7C180400, // 0016 CALL R6 2 + 0x7C140200, // 0017 CALL R5 1 + 0x7C0C0400, // 0018 CALL R3 2 + 0x4C100000, // 0019 LDNIL R4 + 0x20100604, // 001A NE R4 R3 R4 + 0x78120005, // 001B JMPF R4 #0022 + 0x88100108, // 001C GETMBR R4 R0 K8 + 0x20100604, // 001D NE R4 R3 R4 + 0x78120002, // 001E JMPF R4 #0022 + 0x8C100109, // 001F GETMET R4 R0 K9 + 0x7C100200, // 0020 CALL R4 1 + 0x90021003, // 0021 SETMBR R0 K8 R3 + 0x80000000, // 0022 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: filter_name_html +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_filter_name_html, /* name */ + be_nested_proto( + 9, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota_sensor_filter), + /* K1 */ be_nested_str_weak(string), + /* K2 */ be_nested_str_weak(webserver), + /* K3 */ be_nested_str_weak(html_escape), + /* K4 */ be_nested_str_weak(split), + /* K5 */ be_nested_str_weak(_X23), + /* K6 */ be_const_int(0), + /* K7 */ be_nested_str_weak(), + }), + be_str_weak(filter_name_html), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x78060009, // 0001 JMPF R1 #000C + 0xA4060200, // 0002 IMPORT R1 K1 + 0xA40A0400, // 0003 IMPORT R2 K2 + 0x8C0C0503, // 0004 GETMET R3 R2 K3 + 0x8C140304, // 0005 GETMET R5 R1 K4 + 0x881C0100, // 0006 GETMBR R7 R0 K0 + 0x58200005, // 0007 LDCONST R8 K5 + 0x7C140600, // 0008 CALL R5 3 + 0x94140B06, // 0009 GETIDX R5 R5 K6 + 0x7C0C0400, // 000A CALL R3 2 + 0x80040600, // 000B RET 1 R3 + 0x80060E00, // 000C RET 1 K7 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pre_value +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_pre_value, /* name */ + be_nested_proto( + 2, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(pre_value), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80040200, // 0000 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_Sensor +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Bridge_HTTP; +be_local_class(Matter_Plugin_Bridge_Sensor, + 5, + &be_class_Matter_Plugin_Bridge_HTTP, + be_nested_map(22, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(tasmota_sensor_filter, -1), be_const_var(0) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(Filter_X20pattern) }, + { be_const_key_weak(shadow_value, -1), be_const_var(2) }, + { be_const_key_weak(pre_value, 10), be_const_closure(Matter_Plugin_Bridge_Sensor_pre_value_closure) }, + { be_const_key_weak(ARG_HTTP, -1), be_nested_str_weak(url) }, + { be_const_key_weak(pressure_unit, -1), be_const_var(4) }, + { be_const_key_weak(tasmota_sensor_matcher, -1), be_const_var(1) }, + { be_const_key_weak(ARG, -1), be_nested_str_weak(filter) }, + { be_const_key_weak(PRESSURE_MMHG, -1), be_nested_str_weak(mmHg) }, + { be_const_key_weak(value_changed, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_value_changed_closure) }, + { be_const_key_weak(parse_update, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_parse_update_closure) }, + { be_const_key_weak(TEMP_C, -1), be_nested_str_weak(C) }, + { be_const_key_weak(temp_unit, 4), be_const_var(3) }, + { be_const_key_weak(PRESSURE_INHG, -1), be_nested_str_weak(inHg) }, + { be_const_key_weak(PRESSURE_HPA, 18), be_nested_str_weak(hPa) }, + { be_const_key_weak(PROBE_TIMEOUT, 16), be_const_int(1700) }, + { be_const_key_weak(web_values_prefix, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_web_values_prefix_closure) }, + { be_const_key_weak(UPDATE_CMD, 13), be_nested_str_weak(Status_X208) }, + { be_const_key_weak(TEMP_F, -1), be_nested_str_weak(F) }, + { be_const_key_weak(filter_name_html, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_filter_name_html_closure) }, + { be_const_key_weak(UPDATE_TIME, 3), be_const_int(5000) }, + { be_const_key_weak(parse_configuration, 2), be_const_closure(Matter_Plugin_Bridge_Sensor_parse_configuration_closure) }, + })), + be_str_weak(Matter_Plugin_Bridge_Sensor) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_Sensor_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_Sensor); + be_setglobal(vm, "Matter_Plugin_Bridge_Sensor"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Light1.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Light1.h new file mode 100644 index 000000000000..2d227550a83c --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Light1.h @@ -0,0 +1,663 @@ +/* Solidification of Matter_Plugin_3_Light1.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Light1; + +/******************************************************************** +** Solidified function: set_bri +********************************************************************/ +be_local_closure(Matter_Plugin_Light1_set_bri, /* name */ + be_nested_proto( + 11, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(VIRTUAL), + /* K2 */ be_nested_str_weak(light), + /* K3 */ be_nested_str_weak(tasmota), + /* K4 */ be_nested_str_weak(scale_uint), + /* K5 */ be_nested_str_weak(set), + /* K6 */ be_nested_str_weak(bri), + /* K7 */ be_nested_str_weak(power), + /* K8 */ be_nested_str_weak(update_shadow), + /* K9 */ be_nested_str_weak(shadow_onoff), + /* K10 */ be_nested_str_weak(attribute_updated), + /* K11 */ be_nested_str_weak(shadow_bri), + }), + be_str_weak(set_bri), + &be_const_str_solidified, + ( &(const binstruction[65]) { /* code */ + 0x140C0300, // 0000 LT R3 R1 K0 + 0x780E0000, // 0001 JMPF R3 #0003 + 0x58040000, // 0002 LDCONST R1 K0 + 0x540E00FD, // 0003 LDINT R3 254 + 0x240C0203, // 0004 GT R3 R1 R3 + 0x780E0000, // 0005 JMPF R3 #0007 + 0x540600FD, // 0006 LDINT R1 254 + 0x4C0C0000, // 0007 LDNIL R3 + 0x200C0403, // 0008 NE R3 R2 R3 + 0x780E0003, // 0009 JMPF R3 #000E + 0x600C0017, // 000A GETGBL R3 G23 + 0x5C100400, // 000B MOVE R4 R2 + 0x7C0C0200, // 000C CALL R3 1 + 0x70020000, // 000D JMP #000F + 0x4C0C0000, // 000E LDNIL R3 + 0x5C080600, // 000F MOVE R2 R3 + 0x880C0101, // 0010 GETMBR R3 R0 K1 + 0x740E001A, // 0011 JMPT R3 #002D + 0xA40E0400, // 0012 IMPORT R3 K2 + 0xB8120600, // 0013 GETNGBL R4 K3 + 0x8C100904, // 0014 GETMET R4 R4 K4 + 0x5C180200, // 0015 MOVE R6 R1 + 0x581C0000, // 0016 LDCONST R7 K0 + 0x542200FD, // 0017 LDINT R8 254 + 0x58240000, // 0018 LDCONST R9 K0 + 0x542A00FE, // 0019 LDINT R10 255 + 0x7C100C00, // 001A CALL R4 6 + 0x4C140000, // 001B LDNIL R5 + 0x1C140405, // 001C EQ R5 R2 R5 + 0x78160005, // 001D JMPF R5 #0024 + 0x8C140705, // 001E GETMET R5 R3 K5 + 0x601C0013, // 001F GETGBL R7 G19 + 0x7C1C0000, // 0020 CALL R7 0 + 0x981E0C04, // 0021 SETIDX R7 K6 R4 + 0x7C140400, // 0022 CALL R5 2 + 0x70020005, // 0023 JMP #002A + 0x8C140705, // 0024 GETMET R5 R3 K5 + 0x601C0013, // 0025 GETGBL R7 G19 + 0x7C1C0000, // 0026 CALL R7 0 + 0x981E0C04, // 0027 SETIDX R7 K6 R4 + 0x981E0E02, // 0028 SETIDX R7 K7 R2 + 0x7C140400, // 0029 CALL R5 2 + 0x8C140108, // 002A GETMET R5 R0 K8 + 0x7C140200, // 002B CALL R5 1 + 0x70020012, // 002C JMP #0040 + 0x4C0C0000, // 002D LDNIL R3 + 0x200C0403, // 002E NE R3 R2 R3 + 0x780E0007, // 002F JMPF R3 #0038 + 0x880C0109, // 0030 GETMBR R3 R0 K9 + 0x200C0403, // 0031 NE R3 R2 R3 + 0x780E0004, // 0032 JMPF R3 #0038 + 0x8C0C010A, // 0033 GETMET R3 R0 K10 + 0x54160005, // 0034 LDINT R5 6 + 0x58180000, // 0035 LDCONST R6 K0 + 0x7C0C0600, // 0036 CALL R3 3 + 0x90021202, // 0037 SETMBR R0 K9 R2 + 0x880C010B, // 0038 GETMBR R3 R0 K11 + 0x200C0203, // 0039 NE R3 R1 R3 + 0x780E0004, // 003A JMPF R3 #0040 + 0x8C0C010A, // 003B GETMET R3 R0 K10 + 0x54160007, // 003C LDINT R5 8 + 0x58180000, // 003D LDCONST R6 K0 + 0x7C0C0600, // 003E CALL R3 3 + 0x90021601, // 003F SETMBR R0 K11 R1 + 0x80000000, // 0040 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_Light1_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(shadow_bri), + /* K2 */ be_const_int(0), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x90020302, // 0008 SETMBR R0 K1 K2 + 0x80000000, // 0009 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_shadow +********************************************************************/ +be_local_closure(Matter_Plugin_Light1_update_shadow, /* name */ + be_nested_proto( + 11, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(VIRTUAL), + /* K1 */ be_nested_str_weak(light), + /* K2 */ be_nested_str_weak(get), + /* K3 */ be_nested_str_weak(find), + /* K4 */ be_nested_str_weak(bri), + /* K5 */ be_nested_str_weak(tasmota), + /* K6 */ be_nested_str_weak(scale_uint), + /* K7 */ be_const_int(0), + /* K8 */ be_nested_str_weak(shadow_bri), + /* K9 */ be_nested_str_weak(attribute_updated), + /* K10 */ be_nested_str_weak(update_shadow), + }), + be_str_weak(update_shadow), + &be_const_str_solidified, + ( &(const binstruction[38]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x7406001D, // 0001 JMPT R1 #0020 + 0xA4060200, // 0002 IMPORT R1 K1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x7C080200, // 0004 CALL R2 1 + 0x4C0C0000, // 0005 LDNIL R3 + 0x200C0403, // 0006 NE R3 R2 R3 + 0x780E0017, // 0007 JMPF R3 #0020 + 0x8C0C0503, // 0008 GETMET R3 R2 K3 + 0x58140004, // 0009 LDCONST R5 K4 + 0x4C180000, // 000A LDNIL R6 + 0x7C0C0600, // 000B CALL R3 3 + 0x4C100000, // 000C LDNIL R4 + 0x20100604, // 000D NE R4 R3 R4 + 0x78120010, // 000E JMPF R4 #0020 + 0xB8120A00, // 000F GETNGBL R4 K5 + 0x8C100906, // 0010 GETMET R4 R4 K6 + 0x5C180600, // 0011 MOVE R6 R3 + 0x581C0007, // 0012 LDCONST R7 K7 + 0x542200FE, // 0013 LDINT R8 255 + 0x58240007, // 0014 LDCONST R9 K7 + 0x542A00FD, // 0015 LDINT R10 254 + 0x7C100C00, // 0016 CALL R4 6 + 0x5C0C0800, // 0017 MOVE R3 R4 + 0x88100108, // 0018 GETMBR R4 R0 K8 + 0x20100604, // 0019 NE R4 R3 R4 + 0x78120004, // 001A JMPF R4 #0020 + 0x8C100109, // 001B GETMET R4 R0 K9 + 0x541A0007, // 001C LDINT R6 8 + 0x581C0007, // 001D LDCONST R7 K7 + 0x7C100600, // 001E CALL R4 3 + 0x90021003, // 001F SETMBR R0 K8 R3 + 0x60040003, // 0020 GETGBL R1 G3 + 0x5C080000, // 0021 MOVE R2 R0 + 0x7C040200, // 0022 CALL R1 1 + 0x8C04030A, // 0023 GETMET R1 R1 K10 + 0x7C040200, // 0024 CALL R1 1 + 0x80000000, // 0025 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Light1_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(U1), + /* K8 */ be_nested_str_weak(shadow_bri), + /* K9 */ be_const_int(2), + /* K10 */ be_const_int(3), + /* K11 */ be_nested_str_weak(U4), + /* K12 */ be_const_int(1), + /* K13 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[79]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0007, // 0004 LDINT R7 8 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E003D, // 0006 JMPF R7 #0045 + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x1C1C0D05, // 0009 EQ R7 R6 K5 + 0x781E0005, // 000A JMPF R7 #0011 + 0x8C1C0706, // 000B GETMET R7 R3 K6 + 0x88240907, // 000C GETMBR R9 R4 K7 + 0x88280108, // 000D GETMBR R10 R0 K8 + 0x7C1C0600, // 000E CALL R7 3 + 0x80040E00, // 000F RET 1 R7 + 0x70020032, // 0010 JMP #0044 + 0x1C1C0D09, // 0011 EQ R7 R6 K9 + 0x781E0005, // 0012 JMPF R7 #0019 + 0x8C1C0706, // 0013 GETMET R7 R3 K6 + 0x88240907, // 0014 GETMBR R9 R4 K7 + 0x58280005, // 0015 LDCONST R10 K5 + 0x7C1C0600, // 0016 CALL R7 3 + 0x80040E00, // 0017 RET 1 R7 + 0x7002002A, // 0018 JMP #0044 + 0x1C1C0D0A, // 0019 EQ R7 R6 K10 + 0x781E0005, // 001A JMPF R7 #0021 + 0x8C1C0706, // 001B GETMET R7 R3 K6 + 0x88240907, // 001C GETMBR R9 R4 K7 + 0x542A00FD, // 001D LDINT R10 254 + 0x7C1C0600, // 001E CALL R7 3 + 0x80040E00, // 001F RET 1 R7 + 0x70020022, // 0020 JMP #0044 + 0x541E000E, // 0021 LDINT R7 15 + 0x1C1C0C07, // 0022 EQ R7 R6 R7 + 0x781E0005, // 0023 JMPF R7 #002A + 0x8C1C0706, // 0024 GETMET R7 R3 K6 + 0x88240907, // 0025 GETMBR R9 R4 K7 + 0x58280005, // 0026 LDCONST R10 K5 + 0x7C1C0600, // 0027 CALL R7 3 + 0x80040E00, // 0028 RET 1 R7 + 0x70020019, // 0029 JMP #0044 + 0x541E0010, // 002A LDINT R7 17 + 0x1C1C0C07, // 002B EQ R7 R6 R7 + 0x781E0005, // 002C JMPF R7 #0033 + 0x8C1C0706, // 002D GETMET R7 R3 K6 + 0x88240907, // 002E GETMBR R9 R4 K7 + 0x88280108, // 002F GETMBR R10 R0 K8 + 0x7C1C0600, // 0030 CALL R7 3 + 0x80040E00, // 0031 RET 1 R7 + 0x70020010, // 0032 JMP #0044 + 0x541EFFFB, // 0033 LDINT R7 65532 + 0x1C1C0C07, // 0034 EQ R7 R6 R7 + 0x781E0005, // 0035 JMPF R7 #003C + 0x8C1C0706, // 0036 GETMET R7 R3 K6 + 0x8824090B, // 0037 GETMBR R9 R4 K11 + 0x5828000C, // 0038 LDCONST R10 K12 + 0x7C1C0600, // 0039 CALL R7 3 + 0x80040E00, // 003A RET 1 R7 + 0x70020007, // 003B JMP #0044 + 0x541EFFFC, // 003C LDINT R7 65533 + 0x1C1C0C07, // 003D EQ R7 R6 R7 + 0x781E0004, // 003E JMPF R7 #0044 + 0x8C1C0706, // 003F GETMET R7 R3 K6 + 0x8824090B, // 0040 GETMBR R9 R4 K11 + 0x542A0004, // 0041 LDINT R10 5 + 0x7C1C0600, // 0042 CALL R7 3 + 0x80040E00, // 0043 RET 1 R7 + 0x70020008, // 0044 JMP #004E + 0x601C0003, // 0045 GETGBL R7 G3 + 0x5C200000, // 0046 MOVE R8 R0 + 0x7C1C0200, // 0047 CALL R7 1 + 0x8C1C0F0D, // 0048 GETMET R7 R7 K13 + 0x5C240200, // 0049 MOVE R9 R1 + 0x5C280400, // 004A MOVE R10 R2 + 0x5C2C0600, // 004B MOVE R11 R3 + 0x7C1C0800, // 004C CALL R7 4 + 0x80040E00, // 004D RET 1 R7 + 0x80000000, // 004E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_virtual +********************************************************************/ +be_local_closure(Matter_Plugin_Light1_update_virtual, /* name */ + be_nested_proto( + 8, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(find), + /* K1 */ be_nested_str_weak(Power), + /* K2 */ be_nested_str_weak(Bri), + /* K3 */ be_nested_str_weak(set_bri), + /* K4 */ be_nested_str_weak(update_virtual), + }), + be_str_weak(update_virtual), + &be_const_str_solidified, + ( &(const binstruction[23]) { /* code */ + 0x8C080300, // 0000 GETMET R2 R1 K0 + 0x58100001, // 0001 LDCONST R4 K1 + 0x7C080400, // 0002 CALL R2 2 + 0x8C0C0300, // 0003 GETMET R3 R1 K0 + 0x58140002, // 0004 LDCONST R5 K2 + 0x7C0C0400, // 0005 CALL R3 2 + 0x4C100000, // 0006 LDNIL R4 + 0x20100604, // 0007 NE R4 R3 R4 + 0x78120006, // 0008 JMPF R4 #0010 + 0x8C100103, // 0009 GETMET R4 R0 K3 + 0x60180009, // 000A GETGBL R6 G9 + 0x5C1C0600, // 000B MOVE R7 R3 + 0x7C180200, // 000C CALL R6 1 + 0x5C1C0400, // 000D MOVE R7 R2 + 0x7C100600, // 000E CALL R4 3 + 0x80000800, // 000F RET 0 + 0x60100003, // 0010 GETGBL R4 G3 + 0x5C140000, // 0011 MOVE R5 R0 + 0x7C100200, // 0012 CALL R4 1 + 0x8C100904, // 0013 GETMET R4 R4 K4 + 0x5C180200, // 0014 MOVE R6 R1 + 0x7C100400, // 0015 CALL R4 2 + 0x80000000, // 0016 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: invoke_request +********************************************************************/ +be_local_closure(Matter_Plugin_Light1_invoke_request, /* name */ + be_nested_proto( + 22, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[21]) { /* constants */ + /* K0 */ be_nested_str_weak(light), + /* K1 */ be_nested_str_weak(matter), + /* K2 */ be_nested_str_weak(TLV), + /* K3 */ be_nested_str_weak(cluster), + /* K4 */ be_nested_str_weak(command), + /* K5 */ be_nested_str_weak(update_shadow_lazy), + /* K6 */ be_const_int(0), + /* K7 */ be_nested_str_weak(findsubval), + /* K8 */ be_nested_str_weak(set_bri), + /* K9 */ be_nested_str_weak(log), + /* K10 */ be_nested_str_weak(bri_X3A), + /* K11 */ be_nested_str_weak(publish_command), + /* K12 */ be_nested_str_weak(Bri), + /* K13 */ be_nested_str_weak(Dimmer), + /* K14 */ be_nested_str_weak(tasmota), + /* K15 */ be_nested_str_weak(scale_uint), + /* K16 */ be_const_int(1), + /* K17 */ be_const_int(2), + /* K18 */ be_const_int(3), + /* K19 */ be_nested_str_weak(Power), + /* K20 */ be_nested_str_weak(invoke_request), + }), + be_str_weak(invoke_request), + &be_const_str_solidified, + ( &(const binstruction[119]) { /* code */ + 0xA4120000, // 0000 IMPORT R4 K0 + 0xB8160200, // 0001 GETNGBL R5 K1 + 0x88140B02, // 0002 GETMBR R5 R5 K2 + 0x88180703, // 0003 GETMBR R6 R3 K3 + 0x881C0704, // 0004 GETMBR R7 R3 K4 + 0x54220007, // 0005 LDINT R8 8 + 0x1C200C08, // 0006 EQ R8 R6 R8 + 0x78220064, // 0007 JMPF R8 #006D + 0x8C200105, // 0008 GETMET R8 R0 K5 + 0x7C200200, // 0009 CALL R8 1 + 0x1C200F06, // 000A EQ R8 R7 K6 + 0x7822001A, // 000B JMPF R8 #0027 + 0x8C200507, // 000C GETMET R8 R2 K7 + 0x58280006, // 000D LDCONST R10 K6 + 0x7C200400, // 000E CALL R8 2 + 0x8C240108, // 000F GETMET R9 R0 K8 + 0x5C2C1000, // 0010 MOVE R11 R8 + 0x7C240400, // 0011 CALL R9 2 + 0x60240008, // 0012 GETGBL R9 G8 + 0x5C281000, // 0013 MOVE R10 R8 + 0x7C240200, // 0014 CALL R9 1 + 0x00261409, // 0015 ADD R9 K10 R9 + 0x900E1209, // 0016 SETMBR R3 K9 R9 + 0x8C24010B, // 0017 GETMET R9 R0 K11 + 0x582C000C, // 0018 LDCONST R11 K12 + 0x5C301000, // 0019 MOVE R12 R8 + 0x5834000D, // 001A LDCONST R13 K13 + 0xB83A1C00, // 001B GETNGBL R14 K14 + 0x8C381D0F, // 001C GETMET R14 R14 K15 + 0x5C401000, // 001D MOVE R16 R8 + 0x58440006, // 001E LDCONST R17 K6 + 0x544A00FD, // 001F LDINT R18 254 + 0x584C0006, // 0020 LDCONST R19 K6 + 0x54520063, // 0021 LDINT R20 100 + 0x7C380C00, // 0022 CALL R14 6 + 0x7C240A00, // 0023 CALL R9 5 + 0x50240200, // 0024 LDBOOL R9 1 0 + 0x80041200, // 0025 RET 1 R9 + 0x70020044, // 0026 JMP #006C + 0x1C200F10, // 0027 EQ R8 R7 K16 + 0x78220002, // 0028 JMPF R8 #002C + 0x50200200, // 0029 LDBOOL R8 1 0 + 0x80041000, // 002A RET 1 R8 + 0x7002003F, // 002B JMP #006C + 0x1C200F11, // 002C EQ R8 R7 K17 + 0x78220002, // 002D JMPF R8 #0031 + 0x50200200, // 002E LDBOOL R8 1 0 + 0x80041000, // 002F RET 1 R8 + 0x7002003A, // 0030 JMP #006C + 0x1C200F12, // 0031 EQ R8 R7 K18 + 0x78220002, // 0032 JMPF R8 #0036 + 0x50200200, // 0033 LDBOOL R8 1 0 + 0x80041000, // 0034 RET 1 R8 + 0x70020035, // 0035 JMP #006C + 0x54220003, // 0036 LDINT R8 4 + 0x1C200E08, // 0037 EQ R8 R7 R8 + 0x78220021, // 0038 JMPF R8 #005B + 0x8C200507, // 0039 GETMET R8 R2 K7 + 0x58280006, // 003A LDCONST R10 K6 + 0x7C200400, // 003B CALL R8 2 + 0x24241106, // 003C GT R9 R8 K6 + 0x8C280108, // 003D GETMET R10 R0 K8 + 0x5C301000, // 003E MOVE R12 R8 + 0x5C341200, // 003F MOVE R13 R9 + 0x7C280600, // 0040 CALL R10 3 + 0x60280008, // 0041 GETGBL R10 G8 + 0x5C2C1000, // 0042 MOVE R11 R8 + 0x7C280200, // 0043 CALL R10 1 + 0x002A140A, // 0044 ADD R10 K10 R10 + 0x900E120A, // 0045 SETMBR R3 K9 R10 + 0x8C28010B, // 0046 GETMET R10 R0 K11 + 0x5830000C, // 0047 LDCONST R12 K12 + 0x5C341000, // 0048 MOVE R13 R8 + 0x5838000D, // 0049 LDCONST R14 K13 + 0xB83E1C00, // 004A GETNGBL R15 K14 + 0x8C3C1F0F, // 004B GETMET R15 R15 K15 + 0x5C441000, // 004C MOVE R17 R8 + 0x58480006, // 004D LDCONST R18 K6 + 0x544E00FD, // 004E LDINT R19 254 + 0x58500006, // 004F LDCONST R20 K6 + 0x54560063, // 0050 LDINT R21 100 + 0x7C3C0C00, // 0051 CALL R15 6 + 0x58400013, // 0052 LDCONST R16 K19 + 0x78260001, // 0053 JMPF R9 #0056 + 0x58440010, // 0054 LDCONST R17 K16 + 0x70020000, // 0055 JMP #0057 + 0x58440006, // 0056 LDCONST R17 K6 + 0x7C280E00, // 0057 CALL R10 7 + 0x50280200, // 0058 LDBOOL R10 1 0 + 0x80041400, // 0059 RET 1 R10 + 0x70020010, // 005A JMP #006C + 0x54220004, // 005B LDINT R8 5 + 0x1C200E08, // 005C EQ R8 R7 R8 + 0x78220002, // 005D JMPF R8 #0061 + 0x50200200, // 005E LDBOOL R8 1 0 + 0x80041000, // 005F RET 1 R8 + 0x7002000A, // 0060 JMP #006C + 0x54220005, // 0061 LDINT R8 6 + 0x1C200E08, // 0062 EQ R8 R7 R8 + 0x78220002, // 0063 JMPF R8 #0067 + 0x50200200, // 0064 LDBOOL R8 1 0 + 0x80041000, // 0065 RET 1 R8 + 0x70020004, // 0066 JMP #006C + 0x54220006, // 0067 LDINT R8 7 + 0x1C200E08, // 0068 EQ R8 R7 R8 + 0x78220001, // 0069 JMPF R8 #006C + 0x50200200, // 006A LDBOOL R8 1 0 + 0x80041000, // 006B RET 1 R8 + 0x70020008, // 006C JMP #0076 + 0x60200003, // 006D GETGBL R8 G3 + 0x5C240000, // 006E MOVE R9 R0 + 0x7C200200, // 006F CALL R8 1 + 0x8C201114, // 0070 GETMET R8 R8 K20 + 0x5C280200, // 0071 MOVE R10 R1 + 0x5C2C0400, // 0072 MOVE R11 R2 + 0x5C300600, // 0073 MOVE R12 R3 + 0x7C200800, // 0074 CALL R8 4 + 0x80041000, // 0075 RET 1 R8 + 0x80000000, // 0076 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Light1 +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Light0; +be_local_class(Matter_Plugin_Light1, + 1, + &be_class_Matter_Plugin_Light0, + be_nested_map(12, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Light1_invoke_request_closure) }, + { be_const_key_weak(shadow_bri, 7), be_const_var(0) }, + { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(257, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(UPDATE_COMMANDS, 4), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(2, + ( (struct bvalue*) &(const bvalue[]) { + be_nested_str_weak(Power), + be_nested_str_weak(Bri), + })) ) } )) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Light1_init_closure) }, + { be_const_key_weak(update_shadow, -1), be_const_closure(Matter_Plugin_Light1_update_shadow_closure) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Light1_read_attribute_closure) }, + { be_const_key_weak(TYPE, 5), be_nested_str_weak(light1) }, + { be_const_key_weak(update_virtual, -1), be_const_closure(Matter_Plugin_Light1_update_virtual_closure) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Light_X201_X20Dimmer) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(7, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(29, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(8, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(2), + be_const_int(3), + be_const_int(15), + be_const_int(17), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(set_bri, 0), be_const_closure(Matter_Plugin_Light1_set_bri_closure) }, + })), + be_str_weak(Matter_Plugin_Light1) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Light1_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Light1); + be_setglobal(vm, "Matter_Plugin_Light1"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Contact.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Contact.h new file mode 100644 index 000000000000..79f11b865a0d --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Contact.h @@ -0,0 +1,464 @@ +/* Solidification of Matter_Plugin_3_Sensor_Contact.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Sensor_Contact; + +/******************************************************************** +** Solidified function: +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Contact__X3Clambda_X3E, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x60040009, // 0000 GETGBL R1 G9 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Contact_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(shadow_contact), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[11]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x50100000, // 0008 LDBOOL R4 0 0 + 0x90020204, // 0009 SETMBR R0 K1 R4 + 0x80000000, // 000A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_shadow +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Contact_update_shadow, /* name */ + be_nested_proto( + 9, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(update_shadow), + /* K1 */ be_nested_str_weak(json), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(cmd), + /* K4 */ be_nested_str_weak(Status_X208), + /* K5 */ be_nested_str_weak(load), + /* K6 */ be_nested_str_weak(find), + /* K7 */ be_nested_str_weak(Switch), + /* K8 */ be_nested_str_weak(tasmota_switch_index), + /* K9 */ be_nested_str_weak(ON), + /* K10 */ be_nested_str_weak(shadow_contact), + /* K11 */ be_nested_str_weak(attribute_updated), + /* K12 */ be_const_int(0), + }), + be_str_weak(update_shadow), + &be_const_str_solidified, + ( &(const binstruction[38]) { /* code */ + 0x60040003, // 0000 GETGBL R1 G3 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x8C040300, // 0003 GETMET R1 R1 K0 + 0x7C040200, // 0004 CALL R1 1 + 0xA4060200, // 0005 IMPORT R1 K1 + 0xB80A0400, // 0006 GETNGBL R2 K2 + 0x8C080503, // 0007 GETMET R2 R2 K3 + 0x58100004, // 0008 LDCONST R4 K4 + 0x50140200, // 0009 LDBOOL R5 1 0 + 0x7C080600, // 000A CALL R2 3 + 0x4C0C0000, // 000B LDNIL R3 + 0x200C0403, // 000C NE R3 R2 R3 + 0x780E0016, // 000D JMPF R3 #0025 + 0x8C0C0305, // 000E GETMET R3 R1 K5 + 0x5C140400, // 000F MOVE R5 R2 + 0x7C0C0400, // 0010 CALL R3 2 + 0x4C100000, // 0011 LDNIL R4 + 0x20100604, // 0012 NE R4 R3 R4 + 0x78120010, // 0013 JMPF R4 #0025 + 0x50100000, // 0014 LDBOOL R4 0 0 + 0x8C140706, // 0015 GETMET R5 R3 K6 + 0x601C0008, // 0016 GETGBL R7 G8 + 0x88200108, // 0017 GETMBR R8 R0 K8 + 0x7C1C0200, // 0018 CALL R7 1 + 0x001E0E07, // 0019 ADD R7 K7 R7 + 0x7C140400, // 001A CALL R5 2 + 0x1C140B09, // 001B EQ R5 R5 K9 + 0x5C100A00, // 001C MOVE R4 R5 + 0x8814010A, // 001D GETMBR R5 R0 K10 + 0x20140A04, // 001E NE R5 R5 R4 + 0x78160004, // 001F JMPF R5 #0025 + 0x8C14010B, // 0020 GETMET R5 R0 K11 + 0x541E0044, // 0021 LDINT R7 69 + 0x5820000C, // 0022 LDCONST R8 K12 + 0x7C140600, // 0023 CALL R5 3 + 0x90021404, // 0024 SETMBR R0 K10 R4 + 0x80000000, // 0025 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Contact_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(shadow_contact), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(BOOL), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_nested_str_weak(U4), + /* K10 */ be_const_int(1), + /* K11 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[53]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0044, // 0004 LDINT R7 69 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0023, // 0006 JMPF R7 #002B + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E000F, // 0008 JMPF R7 #0019 + 0x881C0105, // 0009 GETMBR R7 R0 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E0005, // 000C JMPF R7 #0013 + 0x8C1C0706, // 000D GETMET R7 R3 K6 + 0x88240907, // 000E GETMBR R9 R4 K7 + 0x88280105, // 000F GETMBR R10 R0 K5 + 0x7C1C0600, // 0010 CALL R7 3 + 0x80040E00, // 0011 RET 1 R7 + 0x70020004, // 0012 JMP #0018 + 0x8C1C0706, // 0013 GETMET R7 R3 K6 + 0x88240908, // 0014 GETMBR R9 R4 K8 + 0x4C280000, // 0015 LDNIL R10 + 0x7C1C0600, // 0016 CALL R7 3 + 0x80040E00, // 0017 RET 1 R7 + 0x70020010, // 0018 JMP #002A + 0x541EFFFB, // 0019 LDINT R7 65532 + 0x1C1C0C07, // 001A EQ R7 R6 R7 + 0x781E0005, // 001B JMPF R7 #0022 + 0x8C1C0706, // 001C GETMET R7 R3 K6 + 0x88240909, // 001D GETMBR R9 R4 K9 + 0x58280004, // 001E LDCONST R10 K4 + 0x7C1C0600, // 001F CALL R7 3 + 0x80040E00, // 0020 RET 1 R7 + 0x70020007, // 0021 JMP #002A + 0x541EFFFC, // 0022 LDINT R7 65533 + 0x1C1C0C07, // 0023 EQ R7 R6 R7 + 0x781E0004, // 0024 JMPF R7 #002A + 0x8C1C0706, // 0025 GETMET R7 R3 K6 + 0x88240909, // 0026 GETMBR R9 R4 K9 + 0x5828000A, // 0027 LDCONST R10 K10 + 0x7C1C0600, // 0028 CALL R7 3 + 0x80040E00, // 0029 RET 1 R7 + 0x70020008, // 002A JMP #0034 + 0x601C0003, // 002B GETGBL R7 G3 + 0x5C200000, // 002C MOVE R8 R0 + 0x7C1C0200, // 002D CALL R7 1 + 0x8C1C0F0B, // 002E GETMET R7 R7 K11 + 0x5C240200, // 002F MOVE R9 R1 + 0x5C280400, // 0030 MOVE R10 R2 + 0x5C2C0600, // 0031 MOVE R11 R3 + 0x7C1C0800, // 0032 CALL R7 4 + 0x80040E00, // 0033 RET 1 R7 + 0x80000000, // 0034 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_configuration +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Contact_parse_configuration, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota_switch_index), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(ARG), + /* K3 */ be_const_int(1), + /* K4 */ be_const_int(0), + }), + be_str_weak(parse_configuration), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x60080009, // 0000 GETGBL R2 G9 + 0x8C0C0301, // 0001 GETMET R3 R1 K1 + 0x88140102, // 0002 GETMBR R5 R0 K2 + 0x58180003, // 0003 LDCONST R6 K3 + 0x7C0C0600, // 0004 CALL R3 3 + 0x7C080200, // 0005 CALL R2 1 + 0x90020002, // 0006 SETMBR R0 K0 R2 + 0x88080100, // 0007 GETMBR R2 R0 K0 + 0x18080504, // 0008 LE R2 R2 K4 + 0x780A0000, // 0009 JMPF R2 #000B + 0x90020103, // 000A SETMBR R0 K0 K3 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_virtual +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Contact_update_virtual, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(find), + /* K1 */ be_nested_str_weak(Contact), + /* K2 */ be_nested_str_weak(shadow_contact), + /* K3 */ be_nested_str_weak(attribute_updated), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(update_virtual), + }), + be_str_weak(update_virtual), + &be_const_str_solidified, + ( &(const binstruction[25]) { /* code */ + 0x8C080300, // 0000 GETMET R2 R1 K0 + 0x58100001, // 0001 LDCONST R4 K1 + 0x7C080400, // 0002 CALL R2 2 + 0x4C0C0000, // 0003 LDNIL R3 + 0x200C0403, // 0004 NE R3 R2 R3 + 0x780E000B, // 0005 JMPF R3 #0012 + 0x600C0017, // 0006 GETGBL R3 G23 + 0x5C100400, // 0007 MOVE R4 R2 + 0x7C0C0200, // 0008 CALL R3 1 + 0x5C080600, // 0009 MOVE R2 R3 + 0x880C0102, // 000A GETMBR R3 R0 K2 + 0x200C0602, // 000B NE R3 R3 R2 + 0x780E0004, // 000C JMPF R3 #0012 + 0x8C0C0103, // 000D GETMET R3 R0 K3 + 0x54160044, // 000E LDINT R5 69 + 0x58180004, // 000F LDCONST R6 K4 + 0x7C0C0600, // 0010 CALL R3 3 + 0x90020402, // 0011 SETMBR R0 K2 R2 + 0x600C0003, // 0012 GETGBL R3 G3 + 0x5C100000, // 0013 MOVE R4 R0 + 0x7C0C0200, // 0014 CALL R3 1 + 0x8C0C0705, // 0015 GETMET R3 R3 K5 + 0x5C140200, // 0016 MOVE R5 R1 + 0x7C0C0400, // 0017 CALL R3 2 + 0x80000000, // 0018 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: append_state_json +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Contact_append_state_json, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(_X2C_X22Contact_X22_X3A_X25s), + /* K1 */ be_nested_str_weak(shadow_contact), + }), + be_str_weak(append_state_json), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x60040018, // 0000 GETGBL R1 G24 + 0x58080000, // 0001 LDCONST R2 K0 + 0x600C0009, // 0002 GETGBL R3 G9 + 0x88100101, // 0003 GETMBR R4 R0 K1 + 0x7C0C0200, // 0004 CALL R3 1 + 0x7C040400, // 0005 CALL R1 2 + 0x80040200, // 0006 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Sensor_Contact +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Device; +be_local_class(Matter_Plugin_Sensor_Contact, + 2, + &be_class_Matter_Plugin_Device, + be_nested_map(16, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(ARG_TYPE, 6), be_const_static_closure(Matter_Plugin_Sensor_Contact__X3Clambda_X3E_closure) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(Switch_X3Cx_X3E_X20number) }, + { be_const_key_weak(shadow_contact, 4), be_const_var(1) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Sensor_Contact_init_closure) }, + { be_const_key_weak(append_state_json, -1), be_const_closure(Matter_Plugin_Sensor_Contact_append_state_json_closure) }, + { be_const_key_weak(update_shadow, 12), be_const_closure(Matter_Plugin_Sensor_Contact_update_shadow_closure) }, + { be_const_key_weak(update_virtual, -1), be_const_closure(Matter_Plugin_Sensor_Contact_update_virtual_closure) }, + { be_const_key_weak(ARG, -1), be_nested_str_weak(switch) }, + { be_const_key_weak(UPDATE_TIME, -1), be_const_int(750) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Contact) }, + { be_const_key_weak(CLUSTERS, 11), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(3, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(69, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(TYPES, 14), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(21, -1), be_const_int(1) }, + })) ) } )) }, + { be_const_key_weak(parse_configuration, -1), be_const_closure(Matter_Plugin_Sensor_Contact_parse_configuration_closure) }, + { be_const_key_weak(TYPE, 9), be_nested_str_weak(contact) }, + { be_const_key_weak(read_attribute, 15), be_const_closure(Matter_Plugin_Sensor_Contact_read_attribute_closure) }, + { be_const_key_weak(tasmota_switch_index, -1), be_const_var(0) }, + })), + be_str_weak(Matter_Plugin_Sensor_Contact) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Sensor_Contact_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor_Contact); + be_setglobal(vm, "Matter_Plugin_Sensor_Contact"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Humidity.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Humidity.h new file mode 100644 index 000000000000..f4e9ebc3a3f1 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Humidity.h @@ -0,0 +1,279 @@ +/* Solidification of Matter_Plugin_3_Sensor_Humidity.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Sensor_Humidity; + +/******************************************************************** +** Solidified function: value_changed +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Humidity_value_changed, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(attribute_updated), + /* K1 */ be_const_int(0), + }), + be_str_weak(value_changed), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x540E0404, // 0001 LDINT R3 1029 + 0x58100001, // 0002 LDCONST R4 K1 + 0x7C040600, // 0003 CALL R1 3 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Humidity_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(shadow_value), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(U2), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_const_int(1), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str_weak(U4), + /* K12 */ be_const_int(3), + /* K13 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[71]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0404, // 0004 LDINT R7 1029 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0035, // 0006 JMPF R7 #003D + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E0011, // 0008 JMPF R7 #001B + 0x881C0105, // 0009 GETMBR R7 R0 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E0007, // 000C JMPF R7 #0015 + 0x8C1C0706, // 000D GETMET R7 R3 K6 + 0x88240907, // 000E GETMBR R9 R4 K7 + 0x60280009, // 000F GETGBL R10 G9 + 0x882C0105, // 0010 GETMBR R11 R0 K5 + 0x7C280200, // 0011 CALL R10 1 + 0x7C1C0600, // 0012 CALL R7 3 + 0x80040E00, // 0013 RET 1 R7 + 0x70020004, // 0014 JMP #001A + 0x8C1C0706, // 0015 GETMET R7 R3 K6 + 0x88240908, // 0016 GETMBR R9 R4 K8 + 0x4C280000, // 0017 LDNIL R10 + 0x7C1C0600, // 0018 CALL R7 3 + 0x80040E00, // 0019 RET 1 R7 + 0x70020020, // 001A JMP #003C + 0x1C1C0D09, // 001B EQ R7 R6 K9 + 0x781E0005, // 001C JMPF R7 #0023 + 0x8C1C0706, // 001D GETMET R7 R3 K6 + 0x88240907, // 001E GETMBR R9 R4 K7 + 0x542A01F3, // 001F LDINT R10 500 + 0x7C1C0600, // 0020 CALL R7 3 + 0x80040E00, // 0021 RET 1 R7 + 0x70020018, // 0022 JMP #003C + 0x1C1C0D0A, // 0023 EQ R7 R6 K10 + 0x781E0005, // 0024 JMPF R7 #002B + 0x8C1C0706, // 0025 GETMET R7 R3 K6 + 0x88240907, // 0026 GETMBR R9 R4 K7 + 0x542A270F, // 0027 LDINT R10 10000 + 0x7C1C0600, // 0028 CALL R7 3 + 0x80040E00, // 0029 RET 1 R7 + 0x70020010, // 002A JMP #003C + 0x541EFFFB, // 002B LDINT R7 65532 + 0x1C1C0C07, // 002C EQ R7 R6 R7 + 0x781E0005, // 002D JMPF R7 #0034 + 0x8C1C0706, // 002E GETMET R7 R3 K6 + 0x8824090B, // 002F GETMBR R9 R4 K11 + 0x58280004, // 0030 LDCONST R10 K4 + 0x7C1C0600, // 0031 CALL R7 3 + 0x80040E00, // 0032 RET 1 R7 + 0x70020007, // 0033 JMP #003C + 0x541EFFFC, // 0034 LDINT R7 65533 + 0x1C1C0C07, // 0035 EQ R7 R6 R7 + 0x781E0004, // 0036 JMPF R7 #003C + 0x8C1C0706, // 0037 GETMET R7 R3 K6 + 0x8824090B, // 0038 GETMBR R9 R4 K11 + 0x5828000C, // 0039 LDCONST R10 K12 + 0x7C1C0600, // 003A CALL R7 3 + 0x80040E00, // 003B RET 1 R7 + 0x70020008, // 003C JMP #0046 + 0x601C0003, // 003D GETGBL R7 G3 + 0x5C200000, // 003E MOVE R8 R0 + 0x7C1C0200, // 003F CALL R7 1 + 0x8C1C0F0D, // 0040 GETMET R7 R7 K13 + 0x5C240200, // 0041 MOVE R9 R1 + 0x5C280400, // 0042 MOVE R10 R2 + 0x5C2C0600, // 0043 MOVE R11 R3 + 0x7C1C0800, // 0044 CALL R7 4 + 0x80040E00, // 0045 RET 1 R7 + 0x80000000, // 0046 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pre_value +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Humidity_pre_value, /* name */ + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(pre_value), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x20080202, // 0001 NE R2 R1 R2 + 0x780A0004, // 0002 JMPF R2 #0008 + 0x60080009, // 0003 GETGBL R2 G9 + 0x540E0063, // 0004 LDINT R3 100 + 0x080C0203, // 0005 MUL R3 R1 R3 + 0x7C080200, // 0006 CALL R2 1 + 0x70020000, // 0007 JMP #0009 + 0x4C080000, // 0008 LDNIL R2 + 0x80040400, // 0009 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Sensor_Humidity +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Sensor; +be_local_class(Matter_Plugin_Sensor_Humidity, + 0, + &be_class_Matter_Plugin_Sensor, + be_nested_map(9, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Humidity) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(humidity) }, + { be_const_key_weak(TYPES, 8), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(775, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(UPDATE_COMMANDS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(1, + ( (struct bvalue*) &(const bvalue[]) { + be_nested_str_weak(Humidity), + })) ) } )) }, + { be_const_key_weak(value_changed, 7), be_const_closure(Matter_Plugin_Sensor_Humidity_value_changed_closure) }, + { be_const_key_weak(JSON_NAME, -1), be_nested_str_weak(Humidity) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Sensor_Humidity_read_attribute_closure) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(3, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(1029, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(5, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(pre_value, -1), be_const_closure(Matter_Plugin_Sensor_Humidity_pre_value_closure) }, + })), + be_str_weak(Matter_Plugin_Sensor_Humidity) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Sensor_Humidity_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor_Humidity); + be_setglobal(vm, "Matter_Plugin_Sensor_Humidity"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Illuminance.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Illuminance.h new file mode 100644 index 000000000000..17b96ce221bd --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Illuminance.h @@ -0,0 +1,291 @@ +/* Solidification of Matter_Plugin_3_Sensor_Illuminance.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Sensor_Illuminance; + +/******************************************************************** +** Solidified function: value_changed +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Illuminance_value_changed, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(attribute_updated), + /* K1 */ be_const_int(0), + }), + be_str_weak(value_changed), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x540E03FF, // 0001 LDINT R3 1024 + 0x58100001, // 0002 LDCONST R4 K1 + 0x7C040600, // 0003 CALL R1 3 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Illuminance_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(shadow_value), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(U2), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_const_int(1), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str_weak(U4), + /* K12 */ be_const_int(3), + /* K13 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[71]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E03FF, // 0004 LDINT R7 1024 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0035, // 0006 JMPF R7 #003D + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E0011, // 0008 JMPF R7 #001B + 0x881C0105, // 0009 GETMBR R7 R0 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E0007, // 000C JMPF R7 #0015 + 0x8C1C0706, // 000D GETMET R7 R3 K6 + 0x88240907, // 000E GETMBR R9 R4 K7 + 0x60280009, // 000F GETGBL R10 G9 + 0x882C0105, // 0010 GETMBR R11 R0 K5 + 0x7C280200, // 0011 CALL R10 1 + 0x7C1C0600, // 0012 CALL R7 3 + 0x80040E00, // 0013 RET 1 R7 + 0x70020004, // 0014 JMP #001A + 0x8C1C0706, // 0015 GETMET R7 R3 K6 + 0x88240908, // 0016 GETMBR R9 R4 K8 + 0x4C280000, // 0017 LDNIL R10 + 0x7C1C0600, // 0018 CALL R7 3 + 0x80040E00, // 0019 RET 1 R7 + 0x70020020, // 001A JMP #003C + 0x1C1C0D09, // 001B EQ R7 R6 K9 + 0x781E0005, // 001C JMPF R7 #0023 + 0x8C1C0706, // 001D GETMET R7 R3 K6 + 0x88240907, // 001E GETMBR R9 R4 K7 + 0x58280009, // 001F LDCONST R10 K9 + 0x7C1C0600, // 0020 CALL R7 3 + 0x80040E00, // 0021 RET 1 R7 + 0x70020018, // 0022 JMP #003C + 0x1C1C0D0A, // 0023 EQ R7 R6 K10 + 0x781E0005, // 0024 JMPF R7 #002B + 0x8C1C0706, // 0025 GETMET R7 R3 K6 + 0x88240907, // 0026 GETMBR R9 R4 K7 + 0x542AFFFD, // 0027 LDINT R10 65534 + 0x7C1C0600, // 0028 CALL R7 3 + 0x80040E00, // 0029 RET 1 R7 + 0x70020010, // 002A JMP #003C + 0x541EFFFB, // 002B LDINT R7 65532 + 0x1C1C0C07, // 002C EQ R7 R6 R7 + 0x781E0005, // 002D JMPF R7 #0034 + 0x8C1C0706, // 002E GETMET R7 R3 K6 + 0x8824090B, // 002F GETMBR R9 R4 K11 + 0x58280004, // 0030 LDCONST R10 K4 + 0x7C1C0600, // 0031 CALL R7 3 + 0x80040E00, // 0032 RET 1 R7 + 0x70020007, // 0033 JMP #003C + 0x541EFFFC, // 0034 LDINT R7 65533 + 0x1C1C0C07, // 0035 EQ R7 R6 R7 + 0x781E0004, // 0036 JMPF R7 #003C + 0x8C1C0706, // 0037 GETMET R7 R3 K6 + 0x8824090B, // 0038 GETMBR R9 R4 K11 + 0x5828000C, // 0039 LDCONST R10 K12 + 0x7C1C0600, // 003A CALL R7 3 + 0x80040E00, // 003B RET 1 R7 + 0x70020008, // 003C JMP #0046 + 0x601C0003, // 003D GETGBL R7 G3 + 0x5C200000, // 003E MOVE R8 R0 + 0x7C1C0200, // 003F CALL R7 1 + 0x8C1C0F0D, // 0040 GETMET R7 R7 K13 + 0x5C240200, // 0041 MOVE R9 R1 + 0x5C280400, // 0042 MOVE R10 R2 + 0x5C2C0600, // 0043 MOVE R11 R3 + 0x7C1C0800, // 0044 CALL R7 4 + 0x80040E00, // 0045 RET 1 R7 + 0x80000000, // 0046 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pre_value +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Illuminance_pre_value, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(math), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(log10), + /* K3 */ be_const_int(1), + }), + be_str_weak(pre_value), + &be_const_str_solidified, + ( &(const binstruction[17]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x1C080202, // 0001 EQ R2 R1 R2 + 0x780A0001, // 0002 JMPF R2 #0005 + 0x4C080000, // 0003 LDNIL R2 + 0x80040400, // 0004 RET 1 R2 + 0xA40A0000, // 0005 IMPORT R2 K0 + 0x140C0301, // 0006 LT R3 R1 K1 + 0x780E0001, // 0007 JMPF R3 #000A + 0x80060200, // 0008 RET 1 K1 + 0x70020005, // 0009 JMP #0010 + 0x8C0C0502, // 000A GETMET R3 R2 K2 + 0x00140303, // 000B ADD R5 R1 K3 + 0x7C0C0400, // 000C CALL R3 2 + 0x5412270F, // 000D LDINT R4 10000 + 0x080C0604, // 000E MUL R3 R3 R4 + 0x80040600, // 000F RET 1 R3 + 0x80000000, // 0010 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Sensor_Illuminance +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Sensor; +be_local_class(Matter_Plugin_Sensor_Illuminance, + 0, + &be_class_Matter_Plugin_Sensor, + be_nested_map(9, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Illuminance) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(illuminance) }, + { be_const_key_weak(TYPES, 8), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(262, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(UPDATE_COMMANDS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(1, + ( (struct bvalue*) &(const bvalue[]) { + be_nested_str_weak(Illuminance), + })) ) } )) }, + { be_const_key_weak(value_changed, 7), be_const_closure(Matter_Plugin_Sensor_Illuminance_value_changed_closure) }, + { be_const_key_weak(JSON_NAME, -1), be_nested_str_weak(Illuminance) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Sensor_Illuminance_read_attribute_closure) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(1024, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(5, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(pre_value, -1), be_const_closure(Matter_Plugin_Sensor_Illuminance_pre_value_closure) }, + })), + be_str_weak(Matter_Plugin_Sensor_Illuminance) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Sensor_Illuminance_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor_Illuminance); + be_setglobal(vm, "Matter_Plugin_Sensor_Illuminance"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Occupancy.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Occupancy.h new file mode 100644 index 000000000000..fd236778f234 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Occupancy.h @@ -0,0 +1,487 @@ +/* Solidification of Matter_Plugin_3_Sensor_Occupancy.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Sensor_Occupancy; + +/******************************************************************** +** Solidified function: +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Occupancy__X3Clambda_X3E, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x60040009, // 0000 GETGBL R1 G9 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: append_state_json +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Occupancy_append_state_json, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(_X2C_X22Occupancy_X22_X3A_X25s), + /* K1 */ be_nested_str_weak(shadow_occupancy), + }), + be_str_weak(append_state_json), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x60040018, // 0000 GETGBL R1 G24 + 0x58080000, // 0001 LDCONST R2 K0 + 0x600C0009, // 0002 GETGBL R3 G9 + 0x88100101, // 0003 GETMBR R4 R0 K1 + 0x7C0C0200, // 0004 CALL R3 1 + 0x7C040400, // 0005 CALL R1 2 + 0x80040200, // 0006 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Occupancy_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(shadow_occupancy), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[11]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x50100000, // 0008 LDBOOL R4 0 0 + 0x90020204, // 0009 SETMBR R0 K1 R4 + 0x80000000, // 000A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_virtual +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Occupancy_update_virtual, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(find), + /* K1 */ be_nested_str_weak(Occupancy), + /* K2 */ be_nested_str_weak(shadow_occupancy), + /* K3 */ be_nested_str_weak(attribute_updated), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(update_virtual), + }), + be_str_weak(update_virtual), + &be_const_str_solidified, + ( &(const binstruction[25]) { /* code */ + 0x8C080300, // 0000 GETMET R2 R1 K0 + 0x58100001, // 0001 LDCONST R4 K1 + 0x7C080400, // 0002 CALL R2 2 + 0x4C0C0000, // 0003 LDNIL R3 + 0x200C0403, // 0004 NE R3 R2 R3 + 0x780E000B, // 0005 JMPF R3 #0012 + 0x600C0017, // 0006 GETGBL R3 G23 + 0x5C100400, // 0007 MOVE R4 R2 + 0x7C0C0200, // 0008 CALL R3 1 + 0x5C080600, // 0009 MOVE R2 R3 + 0x880C0102, // 000A GETMBR R3 R0 K2 + 0x200C0602, // 000B NE R3 R3 R2 + 0x780E0004, // 000C JMPF R3 #0012 + 0x8C0C0103, // 000D GETMET R3 R0 K3 + 0x54160405, // 000E LDINT R5 1030 + 0x58180004, // 000F LDCONST R6 K4 + 0x7C0C0600, // 0010 CALL R3 3 + 0x90020402, // 0011 SETMBR R0 K2 R2 + 0x600C0003, // 0012 GETGBL R3 G3 + 0x5C100000, // 0013 MOVE R4 R0 + 0x7C0C0200, // 0014 CALL R3 1 + 0x8C0C0705, // 0015 GETMET R3 R3 K5 + 0x5C140200, // 0016 MOVE R5 R1 + 0x7C0C0400, // 0017 CALL R3 2 + 0x80000000, // 0018 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_shadow +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Occupancy_update_shadow, /* name */ + be_nested_proto( + 8, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(update_shadow), + /* K1 */ be_nested_str_weak(Switch), + /* K2 */ be_nested_str_weak(tasmota_switch_index), + /* K3 */ be_nested_str_weak(tasmota), + /* K4 */ be_nested_str_weak(cmd), + /* K5 */ be_nested_str_weak(Status_X208), + /* K6 */ be_nested_str_weak(find), + /* K7 */ be_nested_str_weak(StatusSNS), + /* K8 */ be_nested_str_weak(contains), + /* K9 */ be_nested_str_weak(ON), + /* K10 */ be_nested_str_weak(shadow_occupancy), + /* K11 */ be_nested_str_weak(attribute_updated), + /* K12 */ be_const_int(0), + }), + be_str_weak(update_shadow), + &be_const_str_solidified, + ( &(const binstruction[41]) { /* code */ + 0x60040003, // 0000 GETGBL R1 G3 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x8C040300, // 0003 GETMET R1 R1 K0 + 0x7C040200, // 0004 CALL R1 1 + 0x60040008, // 0005 GETGBL R1 G8 + 0x88080102, // 0006 GETMBR R2 R0 K2 + 0x7C040200, // 0007 CALL R1 1 + 0x00060201, // 0008 ADD R1 K1 R1 + 0xB80A0600, // 0009 GETNGBL R2 K3 + 0x8C080504, // 000A GETMET R2 R2 K4 + 0x58100005, // 000B LDCONST R4 K5 + 0x50140200, // 000C LDBOOL R5 1 0 + 0x7C080600, // 000D CALL R2 3 + 0x4C0C0000, // 000E LDNIL R3 + 0x200C0403, // 000F NE R3 R2 R3 + 0x780E0003, // 0010 JMPF R3 #0015 + 0x8C0C0506, // 0011 GETMET R3 R2 K6 + 0x58140007, // 0012 LDCONST R5 K7 + 0x7C0C0400, // 0013 CALL R3 2 + 0x5C080600, // 0014 MOVE R2 R3 + 0x4C0C0000, // 0015 LDNIL R3 + 0x200C0403, // 0016 NE R3 R2 R3 + 0x780E000F, // 0017 JMPF R3 #0028 + 0x8C0C0508, // 0018 GETMET R3 R2 K8 + 0x5C140200, // 0019 MOVE R5 R1 + 0x7C0C0400, // 001A CALL R3 2 + 0x780E000B, // 001B JMPF R3 #0028 + 0x8C0C0506, // 001C GETMET R3 R2 K6 + 0x5C140200, // 001D MOVE R5 R1 + 0x7C0C0400, // 001E CALL R3 2 + 0x1C0C0709, // 001F EQ R3 R3 K9 + 0x8810010A, // 0020 GETMBR R4 R0 K10 + 0x20100803, // 0021 NE R4 R4 R3 + 0x78120003, // 0022 JMPF R4 #0027 + 0x8C10010B, // 0023 GETMET R4 R0 K11 + 0x541A0405, // 0024 LDINT R6 1030 + 0x581C000C, // 0025 LDCONST R7 K12 + 0x7C100600, // 0026 CALL R4 3 + 0x90021403, // 0027 SETMBR R0 K10 R3 + 0x80000000, // 0028 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Occupancy_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(shadow_occupancy), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(U1), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_const_int(1), + /* K10 */ be_const_int(3), + /* K11 */ be_const_int(2), + /* K12 */ be_nested_str_weak(U4), + /* K13 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[69]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0405, // 0004 LDINT R7 1030 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0033, // 0006 JMPF R7 #003B + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E000F, // 0008 JMPF R7 #0019 + 0x881C0105, // 0009 GETMBR R7 R0 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E0005, // 000C JMPF R7 #0013 + 0x8C1C0706, // 000D GETMET R7 R3 K6 + 0x88240907, // 000E GETMBR R9 R4 K7 + 0x88280105, // 000F GETMBR R10 R0 K5 + 0x7C1C0600, // 0010 CALL R7 3 + 0x80040E00, // 0011 RET 1 R7 + 0x70020004, // 0012 JMP #0018 + 0x8C1C0706, // 0013 GETMET R7 R3 K6 + 0x88240908, // 0014 GETMBR R9 R4 K8 + 0x4C280000, // 0015 LDNIL R10 + 0x7C1C0600, // 0016 CALL R7 3 + 0x80040E00, // 0017 RET 1 R7 + 0x70020020, // 0018 JMP #003A + 0x1C1C0D09, // 0019 EQ R7 R6 K9 + 0x781E0005, // 001A JMPF R7 #0021 + 0x8C1C0706, // 001B GETMET R7 R3 K6 + 0x88240907, // 001C GETMBR R9 R4 K7 + 0x5828000A, // 001D LDCONST R10 K10 + 0x7C1C0600, // 001E CALL R7 3 + 0x80040E00, // 001F RET 1 R7 + 0x70020018, // 0020 JMP #003A + 0x1C1C0D0B, // 0021 EQ R7 R6 K11 + 0x781E0005, // 0022 JMPF R7 #0029 + 0x8C1C0706, // 0023 GETMET R7 R3 K6 + 0x88240907, // 0024 GETMBR R9 R4 K7 + 0x58280004, // 0025 LDCONST R10 K4 + 0x7C1C0600, // 0026 CALL R7 3 + 0x80040E00, // 0027 RET 1 R7 + 0x70020010, // 0028 JMP #003A + 0x541EFFFB, // 0029 LDINT R7 65532 + 0x1C1C0C07, // 002A EQ R7 R6 R7 + 0x781E0005, // 002B JMPF R7 #0032 + 0x8C1C0706, // 002C GETMET R7 R3 K6 + 0x8824090C, // 002D GETMBR R9 R4 K12 + 0x58280004, // 002E LDCONST R10 K4 + 0x7C1C0600, // 002F CALL R7 3 + 0x80040E00, // 0030 RET 1 R7 + 0x70020007, // 0031 JMP #003A + 0x541EFFFC, // 0032 LDINT R7 65533 + 0x1C1C0C07, // 0033 EQ R7 R6 R7 + 0x781E0004, // 0034 JMPF R7 #003A + 0x8C1C0706, // 0035 GETMET R7 R3 K6 + 0x8824090C, // 0036 GETMBR R9 R4 K12 + 0x5828000A, // 0037 LDCONST R10 K10 + 0x7C1C0600, // 0038 CALL R7 3 + 0x80040E00, // 0039 RET 1 R7 + 0x70020008, // 003A JMP #0044 + 0x601C0003, // 003B GETGBL R7 G3 + 0x5C200000, // 003C MOVE R8 R0 + 0x7C1C0200, // 003D CALL R7 1 + 0x8C1C0F0D, // 003E GETMET R7 R7 K13 + 0x5C240200, // 003F MOVE R9 R1 + 0x5C280400, // 0040 MOVE R10 R2 + 0x5C2C0600, // 0041 MOVE R11 R3 + 0x7C1C0800, // 0042 CALL R7 4 + 0x80040E00, // 0043 RET 1 R7 + 0x80000000, // 0044 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_configuration +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Occupancy_parse_configuration, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota_switch_index), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(ARG), + /* K3 */ be_const_int(1), + /* K4 */ be_const_int(0), + }), + be_str_weak(parse_configuration), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x60080009, // 0000 GETGBL R2 G9 + 0x8C0C0301, // 0001 GETMET R3 R1 K1 + 0x88140102, // 0002 GETMBR R5 R0 K2 + 0x58180003, // 0003 LDCONST R6 K3 + 0x7C0C0600, // 0004 CALL R3 3 + 0x7C080200, // 0005 CALL R2 1 + 0x90020002, // 0006 SETMBR R0 K0 R2 + 0x88080100, // 0007 GETMBR R2 R0 K0 + 0x18080504, // 0008 LE R2 R2 K4 + 0x780A0000, // 0009 JMPF R2 #000B + 0x90020103, // 000A SETMBR R0 K0 K3 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Sensor_Occupancy +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Device; +be_local_class(Matter_Plugin_Sensor_Occupancy, + 2, + &be_class_Matter_Plugin_Device, + be_nested_map(16, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(ARG_TYPE, 4), be_const_static_closure(Matter_Plugin_Sensor_Occupancy__X3Clambda_X3E_closure) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(Switch_X3Cx_X3E_X20number) }, + { be_const_key_weak(append_state_json, -1), be_const_closure(Matter_Plugin_Sensor_Occupancy_append_state_json_closure) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Sensor_Occupancy_init_closure) }, + { be_const_key_weak(update_virtual, -1), be_const_closure(Matter_Plugin_Sensor_Occupancy_update_virtual_closure) }, + { be_const_key_weak(update_shadow, 6), be_const_closure(Matter_Plugin_Sensor_Occupancy_update_shadow_closure) }, + { be_const_key_weak(parse_configuration, -1), be_const_closure(Matter_Plugin_Sensor_Occupancy_parse_configuration_closure) }, + { be_const_key_weak(ARG, -1), be_nested_str_weak(switch) }, + { be_const_key_weak(UPDATE_TIME, -1), be_const_int(750) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Occupancy) }, + { be_const_key_weak(tasmota_switch_index, 11), be_const_var(0) }, + { be_const_key_weak(TYPES, 12), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(263, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(CLUSTERS, 14), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(1030, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(5, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(TYPE, 9), be_nested_str_weak(occupancy) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Sensor_Occupancy_read_attribute_closure) }, + { be_const_key_weak(shadow_occupancy, -1), be_const_var(1) }, + })), + be_str_weak(Matter_Plugin_Sensor_Occupancy) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Sensor_Occupancy_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor_Occupancy); + be_setglobal(vm, "Matter_Plugin_Sensor_Occupancy"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_OnOff.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_OnOff.h new file mode 100644 index 000000000000..4bb8243a0735 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_OnOff.h @@ -0,0 +1,364 @@ +/* Solidification of Matter_Plugin_3_Sensor_OnOff.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Sensor_OnOff; + +/******************************************************************** +** Solidified function: +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_OnOff__X3Clambda_X3E, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x60040009, // 0000 GETGBL R1 G9 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_shadow +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_OnOff_update_shadow, /* name */ + be_nested_proto( + 8, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(update_shadow), + /* K1 */ be_nested_str_weak(Switch), + /* K2 */ be_nested_str_weak(tasmota_switch_index), + /* K3 */ be_nested_str_weak(tasmota), + /* K4 */ be_nested_str_weak(cmd), + /* K5 */ be_nested_str_weak(Status_X208), + /* K6 */ be_nested_str_weak(find), + /* K7 */ be_nested_str_weak(StatusSNS), + /* K8 */ be_nested_str_weak(contains), + /* K9 */ be_nested_str_weak(ON), + /* K10 */ be_nested_str_weak(shadow_onoff), + /* K11 */ be_nested_str_weak(attribute_updated), + /* K12 */ be_const_int(0), + }), + be_str_weak(update_shadow), + &be_const_str_solidified, + ( &(const binstruction[41]) { /* code */ + 0x60040003, // 0000 GETGBL R1 G3 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x8C040300, // 0003 GETMET R1 R1 K0 + 0x7C040200, // 0004 CALL R1 1 + 0x60040008, // 0005 GETGBL R1 G8 + 0x88080102, // 0006 GETMBR R2 R0 K2 + 0x7C040200, // 0007 CALL R1 1 + 0x00060201, // 0008 ADD R1 K1 R1 + 0xB80A0600, // 0009 GETNGBL R2 K3 + 0x8C080504, // 000A GETMET R2 R2 K4 + 0x58100005, // 000B LDCONST R4 K5 + 0x50140200, // 000C LDBOOL R5 1 0 + 0x7C080600, // 000D CALL R2 3 + 0x4C0C0000, // 000E LDNIL R3 + 0x200C0403, // 000F NE R3 R2 R3 + 0x780E0003, // 0010 JMPF R3 #0015 + 0x8C0C0506, // 0011 GETMET R3 R2 K6 + 0x58140007, // 0012 LDCONST R5 K7 + 0x7C0C0400, // 0013 CALL R3 2 + 0x5C080600, // 0014 MOVE R2 R3 + 0x4C0C0000, // 0015 LDNIL R3 + 0x200C0403, // 0016 NE R3 R2 R3 + 0x780E000F, // 0017 JMPF R3 #0028 + 0x8C0C0508, // 0018 GETMET R3 R2 K8 + 0x5C140200, // 0019 MOVE R5 R1 + 0x7C0C0400, // 001A CALL R3 2 + 0x780E000B, // 001B JMPF R3 #0028 + 0x8C0C0506, // 001C GETMET R3 R2 K6 + 0x5C140200, // 001D MOVE R5 R1 + 0x7C0C0400, // 001E CALL R3 2 + 0x1C0C0709, // 001F EQ R3 R3 K9 + 0x8810010A, // 0020 GETMBR R4 R0 K10 + 0x20100803, // 0021 NE R4 R4 R3 + 0x78120003, // 0022 JMPF R4 #0027 + 0x8C10010B, // 0023 GETMET R4 R0 K11 + 0x541A0005, // 0024 LDINT R6 6 + 0x581C000C, // 0025 LDCONST R7 K12 + 0x7C100600, // 0026 CALL R4 3 + 0x90021403, // 0027 SETMBR R0 K10 R3 + 0x80000000, // 0028 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_configuration +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_OnOff_parse_configuration, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota_switch_index), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(ARG), + /* K3 */ be_const_int(1), + /* K4 */ be_const_int(0), + }), + be_str_weak(parse_configuration), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x60080009, // 0000 GETGBL R2 G9 + 0x8C0C0301, // 0001 GETMET R3 R1 K1 + 0x88140102, // 0002 GETMBR R5 R0 K2 + 0x58180003, // 0003 LDCONST R6 K3 + 0x7C0C0600, // 0004 CALL R3 3 + 0x7C080200, // 0005 CALL R2 1 + 0x90020002, // 0006 SETMBR R0 K0 R2 + 0x88080100, // 0007 GETMBR R2 R0 K0 + 0x18080504, // 0008 LE R2 R2 K4 + 0x780A0000, // 0009 JMPF R2 #000B + 0x90020103, // 000A SETMBR R0 K0 K3 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_OnOff_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(BOOL), + /* K8 */ be_nested_str_weak(shadow_onoff), + /* K9 */ be_nested_str_weak(U4), + /* K10 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0005, // 0004 LDINT R7 6 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E001B, // 0006 JMPF R7 #0023 + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x1C1C0D05, // 0009 EQ R7 R6 K5 + 0x781E0005, // 000A JMPF R7 #0011 + 0x8C1C0706, // 000B GETMET R7 R3 K6 + 0x88240907, // 000C GETMBR R9 R4 K7 + 0x88280108, // 000D GETMBR R10 R0 K8 + 0x7C1C0600, // 000E CALL R7 3 + 0x80040E00, // 000F RET 1 R7 + 0x70020010, // 0010 JMP #0022 + 0x541EFFFB, // 0011 LDINT R7 65532 + 0x1C1C0C07, // 0012 EQ R7 R6 R7 + 0x781E0005, // 0013 JMPF R7 #001A + 0x8C1C0706, // 0014 GETMET R7 R3 K6 + 0x88240909, // 0015 GETMBR R9 R4 K9 + 0x58280005, // 0016 LDCONST R10 K5 + 0x7C1C0600, // 0017 CALL R7 3 + 0x80040E00, // 0018 RET 1 R7 + 0x70020007, // 0019 JMP #0022 + 0x541EFFFC, // 001A LDINT R7 65533 + 0x1C1C0C07, // 001B EQ R7 R6 R7 + 0x781E0004, // 001C JMPF R7 #0022 + 0x8C1C0706, // 001D GETMET R7 R3 K6 + 0x88240909, // 001E GETMBR R9 R4 K9 + 0x542A0003, // 001F LDINT R10 4 + 0x7C1C0600, // 0020 CALL R7 3 + 0x80040E00, // 0021 RET 1 R7 + 0x70020008, // 0022 JMP #002C + 0x601C0003, // 0023 GETGBL R7 G3 + 0x5C200000, // 0024 MOVE R8 R0 + 0x7C1C0200, // 0025 CALL R7 1 + 0x8C1C0F0A, // 0026 GETMET R7 R7 K10 + 0x5C240200, // 0027 MOVE R9 R1 + 0x5C280400, // 0028 MOVE R10 R2 + 0x5C2C0600, // 0029 MOVE R11 R3 + 0x7C1C0800, // 002A CALL R7 4 + 0x80040E00, // 002B RET 1 R7 + 0x80000000, // 002C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: append_state_json +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_OnOff_append_state_json, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(_X2C_X22OnOff_X22_X3A_X25s), + /* K1 */ be_nested_str_weak(shadow_onoff), + }), + be_str_weak(append_state_json), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x60040018, // 0000 GETGBL R1 G24 + 0x58080000, // 0001 LDCONST R2 K0 + 0x600C0009, // 0002 GETGBL R3 G9 + 0x88100101, // 0003 GETMBR R4 R0 K1 + 0x7C0C0200, // 0004 CALL R3 1 + 0x7C040400, // 0005 CALL R1 2 + 0x80040200, // 0006 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Sensor_OnOff +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Device; +be_local_class(Matter_Plugin_Sensor_OnOff, + 2, + &be_class_Matter_Plugin_Device, + be_nested_map(14, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(CLUSTERS, 8), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(ARG, -1), be_nested_str_weak(switch) }, + { be_const_key_weak(UPDATE_TIME, 4), be_const_int(750) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(onoff) }, + { be_const_key_weak(append_state_json, 12), be_const_closure(Matter_Plugin_Sensor_OnOff_append_state_json_closure) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(OnOff_X20Sensor) }, + { be_const_key_weak(shadow_onoff, -1), be_const_var(1) }, + { be_const_key_weak(update_shadow, -1), be_const_closure(Matter_Plugin_Sensor_OnOff_update_shadow_closure) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Sensor_OnOff_read_attribute_closure) }, + { be_const_key_weak(parse_configuration, -1), be_const_closure(Matter_Plugin_Sensor_OnOff_parse_configuration_closure) }, + { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(2128, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(ARG_HINT, 9), be_nested_str_weak(Switch_X3Cx_X3E_X20number) }, + { be_const_key_weak(tasmota_switch_index, 13), be_const_var(0) }, + { be_const_key_weak(ARG_TYPE, -1), be_const_static_closure(Matter_Plugin_Sensor_OnOff__X3Clambda_X3E_closure) }, + })), + be_str_weak(Matter_Plugin_Sensor_OnOff) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Sensor_OnOff_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor_OnOff); + be_setglobal(vm, "Matter_Plugin_Sensor_OnOff"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Pressure.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Pressure.h new file mode 100644 index 000000000000..bcd8a036fb55 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Pressure.h @@ -0,0 +1,278 @@ +/* Solidification of Matter_Plugin_3_Sensor_Pressure.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Sensor_Pressure; + +/******************************************************************** +** Solidified function: value_changed +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Pressure_value_changed, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(attribute_updated), + /* K1 */ be_const_int(0), + }), + be_str_weak(value_changed), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x540E0402, // 0001 LDINT R3 1027 + 0x58100001, // 0002 LDCONST R4 K1 + 0x7C040600, // 0003 CALL R1 3 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Pressure_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(shadow_value), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(I2), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_const_int(1), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str_weak(U4), + /* K12 */ be_const_int(3), + /* K13 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[71]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0402, // 0004 LDINT R7 1027 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0035, // 0006 JMPF R7 #003D + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E0011, // 0008 JMPF R7 #001B + 0x881C0105, // 0009 GETMBR R7 R0 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E0007, // 000C JMPF R7 #0015 + 0x8C1C0706, // 000D GETMET R7 R3 K6 + 0x88240907, // 000E GETMBR R9 R4 K7 + 0x60280009, // 000F GETGBL R10 G9 + 0x882C0105, // 0010 GETMBR R11 R0 K5 + 0x7C280200, // 0011 CALL R10 1 + 0x7C1C0600, // 0012 CALL R7 3 + 0x80040E00, // 0013 RET 1 R7 + 0x70020004, // 0014 JMP #001A + 0x8C1C0706, // 0015 GETMET R7 R3 K6 + 0x88240908, // 0016 GETMBR R9 R4 K8 + 0x4C280000, // 0017 LDNIL R10 + 0x7C1C0600, // 0018 CALL R7 3 + 0x80040E00, // 0019 RET 1 R7 + 0x70020020, // 001A JMP #003C + 0x1C1C0D09, // 001B EQ R7 R6 K9 + 0x781E0005, // 001C JMPF R7 #0023 + 0x8C1C0706, // 001D GETMET R7 R3 K6 + 0x88240907, // 001E GETMBR R9 R4 K7 + 0x542A01F3, // 001F LDINT R10 500 + 0x7C1C0600, // 0020 CALL R7 3 + 0x80040E00, // 0021 RET 1 R7 + 0x70020018, // 0022 JMP #003C + 0x1C1C0D0A, // 0023 EQ R7 R6 K10 + 0x781E0005, // 0024 JMPF R7 #002B + 0x8C1C0706, // 0025 GETMET R7 R3 K6 + 0x88240907, // 0026 GETMBR R9 R4 K7 + 0x542A05DB, // 0027 LDINT R10 1500 + 0x7C1C0600, // 0028 CALL R7 3 + 0x80040E00, // 0029 RET 1 R7 + 0x70020010, // 002A JMP #003C + 0x541EFFFB, // 002B LDINT R7 65532 + 0x1C1C0C07, // 002C EQ R7 R6 R7 + 0x781E0005, // 002D JMPF R7 #0034 + 0x8C1C0706, // 002E GETMET R7 R3 K6 + 0x8824090B, // 002F GETMBR R9 R4 K11 + 0x58280004, // 0030 LDCONST R10 K4 + 0x7C1C0600, // 0031 CALL R7 3 + 0x80040E00, // 0032 RET 1 R7 + 0x70020007, // 0033 JMP #003C + 0x541EFFFC, // 0034 LDINT R7 65533 + 0x1C1C0C07, // 0035 EQ R7 R6 R7 + 0x781E0004, // 0036 JMPF R7 #003C + 0x8C1C0706, // 0037 GETMET R7 R3 K6 + 0x8824090B, // 0038 GETMBR R9 R4 K11 + 0x5828000C, // 0039 LDCONST R10 K12 + 0x7C1C0600, // 003A CALL R7 3 + 0x80040E00, // 003B RET 1 R7 + 0x70020008, // 003C JMP #0046 + 0x601C0003, // 003D GETGBL R7 G3 + 0x5C200000, // 003E MOVE R8 R0 + 0x7C1C0200, // 003F CALL R7 1 + 0x8C1C0F0D, // 0040 GETMET R7 R7 K13 + 0x5C240200, // 0041 MOVE R9 R1 + 0x5C280400, // 0042 MOVE R10 R2 + 0x5C2C0600, // 0043 MOVE R11 R3 + 0x7C1C0800, // 0044 CALL R7 4 + 0x80040E00, // 0045 RET 1 R7 + 0x80000000, // 0046 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pre_value +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Pressure_pre_value, /* name */ + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(pre_value), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x20080202, // 0001 NE R2 R1 R2 + 0x780A0003, // 0002 JMPF R2 #0007 + 0x60080009, // 0003 GETGBL R2 G9 + 0x5C0C0200, // 0004 MOVE R3 R1 + 0x7C080200, // 0005 CALL R2 1 + 0x70020000, // 0006 JMP #0008 + 0x4C080000, // 0007 LDNIL R2 + 0x80040400, // 0008 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Sensor_Pressure +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Sensor; +be_local_class(Matter_Plugin_Sensor_Pressure, + 0, + &be_class_Matter_Plugin_Sensor, + be_nested_map(9, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Pressure) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(pressure) }, + { be_const_key_weak(TYPES, 8), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(773, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(UPDATE_COMMANDS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(1, + ( (struct bvalue*) &(const bvalue[]) { + be_nested_str_weak(Pressure), + })) ) } )) }, + { be_const_key_weak(value_changed, 7), be_const_closure(Matter_Plugin_Sensor_Pressure_value_changed_closure) }, + { be_const_key_weak(JSON_NAME, -1), be_nested_str_weak(Pressure) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Sensor_Pressure_read_attribute_closure) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(1027, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(5, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(pre_value, -1), be_const_closure(Matter_Plugin_Sensor_Pressure_pre_value_closure) }, + })), + be_str_weak(Matter_Plugin_Sensor_Pressure) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Sensor_Pressure_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor_Pressure); + be_setglobal(vm, "Matter_Plugin_Sensor_Pressure"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Temp.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Temp.h new file mode 100644 index 000000000000..a28ac1196dfc --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_Sensor_Temp.h @@ -0,0 +1,291 @@ +/* Solidification of Matter_Plugin_3_Sensor_Temp.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Sensor_Temp; + +/******************************************************************** +** Solidified function: value_changed +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Temp_value_changed, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(attribute_updated), + /* K1 */ be_const_int(0), + }), + be_str_weak(value_changed), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x540E0401, // 0001 LDINT R3 1026 + 0x58100001, // 0002 LDCONST R4 K1 + 0x7C040600, // 0003 CALL R1 3 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Temp_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(shadow_value), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(I2), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_const_int(1), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str_weak(U4), + /* K12 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[69]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0401, // 0004 LDINT R7 1026 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0033, // 0006 JMPF R7 #003B + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E000F, // 0008 JMPF R7 #0019 + 0x881C0105, // 0009 GETMBR R7 R0 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E0005, // 000C JMPF R7 #0013 + 0x8C1C0706, // 000D GETMET R7 R3 K6 + 0x88240907, // 000E GETMBR R9 R4 K7 + 0x88280105, // 000F GETMBR R10 R0 K5 + 0x7C1C0600, // 0010 CALL R7 3 + 0x80040E00, // 0011 RET 1 R7 + 0x70020004, // 0012 JMP #0018 + 0x8C1C0706, // 0013 GETMET R7 R3 K6 + 0x88240908, // 0014 GETMBR R9 R4 K8 + 0x4C280000, // 0015 LDNIL R10 + 0x7C1C0600, // 0016 CALL R7 3 + 0x80040E00, // 0017 RET 1 R7 + 0x70020020, // 0018 JMP #003A + 0x1C1C0D09, // 0019 EQ R7 R6 K9 + 0x781E0005, // 001A JMPF R7 #0021 + 0x8C1C0706, // 001B GETMET R7 R3 K6 + 0x88240907, // 001C GETMBR R9 R4 K7 + 0x5429EC77, // 001D LDINT R10 -5000 + 0x7C1C0600, // 001E CALL R7 3 + 0x80040E00, // 001F RET 1 R7 + 0x70020018, // 0020 JMP #003A + 0x1C1C0D0A, // 0021 EQ R7 R6 K10 + 0x781E0005, // 0022 JMPF R7 #0029 + 0x8C1C0706, // 0023 GETMET R7 R3 K6 + 0x88240907, // 0024 GETMBR R9 R4 K7 + 0x542A3A97, // 0025 LDINT R10 15000 + 0x7C1C0600, // 0026 CALL R7 3 + 0x80040E00, // 0027 RET 1 R7 + 0x70020010, // 0028 JMP #003A + 0x541EFFFB, // 0029 LDINT R7 65532 + 0x1C1C0C07, // 002A EQ R7 R6 R7 + 0x781E0005, // 002B JMPF R7 #0032 + 0x8C1C0706, // 002C GETMET R7 R3 K6 + 0x8824090B, // 002D GETMBR R9 R4 K11 + 0x58280004, // 002E LDCONST R10 K4 + 0x7C1C0600, // 002F CALL R7 3 + 0x80040E00, // 0030 RET 1 R7 + 0x70020007, // 0031 JMP #003A + 0x541EFFFC, // 0032 LDINT R7 65533 + 0x1C1C0C07, // 0033 EQ R7 R6 R7 + 0x781E0004, // 0034 JMPF R7 #003A + 0x8C1C0706, // 0035 GETMET R7 R3 K6 + 0x8824090B, // 0036 GETMBR R9 R4 K11 + 0x542A0003, // 0037 LDINT R10 4 + 0x7C1C0600, // 0038 CALL R7 3 + 0x80040E00, // 0039 RET 1 R7 + 0x70020008, // 003A JMP #0044 + 0x601C0003, // 003B GETGBL R7 G3 + 0x5C200000, // 003C MOVE R8 R0 + 0x7C1C0200, // 003D CALL R7 1 + 0x8C1C0F0C, // 003E GETMET R7 R7 K12 + 0x5C240200, // 003F MOVE R9 R1 + 0x5C280400, // 0040 MOVE R10 R2 + 0x5C2C0600, // 0041 MOVE R11 R3 + 0x7C1C0800, // 0042 CALL R7 4 + 0x80040E00, // 0043 RET 1 R7 + 0x80000000, // 0044 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pre_value +********************************************************************/ +be_local_closure(Matter_Plugin_Sensor_Temp_pre_value, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(get_option), + /* K2 */ be_const_int(1), + /* K3 */ be_const_real_hex(0x3FE66666), + }), + be_str_weak(pre_value), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0xB80A0000, // 0000 GETNGBL R2 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x54120007, // 0002 LDINT R4 8 + 0x7C080400, // 0003 CALL R2 2 + 0x1C080502, // 0004 EQ R2 R2 K2 + 0x780A0003, // 0005 JMPF R2 #000A + 0x540A001F, // 0006 LDINT R2 32 + 0x04080202, // 0007 SUB R2 R1 R2 + 0x0C080503, // 0008 DIV R2 R2 K3 + 0x5C040400, // 0009 MOVE R1 R2 + 0x4C080000, // 000A LDNIL R2 + 0x20080202, // 000B NE R2 R1 R2 + 0x780A0004, // 000C JMPF R2 #0012 + 0x60080009, // 000D GETGBL R2 G9 + 0x540E0063, // 000E LDINT R3 100 + 0x080C0203, // 000F MUL R3 R1 R3 + 0x7C080200, // 0010 CALL R2 1 + 0x70020000, // 0011 JMP #0013 + 0x4C080000, // 0012 LDNIL R2 + 0x80040400, // 0013 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Sensor_Temp +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Sensor; +be_local_class(Matter_Plugin_Sensor_Temp, + 0, + &be_class_Matter_Plugin_Sensor, + be_nested_map(9, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Temperature) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(temperature) }, + { be_const_key_weak(TYPES, 8), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(770, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(UPDATE_COMMANDS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(1, + ( (struct bvalue*) &(const bvalue[]) { + be_nested_str_weak(Temperature), + })) ) } )) }, + { be_const_key_weak(value_changed, 7), be_const_closure(Matter_Plugin_Sensor_Temp_value_changed_closure) }, + { be_const_key_weak(JSON_NAME, -1), be_nested_str_weak(Temperature) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Sensor_Temp_read_attribute_closure) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(1026, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(5, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(pre_value, -1), be_const_closure(Matter_Plugin_Sensor_Temp_pre_value_closure) }, + })), + be_str_weak(Matter_Plugin_Sensor_Temp) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Sensor_Temp_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor_Temp); + be_setglobal(vm, "Matter_Plugin_Sensor_Temp"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_ShutterTilt.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_ShutterTilt.h similarity index 53% rename from lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_ShutterTilt.h rename to lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_ShutterTilt.h index 2d6d0445e579..c661121a969d 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_ShutterTilt.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_3_ShutterTilt.h @@ -1,4 +1,4 @@ -/* Solidification of Matter_Plugin_ShutterTilt.h */ +/* Solidification of Matter_Plugin_3_ShutterTilt.h */ /********************************************************************\ * Generated code, don't edit * \********************************************************************/ @@ -76,6 +76,227 @@ be_local_closure(Matter_Plugin_ShutterTilt_update_tilt_min_max, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_ShutterTilt_read_attribute, /* name */ + be_nested_proto( + 14, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[20]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_nested_str_weak(set), + /* K6 */ be_nested_str_weak(U1), + /* K7 */ be_const_int(1), + /* K8 */ be_nested_str_weak(update_tilt_min_max), + /* K9 */ be_nested_str_weak(tilt_min), + /* K10 */ be_nested_str_weak(tilt_max), + /* K11 */ be_nested_str_weak(tasmota), + /* K12 */ be_nested_str_weak(scale_uint), + /* K13 */ be_nested_str_weak(shadow_shutter_tilt), + /* K14 */ be_const_int(0), + /* K15 */ be_nested_str_weak(U2), + /* K16 */ be_nested_str_weak(NULL), + /* K17 */ be_nested_str_weak(U4), + /* K18 */ be_const_int(3), + /* K19 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[113]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0101, // 0004 LDINT R7 258 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0060, // 0006 JMPF R7 #0068 + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x541E0006, // 0009 LDINT R7 7 + 0x1C1C0C07, // 000A EQ R7 R6 R7 + 0x781E0008, // 000B JMPF R7 #0015 + 0x8C1C0705, // 000C GETMET R7 R3 K5 + 0x88240906, // 000D GETMBR R9 R4 K6 + 0x542A0007, // 000E LDINT R10 8 + 0x002A0E0A, // 000F ADD R10 K7 R10 + 0x542E000F, // 0010 LDINT R11 16 + 0x0028140B, // 0011 ADD R10 R10 R11 + 0x7C1C0600, // 0012 CALL R7 3 + 0x80040E00, // 0013 RET 1 R7 + 0x70020052, // 0014 JMP #0068 + 0x541E000E, // 0015 LDINT R7 15 + 0x1C1C0C07, // 0016 EQ R7 R6 R7 + 0x781E0021, // 0017 JMPF R7 #003A + 0x8C1C0108, // 0018 GETMET R7 R0 K8 + 0x7C1C0200, // 0019 CALL R7 1 + 0x881C0109, // 001A GETMBR R7 R0 K9 + 0x4C200000, // 001B LDNIL R8 + 0x201C0E08, // 001C NE R7 R7 R8 + 0x781E0015, // 001D JMPF R7 #0034 + 0x881C010A, // 001E GETMBR R7 R0 K10 + 0x4C200000, // 001F LDNIL R8 + 0x201C0E08, // 0020 NE R7 R7 R8 + 0x781E0011, // 0021 JMPF R7 #0034 + 0xB81E1600, // 0022 GETNGBL R7 K11 + 0x8C1C0F0C, // 0023 GETMET R7 R7 K12 + 0x8824010D, // 0024 GETMBR R9 R0 K13 + 0x88280109, // 0025 GETMBR R10 R0 K9 + 0x0424120A, // 0026 SUB R9 R9 R10 + 0x5828000E, // 0027 LDCONST R10 K14 + 0x882C010A, // 0028 GETMBR R11 R0 K10 + 0x88300109, // 0029 GETMBR R12 R0 K9 + 0x042C160C, // 002A SUB R11 R11 R12 + 0x5830000E, // 002B LDCONST R12 K14 + 0x5436270F, // 002C LDINT R13 10000 + 0x7C1C0C00, // 002D CALL R7 6 + 0x8C200705, // 002E GETMET R8 R3 K5 + 0x8828090F, // 002F GETMBR R10 R4 K15 + 0x5C2C0E00, // 0030 MOVE R11 R7 + 0x7C200600, // 0031 CALL R8 3 + 0x80041000, // 0032 RET 1 R8 + 0x70020004, // 0033 JMP #0039 + 0x8C1C0705, // 0034 GETMET R7 R3 K5 + 0x88240910, // 0035 GETMBR R9 R4 K16 + 0x4C280000, // 0036 LDNIL R10 + 0x7C1C0600, // 0037 CALL R7 3 + 0x80040E00, // 0038 RET 1 R7 + 0x7002002D, // 0039 JMP #0068 + 0x541E000B, // 003A LDINT R7 12 + 0x1C1C0C07, // 003B EQ R7 R6 R7 + 0x781E001F, // 003C JMPF R7 #005D + 0x881C0109, // 003D GETMBR R7 R0 K9 + 0x4C200000, // 003E LDNIL R8 + 0x201C0E08, // 003F NE R7 R7 R8 + 0x781E0015, // 0040 JMPF R7 #0057 + 0x881C010A, // 0041 GETMBR R7 R0 K10 + 0x4C200000, // 0042 LDNIL R8 + 0x201C0E08, // 0043 NE R7 R7 R8 + 0x781E0011, // 0044 JMPF R7 #0057 + 0xB81E1600, // 0045 GETNGBL R7 K11 + 0x8C1C0F0C, // 0046 GETMET R7 R7 K12 + 0x8824010D, // 0047 GETMBR R9 R0 K13 + 0x88280109, // 0048 GETMBR R10 R0 K9 + 0x0424120A, // 0049 SUB R9 R9 R10 + 0x5828000E, // 004A LDCONST R10 K14 + 0x882C010A, // 004B GETMBR R11 R0 K10 + 0x88300109, // 004C GETMBR R12 R0 K9 + 0x042C160C, // 004D SUB R11 R11 R12 + 0x5830000E, // 004E LDCONST R12 K14 + 0x5436270F, // 004F LDINT R13 10000 + 0x7C1C0C00, // 0050 CALL R7 6 + 0x8C200705, // 0051 GETMET R8 R3 K5 + 0x8828090F, // 0052 GETMBR R10 R4 K15 + 0x5C2C0E00, // 0053 MOVE R11 R7 + 0x7C200600, // 0054 CALL R8 3 + 0x80041000, // 0055 RET 1 R8 + 0x70020004, // 0056 JMP #005C + 0x8C1C0705, // 0057 GETMET R7 R3 K5 + 0x88240910, // 0058 GETMBR R9 R4 K16 + 0x4C280000, // 0059 LDNIL R10 + 0x7C1C0600, // 005A CALL R7 3 + 0x80040E00, // 005B RET 1 R7 + 0x7002000A, // 005C JMP #0068 + 0x541EFFFB, // 005D LDINT R7 65532 + 0x1C1C0C07, // 005E EQ R7 R6 R7 + 0x781E0007, // 005F JMPF R7 #0068 + 0x8C1C0705, // 0060 GETMET R7 R3 K5 + 0x88240911, // 0061 GETMBR R9 R4 K17 + 0x542A0003, // 0062 LDINT R10 4 + 0x002A240A, // 0063 ADD R10 K18 R10 + 0x542E000F, // 0064 LDINT R11 16 + 0x0028140B, // 0065 ADD R10 R10 R11 + 0x7C1C0600, // 0066 CALL R7 3 + 0x80040E00, // 0067 RET 1 R7 + 0x601C0003, // 0068 GETGBL R7 G3 + 0x5C200000, // 0069 MOVE R8 R0 + 0x7C1C0200, // 006A CALL R7 1 + 0x8C1C0F13, // 006B GETMET R7 R7 K19 + 0x5C240200, // 006C MOVE R9 R1 + 0x5C280400, // 006D MOVE R10 R2 + 0x5C2C0600, // 006E MOVE R11 R3 + 0x7C1C0800, // 006F CALL R7 4 + 0x80040E00, // 0070 RET 1 R7 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_sensors +********************************************************************/ +be_local_closure(Matter_Plugin_ShutterTilt_parse_sensors, /* name */ + be_nested_proto( + 9, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(Shutter), + /* K1 */ be_nested_str_weak(tasmota_shutter_index), + /* K2 */ be_const_int(1), + /* K3 */ be_nested_str_weak(contains), + /* K4 */ be_nested_str_weak(find), + /* K5 */ be_nested_str_weak(Tilt), + /* K6 */ be_nested_str_weak(shadow_shutter_tilt), + /* K7 */ be_nested_str_weak(attribute_updated), + /* K8 */ be_nested_str_weak(parse_sensors), + }), + be_str_weak(parse_sensors), + &be_const_str_solidified, + ( &(const binstruction[31]) { /* code */ + 0x60080008, // 0000 GETGBL R2 G8 + 0x880C0101, // 0001 GETMBR R3 R0 K1 + 0x000C0702, // 0002 ADD R3 R3 K2 + 0x7C080200, // 0003 CALL R2 1 + 0x000A0002, // 0004 ADD R2 K0 R2 + 0x8C0C0303, // 0005 GETMET R3 R1 K3 + 0x5C140400, // 0006 MOVE R5 R2 + 0x7C0C0400, // 0007 CALL R3 2 + 0x780E000E, // 0008 JMPF R3 #0018 + 0x940C0202, // 0009 GETIDX R3 R1 R2 + 0x8C100704, // 000A GETMET R4 R3 K4 + 0x58180005, // 000B LDCONST R6 K5 + 0x7C100400, // 000C CALL R4 2 + 0x4C140000, // 000D LDNIL R5 + 0x20140805, // 000E NE R5 R4 R5 + 0x78160007, // 000F JMPF R5 #0018 + 0x88140106, // 0010 GETMBR R5 R0 K6 + 0x20140805, // 0011 NE R5 R4 R5 + 0x78160003, // 0012 JMPF R5 #0017 + 0x8C140107, // 0013 GETMET R5 R0 K7 + 0x541E0101, // 0014 LDINT R7 258 + 0x5422000E, // 0015 LDINT R8 15 + 0x7C140600, // 0016 CALL R5 3 + 0x90020C04, // 0017 SETMBR R0 K6 R4 + 0x600C0003, // 0018 GETGBL R3 G3 + 0x5C100000, // 0019 MOVE R4 R0 + 0x7C0C0200, // 001A CALL R3 1 + 0x8C0C0708, // 001B GETMET R3 R3 K8 + 0x5C140200, // 001C MOVE R5 R1 + 0x7C0C0400, // 001D CALL R3 2 + 0x80000000, // 001E RET 0 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: invoke_request ********************************************************************/ @@ -202,259 +423,94 @@ be_local_closure(Matter_Plugin_ShutterTilt_invoke_request, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_ShutterTilt_read_attribute, /* name */ - be_nested_proto( - 14, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[21]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_nested_str_weak(update_shadow_lazy), - /* K6 */ be_nested_str_weak(create_TLV), - /* K7 */ be_nested_str_weak(U1), - /* K8 */ be_const_int(1), - /* K9 */ be_nested_str_weak(update_tilt_min_max), - /* K10 */ be_nested_str_weak(tilt_min), - /* K11 */ be_nested_str_weak(tilt_max), - /* K12 */ be_nested_str_weak(tasmota), - /* K13 */ be_nested_str_weak(scale_uint), - /* K14 */ be_nested_str_weak(shadow_shutter_tilt), - /* K15 */ be_const_int(0), - /* K16 */ be_nested_str_weak(U2), - /* K17 */ be_nested_str_weak(NULL), - /* K18 */ be_nested_str_weak(U4), - /* K19 */ be_const_int(3), - /* K20 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[113]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x541E0101, // 0005 LDINT R7 258 - 0x1C1C0A07, // 0006 EQ R7 R5 R7 - 0x781E0060, // 0007 JMPF R7 #0069 - 0x8C1C0105, // 0008 GETMET R7 R0 K5 - 0x7C1C0200, // 0009 CALL R7 1 - 0x541E0006, // 000A LDINT R7 7 - 0x1C1C0C07, // 000B EQ R7 R6 R7 - 0x781E0008, // 000C JMPF R7 #0016 - 0x8C1C0906, // 000D GETMET R7 R4 K6 - 0x88240907, // 000E GETMBR R9 R4 K7 - 0x542A0007, // 000F LDINT R10 8 - 0x002A100A, // 0010 ADD R10 K8 R10 - 0x542E000F, // 0011 LDINT R11 16 - 0x0028140B, // 0012 ADD R10 R10 R11 - 0x7C1C0600, // 0013 CALL R7 3 - 0x80040E00, // 0014 RET 1 R7 - 0x70020052, // 0015 JMP #0069 - 0x541E000E, // 0016 LDINT R7 15 - 0x1C1C0C07, // 0017 EQ R7 R6 R7 - 0x781E0021, // 0018 JMPF R7 #003B - 0x8C1C0109, // 0019 GETMET R7 R0 K9 - 0x7C1C0200, // 001A CALL R7 1 - 0x881C010A, // 001B GETMBR R7 R0 K10 - 0x4C200000, // 001C LDNIL R8 - 0x201C0E08, // 001D NE R7 R7 R8 - 0x781E0015, // 001E JMPF R7 #0035 - 0x881C010B, // 001F GETMBR R7 R0 K11 - 0x4C200000, // 0020 LDNIL R8 - 0x201C0E08, // 0021 NE R7 R7 R8 - 0x781E0011, // 0022 JMPF R7 #0035 - 0xB81E1800, // 0023 GETNGBL R7 K12 - 0x8C1C0F0D, // 0024 GETMET R7 R7 K13 - 0x8824010E, // 0025 GETMBR R9 R0 K14 - 0x8828010A, // 0026 GETMBR R10 R0 K10 - 0x0424120A, // 0027 SUB R9 R9 R10 - 0x5828000F, // 0028 LDCONST R10 K15 - 0x882C010B, // 0029 GETMBR R11 R0 K11 - 0x8830010A, // 002A GETMBR R12 R0 K10 - 0x042C160C, // 002B SUB R11 R11 R12 - 0x5830000F, // 002C LDCONST R12 K15 - 0x5436270F, // 002D LDINT R13 10000 - 0x7C1C0C00, // 002E CALL R7 6 - 0x8C200906, // 002F GETMET R8 R4 K6 - 0x88280910, // 0030 GETMBR R10 R4 K16 - 0x5C2C0E00, // 0031 MOVE R11 R7 - 0x7C200600, // 0032 CALL R8 3 - 0x80041000, // 0033 RET 1 R8 - 0x70020004, // 0034 JMP #003A - 0x8C1C0906, // 0035 GETMET R7 R4 K6 - 0x88240911, // 0036 GETMBR R9 R4 K17 - 0x4C280000, // 0037 LDNIL R10 - 0x7C1C0600, // 0038 CALL R7 3 - 0x80040E00, // 0039 RET 1 R7 - 0x7002002D, // 003A JMP #0069 - 0x541E000B, // 003B LDINT R7 12 - 0x1C1C0C07, // 003C EQ R7 R6 R7 - 0x781E001F, // 003D JMPF R7 #005E - 0x881C010A, // 003E GETMBR R7 R0 K10 - 0x4C200000, // 003F LDNIL R8 - 0x201C0E08, // 0040 NE R7 R7 R8 - 0x781E0015, // 0041 JMPF R7 #0058 - 0x881C010B, // 0042 GETMBR R7 R0 K11 - 0x4C200000, // 0043 LDNIL R8 - 0x201C0E08, // 0044 NE R7 R7 R8 - 0x781E0011, // 0045 JMPF R7 #0058 - 0xB81E1800, // 0046 GETNGBL R7 K12 - 0x8C1C0F0D, // 0047 GETMET R7 R7 K13 - 0x8824010E, // 0048 GETMBR R9 R0 K14 - 0x8828010A, // 0049 GETMBR R10 R0 K10 - 0x0424120A, // 004A SUB R9 R9 R10 - 0x5828000F, // 004B LDCONST R10 K15 - 0x882C010B, // 004C GETMBR R11 R0 K11 - 0x8830010A, // 004D GETMBR R12 R0 K10 - 0x042C160C, // 004E SUB R11 R11 R12 - 0x5830000F, // 004F LDCONST R12 K15 - 0x5436270F, // 0050 LDINT R13 10000 - 0x7C1C0C00, // 0051 CALL R7 6 - 0x8C200906, // 0052 GETMET R8 R4 K6 - 0x88280910, // 0053 GETMBR R10 R4 K16 - 0x5C2C0E00, // 0054 MOVE R11 R7 - 0x7C200600, // 0055 CALL R8 3 - 0x80041000, // 0056 RET 1 R8 - 0x70020004, // 0057 JMP #005D - 0x8C1C0906, // 0058 GETMET R7 R4 K6 - 0x88240911, // 0059 GETMBR R9 R4 K17 - 0x4C280000, // 005A LDNIL R10 - 0x7C1C0600, // 005B CALL R7 3 - 0x80040E00, // 005C RET 1 R7 - 0x7002000A, // 005D JMP #0069 - 0x541EFFFB, // 005E LDINT R7 65532 - 0x1C1C0C07, // 005F EQ R7 R6 R7 - 0x781E0007, // 0060 JMPF R7 #0069 - 0x8C1C0906, // 0061 GETMET R7 R4 K6 - 0x88240912, // 0062 GETMBR R9 R4 K18 - 0x542A0003, // 0063 LDINT R10 4 - 0x002A260A, // 0064 ADD R10 K19 R10 - 0x542E000F, // 0065 LDINT R11 16 - 0x0028140B, // 0066 ADD R10 R10 R11 - 0x7C1C0600, // 0067 CALL R7 3 - 0x80040E00, // 0068 RET 1 R7 - 0x601C0003, // 0069 GETGBL R7 G3 - 0x5C200000, // 006A MOVE R8 R0 - 0x7C1C0200, // 006B CALL R7 1 - 0x8C1C0F14, // 006C GETMET R7 R7 K20 - 0x5C240200, // 006D MOVE R9 R1 - 0x5C280400, // 006E MOVE R10 R2 - 0x7C1C0600, // 006F CALL R7 3 - 0x80040E00, // 0070 RET 1 R7 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: parse_sensors -********************************************************************/ -be_local_closure(Matter_Plugin_ShutterTilt_parse_sensors, /* name */ - be_nested_proto( - 10, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(Shutter), - /* K2 */ be_nested_str_weak(tasmota_shutter_index), - /* K3 */ be_const_int(1), - /* K4 */ be_nested_str_weak(contains), - /* K5 */ be_nested_str_weak(find), - /* K6 */ be_nested_str_weak(Tilt), - /* K7 */ be_nested_str_weak(shadow_shutter_tilt), - /* K8 */ be_nested_str_weak(attribute_updated), - /* K9 */ be_nested_str_weak(parse_sensors), - }), - be_str_weak(parse_sensors), - &be_const_str_solidified, - ( &(const binstruction[32]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x600C0008, // 0001 GETGBL R3 G8 - 0x88100102, // 0002 GETMBR R4 R0 K2 - 0x00100903, // 0003 ADD R4 R4 K3 - 0x7C0C0200, // 0004 CALL R3 1 - 0x000E0203, // 0005 ADD R3 K1 R3 - 0x8C100304, // 0006 GETMET R4 R1 K4 - 0x5C180600, // 0007 MOVE R6 R3 - 0x7C100400, // 0008 CALL R4 2 - 0x7812000E, // 0009 JMPF R4 #0019 - 0x94100203, // 000A GETIDX R4 R1 R3 - 0x8C140905, // 000B GETMET R5 R4 K5 - 0x581C0006, // 000C LDCONST R7 K6 - 0x7C140400, // 000D CALL R5 2 - 0x4C180000, // 000E LDNIL R6 - 0x20180A06, // 000F NE R6 R5 R6 - 0x781A0007, // 0010 JMPF R6 #0019 - 0x88180107, // 0011 GETMBR R6 R0 K7 - 0x20180A06, // 0012 NE R6 R5 R6 - 0x781A0003, // 0013 JMPF R6 #0018 - 0x8C180108, // 0014 GETMET R6 R0 K8 - 0x54220101, // 0015 LDINT R8 258 - 0x5426000E, // 0016 LDINT R9 15 - 0x7C180600, // 0017 CALL R6 3 - 0x90020E05, // 0018 SETMBR R0 K7 R5 - 0x60100003, // 0019 GETGBL R4 G3 - 0x5C140000, // 001A MOVE R5 R0 - 0x7C100200, // 001B CALL R4 1 - 0x8C100909, // 001C GETMET R4 R4 K9 - 0x5C180200, // 001D MOVE R6 R1 - 0x7C100400, // 001E CALL R4 2 - 0x80000000, // 001F RET 0 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified class: Matter_Plugin_ShutterTilt ********************************************************************/ extern const bclass be_class_Matter_Plugin_Shutter; be_local_class(Matter_Plugin_ShutterTilt, - 2, + 3, &be_class_Matter_Plugin_Shutter, - be_nested_map(9, + be_nested_map(10, ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(update_tilt_min_max, -1), be_const_closure(Matter_Plugin_ShutterTilt_update_tilt_min_max_closure) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Shutter_X20_X2B_X20Tilt) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_ShutterTilt_read_attribute_closure) }, { be_const_key_weak(TYPE, -1), be_nested_str_weak(shutter_X2Btilt) }, - { be_const_key_weak(update_tilt_min_max, 0), be_const_closure(Matter_Plugin_ShutterTilt_update_tilt_min_max_closure) }, - { be_const_key_weak(parse_sensors, 7), be_const_closure(Matter_Plugin_ShutterTilt_parse_sensors_closure) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak(Shutter_X20_X2B_X20Tilt) }, { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, + be_const_map( * be_nested_map(6, ( (struct bmapnode*) &(const bmapnode[]) { { be_const_key_int(258, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(4, + be_const_list( * be_nested_list(14, ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(5), + be_const_int(7), + be_const_int(10), + be_const_int(11), + be_const_int(13), + be_const_int(14), + be_const_int(23), + be_const_int(65532), + be_const_int(65533), be_const_int(7), be_const_int(12), be_const_int(15), be_const_int(65532), })) ) } )) }, + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), })) ) } )) }, + { be_const_key_int(29, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(tilt_min, 8), be_const_var(1) }, + { be_const_key_weak(parse_sensors, -1), be_const_closure(Matter_Plugin_ShutterTilt_parse_sensors_closure) }, { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_ShutterTilt_invoke_request_closure) }, - { be_const_key_weak(tilt_min, 2), be_const_var(0) }, - { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_ShutterTilt_read_attribute_closure) }, - { be_const_key_weak(tilt_max, -1), be_const_var(1) }, + { be_const_key_weak(shadow_shutter_tilt, -1), be_const_var(0) }, + { be_const_key_weak(tilt_max, 3), be_const_var(2) }, })), be_str_weak(Matter_Plugin_ShutterTilt) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Light1.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Light1.h new file mode 100644 index 000000000000..8cdf671bf84b --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Light1.h @@ -0,0 +1,642 @@ +/* Solidification of Matter_Plugin_4_Bridge_Light1.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Bridge_Light1; + +/******************************************************************** +** Solidified function: invoke_request +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light1_invoke_request, /* name */ + be_nested_proto( + 21, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[20]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(command), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(findsubval), + /* K6 */ be_nested_str_weak(set_bri), + /* K7 */ be_nested_str_weak(log), + /* K8 */ be_nested_str_weak(bri_X3A), + /* K9 */ be_nested_str_weak(publish_command), + /* K10 */ be_nested_str_weak(Bri), + /* K11 */ be_nested_str_weak(tasmota), + /* K12 */ be_nested_str_weak(scale_uint), + /* K13 */ be_nested_str_weak(Dimmer), + /* K14 */ be_const_int(1), + /* K15 */ be_const_int(2), + /* K16 */ be_const_int(3), + /* K17 */ be_nested_str_weak(set_onoff), + /* K18 */ be_nested_str_weak(Power), + /* K19 */ be_nested_str_weak(invoke_request), + }), + be_str_weak(invoke_request), + &be_const_str_solidified, + ( &(const binstruction[132]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140702, // 0002 GETMBR R5 R3 K2 + 0x88180703, // 0003 GETMBR R6 R3 K3 + 0x541E0007, // 0004 LDINT R7 8 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0072, // 0006 JMPF R7 #007A + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E0021, // 0008 JMPF R7 #002B + 0x8C1C0505, // 0009 GETMET R7 R2 K5 + 0x58240004, // 000A LDCONST R9 K4 + 0x7C1C0400, // 000B CALL R7 2 + 0x8C200106, // 000C GETMET R8 R0 K6 + 0x5C280E00, // 000D MOVE R10 R7 + 0x7C200400, // 000E CALL R8 2 + 0x60200008, // 000F GETGBL R8 G8 + 0x5C240E00, // 0010 MOVE R9 R7 + 0x7C200200, // 0011 CALL R8 1 + 0x00221008, // 0012 ADD R8 K8 R8 + 0x900E0E08, // 0013 SETMBR R3 K7 R8 + 0x8C200109, // 0014 GETMET R8 R0 K9 + 0x5828000A, // 0015 LDCONST R10 K10 + 0xB82E1600, // 0016 GETNGBL R11 K11 + 0x8C2C170C, // 0017 GETMET R11 R11 K12 + 0x5C340E00, // 0018 MOVE R13 R7 + 0x58380004, // 0019 LDCONST R14 K4 + 0x543E00FD, // 001A LDINT R15 254 + 0x58400004, // 001B LDCONST R16 K4 + 0x544600FE, // 001C LDINT R17 255 + 0x7C2C0C00, // 001D CALL R11 6 + 0x5830000D, // 001E LDCONST R12 K13 + 0xB8361600, // 001F GETNGBL R13 K11 + 0x8C341B0C, // 0020 GETMET R13 R13 K12 + 0x5C3C0E00, // 0021 MOVE R15 R7 + 0x58400004, // 0022 LDCONST R16 K4 + 0x544600FD, // 0023 LDINT R17 254 + 0x58480004, // 0024 LDCONST R18 K4 + 0x544E0063, // 0025 LDINT R19 100 + 0x7C340C00, // 0026 CALL R13 6 + 0x7C200A00, // 0027 CALL R8 5 + 0x50200200, // 0028 LDBOOL R8 1 0 + 0x80041000, // 0029 RET 1 R8 + 0x7002004D, // 002A JMP #0079 + 0x1C1C0D0E, // 002B EQ R7 R6 K14 + 0x781E0002, // 002C JMPF R7 #0030 + 0x501C0200, // 002D LDBOOL R7 1 0 + 0x80040E00, // 002E RET 1 R7 + 0x70020048, // 002F JMP #0079 + 0x1C1C0D0F, // 0030 EQ R7 R6 K15 + 0x781E0002, // 0031 JMPF R7 #0035 + 0x501C0200, // 0032 LDBOOL R7 1 0 + 0x80040E00, // 0033 RET 1 R7 + 0x70020043, // 0034 JMP #0079 + 0x1C1C0D10, // 0035 EQ R7 R6 K16 + 0x781E0002, // 0036 JMPF R7 #003A + 0x501C0200, // 0037 LDBOOL R7 1 0 + 0x80040E00, // 0038 RET 1 R7 + 0x7002003E, // 0039 JMP #0079 + 0x541E0003, // 003A LDINT R7 4 + 0x1C1C0C07, // 003B EQ R7 R6 R7 + 0x781E002A, // 003C JMPF R7 #0068 + 0x8C1C0505, // 003D GETMET R7 R2 K5 + 0x58240004, // 003E LDCONST R9 K4 + 0x7C1C0400, // 003F CALL R7 2 + 0x8C200106, // 0040 GETMET R8 R0 K6 + 0x5C280E00, // 0041 MOVE R10 R7 + 0x7C200400, // 0042 CALL R8 2 + 0x24200F04, // 0043 GT R8 R7 K4 + 0x8C240111, // 0044 GETMET R9 R0 K17 + 0x5C2C1000, // 0045 MOVE R11 R8 + 0x7C240400, // 0046 CALL R9 2 + 0x60240008, // 0047 GETGBL R9 G8 + 0x5C280E00, // 0048 MOVE R10 R7 + 0x7C240200, // 0049 CALL R9 1 + 0x00261009, // 004A ADD R9 K8 R9 + 0x900E0E09, // 004B SETMBR R3 K7 R9 + 0x8C240109, // 004C GETMET R9 R0 K9 + 0x582C000A, // 004D LDCONST R11 K10 + 0xB8321600, // 004E GETNGBL R12 K11 + 0x8C30190C, // 004F GETMET R12 R12 K12 + 0x5C380E00, // 0050 MOVE R14 R7 + 0x583C0004, // 0051 LDCONST R15 K4 + 0x544200FD, // 0052 LDINT R16 254 + 0x58440004, // 0053 LDCONST R17 K4 + 0x544A00FE, // 0054 LDINT R18 255 + 0x7C300C00, // 0055 CALL R12 6 + 0x5834000D, // 0056 LDCONST R13 K13 + 0xB83A1600, // 0057 GETNGBL R14 K11 + 0x8C381D0C, // 0058 GETMET R14 R14 K12 + 0x5C400E00, // 0059 MOVE R16 R7 + 0x58440004, // 005A LDCONST R17 K4 + 0x544A00FD, // 005B LDINT R18 254 + 0x584C0004, // 005C LDCONST R19 K4 + 0x54520063, // 005D LDINT R20 100 + 0x7C380C00, // 005E CALL R14 6 + 0x583C0012, // 005F LDCONST R15 K18 + 0x78220001, // 0060 JMPF R8 #0063 + 0x5840000E, // 0061 LDCONST R16 K14 + 0x70020000, // 0062 JMP #0064 + 0x58400004, // 0063 LDCONST R16 K4 + 0x7C240E00, // 0064 CALL R9 7 + 0x50240200, // 0065 LDBOOL R9 1 0 + 0x80041200, // 0066 RET 1 R9 + 0x70020010, // 0067 JMP #0079 + 0x541E0004, // 0068 LDINT R7 5 + 0x1C1C0C07, // 0069 EQ R7 R6 R7 + 0x781E0002, // 006A JMPF R7 #006E + 0x501C0200, // 006B LDBOOL R7 1 0 + 0x80040E00, // 006C RET 1 R7 + 0x7002000A, // 006D JMP #0079 + 0x541E0005, // 006E LDINT R7 6 + 0x1C1C0C07, // 006F EQ R7 R6 R7 + 0x781E0002, // 0070 JMPF R7 #0074 + 0x501C0200, // 0071 LDBOOL R7 1 0 + 0x80040E00, // 0072 RET 1 R7 + 0x70020004, // 0073 JMP #0079 + 0x541E0006, // 0074 LDINT R7 7 + 0x1C1C0C07, // 0075 EQ R7 R6 R7 + 0x781E0001, // 0076 JMPF R7 #0079 + 0x501C0200, // 0077 LDBOOL R7 1 0 + 0x80040E00, // 0078 RET 1 R7 + 0x70020008, // 0079 JMP #0083 + 0x601C0003, // 007A GETGBL R7 G3 + 0x5C200000, // 007B MOVE R8 R0 + 0x7C1C0200, // 007C CALL R7 1 + 0x8C1C0F13, // 007D GETMET R7 R7 K19 + 0x5C240200, // 007E MOVE R9 R1 + 0x5C280400, // 007F MOVE R10 R2 + 0x5C2C0600, // 0080 MOVE R11 R3 + 0x7C1C0800, // 0081 CALL R7 4 + 0x80040E00, // 0082 RET 1 R7 + 0x80000000, // 0083 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light1_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[15]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(shadow_bri), + /* K7 */ be_nested_str_weak(set), + /* K8 */ be_nested_str_weak(U1), + /* K9 */ be_nested_str_weak(NULL), + /* K10 */ be_const_int(2), + /* K11 */ be_const_int(3), + /* K12 */ be_nested_str_weak(U4), + /* K13 */ be_const_int(1), + /* K14 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[99]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0007, // 0004 LDINT R7 8 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0051, // 0006 JMPF R7 #0059 + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x1C1C0D05, // 0009 EQ R7 R6 K5 + 0x781E000F, // 000A JMPF R7 #001B + 0x881C0106, // 000B GETMBR R7 R0 K6 + 0x4C200000, // 000C LDNIL R8 + 0x201C0E08, // 000D NE R7 R7 R8 + 0x781E0005, // 000E JMPF R7 #0015 + 0x8C1C0707, // 000F GETMET R7 R3 K7 + 0x88240908, // 0010 GETMBR R9 R4 K8 + 0x88280106, // 0011 GETMBR R10 R0 K6 + 0x7C1C0600, // 0012 CALL R7 3 + 0x80040E00, // 0013 RET 1 R7 + 0x70020004, // 0014 JMP #001A + 0x8C1C0707, // 0015 GETMET R7 R3 K7 + 0x88240909, // 0016 GETMBR R9 R4 K9 + 0x4C280000, // 0017 LDNIL R10 + 0x7C1C0600, // 0018 CALL R7 3 + 0x80040E00, // 0019 RET 1 R7 + 0x7002003C, // 001A JMP #0058 + 0x1C1C0D0A, // 001B EQ R7 R6 K10 + 0x781E0005, // 001C JMPF R7 #0023 + 0x8C1C0707, // 001D GETMET R7 R3 K7 + 0x88240908, // 001E GETMBR R9 R4 K8 + 0x58280005, // 001F LDCONST R10 K5 + 0x7C1C0600, // 0020 CALL R7 3 + 0x80040E00, // 0021 RET 1 R7 + 0x70020034, // 0022 JMP #0058 + 0x1C1C0D0B, // 0023 EQ R7 R6 K11 + 0x781E0005, // 0024 JMPF R7 #002B + 0x8C1C0707, // 0025 GETMET R7 R3 K7 + 0x88240908, // 0026 GETMBR R9 R4 K8 + 0x542A00FD, // 0027 LDINT R10 254 + 0x7C1C0600, // 0028 CALL R7 3 + 0x80040E00, // 0029 RET 1 R7 + 0x7002002C, // 002A JMP #0058 + 0x541E000E, // 002B LDINT R7 15 + 0x1C1C0C07, // 002C EQ R7 R6 R7 + 0x781E0005, // 002D JMPF R7 #0034 + 0x8C1C0707, // 002E GETMET R7 R3 K7 + 0x88240908, // 002F GETMBR R9 R4 K8 + 0x58280005, // 0030 LDCONST R10 K5 + 0x7C1C0600, // 0031 CALL R7 3 + 0x80040E00, // 0032 RET 1 R7 + 0x70020023, // 0033 JMP #0058 + 0x541E0010, // 0034 LDINT R7 17 + 0x1C1C0C07, // 0035 EQ R7 R6 R7 + 0x781E000F, // 0036 JMPF R7 #0047 + 0x881C0106, // 0037 GETMBR R7 R0 K6 + 0x4C200000, // 0038 LDNIL R8 + 0x201C0E08, // 0039 NE R7 R7 R8 + 0x781E0005, // 003A JMPF R7 #0041 + 0x8C1C0707, // 003B GETMET R7 R3 K7 + 0x88240908, // 003C GETMBR R9 R4 K8 + 0x88280106, // 003D GETMBR R10 R0 K6 + 0x7C1C0600, // 003E CALL R7 3 + 0x80040E00, // 003F RET 1 R7 + 0x70020004, // 0040 JMP #0046 + 0x8C1C0707, // 0041 GETMET R7 R3 K7 + 0x88240909, // 0042 GETMBR R9 R4 K9 + 0x4C280000, // 0043 LDNIL R10 + 0x7C1C0600, // 0044 CALL R7 3 + 0x80040E00, // 0045 RET 1 R7 + 0x70020010, // 0046 JMP #0058 + 0x541EFFFB, // 0047 LDINT R7 65532 + 0x1C1C0C07, // 0048 EQ R7 R6 R7 + 0x781E0005, // 0049 JMPF R7 #0050 + 0x8C1C0707, // 004A GETMET R7 R3 K7 + 0x8824090C, // 004B GETMBR R9 R4 K12 + 0x5828000D, // 004C LDCONST R10 K13 + 0x7C1C0600, // 004D CALL R7 3 + 0x80040E00, // 004E RET 1 R7 + 0x70020007, // 004F JMP #0058 + 0x541EFFFC, // 0050 LDINT R7 65533 + 0x1C1C0C07, // 0051 EQ R7 R6 R7 + 0x781E0004, // 0052 JMPF R7 #0058 + 0x8C1C0707, // 0053 GETMET R7 R3 K7 + 0x8824090C, // 0054 GETMBR R9 R4 K12 + 0x542A0004, // 0055 LDINT R10 5 + 0x7C1C0600, // 0056 CALL R7 3 + 0x80040E00, // 0057 RET 1 R7 + 0x70020008, // 0058 JMP #0062 + 0x601C0003, // 0059 GETGBL R7 G3 + 0x5C200000, // 005A MOVE R8 R0 + 0x7C1C0200, // 005B CALL R7 1 + 0x8C1C0F0E, // 005C GETMET R7 R7 K14 + 0x5C240200, // 005D MOVE R9 R1 + 0x5C280400, // 005E MOVE R10 R2 + 0x5C2C0600, // 005F MOVE R11 R3 + 0x7C1C0800, // 0060 CALL R7 4 + 0x80040E00, // 0061 RET 1 R7 + 0x80000000, // 0062 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light1_web_values, /* name */ + be_nested_proto( + 9, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(web_values_prefix), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(_X25s_X20_X25s), + /* K4 */ be_nested_str_weak(web_value_onoff), + /* K5 */ be_nested_str_weak(shadow_onoff), + /* K6 */ be_nested_str_weak(web_value_dimmer), + }), + be_str_weak(web_values), + &be_const_str_solidified, + ( &(const binstruction[14]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x60100018, // 0004 GETGBL R4 G24 + 0x58140003, // 0005 LDCONST R5 K3 + 0x8C180104, // 0006 GETMET R6 R0 K4 + 0x88200105, // 0007 GETMBR R8 R0 K5 + 0x7C180400, // 0008 CALL R6 2 + 0x8C1C0106, // 0009 GETMET R7 R0 K6 + 0x7C1C0200, // 000A CALL R7 1 + 0x7C100600, // 000B CALL R4 3 + 0x7C080400, // 000C CALL R2 2 + 0x80000000, // 000D RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_bri +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light1_set_bri, /* name */ + be_nested_proto( + 9, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(scale_uint), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(call_remote_sync), + /* K4 */ be_nested_str_weak(Dimmer), + /* K5 */ be_nested_str_weak(parse_update), + }), + be_str_weak(set_bri), + &be_const_str_solidified, + ( &(const binstruction[22]) { /* code */ + 0xB80A0000, // 0000 GETNGBL R2 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x58140002, // 0003 LDCONST R5 K2 + 0x541A00FD, // 0004 LDINT R6 254 + 0x581C0002, // 0005 LDCONST R7 K2 + 0x54220063, // 0006 LDINT R8 100 + 0x7C080C00, // 0007 CALL R2 6 + 0x8C0C0103, // 0008 GETMET R3 R0 K3 + 0x58140004, // 0009 LDCONST R5 K4 + 0x60180008, // 000A GETGBL R6 G8 + 0x5C1C0400, // 000B MOVE R7 R2 + 0x7C180200, // 000C CALL R6 1 + 0x7C0C0600, // 000D CALL R3 3 + 0x4C100000, // 000E LDNIL R4 + 0x20100604, // 000F NE R4 R3 R4 + 0x78120003, // 0010 JMPF R4 #0015 + 0x8C100105, // 0011 GETMET R4 R0 K5 + 0x5C180600, // 0012 MOVE R6 R3 + 0x541E000A, // 0013 LDINT R7 11 + 0x7C100600, // 0014 CALL R4 3 + 0x80000000, // 0015 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_update +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light1_parse_update, /* name */ + be_nested_proto( + 11, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(parse_update), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(Dimmer), + /* K3 */ be_nested_str_weak(tasmota), + /* K4 */ be_nested_str_weak(scale_uint), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(shadow_bri), + /* K7 */ be_nested_str_weak(attribute_updated), + }), + be_str_weak(parse_update), + &be_const_str_solidified, + ( &(const binstruction[35]) { /* code */ + 0x600C0003, // 0000 GETGBL R3 G3 + 0x5C100000, // 0001 MOVE R4 R0 + 0x7C0C0200, // 0002 CALL R3 1 + 0x8C0C0700, // 0003 GETMET R3 R3 K0 + 0x5C140200, // 0004 MOVE R5 R1 + 0x5C180400, // 0005 MOVE R6 R2 + 0x7C0C0600, // 0006 CALL R3 3 + 0x540E000A, // 0007 LDINT R3 11 + 0x1C0C0403, // 0008 EQ R3 R2 R3 + 0x780E0017, // 0009 JMPF R3 #0022 + 0x600C0009, // 000A GETGBL R3 G9 + 0x8C100301, // 000B GETMET R4 R1 K1 + 0x58180002, // 000C LDCONST R6 K2 + 0x7C100400, // 000D CALL R4 2 + 0x7C0C0200, // 000E CALL R3 1 + 0x4C100000, // 000F LDNIL R4 + 0x20100604, // 0010 NE R4 R3 R4 + 0x7812000F, // 0011 JMPF R4 #0022 + 0xB8120600, // 0012 GETNGBL R4 K3 + 0x8C100904, // 0013 GETMET R4 R4 K4 + 0x5C180600, // 0014 MOVE R6 R3 + 0x581C0005, // 0015 LDCONST R7 K5 + 0x54220063, // 0016 LDINT R8 100 + 0x58240005, // 0017 LDCONST R9 K5 + 0x542A00FD, // 0018 LDINT R10 254 + 0x7C100C00, // 0019 CALL R4 6 + 0x88140106, // 001A GETMBR R5 R0 K6 + 0x20140805, // 001B NE R5 R4 R5 + 0x78160004, // 001C JMPF R5 #0022 + 0x8C140107, // 001D GETMET R5 R0 K7 + 0x541E0007, // 001E LDINT R7 8 + 0x58200005, // 001F LDCONST R8 K5 + 0x7C140600, // 0020 CALL R5 3 + 0x90020C04, // 0021 SETMBR R0 K6 R4 + 0x80000000, // 0022 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_value_dimmer +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light1_web_value_dimmer, /* name */ + be_nested_proto( + 9, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(), + /* K1 */ be_nested_str_weak(shadow_bri), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(scale_uint), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(_X25i_X25_X25), + /* K6 */ be_nested_str_weak(_X26_X23128261_X3B_X20), + }), + be_str_weak(web_value_dimmer), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x88080101, // 0001 GETMBR R2 R0 K1 + 0x4C0C0000, // 0002 LDNIL R3 + 0x20080403, // 0003 NE R2 R2 R3 + 0x780A000C, // 0004 JMPF R2 #0012 + 0xB80A0400, // 0005 GETNGBL R2 K2 + 0x8C080503, // 0006 GETMET R2 R2 K3 + 0x88100101, // 0007 GETMBR R4 R0 K1 + 0x58140004, // 0008 LDCONST R5 K4 + 0x541A00FD, // 0009 LDINT R6 254 + 0x581C0004, // 000A LDCONST R7 K4 + 0x54220063, // 000B LDINT R8 100 + 0x7C080C00, // 000C CALL R2 6 + 0x600C0018, // 000D GETGBL R3 G24 + 0x58100005, // 000E LDCONST R4 K5 + 0x5C140400, // 000F MOVE R5 R2 + 0x7C0C0400, // 0010 CALL R3 2 + 0x5C040600, // 0011 MOVE R1 R3 + 0x000A0C01, // 0012 ADD R2 K6 R1 + 0x80040400, // 0013 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_Light1 +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Bridge_Light0; +be_local_class(Matter_Plugin_Bridge_Light1, + 1, + &be_class_Matter_Plugin_Bridge_Light0, + be_nested_map(11, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(web_value_dimmer, -1), be_const_closure(Matter_Plugin_Bridge_Light1_web_value_dimmer_closure) }, + { be_const_key_weak(parse_update, -1), be_const_closure(Matter_Plugin_Bridge_Light1_parse_update_closure) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(http_light1) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Bridge_Light1_read_attribute_closure) }, + { be_const_key_weak(TYPES, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(257, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(shadow_bri, -1), be_const_var(0) }, + { be_const_key_weak(CLUSTERS, 5), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(7, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(29, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(8, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(2), + be_const_int(3), + be_const_int(15), + be_const_int(17), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(set_bri, -1), be_const_closure(Matter_Plugin_Bridge_Light1_set_bri_closure) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Light_X201_X20Dimmer) }, + { be_const_key_weak(web_values, 1), be_const_closure(Matter_Plugin_Bridge_Light1_web_values_closure) }, + { be_const_key_weak(invoke_request, 0), be_const_closure(Matter_Plugin_Bridge_Light1_invoke_request_closure) }, + })), + be_str_weak(Matter_Plugin_Bridge_Light1) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_Light1_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_Light1); + be_setglobal(vm, "Matter_Plugin_Bridge_Light1"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_OnOff.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_OnOff.h new file mode 100644 index 000000000000..0e7f4e70751d --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_OnOff.h @@ -0,0 +1,82 @@ +/* Solidification of Matter_Plugin_4_Bridge_OnOff.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Bridge_OnOff; + +/******************************************************************** +** Solidified function: web_values +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_OnOff_web_values, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(web_values_prefix), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(Relay_X20_X25i_X20_X25s), + /* K4 */ be_nested_str_weak(tasmota_relay_index), + /* K5 */ be_nested_str_weak(web_value_onoff), + /* K6 */ be_nested_str_weak(shadow_onoff), + }), + be_str_weak(web_values), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x60100018, // 0004 GETGBL R4 G24 + 0x58140003, // 0005 LDCONST R5 K3 + 0x88180104, // 0006 GETMBR R6 R0 K4 + 0x8C1C0105, // 0007 GETMET R7 R0 K5 + 0x88240106, // 0008 GETMBR R9 R0 K6 + 0x7C1C0400, // 0009 CALL R7 2 + 0x7C100600, // 000A CALL R4 3 + 0x7C080400, // 000B CALL R2 2 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_OnOff +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Bridge_Light0; +be_local_class(Matter_Plugin_Bridge_OnOff, + 0, + &be_class_Matter_Plugin_Bridge_Light0, + be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(TYPES, 3), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(266, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Relay) }, + { be_const_key_weak(web_values, -1), be_const_closure(Matter_Plugin_Bridge_OnOff_web_values_closure) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(Relay_X3Cx_X3E_X20number) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(http_relay) }, + })), + be_str_weak(Matter_Plugin_Bridge_OnOff) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_OnOff_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_OnOff); + be_setglobal(vm, "Matter_Plugin_Bridge_OnOff"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Contact.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Contact.h new file mode 100644 index 000000000000..ded960e54de7 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Contact.h @@ -0,0 +1,430 @@ +/* Solidification of Matter_Plugin_4_Bridge_Sensor_Contact.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Bridge_Sensor_Contact; + +/******************************************************************** +** Solidified function: +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Contact__X3Clambda_X3E, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x60040009, // 0000 GETGBL R1 G9 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Contact_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(tasmota_switch_index), + /* K2 */ be_nested_str_weak(find), + /* K3 */ be_nested_str_weak(ARG), + /* K4 */ be_const_int(1), + /* K5 */ be_const_int(0), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x60100009, // 0008 GETGBL R4 G9 + 0x8C140702, // 0009 GETMET R5 R3 K2 + 0x881C0103, // 000A GETMBR R7 R0 K3 + 0x58200004, // 000B LDCONST R8 K4 + 0x7C140600, // 000C CALL R5 3 + 0x7C100200, // 000D CALL R4 1 + 0x90020204, // 000E SETMBR R0 K1 R4 + 0x88100101, // 000F GETMBR R4 R0 K1 + 0x18100905, // 0010 LE R4 R4 K5 + 0x78120000, // 0011 JMPF R4 #0013 + 0x90020304, // 0012 SETMBR R0 K1 K4 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values_prefix +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Contact_web_values_prefix, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(get_name), + /* K2 */ be_nested_str_weak(Switch), + /* K3 */ be_nested_str_weak(tasmota_switch_index), + /* K4 */ be_nested_str_weak(content_send), + /* K5 */ be_nested_str_weak(PREFIX), + /* K6 */ be_nested_str_weak(html_escape), + /* K7 */ be_nested_str_weak(), + }), + be_str_weak(web_values_prefix), + &be_const_str_solidified, + ( &(const binstruction[22]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x5C0C0400, // 0003 MOVE R3 R2 + 0x740E0004, // 0004 JMPT R3 #000A + 0x600C0008, // 0005 GETGBL R3 G8 + 0x88100103, // 0006 GETMBR R4 R0 K3 + 0x7C0C0200, // 0007 CALL R3 1 + 0x000E0403, // 0008 ADD R3 K2 R3 + 0x5C080600, // 0009 MOVE R2 R3 + 0x8C0C0304, // 000A GETMET R3 R1 K4 + 0x60140018, // 000B GETGBL R5 G24 + 0x88180105, // 000C GETMBR R6 R0 K5 + 0x780A0003, // 000D JMPF R2 #0012 + 0x8C1C0306, // 000E GETMET R7 R1 K6 + 0x5C240400, // 000F MOVE R9 R2 + 0x7C1C0400, // 0010 CALL R7 2 + 0x70020000, // 0011 JMP #0013 + 0x581C0007, // 0012 LDCONST R7 K7 + 0x7C140400, // 0013 CALL R5 2 + 0x7C0C0400, // 0014 CALL R3 2 + 0x80000000, // 0015 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_update +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Contact_parse_update, /* name */ + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(find), + /* K1 */ be_nested_str_weak(Switch), + /* K2 */ be_nested_str_weak(tasmota_switch_index), + /* K3 */ be_nested_str_weak(ON), + /* K4 */ be_nested_str_weak(shadow_contact), + /* K5 */ be_nested_str_weak(attribute_updated), + /* K6 */ be_const_int(0), + }), + be_str_weak(parse_update), + &be_const_str_solidified, + ( &(const binstruction[28]) { /* code */ + 0x540E0007, // 0000 LDINT R3 8 + 0x1C0C0403, // 0001 EQ R3 R2 R3 + 0x780E0017, // 0002 JMPF R3 #001B + 0x500C0000, // 0003 LDBOOL R3 0 0 + 0x8C100300, // 0004 GETMET R4 R1 K0 + 0x60180008, // 0005 GETGBL R6 G8 + 0x881C0102, // 0006 GETMBR R7 R0 K2 + 0x7C180200, // 0007 CALL R6 1 + 0x001A0206, // 0008 ADD R6 K1 R6 + 0x7C100400, // 0009 CALL R4 2 + 0x1C100903, // 000A EQ R4 R4 K3 + 0x5C0C0800, // 000B MOVE R3 R4 + 0x88100104, // 000C GETMBR R4 R0 K4 + 0x4C140000, // 000D LDNIL R5 + 0x20100805, // 000E NE R4 R4 R5 + 0x78120009, // 000F JMPF R4 #001A + 0x88100104, // 0010 GETMBR R4 R0 K4 + 0x60140017, // 0011 GETGBL R5 G23 + 0x5C180600, // 0012 MOVE R6 R3 + 0x7C140200, // 0013 CALL R5 1 + 0x20100805, // 0014 NE R4 R4 R5 + 0x78120003, // 0015 JMPF R4 #001A + 0x8C100105, // 0016 GETMET R4 R0 K5 + 0x541A0044, // 0017 LDINT R6 69 + 0x581C0006, // 0018 LDCONST R7 K6 + 0x7C100600, // 0019 CALL R4 3 + 0x90020803, // 001A SETMBR R0 K4 R3 + 0x80000000, // 001B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Contact_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(shadow_contact), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(BOOL), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_nested_str_weak(U4), + /* K10 */ be_const_int(1), + /* K11 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[53]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0044, // 0004 LDINT R7 69 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0023, // 0006 JMPF R7 #002B + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E000F, // 0008 JMPF R7 #0019 + 0x881C0105, // 0009 GETMBR R7 R0 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E0005, // 000C JMPF R7 #0013 + 0x8C1C0706, // 000D GETMET R7 R3 K6 + 0x88240907, // 000E GETMBR R9 R4 K7 + 0x88280105, // 000F GETMBR R10 R0 K5 + 0x7C1C0600, // 0010 CALL R7 3 + 0x80040E00, // 0011 RET 1 R7 + 0x70020004, // 0012 JMP #0018 + 0x8C1C0706, // 0013 GETMET R7 R3 K6 + 0x88240908, // 0014 GETMBR R9 R4 K8 + 0x4C280000, // 0015 LDNIL R10 + 0x7C1C0600, // 0016 CALL R7 3 + 0x80040E00, // 0017 RET 1 R7 + 0x70020010, // 0018 JMP #002A + 0x541EFFFB, // 0019 LDINT R7 65532 + 0x1C1C0C07, // 001A EQ R7 R6 R7 + 0x781E0005, // 001B JMPF R7 #0022 + 0x8C1C0706, // 001C GETMET R7 R3 K6 + 0x88240909, // 001D GETMBR R9 R4 K9 + 0x58280004, // 001E LDCONST R10 K4 + 0x7C1C0600, // 001F CALL R7 3 + 0x80040E00, // 0020 RET 1 R7 + 0x70020007, // 0021 JMP #002A + 0x541EFFFC, // 0022 LDINT R7 65533 + 0x1C1C0C07, // 0023 EQ R7 R6 R7 + 0x781E0004, // 0024 JMPF R7 #002A + 0x8C1C0706, // 0025 GETMET R7 R3 K6 + 0x88240909, // 0026 GETMBR R9 R4 K9 + 0x5828000A, // 0027 LDCONST R10 K10 + 0x7C1C0600, // 0028 CALL R7 3 + 0x80040E00, // 0029 RET 1 R7 + 0x70020008, // 002A JMP #0034 + 0x601C0003, // 002B GETGBL R7 G3 + 0x5C200000, // 002C MOVE R8 R0 + 0x7C1C0200, // 002D CALL R7 1 + 0x8C1C0F0B, // 002E GETMET R7 R7 K11 + 0x5C240200, // 002F MOVE R9 R1 + 0x5C280400, // 0030 MOVE R10 R2 + 0x5C2C0600, // 0031 MOVE R11 R3 + 0x7C1C0800, // 0032 CALL R7 4 + 0x80040E00, // 0033 RET 1 R7 + 0x80000000, // 0034 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Contact_web_values, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(web_values_prefix), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(Contact_X25i_X20_X25s), + /* K4 */ be_nested_str_weak(tasmota_switch_index), + /* K5 */ be_nested_str_weak(web_value_onoff), + /* K6 */ be_nested_str_weak(shadow_contact), + }), + be_str_weak(web_values), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x60100018, // 0004 GETGBL R4 G24 + 0x58140003, // 0005 LDCONST R5 K3 + 0x88180104, // 0006 GETMBR R6 R0 K4 + 0x8C1C0105, // 0007 GETMET R7 R0 K5 + 0x88240106, // 0008 GETMBR R9 R0 K6 + 0x7C1C0400, // 0009 CALL R7 2 + 0x7C100600, // 000A CALL R4 3 + 0x7C080400, // 000B CALL R2 2 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_Sensor_Contact +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Bridge_HTTP; +be_local_class(Matter_Plugin_Bridge_Sensor_Contact, + 2, + &be_class_Matter_Plugin_Bridge_HTTP, + be_nested_map(16, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(ARG_TYPE, 5), be_const_static_closure(Matter_Plugin_Bridge_Sensor_Contact__X3Clambda_X3E_closure) }, + { be_const_key_weak(ARG_HINT, 4), be_nested_str_weak(Switch_X3Cx_X3E_X20number) }, + { be_const_key_weak(shadow_contact, -1), be_const_var(1) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_Contact_init_closure) }, + { be_const_key_weak(web_values_prefix, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_Contact_web_values_prefix_closure) }, + { be_const_key_weak(web_values, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_Contact_web_values_closure) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Contact) }, + { be_const_key_weak(ARG, -1), be_nested_str_weak(switch) }, + { be_const_key_weak(parse_update, 11), be_const_closure(Matter_Plugin_Bridge_Sensor_Contact_parse_update_closure) }, + { be_const_key_weak(read_attribute, 12), be_const_closure(Matter_Plugin_Bridge_Sensor_Contact_read_attribute_closure) }, + { be_const_key_weak(CLUSTERS, 9), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(3, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(69, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(UPDATE_TIME, -1), be_const_int(5000) }, + { be_const_key_weak(TYPES, 14), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(21, -1), be_const_int(1) }, + })) ) } )) }, + { be_const_key_weak(TYPE, 6), be_nested_str_weak(http_contact) }, + { be_const_key_weak(tasmota_switch_index, -1), be_const_var(0) }, + { be_const_key_weak(UPDATE_CMD, -1), be_nested_str_weak(Status_X208) }, + })), + be_str_weak(Matter_Plugin_Bridge_Sensor_Contact) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_Sensor_Contact_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_Sensor_Contact); + be_setglobal(vm, "Matter_Plugin_Bridge_Sensor_Contact"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Humidity.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Humidity.h new file mode 100644 index 000000000000..6a2032b50b33 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Humidity.h @@ -0,0 +1,323 @@ +/* Solidification of Matter_Plugin_4_Bridge_Sensor_Humidity.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Bridge_Sensor_Humidity; + +/******************************************************************** +** Solidified function: pre_value +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Humidity_pre_value, /* name */ + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(pre_value), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x20080202, // 0001 NE R2 R1 R2 + 0x780A0004, // 0002 JMPF R2 #0008 + 0x60080009, // 0003 GETGBL R2 G9 + 0x540E0063, // 0004 LDINT R3 100 + 0x080C0203, // 0005 MUL R3 R1 R3 + 0x7C080200, // 0006 CALL R2 1 + 0x70020000, // 0007 JMP #0009 + 0x4C080000, // 0008 LDNIL R2 + 0x80040400, // 0009 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: value_changed +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Humidity_value_changed, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(attribute_updated), + /* K1 */ be_const_int(0), + }), + be_str_weak(value_changed), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x540E0404, // 0001 LDINT R3 1029 + 0x58100001, // 0002 LDCONST R4 K1 + 0x7C040600, // 0003 CALL R1 3 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Humidity_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(shadow_value), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(U2), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_const_int(1), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str_weak(U4), + /* K12 */ be_const_int(3), + /* K13 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[71]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0404, // 0004 LDINT R7 1029 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0035, // 0006 JMPF R7 #003D + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E0011, // 0008 JMPF R7 #001B + 0x881C0105, // 0009 GETMBR R7 R0 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E0007, // 000C JMPF R7 #0015 + 0x8C1C0706, // 000D GETMET R7 R3 K6 + 0x88240907, // 000E GETMBR R9 R4 K7 + 0x60280009, // 000F GETGBL R10 G9 + 0x882C0105, // 0010 GETMBR R11 R0 K5 + 0x7C280200, // 0011 CALL R10 1 + 0x7C1C0600, // 0012 CALL R7 3 + 0x80040E00, // 0013 RET 1 R7 + 0x70020004, // 0014 JMP #001A + 0x8C1C0706, // 0015 GETMET R7 R3 K6 + 0x88240908, // 0016 GETMBR R9 R4 K8 + 0x4C280000, // 0017 LDNIL R10 + 0x7C1C0600, // 0018 CALL R7 3 + 0x80040E00, // 0019 RET 1 R7 + 0x70020020, // 001A JMP #003C + 0x1C1C0D09, // 001B EQ R7 R6 K9 + 0x781E0005, // 001C JMPF R7 #0023 + 0x8C1C0706, // 001D GETMET R7 R3 K6 + 0x88240907, // 001E GETMBR R9 R4 K7 + 0x542A01F3, // 001F LDINT R10 500 + 0x7C1C0600, // 0020 CALL R7 3 + 0x80040E00, // 0021 RET 1 R7 + 0x70020018, // 0022 JMP #003C + 0x1C1C0D0A, // 0023 EQ R7 R6 K10 + 0x781E0005, // 0024 JMPF R7 #002B + 0x8C1C0706, // 0025 GETMET R7 R3 K6 + 0x88240907, // 0026 GETMBR R9 R4 K7 + 0x542A270F, // 0027 LDINT R10 10000 + 0x7C1C0600, // 0028 CALL R7 3 + 0x80040E00, // 0029 RET 1 R7 + 0x70020010, // 002A JMP #003C + 0x541EFFFB, // 002B LDINT R7 65532 + 0x1C1C0C07, // 002C EQ R7 R6 R7 + 0x781E0005, // 002D JMPF R7 #0034 + 0x8C1C0706, // 002E GETMET R7 R3 K6 + 0x8824090B, // 002F GETMBR R9 R4 K11 + 0x58280004, // 0030 LDCONST R10 K4 + 0x7C1C0600, // 0031 CALL R7 3 + 0x80040E00, // 0032 RET 1 R7 + 0x70020007, // 0033 JMP #003C + 0x541EFFFC, // 0034 LDINT R7 65533 + 0x1C1C0C07, // 0035 EQ R7 R6 R7 + 0x781E0004, // 0036 JMPF R7 #003C + 0x8C1C0706, // 0037 GETMET R7 R3 K6 + 0x8824090B, // 0038 GETMBR R9 R4 K11 + 0x5828000C, // 0039 LDCONST R10 K12 + 0x7C1C0600, // 003A CALL R7 3 + 0x80040E00, // 003B RET 1 R7 + 0x70020008, // 003C JMP #0046 + 0x601C0003, // 003D GETGBL R7 G3 + 0x5C200000, // 003E MOVE R8 R0 + 0x7C1C0200, // 003F CALL R7 1 + 0x8C1C0F0D, // 0040 GETMET R7 R7 K13 + 0x5C240200, // 0041 MOVE R9 R1 + 0x5C280400, // 0042 MOVE R10 R2 + 0x5C2C0600, // 0043 MOVE R11 R3 + 0x7C1C0800, // 0044 CALL R7 4 + 0x80040E00, // 0045 RET 1 R7 + 0x80000000, // 0046 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Humidity_web_values, /* name */ + be_nested_proto( + 8, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(web_values_prefix), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(_X26_X23x1F4A7_X3B_X20_X252_X2E0f_X25_X25), + /* K4 */ be_nested_str_weak(shadow_value), + }), + be_str_weak(web_values), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x60100018, // 0004 GETGBL R4 G24 + 0x58140003, // 0005 LDCONST R5 K3 + 0x88180104, // 0006 GETMBR R6 R0 K4 + 0x4C1C0000, // 0007 LDNIL R7 + 0x20180C07, // 0008 NE R6 R6 R7 + 0x781A0005, // 0009 JMPF R6 #0010 + 0x6018000A, // 000A GETGBL R6 G10 + 0x881C0104, // 000B GETMBR R7 R0 K4 + 0x7C180200, // 000C CALL R6 1 + 0x541E0063, // 000D LDINT R7 100 + 0x0C180C07, // 000E DIV R6 R6 R7 + 0x70020000, // 000F JMP #0011 + 0x4C180000, // 0010 LDNIL R6 + 0x7C100400, // 0011 CALL R4 2 + 0x7C080400, // 0012 CALL R2 2 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_Sensor_Humidity +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Bridge_Sensor; +be_local_class(Matter_Plugin_Bridge_Sensor_Humidity, + 0, + &be_class_Matter_Plugin_Bridge_Sensor, + be_nested_map(8, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(pre_value, 1), be_const_closure(Matter_Plugin_Bridge_Sensor_Humidity_pre_value_closure) }, + { be_const_key_weak(web_values, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_Humidity_web_values_closure) }, + { be_const_key_weak(TYPES, 3), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(775, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(read_attribute, 7), be_const_closure(Matter_Plugin_Bridge_Sensor_Humidity_read_attribute_closure) }, + { be_const_key_weak(value_changed, 6), be_const_closure(Matter_Plugin_Bridge_Sensor_Humidity_value_changed_closure) }, + { be_const_key_weak(DISPLAY_NAME, 4), be_nested_str_weak(Humidity) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(http_humidity) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(3, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(1029, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(5, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + })), + be_str_weak(Matter_Plugin_Bridge_Sensor_Humidity) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_Sensor_Humidity_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_Sensor_Humidity); + be_setglobal(vm, "Matter_Plugin_Bridge_Sensor_Humidity"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Illuminance.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Illuminance.h new file mode 100644 index 000000000000..739e203bf102 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Illuminance.h @@ -0,0 +1,327 @@ +/* Solidification of Matter_Plugin_4_Bridge_Sensor_Illuminance.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Bridge_Sensor_Illuminance; + +/******************************************************************** +** Solidified function: pre_value +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Illuminance_pre_value, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(math), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(log10), + /* K3 */ be_const_int(1), + }), + be_str_weak(pre_value), + &be_const_str_solidified, + ( &(const binstruction[17]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x1C080202, // 0001 EQ R2 R1 R2 + 0x780A0001, // 0002 JMPF R2 #0005 + 0x4C080000, // 0003 LDNIL R2 + 0x80040400, // 0004 RET 1 R2 + 0xA40A0000, // 0005 IMPORT R2 K0 + 0x140C0301, // 0006 LT R3 R1 K1 + 0x780E0001, // 0007 JMPF R3 #000A + 0x80060200, // 0008 RET 1 K1 + 0x70020005, // 0009 JMP #0010 + 0x8C0C0502, // 000A GETMET R3 R2 K2 + 0x00140303, // 000B ADD R5 R1 K3 + 0x7C0C0400, // 000C CALL R3 2 + 0x5412270F, // 000D LDINT R4 10000 + 0x080C0604, // 000E MUL R3 R3 R4 + 0x80040600, // 000F RET 1 R3 + 0x80000000, // 0010 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: value_changed +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Illuminance_value_changed, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(attribute_updated), + /* K1 */ be_const_int(0), + }), + be_str_weak(value_changed), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x540E03FF, // 0001 LDINT R3 1024 + 0x58100001, // 0002 LDCONST R4 K1 + 0x7C040600, // 0003 CALL R1 3 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Illuminance_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(shadow_value), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(U2), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_const_int(1), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str_weak(U4), + /* K12 */ be_const_int(3), + /* K13 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[71]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E03FF, // 0004 LDINT R7 1024 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0035, // 0006 JMPF R7 #003D + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E0011, // 0008 JMPF R7 #001B + 0x881C0105, // 0009 GETMBR R7 R0 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E0007, // 000C JMPF R7 #0015 + 0x8C1C0706, // 000D GETMET R7 R3 K6 + 0x88240907, // 000E GETMBR R9 R4 K7 + 0x60280009, // 000F GETGBL R10 G9 + 0x882C0105, // 0010 GETMBR R11 R0 K5 + 0x7C280200, // 0011 CALL R10 1 + 0x7C1C0600, // 0012 CALL R7 3 + 0x80040E00, // 0013 RET 1 R7 + 0x70020004, // 0014 JMP #001A + 0x8C1C0706, // 0015 GETMET R7 R3 K6 + 0x88240908, // 0016 GETMBR R9 R4 K8 + 0x4C280000, // 0017 LDNIL R10 + 0x7C1C0600, // 0018 CALL R7 3 + 0x80040E00, // 0019 RET 1 R7 + 0x70020020, // 001A JMP #003C + 0x1C1C0D09, // 001B EQ R7 R6 K9 + 0x781E0005, // 001C JMPF R7 #0023 + 0x8C1C0706, // 001D GETMET R7 R3 K6 + 0x88240907, // 001E GETMBR R9 R4 K7 + 0x58280009, // 001F LDCONST R10 K9 + 0x7C1C0600, // 0020 CALL R7 3 + 0x80040E00, // 0021 RET 1 R7 + 0x70020018, // 0022 JMP #003C + 0x1C1C0D0A, // 0023 EQ R7 R6 K10 + 0x781E0005, // 0024 JMPF R7 #002B + 0x8C1C0706, // 0025 GETMET R7 R3 K6 + 0x88240907, // 0026 GETMBR R9 R4 K7 + 0x542AFFFD, // 0027 LDINT R10 65534 + 0x7C1C0600, // 0028 CALL R7 3 + 0x80040E00, // 0029 RET 1 R7 + 0x70020010, // 002A JMP #003C + 0x541EFFFB, // 002B LDINT R7 65532 + 0x1C1C0C07, // 002C EQ R7 R6 R7 + 0x781E0005, // 002D JMPF R7 #0034 + 0x8C1C0706, // 002E GETMET R7 R3 K6 + 0x8824090B, // 002F GETMBR R9 R4 K11 + 0x58280004, // 0030 LDCONST R10 K4 + 0x7C1C0600, // 0031 CALL R7 3 + 0x80040E00, // 0032 RET 1 R7 + 0x70020007, // 0033 JMP #003C + 0x541EFFFC, // 0034 LDINT R7 65533 + 0x1C1C0C07, // 0035 EQ R7 R6 R7 + 0x781E0004, // 0036 JMPF R7 #003C + 0x8C1C0706, // 0037 GETMET R7 R3 K6 + 0x8824090B, // 0038 GETMBR R9 R4 K11 + 0x5828000C, // 0039 LDCONST R10 K12 + 0x7C1C0600, // 003A CALL R7 3 + 0x80040E00, // 003B RET 1 R7 + 0x70020008, // 003C JMP #0046 + 0x601C0003, // 003D GETGBL R7 G3 + 0x5C200000, // 003E MOVE R8 R0 + 0x7C1C0200, // 003F CALL R7 1 + 0x8C1C0F0D, // 0040 GETMET R7 R7 K13 + 0x5C240200, // 0041 MOVE R9 R1 + 0x5C280400, // 0042 MOVE R10 R2 + 0x5C2C0600, // 0043 MOVE R11 R3 + 0x7C1C0800, // 0044 CALL R7 4 + 0x80040E00, // 0045 RET 1 R7 + 0x80000000, // 0046 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Illuminance_web_values, /* name */ + be_nested_proto( + 8, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(web_values_prefix), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(_X26_X23128261_X3B_X20_X25ilux), + /* K4 */ be_nested_str_weak(shadow_value), + }), + be_str_weak(web_values), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x60100018, // 0004 GETGBL R4 G24 + 0x58140003, // 0005 LDCONST R5 K3 + 0x60180009, // 0006 GETGBL R6 G9 + 0x881C0104, // 0007 GETMBR R7 R0 K4 + 0x7C180200, // 0008 CALL R6 1 + 0x7C100400, // 0009 CALL R4 2 + 0x7C080400, // 000A CALL R2 2 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_Sensor_Illuminance +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Bridge_Sensor; +be_local_class(Matter_Plugin_Bridge_Sensor_Illuminance, + 0, + &be_class_Matter_Plugin_Bridge_Sensor, + be_nested_map(8, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(pre_value, 1), be_const_closure(Matter_Plugin_Bridge_Sensor_Illuminance_pre_value_closure) }, + { be_const_key_weak(web_values, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_Illuminance_web_values_closure) }, + { be_const_key_weak(TYPES, 3), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(262, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(read_attribute, 7), be_const_closure(Matter_Plugin_Bridge_Sensor_Illuminance_read_attribute_closure) }, + { be_const_key_weak(value_changed, 6), be_const_closure(Matter_Plugin_Bridge_Sensor_Illuminance_value_changed_closure) }, + { be_const_key_weak(DISPLAY_NAME, 4), be_nested_str_weak(Illuminance) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(http_illuminance) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(1024, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(5, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + })), + be_str_weak(Matter_Plugin_Bridge_Sensor_Illuminance) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_Sensor_Illuminance_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_Sensor_Illuminance); + be_setglobal(vm, "Matter_Plugin_Bridge_Sensor_Illuminance"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Occupancy.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Occupancy.h new file mode 100644 index 000000000000..b19d193b93c4 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Occupancy.h @@ -0,0 +1,450 @@ +/* Solidification of Matter_Plugin_4_Bridge_Sensor_Occupancy.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Bridge_Sensor_Occupancy; + +/******************************************************************** +** Solidified function: +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Occupancy__X3Clambda_X3E, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x60040009, // 0000 GETGBL R1 G9 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Occupancy_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(tasmota_switch_index), + /* K2 */ be_nested_str_weak(find), + /* K3 */ be_nested_str_weak(ARG), + /* K4 */ be_const_int(1), + /* K5 */ be_const_int(0), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x60100009, // 0008 GETGBL R4 G9 + 0x8C140702, // 0009 GETMET R5 R3 K2 + 0x881C0103, // 000A GETMBR R7 R0 K3 + 0x58200004, // 000B LDCONST R8 K4 + 0x7C140600, // 000C CALL R5 3 + 0x7C100200, // 000D CALL R4 1 + 0x90020204, // 000E SETMBR R0 K1 R4 + 0x88100101, // 000F GETMBR R4 R0 K1 + 0x18100905, // 0010 LE R4 R4 K5 + 0x78120000, // 0011 JMPF R4 #0013 + 0x90020304, // 0012 SETMBR R0 K1 K4 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_update +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Occupancy_parse_update, /* name */ + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(find), + /* K1 */ be_nested_str_weak(Switch), + /* K2 */ be_nested_str_weak(tasmota_switch_index), + /* K3 */ be_nested_str_weak(ON), + /* K4 */ be_nested_str_weak(shadow_occupancy), + /* K5 */ be_nested_str_weak(attribute_updated), + /* K6 */ be_const_int(0), + }), + be_str_weak(parse_update), + &be_const_str_solidified, + ( &(const binstruction[28]) { /* code */ + 0x540E0007, // 0000 LDINT R3 8 + 0x1C0C0403, // 0001 EQ R3 R2 R3 + 0x780E0017, // 0002 JMPF R3 #001B + 0x500C0000, // 0003 LDBOOL R3 0 0 + 0x8C100300, // 0004 GETMET R4 R1 K0 + 0x60180008, // 0005 GETGBL R6 G8 + 0x881C0102, // 0006 GETMBR R7 R0 K2 + 0x7C180200, // 0007 CALL R6 1 + 0x001A0206, // 0008 ADD R6 K1 R6 + 0x7C100400, // 0009 CALL R4 2 + 0x1C100903, // 000A EQ R4 R4 K3 + 0x5C0C0800, // 000B MOVE R3 R4 + 0x88100104, // 000C GETMBR R4 R0 K4 + 0x4C140000, // 000D LDNIL R5 + 0x20100805, // 000E NE R4 R4 R5 + 0x78120009, // 000F JMPF R4 #001A + 0x88100104, // 0010 GETMBR R4 R0 K4 + 0x60140017, // 0011 GETGBL R5 G23 + 0x5C180600, // 0012 MOVE R6 R3 + 0x7C140200, // 0013 CALL R5 1 + 0x20100805, // 0014 NE R4 R4 R5 + 0x78120003, // 0015 JMPF R4 #001A + 0x8C100105, // 0016 GETMET R4 R0 K5 + 0x541A0405, // 0017 LDINT R6 1030 + 0x581C0006, // 0018 LDCONST R7 K6 + 0x7C100600, // 0019 CALL R4 3 + 0x90020803, // 001A SETMBR R0 K4 R3 + 0x80000000, // 001B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values_prefix +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Occupancy_web_values_prefix, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(get_name), + /* K2 */ be_nested_str_weak(Switch), + /* K3 */ be_nested_str_weak(tasmota_switch_index), + /* K4 */ be_nested_str_weak(content_send), + /* K5 */ be_nested_str_weak(PREFIX), + /* K6 */ be_nested_str_weak(html_escape), + /* K7 */ be_nested_str_weak(), + }), + be_str_weak(web_values_prefix), + &be_const_str_solidified, + ( &(const binstruction[22]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x5C0C0400, // 0003 MOVE R3 R2 + 0x740E0004, // 0004 JMPT R3 #000A + 0x600C0008, // 0005 GETGBL R3 G8 + 0x88100103, // 0006 GETMBR R4 R0 K3 + 0x7C0C0200, // 0007 CALL R3 1 + 0x000E0403, // 0008 ADD R3 K2 R3 + 0x5C080600, // 0009 MOVE R2 R3 + 0x8C0C0304, // 000A GETMET R3 R1 K4 + 0x60140018, // 000B GETGBL R5 G24 + 0x88180105, // 000C GETMBR R6 R0 K5 + 0x780A0003, // 000D JMPF R2 #0012 + 0x8C1C0306, // 000E GETMET R7 R1 K6 + 0x5C240400, // 000F MOVE R9 R2 + 0x7C1C0400, // 0010 CALL R7 2 + 0x70020000, // 0011 JMP #0013 + 0x581C0007, // 0012 LDCONST R7 K7 + 0x7C140400, // 0013 CALL R5 2 + 0x7C0C0400, // 0014 CALL R3 2 + 0x80000000, // 0015 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Occupancy_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(shadow_occupancy), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(U1), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_const_int(1), + /* K10 */ be_const_int(3), + /* K11 */ be_const_int(2), + /* K12 */ be_nested_str_weak(U4), + /* K13 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[69]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0405, // 0004 LDINT R7 1030 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0033, // 0006 JMPF R7 #003B + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E000F, // 0008 JMPF R7 #0019 + 0x881C0105, // 0009 GETMBR R7 R0 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E0005, // 000C JMPF R7 #0013 + 0x8C1C0706, // 000D GETMET R7 R3 K6 + 0x88240907, // 000E GETMBR R9 R4 K7 + 0x88280105, // 000F GETMBR R10 R0 K5 + 0x7C1C0600, // 0010 CALL R7 3 + 0x80040E00, // 0011 RET 1 R7 + 0x70020004, // 0012 JMP #0018 + 0x8C1C0706, // 0013 GETMET R7 R3 K6 + 0x88240908, // 0014 GETMBR R9 R4 K8 + 0x4C280000, // 0015 LDNIL R10 + 0x7C1C0600, // 0016 CALL R7 3 + 0x80040E00, // 0017 RET 1 R7 + 0x70020020, // 0018 JMP #003A + 0x1C1C0D09, // 0019 EQ R7 R6 K9 + 0x781E0005, // 001A JMPF R7 #0021 + 0x8C1C0706, // 001B GETMET R7 R3 K6 + 0x88240907, // 001C GETMBR R9 R4 K7 + 0x5828000A, // 001D LDCONST R10 K10 + 0x7C1C0600, // 001E CALL R7 3 + 0x80040E00, // 001F RET 1 R7 + 0x70020018, // 0020 JMP #003A + 0x1C1C0D0B, // 0021 EQ R7 R6 K11 + 0x781E0005, // 0022 JMPF R7 #0029 + 0x8C1C0706, // 0023 GETMET R7 R3 K6 + 0x88240907, // 0024 GETMBR R9 R4 K7 + 0x58280004, // 0025 LDCONST R10 K4 + 0x7C1C0600, // 0026 CALL R7 3 + 0x80040E00, // 0027 RET 1 R7 + 0x70020010, // 0028 JMP #003A + 0x541EFFFB, // 0029 LDINT R7 65532 + 0x1C1C0C07, // 002A EQ R7 R6 R7 + 0x781E0005, // 002B JMPF R7 #0032 + 0x8C1C0706, // 002C GETMET R7 R3 K6 + 0x8824090C, // 002D GETMBR R9 R4 K12 + 0x58280004, // 002E LDCONST R10 K4 + 0x7C1C0600, // 002F CALL R7 3 + 0x80040E00, // 0030 RET 1 R7 + 0x70020007, // 0031 JMP #003A + 0x541EFFFC, // 0032 LDINT R7 65533 + 0x1C1C0C07, // 0033 EQ R7 R6 R7 + 0x781E0004, // 0034 JMPF R7 #003A + 0x8C1C0706, // 0035 GETMET R7 R3 K6 + 0x8824090C, // 0036 GETMBR R9 R4 K12 + 0x5828000A, // 0037 LDCONST R10 K10 + 0x7C1C0600, // 0038 CALL R7 3 + 0x80040E00, // 0039 RET 1 R7 + 0x70020008, // 003A JMP #0044 + 0x601C0003, // 003B GETGBL R7 G3 + 0x5C200000, // 003C MOVE R8 R0 + 0x7C1C0200, // 003D CALL R7 1 + 0x8C1C0F0D, // 003E GETMET R7 R7 K13 + 0x5C240200, // 003F MOVE R9 R1 + 0x5C280400, // 0040 MOVE R10 R2 + 0x5C2C0600, // 0041 MOVE R11 R3 + 0x7C1C0800, // 0042 CALL R7 4 + 0x80040E00, // 0043 RET 1 R7 + 0x80000000, // 0044 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Occupancy_web_values, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(web_values_prefix), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(Occupancy_X25i_X20_X25s), + /* K4 */ be_nested_str_weak(tasmota_switch_index), + /* K5 */ be_nested_str_weak(web_value_onoff), + /* K6 */ be_nested_str_weak(shadow_occupancy), + }), + be_str_weak(web_values), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x60100018, // 0004 GETGBL R4 G24 + 0x58140003, // 0005 LDCONST R5 K3 + 0x88180104, // 0006 GETMBR R6 R0 K4 + 0x8C1C0105, // 0007 GETMET R7 R0 K5 + 0x88240106, // 0008 GETMBR R9 R0 K6 + 0x7C1C0400, // 0009 CALL R7 2 + 0x7C100600, // 000A CALL R4 3 + 0x7C080400, // 000B CALL R2 2 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_Sensor_Occupancy +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Bridge_HTTP; +be_local_class(Matter_Plugin_Bridge_Sensor_Occupancy, + 2, + &be_class_Matter_Plugin_Bridge_HTTP, + be_nested_map(16, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(ARG_TYPE, 4), be_const_static_closure(Matter_Plugin_Bridge_Sensor_Occupancy__X3Clambda_X3E_closure) }, + { be_const_key_weak(ARG_HINT, 12), be_nested_str_weak(Switch_X3Cx_X3E_X20number) }, + { be_const_key_weak(shadow_occupancy, -1), be_const_var(1) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_Occupancy_init_closure) }, + { be_const_key_weak(web_values, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_Occupancy_web_values_closure) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Occupancy) }, + { be_const_key_weak(TYPES, 9), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(263, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(ARG, -1), be_nested_str_weak(switch) }, + { be_const_key_weak(parse_update, 14), be_const_closure(Matter_Plugin_Bridge_Sensor_Occupancy_parse_update_closure) }, + { be_const_key_weak(CLUSTERS, 11), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(1030, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(5, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(tasmota_switch_index, 6), be_const_var(0) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_Occupancy_read_attribute_closure) }, + { be_const_key_weak(web_values_prefix, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_Occupancy_web_values_prefix_closure) }, + { be_const_key_weak(TYPE, 5), be_nested_str_weak(http_occupancy) }, + { be_const_key_weak(UPDATE_TIME, -1), be_const_int(5000) }, + { be_const_key_weak(UPDATE_CMD, 2), be_nested_str_weak(Status_X208) }, + })), + be_str_weak(Matter_Plugin_Bridge_Sensor_Occupancy) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_Sensor_Occupancy_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_Sensor_Occupancy); + be_setglobal(vm, "Matter_Plugin_Bridge_Sensor_Occupancy"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Pressure.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Pressure.h new file mode 100644 index 000000000000..63f96dae4b22 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Pressure.h @@ -0,0 +1,314 @@ +/* Solidification of Matter_Plugin_4_Bridge_Sensor_Pressure.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Bridge_Sensor_Pressure; + +/******************************************************************** +** Solidified function: pre_value +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Pressure_pre_value, /* name */ + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(pre_value), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x20080202, // 0001 NE R2 R1 R2 + 0x780A0003, // 0002 JMPF R2 #0007 + 0x60080009, // 0003 GETGBL R2 G9 + 0x5C0C0200, // 0004 MOVE R3 R1 + 0x7C080200, // 0005 CALL R2 1 + 0x70020000, // 0006 JMP #0008 + 0x4C080000, // 0007 LDNIL R2 + 0x80040400, // 0008 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: value_changed +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Pressure_value_changed, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(attribute_updated), + /* K1 */ be_const_int(0), + }), + be_str_weak(value_changed), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x540E0402, // 0001 LDINT R3 1027 + 0x58100001, // 0002 LDCONST R4 K1 + 0x7C040600, // 0003 CALL R1 3 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Pressure_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(shadow_value), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(I2), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_const_int(1), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str_weak(U4), + /* K12 */ be_const_int(3), + /* K13 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[71]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0402, // 0004 LDINT R7 1027 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0035, // 0006 JMPF R7 #003D + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E0011, // 0008 JMPF R7 #001B + 0x881C0105, // 0009 GETMBR R7 R0 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E0007, // 000C JMPF R7 #0015 + 0x8C1C0706, // 000D GETMET R7 R3 K6 + 0x88240907, // 000E GETMBR R9 R4 K7 + 0x60280009, // 000F GETGBL R10 G9 + 0x882C0105, // 0010 GETMBR R11 R0 K5 + 0x7C280200, // 0011 CALL R10 1 + 0x7C1C0600, // 0012 CALL R7 3 + 0x80040E00, // 0013 RET 1 R7 + 0x70020004, // 0014 JMP #001A + 0x8C1C0706, // 0015 GETMET R7 R3 K6 + 0x88240908, // 0016 GETMBR R9 R4 K8 + 0x4C280000, // 0017 LDNIL R10 + 0x7C1C0600, // 0018 CALL R7 3 + 0x80040E00, // 0019 RET 1 R7 + 0x70020020, // 001A JMP #003C + 0x1C1C0D09, // 001B EQ R7 R6 K9 + 0x781E0005, // 001C JMPF R7 #0023 + 0x8C1C0706, // 001D GETMET R7 R3 K6 + 0x88240907, // 001E GETMBR R9 R4 K7 + 0x542A01F3, // 001F LDINT R10 500 + 0x7C1C0600, // 0020 CALL R7 3 + 0x80040E00, // 0021 RET 1 R7 + 0x70020018, // 0022 JMP #003C + 0x1C1C0D0A, // 0023 EQ R7 R6 K10 + 0x781E0005, // 0024 JMPF R7 #002B + 0x8C1C0706, // 0025 GETMET R7 R3 K6 + 0x88240907, // 0026 GETMBR R9 R4 K7 + 0x542A05DB, // 0027 LDINT R10 1500 + 0x7C1C0600, // 0028 CALL R7 3 + 0x80040E00, // 0029 RET 1 R7 + 0x70020010, // 002A JMP #003C + 0x541EFFFB, // 002B LDINT R7 65532 + 0x1C1C0C07, // 002C EQ R7 R6 R7 + 0x781E0005, // 002D JMPF R7 #0034 + 0x8C1C0706, // 002E GETMET R7 R3 K6 + 0x8824090B, // 002F GETMBR R9 R4 K11 + 0x58280004, // 0030 LDCONST R10 K4 + 0x7C1C0600, // 0031 CALL R7 3 + 0x80040E00, // 0032 RET 1 R7 + 0x70020007, // 0033 JMP #003C + 0x541EFFFC, // 0034 LDINT R7 65533 + 0x1C1C0C07, // 0035 EQ R7 R6 R7 + 0x781E0004, // 0036 JMPF R7 #003C + 0x8C1C0706, // 0037 GETMET R7 R3 K6 + 0x8824090B, // 0038 GETMBR R9 R4 K11 + 0x5828000C, // 0039 LDCONST R10 K12 + 0x7C1C0600, // 003A CALL R7 3 + 0x80040E00, // 003B RET 1 R7 + 0x70020008, // 003C JMP #0046 + 0x601C0003, // 003D GETGBL R7 G3 + 0x5C200000, // 003E MOVE R8 R0 + 0x7C1C0200, // 003F CALL R7 1 + 0x8C1C0F0D, // 0040 GETMET R7 R7 K13 + 0x5C240200, // 0041 MOVE R9 R1 + 0x5C280400, // 0042 MOVE R10 R2 + 0x5C2C0600, // 0043 MOVE R11 R3 + 0x7C1C0800, // 0044 CALL R7 4 + 0x80040E00, // 0045 RET 1 R7 + 0x80000000, // 0046 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Pressure_web_values, /* name */ + be_nested_proto( + 8, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(web_values_prefix), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(_X26_X23x26C5_X3B_X20_X25i_X20hPa), + /* K4 */ be_nested_str_weak(shadow_value), + }), + be_str_weak(web_values), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x60100018, // 0004 GETGBL R4 G24 + 0x58140003, // 0005 LDCONST R5 K3 + 0x60180009, // 0006 GETGBL R6 G9 + 0x881C0104, // 0007 GETMBR R7 R0 K4 + 0x7C180200, // 0008 CALL R6 1 + 0x7C100400, // 0009 CALL R4 2 + 0x7C080400, // 000A CALL R2 2 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_Sensor_Pressure +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Bridge_Sensor; +be_local_class(Matter_Plugin_Bridge_Sensor_Pressure, + 0, + &be_class_Matter_Plugin_Bridge_Sensor, + be_nested_map(8, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(pre_value, 1), be_const_closure(Matter_Plugin_Bridge_Sensor_Pressure_pre_value_closure) }, + { be_const_key_weak(web_values, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_Pressure_web_values_closure) }, + { be_const_key_weak(TYPES, 3), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(773, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(read_attribute, 7), be_const_closure(Matter_Plugin_Bridge_Sensor_Pressure_read_attribute_closure) }, + { be_const_key_weak(value_changed, 6), be_const_closure(Matter_Plugin_Bridge_Sensor_Pressure_value_changed_closure) }, + { be_const_key_weak(DISPLAY_NAME, 4), be_nested_str_weak(Pressure) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(http_pressure) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(1027, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(5, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + })), + be_str_weak(Matter_Plugin_Bridge_Sensor_Pressure) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_Sensor_Pressure_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_Sensor_Pressure); + be_setglobal(vm, "Matter_Plugin_Bridge_Sensor_Pressure"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Temp.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Temp.h new file mode 100644 index 000000000000..44b133271037 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Bridge_Sensor_Temp.h @@ -0,0 +1,332 @@ +/* Solidification of Matter_Plugin_4_Bridge_Sensor_Temp.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Bridge_Sensor_Temp; + +/******************************************************************** +** Solidified function: pre_value +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Temp_pre_value, /* name */ + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(temp_unit), + /* K1 */ be_nested_str_weak(TEMP_F), + /* K2 */ be_const_real_hex(0x3FE66666), + }), + be_str_weak(pre_value), + &be_const_str_solidified, + ( &(const binstruction[18]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x880C0101, // 0001 GETMBR R3 R0 K1 + 0x1C080403, // 0002 EQ R2 R2 R3 + 0x780A0003, // 0003 JMPF R2 #0008 + 0x540A001F, // 0004 LDINT R2 32 + 0x04080202, // 0005 SUB R2 R1 R2 + 0x0C080502, // 0006 DIV R2 R2 K2 + 0x5C040400, // 0007 MOVE R1 R2 + 0x4C080000, // 0008 LDNIL R2 + 0x20080202, // 0009 NE R2 R1 R2 + 0x780A0004, // 000A JMPF R2 #0010 + 0x60080009, // 000B GETGBL R2 G9 + 0x540E0063, // 000C LDINT R3 100 + 0x080C0203, // 000D MUL R3 R1 R3 + 0x7C080200, // 000E CALL R2 1 + 0x70020000, // 000F JMP #0011 + 0x4C080000, // 0010 LDNIL R2 + 0x80040400, // 0011 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: value_changed +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Temp_value_changed, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(attribute_updated), + /* K1 */ be_const_int(0), + }), + be_str_weak(value_changed), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x540E0401, // 0001 LDINT R3 1026 + 0x58100001, // 0002 LDCONST R4 K1 + 0x7C040600, // 0003 CALL R1 3 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Temp_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(shadow_value), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(I2), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_const_int(1), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str_weak(U4), + /* K12 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[69]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E0401, // 0004 LDINT R7 1026 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0033, // 0006 JMPF R7 #003B + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E000F, // 0008 JMPF R7 #0019 + 0x881C0105, // 0009 GETMBR R7 R0 K5 + 0x4C200000, // 000A LDNIL R8 + 0x201C0E08, // 000B NE R7 R7 R8 + 0x781E0005, // 000C JMPF R7 #0013 + 0x8C1C0706, // 000D GETMET R7 R3 K6 + 0x88240907, // 000E GETMBR R9 R4 K7 + 0x88280105, // 000F GETMBR R10 R0 K5 + 0x7C1C0600, // 0010 CALL R7 3 + 0x80040E00, // 0011 RET 1 R7 + 0x70020004, // 0012 JMP #0018 + 0x8C1C0706, // 0013 GETMET R7 R3 K6 + 0x88240908, // 0014 GETMBR R9 R4 K8 + 0x4C280000, // 0015 LDNIL R10 + 0x7C1C0600, // 0016 CALL R7 3 + 0x80040E00, // 0017 RET 1 R7 + 0x70020020, // 0018 JMP #003A + 0x1C1C0D09, // 0019 EQ R7 R6 K9 + 0x781E0005, // 001A JMPF R7 #0021 + 0x8C1C0706, // 001B GETMET R7 R3 K6 + 0x88240907, // 001C GETMBR R9 R4 K7 + 0x5429EC77, // 001D LDINT R10 -5000 + 0x7C1C0600, // 001E CALL R7 3 + 0x80040E00, // 001F RET 1 R7 + 0x70020018, // 0020 JMP #003A + 0x1C1C0D0A, // 0021 EQ R7 R6 K10 + 0x781E0005, // 0022 JMPF R7 #0029 + 0x8C1C0706, // 0023 GETMET R7 R3 K6 + 0x88240907, // 0024 GETMBR R9 R4 K7 + 0x542A3A97, // 0025 LDINT R10 15000 + 0x7C1C0600, // 0026 CALL R7 3 + 0x80040E00, // 0027 RET 1 R7 + 0x70020010, // 0028 JMP #003A + 0x541EFFFB, // 0029 LDINT R7 65532 + 0x1C1C0C07, // 002A EQ R7 R6 R7 + 0x781E0005, // 002B JMPF R7 #0032 + 0x8C1C0706, // 002C GETMET R7 R3 K6 + 0x8824090B, // 002D GETMBR R9 R4 K11 + 0x58280004, // 002E LDCONST R10 K4 + 0x7C1C0600, // 002F CALL R7 3 + 0x80040E00, // 0030 RET 1 R7 + 0x70020007, // 0031 JMP #003A + 0x541EFFFC, // 0032 LDINT R7 65533 + 0x1C1C0C07, // 0033 EQ R7 R6 R7 + 0x781E0004, // 0034 JMPF R7 #003A + 0x8C1C0706, // 0035 GETMET R7 R3 K6 + 0x8824090B, // 0036 GETMBR R9 R4 K11 + 0x542A0003, // 0037 LDINT R10 4 + 0x7C1C0600, // 0038 CALL R7 3 + 0x80040E00, // 0039 RET 1 R7 + 0x70020008, // 003A JMP #0044 + 0x601C0003, // 003B GETGBL R7 G3 + 0x5C200000, // 003C MOVE R8 R0 + 0x7C1C0200, // 003D CALL R7 1 + 0x8C1C0F0C, // 003E GETMET R7 R7 K12 + 0x5C240200, // 003F MOVE R9 R1 + 0x5C280400, // 0040 MOVE R10 R2 + 0x5C2C0600, // 0041 MOVE R11 R3 + 0x7C1C0800, // 0042 CALL R7 4 + 0x80040E00, // 0043 RET 1 R7 + 0x80000000, // 0044 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Sensor_Temp_web_values, /* name */ + be_nested_proto( + 8, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(web_values_prefix), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(_X26_X23x2600_X3B_X26_X23xFE0F_X3B_X20_X25_X2E1f_X20_XC2_XB0C), + /* K4 */ be_nested_str_weak(shadow_value), + }), + be_str_weak(web_values), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x60100018, // 0004 GETGBL R4 G24 + 0x58140003, // 0005 LDCONST R5 K3 + 0x88180104, // 0006 GETMBR R6 R0 K4 + 0x4C1C0000, // 0007 LDNIL R7 + 0x20180C07, // 0008 NE R6 R6 R7 + 0x781A0005, // 0009 JMPF R6 #0010 + 0x6018000A, // 000A GETGBL R6 G10 + 0x881C0104, // 000B GETMBR R7 R0 K4 + 0x7C180200, // 000C CALL R6 1 + 0x541E0063, // 000D LDINT R7 100 + 0x0C180C07, // 000E DIV R6 R6 R7 + 0x70020000, // 000F JMP #0011 + 0x4C180000, // 0010 LDNIL R6 + 0x7C100400, // 0011 CALL R4 2 + 0x7C080400, // 0012 CALL R2 2 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_Sensor_Temp +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Bridge_Sensor; +be_local_class(Matter_Plugin_Bridge_Sensor_Temp, + 0, + &be_class_Matter_Plugin_Bridge_Sensor, + be_nested_map(8, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(pre_value, 1), be_const_closure(Matter_Plugin_Bridge_Sensor_Temp_pre_value_closure) }, + { be_const_key_weak(web_values, -1), be_const_closure(Matter_Plugin_Bridge_Sensor_Temp_web_values_closure) }, + { be_const_key_weak(TYPES, 3), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(770, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(read_attribute, 7), be_const_closure(Matter_Plugin_Bridge_Sensor_Temp_read_attribute_closure) }, + { be_const_key_weak(value_changed, 6), be_const_closure(Matter_Plugin_Bridge_Sensor_Temp_value_changed_closure) }, + { be_const_key_weak(DISPLAY_NAME, 4), be_nested_str_weak(Temperature) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(http_temperature) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(6, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(1026, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(5, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(3, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(29, 1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + })), + be_str_weak(Matter_Plugin_Bridge_Sensor_Temp) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_Sensor_Temp_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_Sensor_Temp); + be_setglobal(vm, "Matter_Plugin_Bridge_Sensor_Temp"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Light2.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Light2.h new file mode 100644 index 000000000000..a52eb72295d2 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Light2.h @@ -0,0 +1,603 @@ +/* Solidification of Matter_Plugin_4_Light2.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Light2; + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_Light2_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(shadow_ct), + /* K2 */ be_nested_str_weak(update_ct_minmax), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x54120144, // 0008 LDINT R4 325 + 0x90020204, // 0009 SETMBR R0 K1 R4 + 0x8C100102, // 000A GETMET R4 R0 K2 + 0x7C100200, // 000B CALL R4 1 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: invoke_request +********************************************************************/ +be_local_closure(Matter_Plugin_Light2_invoke_request, /* name */ + be_nested_proto( + 13, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(light), + /* K1 */ be_nested_str_weak(matter), + /* K2 */ be_nested_str_weak(TLV), + /* K3 */ be_nested_str_weak(cluster), + /* K4 */ be_nested_str_weak(command), + /* K5 */ be_nested_str_weak(update_shadow_lazy), + /* K6 */ be_nested_str_weak(findsubval), + /* K7 */ be_const_int(0), + /* K8 */ be_nested_str_weak(set_ct), + /* K9 */ be_nested_str_weak(log), + /* K10 */ be_nested_str_weak(ct_X3A), + /* K11 */ be_nested_str_weak(publish_command), + /* K12 */ be_nested_str_weak(CT), + /* K13 */ be_nested_str_weak(invoke_request), + }), + be_str_weak(invoke_request), + &be_const_str_solidified, + ( &(const binstruction[59]) { /* code */ + 0xA4120000, // 0000 IMPORT R4 K0 + 0xB8160200, // 0001 GETNGBL R5 K1 + 0x88140B02, // 0002 GETMBR R5 R5 K2 + 0x88180703, // 0003 GETMBR R6 R3 K3 + 0x881C0704, // 0004 GETMBR R7 R3 K4 + 0x542202FF, // 0005 LDINT R8 768 + 0x1C200C08, // 0006 EQ R8 R6 R8 + 0x78220028, // 0007 JMPF R8 #0031 + 0x8C200105, // 0008 GETMET R8 R0 K5 + 0x7C200200, // 0009 CALL R8 1 + 0x54220009, // 000A LDINT R8 10 + 0x1C200E08, // 000B EQ R8 R7 R8 + 0x78220011, // 000C JMPF R8 #001F + 0x8C200506, // 000D GETMET R8 R2 K6 + 0x58280007, // 000E LDCONST R10 K7 + 0x7C200400, // 000F CALL R8 2 + 0x8C240108, // 0010 GETMET R9 R0 K8 + 0x5C2C1000, // 0011 MOVE R11 R8 + 0x7C240400, // 0012 CALL R9 2 + 0x60240008, // 0013 GETGBL R9 G8 + 0x5C281000, // 0014 MOVE R10 R8 + 0x7C240200, // 0015 CALL R9 1 + 0x00261409, // 0016 ADD R9 K10 R9 + 0x900E1209, // 0017 SETMBR R3 K9 R9 + 0x8C24010B, // 0018 GETMET R9 R0 K11 + 0x582C000C, // 0019 LDCONST R11 K12 + 0x5C301000, // 001A MOVE R12 R8 + 0x7C240600, // 001B CALL R9 3 + 0x50240200, // 001C LDBOOL R9 1 0 + 0x80041200, // 001D RET 1 R9 + 0x70020010, // 001E JMP #0030 + 0x54220046, // 001F LDINT R8 71 + 0x1C200E08, // 0020 EQ R8 R7 R8 + 0x78220002, // 0021 JMPF R8 #0025 + 0x50200200, // 0022 LDBOOL R8 1 0 + 0x80041000, // 0023 RET 1 R8 + 0x7002000A, // 0024 JMP #0030 + 0x5422004A, // 0025 LDINT R8 75 + 0x1C200E08, // 0026 EQ R8 R7 R8 + 0x78220002, // 0027 JMPF R8 #002B + 0x50200200, // 0028 LDBOOL R8 1 0 + 0x80041000, // 0029 RET 1 R8 + 0x70020004, // 002A JMP #0030 + 0x5422004B, // 002B LDINT R8 76 + 0x1C200E08, // 002C EQ R8 R7 R8 + 0x78220001, // 002D JMPF R8 #0030 + 0x50200200, // 002E LDBOOL R8 1 0 + 0x80041000, // 002F RET 1 R8 + 0x70020008, // 0030 JMP #003A + 0x60200003, // 0031 GETGBL R8 G3 + 0x5C240000, // 0032 MOVE R9 R0 + 0x7C200200, // 0033 CALL R8 1 + 0x8C20110D, // 0034 GETMET R8 R8 K13 + 0x5C280200, // 0035 MOVE R10 R1 + 0x5C2C0400, // 0036 MOVE R11 R2 + 0x5C300600, // 0037 MOVE R12 R3 + 0x7C200800, // 0038 CALL R8 4 + 0x80041000, // 0039 RET 1 R8 + 0x80000000, // 003A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_shadow +********************************************************************/ +be_local_closure(Matter_Plugin_Light2_update_shadow, /* name */ + be_nested_proto( + 8, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(light), + /* K1 */ be_nested_str_weak(update_ct_minmax), + /* K2 */ be_nested_str_weak(update_shadow), + /* K3 */ be_nested_str_weak(get), + /* K4 */ be_nested_str_weak(find), + /* K5 */ be_nested_str_weak(ct), + /* K6 */ be_nested_str_weak(shadow_ct), + /* K7 */ be_nested_str_weak(attribute_updated), + }), + be_str_weak(update_shadow), + &be_const_str_solidified, + ( &(const binstruction[30]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x60080003, // 0003 GETGBL R2 G3 + 0x5C0C0000, // 0004 MOVE R3 R0 + 0x7C080200, // 0005 CALL R2 1 + 0x8C080502, // 0006 GETMET R2 R2 K2 + 0x7C080200, // 0007 CALL R2 1 + 0x8C080303, // 0008 GETMET R2 R1 K3 + 0x7C080200, // 0009 CALL R2 1 + 0x4C0C0000, // 000A LDNIL R3 + 0x200C0403, // 000B NE R3 R2 R3 + 0x780E000F, // 000C JMPF R3 #001D + 0x8C0C0504, // 000D GETMET R3 R2 K4 + 0x58140005, // 000E LDCONST R5 K5 + 0x4C180000, // 000F LDNIL R6 + 0x7C0C0600, // 0010 CALL R3 3 + 0x4C100000, // 0011 LDNIL R4 + 0x1C100604, // 0012 EQ R4 R3 R4 + 0x78120000, // 0013 JMPF R4 #0015 + 0x880C0106, // 0014 GETMBR R3 R0 K6 + 0x88100106, // 0015 GETMBR R4 R0 K6 + 0x20100604, // 0016 NE R4 R3 R4 + 0x78120004, // 0017 JMPF R4 #001D + 0x8C100107, // 0018 GETMET R4 R0 K7 + 0x541A02FF, // 0019 LDINT R6 768 + 0x541E0006, // 001A LDINT R7 7 + 0x7C100600, // 001B CALL R4 3 + 0x90020C03, // 001C SETMBR R0 K6 R3 + 0x80000000, // 001D RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_virtual +********************************************************************/ +be_local_closure(Matter_Plugin_Light2_update_virtual, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(find), + /* K1 */ be_nested_str_weak(CT), + /* K2 */ be_nested_str_weak(set_ct), + /* K3 */ be_nested_str_weak(update_virtual), + }), + be_str_weak(update_virtual), + &be_const_str_solidified, + ( &(const binstruction[18]) { /* code */ + 0x60080009, // 0000 GETGBL R2 G9 + 0x8C0C0300, // 0001 GETMET R3 R1 K0 + 0x58140001, // 0002 LDCONST R5 K1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x7C080200, // 0004 CALL R2 1 + 0x4C0C0000, // 0005 LDNIL R3 + 0x200C0403, // 0006 NE R3 R2 R3 + 0x780E0002, // 0007 JMPF R3 #000B + 0x8C0C0102, // 0008 GETMET R3 R0 K2 + 0x5C140400, // 0009 MOVE R5 R2 + 0x7C0C0400, // 000A CALL R3 2 + 0x600C0003, // 000B GETGBL R3 G3 + 0x5C100000, // 000C MOVE R4 R0 + 0x7C0C0200, // 000D CALL R3 1 + 0x8C0C0703, // 000E GETMET R3 R3 K3 + 0x5C140200, // 000F MOVE R5 R1 + 0x7C0C0400, // 0010 CALL R3 2 + 0x80000000, // 0011 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_ct +********************************************************************/ +be_local_closure(Matter_Plugin_Light2_set_ct, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(ct_min), + /* K1 */ be_nested_str_weak(ct_max), + /* K2 */ be_nested_str_weak(VIRTUAL), + /* K3 */ be_nested_str_weak(light), + /* K4 */ be_nested_str_weak(set), + /* K5 */ be_nested_str_weak(ct), + /* K6 */ be_nested_str_weak(update_shadow), + /* K7 */ be_nested_str_weak(shadow_ct), + /* K8 */ be_nested_str_weak(attribute_updated), + }), + be_str_weak(set_ct), + &be_const_str_solidified, + ( &(const binstruction[28]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x14080202, // 0001 LT R2 R1 R2 + 0x780A0000, // 0002 JMPF R2 #0004 + 0x88040100, // 0003 GETMBR R1 R0 K0 + 0x88080101, // 0004 GETMBR R2 R0 K1 + 0x24080202, // 0005 GT R2 R1 R2 + 0x780A0000, // 0006 JMPF R2 #0008 + 0x88040101, // 0007 GETMBR R1 R0 K1 + 0x88080102, // 0008 GETMBR R2 R0 K2 + 0x740A0008, // 0009 JMPT R2 #0013 + 0xA40A0600, // 000A IMPORT R2 K3 + 0x8C0C0504, // 000B GETMET R3 R2 K4 + 0x60140013, // 000C GETGBL R5 G19 + 0x7C140000, // 000D CALL R5 0 + 0x98160A01, // 000E SETIDX R5 K5 R1 + 0x7C0C0400, // 000F CALL R3 2 + 0x8C0C0106, // 0010 GETMET R3 R0 K6 + 0x7C0C0200, // 0011 CALL R3 1 + 0x70020007, // 0012 JMP #001B + 0x88080107, // 0013 GETMBR R2 R0 K7 + 0x20080202, // 0014 NE R2 R1 R2 + 0x780A0004, // 0015 JMPF R2 #001B + 0x8C080108, // 0016 GETMET R2 R0 K8 + 0x541202FF, // 0017 LDINT R4 768 + 0x54160006, // 0018 LDINT R5 7 + 0x7C080600, // 0019 CALL R2 3 + 0x90020E01, // 001A SETMBR R0 K7 R1 + 0x80000000, // 001B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Light2_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_nested_str_weak(set), + /* K6 */ be_nested_str_weak(U1), + /* K7 */ be_nested_str_weak(shadow_ct), + /* K8 */ be_const_int(2), + /* K9 */ be_const_int(0), + /* K10 */ be_nested_str_weak(ct_min), + /* K11 */ be_nested_str_weak(ct_max), + /* K12 */ be_nested_str_weak(U4), + /* K13 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[82]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E02FF, // 0004 LDINT R7 768 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0040, // 0006 JMPF R7 #0048 + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x541E0006, // 0009 LDINT R7 7 + 0x1C1C0C07, // 000A EQ R7 R6 R7 + 0x781E0005, // 000B JMPF R7 #0012 + 0x8C1C0705, // 000C GETMET R7 R3 K5 + 0x88240906, // 000D GETMBR R9 R4 K6 + 0x88280107, // 000E GETMBR R10 R0 K7 + 0x7C1C0600, // 000F CALL R7 3 + 0x80040E00, // 0010 RET 1 R7 + 0x70020034, // 0011 JMP #0047 + 0x541E0007, // 0012 LDINT R7 8 + 0x1C1C0C07, // 0013 EQ R7 R6 R7 + 0x781E0005, // 0014 JMPF R7 #001B + 0x8C1C0705, // 0015 GETMET R7 R3 K5 + 0x88240906, // 0016 GETMBR R9 R4 K6 + 0x58280008, // 0017 LDCONST R10 K8 + 0x7C1C0600, // 0018 CALL R7 3 + 0x80040E00, // 0019 RET 1 R7 + 0x7002002B, // 001A JMP #0047 + 0x541E000E, // 001B LDINT R7 15 + 0x1C1C0C07, // 001C EQ R7 R6 R7 + 0x781E0005, // 001D JMPF R7 #0024 + 0x8C1C0705, // 001E GETMET R7 R3 K5 + 0x88240906, // 001F GETMBR R9 R4 K6 + 0x58280009, // 0020 LDCONST R10 K9 + 0x7C1C0600, // 0021 CALL R7 3 + 0x80040E00, // 0022 RET 1 R7 + 0x70020022, // 0023 JMP #0047 + 0x541E400A, // 0024 LDINT R7 16395 + 0x1C1C0C07, // 0025 EQ R7 R6 R7 + 0x781E0005, // 0026 JMPF R7 #002D + 0x8C1C0705, // 0027 GETMET R7 R3 K5 + 0x88240906, // 0028 GETMBR R9 R4 K6 + 0x8828010A, // 0029 GETMBR R10 R0 K10 + 0x7C1C0600, // 002A CALL R7 3 + 0x80040E00, // 002B RET 1 R7 + 0x70020019, // 002C JMP #0047 + 0x541E400B, // 002D LDINT R7 16396 + 0x1C1C0C07, // 002E EQ R7 R6 R7 + 0x781E0005, // 002F JMPF R7 #0036 + 0x8C1C0705, // 0030 GETMET R7 R3 K5 + 0x88240906, // 0031 GETMBR R9 R4 K6 + 0x8828010B, // 0032 GETMBR R10 R0 K11 + 0x7C1C0600, // 0033 CALL R7 3 + 0x80040E00, // 0034 RET 1 R7 + 0x70020010, // 0035 JMP #0047 + 0x541EFFFB, // 0036 LDINT R7 65532 + 0x1C1C0C07, // 0037 EQ R7 R6 R7 + 0x781E0005, // 0038 JMPF R7 #003F + 0x8C1C0705, // 0039 GETMET R7 R3 K5 + 0x8824090C, // 003A GETMBR R9 R4 K12 + 0x542A000F, // 003B LDINT R10 16 + 0x7C1C0600, // 003C CALL R7 3 + 0x80040E00, // 003D RET 1 R7 + 0x70020007, // 003E JMP #0047 + 0x541EFFFC, // 003F LDINT R7 65533 + 0x1C1C0C07, // 0040 EQ R7 R6 R7 + 0x781E0004, // 0041 JMPF R7 #0047 + 0x8C1C0705, // 0042 GETMET R7 R3 K5 + 0x8824090C, // 0043 GETMBR R9 R4 K12 + 0x542A0004, // 0044 LDINT R10 5 + 0x7C1C0600, // 0045 CALL R7 3 + 0x80040E00, // 0046 RET 1 R7 + 0x70020008, // 0047 JMP #0051 + 0x601C0003, // 0048 GETGBL R7 G3 + 0x5C200000, // 0049 MOVE R8 R0 + 0x7C1C0200, // 004A CALL R7 1 + 0x8C1C0F0D, // 004B GETMET R7 R7 K13 + 0x5C240200, // 004C MOVE R9 R1 + 0x5C280400, // 004D MOVE R10 R2 + 0x5C2C0600, // 004E MOVE R11 R3 + 0x7C1C0800, // 004F CALL R7 4 + 0x80040E00, // 0050 RET 1 R7 + 0x80000000, // 0051 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_ct_minmax +********************************************************************/ +be_local_closure(Matter_Plugin_Light2_update_ct_minmax, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(get_option), + /* K2 */ be_nested_str_weak(ct_min), + /* K3 */ be_nested_str_weak(ct_max), + }), + be_str_weak(update_ct_minmax), + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0xB8060000, // 0000 GETNGBL R1 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x540E0051, // 0002 LDINT R3 82 + 0x7C040400, // 0003 CALL R1 2 + 0x78060001, // 0004 JMPF R1 #0007 + 0x540A00C7, // 0005 LDINT R2 200 + 0x70020000, // 0006 JMP #0008 + 0x540A0098, // 0007 LDINT R2 153 + 0x90020402, // 0008 SETMBR R0 K2 R2 + 0x78060001, // 0009 JMPF R1 #000C + 0x540A017B, // 000A LDINT R2 380 + 0x70020000, // 000B JMP #000D + 0x540A01F3, // 000C LDINT R2 500 + 0x90020602, // 000D SETMBR R0 K3 R2 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Light2 +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Light1; +be_local_class(Matter_Plugin_Light2, + 3, + &be_class_Matter_Plugin_Light1, + be_nested_map(15, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Light2_init_closure) }, + { be_const_key_weak(shadow_ct, -1), be_const_var(0) }, + { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Light2_invoke_request_closure) }, + { be_const_key_weak(ct_max, -1), be_const_var(2) }, + { be_const_key_weak(update_shadow, 10), be_const_closure(Matter_Plugin_Light2_update_shadow_closure) }, + { be_const_key_weak(update_virtual, 8), be_const_closure(Matter_Plugin_Light2_update_virtual_closure) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Light_X202_X20CT) }, + { be_const_key_weak(set_ct, -1), be_const_closure(Matter_Plugin_Light2_set_ct_closure) }, + { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(268, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(UPDATE_COMMANDS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_nested_str_weak(Power), + be_nested_str_weak(Bri), + be_nested_str_weak(CT), + })) ) } )) }, + { be_const_key_weak(CLUSTERS, 14), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(8, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(8, 7), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(2), + be_const_int(3), + be_const_int(15), + be_const_int(17), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(29, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(3, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(5, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(768, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(7), + be_const_int(8), + be_const_int(15), + be_const_int(16395), + be_const_int(16396), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(update_ct_minmax, -1), be_const_closure(Matter_Plugin_Light2_update_ct_minmax_closure) }, + { be_const_key_weak(read_attribute, 11), be_const_closure(Matter_Plugin_Light2_read_attribute_closure) }, + { be_const_key_weak(ct_min, -1), be_const_var(1) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(light2) }, + })), + be_str_weak(Matter_Plugin_Light2) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Light2_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Light2); + be_setglobal(vm, "Matter_Plugin_Light2"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Light3.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Light3.h new file mode 100644 index 000000000000..538d02b80427 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_4_Light3.h @@ -0,0 +1,785 @@ +/* Solidification of Matter_Plugin_4_Light3.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Light3; + +/******************************************************************** +** Solidified function: update_virtual +********************************************************************/ +be_local_closure(Matter_Plugin_Light3_update_virtual, /* name */ + be_nested_proto( + 8, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(find), + /* K1 */ be_nested_str_weak(Hue), + /* K2 */ be_nested_str_weak(Sat), + /* K3 */ be_nested_str_weak(set_hue_sat), + /* K4 */ be_nested_str_weak(update_virtual), + }), + be_str_weak(update_virtual), + &be_const_str_solidified, + ( &(const binstruction[27]) { /* code */ + 0x60080009, // 0000 GETGBL R2 G9 + 0x8C0C0300, // 0001 GETMET R3 R1 K0 + 0x58140001, // 0002 LDCONST R5 K1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x7C080200, // 0004 CALL R2 1 + 0x600C0009, // 0005 GETGBL R3 G9 + 0x8C100300, // 0006 GETMET R4 R1 K0 + 0x58180002, // 0007 LDCONST R6 K2 + 0x7C100400, // 0008 CALL R4 2 + 0x7C0C0200, // 0009 CALL R3 1 + 0x4C100000, // 000A LDNIL R4 + 0x20100404, // 000B NE R4 R2 R4 + 0x74120002, // 000C JMPT R4 #0010 + 0x4C100000, // 000D LDNIL R4 + 0x20100604, // 000E NE R4 R3 R4 + 0x78120003, // 000F JMPF R4 #0014 + 0x8C100103, // 0010 GETMET R4 R0 K3 + 0x5C180400, // 0011 MOVE R6 R2 + 0x5C1C0600, // 0012 MOVE R7 R3 + 0x7C100600, // 0013 CALL R4 3 + 0x60100003, // 0014 GETGBL R4 G3 + 0x5C140000, // 0015 MOVE R5 R0 + 0x7C100200, // 0016 CALL R4 1 + 0x8C100904, // 0017 GETMET R4 R4 K4 + 0x5C180200, // 0018 MOVE R6 R1 + 0x7C100400, // 0019 CALL R4 2 + 0x80000000, // 001A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_hue_sat +********************************************************************/ +be_local_closure(Matter_Plugin_Light3_set_hue_sat, /* name */ + be_nested_proto( + 11, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(VIRTUAL), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(scale_uint), + /* K4 */ be_nested_str_weak(light), + /* K5 */ be_nested_str_weak(set), + /* K6 */ be_nested_str_weak(hue), + /* K7 */ be_nested_str_weak(sat), + /* K8 */ be_nested_str_weak(update_shadow), + /* K9 */ be_nested_str_weak(shadow_hue), + /* K10 */ be_nested_str_weak(attribute_updated), + /* K11 */ be_nested_str_weak(shadow_sat), + /* K12 */ be_const_int(1), + }), + be_str_weak(set_hue_sat), + &be_const_str_solidified, + ( &(const binstruction[104]) { /* code */ + 0x4C0C0000, // 0000 LDNIL R3 + 0x200C0203, // 0001 NE R3 R1 R3 + 0x780E0006, // 0002 JMPF R3 #000A + 0x140C0300, // 0003 LT R3 R1 K0 + 0x780E0000, // 0004 JMPF R3 #0006 + 0x58040000, // 0005 LDCONST R1 K0 + 0x540E00FD, // 0006 LDINT R3 254 + 0x240C0203, // 0007 GT R3 R1 R3 + 0x780E0000, // 0008 JMPF R3 #000A + 0x540600FD, // 0009 LDINT R1 254 + 0x4C0C0000, // 000A LDNIL R3 + 0x200C0403, // 000B NE R3 R2 R3 + 0x780E0006, // 000C JMPF R3 #0014 + 0x140C0500, // 000D LT R3 R2 K0 + 0x780E0000, // 000E JMPF R3 #0010 + 0x58080000, // 000F LDCONST R2 K0 + 0x540E00FD, // 0010 LDINT R3 254 + 0x240C0403, // 0011 GT R3 R2 R3 + 0x780E0000, // 0012 JMPF R3 #0014 + 0x540A00FD, // 0013 LDINT R2 254 + 0x880C0101, // 0014 GETMBR R3 R0 K1 + 0x740E003A, // 0015 JMPT R3 #0051 + 0x4C0C0000, // 0016 LDNIL R3 + 0x200C0203, // 0017 NE R3 R1 R3 + 0x780E0008, // 0018 JMPF R3 #0022 + 0xB80E0400, // 0019 GETNGBL R3 K2 + 0x8C0C0703, // 001A GETMET R3 R3 K3 + 0x5C140200, // 001B MOVE R5 R1 + 0x58180000, // 001C LDCONST R6 K0 + 0x541E00FD, // 001D LDINT R7 254 + 0x58200000, // 001E LDCONST R8 K0 + 0x54260167, // 001F LDINT R9 360 + 0x7C0C0C00, // 0020 CALL R3 6 + 0x70020000, // 0021 JMP #0023 + 0x4C0C0000, // 0022 LDNIL R3 + 0x4C100000, // 0023 LDNIL R4 + 0x20100404, // 0024 NE R4 R2 R4 + 0x78120008, // 0025 JMPF R4 #002F + 0xB8120400, // 0026 GETNGBL R4 K2 + 0x8C100903, // 0027 GETMET R4 R4 K3 + 0x5C180400, // 0028 MOVE R6 R2 + 0x581C0000, // 0029 LDCONST R7 K0 + 0x542200FD, // 002A LDINT R8 254 + 0x58240000, // 002B LDCONST R9 K0 + 0x542A00FE, // 002C LDINT R10 255 + 0x7C100C00, // 002D CALL R4 6 + 0x70020000, // 002E JMP #0030 + 0x4C100000, // 002F LDNIL R4 + 0x4C140000, // 0030 LDNIL R5 + 0x20140605, // 0031 NE R5 R3 R5 + 0x7816000A, // 0032 JMPF R5 #003E + 0x4C140000, // 0033 LDNIL R5 + 0x20140805, // 0034 NE R5 R4 R5 + 0x78160007, // 0035 JMPF R5 #003E + 0xB8160800, // 0036 GETNGBL R5 K4 + 0x8C140B05, // 0037 GETMET R5 R5 K5 + 0x601C0013, // 0038 GETGBL R7 G19 + 0x7C1C0000, // 0039 CALL R7 0 + 0x981E0C03, // 003A SETIDX R7 K6 R3 + 0x981E0E04, // 003B SETIDX R7 K7 R4 + 0x7C140400, // 003C CALL R5 2 + 0x7002000F, // 003D JMP #004E + 0x4C140000, // 003E LDNIL R5 + 0x20140605, // 003F NE R5 R3 R5 + 0x78160006, // 0040 JMPF R5 #0048 + 0xB8160800, // 0041 GETNGBL R5 K4 + 0x8C140B05, // 0042 GETMET R5 R5 K5 + 0x601C0013, // 0043 GETGBL R7 G19 + 0x7C1C0000, // 0044 CALL R7 0 + 0x981E0C03, // 0045 SETIDX R7 K6 R3 + 0x7C140400, // 0046 CALL R5 2 + 0x70020005, // 0047 JMP #004E + 0xB8160800, // 0048 GETNGBL R5 K4 + 0x8C140B05, // 0049 GETMET R5 R5 K5 + 0x601C0013, // 004A GETGBL R7 G19 + 0x7C1C0000, // 004B CALL R7 0 + 0x981E0E04, // 004C SETIDX R7 K7 R4 + 0x7C140400, // 004D CALL R5 2 + 0x8C140108, // 004E GETMET R5 R0 K8 + 0x7C140200, // 004F CALL R5 1 + 0x70020015, // 0050 JMP #0067 + 0x4C0C0000, // 0051 LDNIL R3 + 0x200C0203, // 0052 NE R3 R1 R3 + 0x780E0007, // 0053 JMPF R3 #005C + 0x880C0109, // 0054 GETMBR R3 R0 K9 + 0x200C0203, // 0055 NE R3 R1 R3 + 0x780E0004, // 0056 JMPF R3 #005C + 0x8C0C010A, // 0057 GETMET R3 R0 K10 + 0x541602FF, // 0058 LDINT R5 768 + 0x58180000, // 0059 LDCONST R6 K0 + 0x7C0C0600, // 005A CALL R3 3 + 0x90021201, // 005B SETMBR R0 K9 R1 + 0x4C0C0000, // 005C LDNIL R3 + 0x200C0403, // 005D NE R3 R2 R3 + 0x780E0007, // 005E JMPF R3 #0067 + 0x880C010B, // 005F GETMBR R3 R0 K11 + 0x200C0403, // 0060 NE R3 R2 R3 + 0x780E0004, // 0061 JMPF R3 #0067 + 0x8C0C010A, // 0062 GETMET R3 R0 K10 + 0x541602FF, // 0063 LDINT R5 768 + 0x5818000C, // 0064 LDCONST R6 K12 + 0x7C0C0600, // 0065 CALL R3 3 + 0x90021602, // 0066 SETMBR R0 K11 R2 + 0x80000000, // 0067 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: invoke_request +********************************************************************/ +be_local_closure(Matter_Plugin_Light3_invoke_request, /* name */ + be_nested_proto( + 16, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[20]) { /* constants */ + /* K0 */ be_nested_str_weak(light), + /* K1 */ be_nested_str_weak(matter), + /* K2 */ be_nested_str_weak(TLV), + /* K3 */ be_nested_str_weak(cluster), + /* K4 */ be_nested_str_weak(command), + /* K5 */ be_nested_str_weak(update_shadow_lazy), + /* K6 */ be_const_int(0), + /* K7 */ be_nested_str_weak(findsubval), + /* K8 */ be_nested_str_weak(set_hue_sat), + /* K9 */ be_nested_str_weak(log), + /* K10 */ be_nested_str_weak(hue_X3A), + /* K11 */ be_nested_str_weak(publish_command), + /* K12 */ be_nested_str_weak(Hue), + /* K13 */ be_const_int(1), + /* K14 */ be_const_int(2), + /* K15 */ be_const_int(3), + /* K16 */ be_nested_str_weak(sat_X3A), + /* K17 */ be_nested_str_weak(Sat), + /* K18 */ be_nested_str_weak(_X20sat_X3A), + /* K19 */ be_nested_str_weak(invoke_request), + }), + be_str_weak(invoke_request), + &be_const_str_solidified, + ( &(const binstruction[122]) { /* code */ + 0xA4120000, // 0000 IMPORT R4 K0 + 0xB8160200, // 0001 GETNGBL R5 K1 + 0x88140B02, // 0002 GETMBR R5 R5 K2 + 0x88180703, // 0003 GETMBR R6 R3 K3 + 0x881C0704, // 0004 GETMBR R7 R3 K4 + 0x542202FF, // 0005 LDINT R8 768 + 0x1C200C08, // 0006 EQ R8 R6 R8 + 0x78220067, // 0007 JMPF R8 #0070 + 0x8C200105, // 0008 GETMET R8 R0 K5 + 0x7C200200, // 0009 CALL R8 1 + 0x1C200F06, // 000A EQ R8 R7 K6 + 0x78220012, // 000B JMPF R8 #001F + 0x8C200507, // 000C GETMET R8 R2 K7 + 0x58280006, // 000D LDCONST R10 K6 + 0x7C200400, // 000E CALL R8 2 + 0x8C240108, // 000F GETMET R9 R0 K8 + 0x5C2C1000, // 0010 MOVE R11 R8 + 0x4C300000, // 0011 LDNIL R12 + 0x7C240600, // 0012 CALL R9 3 + 0x60240008, // 0013 GETGBL R9 G8 + 0x5C281000, // 0014 MOVE R10 R8 + 0x7C240200, // 0015 CALL R9 1 + 0x00261409, // 0016 ADD R9 K10 R9 + 0x900E1209, // 0017 SETMBR R3 K9 R9 + 0x8C24010B, // 0018 GETMET R9 R0 K11 + 0x582C000C, // 0019 LDCONST R11 K12 + 0x5C301000, // 001A MOVE R12 R8 + 0x7C240600, // 001B CALL R9 3 + 0x50240200, // 001C LDBOOL R9 1 0 + 0x80041200, // 001D RET 1 R9 + 0x7002004F, // 001E JMP #006F + 0x1C200F0D, // 001F EQ R8 R7 K13 + 0x78220002, // 0020 JMPF R8 #0024 + 0x50200200, // 0021 LDBOOL R8 1 0 + 0x80041000, // 0022 RET 1 R8 + 0x7002004A, // 0023 JMP #006F + 0x1C200F0E, // 0024 EQ R8 R7 K14 + 0x78220002, // 0025 JMPF R8 #0029 + 0x50200200, // 0026 LDBOOL R8 1 0 + 0x80041000, // 0027 RET 1 R8 + 0x70020045, // 0028 JMP #006F + 0x1C200F0F, // 0029 EQ R8 R7 K15 + 0x78220012, // 002A JMPF R8 #003E + 0x8C200507, // 002B GETMET R8 R2 K7 + 0x58280006, // 002C LDCONST R10 K6 + 0x7C200400, // 002D CALL R8 2 + 0x8C240108, // 002E GETMET R9 R0 K8 + 0x4C2C0000, // 002F LDNIL R11 + 0x5C301000, // 0030 MOVE R12 R8 + 0x7C240600, // 0031 CALL R9 3 + 0x60240008, // 0032 GETGBL R9 G8 + 0x5C281000, // 0033 MOVE R10 R8 + 0x7C240200, // 0034 CALL R9 1 + 0x00262009, // 0035 ADD R9 K16 R9 + 0x900E1209, // 0036 SETMBR R3 K9 R9 + 0x8C24010B, // 0037 GETMET R9 R0 K11 + 0x582C0011, // 0038 LDCONST R11 K17 + 0x5C301000, // 0039 MOVE R12 R8 + 0x7C240600, // 003A CALL R9 3 + 0x50240200, // 003B LDBOOL R9 1 0 + 0x80041200, // 003C RET 1 R9 + 0x70020030, // 003D JMP #006F + 0x54220003, // 003E LDINT R8 4 + 0x1C200E08, // 003F EQ R8 R7 R8 + 0x78220002, // 0040 JMPF R8 #0044 + 0x50200200, // 0041 LDBOOL R8 1 0 + 0x80041000, // 0042 RET 1 R8 + 0x7002002A, // 0043 JMP #006F + 0x54220004, // 0044 LDINT R8 5 + 0x1C200E08, // 0045 EQ R8 R7 R8 + 0x78220002, // 0046 JMPF R8 #004A + 0x50200200, // 0047 LDBOOL R8 1 0 + 0x80041000, // 0048 RET 1 R8 + 0x70020024, // 0049 JMP #006F + 0x54220005, // 004A LDINT R8 6 + 0x1C200E08, // 004B EQ R8 R7 R8 + 0x7822001C, // 004C JMPF R8 #006A + 0x8C200507, // 004D GETMET R8 R2 K7 + 0x58280006, // 004E LDCONST R10 K6 + 0x7C200400, // 004F CALL R8 2 + 0x8C240507, // 0050 GETMET R9 R2 K7 + 0x582C000D, // 0051 LDCONST R11 K13 + 0x7C240400, // 0052 CALL R9 2 + 0x8C280108, // 0053 GETMET R10 R0 K8 + 0x5C301000, // 0054 MOVE R12 R8 + 0x5C341200, // 0055 MOVE R13 R9 + 0x7C280600, // 0056 CALL R10 3 + 0x60280008, // 0057 GETGBL R10 G8 + 0x5C2C1000, // 0058 MOVE R11 R8 + 0x7C280200, // 0059 CALL R10 1 + 0x002A140A, // 005A ADD R10 K10 R10 + 0x00281512, // 005B ADD R10 R10 K18 + 0x602C0008, // 005C GETGBL R11 G8 + 0x5C301200, // 005D MOVE R12 R9 + 0x7C2C0200, // 005E CALL R11 1 + 0x0028140B, // 005F ADD R10 R10 R11 + 0x900E120A, // 0060 SETMBR R3 K9 R10 + 0x8C28010B, // 0061 GETMET R10 R0 K11 + 0x5830000C, // 0062 LDCONST R12 K12 + 0x5C341000, // 0063 MOVE R13 R8 + 0x58380011, // 0064 LDCONST R14 K17 + 0x5C3C1200, // 0065 MOVE R15 R9 + 0x7C280A00, // 0066 CALL R10 5 + 0x50280200, // 0067 LDBOOL R10 1 0 + 0x80041400, // 0068 RET 1 R10 + 0x70020004, // 0069 JMP #006F + 0x54220046, // 006A LDINT R8 71 + 0x1C200E08, // 006B EQ R8 R7 R8 + 0x78220001, // 006C JMPF R8 #006F + 0x50200200, // 006D LDBOOL R8 1 0 + 0x80041000, // 006E RET 1 R8 + 0x70020008, // 006F JMP #0079 + 0x60200003, // 0070 GETGBL R8 G3 + 0x5C240000, // 0071 MOVE R9 R0 + 0x7C200200, // 0072 CALL R8 1 + 0x8C201113, // 0073 GETMET R8 R8 K19 + 0x5C280200, // 0074 MOVE R10 R1 + 0x5C2C0400, // 0075 MOVE R11 R2 + 0x5C300600, // 0076 MOVE R12 R3 + 0x7C200800, // 0077 CALL R8 4 + 0x80041000, // 0078 RET 1 R8 + 0x80000000, // 0079 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_Light3_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(shadow_hue), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(shadow_sat), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[11]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x90020302, // 0008 SETMBR R0 K1 K2 + 0x90020702, // 0009 SETMBR R0 K3 K2 + 0x80000000, // 000A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_shadow +********************************************************************/ +be_local_closure(Matter_Plugin_Light3_update_shadow, /* name */ + be_nested_proto( + 12, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(update_shadow), + /* K1 */ be_nested_str_weak(VIRTUAL), + /* K2 */ be_nested_str_weak(light), + /* K3 */ be_nested_str_weak(get), + /* K4 */ be_nested_str_weak(find), + /* K5 */ be_nested_str_weak(hue), + /* K6 */ be_nested_str_weak(sat), + /* K7 */ be_nested_str_weak(tasmota), + /* K8 */ be_nested_str_weak(scale_uint), + /* K9 */ be_const_int(0), + /* K10 */ be_nested_str_weak(shadow_hue), + /* K11 */ be_nested_str_weak(shadow_sat), + /* K12 */ be_nested_str_weak(attribute_updated), + /* K13 */ be_const_int(1), + }), + be_str_weak(update_shadow), + &be_const_str_solidified, + ( &(const binstruction[66]) { /* code */ + 0x60040003, // 0000 GETGBL R1 G3 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x8C040300, // 0003 GETMET R1 R1 K0 + 0x7C040200, // 0004 CALL R1 1 + 0x88040101, // 0005 GETMBR R1 R0 K1 + 0x74060039, // 0006 JMPT R1 #0041 + 0xA4060400, // 0007 IMPORT R1 K2 + 0x8C080303, // 0008 GETMET R2 R1 K3 + 0x7C080200, // 0009 CALL R2 1 + 0x4C0C0000, // 000A LDNIL R3 + 0x200C0403, // 000B NE R3 R2 R3 + 0x780E0033, // 000C JMPF R3 #0041 + 0x8C0C0504, // 000D GETMET R3 R2 K4 + 0x58140005, // 000E LDCONST R5 K5 + 0x4C180000, // 000F LDNIL R6 + 0x7C0C0600, // 0010 CALL R3 3 + 0x8C100504, // 0011 GETMET R4 R2 K4 + 0x58180006, // 0012 LDCONST R6 K6 + 0x4C1C0000, // 0013 LDNIL R7 + 0x7C100600, // 0014 CALL R4 3 + 0x4C140000, // 0015 LDNIL R5 + 0x20140605, // 0016 NE R5 R3 R5 + 0x78160009, // 0017 JMPF R5 #0022 + 0xB8160E00, // 0018 GETNGBL R5 K7 + 0x8C140B08, // 0019 GETMET R5 R5 K8 + 0x5C1C0600, // 001A MOVE R7 R3 + 0x58200009, // 001B LDCONST R8 K9 + 0x54260167, // 001C LDINT R9 360 + 0x58280009, // 001D LDCONST R10 K9 + 0x542E00FD, // 001E LDINT R11 254 + 0x7C140C00, // 001F CALL R5 6 + 0x5C0C0A00, // 0020 MOVE R3 R5 + 0x70020000, // 0021 JMP #0023 + 0x880C010A, // 0022 GETMBR R3 R0 K10 + 0x4C140000, // 0023 LDNIL R5 + 0x20140805, // 0024 NE R5 R4 R5 + 0x78160009, // 0025 JMPF R5 #0030 + 0xB8160E00, // 0026 GETNGBL R5 K7 + 0x8C140B08, // 0027 GETMET R5 R5 K8 + 0x5C1C0800, // 0028 MOVE R7 R4 + 0x58200009, // 0029 LDCONST R8 K9 + 0x542600FE, // 002A LDINT R9 255 + 0x58280009, // 002B LDCONST R10 K9 + 0x542E00FD, // 002C LDINT R11 254 + 0x7C140C00, // 002D CALL R5 6 + 0x5C100A00, // 002E MOVE R4 R5 + 0x70020000, // 002F JMP #0031 + 0x8810010B, // 0030 GETMBR R4 R0 K11 + 0x8814010A, // 0031 GETMBR R5 R0 K10 + 0x20140605, // 0032 NE R5 R3 R5 + 0x78160004, // 0033 JMPF R5 #0039 + 0x8C14010C, // 0034 GETMET R5 R0 K12 + 0x541E02FF, // 0035 LDINT R7 768 + 0x58200009, // 0036 LDCONST R8 K9 + 0x7C140600, // 0037 CALL R5 3 + 0x90021403, // 0038 SETMBR R0 K10 R3 + 0x8814010B, // 0039 GETMBR R5 R0 K11 + 0x20140805, // 003A NE R5 R4 R5 + 0x78160004, // 003B JMPF R5 #0041 + 0x8C14010C, // 003C GETMET R5 R0 K12 + 0x541E02FF, // 003D LDINT R7 768 + 0x5820000D, // 003E LDCONST R8 K13 + 0x7C140600, // 003F CALL R5 3 + 0x90021604, // 0040 SETMBR R0 K11 R4 + 0x80000000, // 0041 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Light3_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(U1), + /* K8 */ be_nested_str_weak(shadow_hue), + /* K9 */ be_const_int(1), + /* K10 */ be_nested_str_weak(shadow_sat), + /* K11 */ be_nested_str_weak(U4), + /* K12 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[107]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E02FF, // 0004 LDINT R7 768 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0059, // 0006 JMPF R7 #0061 + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x1C1C0D05, // 0009 EQ R7 R6 K5 + 0x781E0005, // 000A JMPF R7 #0011 + 0x8C1C0706, // 000B GETMET R7 R3 K6 + 0x88240907, // 000C GETMBR R9 R4 K7 + 0x88280108, // 000D GETMBR R10 R0 K8 + 0x7C1C0600, // 000E CALL R7 3 + 0x80040E00, // 000F RET 1 R7 + 0x7002004E, // 0010 JMP #0060 + 0x1C1C0D09, // 0011 EQ R7 R6 K9 + 0x781E0005, // 0012 JMPF R7 #0019 + 0x8C1C0706, // 0013 GETMET R7 R3 K6 + 0x88240907, // 0014 GETMBR R9 R4 K7 + 0x8828010A, // 0015 GETMBR R10 R0 K10 + 0x7C1C0600, // 0016 CALL R7 3 + 0x80040E00, // 0017 RET 1 R7 + 0x70020046, // 0018 JMP #0060 + 0x541E0006, // 0019 LDINT R7 7 + 0x1C1C0C07, // 001A EQ R7 R6 R7 + 0x781E0005, // 001B JMPF R7 #0022 + 0x8C1C0706, // 001C GETMET R7 R3 K6 + 0x88240907, // 001D GETMBR R9 R4 K7 + 0x58280005, // 001E LDCONST R10 K5 + 0x7C1C0600, // 001F CALL R7 3 + 0x80040E00, // 0020 RET 1 R7 + 0x7002003D, // 0021 JMP #0060 + 0x541E0007, // 0022 LDINT R7 8 + 0x1C1C0C07, // 0023 EQ R7 R6 R7 + 0x781E0005, // 0024 JMPF R7 #002B + 0x8C1C0706, // 0025 GETMET R7 R3 K6 + 0x88240907, // 0026 GETMBR R9 R4 K7 + 0x58280005, // 0027 LDCONST R10 K5 + 0x7C1C0600, // 0028 CALL R7 3 + 0x80040E00, // 0029 RET 1 R7 + 0x70020034, // 002A JMP #0060 + 0x541E000E, // 002B LDINT R7 15 + 0x1C1C0C07, // 002C EQ R7 R6 R7 + 0x781E0005, // 002D JMPF R7 #0034 + 0x8C1C0706, // 002E GETMET R7 R3 K6 + 0x88240907, // 002F GETMBR R9 R4 K7 + 0x58280005, // 0030 LDCONST R10 K5 + 0x7C1C0600, // 0031 CALL R7 3 + 0x80040E00, // 0032 RET 1 R7 + 0x7002002B, // 0033 JMP #0060 + 0x541E4000, // 0034 LDINT R7 16385 + 0x1C1C0C07, // 0035 EQ R7 R6 R7 + 0x781E0005, // 0036 JMPF R7 #003D + 0x8C1C0706, // 0037 GETMET R7 R3 K6 + 0x88240907, // 0038 GETMBR R9 R4 K7 + 0x58280005, // 0039 LDCONST R10 K5 + 0x7C1C0600, // 003A CALL R7 3 + 0x80040E00, // 003B RET 1 R7 + 0x70020022, // 003C JMP #0060 + 0x541E4009, // 003D LDINT R7 16394 + 0x1C1C0C07, // 003E EQ R7 R6 R7 + 0x781E0005, // 003F JMPF R7 #0046 + 0x8C1C0706, // 0040 GETMET R7 R3 K6 + 0x88240907, // 0041 GETMBR R9 R4 K7 + 0x58280009, // 0042 LDCONST R10 K9 + 0x7C1C0600, // 0043 CALL R7 3 + 0x80040E00, // 0044 RET 1 R7 + 0x70020019, // 0045 JMP #0060 + 0x541E000F, // 0046 LDINT R7 16 + 0x1C1C0C07, // 0047 EQ R7 R6 R7 + 0x781E0005, // 0048 JMPF R7 #004F + 0x8C1C0706, // 0049 GETMET R7 R3 K6 + 0x88240907, // 004A GETMBR R9 R4 K7 + 0x58280005, // 004B LDCONST R10 K5 + 0x7C1C0600, // 004C CALL R7 3 + 0x80040E00, // 004D RET 1 R7 + 0x70020010, // 004E JMP #0060 + 0x541EFFFB, // 004F LDINT R7 65532 + 0x1C1C0C07, // 0050 EQ R7 R6 R7 + 0x781E0005, // 0051 JMPF R7 #0058 + 0x8C1C0706, // 0052 GETMET R7 R3 K6 + 0x8824090B, // 0053 GETMBR R9 R4 K11 + 0x58280009, // 0054 LDCONST R10 K9 + 0x7C1C0600, // 0055 CALL R7 3 + 0x80040E00, // 0056 RET 1 R7 + 0x70020007, // 0057 JMP #0060 + 0x541EFFFC, // 0058 LDINT R7 65533 + 0x1C1C0C07, // 0059 EQ R7 R6 R7 + 0x781E0004, // 005A JMPF R7 #0060 + 0x8C1C0706, // 005B GETMET R7 R3 K6 + 0x8824090B, // 005C GETMBR R9 R4 K11 + 0x542A0004, // 005D LDINT R10 5 + 0x7C1C0600, // 005E CALL R7 3 + 0x80040E00, // 005F RET 1 R7 + 0x70020008, // 0060 JMP #006A + 0x601C0003, // 0061 GETGBL R7 G3 + 0x5C200000, // 0062 MOVE R8 R0 + 0x7C1C0200, // 0063 CALL R7 1 + 0x8C1C0F0C, // 0064 GETMET R7 R7 K12 + 0x5C240200, // 0065 MOVE R9 R1 + 0x5C280400, // 0066 MOVE R10 R2 + 0x5C2C0600, // 0067 MOVE R11 R3 + 0x7C1C0800, // 0068 CALL R7 4 + 0x80040E00, // 0069 RET 1 R7 + 0x80000000, // 006A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Light3 +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Light1; +be_local_class(Matter_Plugin_Light3, + 2, + &be_class_Matter_Plugin_Light1, + be_nested_map(13, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(shadow_hue, -1), be_const_var(0) }, + { be_const_key_weak(shadow_sat, -1), be_const_var(1) }, + { be_const_key_weak(update_virtual, 8), be_const_closure(Matter_Plugin_Light3_update_virtual_closure) }, + { be_const_key_weak(update_shadow, -1), be_const_closure(Matter_Plugin_Light3_update_shadow_closure) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Light3_read_attribute_closure) }, + { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Light3_invoke_request_closure) }, + { be_const_key_weak(init, 9), be_const_closure(Matter_Plugin_Light3_init_closure) }, + { be_const_key_weak(set_hue_sat, 3), be_const_closure(Matter_Plugin_Light3_set_hue_sat_closure) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(light3) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Light_X203_X20RGB) }, + { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(8, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(8, 7), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(2), + be_const_int(3), + be_const_int(15), + be_const_int(17), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(29, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(3, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(5, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(768, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(9, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(7), + be_const_int(8), + be_const_int(15), + be_const_int(16385), + be_const_int(16394), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(UPDATE_COMMANDS, 4), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_nested_str_weak(Power), + be_nested_str_weak(Bri), + be_nested_str_weak(Hue), + be_nested_str_weak(Sat), + })) ) } )) }, + { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(269, -1), be_const_int(2) }, + })) ) } )) }, + })), + be_str_weak(Matter_Plugin_Light3) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Light3_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Light3); + be_setglobal(vm, "Matter_Plugin_Light3"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_5_Bridge_Light2.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_5_Bridge_Light2.h new file mode 100644 index 000000000000..712aa9f6d330 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_5_Bridge_Light2.h @@ -0,0 +1,655 @@ +/* Solidification of Matter_Plugin_5_Bridge_Light2.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Bridge_Light2; + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light2_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(update_ct_minmax), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[11]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x8C100101, // 0008 GETMET R4 R0 K1 + 0x7C100200, // 0009 CALL R4 1 + 0x80000000, // 000A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_update +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light2_parse_update, /* name */ + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(parse_update), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(CT), + /* K3 */ be_nested_str_weak(shadow_ct), + /* K4 */ be_nested_str_weak(ct_min), + /* K5 */ be_nested_str_weak(ct_max), + /* K6 */ be_nested_str_weak(attribute_updated), + }), + be_str_weak(parse_update), + &be_const_str_solidified, + ( &(const binstruction[35]) { /* code */ + 0x600C0003, // 0000 GETGBL R3 G3 + 0x5C100000, // 0001 MOVE R4 R0 + 0x7C0C0200, // 0002 CALL R3 1 + 0x8C0C0700, // 0003 GETMET R3 R3 K0 + 0x5C140200, // 0004 MOVE R5 R1 + 0x5C180400, // 0005 MOVE R6 R2 + 0x7C0C0600, // 0006 CALL R3 3 + 0x540E000A, // 0007 LDINT R3 11 + 0x1C0C0403, // 0008 EQ R3 R2 R3 + 0x780E0017, // 0009 JMPF R3 #0022 + 0x600C0009, // 000A GETGBL R3 G9 + 0x8C100301, // 000B GETMET R4 R1 K1 + 0x58180002, // 000C LDCONST R6 K2 + 0x7C100400, // 000D CALL R4 2 + 0x7C0C0200, // 000E CALL R3 1 + 0x4C100000, // 000F LDNIL R4 + 0x20100604, // 0010 NE R4 R3 R4 + 0x7812000F, // 0011 JMPF R4 #0022 + 0x88100103, // 0012 GETMBR R4 R0 K3 + 0x20100604, // 0013 NE R4 R3 R4 + 0x7812000C, // 0014 JMPF R4 #0022 + 0x88100104, // 0015 GETMBR R4 R0 K4 + 0x14100604, // 0016 LT R4 R3 R4 + 0x78120000, // 0017 JMPF R4 #0019 + 0x880C0104, // 0018 GETMBR R3 R0 K4 + 0x88100105, // 0019 GETMBR R4 R0 K5 + 0x24100604, // 001A GT R4 R3 R4 + 0x78120000, // 001B JMPF R4 #001D + 0x880C0105, // 001C GETMBR R3 R0 K5 + 0x8C100106, // 001D GETMET R4 R0 K6 + 0x541A02FF, // 001E LDINT R6 768 + 0x541E0006, // 001F LDINT R7 7 + 0x7C100600, // 0020 CALL R4 3 + 0x90020603, // 0021 SETMBR R0 K3 R3 + 0x80000000, // 0022 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light2_web_values, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(web_values_prefix), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(_X25s_X20_X25s_X20_X25s), + /* K4 */ be_nested_str_weak(web_value_onoff), + /* K5 */ be_nested_str_weak(shadow_onoff), + /* K6 */ be_nested_str_weak(web_value_dimmer), + /* K7 */ be_nested_str_weak(web_value_ct), + }), + be_str_weak(web_values), + &be_const_str_solidified, + ( &(const binstruction[16]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x60100018, // 0004 GETGBL R4 G24 + 0x58140003, // 0005 LDCONST R5 K3 + 0x8C180104, // 0006 GETMET R6 R0 K4 + 0x88200105, // 0007 GETMBR R8 R0 K5 + 0x7C180400, // 0008 CALL R6 2 + 0x8C1C0106, // 0009 GETMET R7 R0 K6 + 0x7C1C0200, // 000A CALL R7 1 + 0x8C200107, // 000B GETMET R8 R0 K7 + 0x7C200200, // 000C CALL R8 1 + 0x7C100800, // 000D CALL R4 4 + 0x7C080400, // 000E CALL R2 2 + 0x80000000, // 000F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_value_ct +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light2_web_value_ct, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(), + /* K1 */ be_nested_str_weak(shadow_ct), + /* K2 */ be_const_int(1000000), + /* K3 */ be_nested_str_weak(_X25iK), + /* K4 */ be_nested_str_weak(_X26_X239898_X3B_X20), + }), + be_str_weak(web_value_ct), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x88080101, // 0001 GETMBR R2 R0 K1 + 0x4C0C0000, // 0002 LDNIL R3 + 0x20080403, // 0003 NE R2 R2 R3 + 0x780A000C, // 0004 JMPF R2 #0012 + 0x88080101, // 0005 GETMBR R2 R0 K1 + 0x0C0A0402, // 0006 DIV R2 K2 R2 + 0x540E0018, // 0007 LDINT R3 25 + 0x00080403, // 0008 ADD R2 R2 R3 + 0x540E0031, // 0009 LDINT R3 50 + 0x0C080403, // 000A DIV R2 R2 R3 + 0x540E0031, // 000B LDINT R3 50 + 0x08080403, // 000C MUL R2 R2 R3 + 0x600C0018, // 000D GETGBL R3 G24 + 0x58100003, // 000E LDCONST R4 K3 + 0x5C140400, // 000F MOVE R5 R2 + 0x7C0C0400, // 0010 CALL R3 2 + 0x5C040600, // 0011 MOVE R1 R3 + 0x000A0801, // 0012 ADD R2 K4 R1 + 0x80040400, // 0013 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_ct +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light2_set_ct, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(call_remote_sync), + /* K1 */ be_nested_str_weak(CT), + /* K2 */ be_nested_str_weak(parse_update), + }), + be_str_weak(set_ct), + &be_const_str_solidified, + ( &(const binstruction[14]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x58100001, // 0001 LDCONST R4 K1 + 0x60140008, // 0002 GETGBL R5 G8 + 0x5C180200, // 0003 MOVE R6 R1 + 0x7C140200, // 0004 CALL R5 1 + 0x7C080600, // 0005 CALL R2 3 + 0x4C0C0000, // 0006 LDNIL R3 + 0x200C0403, // 0007 NE R3 R2 R3 + 0x780E0003, // 0008 JMPF R3 #000D + 0x8C0C0102, // 0009 GETMET R3 R0 K2 + 0x5C140400, // 000A MOVE R5 R2 + 0x541A000A, // 000B LDINT R6 11 + 0x7C0C0600, // 000C CALL R3 3 + 0x80000000, // 000D RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: invoke_request +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light2_invoke_request, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(command), + /* K4 */ be_nested_str_weak(findsubval), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(ct_min), + /* K7 */ be_nested_str_weak(ct_max), + /* K8 */ be_nested_str_weak(set_ct), + /* K9 */ be_nested_str_weak(log), + /* K10 */ be_nested_str_weak(ct_X3A), + /* K11 */ be_nested_str_weak(publish_command), + /* K12 */ be_nested_str_weak(CT), + /* K13 */ be_nested_str_weak(invoke_request), + }), + be_str_weak(invoke_request), + &be_const_str_solidified, + ( &(const binstruction[64]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140702, // 0002 GETMBR R5 R3 K2 + 0x88180703, // 0003 GETMBR R6 R3 K3 + 0x541E02FF, // 0004 LDINT R7 768 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E002E, // 0006 JMPF R7 #0036 + 0x541E0009, // 0007 LDINT R7 10 + 0x1C1C0C07, // 0008 EQ R7 R6 R7 + 0x781E0019, // 0009 JMPF R7 #0024 + 0x8C1C0504, // 000A GETMET R7 R2 K4 + 0x58240005, // 000B LDCONST R9 K5 + 0x7C1C0400, // 000C CALL R7 2 + 0x88200106, // 000D GETMBR R8 R0 K6 + 0x14200E08, // 000E LT R8 R7 R8 + 0x78220000, // 000F JMPF R8 #0011 + 0x881C0106, // 0010 GETMBR R7 R0 K6 + 0x88200107, // 0011 GETMBR R8 R0 K7 + 0x24200E08, // 0012 GT R8 R7 R8 + 0x78220000, // 0013 JMPF R8 #0015 + 0x881C0107, // 0014 GETMBR R7 R0 K7 + 0x8C200108, // 0015 GETMET R8 R0 K8 + 0x5C280E00, // 0016 MOVE R10 R7 + 0x7C200400, // 0017 CALL R8 2 + 0x60200008, // 0018 GETGBL R8 G8 + 0x5C240E00, // 0019 MOVE R9 R7 + 0x7C200200, // 001A CALL R8 1 + 0x00221408, // 001B ADD R8 K10 R8 + 0x900E1208, // 001C SETMBR R3 K9 R8 + 0x8C20010B, // 001D GETMET R8 R0 K11 + 0x5828000C, // 001E LDCONST R10 K12 + 0x5C2C0E00, // 001F MOVE R11 R7 + 0x7C200600, // 0020 CALL R8 3 + 0x50200200, // 0021 LDBOOL R8 1 0 + 0x80041000, // 0022 RET 1 R8 + 0x70020010, // 0023 JMP #0035 + 0x541E0046, // 0024 LDINT R7 71 + 0x1C1C0C07, // 0025 EQ R7 R6 R7 + 0x781E0002, // 0026 JMPF R7 #002A + 0x501C0200, // 0027 LDBOOL R7 1 0 + 0x80040E00, // 0028 RET 1 R7 + 0x7002000A, // 0029 JMP #0035 + 0x541E004A, // 002A LDINT R7 75 + 0x1C1C0C07, // 002B EQ R7 R6 R7 + 0x781E0002, // 002C JMPF R7 #0030 + 0x501C0200, // 002D LDBOOL R7 1 0 + 0x80040E00, // 002E RET 1 R7 + 0x70020004, // 002F JMP #0035 + 0x541E004B, // 0030 LDINT R7 76 + 0x1C1C0C07, // 0031 EQ R7 R6 R7 + 0x781E0001, // 0032 JMPF R7 #0035 + 0x501C0200, // 0033 LDBOOL R7 1 0 + 0x80040E00, // 0034 RET 1 R7 + 0x70020008, // 0035 JMP #003F + 0x601C0003, // 0036 GETGBL R7 G3 + 0x5C200000, // 0037 MOVE R8 R0 + 0x7C1C0200, // 0038 CALL R7 1 + 0x8C1C0F0D, // 0039 GETMET R7 R7 K13 + 0x5C240200, // 003A MOVE R9 R1 + 0x5C280400, // 003B MOVE R10 R2 + 0x5C2C0600, // 003C MOVE R11 R3 + 0x7C1C0800, // 003D CALL R7 4 + 0x80040E00, // 003E RET 1 R7 + 0x80000000, // 003F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light2_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[15]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_nested_str_weak(shadow_ct), + /* K6 */ be_nested_str_weak(set), + /* K7 */ be_nested_str_weak(U1), + /* K8 */ be_nested_str_weak(NULL), + /* K9 */ be_const_int(2), + /* K10 */ be_const_int(0), + /* K11 */ be_nested_str_weak(ct_min), + /* K12 */ be_nested_str_weak(ct_max), + /* K13 */ be_nested_str_weak(U4), + /* K14 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[101]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E02FF, // 0004 LDINT R7 768 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0053, // 0006 JMPF R7 #005B + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x541E0006, // 0009 LDINT R7 7 + 0x1C1C0C07, // 000A EQ R7 R6 R7 + 0x781E000F, // 000B JMPF R7 #001C + 0x881C0105, // 000C GETMBR R7 R0 K5 + 0x4C200000, // 000D LDNIL R8 + 0x201C0E08, // 000E NE R7 R7 R8 + 0x781E0005, // 000F JMPF R7 #0016 + 0x8C1C0706, // 0010 GETMET R7 R3 K6 + 0x88240907, // 0011 GETMBR R9 R4 K7 + 0x88280105, // 0012 GETMBR R10 R0 K5 + 0x7C1C0600, // 0013 CALL R7 3 + 0x80040E00, // 0014 RET 1 R7 + 0x70020004, // 0015 JMP #001B + 0x8C1C0706, // 0016 GETMET R7 R3 K6 + 0x88240908, // 0017 GETMBR R9 R4 K8 + 0x4C280000, // 0018 LDNIL R10 + 0x7C1C0600, // 0019 CALL R7 3 + 0x80040E00, // 001A RET 1 R7 + 0x7002003D, // 001B JMP #005A + 0x541E0007, // 001C LDINT R7 8 + 0x1C1C0C07, // 001D EQ R7 R6 R7 + 0x781E0005, // 001E JMPF R7 #0025 + 0x8C1C0706, // 001F GETMET R7 R3 K6 + 0x88240907, // 0020 GETMBR R9 R4 K7 + 0x58280009, // 0021 LDCONST R10 K9 + 0x7C1C0600, // 0022 CALL R7 3 + 0x80040E00, // 0023 RET 1 R7 + 0x70020034, // 0024 JMP #005A + 0x541E000E, // 0025 LDINT R7 15 + 0x1C1C0C07, // 0026 EQ R7 R6 R7 + 0x781E0005, // 0027 JMPF R7 #002E + 0x8C1C0706, // 0028 GETMET R7 R3 K6 + 0x88240907, // 0029 GETMBR R9 R4 K7 + 0x5828000A, // 002A LDCONST R10 K10 + 0x7C1C0600, // 002B CALL R7 3 + 0x80040E00, // 002C RET 1 R7 + 0x7002002B, // 002D JMP #005A + 0x541E400A, // 002E LDINT R7 16395 + 0x1C1C0C07, // 002F EQ R7 R6 R7 + 0x781E0005, // 0030 JMPF R7 #0037 + 0x8C1C0706, // 0031 GETMET R7 R3 K6 + 0x88240907, // 0032 GETMBR R9 R4 K7 + 0x8828010B, // 0033 GETMBR R10 R0 K11 + 0x7C1C0600, // 0034 CALL R7 3 + 0x80040E00, // 0035 RET 1 R7 + 0x70020022, // 0036 JMP #005A + 0x541E400B, // 0037 LDINT R7 16396 + 0x1C1C0C07, // 0038 EQ R7 R6 R7 + 0x781E0005, // 0039 JMPF R7 #0040 + 0x8C1C0706, // 003A GETMET R7 R3 K6 + 0x88240907, // 003B GETMBR R9 R4 K7 + 0x8828010C, // 003C GETMBR R10 R0 K12 + 0x7C1C0600, // 003D CALL R7 3 + 0x80040E00, // 003E RET 1 R7 + 0x70020019, // 003F JMP #005A + 0x541E4009, // 0040 LDINT R7 16394 + 0x1C1C0C07, // 0041 EQ R7 R6 R7 + 0x781E0005, // 0042 JMPF R7 #0049 + 0x8C1C0706, // 0043 GETMET R7 R3 K6 + 0x8824090D, // 0044 GETMBR R9 R4 K13 + 0x542A000F, // 0045 LDINT R10 16 + 0x7C1C0600, // 0046 CALL R7 3 + 0x80040E00, // 0047 RET 1 R7 + 0x70020010, // 0048 JMP #005A + 0x541EFFFB, // 0049 LDINT R7 65532 + 0x1C1C0C07, // 004A EQ R7 R6 R7 + 0x781E0005, // 004B JMPF R7 #0052 + 0x8C1C0706, // 004C GETMET R7 R3 K6 + 0x8824090D, // 004D GETMBR R9 R4 K13 + 0x542A000F, // 004E LDINT R10 16 + 0x7C1C0600, // 004F CALL R7 3 + 0x80040E00, // 0050 RET 1 R7 + 0x70020007, // 0051 JMP #005A + 0x541EFFFC, // 0052 LDINT R7 65533 + 0x1C1C0C07, // 0053 EQ R7 R6 R7 + 0x781E0004, // 0054 JMPF R7 #005A + 0x8C1C0706, // 0055 GETMET R7 R3 K6 + 0x8824090D, // 0056 GETMBR R9 R4 K13 + 0x542A0004, // 0057 LDINT R10 5 + 0x7C1C0600, // 0058 CALL R7 3 + 0x80040E00, // 0059 RET 1 R7 + 0x70020008, // 005A JMP #0064 + 0x601C0003, // 005B GETGBL R7 G3 + 0x5C200000, // 005C MOVE R8 R0 + 0x7C1C0200, // 005D CALL R7 1 + 0x8C1C0F0E, // 005E GETMET R7 R7 K14 + 0x5C240200, // 005F MOVE R9 R1 + 0x5C280400, // 0060 MOVE R10 R2 + 0x5C2C0600, // 0061 MOVE R11 R3 + 0x7C1C0800, // 0062 CALL R7 4 + 0x80040E00, // 0063 RET 1 R7 + 0x80000000, // 0064 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: update_ct_minmax +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light2_update_ct_minmax, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(get_option), + /* K2 */ be_nested_str_weak(ct_min), + /* K3 */ be_nested_str_weak(ct_max), + }), + be_str_weak(update_ct_minmax), + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0xB8060000, // 0000 GETNGBL R1 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x540E0051, // 0002 LDINT R3 82 + 0x7C040400, // 0003 CALL R1 2 + 0x78060001, // 0004 JMPF R1 #0007 + 0x540A00C7, // 0005 LDINT R2 200 + 0x70020000, // 0006 JMP #0008 + 0x540A0098, // 0007 LDINT R2 153 + 0x90020402, // 0008 SETMBR R0 K2 R2 + 0x78060001, // 0009 JMPF R1 #000C + 0x540A017B, // 000A LDINT R2 380 + 0x70020000, // 000B JMP #000D + 0x540A01F3, // 000C LDINT R2 500 + 0x90020602, // 000D SETMBR R0 K3 R2 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_Light2 +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Bridge_Light1; +be_local_class(Matter_Plugin_Bridge_Light2, + 3, + &be_class_Matter_Plugin_Bridge_Light1, + be_nested_map(15, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Bridge_Light2_init_closure) }, + { be_const_key_weak(parse_update, 9), be_const_closure(Matter_Plugin_Bridge_Light2_parse_update_closure) }, + { be_const_key_weak(web_values, 11), be_const_closure(Matter_Plugin_Bridge_Light2_web_values_closure) }, + { be_const_key_weak(ct_max, -1), be_const_var(2) }, + { be_const_key_weak(CLUSTERS, 14), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(8, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(8, 7), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(2), + be_const_int(3), + be_const_int(15), + be_const_int(17), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(29, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(3, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(5, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(768, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(7), + be_const_int(8), + be_const_int(15), + be_const_int(16394), + be_const_int(16395), + be_const_int(16396), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(268, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(web_value_ct, 8), be_const_closure(Matter_Plugin_Bridge_Light2_web_value_ct_closure) }, + { be_const_key_weak(set_ct, -1), be_const_closure(Matter_Plugin_Bridge_Light2_set_ct_closure) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Light_X202_X20CT) }, + { be_const_key_weak(shadow_ct, -1), be_const_var(0) }, + { be_const_key_weak(update_ct_minmax, -1), be_const_closure(Matter_Plugin_Bridge_Light2_update_ct_minmax_closure) }, + { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Bridge_Light2_invoke_request_closure) }, + { be_const_key_weak(read_attribute, 10), be_const_closure(Matter_Plugin_Bridge_Light2_read_attribute_closure) }, + { be_const_key_weak(ct_min, -1), be_const_var(1) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(http_light2) }, + })), + be_str_weak(Matter_Plugin_Bridge_Light2) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_Light2_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_Light2); + be_setglobal(vm, "Matter_Plugin_Bridge_Light2"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_5_Bridge_Light3.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_5_Bridge_Light3.h new file mode 100644 index 000000000000..18cd5c467898 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_5_Bridge_Light3.h @@ -0,0 +1,829 @@ +/* Solidification of Matter_Plugin_5_Bridge_Light3.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Bridge_Light3; + +/******************************************************************** +** Solidified function: set_sat +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light3_set_sat, /* name */ + be_nested_proto( + 9, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(scale_uint), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(call_remote_sync), + /* K4 */ be_nested_str_weak(HSBColor2), + /* K5 */ be_nested_str_weak(parse_update), + }), + be_str_weak(set_sat), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0xB80A0000, // 0000 GETNGBL R2 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x58140002, // 0003 LDCONST R5 K2 + 0x541A00FD, // 0004 LDINT R6 254 + 0x581C0002, // 0005 LDCONST R7 K2 + 0x54220063, // 0006 LDINT R8 100 + 0x7C080C00, // 0007 CALL R2 6 + 0x8C0C0103, // 0008 GETMET R3 R0 K3 + 0x58140004, // 0009 LDCONST R5 K4 + 0x5C180400, // 000A MOVE R6 R2 + 0x7C0C0600, // 000B CALL R3 3 + 0x4C100000, // 000C LDNIL R4 + 0x20100604, // 000D NE R4 R3 R4 + 0x78120003, // 000E JMPF R4 #0013 + 0x8C100105, // 000F GETMET R4 R0 K5 + 0x5C180600, // 0010 MOVE R6 R3 + 0x541E000A, // 0011 LDINT R7 11 + 0x7C100600, // 0012 CALL R4 3 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: parse_update +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light3_parse_update, /* name */ + be_nested_proto( + 15, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(parse_update), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(HSBColor), + /* K3 */ be_nested_str_weak(string), + /* K4 */ be_nested_str_weak(split), + /* K5 */ be_nested_str_weak(_X2C), + /* K6 */ be_const_int(0), + /* K7 */ be_const_int(1), + /* K8 */ be_nested_str_weak(tasmota), + /* K9 */ be_nested_str_weak(scale_uint), + /* K10 */ be_nested_str_weak(shadow_hue), + /* K11 */ be_nested_str_weak(shadow_sat), + /* K12 */ be_nested_str_weak(attribute_updated), + }), + be_str_weak(parse_update), + &be_const_str_solidified, + ( &(const binstruction[70]) { /* code */ + 0x600C0003, // 0000 GETGBL R3 G3 + 0x5C100000, // 0001 MOVE R4 R0 + 0x7C0C0200, // 0002 CALL R3 1 + 0x8C0C0700, // 0003 GETMET R3 R3 K0 + 0x5C140200, // 0004 MOVE R5 R1 + 0x5C180400, // 0005 MOVE R6 R2 + 0x7C0C0600, // 0006 CALL R3 3 + 0x540E000A, // 0007 LDINT R3 11 + 0x1C0C0403, // 0008 EQ R3 R2 R3 + 0x780E003A, // 0009 JMPF R3 #0045 + 0x8C0C0301, // 000A GETMET R3 R1 K1 + 0x58140002, // 000B LDCONST R5 K2 + 0x7C0C0400, // 000C CALL R3 2 + 0x780E0036, // 000D JMPF R3 #0045 + 0xA4120600, // 000E IMPORT R4 K3 + 0x8C140904, // 000F GETMET R5 R4 K4 + 0x5C1C0600, // 0010 MOVE R7 R3 + 0x58200005, // 0011 LDCONST R8 K5 + 0x7C140600, // 0012 CALL R5 3 + 0x60180009, // 0013 GETGBL R6 G9 + 0x941C0B06, // 0014 GETIDX R7 R5 K6 + 0x7C180200, // 0015 CALL R6 1 + 0x601C0009, // 0016 GETGBL R7 G9 + 0x94200B07, // 0017 GETIDX R8 R5 K7 + 0x7C1C0200, // 0018 CALL R7 1 + 0x4C200000, // 0019 LDNIL R8 + 0x20200C08, // 001A NE R8 R6 R8 + 0x78220009, // 001B JMPF R8 #0026 + 0xB8221000, // 001C GETNGBL R8 K8 + 0x8C201109, // 001D GETMET R8 R8 K9 + 0x5C280C00, // 001E MOVE R10 R6 + 0x582C0006, // 001F LDCONST R11 K6 + 0x54320167, // 0020 LDINT R12 360 + 0x58340006, // 0021 LDCONST R13 K6 + 0x543A00FD, // 0022 LDINT R14 254 + 0x7C200C00, // 0023 CALL R8 6 + 0x5C181000, // 0024 MOVE R6 R8 + 0x70020000, // 0025 JMP #0027 + 0x8818010A, // 0026 GETMBR R6 R0 K10 + 0x4C200000, // 0027 LDNIL R8 + 0x20200E08, // 0028 NE R8 R7 R8 + 0x78220009, // 0029 JMPF R8 #0034 + 0xB8221000, // 002A GETNGBL R8 K8 + 0x8C201109, // 002B GETMET R8 R8 K9 + 0x5C280E00, // 002C MOVE R10 R7 + 0x582C0006, // 002D LDCONST R11 K6 + 0x54320063, // 002E LDINT R12 100 + 0x58340006, // 002F LDCONST R13 K6 + 0x543A00FD, // 0030 LDINT R14 254 + 0x7C200C00, // 0031 CALL R8 6 + 0x5C1C1000, // 0032 MOVE R7 R8 + 0x70020000, // 0033 JMP #0035 + 0x881C010B, // 0034 GETMBR R7 R0 K11 + 0x8820010A, // 0035 GETMBR R8 R0 K10 + 0x20200C08, // 0036 NE R8 R6 R8 + 0x78220004, // 0037 JMPF R8 #003D + 0x8C20010C, // 0038 GETMET R8 R0 K12 + 0x542A02FF, // 0039 LDINT R10 768 + 0x582C0006, // 003A LDCONST R11 K6 + 0x7C200600, // 003B CALL R8 3 + 0x90021406, // 003C SETMBR R0 K10 R6 + 0x8820010B, // 003D GETMBR R8 R0 K11 + 0x20200E08, // 003E NE R8 R7 R8 + 0x78220004, // 003F JMPF R8 #0045 + 0x8C20010C, // 0040 GETMET R8 R0 K12 + 0x542A02FF, // 0041 LDINT R10 768 + 0x582C0007, // 0042 LDCONST R11 K7 + 0x7C200600, // 0043 CALL R8 3 + 0x90021607, // 0044 SETMBR R0 K11 R7 + 0x80000000, // 0045 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_values +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light3_web_values, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(web_values_prefix), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(_X25s_X20_X25s_X20_X25s), + /* K4 */ be_nested_str_weak(web_value_onoff), + /* K5 */ be_nested_str_weak(shadow_onoff), + /* K6 */ be_nested_str_weak(web_value_dimmer), + /* K7 */ be_nested_str_weak(web_value_RGB), + }), + be_str_weak(web_values), + &be_const_str_solidified, + ( &(const binstruction[16]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x60100018, // 0004 GETGBL R4 G24 + 0x58140003, // 0005 LDCONST R5 K3 + 0x8C180104, // 0006 GETMET R6 R0 K4 + 0x88200105, // 0007 GETMBR R8 R0 K5 + 0x7C180400, // 0008 CALL R6 2 + 0x8C1C0106, // 0009 GETMET R7 R0 K6 + 0x7C1C0200, // 000A CALL R7 1 + 0x8C200107, // 000B GETMET R8 R0 K7 + 0x7C200200, // 000C CALL R8 1 + 0x7C100800, // 000D CALL R4 4 + 0x7C080400, // 000E CALL R2 2 + 0x80000000, // 000F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_value_RGB +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light3_web_value_RGB, /* name */ + be_nested_proto( + 12, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[15]) { /* constants */ + /* K0 */ be_nested_str_weak(shadow_hue), + /* K1 */ be_nested_str_weak(shadow_sat), + /* K2 */ be_nested_str_weak(light_state), + /* K3 */ be_const_int(3), + /* K4 */ be_nested_str_weak(set_bri), + /* K5 */ be_nested_str_weak(set_huesat), + /* K6 */ be_nested_str_weak(tasmota), + /* K7 */ be_nested_str_weak(scale_uint), + /* K8 */ be_const_int(0), + /* K9 */ be_nested_str_weak(_X23_X2502X_X2502X_X2502X), + /* K10 */ be_nested_str_weak(r), + /* K11 */ be_nested_str_weak(g), + /* K12 */ be_nested_str_weak(b), + /* K13 */ be_nested_str_weak(_X3Ci_X20class_X3D_X22bxm_X22_X20style_X3D_X22_X2D_X2Dcl_X3A_X25s_X22_X3E_X3C_X2Fi_X3E_X25s), + /* K14 */ be_nested_str_weak(), + }), + be_str_weak(web_value_RGB), + &be_const_str_solidified, + ( &(const binstruction[45]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x20040202, // 0002 NE R1 R1 R2 + 0x78060027, // 0003 JMPF R1 #002C + 0x88040101, // 0004 GETMBR R1 R0 K1 + 0x4C080000, // 0005 LDNIL R2 + 0x20040202, // 0006 NE R1 R1 R2 + 0x78060023, // 0007 JMPF R1 #002C + 0xB8060400, // 0008 GETNGBL R1 K2 + 0x58080003, // 0009 LDCONST R2 K3 + 0x7C040200, // 000A CALL R1 1 + 0x8C080304, // 000B GETMET R2 R1 K4 + 0x541200FE, // 000C LDINT R4 255 + 0x7C080400, // 000D CALL R2 2 + 0x8C080305, // 000E GETMET R2 R1 K5 + 0xB8120C00, // 000F GETNGBL R4 K6 + 0x8C100907, // 0010 GETMET R4 R4 K7 + 0x88180100, // 0011 GETMBR R6 R0 K0 + 0x581C0008, // 0012 LDCONST R7 K8 + 0x542200FD, // 0013 LDINT R8 254 + 0x58240008, // 0014 LDCONST R9 K8 + 0x542A0167, // 0015 LDINT R10 360 + 0x7C100C00, // 0016 CALL R4 6 + 0xB8160C00, // 0017 GETNGBL R5 K6 + 0x8C140B07, // 0018 GETMET R5 R5 K7 + 0x881C0101, // 0019 GETMBR R7 R0 K1 + 0x58200008, // 001A LDCONST R8 K8 + 0x542600FD, // 001B LDINT R9 254 + 0x58280008, // 001C LDCONST R10 K8 + 0x542E00FE, // 001D LDINT R11 255 + 0x7C140C00, // 001E CALL R5 6 + 0x7C080600, // 001F CALL R2 3 + 0x60080018, // 0020 GETGBL R2 G24 + 0x580C0009, // 0021 LDCONST R3 K9 + 0x8810030A, // 0022 GETMBR R4 R1 K10 + 0x8814030B, // 0023 GETMBR R5 R1 K11 + 0x8818030C, // 0024 GETMBR R6 R1 K12 + 0x7C080800, // 0025 CALL R2 4 + 0x600C0018, // 0026 GETGBL R3 G24 + 0x5810000D, // 0027 LDCONST R4 K13 + 0x5C140400, // 0028 MOVE R5 R2 + 0x5C180400, // 0029 MOVE R6 R2 + 0x7C0C0600, // 002A CALL R3 3 + 0x80040600, // 002B RET 1 R3 + 0x80061C00, // 002C RET 1 K14 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read_attribute +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light3_read_attribute, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(attribute), + /* K4 */ be_nested_str_weak(update_shadow_lazy), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(shadow_hue), + /* K7 */ be_nested_str_weak(set), + /* K8 */ be_nested_str_weak(U1), + /* K9 */ be_nested_str_weak(NULL), + /* K10 */ be_const_int(1), + /* K11 */ be_nested_str_weak(shadow_sat), + /* K12 */ be_nested_str_weak(U4), + /* K13 */ be_nested_str_weak(read_attribute), + }), + be_str_weak(read_attribute), + &be_const_str_solidified, + ( &(const binstruction[127]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140502, // 0002 GETMBR R5 R2 K2 + 0x88180503, // 0003 GETMBR R6 R2 K3 + 0x541E02FF, // 0004 LDINT R7 768 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E006D, // 0006 JMPF R7 #0075 + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x1C1C0D05, // 0009 EQ R7 R6 K5 + 0x781E000F, // 000A JMPF R7 #001B + 0x881C0106, // 000B GETMBR R7 R0 K6 + 0x4C200000, // 000C LDNIL R8 + 0x201C0E08, // 000D NE R7 R7 R8 + 0x781E0005, // 000E JMPF R7 #0015 + 0x8C1C0707, // 000F GETMET R7 R3 K7 + 0x88240908, // 0010 GETMBR R9 R4 K8 + 0x88280106, // 0011 GETMBR R10 R0 K6 + 0x7C1C0600, // 0012 CALL R7 3 + 0x80040E00, // 0013 RET 1 R7 + 0x70020004, // 0014 JMP #001A + 0x8C1C0707, // 0015 GETMET R7 R3 K7 + 0x88240909, // 0016 GETMBR R9 R4 K9 + 0x4C280000, // 0017 LDNIL R10 + 0x7C1C0600, // 0018 CALL R7 3 + 0x80040E00, // 0019 RET 1 R7 + 0x70020058, // 001A JMP #0074 + 0x1C1C0D0A, // 001B EQ R7 R6 K10 + 0x781E000F, // 001C JMPF R7 #002D + 0x881C010B, // 001D GETMBR R7 R0 K11 + 0x4C200000, // 001E LDNIL R8 + 0x201C0E08, // 001F NE R7 R7 R8 + 0x781E0005, // 0020 JMPF R7 #0027 + 0x8C1C0707, // 0021 GETMET R7 R3 K7 + 0x88240908, // 0022 GETMBR R9 R4 K8 + 0x8828010B, // 0023 GETMBR R10 R0 K11 + 0x7C1C0600, // 0024 CALL R7 3 + 0x80040E00, // 0025 RET 1 R7 + 0x70020004, // 0026 JMP #002C + 0x8C1C0707, // 0027 GETMET R7 R3 K7 + 0x88240909, // 0028 GETMBR R9 R4 K9 + 0x4C280000, // 0029 LDNIL R10 + 0x7C1C0600, // 002A CALL R7 3 + 0x80040E00, // 002B RET 1 R7 + 0x70020046, // 002C JMP #0074 + 0x541E0006, // 002D LDINT R7 7 + 0x1C1C0C07, // 002E EQ R7 R6 R7 + 0x781E0005, // 002F JMPF R7 #0036 + 0x8C1C0707, // 0030 GETMET R7 R3 K7 + 0x88240908, // 0031 GETMBR R9 R4 K8 + 0x58280005, // 0032 LDCONST R10 K5 + 0x7C1C0600, // 0033 CALL R7 3 + 0x80040E00, // 0034 RET 1 R7 + 0x7002003D, // 0035 JMP #0074 + 0x541E0007, // 0036 LDINT R7 8 + 0x1C1C0C07, // 0037 EQ R7 R6 R7 + 0x781E0005, // 0038 JMPF R7 #003F + 0x8C1C0707, // 0039 GETMET R7 R3 K7 + 0x88240908, // 003A GETMBR R9 R4 K8 + 0x58280005, // 003B LDCONST R10 K5 + 0x7C1C0600, // 003C CALL R7 3 + 0x80040E00, // 003D RET 1 R7 + 0x70020034, // 003E JMP #0074 + 0x541E000E, // 003F LDINT R7 15 + 0x1C1C0C07, // 0040 EQ R7 R6 R7 + 0x781E0005, // 0041 JMPF R7 #0048 + 0x8C1C0707, // 0042 GETMET R7 R3 K7 + 0x88240908, // 0043 GETMBR R9 R4 K8 + 0x58280005, // 0044 LDCONST R10 K5 + 0x7C1C0600, // 0045 CALL R7 3 + 0x80040E00, // 0046 RET 1 R7 + 0x7002002B, // 0047 JMP #0074 + 0x541E4000, // 0048 LDINT R7 16385 + 0x1C1C0C07, // 0049 EQ R7 R6 R7 + 0x781E0005, // 004A JMPF R7 #0051 + 0x8C1C0707, // 004B GETMET R7 R3 K7 + 0x88240908, // 004C GETMBR R9 R4 K8 + 0x58280005, // 004D LDCONST R10 K5 + 0x7C1C0600, // 004E CALL R7 3 + 0x80040E00, // 004F RET 1 R7 + 0x70020022, // 0050 JMP #0074 + 0x541E4009, // 0051 LDINT R7 16394 + 0x1C1C0C07, // 0052 EQ R7 R6 R7 + 0x781E0005, // 0053 JMPF R7 #005A + 0x8C1C0707, // 0054 GETMET R7 R3 K7 + 0x8824090C, // 0055 GETMBR R9 R4 K12 + 0x5828000A, // 0056 LDCONST R10 K10 + 0x7C1C0600, // 0057 CALL R7 3 + 0x80040E00, // 0058 RET 1 R7 + 0x70020019, // 0059 JMP #0074 + 0x541E000F, // 005A LDINT R7 16 + 0x1C1C0C07, // 005B EQ R7 R6 R7 + 0x781E0005, // 005C JMPF R7 #0063 + 0x8C1C0707, // 005D GETMET R7 R3 K7 + 0x88240908, // 005E GETMBR R9 R4 K8 + 0x58280005, // 005F LDCONST R10 K5 + 0x7C1C0600, // 0060 CALL R7 3 + 0x80040E00, // 0061 RET 1 R7 + 0x70020010, // 0062 JMP #0074 + 0x541EFFFB, // 0063 LDINT R7 65532 + 0x1C1C0C07, // 0064 EQ R7 R6 R7 + 0x781E0005, // 0065 JMPF R7 #006C + 0x8C1C0707, // 0066 GETMET R7 R3 K7 + 0x8824090C, // 0067 GETMBR R9 R4 K12 + 0x5828000A, // 0068 LDCONST R10 K10 + 0x7C1C0600, // 0069 CALL R7 3 + 0x80040E00, // 006A RET 1 R7 + 0x70020007, // 006B JMP #0074 + 0x541EFFFC, // 006C LDINT R7 65533 + 0x1C1C0C07, // 006D EQ R7 R6 R7 + 0x781E0004, // 006E JMPF R7 #0074 + 0x8C1C0707, // 006F GETMET R7 R3 K7 + 0x8824090C, // 0070 GETMBR R9 R4 K12 + 0x542A0004, // 0071 LDINT R10 5 + 0x7C1C0600, // 0072 CALL R7 3 + 0x80040E00, // 0073 RET 1 R7 + 0x70020008, // 0074 JMP #007E + 0x601C0003, // 0075 GETGBL R7 G3 + 0x5C200000, // 0076 MOVE R8 R0 + 0x7C1C0200, // 0077 CALL R7 1 + 0x8C1C0F0D, // 0078 GETMET R7 R7 K13 + 0x5C240200, // 0079 MOVE R9 R1 + 0x5C280400, // 007A MOVE R10 R2 + 0x5C2C0600, // 007B MOVE R11 R3 + 0x7C1C0800, // 007C CALL R7 4 + 0x80040E00, // 007D RET 1 R7 + 0x80000000, // 007E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: invoke_request +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light3_invoke_request, /* name */ + be_nested_proto( + 15, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[19]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(cluster), + /* K3 */ be_nested_str_weak(command), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str_weak(findsubval), + /* K6 */ be_nested_str_weak(set_hue), + /* K7 */ be_nested_str_weak(log), + /* K8 */ be_nested_str_weak(hue_X3A), + /* K9 */ be_nested_str_weak(publish_command), + /* K10 */ be_nested_str_weak(Hue), + /* K11 */ be_const_int(1), + /* K12 */ be_const_int(2), + /* K13 */ be_const_int(3), + /* K14 */ be_nested_str_weak(set_sat), + /* K15 */ be_nested_str_weak(sat_X3A), + /* K16 */ be_nested_str_weak(Sat), + /* K17 */ be_nested_str_weak(_X20sat_X3A), + /* K18 */ be_nested_str_weak(invoke_request), + }), + be_str_weak(invoke_request), + &be_const_str_solidified, + ( &(const binstruction[119]) { /* code */ + 0xB8120000, // 0000 GETNGBL R4 K0 + 0x88100901, // 0001 GETMBR R4 R4 K1 + 0x88140702, // 0002 GETMBR R5 R3 K2 + 0x88180703, // 0003 GETMBR R6 R3 K3 + 0x541E02FF, // 0004 LDINT R7 768 + 0x1C1C0A07, // 0005 EQ R7 R5 R7 + 0x781E0065, // 0006 JMPF R7 #006D + 0x1C1C0D04, // 0007 EQ R7 R6 K4 + 0x781E0011, // 0008 JMPF R7 #001B + 0x8C1C0505, // 0009 GETMET R7 R2 K5 + 0x58240004, // 000A LDCONST R9 K4 + 0x7C1C0400, // 000B CALL R7 2 + 0x8C200106, // 000C GETMET R8 R0 K6 + 0x5C280E00, // 000D MOVE R10 R7 + 0x7C200400, // 000E CALL R8 2 + 0x60200008, // 000F GETGBL R8 G8 + 0x5C240E00, // 0010 MOVE R9 R7 + 0x7C200200, // 0011 CALL R8 1 + 0x00221008, // 0012 ADD R8 K8 R8 + 0x900E0E08, // 0013 SETMBR R3 K7 R8 + 0x8C200109, // 0014 GETMET R8 R0 K9 + 0x5828000A, // 0015 LDCONST R10 K10 + 0x5C2C0E00, // 0016 MOVE R11 R7 + 0x7C200600, // 0017 CALL R8 3 + 0x50200200, // 0018 LDBOOL R8 1 0 + 0x80041000, // 0019 RET 1 R8 + 0x70020050, // 001A JMP #006C + 0x1C1C0D0B, // 001B EQ R7 R6 K11 + 0x781E0002, // 001C JMPF R7 #0020 + 0x501C0200, // 001D LDBOOL R7 1 0 + 0x80040E00, // 001E RET 1 R7 + 0x7002004B, // 001F JMP #006C + 0x1C1C0D0C, // 0020 EQ R7 R6 K12 + 0x781E0002, // 0021 JMPF R7 #0025 + 0x501C0200, // 0022 LDBOOL R7 1 0 + 0x80040E00, // 0023 RET 1 R7 + 0x70020046, // 0024 JMP #006C + 0x1C1C0D0D, // 0025 EQ R7 R6 K13 + 0x781E0011, // 0026 JMPF R7 #0039 + 0x8C1C0505, // 0027 GETMET R7 R2 K5 + 0x58240004, // 0028 LDCONST R9 K4 + 0x7C1C0400, // 0029 CALL R7 2 + 0x8C20010E, // 002A GETMET R8 R0 K14 + 0x5C280E00, // 002B MOVE R10 R7 + 0x7C200400, // 002C CALL R8 2 + 0x60200008, // 002D GETGBL R8 G8 + 0x5C240E00, // 002E MOVE R9 R7 + 0x7C200200, // 002F CALL R8 1 + 0x00221E08, // 0030 ADD R8 K15 R8 + 0x900E0E08, // 0031 SETMBR R3 K7 R8 + 0x8C200109, // 0032 GETMET R8 R0 K9 + 0x58280010, // 0033 LDCONST R10 K16 + 0x5C2C0E00, // 0034 MOVE R11 R7 + 0x7C200600, // 0035 CALL R8 3 + 0x50200200, // 0036 LDBOOL R8 1 0 + 0x80041000, // 0037 RET 1 R8 + 0x70020032, // 0038 JMP #006C + 0x541E0003, // 0039 LDINT R7 4 + 0x1C1C0C07, // 003A EQ R7 R6 R7 + 0x781E0002, // 003B JMPF R7 #003F + 0x501C0200, // 003C LDBOOL R7 1 0 + 0x80040E00, // 003D RET 1 R7 + 0x7002002C, // 003E JMP #006C + 0x541E0004, // 003F LDINT R7 5 + 0x1C1C0C07, // 0040 EQ R7 R6 R7 + 0x781E0002, // 0041 JMPF R7 #0045 + 0x501C0200, // 0042 LDBOOL R7 1 0 + 0x80040E00, // 0043 RET 1 R7 + 0x70020026, // 0044 JMP #006C + 0x541E0005, // 0045 LDINT R7 6 + 0x1C1C0C07, // 0046 EQ R7 R6 R7 + 0x781E001E, // 0047 JMPF R7 #0067 + 0x8C1C0505, // 0048 GETMET R7 R2 K5 + 0x58240004, // 0049 LDCONST R9 K4 + 0x7C1C0400, // 004A CALL R7 2 + 0x8C200505, // 004B GETMET R8 R2 K5 + 0x5828000B, // 004C LDCONST R10 K11 + 0x7C200400, // 004D CALL R8 2 + 0x8C240106, // 004E GETMET R9 R0 K6 + 0x5C2C0E00, // 004F MOVE R11 R7 + 0x7C240400, // 0050 CALL R9 2 + 0x8C24010E, // 0051 GETMET R9 R0 K14 + 0x5C2C1000, // 0052 MOVE R11 R8 + 0x7C240400, // 0053 CALL R9 2 + 0x60240008, // 0054 GETGBL R9 G8 + 0x5C280E00, // 0055 MOVE R10 R7 + 0x7C240200, // 0056 CALL R9 1 + 0x00261009, // 0057 ADD R9 K8 R9 + 0x00241311, // 0058 ADD R9 R9 K17 + 0x60280008, // 0059 GETGBL R10 G8 + 0x5C2C1000, // 005A MOVE R11 R8 + 0x7C280200, // 005B CALL R10 1 + 0x0024120A, // 005C ADD R9 R9 R10 + 0x900E0E09, // 005D SETMBR R3 K7 R9 + 0x8C240109, // 005E GETMET R9 R0 K9 + 0x582C000A, // 005F LDCONST R11 K10 + 0x5C300E00, // 0060 MOVE R12 R7 + 0x58340010, // 0061 LDCONST R13 K16 + 0x5C381000, // 0062 MOVE R14 R8 + 0x7C240A00, // 0063 CALL R9 5 + 0x50240200, // 0064 LDBOOL R9 1 0 + 0x80041200, // 0065 RET 1 R9 + 0x70020004, // 0066 JMP #006C + 0x541E0046, // 0067 LDINT R7 71 + 0x1C1C0C07, // 0068 EQ R7 R6 R7 + 0x781E0001, // 0069 JMPF R7 #006C + 0x501C0200, // 006A LDBOOL R7 1 0 + 0x80040E00, // 006B RET 1 R7 + 0x70020008, // 006C JMP #0076 + 0x601C0003, // 006D GETGBL R7 G3 + 0x5C200000, // 006E MOVE R8 R0 + 0x7C1C0200, // 006F CALL R7 1 + 0x8C1C0F12, // 0070 GETMET R7 R7 K18 + 0x5C240200, // 0071 MOVE R9 R1 + 0x5C280400, // 0072 MOVE R10 R2 + 0x5C2C0600, // 0073 MOVE R11 R3 + 0x7C1C0800, // 0074 CALL R7 4 + 0x80040E00, // 0075 RET 1 R7 + 0x80000000, // 0076 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_hue +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light3_set_hue, /* name */ + be_nested_proto( + 9, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(scale_uint), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(call_remote_sync), + /* K4 */ be_nested_str_weak(HSBColor1), + /* K5 */ be_nested_str_weak(parse_update), + }), + be_str_weak(set_hue), + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0xB80A0000, // 0000 GETNGBL R2 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x58140002, // 0003 LDCONST R5 K2 + 0x541A00FD, // 0004 LDINT R6 254 + 0x581C0002, // 0005 LDCONST R7 K2 + 0x54220167, // 0006 LDINT R8 360 + 0x7C080C00, // 0007 CALL R2 6 + 0x8C0C0103, // 0008 GETMET R3 R0 K3 + 0x58140004, // 0009 LDCONST R5 K4 + 0x5C180400, // 000A MOVE R6 R2 + 0x7C0C0600, // 000B CALL R3 3 + 0x4C100000, // 000C LDNIL R4 + 0x20100604, // 000D NE R4 R3 R4 + 0x78120003, // 000E JMPF R4 #0013 + 0x8C100105, // 000F GETMET R4 R0 K5 + 0x5C180600, // 0010 MOVE R6 R3 + 0x541E000A, // 0011 LDINT R7 11 + 0x7C100600, // 0012 CALL R4 3 + 0x80000000, // 0013 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Plugin_Bridge_Light3_init, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x60100003, // 0000 GETGBL R4 G3 + 0x5C140000, // 0001 MOVE R5 R0 + 0x7C100200, // 0002 CALL R4 1 + 0x8C100900, // 0003 GETMET R4 R4 K0 + 0x5C180200, // 0004 MOVE R6 R1 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x5C200600, // 0006 MOVE R8 R3 + 0x7C100800, // 0007 CALL R4 4 + 0x80000000, // 0008 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Plugin_Bridge_Light3 +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Bridge_Light1; +be_local_class(Matter_Plugin_Bridge_Light3, + 2, + &be_class_Matter_Plugin_Bridge_Light1, + be_nested_map(14, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(set_sat, 6), be_const_closure(Matter_Plugin_Bridge_Light3_set_sat_closure) }, + { be_const_key_weak(init, 8), be_const_closure(Matter_Plugin_Bridge_Light3_init_closure) }, + { be_const_key_weak(parse_update, -1), be_const_closure(Matter_Plugin_Bridge_Light3_parse_update_closure) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(http_light3) }, + { be_const_key_weak(web_values, -1), be_const_closure(Matter_Plugin_Bridge_Light3_web_values_closure) }, + { be_const_key_weak(web_value_RGB, 1), be_const_closure(Matter_Plugin_Bridge_Light3_web_value_RGB_closure) }, + { be_const_key_weak(CLUSTERS, 13), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(8, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(8, 7), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(2), + be_const_int(3), + be_const_int(15), + be_const_int(17), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(7, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(17), + be_const_int(3), + be_const_int(5), + be_const_int(10), + be_const_int(15), + be_const_int(17), + be_const_int(18), + })) ) } )) }, + { be_const_key_int(29, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(6, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(3, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(5, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(8, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(2), + be_const_int(3), + be_const_int(4), + be_const_int(5), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(3, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + { be_const_key_int(768, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(9, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(0), + be_const_int(1), + be_const_int(7), + be_const_int(8), + be_const_int(15), + be_const_int(16385), + be_const_int(16394), + be_const_int(65532), + be_const_int(65533), + })) ) } )) }, + })) ) } )) }, + { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Bridge_Light3_invoke_request_closure) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(Light_X203_X20RGB) }, + { be_const_key_weak(set_hue, 11), be_const_closure(Matter_Plugin_Bridge_Light3_set_hue_closure) }, + { be_const_key_weak(shadow_hue, 9), be_const_var(0) }, + { be_const_key_weak(TYPES, 12), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(1, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_int(269, -1), be_const_int(2) }, + })) ) } )) }, + { be_const_key_weak(shadow_sat, -1), be_const_var(1) }, + { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Bridge_Light3_read_attribute_closure) }, + })), + be_str_weak(Matter_Plugin_Bridge_Light3) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Bridge_Light3_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_Light3); + be_setglobal(vm, "Matter_Plugin_Bridge_Light3"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Light0.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Light0.h new file mode 100644 index 000000000000..2d946c844daf --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Light0.h @@ -0,0 +1,34 @@ +/* Solidification of Matter_Plugin_9_Virt_Light0.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Virt_Light0; + +/******************************************************************** +** Solidified class: Matter_Plugin_Virt_Light0 +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Light0; +be_local_class(Matter_Plugin_Virt_Light0, + 0, + &be_class_Matter_Plugin_Light0, + be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(VIRTUAL, 3), be_const_bool(1) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(v_X2ELight_X200_X20On) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(v_light0) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(_Not_X20used_) }, + { be_const_key_weak(ARG, 2), be_nested_str_weak() }, + })), + be_str_weak(Matter_Plugin_Virt_Light0) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Virt_Light0_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Virt_Light0); + be_setglobal(vm, "Matter_Plugin_Virt_Light0"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Light1.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Light1.h new file mode 100644 index 000000000000..123fc3e511e7 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Light1.h @@ -0,0 +1,34 @@ +/* Solidification of Matter_Plugin_9_Virt_Light1.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Virt_Light1; + +/******************************************************************** +** Solidified class: Matter_Plugin_Virt_Light1 +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Light1; +be_local_class(Matter_Plugin_Virt_Light1, + 0, + &be_class_Matter_Plugin_Light1, + be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(VIRTUAL, 3), be_const_bool(1) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(v_X2ELight_X201_X20Dimmer) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(v_light1) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(_Not_X20used_) }, + { be_const_key_weak(ARG, 2), be_nested_str_weak() }, + })), + be_str_weak(Matter_Plugin_Virt_Light1) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Virt_Light1_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Virt_Light1); + be_setglobal(vm, "Matter_Plugin_Virt_Light1"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Light2.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Light2.h new file mode 100644 index 000000000000..c81c9044daf8 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Light2.h @@ -0,0 +1,34 @@ +/* Solidification of Matter_Plugin_9_Virt_Light2.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Virt_Light2; + +/******************************************************************** +** Solidified class: Matter_Plugin_Virt_Light2 +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Light2; +be_local_class(Matter_Plugin_Virt_Light2, + 0, + &be_class_Matter_Plugin_Light2, + be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(VIRTUAL, 3), be_const_bool(1) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(v_X2ELight_X202_X20CT) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(v_light2) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(_Not_X20used_) }, + { be_const_key_weak(ARG, 2), be_nested_str_weak() }, + })), + be_str_weak(Matter_Plugin_Virt_Light2) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Virt_Light2_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Virt_Light2); + be_setglobal(vm, "Matter_Plugin_Virt_Light2"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Light3.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Light3.h new file mode 100644 index 000000000000..d90363be70f1 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Light3.h @@ -0,0 +1,34 @@ +/* Solidification of Matter_Plugin_9_Virt_Light3.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Virt_Light3; + +/******************************************************************** +** Solidified class: Matter_Plugin_Virt_Light3 +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Light3; +be_local_class(Matter_Plugin_Virt_Light3, + 0, + &be_class_Matter_Plugin_Light3, + be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(VIRTUAL, 3), be_const_bool(1) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(v_X2ELight_X203_X20RGB) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(v_light3) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(_Not_X20used_) }, + { be_const_key_weak(ARG, 2), be_nested_str_weak() }, + })), + be_str_weak(Matter_Plugin_Virt_Light3) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Virt_Light3_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Virt_Light3); + be_setglobal(vm, "Matter_Plugin_Virt_Light3"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_OnOff.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_OnOff.h new file mode 100644 index 000000000000..ef9f3ac5ba55 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_OnOff.h @@ -0,0 +1,34 @@ +/* Solidification of Matter_Plugin_9_Virt_OnOff.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Virt_OnOff; + +/******************************************************************** +** Solidified class: Matter_Plugin_Virt_OnOff +********************************************************************/ +extern const bclass be_class_Matter_Plugin_OnOff; +be_local_class(Matter_Plugin_Virt_OnOff, + 0, + &be_class_Matter_Plugin_OnOff, + be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(VIRTUAL, 3), be_const_bool(1) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(v_X2ERelay) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(v_relay) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(_Not_X20used_) }, + { be_const_key_weak(ARG, 2), be_nested_str_weak() }, + })), + be_str_weak(Matter_Plugin_Virt_OnOff) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Virt_OnOff_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Virt_OnOff); + be_setglobal(vm, "Matter_Plugin_Virt_OnOff"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Contact.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Contact.h new file mode 100644 index 000000000000..a9a6b8aaf349 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Contact.h @@ -0,0 +1,34 @@ +/* Solidification of Matter_Plugin_9_Virt_Sensor_Contact.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Virt_Sensor_Contact; + +/******************************************************************** +** Solidified class: Matter_Plugin_Virt_Sensor_Contact +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Sensor_Contact; +be_local_class(Matter_Plugin_Virt_Sensor_Contact, + 0, + &be_class_Matter_Plugin_Sensor_Contact, + be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(VIRTUAL, 3), be_const_bool(1) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(v_X2EContact) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(v_contact) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(_Not_X20used_) }, + { be_const_key_weak(ARG, 2), be_nested_str_weak() }, + })), + be_str_weak(Matter_Plugin_Virt_Sensor_Contact) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Virt_Sensor_Contact_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Virt_Sensor_Contact); + be_setglobal(vm, "Matter_Plugin_Virt_Sensor_Contact"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Humidity.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Humidity.h new file mode 100644 index 000000000000..21b40f75f802 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Humidity.h @@ -0,0 +1,34 @@ +/* Solidification of Matter_Plugin_9_Virt_Sensor_Humidity.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Virt_Sensor_Humidity; + +/******************************************************************** +** Solidified class: Matter_Plugin_Virt_Sensor_Humidity +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Sensor_Humidity; +be_local_class(Matter_Plugin_Virt_Sensor_Humidity, + 0, + &be_class_Matter_Plugin_Sensor_Humidity, + be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(VIRTUAL, 3), be_const_bool(1) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(v_X2EHumidity) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(v_humidity) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(_Not_X20used_) }, + { be_const_key_weak(ARG, 2), be_nested_str_weak() }, + })), + be_str_weak(Matter_Plugin_Virt_Sensor_Humidity) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Virt_Sensor_Humidity_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Virt_Sensor_Humidity); + be_setglobal(vm, "Matter_Plugin_Virt_Sensor_Humidity"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Illuminance.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Illuminance.h new file mode 100644 index 000000000000..792d4324f49f --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Illuminance.h @@ -0,0 +1,34 @@ +/* Solidification of Matter_Plugin_9_Virt_Sensor_Illuminance.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Virt_Sensor_Illuminance; + +/******************************************************************** +** Solidified class: Matter_Plugin_Virt_Sensor_Illuminance +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Sensor_Illuminance; +be_local_class(Matter_Plugin_Virt_Sensor_Illuminance, + 0, + &be_class_Matter_Plugin_Sensor_Illuminance, + be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(VIRTUAL, 3), be_const_bool(1) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(v_X2EIlluminance) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(v_illuminance) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(_Not_X20used_) }, + { be_const_key_weak(ARG, 2), be_nested_str_weak() }, + })), + be_str_weak(Matter_Plugin_Virt_Sensor_Illuminance) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Virt_Sensor_Illuminance_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Virt_Sensor_Illuminance); + be_setglobal(vm, "Matter_Plugin_Virt_Sensor_Illuminance"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Pressure.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Pressure.h new file mode 100644 index 000000000000..db256979e9ca --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Pressure.h @@ -0,0 +1,34 @@ +/* Solidification of Matter_Plugin_9_Virt_Sensor_Pressure.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Virt_Sensor_Pressure; + +/******************************************************************** +** Solidified class: Matter_Plugin_Virt_Sensor_Pressure +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Sensor_Pressure; +be_local_class(Matter_Plugin_Virt_Sensor_Pressure, + 0, + &be_class_Matter_Plugin_Sensor_Pressure, + be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(VIRTUAL, 3), be_const_bool(1) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(v_X2EPressure) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(v_pressure) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(_Not_X20used_) }, + { be_const_key_weak(ARG, 2), be_nested_str_weak() }, + })), + be_str_weak(Matter_Plugin_Virt_Sensor_Pressure) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Virt_Sensor_Pressure_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Virt_Sensor_Pressure); + be_setglobal(vm, "Matter_Plugin_Virt_Sensor_Pressure"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Temp.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Temp.h new file mode 100644 index 000000000000..3e678420d2ee --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_9_Virt_Sensor_Temp.h @@ -0,0 +1,34 @@ +/* Solidification of Matter_Plugin_9_Virt_Sensor_Temp.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Plugin_Virt_Sensor_Temp; + +/******************************************************************** +** Solidified class: Matter_Plugin_Virt_Sensor_Temp +********************************************************************/ +extern const bclass be_class_Matter_Plugin_Sensor_Temp; +be_local_class(Matter_Plugin_Virt_Sensor_Temp, + 0, + &be_class_Matter_Plugin_Sensor_Temp, + be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(VIRTUAL, 3), be_const_bool(1) }, + { be_const_key_weak(DISPLAY_NAME, -1), be_nested_str_weak(v_X2ETemperature) }, + { be_const_key_weak(TYPE, -1), be_nested_str_weak(v_temp) }, + { be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(_Not_X20used_) }, + { be_const_key_weak(ARG, 2), be_nested_str_weak() }, + })), + be_str_weak(Matter_Plugin_Virt_Sensor_Temp) +); +/*******************************************************************/ + +void be_load_Matter_Plugin_Virt_Sensor_Temp_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Plugin_Virt_Sensor_Temp); + be_setglobal(vm, "Matter_Plugin_Virt_Sensor_Temp"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Bridge_HTTP.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Bridge_HTTP.h deleted file mode 100644 index 1fd4d331ac2f..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Bridge_HTTP.h +++ /dev/null @@ -1,665 +0,0 @@ -/* Solidification of Matter_Plugin_Bridge_HTTP.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Bridge_HTTP; - -/******************************************************************** -** Solidified function: get_types -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_HTTP_get_types, /* name */ - be_nested_proto( - 5, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(TYPES), - /* K1 */ be_nested_str_weak(keys), - /* K2 */ be_nested_str_weak(stop_iteration), - /* K3 */ be_const_int(1), - }), - be_str_weak(get_types), - &be_const_str_solidified, - ( &(const binstruction[20]) { /* code */ - 0x60040013, // 0000 GETGBL R1 G19 - 0x7C040000, // 0001 CALL R1 0 - 0x60080010, // 0002 GETGBL R2 G16 - 0x880C0100, // 0003 GETMBR R3 R0 K0 - 0x8C0C0701, // 0004 GETMET R3 R3 K1 - 0x7C0C0200, // 0005 CALL R3 1 - 0x7C080200, // 0006 CALL R2 1 - 0xA8020005, // 0007 EXBLK 0 #000E - 0x5C0C0400, // 0008 MOVE R3 R2 - 0x7C0C0000, // 0009 CALL R3 0 - 0x88100100, // 000A GETMBR R4 R0 K0 - 0x94100803, // 000B GETIDX R4 R4 R3 - 0x98040604, // 000C SETIDX R1 R3 R4 - 0x7001FFF9, // 000D JMP #0008 - 0x58080002, // 000E LDCONST R2 K2 - 0xAC080200, // 000F CATCH R2 1 0 - 0xB0080000, // 0010 RAISE 2 R0 R0 - 0x540A0012, // 0011 LDINT R2 19 - 0x98040503, // 0012 SETIDX R1 R2 K3 - 0x80040200, // 0013 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: is_reachable -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_HTTP_is_reachable, /* name */ - be_nested_proto( - 5, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(device), - /* K1 */ be_nested_str_weak(tick), - /* K2 */ be_nested_str_weak(reachable_tick), - /* K3 */ be_nested_str_weak(call_remote), - /* K4 */ be_nested_str_weak(), - /* K5 */ be_nested_str_weak(reachable), - }), - be_str_weak(is_reachable), - &be_const_str_solidified, - ( &(const binstruction[14]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x88080102, // 0002 GETMBR R2 R0 K2 - 0x20040202, // 0003 NE R1 R1 R2 - 0x78060006, // 0004 JMPF R1 #000C - 0x8C040103, // 0005 GETMET R1 R0 K3 - 0x580C0004, // 0006 LDCONST R3 K4 - 0x58100004, // 0007 LDCONST R4 K4 - 0x7C040600, // 0008 CALL R1 3 - 0x4C080000, // 0009 LDNIL R2 - 0x20080202, // 000A NE R2 R1 R2 - 0x90020A02, // 000B SETMBR R0 K5 R2 - 0x88040105, // 000C GETMBR R1 R0 K5 - 0x80040200, // 000D RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_HTTP_read_attribute, /* name */ - be_nested_proto( - 10, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(matter), - /* K1 */ be_nested_str_weak(TLV), - /* K2 */ be_nested_str_weak(cluster), - /* K3 */ be_nested_str_weak(attribute), - /* K4 */ be_const_int(0), - /* K5 */ be_nested_str_weak(create_TLV), - /* K6 */ be_nested_str_weak(BOOL), - /* K7 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[28]) { /* code */ - 0xB80E0000, // 0000 GETNGBL R3 K0 - 0x880C0701, // 0001 GETMBR R3 R3 K1 - 0x88100502, // 0002 GETMBR R4 R2 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x541A0038, // 0004 LDINT R6 57 - 0x1C180806, // 0005 EQ R6 R4 R6 - 0x781A000B, // 0006 JMPF R6 #0013 - 0x1C180B04, // 0007 EQ R6 R5 K4 - 0x781A0000, // 0008 JMPF R6 #000A - 0x70020007, // 0009 JMP #0012 - 0x541A0010, // 000A LDINT R6 17 - 0x1C180A06, // 000B EQ R6 R5 R6 - 0x781A0004, // 000C JMPF R6 #0012 - 0x8C180705, // 000D GETMET R6 R3 K5 - 0x88200706, // 000E GETMBR R8 R3 K6 - 0x50240200, // 000F LDBOOL R9 1 0 - 0x7C180600, // 0010 CALL R6 3 - 0x80040C00, // 0011 RET 1 R6 - 0x70020007, // 0012 JMP #001B - 0x60180003, // 0013 GETGBL R6 G3 - 0x5C1C0000, // 0014 MOVE R7 R0 - 0x7C180200, // 0015 CALL R6 1 - 0x8C180D07, // 0016 GETMET R6 R6 K7 - 0x5C200200, // 0017 MOVE R8 R1 - 0x5C240400, // 0018 MOVE R9 R2 - 0x7C180600, // 0019 CALL R6 3 - 0x80040C00, // 001A RET 1 R6 - 0x80000000, // 001B RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_status_11 -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_HTTP_get_status_11, /* name */ - be_nested_proto( - 6, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(device), - /* K1 */ be_nested_str_weak(tick), - /* K2 */ be_nested_str_weak(tasmota_status_11), - /* K3 */ be_nested_str_weak(find), - /* K4 */ be_nested_str_weak(_tick), - /* K5 */ be_nested_str_weak(call_remote), - /* K6 */ be_nested_str_weak(Status), - /* K7 */ be_nested_str_weak(11), - }), - be_str_weak(get_status_11), - &be_const_str_solidified, - ( &(const binstruction[27]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x88080102, // 0002 GETMBR R2 R0 K2 - 0x4C0C0000, // 0003 LDNIL R3 - 0x1C080403, // 0004 EQ R2 R2 R3 - 0x740A0005, // 0005 JMPT R2 #000C - 0x88080102, // 0006 GETMBR R2 R0 K2 - 0x8C080503, // 0007 GETMET R2 R2 K3 - 0x58100004, // 0008 LDCONST R4 K4 - 0x7C080400, // 0009 CALL R2 2 - 0x20080401, // 000A NE R2 R2 R1 - 0x780A000B, // 000B JMPF R2 #0018 - 0x8C080105, // 000C GETMET R2 R0 K5 - 0x58100006, // 000D LDCONST R4 K6 - 0x58140007, // 000E LDCONST R5 K7 - 0x7C080600, // 000F CALL R2 3 - 0x780A0003, // 0010 JMPF R2 #0015 - 0x980A0801, // 0011 SETIDX R2 K4 R1 - 0x90020402, // 0012 SETMBR R0 K2 R2 - 0x80040400, // 0013 RET 1 R2 - 0x70020001, // 0014 JMP #0017 - 0x4C0C0000, // 0015 LDNIL R3 - 0x80040600, // 0016 RET 1 R3 - 0x70020001, // 0017 JMP #001A - 0x88080102, // 0018 GETMBR R2 R0 K2 - 0x80040400, // 0019 RET 1 R2 - 0x80000000, // 001A RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: ui_string_to_conf -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_HTTP_ui_string_to_conf, /* name */ - be_nested_proto( - 11, /* nstack */ - 3, /* argc */ - 4, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 9]) { /* constants */ - /* K0 */ be_const_class(be_class_Matter_Plugin_Bridge_HTTP), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(split), - /* K3 */ be_nested_str_weak(_X2C), - /* K4 */ be_const_int(3), - /* K5 */ be_nested_str_weak(ARG_HTTP), - /* K6 */ be_const_int(1), - /* K7 */ be_nested_str_weak(ui_string_to_conf), - /* K8 */ be_const_int(0), - }), - be_str_weak(ui_string_to_conf), - &be_const_str_solidified, - ( &(const binstruction[24]) { /* code */ - 0x580C0000, // 0000 LDCONST R3 K0 - 0xA4120200, // 0001 IMPORT R4 K1 - 0x8C140902, // 0002 GETMET R5 R4 K2 - 0x001C0503, // 0003 ADD R7 R2 K3 - 0x58200003, // 0004 LDCONST R8 K3 - 0x58240004, // 0005 LDCONST R9 K4 - 0x7C140800, // 0006 CALL R5 4 - 0x88180705, // 0007 GETMBR R6 R3 K5 - 0x941C0B06, // 0008 GETIDX R7 R5 K6 - 0x98040C07, // 0009 SETIDX R1 R6 R7 - 0x60180003, // 000A GETGBL R6 G3 - 0x5C1C0600, // 000B MOVE R7 R3 - 0x7C180200, // 000C CALL R6 1 - 0x8C180D07, // 000D GETMET R6 R6 K7 - 0x5C200000, // 000E MOVE R8 R0 - 0x5C240200, // 000F MOVE R9 R1 - 0x94280B08, // 0010 GETIDX R10 R5 K8 - 0x7C180800, // 0011 CALL R6 4 - 0x60180001, // 0012 GETGBL R6 G1 - 0x581C0007, // 0013 LDCONST R7 K7 - 0x5C200200, // 0014 MOVE R8 R1 - 0x5C240400, // 0015 MOVE R9 R2 - 0x7C180600, // 0016 CALL R6 3 - 0x80040200, // 0017 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: call_remote -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_HTTP_call_remote, /* name */ - be_nested_proto( - 14, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[31]) { /* constants */ - /* K0 */ be_nested_str_weak(tasmota_http), - /* K1 */ be_nested_str_weak(json), - /* K2 */ be_nested_str_weak(string), - /* K3 */ be_nested_str_weak(tasmota), - /* K4 */ be_nested_str_weak(wifi), - /* K5 */ be_nested_str_weak(up), - /* K6 */ be_nested_str_weak(eth), - /* K7 */ be_const_int(2), - /* K8 */ be_const_int(0), - /* K9 */ be_nested_str_weak(webclient), - /* K10 */ be_nested_str_weak(set_timeouts), - /* K11 */ be_nested_str_weak(set_follow_redirects), - /* K12 */ be_nested_str_weak(format), - /* K13 */ be_nested_str_weak(_X25scm_X3Fcmnd_X3D_X25s_X25_X2520_X25s), - /* K14 */ be_nested_str_weak(), - /* K15 */ be_nested_str_weak(log), - /* K16 */ be_nested_str_weak(MTR_X3A_X20HTTP_X20GET_X20), - /* K17 */ be_const_int(3), - /* K18 */ be_nested_str_weak(begin), - /* K19 */ be_nested_str_weak(GET), - /* K20 */ be_nested_str_weak(MTR_X3A_X20HTTP_X20GET_X20code_X3D), - /* K21 */ be_nested_str_weak(get_string), - /* K22 */ be_nested_str_weak(close), - /* K23 */ be_nested_str_weak(MTR_X3A_X20HTTP_X20GET_X20payload_X3D), - /* K24 */ be_nested_str_weak(load), - /* K25 */ be_nested_str_weak(reachable), - /* K26 */ be_nested_str_weak(reachable_tick), - /* K27 */ be_nested_str_weak(device), - /* K28 */ be_nested_str_weak(tick), - /* K29 */ be_const_int(1), - /* K30 */ be_nested_str_weak(MTR_X3A_X20HTTP_X20GET_X20retrying), - }), - be_str_weak(call_remote), - &be_const_str_solidified, - ( &(const binstruction[91]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x740E0001, // 0001 JMPT R3 #0004 - 0x4C0C0000, // 0002 LDNIL R3 - 0x80040600, // 0003 RET 1 R3 - 0xA40E0200, // 0004 IMPORT R3 K1 - 0xA4120400, // 0005 IMPORT R4 K2 - 0xB8160600, // 0006 GETNGBL R5 K3 - 0x8C140B04, // 0007 GETMET R5 R5 K4 - 0x7C140200, // 0008 CALL R5 1 - 0x94140B05, // 0009 GETIDX R5 R5 K5 - 0x74160006, // 000A JMPT R5 #0012 - 0xB8160600, // 000B GETNGBL R5 K3 - 0x8C140B06, // 000C GETMET R5 R5 K6 - 0x7C140200, // 000D CALL R5 1 - 0x94140B05, // 000E GETIDX R5 R5 K5 - 0x74160001, // 000F JMPT R5 #0012 - 0x4C140000, // 0010 LDNIL R5 - 0x80040A00, // 0011 RET 1 R5 - 0x58140007, // 0012 LDCONST R5 K7 - 0x24180B08, // 0013 GT R6 R5 K8 - 0x781A0041, // 0014 JMPF R6 #0057 - 0xB81A1200, // 0015 GETNGBL R6 K9 - 0x7C180000, // 0016 CALL R6 0 - 0x8C1C0D0A, // 0017 GETMET R7 R6 K10 - 0x542603E7, // 0018 LDINT R9 1000 - 0x542A03E7, // 0019 LDINT R10 1000 - 0x7C1C0600, // 001A CALL R7 3 - 0x8C1C0D0B, // 001B GETMET R7 R6 K11 - 0x50240000, // 001C LDBOOL R9 0 0 - 0x7C1C0400, // 001D CALL R7 2 - 0x8C1C090C, // 001E GETMET R7 R4 K12 - 0x5824000D, // 001F LDCONST R9 K13 - 0x88280100, // 0020 GETMBR R10 R0 K0 - 0x5C2C0200, // 0021 MOVE R11 R1 - 0x780A0001, // 0022 JMPF R2 #0025 - 0x5C300400, // 0023 MOVE R12 R2 - 0x70020000, // 0024 JMP #0026 - 0x5830000E, // 0025 LDCONST R12 K14 - 0x7C1C0A00, // 0026 CALL R7 5 - 0xB8220600, // 0027 GETNGBL R8 K3 - 0x8C20110F, // 0028 GETMET R8 R8 K15 - 0x002A2007, // 0029 ADD R10 K16 R7 - 0x582C0011, // 002A LDCONST R11 K17 - 0x7C200600, // 002B CALL R8 3 - 0x8C200D12, // 002C GETMET R8 R6 K18 - 0x5C280E00, // 002D MOVE R10 R7 - 0x7C200400, // 002E CALL R8 2 - 0x8C200D13, // 002F GETMET R8 R6 K19 - 0x7C200200, // 0030 CALL R8 1 - 0xB8260600, // 0031 GETNGBL R9 K3 - 0x8C24130F, // 0032 GETMET R9 R9 K15 - 0x602C0008, // 0033 GETGBL R11 G8 - 0x5C301000, // 0034 MOVE R12 R8 - 0x7C2C0200, // 0035 CALL R11 1 - 0x002E280B, // 0036 ADD R11 K20 R11 - 0x58300011, // 0037 LDCONST R12 K17 - 0x7C240600, // 0038 CALL R9 3 - 0x542600C7, // 0039 LDINT R9 200 - 0x1C241009, // 003A EQ R9 R8 R9 - 0x78260011, // 003B JMPF R9 #004E - 0x8C240D15, // 003C GETMET R9 R6 K21 - 0x7C240200, // 003D CALL R9 1 - 0x8C280D16, // 003E GETMET R10 R6 K22 - 0x7C280200, // 003F CALL R10 1 - 0xB82A0600, // 0040 GETNGBL R10 K3 - 0x8C28150F, // 0041 GETMET R10 R10 K15 - 0x00322E09, // 0042 ADD R12 K23 R9 - 0x58340011, // 0043 LDCONST R13 K17 - 0x7C280600, // 0044 CALL R10 3 - 0x8C280718, // 0045 GETMET R10 R3 K24 - 0x5C301200, // 0046 MOVE R12 R9 - 0x7C280400, // 0047 CALL R10 2 - 0x502C0200, // 0048 LDBOOL R11 1 0 - 0x9002320B, // 0049 SETMBR R0 K25 R11 - 0x882C011B, // 004A GETMBR R11 R0 K27 - 0x882C171C, // 004B GETMBR R11 R11 K28 - 0x9002340B, // 004C SETMBR R0 K26 R11 - 0x80041400, // 004D RET 1 R10 - 0x8C240D16, // 004E GETMET R9 R6 K22 - 0x7C240200, // 004F CALL R9 1 - 0x04140B1D, // 0050 SUB R5 R5 K29 - 0xB8260600, // 0051 GETNGBL R9 K3 - 0x8C24130F, // 0052 GETMET R9 R9 K15 - 0x582C001E, // 0053 LDCONST R11 K30 - 0x58300011, // 0054 LDCONST R12 K17 - 0x7C240600, // 0055 CALL R9 3 - 0x7001FFBB, // 0056 JMP #0013 - 0x50180000, // 0057 LDBOOL R6 0 0 - 0x90023206, // 0058 SETMBR R0 K25 R6 - 0x4C180000, // 0059 LDNIL R6 - 0x80040C00, // 005A RET 1 R6 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_status_8 -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_HTTP_get_status_8, /* name */ - be_nested_proto( - 6, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(device), - /* K1 */ be_nested_str_weak(tick), - /* K2 */ be_nested_str_weak(tasmota_status_8), - /* K3 */ be_nested_str_weak(find), - /* K4 */ be_nested_str_weak(_tick), - /* K5 */ be_nested_str_weak(call_remote), - /* K6 */ be_nested_str_weak(Status), - /* K7 */ be_nested_str_weak(8), - }), - be_str_weak(get_status_8), - &be_const_str_solidified, - ( &(const binstruction[27]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x88080102, // 0002 GETMBR R2 R0 K2 - 0x4C0C0000, // 0003 LDNIL R3 - 0x1C080403, // 0004 EQ R2 R2 R3 - 0x740A0005, // 0005 JMPT R2 #000C - 0x88080102, // 0006 GETMBR R2 R0 K2 - 0x8C080503, // 0007 GETMET R2 R2 K3 - 0x58100004, // 0008 LDCONST R4 K4 - 0x7C080400, // 0009 CALL R2 2 - 0x20080401, // 000A NE R2 R2 R1 - 0x780A000B, // 000B JMPF R2 #0018 - 0x8C080105, // 000C GETMET R2 R0 K5 - 0x58100006, // 000D LDCONST R4 K6 - 0x58140007, // 000E LDCONST R5 K7 - 0x7C080600, // 000F CALL R2 3 - 0x780A0003, // 0010 JMPF R2 #0015 - 0x980A0801, // 0011 SETIDX R2 K4 R1 - 0x90020402, // 0012 SETMBR R0 K2 R2 - 0x80040400, // 0013 RET 1 R2 - 0x70020001, // 0014 JMP #0017 - 0x4C0C0000, // 0015 LDNIL R3 - 0x80040600, // 0016 RET 1 R3 - 0x70020001, // 0017 JMP #001A - 0x88080102, // 0018 GETMBR R2 R0 K2 - 0x80040400, // 0019 RET 1 R2 - 0x80000000, // 001A RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: ui_conf_to_string -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_HTTP_ui_conf_to_string, /* name */ - be_nested_proto( - 11, /* nstack */ - 2, /* argc */ - 4, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_const_class(be_class_Matter_Plugin_Bridge_HTTP), - /* K1 */ be_nested_str_weak(ui_conf_to_string), - /* K2 */ be_nested_str_weak(find), - /* K3 */ be_nested_str_weak(ARG_HTTP), - /* K4 */ be_nested_str_weak(), - /* K5 */ be_nested_str_weak(_X2C), - /* K6 */ be_nested_str_weak(MTR_X3A_X20ui_conf_to_string), - }), - be_str_weak(ui_conf_to_string), - &be_const_str_solidified, - ( &(const binstruction[23]) { /* code */ - 0x58080000, // 0000 LDCONST R2 K0 - 0x600C0003, // 0001 GETGBL R3 G3 - 0x5C100400, // 0002 MOVE R4 R2 - 0x7C0C0200, // 0003 CALL R3 1 - 0x8C0C0701, // 0004 GETMET R3 R3 K1 - 0x5C140000, // 0005 MOVE R5 R0 - 0x5C180200, // 0006 MOVE R6 R1 - 0x7C0C0600, // 0007 CALL R3 3 - 0x60100008, // 0008 GETGBL R4 G8 - 0x8C140302, // 0009 GETMET R5 R1 K2 - 0x881C0503, // 000A GETMBR R7 R2 K3 - 0x58200004, // 000B LDCONST R8 K4 - 0x7C140600, // 000C CALL R5 3 - 0x7C100200, // 000D CALL R4 1 - 0x00140705, // 000E ADD R5 R3 K5 - 0x00140A04, // 000F ADD R5 R5 R4 - 0x60180001, // 0010 GETGBL R6 G1 - 0x581C0006, // 0011 LDCONST R7 K6 - 0x5C200200, // 0012 MOVE R8 R1 - 0x5C240000, // 0013 MOVE R9 R0 - 0x5C280A00, // 0014 MOVE R10 R5 - 0x7C180800, // 0015 CALL R6 4 - 0x80040A00, // 0016 RET 1 R5 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_HTTP_init, /* name */ - be_nested_proto( - 12, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[17]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(init), - /* K2 */ be_nested_str_weak(find), - /* K3 */ be_nested_str_weak(ARG_HTTP), - /* K4 */ be_nested_str_weak(_X3A_X2F_X2F), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(http_X3A_X2F_X2F), - /* K7 */ be_nested_str_weak(_X2F), - /* K8 */ be_nested_str_weak(tasmota_http), - /* K9 */ be_nested_str_weak(tasmota), - /* K10 */ be_nested_str_weak(log), - /* K11 */ be_nested_str_weak(format), - /* K12 */ be_nested_str_weak(MTR_X3A_X20ERROR_X3A_X20_X27url_X27_X20is_X20not_X20configured_X20for_X20endpoint_X20_X25i), - /* K13 */ be_const_int(2), - /* K14 */ be_nested_str_weak(tasmota_status_8), - /* K15 */ be_nested_str_weak(tasmota_status_11), - /* K16 */ be_nested_str_weak(reachable), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[39]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0x60140003, // 0001 GETGBL R5 G3 - 0x5C180000, // 0002 MOVE R6 R0 - 0x7C140200, // 0003 CALL R5 1 - 0x8C140B01, // 0004 GETMET R5 R5 K1 - 0x5C1C0200, // 0005 MOVE R7 R1 - 0x5C200400, // 0006 MOVE R8 R2 - 0x5C240600, // 0007 MOVE R9 R3 - 0x7C140800, // 0008 CALL R5 4 - 0x8C140702, // 0009 GETMET R5 R3 K2 - 0x881C0103, // 000A GETMBR R7 R0 K3 - 0x7C140400, // 000B CALL R5 2 - 0x7816000A, // 000C JMPF R5 #0018 - 0x8C180902, // 000D GETMET R6 R4 K2 - 0x5C200A00, // 000E MOVE R8 R5 - 0x58240004, // 000F LDCONST R9 K4 - 0x7C180600, // 0010 CALL R6 3 - 0x14180D05, // 0011 LT R6 R6 K5 - 0x781A0002, // 0012 JMPF R6 #0016 - 0x001A0C05, // 0013 ADD R6 K6 R5 - 0x00180D07, // 0014 ADD R6 R6 K7 - 0x5C140C00, // 0015 MOVE R5 R6 - 0x90021005, // 0016 SETMBR R0 K8 R5 - 0x70020007, // 0017 JMP #0020 - 0xB81A1200, // 0018 GETNGBL R6 K9 - 0x8C180D0A, // 0019 GETMET R6 R6 K10 - 0x8C20090B, // 001A GETMET R8 R4 K11 - 0x5828000C, // 001B LDCONST R10 K12 - 0x5C2C0400, // 001C MOVE R11 R2 - 0x7C200600, // 001D CALL R8 3 - 0x5824000D, // 001E LDCONST R9 K13 - 0x7C180600, // 001F CALL R6 3 - 0x4C180000, // 0020 LDNIL R6 - 0x90021C06, // 0021 SETMBR R0 K14 R6 - 0x4C180000, // 0022 LDNIL R6 - 0x90021E06, // 0023 SETMBR R0 K15 R6 - 0x50180000, // 0024 LDBOOL R6 0 0 - 0x90022006, // 0025 SETMBR R0 K16 R6 - 0x80000000, // 0026 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Bridge_HTTP -********************************************************************/ -extern const bclass be_class_Matter_Plugin_Device; -be_local_class(Matter_Plugin_Bridge_HTTP, - 5, - &be_class_Matter_Plugin_Device, - be_nested_map(21, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(get_types, 20), be_const_closure(Matter_Plugin_Bridge_HTTP_get_types_closure) }, - { be_const_key_weak(is_reachable, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_is_reachable_closure) }, - { be_const_key_weak(tasmota_http, -1), be_const_var(0) }, - { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_init_closure) }, - { be_const_key_weak(reachable_tick, -1), be_const_var(4) }, - { be_const_key_weak(get_status_8, 6), be_const_closure(Matter_Plugin_Bridge_HTTP_get_status_8_closure) }, - { be_const_key_weak(tasmota_status_11, -1), be_const_var(2) }, - { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(57, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(1, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(17), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak() }, - { be_const_key_weak(UPDATE_TIME, -1), be_const_int(3000) }, - { be_const_key_weak(TYPE, -1), be_nested_str_weak() }, - { be_const_key_weak(reachable, -1), be_const_var(3) }, - { be_const_key_weak(ARG_HTTP, 3), be_nested_str_weak(url) }, - { be_const_key_weak(ui_string_to_conf, -1), be_const_static_closure(Matter_Plugin_Bridge_HTTP_ui_string_to_conf_closure) }, - { be_const_key_weak(tasmota_status_8, 18), be_const_var(1) }, - { be_const_key_weak(ARG, 8), be_nested_str_weak() }, - { be_const_key_weak(call_remote, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_call_remote_closure) }, - { be_const_key_weak(get_status_11, 5), be_const_closure(Matter_Plugin_Bridge_HTTP_get_status_11_closure) }, - { be_const_key_weak(HTTP_TIMEOUT, 4), be_const_int(300) }, - { be_const_key_weak(ui_conf_to_string, -1), be_const_static_closure(Matter_Plugin_Bridge_HTTP_ui_conf_to_string_closure) }, - { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Bridge_HTTP_read_attribute_closure) }, - })), - be_str_weak(Matter_Plugin_Bridge_HTTP) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Bridge_HTTP_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_HTTP); - be_setglobal(vm, "Matter_Plugin_Bridge_HTTP"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Bridge_OnOff.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Bridge_OnOff.h deleted file mode 100644 index 937ff508ab72..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Bridge_OnOff.h +++ /dev/null @@ -1,400 +0,0 @@ -/* Solidification of Matter_Plugin_Bridge_OnOff.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Bridge_OnOff; - -/******************************************************************** -** Solidified function: -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_OnOff__X3Clambda_X3E, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(_X3Clambda_X3E), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x60040009, // 0000 GETGBL R1 G9 - 0x5C080000, // 0001 MOVE R2 R0 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_OnOff_init, /* name */ - be_nested_proto( - 10, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(init), - /* K2 */ be_nested_str_weak(shadow_onoff), - /* K3 */ be_nested_str_weak(tasmota_relay_index), - /* K4 */ be_nested_str_weak(find), - /* K5 */ be_nested_str_weak(ARG), - /* K6 */ be_const_int(0), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0x60140003, // 0001 GETGBL R5 G3 - 0x5C180000, // 0002 MOVE R6 R0 - 0x7C140200, // 0003 CALL R5 1 - 0x8C140B01, // 0004 GETMET R5 R5 K1 - 0x5C1C0200, // 0005 MOVE R7 R1 - 0x5C200400, // 0006 MOVE R8 R2 - 0x5C240600, // 0007 MOVE R9 R3 - 0x7C140800, // 0008 CALL R5 4 - 0x50140000, // 0009 LDBOOL R5 0 0 - 0x90020405, // 000A SETMBR R0 K2 R5 - 0x8C140704, // 000B GETMET R5 R3 K4 - 0x881C0105, // 000C GETMBR R7 R0 K5 - 0x7C140400, // 000D CALL R5 2 - 0x90020605, // 000E SETMBR R0 K3 R5 - 0x88140103, // 000F GETMBR R5 R0 K3 - 0x4C180000, // 0010 LDNIL R6 - 0x1C140A06, // 0011 EQ R5 R5 R6 - 0x78160000, // 0012 JMPF R5 #0014 - 0x90020706, // 0013 SETMBR R0 K3 K6 - 0x80000000, // 0014 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_onoff -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_OnOff_set_onoff, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(call_remote), - /* K1 */ be_nested_str_weak(Power), - /* K2 */ be_nested_str_weak(1), - /* K3 */ be_nested_str_weak(0), - /* K4 */ be_nested_str_weak(update_shadow), - }), - be_str_weak(set_onoff), - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x58100001, // 0001 LDCONST R4 K1 - 0x78060001, // 0002 JMPF R1 #0005 - 0x58140002, // 0003 LDCONST R5 K2 - 0x70020000, // 0004 JMP #0006 - 0x58140003, // 0005 LDCONST R5 K3 - 0x7C080600, // 0006 CALL R2 3 - 0x8C080104, // 0007 GETMET R2 R0 K4 - 0x7C080200, // 0008 CALL R2 1 - 0x80000000, // 0009 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: invoke_request -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_OnOff_invoke_request, /* name */ - be_nested_proto( - 10, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ - /* K0 */ be_nested_str_weak(matter), - /* K1 */ be_nested_str_weak(TLV), - /* K2 */ be_nested_str_weak(cluster), - /* K3 */ be_nested_str_weak(command), - /* K4 */ be_nested_str_weak(update_shadow_lazy), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(set_onoff), - /* K7 */ be_nested_str_weak(update_shadow), - /* K8 */ be_const_int(1), - /* K9 */ be_const_int(2), - /* K10 */ be_nested_str_weak(shadow_onoff), - }), - be_str_weak(invoke_request), - &be_const_str_solidified, - ( &(const binstruction[42]) { /* code */ - 0xB8120000, // 0000 GETNGBL R4 K0 - 0x88100901, // 0001 GETMBR R4 R4 K1 - 0x88140702, // 0002 GETMBR R5 R3 K2 - 0x88180703, // 0003 GETMBR R6 R3 K3 - 0x541E0005, // 0004 LDINT R7 6 - 0x1C1C0A07, // 0005 EQ R7 R5 R7 - 0x781E0021, // 0006 JMPF R7 #0029 - 0x8C1C0104, // 0007 GETMET R7 R0 K4 - 0x7C1C0200, // 0008 CALL R7 1 - 0x1C1C0D05, // 0009 EQ R7 R6 K5 - 0x781E0007, // 000A JMPF R7 #0013 - 0x8C1C0106, // 000B GETMET R7 R0 K6 - 0x50240000, // 000C LDBOOL R9 0 0 - 0x7C1C0400, // 000D CALL R7 2 - 0x8C1C0107, // 000E GETMET R7 R0 K7 - 0x7C1C0200, // 000F CALL R7 1 - 0x501C0200, // 0010 LDBOOL R7 1 0 - 0x80040E00, // 0011 RET 1 R7 - 0x70020015, // 0012 JMP #0029 - 0x1C1C0D08, // 0013 EQ R7 R6 K8 - 0x781E0007, // 0014 JMPF R7 #001D - 0x8C1C0106, // 0015 GETMET R7 R0 K6 - 0x50240200, // 0016 LDBOOL R9 1 0 - 0x7C1C0400, // 0017 CALL R7 2 - 0x8C1C0107, // 0018 GETMET R7 R0 K7 - 0x7C1C0200, // 0019 CALL R7 1 - 0x501C0200, // 001A LDBOOL R7 1 0 - 0x80040E00, // 001B RET 1 R7 - 0x7002000B, // 001C JMP #0029 - 0x1C1C0D09, // 001D EQ R7 R6 K9 - 0x781E0009, // 001E JMPF R7 #0029 - 0x8C1C0106, // 001F GETMET R7 R0 K6 - 0x8824010A, // 0020 GETMBR R9 R0 K10 - 0x78260000, // 0021 JMPF R9 #0023 - 0x50240001, // 0022 LDBOOL R9 0 1 - 0x50240200, // 0023 LDBOOL R9 1 0 - 0x7C1C0400, // 0024 CALL R7 2 - 0x8C1C0107, // 0025 GETMET R7 R0 K7 - 0x7C1C0200, // 0026 CALL R7 1 - 0x501C0200, // 0027 LDBOOL R7 1 0 - 0x80040E00, // 0028 RET 1 R7 - 0x80000000, // 0029 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_OnOff_read_attribute, /* name */ - be_nested_proto( - 11, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[12]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_nested_str_weak(update_shadow_lazy), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(create_TLV), - /* K8 */ be_nested_str_weak(BOOL), - /* K9 */ be_nested_str_weak(shadow_onoff), - /* K10 */ be_nested_str_weak(U4), - /* K11 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[45]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x541E0005, // 0005 LDINT R7 6 - 0x1C1C0A07, // 0006 EQ R7 R5 R7 - 0x781E001B, // 0007 JMPF R7 #0024 - 0x8C1C0105, // 0008 GETMET R7 R0 K5 - 0x7C1C0200, // 0009 CALL R7 1 - 0x1C1C0D06, // 000A EQ R7 R6 K6 - 0x781E0005, // 000B JMPF R7 #0012 - 0x8C1C0907, // 000C GETMET R7 R4 K7 - 0x88240908, // 000D GETMBR R9 R4 K8 - 0x88280109, // 000E GETMBR R10 R0 K9 - 0x7C1C0600, // 000F CALL R7 3 - 0x80040E00, // 0010 RET 1 R7 - 0x70020010, // 0011 JMP #0023 - 0x541EFFFB, // 0012 LDINT R7 65532 - 0x1C1C0C07, // 0013 EQ R7 R6 R7 - 0x781E0005, // 0014 JMPF R7 #001B - 0x8C1C0907, // 0015 GETMET R7 R4 K7 - 0x8824090A, // 0016 GETMBR R9 R4 K10 - 0x58280006, // 0017 LDCONST R10 K6 - 0x7C1C0600, // 0018 CALL R7 3 - 0x80040E00, // 0019 RET 1 R7 - 0x70020007, // 001A JMP #0023 - 0x541EFFFC, // 001B LDINT R7 65533 - 0x1C1C0C07, // 001C EQ R7 R6 R7 - 0x781E0004, // 001D JMPF R7 #0023 - 0x8C1C0907, // 001E GETMET R7 R4 K7 - 0x8824090A, // 001F GETMBR R9 R4 K10 - 0x542A0003, // 0020 LDINT R10 4 - 0x7C1C0600, // 0021 CALL R7 3 - 0x80040E00, // 0022 RET 1 R7 - 0x70020007, // 0023 JMP #002C - 0x601C0003, // 0024 GETGBL R7 G3 - 0x5C200000, // 0025 MOVE R8 R0 - 0x7C1C0200, // 0026 CALL R7 1 - 0x8C1C0F0B, // 0027 GETMET R7 R7 K11 - 0x5C240200, // 0028 MOVE R9 R1 - 0x5C280400, // 0029 MOVE R10 R2 - 0x7C1C0600, // 002A CALL R7 3 - 0x80040E00, // 002B RET 1 R7 - 0x80000000, // 002C RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: update_shadow -********************************************************************/ -be_local_closure(Matter_Plugin_Bridge_OnOff_update_shadow, /* name */ - be_nested_proto( - 7, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 9]) { /* constants */ - /* K0 */ be_nested_str_weak(get_status_11), - /* K1 */ be_nested_str_weak(find), - /* K2 */ be_nested_str_weak(StatusSTS), - /* K3 */ be_nested_str_weak(POWER), - /* K4 */ be_nested_str_weak(ON), - /* K5 */ be_nested_str_weak(shadow_onoff), - /* K6 */ be_nested_str_weak(attribute_updated), - /* K7 */ be_const_int(0), - /* K8 */ be_nested_str_weak(update_shadow), - }), - be_str_weak(update_shadow), - &be_const_str_solidified, - ( &(const binstruction[34]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x78060018, // 0002 JMPF R1 #001C - 0x8C080301, // 0003 GETMET R2 R1 K1 - 0x58100002, // 0004 LDCONST R4 K2 - 0x60140013, // 0005 GETGBL R5 G19 - 0x7C140000, // 0006 CALL R5 0 - 0x7C080600, // 0007 CALL R2 3 - 0x5C040400, // 0008 MOVE R1 R2 - 0x8C080301, // 0009 GETMET R2 R1 K1 - 0x58100003, // 000A LDCONST R4 K3 - 0x7C080400, // 000B CALL R2 2 - 0x1C080504, // 000C EQ R2 R2 K4 - 0x880C0105, // 000D GETMBR R3 R0 K5 - 0x4C100000, // 000E LDNIL R4 - 0x200C0604, // 000F NE R3 R3 R4 - 0x780E0009, // 0010 JMPF R3 #001B - 0x880C0105, // 0011 GETMBR R3 R0 K5 - 0x60100017, // 0012 GETGBL R4 G23 - 0x5C140400, // 0013 MOVE R5 R2 - 0x7C100200, // 0014 CALL R4 1 - 0x200C0604, // 0015 NE R3 R3 R4 - 0x780E0003, // 0016 JMPF R3 #001B - 0x8C0C0106, // 0017 GETMET R3 R0 K6 - 0x54160005, // 0018 LDINT R5 6 - 0x58180007, // 0019 LDCONST R6 K7 - 0x7C0C0600, // 001A CALL R3 3 - 0x90020A02, // 001B SETMBR R0 K5 R2 - 0x60080003, // 001C GETGBL R2 G3 - 0x5C0C0000, // 001D MOVE R3 R0 - 0x7C080200, // 001E CALL R2 1 - 0x8C080508, // 001F GETMET R2 R2 K8 - 0x7C080200, // 0020 CALL R2 1 - 0x80000000, // 0021 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Bridge_OnOff -********************************************************************/ -extern const bclass be_class_Matter_Plugin_Bridge_HTTP; -be_local_class(Matter_Plugin_Bridge_OnOff, - 3, - &be_class_Matter_Plugin_Bridge_HTTP, - be_nested_map(14, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(CLUSTERS, 11), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(3, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(ARG, -1), be_nested_str_weak(relay) }, - { be_const_key_weak(ARG_TYPE, -1), be_const_static_closure(Matter_Plugin_Bridge_OnOff__X3Clambda_X3E_closure) }, - { be_const_key_weak(TYPE, -1), be_nested_str_weak(http_relay) }, - { be_const_key_weak(update_shadow, -1), be_const_closure(Matter_Plugin_Bridge_OnOff_update_shadow_closure) }, - { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Bridge_OnOff_init_closure) }, - { be_const_key_weak(shadow_onoff, 13), be_const_var(2) }, - { be_const_key_weak(invoke_request, 4), be_const_closure(Matter_Plugin_Bridge_OnOff_invoke_request_closure) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak(_X26_X23x1F517_X3B_X20Relay) }, - { be_const_key_weak(tasmota_http, 12), be_const_var(0) }, - { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(266, -1), be_const_int(2) }, - })) ) } )) }, - { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Bridge_OnOff_read_attribute_closure) }, - { be_const_key_weak(tasmota_relay_index, -1), be_const_var(1) }, - { be_const_key_weak(set_onoff, -1), be_const_closure(Matter_Plugin_Bridge_OnOff_set_onoff_closure) }, - })), - be_str_weak(Matter_Plugin_Bridge_OnOff) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Bridge_OnOff_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Bridge_OnOff); - be_setglobal(vm, "Matter_Plugin_Bridge_OnOff"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Device.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Device.h deleted file mode 100644 index 054d6a0dbce3..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Device.h +++ /dev/null @@ -1,287 +0,0 @@ -/* Solidification of Matter_Plugin_Device.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Device; - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Device_read_attribute, /* name */ - be_nested_proto( - 11, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_const_int(3), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(create_TLV), - /* K8 */ be_nested_str_weak(U2), - /* K9 */ be_const_int(1), - /* K10 */ be_nested_str_weak(U1), - /* K11 */ be_nested_str_weak(U4), - /* K12 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[97]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x1C1C0B05, // 0005 EQ R7 R5 K5 - 0x781E0021, // 0006 JMPF R7 #0029 - 0x1C1C0D06, // 0007 EQ R7 R6 K6 - 0x781E0005, // 0008 JMPF R7 #000F - 0x8C1C0907, // 0009 GETMET R7 R4 K7 - 0x88240908, // 000A GETMBR R9 R4 K8 - 0x58280006, // 000B LDCONST R10 K6 - 0x7C1C0600, // 000C CALL R7 3 - 0x80040E00, // 000D RET 1 R7 - 0x70020018, // 000E JMP #0028 - 0x1C1C0D09, // 000F EQ R7 R6 K9 - 0x781E0005, // 0010 JMPF R7 #0017 - 0x8C1C0907, // 0011 GETMET R7 R4 K7 - 0x8824090A, // 0012 GETMBR R9 R4 K10 - 0x58280006, // 0013 LDCONST R10 K6 - 0x7C1C0600, // 0014 CALL R7 3 - 0x80040E00, // 0015 RET 1 R7 - 0x70020010, // 0016 JMP #0028 - 0x541EFFFB, // 0017 LDINT R7 65532 - 0x1C1C0C07, // 0018 EQ R7 R6 R7 - 0x781E0005, // 0019 JMPF R7 #0020 - 0x8C1C0907, // 001A GETMET R7 R4 K7 - 0x8824090B, // 001B GETMBR R9 R4 K11 - 0x58280006, // 001C LDCONST R10 K6 - 0x7C1C0600, // 001D CALL R7 3 - 0x80040E00, // 001E RET 1 R7 - 0x70020007, // 001F JMP #0028 - 0x541EFFFC, // 0020 LDINT R7 65533 - 0x1C1C0C07, // 0021 EQ R7 R6 R7 - 0x781E0004, // 0022 JMPF R7 #0028 - 0x8C1C0907, // 0023 GETMET R7 R4 K7 - 0x8824090B, // 0024 GETMBR R9 R4 K11 - 0x542A0003, // 0025 LDINT R10 4 - 0x7C1C0600, // 0026 CALL R7 3 - 0x80040E00, // 0027 RET 1 R7 - 0x70020036, // 0028 JMP #0060 - 0x541E0003, // 0029 LDINT R7 4 - 0x1C1C0A07, // 002A EQ R7 R5 R7 - 0x781E0016, // 002B JMPF R7 #0043 - 0x1C1C0D06, // 002C EQ R7 R6 K6 - 0x781E0002, // 002D JMPF R7 #0031 - 0x4C1C0000, // 002E LDNIL R7 - 0x80040E00, // 002F RET 1 R7 - 0x70020010, // 0030 JMP #0042 - 0x541EFFFB, // 0031 LDINT R7 65532 - 0x1C1C0C07, // 0032 EQ R7 R6 R7 - 0x781E0005, // 0033 JMPF R7 #003A - 0x8C1C0907, // 0034 GETMET R7 R4 K7 - 0x8824090B, // 0035 GETMBR R9 R4 K11 - 0x58280006, // 0036 LDCONST R10 K6 - 0x7C1C0600, // 0037 CALL R7 3 - 0x80040E00, // 0038 RET 1 R7 - 0x70020007, // 0039 JMP #0042 - 0x541EFFFC, // 003A LDINT R7 65533 - 0x1C1C0C07, // 003B EQ R7 R6 R7 - 0x781E0004, // 003C JMPF R7 #0042 - 0x8C1C0907, // 003D GETMET R7 R4 K7 - 0x8824090B, // 003E GETMBR R9 R4 K11 - 0x542A0003, // 003F LDINT R10 4 - 0x7C1C0600, // 0040 CALL R7 3 - 0x80040E00, // 0041 RET 1 R7 - 0x7002001C, // 0042 JMP #0060 - 0x541E0004, // 0043 LDINT R7 5 - 0x1C1C0A07, // 0044 EQ R7 R5 R7 - 0x781E0011, // 0045 JMPF R7 #0058 - 0x541EFFFB, // 0046 LDINT R7 65532 - 0x1C1C0C07, // 0047 EQ R7 R6 R7 - 0x781E0005, // 0048 JMPF R7 #004F - 0x8C1C0907, // 0049 GETMET R7 R4 K7 - 0x8824090B, // 004A GETMBR R9 R4 K11 - 0x58280006, // 004B LDCONST R10 K6 - 0x7C1C0600, // 004C CALL R7 3 - 0x80040E00, // 004D RET 1 R7 - 0x70020007, // 004E JMP #0057 - 0x541EFFFC, // 004F LDINT R7 65533 - 0x1C1C0C07, // 0050 EQ R7 R6 R7 - 0x781E0004, // 0051 JMPF R7 #0057 - 0x8C1C0907, // 0052 GETMET R7 R4 K7 - 0x8824090B, // 0053 GETMBR R9 R4 K11 - 0x542A0003, // 0054 LDINT R10 4 - 0x7C1C0600, // 0055 CALL R7 3 - 0x80040E00, // 0056 RET 1 R7 - 0x70020007, // 0057 JMP #0060 - 0x601C0003, // 0058 GETGBL R7 G3 - 0x5C200000, // 0059 MOVE R8 R0 - 0x7C1C0200, // 005A CALL R7 1 - 0x8C1C0F0C, // 005B GETMET R7 R7 K12 - 0x5C240200, // 005C MOVE R9 R1 - 0x5C280400, // 005D MOVE R10 R2 - 0x7C1C0600, // 005E CALL R7 3 - 0x80040E00, // 005F RET 1 R7 - 0x80000000, // 0060 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: invoke_request -********************************************************************/ -be_local_closure(Matter_Plugin_Device_invoke_request, /* name */ - be_nested_proto( - 13, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ - /* K0 */ be_nested_str_weak(matter), - /* K1 */ be_nested_str_weak(TLV), - /* K2 */ be_nested_str_weak(cluster), - /* K3 */ be_nested_str_weak(command), - /* K4 */ be_const_int(3), - /* K5 */ be_const_int(0), - /* K6 */ be_const_int(1), - /* K7 */ be_nested_str_weak(Matter_TLV_struct), - /* K8 */ be_nested_str_weak(add_TLV), - /* K9 */ be_nested_str_weak(U2), - /* K10 */ be_nested_str_weak(invoke_request), - }), - be_str_weak(invoke_request), - &be_const_str_solidified, - ( &(const binstruction[51]) { /* code */ - 0xB8120000, // 0000 GETNGBL R4 K0 - 0x88100901, // 0001 GETMBR R4 R4 K1 - 0x88140702, // 0002 GETMBR R5 R3 K2 - 0x88180703, // 0003 GETMBR R6 R3 K3 - 0x1C1C0B04, // 0004 EQ R7 R5 K4 - 0x781E0016, // 0005 JMPF R7 #001D - 0x1C1C0D05, // 0006 EQ R7 R6 K5 - 0x781E0002, // 0007 JMPF R7 #000B - 0x501C0200, // 0008 LDBOOL R7 1 0 - 0x80040E00, // 0009 RET 1 R7 - 0x70020010, // 000A JMP #001C - 0x1C1C0D06, // 000B EQ R7 R6 K6 - 0x781E0009, // 000C JMPF R7 #0017 - 0x8C1C0907, // 000D GETMET R7 R4 K7 - 0x7C1C0200, // 000E CALL R7 1 - 0x8C200F08, // 000F GETMET R8 R7 K8 - 0x58280005, // 0010 LDCONST R10 K5 - 0x882C0909, // 0011 GETMBR R11 R4 K9 - 0x58300005, // 0012 LDCONST R12 K5 - 0x7C200800, // 0013 CALL R8 4 - 0x900E0705, // 0014 SETMBR R3 K3 K5 - 0x80040E00, // 0015 RET 1 R7 - 0x70020004, // 0016 JMP #001C - 0x541E003F, // 0017 LDINT R7 64 - 0x1C1C0C07, // 0018 EQ R7 R6 R7 - 0x781E0001, // 0019 JMPF R7 #001C - 0x501C0200, // 001A LDBOOL R7 1 0 - 0x80040E00, // 001B RET 1 R7 - 0x70020014, // 001C JMP #0032 - 0x541E0003, // 001D LDINT R7 4 - 0x1C1C0A07, // 001E EQ R7 R5 R7 - 0x781E0002, // 001F JMPF R7 #0023 - 0x501C0200, // 0020 LDBOOL R7 1 0 - 0x80040E00, // 0021 RET 1 R7 - 0x7002000E, // 0022 JMP #0032 - 0x541E0004, // 0023 LDINT R7 5 - 0x1C1C0A07, // 0024 EQ R7 R5 R7 - 0x781E0002, // 0025 JMPF R7 #0029 - 0x501C0200, // 0026 LDBOOL R7 1 0 - 0x80040E00, // 0027 RET 1 R7 - 0x70020008, // 0028 JMP #0032 - 0x601C0003, // 0029 GETGBL R7 G3 - 0x5C200000, // 002A MOVE R8 R0 - 0x7C1C0200, // 002B CALL R7 1 - 0x8C1C0F0A, // 002C GETMET R7 R7 K10 - 0x5C240200, // 002D MOVE R9 R1 - 0x5C280400, // 002E MOVE R10 R2 - 0x5C2C0600, // 002F MOVE R11 R3 - 0x7C1C0800, // 0030 CALL R7 4 - 0x80040E00, // 0031 RET 1 R7 - 0x80000000, // 0032 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Device -********************************************************************/ -extern const bclass be_class_Matter_Plugin; -be_local_class(Matter_Plugin_Device, - 0, - &be_class_Matter_Plugin, - be_nested_map(4, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(3, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(3, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(4, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - { be_const_key_int(4, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(3, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - { be_const_key_int(5, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(8, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(2), - be_const_int(3), - be_const_int(4), - be_const_int(5), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(TYPES, 0), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(0, -1), be_const_int(0) }, - })) ) } )) }, - { be_const_key_weak(read_attribute, 1), be_const_closure(Matter_Plugin_Device_read_attribute_closure) }, - { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Device_invoke_request_closure) }, - })), - be_str_weak(Matter_Plugin_Device) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Device_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Device); - be_setglobal(vm, "Matter_Plugin_Device"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Light0.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Light0.h deleted file mode 100644 index d8782dcac360..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Light0.h +++ /dev/null @@ -1,313 +0,0 @@ -/* Solidification of Matter_Plugin_Light0.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Light0; - -/******************************************************************** -** Solidified function: update_shadow -********************************************************************/ -be_local_closure(Matter_Plugin_Light0_update_shadow, /* name */ - be_nested_proto( - 8, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(light), - /* K1 */ be_nested_str_weak(get), - /* K2 */ be_nested_str_weak(find), - /* K3 */ be_nested_str_weak(power), - /* K4 */ be_nested_str_weak(shadow_onoff), - /* K5 */ be_nested_str_weak(attribute_updated), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(update_shadow), - }), - be_str_weak(update_shadow), - &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x7C080200, // 0002 CALL R2 1 - 0x8C0C0502, // 0003 GETMET R3 R2 K2 - 0x58140003, // 0004 LDCONST R5 K3 - 0x4C180000, // 0005 LDNIL R6 - 0x7C0C0600, // 0006 CALL R3 3 - 0x88100104, // 0007 GETMBR R4 R0 K4 - 0x20100604, // 0008 NE R4 R3 R4 - 0x78120004, // 0009 JMPF R4 #000F - 0x8C100105, // 000A GETMET R4 R0 K5 - 0x541A0005, // 000B LDINT R6 6 - 0x581C0006, // 000C LDCONST R7 K6 - 0x7C100600, // 000D CALL R4 3 - 0x90020803, // 000E SETMBR R0 K4 R3 - 0x60100003, // 000F GETGBL R4 G3 - 0x5C140000, // 0010 MOVE R5 R0 - 0x7C100200, // 0011 CALL R4 1 - 0x8C100907, // 0012 GETMET R4 R4 K7 - 0x7C100200, // 0013 CALL R4 1 - 0x80000000, // 0014 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Light0_read_attribute, /* name */ - be_nested_proto( - 11, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[12]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_nested_str_weak(update_shadow_lazy), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(create_TLV), - /* K8 */ be_nested_str_weak(BOOL), - /* K9 */ be_nested_str_weak(shadow_onoff), - /* K10 */ be_nested_str_weak(U4), - /* K11 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[45]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x541E0005, // 0005 LDINT R7 6 - 0x1C1C0A07, // 0006 EQ R7 R5 R7 - 0x781E001B, // 0007 JMPF R7 #0024 - 0x8C1C0105, // 0008 GETMET R7 R0 K5 - 0x7C1C0200, // 0009 CALL R7 1 - 0x1C1C0D06, // 000A EQ R7 R6 K6 - 0x781E0005, // 000B JMPF R7 #0012 - 0x8C1C0907, // 000C GETMET R7 R4 K7 - 0x88240908, // 000D GETMBR R9 R4 K8 - 0x88280109, // 000E GETMBR R10 R0 K9 - 0x7C1C0600, // 000F CALL R7 3 - 0x80040E00, // 0010 RET 1 R7 - 0x70020010, // 0011 JMP #0023 - 0x541EFFFB, // 0012 LDINT R7 65532 - 0x1C1C0C07, // 0013 EQ R7 R6 R7 - 0x781E0005, // 0014 JMPF R7 #001B - 0x8C1C0907, // 0015 GETMET R7 R4 K7 - 0x8824090A, // 0016 GETMBR R9 R4 K10 - 0x58280006, // 0017 LDCONST R10 K6 - 0x7C1C0600, // 0018 CALL R7 3 - 0x80040E00, // 0019 RET 1 R7 - 0x70020007, // 001A JMP #0023 - 0x541EFFFC, // 001B LDINT R7 65533 - 0x1C1C0C07, // 001C EQ R7 R6 R7 - 0x781E0004, // 001D JMPF R7 #0023 - 0x8C1C0907, // 001E GETMET R7 R4 K7 - 0x8824090A, // 001F GETMBR R9 R4 K10 - 0x542A0003, // 0020 LDINT R10 4 - 0x7C1C0600, // 0021 CALL R7 3 - 0x80040E00, // 0022 RET 1 R7 - 0x70020007, // 0023 JMP #002C - 0x601C0003, // 0024 GETGBL R7 G3 - 0x5C200000, // 0025 MOVE R8 R0 - 0x7C1C0200, // 0026 CALL R7 1 - 0x8C1C0F0B, // 0027 GETMET R7 R7 K11 - 0x5C240200, // 0028 MOVE R9 R1 - 0x5C280400, // 0029 MOVE R10 R2 - 0x7C1C0600, // 002A CALL R7 3 - 0x80040E00, // 002B RET 1 R7 - 0x80000000, // 002C RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Matter_Plugin_Light0_init, /* name */ - be_nested_proto( - 9, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(init), - /* K1 */ be_nested_str_weak(shadow_onoff), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[11]) { /* code */ - 0x60100003, // 0000 GETGBL R4 G3 - 0x5C140000, // 0001 MOVE R5 R0 - 0x7C100200, // 0002 CALL R4 1 - 0x8C100900, // 0003 GETMET R4 R4 K0 - 0x5C180200, // 0004 MOVE R6 R1 - 0x5C1C0400, // 0005 MOVE R7 R2 - 0x5C200600, // 0006 MOVE R8 R3 - 0x7C100800, // 0007 CALL R4 4 - 0x50100000, // 0008 LDBOOL R4 0 0 - 0x90020204, // 0009 SETMBR R0 K1 R4 - 0x80000000, // 000A RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: invoke_request -********************************************************************/ -be_local_closure(Matter_Plugin_Light0_invoke_request, /* name */ - be_nested_proto( - 12, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ - /* K0 */ be_nested_str_weak(light), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(command), - /* K5 */ be_nested_str_weak(update_shadow_lazy), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(set), - /* K8 */ be_nested_str_weak(power), - /* K9 */ be_nested_str_weak(update_shadow), - /* K10 */ be_const_int(1), - /* K11 */ be_const_int(2), - /* K12 */ be_nested_str_weak(shadow_onoff), - }), - be_str_weak(invoke_request), - &be_const_str_solidified, - ( &(const binstruction[52]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0xB8160200, // 0001 GETNGBL R5 K1 - 0x88140B02, // 0002 GETMBR R5 R5 K2 - 0x88180703, // 0003 GETMBR R6 R3 K3 - 0x881C0704, // 0004 GETMBR R7 R3 K4 - 0x54220005, // 0005 LDINT R8 6 - 0x1C200C08, // 0006 EQ R8 R6 R8 - 0x7822002A, // 0007 JMPF R8 #0033 - 0x8C200105, // 0008 GETMET R8 R0 K5 - 0x7C200200, // 0009 CALL R8 1 - 0x1C200F06, // 000A EQ R8 R7 K6 - 0x7822000A, // 000B JMPF R8 #0017 - 0x8C200907, // 000C GETMET R8 R4 K7 - 0x60280013, // 000D GETGBL R10 G19 - 0x7C280000, // 000E CALL R10 0 - 0x502C0000, // 000F LDBOOL R11 0 0 - 0x982A100B, // 0010 SETIDX R10 K8 R11 - 0x7C200400, // 0011 CALL R8 2 - 0x8C200109, // 0012 GETMET R8 R0 K9 - 0x7C200200, // 0013 CALL R8 1 - 0x50200200, // 0014 LDBOOL R8 1 0 - 0x80041000, // 0015 RET 1 R8 - 0x7002001B, // 0016 JMP #0033 - 0x1C200F0A, // 0017 EQ R8 R7 K10 - 0x7822000A, // 0018 JMPF R8 #0024 - 0x8C200907, // 0019 GETMET R8 R4 K7 - 0x60280013, // 001A GETGBL R10 G19 - 0x7C280000, // 001B CALL R10 0 - 0x502C0200, // 001C LDBOOL R11 1 0 - 0x982A100B, // 001D SETIDX R10 K8 R11 - 0x7C200400, // 001E CALL R8 2 - 0x8C200109, // 001F GETMET R8 R0 K9 - 0x7C200200, // 0020 CALL R8 1 - 0x50200200, // 0021 LDBOOL R8 1 0 - 0x80041000, // 0022 RET 1 R8 - 0x7002000E, // 0023 JMP #0033 - 0x1C200F0B, // 0024 EQ R8 R7 K11 - 0x7822000C, // 0025 JMPF R8 #0033 - 0x8C200907, // 0026 GETMET R8 R4 K7 - 0x60280013, // 0027 GETGBL R10 G19 - 0x7C280000, // 0028 CALL R10 0 - 0x882C010C, // 0029 GETMBR R11 R0 K12 - 0x782E0000, // 002A JMPF R11 #002C - 0x502C0001, // 002B LDBOOL R11 0 1 - 0x502C0200, // 002C LDBOOL R11 1 0 - 0x982A100B, // 002D SETIDX R10 K8 R11 - 0x7C200400, // 002E CALL R8 2 - 0x8C200109, // 002F GETMET R8 R0 K9 - 0x7C200200, // 0030 CALL R8 1 - 0x50200200, // 0031 LDBOOL R8 1 0 - 0x80041000, // 0032 RET 1 R8 - 0x80000000, // 0033 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Light0 -********************************************************************/ -extern const bclass be_class_Matter_Plugin_Device; -be_local_class(Matter_Plugin_Light0, - 1, - &be_class_Matter_Plugin_Device, - be_nested_map(10, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(256, -1), be_const_int(2) }, - })) ) } )) }, - { be_const_key_weak(TYPE, -1), be_nested_str_weak(light0) }, - { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Light0_read_attribute_closure) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak(Light_X200_X20On) }, - { be_const_key_weak(CLUSTERS, 3), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(3, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Light0_init_closure) }, - { be_const_key_weak(UPDATE_TIME, -1), be_const_int(250) }, - { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Light0_invoke_request_closure) }, - { be_const_key_weak(shadow_onoff, -1), be_const_var(0) }, - { be_const_key_weak(update_shadow, 1), be_const_closure(Matter_Plugin_Light0_update_shadow_closure) }, - })), - be_str_weak(Matter_Plugin_Light0) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Light0_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Light0); - be_setglobal(vm, "Matter_Plugin_Light0"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Light1.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Light1.h deleted file mode 100644 index 4fad7a87614a..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Light1.h +++ /dev/null @@ -1,434 +0,0 @@ -/* Solidification of Matter_Plugin_Light1.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Light1; - -/******************************************************************** -** Solidified function: update_shadow -********************************************************************/ -be_local_closure(Matter_Plugin_Light1_update_shadow, /* name */ - be_nested_proto( - 11, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str_weak(light), - /* K1 */ be_nested_str_weak(get), - /* K2 */ be_nested_str_weak(find), - /* K3 */ be_nested_str_weak(bri), - /* K4 */ be_nested_str_weak(tasmota), - /* K5 */ be_nested_str_weak(scale_uint), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(shadow_bri), - /* K8 */ be_nested_str_weak(attribute_updated), - /* K9 */ be_nested_str_weak(update_shadow), - }), - be_str_weak(update_shadow), - &be_const_str_solidified, - ( &(const binstruction[33]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x7C080200, // 0002 CALL R2 1 - 0x8C0C0502, // 0003 GETMET R3 R2 K2 - 0x58140003, // 0004 LDCONST R5 K3 - 0x4C180000, // 0005 LDNIL R6 - 0x7C0C0600, // 0006 CALL R3 3 - 0x4C100000, // 0007 LDNIL R4 - 0x20100604, // 0008 NE R4 R3 R4 - 0x78120010, // 0009 JMPF R4 #001B - 0xB8120800, // 000A GETNGBL R4 K4 - 0x8C100905, // 000B GETMET R4 R4 K5 - 0x5C180600, // 000C MOVE R6 R3 - 0x581C0006, // 000D LDCONST R7 K6 - 0x542200FE, // 000E LDINT R8 255 - 0x58240006, // 000F LDCONST R9 K6 - 0x542A00FD, // 0010 LDINT R10 254 - 0x7C100C00, // 0011 CALL R4 6 - 0x5C0C0800, // 0012 MOVE R3 R4 - 0x88100107, // 0013 GETMBR R4 R0 K7 - 0x20100604, // 0014 NE R4 R3 R4 - 0x78120004, // 0015 JMPF R4 #001B - 0x8C100108, // 0016 GETMET R4 R0 K8 - 0x541A0007, // 0017 LDINT R6 8 - 0x581C0006, // 0018 LDCONST R7 K6 - 0x7C100600, // 0019 CALL R4 3 - 0x90020E03, // 001A SETMBR R0 K7 R3 - 0x60100003, // 001B GETGBL R4 G3 - 0x5C140000, // 001C MOVE R5 R0 - 0x7C100200, // 001D CALL R4 1 - 0x8C100909, // 001E GETMET R4 R4 K9 - 0x7C100200, // 001F CALL R4 1 - 0x80000000, // 0020 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: invoke_request -********************************************************************/ -be_local_closure(Matter_Plugin_Light1_invoke_request, /* name */ - be_nested_proto( - 16, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[20]) { /* constants */ - /* K0 */ be_nested_str_weak(light), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(command), - /* K5 */ be_nested_str_weak(update_shadow_lazy), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(findsubval), - /* K8 */ be_nested_str_weak(tasmota), - /* K9 */ be_nested_str_weak(scale_uint), - /* K10 */ be_nested_str_weak(set), - /* K11 */ be_nested_str_weak(bri), - /* K12 */ be_nested_str_weak(update_shadow), - /* K13 */ be_nested_str_weak(log), - /* K14 */ be_nested_str_weak(bri_X3A), - /* K15 */ be_const_int(1), - /* K16 */ be_const_int(2), - /* K17 */ be_const_int(3), - /* K18 */ be_nested_str_weak(power), - /* K19 */ be_nested_str_weak(invoke_request), - }), - be_str_weak(invoke_request), - &be_const_str_solidified, - ( &(const binstruction[112]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0xB8160200, // 0001 GETNGBL R5 K1 - 0x88140B02, // 0002 GETMBR R5 R5 K2 - 0x88180703, // 0003 GETMBR R6 R3 K3 - 0x881C0704, // 0004 GETMBR R7 R3 K4 - 0x54220007, // 0005 LDINT R8 8 - 0x1C200C08, // 0006 EQ R8 R6 R8 - 0x7822005D, // 0007 JMPF R8 #0066 - 0x8C200105, // 0008 GETMET R8 R0 K5 - 0x7C200200, // 0009 CALL R8 1 - 0x1C200F06, // 000A EQ R8 R7 K6 - 0x78220019, // 000B JMPF R8 #0026 - 0x8C200507, // 000C GETMET R8 R2 K7 - 0x58280006, // 000D LDCONST R10 K6 - 0x7C200400, // 000E CALL R8 2 - 0xB8261000, // 000F GETNGBL R9 K8 - 0x8C241309, // 0010 GETMET R9 R9 K9 - 0x5C2C1000, // 0011 MOVE R11 R8 - 0x58300006, // 0012 LDCONST R12 K6 - 0x543600FD, // 0013 LDINT R13 254 - 0x58380006, // 0014 LDCONST R14 K6 - 0x543E00FE, // 0015 LDINT R15 255 - 0x7C240C00, // 0016 CALL R9 6 - 0x8C28090A, // 0017 GETMET R10 R4 K10 - 0x60300013, // 0018 GETGBL R12 G19 - 0x7C300000, // 0019 CALL R12 0 - 0x98321609, // 001A SETIDX R12 K11 R9 - 0x7C280400, // 001B CALL R10 2 - 0x8C28010C, // 001C GETMET R10 R0 K12 - 0x7C280200, // 001D CALL R10 1 - 0x60280008, // 001E GETGBL R10 G8 - 0x5C2C1000, // 001F MOVE R11 R8 - 0x7C280200, // 0020 CALL R10 1 - 0x002A1C0A, // 0021 ADD R10 K14 R10 - 0x900E1A0A, // 0022 SETMBR R3 K13 R10 - 0x50280200, // 0023 LDBOOL R10 1 0 - 0x80041400, // 0024 RET 1 R10 - 0x7002003E, // 0025 JMP #0065 - 0x1C200F0F, // 0026 EQ R8 R7 K15 - 0x78220002, // 0027 JMPF R8 #002B - 0x50200200, // 0028 LDBOOL R8 1 0 - 0x80041000, // 0029 RET 1 R8 - 0x70020039, // 002A JMP #0065 - 0x1C200F10, // 002B EQ R8 R7 K16 - 0x78220002, // 002C JMPF R8 #0030 - 0x50200200, // 002D LDBOOL R8 1 0 - 0x80041000, // 002E RET 1 R8 - 0x70020034, // 002F JMP #0065 - 0x1C200F11, // 0030 EQ R8 R7 K17 - 0x78220002, // 0031 JMPF R8 #0035 - 0x50200200, // 0032 LDBOOL R8 1 0 - 0x80041000, // 0033 RET 1 R8 - 0x7002002F, // 0034 JMP #0065 - 0x54220003, // 0035 LDINT R8 4 - 0x1C200E08, // 0036 EQ R8 R7 R8 - 0x7822001B, // 0037 JMPF R8 #0054 - 0x8C200507, // 0038 GETMET R8 R2 K7 - 0x58280006, // 0039 LDCONST R10 K6 - 0x7C200400, // 003A CALL R8 2 - 0xB8261000, // 003B GETNGBL R9 K8 - 0x8C241309, // 003C GETMET R9 R9 K9 - 0x5C2C1000, // 003D MOVE R11 R8 - 0x58300006, // 003E LDCONST R12 K6 - 0x543600FD, // 003F LDINT R13 254 - 0x58380006, // 0040 LDCONST R14 K6 - 0x543E00FE, // 0041 LDINT R15 255 - 0x7C240C00, // 0042 CALL R9 6 - 0x24281306, // 0043 GT R10 R9 K6 - 0x8C2C090A, // 0044 GETMET R11 R4 K10 - 0x60340013, // 0045 GETGBL R13 G19 - 0x7C340000, // 0046 CALL R13 0 - 0x98361609, // 0047 SETIDX R13 K11 R9 - 0x9836240A, // 0048 SETIDX R13 K18 R10 - 0x7C2C0400, // 0049 CALL R11 2 - 0x8C2C010C, // 004A GETMET R11 R0 K12 - 0x7C2C0200, // 004B CALL R11 1 - 0x602C0008, // 004C GETGBL R11 G8 - 0x5C301000, // 004D MOVE R12 R8 - 0x7C2C0200, // 004E CALL R11 1 - 0x002E1C0B, // 004F ADD R11 K14 R11 - 0x900E1A0B, // 0050 SETMBR R3 K13 R11 - 0x502C0200, // 0051 LDBOOL R11 1 0 - 0x80041600, // 0052 RET 1 R11 - 0x70020010, // 0053 JMP #0065 - 0x54220004, // 0054 LDINT R8 5 - 0x1C200E08, // 0055 EQ R8 R7 R8 - 0x78220002, // 0056 JMPF R8 #005A - 0x50200200, // 0057 LDBOOL R8 1 0 - 0x80041000, // 0058 RET 1 R8 - 0x7002000A, // 0059 JMP #0065 - 0x54220005, // 005A LDINT R8 6 - 0x1C200E08, // 005B EQ R8 R7 R8 - 0x78220002, // 005C JMPF R8 #0060 - 0x50200200, // 005D LDBOOL R8 1 0 - 0x80041000, // 005E RET 1 R8 - 0x70020004, // 005F JMP #0065 - 0x54220006, // 0060 LDINT R8 7 - 0x1C200E08, // 0061 EQ R8 R7 R8 - 0x78220001, // 0062 JMPF R8 #0065 - 0x50200200, // 0063 LDBOOL R8 1 0 - 0x80041000, // 0064 RET 1 R8 - 0x70020008, // 0065 JMP #006F - 0x60200003, // 0066 GETGBL R8 G3 - 0x5C240000, // 0067 MOVE R9 R0 - 0x7C200200, // 0068 CALL R8 1 - 0x8C201113, // 0069 GETMET R8 R8 K19 - 0x5C280200, // 006A MOVE R10 R1 - 0x5C2C0400, // 006B MOVE R11 R2 - 0x5C300600, // 006C MOVE R12 R3 - 0x7C200800, // 006D CALL R8 4 - 0x80041000, // 006E RET 1 R8 - 0x80000000, // 006F RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Light1_read_attribute, /* name */ - be_nested_proto( - 11, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_nested_str_weak(update_shadow_lazy), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(create_TLV), - /* K8 */ be_nested_str_weak(U1), - /* K9 */ be_nested_str_weak(shadow_bri), - /* K10 */ be_const_int(2), - /* K11 */ be_const_int(3), - /* K12 */ be_nested_str_weak(U4), - /* K13 */ be_const_int(1), - /* K14 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[79]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x541E0007, // 0005 LDINT R7 8 - 0x1C1C0A07, // 0006 EQ R7 R5 R7 - 0x781E003D, // 0007 JMPF R7 #0046 - 0x8C1C0105, // 0008 GETMET R7 R0 K5 - 0x7C1C0200, // 0009 CALL R7 1 - 0x1C1C0D06, // 000A EQ R7 R6 K6 - 0x781E0005, // 000B JMPF R7 #0012 - 0x8C1C0907, // 000C GETMET R7 R4 K7 - 0x88240908, // 000D GETMBR R9 R4 K8 - 0x88280109, // 000E GETMBR R10 R0 K9 - 0x7C1C0600, // 000F CALL R7 3 - 0x80040E00, // 0010 RET 1 R7 - 0x70020032, // 0011 JMP #0045 - 0x1C1C0D0A, // 0012 EQ R7 R6 K10 - 0x781E0005, // 0013 JMPF R7 #001A - 0x8C1C0907, // 0014 GETMET R7 R4 K7 - 0x88240908, // 0015 GETMBR R9 R4 K8 - 0x58280006, // 0016 LDCONST R10 K6 - 0x7C1C0600, // 0017 CALL R7 3 - 0x80040E00, // 0018 RET 1 R7 - 0x7002002A, // 0019 JMP #0045 - 0x1C1C0D0B, // 001A EQ R7 R6 K11 - 0x781E0005, // 001B JMPF R7 #0022 - 0x8C1C0907, // 001C GETMET R7 R4 K7 - 0x88240908, // 001D GETMBR R9 R4 K8 - 0x542A00FD, // 001E LDINT R10 254 - 0x7C1C0600, // 001F CALL R7 3 - 0x80040E00, // 0020 RET 1 R7 - 0x70020022, // 0021 JMP #0045 - 0x541E000E, // 0022 LDINT R7 15 - 0x1C1C0C07, // 0023 EQ R7 R6 R7 - 0x781E0005, // 0024 JMPF R7 #002B - 0x8C1C0907, // 0025 GETMET R7 R4 K7 - 0x88240908, // 0026 GETMBR R9 R4 K8 - 0x58280006, // 0027 LDCONST R10 K6 - 0x7C1C0600, // 0028 CALL R7 3 - 0x80040E00, // 0029 RET 1 R7 - 0x70020019, // 002A JMP #0045 - 0x541E0010, // 002B LDINT R7 17 - 0x1C1C0C07, // 002C EQ R7 R6 R7 - 0x781E0005, // 002D JMPF R7 #0034 - 0x8C1C0907, // 002E GETMET R7 R4 K7 - 0x88240908, // 002F GETMBR R9 R4 K8 - 0x88280109, // 0030 GETMBR R10 R0 K9 - 0x7C1C0600, // 0031 CALL R7 3 - 0x80040E00, // 0032 RET 1 R7 - 0x70020010, // 0033 JMP #0045 - 0x541EFFFB, // 0034 LDINT R7 65532 - 0x1C1C0C07, // 0035 EQ R7 R6 R7 - 0x781E0005, // 0036 JMPF R7 #003D - 0x8C1C0907, // 0037 GETMET R7 R4 K7 - 0x8824090C, // 0038 GETMBR R9 R4 K12 - 0x5828000D, // 0039 LDCONST R10 K13 - 0x7C1C0600, // 003A CALL R7 3 - 0x80040E00, // 003B RET 1 R7 - 0x70020007, // 003C JMP #0045 - 0x541EFFFC, // 003D LDINT R7 65533 - 0x1C1C0C07, // 003E EQ R7 R6 R7 - 0x781E0004, // 003F JMPF R7 #0045 - 0x8C1C0907, // 0040 GETMET R7 R4 K7 - 0x8824090C, // 0041 GETMBR R9 R4 K12 - 0x542A0004, // 0042 LDINT R10 5 - 0x7C1C0600, // 0043 CALL R7 3 - 0x80040E00, // 0044 RET 1 R7 - 0x70020007, // 0045 JMP #004E - 0x601C0003, // 0046 GETGBL R7 G3 - 0x5C200000, // 0047 MOVE R8 R0 - 0x7C1C0200, // 0048 CALL R7 1 - 0x8C1C0F0E, // 0049 GETMET R7 R7 K14 - 0x5C240200, // 004A MOVE R9 R1 - 0x5C280400, // 004B MOVE R10 R2 - 0x7C1C0600, // 004C CALL R7 3 - 0x80040E00, // 004D RET 1 R7 - 0x80000000, // 004E RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Matter_Plugin_Light1_init, /* name */ - be_nested_proto( - 9, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(init), - /* K1 */ be_nested_str_weak(shadow_bri), - /* K2 */ be_const_int(0), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x60100003, // 0000 GETGBL R4 G3 - 0x5C140000, // 0001 MOVE R5 R0 - 0x7C100200, // 0002 CALL R4 1 - 0x8C100900, // 0003 GETMET R4 R4 K0 - 0x5C180200, // 0004 MOVE R6 R1 - 0x5C1C0400, // 0005 MOVE R7 R2 - 0x5C200600, // 0006 MOVE R8 R3 - 0x7C100800, // 0007 CALL R4 4 - 0x90020302, // 0008 SETMBR R0 K1 K2 - 0x80000000, // 0009 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Light1 -********************************************************************/ -extern const bclass be_class_Matter_Plugin_Light0; -be_local_class(Matter_Plugin_Light1, - 1, - &be_class_Matter_Plugin_Light0, - be_nested_map(9, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Light1_init_closure) }, - { be_const_key_weak(TYPE, -1), be_nested_str_weak(light1) }, - { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(257, -1), be_const_int(2) }, - })) ) } )) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak(Light_X201_X20Dimmer) }, - { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(8, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(7, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(2), - be_const_int(3), - be_const_int(15), - be_const_int(17), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Light1_invoke_request_closure) }, - { be_const_key_weak(read_attribute, 0), be_const_closure(Matter_Plugin_Light1_read_attribute_closure) }, - { be_const_key_weak(update_shadow, 8), be_const_closure(Matter_Plugin_Light1_update_shadow_closure) }, - { be_const_key_weak(shadow_bri, -1), be_const_var(0) }, - })), - be_str_weak(Matter_Plugin_Light1) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Light1_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Light1); - be_setglobal(vm, "Matter_Plugin_Light1"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Light2.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Light2.h deleted file mode 100644 index 50328f5df4b7..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Light2.h +++ /dev/null @@ -1,429 +0,0 @@ -/* Solidification of Matter_Plugin_Light2.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Light2; - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Light2_read_attribute, /* name */ - be_nested_proto( - 11, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_nested_str_weak(update_shadow_lazy), - /* K6 */ be_nested_str_weak(create_TLV), - /* K7 */ be_nested_str_weak(U1), - /* K8 */ be_nested_str_weak(shadow_ct), - /* K9 */ be_const_int(2), - /* K10 */ be_const_int(0), - /* K11 */ be_nested_str_weak(ct_min), - /* K12 */ be_nested_str_weak(ct_max), - /* K13 */ be_nested_str_weak(U4), - /* K14 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[82]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x541E02FF, // 0005 LDINT R7 768 - 0x1C1C0A07, // 0006 EQ R7 R5 R7 - 0x781E0040, // 0007 JMPF R7 #0049 - 0x8C1C0105, // 0008 GETMET R7 R0 K5 - 0x7C1C0200, // 0009 CALL R7 1 - 0x541E0006, // 000A LDINT R7 7 - 0x1C1C0C07, // 000B EQ R7 R6 R7 - 0x781E0005, // 000C JMPF R7 #0013 - 0x8C1C0906, // 000D GETMET R7 R4 K6 - 0x88240907, // 000E GETMBR R9 R4 K7 - 0x88280108, // 000F GETMBR R10 R0 K8 - 0x7C1C0600, // 0010 CALL R7 3 - 0x80040E00, // 0011 RET 1 R7 - 0x70020034, // 0012 JMP #0048 - 0x541E0007, // 0013 LDINT R7 8 - 0x1C1C0C07, // 0014 EQ R7 R6 R7 - 0x781E0005, // 0015 JMPF R7 #001C - 0x8C1C0906, // 0016 GETMET R7 R4 K6 - 0x88240907, // 0017 GETMBR R9 R4 K7 - 0x58280009, // 0018 LDCONST R10 K9 - 0x7C1C0600, // 0019 CALL R7 3 - 0x80040E00, // 001A RET 1 R7 - 0x7002002B, // 001B JMP #0048 - 0x541E000E, // 001C LDINT R7 15 - 0x1C1C0C07, // 001D EQ R7 R6 R7 - 0x781E0005, // 001E JMPF R7 #0025 - 0x8C1C0906, // 001F GETMET R7 R4 K6 - 0x88240907, // 0020 GETMBR R9 R4 K7 - 0x5828000A, // 0021 LDCONST R10 K10 - 0x7C1C0600, // 0022 CALL R7 3 - 0x80040E00, // 0023 RET 1 R7 - 0x70020022, // 0024 JMP #0048 - 0x541E400A, // 0025 LDINT R7 16395 - 0x1C1C0C07, // 0026 EQ R7 R6 R7 - 0x781E0005, // 0027 JMPF R7 #002E - 0x8C1C0906, // 0028 GETMET R7 R4 K6 - 0x88240907, // 0029 GETMBR R9 R4 K7 - 0x8828010B, // 002A GETMBR R10 R0 K11 - 0x7C1C0600, // 002B CALL R7 3 - 0x80040E00, // 002C RET 1 R7 - 0x70020019, // 002D JMP #0048 - 0x541E400B, // 002E LDINT R7 16396 - 0x1C1C0C07, // 002F EQ R7 R6 R7 - 0x781E0005, // 0030 JMPF R7 #0037 - 0x8C1C0906, // 0031 GETMET R7 R4 K6 - 0x88240907, // 0032 GETMBR R9 R4 K7 - 0x8828010C, // 0033 GETMBR R10 R0 K12 - 0x7C1C0600, // 0034 CALL R7 3 - 0x80040E00, // 0035 RET 1 R7 - 0x70020010, // 0036 JMP #0048 - 0x541EFFFB, // 0037 LDINT R7 65532 - 0x1C1C0C07, // 0038 EQ R7 R6 R7 - 0x781E0005, // 0039 JMPF R7 #0040 - 0x8C1C0906, // 003A GETMET R7 R4 K6 - 0x8824090D, // 003B GETMBR R9 R4 K13 - 0x542A000F, // 003C LDINT R10 16 - 0x7C1C0600, // 003D CALL R7 3 - 0x80040E00, // 003E RET 1 R7 - 0x70020007, // 003F JMP #0048 - 0x541EFFFC, // 0040 LDINT R7 65533 - 0x1C1C0C07, // 0041 EQ R7 R6 R7 - 0x781E0004, // 0042 JMPF R7 #0048 - 0x8C1C0906, // 0043 GETMET R7 R4 K6 - 0x8824090D, // 0044 GETMBR R9 R4 K13 - 0x542A0004, // 0045 LDINT R10 5 - 0x7C1C0600, // 0046 CALL R7 3 - 0x80040E00, // 0047 RET 1 R7 - 0x70020007, // 0048 JMP #0051 - 0x601C0003, // 0049 GETGBL R7 G3 - 0x5C200000, // 004A MOVE R8 R0 - 0x7C1C0200, // 004B CALL R7 1 - 0x8C1C0F0E, // 004C GETMET R7 R7 K14 - 0x5C240200, // 004D MOVE R9 R1 - 0x5C280400, // 004E MOVE R10 R2 - 0x7C1C0600, // 004F CALL R7 3 - 0x80040E00, // 0050 RET 1 R7 - 0x80000000, // 0051 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: update_shadow -********************************************************************/ -be_local_closure(Matter_Plugin_Light2_update_shadow, /* name */ - be_nested_proto( - 8, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(light), - /* K1 */ be_nested_str_weak(update_ct_minmax), - /* K2 */ be_nested_str_weak(update_shadow), - /* K3 */ be_nested_str_weak(get), - /* K4 */ be_nested_str_weak(find), - /* K5 */ be_nested_str_weak(ct), - /* K6 */ be_nested_str_weak(shadow_ct), - /* K7 */ be_nested_str_weak(attribute_updated), - }), - be_str_weak(update_shadow), - &be_const_str_solidified, - ( &(const binstruction[27]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080101, // 0001 GETMET R2 R0 K1 - 0x7C080200, // 0002 CALL R2 1 - 0x60080003, // 0003 GETGBL R2 G3 - 0x5C0C0000, // 0004 MOVE R3 R0 - 0x7C080200, // 0005 CALL R2 1 - 0x8C080502, // 0006 GETMET R2 R2 K2 - 0x7C080200, // 0007 CALL R2 1 - 0x8C080303, // 0008 GETMET R2 R1 K3 - 0x7C080200, // 0009 CALL R2 1 - 0x8C0C0504, // 000A GETMET R3 R2 K4 - 0x58140005, // 000B LDCONST R5 K5 - 0x4C180000, // 000C LDNIL R6 - 0x7C0C0600, // 000D CALL R3 3 - 0x4C100000, // 000E LDNIL R4 - 0x1C100604, // 000F EQ R4 R3 R4 - 0x78120000, // 0010 JMPF R4 #0012 - 0x880C0106, // 0011 GETMBR R3 R0 K6 - 0x88100106, // 0012 GETMBR R4 R0 K6 - 0x20100604, // 0013 NE R4 R3 R4 - 0x78120004, // 0014 JMPF R4 #001A - 0x8C100107, // 0015 GETMET R4 R0 K7 - 0x541A02FF, // 0016 LDINT R6 768 - 0x541E0006, // 0017 LDINT R7 7 - 0x7C100600, // 0018 CALL R4 3 - 0x90020C03, // 0019 SETMBR R0 K6 R3 - 0x80000000, // 001A RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Matter_Plugin_Light2_init, /* name */ - be_nested_proto( - 9, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(init), - /* K1 */ be_nested_str_weak(shadow_ct), - /* K2 */ be_nested_str_weak(update_ct_minmax), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x60100003, // 0000 GETGBL R4 G3 - 0x5C140000, // 0001 MOVE R5 R0 - 0x7C100200, // 0002 CALL R4 1 - 0x8C100900, // 0003 GETMET R4 R4 K0 - 0x5C180200, // 0004 MOVE R6 R1 - 0x5C1C0400, // 0005 MOVE R7 R2 - 0x5C200600, // 0006 MOVE R8 R3 - 0x7C100800, // 0007 CALL R4 4 - 0x54120144, // 0008 LDINT R4 325 - 0x90020204, // 0009 SETMBR R0 K1 R4 - 0x8C100102, // 000A GETMET R4 R0 K2 - 0x7C100200, // 000B CALL R4 1 - 0x80000000, // 000C RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: update_ct_minmax -********************************************************************/ -be_local_closure(Matter_Plugin_Light2_update_ct_minmax, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(tasmota), - /* K1 */ be_nested_str_weak(get_option), - /* K2 */ be_nested_str_weak(ct_min), - /* K3 */ be_nested_str_weak(ct_max), - }), - be_str_weak(update_ct_minmax), - &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0xB8060000, // 0000 GETNGBL R1 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x540E0051, // 0002 LDINT R3 82 - 0x7C040400, // 0003 CALL R1 2 - 0x78060001, // 0004 JMPF R1 #0007 - 0x540A00C7, // 0005 LDINT R2 200 - 0x70020000, // 0006 JMP #0008 - 0x540A0098, // 0007 LDINT R2 153 - 0x90020402, // 0008 SETMBR R0 K2 R2 - 0x78060001, // 0009 JMPF R1 #000C - 0x540A017B, // 000A LDINT R2 380 - 0x70020000, // 000B JMP #000D - 0x540A01F3, // 000C LDINT R2 500 - 0x90020602, // 000D SETMBR R0 K3 R2 - 0x80000000, // 000E RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: invoke_request -********************************************************************/ -be_local_closure(Matter_Plugin_Light2_invoke_request, /* name */ - be_nested_proto( - 13, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[16]) { /* constants */ - /* K0 */ be_nested_str_weak(light), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(command), - /* K5 */ be_nested_str_weak(update_shadow_lazy), - /* K6 */ be_nested_str_weak(findsubval), - /* K7 */ be_const_int(0), - /* K8 */ be_nested_str_weak(ct_min), - /* K9 */ be_nested_str_weak(ct_max), - /* K10 */ be_nested_str_weak(set), - /* K11 */ be_nested_str_weak(ct), - /* K12 */ be_nested_str_weak(update_shadow), - /* K13 */ be_nested_str_weak(log), - /* K14 */ be_nested_str_weak(ct_X3A), - /* K15 */ be_nested_str_weak(invoke_request), - }), - be_str_weak(invoke_request), - &be_const_str_solidified, - ( &(const binstruction[67]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0xB8160200, // 0001 GETNGBL R5 K1 - 0x88140B02, // 0002 GETMBR R5 R5 K2 - 0x88180703, // 0003 GETMBR R6 R3 K3 - 0x881C0704, // 0004 GETMBR R7 R3 K4 - 0x542202FF, // 0005 LDINT R8 768 - 0x1C200C08, // 0006 EQ R8 R6 R8 - 0x78220030, // 0007 JMPF R8 #0039 - 0x8C200105, // 0008 GETMET R8 R0 K5 - 0x7C200200, // 0009 CALL R8 1 - 0x54220009, // 000A LDINT R8 10 - 0x1C200E08, // 000B EQ R8 R7 R8 - 0x78220019, // 000C JMPF R8 #0027 - 0x8C200506, // 000D GETMET R8 R2 K6 - 0x58280007, // 000E LDCONST R10 K7 - 0x7C200400, // 000F CALL R8 2 - 0x88240108, // 0010 GETMBR R9 R0 K8 - 0x14241009, // 0011 LT R9 R8 R9 - 0x78260000, // 0012 JMPF R9 #0014 - 0x88200108, // 0013 GETMBR R8 R0 K8 - 0x88240109, // 0014 GETMBR R9 R0 K9 - 0x24241009, // 0015 GT R9 R8 R9 - 0x78260000, // 0016 JMPF R9 #0018 - 0x88200109, // 0017 GETMBR R8 R0 K9 - 0x8C24090A, // 0018 GETMET R9 R4 K10 - 0x602C0013, // 0019 GETGBL R11 G19 - 0x7C2C0000, // 001A CALL R11 0 - 0x982E1608, // 001B SETIDX R11 K11 R8 - 0x7C240400, // 001C CALL R9 2 - 0x8C24010C, // 001D GETMET R9 R0 K12 - 0x7C240200, // 001E CALL R9 1 - 0x60240008, // 001F GETGBL R9 G8 - 0x5C281000, // 0020 MOVE R10 R8 - 0x7C240200, // 0021 CALL R9 1 - 0x00261C09, // 0022 ADD R9 K14 R9 - 0x900E1A09, // 0023 SETMBR R3 K13 R9 - 0x50240200, // 0024 LDBOOL R9 1 0 - 0x80041200, // 0025 RET 1 R9 - 0x70020010, // 0026 JMP #0038 - 0x54220046, // 0027 LDINT R8 71 - 0x1C200E08, // 0028 EQ R8 R7 R8 - 0x78220002, // 0029 JMPF R8 #002D - 0x50200200, // 002A LDBOOL R8 1 0 - 0x80041000, // 002B RET 1 R8 - 0x7002000A, // 002C JMP #0038 - 0x5422004A, // 002D LDINT R8 75 - 0x1C200E08, // 002E EQ R8 R7 R8 - 0x78220002, // 002F JMPF R8 #0033 - 0x50200200, // 0030 LDBOOL R8 1 0 - 0x80041000, // 0031 RET 1 R8 - 0x70020004, // 0032 JMP #0038 - 0x5422004B, // 0033 LDINT R8 76 - 0x1C200E08, // 0034 EQ R8 R7 R8 - 0x78220001, // 0035 JMPF R8 #0038 - 0x50200200, // 0036 LDBOOL R8 1 0 - 0x80041000, // 0037 RET 1 R8 - 0x70020008, // 0038 JMP #0042 - 0x60200003, // 0039 GETGBL R8 G3 - 0x5C240000, // 003A MOVE R9 R0 - 0x7C200200, // 003B CALL R8 1 - 0x8C20110F, // 003C GETMET R8 R8 K15 - 0x5C280200, // 003D MOVE R10 R1 - 0x5C2C0400, // 003E MOVE R11 R2 - 0x5C300600, // 003F MOVE R12 R3 - 0x7C200800, // 0040 CALL R8 4 - 0x80041000, // 0041 RET 1 R8 - 0x80000000, // 0042 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Light2 -********************************************************************/ -extern const bclass be_class_Matter_Plugin_Light1; -be_local_class(Matter_Plugin_Light2, - 3, - &be_class_Matter_Plugin_Light1, - be_nested_map(12, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(ct_min, -1), be_const_var(1) }, - { be_const_key_weak(shadow_ct, 8), be_const_var(0) }, - { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(268, -1), be_const_int(2) }, - })) ) } )) }, - { be_const_key_weak(ct_max, 7), be_const_var(2) }, - { be_const_key_weak(TYPE, 0), be_nested_str_weak(light2) }, - { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Light2_read_attribute_closure) }, - { be_const_key_weak(NAME, 5), be_nested_str_weak(Light_X202_X20CT) }, - { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Light2_init_closure) }, - { be_const_key_weak(update_shadow, 4), be_const_closure(Matter_Plugin_Light2_update_shadow_closure) }, - { be_const_key_weak(update_ct_minmax, -1), be_const_closure(Matter_Plugin_Light2_update_ct_minmax_closure) }, - { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(768, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(7, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(7), - be_const_int(8), - be_const_int(15), - be_const_int(16395), - be_const_int(16396), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Light2_invoke_request_closure) }, - })), - be_str_weak(Matter_Plugin_Light2) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Light2_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Light2); - be_setglobal(vm, "Matter_Plugin_Light2"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Light3.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Light3.h deleted file mode 100644 index abfb7e030856..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Light3.h +++ /dev/null @@ -1,537 +0,0 @@ -/* Solidification of Matter_Plugin_Light3.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Light3; - -/******************************************************************** -** Solidified function: update_shadow -********************************************************************/ -be_local_closure(Matter_Plugin_Light3_update_shadow, /* name */ - be_nested_proto( - 12, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ - /* K0 */ be_nested_str_weak(light), - /* K1 */ be_nested_str_weak(update_shadow), - /* K2 */ be_nested_str_weak(get), - /* K3 */ be_nested_str_weak(find), - /* K4 */ be_nested_str_weak(hue), - /* K5 */ be_nested_str_weak(sat), - /* K6 */ be_nested_str_weak(tasmota), - /* K7 */ be_nested_str_weak(scale_uint), - /* K8 */ be_const_int(0), - /* K9 */ be_nested_str_weak(shadow_hue), - /* K10 */ be_nested_str_weak(shadow_sat), - /* K11 */ be_nested_str_weak(attribute_updated), - /* K12 */ be_const_int(1), - }), - be_str_weak(update_shadow), - &be_const_str_solidified, - ( &(const binstruction[61]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x60080003, // 0001 GETGBL R2 G3 - 0x5C0C0000, // 0002 MOVE R3 R0 - 0x7C080200, // 0003 CALL R2 1 - 0x8C080501, // 0004 GETMET R2 R2 K1 - 0x7C080200, // 0005 CALL R2 1 - 0x8C080302, // 0006 GETMET R2 R1 K2 - 0x7C080200, // 0007 CALL R2 1 - 0x8C0C0503, // 0008 GETMET R3 R2 K3 - 0x58140004, // 0009 LDCONST R5 K4 - 0x4C180000, // 000A LDNIL R6 - 0x7C0C0600, // 000B CALL R3 3 - 0x8C100503, // 000C GETMET R4 R2 K3 - 0x58180005, // 000D LDCONST R6 K5 - 0x4C1C0000, // 000E LDNIL R7 - 0x7C100600, // 000F CALL R4 3 - 0x4C140000, // 0010 LDNIL R5 - 0x20140605, // 0011 NE R5 R3 R5 - 0x78160009, // 0012 JMPF R5 #001D - 0xB8160C00, // 0013 GETNGBL R5 K6 - 0x8C140B07, // 0014 GETMET R5 R5 K7 - 0x5C1C0600, // 0015 MOVE R7 R3 - 0x58200008, // 0016 LDCONST R8 K8 - 0x54260167, // 0017 LDINT R9 360 - 0x58280008, // 0018 LDCONST R10 K8 - 0x542E00FD, // 0019 LDINT R11 254 - 0x7C140C00, // 001A CALL R5 6 - 0x5C0C0A00, // 001B MOVE R3 R5 - 0x70020000, // 001C JMP #001E - 0x880C0109, // 001D GETMBR R3 R0 K9 - 0x4C140000, // 001E LDNIL R5 - 0x20140805, // 001F NE R5 R4 R5 - 0x78160009, // 0020 JMPF R5 #002B - 0xB8160C00, // 0021 GETNGBL R5 K6 - 0x8C140B07, // 0022 GETMET R5 R5 K7 - 0x5C1C0800, // 0023 MOVE R7 R4 - 0x58200008, // 0024 LDCONST R8 K8 - 0x542600FE, // 0025 LDINT R9 255 - 0x58280008, // 0026 LDCONST R10 K8 - 0x542E00FD, // 0027 LDINT R11 254 - 0x7C140C00, // 0028 CALL R5 6 - 0x5C100A00, // 0029 MOVE R4 R5 - 0x70020000, // 002A JMP #002C - 0x8810010A, // 002B GETMBR R4 R0 K10 - 0x88140109, // 002C GETMBR R5 R0 K9 - 0x20140605, // 002D NE R5 R3 R5 - 0x78160004, // 002E JMPF R5 #0034 - 0x8C14010B, // 002F GETMET R5 R0 K11 - 0x541E02FF, // 0030 LDINT R7 768 - 0x58200008, // 0031 LDCONST R8 K8 - 0x7C140600, // 0032 CALL R5 3 - 0x90021203, // 0033 SETMBR R0 K9 R3 - 0x8814010A, // 0034 GETMBR R5 R0 K10 - 0x20140805, // 0035 NE R5 R4 R5 - 0x78160004, // 0036 JMPF R5 #003C - 0x8C14010B, // 0037 GETMET R5 R0 K11 - 0x541E02FF, // 0038 LDINT R7 768 - 0x5820000C, // 0039 LDCONST R8 K12 - 0x7C140600, // 003A CALL R5 3 - 0x90021404, // 003B SETMBR R0 K10 R4 - 0x80000000, // 003C RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Light3_read_attribute, /* name */ - be_nested_proto( - 11, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[14]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_nested_str_weak(update_shadow_lazy), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(create_TLV), - /* K8 */ be_nested_str_weak(U1), - /* K9 */ be_nested_str_weak(shadow_hue), - /* K10 */ be_const_int(1), - /* K11 */ be_nested_str_weak(shadow_sat), - /* K12 */ be_nested_str_weak(U4), - /* K13 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[107]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x541E02FF, // 0005 LDINT R7 768 - 0x1C1C0A07, // 0006 EQ R7 R5 R7 - 0x781E0059, // 0007 JMPF R7 #0062 - 0x8C1C0105, // 0008 GETMET R7 R0 K5 - 0x7C1C0200, // 0009 CALL R7 1 - 0x1C1C0D06, // 000A EQ R7 R6 K6 - 0x781E0005, // 000B JMPF R7 #0012 - 0x8C1C0907, // 000C GETMET R7 R4 K7 - 0x88240908, // 000D GETMBR R9 R4 K8 - 0x88280109, // 000E GETMBR R10 R0 K9 - 0x7C1C0600, // 000F CALL R7 3 - 0x80040E00, // 0010 RET 1 R7 - 0x7002004E, // 0011 JMP #0061 - 0x1C1C0D0A, // 0012 EQ R7 R6 K10 - 0x781E0005, // 0013 JMPF R7 #001A - 0x8C1C0907, // 0014 GETMET R7 R4 K7 - 0x88240908, // 0015 GETMBR R9 R4 K8 - 0x8828010B, // 0016 GETMBR R10 R0 K11 - 0x7C1C0600, // 0017 CALL R7 3 - 0x80040E00, // 0018 RET 1 R7 - 0x70020046, // 0019 JMP #0061 - 0x541E0006, // 001A LDINT R7 7 - 0x1C1C0C07, // 001B EQ R7 R6 R7 - 0x781E0005, // 001C JMPF R7 #0023 - 0x8C1C0907, // 001D GETMET R7 R4 K7 - 0x88240908, // 001E GETMBR R9 R4 K8 - 0x58280006, // 001F LDCONST R10 K6 - 0x7C1C0600, // 0020 CALL R7 3 - 0x80040E00, // 0021 RET 1 R7 - 0x7002003D, // 0022 JMP #0061 - 0x541E0007, // 0023 LDINT R7 8 - 0x1C1C0C07, // 0024 EQ R7 R6 R7 - 0x781E0005, // 0025 JMPF R7 #002C - 0x8C1C0907, // 0026 GETMET R7 R4 K7 - 0x88240908, // 0027 GETMBR R9 R4 K8 - 0x58280006, // 0028 LDCONST R10 K6 - 0x7C1C0600, // 0029 CALL R7 3 - 0x80040E00, // 002A RET 1 R7 - 0x70020034, // 002B JMP #0061 - 0x541E000E, // 002C LDINT R7 15 - 0x1C1C0C07, // 002D EQ R7 R6 R7 - 0x781E0005, // 002E JMPF R7 #0035 - 0x8C1C0907, // 002F GETMET R7 R4 K7 - 0x88240908, // 0030 GETMBR R9 R4 K8 - 0x58280006, // 0031 LDCONST R10 K6 - 0x7C1C0600, // 0032 CALL R7 3 - 0x80040E00, // 0033 RET 1 R7 - 0x7002002B, // 0034 JMP #0061 - 0x541E4000, // 0035 LDINT R7 16385 - 0x1C1C0C07, // 0036 EQ R7 R6 R7 - 0x781E0005, // 0037 JMPF R7 #003E - 0x8C1C0907, // 0038 GETMET R7 R4 K7 - 0x88240908, // 0039 GETMBR R9 R4 K8 - 0x58280006, // 003A LDCONST R10 K6 - 0x7C1C0600, // 003B CALL R7 3 - 0x80040E00, // 003C RET 1 R7 - 0x70020022, // 003D JMP #0061 - 0x541E4009, // 003E LDINT R7 16394 - 0x1C1C0C07, // 003F EQ R7 R6 R7 - 0x781E0005, // 0040 JMPF R7 #0047 - 0x8C1C0907, // 0041 GETMET R7 R4 K7 - 0x88240908, // 0042 GETMBR R9 R4 K8 - 0x58280006, // 0043 LDCONST R10 K6 - 0x7C1C0600, // 0044 CALL R7 3 - 0x80040E00, // 0045 RET 1 R7 - 0x70020019, // 0046 JMP #0061 - 0x541E000F, // 0047 LDINT R7 16 - 0x1C1C0C07, // 0048 EQ R7 R6 R7 - 0x781E0005, // 0049 JMPF R7 #0050 - 0x8C1C0907, // 004A GETMET R7 R4 K7 - 0x88240908, // 004B GETMBR R9 R4 K8 - 0x58280006, // 004C LDCONST R10 K6 - 0x7C1C0600, // 004D CALL R7 3 - 0x80040E00, // 004E RET 1 R7 - 0x70020010, // 004F JMP #0061 - 0x541EFFFB, // 0050 LDINT R7 65532 - 0x1C1C0C07, // 0051 EQ R7 R6 R7 - 0x781E0005, // 0052 JMPF R7 #0059 - 0x8C1C0907, // 0053 GETMET R7 R4 K7 - 0x8824090C, // 0054 GETMBR R9 R4 K12 - 0x5828000A, // 0055 LDCONST R10 K10 - 0x7C1C0600, // 0056 CALL R7 3 - 0x80040E00, // 0057 RET 1 R7 - 0x70020007, // 0058 JMP #0061 - 0x541EFFFC, // 0059 LDINT R7 65533 - 0x1C1C0C07, // 005A EQ R7 R6 R7 - 0x781E0004, // 005B JMPF R7 #0061 - 0x8C1C0907, // 005C GETMET R7 R4 K7 - 0x8824090C, // 005D GETMBR R9 R4 K12 - 0x542A0004, // 005E LDINT R10 5 - 0x7C1C0600, // 005F CALL R7 3 - 0x80040E00, // 0060 RET 1 R7 - 0x70020007, // 0061 JMP #006A - 0x601C0003, // 0062 GETGBL R7 G3 - 0x5C200000, // 0063 MOVE R8 R0 - 0x7C1C0200, // 0064 CALL R7 1 - 0x8C1C0F0D, // 0065 GETMET R7 R7 K13 - 0x5C240200, // 0066 MOVE R9 R1 - 0x5C280400, // 0067 MOVE R10 R2 - 0x7C1C0600, // 0068 CALL R7 3 - 0x80040E00, // 0069 RET 1 R7 - 0x80000000, // 006A RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Matter_Plugin_Light3_init, /* name */ - be_nested_proto( - 9, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(init), - /* K1 */ be_nested_str_weak(shadow_hue), - /* K2 */ be_const_int(0), - /* K3 */ be_nested_str_weak(shadow_sat), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[11]) { /* code */ - 0x60100003, // 0000 GETGBL R4 G3 - 0x5C140000, // 0001 MOVE R5 R0 - 0x7C100200, // 0002 CALL R4 1 - 0x8C100900, // 0003 GETMET R4 R4 K0 - 0x5C180200, // 0004 MOVE R6 R1 - 0x5C1C0400, // 0005 MOVE R7 R2 - 0x5C200600, // 0006 MOVE R8 R3 - 0x7C100800, // 0007 CALL R4 4 - 0x90020302, // 0008 SETMBR R0 K1 K2 - 0x90020702, // 0009 SETMBR R0 K3 K2 - 0x80000000, // 000A RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: invoke_request -********************************************************************/ -be_local_closure(Matter_Plugin_Light3_invoke_request, /* name */ - be_nested_proto( - 18, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[22]) { /* constants */ - /* K0 */ be_nested_str_weak(light), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(command), - /* K5 */ be_nested_str_weak(update_shadow_lazy), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(findsubval), - /* K8 */ be_nested_str_weak(tasmota), - /* K9 */ be_nested_str_weak(scale_uint), - /* K10 */ be_nested_str_weak(set), - /* K11 */ be_nested_str_weak(hue), - /* K12 */ be_nested_str_weak(update_shadow), - /* K13 */ be_nested_str_weak(log), - /* K14 */ be_nested_str_weak(hue_X3A), - /* K15 */ be_const_int(1), - /* K16 */ be_const_int(2), - /* K17 */ be_const_int(3), - /* K18 */ be_nested_str_weak(sat), - /* K19 */ be_nested_str_weak(sat_X3A), - /* K20 */ be_nested_str_weak(_X20sat_X3A), - /* K21 */ be_nested_str_weak(invoke_request), - }), - be_str_weak(invoke_request), - &be_const_str_solidified, - ( &(const binstruction[150]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0xB8160200, // 0001 GETNGBL R5 K1 - 0x88140B02, // 0002 GETMBR R5 R5 K2 - 0x88180703, // 0003 GETMBR R6 R3 K3 - 0x881C0704, // 0004 GETMBR R7 R3 K4 - 0x542202FF, // 0005 LDINT R8 768 - 0x1C200C08, // 0006 EQ R8 R6 R8 - 0x78220083, // 0007 JMPF R8 #008C - 0x8C200105, // 0008 GETMET R8 R0 K5 - 0x7C200200, // 0009 CALL R8 1 - 0x1C200F06, // 000A EQ R8 R7 K6 - 0x78220019, // 000B JMPF R8 #0026 - 0x8C200507, // 000C GETMET R8 R2 K7 - 0x58280006, // 000D LDCONST R10 K6 - 0x7C200400, // 000E CALL R8 2 - 0xB8261000, // 000F GETNGBL R9 K8 - 0x8C241309, // 0010 GETMET R9 R9 K9 - 0x5C2C1000, // 0011 MOVE R11 R8 - 0x58300006, // 0012 LDCONST R12 K6 - 0x543600FD, // 0013 LDINT R13 254 - 0x58380006, // 0014 LDCONST R14 K6 - 0x543E0167, // 0015 LDINT R15 360 - 0x7C240C00, // 0016 CALL R9 6 - 0x8C28090A, // 0017 GETMET R10 R4 K10 - 0x60300013, // 0018 GETGBL R12 G19 - 0x7C300000, // 0019 CALL R12 0 - 0x98321609, // 001A SETIDX R12 K11 R9 - 0x7C280400, // 001B CALL R10 2 - 0x8C28010C, // 001C GETMET R10 R0 K12 - 0x7C280200, // 001D CALL R10 1 - 0x60280008, // 001E GETGBL R10 G8 - 0x5C2C1000, // 001F MOVE R11 R8 - 0x7C280200, // 0020 CALL R10 1 - 0x002A1C0A, // 0021 ADD R10 K14 R10 - 0x900E1A0A, // 0022 SETMBR R3 K13 R10 - 0x50280200, // 0023 LDBOOL R10 1 0 - 0x80041400, // 0024 RET 1 R10 - 0x70020064, // 0025 JMP #008B - 0x1C200F0F, // 0026 EQ R8 R7 K15 - 0x78220002, // 0027 JMPF R8 #002B - 0x50200200, // 0028 LDBOOL R8 1 0 - 0x80041000, // 0029 RET 1 R8 - 0x7002005F, // 002A JMP #008B - 0x1C200F10, // 002B EQ R8 R7 K16 - 0x78220002, // 002C JMPF R8 #0030 - 0x50200200, // 002D LDBOOL R8 1 0 - 0x80041000, // 002E RET 1 R8 - 0x7002005A, // 002F JMP #008B - 0x1C200F11, // 0030 EQ R8 R7 K17 - 0x78220019, // 0031 JMPF R8 #004C - 0x8C200507, // 0032 GETMET R8 R2 K7 - 0x58280006, // 0033 LDCONST R10 K6 - 0x7C200400, // 0034 CALL R8 2 - 0xB8261000, // 0035 GETNGBL R9 K8 - 0x8C241309, // 0036 GETMET R9 R9 K9 - 0x5C2C1000, // 0037 MOVE R11 R8 - 0x58300006, // 0038 LDCONST R12 K6 - 0x543600FD, // 0039 LDINT R13 254 - 0x58380006, // 003A LDCONST R14 K6 - 0x543E00FE, // 003B LDINT R15 255 - 0x7C240C00, // 003C CALL R9 6 - 0x8C28090A, // 003D GETMET R10 R4 K10 - 0x60300013, // 003E GETGBL R12 G19 - 0x7C300000, // 003F CALL R12 0 - 0x98322409, // 0040 SETIDX R12 K18 R9 - 0x7C280400, // 0041 CALL R10 2 - 0x8C28010C, // 0042 GETMET R10 R0 K12 - 0x7C280200, // 0043 CALL R10 1 - 0x60280008, // 0044 GETGBL R10 G8 - 0x5C2C1000, // 0045 MOVE R11 R8 - 0x7C280200, // 0046 CALL R10 1 - 0x002A260A, // 0047 ADD R10 K19 R10 - 0x900E1A0A, // 0048 SETMBR R3 K13 R10 - 0x50280200, // 0049 LDBOOL R10 1 0 - 0x80041400, // 004A RET 1 R10 - 0x7002003E, // 004B JMP #008B - 0x54220003, // 004C LDINT R8 4 - 0x1C200E08, // 004D EQ R8 R7 R8 - 0x78220002, // 004E JMPF R8 #0052 - 0x50200200, // 004F LDBOOL R8 1 0 - 0x80041000, // 0050 RET 1 R8 - 0x70020038, // 0051 JMP #008B - 0x54220004, // 0052 LDINT R8 5 - 0x1C200E08, // 0053 EQ R8 R7 R8 - 0x78220002, // 0054 JMPF R8 #0058 - 0x50200200, // 0055 LDBOOL R8 1 0 - 0x80041000, // 0056 RET 1 R8 - 0x70020032, // 0057 JMP #008B - 0x54220005, // 0058 LDINT R8 6 - 0x1C200E08, // 0059 EQ R8 R7 R8 - 0x7822002A, // 005A JMPF R8 #0086 - 0x8C200507, // 005B GETMET R8 R2 K7 - 0x58280006, // 005C LDCONST R10 K6 - 0x7C200400, // 005D CALL R8 2 - 0xB8261000, // 005E GETNGBL R9 K8 - 0x8C241309, // 005F GETMET R9 R9 K9 - 0x5C2C1000, // 0060 MOVE R11 R8 - 0x58300006, // 0061 LDCONST R12 K6 - 0x543600FD, // 0062 LDINT R13 254 - 0x58380006, // 0063 LDCONST R14 K6 - 0x543E0167, // 0064 LDINT R15 360 - 0x7C240C00, // 0065 CALL R9 6 - 0x8C280507, // 0066 GETMET R10 R2 K7 - 0x5830000F, // 0067 LDCONST R12 K15 - 0x7C280400, // 0068 CALL R10 2 - 0xB82E1000, // 0069 GETNGBL R11 K8 - 0x8C2C1709, // 006A GETMET R11 R11 K9 - 0x5C341400, // 006B MOVE R13 R10 - 0x58380006, // 006C LDCONST R14 K6 - 0x543E00FD, // 006D LDINT R15 254 - 0x58400006, // 006E LDCONST R16 K6 - 0x544600FE, // 006F LDINT R17 255 - 0x7C2C0C00, // 0070 CALL R11 6 - 0x8C30090A, // 0071 GETMET R12 R4 K10 - 0x60380013, // 0072 GETGBL R14 G19 - 0x7C380000, // 0073 CALL R14 0 - 0x983A1609, // 0074 SETIDX R14 K11 R9 - 0x983A240B, // 0075 SETIDX R14 K18 R11 - 0x7C300400, // 0076 CALL R12 2 - 0x8C30010C, // 0077 GETMET R12 R0 K12 - 0x7C300200, // 0078 CALL R12 1 - 0x60300008, // 0079 GETGBL R12 G8 - 0x5C341000, // 007A MOVE R13 R8 - 0x7C300200, // 007B CALL R12 1 - 0x00321C0C, // 007C ADD R12 K14 R12 - 0x00301914, // 007D ADD R12 R12 K20 - 0x60340008, // 007E GETGBL R13 G8 - 0x5C381400, // 007F MOVE R14 R10 - 0x7C340200, // 0080 CALL R13 1 - 0x0030180D, // 0081 ADD R12 R12 R13 - 0x900E1A0C, // 0082 SETMBR R3 K13 R12 - 0x50300200, // 0083 LDBOOL R12 1 0 - 0x80041800, // 0084 RET 1 R12 - 0x70020004, // 0085 JMP #008B - 0x54220046, // 0086 LDINT R8 71 - 0x1C200E08, // 0087 EQ R8 R7 R8 - 0x78220001, // 0088 JMPF R8 #008B - 0x50200200, // 0089 LDBOOL R8 1 0 - 0x80041000, // 008A RET 1 R8 - 0x70020008, // 008B JMP #0095 - 0x60200003, // 008C GETGBL R8 G3 - 0x5C240000, // 008D MOVE R9 R0 - 0x7C200200, // 008E CALL R8 1 - 0x8C201115, // 008F GETMET R8 R8 K21 - 0x5C280200, // 0090 MOVE R10 R1 - 0x5C2C0400, // 0091 MOVE R11 R2 - 0x5C300600, // 0092 MOVE R12 R3 - 0x7C200800, // 0093 CALL R8 4 - 0x80041000, // 0094 RET 1 R8 - 0x80000000, // 0095 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Light3 -********************************************************************/ -extern const bclass be_class_Matter_Plugin_Light1; -be_local_class(Matter_Plugin_Light3, - 2, - &be_class_Matter_Plugin_Light1, - be_nested_map(10, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(269, -1), be_const_int(2) }, - })) ) } )) }, - { be_const_key_weak(TYPE, -1), be_nested_str_weak(light3) }, - { be_const_key_weak(shadow_hue, 8), be_const_var(0) }, - { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(768, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(9, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(7), - be_const_int(8), - be_const_int(15), - be_const_int(16385), - be_const_int(16394), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(NAME, 3), be_nested_str_weak(Light_X203_X20RGB) }, - { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_Light3_init_closure) }, - { be_const_key_weak(shadow_sat, -1), be_const_var(1) }, - { be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_Light3_invoke_request_closure) }, - { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_Light3_read_attribute_closure) }, - { be_const_key_weak(update_shadow, 1), be_const_closure(Matter_Plugin_Light3_update_shadow_closure) }, - })), - be_str_weak(Matter_Plugin_Light3) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Light3_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Light3); - be_setglobal(vm, "Matter_Plugin_Light3"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_OnOff.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_OnOff.h deleted file mode 100644 index 4d753eca5f64..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_OnOff.h +++ /dev/null @@ -1,389 +0,0 @@ -/* Solidification of Matter_Plugin_OnOff.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_OnOff; - -/******************************************************************** -** Solidified function: -********************************************************************/ -be_local_closure(Matter_Plugin_OnOff__X3Clambda_X3E, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(_X3Clambda_X3E), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x60040009, // 0000 GETGBL R1 G9 - 0x5C080000, // 0001 MOVE R2 R0 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Matter_Plugin_OnOff_init, /* name */ - be_nested_proto( - 9, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(init), - /* K1 */ be_nested_str_weak(shadow_onoff), - /* K2 */ be_nested_str_weak(tasmota_relay_index), - /* K3 */ be_nested_str_weak(find), - /* K4 */ be_nested_str_weak(ARG), - /* K5 */ be_const_int(0), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[20]) { /* code */ - 0x60100003, // 0000 GETGBL R4 G3 - 0x5C140000, // 0001 MOVE R5 R0 - 0x7C100200, // 0002 CALL R4 1 - 0x8C100900, // 0003 GETMET R4 R4 K0 - 0x5C180200, // 0004 MOVE R6 R1 - 0x5C1C0400, // 0005 MOVE R7 R2 - 0x5C200600, // 0006 MOVE R8 R3 - 0x7C100800, // 0007 CALL R4 4 - 0x50100000, // 0008 LDBOOL R4 0 0 - 0x90020204, // 0009 SETMBR R0 K1 R4 - 0x8C100703, // 000A GETMET R4 R3 K3 - 0x88180104, // 000B GETMBR R6 R0 K4 - 0x7C100400, // 000C CALL R4 2 - 0x90020404, // 000D SETMBR R0 K2 R4 - 0x88100102, // 000E GETMBR R4 R0 K2 - 0x4C140000, // 000F LDNIL R5 - 0x1C100805, // 0010 EQ R4 R4 R5 - 0x78120000, // 0011 JMPF R4 #0013 - 0x90020505, // 0012 SETMBR R0 K2 K5 - 0x80000000, // 0013 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_onoff -********************************************************************/ -be_local_closure(Matter_Plugin_OnOff_set_onoff, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(tasmota), - /* K1 */ be_nested_str_weak(set_power), - /* K2 */ be_nested_str_weak(tasmota_relay_index), - /* K3 */ be_nested_str_weak(update_shadow), - }), - be_str_weak(set_onoff), - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0xB80A0000, // 0000 GETNGBL R2 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x88100102, // 0002 GETMBR R4 R0 K2 - 0x60140017, // 0003 GETGBL R5 G23 - 0x5C180200, // 0004 MOVE R6 R1 - 0x7C140200, // 0005 CALL R5 1 - 0x7C080600, // 0006 CALL R2 3 - 0x8C080103, // 0007 GETMET R2 R0 K3 - 0x7C080200, // 0008 CALL R2 1 - 0x80000000, // 0009 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: invoke_request -********************************************************************/ -be_local_closure(Matter_Plugin_OnOff_invoke_request, /* name */ - be_nested_proto( - 10, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ - /* K0 */ be_nested_str_weak(matter), - /* K1 */ be_nested_str_weak(TLV), - /* K2 */ be_nested_str_weak(cluster), - /* K3 */ be_nested_str_weak(command), - /* K4 */ be_nested_str_weak(update_shadow_lazy), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(set_onoff), - /* K7 */ be_nested_str_weak(update_shadow), - /* K8 */ be_const_int(1), - /* K9 */ be_const_int(2), - /* K10 */ be_nested_str_weak(shadow_onoff), - }), - be_str_weak(invoke_request), - &be_const_str_solidified, - ( &(const binstruction[42]) { /* code */ - 0xB8120000, // 0000 GETNGBL R4 K0 - 0x88100901, // 0001 GETMBR R4 R4 K1 - 0x88140702, // 0002 GETMBR R5 R3 K2 - 0x88180703, // 0003 GETMBR R6 R3 K3 - 0x541E0005, // 0004 LDINT R7 6 - 0x1C1C0A07, // 0005 EQ R7 R5 R7 - 0x781E0021, // 0006 JMPF R7 #0029 - 0x8C1C0104, // 0007 GETMET R7 R0 K4 - 0x7C1C0200, // 0008 CALL R7 1 - 0x1C1C0D05, // 0009 EQ R7 R6 K5 - 0x781E0007, // 000A JMPF R7 #0013 - 0x8C1C0106, // 000B GETMET R7 R0 K6 - 0x50240000, // 000C LDBOOL R9 0 0 - 0x7C1C0400, // 000D CALL R7 2 - 0x8C1C0107, // 000E GETMET R7 R0 K7 - 0x7C1C0200, // 000F CALL R7 1 - 0x501C0200, // 0010 LDBOOL R7 1 0 - 0x80040E00, // 0011 RET 1 R7 - 0x70020015, // 0012 JMP #0029 - 0x1C1C0D08, // 0013 EQ R7 R6 K8 - 0x781E0007, // 0014 JMPF R7 #001D - 0x8C1C0106, // 0015 GETMET R7 R0 K6 - 0x50240200, // 0016 LDBOOL R9 1 0 - 0x7C1C0400, // 0017 CALL R7 2 - 0x8C1C0107, // 0018 GETMET R7 R0 K7 - 0x7C1C0200, // 0019 CALL R7 1 - 0x501C0200, // 001A LDBOOL R7 1 0 - 0x80040E00, // 001B RET 1 R7 - 0x7002000B, // 001C JMP #0029 - 0x1C1C0D09, // 001D EQ R7 R6 K9 - 0x781E0009, // 001E JMPF R7 #0029 - 0x8C1C0106, // 001F GETMET R7 R0 K6 - 0x8824010A, // 0020 GETMBR R9 R0 K10 - 0x78260000, // 0021 JMPF R9 #0023 - 0x50240001, // 0022 LDBOOL R9 0 1 - 0x50240200, // 0023 LDBOOL R9 1 0 - 0x7C1C0400, // 0024 CALL R7 2 - 0x8C1C0107, // 0025 GETMET R7 R0 K7 - 0x7C1C0200, // 0026 CALL R7 1 - 0x501C0200, // 0027 LDBOOL R7 1 0 - 0x80040E00, // 0028 RET 1 R7 - 0x80000000, // 0029 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_OnOff_read_attribute, /* name */ - be_nested_proto( - 11, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[12]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_nested_str_weak(update_shadow_lazy), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(create_TLV), - /* K8 */ be_nested_str_weak(BOOL), - /* K9 */ be_nested_str_weak(shadow_onoff), - /* K10 */ be_nested_str_weak(U4), - /* K11 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[45]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x541E0005, // 0005 LDINT R7 6 - 0x1C1C0A07, // 0006 EQ R7 R5 R7 - 0x781E001B, // 0007 JMPF R7 #0024 - 0x8C1C0105, // 0008 GETMET R7 R0 K5 - 0x7C1C0200, // 0009 CALL R7 1 - 0x1C1C0D06, // 000A EQ R7 R6 K6 - 0x781E0005, // 000B JMPF R7 #0012 - 0x8C1C0907, // 000C GETMET R7 R4 K7 - 0x88240908, // 000D GETMBR R9 R4 K8 - 0x88280109, // 000E GETMBR R10 R0 K9 - 0x7C1C0600, // 000F CALL R7 3 - 0x80040E00, // 0010 RET 1 R7 - 0x70020010, // 0011 JMP #0023 - 0x541EFFFB, // 0012 LDINT R7 65532 - 0x1C1C0C07, // 0013 EQ R7 R6 R7 - 0x781E0005, // 0014 JMPF R7 #001B - 0x8C1C0907, // 0015 GETMET R7 R4 K7 - 0x8824090A, // 0016 GETMBR R9 R4 K10 - 0x58280006, // 0017 LDCONST R10 K6 - 0x7C1C0600, // 0018 CALL R7 3 - 0x80040E00, // 0019 RET 1 R7 - 0x70020007, // 001A JMP #0023 - 0x541EFFFC, // 001B LDINT R7 65533 - 0x1C1C0C07, // 001C EQ R7 R6 R7 - 0x781E0004, // 001D JMPF R7 #0023 - 0x8C1C0907, // 001E GETMET R7 R4 K7 - 0x8824090A, // 001F GETMBR R9 R4 K10 - 0x542A0003, // 0020 LDINT R10 4 - 0x7C1C0600, // 0021 CALL R7 3 - 0x80040E00, // 0022 RET 1 R7 - 0x70020007, // 0023 JMP #002C - 0x601C0003, // 0024 GETGBL R7 G3 - 0x5C200000, // 0025 MOVE R8 R0 - 0x7C1C0200, // 0026 CALL R7 1 - 0x8C1C0F0B, // 0027 GETMET R7 R7 K11 - 0x5C240200, // 0028 MOVE R9 R1 - 0x5C280400, // 0029 MOVE R10 R2 - 0x7C1C0600, // 002A CALL R7 3 - 0x80040E00, // 002B RET 1 R7 - 0x80000000, // 002C RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: update_shadow -********************************************************************/ -be_local_closure(Matter_Plugin_OnOff_update_shadow, /* name */ - be_nested_proto( - 6, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str_weak(tasmota), - /* K1 */ be_nested_str_weak(get_power), - /* K2 */ be_nested_str_weak(tasmota_relay_index), - /* K3 */ be_nested_str_weak(shadow_onoff), - /* K4 */ be_nested_str_weak(attribute_updated), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(update_shadow), - }), - be_str_weak(update_shadow), - &be_const_str_solidified, - ( &(const binstruction[28]) { /* code */ - 0xB8060000, // 0000 GETNGBL R1 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x880C0102, // 0002 GETMBR R3 R0 K2 - 0x7C040400, // 0003 CALL R1 2 - 0x4C080000, // 0004 LDNIL R2 - 0x20080202, // 0005 NE R2 R1 R2 - 0x780A000E, // 0006 JMPF R2 #0016 - 0x88080103, // 0007 GETMBR R2 R0 K3 - 0x4C0C0000, // 0008 LDNIL R3 - 0x20080403, // 0009 NE R2 R2 R3 - 0x780A0009, // 000A JMPF R2 #0015 - 0x88080103, // 000B GETMBR R2 R0 K3 - 0x600C0017, // 000C GETGBL R3 G23 - 0x5C100200, // 000D MOVE R4 R1 - 0x7C0C0200, // 000E CALL R3 1 - 0x20080403, // 000F NE R2 R2 R3 - 0x780A0003, // 0010 JMPF R2 #0015 - 0x8C080104, // 0011 GETMET R2 R0 K4 - 0x54120005, // 0012 LDINT R4 6 - 0x58140005, // 0013 LDCONST R5 K5 - 0x7C080600, // 0014 CALL R2 3 - 0x90020601, // 0015 SETMBR R0 K3 R1 - 0x60080003, // 0016 GETGBL R2 G3 - 0x5C0C0000, // 0017 MOVE R3 R0 - 0x7C080200, // 0018 CALL R2 1 - 0x8C080506, // 0019 GETMET R2 R2 K6 - 0x7C080200, // 001A CALL R2 1 - 0x80000000, // 001B RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_OnOff -********************************************************************/ -extern const bclass be_class_Matter_Plugin_Device; -be_local_class(Matter_Plugin_OnOff, - 2, - &be_class_Matter_Plugin_Device, - be_nested_map(14, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(CLUSTERS, 11), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(6, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(3, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(ARG, -1), be_nested_str_weak(relay) }, - { be_const_key_weak(UPDATE_TIME, 13), be_const_int(250) }, - { be_const_key_weak(TYPE, -1), be_nested_str_weak(relay) }, - { be_const_key_weak(update_shadow, -1), be_const_closure(Matter_Plugin_OnOff_update_shadow_closure) }, - { be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_OnOff_init_closure) }, - { be_const_key_weak(set_onoff, 12), be_const_closure(Matter_Plugin_OnOff_set_onoff_closure) }, - { be_const_key_weak(invoke_request, 4), be_const_closure(Matter_Plugin_OnOff_invoke_request_closure) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak(Relay) }, - { be_const_key_weak(tasmota_relay_index, -1), be_const_var(0) }, - { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(266, -1), be_const_int(2) }, - })) ) } )) }, - { be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_OnOff_read_attribute_closure) }, - { be_const_key_weak(shadow_onoff, -1), be_const_var(1) }, - { be_const_key_weak(ARG_TYPE, -1), be_const_static_closure(Matter_Plugin_OnOff__X3Clambda_X3E_closure) }, - })), - be_str_weak(Matter_Plugin_OnOff) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_OnOff_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_OnOff); - be_setglobal(vm, "Matter_Plugin_OnOff"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Root.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Root.h deleted file mode 100644 index 2e52225b9c30..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Root.h +++ /dev/null @@ -1,2202 +0,0 @@ -/* Solidification of Matter_Plugin_Root.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Root; - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Matter_Plugin_Root_init, /* name */ - be_nested_proto( - 9, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(init), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x60100003, // 0000 GETGBL R4 G3 - 0x5C140000, // 0001 MOVE R5 R0 - 0x7C100200, // 0002 CALL R4 1 - 0x8C100900, // 0003 GETMET R4 R4 K0 - 0x5C180200, // 0004 MOVE R6 R1 - 0x5C1C0400, // 0005 MOVE R7 R2 - 0x5C200600, // 0006 MOVE R8 R3 - 0x7C100800, // 0007 CALL R4 4 - 0x80000000, // 0008 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: write_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Root_write_attribute, /* name */ - be_nested_proto( - 12, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[14]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(int), - /* K7 */ be_nested_str_weak(int64), - /* K8 */ be_nested_str_weak(_breadcrumb), - /* K9 */ be_nested_str_weak(attribute_updated), - /* K10 */ be_nested_str_weak(status), - /* K11 */ be_nested_str_weak(CONSTRAINT_ERROR), - /* K12 */ be_const_int(1), - /* K13 */ be_nested_str_weak(INVALID_ACTION), - }), - be_str_weak(write_attribute), - &be_const_str_solidified, - ( &(const binstruction[101]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0xB8160200, // 0001 GETNGBL R5 K1 - 0x88140B02, // 0002 GETMBR R5 R5 K2 - 0x88180503, // 0003 GETMBR R6 R2 K3 - 0x881C0504, // 0004 GETMBR R7 R2 K4 - 0x5422002F, // 0005 LDINT R8 48 - 0x1C200C08, // 0006 EQ R8 R6 R8 - 0x78220019, // 0007 JMPF R8 #0022 - 0x1C200F05, // 0008 EQ R8 R7 K5 - 0x78220016, // 0009 JMPF R8 #0021 - 0x60200004, // 000A GETGBL R8 G4 - 0x5C240600, // 000B MOVE R9 R3 - 0x7C200200, // 000C CALL R8 1 - 0x1C201106, // 000D EQ R8 R8 K6 - 0x74220004, // 000E JMPT R8 #0014 - 0x6020000F, // 000F GETGBL R8 G15 - 0x5C240600, // 0010 MOVE R9 R3 - 0xB82A0E00, // 0011 GETNGBL R10 K7 - 0x7C200400, // 0012 CALL R8 2 - 0x78220007, // 0013 JMPF R8 #001C - 0x90061003, // 0014 SETMBR R1 K8 R3 - 0x8C200109, // 0015 GETMET R8 R0 K9 - 0x88280503, // 0016 GETMBR R10 R2 K3 - 0x882C0504, // 0017 GETMBR R11 R2 K4 - 0x7C200600, // 0018 CALL R8 3 - 0x50200200, // 0019 LDBOOL R8 1 0 - 0x80041000, // 001A RET 1 R8 - 0x70020004, // 001B JMP #0021 - 0xB8220200, // 001C GETNGBL R8 K1 - 0x8820110B, // 001D GETMBR R8 R8 K11 - 0x900A1408, // 001E SETMBR R2 K10 R8 - 0x50200000, // 001F LDBOOL R8 0 0 - 0x80041000, // 0020 RET 1 R8 - 0x70020041, // 0021 JMP #0064 - 0x5422001E, // 0022 LDINT R8 31 - 0x1C200C08, // 0023 EQ R8 R6 R8 - 0x78220004, // 0024 JMPF R8 #002A - 0x1C200F05, // 0025 EQ R8 R7 K5 - 0x78220001, // 0026 JMPF R8 #0029 - 0x50200200, // 0027 LDBOOL R8 1 0 - 0x80041000, // 0028 RET 1 R8 - 0x70020039, // 0029 JMP #0064 - 0x54220027, // 002A LDINT R8 40 - 0x1C200C08, // 002B EQ R8 R6 R8 - 0x7822000B, // 002C JMPF R8 #0039 - 0x54220004, // 002D LDINT R8 5 - 0x1C200E08, // 002E EQ R8 R7 R8 - 0x78220002, // 002F JMPF R8 #0033 - 0x50200200, // 0030 LDBOOL R8 1 0 - 0x80041000, // 0031 RET 1 R8 - 0x70020004, // 0032 JMP #0038 - 0x54220005, // 0033 LDINT R8 6 - 0x1C200E08, // 0034 EQ R8 R7 R8 - 0x78220001, // 0035 JMPF R8 #0038 - 0x50200200, // 0036 LDBOOL R8 1 0 - 0x80041000, // 0037 RET 1 R8 - 0x7002002A, // 0038 JMP #0064 - 0x54220029, // 0039 LDINT R8 42 - 0x1C200C08, // 003A EQ R8 R6 R8 - 0x78220004, // 003B JMPF R8 #0041 - 0x1C200F05, // 003C EQ R8 R7 K5 - 0x78220001, // 003D JMPF R8 #0040 - 0x50200200, // 003E LDBOOL R8 1 0 - 0x80041000, // 003F RET 1 R8 - 0x70020022, // 0040 JMP #0064 - 0x5422002A, // 0041 LDINT R8 43 - 0x1C200C08, // 0042 EQ R8 R6 R8 - 0x78220007, // 0043 JMPF R8 #004C - 0x1C200F05, // 0044 EQ R8 R7 K5 - 0x78220004, // 0045 JMPF R8 #004B - 0xB8220200, // 0046 GETNGBL R8 K1 - 0x8820110B, // 0047 GETMBR R8 R8 K11 - 0x900A1408, // 0048 SETMBR R2 K10 R8 - 0x50200000, // 0049 LDBOOL R8 0 0 - 0x80041000, // 004A RET 1 R8 - 0x70020017, // 004B JMP #0064 - 0x5422002B, // 004C LDINT R8 44 - 0x1C200C08, // 004D EQ R8 R6 R8 - 0x78220009, // 004E JMPF R8 #0059 - 0x1C200F05, // 004F EQ R8 R7 K5 - 0x78220002, // 0050 JMPF R8 #0054 - 0x50200200, // 0051 LDBOOL R8 1 0 - 0x80041000, // 0052 RET 1 R8 - 0x70020003, // 0053 JMP #0058 - 0x1C200F0C, // 0054 EQ R8 R7 K12 - 0x78220001, // 0055 JMPF R8 #0058 - 0x50200200, // 0056 LDBOOL R8 1 0 - 0x80041000, // 0057 RET 1 R8 - 0x7002000A, // 0058 JMP #0064 - 0x54220030, // 0059 LDINT R8 49 - 0x1C200C08, // 005A EQ R8 R6 R8 - 0x78220007, // 005B JMPF R8 #0064 - 0x54220003, // 005C LDINT R8 4 - 0x1C200E08, // 005D EQ R8 R7 R8 - 0x78220004, // 005E JMPF R8 #0064 - 0xB8220200, // 005F GETNGBL R8 K1 - 0x8820110D, // 0060 GETMBR R8 R8 K13 - 0x900A1408, // 0061 SETMBR R2 K10 R8 - 0x50200000, // 0062 LDBOOL R8 0 0 - 0x80041000, // 0063 RET 1 R8 - 0x80000000, // 0064 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Root_read_attribute, /* name */ - be_nested_proto( - 24, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[87]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(create_TLV), - /* K7 */ be_nested_str_weak(U8), - /* K8 */ be_nested_str_weak(_breadcrumb), - /* K9 */ be_const_int(1), - /* K10 */ be_nested_str_weak(Matter_TLV_struct), - /* K11 */ be_nested_str_weak(add_TLV), - /* K12 */ be_nested_str_weak(U2), - /* K13 */ be_const_int(2), - /* K14 */ be_nested_str_weak(U1), - /* K15 */ be_const_int(3), - /* K16 */ be_nested_str_weak(BOOL), - /* K17 */ be_nested_str_weak(Matter_TLV_array), - /* K18 */ be_nested_str_weak(tasmota), - /* K19 */ be_nested_str_weak(eth), - /* K20 */ be_nested_str_weak(up), - /* K21 */ be_nested_str_weak(add_struct), - /* K22 */ be_nested_str_weak(UTF1), - /* K23 */ be_nested_str_weak(ethernet), - /* K24 */ be_nested_str_weak(NULL), - /* K25 */ be_nested_str_weak(fromhex), - /* K26 */ be_nested_str_weak(replace), - /* K27 */ be_nested_str_weak(find), - /* K28 */ be_nested_str_weak(mac), - /* K29 */ be_nested_str_weak(), - /* K30 */ be_nested_str_weak(_X3A), - /* K31 */ be_nested_str_weak(B1), - /* K32 */ be_nested_str_weak(add_array), - /* K33 */ be_nested_str_weak(get_ip_bytes), - /* K34 */ be_nested_str_weak(ip), - /* K35 */ be_nested_str_weak(ip6local), - /* K36 */ be_nested_str_weak(ip6), - /* K37 */ be_nested_str_weak(wifi), - /* K38 */ be_nested_str_weak(cmd), - /* K39 */ be_nested_str_weak(Status_X201), - /* K40 */ be_nested_str_weak(StatusPRM), - /* K41 */ be_nested_str_weak(BootCount), - /* K42 */ be_nested_str_weak(U4), - /* K43 */ be_nested_str_weak(Status_X2011), - /* K44 */ be_nested_str_weak(StatusSTS), - /* K45 */ be_nested_str_weak(UptimeSec), - /* K46 */ be_nested_str_weak(int64), - /* K47 */ be_nested_str_weak(rtc), - /* K48 */ be_nested_str_weak(utc), - /* K49 */ be_const_int(1000000), - /* K50 */ be_nested_str_weak(local), - /* K51 */ be_nested_str_weak(device), - /* K52 */ be_nested_str_weak(sessions), - /* K53 */ be_nested_str_weak(active_fabrics), - /* K54 */ be_nested_str_weak(B2), - /* K55 */ be_nested_str_weak(get_noc), - /* K56 */ be_nested_str_weak(get_icac), - /* K57 */ be_nested_str_weak(get_fabric_index), - /* K58 */ be_nested_str_weak(stop_iteration), - /* K59 */ be_nested_str_weak(parse), - /* K60 */ be_nested_str_weak(get_ca), - /* K61 */ be_nested_str_weak(findsubval), - /* K62 */ be_nested_str_weak(get_admin_vendor), - /* K63 */ be_nested_str_weak(get_fabric_id), - /* K64 */ be_nested_str_weak(get_device_id), - /* K65 */ be_nested_str_weak(get_fabric_label), - /* K66 */ be_nested_str_weak(Fabric), - /* K67 */ be_nested_str_weak(_MAX_CASE), - /* K68 */ be_nested_str_weak(count_active_fabrics), - /* K69 */ be_nested_str_weak(_fabric), - /* K70 */ be_nested_str_weak(is_commissioning_open), - /* K71 */ be_nested_str_weak(is_root_commissioning_open), - /* K72 */ be_nested_str_weak(commissioning_admin_fabric), - /* K73 */ be_nested_str_weak(Tasmota), - /* K74 */ be_nested_str_weak(vendorid), - /* K75 */ be_nested_str_weak(DeviceName), - /* K76 */ be_nested_str_weak(FriendlyName), - /* K77 */ be_nested_str_weak(FriendlyName1), - /* K78 */ be_nested_str_weak(XX), - /* K79 */ be_nested_str_weak(Status_X202), - /* K80 */ be_nested_str_weak(StatusFWR), - /* K81 */ be_nested_str_weak(Hardware), - /* K82 */ be_nested_str_weak(Version), - /* K83 */ be_nested_str_weak(_X28), - /* K84 */ be_nested_str_weak(locale), - /* K85 */ be_nested_str_weak(get_active_endpoints), - /* K86 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[888]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x541E002F, // 0005 LDINT R7 48 - 0x1C1C0A07, // 0006 EQ R7 R5 R7 - 0x781E0030, // 0007 JMPF R7 #0039 - 0x1C1C0D05, // 0008 EQ R7 R6 K5 - 0x781E0005, // 0009 JMPF R7 #0010 - 0x8C1C0906, // 000A GETMET R7 R4 K6 - 0x88240907, // 000B GETMBR R9 R4 K7 - 0x88280308, // 000C GETMBR R10 R1 K8 - 0x7C1C0600, // 000D CALL R7 3 - 0x80040E00, // 000E RET 1 R7 - 0x70020027, // 000F JMP #0038 - 0x1C1C0D09, // 0010 EQ R7 R6 K9 - 0x781E000D, // 0011 JMPF R7 #0020 - 0x8C1C090A, // 0012 GETMET R7 R4 K10 - 0x7C1C0200, // 0013 CALL R7 1 - 0x8C200F0B, // 0014 GETMET R8 R7 K11 - 0x58280005, // 0015 LDCONST R10 K5 - 0x882C090C, // 0016 GETMBR R11 R4 K12 - 0x5432003B, // 0017 LDINT R12 60 - 0x7C200800, // 0018 CALL R8 4 - 0x8C200F0B, // 0019 GETMET R8 R7 K11 - 0x58280009, // 001A LDCONST R10 K9 - 0x882C090C, // 001B GETMBR R11 R4 K12 - 0x54320383, // 001C LDINT R12 900 - 0x7C200800, // 001D CALL R8 4 - 0x80040E00, // 001E RET 1 R7 - 0x70020017, // 001F JMP #0038 - 0x1C1C0D0D, // 0020 EQ R7 R6 K13 - 0x781E0005, // 0021 JMPF R7 #0028 - 0x8C1C0906, // 0022 GETMET R7 R4 K6 - 0x8824090E, // 0023 GETMBR R9 R4 K14 - 0x5828000D, // 0024 LDCONST R10 K13 - 0x7C1C0600, // 0025 CALL R7 3 - 0x80040E00, // 0026 RET 1 R7 - 0x7002000F, // 0027 JMP #0038 - 0x1C1C0D0F, // 0028 EQ R7 R6 K15 - 0x781E0005, // 0029 JMPF R7 #0030 - 0x8C1C0906, // 002A GETMET R7 R4 K6 - 0x8824090E, // 002B GETMBR R9 R4 K14 - 0x5828000D, // 002C LDCONST R10 K13 - 0x7C1C0600, // 002D CALL R7 3 - 0x80040E00, // 002E RET 1 R7 - 0x70020007, // 002F JMP #0038 - 0x541E0003, // 0030 LDINT R7 4 - 0x1C1C0C07, // 0031 EQ R7 R6 R7 - 0x781E0004, // 0032 JMPF R7 #0038 - 0x8C1C0906, // 0033 GETMET R7 R4 K6 - 0x88240910, // 0034 GETMBR R9 R4 K16 - 0x50280000, // 0035 LDBOOL R10 0 0 - 0x7C1C0600, // 0036 CALL R7 3 - 0x80040E00, // 0037 RET 1 R7 - 0x7002033D, // 0038 JMP #0377 - 0x541E0031, // 0039 LDINT R7 50 - 0x1C1C0A07, // 003A EQ R7 R5 R7 - 0x781E0000, // 003B JMPF R7 #003D - 0x70020339, // 003C JMP #0377 - 0x541E0032, // 003D LDINT R7 51 - 0x1C1C0A07, // 003E EQ R7 R5 R7 - 0x781E00DC, // 003F JMPF R7 #011D - 0x1C1C0D05, // 0040 EQ R7 R6 K5 - 0x781E00B5, // 0041 JMPF R7 #00F8 - 0x8C1C0911, // 0042 GETMET R7 R4 K17 - 0x7C1C0200, // 0043 CALL R7 1 - 0xB8222400, // 0044 GETNGBL R8 K18 - 0x8C201113, // 0045 GETMET R8 R8 K19 - 0x7C200200, // 0046 CALL R8 1 - 0x94241114, // 0047 GETIDX R9 R8 K20 - 0x78260053, // 0048 JMPF R9 #009D - 0x8C240F15, // 0049 GETMET R9 R7 K21 - 0x4C2C0000, // 004A LDNIL R11 - 0x7C240400, // 004B CALL R9 2 - 0x8C28130B, // 004C GETMET R10 R9 K11 - 0x58300005, // 004D LDCONST R12 K5 - 0x88340916, // 004E GETMBR R13 R4 K22 - 0x58380017, // 004F LDCONST R14 K23 - 0x7C280800, // 0050 CALL R10 4 - 0x8C28130B, // 0051 GETMET R10 R9 K11 - 0x58300009, // 0052 LDCONST R12 K9 - 0x88340910, // 0053 GETMBR R13 R4 K16 - 0x58380009, // 0054 LDCONST R14 K9 - 0x7C280800, // 0055 CALL R10 4 - 0x8C28130B, // 0056 GETMET R10 R9 K11 - 0x5830000D, // 0057 LDCONST R12 K13 - 0x88340910, // 0058 GETMBR R13 R4 K16 - 0x58380009, // 0059 LDCONST R14 K9 - 0x7C280800, // 005A CALL R10 4 - 0x8C28130B, // 005B GETMET R10 R9 K11 - 0x5830000F, // 005C LDCONST R12 K15 - 0x88340918, // 005D GETMBR R13 R4 K24 - 0x4C380000, // 005E LDNIL R14 - 0x7C280800, // 005F CALL R10 4 - 0x60280015, // 0060 GETGBL R10 G21 - 0x7C280000, // 0061 CALL R10 0 - 0x8C281519, // 0062 GETMET R10 R10 K25 - 0x8C30071A, // 0063 GETMET R12 R3 K26 - 0x8C38111B, // 0064 GETMET R14 R8 K27 - 0x5840001C, // 0065 LDCONST R16 K28 - 0x5844001D, // 0066 LDCONST R17 K29 - 0x7C380600, // 0067 CALL R14 3 - 0x583C001E, // 0068 LDCONST R15 K30 - 0x5840001D, // 0069 LDCONST R16 K29 - 0x7C300800, // 006A CALL R12 4 - 0x7C280400, // 006B CALL R10 2 - 0x8C2C130B, // 006C GETMET R11 R9 K11 - 0x54360003, // 006D LDINT R13 4 - 0x8838091F, // 006E GETMBR R14 R4 K31 - 0x5C3C1400, // 006F MOVE R15 R10 - 0x7C2C0800, // 0070 CALL R11 4 - 0x8C2C1320, // 0071 GETMET R11 R9 K32 - 0x54360004, // 0072 LDINT R13 5 - 0x7C2C0400, // 0073 CALL R11 2 - 0x8C30170B, // 0074 GETMET R12 R11 K11 - 0x4C380000, // 0075 LDNIL R14 - 0x883C091F, // 0076 GETMBR R15 R4 K31 - 0xB8420200, // 0077 GETNGBL R16 K1 - 0x8C402121, // 0078 GETMET R16 R16 K33 - 0x8C48111B, // 0079 GETMET R18 R8 K27 - 0x58500022, // 007A LDCONST R20 K34 - 0x5854001D, // 007B LDCONST R21 K29 - 0x7C480600, // 007C CALL R18 3 - 0x7C400400, // 007D CALL R16 2 - 0x7C300800, // 007E CALL R12 4 - 0x8C301320, // 007F GETMET R12 R9 K32 - 0x543A0005, // 0080 LDINT R14 6 - 0x7C300400, // 0081 CALL R12 2 - 0x8C34190B, // 0082 GETMET R13 R12 K11 - 0x4C3C0000, // 0083 LDNIL R15 - 0x8840091F, // 0084 GETMBR R16 R4 K31 - 0xB8460200, // 0085 GETNGBL R17 K1 - 0x8C442321, // 0086 GETMET R17 R17 K33 - 0x8C4C111B, // 0087 GETMET R19 R8 K27 - 0x58540023, // 0088 LDCONST R21 K35 - 0x5858001D, // 0089 LDCONST R22 K29 - 0x7C4C0600, // 008A CALL R19 3 - 0x7C440400, // 008B CALL R17 2 - 0x7C340800, // 008C CALL R13 4 - 0x8C34190B, // 008D GETMET R13 R12 K11 - 0x4C3C0000, // 008E LDNIL R15 - 0x8840091F, // 008F GETMBR R16 R4 K31 - 0xB8460200, // 0090 GETNGBL R17 K1 - 0x8C442321, // 0091 GETMET R17 R17 K33 - 0x8C4C111B, // 0092 GETMET R19 R8 K27 - 0x58540024, // 0093 LDCONST R21 K36 - 0x5858001D, // 0094 LDCONST R22 K29 - 0x7C4C0600, // 0095 CALL R19 3 - 0x7C440400, // 0096 CALL R17 2 - 0x7C340800, // 0097 CALL R13 4 - 0x8C34130B, // 0098 GETMET R13 R9 K11 - 0x543E0006, // 0099 LDINT R15 7 - 0x8840090E, // 009A GETMBR R16 R4 K14 - 0x5844000D, // 009B LDCONST R17 K13 - 0x7C340800, // 009C CALL R13 4 - 0xB8262400, // 009D GETNGBL R9 K18 - 0x8C241325, // 009E GETMET R9 R9 K37 - 0x7C240200, // 009F CALL R9 1 - 0x94281314, // 00A0 GETIDX R10 R9 K20 - 0x782A0053, // 00A1 JMPF R10 #00F6 - 0x8C280F15, // 00A2 GETMET R10 R7 K21 - 0x4C300000, // 00A3 LDNIL R12 - 0x7C280400, // 00A4 CALL R10 2 - 0x8C2C150B, // 00A5 GETMET R11 R10 K11 - 0x58340005, // 00A6 LDCONST R13 K5 - 0x88380916, // 00A7 GETMBR R14 R4 K22 - 0x583C0025, // 00A8 LDCONST R15 K37 - 0x7C2C0800, // 00A9 CALL R11 4 - 0x8C2C150B, // 00AA GETMET R11 R10 K11 - 0x58340009, // 00AB LDCONST R13 K9 - 0x88380910, // 00AC GETMBR R14 R4 K16 - 0x583C0009, // 00AD LDCONST R15 K9 - 0x7C2C0800, // 00AE CALL R11 4 - 0x8C2C150B, // 00AF GETMET R11 R10 K11 - 0x5834000D, // 00B0 LDCONST R13 K13 - 0x88380910, // 00B1 GETMBR R14 R4 K16 - 0x583C0009, // 00B2 LDCONST R15 K9 - 0x7C2C0800, // 00B3 CALL R11 4 - 0x8C2C150B, // 00B4 GETMET R11 R10 K11 - 0x5834000F, // 00B5 LDCONST R13 K15 - 0x88380918, // 00B6 GETMBR R14 R4 K24 - 0x4C3C0000, // 00B7 LDNIL R15 - 0x7C2C0800, // 00B8 CALL R11 4 - 0x602C0015, // 00B9 GETGBL R11 G21 - 0x7C2C0000, // 00BA CALL R11 0 - 0x8C2C1719, // 00BB GETMET R11 R11 K25 - 0x8C34071A, // 00BC GETMET R13 R3 K26 - 0x8C3C131B, // 00BD GETMET R15 R9 K27 - 0x5844001C, // 00BE LDCONST R17 K28 - 0x5848001D, // 00BF LDCONST R18 K29 - 0x7C3C0600, // 00C0 CALL R15 3 - 0x5840001E, // 00C1 LDCONST R16 K30 - 0x5844001D, // 00C2 LDCONST R17 K29 - 0x7C340800, // 00C3 CALL R13 4 - 0x7C2C0400, // 00C4 CALL R11 2 - 0x8C30150B, // 00C5 GETMET R12 R10 K11 - 0x543A0003, // 00C6 LDINT R14 4 - 0x883C091F, // 00C7 GETMBR R15 R4 K31 - 0x5C401600, // 00C8 MOVE R16 R11 - 0x7C300800, // 00C9 CALL R12 4 - 0x8C301520, // 00CA GETMET R12 R10 K32 - 0x543A0004, // 00CB LDINT R14 5 - 0x7C300400, // 00CC CALL R12 2 - 0x8C34190B, // 00CD GETMET R13 R12 K11 - 0x4C3C0000, // 00CE LDNIL R15 - 0x8840091F, // 00CF GETMBR R16 R4 K31 - 0xB8460200, // 00D0 GETNGBL R17 K1 - 0x8C442321, // 00D1 GETMET R17 R17 K33 - 0x8C4C131B, // 00D2 GETMET R19 R9 K27 - 0x58540022, // 00D3 LDCONST R21 K34 - 0x5858001D, // 00D4 LDCONST R22 K29 - 0x7C4C0600, // 00D5 CALL R19 3 - 0x7C440400, // 00D6 CALL R17 2 - 0x7C340800, // 00D7 CALL R13 4 - 0x8C341520, // 00D8 GETMET R13 R10 K32 - 0x543E0005, // 00D9 LDINT R15 6 - 0x7C340400, // 00DA CALL R13 2 - 0x8C381B0B, // 00DB GETMET R14 R13 K11 - 0x4C400000, // 00DC LDNIL R16 - 0x8844091F, // 00DD GETMBR R17 R4 K31 - 0xB84A0200, // 00DE GETNGBL R18 K1 - 0x8C482521, // 00DF GETMET R18 R18 K33 - 0x8C50131B, // 00E0 GETMET R20 R9 K27 - 0x58580023, // 00E1 LDCONST R22 K35 - 0x585C001D, // 00E2 LDCONST R23 K29 - 0x7C500600, // 00E3 CALL R20 3 - 0x7C480400, // 00E4 CALL R18 2 - 0x7C380800, // 00E5 CALL R14 4 - 0x8C381B0B, // 00E6 GETMET R14 R13 K11 - 0x4C400000, // 00E7 LDNIL R16 - 0x8844091F, // 00E8 GETMBR R17 R4 K31 - 0xB84A0200, // 00E9 GETNGBL R18 K1 - 0x8C482521, // 00EA GETMET R18 R18 K33 - 0x8C50131B, // 00EB GETMET R20 R9 K27 - 0x58580024, // 00EC LDCONST R22 K36 - 0x585C001D, // 00ED LDCONST R23 K29 - 0x7C500600, // 00EE CALL R20 3 - 0x7C480400, // 00EF CALL R18 2 - 0x7C380800, // 00F0 CALL R14 4 - 0x8C38150B, // 00F1 GETMET R14 R10 K11 - 0x54420006, // 00F2 LDINT R16 7 - 0x8844090E, // 00F3 GETMBR R17 R4 K14 - 0x58480009, // 00F4 LDCONST R18 K9 - 0x7C380800, // 00F5 CALL R14 4 - 0x80040E00, // 00F6 RET 1 R7 - 0x70020023, // 00F7 JMP #011C - 0x1C1C0D09, // 00F8 EQ R7 R6 K9 - 0x781E000B, // 00F9 JMPF R7 #0106 - 0x8C1C0906, // 00FA GETMET R7 R4 K6 - 0x8824090C, // 00FB GETMBR R9 R4 K12 - 0xB82A2400, // 00FC GETNGBL R10 K18 - 0x8C281526, // 00FD GETMET R10 R10 K38 - 0x58300027, // 00FE LDCONST R12 K39 - 0x50340200, // 00FF LDBOOL R13 1 0 - 0x7C280600, // 0100 CALL R10 3 - 0x94281528, // 0101 GETIDX R10 R10 K40 - 0x94281529, // 0102 GETIDX R10 R10 K41 - 0x7C1C0600, // 0103 CALL R7 3 - 0x80040E00, // 0104 RET 1 R7 - 0x70020015, // 0105 JMP #011C - 0x1C1C0D0D, // 0106 EQ R7 R6 K13 - 0x781E000B, // 0107 JMPF R7 #0114 - 0x8C1C0906, // 0108 GETMET R7 R4 K6 - 0x8824092A, // 0109 GETMBR R9 R4 K42 - 0xB82A2400, // 010A GETNGBL R10 K18 - 0x8C281526, // 010B GETMET R10 R10 K38 - 0x5830002B, // 010C LDCONST R12 K43 - 0x50340200, // 010D LDBOOL R13 1 0 - 0x7C280600, // 010E CALL R10 3 - 0x9428152C, // 010F GETIDX R10 R10 K44 - 0x9428152D, // 0110 GETIDX R10 R10 K45 - 0x7C1C0600, // 0111 CALL R7 3 - 0x80040E00, // 0112 RET 1 R7 - 0x70020007, // 0113 JMP #011C - 0x541E0007, // 0114 LDINT R7 8 - 0x1C1C0C07, // 0115 EQ R7 R6 R7 - 0x781E0004, // 0116 JMPF R7 #011C - 0x8C1C0906, // 0117 GETMET R7 R4 K6 - 0x88240910, // 0118 GETMBR R9 R4 K16 - 0x50280000, // 0119 LDBOOL R10 0 0 - 0x7C1C0600, // 011A CALL R7 3 - 0x80040E00, // 011B RET 1 R7 - 0x70020259, // 011C JMP #0377 - 0x541E0033, // 011D LDINT R7 52 - 0x1C1C0A07, // 011E EQ R7 R5 R7 - 0x781E0000, // 011F JMPF R7 #0121 - 0x70020255, // 0120 JMP #0377 - 0x541E0037, // 0121 LDINT R7 56 - 0x1C1C0A07, // 0122 EQ R7 R5 R7 - 0x781E002C, // 0123 JMPF R7 #0151 - 0x1C1C0D05, // 0124 EQ R7 R6 K5 - 0x781E000F, // 0125 JMPF R7 #0136 - 0xB81E5C00, // 0126 GETNGBL R7 K46 - 0xB8222400, // 0127 GETNGBL R8 K18 - 0x8C20112F, // 0128 GETMET R8 R8 K47 - 0x7C200200, // 0129 CALL R8 1 - 0x94201130, // 012A GETIDX R8 R8 K48 - 0x7C1C0200, // 012B CALL R7 1 - 0xB8225C00, // 012C GETNGBL R8 K46 - 0x58240031, // 012D LDCONST R9 K49 - 0x7C200200, // 012E CALL R8 1 - 0x081C0E08, // 012F MUL R7 R7 R8 - 0x8C200906, // 0130 GETMET R8 R4 K6 - 0x88280907, // 0131 GETMBR R10 R4 K7 - 0x5C2C0E00, // 0132 MOVE R11 R7 - 0x7C200600, // 0133 CALL R8 3 - 0x80041000, // 0134 RET 1 R8 - 0x70020019, // 0135 JMP #0150 - 0x1C1C0D09, // 0136 EQ R7 R6 K9 - 0x781E0005, // 0137 JMPF R7 #013E - 0x8C1C0906, // 0138 GETMET R7 R4 K6 - 0x8824090E, // 0139 GETMBR R9 R4 K14 - 0x5828000F, // 013A LDCONST R10 K15 - 0x7C1C0600, // 013B CALL R7 3 - 0x80040E00, // 013C RET 1 R7 - 0x70020011, // 013D JMP #0150 - 0x541E0006, // 013E LDINT R7 7 - 0x1C1C0C07, // 013F EQ R7 R6 R7 - 0x781E000E, // 0140 JMPF R7 #0150 - 0xB81E5C00, // 0141 GETNGBL R7 K46 - 0xB8222400, // 0142 GETNGBL R8 K18 - 0x8C20112F, // 0143 GETMET R8 R8 K47 - 0x7C200200, // 0144 CALL R8 1 - 0x94201132, // 0145 GETIDX R8 R8 K50 - 0x7C1C0200, // 0146 CALL R7 1 - 0xB8225C00, // 0147 GETNGBL R8 K46 - 0x58240031, // 0148 LDCONST R9 K49 - 0x7C200200, // 0149 CALL R8 1 - 0x081C0E08, // 014A MUL R7 R7 R8 - 0x8C200906, // 014B GETMET R8 R4 K6 - 0x88280907, // 014C GETMBR R10 R4 K7 - 0x5C2C0E00, // 014D MOVE R11 R7 - 0x7C200600, // 014E CALL R8 3 - 0x80041000, // 014F RET 1 R8 - 0x70020225, // 0150 JMP #0377 - 0x541E003D, // 0151 LDINT R7 62 - 0x1C1C0A07, // 0152 EQ R7 R5 R7 - 0x781E0090, // 0153 JMPF R7 #01E5 - 0x1C1C0D05, // 0154 EQ R7 R6 K5 - 0x781E0025, // 0155 JMPF R7 #017C - 0x8C1C0911, // 0156 GETMET R7 R4 K17 - 0x7C1C0200, // 0157 CALL R7 1 - 0x60200010, // 0158 GETGBL R8 G16 - 0x88240133, // 0159 GETMBR R9 R0 K51 - 0x88241334, // 015A GETMBR R9 R9 K52 - 0x8C241335, // 015B GETMET R9 R9 K53 - 0x7C240200, // 015C CALL R9 1 - 0x7C200200, // 015D CALL R8 1 - 0xA8020017, // 015E EXBLK 0 #0177 - 0x5C241000, // 015F MOVE R9 R8 - 0x7C240000, // 0160 CALL R9 0 - 0x8C280F15, // 0161 GETMET R10 R7 K21 - 0x4C300000, // 0162 LDNIL R12 - 0x7C280400, // 0163 CALL R10 2 - 0x8C2C150B, // 0164 GETMET R11 R10 K11 - 0x58340009, // 0165 LDCONST R13 K9 - 0x88380936, // 0166 GETMBR R14 R4 K54 - 0x8C3C1337, // 0167 GETMET R15 R9 K55 - 0x7C3C0200, // 0168 CALL R15 1 - 0x7C2C0800, // 0169 CALL R11 4 - 0x8C2C150B, // 016A GETMET R11 R10 K11 - 0x5834000D, // 016B LDCONST R13 K13 - 0x88380936, // 016C GETMBR R14 R4 K54 - 0x8C3C1338, // 016D GETMET R15 R9 K56 - 0x7C3C0200, // 016E CALL R15 1 - 0x7C2C0800, // 016F CALL R11 4 - 0x8C2C150B, // 0170 GETMET R11 R10 K11 - 0x543600FD, // 0171 LDINT R13 254 - 0x8838090C, // 0172 GETMBR R14 R4 K12 - 0x8C3C1339, // 0173 GETMET R15 R9 K57 - 0x7C3C0200, // 0174 CALL R15 1 - 0x7C2C0800, // 0175 CALL R11 4 - 0x7001FFE7, // 0176 JMP #015F - 0x5820003A, // 0177 LDCONST R8 K58 - 0xAC200200, // 0178 CATCH R8 1 0 - 0xB0080000, // 0179 RAISE 2 R0 R0 - 0x80040E00, // 017A RET 1 R7 - 0x70020067, // 017B JMP #01E4 - 0x1C1C0D09, // 017C EQ R7 R6 K9 - 0x781E003C, // 017D JMPF R7 #01BB - 0x8C1C0911, // 017E GETMET R7 R4 K17 - 0x7C1C0200, // 017F CALL R7 1 - 0x60200010, // 0180 GETGBL R8 G16 - 0x88240133, // 0181 GETMBR R9 R0 K51 - 0x88241334, // 0182 GETMBR R9 R9 K52 - 0x8C241335, // 0183 GETMET R9 R9 K53 - 0x7C240200, // 0184 CALL R9 1 - 0x7C200200, // 0185 CALL R8 1 - 0xA802002E, // 0186 EXBLK 0 #01B6 - 0x5C241000, // 0187 MOVE R9 R8 - 0x7C240000, // 0188 CALL R9 0 - 0x8C28093B, // 0189 GETMET R10 R4 K59 - 0x8C30133C, // 018A GETMET R12 R9 K60 - 0x7C300200, // 018B CALL R12 1 - 0x7C280400, // 018C CALL R10 2 - 0x8C2C0F15, // 018D GETMET R11 R7 K21 - 0x4C340000, // 018E LDNIL R13 - 0x7C2C0400, // 018F CALL R11 2 - 0x8C30170B, // 0190 GETMET R12 R11 K11 - 0x58380009, // 0191 LDCONST R14 K9 - 0x883C0936, // 0192 GETMBR R15 R4 K54 - 0x8C40153D, // 0193 GETMET R16 R10 K61 - 0x544A0008, // 0194 LDINT R18 9 - 0x7C400400, // 0195 CALL R16 2 - 0x7C300800, // 0196 CALL R12 4 - 0x8C30170B, // 0197 GETMET R12 R11 K11 - 0x5838000D, // 0198 LDCONST R14 K13 - 0x883C090C, // 0199 GETMBR R15 R4 K12 - 0x8C40133E, // 019A GETMET R16 R9 K62 - 0x7C400200, // 019B CALL R16 1 - 0x7C300800, // 019C CALL R12 4 - 0x8C30170B, // 019D GETMET R12 R11 K11 - 0x5838000F, // 019E LDCONST R14 K15 - 0x883C0907, // 019F GETMBR R15 R4 K7 - 0x8C40133F, // 01A0 GETMET R16 R9 K63 - 0x7C400200, // 01A1 CALL R16 1 - 0x7C300800, // 01A2 CALL R12 4 - 0x8C30170B, // 01A3 GETMET R12 R11 K11 - 0x543A0003, // 01A4 LDINT R14 4 - 0x883C0907, // 01A5 GETMBR R15 R4 K7 - 0x8C401340, // 01A6 GETMET R16 R9 K64 - 0x7C400200, // 01A7 CALL R16 1 - 0x7C300800, // 01A8 CALL R12 4 - 0x8C30170B, // 01A9 GETMET R12 R11 K11 - 0x543A0004, // 01AA LDINT R14 5 - 0x883C0916, // 01AB GETMBR R15 R4 K22 - 0x8C401341, // 01AC GETMET R16 R9 K65 - 0x7C400200, // 01AD CALL R16 1 - 0x7C300800, // 01AE CALL R12 4 - 0x8C30170B, // 01AF GETMET R12 R11 K11 - 0x543A00FD, // 01B0 LDINT R14 254 - 0x883C090C, // 01B1 GETMBR R15 R4 K12 - 0x8C401339, // 01B2 GETMET R16 R9 K57 - 0x7C400200, // 01B3 CALL R16 1 - 0x7C300800, // 01B4 CALL R12 4 - 0x7001FFD0, // 01B5 JMP #0187 - 0x5820003A, // 01B6 LDCONST R8 K58 - 0xAC200200, // 01B7 CATCH R8 1 0 - 0xB0080000, // 01B8 RAISE 2 R0 R0 - 0x80040E00, // 01B9 RET 1 R7 - 0x70020028, // 01BA JMP #01E4 - 0x1C1C0D0D, // 01BB EQ R7 R6 K13 - 0x781E0007, // 01BC JMPF R7 #01C5 - 0x8C1C0906, // 01BD GETMET R7 R4 K6 - 0x8824090E, // 01BE GETMBR R9 R4 K14 - 0xB82A0200, // 01BF GETNGBL R10 K1 - 0x88281542, // 01C0 GETMBR R10 R10 K66 - 0x88281543, // 01C1 GETMBR R10 R10 K67 - 0x7C1C0600, // 01C2 CALL R7 3 - 0x80040E00, // 01C3 RET 1 R7 - 0x7002001E, // 01C4 JMP #01E4 - 0x1C1C0D0F, // 01C5 EQ R7 R6 K15 - 0x781E0009, // 01C6 JMPF R7 #01D1 - 0x881C0133, // 01C7 GETMBR R7 R0 K51 - 0x881C0F34, // 01C8 GETMBR R7 R7 K52 - 0x8C1C0F44, // 01C9 GETMET R7 R7 K68 - 0x7C1C0200, // 01CA CALL R7 1 - 0x8C200906, // 01CB GETMET R8 R4 K6 - 0x8828090E, // 01CC GETMBR R10 R4 K14 - 0x5C2C0E00, // 01CD MOVE R11 R7 - 0x7C200600, // 01CE CALL R8 3 - 0x80041000, // 01CF RET 1 R8 - 0x70020012, // 01D0 JMP #01E4 - 0x541E0003, // 01D1 LDINT R7 4 - 0x1C1C0C07, // 01D2 EQ R7 R6 R7 - 0x781E0000, // 01D3 JMPF R7 #01D5 - 0x7002000E, // 01D4 JMP #01E4 - 0x541E0004, // 01D5 LDINT R7 5 - 0x1C1C0C07, // 01D6 EQ R7 R6 R7 - 0x781E000B, // 01D7 JMPF R7 #01E4 - 0x881C0345, // 01D8 GETMBR R7 R1 K69 - 0x8C1C0F39, // 01D9 GETMET R7 R7 K57 - 0x7C1C0200, // 01DA CALL R7 1 - 0x4C200000, // 01DB LDNIL R8 - 0x1C200E08, // 01DC EQ R8 R7 R8 - 0x78220000, // 01DD JMPF R8 #01DF - 0x581C0005, // 01DE LDCONST R7 K5 - 0x8C200906, // 01DF GETMET R8 R4 K6 - 0x8828090E, // 01E0 GETMBR R10 R4 K14 - 0x5C2C0E00, // 01E1 MOVE R11 R7 - 0x7C200600, // 01E2 CALL R8 3 - 0x80041000, // 01E3 RET 1 R8 - 0x70020191, // 01E4 JMP #0377 - 0x541E003B, // 01E5 LDINT R7 60 - 0x1C1C0A07, // 01E6 EQ R7 R5 R7 - 0x781E003C, // 01E7 JMPF R7 #0225 - 0x1C1C0D05, // 01E8 EQ R7 R6 K5 - 0x781E0012, // 01E9 JMPF R7 #01FD - 0x881C0133, // 01EA GETMBR R7 R0 K51 - 0x8C1C0F46, // 01EB GETMET R7 R7 K70 - 0x7C1C0200, // 01EC CALL R7 1 - 0x88200133, // 01ED GETMBR R8 R0 K51 - 0x8C201147, // 01EE GETMET R8 R8 K71 - 0x7C200200, // 01EF CALL R8 1 - 0x781E0004, // 01F0 JMPF R7 #01F6 - 0x78220001, // 01F1 JMPF R8 #01F4 - 0x5824000D, // 01F2 LDCONST R9 K13 - 0x70020000, // 01F3 JMP #01F5 - 0x58240009, // 01F4 LDCONST R9 K9 - 0x70020000, // 01F5 JMP #01F7 - 0x58240005, // 01F6 LDCONST R9 K5 - 0x8C280906, // 01F7 GETMET R10 R4 K6 - 0x8830090E, // 01F8 GETMBR R12 R4 K14 - 0x5C341200, // 01F9 MOVE R13 R9 - 0x7C280600, // 01FA CALL R10 3 - 0x80041400, // 01FB RET 1 R10 - 0x70020026, // 01FC JMP #0224 - 0x1C1C0D09, // 01FD EQ R7 R6 K9 - 0x781E0011, // 01FE JMPF R7 #0211 - 0x881C0133, // 01FF GETMBR R7 R0 K51 - 0x881C0F48, // 0200 GETMBR R7 R7 K72 - 0x4C200000, // 0201 LDNIL R8 - 0x20200E08, // 0202 NE R8 R7 R8 - 0x78220006, // 0203 JMPF R8 #020B - 0x8C200906, // 0204 GETMET R8 R4 K6 - 0x8828090C, // 0205 GETMBR R10 R4 K12 - 0x8C2C0F39, // 0206 GETMET R11 R7 K57 - 0x7C2C0200, // 0207 CALL R11 1 - 0x7C200600, // 0208 CALL R8 3 - 0x80041000, // 0209 RET 1 R8 - 0x70020004, // 020A JMP #0210 - 0x8C200906, // 020B GETMET R8 R4 K6 - 0x88280918, // 020C GETMBR R10 R4 K24 - 0x4C2C0000, // 020D LDNIL R11 - 0x7C200600, // 020E CALL R8 3 - 0x80041000, // 020F RET 1 R8 - 0x70020012, // 0210 JMP #0224 - 0x1C1C0D0D, // 0211 EQ R7 R6 K13 - 0x781E0010, // 0212 JMPF R7 #0224 - 0x881C0133, // 0213 GETMBR R7 R0 K51 - 0x881C0F48, // 0214 GETMBR R7 R7 K72 - 0x4C200000, // 0215 LDNIL R8 - 0x20200E08, // 0216 NE R8 R7 R8 - 0x78220006, // 0217 JMPF R8 #021F - 0x8C200906, // 0218 GETMET R8 R4 K6 - 0x8828090C, // 0219 GETMBR R10 R4 K12 - 0x8C2C0F3E, // 021A GETMET R11 R7 K62 - 0x7C2C0200, // 021B CALL R11 1 - 0x7C200600, // 021C CALL R8 3 - 0x80041000, // 021D RET 1 R8 - 0x70020004, // 021E JMP #0224 - 0x8C200906, // 021F GETMET R8 R4 K6 - 0x88280918, // 0220 GETMBR R10 R4 K24 - 0x4C2C0000, // 0221 LDNIL R11 - 0x7C200600, // 0222 CALL R8 3 - 0x80041000, // 0223 RET 1 R8 - 0x70020151, // 0224 JMP #0377 - 0x541E0027, // 0225 LDINT R7 40 - 0x1C1C0A07, // 0226 EQ R7 R5 R7 - 0x781E00AE, // 0227 JMPF R7 #02D7 - 0x1C1C0D05, // 0228 EQ R7 R6 K5 - 0x781E0005, // 0229 JMPF R7 #0230 - 0x8C1C0906, // 022A GETMET R7 R4 K6 - 0x8824090C, // 022B GETMBR R9 R4 K12 - 0x58280009, // 022C LDCONST R10 K9 - 0x7C1C0600, // 022D CALL R7 3 - 0x80040E00, // 022E RET 1 R7 - 0x700200A5, // 022F JMP #02D6 - 0x1C1C0D09, // 0230 EQ R7 R6 K9 - 0x781E0005, // 0231 JMPF R7 #0238 - 0x8C1C0906, // 0232 GETMET R7 R4 K6 - 0x88240916, // 0233 GETMBR R9 R4 K22 - 0x58280049, // 0234 LDCONST R10 K73 - 0x7C1C0600, // 0235 CALL R7 3 - 0x80040E00, // 0236 RET 1 R7 - 0x7002009D, // 0237 JMP #02D6 - 0x1C1C0D0D, // 0238 EQ R7 R6 K13 - 0x781E0006, // 0239 JMPF R7 #0241 - 0x8C1C0906, // 023A GETMET R7 R4 K6 - 0x8824090C, // 023B GETMBR R9 R4 K12 - 0x88280133, // 023C GETMBR R10 R0 K51 - 0x8828154A, // 023D GETMBR R10 R10 K74 - 0x7C1C0600, // 023E CALL R7 3 - 0x80040E00, // 023F RET 1 R7 - 0x70020094, // 0240 JMP #02D6 - 0x1C1C0D0F, // 0241 EQ R7 R6 K15 - 0x781E000A, // 0242 JMPF R7 #024E - 0x8C1C0906, // 0243 GETMET R7 R4 K6 - 0x88240916, // 0244 GETMBR R9 R4 K22 - 0xB82A2400, // 0245 GETNGBL R10 K18 - 0x8C281526, // 0246 GETMET R10 R10 K38 - 0x5830004B, // 0247 LDCONST R12 K75 - 0x50340200, // 0248 LDBOOL R13 1 0 - 0x7C280600, // 0249 CALL R10 3 - 0x9428154B, // 024A GETIDX R10 R10 K75 - 0x7C1C0600, // 024B CALL R7 3 - 0x80040E00, // 024C RET 1 R7 - 0x70020087, // 024D JMP #02D6 - 0x541E0003, // 024E LDINT R7 4 - 0x1C1C0C07, // 024F EQ R7 R6 R7 - 0x781E0005, // 0250 JMPF R7 #0257 - 0x8C1C0906, // 0251 GETMET R7 R4 K6 - 0x8824090C, // 0252 GETMBR R9 R4 K12 - 0x542A7FFF, // 0253 LDINT R10 32768 - 0x7C1C0600, // 0254 CALL R7 3 - 0x80040E00, // 0255 RET 1 R7 - 0x7002007E, // 0256 JMP #02D6 - 0x541E0004, // 0257 LDINT R7 5 - 0x1C1C0C07, // 0258 EQ R7 R6 R7 - 0x781E000A, // 0259 JMPF R7 #0265 - 0x8C1C0906, // 025A GETMET R7 R4 K6 - 0x88240916, // 025B GETMBR R9 R4 K22 - 0xB82A2400, // 025C GETNGBL R10 K18 - 0x8C281526, // 025D GETMET R10 R10 K38 - 0x5830004C, // 025E LDCONST R12 K76 - 0x50340200, // 025F LDBOOL R13 1 0 - 0x7C280600, // 0260 CALL R10 3 - 0x9428154D, // 0261 GETIDX R10 R10 K77 - 0x7C1C0600, // 0262 CALL R7 3 - 0x80040E00, // 0263 RET 1 R7 - 0x70020070, // 0264 JMP #02D6 - 0x541E0005, // 0265 LDINT R7 6 - 0x1C1C0C07, // 0266 EQ R7 R6 R7 - 0x781E0005, // 0267 JMPF R7 #026E - 0x8C1C0906, // 0268 GETMET R7 R4 K6 - 0x88240916, // 0269 GETMBR R9 R4 K22 - 0x5828004E, // 026A LDCONST R10 K78 - 0x7C1C0600, // 026B CALL R7 3 - 0x80040E00, // 026C RET 1 R7 - 0x70020067, // 026D JMP #02D6 - 0x541E0006, // 026E LDINT R7 7 - 0x1C1C0C07, // 026F EQ R7 R6 R7 - 0x781E0005, // 0270 JMPF R7 #0277 - 0x8C1C0906, // 0271 GETMET R7 R4 K6 - 0x8824090C, // 0272 GETMBR R9 R4 K12 - 0x58280005, // 0273 LDCONST R10 K5 - 0x7C1C0600, // 0274 CALL R7 3 - 0x80040E00, // 0275 RET 1 R7 - 0x7002005E, // 0276 JMP #02D6 - 0x541E0007, // 0277 LDINT R7 8 - 0x1C1C0C07, // 0278 EQ R7 R6 R7 - 0x781E000B, // 0279 JMPF R7 #0286 - 0x8C1C0906, // 027A GETMET R7 R4 K6 - 0x88240916, // 027B GETMBR R9 R4 K22 - 0xB82A2400, // 027C GETNGBL R10 K18 - 0x8C281526, // 027D GETMET R10 R10 K38 - 0x5830004F, // 027E LDCONST R12 K79 - 0x50340200, // 027F LDBOOL R13 1 0 - 0x7C280600, // 0280 CALL R10 3 - 0x94281550, // 0281 GETIDX R10 R10 K80 - 0x94281551, // 0282 GETIDX R10 R10 K81 - 0x7C1C0600, // 0283 CALL R7 3 - 0x80040E00, // 0284 RET 1 R7 - 0x7002004F, // 0285 JMP #02D6 - 0x541E0008, // 0286 LDINT R7 9 - 0x1C1C0C07, // 0287 EQ R7 R6 R7 - 0x781E0005, // 0288 JMPF R7 #028F - 0x8C1C0906, // 0289 GETMET R7 R4 K6 - 0x8824090C, // 028A GETMBR R9 R4 K12 - 0x58280009, // 028B LDCONST R10 K9 - 0x7C1C0600, // 028C CALL R7 3 - 0x80040E00, // 028D RET 1 R7 - 0x70020046, // 028E JMP #02D6 - 0x541E0009, // 028F LDINT R7 10 - 0x1C1C0C07, // 0290 EQ R7 R6 R7 - 0x781E0015, // 0291 JMPF R7 #02A8 - 0xB81E2400, // 0292 GETNGBL R7 K18 - 0x8C1C0F26, // 0293 GETMET R7 R7 K38 - 0x5824004F, // 0294 LDCONST R9 K79 - 0x50280200, // 0295 LDBOOL R10 1 0 - 0x7C1C0600, // 0296 CALL R7 3 - 0x941C0F50, // 0297 GETIDX R7 R7 K80 - 0x941C0F52, // 0298 GETIDX R7 R7 K82 - 0x8C20071B, // 0299 GETMET R8 R3 K27 - 0x5C280E00, // 029A MOVE R10 R7 - 0x582C0053, // 029B LDCONST R11 K83 - 0x7C200600, // 029C CALL R8 3 - 0x24241105, // 029D GT R9 R8 K5 - 0x78260002, // 029E JMPF R9 #02A2 - 0x04241109, // 029F SUB R9 R8 K9 - 0x40260A09, // 02A0 CONNECT R9 K5 R9 - 0x941C0E09, // 02A1 GETIDX R7 R7 R9 - 0x8C240906, // 02A2 GETMET R9 R4 K6 - 0x882C0916, // 02A3 GETMBR R11 R4 K22 - 0x5C300E00, // 02A4 MOVE R12 R7 - 0x7C240600, // 02A5 CALL R9 3 - 0x80041200, // 02A6 RET 1 R9 - 0x7002002D, // 02A7 JMP #02D6 - 0x541E000E, // 02A8 LDINT R7 15 - 0x1C1C0C07, // 02A9 EQ R7 R6 R7 - 0x781E000B, // 02AA JMPF R7 #02B7 - 0x8C1C0906, // 02AB GETMET R7 R4 K6 - 0x88240916, // 02AC GETMBR R9 R4 K22 - 0xB82A2400, // 02AD GETNGBL R10 K18 - 0x8C281525, // 02AE GETMET R10 R10 K37 - 0x7C280200, // 02AF CALL R10 1 - 0x8C28151B, // 02B0 GETMET R10 R10 K27 - 0x5830001C, // 02B1 LDCONST R12 K28 - 0x5834001D, // 02B2 LDCONST R13 K29 - 0x7C280600, // 02B3 CALL R10 3 - 0x7C1C0600, // 02B4 CALL R7 3 - 0x80040E00, // 02B5 RET 1 R7 - 0x7002001E, // 02B6 JMP #02D6 - 0x541E0011, // 02B7 LDINT R7 18 - 0x1C1C0C07, // 02B8 EQ R7 R6 R7 - 0x781E000B, // 02B9 JMPF R7 #02C6 - 0x8C1C0906, // 02BA GETMET R7 R4 K6 - 0x88240916, // 02BB GETMBR R9 R4 K22 - 0xB82A2400, // 02BC GETNGBL R10 K18 - 0x8C281525, // 02BD GETMET R10 R10 K37 - 0x7C280200, // 02BE CALL R10 1 - 0x8C28151B, // 02BF GETMET R10 R10 K27 - 0x5830001C, // 02C0 LDCONST R12 K28 - 0x5834001D, // 02C1 LDCONST R13 K29 - 0x7C280600, // 02C2 CALL R10 3 - 0x7C1C0600, // 02C3 CALL R7 3 - 0x80040E00, // 02C4 RET 1 R7 - 0x7002000F, // 02C5 JMP #02D6 - 0x541E0012, // 02C6 LDINT R7 19 - 0x1C1C0C07, // 02C7 EQ R7 R6 R7 - 0x781E000C, // 02C8 JMPF R7 #02D6 - 0x8C1C090A, // 02C9 GETMET R7 R4 K10 - 0x7C1C0200, // 02CA CALL R7 1 - 0x8C200F0B, // 02CB GETMET R8 R7 K11 - 0x58280005, // 02CC LDCONST R10 K5 - 0x882C090C, // 02CD GETMBR R11 R4 K12 - 0x5830000F, // 02CE LDCONST R12 K15 - 0x7C200800, // 02CF CALL R8 4 - 0x8C200F0B, // 02D0 GETMET R8 R7 K11 - 0x58280009, // 02D1 LDCONST R10 K9 - 0x882C090C, // 02D2 GETMBR R11 R4 K12 - 0x5830000F, // 02D3 LDCONST R12 K15 - 0x7C200800, // 02D4 CALL R8 4 - 0x80040E00, // 02D5 RET 1 R7 - 0x7002009F, // 02D6 JMP #0377 - 0x541E003E, // 02D7 LDINT R7 63 - 0x1C1C0A07, // 02D8 EQ R7 R5 R7 - 0x781E0000, // 02D9 JMPF R7 #02DB - 0x7002009B, // 02DA JMP #0377 - 0x541E0029, // 02DB LDINT R7 42 - 0x1C1C0A07, // 02DC EQ R7 R5 R7 - 0x781E001D, // 02DD JMPF R7 #02FC - 0x1C1C0D05, // 02DE EQ R7 R6 K5 - 0x781E0003, // 02DF JMPF R7 #02E4 - 0x8C1C0911, // 02E0 GETMET R7 R4 K17 - 0x7C1C0200, // 02E1 CALL R7 1 - 0x80040E00, // 02E2 RET 1 R7 - 0x70020016, // 02E3 JMP #02FB - 0x1C1C0D09, // 02E4 EQ R7 R6 K9 - 0x781E0005, // 02E5 JMPF R7 #02EC - 0x8C1C0906, // 02E6 GETMET R7 R4 K6 - 0x88240910, // 02E7 GETMBR R9 R4 K16 - 0x58280005, // 02E8 LDCONST R10 K5 - 0x7C1C0600, // 02E9 CALL R7 3 - 0x80040E00, // 02EA RET 1 R7 - 0x7002000E, // 02EB JMP #02FB - 0x1C1C0D0D, // 02EC EQ R7 R6 K13 - 0x781E0005, // 02ED JMPF R7 #02F4 - 0x8C1C0906, // 02EE GETMET R7 R4 K6 - 0x8824090E, // 02EF GETMBR R9 R4 K14 - 0x58280009, // 02F0 LDCONST R10 K9 - 0x7C1C0600, // 02F1 CALL R7 3 - 0x80040E00, // 02F2 RET 1 R7 - 0x70020006, // 02F3 JMP #02FB - 0x1C1C0D0F, // 02F4 EQ R7 R6 K15 - 0x781E0004, // 02F5 JMPF R7 #02FB - 0x8C1C0906, // 02F6 GETMET R7 R4 K6 - 0x88240918, // 02F7 GETMBR R9 R4 K24 - 0x4C280000, // 02F8 LDNIL R10 - 0x7C1C0600, // 02F9 CALL R7 3 - 0x80040E00, // 02FA RET 1 R7 - 0x7002007A, // 02FB JMP #0377 - 0x541E002A, // 02FC LDINT R7 43 - 0x1C1C0A07, // 02FD EQ R7 R5 R7 - 0x781E0016, // 02FE JMPF R7 #0316 - 0x1C1C0D05, // 02FF EQ R7 R6 K5 - 0x781E0007, // 0300 JMPF R7 #0309 - 0x8C1C0906, // 0301 GETMET R7 R4 K6 - 0x88240916, // 0302 GETMBR R9 R4 K22 - 0xB82A2400, // 0303 GETNGBL R10 K18 - 0x8C281554, // 0304 GETMET R10 R10 K84 - 0x7C280200, // 0305 CALL R10 1 - 0x7C1C0600, // 0306 CALL R7 3 - 0x80040E00, // 0307 RET 1 R7 - 0x7002000B, // 0308 JMP #0315 - 0x1C1C0D09, // 0309 EQ R7 R6 K9 - 0x781E0009, // 030A JMPF R7 #0315 - 0x8C1C0911, // 030B GETMET R7 R4 K17 - 0x7C1C0200, // 030C CALL R7 1 - 0x8C200F0B, // 030D GETMET R8 R7 K11 - 0x4C280000, // 030E LDNIL R10 - 0x882C0916, // 030F GETMBR R11 R4 K22 - 0xB8322400, // 0310 GETNGBL R12 K18 - 0x8C301954, // 0311 GETMET R12 R12 K84 - 0x7C300200, // 0312 CALL R12 1 - 0x7C200800, // 0313 CALL R8 4 - 0x80040E00, // 0314 RET 1 R7 - 0x70020060, // 0315 JMP #0377 - 0x541E002B, // 0316 LDINT R7 44 - 0x1C1C0A07, // 0317 EQ R7 R5 R7 - 0x781E001C, // 0318 JMPF R7 #0336 - 0x1C1C0D05, // 0319 EQ R7 R6 K5 - 0x781E0005, // 031A JMPF R7 #0321 - 0x8C1C0906, // 031B GETMET R7 R4 K6 - 0x8824090E, // 031C GETMBR R9 R4 K14 - 0x58280009, // 031D LDCONST R10 K9 - 0x7C1C0600, // 031E CALL R7 3 - 0x80040E00, // 031F RET 1 R7 - 0x70020013, // 0320 JMP #0335 - 0x1C1C0D09, // 0321 EQ R7 R6 K9 - 0x781E0005, // 0322 JMPF R7 #0329 - 0x8C1C0906, // 0323 GETMET R7 R4 K6 - 0x8824090E, // 0324 GETMBR R9 R4 K14 - 0x542A0003, // 0325 LDINT R10 4 - 0x7C1C0600, // 0326 CALL R7 3 - 0x80040E00, // 0327 RET 1 R7 - 0x7002000B, // 0328 JMP #0335 - 0x1C1C0D0D, // 0329 EQ R7 R6 K13 - 0x781E0009, // 032A JMPF R7 #0335 - 0x8C1C0911, // 032B GETMET R7 R4 K17 - 0x7C1C0200, // 032C CALL R7 1 - 0x8C200F0B, // 032D GETMET R8 R7 K11 - 0x4C280000, // 032E LDNIL R10 - 0x8C2C0906, // 032F GETMET R11 R4 K6 - 0x8834090E, // 0330 GETMBR R13 R4 K14 - 0x543A0003, // 0331 LDINT R14 4 - 0x7C2C0600, // 0332 CALL R11 3 - 0x7C200600, // 0333 CALL R8 3 - 0x80040E00, // 0334 RET 1 R7 - 0x70020040, // 0335 JMP #0377 - 0x541E0030, // 0336 LDINT R7 49 - 0x1C1C0A07, // 0337 EQ R7 R5 R7 - 0x781E0010, // 0338 JMPF R7 #034A - 0x1C1C0D0F, // 0339 EQ R7 R6 K15 - 0x781E0005, // 033A JMPF R7 #0341 - 0x8C1C0906, // 033B GETMET R7 R4 K6 - 0x8824090E, // 033C GETMBR R9 R4 K14 - 0x542A001D, // 033D LDINT R10 30 - 0x7C1C0600, // 033E CALL R7 3 - 0x80040E00, // 033F RET 1 R7 - 0x70020007, // 0340 JMP #0349 - 0x541EFFFB, // 0341 LDINT R7 65532 - 0x1C1C0C07, // 0342 EQ R7 R6 R7 - 0x781E0004, // 0343 JMPF R7 #0349 - 0x8C1C0906, // 0344 GETMET R7 R4 K6 - 0x8824092A, // 0345 GETMBR R9 R4 K42 - 0x542A0003, // 0346 LDINT R10 4 - 0x7C1C0600, // 0347 CALL R7 3 - 0x80040E00, // 0348 RET 1 R7 - 0x7002002C, // 0349 JMP #0377 - 0x541E001C, // 034A LDINT R7 29 - 0x1C1C0A07, // 034B EQ R7 R5 R7 - 0x781E0021, // 034C JMPF R7 #036F - 0x1C1C0D0F, // 034D EQ R7 R6 K15 - 0x781E0016, // 034E JMPF R7 #0366 - 0x8C1C0911, // 034F GETMET R7 R4 K17 - 0x7C1C0200, // 0350 CALL R7 1 - 0x88200133, // 0351 GETMBR R8 R0 K51 - 0x8C201155, // 0352 GETMET R8 R8 K85 - 0x50280200, // 0353 LDBOOL R10 1 0 - 0x7C200400, // 0354 CALL R8 2 - 0x60240010, // 0355 GETGBL R9 G16 - 0x5C281000, // 0356 MOVE R10 R8 - 0x7C240200, // 0357 CALL R9 1 - 0xA8020007, // 0358 EXBLK 0 #0361 - 0x5C281200, // 0359 MOVE R10 R9 - 0x7C280000, // 035A CALL R10 0 - 0x8C2C0F0B, // 035B GETMET R11 R7 K11 - 0x4C340000, // 035C LDNIL R13 - 0x8838090C, // 035D GETMBR R14 R4 K12 - 0x5C3C1400, // 035E MOVE R15 R10 - 0x7C2C0800, // 035F CALL R11 4 - 0x7001FFF7, // 0360 JMP #0359 - 0x5824003A, // 0361 LDCONST R9 K58 - 0xAC240200, // 0362 CATCH R9 1 0 - 0xB0080000, // 0363 RAISE 2 R0 R0 - 0x80040E00, // 0364 RET 1 R7 - 0x70020007, // 0365 JMP #036E - 0x601C0003, // 0366 GETGBL R7 G3 - 0x5C200000, // 0367 MOVE R8 R0 - 0x7C1C0200, // 0368 CALL R7 1 - 0x8C1C0F56, // 0369 GETMET R7 R7 K86 - 0x5C240200, // 036A MOVE R9 R1 - 0x5C280400, // 036B MOVE R10 R2 - 0x7C1C0600, // 036C CALL R7 3 - 0x80040E00, // 036D RET 1 R7 - 0x70020007, // 036E JMP #0377 - 0x601C0003, // 036F GETGBL R7 G3 - 0x5C200000, // 0370 MOVE R8 R0 - 0x7C1C0200, // 0371 CALL R7 1 - 0x8C1C0F56, // 0372 GETMET R7 R7 K86 - 0x5C240200, // 0373 MOVE R9 R1 - 0x5C280400, // 0374 MOVE R10 R2 - 0x7C1C0600, // 0375 CALL R7 3 - 0x80040E00, // 0376 RET 1 R7 - 0x80000000, // 0377 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: invoke_request -********************************************************************/ -be_local_closure(Matter_Plugin_Root_invoke_request, /* name */ - be_nested_proto( - 29, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 1]) { - be_nested_proto( - 3, /* nstack */ - 0, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 2]) { /* upvals */ - be_local_const_upval(1, 0), - be_local_const_upval(1, 11), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(device), - /* K1 */ be_nested_str_weak(remove_fabric), - }), - be_str_weak(_anonymous_), - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x68000000, // 0000 GETUPV R0 U0 - 0x88000100, // 0001 GETMBR R0 R0 K0 - 0x8C000101, // 0002 GETMET R0 R0 K1 - 0x68080001, // 0003 GETUPV R2 U1 - 0x7C000400, // 0004 CALL R0 2 - 0x80000000, // 0005 RET 0 - }) - ), - }), - 1, /* has constants */ - ( &(const bvalue[100]) { /* constants */ - /* K0 */ be_nested_str_weak(crypto), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(matter), - /* K3 */ be_nested_str_weak(TLV), - /* K4 */ be_nested_str_weak(cluster), - /* K5 */ be_nested_str_weak(command), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(findsubval), - /* K8 */ be_const_int(1), - /* K9 */ be_nested_str_weak(_breadcrumb), - /* K10 */ be_nested_str_weak(Matter_TLV_struct), - /* K11 */ be_nested_str_weak(add_TLV), - /* K12 */ be_nested_str_weak(U1), - /* K13 */ be_nested_str_weak(UTF1), - /* K14 */ be_nested_str_weak(), - /* K15 */ be_const_int(2), - /* K16 */ be_nested_str_weak(XX), - /* K17 */ be_const_int(3), - /* K18 */ be_nested_str_weak(fabric_completed), - /* K19 */ be_nested_str_weak(set_no_expiration), - /* K20 */ be_nested_str_weak(save), - /* K21 */ be_nested_str_weak(device), - /* K22 */ be_nested_str_weak(start_commissioning_complete_deferred), - /* K23 */ be_nested_str_weak(status), - /* K24 */ be_nested_str_weak(UNSUPPORTED_COMMAND), - /* K25 */ be_nested_str_weak(B2), - /* K26 */ be_nested_str_weak(DAC_Cert_FFF1_8000), - /* K27 */ be_nested_str_weak(PAI_Cert_FFF1), - /* K28 */ be_nested_str_weak(CD_FFF1_8000), - /* K29 */ be_nested_str_weak(B1), - /* K30 */ be_nested_str_weak(U4), - /* K31 */ be_nested_str_weak(tasmota), - /* K32 */ be_nested_str_weak(rtc), - /* K33 */ be_nested_str_weak(utc), - /* K34 */ be_nested_str_weak(tlv2raw), - /* K35 */ be_nested_str_weak(get_ac), - /* K36 */ be_nested_str_weak(log), - /* K37 */ be_nested_str_weak(MTR_X3A_X20attestation_tbs_X3D), - /* K38 */ be_nested_str_weak(tohex), - /* K39 */ be_nested_str_weak(EC_P256), - /* K40 */ be_nested_str_weak(ecdsa_sign_sha256), - /* K41 */ be_nested_str_weak(DAC_Priv_FFF1_8000), - /* K42 */ be_nested_str_weak(gen_CSR), - /* K43 */ be_nested_str_weak(MTR_X3A_X20nocsr_tbs_X3D), - /* K44 */ be_nested_str_weak(set_ca), - /* K45 */ be_nested_str_weak(MTR_X3A_X20received_X20ca_root_X3D), - /* K46 */ be_nested_str_weak(SUCCESS), - /* K47 */ be_nested_str_weak(get_ca), - /* K48 */ be_nested_str_weak(MTR_X3A_X20Error_X3A_X20AdNOC_X20without_X20CA), - /* K49 */ be_nested_str_weak(set_noc), - /* K50 */ be_nested_str_weak(set_ipk_epoch_key), - /* K51 */ be_nested_str_weak(set_admin_subject_vendor), - /* K52 */ be_nested_str_weak(parse), - /* K53 */ be_nested_str_weak(findsub), - /* K54 */ be_nested_str_weak(MTR_X3A_X20Error_X3A_X20no_X20fabricid_X20nor_X20deviceid_X20in_X20NOC_X20certificate), - /* K55 */ be_nested_str_weak(int), - /* K56 */ be_nested_str_weak(int64), - /* K57 */ be_nested_str_weak(fromu32), - /* K58 */ be_nested_str_weak(tobytes), - /* K59 */ be_const_int(2147483647), - /* K60 */ be_nested_str_weak(fromstring), - /* K61 */ be_nested_str_weak(CompressedFabric), - /* K62 */ be_nested_str_weak(HKDF_SHA256), - /* K63 */ be_nested_str_weak(copy), - /* K64 */ be_nested_str_weak(reverse), - /* K65 */ be_nested_str_weak(derive), - /* K66 */ be_nested_str_weak(set_fabric_device), - /* K67 */ be_nested_str_weak(commissioning_admin_fabric), - /* K68 */ be_nested_str_weak(persist_to_fabric), - /* K69 */ be_nested_str_weak(fabric_candidate), - /* K70 */ be_nested_str_weak(start_operational_discovery_deferred), - /* K71 */ be_nested_str_weak(MTR_X3A_X20_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D_X2D), - /* K72 */ be_nested_str_weak(MTR_X3A_X20fabric_X3D), - /* K73 */ be_nested_str_weak(inspect), - /* K74 */ be_nested_str_weak(_fabric), - /* K75 */ be_nested_str_weak(log_new_fabric), - /* K76 */ be_nested_str_weak(set_fabric_label), - /* K77 */ be_nested_str_weak(format), - /* K78 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Update_X20fabric_X20_X27_X25s_X27_X20label_X3D_X27_X25s_X27), - /* K79 */ be_nested_str_weak(get_fabric_id), - /* K80 */ be_nested_str_weak(fabric_index_X3A), - /* K81 */ be_nested_str_weak(sessions), - /* K82 */ be_nested_str_weak(active_fabrics), - /* K83 */ be_nested_str_weak(get_fabric_index), - /* K84 */ be_nested_str_weak(MTR_X3A_X20removing_X20fabric_X20), - /* K85 */ be_nested_str_weak(set_timer), - /* K86 */ be_nested_str_weak(stop_iteration), - /* K87 */ be_nested_str_weak(MTR_X3A_X20RemoveFabric_X20fabric_X28), - /* K88 */ be_nested_str_weak(_X29_X20not_X20found), - /* K89 */ be_nested_str_weak(INVALID_ACTION), - /* K90 */ be_nested_str_weak(MTR_X3A_X20OpenCommissioningWindow_X28timeout_X3D_X25i_X2C_X20passcode_X3D_X25s_X2C_X20discriminator_X3D_X25i_X2C_X20iterations_X3D_X25i_X2C_X20salt_X3D_X25s_X29), - /* K91 */ be_nested_str_weak(INVALID_DATA_TYPE), - /* K92 */ be_nested_str_weak(MTR_X3A_X20wrong_X20size_X20for_X20PAKE_X20parameters), - /* K93 */ be_nested_str_weak(CONSTRAINT_ERROR), - /* K94 */ be_nested_str_weak(start_basic_commissioning), - /* K95 */ be_nested_str_weak(get_fabric), - /* K96 */ be_nested_str_weak(MTR_X3A_X20OpenBasicCommissioningWindow_X20commissioning_timeout_X3D), - /* K97 */ be_nested_str_weak(start_root_basic_commissioning), - /* K98 */ be_nested_str_weak(stop_basic_commissioning), - /* K99 */ be_nested_str_weak(invoke_request), - }), - be_str_weak(invoke_request), - &be_const_str_solidified, - ( &(const binstruction[735]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0xA4160200, // 0001 IMPORT R5 K1 - 0xB81A0400, // 0002 GETNGBL R6 K2 - 0x88180D03, // 0003 GETMBR R6 R6 K3 - 0x881C0704, // 0004 GETMBR R7 R3 K4 - 0x88200705, // 0005 GETMBR R8 R3 K5 - 0x5426002F, // 0006 LDINT R9 48 - 0x1C240E09, // 0007 EQ R9 R7 R9 - 0x78260054, // 0008 JMPF R9 #005E - 0x1C241106, // 0009 EQ R9 R8 K6 - 0x78260017, // 000A JMPF R9 #0023 - 0x8C240507, // 000B GETMET R9 R2 K7 - 0x582C0006, // 000C LDCONST R11 K6 - 0x54320383, // 000D LDINT R12 900 - 0x7C240600, // 000E CALL R9 3 - 0x8C280507, // 000F GETMET R10 R2 K7 - 0x58300008, // 0010 LDCONST R12 K8 - 0x58340006, // 0011 LDCONST R13 K6 - 0x7C280600, // 0012 CALL R10 3 - 0x9006120A, // 0013 SETMBR R1 K9 R10 - 0x8C2C0D0A, // 0014 GETMET R11 R6 K10 - 0x7C2C0200, // 0015 CALL R11 1 - 0x8C30170B, // 0016 GETMET R12 R11 K11 - 0x58380006, // 0017 LDCONST R14 K6 - 0x883C0D0C, // 0018 GETMBR R15 R6 K12 - 0x58400006, // 0019 LDCONST R16 K6 - 0x7C300800, // 001A CALL R12 4 - 0x8C30170B, // 001B GETMET R12 R11 K11 - 0x58380008, // 001C LDCONST R14 K8 - 0x883C0D0D, // 001D GETMBR R15 R6 K13 - 0x5840000E, // 001E LDCONST R16 K14 - 0x7C300800, // 001F CALL R12 4 - 0x900E0B08, // 0020 SETMBR R3 K5 K8 - 0x80041600, // 0021 RET 1 R11 - 0x70020039, // 0022 JMP #005D - 0x1C24110F, // 0023 EQ R9 R8 K15 - 0x7826001A, // 0024 JMPF R9 #0040 - 0x8C240507, // 0025 GETMET R9 R2 K7 - 0x582C0006, // 0026 LDCONST R11 K6 - 0x7C240400, // 0027 CALL R9 2 - 0x8C280507, // 0028 GETMET R10 R2 K7 - 0x58300008, // 0029 LDCONST R12 K8 - 0x58340010, // 002A LDCONST R13 K16 - 0x7C280600, // 002B CALL R10 3 - 0x8C2C0507, // 002C GETMET R11 R2 K7 - 0x5834000F, // 002D LDCONST R13 K15 - 0x58380006, // 002E LDCONST R14 K6 - 0x7C2C0600, // 002F CALL R11 3 - 0x9006120B, // 0030 SETMBR R1 K9 R11 - 0x8C300D0A, // 0031 GETMET R12 R6 K10 - 0x7C300200, // 0032 CALL R12 1 - 0x8C34190B, // 0033 GETMET R13 R12 K11 - 0x583C0006, // 0034 LDCONST R15 K6 - 0x88400D0C, // 0035 GETMBR R16 R6 K12 - 0x58440006, // 0036 LDCONST R17 K6 - 0x7C340800, // 0037 CALL R13 4 - 0x8C34190B, // 0038 GETMET R13 R12 K11 - 0x583C0008, // 0039 LDCONST R15 K8 - 0x88400D0D, // 003A GETMBR R16 R6 K13 - 0x5844000E, // 003B LDCONST R17 K14 - 0x7C340800, // 003C CALL R13 4 - 0x900E0B11, // 003D SETMBR R3 K5 K17 - 0x80041800, // 003E RET 1 R12 - 0x7002001C, // 003F JMP #005D - 0x54260003, // 0040 LDINT R9 4 - 0x1C241009, // 0041 EQ R9 R8 R9 - 0x78260019, // 0042 JMPF R9 #005D - 0x90061306, // 0043 SETMBR R1 K9 K6 - 0x8C240312, // 0044 GETMET R9 R1 K18 - 0x7C240200, // 0045 CALL R9 1 - 0x8C240313, // 0046 GETMET R9 R1 K19 - 0x7C240200, // 0047 CALL R9 1 - 0x8C240314, // 0048 GETMET R9 R1 K20 - 0x7C240200, // 0049 CALL R9 1 - 0x8C240D0A, // 004A GETMET R9 R6 K10 - 0x7C240200, // 004B CALL R9 1 - 0x8C28130B, // 004C GETMET R10 R9 K11 - 0x58300006, // 004D LDCONST R12 K6 - 0x88340D0C, // 004E GETMBR R13 R6 K12 - 0x58380006, // 004F LDCONST R14 K6 - 0x7C280800, // 0050 CALL R10 4 - 0x8C28130B, // 0051 GETMET R10 R9 K11 - 0x58300008, // 0052 LDCONST R12 K8 - 0x88340D0D, // 0053 GETMBR R13 R6 K13 - 0x5838000E, // 0054 LDCONST R14 K14 - 0x7C280800, // 0055 CALL R10 4 - 0x542A0004, // 0056 LDINT R10 5 - 0x900E0A0A, // 0057 SETMBR R3 K5 R10 - 0x88280115, // 0058 GETMBR R10 R0 K21 - 0x8C281516, // 0059 GETMET R10 R10 K22 - 0x5C300200, // 005A MOVE R12 R1 - 0x7C280400, // 005B CALL R10 2 - 0x80041200, // 005C RET 1 R9 - 0x7002027E, // 005D JMP #02DD - 0x5426003D, // 005E LDINT R9 62 - 0x1C240E09, // 005F EQ R9 R7 R9 - 0x782601E0, // 0060 JMPF R9 #0242 - 0x1C24110F, // 0061 EQ R9 R8 K15 - 0x7826001D, // 0062 JMPF R9 #0081 - 0x8C240507, // 0063 GETMET R9 R2 K7 - 0x582C0006, // 0064 LDCONST R11 K6 - 0x7C240400, // 0065 CALL R9 2 - 0x20281308, // 0066 NE R10 R9 K8 - 0x782A0006, // 0067 JMPF R10 #006F - 0x2028130F, // 0068 NE R10 R9 K15 - 0x782A0004, // 0069 JMPF R10 #006F - 0xB82A0400, // 006A GETNGBL R10 K2 - 0x88281518, // 006B GETMBR R10 R10 K24 - 0x900E2E0A, // 006C SETMBR R3 K23 R10 - 0x4C280000, // 006D LDNIL R10 - 0x80041400, // 006E RET 1 R10 - 0x8C280D0A, // 006F GETMET R10 R6 K10 - 0x7C280200, // 0070 CALL R10 1 - 0x8C2C150B, // 0071 GETMET R11 R10 K11 - 0x58340006, // 0072 LDCONST R13 K6 - 0x88380D19, // 0073 GETMBR R14 R6 K25 - 0x1C3C1308, // 0074 EQ R15 R9 K8 - 0x783E0003, // 0075 JMPF R15 #007A - 0xB83E0400, // 0076 GETNGBL R15 K2 - 0x8C3C1F1A, // 0077 GETMET R15 R15 K26 - 0x7C3C0200, // 0078 CALL R15 1 - 0x70020002, // 0079 JMP #007D - 0xB83E0400, // 007A GETNGBL R15 K2 - 0x8C3C1F1B, // 007B GETMET R15 R15 K27 - 0x7C3C0200, // 007C CALL R15 1 - 0x7C2C0800, // 007D CALL R11 4 - 0x900E0B11, // 007E SETMBR R3 K5 K17 - 0x80041400, // 007F RET 1 R10 - 0x700201BF, // 0080 JMP #0241 - 0x1C241106, // 0081 EQ R9 R8 K6 - 0x78260044, // 0082 JMPF R9 #00C8 - 0x8C240507, // 0083 GETMET R9 R2 K7 - 0x582C0006, // 0084 LDCONST R11 K6 - 0x7C240400, // 0085 CALL R9 2 - 0x6028000C, // 0086 GETGBL R10 G12 - 0x5C2C1200, // 0087 MOVE R11 R9 - 0x7C280200, // 0088 CALL R10 1 - 0x542E001F, // 0089 LDINT R11 32 - 0x2028140B, // 008A NE R10 R10 R11 - 0x782A0001, // 008B JMPF R10 #008E - 0x4C280000, // 008C LDNIL R10 - 0x80041400, // 008D RET 1 R10 - 0x900E0B08, // 008E SETMBR R3 K5 K8 - 0x8C280D0A, // 008F GETMET R10 R6 K10 - 0x7C280200, // 0090 CALL R10 1 - 0x8C2C150B, // 0091 GETMET R11 R10 K11 - 0x58340008, // 0092 LDCONST R13 K8 - 0x88380D19, // 0093 GETMBR R14 R6 K25 - 0xB83E0400, // 0094 GETNGBL R15 K2 - 0x8C3C1F1C, // 0095 GETMET R15 R15 K28 - 0x7C3C0200, // 0096 CALL R15 1 - 0x7C2C0800, // 0097 CALL R11 4 - 0x8C2C150B, // 0098 GETMET R11 R10 K11 - 0x5834000F, // 0099 LDCONST R13 K15 - 0x88380D1D, // 009A GETMBR R14 R6 K29 - 0x5C3C1200, // 009B MOVE R15 R9 - 0x7C2C0800, // 009C CALL R11 4 - 0x8C2C150B, // 009D GETMET R11 R10 K11 - 0x58340011, // 009E LDCONST R13 K17 - 0x88380D1E, // 009F GETMBR R14 R6 K30 - 0xB83E3E00, // 00A0 GETNGBL R15 K31 - 0x8C3C1F20, // 00A1 GETMET R15 R15 K32 - 0x7C3C0200, // 00A2 CALL R15 1 - 0x943C1F21, // 00A3 GETIDX R15 R15 K33 - 0x7C2C0800, // 00A4 CALL R11 4 - 0x8C2C1522, // 00A5 GETMET R11 R10 K34 - 0x7C2C0200, // 00A6 CALL R11 1 - 0x8C300323, // 00A7 GETMET R12 R1 K35 - 0x7C300200, // 00A8 CALL R12 1 - 0x0034160C, // 00A9 ADD R13 R11 R12 - 0xB83A3E00, // 00AA GETNGBL R14 K31 - 0x8C381D24, // 00AB GETMET R14 R14 K36 - 0x8C401B26, // 00AC GETMET R16 R13 K38 - 0x7C400200, // 00AD CALL R16 1 - 0x00424A10, // 00AE ADD R16 K37 R16 - 0x58440011, // 00AF LDCONST R17 K17 - 0x7C380600, // 00B0 CALL R14 3 - 0x8C380927, // 00B1 GETMET R14 R4 K39 - 0x7C380200, // 00B2 CALL R14 1 - 0x8C381D28, // 00B3 GETMET R14 R14 K40 - 0xB8420400, // 00B4 GETNGBL R16 K2 - 0x8C402129, // 00B5 GETMET R16 R16 K41 - 0x7C400200, // 00B6 CALL R16 1 - 0x5C441A00, // 00B7 MOVE R17 R13 - 0x7C380600, // 00B8 CALL R14 3 - 0x8C3C0D0A, // 00B9 GETMET R15 R6 K10 - 0x7C3C0200, // 00BA CALL R15 1 - 0x8C401F0B, // 00BB GETMET R16 R15 K11 - 0x58480006, // 00BC LDCONST R18 K6 - 0x884C0D19, // 00BD GETMBR R19 R6 K25 - 0x5C501600, // 00BE MOVE R20 R11 - 0x7C400800, // 00BF CALL R16 4 - 0x8C401F0B, // 00C0 GETMET R16 R15 K11 - 0x58480008, // 00C1 LDCONST R18 K8 - 0x884C0D1D, // 00C2 GETMBR R19 R6 K29 - 0x5C501C00, // 00C3 MOVE R20 R14 - 0x7C400800, // 00C4 CALL R16 4 - 0x900E0B08, // 00C5 SETMBR R3 K5 K8 - 0x80041E00, // 00C6 RET 1 R15 - 0x70020178, // 00C7 JMP #0241 - 0x54260003, // 00C8 LDINT R9 4 - 0x1C241009, // 00C9 EQ R9 R8 R9 - 0x78260040, // 00CA JMPF R9 #010C - 0x8C240507, // 00CB GETMET R9 R2 K7 - 0x582C0006, // 00CC LDCONST R11 K6 - 0x7C240400, // 00CD CALL R9 2 - 0x6028000C, // 00CE GETGBL R10 G12 - 0x5C2C1200, // 00CF MOVE R11 R9 - 0x7C280200, // 00D0 CALL R10 1 - 0x542E001F, // 00D1 LDINT R11 32 - 0x2028140B, // 00D2 NE R10 R10 R11 - 0x782A0001, // 00D3 JMPF R10 #00D6 - 0x4C280000, // 00D4 LDNIL R10 - 0x80041400, // 00D5 RET 1 R10 - 0x8C280507, // 00D6 GETMET R10 R2 K7 - 0x58300008, // 00D7 LDCONST R12 K8 - 0x50340000, // 00D8 LDBOOL R13 0 0 - 0x7C280600, // 00D9 CALL R10 3 - 0x8C2C032A, // 00DA GETMET R11 R1 K42 - 0x7C2C0200, // 00DB CALL R11 1 - 0x8C300D0A, // 00DC GETMET R12 R6 K10 - 0x7C300200, // 00DD CALL R12 1 - 0x8C34190B, // 00DE GETMET R13 R12 K11 - 0x583C0008, // 00DF LDCONST R15 K8 - 0x88400D19, // 00E0 GETMBR R16 R6 K25 - 0x5C441600, // 00E1 MOVE R17 R11 - 0x7C340800, // 00E2 CALL R13 4 - 0x8C34190B, // 00E3 GETMET R13 R12 K11 - 0x583C000F, // 00E4 LDCONST R15 K15 - 0x88400D1D, // 00E5 GETMBR R16 R6 K29 - 0x5C441200, // 00E6 MOVE R17 R9 - 0x7C340800, // 00E7 CALL R13 4 - 0x8C341922, // 00E8 GETMET R13 R12 K34 - 0x7C340200, // 00E9 CALL R13 1 - 0x8C380323, // 00EA GETMET R14 R1 K35 - 0x7C380200, // 00EB CALL R14 1 - 0x00381A0E, // 00EC ADD R14 R13 R14 - 0xB83E3E00, // 00ED GETNGBL R15 K31 - 0x8C3C1F24, // 00EE GETMET R15 R15 K36 - 0x8C441D26, // 00EF GETMET R17 R14 K38 - 0x7C440200, // 00F0 CALL R17 1 - 0x00465611, // 00F1 ADD R17 K43 R17 - 0x58480011, // 00F2 LDCONST R18 K17 - 0x7C3C0600, // 00F3 CALL R15 3 - 0x8C3C0927, // 00F4 GETMET R15 R4 K39 - 0x7C3C0200, // 00F5 CALL R15 1 - 0x8C3C1F28, // 00F6 GETMET R15 R15 K40 - 0xB8460400, // 00F7 GETNGBL R17 K2 - 0x8C442329, // 00F8 GETMET R17 R17 K41 - 0x7C440200, // 00F9 CALL R17 1 - 0x5C481C00, // 00FA MOVE R18 R14 - 0x7C3C0600, // 00FB CALL R15 3 - 0x8C400D0A, // 00FC GETMET R16 R6 K10 - 0x7C400200, // 00FD CALL R16 1 - 0x8C44210B, // 00FE GETMET R17 R16 K11 - 0x584C0006, // 00FF LDCONST R19 K6 - 0x88500D19, // 0100 GETMBR R20 R6 K25 - 0x5C541A00, // 0101 MOVE R21 R13 - 0x7C440800, // 0102 CALL R17 4 - 0x8C44210B, // 0103 GETMET R17 R16 K11 - 0x584C0008, // 0104 LDCONST R19 K8 - 0x88500D1D, // 0105 GETMBR R20 R6 K29 - 0x5C541E00, // 0106 MOVE R21 R15 - 0x7C440800, // 0107 CALL R17 4 - 0x54460004, // 0108 LDINT R17 5 - 0x900E0A11, // 0109 SETMBR R3 K5 R17 - 0x80042000, // 010A RET 1 R16 - 0x70020134, // 010B JMP #0241 - 0x5426000A, // 010C LDINT R9 11 - 0x1C241009, // 010D EQ R9 R8 R9 - 0x78260012, // 010E JMPF R9 #0122 - 0x8C240507, // 010F GETMET R9 R2 K7 - 0x582C0006, // 0110 LDCONST R11 K6 - 0x7C240400, // 0111 CALL R9 2 - 0x8C28032C, // 0112 GETMET R10 R1 K44 - 0x5C301200, // 0113 MOVE R12 R9 - 0x7C280400, // 0114 CALL R10 2 - 0xB82A3E00, // 0115 GETNGBL R10 K31 - 0x8C281524, // 0116 GETMET R10 R10 K36 - 0x8C301326, // 0117 GETMET R12 R9 K38 - 0x7C300200, // 0118 CALL R12 1 - 0x00325A0C, // 0119 ADD R12 K45 R12 - 0x58340011, // 011A LDCONST R13 K17 - 0x7C280600, // 011B CALL R10 3 - 0xB82A0400, // 011C GETNGBL R10 K2 - 0x8828152E, // 011D GETMBR R10 R10 K46 - 0x900E2E0A, // 011E SETMBR R3 K23 R10 - 0x4C280000, // 011F LDNIL R10 - 0x80041400, // 0120 RET 1 R10 - 0x7002011E, // 0121 JMP #0241 - 0x54260005, // 0122 LDINT R9 6 - 0x1C241009, // 0123 EQ R9 R8 R9 - 0x782600B7, // 0124 JMPF R9 #01DD - 0x8C240507, // 0125 GETMET R9 R2 K7 - 0x582C0006, // 0126 LDCONST R11 K6 - 0x7C240400, // 0127 CALL R9 2 - 0x8C280507, // 0128 GETMET R10 R2 K7 - 0x58300008, // 0129 LDCONST R12 K8 - 0x7C280400, // 012A CALL R10 2 - 0x602C000C, // 012B GETGBL R11 G12 - 0x5C301400, // 012C MOVE R12 R10 - 0x7C2C0200, // 012D CALL R11 1 - 0x1C2C1706, // 012E EQ R11 R11 K6 - 0x782E0000, // 012F JMPF R11 #0131 - 0x4C280000, // 0130 LDNIL R10 - 0x8C2C0507, // 0131 GETMET R11 R2 K7 - 0x5834000F, // 0132 LDCONST R13 K15 - 0x7C2C0400, // 0133 CALL R11 2 - 0x8C300507, // 0134 GETMET R12 R2 K7 - 0x58380011, // 0135 LDCONST R14 K17 - 0x7C300400, // 0136 CALL R12 2 - 0x8C340507, // 0137 GETMET R13 R2 K7 - 0x543E0003, // 0138 LDINT R15 4 - 0x7C340400, // 0139 CALL R13 2 - 0x8C38032F, // 013A GETMET R14 R1 K47 - 0x7C380200, // 013B CALL R14 1 - 0x4C3C0000, // 013C LDNIL R15 - 0x1C381C0F, // 013D EQ R14 R14 R15 - 0x783A0006, // 013E JMPF R14 #0146 - 0xB83A3E00, // 013F GETNGBL R14 K31 - 0x8C381D24, // 0140 GETMET R14 R14 K36 - 0x58400030, // 0141 LDCONST R16 K48 - 0x5844000F, // 0142 LDCONST R17 K15 - 0x7C380600, // 0143 CALL R14 3 - 0x4C380000, // 0144 LDNIL R14 - 0x80041C00, // 0145 RET 1 R14 - 0x8C380331, // 0146 GETMET R14 R1 K49 - 0x5C401200, // 0147 MOVE R16 R9 - 0x5C441400, // 0148 MOVE R17 R10 - 0x7C380600, // 0149 CALL R14 3 - 0x8C380332, // 014A GETMET R14 R1 K50 - 0x5C401600, // 014B MOVE R16 R11 - 0x7C380400, // 014C CALL R14 2 - 0x8C380333, // 014D GETMET R14 R1 K51 - 0x5C401800, // 014E MOVE R16 R12 - 0x5C441A00, // 014F MOVE R17 R13 - 0x7C380600, // 0150 CALL R14 3 - 0xB83A0400, // 0151 GETNGBL R14 K2 - 0x88381D03, // 0152 GETMBR R14 R14 K3 - 0x8C381D34, // 0153 GETMET R14 R14 K52 - 0x5C401200, // 0154 MOVE R16 R9 - 0x7C380400, // 0155 CALL R14 2 - 0x8C3C1D35, // 0156 GETMET R15 R14 K53 - 0x54460005, // 0157 LDINT R17 6 - 0x7C3C0400, // 0158 CALL R15 2 - 0x8C401F07, // 0159 GETMET R16 R15 K7 - 0x544A0014, // 015A LDINT R18 21 - 0x7C400400, // 015B CALL R16 2 - 0x8C441F07, // 015C GETMET R17 R15 K7 - 0x544E0010, // 015D LDINT R19 17 - 0x7C440400, // 015E CALL R17 2 - 0x5C482000, // 015F MOVE R18 R16 - 0x784A0001, // 0160 JMPF R18 #0163 - 0x5C482200, // 0161 MOVE R18 R17 - 0x744A0006, // 0162 JMPT R18 #016A - 0xB84A3E00, // 0163 GETNGBL R18 K31 - 0x8C482524, // 0164 GETMET R18 R18 K36 - 0x58500036, // 0165 LDCONST R20 K54 - 0x5854000F, // 0166 LDCONST R21 K15 - 0x7C480600, // 0167 CALL R18 3 - 0x50480000, // 0168 LDBOOL R18 0 0 - 0x80042400, // 0169 RET 1 R18 - 0x60480004, // 016A GETGBL R18 G4 - 0x5C4C2000, // 016B MOVE R19 R16 - 0x7C480200, // 016C CALL R18 1 - 0x1C482537, // 016D EQ R18 R18 K55 - 0x784A0007, // 016E JMPF R18 #0177 - 0xB84A7000, // 016F GETNGBL R18 K56 - 0x8C482539, // 0170 GETMET R18 R18 K57 - 0x5C502000, // 0171 MOVE R20 R16 - 0x7C480400, // 0172 CALL R18 2 - 0x8C48253A, // 0173 GETMET R18 R18 K58 - 0x7C480200, // 0174 CALL R18 1 - 0x5C402400, // 0175 MOVE R16 R18 - 0x70020002, // 0176 JMP #017A - 0x8C48213A, // 0177 GETMET R18 R16 K58 - 0x7C480200, // 0178 CALL R18 1 - 0x5C402400, // 0179 MOVE R16 R18 - 0x60480004, // 017A GETGBL R18 G4 - 0x5C4C2200, // 017B MOVE R19 R17 - 0x7C480200, // 017C CALL R18 1 - 0x1C482537, // 017D EQ R18 R18 K55 - 0x784A0007, // 017E JMPF R18 #0187 - 0xB84A7000, // 017F GETNGBL R18 K56 - 0x8C482539, // 0180 GETMET R18 R18 K57 - 0x5C502200, // 0181 MOVE R20 R17 - 0x7C480400, // 0182 CALL R18 2 - 0x8C48253A, // 0183 GETMET R18 R18 K58 - 0x7C480200, // 0184 CALL R18 1 - 0x5C442400, // 0185 MOVE R17 R18 - 0x70020002, // 0186 JMP #018A - 0x8C48233A, // 0187 GETMET R18 R17 K58 - 0x7C480200, // 0188 CALL R18 1 - 0x5C442400, // 0189 MOVE R17 R18 - 0xB84A0400, // 018A GETNGBL R18 K2 - 0x88482503, // 018B GETMBR R18 R18 K3 - 0x8C482534, // 018C GETMET R18 R18 K52 - 0x8C50032F, // 018D GETMET R20 R1 K47 - 0x7C500200, // 018E CALL R20 1 - 0x7C480400, // 018F CALL R18 2 - 0x8C482507, // 0190 GETMET R18 R18 K7 - 0x54520008, // 0191 LDINT R20 9 - 0x7C480400, // 0192 CALL R18 2 - 0x404E113B, // 0193 CONNECT R19 K8 K59 - 0x94482413, // 0194 GETIDX R18 R18 R19 - 0x60500015, // 0195 GETGBL R20 G21 - 0x7C500000, // 0196 CALL R20 0 - 0x8C50293C, // 0197 GETMET R20 R20 K60 - 0x5858003D, // 0198 LDCONST R22 K61 - 0x7C500400, // 0199 CALL R20 2 - 0x5C4C2800, // 019A MOVE R19 R20 - 0x8C50093E, // 019B GETMET R20 R4 K62 - 0x7C500200, // 019C CALL R20 1 - 0x8C54213F, // 019D GETMET R21 R16 K63 - 0x7C540200, // 019E CALL R21 1 - 0x8C542B40, // 019F GETMET R21 R21 K64 - 0x7C540200, // 01A0 CALL R21 1 - 0x8C582941, // 01A1 GETMET R22 R20 K65 - 0x5C602400, // 01A2 MOVE R24 R18 - 0x5C642A00, // 01A3 MOVE R25 R21 - 0x5C682600, // 01A4 MOVE R26 R19 - 0x546E0007, // 01A5 LDINT R27 8 - 0x7C580A00, // 01A6 CALL R22 5 - 0x8C5C0342, // 01A7 GETMET R23 R1 K66 - 0x5C642000, // 01A8 MOVE R25 R16 - 0x5C682200, // 01A9 MOVE R26 R17 - 0x5C6C2C00, // 01AA MOVE R27 R22 - 0x88700115, // 01AB GETMBR R28 R0 K21 - 0x88703943, // 01AC GETMBR R28 R28 K67 - 0x7C5C0A00, // 01AD CALL R23 5 - 0x8C5C0344, // 01AE GETMET R23 R1 K68 - 0x7C5C0200, // 01AF CALL R23 1 - 0x8C5C0345, // 01B0 GETMET R23 R1 K69 - 0x7C5C0200, // 01B1 CALL R23 1 - 0x885C0115, // 01B2 GETMBR R23 R0 K21 - 0x8C5C2F46, // 01B3 GETMET R23 R23 K70 - 0x5C640200, // 01B4 MOVE R25 R1 - 0x7C5C0400, // 01B5 CALL R23 2 - 0xB85E3E00, // 01B6 GETNGBL R23 K31 - 0x8C5C2F24, // 01B7 GETMET R23 R23 K36 - 0x58640047, // 01B8 LDCONST R25 K71 - 0x58680011, // 01B9 LDCONST R26 K17 - 0x7C5C0600, // 01BA CALL R23 3 - 0xB85E3E00, // 01BB GETNGBL R23 K31 - 0x8C5C2F24, // 01BC GETMET R23 R23 K36 - 0xB8660400, // 01BD GETNGBL R25 K2 - 0x8C643349, // 01BE GETMET R25 R25 K73 - 0x886C034A, // 01BF GETMBR R27 R1 K74 - 0x7C640400, // 01C0 CALL R25 2 - 0x00669019, // 01C1 ADD R25 K72 R25 - 0x58680011, // 01C2 LDCONST R26 K17 - 0x7C5C0600, // 01C3 CALL R23 3 - 0xB85E3E00, // 01C4 GETNGBL R23 K31 - 0x8C5C2F24, // 01C5 GETMET R23 R23 K36 - 0x58640047, // 01C6 LDCONST R25 K71 - 0x58680011, // 01C7 LDCONST R26 K17 - 0x7C5C0600, // 01C8 CALL R23 3 - 0x885C034A, // 01C9 GETMBR R23 R1 K74 - 0x8C5C2F4B, // 01CA GETMET R23 R23 K75 - 0x7C5C0200, // 01CB CALL R23 1 - 0x8C5C0D0A, // 01CC GETMET R23 R6 K10 - 0x7C5C0200, // 01CD CALL R23 1 - 0x8C602F0B, // 01CE GETMET R24 R23 K11 - 0x58680006, // 01CF LDCONST R26 K6 - 0x886C0D0C, // 01D0 GETMBR R27 R6 K12 - 0xB8720400, // 01D1 GETNGBL R28 K2 - 0x8870392E, // 01D2 GETMBR R28 R28 K46 - 0x7C600800, // 01D3 CALL R24 4 - 0x8C602F0B, // 01D4 GETMET R24 R23 K11 - 0x58680008, // 01D5 LDCONST R26 K8 - 0x886C0D0C, // 01D6 GETMBR R27 R6 K12 - 0x58700008, // 01D7 LDCONST R28 K8 - 0x7C600800, // 01D8 CALL R24 4 - 0x54620007, // 01D9 LDINT R24 8 - 0x900E0A18, // 01DA SETMBR R3 K5 R24 - 0x80042E00, // 01DB RET 1 R23 - 0x70020063, // 01DC JMP #0241 - 0x54260008, // 01DD LDINT R9 9 - 0x1C241009, // 01DE EQ R9 R8 R9 - 0x7826001E, // 01DF JMPF R9 #01FF - 0x8C240507, // 01E0 GETMET R9 R2 K7 - 0x582C0006, // 01E1 LDCONST R11 K6 - 0x7C240400, // 01E2 CALL R9 2 - 0x8C28034C, // 01E3 GETMET R10 R1 K76 - 0x5C301200, // 01E4 MOVE R12 R9 - 0x7C280400, // 01E5 CALL R10 2 - 0xB82A3E00, // 01E6 GETNGBL R10 K31 - 0x8C281524, // 01E7 GETMET R10 R10 K36 - 0x8C300B4D, // 01E8 GETMET R12 R5 K77 - 0x5838004E, // 01E9 LDCONST R14 K78 - 0x883C034A, // 01EA GETMBR R15 R1 K74 - 0x8C3C1F4F, // 01EB GETMET R15 R15 K79 - 0x7C3C0200, // 01EC CALL R15 1 - 0x8C3C1F3F, // 01ED GETMET R15 R15 K63 - 0x7C3C0200, // 01EE CALL R15 1 - 0x8C3C1F40, // 01EF GETMET R15 R15 K64 - 0x7C3C0200, // 01F0 CALL R15 1 - 0x8C3C1F26, // 01F1 GETMET R15 R15 K38 - 0x7C3C0200, // 01F2 CALL R15 1 - 0x60400008, // 01F3 GETGBL R16 G8 - 0x5C441200, // 01F4 MOVE R17 R9 - 0x7C400200, // 01F5 CALL R16 1 - 0x7C300800, // 01F6 CALL R12 4 - 0x5834000F, // 01F7 LDCONST R13 K15 - 0x7C280600, // 01F8 CALL R10 3 - 0xB82A0400, // 01F9 GETNGBL R10 K2 - 0x8828152E, // 01FA GETMBR R10 R10 K46 - 0x900E2E0A, // 01FB SETMBR R3 K23 R10 - 0x4C280000, // 01FC LDNIL R10 - 0x80041400, // 01FD RET 1 R10 - 0x70020041, // 01FE JMP #0241 - 0x54260009, // 01FF LDINT R9 10 - 0x1C241009, // 0200 EQ R9 R8 R9 - 0x7826003E, // 0201 JMPF R9 #0241 - 0x8C240507, // 0202 GETMET R9 R2 K7 - 0x582C0006, // 0203 LDCONST R11 K6 - 0x7C240400, // 0204 CALL R9 2 - 0x60280008, // 0205 GETGBL R10 G8 - 0x5C2C1200, // 0206 MOVE R11 R9 - 0x7C280200, // 0207 CALL R10 1 - 0x002AA00A, // 0208 ADD R10 K80 R10 - 0x900E480A, // 0209 SETMBR R3 K36 R10 - 0x60280010, // 020A GETGBL R10 G16 - 0x882C0115, // 020B GETMBR R11 R0 K21 - 0x882C1751, // 020C GETMBR R11 R11 K81 - 0x8C2C1752, // 020D GETMET R11 R11 K82 - 0x7C2C0200, // 020E CALL R11 1 - 0x7C280200, // 020F CALL R10 1 - 0xA802001D, // 0210 EXBLK 0 #022F - 0x5C2C1400, // 0211 MOVE R11 R10 - 0x7C2C0000, // 0212 CALL R11 0 - 0x8C301753, // 0213 GETMET R12 R11 K83 - 0x7C300200, // 0214 CALL R12 1 - 0x1C301809, // 0215 EQ R12 R12 R9 - 0x78320015, // 0216 JMPF R12 #022D - 0xB8323E00, // 0217 GETNGBL R12 K31 - 0x8C301924, // 0218 GETMET R12 R12 K36 - 0x8C38174F, // 0219 GETMET R14 R11 K79 - 0x7C380200, // 021A CALL R14 1 - 0x8C381D3F, // 021B GETMET R14 R14 K63 - 0x7C380200, // 021C CALL R14 1 - 0x8C381D40, // 021D GETMET R14 R14 K64 - 0x7C380200, // 021E CALL R14 1 - 0x8C381D26, // 021F GETMET R14 R14 K38 - 0x7C380200, // 0220 CALL R14 1 - 0x003AA80E, // 0221 ADD R14 K84 R14 - 0x583C000F, // 0222 LDCONST R15 K15 - 0x7C300600, // 0223 CALL R12 3 - 0xB8323E00, // 0224 GETNGBL R12 K31 - 0x8C301955, // 0225 GETMET R12 R12 K85 - 0x543A07CF, // 0226 LDINT R14 2000 - 0x843C0000, // 0227 CLOSURE R15 P0 - 0x7C300600, // 0228 CALL R12 3 - 0x50300200, // 0229 LDBOOL R12 1 0 - 0xA0000000, // 022A CLOSE R0 - 0xA8040001, // 022B EXBLK 1 1 - 0x80041800, // 022C RET 1 R12 - 0xA0280000, // 022D CLOSE R10 - 0x7001FFE1, // 022E JMP #0211 - 0x58280056, // 022F LDCONST R10 K86 - 0xAC280200, // 0230 CATCH R10 1 0 - 0xB0080000, // 0231 RAISE 2 R0 R0 - 0xB82A3E00, // 0232 GETNGBL R10 K31 - 0x8C281524, // 0233 GETMET R10 R10 K36 - 0x60300008, // 0234 GETGBL R12 G8 - 0x5C341200, // 0235 MOVE R13 R9 - 0x7C300200, // 0236 CALL R12 1 - 0x0032AE0C, // 0237 ADD R12 K87 R12 - 0x00301958, // 0238 ADD R12 R12 K88 - 0x5834000F, // 0239 LDCONST R13 K15 - 0x7C280600, // 023A CALL R10 3 - 0xB82A0400, // 023B GETNGBL R10 K2 - 0x88281559, // 023C GETMBR R10 R10 K89 - 0x900E2E0A, // 023D SETMBR R3 K23 R10 - 0x4C280000, // 023E LDNIL R10 - 0xA0000000, // 023F CLOSE R0 - 0x80041400, // 0240 RET 1 R10 - 0x7002009A, // 0241 JMP #02DD - 0x5426003B, // 0242 LDINT R9 60 - 0x1C240E09, // 0243 EQ R9 R7 R9 - 0x78260084, // 0244 JMPF R9 #02CA - 0x1C241106, // 0245 EQ R9 R8 K6 - 0x78260064, // 0246 JMPF R9 #02AC - 0x8C240507, // 0247 GETMET R9 R2 K7 - 0x582C0006, // 0248 LDCONST R11 K6 - 0x7C240400, // 0249 CALL R9 2 - 0x8C280507, // 024A GETMET R10 R2 K7 - 0x58300008, // 024B LDCONST R12 K8 - 0x7C280400, // 024C CALL R10 2 - 0x8C2C0507, // 024D GETMET R11 R2 K7 - 0x5834000F, // 024E LDCONST R13 K15 - 0x7C2C0400, // 024F CALL R11 2 - 0x8C300507, // 0250 GETMET R12 R2 K7 - 0x58380011, // 0251 LDCONST R14 K17 - 0x7C300400, // 0252 CALL R12 2 - 0x8C340507, // 0253 GETMET R13 R2 K7 - 0x543E0003, // 0254 LDINT R15 4 - 0x7C340400, // 0255 CALL R13 2 - 0xB83A3E00, // 0256 GETNGBL R14 K31 - 0x8C381D24, // 0257 GETMET R14 R14 K36 - 0x8C400B4D, // 0258 GETMET R16 R5 K77 - 0x5848005A, // 0259 LDCONST R18 K90 - 0x5C4C1200, // 025A MOVE R19 R9 - 0x8C501526, // 025B GETMET R20 R10 K38 - 0x7C500200, // 025C CALL R20 1 - 0x5C541600, // 025D MOVE R21 R11 - 0x5C581800, // 025E MOVE R22 R12 - 0x8C5C1B26, // 025F GETMET R23 R13 K38 - 0x7C5C0200, // 0260 CALL R23 1 - 0x7C400E00, // 0261 CALL R16 7 - 0x5844000F, // 0262 LDCONST R17 K15 - 0x7C380600, // 0263 CALL R14 3 - 0x4C380000, // 0264 LDNIL R14 - 0x1C38120E, // 0265 EQ R14 R9 R14 - 0x743A000B, // 0266 JMPT R14 #0273 - 0x4C380000, // 0267 LDNIL R14 - 0x1C38140E, // 0268 EQ R14 R10 R14 - 0x743A0008, // 0269 JMPT R14 #0273 - 0x4C380000, // 026A LDNIL R14 - 0x1C38160E, // 026B EQ R14 R11 R14 - 0x743A0005, // 026C JMPT R14 #0273 - 0x4C380000, // 026D LDNIL R14 - 0x1C38180E, // 026E EQ R14 R12 R14 - 0x743A0002, // 026F JMPT R14 #0273 - 0x4C380000, // 0270 LDNIL R14 - 0x1C381A0E, // 0271 EQ R14 R13 R14 - 0x783A0005, // 0272 JMPF R14 #0279 - 0xB83A0400, // 0273 GETNGBL R14 K2 - 0x88381D5B, // 0274 GETMBR R14 R14 K91 - 0x900E2E0E, // 0275 SETMBR R3 K23 R14 - 0x4C380000, // 0276 LDNIL R14 - 0xA0000000, // 0277 CLOSE R0 - 0x80041C00, // 0278 RET 1 R14 - 0x6038000C, // 0279 GETGBL R14 G12 - 0x5C3C1400, // 027A MOVE R15 R10 - 0x7C380200, // 027B CALL R14 1 - 0x543E001F, // 027C LDINT R15 32 - 0x54420040, // 027D LDINT R16 65 - 0x003C1E10, // 027E ADD R15 R15 R16 - 0x20381C0F, // 027F NE R14 R14 R15 - 0x743A000B, // 0280 JMPT R14 #028D - 0x6038000C, // 0281 GETGBL R14 G12 - 0x5C3C1A00, // 0282 MOVE R15 R13 - 0x7C380200, // 0283 CALL R14 1 - 0x543E000F, // 0284 LDINT R15 16 - 0x14381C0F, // 0285 LT R14 R14 R15 - 0x743A0005, // 0286 JMPT R14 #028D - 0x6038000C, // 0287 GETGBL R14 G12 - 0x5C3C1A00, // 0288 MOVE R15 R13 - 0x7C380200, // 0289 CALL R14 1 - 0x543E001F, // 028A LDINT R15 32 - 0x24381C0F, // 028B GT R14 R14 R15 - 0x783A0009, // 028C JMPF R14 #0297 - 0xB83A3E00, // 028D GETNGBL R14 K31 - 0x8C381D24, // 028E GETMET R14 R14 K36 - 0x5840005C, // 028F LDCONST R16 K92 - 0x7C380400, // 0290 CALL R14 2 - 0xB83A0400, // 0291 GETNGBL R14 K2 - 0x88381D5D, // 0292 GETMBR R14 R14 K93 - 0x900E2E0E, // 0293 SETMBR R3 K23 R14 - 0x4C380000, // 0294 LDNIL R14 - 0xA0000000, // 0295 CLOSE R0 - 0x80041C00, // 0296 RET 1 R14 - 0x543A001E, // 0297 LDINT R14 31 - 0x403A0C0E, // 0298 CONNECT R14 K6 R14 - 0x9438140E, // 0299 GETIDX R14 R10 R14 - 0x543E001F, // 029A LDINT R15 32 - 0x403C1F3B, // 029B CONNECT R15 R15 K59 - 0x943C140F, // 029C GETIDX R15 R10 R15 - 0x88400115, // 029D GETMBR R16 R0 K21 - 0x8C40215E, // 029E GETMET R16 R16 K94 - 0x5C481200, // 029F MOVE R18 R9 - 0x5C4C1800, // 02A0 MOVE R19 R12 - 0x5C501600, // 02A1 MOVE R20 R11 - 0x5C541A00, // 02A2 MOVE R21 R13 - 0x5C581C00, // 02A3 MOVE R22 R14 - 0x5C5C1E00, // 02A4 MOVE R23 R15 - 0x8C60035F, // 02A5 GETMET R24 R1 K95 - 0x7C600200, // 02A6 CALL R24 1 - 0x7C401000, // 02A7 CALL R16 8 - 0x50400200, // 02A8 LDBOOL R16 1 0 - 0xA0000000, // 02A9 CLOSE R0 - 0x80042000, // 02AA RET 1 R16 - 0x7002001C, // 02AB JMP #02C9 - 0x1C241108, // 02AC EQ R9 R8 K8 - 0x78260012, // 02AD JMPF R9 #02C1 - 0x8C240507, // 02AE GETMET R9 R2 K7 - 0x582C0006, // 02AF LDCONST R11 K6 - 0x7C240400, // 02B0 CALL R9 2 - 0xB82A3E00, // 02B1 GETNGBL R10 K31 - 0x8C281524, // 02B2 GETMET R10 R10 K36 - 0x60300008, // 02B3 GETGBL R12 G8 - 0x5C341200, // 02B4 MOVE R13 R9 - 0x7C300200, // 02B5 CALL R12 1 - 0x0032C00C, // 02B6 ADD R12 K96 R12 - 0x5834000F, // 02B7 LDCONST R13 K15 - 0x7C280600, // 02B8 CALL R10 3 - 0x88280115, // 02B9 GETMBR R10 R0 K21 - 0x8C281561, // 02BA GETMET R10 R10 K97 - 0x5C301200, // 02BB MOVE R12 R9 - 0x7C280400, // 02BC CALL R10 2 - 0x50280200, // 02BD LDBOOL R10 1 0 - 0xA0000000, // 02BE CLOSE R0 - 0x80041400, // 02BF RET 1 R10 - 0x70020007, // 02C0 JMP #02C9 - 0x1C24110F, // 02C1 EQ R9 R8 K15 - 0x78260005, // 02C2 JMPF R9 #02C9 - 0x88240115, // 02C3 GETMBR R9 R0 K21 - 0x8C241362, // 02C4 GETMET R9 R9 K98 - 0x7C240200, // 02C5 CALL R9 1 - 0x50240200, // 02C6 LDBOOL R9 1 0 - 0xA0000000, // 02C7 CLOSE R0 - 0x80041200, // 02C8 RET 1 R9 - 0x70020012, // 02C9 JMP #02DD - 0x54260029, // 02CA LDINT R9 42 - 0x1C240E09, // 02CB EQ R9 R7 R9 - 0x78260005, // 02CC JMPF R9 #02D3 - 0x1C241106, // 02CD EQ R9 R8 K6 - 0x78260002, // 02CE JMPF R9 #02D2 - 0x50240200, // 02CF LDBOOL R9 1 0 - 0xA0000000, // 02D0 CLOSE R0 - 0x80041200, // 02D1 RET 1 R9 - 0x70020009, // 02D2 JMP #02DD - 0x60240003, // 02D3 GETGBL R9 G3 - 0x5C280000, // 02D4 MOVE R10 R0 - 0x7C240200, // 02D5 CALL R9 1 - 0x8C241363, // 02D6 GETMET R9 R9 K99 - 0x5C2C0200, // 02D7 MOVE R11 R1 - 0x5C300400, // 02D8 MOVE R12 R2 - 0x5C340600, // 02D9 MOVE R13 R3 - 0x7C240800, // 02DA CALL R9 4 - 0xA0000000, // 02DB CLOSE R0 - 0x80041200, // 02DC RET 1 R9 - 0xA0000000, // 02DD CLOSE R0 - 0x80000000, // 02DE RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Root -********************************************************************/ -extern const bclass be_class_Matter_Plugin; -be_local_class(Matter_Plugin_Root, - 0, - &be_class_Matter_Plugin, - be_nested_map(8, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(invoke_request, 1), be_const_closure(Matter_Plugin_Root_invoke_request_closure) }, - { be_const_key_weak(write_attribute, -1), be_const_closure(Matter_Plugin_Root_write_attribute_closure) }, - { be_const_key_weak(CLUSTERS, 4), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(13, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(52, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(0, - ( (struct bvalue*) &(const bvalue[]) { - })) ) } )) }, - { be_const_key_int(40, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(14, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(2), - be_const_int(3), - be_const_int(4), - be_const_int(5), - be_const_int(6), - be_const_int(7), - be_const_int(8), - be_const_int(9), - be_const_int(10), - be_const_int(15), - be_const_int(18), - be_const_int(19), - })) ) } )) }, - { be_const_key_int(62, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(6, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(2), - be_const_int(3), - be_const_int(4), - be_const_int(5), - })) ) } )) }, - { be_const_key_int(63, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(0, - ( (struct bvalue*) &(const bvalue[]) { - })) ) } )) }, - { be_const_key_int(56, 6), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(3, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(7), - })) ) } )) }, - { be_const_key_int(44, 7), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(3, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(2), - })) ) } )) }, - { be_const_key_int(43, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(2, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - })) ) } )) }, - { be_const_key_int(31, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(4, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(2), - be_const_int(3), - be_const_int(4), - })) ) } )) }, - { be_const_key_int(60, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(3, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(2), - })) ) } )) }, - { be_const_key_int(48, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(5, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(2), - be_const_int(3), - be_const_int(4), - })) ) } )) }, - { be_const_key_int(49, 2), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(3, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(3), - be_const_int(4), - be_const_int(65532), - })) ) } )) }, - { be_const_key_int(50, 3), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(0, - ( (struct bvalue*) &(const bvalue[]) { - })) ) } )) }, - { be_const_key_int(51, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(4, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(2), - be_const_int(8), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(init, 0), be_const_closure(Matter_Plugin_Root_init_closure) }, - { be_const_key_weak(read_attribute, 7), be_const_closure(Matter_Plugin_Root_read_attribute_closure) }, - { be_const_key_weak(TYPE, -1), be_nested_str_weak(root) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak(Root_X20node) }, - { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(22, -1), be_const_int(1) }, - })) ) } )) }, - })), - be_str_weak(Matter_Plugin_Root) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Root_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Root); - be_setglobal(vm, "Matter_Plugin_Root"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor.h deleted file mode 100644 index 788358b91373..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor.h +++ /dev/null @@ -1,189 +0,0 @@ -/* Solidification of Matter_Plugin_Sensor.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Sensor; - -/******************************************************************** -** Solidified function: pre_value -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_pre_value, /* name */ - be_nested_proto( - 2, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(pre_value), - &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80040200, // 0000 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: value_changed -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_value_changed, /* name */ - be_nested_proto( - 2, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(value_changed), - &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: parse_sensors -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_parse_sensors, /* name */ - be_nested_proto( - 8, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(tasmota_sensor_matcher), - /* K1 */ be_nested_str_weak(pre_value), - /* K2 */ be_nested_str_weak(match), - /* K3 */ be_nested_str_weak(shadow_value), - /* K4 */ be_nested_str_weak(value_changed), - }), - be_str_weak(parse_sensors), - &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x780A0011, // 0001 JMPF R2 #0014 - 0x8C080101, // 0002 GETMET R2 R0 K1 - 0x6010000A, // 0003 GETGBL R4 G10 - 0x88140100, // 0004 GETMBR R5 R0 K0 - 0x8C140B02, // 0005 GETMET R5 R5 K2 - 0x5C1C0200, // 0006 MOVE R7 R1 - 0x7C140400, // 0007 CALL R5 2 - 0x7C100200, // 0008 CALL R4 1 - 0x7C080400, // 0009 CALL R2 2 - 0x4C0C0000, // 000A LDNIL R3 - 0x200C0403, // 000B NE R3 R2 R3 - 0x780E0006, // 000C JMPF R3 #0014 - 0x880C0103, // 000D GETMBR R3 R0 K3 - 0x200C0403, // 000E NE R3 R2 R3 - 0x780E0002, // 000F JMPF R3 #0013 - 0x8C0C0104, // 0010 GETMET R3 R0 K4 - 0x5C140400, // 0011 MOVE R5 R2 - 0x7C0C0400, // 0012 CALL R3 2 - 0x90020602, // 0013 SETMBR R0 K3 R2 - 0x80000000, // 0014 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_init, /* name */ - be_nested_proto( - 9, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(init), - /* K1 */ be_nested_str_weak(tasmota_sensor_filter), - /* K2 */ be_nested_str_weak(find), - /* K3 */ be_nested_str_weak(ARG), - /* K4 */ be_nested_str_weak(tasmota_sensor_matcher), - /* K5 */ be_nested_str_weak(tasmota), - /* K6 */ be_nested_str_weak(Rule_Matcher), - /* K7 */ be_nested_str_weak(parse), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0x60100003, // 0000 GETGBL R4 G3 - 0x5C140000, // 0001 MOVE R5 R0 - 0x7C100200, // 0002 CALL R4 1 - 0x8C100900, // 0003 GETMET R4 R4 K0 - 0x5C180200, // 0004 MOVE R6 R1 - 0x5C1C0400, // 0005 MOVE R7 R2 - 0x5C200600, // 0006 MOVE R8 R3 - 0x7C100800, // 0007 CALL R4 4 - 0x8C100702, // 0008 GETMET R4 R3 K2 - 0x88180103, // 0009 GETMBR R6 R0 K3 - 0x7C100400, // 000A CALL R4 2 - 0x90020204, // 000B SETMBR R0 K1 R4 - 0x88100101, // 000C GETMBR R4 R0 K1 - 0x78120005, // 000D JMPF R4 #0014 - 0xB8120A00, // 000E GETNGBL R4 K5 - 0x88100906, // 000F GETMBR R4 R4 K6 - 0x8C100907, // 0010 GETMET R4 R4 K7 - 0x88180101, // 0011 GETMBR R6 R0 K1 - 0x7C100400, // 0012 CALL R4 2 - 0x90020804, // 0013 SETMBR R0 K4 R4 - 0x80000000, // 0014 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Sensor -********************************************************************/ -extern const bclass be_class_Matter_Plugin_Device; -be_local_class(Matter_Plugin_Sensor, - 3, - &be_class_Matter_Plugin_Device, - be_nested_map(9, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(UPDATE_TIME, 3), be_const_int(5000) }, - { be_const_key_weak(tasmota_sensor_filter, -1), be_const_var(0) }, - { be_const_key_weak(pre_value, -1), be_const_closure(Matter_Plugin_Sensor_pre_value_closure) }, - { be_const_key_weak(ARG, -1), be_nested_str_weak(filter) }, - { be_const_key_weak(value_changed, -1), be_const_closure(Matter_Plugin_Sensor_value_changed_closure) }, - { be_const_key_weak(init, 7), be_const_closure(Matter_Plugin_Sensor_init_closure) }, - { be_const_key_weak(parse_sensors, 5), be_const_closure(Matter_Plugin_Sensor_parse_sensors_closure) }, - { be_const_key_weak(shadow_value, -1), be_const_var(2) }, - { be_const_key_weak(tasmota_sensor_matcher, -1), be_const_var(1) }, - })), - be_str_weak(Matter_Plugin_Sensor) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Sensor_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor); - be_setglobal(vm, "Matter_Plugin_Sensor"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor_Humidity.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor_Humidity.h deleted file mode 100644 index 179384ac0be3..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor_Humidity.h +++ /dev/null @@ -1,226 +0,0 @@ -/* Solidification of Matter_Plugin_Sensor_Humidity.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Sensor_Humidity; - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_Humidity_read_attribute, /* name */ - be_nested_proto( - 12, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(shadow_value), - /* K7 */ be_nested_str_weak(create_TLV), - /* K8 */ be_nested_str_weak(U2), - /* K9 */ be_nested_str_weak(NULL), - /* K10 */ be_const_int(1), - /* K11 */ be_const_int(2), - /* K12 */ be_nested_str_weak(U4), - /* K13 */ be_const_int(3), - /* K14 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[71]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x541E0404, // 0005 LDINT R7 1029 - 0x1C1C0A07, // 0006 EQ R7 R5 R7 - 0x781E0035, // 0007 JMPF R7 #003E - 0x1C1C0D05, // 0008 EQ R7 R6 K5 - 0x781E0011, // 0009 JMPF R7 #001C - 0x881C0106, // 000A GETMBR R7 R0 K6 - 0x4C200000, // 000B LDNIL R8 - 0x201C0E08, // 000C NE R7 R7 R8 - 0x781E0007, // 000D JMPF R7 #0016 - 0x8C1C0907, // 000E GETMET R7 R4 K7 - 0x88240908, // 000F GETMBR R9 R4 K8 - 0x60280009, // 0010 GETGBL R10 G9 - 0x882C0106, // 0011 GETMBR R11 R0 K6 - 0x7C280200, // 0012 CALL R10 1 - 0x7C1C0600, // 0013 CALL R7 3 - 0x80040E00, // 0014 RET 1 R7 - 0x70020004, // 0015 JMP #001B - 0x8C1C0907, // 0016 GETMET R7 R4 K7 - 0x88240909, // 0017 GETMBR R9 R4 K9 - 0x4C280000, // 0018 LDNIL R10 - 0x7C1C0600, // 0019 CALL R7 3 - 0x80040E00, // 001A RET 1 R7 - 0x70020020, // 001B JMP #003D - 0x1C1C0D0A, // 001C EQ R7 R6 K10 - 0x781E0005, // 001D JMPF R7 #0024 - 0x8C1C0907, // 001E GETMET R7 R4 K7 - 0x88240908, // 001F GETMBR R9 R4 K8 - 0x542A01F3, // 0020 LDINT R10 500 - 0x7C1C0600, // 0021 CALL R7 3 - 0x80040E00, // 0022 RET 1 R7 - 0x70020018, // 0023 JMP #003D - 0x1C1C0D0B, // 0024 EQ R7 R6 K11 - 0x781E0005, // 0025 JMPF R7 #002C - 0x8C1C0907, // 0026 GETMET R7 R4 K7 - 0x88240908, // 0027 GETMBR R9 R4 K8 - 0x542A270F, // 0028 LDINT R10 10000 - 0x7C1C0600, // 0029 CALL R7 3 - 0x80040E00, // 002A RET 1 R7 - 0x70020010, // 002B JMP #003D - 0x541EFFFB, // 002C LDINT R7 65532 - 0x1C1C0C07, // 002D EQ R7 R6 R7 - 0x781E0005, // 002E JMPF R7 #0035 - 0x8C1C0907, // 002F GETMET R7 R4 K7 - 0x8824090C, // 0030 GETMBR R9 R4 K12 - 0x58280005, // 0031 LDCONST R10 K5 - 0x7C1C0600, // 0032 CALL R7 3 - 0x80040E00, // 0033 RET 1 R7 - 0x70020007, // 0034 JMP #003D - 0x541EFFFC, // 0035 LDINT R7 65533 - 0x1C1C0C07, // 0036 EQ R7 R6 R7 - 0x781E0004, // 0037 JMPF R7 #003D - 0x8C1C0907, // 0038 GETMET R7 R4 K7 - 0x8824090C, // 0039 GETMBR R9 R4 K12 - 0x5828000D, // 003A LDCONST R10 K13 - 0x7C1C0600, // 003B CALL R7 3 - 0x80040E00, // 003C RET 1 R7 - 0x70020007, // 003D JMP #0046 - 0x601C0003, // 003E GETGBL R7 G3 - 0x5C200000, // 003F MOVE R8 R0 - 0x7C1C0200, // 0040 CALL R7 1 - 0x8C1C0F0E, // 0041 GETMET R7 R7 K14 - 0x5C240200, // 0042 MOVE R9 R1 - 0x5C280400, // 0043 MOVE R10 R2 - 0x7C1C0600, // 0044 CALL R7 3 - 0x80040E00, // 0045 RET 1 R7 - 0x80000000, // 0046 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pre_value -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_Humidity_pre_value, /* name */ - be_nested_proto( - 4, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(pre_value), - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x4C080000, // 0000 LDNIL R2 - 0x20080202, // 0001 NE R2 R1 R2 - 0x780A0004, // 0002 JMPF R2 #0008 - 0x60080009, // 0003 GETGBL R2 G9 - 0x540E0063, // 0004 LDINT R3 100 - 0x080C0203, // 0005 MUL R3 R1 R3 - 0x7C080200, // 0006 CALL R2 1 - 0x70020000, // 0007 JMP #0009 - 0x4C080000, // 0008 LDNIL R2 - 0x80040400, // 0009 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: value_changed -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_Humidity_value_changed, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(attribute_updated), - /* K1 */ be_const_int(0), - }), - be_str_weak(value_changed), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x54120404, // 0001 LDINT R4 1029 - 0x58140001, // 0002 LDCONST R5 K1 - 0x7C080600, // 0003 CALL R2 3 - 0x80000000, // 0004 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Sensor_Humidity -********************************************************************/ -extern const bclass be_class_Matter_Plugin_Sensor; -be_local_class(Matter_Plugin_Sensor_Humidity, - 0, - &be_class_Matter_Plugin_Sensor, - be_nested_map(7, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(read_attribute, 2), be_const_closure(Matter_Plugin_Sensor_Humidity_read_attribute_closure) }, - { be_const_key_weak(pre_value, 4), be_const_closure(Matter_Plugin_Sensor_Humidity_pre_value_closure) }, - { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(1029, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(5, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(2), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(TYPE, 6), be_nested_str_weak(humidity) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak(Humidity) }, - { be_const_key_weak(value_changed, -1), be_const_closure(Matter_Plugin_Sensor_Humidity_value_changed_closure) }, - { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(775, -1), be_const_int(2) }, - })) ) } )) }, - })), - be_str_weak(Matter_Plugin_Sensor_Humidity) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Sensor_Humidity_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor_Humidity); - be_setglobal(vm, "Matter_Plugin_Sensor_Humidity"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor_Illuminance.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor_Illuminance.h deleted file mode 100644 index 99cba606834f..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor_Illuminance.h +++ /dev/null @@ -1,225 +0,0 @@ -/* Solidification of Matter_Plugin_Sensor_Illuminance.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Sensor_Illuminance; - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_Illuminance_read_attribute, /* name */ - be_nested_proto( - 12, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(shadow_value), - /* K7 */ be_nested_str_weak(create_TLV), - /* K8 */ be_nested_str_weak(I2), - /* K9 */ be_nested_str_weak(NULL), - /* K10 */ be_const_int(1), - /* K11 */ be_const_int(2), - /* K12 */ be_nested_str_weak(U4), - /* K13 */ be_const_int(3), - /* K14 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[71]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x541E03FF, // 0005 LDINT R7 1024 - 0x1C1C0A07, // 0006 EQ R7 R5 R7 - 0x781E0035, // 0007 JMPF R7 #003E - 0x1C1C0D05, // 0008 EQ R7 R6 K5 - 0x781E0011, // 0009 JMPF R7 #001C - 0x881C0106, // 000A GETMBR R7 R0 K6 - 0x4C200000, // 000B LDNIL R8 - 0x201C0E08, // 000C NE R7 R7 R8 - 0x781E0007, // 000D JMPF R7 #0016 - 0x8C1C0907, // 000E GETMET R7 R4 K7 - 0x88240908, // 000F GETMBR R9 R4 K8 - 0x60280009, // 0010 GETGBL R10 G9 - 0x882C0106, // 0011 GETMBR R11 R0 K6 - 0x7C280200, // 0012 CALL R10 1 - 0x7C1C0600, // 0013 CALL R7 3 - 0x80040E00, // 0014 RET 1 R7 - 0x70020004, // 0015 JMP #001B - 0x8C1C0907, // 0016 GETMET R7 R4 K7 - 0x88240909, // 0017 GETMBR R9 R4 K9 - 0x4C280000, // 0018 LDNIL R10 - 0x7C1C0600, // 0019 CALL R7 3 - 0x80040E00, // 001A RET 1 R7 - 0x70020020, // 001B JMP #003D - 0x1C1C0D0A, // 001C EQ R7 R6 K10 - 0x781E0005, // 001D JMPF R7 #0024 - 0x8C1C0907, // 001E GETMET R7 R4 K7 - 0x88240908, // 001F GETMBR R9 R4 K8 - 0x58280005, // 0020 LDCONST R10 K5 - 0x7C1C0600, // 0021 CALL R7 3 - 0x80040E00, // 0022 RET 1 R7 - 0x70020018, // 0023 JMP #003D - 0x1C1C0D0B, // 0024 EQ R7 R6 K11 - 0x781E0005, // 0025 JMPF R7 #002C - 0x8C1C0907, // 0026 GETMET R7 R4 K7 - 0x88240908, // 0027 GETMBR R9 R4 K8 - 0x542A270F, // 0028 LDINT R10 10000 - 0x7C1C0600, // 0029 CALL R7 3 - 0x80040E00, // 002A RET 1 R7 - 0x70020010, // 002B JMP #003D - 0x541EFFFB, // 002C LDINT R7 65532 - 0x1C1C0C07, // 002D EQ R7 R6 R7 - 0x781E0005, // 002E JMPF R7 #0035 - 0x8C1C0907, // 002F GETMET R7 R4 K7 - 0x8824090C, // 0030 GETMBR R9 R4 K12 - 0x58280005, // 0031 LDCONST R10 K5 - 0x7C1C0600, // 0032 CALL R7 3 - 0x80040E00, // 0033 RET 1 R7 - 0x70020007, // 0034 JMP #003D - 0x541EFFFC, // 0035 LDINT R7 65533 - 0x1C1C0C07, // 0036 EQ R7 R6 R7 - 0x781E0004, // 0037 JMPF R7 #003D - 0x8C1C0907, // 0038 GETMET R7 R4 K7 - 0x8824090C, // 0039 GETMBR R9 R4 K12 - 0x5828000D, // 003A LDCONST R10 K13 - 0x7C1C0600, // 003B CALL R7 3 - 0x80040E00, // 003C RET 1 R7 - 0x70020007, // 003D JMP #0046 - 0x601C0003, // 003E GETGBL R7 G3 - 0x5C200000, // 003F MOVE R8 R0 - 0x7C1C0200, // 0040 CALL R7 1 - 0x8C1C0F0E, // 0041 GETMET R7 R7 K14 - 0x5C240200, // 0042 MOVE R9 R1 - 0x5C280400, // 0043 MOVE R10 R2 - 0x7C1C0600, // 0044 CALL R7 3 - 0x80040E00, // 0045 RET 1 R7 - 0x80000000, // 0046 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pre_value -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_Illuminance_pre_value, /* name */ - be_nested_proto( - 4, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(pre_value), - &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x4C080000, // 0000 LDNIL R2 - 0x20080202, // 0001 NE R2 R1 R2 - 0x780A0003, // 0002 JMPF R2 #0007 - 0x60080009, // 0003 GETGBL R2 G9 - 0x5C0C0200, // 0004 MOVE R3 R1 - 0x7C080200, // 0005 CALL R2 1 - 0x70020000, // 0006 JMP #0008 - 0x4C080000, // 0007 LDNIL R2 - 0x80040400, // 0008 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: value_changed -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_Illuminance_value_changed, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(attribute_updated), - /* K1 */ be_const_int(0), - }), - be_str_weak(value_changed), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x541203FF, // 0001 LDINT R4 1024 - 0x58140001, // 0002 LDCONST R5 K1 - 0x7C080600, // 0003 CALL R2 3 - 0x80000000, // 0004 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Sensor_Illuminance -********************************************************************/ -extern const bclass be_class_Matter_Plugin_Sensor; -be_local_class(Matter_Plugin_Sensor_Illuminance, - 0, - &be_class_Matter_Plugin_Sensor, - be_nested_map(7, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(read_attribute, 2), be_const_closure(Matter_Plugin_Sensor_Illuminance_read_attribute_closure) }, - { be_const_key_weak(pre_value, 4), be_const_closure(Matter_Plugin_Sensor_Illuminance_pre_value_closure) }, - { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(1024, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(5, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(2), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(TYPE, 6), be_nested_str_weak(illuminance) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak(Illuminance) }, - { be_const_key_weak(value_changed, -1), be_const_closure(Matter_Plugin_Sensor_Illuminance_value_changed_closure) }, - { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(262, -1), be_const_int(2) }, - })) ) } )) }, - })), - be_str_weak(Matter_Plugin_Sensor_Illuminance) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Sensor_Illuminance_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor_Illuminance); - be_setglobal(vm, "Matter_Plugin_Sensor_Illuminance"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor_Pressure.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor_Pressure.h deleted file mode 100644 index d3e645510601..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor_Pressure.h +++ /dev/null @@ -1,225 +0,0 @@ -/* Solidification of Matter_Plugin_Sensor_Pressure.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Sensor_Pressure; - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_Pressure_read_attribute, /* name */ - be_nested_proto( - 12, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(shadow_value), - /* K7 */ be_nested_str_weak(create_TLV), - /* K8 */ be_nested_str_weak(I2), - /* K9 */ be_nested_str_weak(NULL), - /* K10 */ be_const_int(1), - /* K11 */ be_const_int(2), - /* K12 */ be_nested_str_weak(U4), - /* K13 */ be_const_int(3), - /* K14 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[71]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x541E0402, // 0005 LDINT R7 1027 - 0x1C1C0A07, // 0006 EQ R7 R5 R7 - 0x781E0035, // 0007 JMPF R7 #003E - 0x1C1C0D05, // 0008 EQ R7 R6 K5 - 0x781E0011, // 0009 JMPF R7 #001C - 0x881C0106, // 000A GETMBR R7 R0 K6 - 0x4C200000, // 000B LDNIL R8 - 0x201C0E08, // 000C NE R7 R7 R8 - 0x781E0007, // 000D JMPF R7 #0016 - 0x8C1C0907, // 000E GETMET R7 R4 K7 - 0x88240908, // 000F GETMBR R9 R4 K8 - 0x60280009, // 0010 GETGBL R10 G9 - 0x882C0106, // 0011 GETMBR R11 R0 K6 - 0x7C280200, // 0012 CALL R10 1 - 0x7C1C0600, // 0013 CALL R7 3 - 0x80040E00, // 0014 RET 1 R7 - 0x70020004, // 0015 JMP #001B - 0x8C1C0907, // 0016 GETMET R7 R4 K7 - 0x88240909, // 0017 GETMBR R9 R4 K9 - 0x4C280000, // 0018 LDNIL R10 - 0x7C1C0600, // 0019 CALL R7 3 - 0x80040E00, // 001A RET 1 R7 - 0x70020020, // 001B JMP #003D - 0x1C1C0D0A, // 001C EQ R7 R6 K10 - 0x781E0005, // 001D JMPF R7 #0024 - 0x8C1C0907, // 001E GETMET R7 R4 K7 - 0x88240908, // 001F GETMBR R9 R4 K8 - 0x542A01F3, // 0020 LDINT R10 500 - 0x7C1C0600, // 0021 CALL R7 3 - 0x80040E00, // 0022 RET 1 R7 - 0x70020018, // 0023 JMP #003D - 0x1C1C0D0B, // 0024 EQ R7 R6 K11 - 0x781E0005, // 0025 JMPF R7 #002C - 0x8C1C0907, // 0026 GETMET R7 R4 K7 - 0x88240908, // 0027 GETMBR R9 R4 K8 - 0x542A05DB, // 0028 LDINT R10 1500 - 0x7C1C0600, // 0029 CALL R7 3 - 0x80040E00, // 002A RET 1 R7 - 0x70020010, // 002B JMP #003D - 0x541EFFFB, // 002C LDINT R7 65532 - 0x1C1C0C07, // 002D EQ R7 R6 R7 - 0x781E0005, // 002E JMPF R7 #0035 - 0x8C1C0907, // 002F GETMET R7 R4 K7 - 0x8824090C, // 0030 GETMBR R9 R4 K12 - 0x58280005, // 0031 LDCONST R10 K5 - 0x7C1C0600, // 0032 CALL R7 3 - 0x80040E00, // 0033 RET 1 R7 - 0x70020007, // 0034 JMP #003D - 0x541EFFFC, // 0035 LDINT R7 65533 - 0x1C1C0C07, // 0036 EQ R7 R6 R7 - 0x781E0004, // 0037 JMPF R7 #003D - 0x8C1C0907, // 0038 GETMET R7 R4 K7 - 0x8824090C, // 0039 GETMBR R9 R4 K12 - 0x5828000D, // 003A LDCONST R10 K13 - 0x7C1C0600, // 003B CALL R7 3 - 0x80040E00, // 003C RET 1 R7 - 0x70020007, // 003D JMP #0046 - 0x601C0003, // 003E GETGBL R7 G3 - 0x5C200000, // 003F MOVE R8 R0 - 0x7C1C0200, // 0040 CALL R7 1 - 0x8C1C0F0E, // 0041 GETMET R7 R7 K14 - 0x5C240200, // 0042 MOVE R9 R1 - 0x5C280400, // 0043 MOVE R10 R2 - 0x7C1C0600, // 0044 CALL R7 3 - 0x80040E00, // 0045 RET 1 R7 - 0x80000000, // 0046 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pre_value -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_Pressure_pre_value, /* name */ - be_nested_proto( - 4, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(pre_value), - &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x4C080000, // 0000 LDNIL R2 - 0x20080202, // 0001 NE R2 R1 R2 - 0x780A0003, // 0002 JMPF R2 #0007 - 0x60080009, // 0003 GETGBL R2 G9 - 0x5C0C0200, // 0004 MOVE R3 R1 - 0x7C080200, // 0005 CALL R2 1 - 0x70020000, // 0006 JMP #0008 - 0x4C080000, // 0007 LDNIL R2 - 0x80040400, // 0008 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: value_changed -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_Pressure_value_changed, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(attribute_updated), - /* K1 */ be_const_int(0), - }), - be_str_weak(value_changed), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x54120402, // 0001 LDINT R4 1027 - 0x58140001, // 0002 LDCONST R5 K1 - 0x7C080600, // 0003 CALL R2 3 - 0x80000000, // 0004 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Sensor_Pressure -********************************************************************/ -extern const bclass be_class_Matter_Plugin_Sensor; -be_local_class(Matter_Plugin_Sensor_Pressure, - 0, - &be_class_Matter_Plugin_Sensor, - be_nested_map(7, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(read_attribute, 2), be_const_closure(Matter_Plugin_Sensor_Pressure_read_attribute_closure) }, - { be_const_key_weak(pre_value, 4), be_const_closure(Matter_Plugin_Sensor_Pressure_pre_value_closure) }, - { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(1027, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(5, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(2), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(TYPE, 6), be_nested_str_weak(pressure) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak(Pressure) }, - { be_const_key_weak(value_changed, -1), be_const_closure(Matter_Plugin_Sensor_Pressure_value_changed_closure) }, - { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(773, -1), be_const_int(2) }, - })) ) } )) }, - })), - be_str_weak(Matter_Plugin_Sensor_Pressure) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Sensor_Pressure_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor_Pressure); - be_setglobal(vm, "Matter_Plugin_Sensor_Pressure"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor_Temp.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor_Temp.h deleted file mode 100644 index 13569d9e4fa4..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Plugin_Sensor_Temp.h +++ /dev/null @@ -1,223 +0,0 @@ -/* Solidification of Matter_Plugin_Sensor_Temp.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -extern const bclass be_class_Matter_Plugin_Sensor_Temp; - -/******************************************************************** -** Solidified function: read_attribute -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_Temp_read_attribute, /* name */ - be_nested_proto( - 11, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[14]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(matter), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(cluster), - /* K4 */ be_nested_str_weak(attribute), - /* K5 */ be_const_int(0), - /* K6 */ be_nested_str_weak(shadow_value), - /* K7 */ be_nested_str_weak(create_TLV), - /* K8 */ be_nested_str_weak(I2), - /* K9 */ be_nested_str_weak(NULL), - /* K10 */ be_const_int(1), - /* K11 */ be_const_int(2), - /* K12 */ be_nested_str_weak(U4), - /* K13 */ be_nested_str_weak(read_attribute), - }), - be_str_weak(read_attribute), - &be_const_str_solidified, - ( &(const binstruction[69]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xB8120200, // 0001 GETNGBL R4 K1 - 0x88100902, // 0002 GETMBR R4 R4 K2 - 0x88140503, // 0003 GETMBR R5 R2 K3 - 0x88180504, // 0004 GETMBR R6 R2 K4 - 0x541E0401, // 0005 LDINT R7 1026 - 0x1C1C0A07, // 0006 EQ R7 R5 R7 - 0x781E0033, // 0007 JMPF R7 #003C - 0x1C1C0D05, // 0008 EQ R7 R6 K5 - 0x781E000F, // 0009 JMPF R7 #001A - 0x881C0106, // 000A GETMBR R7 R0 K6 - 0x4C200000, // 000B LDNIL R8 - 0x201C0E08, // 000C NE R7 R7 R8 - 0x781E0005, // 000D JMPF R7 #0014 - 0x8C1C0907, // 000E GETMET R7 R4 K7 - 0x88240908, // 000F GETMBR R9 R4 K8 - 0x88280106, // 0010 GETMBR R10 R0 K6 - 0x7C1C0600, // 0011 CALL R7 3 - 0x80040E00, // 0012 RET 1 R7 - 0x70020004, // 0013 JMP #0019 - 0x8C1C0907, // 0014 GETMET R7 R4 K7 - 0x88240909, // 0015 GETMBR R9 R4 K9 - 0x4C280000, // 0016 LDNIL R10 - 0x7C1C0600, // 0017 CALL R7 3 - 0x80040E00, // 0018 RET 1 R7 - 0x70020020, // 0019 JMP #003B - 0x1C1C0D0A, // 001A EQ R7 R6 K10 - 0x781E0005, // 001B JMPF R7 #0022 - 0x8C1C0907, // 001C GETMET R7 R4 K7 - 0x88240908, // 001D GETMBR R9 R4 K8 - 0x5429EC77, // 001E LDINT R10 -5000 - 0x7C1C0600, // 001F CALL R7 3 - 0x80040E00, // 0020 RET 1 R7 - 0x70020018, // 0021 JMP #003B - 0x1C1C0D0B, // 0022 EQ R7 R6 K11 - 0x781E0005, // 0023 JMPF R7 #002A - 0x8C1C0907, // 0024 GETMET R7 R4 K7 - 0x88240908, // 0025 GETMBR R9 R4 K8 - 0x542A3A97, // 0026 LDINT R10 15000 - 0x7C1C0600, // 0027 CALL R7 3 - 0x80040E00, // 0028 RET 1 R7 - 0x70020010, // 0029 JMP #003B - 0x541EFFFB, // 002A LDINT R7 65532 - 0x1C1C0C07, // 002B EQ R7 R6 R7 - 0x781E0005, // 002C JMPF R7 #0033 - 0x8C1C0907, // 002D GETMET R7 R4 K7 - 0x8824090C, // 002E GETMBR R9 R4 K12 - 0x58280005, // 002F LDCONST R10 K5 - 0x7C1C0600, // 0030 CALL R7 3 - 0x80040E00, // 0031 RET 1 R7 - 0x70020007, // 0032 JMP #003B - 0x541EFFFC, // 0033 LDINT R7 65533 - 0x1C1C0C07, // 0034 EQ R7 R6 R7 - 0x781E0004, // 0035 JMPF R7 #003B - 0x8C1C0907, // 0036 GETMET R7 R4 K7 - 0x8824090C, // 0037 GETMBR R9 R4 K12 - 0x542A0003, // 0038 LDINT R10 4 - 0x7C1C0600, // 0039 CALL R7 3 - 0x80040E00, // 003A RET 1 R7 - 0x70020007, // 003B JMP #0044 - 0x601C0003, // 003C GETGBL R7 G3 - 0x5C200000, // 003D MOVE R8 R0 - 0x7C1C0200, // 003E CALL R7 1 - 0x8C1C0F0D, // 003F GETMET R7 R7 K13 - 0x5C240200, // 0040 MOVE R9 R1 - 0x5C280400, // 0041 MOVE R10 R2 - 0x7C1C0600, // 0042 CALL R7 3 - 0x80040E00, // 0043 RET 1 R7 - 0x80000000, // 0044 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pre_value -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_Temp_pre_value, /* name */ - be_nested_proto( - 4, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(pre_value), - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x4C080000, // 0000 LDNIL R2 - 0x20080202, // 0001 NE R2 R1 R2 - 0x780A0004, // 0002 JMPF R2 #0008 - 0x60080009, // 0003 GETGBL R2 G9 - 0x540E0063, // 0004 LDINT R3 100 - 0x080C0203, // 0005 MUL R3 R1 R3 - 0x7C080200, // 0006 CALL R2 1 - 0x70020000, // 0007 JMP #0009 - 0x4C080000, // 0008 LDNIL R2 - 0x80040400, // 0009 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: value_changed -********************************************************************/ -be_local_closure(Matter_Plugin_Sensor_Temp_value_changed, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(attribute_updated), - /* K1 */ be_const_int(0), - }), - be_str_weak(value_changed), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x54120401, // 0001 LDINT R4 1026 - 0x58140001, // 0002 LDCONST R5 K1 - 0x7C080600, // 0003 CALL R2 3 - 0x80000000, // 0004 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Matter_Plugin_Sensor_Temp -********************************************************************/ -extern const bclass be_class_Matter_Plugin_Sensor; -be_local_class(Matter_Plugin_Sensor_Temp, - 0, - &be_class_Matter_Plugin_Sensor, - be_nested_map(7, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(read_attribute, 2), be_const_closure(Matter_Plugin_Sensor_Temp_read_attribute_closure) }, - { be_const_key_weak(pre_value, 4), be_const_closure(Matter_Plugin_Sensor_Temp_pre_value_closure) }, - { be_const_key_weak(CLUSTERS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(1026, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { - be_const_list( * be_nested_list(5, - ( (struct bvalue*) &(const bvalue[]) { - be_const_int(0), - be_const_int(1), - be_const_int(2), - be_const_int(65532), - be_const_int(65533), - })) ) } )) }, - })) ) } )) }, - { be_const_key_weak(TYPE, 6), be_nested_str_weak(temperature) }, - { be_const_key_weak(NAME, -1), be_nested_str_weak(Temperature) }, - { be_const_key_weak(value_changed, -1), be_const_closure(Matter_Plugin_Sensor_Temp_value_changed_closure) }, - { be_const_key_weak(TYPES, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(1, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(770, -1), be_const_int(2) }, - })) ) } )) }, - })), - be_str_weak(Matter_Plugin_Sensor_Temp) -); -/*******************************************************************/ - -void be_load_Matter_Plugin_Sensor_Temp_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_Plugin_Sensor_Temp); - be_setglobal(vm, "Matter_Plugin_Sensor_Temp"); - be_pop(vm, 1); -} -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Profiler.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Profiler.h new file mode 100644 index 000000000000..4150c0997784 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Profiler.h @@ -0,0 +1,331 @@ +/* Solidification of Matter_Profiler.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_Profiler; + +/******************************************************************** +** Solidified function: start +********************************************************************/ +be_local_closure(Matter_Profiler_start, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(active), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(PREALLOCATED), + /* K3 */ be_nested_str_weak(millis), + /* K4 */ be_nested_str_weak(names), + /* K5 */ be_const_int(1), + /* K6 */ be_nested_str_weak(len), + /* K7 */ be_nested_str_weak(tasmota), + /* K8 */ be_nested_str_weak(gc), + /* K9 */ be_nested_str_weak(log), + /* K10 */ be_nested_str_weak(start), + }), + be_str_weak(start), + &be_const_str_solidified, + ( &(const binstruction[23]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x74060000, // 0001 JMPT R1 #0003 + 0x80000200, // 0002 RET 0 + 0x58040001, // 0003 LDCONST R1 K1 + 0x88080102, // 0004 GETMBR R2 R0 K2 + 0x14080202, // 0005 LT R2 R1 R2 + 0x780A0007, // 0006 JMPF R2 #000F + 0x88080103, // 0007 GETMBR R2 R0 K3 + 0x4C0C0000, // 0008 LDNIL R3 + 0x98080203, // 0009 SETIDX R2 R1 R3 + 0x88080104, // 000A GETMBR R2 R0 K4 + 0x4C0C0000, // 000B LDNIL R3 + 0x98080203, // 000C SETIDX R2 R1 R3 + 0x00040305, // 000D ADD R1 R1 K5 + 0x7001FFF4, // 000E JMP #0004 + 0x90020D01, // 000F SETMBR R0 K6 K1 + 0xB80A0E00, // 0010 GETNGBL R2 K7 + 0x8C080508, // 0011 GETMET R2 R2 K8 + 0x7C080200, // 0012 CALL R2 1 + 0x8C080109, // 0013 GETMET R2 R0 K9 + 0x5810000A, // 0014 LDCONST R4 K10 + 0x7C080400, // 0015 CALL R2 2 + 0x80000000, // 0016 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_Profiler_init, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(active), + /* K1 */ be_nested_str_weak(millis), + /* K2 */ be_nested_str_weak(resize), + /* K3 */ be_nested_str_weak(PREALLOCATED), + /* K4 */ be_nested_str_weak(names), + /* K5 */ be_nested_str_weak(allocs), + /* K6 */ be_nested_str_weak(reallocs), + /* K7 */ be_nested_str_weak(len), + /* K8 */ be_const_int(0), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[32]) { /* code */ + 0x50040000, // 0000 LDBOOL R1 0 0 + 0x90020001, // 0001 SETMBR R0 K0 R1 + 0x60040012, // 0002 GETGBL R1 G18 + 0x7C040000, // 0003 CALL R1 0 + 0x90020201, // 0004 SETMBR R0 K1 R1 + 0x88040101, // 0005 GETMBR R1 R0 K1 + 0x8C040302, // 0006 GETMET R1 R1 K2 + 0x880C0103, // 0007 GETMBR R3 R0 K3 + 0x7C040400, // 0008 CALL R1 2 + 0x60040012, // 0009 GETGBL R1 G18 + 0x7C040000, // 000A CALL R1 0 + 0x90020801, // 000B SETMBR R0 K4 R1 + 0x88040104, // 000C GETMBR R1 R0 K4 + 0x8C040302, // 000D GETMET R1 R1 K2 + 0x880C0103, // 000E GETMBR R3 R0 K3 + 0x7C040400, // 000F CALL R1 2 + 0x60040012, // 0010 GETGBL R1 G18 + 0x7C040000, // 0011 CALL R1 0 + 0x90020A01, // 0012 SETMBR R0 K5 R1 + 0x88040105, // 0013 GETMBR R1 R0 K5 + 0x8C040302, // 0014 GETMET R1 R1 K2 + 0x880C0103, // 0015 GETMBR R3 R0 K3 + 0x7C040400, // 0016 CALL R1 2 + 0x60040012, // 0017 GETGBL R1 G18 + 0x7C040000, // 0018 CALL R1 0 + 0x90020C01, // 0019 SETMBR R0 K6 R1 + 0x88040106, // 001A GETMBR R1 R0 K6 + 0x8C040302, // 001B GETMET R1 R1 K2 + 0x880C0103, // 001C GETMBR R3 R0 K3 + 0x7C040400, // 001D CALL R1 2 + 0x90020F08, // 001E SETMBR R0 K7 K8 + 0x80000000, // 001F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_active +********************************************************************/ +be_local_closure(Matter_Profiler_set_active, /* name */ + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(active), + }), + be_str_weak(set_active), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x60080017, // 0000 GETGBL R2 G23 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x90020002, // 0003 SETMBR R0 K0 R2 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: log +********************************************************************/ +be_local_closure(Matter_Profiler_log, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str_weak(active), + /* K1 */ be_nested_str_weak(debug), + /* K2 */ be_nested_str_weak(len), + /* K3 */ be_nested_str_weak(PREALLOCATED), + /* K4 */ be_nested_str_weak(millis), + /* K5 */ be_nested_str_weak(tasmota), + /* K6 */ be_nested_str_weak(names), + /* K7 */ be_nested_str_weak(allocs), + /* K8 */ be_nested_str_weak(reallocs), + /* K9 */ be_const_int(1), + }), + be_str_weak(log), + &be_const_str_solidified, + ( &(const binstruction[28]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x740A0000, // 0001 JMPT R2 #0003 + 0x80000400, // 0002 RET 0 + 0xA40A0200, // 0003 IMPORT R2 K1 + 0x880C0102, // 0004 GETMBR R3 R0 K2 + 0x88100103, // 0005 GETMBR R4 R0 K3 + 0x28100604, // 0006 GE R4 R3 R4 + 0x78120000, // 0007 JMPF R4 #0009 + 0x80000800, // 0008 RET 0 + 0x88100104, // 0009 GETMBR R4 R0 K4 + 0xB8160A00, // 000A GETNGBL R5 K5 + 0x8C140B04, // 000B GETMET R5 R5 K4 + 0x7C140200, // 000C CALL R5 1 + 0x98100605, // 000D SETIDX R4 R3 R5 + 0x88100106, // 000E GETMBR R4 R0 K6 + 0x98100601, // 000F SETIDX R4 R3 R1 + 0x88100107, // 0010 GETMBR R4 R0 K7 + 0x8C140507, // 0011 GETMET R5 R2 K7 + 0x7C140200, // 0012 CALL R5 1 + 0x98100605, // 0013 SETIDX R4 R3 R5 + 0x88100108, // 0014 GETMBR R4 R0 K8 + 0x8C140508, // 0015 GETMET R5 R2 K8 + 0x7C140200, // 0016 CALL R5 1 + 0x98100605, // 0017 SETIDX R4 R3 R5 + 0x88100102, // 0018 GETMBR R4 R0 K2 + 0x00100909, // 0019 ADD R4 R4 K9 + 0x90020404, // 001A SETMBR R0 K2 R4 + 0x80000000, // 001B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: dump +********************************************************************/ +be_local_closure(Matter_Profiler_dump, /* name */ + be_nested_proto( + 13, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(active), + /* K1 */ be_nested_str_weak(log), + /* K2 */ be_nested_str_weak(_X3C_X2D_X2Dend_X2D_X2D_X3E), + /* K3 */ be_nested_str_weak(tasmota), + /* K4 */ be_nested_str_weak(MTR_X3A_X20Profiler_X20dump_X3A), + /* K5 */ be_nested_str_weak(millis), + /* K6 */ be_const_int(0), + /* K7 */ be_nested_str_weak(allocs), + /* K8 */ be_nested_str_weak(reallocs), + /* K9 */ be_const_int(1), + /* K10 */ be_nested_str_weak(len), + /* K11 */ be_nested_str_weak(MTR_X3A_X20_X20_X20_X254i_X20_X5B_X254i_X5D_X27_X25s_X27), + /* K12 */ be_nested_str_weak(names), + }), + be_str_weak(dump), + &be_const_str_solidified, + ( &(const binstruction[39]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x740A0000, // 0001 JMPT R2 #0003 + 0x80000400, // 0002 RET 0 + 0x8C080101, // 0003 GETMET R2 R0 K1 + 0x58100002, // 0004 LDCONST R4 K2 + 0x7C080400, // 0005 CALL R2 2 + 0xB80A0600, // 0006 GETNGBL R2 K3 + 0x8C080501, // 0007 GETMET R2 R2 K1 + 0x58100004, // 0008 LDCONST R4 K4 + 0x5C140200, // 0009 MOVE R5 R1 + 0x7C080600, // 000A CALL R2 3 + 0x88080105, // 000B GETMBR R2 R0 K5 + 0x94080506, // 000C GETIDX R2 R2 K6 + 0x880C0107, // 000D GETMBR R3 R0 K7 + 0x940C0706, // 000E GETIDX R3 R3 K6 + 0x88100108, // 000F GETMBR R4 R0 K8 + 0x94100906, // 0010 GETIDX R4 R4 K6 + 0x58140009, // 0011 LDCONST R5 K9 + 0x8818010A, // 0012 GETMBR R6 R0 K10 + 0x14180A06, // 0013 LT R6 R5 R6 + 0x781A0010, // 0014 JMPF R6 #0026 + 0xB81A0600, // 0015 GETNGBL R6 K3 + 0x8C180D01, // 0016 GETMET R6 R6 K1 + 0x60200018, // 0017 GETGBL R8 G24 + 0x5824000B, // 0018 LDCONST R9 K11 + 0x88280105, // 0019 GETMBR R10 R0 K5 + 0x94281405, // 001A GETIDX R10 R10 R5 + 0x04281402, // 001B SUB R10 R10 R2 + 0x882C0107, // 001C GETMBR R11 R0 K7 + 0x942C1605, // 001D GETIDX R11 R11 R5 + 0x042C1603, // 001E SUB R11 R11 R3 + 0x8830010C, // 001F GETMBR R12 R0 K12 + 0x94301805, // 0020 GETIDX R12 R12 R5 + 0x7C200800, // 0021 CALL R8 4 + 0x5C240200, // 0022 MOVE R9 R1 + 0x7C180600, // 0023 CALL R6 3 + 0x00140B09, // 0024 ADD R5 R5 K9 + 0x7001FFEB, // 0025 JMP #0012 + 0x80000000, // 0026 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_Profiler +********************************************************************/ +be_local_class(Matter_Profiler, + 6, + NULL, + be_nested_map(12, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(dump, 8), be_const_closure(Matter_Profiler_dump_closure) }, + { be_const_key_weak(millis, 5), be_const_var(0) }, + { be_const_key_weak(reallocs, -1), be_const_var(4) }, + { be_const_key_weak(init, 1), be_const_closure(Matter_Profiler_init_closure) }, + { be_const_key_weak(len, -1), be_const_var(5) }, + { be_const_key_weak(active, -1), be_const_var(2) }, + { be_const_key_weak(set_active, -1), be_const_closure(Matter_Profiler_set_active_closure) }, + { be_const_key_weak(names, -1), be_const_var(1) }, + { be_const_key_weak(allocs, 10), be_const_var(3) }, + { be_const_key_weak(log, -1), be_const_closure(Matter_Profiler_log_closure) }, + { be_const_key_weak(PREALLOCATED, -1), be_const_int(50) }, + { be_const_key_weak(start, 0), be_const_closure(Matter_Profiler_start_closure) }, + })), + be_str_weak(Matter_Profiler) +); +/*******************************************************************/ + +void be_load_Matter_Profiler_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_Profiler); + be_setglobal(vm, "Matter_Profiler"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Session.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Session.h index d35617f1e288..b0e498421e13 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Session.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Session.h @@ -7,11 +7,11 @@ extern const bclass be_class_Matter_Session; /******************************************************************** -** Solidified function: get_i2r +** Solidified function: close ********************************************************************/ -be_local_closure(Matter_Session_get_i2r, /* name */ +be_local_closure(Matter_Session_close, /* name */ be_nested_proto( - 2, /* nstack */ + 8, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -19,14 +19,93 @@ be_local_closure(Matter_Session_get_i2r, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(i2rkey), + ( &(const bvalue[23]) { /* constants */ + /* K0 */ be_nested_str_weak(local_session_id), + /* K1 */ be_nested_str_weak(__future_local_session_id), + /* K2 */ be_nested_str_weak(initiator_session_id), + /* K3 */ be_nested_str_weak(__future_initiator_session_id), + /* K4 */ be_nested_str_weak(_counter_rcv_impl), + /* K5 */ be_nested_str_weak(reset), + /* K6 */ be_nested_str_weak(_counter_snd_impl), + /* K7 */ be_nested_str_weak(counter_rcv), + /* K8 */ be_const_int(0), + /* K9 */ be_nested_str_weak(counter_snd), + /* K10 */ be_nested_str_weak(next), + /* K11 */ be_nested_str_weak(i2rkey), + /* K12 */ be_nested_str_weak(_i2r_privacy), + /* K13 */ be_nested_str_weak(r2ikey), + /* K14 */ be_nested_str_weak(attestation_challenge), + /* K15 */ be_nested_str_weak(introspect), + /* K16 */ be_nested_str_weak(members), + /* K17 */ be_nested_str_weak(get), + /* K18 */ be_nested_str_weak(function), + /* K19 */ be_nested_str_weak(instance), + /* K20 */ be_nested_str_weak(_), + /* K21 */ be_const_int(1), + /* K22 */ be_nested_str_weak(stop_iteration), }), - be_str_weak(get_i2r), + be_str_weak(close), &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 + ( &(const binstruction[59]) { /* code */ + 0x88040101, // 0000 GETMBR R1 R0 K1 + 0x90020001, // 0001 SETMBR R0 K0 R1 + 0x88040103, // 0002 GETMBR R1 R0 K3 + 0x90020401, // 0003 SETMBR R0 K2 R1 + 0x88040104, // 0004 GETMBR R1 R0 K4 + 0x8C040305, // 0005 GETMET R1 R1 K5 + 0x7C040200, // 0006 CALL R1 1 + 0x88040106, // 0007 GETMBR R1 R0 K6 + 0x8C040305, // 0008 GETMET R1 R1 K5 + 0x7C040200, // 0009 CALL R1 1 + 0x90020F08, // 000A SETMBR R0 K7 K8 + 0x88040106, // 000B GETMBR R1 R0 K6 + 0x8C04030A, // 000C GETMET R1 R1 K10 + 0x7C040200, // 000D CALL R1 1 + 0x90021201, // 000E SETMBR R0 K9 R1 + 0x4C040000, // 000F LDNIL R1 + 0x90021601, // 0010 SETMBR R0 K11 R1 + 0x4C040000, // 0011 LDNIL R1 + 0x90021801, // 0012 SETMBR R0 K12 R1 + 0x4C040000, // 0013 LDNIL R1 + 0x90021A01, // 0014 SETMBR R0 K13 R1 + 0x4C040000, // 0015 LDNIL R1 + 0x90021C01, // 0016 SETMBR R0 K14 R1 + 0xA4061E00, // 0017 IMPORT R1 K15 + 0x60080010, // 0018 GETGBL R2 G16 + 0x8C0C0310, // 0019 GETMET R3 R1 K16 + 0x5C140000, // 001A MOVE R5 R0 + 0x7C0C0400, // 001B CALL R3 2 + 0x7C080200, // 001C CALL R2 1 + 0xA8020018, // 001D EXBLK 0 #0037 + 0x5C0C0400, // 001E MOVE R3 R2 + 0x7C0C0000, // 001F CALL R3 0 + 0x8C100311, // 0020 GETMET R4 R1 K17 + 0x5C180000, // 0021 MOVE R6 R0 + 0x5C1C0600, // 0022 MOVE R7 R3 + 0x7C100600, // 0023 CALL R4 3 + 0x60140004, // 0024 GETGBL R5 G4 + 0x5C180800, // 0025 MOVE R6 R4 + 0x7C140200, // 0026 CALL R5 1 + 0x20140B12, // 0027 NE R5 R5 K18 + 0x7816000C, // 0028 JMPF R5 #0036 + 0x60140004, // 0029 GETGBL R5 G4 + 0x5C180800, // 002A MOVE R6 R4 + 0x7C140200, // 002B CALL R5 1 + 0x20140B13, // 002C NE R5 R5 K19 + 0x78160007, // 002D JMPF R5 #0036 + 0x94140708, // 002E GETIDX R5 R3 K8 + 0x1C140B14, // 002F EQ R5 R5 K20 + 0x78160004, // 0030 JMPF R5 #0036 + 0x94140715, // 0031 GETIDX R5 R3 K21 + 0x1C140B14, // 0032 EQ R5 R5 K20 + 0x78160001, // 0033 JMPF R5 #0036 + 0x4C140000, // 0034 LDNIL R5 + 0x90000605, // 0035 SETMBR R0 R3 R5 + 0x7001FFE6, // 0036 JMP #001E + 0x58080016, // 0037 LDCONST R2 K22 + 0xAC080200, // 0038 CATCH R2 1 0 + 0xB0080000, // 0039 RAISE 2 R0 R0 + 0x80000000, // 003A RET 0 }) ) ); @@ -34,11 +113,11 @@ be_local_closure(Matter_Session_get_i2r, /* name */ /******************************************************************** -** Solidified function: tojson +** Solidified function: update ********************************************************************/ -be_local_closure(Matter_Session_tojson, /* name */ +be_local_closure(Matter_Session_update, /* name */ be_nested_proto( - 18, /* nstack */ + 3, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -46,131 +125,19 @@ be_local_closure(Matter_Session_tojson, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[24]) { /* constants */ - /* K0 */ be_nested_str_weak(json), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(introspect), - /* K3 */ be_nested_str_weak(persist_pre), - /* K4 */ be_nested_str_weak(members), - /* K5 */ be_nested_str_weak(get), - /* K6 */ be_nested_str_weak(function), - /* K7 */ be_const_int(0), - /* K8 */ be_nested_str_weak(_), - /* K9 */ be_nested_str_weak(push), - /* K10 */ be_nested_str_weak(stop_iteration), - /* K11 */ be_nested_str_weak(matter), - /* K12 */ be_nested_str_weak(sort), - /* K13 */ be_nested_str_weak(_X24_X24), - /* K14 */ be_nested_str_weak(tob64), - /* K15 */ be_nested_str_weak(instance), - /* K16 */ be_nested_str_weak(format), - /* K17 */ be_nested_str_weak(_X25s_X3A_X25s), - /* K18 */ be_nested_str_weak(dump), - /* K19 */ be_nested_str_weak(persist_post), - /* K20 */ be_nested_str_weak(_X7B), - /* K21 */ be_nested_str_weak(concat), - /* K22 */ be_nested_str_weak(_X2C), - /* K23 */ be_nested_str_weak(_X7D), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(last_used), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(rtc_utc), }), - be_str_weak(tojson), + be_str_weak(update), &be_const_str_solidified, - ( &(const binstruction[96]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0xA40E0400, // 0002 IMPORT R3 K2 - 0x8C100103, // 0003 GETMET R4 R0 K3 - 0x7C100200, // 0004 CALL R4 1 - 0x60100012, // 0005 GETGBL R4 G18 - 0x7C100000, // 0006 CALL R4 0 - 0x60140010, // 0007 GETGBL R5 G16 - 0x8C180704, // 0008 GETMET R6 R3 K4 - 0x5C200000, // 0009 MOVE R8 R0 - 0x7C180400, // 000A CALL R6 2 - 0x7C140200, // 000B CALL R5 1 - 0xA8020011, // 000C EXBLK 0 #001F - 0x5C180A00, // 000D MOVE R6 R5 - 0x7C180000, // 000E CALL R6 0 - 0x8C1C0705, // 000F GETMET R7 R3 K5 - 0x5C240000, // 0010 MOVE R9 R0 - 0x5C280C00, // 0011 MOVE R10 R6 - 0x7C1C0600, // 0012 CALL R7 3 - 0x60200004, // 0013 GETGBL R8 G4 - 0x5C240E00, // 0014 MOVE R9 R7 - 0x7C200200, // 0015 CALL R8 1 - 0x20201106, // 0016 NE R8 R8 K6 - 0x78220005, // 0017 JMPF R8 #001E - 0x94200D07, // 0018 GETIDX R8 R6 K7 - 0x20201108, // 0019 NE R8 R8 K8 - 0x78220002, // 001A JMPF R8 #001E - 0x8C200909, // 001B GETMET R8 R4 K9 - 0x5C280C00, // 001C MOVE R10 R6 - 0x7C200400, // 001D CALL R8 2 - 0x7001FFED, // 001E JMP #000D - 0x5814000A, // 001F LDCONST R5 K10 - 0xAC140200, // 0020 CATCH R5 1 0 - 0xB0080000, // 0021 RAISE 2 R0 R0 - 0xB8161600, // 0022 GETNGBL R5 K11 - 0x8C140B0C, // 0023 GETMET R5 R5 K12 - 0x5C1C0800, // 0024 MOVE R7 R4 - 0x7C140400, // 0025 CALL R5 2 - 0x5C100A00, // 0026 MOVE R4 R5 - 0x60140012, // 0027 GETGBL R5 G18 - 0x7C140000, // 0028 CALL R5 0 - 0x60180010, // 0029 GETGBL R6 G16 - 0x5C1C0800, // 002A MOVE R7 R4 - 0x7C180200, // 002B CALL R6 1 - 0xA8020027, // 002C EXBLK 0 #0055 - 0x5C1C0C00, // 002D MOVE R7 R6 - 0x7C1C0000, // 002E CALL R7 0 - 0x8C200705, // 002F GETMET R8 R3 K5 - 0x5C280000, // 0030 MOVE R10 R0 - 0x5C2C0E00, // 0031 MOVE R11 R7 - 0x7C200600, // 0032 CALL R8 3 - 0x4C240000, // 0033 LDNIL R9 - 0x1C241009, // 0034 EQ R9 R8 R9 - 0x78260000, // 0035 JMPF R9 #0037 - 0x7001FFF5, // 0036 JMP #002D - 0x6024000F, // 0037 GETGBL R9 G15 - 0x5C281000, // 0038 MOVE R10 R8 - 0x602C0015, // 0039 GETGBL R11 G21 - 0x7C240400, // 003A CALL R9 2 - 0x78260004, // 003B JMPF R9 #0041 - 0x8C24110E, // 003C GETMET R9 R8 K14 - 0x7C240200, // 003D CALL R9 1 - 0x00261A09, // 003E ADD R9 K13 R9 - 0x5C201200, // 003F MOVE R8 R9 - 0x70020005, // 0040 JMP #0047 - 0x60240004, // 0041 GETGBL R9 G4 - 0x5C281000, // 0042 MOVE R10 R8 - 0x7C240200, // 0043 CALL R9 1 - 0x1C24130F, // 0044 EQ R9 R9 K15 - 0x78260000, // 0045 JMPF R9 #0047 - 0x7001FFE5, // 0046 JMP #002D - 0x8C240B09, // 0047 GETMET R9 R5 K9 - 0x8C2C0510, // 0048 GETMET R11 R2 K16 - 0x58340011, // 0049 LDCONST R13 K17 - 0x8C380312, // 004A GETMET R14 R1 K18 - 0x60400008, // 004B GETGBL R16 G8 - 0x5C440E00, // 004C MOVE R17 R7 - 0x7C400200, // 004D CALL R16 1 - 0x7C380400, // 004E CALL R14 2 - 0x8C3C0312, // 004F GETMET R15 R1 K18 - 0x5C441000, // 0050 MOVE R17 R8 - 0x7C3C0400, // 0051 CALL R15 2 - 0x7C2C0800, // 0052 CALL R11 4 - 0x7C240400, // 0053 CALL R9 2 - 0x7001FFD7, // 0054 JMP #002D - 0x5818000A, // 0055 LDCONST R6 K10 - 0xAC180200, // 0056 CATCH R6 1 0 - 0xB0080000, // 0057 RAISE 2 R0 R0 - 0x8C180113, // 0058 GETMET R6 R0 K19 - 0x7C180200, // 0059 CALL R6 1 - 0x8C180B15, // 005A GETMET R6 R5 K21 - 0x58200016, // 005B LDCONST R8 K22 - 0x7C180400, // 005C CALL R6 2 - 0x001A2806, // 005D ADD R6 K20 R6 - 0x00180D17, // 005E ADD R6 R6 K23 - 0x80040C00, // 005F RET 1 R6 + ( &(const binstruction[ 5]) { /* code */ + 0xB8060200, // 0000 GETNGBL R1 K1 + 0x8C040302, // 0001 GETMET R1 R1 K2 + 0x7C040200, // 0002 CALL R1 1 + 0x90020001, // 0003 SETMBR R0 K0 R1 + 0x80000000, // 0004 RET 0 }) ) ); @@ -178,11 +145,11 @@ be_local_closure(Matter_Session_tojson, /* name */ /******************************************************************** -** Solidified function: assign_fabric_index +** Solidified function: get_ac ********************************************************************/ -be_local_closure(Matter_Session_assign_fabric_index, /* name */ +be_local_closure(Matter_Session_get_ac, /* name */ be_nested_proto( - 5, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -190,29 +157,14 @@ be_local_closure(Matter_Session_assign_fabric_index, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(get_fabric_index), - /* K2 */ be_nested_str_weak(set_fabric_index), - /* K3 */ be_nested_str_weak(_store), - /* K4 */ be_nested_str_weak(next_fabric_idx), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(attestation_challenge), }), - be_str_weak(assign_fabric_index), + be_str_weak(get_ac), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ + ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x4C080000, // 0003 LDNIL R2 - 0x1C040202, // 0004 EQ R1 R1 R2 - 0x78060005, // 0005 JMPF R1 #000C - 0x88040100, // 0006 GETMBR R1 R0 K0 - 0x8C040302, // 0007 GETMET R1 R1 K2 - 0x880C0103, // 0008 GETMBR R3 R0 K3 - 0x8C0C0704, // 0009 GETMET R3 R3 K4 - 0x7C0C0200, // 000A CALL R3 1 - 0x7C040400, // 000B CALL R1 2 - 0x80000000, // 000C RET 0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -220,11 +172,11 @@ be_local_closure(Matter_Session_assign_fabric_index, /* name */ /******************************************************************** -** Solidified function: persist_to_fabric +** Solidified function: get_fabric ********************************************************************/ -be_local_closure(Matter_Session_persist_to_fabric, /* name */ +be_local_closure(Matter_Session_get_fabric, /* name */ be_nested_proto( - 4, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -232,18 +184,14 @@ be_local_closure(Matter_Session_persist_to_fabric, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ + ( &(const bvalue[ 1]) { /* constants */ /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(add_session), }), - be_str_weak(persist_to_fabric), + be_str_weak(get_fabric), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ + ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x5C0C0000, // 0002 MOVE R3 R0 - 0x7C040400, // 0003 CALL R1 2 - 0x80000000, // 0004 RET 0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -251,11 +199,11 @@ be_local_closure(Matter_Session_persist_to_fabric, /* name */ /******************************************************************** -** Solidified function: set_mode_PASE +** Solidified function: get_noc ********************************************************************/ -be_local_closure(Matter_Session_set_mode_PASE, /* name */ +be_local_closure(Matter_Session_get_noc, /* name */ be_nested_proto( - 4, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -264,16 +212,15 @@ be_local_closure(Matter_Session_set_mode_PASE, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(set_mode), - /* K1 */ be_nested_str_weak(_PASE), + /* K0 */ be_nested_str_weak(_fabric), + /* K1 */ be_nested_str_weak(noc), }), - be_str_weak(set_mode_PASE), + be_str_weak(get_noc), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x880C0101, // 0001 GETMBR R3 R0 K1 - 0x7C040400, // 0002 CALL R1 2 - 0x80000000, // 0003 RET 0 + ( &(const binstruction[ 3]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x88040301, // 0001 GETMBR R1 R1 K1 + 0x80040200, // 0002 RET 1 R1 }) ) ); @@ -281,9 +228,9 @@ be_local_closure(Matter_Session_set_mode_PASE, /* name */ /******************************************************************** -** Solidified function: get_fabric_label +** Solidified function: get_device_id ********************************************************************/ -be_local_closure(Matter_Session_get_fabric_label, /* name */ +be_local_closure(Matter_Session_get_device_id, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -295,14 +242,18 @@ be_local_closure(Matter_Session_get_fabric_label, /* name */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(fabric_label), + /* K1 */ be_nested_str_weak(device_id), }), - be_str_weak(get_fabric_label), + be_str_weak(get_device_id), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ + ( &(const binstruction[ 7]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x80040200, // 0002 RET 1 R1 + 0x78060002, // 0001 JMPF R1 #0005 + 0x88040100, // 0002 GETMBR R1 R0 K0 + 0x88040301, // 0003 GETMBR R1 R1 K1 + 0x70020000, // 0004 JMP #0006 + 0x4C040000, // 0005 LDNIL R1 + 0x80040200, // 0006 RET 1 R1 }) ) ); @@ -310,28 +261,70 @@ be_local_closure(Matter_Session_get_fabric_label, /* name */ /******************************************************************** -** Solidified function: get_device_id +** Solidified function: set_fabric_label ********************************************************************/ -be_local_closure(Matter_Session_get_device_id, /* name */ +be_local_closure(Matter_Session_set_fabric_label, /* name */ be_nested_proto( - 2, /* nstack */ - 1, /* argc */ + 4, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(device_id), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(string), + /* K1 */ be_nested_str_weak(_fabric), + /* K2 */ be_nested_str_weak(fabric_label), }), - be_str_weak(get_device_id), + be_str_weak(set_fabric_label), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x80040200, // 0002 RET 1 R1 + ( &(const binstruction[ 8]) { /* code */ + 0x60080004, // 0000 GETGBL R2 G4 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x1C080500, // 0003 EQ R2 R2 K0 + 0x780A0001, // 0004 JMPF R2 #0007 + 0x88080101, // 0005 GETMBR R2 R0 K1 + 0x900A0401, // 0006 SETMBR R2 K2 R1 + 0x80000000, // 0007 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_keys +********************************************************************/ +be_local_closure(Matter_Session_set_keys, /* name */ + be_nested_proto( + 6, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(i2rkey), + /* K1 */ be_nested_str_weak(_i2r_privacy), + /* K2 */ be_nested_str_weak(r2ikey), + /* K3 */ be_nested_str_weak(attestation_challenge), + /* K4 */ be_nested_str_weak(created), + }), + be_str_weak(set_keys), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x4C140000, // 0001 LDNIL R5 + 0x90020205, // 0002 SETMBR R0 K1 R5 + 0x90020402, // 0003 SETMBR R0 K2 R2 + 0x90020603, // 0004 SETMBR R0 K3 R3 + 0x90020804, // 0005 SETMBR R0 K4 R4 + 0x80000000, // 0006 RET 0 }) ) ); @@ -366,121 +359,140 @@ be_local_closure(Matter_Session_get_r2i, /* name */ /******************************************************************** -** Solidified function: init +** Solidified function: tojson ********************************************************************/ -be_local_closure(Matter_Session_init, /* name */ +be_local_closure(Matter_Session_tojson, /* name */ be_nested_proto( - 10, /* nstack */ - 5, /* argc */ + 16, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[24]) { /* constants */ - /* K0 */ be_nested_str_weak(crypto), - /* K1 */ be_nested_str_weak(_store), - /* K2 */ be_nested_str_weak(mode), - /* K3 */ be_const_int(0), - /* K4 */ be_nested_str_weak(local_session_id), - /* K5 */ be_nested_str_weak(initiator_session_id), - /* K6 */ be_nested_str_weak(_counter_snd_impl), - /* K7 */ be_nested_str_weak(matter), - /* K8 */ be_nested_str_weak(Counter), - /* K9 */ be_nested_str_weak(_counter_rcv_impl), - /* K10 */ be_nested_str_weak(counter_rcv), - /* K11 */ be_nested_str_weak(counter_snd), - /* K12 */ be_nested_str_weak(next), - /* K13 */ be_nested_str_weak(_COUNTER_SND_INCR), - /* K14 */ be_nested_str_weak(_counter_insecure_rcv), - /* K15 */ be_nested_str_weak(_counter_insecure_snd), - /* K16 */ be_nested_str_weak(_breadcrumb), - /* K17 */ be_nested_str_weak(_exchange_id), - /* K18 */ be_nested_str_weak(random), - /* K19 */ be_const_int(2), - /* K20 */ be_nested_str_weak(get), - /* K21 */ be_nested_str_weak(_fabric), - /* K22 */ be_nested_str_weak(create_fabric), - /* K23 */ be_nested_str_weak(update), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[47]) { /* code */ - 0xA4160000, // 0000 IMPORT R5 K0 - 0x90020201, // 0001 SETMBR R0 K1 R1 - 0x90020503, // 0002 SETMBR R0 K2 K3 - 0x90020802, // 0003 SETMBR R0 K4 R2 - 0x90020A03, // 0004 SETMBR R0 K5 R3 - 0xB81A0E00, // 0005 GETNGBL R6 K7 - 0x8C180D08, // 0006 GETMET R6 R6 K8 - 0x7C180200, // 0007 CALL R6 1 - 0x90020C06, // 0008 SETMBR R0 K6 R6 - 0xB81A0E00, // 0009 GETNGBL R6 K7 - 0x8C180D08, // 000A GETMET R6 R6 K8 - 0x7C180200, // 000B CALL R6 1 - 0x90021206, // 000C SETMBR R0 K9 R6 - 0x90021503, // 000D SETMBR R0 K10 K3 - 0x88180106, // 000E GETMBR R6 R0 K6 - 0x8C180D0C, // 000F GETMET R6 R6 K12 - 0x7C180200, // 0010 CALL R6 1 - 0x881C010D, // 0011 GETMBR R7 R0 K13 - 0x00180C07, // 0012 ADD R6 R6 R7 - 0x90021606, // 0013 SETMBR R0 K11 R6 - 0xB81A0E00, // 0014 GETNGBL R6 K7 - 0x8C180D08, // 0015 GETMET R6 R6 K8 - 0x7C180200, // 0016 CALL R6 1 - 0x90021C06, // 0017 SETMBR R0 K14 R6 - 0xB81A0E00, // 0018 GETNGBL R6 K7 - 0x8C180D08, // 0019 GETMET R6 R6 K8 - 0x7C180200, // 001A CALL R6 1 - 0x90021E06, // 001B SETMBR R0 K15 R6 - 0x90022103, // 001C SETMBR R0 K16 K3 - 0x8C180B12, // 001D GETMET R6 R5 K18 - 0x58200013, // 001E LDCONST R8 K19 - 0x7C180400, // 001F CALL R6 2 - 0x8C180D14, // 0020 GETMET R6 R6 K20 - 0x58200003, // 0021 LDCONST R8 K3 - 0x58240013, // 0022 LDCONST R9 K19 - 0x7C180600, // 0023 CALL R6 3 - 0x90022206, // 0024 SETMBR R0 K17 R6 - 0x78120001, // 0025 JMPF R4 #0028 - 0x5C180800, // 0026 MOVE R6 R4 - 0x70020002, // 0027 JMP #002B - 0x88180101, // 0028 GETMBR R6 R0 K1 - 0x8C180D16, // 0029 GETMET R6 R6 K22 - 0x7C180200, // 002A CALL R6 1 - 0x90022A06, // 002B SETMBR R0 K21 R6 - 0x8C180117, // 002C GETMET R6 R0 K23 - 0x7C180200, // 002D CALL R6 1 - 0x80000000, // 002E RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_mode -********************************************************************/ -be_local_closure(Matter_Session_get_mode, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(mode), + ( &(const bvalue[22]) { /* constants */ + /* K0 */ be_nested_str_weak(json), + /* K1 */ be_nested_str_weak(introspect), + /* K2 */ be_nested_str_weak(persist_pre), + /* K3 */ be_nested_str_weak(members), + /* K4 */ be_nested_str_weak(get), + /* K5 */ be_nested_str_weak(function), + /* K6 */ be_const_int(0), + /* K7 */ be_nested_str_weak(_), + /* K8 */ be_nested_str_weak(push), + /* K9 */ be_nested_str_weak(stop_iteration), + /* K10 */ be_nested_str_weak(matter), + /* K11 */ be_nested_str_weak(sort), + /* K12 */ be_nested_str_weak(_X24_X24), + /* K13 */ be_nested_str_weak(tob64), + /* K14 */ be_nested_str_weak(instance), + /* K15 */ be_nested_str_weak(_X25s_X3A_X25s), + /* K16 */ be_nested_str_weak(dump), + /* K17 */ be_nested_str_weak(persist_post), + /* K18 */ be_nested_str_weak(_X7B), + /* K19 */ be_nested_str_weak(concat), + /* K20 */ be_nested_str_weak(_X2C), + /* K21 */ be_nested_str_weak(_X7D), }), - be_str_weak(get_mode), + be_str_weak(tojson), &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 + ( &(const binstruction[95]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0xA40A0200, // 0001 IMPORT R2 K1 + 0x8C0C0102, // 0002 GETMET R3 R0 K2 + 0x7C0C0200, // 0003 CALL R3 1 + 0x600C0012, // 0004 GETGBL R3 G18 + 0x7C0C0000, // 0005 CALL R3 0 + 0x60100010, // 0006 GETGBL R4 G16 + 0x8C140503, // 0007 GETMET R5 R2 K3 + 0x5C1C0000, // 0008 MOVE R7 R0 + 0x7C140400, // 0009 CALL R5 2 + 0x7C100200, // 000A CALL R4 1 + 0xA8020011, // 000B EXBLK 0 #001E + 0x5C140800, // 000C MOVE R5 R4 + 0x7C140000, // 000D CALL R5 0 + 0x8C180504, // 000E GETMET R6 R2 K4 + 0x5C200000, // 000F MOVE R8 R0 + 0x5C240A00, // 0010 MOVE R9 R5 + 0x7C180600, // 0011 CALL R6 3 + 0x601C0004, // 0012 GETGBL R7 G4 + 0x5C200C00, // 0013 MOVE R8 R6 + 0x7C1C0200, // 0014 CALL R7 1 + 0x201C0F05, // 0015 NE R7 R7 K5 + 0x781E0005, // 0016 JMPF R7 #001D + 0x941C0B06, // 0017 GETIDX R7 R5 K6 + 0x201C0F07, // 0018 NE R7 R7 K7 + 0x781E0002, // 0019 JMPF R7 #001D + 0x8C1C0708, // 001A GETMET R7 R3 K8 + 0x5C240A00, // 001B MOVE R9 R5 + 0x7C1C0400, // 001C CALL R7 2 + 0x7001FFED, // 001D JMP #000C + 0x58100009, // 001E LDCONST R4 K9 + 0xAC100200, // 001F CATCH R4 1 0 + 0xB0080000, // 0020 RAISE 2 R0 R0 + 0xB8121400, // 0021 GETNGBL R4 K10 + 0x8C10090B, // 0022 GETMET R4 R4 K11 + 0x5C180600, // 0023 MOVE R6 R3 + 0x7C100400, // 0024 CALL R4 2 + 0x5C0C0800, // 0025 MOVE R3 R4 + 0x60100012, // 0026 GETGBL R4 G18 + 0x7C100000, // 0027 CALL R4 0 + 0x60140010, // 0028 GETGBL R5 G16 + 0x5C180600, // 0029 MOVE R6 R3 + 0x7C140200, // 002A CALL R5 1 + 0xA8020027, // 002B EXBLK 0 #0054 + 0x5C180A00, // 002C MOVE R6 R5 + 0x7C180000, // 002D CALL R6 0 + 0x8C1C0504, // 002E GETMET R7 R2 K4 + 0x5C240000, // 002F MOVE R9 R0 + 0x5C280C00, // 0030 MOVE R10 R6 + 0x7C1C0600, // 0031 CALL R7 3 + 0x4C200000, // 0032 LDNIL R8 + 0x1C200E08, // 0033 EQ R8 R7 R8 + 0x78220000, // 0034 JMPF R8 #0036 + 0x7001FFF5, // 0035 JMP #002C + 0x6020000F, // 0036 GETGBL R8 G15 + 0x5C240E00, // 0037 MOVE R9 R7 + 0x60280015, // 0038 GETGBL R10 G21 + 0x7C200400, // 0039 CALL R8 2 + 0x78220004, // 003A JMPF R8 #0040 + 0x8C200F0D, // 003B GETMET R8 R7 K13 + 0x7C200200, // 003C CALL R8 1 + 0x00221808, // 003D ADD R8 K12 R8 + 0x5C1C1000, // 003E MOVE R7 R8 + 0x70020005, // 003F JMP #0046 + 0x60200004, // 0040 GETGBL R8 G4 + 0x5C240E00, // 0041 MOVE R9 R7 + 0x7C200200, // 0042 CALL R8 1 + 0x1C20110E, // 0043 EQ R8 R8 K14 + 0x78220000, // 0044 JMPF R8 #0046 + 0x7001FFE5, // 0045 JMP #002C + 0x8C200908, // 0046 GETMET R8 R4 K8 + 0x60280018, // 0047 GETGBL R10 G24 + 0x582C000F, // 0048 LDCONST R11 K15 + 0x8C300310, // 0049 GETMET R12 R1 K16 + 0x60380008, // 004A GETGBL R14 G8 + 0x5C3C0C00, // 004B MOVE R15 R6 + 0x7C380200, // 004C CALL R14 1 + 0x7C300400, // 004D CALL R12 2 + 0x8C340310, // 004E GETMET R13 R1 K16 + 0x5C3C0E00, // 004F MOVE R15 R7 + 0x7C340400, // 0050 CALL R13 2 + 0x7C280600, // 0051 CALL R10 3 + 0x7C200400, // 0052 CALL R8 2 + 0x7001FFD7, // 0053 JMP #002C + 0x58140009, // 0054 LDCONST R5 K9 + 0xAC140200, // 0055 CATCH R5 1 0 + 0xB0080000, // 0056 RAISE 2 R0 R0 + 0x8C140111, // 0057 GETMET R5 R0 K17 + 0x7C140200, // 0058 CALL R5 1 + 0x8C140913, // 0059 GETMET R5 R4 K19 + 0x581C0014, // 005A LDCONST R7 K20 + 0x7C140400, // 005B CALL R5 2 + 0x00162405, // 005C ADD R5 K18 R5 + 0x00140B15, // 005D ADD R5 R5 K21 + 0x80040A00, // 005E RET 1 R5 }) ) ); @@ -604,11 +616,11 @@ be_local_closure(Matter_Session_fromjson, /* name */ /******************************************************************** -** Solidified function: is_PASE +** Solidified function: gen_CSR ********************************************************************/ -be_local_closure(Matter_Session_is_PASE, /* name */ +be_local_closure(Matter_Session_gen_CSR, /* name */ be_nested_proto( - 3, /* nstack */ + 15, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -616,17 +628,96 @@ be_local_closure(Matter_Session_is_PASE, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(mode), - /* K1 */ be_nested_str_weak(_PASE), + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(get_pk), + /* K1 */ be_nested_str_weak(crypto), + /* K2 */ be_nested_str_weak(EC_P256), + /* K3 */ be_nested_str_weak(public_key), + /* K4 */ be_nested_str_weak(3070020100300E310C300A060355040A0C034353523059301306072A8648CE3D020106082A8648CE3D030107034200), + /* K5 */ be_nested_str_weak(A000), + /* K6 */ be_nested_str_weak(300C06082A8648CE3D0403020500), + /* K7 */ be_nested_str_weak(ecdsa_sign_sha256_asn1), + /* K8 */ be_nested_str_weak(add), + /* K9 */ be_const_int(3), + /* K10 */ be_const_int(1), + /* K11 */ be_const_int(0), }), - be_str_weak(is_PASE), + be_str_weak(gen_CSR), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88080101, // 0001 GETMBR R2 R0 K1 - 0x1C040202, // 0002 EQ R1 R1 R2 - 0x80040200, // 0003 RET 1 R1 + ( &(const binstruction[73]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0xA40A0200, // 0002 IMPORT R2 K1 + 0x8C0C0502, // 0003 GETMET R3 R2 K2 + 0x7C0C0200, // 0004 CALL R3 1 + 0x8C100703, // 0005 GETMET R4 R3 K3 + 0x5C180200, // 0006 MOVE R6 R1 + 0x7C100400, // 0007 CALL R4 2 + 0x60140015, // 0008 GETGBL R5 G21 + 0x58180004, // 0009 LDCONST R6 K4 + 0x7C140200, // 000A CALL R5 1 + 0x40180A04, // 000B CONNECT R6 R5 R4 + 0x60180015, // 000C GETGBL R6 G21 + 0x581C0005, // 000D LDCONST R7 K5 + 0x7C180200, // 000E CALL R6 1 + 0x40180A06, // 000F CONNECT R6 R5 R6 + 0x60180015, // 0010 GETGBL R6 G21 + 0x581C0006, // 0011 LDCONST R7 K6 + 0x7C180200, // 0012 CALL R6 1 + 0x8C1C0707, // 0013 GETMET R7 R3 K7 + 0x5C240200, // 0014 MOVE R9 R1 + 0x5C280A00, // 0015 MOVE R10 R5 + 0x7C1C0600, // 0016 CALL R7 3 + 0x60200015, // 0017 GETGBL R8 G21 + 0x5426007F, // 0018 LDINT R9 128 + 0x7C200200, // 0019 CALL R8 1 + 0x8C241108, // 001A GETMET R9 R8 K8 + 0x582C0009, // 001B LDCONST R11 K9 + 0x5830000A, // 001C LDCONST R12 K10 + 0x7C240600, // 001D CALL R9 3 + 0x8C241108, // 001E GETMET R9 R8 K8 + 0x602C000C, // 001F GETGBL R11 G12 + 0x5C300E00, // 0020 MOVE R12 R7 + 0x7C2C0200, // 0021 CALL R11 1 + 0x002C170A, // 0022 ADD R11 R11 K10 + 0x5830000A, // 0023 LDCONST R12 K10 + 0x7C240600, // 0024 CALL R9 3 + 0x8C241108, // 0025 GETMET R9 R8 K8 + 0x582C000B, // 0026 LDCONST R11 K11 + 0x5830000A, // 0027 LDCONST R12 K10 + 0x7C240600, // 0028 CALL R9 3 + 0x40241007, // 0029 CONNECT R9 R8 R7 + 0x6024000C, // 002A GETGBL R9 G12 + 0x5C280A00, // 002B MOVE R10 R5 + 0x7C240200, // 002C CALL R9 1 + 0x6028000C, // 002D GETGBL R10 G12 + 0x5C2C0C00, // 002E MOVE R11 R6 + 0x7C280200, // 002F CALL R10 1 + 0x0024120A, // 0030 ADD R9 R9 R10 + 0x6028000C, // 0031 GETGBL R10 G12 + 0x5C2C1000, // 0032 MOVE R11 R8 + 0x7C280200, // 0033 CALL R10 1 + 0x0024120A, // 0034 ADD R9 R9 R10 + 0x60280015, // 0035 GETGBL R10 G21 + 0x542E00CF, // 0036 LDINT R11 208 + 0x7C280200, // 0037 CALL R10 1 + 0x8C2C1508, // 0038 GETMET R11 R10 K8 + 0x5436002F, // 0039 LDINT R13 48 + 0x5838000A, // 003A LDCONST R14 K10 + 0x7C2C0600, // 003B CALL R11 3 + 0x8C2C1508, // 003C GETMET R11 R10 K8 + 0x54360080, // 003D LDINT R13 129 + 0x5838000A, // 003E LDCONST R14 K10 + 0x7C2C0600, // 003F CALL R11 3 + 0x8C2C1508, // 0040 GETMET R11 R10 K8 + 0x543600FE, // 0041 LDINT R13 255 + 0x2C34120D, // 0042 AND R13 R9 R13 + 0x5838000A, // 0043 LDCONST R14 K10 + 0x7C2C0600, // 0044 CALL R11 3 + 0x402C1405, // 0045 CONNECT R11 R10 R5 + 0x402C1406, // 0046 CONNECT R11 R10 R6 + 0x402C1408, // 0047 CONNECT R11 R10 R8 + 0x80041400, // 0048 RET 1 R10 }) ) ); @@ -634,9 +725,9 @@ be_local_closure(Matter_Session_is_PASE, /* name */ /******************************************************************** -** Solidified function: get_admin_subject +** Solidified function: get_ipk_epoch_key ********************************************************************/ -be_local_closure(Matter_Session_get_admin_subject, /* name */ +be_local_closure(Matter_Session_get_ipk_epoch_key, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -648,9 +739,9 @@ be_local_closure(Matter_Session_get_admin_subject, /* name */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(admin_subject), + /* K1 */ be_nested_str_weak(ipk_epoch_key), }), - be_str_weak(get_admin_subject), + be_str_weak(get_ipk_epoch_key), &be_const_str_solidified, ( &(const binstruction[ 3]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -663,29 +754,38 @@ be_local_closure(Matter_Session_get_admin_subject, /* name */ /******************************************************************** -** Solidified function: save +** Solidified function: counter_rcv_validate ********************************************************************/ -be_local_closure(Matter_Session_save, /* name */ +be_local_closure(Matter_Session_counter_rcv_validate, /* name */ be_nested_proto( - 3, /* nstack */ - 1, /* argc */ + 7, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(_store), - /* K1 */ be_nested_str_weak(save_fabrics), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(_counter_rcv_impl), + /* K1 */ be_nested_str_weak(validate), + /* K2 */ be_nested_str_weak(counter_rcv), + /* K3 */ be_nested_str_weak(val), }), - be_str_weak(save), + be_str_weak(counter_rcv_validate), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x80000000, // 0003 RET 0 + ( &(const binstruction[11]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x5C140200, // 0002 MOVE R5 R1 + 0x5C180400, // 0003 MOVE R6 R2 + 0x7C0C0600, // 0004 CALL R3 3 + 0x780E0003, // 0005 JMPF R3 #000A + 0x88100100, // 0006 GETMBR R4 R0 K0 + 0x8C100903, // 0007 GETMET R4 R4 K3 + 0x7C100200, // 0008 CALL R4 1 + 0x90020404, // 0009 SETMBR R0 K2 R4 + 0x80040600, // 000A RET 1 R3 }) ) ); @@ -693,9 +793,9 @@ be_local_closure(Matter_Session_save, /* name */ /******************************************************************** -** Solidified function: get_ipk_epoch_key +** Solidified function: get_admin_subject ********************************************************************/ -be_local_closure(Matter_Session_get_ipk_epoch_key, /* name */ +be_local_closure(Matter_Session_get_admin_subject, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -707,9 +807,9 @@ be_local_closure(Matter_Session_get_ipk_epoch_key, /* name */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(ipk_epoch_key), + /* K1 */ be_nested_str_weak(admin_subject), }), - be_str_weak(get_ipk_epoch_key), + be_str_weak(get_admin_subject), &be_const_str_solidified, ( &(const binstruction[ 3]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -722,11 +822,11 @@ be_local_closure(Matter_Session_get_ipk_epoch_key, /* name */ /******************************************************************** -** Solidified function: is_CASE +** Solidified function: get_fabric_compressed ********************************************************************/ -be_local_closure(Matter_Session_is_CASE, /* name */ +be_local_closure(Matter_Session_get_fabric_compressed, /* name */ be_nested_proto( - 3, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -735,16 +835,15 @@ be_local_closure(Matter_Session_is_CASE, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(mode), - /* K1 */ be_nested_str_weak(_CASE), + /* K0 */ be_nested_str_weak(_fabric), + /* K1 */ be_nested_str_weak(fabric_compressed), }), - be_str_weak(is_CASE), + be_str_weak(get_fabric_compressed), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ + ( &(const binstruction[ 3]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88080101, // 0001 GETMBR R2 R0 K1 - 0x1C040202, // 0002 EQ R1 R1 R2 - 0x80040200, // 0003 RET 1 R1 + 0x88040301, // 0001 GETMBR R1 R1 K1 + 0x80040200, // 0002 RET 1 R1 }) ) ); @@ -752,9 +851,9 @@ be_local_closure(Matter_Session_is_CASE, /* name */ /******************************************************************** -** Solidified function: fabric_candidate +** Solidified function: persist_to_fabric ********************************************************************/ -be_local_closure(Matter_Session_fabric_candidate, /* name */ +be_local_closure(Matter_Session_persist_to_fabric, /* name */ be_nested_proto( 4, /* nstack */ 1, /* argc */ @@ -764,27 +863,18 @@ be_local_closure(Matter_Session_fabric_candidate, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ + ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(set_expire_in_seconds), - /* K2 */ be_nested_str_weak(assign_fabric_index), - /* K3 */ be_nested_str_weak(_store), - /* K4 */ be_nested_str_weak(add_fabric), + /* K1 */ be_nested_str_weak(add_session), }), - be_str_weak(fabric_candidate), + be_str_weak(persist_to_fabric), &be_const_str_solidified, - ( &(const binstruction[11]) { /* code */ + ( &(const binstruction[ 5]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x540E0077, // 0002 LDINT R3 120 + 0x5C0C0000, // 0002 MOVE R3 R0 0x7C040400, // 0003 CALL R1 2 - 0x8C040102, // 0004 GETMET R1 R0 K2 - 0x7C040200, // 0005 CALL R1 1 - 0x88040103, // 0006 GETMBR R1 R0 K3 - 0x8C040304, // 0007 GETMET R1 R1 K4 - 0x880C0100, // 0008 GETMBR R3 R0 K0 - 0x7C040400, // 0009 CALL R1 2 - 0x80000000, // 000A RET 0 + 0x80000000, // 0004 RET 0 }) ) ); @@ -792,11 +882,11 @@ be_local_closure(Matter_Session_fabric_candidate, /* name */ /******************************************************************** -** Solidified function: get_ipk_group_key +** Solidified function: get_ca ********************************************************************/ -be_local_closure(Matter_Session_get_ipk_group_key, /* name */ +be_local_closure(Matter_Session_get_ca, /* name */ be_nested_proto( - 10, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -804,47 +894,16 @@ be_local_closure(Matter_Session_get_ipk_group_key, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str_weak(get_ipk_epoch_key), - /* K1 */ be_nested_str_weak(get_fabric_compressed), - /* K2 */ be_nested_str_weak(crypto), - /* K3 */ be_nested_str_weak(HKDF_SHA256), - /* K4 */ be_nested_str_weak(fromstring), - /* K5 */ be_nested_str_weak(_GROUP_KEY), - /* K6 */ be_nested_str_weak(derive), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(_fabric), + /* K1 */ be_nested_str_weak(root_ca_certificate), }), - be_str_weak(get_ipk_group_key), + be_str_weak(get_ca), &be_const_str_solidified, - ( &(const binstruction[29]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x4C080000, // 0002 LDNIL R2 - 0x1C040202, // 0003 EQ R1 R1 R2 - 0x74060004, // 0004 JMPT R1 #000A - 0x8C040101, // 0005 GETMET R1 R0 K1 - 0x7C040200, // 0006 CALL R1 1 - 0x4C080000, // 0007 LDNIL R2 - 0x1C040202, // 0008 EQ R1 R1 R2 - 0x78060001, // 0009 JMPF R1 #000C - 0x4C040000, // 000A LDNIL R1 - 0x80040200, // 000B RET 1 R1 - 0xA4060400, // 000C IMPORT R1 K2 - 0x8C080303, // 000D GETMET R2 R1 K3 - 0x7C080200, // 000E CALL R2 1 - 0x600C0015, // 000F GETGBL R3 G21 - 0x7C0C0000, // 0010 CALL R3 0 - 0x8C0C0704, // 0011 GETMET R3 R3 K4 - 0x88140105, // 0012 GETMBR R5 R0 K5 - 0x7C0C0400, // 0013 CALL R3 2 - 0x8C100506, // 0014 GETMET R4 R2 K6 - 0x8C180100, // 0015 GETMET R6 R0 K0 - 0x7C180200, // 0016 CALL R6 1 - 0x8C1C0101, // 0017 GETMET R7 R0 K1 - 0x7C1C0200, // 0018 CALL R7 1 - 0x5C200600, // 0019 MOVE R8 R3 - 0x5426000F, // 001A LDINT R9 16 - 0x7C100A00, // 001B CALL R4 5 - 0x80040800, // 001C RET 1 R4 + ( &(const binstruction[ 3]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x88040301, // 0001 GETMBR R1 R1 K1 + 0x80040200, // 0002 RET 1 R1 }) ) ); @@ -852,11 +911,11 @@ be_local_closure(Matter_Session_get_ipk_group_key, /* name */ /******************************************************************** -** Solidified function: get_noc +** Solidified function: is_PASE ********************************************************************/ -be_local_closure(Matter_Session_get_noc, /* name */ +be_local_closure(Matter_Session_is_PASE, /* name */ be_nested_proto( - 2, /* nstack */ + 3, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -865,15 +924,16 @@ be_local_closure(Matter_Session_get_noc, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(noc), + /* K0 */ be_nested_str_weak(mode), + /* K1 */ be_nested_str_weak(_PASE), }), - be_str_weak(get_noc), + be_str_weak(is_PASE), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ + ( &(const binstruction[ 4]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x80040200, // 0002 RET 1 R1 + 0x88080101, // 0001 GETMBR R2 R0 K1 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x80040200, // 0003 RET 1 R1 }) ) ); @@ -881,11 +941,11 @@ be_local_closure(Matter_Session_get_noc, /* name */ /******************************************************************** -** Solidified function: fabric_completed +** Solidified function: is_CASE ********************************************************************/ -be_local_closure(Matter_Session_fabric_completed, /* name */ +be_local_closure(Matter_Session_is_CASE, /* name */ be_nested_proto( - 4, /* nstack */ + 3, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -893,31 +953,17 @@ be_local_closure(Matter_Session_fabric_completed, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(set_no_expiration), - /* K2 */ be_nested_str_weak(set_persist), - /* K3 */ be_nested_str_weak(assign_fabric_index), - /* K4 */ be_nested_str_weak(_store), - /* K5 */ be_nested_str_weak(add_fabric), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(mode), + /* K1 */ be_nested_str_weak(_CASE), }), - be_str_weak(fabric_completed), + be_str_weak(is_CASE), &be_const_str_solidified, - ( &(const binstruction[14]) { /* code */ + ( &(const binstruction[ 4]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x88040100, // 0003 GETMBR R1 R0 K0 - 0x8C040302, // 0004 GETMET R1 R1 K2 - 0x500C0200, // 0005 LDBOOL R3 1 0 - 0x7C040400, // 0006 CALL R1 2 - 0x8C040103, // 0007 GETMET R1 R0 K3 - 0x7C040200, // 0008 CALL R1 1 - 0x88040104, // 0009 GETMBR R1 R0 K4 - 0x8C040305, // 000A GETMET R1 R1 K5 - 0x880C0100, // 000B GETMBR R3 R0 K0 - 0x7C040400, // 000C CALL R1 2 - 0x80000000, // 000D RET 0 + 0x88080101, // 0001 GETMBR R2 R0 K1 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x80040200, // 0003 RET 1 R1 }) ) ); @@ -925,12 +971,12 @@ be_local_closure(Matter_Session_fabric_completed, /* name */ /******************************************************************** -** Solidified function: set_keys +** Solidified function: before_remove ********************************************************************/ -be_local_closure(Matter_Session_set_keys, /* name */ +be_local_closure(Matter_Session_before_remove, /* name */ be_nested_proto( 6, /* nstack */ - 5, /* argc */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -938,22 +984,24 @@ be_local_closure(Matter_Session_set_keys, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(i2rkey), - /* K1 */ be_nested_str_weak(_i2r_privacy), - /* K2 */ be_nested_str_weak(r2ikey), - /* K3 */ be_nested_str_weak(attestation_challenge), - /* K4 */ be_nested_str_weak(created), + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(log), + /* K2 */ be_nested_str_weak(MTR_X3A_X20_X2DSession_X20_X20_X20_X28_X256i_X29_X20_X28removed_X29), + /* K3 */ be_nested_str_weak(local_session_id), + /* K4 */ be_const_int(3), }), - be_str_weak(set_keys), + be_str_weak(before_remove), &be_const_str_solidified, - ( &(const binstruction[ 7]) { /* code */ - 0x90020001, // 0000 SETMBR R0 K0 R1 - 0x4C140000, // 0001 LDNIL R5 - 0x90020205, // 0002 SETMBR R0 K1 R5 - 0x90020402, // 0003 SETMBR R0 K2 R2 - 0x90020603, // 0004 SETMBR R0 K3 R3 - 0x90020804, // 0005 SETMBR R0 K4 R4 - 0x80000000, // 0006 RET 0 + ( &(const binstruction[ 9]) { /* code */ + 0xB8060000, // 0000 GETNGBL R1 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x600C0018, // 0002 GETGBL R3 G24 + 0x58100002, // 0003 LDCONST R4 K2 + 0x88140103, // 0004 GETMBR R5 R0 K3 + 0x7C0C0400, // 0005 CALL R3 2 + 0x58100004, // 0006 LDCONST R4 K4 + 0x7C040600, // 0007 CALL R1 3 + 0x80000000, // 0008 RET 0 }) ) ); @@ -961,11 +1009,11 @@ be_local_closure(Matter_Session_set_keys, /* name */ /******************************************************************** -** Solidified function: counter_snd_next +** Solidified function: save ********************************************************************/ -be_local_closure(Matter_Session_counter_snd_next, /* name */ +be_local_closure(Matter_Session_save, /* name */ be_nested_proto( - 9, /* nstack */ + 3, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -973,54 +1021,17 @@ be_local_closure(Matter_Session_counter_snd_next, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(_counter_snd_impl), - /* K2 */ be_nested_str_weak(next), - /* K3 */ be_nested_str_weak(tasmota), - /* K4 */ be_nested_str_weak(log), - /* K5 */ be_nested_str_weak(format), - /* K6 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Counter_snd_X3D_X25i), - /* K7 */ be_const_int(3), - /* K8 */ be_nested_str_weak(matter), - /* K9 */ be_nested_str_weak(Counter), - /* K10 */ be_nested_str_weak(is_greater), - /* K11 */ be_nested_str_weak(counter_snd), - /* K12 */ be_nested_str_weak(_COUNTER_SND_INCR), - /* K13 */ be_nested_str_weak(does_persist), - /* K14 */ be_nested_str_weak(save), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(_store), + /* K1 */ be_nested_str_weak(save_fabrics), }), - be_str_weak(counter_snd_next), + be_str_weak(save), &be_const_str_solidified, - ( &(const binstruction[28]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x88080101, // 0001 GETMBR R2 R0 K1 - 0x8C080502, // 0002 GETMET R2 R2 K2 - 0x7C080200, // 0003 CALL R2 1 - 0xB80E0600, // 0004 GETNGBL R3 K3 - 0x8C0C0704, // 0005 GETMET R3 R3 K4 - 0x8C140305, // 0006 GETMET R5 R1 K5 - 0x581C0006, // 0007 LDCONST R7 K6 - 0x5C200400, // 0008 MOVE R8 R2 - 0x7C140600, // 0009 CALL R5 3 - 0x58180007, // 000A LDCONST R6 K7 - 0x7C0C0600, // 000B CALL R3 3 - 0xB80E1000, // 000C GETNGBL R3 K8 - 0x880C0709, // 000D GETMBR R3 R3 K9 - 0x8C0C070A, // 000E GETMET R3 R3 K10 - 0x5C140400, // 000F MOVE R5 R2 - 0x8818010B, // 0010 GETMBR R6 R0 K11 - 0x7C0C0600, // 0011 CALL R3 3 - 0x780E0007, // 0012 JMPF R3 #001B - 0x880C010C, // 0013 GETMBR R3 R0 K12 - 0x000C0403, // 0014 ADD R3 R2 R3 - 0x90021603, // 0015 SETMBR R0 K11 R3 - 0x8C0C010D, // 0016 GETMET R3 R0 K13 - 0x7C0C0200, // 0017 CALL R3 1 - 0x780E0001, // 0018 JMPF R3 #001B - 0x8C0C010E, // 0019 GETMET R3 R0 K14 - 0x7C0C0200, // 001A CALL R3 1 - 0x80040400, // 001B RET 1 R2 + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80000000, // 0003 RET 0 }) ) ); @@ -1057,12 +1068,12 @@ be_local_closure(Matter_Session_get_fabric_id, /* name */ /******************************************************************** -** Solidified function: set_ca +** Solidified function: get_ipk_group_key ********************************************************************/ -be_local_closure(Matter_Session_set_ca, /* name */ +be_local_closure(Matter_Session_get_ipk_group_key, /* name */ be_nested_proto( 3, /* nstack */ - 2, /* argc */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -1071,14 +1082,15 @@ be_local_closure(Matter_Session_set_ca, /* name */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(root_ca_certificate), + /* K1 */ be_nested_str_weak(get_ipk_group_key), }), - be_str_weak(set_ca), + be_str_weak(get_ipk_group_key), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x900A0201, // 0001 SETMBR R2 K1 R1 - 0x80000000, // 0002 RET 0 + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 }) ) ); @@ -1086,34 +1098,40 @@ be_local_closure(Matter_Session_set_ca, /* name */ /******************************************************************** -** Solidified function: set_fabric_label +** Solidified function: get_temp_ca_pub ********************************************************************/ -be_local_closure(Matter_Session_set_fabric_label, /* name */ +be_local_closure(Matter_Session_get_temp_ca_pub, /* name */ be_nested_proto( - 4, /* nstack */ - 2, /* argc */ + 6, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(_fabric), - /* K2 */ be_nested_str_weak(fabric_label), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_temp_root_ca_certificate), + /* K1 */ be_nested_str_weak(matter), + /* K2 */ be_nested_str_weak(TLV), + /* K3 */ be_nested_str_weak(parse), + /* K4 */ be_nested_str_weak(findsubval), }), - be_str_weak(set_fabric_label), + be_str_weak(get_temp_ca_pub), &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x60080004, // 0000 GETGBL R2 G4 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x1C080500, // 0003 EQ R2 R2 K0 - 0x780A0001, // 0004 JMPF R2 #0007 - 0x88080101, // 0005 GETMBR R2 R0 K1 - 0x900A0401, // 0006 SETMBR R2 K2 R1 - 0x80000000, // 0007 RET 0 + ( &(const binstruction[12]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x78060008, // 0001 JMPF R1 #000B + 0xB80A0200, // 0002 GETNGBL R2 K1 + 0x88080502, // 0003 GETMBR R2 R2 K2 + 0x8C080503, // 0004 GETMET R2 R2 K3 + 0x5C100200, // 0005 MOVE R4 R1 + 0x7C080400, // 0006 CALL R2 2 + 0x8C0C0504, // 0007 GETMET R3 R2 K4 + 0x54160008, // 0008 LDINT R5 9 + 0x7C0C0400, // 0009 CALL R3 2 + 0x80040600, // 000A RET 1 R3 + 0x80000000, // 000B RET 0 }) ) ); @@ -1121,11 +1139,11 @@ be_local_closure(Matter_Session_set_fabric_label, /* name */ /******************************************************************** -** Solidified function: get_ca +** Solidified function: get_ca_pub ********************************************************************/ -be_local_closure(Matter_Session_get_ca, /* name */ +be_local_closure(Matter_Session_get_ca_pub, /* name */ be_nested_proto( - 2, /* nstack */ + 3, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1135,41 +1153,15 @@ be_local_closure(Matter_Session_get_ca, /* name */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(root_ca_certificate), + /* K1 */ be_nested_str_weak(get_ca_pub), }), - be_str_weak(get_ca), + be_str_weak(get_ca_pub), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ + ( &(const binstruction[ 4]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x80040200, // 0002 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_mode -********************************************************************/ -be_local_closure(Matter_Session_set_mode, /* name */ - be_nested_proto( - 2, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(mode), - }), - be_str_weak(set_mode), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x90020001, // 0000 SETMBR R0 K0 R1 - 0x80000000, // 0001 RET 0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 }) ) ); @@ -1177,9 +1169,9 @@ be_local_closure(Matter_Session_set_mode, /* name */ /******************************************************************** -** Solidified function: get_ac +** Solidified function: get_mode ********************************************************************/ -be_local_closure(Matter_Session_get_ac, /* name */ +be_local_closure(Matter_Session_get_mode, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -1190,9 +1182,9 @@ be_local_closure(Matter_Session_get_ac, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(attestation_challenge), + /* K0 */ be_nested_str_weak(mode), }), - be_str_weak(get_ac), + be_str_weak(get_mode), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -1251,9 +1243,9 @@ be_local_closure(Matter_Session_hydrate_post, /* name */ /******************************************************************** -** Solidified function: get_icac +** Solidified function: get_fabric_label ********************************************************************/ -be_local_closure(Matter_Session_get_icac, /* name */ +be_local_closure(Matter_Session_get_fabric_label, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -1265,9 +1257,9 @@ be_local_closure(Matter_Session_get_icac, /* name */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(icac), + /* K1 */ be_nested_str_weak(fabric_label), }), - be_str_weak(get_icac), + be_str_weak(get_fabric_label), &be_const_str_solidified, ( &(const binstruction[ 3]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -1280,31 +1272,28 @@ be_local_closure(Matter_Session_get_icac, /* name */ /******************************************************************** -** Solidified function: set_admin_subject_vendor +** Solidified function: get_icac ********************************************************************/ -be_local_closure(Matter_Session_set_admin_subject_vendor, /* name */ +be_local_closure(Matter_Session_get_icac, /* name */ be_nested_proto( - 4, /* nstack */ - 3, /* argc */ + 2, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ + ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(admin_subject), - /* K2 */ be_nested_str_weak(admin_vendor), + /* K1 */ be_nested_str_weak(icac), }), - be_str_weak(set_admin_subject_vendor), + be_str_weak(get_icac), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x900E0201, // 0001 SETMBR R3 K1 R1 - 0x880C0100, // 0002 GETMBR R3 R0 K0 - 0x900E0402, // 0003 SETMBR R3 K2 R2 - 0x80000000, // 0004 RET 0 + ( &(const binstruction[ 3]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x88040301, // 0001 GETMBR R1 R1 K1 + 0x80040200, // 0002 RET 1 R1 }) ) ); @@ -1312,12 +1301,12 @@ be_local_closure(Matter_Session_set_admin_subject_vendor, /* name */ /******************************************************************** -** Solidified function: set_ipk_epoch_key +** Solidified function: set_mode_CASE ********************************************************************/ -be_local_closure(Matter_Session_set_ipk_epoch_key, /* name */ +be_local_closure(Matter_Session_set_mode_CASE, /* name */ be_nested_proto( - 3, /* nstack */ - 2, /* argc */ + 4, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -1325,15 +1314,16 @@ be_local_closure(Matter_Session_set_ipk_epoch_key, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(ipk_epoch_key), + /* K0 */ be_nested_str_weak(set_mode), + /* K1 */ be_nested_str_weak(_CASE), }), - be_str_weak(set_ipk_epoch_key), + be_str_weak(set_mode_CASE), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x900A0201, // 0001 SETMBR R2 K1 R1 - 0x80000000, // 0002 RET 0 + ( &(const binstruction[ 4]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x880C0101, // 0001 GETMBR R3 R0 K1 + 0x7C040400, // 0002 CALL R1 2 + 0x80000000, // 0003 RET 0 }) ) ); @@ -1341,11 +1331,11 @@ be_local_closure(Matter_Session_set_ipk_epoch_key, /* name */ /******************************************************************** -** Solidified function: before_remove +** Solidified function: counter_snd_next ********************************************************************/ -be_local_closure(Matter_Session_before_remove, /* name */ +be_local_closure(Matter_Session_counter_snd_next, /* name */ be_nested_proto( - 8, /* nstack */ + 6, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1353,92 +1343,39 @@ be_local_closure(Matter_Session_before_remove, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(log), - /* K3 */ be_nested_str_weak(format), - /* K4 */ be_nested_str_weak(MTR_X3A_X20_X2DSession_X20_X20_X20_X28_X256i_X29_X20_X28removed_X29), - /* K5 */ be_nested_str_weak(local_session_id), - /* K6 */ be_const_int(3), + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(_counter_snd_impl), + /* K1 */ be_nested_str_weak(next), + /* K2 */ be_nested_str_weak(matter), + /* K3 */ be_nested_str_weak(Counter), + /* K4 */ be_nested_str_weak(is_greater), + /* K5 */ be_nested_str_weak(counter_snd), + /* K6 */ be_nested_str_weak(_COUNTER_SND_INCR), + /* K7 */ be_nested_str_weak(does_persist), + /* K8 */ be_nested_str_weak(save), }), - be_str_weak(before_remove), - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xB80A0200, // 0001 GETNGBL R2 K1 - 0x8C080502, // 0002 GETMET R2 R2 K2 - 0x8C100303, // 0003 GETMET R4 R1 K3 - 0x58180004, // 0004 LDCONST R6 K4 - 0x881C0105, // 0005 GETMBR R7 R0 K5 - 0x7C100600, // 0006 CALL R4 3 - 0x58140006, // 0007 LDCONST R5 K6 - 0x7C080600, // 0008 CALL R2 3 - 0x80000000, // 0009 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: update -********************************************************************/ -be_local_closure(Matter_Session_update, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(last_used), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(rtc), - /* K3 */ be_nested_str_weak(utc), - }), - be_str_weak(update), + be_str_weak(counter_snd_next), &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0xB8060200, // 0000 GETNGBL R1 K1 - 0x8C040302, // 0001 GETMET R1 R1 K2 + ( &(const binstruction[19]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 0x7C040200, // 0002 CALL R1 1 - 0x94040303, // 0003 GETIDX R1 R1 K3 - 0x90020001, // 0004 SETMBR R0 K0 R1 - 0x80000000, // 0005 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_mode_CASE -********************************************************************/ -be_local_closure(Matter_Session_set_mode_CASE, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(set_mode), - /* K1 */ be_nested_str_weak(_CASE), - }), - be_str_weak(set_mode_CASE), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x880C0101, // 0001 GETMBR R3 R0 K1 - 0x7C040400, // 0002 CALL R1 2 - 0x80000000, // 0003 RET 0 + 0xB80A0400, // 0003 GETNGBL R2 K2 + 0x88080503, // 0004 GETMBR R2 R2 K3 + 0x8C080504, // 0005 GETMET R2 R2 K4 + 0x5C100200, // 0006 MOVE R4 R1 + 0x88140105, // 0007 GETMBR R5 R0 K5 + 0x7C080600, // 0008 CALL R2 3 + 0x780A0007, // 0009 JMPF R2 #0012 + 0x88080106, // 000A GETMBR R2 R0 K6 + 0x00080202, // 000B ADD R2 R1 R2 + 0x90020A02, // 000C SETMBR R0 K5 R2 + 0x8C080107, // 000D GETMET R2 R0 K7 + 0x7C080200, // 000E CALL R2 1 + 0x780A0001, // 000F JMPF R2 #0012 + 0x8C080108, // 0010 GETMET R2 R0 K8 + 0x7C080200, // 0011 CALL R2 1 + 0x80040200, // 0012 RET 1 R1 }) ) ); @@ -1499,11 +1436,11 @@ be_local_closure(Matter_Session_get_i2r_privacy, /* name */ /******************************************************************** -** Solidified function: get_ca_pub +** Solidified function: get_i2r ********************************************************************/ -be_local_closure(Matter_Session_get_ca_pub, /* name */ +be_local_closure(Matter_Session_get_i2r, /* name */ be_nested_proto( - 3, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1511,123 +1448,14 @@ be_local_closure(Matter_Session_get_ca_pub, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(get_ca_pub), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(i2rkey), }), - be_str_weak(get_ca_pub), + be_str_weak(get_i2r), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ + ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: close -********************************************************************/ -be_local_closure(Matter_Session_close, /* name */ - be_nested_proto( - 8, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[23]) { /* constants */ - /* K0 */ be_nested_str_weak(local_session_id), - /* K1 */ be_nested_str_weak(__future_local_session_id), - /* K2 */ be_nested_str_weak(initiator_session_id), - /* K3 */ be_nested_str_weak(__future_initiator_session_id), - /* K4 */ be_nested_str_weak(_counter_rcv_impl), - /* K5 */ be_nested_str_weak(reset), - /* K6 */ be_nested_str_weak(_counter_snd_impl), - /* K7 */ be_nested_str_weak(counter_rcv), - /* K8 */ be_const_int(0), - /* K9 */ be_nested_str_weak(counter_snd), - /* K10 */ be_nested_str_weak(next), - /* K11 */ be_nested_str_weak(i2rkey), - /* K12 */ be_nested_str_weak(_i2r_privacy), - /* K13 */ be_nested_str_weak(r2ikey), - /* K14 */ be_nested_str_weak(attestation_challenge), - /* K15 */ be_nested_str_weak(introspect), - /* K16 */ be_nested_str_weak(members), - /* K17 */ be_nested_str_weak(get), - /* K18 */ be_nested_str_weak(function), - /* K19 */ be_nested_str_weak(instance), - /* K20 */ be_nested_str_weak(_), - /* K21 */ be_const_int(1), - /* K22 */ be_nested_str_weak(stop_iteration), - }), - be_str_weak(close), - &be_const_str_solidified, - ( &(const binstruction[59]) { /* code */ - 0x88040101, // 0000 GETMBR R1 R0 K1 - 0x90020001, // 0001 SETMBR R0 K0 R1 - 0x88040103, // 0002 GETMBR R1 R0 K3 - 0x90020401, // 0003 SETMBR R0 K2 R1 - 0x88040104, // 0004 GETMBR R1 R0 K4 - 0x8C040305, // 0005 GETMET R1 R1 K5 - 0x7C040200, // 0006 CALL R1 1 - 0x88040106, // 0007 GETMBR R1 R0 K6 - 0x8C040305, // 0008 GETMET R1 R1 K5 - 0x7C040200, // 0009 CALL R1 1 - 0x90020F08, // 000A SETMBR R0 K7 K8 - 0x88040106, // 000B GETMBR R1 R0 K6 - 0x8C04030A, // 000C GETMET R1 R1 K10 - 0x7C040200, // 000D CALL R1 1 - 0x90021201, // 000E SETMBR R0 K9 R1 - 0x4C040000, // 000F LDNIL R1 - 0x90021601, // 0010 SETMBR R0 K11 R1 - 0x4C040000, // 0011 LDNIL R1 - 0x90021801, // 0012 SETMBR R0 K12 R1 - 0x4C040000, // 0013 LDNIL R1 - 0x90021A01, // 0014 SETMBR R0 K13 R1 - 0x4C040000, // 0015 LDNIL R1 - 0x90021C01, // 0016 SETMBR R0 K14 R1 - 0xA4061E00, // 0017 IMPORT R1 K15 - 0x60080010, // 0018 GETGBL R2 G16 - 0x8C0C0310, // 0019 GETMET R3 R1 K16 - 0x5C140000, // 001A MOVE R5 R0 - 0x7C0C0400, // 001B CALL R3 2 - 0x7C080200, // 001C CALL R2 1 - 0xA8020018, // 001D EXBLK 0 #0037 - 0x5C0C0400, // 001E MOVE R3 R2 - 0x7C0C0000, // 001F CALL R3 0 - 0x8C100311, // 0020 GETMET R4 R1 K17 - 0x5C180000, // 0021 MOVE R6 R0 - 0x5C1C0600, // 0022 MOVE R7 R3 - 0x7C100600, // 0023 CALL R4 3 - 0x60140004, // 0024 GETGBL R5 G4 - 0x5C180800, // 0025 MOVE R6 R4 - 0x7C140200, // 0026 CALL R5 1 - 0x20140B12, // 0027 NE R5 R5 K18 - 0x7816000C, // 0028 JMPF R5 #0036 - 0x60140004, // 0029 GETGBL R5 G4 - 0x5C180800, // 002A MOVE R6 R4 - 0x7C140200, // 002B CALL R5 1 - 0x20140B13, // 002C NE R5 R5 K19 - 0x78160007, // 002D JMPF R5 #0036 - 0x94140708, // 002E GETIDX R5 R3 K8 - 0x1C140B14, // 002F EQ R5 R5 K20 - 0x78160004, // 0030 JMPF R5 #0036 - 0x94140715, // 0031 GETIDX R5 R3 K21 - 0x1C140B14, // 0032 EQ R5 R5 K20 - 0x78160001, // 0033 JMPF R5 #0036 - 0x4C140000, // 0034 LDNIL R5 - 0x90000605, // 0035 SETMBR R0 R3 R5 - 0x7001FFE6, // 0036 JMP #001E - 0x58080016, // 0037 LDCONST R2 K22 - 0xAC080200, // 0038 CATCH R2 1 0 - 0xB0080000, // 0039 RAISE 2 R0 R0 - 0x80000000, // 003A RET 0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -1635,9 +1463,9 @@ be_local_closure(Matter_Session_close, /* name */ /******************************************************************** -** Solidified function: get_fabric_compressed +** Solidified function: get_admin_vendor ********************************************************************/ -be_local_closure(Matter_Session_get_fabric_compressed, /* name */ +be_local_closure(Matter_Session_get_admin_vendor, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -1649,9 +1477,9 @@ be_local_closure(Matter_Session_get_fabric_compressed, /* name */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(fabric_compressed), + /* K1 */ be_nested_str_weak(admin_vendor), }), - be_str_weak(get_fabric_compressed), + be_str_weak(get_admin_vendor), &be_const_str_solidified, ( &(const binstruction[ 3]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -1664,28 +1492,26 @@ be_local_closure(Matter_Session_get_fabric_compressed, /* name */ /******************************************************************** -** Solidified function: get_admin_vendor +** Solidified function: set_temp_ca ********************************************************************/ -be_local_closure(Matter_Session_get_admin_vendor, /* name */ +be_local_closure(Matter_Session_set_temp_ca, /* name */ be_nested_proto( 2, /* nstack */ - 1, /* argc */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(admin_vendor), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(_temp_root_ca_certificate), }), - be_str_weak(get_admin_vendor), + be_str_weak(set_temp_ca), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x80040200, // 0002 RET 1 R1 + ( &(const binstruction[ 2]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x80000000, // 0001 RET 0 }) ) ); @@ -1693,39 +1519,87 @@ be_local_closure(Matter_Session_get_admin_vendor, /* name */ /******************************************************************** -** Solidified function: get_pk +** Solidified function: init ********************************************************************/ -be_local_closure(Matter_Session_get_pk, /* name */ +be_local_closure(Matter_Session_init, /* name */ be_nested_proto( - 6, /* nstack */ - 1, /* argc */ + 10, /* nstack */ + 5, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(no_private_key), - /* K2 */ be_nested_str_weak(crypto), - /* K3 */ be_nested_str_weak(random), + ( &(const bvalue[23]) { /* constants */ + /* K0 */ be_nested_str_weak(crypto), + /* K1 */ be_nested_str_weak(_store), + /* K2 */ be_nested_str_weak(mode), + /* K3 */ be_const_int(0), + /* K4 */ be_nested_str_weak(local_session_id), + /* K5 */ be_nested_str_weak(initiator_session_id), + /* K6 */ be_nested_str_weak(_counter_snd_impl), + /* K7 */ be_nested_str_weak(matter), + /* K8 */ be_nested_str_weak(Counter), + /* K9 */ be_nested_str_weak(_counter_rcv_impl), + /* K10 */ be_nested_str_weak(counter_rcv), + /* K11 */ be_nested_str_weak(counter_snd), + /* K12 */ be_nested_str_weak(next), + /* K13 */ be_nested_str_weak(_COUNTER_SND_INCR), + /* K14 */ be_nested_str_weak(_counter_insecure_rcv), + /* K15 */ be_nested_str_weak(_counter_insecure_snd), + /* K16 */ be_nested_str_weak(_breadcrumb), + /* K17 */ be_nested_str_weak(_exchange_id), + /* K18 */ be_nested_str_weak(random), + /* K19 */ be_const_int(2), + /* K20 */ be_nested_str_weak(get), + /* K21 */ be_nested_str_weak(_fabric), + /* K22 */ be_nested_str_weak(update), }), - be_str_weak(get_pk), + be_str_weak(init), &be_const_str_solidified, - ( &(const binstruction[12]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x74060005, // 0002 JMPT R1 #0009 - 0xA4060400, // 0003 IMPORT R1 K2 - 0x88080100, // 0004 GETMBR R2 R0 K0 - 0x8C0C0303, // 0005 GETMET R3 R1 K3 - 0x5416001F, // 0006 LDINT R5 32 - 0x7C0C0400, // 0007 CALL R3 2 - 0x900A0203, // 0008 SETMBR R2 K1 R3 - 0x88040100, // 0009 GETMBR R1 R0 K0 - 0x88040301, // 000A GETMBR R1 R1 K1 - 0x80040200, // 000B RET 1 R1 + ( &(const binstruction[41]) { /* code */ + 0xA4160000, // 0000 IMPORT R5 K0 + 0x90020201, // 0001 SETMBR R0 K1 R1 + 0x90020503, // 0002 SETMBR R0 K2 K3 + 0x90020802, // 0003 SETMBR R0 K4 R2 + 0x90020A03, // 0004 SETMBR R0 K5 R3 + 0xB81A0E00, // 0005 GETNGBL R6 K7 + 0x8C180D08, // 0006 GETMET R6 R6 K8 + 0x7C180200, // 0007 CALL R6 1 + 0x90020C06, // 0008 SETMBR R0 K6 R6 + 0xB81A0E00, // 0009 GETNGBL R6 K7 + 0x8C180D08, // 000A GETMET R6 R6 K8 + 0x7C180200, // 000B CALL R6 1 + 0x90021206, // 000C SETMBR R0 K9 R6 + 0x90021503, // 000D SETMBR R0 K10 K3 + 0x88180106, // 000E GETMBR R6 R0 K6 + 0x8C180D0C, // 000F GETMET R6 R6 K12 + 0x7C180200, // 0010 CALL R6 1 + 0x881C010D, // 0011 GETMBR R7 R0 K13 + 0x00180C07, // 0012 ADD R6 R6 R7 + 0x90021606, // 0013 SETMBR R0 K11 R6 + 0xB81A0E00, // 0014 GETNGBL R6 K7 + 0x8C180D08, // 0015 GETMET R6 R6 K8 + 0x7C180200, // 0016 CALL R6 1 + 0x90021C06, // 0017 SETMBR R0 K14 R6 + 0xB81A0E00, // 0018 GETNGBL R6 K7 + 0x8C180D08, // 0019 GETMET R6 R6 K8 + 0x7C180200, // 001A CALL R6 1 + 0x90021E06, // 001B SETMBR R0 K15 R6 + 0x90022103, // 001C SETMBR R0 K16 K3 + 0x8C180B12, // 001D GETMET R6 R5 K18 + 0x58200013, // 001E LDCONST R8 K19 + 0x7C180400, // 001F CALL R6 2 + 0x8C180D14, // 0020 GETMET R6 R6 K20 + 0x58200003, // 0021 LDCONST R8 K3 + 0x58240013, // 0022 LDCONST R9 K19 + 0x7C180600, // 0023 CALL R6 3 + 0x90022206, // 0024 SETMBR R0 K17 R6 + 0x90022A04, // 0025 SETMBR R0 K21 R4 + 0x8C180116, // 0026 GETMET R6 R0 K22 + 0x7C180200, // 0027 CALL R6 1 + 0x80000000, // 0028 RET 0 }) ) ); @@ -1733,45 +1607,32 @@ be_local_closure(Matter_Session_get_pk, /* name */ /******************************************************************** -** Solidified function: set_fabric_device +** Solidified function: get_fabric_index ********************************************************************/ -be_local_closure(Matter_Session_set_fabric_device, /* name */ +be_local_closure(Matter_Session_get_fabric_index, /* name */ be_nested_proto( - 8, /* nstack */ - 5, /* argc */ + 2, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ + ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(fabric_id), - /* K2 */ be_nested_str_weak(device_id), - /* K3 */ be_nested_str_weak(fabric_compressed), - /* K4 */ be_nested_str_weak(fabric_parent), - /* K5 */ be_nested_str_weak(get_fabric_index), + /* K1 */ be_nested_str_weak(fabric_index), }), - be_str_weak(set_fabric_device), + be_str_weak(get_fabric_index), &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x88140100, // 0000 GETMBR R5 R0 K0 - 0x90160201, // 0001 SETMBR R5 K1 R1 - 0x88140100, // 0002 GETMBR R5 R0 K0 - 0x90160402, // 0003 SETMBR R5 K2 R2 - 0x88140100, // 0004 GETMBR R5 R0 K0 - 0x90160603, // 0005 SETMBR R5 K3 R3 - 0x88140100, // 0006 GETMBR R5 R0 K0 - 0x4C180000, // 0007 LDNIL R6 - 0x20180806, // 0008 NE R6 R4 R6 - 0x781A0002, // 0009 JMPF R6 #000D - 0x8C180905, // 000A GETMET R6 R4 K5 - 0x7C180200, // 000B CALL R6 1 - 0x70020000, // 000C JMP #000E - 0x4C180000, // 000D LDNIL R6 - 0x90160806, // 000E SETMBR R5 K4 R6 - 0x80000000, // 000F RET 0 + ( &(const binstruction[ 7]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x78060002, // 0001 JMPF R1 #0005 + 0x88040100, // 0002 GETMBR R1 R0 K0 + 0x88040301, // 0003 GETMBR R1 R1 K1 + 0x70020000, // 0004 JMP #0006 + 0x4C040000, // 0005 LDNIL R1 + 0x80040200, // 0006 RET 1 R1 }) ) ); @@ -1779,11 +1640,11 @@ be_local_closure(Matter_Session_set_fabric_device, /* name */ /******************************************************************** -** Solidified function: gen_CSR +** Solidified function: get_temp_ca ********************************************************************/ -be_local_closure(Matter_Session_gen_CSR, /* name */ +be_local_closure(Matter_Session_get_temp_ca, /* name */ be_nested_proto( - 15, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1791,96 +1652,14 @@ be_local_closure(Matter_Session_gen_CSR, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[12]) { /* constants */ - /* K0 */ be_nested_str_weak(get_pk), - /* K1 */ be_nested_str_weak(crypto), - /* K2 */ be_nested_str_weak(EC_P256), - /* K3 */ be_nested_str_weak(public_key), - /* K4 */ be_nested_str_weak(3070020100300E310C300A060355040A0C034353523059301306072A8648CE3D020106082A8648CE3D030107034200), - /* K5 */ be_nested_str_weak(A000), - /* K6 */ be_nested_str_weak(300C06082A8648CE3D0403020500), - /* K7 */ be_nested_str_weak(ecdsa_sign_sha256_asn1), - /* K8 */ be_nested_str_weak(add), - /* K9 */ be_const_int(3), - /* K10 */ be_const_int(1), - /* K11 */ be_const_int(0), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(_temp_root_ca_certificate), }), - be_str_weak(gen_CSR), + be_str_weak(get_temp_ca), &be_const_str_solidified, - ( &(const binstruction[73]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0xA40A0200, // 0002 IMPORT R2 K1 - 0x8C0C0502, // 0003 GETMET R3 R2 K2 - 0x7C0C0200, // 0004 CALL R3 1 - 0x8C100703, // 0005 GETMET R4 R3 K3 - 0x5C180200, // 0006 MOVE R6 R1 - 0x7C100400, // 0007 CALL R4 2 - 0x60140015, // 0008 GETGBL R5 G21 - 0x58180004, // 0009 LDCONST R6 K4 - 0x7C140200, // 000A CALL R5 1 - 0x40180A04, // 000B CONNECT R6 R5 R4 - 0x60180015, // 000C GETGBL R6 G21 - 0x581C0005, // 000D LDCONST R7 K5 - 0x7C180200, // 000E CALL R6 1 - 0x40180A06, // 000F CONNECT R6 R5 R6 - 0x60180015, // 0010 GETGBL R6 G21 - 0x581C0006, // 0011 LDCONST R7 K6 - 0x7C180200, // 0012 CALL R6 1 - 0x8C1C0707, // 0013 GETMET R7 R3 K7 - 0x5C240200, // 0014 MOVE R9 R1 - 0x5C280A00, // 0015 MOVE R10 R5 - 0x7C1C0600, // 0016 CALL R7 3 - 0x60200015, // 0017 GETGBL R8 G21 - 0x5426007F, // 0018 LDINT R9 128 - 0x7C200200, // 0019 CALL R8 1 - 0x8C241108, // 001A GETMET R9 R8 K8 - 0x582C0009, // 001B LDCONST R11 K9 - 0x5830000A, // 001C LDCONST R12 K10 - 0x7C240600, // 001D CALL R9 3 - 0x8C241108, // 001E GETMET R9 R8 K8 - 0x602C000C, // 001F GETGBL R11 G12 - 0x5C300E00, // 0020 MOVE R12 R7 - 0x7C2C0200, // 0021 CALL R11 1 - 0x002C170A, // 0022 ADD R11 R11 K10 - 0x5830000A, // 0023 LDCONST R12 K10 - 0x7C240600, // 0024 CALL R9 3 - 0x8C241108, // 0025 GETMET R9 R8 K8 - 0x582C000B, // 0026 LDCONST R11 K11 - 0x5830000A, // 0027 LDCONST R12 K10 - 0x7C240600, // 0028 CALL R9 3 - 0x40241007, // 0029 CONNECT R9 R8 R7 - 0x6024000C, // 002A GETGBL R9 G12 - 0x5C280A00, // 002B MOVE R10 R5 - 0x7C240200, // 002C CALL R9 1 - 0x6028000C, // 002D GETGBL R10 G12 - 0x5C2C0C00, // 002E MOVE R11 R6 - 0x7C280200, // 002F CALL R10 1 - 0x0024120A, // 0030 ADD R9 R9 R10 - 0x6028000C, // 0031 GETGBL R10 G12 - 0x5C2C1000, // 0032 MOVE R11 R8 - 0x7C280200, // 0033 CALL R10 1 - 0x0024120A, // 0034 ADD R9 R9 R10 - 0x60280015, // 0035 GETGBL R10 G21 - 0x542E00CF, // 0036 LDINT R11 208 - 0x7C280200, // 0037 CALL R10 1 - 0x8C2C1508, // 0038 GETMET R11 R10 K8 - 0x5436002F, // 0039 LDINT R13 48 - 0x5838000A, // 003A LDCONST R14 K10 - 0x7C2C0600, // 003B CALL R11 3 - 0x8C2C1508, // 003C GETMET R11 R10 K8 - 0x54360080, // 003D LDINT R13 129 - 0x5838000A, // 003E LDCONST R14 K10 - 0x7C2C0600, // 003F CALL R11 3 - 0x8C2C1508, // 0040 GETMET R11 R10 K8 - 0x543600FE, // 0041 LDINT R13 255 - 0x2C34120D, // 0042 AND R13 R9 R13 - 0x5838000A, // 0043 LDCONST R14 K10 - 0x7C2C0600, // 0044 CALL R11 3 - 0x402C1405, // 0045 CONNECT R11 R10 R5 - 0x402C1406, // 0046 CONNECT R11 R10 R6 - 0x402C1408, // 0047 CONNECT R11 R10 R8 - 0x80041400, // 0048 RET 1 R10 + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -1888,11 +1667,11 @@ be_local_closure(Matter_Session_gen_CSR, /* name */ /******************************************************************** -** Solidified function: get_fabric +** Solidified function: get_pk ********************************************************************/ -be_local_closure(Matter_Session_get_fabric, /* name */ +be_local_closure(Matter_Session_get_pk, /* name */ be_nested_proto( - 2, /* nstack */ + 5, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1900,14 +1679,33 @@ be_local_closure(Matter_Session_get_fabric, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ + ( &(const bvalue[ 5]) { /* constants */ /* K0 */ be_nested_str_weak(_fabric), + /* K1 */ be_nested_str_weak(get_pk), + /* K2 */ be_nested_str_weak(_temp_pk), + /* K3 */ be_nested_str_weak(crypto), + /* K4 */ be_nested_str_weak(random), }), - be_str_weak(get_fabric), + be_str_weak(get_pk), &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ + ( &(const binstruction[17]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 + 0x78060004, // 0001 JMPF R1 #0007 + 0x88040100, // 0002 GETMBR R1 R0 K0 + 0x8C040301, // 0003 GETMET R1 R1 K1 + 0x7C040200, // 0004 CALL R1 1 + 0x80040200, // 0005 RET 1 R1 + 0x70020008, // 0006 JMP #0010 + 0x88040102, // 0007 GETMBR R1 R0 K2 + 0x74060004, // 0008 JMPT R1 #000E + 0xA4060600, // 0009 IMPORT R1 K3 + 0x8C080304, // 000A GETMET R2 R1 K4 + 0x5412001F, // 000B LDINT R4 32 + 0x7C080400, // 000C CALL R2 2 + 0x90020402, // 000D SETMBR R0 K2 R2 + 0x88040102, // 000E GETMBR R1 R0 K2 + 0x80040200, // 000F RET 1 R1 + 0x80000000, // 0010 RET 0 }) ) ); @@ -1915,38 +1713,29 @@ be_local_closure(Matter_Session_get_fabric, /* name */ /******************************************************************** -** Solidified function: counter_rcv_validate +** Solidified function: set_mode_PASE ********************************************************************/ -be_local_closure(Matter_Session_counter_rcv_validate, /* name */ +be_local_closure(Matter_Session_set_mode_PASE, /* name */ be_nested_proto( - 7, /* nstack */ - 3, /* argc */ + 4, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(_counter_rcv_impl), - /* K1 */ be_nested_str_weak(validate), - /* K2 */ be_nested_str_weak(counter_rcv), - /* K3 */ be_nested_str_weak(val), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(set_mode), + /* K1 */ be_nested_str_weak(_PASE), }), - be_str_weak(counter_rcv_validate), + be_str_weak(set_mode_PASE), &be_const_str_solidified, - ( &(const binstruction[11]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x8C0C0701, // 0001 GETMET R3 R3 K1 - 0x5C140200, // 0002 MOVE R5 R1 - 0x5C180400, // 0003 MOVE R6 R2 - 0x7C0C0600, // 0004 CALL R3 3 - 0x780E0003, // 0005 JMPF R3 #000A - 0x88100100, // 0006 GETMBR R4 R0 K0 - 0x8C100903, // 0007 GETMET R4 R4 K3 - 0x7C100200, // 0008 CALL R4 1 - 0x90020404, // 0009 SETMBR R0 K2 R4 - 0x80040600, // 000A RET 1 R3 + ( &(const binstruction[ 4]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x880C0101, // 0001 GETMBR R3 R0 K1 + 0x7C040400, // 0002 CALL R1 2 + 0x80000000, // 0003 RET 0 }) ) ); @@ -1954,31 +1743,26 @@ be_local_closure(Matter_Session_counter_rcv_validate, /* name */ /******************************************************************** -** Solidified function: set_noc +** Solidified function: set_mode ********************************************************************/ -be_local_closure(Matter_Session_set_noc, /* name */ +be_local_closure(Matter_Session_set_mode, /* name */ be_nested_proto( - 4, /* nstack */ - 3, /* argc */ + 2, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(_fabric), - /* K1 */ be_nested_str_weak(noc), - /* K2 */ be_nested_str_weak(icac), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(mode), }), - be_str_weak(set_noc), + be_str_weak(set_mode), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x900E0201, // 0001 SETMBR R3 K1 R1 - 0x880C0100, // 0002 GETMBR R3 R0 K0 - 0x900E0402, // 0003 SETMBR R3 K2 R2 - 0x80000000, // 0004 RET 0 + ( &(const binstruction[ 2]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x80000000, // 0001 RET 0 }) ) ); @@ -1990,96 +1774,94 @@ be_local_closure(Matter_Session_set_noc, /* name */ ********************************************************************/ extern const bclass be_class_Matter_Expirable; be_local_class(Matter_Session, - 36, + 38, &be_class_Matter_Expirable, - be_nested_map(86, + be_nested_map(84, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(__Msg2, -1), be_const_var(34) }, - { be_const_key_weak(_GROUP_KEY, -1), be_nested_str_weak(GroupKey_X20v1_X2E0) }, - { be_const_key_weak(set_noc, 50), be_const_closure(Matter_Session_set_noc_closure) }, - { be_const_key_weak(get_i2r, 79), be_const_closure(Matter_Session_get_i2r_closure) }, - { be_const_key_weak(tojson, -1), be_const_closure(Matter_Session_tojson_closure) }, - { be_const_key_weak(assign_fabric_index, 30), be_const_closure(Matter_Session_assign_fabric_index_closure) }, - { be_const_key_weak(get_r2i, -1), be_const_closure(Matter_Session_get_r2i_closure) }, - { be_const_key_weak(_breadcrumb, -1), be_const_var(25) }, - { be_const_key_weak(_counter_snd_impl, -1), be_const_var(13) }, - { be_const_key_weak(gen_CSR, -1), be_const_closure(Matter_Session_gen_CSR_closure) }, - { be_const_key_weak(__future_local_session_id, -1), be_const_var(9) }, - { be_const_key_weak(set_mode_PASE, -1), be_const_closure(Matter_Session_set_mode_PASE_closure) }, - { be_const_key_weak(get_fabric_label, -1), be_const_closure(Matter_Session_get_fabric_label_closure) }, - { be_const_key_weak(__spake_Ke, -1), be_const_var(32) }, - { be_const_key_weak(get_device_id, 85), be_const_closure(Matter_Session_get_device_id_closure) }, - { be_const_key_weak(persist_to_fabric, 6), be_const_closure(Matter_Session_persist_to_fabric_closure) }, + { be_const_key_weak(set_mode, 6), be_const_closure(Matter_Session_set_mode_closure) }, + { be_const_key_weak(set_mode_PASE, 57), be_const_closure(Matter_Session_set_mode_PASE_closure) }, + { be_const_key_weak(_counter_rcv_impl, 79), be_const_var(14) }, + { be_const_key_weak(attestation_challenge, 56), be_const_var(25) }, + { be_const_key_weak(get_ac, -1), be_const_closure(Matter_Session_get_ac_closure) }, + { be_const_key_weak(get_fabric, -1), be_const_closure(Matter_Session_get_fabric_closure) }, + { be_const_key_weak(get_temp_ca, 69), be_const_closure(Matter_Session_get_temp_ca_closure) }, { be_const_key_weak(_COUNTER_SND_INCR, -1), be_const_int(1024) }, - { be_const_key_weak(local_session_id, 18), be_const_var(3) }, - { be_const_key_weak(shared_secret, 42), be_const_var(27) }, - { be_const_key_weak(get_mode, 74), be_const_closure(Matter_Session_get_mode_closure) }, - { be_const_key_weak(peer_node_id, -1), be_const_var(24) }, - { be_const_key_weak(i2rkey, -1), be_const_var(20) }, - { be_const_key_weak(get_pk, -1), be_const_closure(Matter_Session_get_pk_closure) }, - { be_const_key_weak(is_PASE, -1), be_const_closure(Matter_Session_is_PASE_closure) }, - { be_const_key_weak(get_admin_subject, -1), be_const_closure(Matter_Session_get_admin_subject_closure) }, - { be_const_key_weak(get_admin_vendor, -1), be_const_closure(Matter_Session_get_admin_vendor_closure) }, - { be_const_key_weak(get_ipk_epoch_key, 2), be_const_closure(Matter_Session_get_ipk_epoch_key_closure) }, - { be_const_key_weak(_counter_insecure_snd, -1), be_const_var(19) }, - { be_const_key_weak(_i2r_privacy, 78), be_const_var(22) }, + { be_const_key_weak(_CASE, -1), be_const_int(2) }, + { be_const_key_weak(_counter_insecure_rcv, 2), be_const_var(20) }, + { be_const_key_weak(_breadcrumb, -1), be_const_var(27) }, + { be_const_key_weak(r2ikey, 82), be_const_var(23) }, + { be_const_key_weak(set_keys, 52), be_const_closure(Matter_Session_set_keys_closure) }, + { be_const_key_weak(_exchange_id, -1), be_const_var(16) }, + { be_const_key_weak(peer_node_id, 8), be_const_var(26) }, + { be_const_key_weak(last_used, 80), be_const_var(6) }, + { be_const_key_weak(_source_node_id, 48), be_const_var(7) }, + { be_const_key_weak(init, 36), be_const_closure(Matter_Session_init_closure) }, + { be_const_key_weak(set_temp_ca, -1), be_const_closure(Matter_Session_set_temp_ca_closure) }, + { be_const_key_weak(created, -1), be_const_var(5) }, + { be_const_key_weak(persist_to_fabric, -1), be_const_closure(Matter_Session_persist_to_fabric_closure) }, + { be_const_key_weak(__initiator_pub, -1), be_const_var(32) }, + { be_const_key_weak(gen_CSR, -1), be_const_closure(Matter_Session_gen_CSR_closure) }, + { be_const_key_weak(_store, -1), be_const_var(0) }, + { be_const_key_weak(get_ipk_epoch_key, 49), be_const_closure(Matter_Session_get_ipk_epoch_key_closure) }, + { be_const_key_weak(__responder_priv, 7), be_const_var(30) }, + { be_const_key_weak(counter_rcv_validate, -1), be_const_closure(Matter_Session_counter_rcv_validate_closure) }, + { be_const_key_weak(_ip, -1), be_const_var(17) }, + { be_const_key_weak(get_admin_subject, 40), be_const_closure(Matter_Session_get_admin_subject_closure) }, + { be_const_key_weak(resumption_id, -1), be_const_var(28) }, + { be_const_key_weak(_i2r_privacy, -1), be_const_var(24) }, { be_const_key_weak(get_fabric_compressed, -1), be_const_closure(Matter_Session_get_fabric_compressed_closure) }, - { be_const_key_weak(get_fabric_id, -1), be_const_closure(Matter_Session_get_fabric_id_closure) }, - { be_const_key_weak(_exchange_id, 29), be_const_var(14) }, - { be_const_key_weak(fabric_candidate, -1), be_const_closure(Matter_Session_fabric_candidate_closure) }, - { be_const_key_weak(__responder_pub, -1), be_const_var(29) }, + { be_const_key_weak(_temp_pk, -1), be_const_var(9) }, + { be_const_key_weak(shared_secret, 74), be_const_var(29) }, + { be_const_key_weak(_temp_root_ca_certificate, -1), be_const_var(8) }, + { be_const_key_weak(get_ca, -1), be_const_closure(Matter_Session_get_ca_closure) }, + { be_const_key_weak(_fabric, 10), be_const_var(2) }, + { be_const_key_weak(__spake_cA, -1), be_const_var(33) }, { be_const_key_weak(get_ipk_group_key, -1), be_const_closure(Matter_Session_get_ipk_group_key_closure) }, - { be_const_key_weak(__Msg1, -1), be_const_var(33) }, - { be_const_key_weak(get_noc, -1), be_const_closure(Matter_Session_get_noc_closure) }, - { be_const_key_weak(_port, 48), be_const_var(16) }, - { be_const_key_weak(fabric_completed, -1), be_const_closure(Matter_Session_fabric_completed_closure) }, - { be_const_key_weak(__future_initiator_session_id, -1), be_const_var(8) }, - { be_const_key_weak(__spake_cA, 54), be_const_var(31) }, - { be_const_key_weak(_message_handler, -1), be_const_var(17) }, - { be_const_key_weak(attestation_challenge, 8), be_const_var(23) }, + { be_const_key_weak(initiator_session_id, 18), be_const_var(4) }, { be_const_key_weak(get_i2r_privacy, -1), be_const_closure(Matter_Session_get_i2r_privacy_closure) }, - { be_const_key_weak(set_keys, -1), be_const_closure(Matter_Session_set_keys_closure) }, - { be_const_key_weak(counter_snd_next, -1), be_const_closure(Matter_Session_counter_snd_next_closure) }, - { be_const_key_weak(_CASE, -1), be_const_int(2) }, - { be_const_key_weak(last_used, -1), be_const_var(6) }, - { be_const_key_weak(_ip, -1), be_const_var(15) }, - { be_const_key_weak(set_mode_CASE, 28), be_const_closure(Matter_Session_set_mode_CASE_closure) }, - { be_const_key_weak(set_fabric_label, 13), be_const_closure(Matter_Session_set_fabric_label_closure) }, - { be_const_key_weak(hydrate_post, -1), be_const_closure(Matter_Session_hydrate_post_closure) }, - { be_const_key_weak(get_ca, -1), be_const_closure(Matter_Session_get_ca_closure) }, - { be_const_key_weak(init, 69), be_const_closure(Matter_Session_init_closure) }, - { be_const_key_weak(get_icac, 41), be_const_closure(Matter_Session_get_icac_closure) }, - { be_const_key_weak(_store, 51), be_const_var(0) }, - { be_const_key_weak(__chunked_attr_reports, -1), be_const_var(35) }, - { be_const_key_weak(counter_rcv, -1), be_const_var(10) }, - { be_const_key_weak(_source_node_id, -1), be_const_var(7) }, - { be_const_key_weak(set_admin_subject_vendor, 63), be_const_closure(Matter_Session_set_admin_subject_vendor_closure) }, - { be_const_key_weak(set_ipk_epoch_key, -1), be_const_closure(Matter_Session_set_ipk_epoch_key_closure) }, - { be_const_key_weak(_counter_insecure_rcv, 62), be_const_var(18) }, - { be_const_key_weak(before_remove, 64), be_const_closure(Matter_Session_before_remove_closure) }, - { be_const_key_weak(__responder_priv, -1), be_const_var(28) }, - { be_const_key_weak(initiator_session_id, -1), be_const_var(4) }, - { be_const_key_weak(r2ikey, 16), be_const_var(21) }, - { be_const_key_weak(__initiator_pub, -1), be_const_var(30) }, - { be_const_key_weak(resumption_id, -1), be_const_var(26) }, - { be_const_key_weak(save, 49), be_const_closure(Matter_Session_save_closure) }, - { be_const_key_weak(set_mode, 56), be_const_closure(Matter_Session_set_mode_closure) }, - { be_const_key_weak(get_ac, 43), be_const_closure(Matter_Session_get_ac_closure) }, - { be_const_key_weak(_PASE, -1), be_const_int(1) }, + { be_const_key_weak(__chunked_attr_reports, -1), be_const_var(37) }, { be_const_key_weak(get_ca_pub, -1), be_const_closure(Matter_Session_get_ca_pub_closure) }, - { be_const_key_weak(close, -1), be_const_closure(Matter_Session_close_closure) }, - { be_const_key_weak(_counter_rcv_impl, -1), be_const_var(12) }, - { be_const_key_weak(_fabric, -1), be_const_var(2) }, - { be_const_key_weak(update, 25), be_const_closure(Matter_Session_update_closure) }, - { be_const_key_weak(fromjson, 22), be_const_static_closure(Matter_Session_fromjson_closure) }, + { be_const_key_weak(counter_snd, 20), be_const_var(13) }, + { be_const_key_weak(set_fabric_label, 35), be_const_closure(Matter_Session_set_fabric_label_closure) }, + { be_const_key_weak(_counter_snd_impl, 71), be_const_var(15) }, { be_const_key_weak(is_CASE, -1), be_const_closure(Matter_Session_is_CASE_closure) }, - { be_const_key_weak(counter_snd, -1), be_const_var(11) }, - { be_const_key_weak(set_fabric_device, -1), be_const_closure(Matter_Session_set_fabric_device_closure) }, - { be_const_key_weak(created, 10), be_const_var(5) }, - { be_const_key_weak(set_ca, 9), be_const_closure(Matter_Session_set_ca_closure) }, - { be_const_key_weak(get_fabric, -1), be_const_closure(Matter_Session_get_fabric_closure) }, - { be_const_key_weak(counter_rcv_validate, -1), be_const_closure(Matter_Session_counter_rcv_validate_closure) }, + { be_const_key_weak(before_remove, -1), be_const_closure(Matter_Session_before_remove_closure) }, + { be_const_key_weak(set_mode_CASE, -1), be_const_closure(Matter_Session_set_mode_CASE_closure) }, + { be_const_key_weak(get_icac, -1), be_const_closure(Matter_Session_get_icac_closure) }, + { be_const_key_weak(tojson, 61), be_const_closure(Matter_Session_tojson_closure) }, + { be_const_key_weak(close, 1), be_const_closure(Matter_Session_close_closure) }, + { be_const_key_weak(get_fabric_label, 42), be_const_closure(Matter_Session_get_fabric_label_closure) }, + { be_const_key_weak(_counter_insecure_snd, -1), be_const_var(21) }, + { be_const_key_weak(get_device_id, 63), be_const_closure(Matter_Session_get_device_id_closure) }, + { be_const_key_weak(counter_rcv, 62), be_const_var(12) }, + { be_const_key_weak(__Msg1, -1), be_const_var(35) }, + { be_const_key_weak(hydrate_post, 66), be_const_closure(Matter_Session_hydrate_post_closure) }, + { be_const_key_weak(_message_handler, -1), be_const_var(19) }, + { be_const_key_weak(__future_initiator_session_id, -1), be_const_var(10) }, + { be_const_key_weak(__spake_Ke, 32), be_const_var(34) }, + { be_const_key_weak(__Msg2, 38), be_const_var(36) }, + { be_const_key_weak(get_mode, -1), be_const_closure(Matter_Session_get_mode_closure) }, { be_const_key_weak(mode, -1), be_const_var(1) }, + { be_const_key_weak(update, 16), be_const_closure(Matter_Session_update_closure) }, + { be_const_key_weak(counter_snd_next, -1), be_const_closure(Matter_Session_counter_snd_next_closure) }, + { be_const_key_weak(get_temp_ca_pub, -1), be_const_closure(Matter_Session_get_temp_ca_pub_closure) }, + { be_const_key_weak(get_i2r, -1), be_const_closure(Matter_Session_get_i2r_closure) }, + { be_const_key_weak(get_noc, 37), be_const_closure(Matter_Session_get_noc_closure) }, + { be_const_key_weak(get_fabric_id, -1), be_const_closure(Matter_Session_get_fabric_id_closure) }, + { be_const_key_weak(get_admin_vendor, -1), be_const_closure(Matter_Session_get_admin_vendor_closure) }, + { be_const_key_weak(is_PASE, -1), be_const_closure(Matter_Session_is_PASE_closure) }, + { be_const_key_weak(save, 21), be_const_closure(Matter_Session_save_closure) }, + { be_const_key_weak(_GROUP_KEY, -1), be_nested_str_weak(GroupKey_X20v1_X2E0) }, + { be_const_key_weak(local_session_id, 76), be_const_var(3) }, + { be_const_key_weak(i2rkey, 17), be_const_var(22) }, + { be_const_key_weak(__future_local_session_id, -1), be_const_var(11) }, + { be_const_key_weak(_PASE, -1), be_const_int(1) }, + { be_const_key_weak(get_fabric_index, -1), be_const_closure(Matter_Session_get_fabric_index_closure) }, + { be_const_key_weak(_port, -1), be_const_var(18) }, + { be_const_key_weak(get_r2i, -1), be_const_closure(Matter_Session_get_r2i_closure) }, + { be_const_key_weak(get_pk, -1), be_const_closure(Matter_Session_get_pk_closure) }, + { be_const_key_weak(__responder_pub, -1), be_const_var(31) }, + { be_const_key_weak(fromjson, 0), be_const_static_closure(Matter_Session_fromjson_closure) }, })), be_str_weak(Matter_Session) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Session_Store.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Session_Store.h index 2417ab0962f5..e4ccf468a5fe 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Session_Store.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_Session_Store.h @@ -332,7 +332,7 @@ be_local_closure(Matter_Session_Store_next_fabric_idx, /* name */ ********************************************************************/ be_local_closure(Matter_Session_Store_load_fabrics, /* name */ be_nested_proto( - 17, /* nstack */ + 16, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -340,158 +340,155 @@ be_local_closure(Matter_Session_Store_load_fabrics, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[29]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(sessions), - /* K2 */ be_nested_str_weak(matter), - /* K3 */ be_nested_str_weak(Expirable_list), - /* K4 */ be_nested_str_weak(fabrics), - /* K5 */ be_nested_str_weak(_FABRICS), - /* K6 */ be_nested_str_weak(read), - /* K7 */ be_nested_str_weak(close), - /* K8 */ be_nested_str_weak(json), - /* K9 */ be_nested_str_weak(load), - /* K10 */ be_nested_str_weak(tasmota), - /* K11 */ be_nested_str_weak(gc), - /* K12 */ be_nested_str_weak(Fabric), - /* K13 */ be_nested_str_weak(fromjson), - /* K14 */ be_nested_str_weak(set_no_expiration), - /* K15 */ be_nested_str_weak(set_persist), - /* K16 */ be_nested_str_weak(find), - /* K17 */ be_nested_str_weak(_sessions), - /* K18 */ be_nested_str_weak(Session), - /* K19 */ be_nested_str_weak(add_session), - /* K20 */ be_nested_str_weak(stop_iteration), - /* K21 */ be_nested_str_weak(push), - /* K22 */ be_nested_str_weak(log), - /* K23 */ be_nested_str_weak(format), - /* K24 */ be_nested_str_weak(MTR_X3A_X20Loaded_X20_X25i_X20fabric_X28s_X29), - /* K25 */ be_const_int(2), - /* K26 */ be_nested_str_weak(io_error), - /* K27 */ be_nested_str_weak(MTR_X3A_X20Session_Store_X3A_X3Aload_X20Exception_X3A), - /* K28 */ be_nested_str_weak(_X7C), + ( &(const bvalue[27]) { /* constants */ + /* K0 */ be_nested_str_weak(sessions), + /* K1 */ be_nested_str_weak(matter), + /* K2 */ be_nested_str_weak(Expirable_list), + /* K3 */ be_nested_str_weak(fabrics), + /* K4 */ be_nested_str_weak(_FABRICS), + /* K5 */ be_nested_str_weak(read), + /* K6 */ be_nested_str_weak(close), + /* K7 */ be_nested_str_weak(json), + /* K8 */ be_nested_str_weak(load), + /* K9 */ be_nested_str_weak(tasmota), + /* K10 */ be_nested_str_weak(gc), + /* K11 */ be_nested_str_weak(Fabric), + /* K12 */ be_nested_str_weak(fromjson), + /* K13 */ be_nested_str_weak(set_no_expiration), + /* K14 */ be_nested_str_weak(set_persist), + /* K15 */ be_nested_str_weak(find), + /* K16 */ be_nested_str_weak(_sessions), + /* K17 */ be_nested_str_weak(Session), + /* K18 */ be_nested_str_weak(add_session), + /* K19 */ be_nested_str_weak(stop_iteration), + /* K20 */ be_nested_str_weak(push), + /* K21 */ be_nested_str_weak(log), + /* K22 */ be_nested_str_weak(MTR_X3A_X20Loaded_X20_X25i_X20fabric_X28s_X29), + /* K23 */ be_const_int(2), + /* K24 */ be_nested_str_weak(io_error), + /* K25 */ be_nested_str_weak(MTR_X3A_X20Session_Store_X3A_X3Aload_X20Exception_X3A), + /* K26 */ be_nested_str_weak(_X7C), }), be_str_weak(load_fabrics), &be_const_str_solidified, - ( &(const binstruction[118]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xA802005F, // 0001 EXBLK 0 #0062 - 0xB80A0400, // 0002 GETNGBL R2 K2 - 0x8C080503, // 0003 GETMET R2 R2 K3 - 0x7C080200, // 0004 CALL R2 1 - 0x90020202, // 0005 SETMBR R0 K1 R2 - 0xB80A0400, // 0006 GETNGBL R2 K2 - 0x8C080503, // 0007 GETMET R2 R2 K3 - 0x7C080200, // 0008 CALL R2 1 - 0x90020802, // 0009 SETMBR R0 K4 R2 - 0x60080011, // 000A GETGBL R2 G17 - 0x880C0105, // 000B GETMBR R3 R0 K5 - 0x7C080200, // 000C CALL R2 1 - 0x8C0C0506, // 000D GETMET R3 R2 K6 - 0x7C0C0200, // 000E CALL R3 1 - 0x8C100507, // 000F GETMET R4 R2 K7 - 0x7C100200, // 0010 CALL R4 1 - 0xA4121000, // 0011 IMPORT R4 K8 - 0x8C140909, // 0012 GETMET R5 R4 K9 - 0x5C1C0600, // 0013 MOVE R7 R3 - 0x7C140400, // 0014 CALL R5 2 - 0x4C0C0000, // 0015 LDNIL R3 - 0xB81A1400, // 0016 GETNGBL R6 K10 - 0x8C180D0B, // 0017 GETMET R6 R6 K11 - 0x7C180200, // 0018 CALL R6 1 - 0x60180010, // 0019 GETGBL R6 G16 - 0x5C1C0A00, // 001A MOVE R7 R5 - 0x7C180200, // 001B CALL R6 1 - 0xA8020035, // 001C EXBLK 0 #0053 - 0x5C1C0C00, // 001D MOVE R7 R6 - 0x7C1C0000, // 001E CALL R7 0 - 0xB8220400, // 001F GETNGBL R8 K2 - 0x8820110C, // 0020 GETMBR R8 R8 K12 - 0x8C20110D, // 0021 GETMET R8 R8 K13 - 0x5C280000, // 0022 MOVE R10 R0 - 0x5C2C0E00, // 0023 MOVE R11 R7 - 0x7C200600, // 0024 CALL R8 3 - 0x8C24110E, // 0025 GETMET R9 R8 K14 - 0x7C240200, // 0026 CALL R9 1 - 0x8C24110F, // 0027 GETMET R9 R8 K15 - 0x502C0200, // 0028 LDBOOL R11 1 0 - 0x7C240400, // 0029 CALL R9 2 - 0x8C240F10, // 002A GETMET R9 R7 K16 - 0x582C0011, // 002B LDCONST R11 K17 - 0x60300012, // 002C GETGBL R12 G18 - 0x7C300000, // 002D CALL R12 0 - 0x7C240600, // 002E CALL R9 3 - 0x60280010, // 002F GETGBL R10 G16 - 0x5C2C1200, // 0030 MOVE R11 R9 - 0x7C280200, // 0031 CALL R10 1 - 0xA8020017, // 0032 EXBLK 0 #004B - 0x5C2C1400, // 0033 MOVE R11 R10 - 0x7C2C0000, // 0034 CALL R11 0 - 0xB8320400, // 0035 GETNGBL R12 K2 - 0x88301912, // 0036 GETMBR R12 R12 K18 - 0x8C30190D, // 0037 GETMET R12 R12 K13 - 0x5C380000, // 0038 MOVE R14 R0 - 0x5C3C1600, // 0039 MOVE R15 R11 - 0x5C401000, // 003A MOVE R16 R8 - 0x7C300800, // 003B CALL R12 4 - 0x4C340000, // 003C LDNIL R13 - 0x2034180D, // 003D NE R13 R12 R13 - 0x7836000A, // 003E JMPF R13 #004A - 0x8C34190E, // 003F GETMET R13 R12 K14 - 0x7C340200, // 0040 CALL R13 1 - 0x8C34190F, // 0041 GETMET R13 R12 K15 - 0x503C0200, // 0042 LDBOOL R15 1 0 - 0x7C340400, // 0043 CALL R13 2 - 0x8C340113, // 0044 GETMET R13 R0 K19 - 0x5C3C1800, // 0045 MOVE R15 R12 - 0x7C340400, // 0046 CALL R13 2 - 0x8C341113, // 0047 GETMET R13 R8 K19 - 0x5C3C1800, // 0048 MOVE R15 R12 - 0x7C340400, // 0049 CALL R13 2 - 0x7001FFE7, // 004A JMP #0033 - 0x58280014, // 004B LDCONST R10 K20 - 0xAC280200, // 004C CATCH R10 1 0 - 0xB0080000, // 004D RAISE 2 R0 R0 - 0x88280104, // 004E GETMBR R10 R0 K4 - 0x8C281515, // 004F GETMET R10 R10 K21 - 0x5C301000, // 0050 MOVE R12 R8 - 0x7C280400, // 0051 CALL R10 2 - 0x7001FFC9, // 0052 JMP #001D - 0x58180014, // 0053 LDCONST R6 K20 - 0xAC180200, // 0054 CATCH R6 1 0 - 0xB0080000, // 0055 RAISE 2 R0 R0 - 0xB81A1400, // 0056 GETNGBL R6 K10 - 0x8C180D16, // 0057 GETMET R6 R6 K22 - 0x8C200317, // 0058 GETMET R8 R1 K23 - 0x58280018, // 0059 LDCONST R10 K24 - 0x602C000C, // 005A GETGBL R11 G12 - 0x88300104, // 005B GETMBR R12 R0 K4 - 0x7C2C0200, // 005C CALL R11 1 - 0x7C200600, // 005D CALL R8 3 - 0x58240019, // 005E LDCONST R9 K25 - 0x7C180600, // 005F CALL R6 3 - 0xA8040001, // 0060 EXBLK 1 1 - 0x70020012, // 0061 JMP #0075 - 0xAC080002, // 0062 CATCH R2 0 2 - 0x7002000F, // 0063 JMP #0074 - 0x2010051A, // 0064 NE R4 R2 K26 - 0x7812000C, // 0065 JMPF R4 #0073 - 0xB8121400, // 0066 GETNGBL R4 K10 - 0x8C100916, // 0067 GETMET R4 R4 K22 - 0x60180008, // 0068 GETGBL R6 G8 - 0x5C1C0400, // 0069 MOVE R7 R2 - 0x7C180200, // 006A CALL R6 1 - 0x001A3606, // 006B ADD R6 K27 R6 - 0x00180D1C, // 006C ADD R6 R6 K28 - 0x601C0008, // 006D GETGBL R7 G8 - 0x5C200600, // 006E MOVE R8 R3 - 0x7C1C0200, // 006F CALL R7 1 - 0x00180C07, // 0070 ADD R6 R6 R7 - 0x581C0019, // 0071 LDCONST R7 K25 - 0x7C100600, // 0072 CALL R4 3 - 0x70020000, // 0073 JMP #0075 - 0xB0080000, // 0074 RAISE 2 R0 R0 - 0x80000000, // 0075 RET 0 + ( &(const binstruction[117]) { /* code */ + 0xA802005F, // 0000 EXBLK 0 #0061 + 0xB8060200, // 0001 GETNGBL R1 K1 + 0x8C040302, // 0002 GETMET R1 R1 K2 + 0x7C040200, // 0003 CALL R1 1 + 0x90020001, // 0004 SETMBR R0 K0 R1 + 0xB8060200, // 0005 GETNGBL R1 K1 + 0x8C040302, // 0006 GETMET R1 R1 K2 + 0x7C040200, // 0007 CALL R1 1 + 0x90020601, // 0008 SETMBR R0 K3 R1 + 0x60040011, // 0009 GETGBL R1 G17 + 0x88080104, // 000A GETMBR R2 R0 K4 + 0x7C040200, // 000B CALL R1 1 + 0x8C080305, // 000C GETMET R2 R1 K5 + 0x7C080200, // 000D CALL R2 1 + 0x8C0C0306, // 000E GETMET R3 R1 K6 + 0x7C0C0200, // 000F CALL R3 1 + 0xA40E0E00, // 0010 IMPORT R3 K7 + 0x8C100708, // 0011 GETMET R4 R3 K8 + 0x5C180400, // 0012 MOVE R6 R2 + 0x7C100400, // 0013 CALL R4 2 + 0x4C080000, // 0014 LDNIL R2 + 0xB8161200, // 0015 GETNGBL R5 K9 + 0x8C140B0A, // 0016 GETMET R5 R5 K10 + 0x7C140200, // 0017 CALL R5 1 + 0x60140010, // 0018 GETGBL R5 G16 + 0x5C180800, // 0019 MOVE R6 R4 + 0x7C140200, // 001A CALL R5 1 + 0xA8020035, // 001B EXBLK 0 #0052 + 0x5C180A00, // 001C MOVE R6 R5 + 0x7C180000, // 001D CALL R6 0 + 0xB81E0200, // 001E GETNGBL R7 K1 + 0x881C0F0B, // 001F GETMBR R7 R7 K11 + 0x8C1C0F0C, // 0020 GETMET R7 R7 K12 + 0x5C240000, // 0021 MOVE R9 R0 + 0x5C280C00, // 0022 MOVE R10 R6 + 0x7C1C0600, // 0023 CALL R7 3 + 0x8C200F0D, // 0024 GETMET R8 R7 K13 + 0x7C200200, // 0025 CALL R8 1 + 0x8C200F0E, // 0026 GETMET R8 R7 K14 + 0x50280200, // 0027 LDBOOL R10 1 0 + 0x7C200400, // 0028 CALL R8 2 + 0x8C200D0F, // 0029 GETMET R8 R6 K15 + 0x58280010, // 002A LDCONST R10 K16 + 0x602C0012, // 002B GETGBL R11 G18 + 0x7C2C0000, // 002C CALL R11 0 + 0x7C200600, // 002D CALL R8 3 + 0x60240010, // 002E GETGBL R9 G16 + 0x5C281000, // 002F MOVE R10 R8 + 0x7C240200, // 0030 CALL R9 1 + 0xA8020017, // 0031 EXBLK 0 #004A + 0x5C281200, // 0032 MOVE R10 R9 + 0x7C280000, // 0033 CALL R10 0 + 0xB82E0200, // 0034 GETNGBL R11 K1 + 0x882C1711, // 0035 GETMBR R11 R11 K17 + 0x8C2C170C, // 0036 GETMET R11 R11 K12 + 0x5C340000, // 0037 MOVE R13 R0 + 0x5C381400, // 0038 MOVE R14 R10 + 0x5C3C0E00, // 0039 MOVE R15 R7 + 0x7C2C0800, // 003A CALL R11 4 + 0x4C300000, // 003B LDNIL R12 + 0x2030160C, // 003C NE R12 R11 R12 + 0x7832000A, // 003D JMPF R12 #0049 + 0x8C30170D, // 003E GETMET R12 R11 K13 + 0x7C300200, // 003F CALL R12 1 + 0x8C30170E, // 0040 GETMET R12 R11 K14 + 0x50380200, // 0041 LDBOOL R14 1 0 + 0x7C300400, // 0042 CALL R12 2 + 0x8C300112, // 0043 GETMET R12 R0 K18 + 0x5C381600, // 0044 MOVE R14 R11 + 0x7C300400, // 0045 CALL R12 2 + 0x8C300F12, // 0046 GETMET R12 R7 K18 + 0x5C381600, // 0047 MOVE R14 R11 + 0x7C300400, // 0048 CALL R12 2 + 0x7001FFE7, // 0049 JMP #0032 + 0x58240013, // 004A LDCONST R9 K19 + 0xAC240200, // 004B CATCH R9 1 0 + 0xB0080000, // 004C RAISE 2 R0 R0 + 0x88240103, // 004D GETMBR R9 R0 K3 + 0x8C241314, // 004E GETMET R9 R9 K20 + 0x5C2C0E00, // 004F MOVE R11 R7 + 0x7C240400, // 0050 CALL R9 2 + 0x7001FFC9, // 0051 JMP #001C + 0x58140013, // 0052 LDCONST R5 K19 + 0xAC140200, // 0053 CATCH R5 1 0 + 0xB0080000, // 0054 RAISE 2 R0 R0 + 0xB8161200, // 0055 GETNGBL R5 K9 + 0x8C140B15, // 0056 GETMET R5 R5 K21 + 0x601C0018, // 0057 GETGBL R7 G24 + 0x58200016, // 0058 LDCONST R8 K22 + 0x6024000C, // 0059 GETGBL R9 G12 + 0x88280103, // 005A GETMBR R10 R0 K3 + 0x7C240200, // 005B CALL R9 1 + 0x7C1C0400, // 005C CALL R7 2 + 0x58200017, // 005D LDCONST R8 K23 + 0x7C140600, // 005E CALL R5 3 + 0xA8040001, // 005F EXBLK 1 1 + 0x70020012, // 0060 JMP #0074 + 0xAC040002, // 0061 CATCH R1 0 2 + 0x7002000F, // 0062 JMP #0073 + 0x200C0318, // 0063 NE R3 R1 K24 + 0x780E000C, // 0064 JMPF R3 #0072 + 0xB80E1200, // 0065 GETNGBL R3 K9 + 0x8C0C0715, // 0066 GETMET R3 R3 K21 + 0x60140008, // 0067 GETGBL R5 G8 + 0x5C180200, // 0068 MOVE R6 R1 + 0x7C140200, // 0069 CALL R5 1 + 0x00163205, // 006A ADD R5 K25 R5 + 0x00140B1A, // 006B ADD R5 R5 K26 + 0x60180008, // 006C GETGBL R6 G8 + 0x5C1C0400, // 006D MOVE R7 R2 + 0x7C180200, // 006E CALL R6 1 + 0x00140A06, // 006F ADD R5 R5 R6 + 0x58180017, // 0070 LDCONST R6 K23 + 0x7C0C0600, // 0071 CALL R3 3 + 0x70020000, // 0072 JMP #0074 + 0xB0080000, // 0073 RAISE 2 R0 R0 + 0x80000000, // 0074 RET 0 }) ) ); @@ -1088,7 +1085,7 @@ be_local_closure(Matter_Session_Store_sessions_active, /* name */ ********************************************************************/ be_local_closure(Matter_Session_Store_find_session_by_resumption_id, /* name */ be_nested_proto( - 14, /* nstack */ + 12, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1096,73 +1093,58 @@ be_local_closure(Matter_Session_Store_find_session_by_resumption_id, /* name * 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str_weak(sessions), - /* K3 */ be_nested_str_weak(tasmota), - /* K4 */ be_nested_str_weak(log), - /* K5 */ be_nested_str_weak(format), - /* K6 */ be_nested_str_weak(MTR_X3A_X20session_X2Eresumption_id_X3D_X25s_X20vs_X20_X25s), - /* K7 */ be_nested_str_weak(resumption_id), - /* K8 */ be_const_int(3), - /* K9 */ be_nested_str_weak(shared_secret), - /* K10 */ be_nested_str_weak(MTR_X3A_X20session_X2Eshared_secret_X3D_X25s), - /* K11 */ be_nested_str_weak(update), - /* K12 */ be_const_int(1), + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(sessions), + /* K2 */ be_nested_str_weak(tasmota), + /* K3 */ be_nested_str_weak(log), + /* K4 */ be_nested_str_weak(MTR_X3A_X20session_X2Eresumption_id_X3D_X25s_X20vs_X20_X25s), + /* K5 */ be_nested_str_weak(resumption_id), + /* K6 */ be_nested_str_weak(shared_secret), + /* K7 */ be_nested_str_weak(update), + /* K8 */ be_const_int(1), }), be_str_weak(find_session_by_resumption_id), &be_const_str_solidified, - ( &(const binstruction[49]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x740E0001, // 0002 JMPT R3 #0005 - 0x4C0C0000, // 0003 LDNIL R3 - 0x80040600, // 0004 RET 1 R3 - 0x580C0001, // 0005 LDCONST R3 K1 - 0x88100102, // 0006 GETMBR R4 R0 K2 - 0x6014000C, // 0007 GETGBL R5 G12 - 0x5C180800, // 0008 MOVE R6 R4 - 0x7C140200, // 0009 CALL R5 1 - 0x14140605, // 000A LT R5 R3 R5 - 0x78160023, // 000B JMPF R5 #0030 - 0x94140803, // 000C GETIDX R5 R4 R3 - 0xB81A0600, // 000D GETNGBL R6 K3 - 0x8C180D04, // 000E GETMET R6 R6 K4 - 0x8C200505, // 000F GETMET R8 R2 K5 - 0x58280006, // 0010 LDCONST R10 K6 - 0x602C0008, // 0011 GETGBL R11 G8 - 0x88300B07, // 0012 GETMBR R12 R5 K7 - 0x7C2C0200, // 0013 CALL R11 1 - 0x60300008, // 0014 GETGBL R12 G8 - 0x5C340200, // 0015 MOVE R13 R1 - 0x7C300200, // 0016 CALL R12 1 - 0x7C200800, // 0017 CALL R8 4 - 0x58240008, // 0018 LDCONST R9 K8 - 0x7C180600, // 0019 CALL R6 3 - 0x88180B07, // 001A GETMBR R6 R5 K7 - 0x1C180C01, // 001B EQ R6 R6 R1 - 0x781A0010, // 001C JMPF R6 #002E - 0x88180B09, // 001D GETMBR R6 R5 K9 - 0x4C1C0000, // 001E LDNIL R7 - 0x20180C07, // 001F NE R6 R6 R7 - 0x781A000C, // 0020 JMPF R6 #002E - 0xB81A0600, // 0021 GETNGBL R6 K3 - 0x8C180D04, // 0022 GETMET R6 R6 K4 - 0x8C200505, // 0023 GETMET R8 R2 K5 - 0x5828000A, // 0024 LDCONST R10 K10 - 0x602C0008, // 0025 GETGBL R11 G8 - 0x88300B09, // 0026 GETMBR R12 R5 K9 - 0x7C2C0200, // 0027 CALL R11 1 - 0x7C200600, // 0028 CALL R8 3 - 0x58240008, // 0029 LDCONST R9 K8 - 0x7C180600, // 002A CALL R6 3 - 0x8C180B0B, // 002B GETMET R6 R5 K11 - 0x7C180200, // 002C CALL R6 1 - 0x80040A00, // 002D RET 1 R5 - 0x000C070C, // 002E ADD R3 R3 K12 - 0x7001FFD6, // 002F JMP #0007 - 0x80000000, // 0030 RET 0 + ( &(const binstruction[38]) { /* code */ + 0x5C080200, // 0000 MOVE R2 R1 + 0x740A0001, // 0001 JMPT R2 #0004 + 0x4C080000, // 0002 LDNIL R2 + 0x80040400, // 0003 RET 1 R2 + 0x58080000, // 0004 LDCONST R2 K0 + 0x880C0101, // 0005 GETMBR R3 R0 K1 + 0x6010000C, // 0006 GETGBL R4 G12 + 0x5C140600, // 0007 MOVE R5 R3 + 0x7C100200, // 0008 CALL R4 1 + 0x14100404, // 0009 LT R4 R2 R4 + 0x78120019, // 000A JMPF R4 #0025 + 0x94100602, // 000B GETIDX R4 R3 R2 + 0xB8160400, // 000C GETNGBL R5 K2 + 0x8C140B03, // 000D GETMET R5 R5 K3 + 0x601C0018, // 000E GETGBL R7 G24 + 0x58200004, // 000F LDCONST R8 K4 + 0x60240008, // 0010 GETGBL R9 G8 + 0x88280905, // 0011 GETMBR R10 R4 K5 + 0x7C240200, // 0012 CALL R9 1 + 0x60280008, // 0013 GETGBL R10 G8 + 0x5C2C0200, // 0014 MOVE R11 R1 + 0x7C280200, // 0015 CALL R10 1 + 0x7C1C0600, // 0016 CALL R7 3 + 0x54220003, // 0017 LDINT R8 4 + 0x7C140600, // 0018 CALL R5 3 + 0x88140905, // 0019 GETMBR R5 R4 K5 + 0x1C140A01, // 001A EQ R5 R5 R1 + 0x78160006, // 001B JMPF R5 #0023 + 0x88140906, // 001C GETMBR R5 R4 K6 + 0x4C180000, // 001D LDNIL R6 + 0x20140A06, // 001E NE R5 R5 R6 + 0x78160002, // 001F JMPF R5 #0023 + 0x8C140907, // 0020 GETMET R5 R4 K7 + 0x7C140200, // 0021 CALL R5 1 + 0x80040800, // 0022 RET 1 R4 + 0x00080508, // 0023 ADD R2 R2 K8 + 0x7001FFE0, // 0024 JMP #0006 + 0x80000000, // 0025 RET 0 }) ) ); @@ -1174,7 +1156,7 @@ be_local_closure(Matter_Session_Store_find_session_by_resumption_id, /* name * ********************************************************************/ be_local_closure(Matter_Session_Store_save_fabrics, /* name */ be_nested_proto( - 14, /* nstack */ + 11, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1182,126 +1164,121 @@ be_local_closure(Matter_Session_Store_save_fabrics, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[28]) { /* constants */ + ( &(const bvalue[24]) { /* constants */ /* K0 */ be_nested_str_weak(json), /* K1 */ be_nested_str_weak(remove_expired), /* K2 */ be_const_int(0), - /* K3 */ be_nested_str_weak(fabrics), - /* K4 */ be_nested_str_weak(persistables), - /* K5 */ be_nested_str_weak(_sessions), - /* K6 */ be_const_int(1), - /* K7 */ be_nested_str_weak(stop_iteration), - /* K8 */ be_nested_str_weak(push), - /* K9 */ be_nested_str_weak(tojson), - /* K10 */ be_nested_str_weak(_X5B), - /* K11 */ be_nested_str_weak(concat), + /* K3 */ be_nested_str_weak(_FABRICS), + /* K4 */ be_nested_str_weak(w), + /* K5 */ be_nested_str_weak(write), + /* K6 */ be_nested_str_weak(_X5B), + /* K7 */ be_nested_str_weak(fabrics), + /* K8 */ be_nested_str_weak(persistables), + /* K9 */ be_nested_str_weak(_sessions), + /* K10 */ be_const_int(1), + /* K11 */ be_nested_str_weak(stop_iteration), /* K12 */ be_nested_str_weak(_X2C), - /* K13 */ be_nested_str_weak(_X5D), - /* K14 */ be_nested_str_weak(string), - /* K15 */ be_nested_str_weak(_FABRICS), - /* K16 */ be_nested_str_weak(w), - /* K17 */ be_nested_str_weak(write), - /* K18 */ be_nested_str_weak(close), - /* K19 */ be_nested_str_weak(tasmota), - /* K20 */ be_nested_str_weak(log), - /* K21 */ be_nested_str_weak(format), - /* K22 */ be_nested_str_weak(MTR_X3A_X20_X3DSaved_X20_X20_X20_X20_X20_X25i_X20fabric_X28s_X29_X20and_X20_X25i_X20session_X28s_X29), - /* K23 */ be_const_int(2), - /* K24 */ be_nested_str_weak(device), - /* K25 */ be_nested_str_weak(event_fabrics_saved), - /* K26 */ be_nested_str_weak(MTR_X3A_X20Session_Store_X3A_X3Asave_X20Exception_X3A), - /* K27 */ be_nested_str_weak(_X7C), + /* K13 */ be_nested_str_weak(tojson), + /* K14 */ be_nested_str_weak(_X5D), + /* K15 */ be_nested_str_weak(close), + /* K16 */ be_nested_str_weak(tasmota), + /* K17 */ be_nested_str_weak(log), + /* K18 */ be_nested_str_weak(MTR_X3A_X20_X3DSaved_X20_X20_X20_X20_X20_X25s_X20fabric_X28s_X29_X20and_X20_X25s_X20session_X28s_X29), + /* K19 */ be_const_int(2), + /* K20 */ be_nested_str_weak(device), + /* K21 */ be_nested_str_weak(event_fabrics_saved), + /* K22 */ be_nested_str_weak(MTR_X3A_X20Session_Store_X3A_X3Asave_X20Exception_X3A), + /* K23 */ be_nested_str_weak(_X7C), }), be_str_weak(save_fabrics), &be_const_str_solidified, - ( &(const binstruction[87]) { /* code */ + ( &(const binstruction[86]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080101, // 0001 GETMET R2 R0 K1 - 0x7C080200, // 0002 CALL R2 1 - 0x58080002, // 0003 LDCONST R2 K2 - 0x600C0012, // 0004 GETGBL R3 G18 - 0x7C0C0000, // 0005 CALL R3 0 - 0x60100010, // 0006 GETGBL R4 G16 + 0xA8020041, // 0001 EXBLK 0 #0044 + 0x8C080101, // 0002 GETMET R2 R0 K1 + 0x7C080200, // 0003 CALL R2 1 + 0x58080002, // 0004 LDCONST R2 K2 + 0x580C0002, // 0005 LDCONST R3 K2 + 0x60100011, // 0006 GETGBL R4 G17 0x88140103, // 0007 GETMBR R5 R0 K3 - 0x8C140B04, // 0008 GETMET R5 R5 K4 - 0x7C140200, // 0009 CALL R5 1 - 0x7C100200, // 000A CALL R4 1 - 0xA8020013, // 000B EXBLK 0 #0020 - 0x5C140800, // 000C MOVE R5 R4 - 0x7C140000, // 000D CALL R5 0 - 0x60180010, // 000E GETGBL R6 G16 - 0x881C0B05, // 000F GETMBR R7 R5 K5 - 0x8C1C0F04, // 0010 GETMET R7 R7 K4 - 0x7C1C0200, // 0011 CALL R7 1 - 0x7C180200, // 0012 CALL R6 1 - 0xA8020003, // 0013 EXBLK 0 #0018 - 0x5C1C0C00, // 0014 MOVE R7 R6 - 0x7C1C0000, // 0015 CALL R7 0 - 0x00080506, // 0016 ADD R2 R2 K6 - 0x7001FFFB, // 0017 JMP #0014 - 0x58180007, // 0018 LDCONST R6 K7 - 0xAC180200, // 0019 CATCH R6 1 0 - 0xB0080000, // 001A RAISE 2 R0 R0 - 0x8C180708, // 001B GETMET R6 R3 K8 - 0x8C200B09, // 001C GETMET R8 R5 K9 - 0x7C200200, // 001D CALL R8 1 - 0x7C180400, // 001E CALL R6 2 - 0x7001FFEB, // 001F JMP #000C - 0x58100007, // 0020 LDCONST R4 K7 - 0xAC100200, // 0021 CATCH R4 1 0 - 0xB0080000, // 0022 RAISE 2 R0 R0 - 0x6010000C, // 0023 GETGBL R4 G12 - 0x5C140600, // 0024 MOVE R5 R3 - 0x7C100200, // 0025 CALL R4 1 - 0x8C14070B, // 0026 GETMET R5 R3 K11 - 0x581C000C, // 0027 LDCONST R7 K12 - 0x7C140400, // 0028 CALL R5 2 - 0x00161405, // 0029 ADD R5 K10 R5 - 0x00140B0D, // 002A ADD R5 R5 K13 - 0x5C0C0A00, // 002B MOVE R3 R5 - 0xA8020017, // 002C EXBLK 0 #0045 - 0xA4161C00, // 002D IMPORT R5 K14 - 0x60180011, // 002E GETGBL R6 G17 - 0x881C010F, // 002F GETMBR R7 R0 K15 - 0x58200010, // 0030 LDCONST R8 K16 - 0x7C180400, // 0031 CALL R6 2 - 0x8C1C0D11, // 0032 GETMET R7 R6 K17 - 0x5C240600, // 0033 MOVE R9 R3 - 0x7C1C0400, // 0034 CALL R7 2 - 0x8C1C0D12, // 0035 GETMET R7 R6 K18 - 0x7C1C0200, // 0036 CALL R7 1 - 0xB81E2600, // 0037 GETNGBL R7 K19 - 0x8C1C0F14, // 0038 GETMET R7 R7 K20 - 0x8C240B15, // 0039 GETMET R9 R5 K21 - 0x582C0016, // 003A LDCONST R11 K22 - 0x5C300800, // 003B MOVE R12 R4 - 0x5C340400, // 003C MOVE R13 R2 - 0x7C240800, // 003D CALL R9 4 - 0x58280017, // 003E LDCONST R10 K23 - 0x7C1C0600, // 003F CALL R7 3 - 0x881C0118, // 0040 GETMBR R7 R0 K24 - 0x8C1C0F19, // 0041 GETMET R7 R7 K25 - 0x7C1C0200, // 0042 CALL R7 1 - 0xA8040001, // 0043 EXBLK 1 1 - 0x70020010, // 0044 JMP #0056 - 0xAC140002, // 0045 CATCH R5 0 2 - 0x7002000D, // 0046 JMP #0055 - 0xB81E2600, // 0047 GETNGBL R7 K19 - 0x8C1C0F14, // 0048 GETMET R7 R7 K20 - 0x60240008, // 0049 GETGBL R9 G8 - 0x5C280A00, // 004A MOVE R10 R5 - 0x7C240200, // 004B CALL R9 1 - 0x00263409, // 004C ADD R9 K26 R9 - 0x0024131B, // 004D ADD R9 R9 K27 - 0x60280008, // 004E GETGBL R10 G8 - 0x5C2C0C00, // 004F MOVE R11 R6 - 0x7C280200, // 0050 CALL R10 1 - 0x0024120A, // 0051 ADD R9 R9 R10 - 0x58280017, // 0052 LDCONST R10 K23 - 0x7C1C0600, // 0053 CALL R7 3 - 0x70020000, // 0054 JMP #0056 - 0xB0080000, // 0055 RAISE 2 R0 R0 - 0x80000000, // 0056 RET 0 + 0x58180004, // 0008 LDCONST R6 K4 + 0x7C100400, // 0009 CALL R4 2 + 0x8C140905, // 000A GETMET R5 R4 K5 + 0x581C0006, // 000B LDCONST R7 K6 + 0x7C140400, // 000C CALL R5 2 + 0x60140010, // 000D GETGBL R5 G16 + 0x88180107, // 000E GETMBR R6 R0 K7 + 0x8C180D08, // 000F GETMET R6 R6 K8 + 0x7C180200, // 0010 CALL R6 1 + 0x7C140200, // 0011 CALL R5 1 + 0xA802001A, // 0012 EXBLK 0 #002E + 0x5C180A00, // 0013 MOVE R6 R5 + 0x7C180000, // 0014 CALL R6 0 + 0x601C0010, // 0015 GETGBL R7 G16 + 0x88200D09, // 0016 GETMBR R8 R6 K9 + 0x8C201108, // 0017 GETMET R8 R8 K8 + 0x7C200200, // 0018 CALL R8 1 + 0x7C1C0200, // 0019 CALL R7 1 + 0xA8020003, // 001A EXBLK 0 #001F + 0x5C200E00, // 001B MOVE R8 R7 + 0x7C200000, // 001C CALL R8 0 + 0x0008050A, // 001D ADD R2 R2 K10 + 0x7001FFFB, // 001E JMP #001B + 0x581C000B, // 001F LDCONST R7 K11 + 0xAC1C0200, // 0020 CATCH R7 1 0 + 0xB0080000, // 0021 RAISE 2 R0 R0 + 0x241C0702, // 0022 GT R7 R3 K2 + 0x781E0002, // 0023 JMPF R7 #0027 + 0x8C1C0905, // 0024 GETMET R7 R4 K5 + 0x5824000C, // 0025 LDCONST R9 K12 + 0x7C1C0400, // 0026 CALL R7 2 + 0x8C1C0D0D, // 0027 GETMET R7 R6 K13 + 0x7C1C0200, // 0028 CALL R7 1 + 0x8C200905, // 0029 GETMET R8 R4 K5 + 0x5C280E00, // 002A MOVE R10 R7 + 0x7C200400, // 002B CALL R8 2 + 0x000C070A, // 002C ADD R3 R3 K10 + 0x7001FFE4, // 002D JMP #0013 + 0x5814000B, // 002E LDCONST R5 K11 + 0xAC140200, // 002F CATCH R5 1 0 + 0xB0080000, // 0030 RAISE 2 R0 R0 + 0x8C140905, // 0031 GETMET R5 R4 K5 + 0x581C000E, // 0032 LDCONST R7 K14 + 0x7C140400, // 0033 CALL R5 2 + 0x8C14090F, // 0034 GETMET R5 R4 K15 + 0x7C140200, // 0035 CALL R5 1 + 0xB8162000, // 0036 GETNGBL R5 K16 + 0x8C140B11, // 0037 GETMET R5 R5 K17 + 0x601C0018, // 0038 GETGBL R7 G24 + 0x58200012, // 0039 LDCONST R8 K18 + 0x5C240600, // 003A MOVE R9 R3 + 0x5C280400, // 003B MOVE R10 R2 + 0x7C1C0600, // 003C CALL R7 3 + 0x58200013, // 003D LDCONST R8 K19 + 0x7C140600, // 003E CALL R5 3 + 0x88140114, // 003F GETMBR R5 R0 K20 + 0x8C140B15, // 0040 GETMET R5 R5 K21 + 0x7C140200, // 0041 CALL R5 1 + 0xA8040001, // 0042 EXBLK 1 1 + 0x70020010, // 0043 JMP #0055 + 0xAC080002, // 0044 CATCH R2 0 2 + 0x7002000D, // 0045 JMP #0054 + 0xB8122000, // 0046 GETNGBL R4 K16 + 0x8C100911, // 0047 GETMET R4 R4 K17 + 0x60180008, // 0048 GETGBL R6 G8 + 0x5C1C0400, // 0049 MOVE R7 R2 + 0x7C180200, // 004A CALL R6 1 + 0x001A2C06, // 004B ADD R6 K22 R6 + 0x00180D17, // 004C ADD R6 R6 K23 + 0x601C0008, // 004D GETGBL R7 G8 + 0x5C200600, // 004E MOVE R8 R3 + 0x7C1C0200, // 004F CALL R7 1 + 0x00180C07, // 0050 ADD R6 R6 R7 + 0x581C0013, // 0051 LDCONST R7 K19 + 0x7C100600, // 0052 CALL R4 3 + 0x70020000, // 0053 JMP #0055 + 0xB0080000, // 0054 RAISE 2 R0 R0 + 0x80000000, // 0055 RET 0 }) ) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_TCP_async.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_TCP_async.h new file mode 100644 index 000000000000..aa854e2c7383 --- /dev/null +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_TCP_async.h @@ -0,0 +1,897 @@ +/* Solidification of Matter_TCP_async.h */ +/********************************************************************\ +* Generated code, don't edit * +\********************************************************************/ +#include "be_constobj.h" + +extern const bclass be_class_Matter_TCP_async; + +/******************************************************************** +** Solidified function: read +********************************************************************/ +be_local_closure(Matter_TCP_async_read, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(tcp_connected), + /* K1 */ be_nested_str_weak(tcp), + /* K2 */ be_nested_str_weak(read), + }), + be_str_weak(read), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x78060003, // 0001 JMPF R1 #0006 + 0x88040101, // 0002 GETMBR R1 R0 K1 + 0x8C040302, // 0003 GETMET R1 R1 K2 + 0x7C040200, // 0004 CALL R1 1 + 0x80040200, // 0005 RET 1 R1 + 0x4C040000, // 0006 LDNIL R1 + 0x80040200, // 0007 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: begin +********************************************************************/ +be_local_closure(Matter_TCP_async_begin, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[23]) { /* constants */ + /* K0 */ be_nested_str_weak(reset), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(wifi), + /* K3 */ be_nested_str_weak(up), + /* K4 */ be_nested_str_weak(eth), + /* K5 */ be_nested_str_weak(time_start), + /* K6 */ be_nested_str_weak(millis), + /* K7 */ be_nested_str_weak(status), + /* K8 */ be_const_int(0), + /* K9 */ be_nested_str_weak(tcp), + /* K10 */ be_nested_str_weak(connect), + /* K11 */ be_nested_str_weak(addr), + /* K12 */ be_nested_str_weak(port), + /* K13 */ be_nested_str_weak(fast_loop), + /* K14 */ be_nested_str_weak(remove_fast_loop), + /* K15 */ be_nested_str_weak(add_fast_loop), + /* K16 */ be_nested_str_weak(add_driver), + /* K17 */ be_nested_str_weak(log), + /* K18 */ be_nested_str_weak(BRY_X3A_X20failed_X20to_X20resolve_X20_X5B_X25s_X5D_X3A_X25i), + /* K19 */ be_const_int(3), + /* K20 */ be_nested_str_weak(close), + /* K21 */ be_nested_str_weak(tcp_connected), + /* K22 */ be_nested_str_weak(event_dnsfailed), + }), + be_str_weak(begin), + &be_const_str_solidified, + ( &(const binstruction[63]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0xB8060200, // 0002 GETNGBL R1 K1 + 0x8C040302, // 0003 GETMET R1 R1 K2 + 0x7C040200, // 0004 CALL R1 1 + 0x94040303, // 0005 GETIDX R1 R1 K3 + 0x74060006, // 0006 JMPT R1 #000E + 0xB8060200, // 0007 GETNGBL R1 K1 + 0x8C040304, // 0008 GETMET R1 R1 K4 + 0x7C040200, // 0009 CALL R1 1 + 0x94040303, // 000A GETIDX R1 R1 K3 + 0x74060001, // 000B JMPT R1 #000E + 0x4C040000, // 000C LDNIL R1 + 0x80040200, // 000D RET 1 R1 + 0xB8060200, // 000E GETNGBL R1 K1 + 0x8C040306, // 000F GETMET R1 R1 K6 + 0x7C040200, // 0010 CALL R1 1 + 0x90020A01, // 0011 SETMBR R0 K5 R1 + 0x90020F08, // 0012 SETMBR R0 K7 K8 + 0x88040109, // 0013 GETMBR R1 R0 K9 + 0x8C04030A, // 0014 GETMET R1 R1 K10 + 0x880C010B, // 0015 GETMBR R3 R0 K11 + 0x8810010C, // 0016 GETMBR R4 R0 K12 + 0x7C040600, // 0017 CALL R1 3 + 0x78060011, // 0018 JMPF R1 #002B + 0x8804010D, // 0019 GETMBR R1 R0 K13 + 0x78060008, // 001A JMPF R1 #0024 + 0xB8060200, // 001B GETNGBL R1 K1 + 0x8C04030E, // 001C GETMET R1 R1 K14 + 0x880C010D, // 001D GETMBR R3 R0 K13 + 0x7C040400, // 001E CALL R1 2 + 0xB8060200, // 001F GETNGBL R1 K1 + 0x8C04030F, // 0020 GETMET R1 R1 K15 + 0x880C010D, // 0021 GETMBR R3 R0 K13 + 0x7C040400, // 0022 CALL R1 2 + 0x70020003, // 0023 JMP #0028 + 0xB8060200, // 0024 GETNGBL R1 K1 + 0x8C040310, // 0025 GETMET R1 R1 K16 + 0x5C0C0000, // 0026 MOVE R3 R0 + 0x7C040400, // 0027 CALL R1 2 + 0x50040200, // 0028 LDBOOL R1 1 0 + 0x80040200, // 0029 RET 1 R1 + 0x70020012, // 002A JMP #003E + 0xB8060200, // 002B GETNGBL R1 K1 + 0x8C040311, // 002C GETMET R1 R1 K17 + 0x600C0018, // 002D GETGBL R3 G24 + 0x58100012, // 002E LDCONST R4 K18 + 0x8814010B, // 002F GETMBR R5 R0 K11 + 0x8818010C, // 0030 GETMBR R6 R0 K12 + 0x7C0C0600, // 0031 CALL R3 3 + 0x58100013, // 0032 LDCONST R4 K19 + 0x7C040600, // 0033 CALL R1 3 + 0x8C040114, // 0034 GETMET R1 R0 K20 + 0x7C040200, // 0035 CALL R1 1 + 0x5405FFFE, // 0036 LDINT R1 -1 + 0x90020E01, // 0037 SETMBR R0 K7 R1 + 0x50040000, // 0038 LDBOOL R1 0 0 + 0x90022A01, // 0039 SETMBR R0 K21 R1 + 0x8C040116, // 003A GETMET R1 R0 K22 + 0x7C040200, // 003B CALL R1 1 + 0x50040000, // 003C LDBOOL R1 0 0 + 0x80040200, // 003D RET 1 R1 + 0x80000000, // 003E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: readbytes +********************************************************************/ +be_local_closure(Matter_TCP_async_readbytes, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(tcp_connected), + /* K1 */ be_nested_str_weak(tcp), + /* K2 */ be_nested_str_weak(readbytes), + }), + be_str_weak(readbytes), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x78060003, // 0001 JMPF R1 #0006 + 0x88040101, // 0002 GETMBR R1 R0 K1 + 0x8C040302, // 0003 GETMET R1 R1 K2 + 0x7C040200, // 0004 CALL R1 1 + 0x80040200, // 0005 RET 1 R1 + 0x4C040000, // 0006 LDNIL R1 + 0x80040200, // 0007 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_closed +********************************************************************/ +be_local_closure(Matter_TCP_async_event_closed, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(event_closed), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: available +********************************************************************/ +be_local_closure(Matter_TCP_async_available, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(tcp_connected), + /* K1 */ be_nested_str_weak(tcp), + /* K2 */ be_nested_str_weak(available), + /* K3 */ be_const_int(0), + }), + be_str_weak(available), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x78060003, // 0001 JMPF R1 #0006 + 0x88040101, // 0002 GETMBR R1 R0 K1 + 0x8C040302, // 0003 GETMET R1 R1 K2 + 0x7C040200, // 0004 CALL R1 1 + 0x80040200, // 0005 RET 1 R1 + 0x80060600, // 0006 RET 1 K3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_listening +********************************************************************/ +be_local_closure(Matter_TCP_async_event_listening, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(event_listening), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_timeout +********************************************************************/ +be_local_closure(Matter_TCP_async_get_timeout, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(timeout), + }), + be_str_weak(get_timeout), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_TCP_async_init, /* name */ + be_nested_proto( + 7, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 2, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(loop), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x7C000200, // 0002 CALL R0 1 + 0x80040000, // 0003 RET 1 R0 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(TIMEOUT), + /* K1 */ be_nested_str_weak(addr), + /* K2 */ be_nested_str_weak(port), + /* K3 */ be_nested_str_weak(timeout), + /* K4 */ be_nested_str_weak(tcp), + /* K5 */ be_nested_str_weak(tcpclientasync), + /* K6 */ be_nested_str_weak(fast_loop), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[25]) { /* code */ + 0x4C140000, // 0000 LDNIL R5 + 0x1C140605, // 0001 EQ R5 R3 R5 + 0x78160000, // 0002 JMPF R5 #0004 + 0x880C0100, // 0003 GETMBR R3 R0 K0 + 0x4C140000, // 0004 LDNIL R5 + 0x1C140405, // 0005 EQ R5 R2 R5 + 0x78160000, // 0006 JMPF R5 #0008 + 0x540A004F, // 0007 LDINT R2 80 + 0x60140008, // 0008 GETGBL R5 G8 + 0x5C180200, // 0009 MOVE R6 R1 + 0x7C140200, // 000A CALL R5 1 + 0x90020205, // 000B SETMBR R0 K1 R5 + 0x60140009, // 000C GETGBL R5 G9 + 0x5C180400, // 000D MOVE R6 R2 + 0x7C140200, // 000E CALL R5 1 + 0x90020405, // 000F SETMBR R0 K2 R5 + 0x90020603, // 0010 SETMBR R0 K3 R3 + 0xB8160A00, // 0011 GETNGBL R5 K5 + 0x7C140000, // 0012 CALL R5 0 + 0x90020805, // 0013 SETMBR R0 K4 R5 + 0x78120001, // 0014 JMPF R4 #0017 + 0x84140000, // 0015 CLOSURE R5 P0 + 0x90020C05, // 0016 SETMBR R0 K6 R5 + 0xA0000000, // 0017 CLOSE R0 + 0x80000000, // 0018 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: every_50ms +********************************************************************/ +be_local_closure(Matter_TCP_async_every_50ms, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(loop), + }), + be_str_weak(every_50ms), + &be_const_str_solidified, + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80000000, // 0002 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_timeout +********************************************************************/ +be_local_closure(Matter_TCP_async_event_timeout, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(event_timeout), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_available +********************************************************************/ +be_local_closure(Matter_TCP_async_event_available, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(event_available), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: write +********************************************************************/ +be_local_closure(Matter_TCP_async_write, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(tcp_connected), + /* K1 */ be_nested_str_weak(tcp), + /* K2 */ be_nested_str_weak(write), + /* K3 */ be_const_int(0), + }), + be_str_weak(write), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A0004, // 0001 JMPF R2 #0007 + 0x88080101, // 0002 GETMBR R2 R0 K1 + 0x8C080502, // 0003 GETMET R2 R2 K2 + 0x5C100200, // 0004 MOVE R4 R1 + 0x7C080400, // 0005 CALL R2 2 + 0x80040400, // 0006 RET 1 R2 + 0x80060600, // 0007 RET 1 K3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_established +********************************************************************/ +be_local_closure(Matter_TCP_async_event_established, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(event_established), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: reset +********************************************************************/ +be_local_closure(Matter_TCP_async_reset, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(tcp), + /* K1 */ be_nested_str_weak(close), + /* K2 */ be_nested_str_weak(tcp_connected), + }), + be_str_weak(reset), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x4C040000, // 0003 LDNIL R1 + 0x90020401, // 0004 SETMBR R0 K2 R1 + 0x80000000, // 0005 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: loop +********************************************************************/ +be_local_closure(Matter_TCP_async_loop, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[18]) { /* constants */ + /* K0 */ be_nested_str_weak(tcp_connected), + /* K1 */ be_nested_str_weak(status), + /* K2 */ be_nested_str_weak(close), + /* K3 */ be_nested_str_weak(tcp), + /* K4 */ be_nested_str_weak(connected), + /* K5 */ be_const_int(1), + /* K6 */ be_nested_str_weak(event_established), + /* K7 */ be_nested_str_weak(event_refused), + /* K8 */ be_nested_str_weak(tasmota), + /* K9 */ be_nested_str_weak(millis), + /* K10 */ be_nested_str_weak(time_start), + /* K11 */ be_nested_str_weak(timeout), + /* K12 */ be_nested_str_weak(event_timeout), + /* K13 */ be_nested_str_weak(event_closed), + /* K14 */ be_nested_str_weak(available), + /* K15 */ be_nested_str_weak(event_available), + /* K16 */ be_nested_str_weak(listening), + /* K17 */ be_nested_str_weak(event_listening), + }), + be_str_weak(loop), + &be_const_str_solidified, + ( &(const binstruction[89]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x88080101, // 0001 GETMBR R2 R0 K1 + 0x4C0C0000, // 0002 LDNIL R3 + 0x1C080403, // 0003 EQ R2 R2 R3 + 0x780A0002, // 0004 JMPF R2 #0008 + 0x8C080102, // 0005 GETMET R2 R0 K2 + 0x7C080200, // 0006 CALL R2 1 + 0x80000400, // 0007 RET 0 + 0x88080103, // 0008 GETMBR R2 R0 K3 + 0x8C080504, // 0009 GETMET R2 R2 K4 + 0x7C080200, // 000A CALL R2 1 + 0x90020002, // 000B SETMBR R0 K0 R2 + 0x4C080000, // 000C LDNIL R2 + 0x1C080202, // 000D EQ R2 R1 R2 + 0x780A0021, // 000E JMPF R2 #0031 + 0x88080100, // 000F GETMBR R2 R0 K0 + 0x500C0200, // 0010 LDBOOL R3 1 0 + 0x1C080403, // 0011 EQ R2 R2 R3 + 0x780A0003, // 0012 JMPF R2 #0017 + 0x90020305, // 0013 SETMBR R0 K1 K5 + 0x8C080106, // 0014 GETMET R2 R0 K6 + 0x7C080200, // 0015 CALL R2 1 + 0x70020019, // 0016 JMP #0031 + 0x88080100, // 0017 GETMBR R2 R0 K0 + 0x500C0000, // 0018 LDBOOL R3 0 0 + 0x1C080403, // 0019 EQ R2 R2 R3 + 0x780A0007, // 001A JMPF R2 #0023 + 0x5409FFFD, // 001B LDINT R2 -2 + 0x90020202, // 001C SETMBR R0 K1 R2 + 0x8C080107, // 001D GETMET R2 R0 K7 + 0x7C080200, // 001E CALL R2 1 + 0x8C080102, // 001F GETMET R2 R0 K2 + 0x7C080200, // 0020 CALL R2 1 + 0x80000400, // 0021 RET 0 + 0x7002000D, // 0022 JMP #0031 + 0xB80A1000, // 0023 GETNGBL R2 K8 + 0x8C080509, // 0024 GETMET R2 R2 K9 + 0x7C080200, // 0025 CALL R2 1 + 0x880C010A, // 0026 GETMBR R3 R0 K10 + 0x04080403, // 0027 SUB R2 R2 R3 + 0x880C010B, // 0028 GETMBR R3 R0 K11 + 0x24080403, // 0029 GT R2 R2 R3 + 0x780A0005, // 002A JMPF R2 #0031 + 0x5409FFFC, // 002B LDINT R2 -3 + 0x90020202, // 002C SETMBR R0 K1 R2 + 0x50080000, // 002D LDBOOL R2 0 0 + 0x90020002, // 002E SETMBR R0 K0 R2 + 0x8C08010C, // 002F GETMET R2 R0 K12 + 0x7C080200, // 0030 CALL R2 1 + 0xB80A1000, // 0031 GETNGBL R2 K8 + 0x8C080509, // 0032 GETMET R2 R2 K9 + 0x7C080200, // 0033 CALL R2 1 + 0x880C010A, // 0034 GETMBR R3 R0 K10 + 0x04080403, // 0035 SUB R2 R2 R3 + 0x880C010B, // 0036 GETMBR R3 R0 K11 + 0x24080403, // 0037 GT R2 R2 R3 + 0x780A0006, // 0038 JMPF R2 #0040 + 0x8C080102, // 0039 GETMET R2 R0 K2 + 0x7C080200, // 003A CALL R2 1 + 0x5409FFFC, // 003B LDINT R2 -3 + 0x90020202, // 003C SETMBR R0 K1 R2 + 0x8C08010C, // 003D GETMET R2 R0 K12 + 0x7C080200, // 003E CALL R2 1 + 0x80000400, // 003F RET 0 + 0x88080100, // 0040 GETMBR R2 R0 K0 + 0x500C0000, // 0041 LDBOOL R3 0 0 + 0x1C080403, // 0042 EQ R2 R2 R3 + 0x780A0007, // 0043 JMPF R2 #004C + 0x50080200, // 0044 LDBOOL R2 1 0 + 0x1C080202, // 0045 EQ R2 R1 R2 + 0x780A0001, // 0046 JMPF R2 #0049 + 0x8C08010D, // 0047 GETMET R2 R0 K13 + 0x7C080200, // 0048 CALL R2 1 + 0x8C080102, // 0049 GETMET R2 R0 K2 + 0x7C080200, // 004A CALL R2 1 + 0x80000400, // 004B RET 0 + 0x88080103, // 004C GETMBR R2 R0 K3 + 0x8C08050E, // 004D GETMET R2 R2 K14 + 0x7C080200, // 004E CALL R2 1 + 0x780A0001, // 004F JMPF R2 #0052 + 0x8C08010F, // 0050 GETMET R2 R0 K15 + 0x7C080200, // 0051 CALL R2 1 + 0x88080103, // 0052 GETMBR R2 R0 K3 + 0x8C080510, // 0053 GETMET R2 R2 K16 + 0x7C080200, // 0054 CALL R2 1 + 0x780A0001, // 0055 JMPF R2 #0058 + 0x8C080111, // 0056 GETMET R2 R0 K17 + 0x7C080200, // 0057 CALL R2 1 + 0x80000000, // 0058 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: listening +********************************************************************/ +be_local_closure(Matter_TCP_async_listening, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(tcp_connected), + /* K1 */ be_nested_str_weak(tcp), + /* K2 */ be_nested_str_weak(listening), + }), + be_str_weak(listening), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x78060003, // 0001 JMPF R1 #0006 + 0x88040101, // 0002 GETMBR R1 R0 K1 + 0x8C040302, // 0003 GETMET R1 R1 K2 + 0x7C040200, // 0004 CALL R1 1 + 0x80040200, // 0005 RET 1 R1 + 0x50040000, // 0006 LDBOOL R1 0 0 + 0x80040200, // 0007 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_timeout +********************************************************************/ +be_local_closure(Matter_TCP_async_set_timeout, /* name */ + be_nested_proto( + 3, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(TIMEOUT), + /* K1 */ be_nested_str_weak(timeout), + }), + be_str_weak(set_timeout), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x1C080202, // 0001 EQ R2 R1 R2 + 0x780A0000, // 0002 JMPF R2 #0004 + 0x88040100, // 0003 GETMBR R1 R0 K0 + 0x90020201, // 0004 SETMBR R0 K1 R1 + 0x80000000, // 0005 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_dnsfailed +********************************************************************/ +be_local_closure(Matter_TCP_async_event_dnsfailed, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(event_dnsfailed), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: close +********************************************************************/ +be_local_closure(Matter_TCP_async_close, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(tcp), + /* K1 */ be_nested_str_weak(close), + /* K2 */ be_nested_str_weak(fast_loop), + /* K3 */ be_nested_str_weak(tasmota), + /* K4 */ be_nested_str_weak(remove_fast_loop), + /* K5 */ be_nested_str_weak(remove_driver), + /* K6 */ be_nested_str_weak(tcp_connected), + /* K7 */ be_nested_str_weak(event_closed), + }), + be_str_weak(close), + &be_const_str_solidified, + ( &(const binstruction[23]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x88040102, // 0003 GETMBR R1 R0 K2 + 0x78060004, // 0004 JMPF R1 #000A + 0xB8060600, // 0005 GETNGBL R1 K3 + 0x8C040304, // 0006 GETMET R1 R1 K4 + 0x880C0102, // 0007 GETMBR R3 R0 K2 + 0x7C040400, // 0008 CALL R1 2 + 0x70020003, // 0009 JMP #000E + 0xB8060600, // 000A GETNGBL R1 K3 + 0x8C040305, // 000B GETMET R1 R1 K5 + 0x5C0C0000, // 000C MOVE R3 R0 + 0x7C040400, // 000D CALL R1 2 + 0x88040106, // 000E GETMBR R1 R0 K6 + 0x50080200, // 000F LDBOOL R2 1 0 + 0x1C040202, // 0010 EQ R1 R1 R2 + 0x78060001, // 0011 JMPF R1 #0014 + 0x8C040107, // 0012 GETMET R1 R0 K7 + 0x7C040200, // 0013 CALL R1 1 + 0x50040000, // 0014 LDBOOL R1 0 0 + 0x90020C01, // 0015 SETMBR R0 K6 R1 + 0x80000000, // 0016 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event_refused +********************************************************************/ +be_local_closure(Matter_TCP_async_event_refused, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(event_refused), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Matter_TCP_async +********************************************************************/ +be_local_class(Matter_TCP_async, + 8, + NULL, + be_nested_map(29, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(read, 13), be_const_closure(Matter_TCP_async_read_closure) }, + { be_const_key_weak(addr, -1), be_const_var(0) }, + { be_const_key_weak(event_refused, -1), be_const_closure(Matter_TCP_async_event_refused_closure) }, + { be_const_key_weak(begin, -1), be_const_closure(Matter_TCP_async_begin_closure) }, + { be_const_key_weak(readbytes, -1), be_const_closure(Matter_TCP_async_readbytes_closure) }, + { be_const_key_weak(event_closed, 11), be_const_closure(Matter_TCP_async_event_closed_closure) }, + { be_const_key_weak(event_listening, -1), be_const_closure(Matter_TCP_async_event_listening_closure) }, + { be_const_key_weak(tcp_connected, -1), be_const_var(5) }, + { be_const_key_weak(get_timeout, -1), be_const_closure(Matter_TCP_async_get_timeout_closure) }, + { be_const_key_weak(timeout, 18), be_const_var(2) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_TCP_async_init_closure) }, + { be_const_key_weak(event_timeout, 6), be_const_closure(Matter_TCP_async_event_timeout_closure) }, + { be_const_key_weak(set_timeout, -1), be_const_closure(Matter_TCP_async_set_timeout_closure) }, + { be_const_key_weak(listening, 23), be_const_closure(Matter_TCP_async_listening_closure) }, + { be_const_key_weak(tcp, -1), be_const_var(3) }, + { be_const_key_weak(event_available, -1), be_const_closure(Matter_TCP_async_event_available_closure) }, + { be_const_key_weak(write, -1), be_const_closure(Matter_TCP_async_write_closure) }, + { be_const_key_weak(event_established, -1), be_const_closure(Matter_TCP_async_event_established_closure) }, + { be_const_key_weak(TIMEOUT, 7), be_const_int(1000) }, + { be_const_key_weak(time_start, 22), be_const_var(4) }, + { be_const_key_weak(reset, -1), be_const_closure(Matter_TCP_async_reset_closure) }, + { be_const_key_weak(loop, -1), be_const_closure(Matter_TCP_async_loop_closure) }, + { be_const_key_weak(status, -1), be_const_var(6) }, + { be_const_key_weak(port, -1), be_const_var(1) }, + { be_const_key_weak(every_50ms, 12), be_const_closure(Matter_TCP_async_every_50ms_closure) }, + { be_const_key_weak(fast_loop, -1), be_const_var(7) }, + { be_const_key_weak(event_dnsfailed, -1), be_const_closure(Matter_TCP_async_event_dnsfailed_closure) }, + { be_const_key_weak(close, -1), be_const_closure(Matter_TCP_async_close_closure) }, + { be_const_key_weak(available, 2), be_const_closure(Matter_TCP_async_available_closure) }, + })), + be_str_weak(Matter_TCP_async) +); +/*******************************************************************/ + +void be_load_Matter_TCP_async_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_TCP_async); + be_setglobal(vm, "Matter_TCP_async"); + be_pop(vm, 1); +} +/********************************************************************/ +/* End of solidification */ diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_TLV.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_TLV.h index b1e3292f39cd..c829d034672d 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_TLV.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_TLV.h @@ -6,6 +6,30 @@ extern const bclass be_class_Matter_TLV_item; +/******************************************************************** +** Solidified function: to_TLV +********************************************************************/ +be_local_closure(Matter_TLV_item_to_TLV, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(to_TLV), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80040000, // 0000 RET 1 R0 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: set_parent ********************************************************************/ @@ -34,39 +58,42 @@ be_local_closure(Matter_TLV_item_set_parent, /* name */ /******************************************************************** -** Solidified function: create_TLV +** Solidified function: set_fulltag ********************************************************************/ -be_local_closure(Matter_TLV_item_create_TLV, /* name */ +be_local_closure(Matter_TLV_item_set_fulltag, /* name */ be_nested_proto( - 4, /* nstack */ - 2, /* argc */ - 4, /* varg */ + 6, /* nstack */ + 4, /* argc */ + 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_const_class(be_class_Matter_TLV_item), - /* K1 */ be_nested_str_weak(typ), - /* K2 */ be_nested_str_weak(val), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(tag_vendor), + /* K1 */ be_nested_str_weak(tag_profile), + /* K2 */ be_nested_str_weak(tag_number), + /* K3 */ be_nested_str_weak(tag_sub), }), - be_str_weak(create_TLV), + be_str_weak(set_fulltag), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x58080000, // 0000 LDCONST R2 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x200C0203, // 0002 NE R3 R1 R3 - 0x740E0002, // 0003 JMPT R3 #0007 - 0x540E0013, // 0004 LDINT R3 20 - 0x1C0C0003, // 0005 EQ R3 R0 R3 - 0x780E0004, // 0006 JMPF R3 #000C - 0x5C0C0400, // 0007 MOVE R3 R2 - 0x7C0C0000, // 0008 CALL R3 0 - 0x900E0200, // 0009 SETMBR R3 K1 R0 - 0x900E0401, // 000A SETMBR R3 K2 R1 - 0x80040600, // 000B RET 1 R3 - 0x80000000, // 000C RET 0 + ( &(const binstruction[15]) { /* code */ + 0x60100009, // 0000 GETGBL R4 G9 + 0x5C140200, // 0001 MOVE R5 R1 + 0x7C100200, // 0002 CALL R4 1 + 0x90020004, // 0003 SETMBR R0 K0 R4 + 0x60100009, // 0004 GETGBL R4 G9 + 0x5C140400, // 0005 MOVE R5 R2 + 0x7C100200, // 0006 CALL R4 1 + 0x90020204, // 0007 SETMBR R0 K1 R4 + 0x60100009, // 0008 GETGBL R4 G9 + 0x5C140600, // 0009 MOVE R5 R3 + 0x7C100200, // 000A CALL R4 1 + 0x90020404, // 000B SETMBR R0 K2 R4 + 0x4C100000, // 000C LDNIL R4 + 0x90020604, // 000D SETMBR R0 K3 R4 + 0x80000000, // 000E RET 0 }) ) ); @@ -74,27 +101,32 @@ be_local_closure(Matter_TLV_item_create_TLV, /* name */ /******************************************************************** -** Solidified function: set_anonymoustag +** Solidified function: set_contextspecific ********************************************************************/ -be_local_closure(Matter_TLV_item_set_anonymoustag, /* name */ +be_local_closure(Matter_TLV_item_set_contextspecific, /* name */ be_nested_proto( - 3, /* nstack */ - 1, /* argc */ + 4, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ + ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str_weak(set_fulltag), + /* K1 */ be_nested_str_weak(tag_sub), }), - be_str_weak(set_anonymoustag), + be_str_weak(set_contextspecific), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x80000000, // 0002 RET 0 + ( &(const binstruction[ 7]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x7C080200, // 0001 CALL R2 1 + 0x60080009, // 0002 GETGBL R2 G9 + 0x5C0C0200, // 0003 MOVE R3 R1 + 0x7C080200, // 0004 CALL R2 1 + 0x90020202, // 0005 SETMBR R0 K1 R2 + 0x80000000, // 0006 RET 0 }) ) ); @@ -102,30 +134,61 @@ be_local_closure(Matter_TLV_item_set_anonymoustag, /* name */ /******************************************************************** -** Solidified function: set_commonprofile +** Solidified function: sort ********************************************************************/ -be_local_closure(Matter_TLV_item_set_commonprofile, /* name */ +be_local_closure(Matter_TLV_item_sort, /* name */ be_nested_proto( - 6, /* nstack */ + 9, /* nstack */ 1, /* argc */ - 2, /* varg */ + 4, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(set_fulltag), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_const_class(be_class_Matter_TLV_item), + /* K1 */ be_const_int(1), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(_cmp_gt), + /* K4 */ be_nested_str_weak(stop_iteration), }), - be_str_weak(set_commonprofile), + be_str_weak(sort), &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x5411FFFE, // 0002 LDINT R4 -1 - 0x4C140000, // 0003 LDNIL R5 - 0x7C040800, // 0004 CALL R1 4 - 0x80000000, // 0005 RET 0 + ( &(const binstruction[33]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x60080010, // 0001 GETGBL R2 G16 + 0x600C000C, // 0002 GETGBL R3 G12 + 0x5C100000, // 0003 MOVE R4 R0 + 0x7C0C0200, // 0004 CALL R3 1 + 0x040C0701, // 0005 SUB R3 R3 K1 + 0x400E0203, // 0006 CONNECT R3 K1 R3 + 0x7C080200, // 0007 CALL R2 1 + 0xA8020013, // 0008 EXBLK 0 #001D + 0x5C0C0400, // 0009 MOVE R3 R2 + 0x7C0C0000, // 000A CALL R3 0 + 0x94100003, // 000B GETIDX R4 R0 R3 + 0x5C140600, // 000C MOVE R5 R3 + 0x24180B02, // 000D GT R6 R5 K2 + 0x781A000B, // 000E JMPF R6 #001B + 0x04180B01, // 000F SUB R6 R5 K1 + 0x94180006, // 0010 GETIDX R6 R0 R6 + 0x8C180D03, // 0011 GETMET R6 R6 K3 + 0x5C200800, // 0012 MOVE R8 R4 + 0x7C180400, // 0013 CALL R6 2 + 0x24180D02, // 0014 GT R6 R6 K2 + 0x781A0004, // 0015 JMPF R6 #001B + 0x04180B01, // 0016 SUB R6 R5 K1 + 0x94180006, // 0017 GETIDX R6 R0 R6 + 0x98000A06, // 0018 SETIDX R0 R5 R6 + 0x04140B01, // 0019 SUB R5 R5 K1 + 0x7001FFF1, // 001A JMP #000D + 0x98000A04, // 001B SETIDX R0 R5 R4 + 0x7001FFEB, // 001C JMP #0009 + 0x58080004, // 001D LDCONST R2 K4 + 0xAC080200, // 001E CATCH R2 1 0 + 0xB0080000, // 001F RAISE 2 R0 R0 + 0x80040000, // 0020 RET 1 R0 }) ) ); @@ -133,101 +196,137 @@ be_local_closure(Matter_TLV_item_set_commonprofile, /* name */ /******************************************************************** -** Solidified function: _cmp_gt +** Solidified function: to_str_val ********************************************************************/ -be_local_closure(Matter_TLV_item__cmp_gt, /* name */ +be_local_closure(Matter_TLV_item_to_str_val, /* name */ be_nested_proto( 4, /* nstack */ - 2, /* argc */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(tag_vendor), - /* K1 */ be_const_int(1), - /* K2 */ be_nested_str_weak(tag_profile), - /* K3 */ be_const_int(0), - /* K4 */ be_nested_str_weak(tag_number), - /* K5 */ be_nested_str_weak(tag_sub), + ( &(const bvalue[16]) { /* constants */ + /* K0 */ be_nested_str_weak(val), + /* K1 */ be_nested_str_weak(int), + /* K2 */ be_nested_str_weak(typ), + /* K3 */ be_nested_str_weak(TLV), + /* K4 */ be_nested_str_weak(U1), + /* K5 */ be_nested_str_weak(U8), + /* K6 */ be_nested_str_weak(U), + /* K7 */ be_nested_str_weak(bool), + /* K8 */ be_nested_str_weak(true), + /* K9 */ be_nested_str_weak(false), + /* K10 */ be_nested_str_weak(null), + /* K11 */ be_nested_str_weak(real), + /* K12 */ be_nested_str_weak(string), + /* K13 */ be_nested_str_weak(int64), + /* K14 */ be_nested_str_weak(tostring), + /* K15 */ be_nested_str_weak(instance), }), - be_str_weak(_cmp_gt), + be_str_weak(to_str_val), &be_const_str_solidified, - ( &(const binstruction[72]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x20080403, // 0002 NE R2 R2 R3 - 0x780A0012, // 0003 JMPF R2 #0017 - 0x88080300, // 0004 GETMBR R2 R1 K0 - 0x4C0C0000, // 0005 LDNIL R3 - 0x1C080403, // 0006 EQ R2 R2 R3 - 0x780A0000, // 0007 JMPF R2 #0009 - 0x80060200, // 0008 RET 1 K1 - 0x88080100, // 0009 GETMBR R2 R0 K0 - 0x880C0300, // 000A GETMBR R3 R1 K0 - 0x24080403, // 000B GT R2 R2 R3 - 0x780A0000, // 000C JMPF R2 #000E - 0x80060200, // 000D RET 1 K1 - 0x88080100, // 000E GETMBR R2 R0 K0 - 0x880C0300, // 000F GETMBR R3 R1 K0 - 0x1C080403, // 0010 EQ R2 R2 R3 - 0x780A0004, // 0011 JMPF R2 #0017 - 0x88080102, // 0012 GETMBR R2 R0 K2 - 0x880C0302, // 0013 GETMBR R3 R1 K2 - 0x24080403, // 0014 GT R2 R2 R3 - 0x780A0000, // 0015 JMPF R2 #0017 - 0x80060200, // 0016 RET 1 K1 - 0x88080102, // 0017 GETMBR R2 R0 K2 - 0x540DFFFE, // 0018 LDINT R3 -1 - 0x1C080403, // 0019 EQ R2 R2 R3 - 0x780A0005, // 001A JMPF R2 #0021 - 0x88080302, // 001B GETMBR R2 R1 K2 - 0x4C0C0000, // 001C LDNIL R3 - 0x1C080403, // 001D EQ R2 R2 R3 - 0x780A0000, // 001E JMPF R2 #0020 - 0x80060200, // 001F RET 1 K1 - 0x70020008, // 0020 JMP #002A - 0x88080102, // 0021 GETMBR R2 R0 K2 - 0x4C0C0000, // 0022 LDNIL R3 - 0x1C080403, // 0023 EQ R2 R2 R3 - 0x780A0004, // 0024 JMPF R2 #002A - 0x88080302, // 0025 GETMBR R2 R1 K2 - 0x540DFFFE, // 0026 LDINT R3 -1 - 0x1C080403, // 0027 EQ R2 R2 R3 - 0x780A0000, // 0028 JMPF R2 #002A - 0x80060600, // 0029 RET 1 K3 - 0x88080104, // 002A GETMBR R2 R0 K4 - 0x4C0C0000, // 002B LDNIL R3 - 0x20080403, // 002C NE R2 R2 R3 - 0x780A000A, // 002D JMPF R2 #0039 - 0x88080304, // 002E GETMBR R2 R1 K4 - 0x4C0C0000, // 002F LDNIL R3 - 0x1C080403, // 0030 EQ R2 R2 R3 - 0x780A0000, // 0031 JMPF R2 #0033 - 0x80060200, // 0032 RET 1 K1 - 0x88080104, // 0033 GETMBR R2 R0 K4 - 0x880C0304, // 0034 GETMBR R3 R1 K4 - 0x24080403, // 0035 GT R2 R2 R3 - 0x780A0000, // 0036 JMPF R2 #0038 - 0x80060200, // 0037 RET 1 K1 - 0x80060600, // 0038 RET 1 K3 - 0x88080105, // 0039 GETMBR R2 R0 K5 - 0x4C0C0000, // 003A LDNIL R3 - 0x20080403, // 003B NE R2 R2 R3 - 0x780A0009, // 003C JMPF R2 #0047 - 0x88080305, // 003D GETMBR R2 R1 K5 - 0x4C0C0000, // 003E LDNIL R3 - 0x1C080403, // 003F EQ R2 R2 R3 - 0x780A0000, // 0040 JMPF R2 #0042 - 0x80060200, // 0041 RET 1 K1 - 0x88080105, // 0042 GETMBR R2 R0 K5 - 0x880C0305, // 0043 GETMBR R3 R1 K5 - 0x24080403, // 0044 GT R2 R2 R3 - 0x780A0000, // 0045 JMPF R2 #0047 - 0x80060200, // 0046 RET 1 K1 - 0x80060600, // 0047 RET 1 K3 + ( &(const binstruction[98]) { /* code */ + 0x60040004, // 0000 GETGBL R1 G4 + 0x88080100, // 0001 GETMBR R2 R0 K0 + 0x7C040200, // 0002 CALL R1 1 + 0x1C040301, // 0003 EQ R1 R1 K1 + 0x78060014, // 0004 JMPF R1 #001A + 0x88040102, // 0005 GETMBR R1 R0 K2 + 0x88080103, // 0006 GETMBR R2 R0 K3 + 0x88080504, // 0007 GETMBR R2 R2 K4 + 0x28040202, // 0008 GE R1 R1 R2 + 0x7806000A, // 0009 JMPF R1 #0015 + 0x88040102, // 000A GETMBR R1 R0 K2 + 0x88080103, // 000B GETMBR R2 R0 K3 + 0x88080505, // 000C GETMBR R2 R2 K5 + 0x18040202, // 000D LE R1 R1 R2 + 0x78060005, // 000E JMPF R1 #0015 + 0x60040008, // 000F GETGBL R1 G8 + 0x88080100, // 0010 GETMBR R2 R0 K0 + 0x7C040200, // 0011 CALL R1 1 + 0x00040306, // 0012 ADD R1 R1 K6 + 0x80040200, // 0013 RET 1 R1 + 0x70020003, // 0014 JMP #0019 + 0x60040008, // 0015 GETGBL R1 G8 + 0x88080100, // 0016 GETMBR R2 R0 K0 + 0x7C040200, // 0017 CALL R1 1 + 0x80040200, // 0018 RET 1 R1 + 0x70020046, // 0019 JMP #0061 + 0x60040004, // 001A GETGBL R1 G4 + 0x88080100, // 001B GETMBR R2 R0 K0 + 0x7C040200, // 001C CALL R1 1 + 0x1C040307, // 001D EQ R1 R1 K7 + 0x78060006, // 001E JMPF R1 #0026 + 0x88040100, // 001F GETMBR R1 R0 K0 + 0x78060001, // 0020 JMPF R1 #0023 + 0x58040008, // 0021 LDCONST R1 K8 + 0x70020000, // 0022 JMP #0024 + 0x58040009, // 0023 LDCONST R1 K9 + 0x80040200, // 0024 RET 1 R1 + 0x7002003A, // 0025 JMP #0061 + 0x88040100, // 0026 GETMBR R1 R0 K0 + 0x4C080000, // 0027 LDNIL R2 + 0x1C040202, // 0028 EQ R1 R1 R2 + 0x78060001, // 0029 JMPF R1 #002C + 0x80061400, // 002A RET 1 K10 + 0x70020034, // 002B JMP #0061 + 0x60040004, // 002C GETGBL R1 G4 + 0x88080100, // 002D GETMBR R2 R0 K0 + 0x7C040200, // 002E CALL R1 1 + 0x1C04030B, // 002F EQ R1 R1 K11 + 0x78060004, // 0030 JMPF R1 #0036 + 0x60040008, // 0031 GETGBL R1 G8 + 0x88080100, // 0032 GETMBR R2 R0 K0 + 0x7C040200, // 0033 CALL R1 1 + 0x80040200, // 0034 RET 1 R1 + 0x7002002A, // 0035 JMP #0061 + 0x60040004, // 0036 GETGBL R1 G4 + 0x88080100, // 0037 GETMBR R2 R0 K0 + 0x7C040200, // 0038 CALL R1 1 + 0x1C04030C, // 0039 EQ R1 R1 K12 + 0x78060002, // 003A JMPF R1 #003E + 0x88040100, // 003B GETMBR R1 R0 K0 + 0x80040200, // 003C RET 1 R1 + 0x70020022, // 003D JMP #0061 + 0x6004000F, // 003E GETGBL R1 G15 + 0x88080100, // 003F GETMBR R2 R0 K0 + 0xB80E1A00, // 0040 GETNGBL R3 K13 + 0x7C040400, // 0041 CALL R1 2 + 0x78060014, // 0042 JMPF R1 #0058 + 0x88040102, // 0043 GETMBR R1 R0 K2 + 0x88080103, // 0044 GETMBR R2 R0 K3 + 0x88080504, // 0045 GETMBR R2 R2 K4 + 0x28040202, // 0046 GE R1 R1 R2 + 0x7806000A, // 0047 JMPF R1 #0053 + 0x88040102, // 0048 GETMBR R1 R0 K2 + 0x88080103, // 0049 GETMBR R2 R0 K3 + 0x88080505, // 004A GETMBR R2 R2 K5 + 0x18040202, // 004B LE R1 R1 R2 + 0x78060005, // 004C JMPF R1 #0053 + 0x88040100, // 004D GETMBR R1 R0 K0 + 0x8C04030E, // 004E GETMET R1 R1 K14 + 0x7C040200, // 004F CALL R1 1 + 0x00040306, // 0050 ADD R1 R1 K6 + 0x80040200, // 0051 RET 1 R1 + 0x70020003, // 0052 JMP #0057 + 0x88040100, // 0053 GETMBR R1 R0 K0 + 0x8C04030E, // 0054 GETMET R1 R1 K14 + 0x7C040200, // 0055 CALL R1 1 + 0x80040200, // 0056 RET 1 R1 + 0x70020008, // 0057 JMP #0061 + 0x60040004, // 0058 GETGBL R1 G4 + 0x88080100, // 0059 GETMBR R2 R0 K0 + 0x7C040200, // 005A CALL R1 1 + 0x1C04030F, // 005B EQ R1 R1 K15 + 0x78060003, // 005C JMPF R1 #0061 + 0x8C04010E, // 005D GETMET R1 R0 K14 + 0x500C0200, // 005E LDBOOL R3 1 0 + 0x7C040400, // 005F CALL R1 2 + 0x80040200, // 0060 RET 1 R1 + 0x80000000, // 0061 RET 0 }) ) ); @@ -235,178 +334,12 @@ be_local_closure(Matter_TLV_item__cmp_gt, /* name */ /******************************************************************** -** Solidified function: _encode_tag +** Solidified function: encode_len ********************************************************************/ -be_local_closure(Matter_TLV_item__encode_tag, /* name */ +be_local_closure(Matter_TLV_item_encode_len, /* name */ be_nested_proto( - 9, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 9]) { /* constants */ - /* K0 */ be_nested_str_weak(tag_number), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str_weak(tag_vendor), - /* K3 */ be_nested_str_weak(add), - /* K4 */ be_nested_str_weak(typ), - /* K5 */ be_const_int(1), - /* K6 */ be_const_int(2), - /* K7 */ be_nested_str_weak(tag_profile), - /* K8 */ be_nested_str_weak(tag_sub), - }), - be_str_weak(_encode_tag), - &be_const_str_solidified, - ( &(const binstruction[133]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x20080403, // 0002 NE R2 R2 R3 - 0x780A0001, // 0003 JMPF R2 #0006 - 0x88080100, // 0004 GETMBR R2 R0 K0 - 0x70020000, // 0005 JMP #0007 - 0x58080001, // 0006 LDCONST R2 K1 - 0x540EFFFF, // 0007 LDINT R3 65536 - 0x280C0403, // 0008 GE R3 R2 R3 - 0x740E0002, // 0009 JMPT R3 #000D - 0x140C0501, // 000A LT R3 R2 K1 - 0x740E0000, // 000B JMPT R3 #000D - 0x500C0001, // 000C LDBOOL R3 0 1 - 0x500C0200, // 000D LDBOOL R3 1 0 - 0x58100001, // 000E LDCONST R4 K1 - 0x88140102, // 000F GETMBR R5 R0 K2 - 0x4C180000, // 0010 LDNIL R6 - 0x20140A06, // 0011 NE R5 R5 R6 - 0x78160026, // 0012 JMPF R5 #003A - 0x780E0012, // 0013 JMPF R3 #0027 - 0x8C140303, // 0014 GETMET R5 R1 K3 - 0x541E00DF, // 0015 LDINT R7 224 - 0x88200104, // 0016 GETMBR R8 R0 K4 - 0x001C0E08, // 0017 ADD R7 R7 R8 - 0x58200005, // 0018 LDCONST R8 K5 - 0x7C140600, // 0019 CALL R5 3 - 0x8C140303, // 001A GETMET R5 R1 K3 - 0x881C0102, // 001B GETMBR R7 R0 K2 - 0x58200006, // 001C LDCONST R8 K6 - 0x7C140600, // 001D CALL R5 3 - 0x8C140303, // 001E GETMET R5 R1 K3 - 0x881C0107, // 001F GETMBR R7 R0 K7 - 0x58200006, // 0020 LDCONST R8 K6 - 0x7C140600, // 0021 CALL R5 3 - 0x8C140303, // 0022 GETMET R5 R1 K3 - 0x881C0100, // 0023 GETMBR R7 R0 K0 - 0x54220003, // 0024 LDINT R8 4 - 0x7C140600, // 0025 CALL R5 3 - 0x70020011, // 0026 JMP #0039 - 0x8C140303, // 0027 GETMET R5 R1 K3 - 0x541E00BF, // 0028 LDINT R7 192 - 0x88200104, // 0029 GETMBR R8 R0 K4 - 0x001C0E08, // 002A ADD R7 R7 R8 - 0x58200005, // 002B LDCONST R8 K5 - 0x7C140600, // 002C CALL R5 3 - 0x8C140303, // 002D GETMET R5 R1 K3 - 0x881C0102, // 002E GETMBR R7 R0 K2 - 0x58200006, // 002F LDCONST R8 K6 - 0x7C140600, // 0030 CALL R5 3 - 0x8C140303, // 0031 GETMET R5 R1 K3 - 0x881C0107, // 0032 GETMBR R7 R0 K7 - 0x58200006, // 0033 LDCONST R8 K6 - 0x7C140600, // 0034 CALL R5 3 - 0x8C140303, // 0035 GETMET R5 R1 K3 - 0x881C0100, // 0036 GETMBR R7 R0 K0 - 0x58200006, // 0037 LDCONST R8 K6 - 0x7C140600, // 0038 CALL R5 3 - 0x70020049, // 0039 JMP #0084 - 0x88140107, // 003A GETMBR R5 R0 K7 - 0x5419FFFE, // 003B LDINT R6 -1 - 0x1C140A06, // 003C EQ R5 R5 R6 - 0x78160016, // 003D JMPF R5 #0055 - 0x780E000A, // 003E JMPF R3 #004A - 0x8C140303, // 003F GETMET R5 R1 K3 - 0x541E005F, // 0040 LDINT R7 96 - 0x88200104, // 0041 GETMBR R8 R0 K4 - 0x001C0E08, // 0042 ADD R7 R7 R8 - 0x58200005, // 0043 LDCONST R8 K5 - 0x7C140600, // 0044 CALL R5 3 - 0x8C140303, // 0045 GETMET R5 R1 K3 - 0x881C0100, // 0046 GETMBR R7 R0 K0 - 0x54220003, // 0047 LDINT R8 4 - 0x7C140600, // 0048 CALL R5 3 - 0x70020009, // 0049 JMP #0054 - 0x8C140303, // 004A GETMET R5 R1 K3 - 0x541E003F, // 004B LDINT R7 64 - 0x88200104, // 004C GETMBR R8 R0 K4 - 0x001C0E08, // 004D ADD R7 R7 R8 - 0x58200005, // 004E LDCONST R8 K5 - 0x7C140600, // 004F CALL R5 3 - 0x8C140303, // 0050 GETMET R5 R1 K3 - 0x881C0100, // 0051 GETMBR R7 R0 K0 - 0x58200006, // 0052 LDCONST R8 K6 - 0x7C140600, // 0053 CALL R5 3 - 0x7002002E, // 0054 JMP #0084 - 0x88140107, // 0055 GETMBR R5 R0 K7 - 0x4C180000, // 0056 LDNIL R6 - 0x20140A06, // 0057 NE R5 R5 R6 - 0x78160016, // 0058 JMPF R5 #0070 - 0x780E000A, // 0059 JMPF R3 #0065 - 0x8C140303, // 005A GETMET R5 R1 K3 - 0x541E009F, // 005B LDINT R7 160 - 0x88200104, // 005C GETMBR R8 R0 K4 - 0x001C0E08, // 005D ADD R7 R7 R8 - 0x58200005, // 005E LDCONST R8 K5 - 0x7C140600, // 005F CALL R5 3 - 0x8C140303, // 0060 GETMET R5 R1 K3 - 0x881C0100, // 0061 GETMBR R7 R0 K0 - 0x54220003, // 0062 LDINT R8 4 - 0x7C140600, // 0063 CALL R5 3 - 0x70020009, // 0064 JMP #006F - 0x8C140303, // 0065 GETMET R5 R1 K3 - 0x541E007F, // 0066 LDINT R7 128 - 0x88200104, // 0067 GETMBR R8 R0 K4 - 0x001C0E08, // 0068 ADD R7 R7 R8 - 0x58200005, // 0069 LDCONST R8 K5 - 0x7C140600, // 006A CALL R5 3 - 0x8C140303, // 006B GETMET R5 R1 K3 - 0x881C0100, // 006C GETMBR R7 R0 K0 - 0x58200006, // 006D LDCONST R8 K6 - 0x7C140600, // 006E CALL R5 3 - 0x70020013, // 006F JMP #0084 - 0x88140108, // 0070 GETMBR R5 R0 K8 - 0x4C180000, // 0071 LDNIL R6 - 0x20140A06, // 0072 NE R5 R5 R6 - 0x7816000A, // 0073 JMPF R5 #007F - 0x8C140303, // 0074 GETMET R5 R1 K3 - 0x541E001F, // 0075 LDINT R7 32 - 0x88200104, // 0076 GETMBR R8 R0 K4 - 0x001C0E08, // 0077 ADD R7 R7 R8 - 0x58200005, // 0078 LDCONST R8 K5 - 0x7C140600, // 0079 CALL R5 3 - 0x8C140303, // 007A GETMET R5 R1 K3 - 0x881C0108, // 007B GETMBR R7 R0 K8 - 0x58200005, // 007C LDCONST R8 K5 - 0x7C140600, // 007D CALL R5 3 - 0x70020004, // 007E JMP #0084 - 0x8C140303, // 007F GETMET R5 R1 K3 - 0x881C0104, // 0080 GETMBR R7 R0 K4 - 0x001E0207, // 0081 ADD R7 K1 R7 - 0x58200005, // 0082 LDCONST R8 K5 - 0x7C140600, // 0083 CALL R5 3 - 0x80000000, // 0084 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: encode_len -********************************************************************/ -be_local_closure(Matter_TLV_item_encode_len, /* name */ - be_nested_proto( - 5, /* nstack */ - 1, /* argc */ + 5, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -715,11 +648,11 @@ be_local_closure(Matter_TLV_item_encode_len, /* name */ /******************************************************************** -** Solidified function: set_contextspecific +** Solidified function: reset ********************************************************************/ -be_local_closure(Matter_TLV_item_set_contextspecific, /* name */ +be_local_closure(Matter_TLV_item_reset, /* name */ be_nested_proto( - 4, /* nstack */ + 3, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -727,20 +660,29 @@ be_local_closure(Matter_TLV_item_set_contextspecific, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(set_fulltag), - /* K1 */ be_nested_str_weak(tag_sub), + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(parent), + /* K1 */ be_nested_str_weak(next_idx), + /* K2 */ be_nested_str_weak(tag_vendor), + /* K3 */ be_nested_str_weak(tag_profile), + /* K4 */ be_nested_str_weak(tag_number), + /* K5 */ be_nested_str_weak(tag_sub), + /* K6 */ be_nested_str_weak(typ), + /* K7 */ be_nested_str_weak(val), }), - be_str_weak(set_contextspecific), + be_str_weak(reset), &be_const_str_solidified, - ( &(const binstruction[ 7]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x7C080200, // 0001 CALL R2 1 - 0x60080009, // 0002 GETGBL R2 G9 - 0x5C0C0200, // 0003 MOVE R3 R1 - 0x7C080200, // 0004 CALL R2 1 - 0x90020202, // 0005 SETMBR R0 K1 R2 - 0x80000000, // 0006 RET 0 + ( &(const binstruction[10]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x90020001, // 0001 SETMBR R0 K0 R1 + 0x90020202, // 0002 SETMBR R0 K1 R2 + 0x90020402, // 0003 SETMBR R0 K2 R2 + 0x90020602, // 0004 SETMBR R0 K3 R2 + 0x90020802, // 0005 SETMBR R0 K4 R2 + 0x90020A02, // 0006 SETMBR R0 K5 R2 + 0x90020C02, // 0007 SETMBR R0 K6 R2 + 0x90020E02, // 0008 SETMBR R0 K7 R2 + 0x80000000, // 0009 RET 0 }) ) ); @@ -748,42 +690,39 @@ be_local_closure(Matter_TLV_item_set_contextspecific, /* name */ /******************************************************************** -** Solidified function: set_fulltag +** Solidified function: create_TLV ********************************************************************/ -be_local_closure(Matter_TLV_item_set_fulltag, /* name */ +be_local_closure(Matter_TLV_item_create_TLV, /* name */ be_nested_proto( - 6, /* nstack */ - 4, /* argc */ - 2, /* varg */ + 4, /* nstack */ + 2, /* argc */ + 4, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(tag_vendor), - /* K1 */ be_nested_str_weak(tag_profile), - /* K2 */ be_nested_str_weak(tag_number), - /* K3 */ be_nested_str_weak(tag_sub), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_const_class(be_class_Matter_TLV_item), + /* K1 */ be_nested_str_weak(typ), + /* K2 */ be_nested_str_weak(val), }), - be_str_weak(set_fulltag), + be_str_weak(create_TLV), &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x60100009, // 0000 GETGBL R4 G9 - 0x5C140200, // 0001 MOVE R5 R1 - 0x7C100200, // 0002 CALL R4 1 - 0x90020004, // 0003 SETMBR R0 K0 R4 - 0x60100009, // 0004 GETGBL R4 G9 - 0x5C140400, // 0005 MOVE R5 R2 - 0x7C100200, // 0006 CALL R4 1 - 0x90020204, // 0007 SETMBR R0 K1 R4 - 0x60100009, // 0008 GETGBL R4 G9 - 0x5C140600, // 0009 MOVE R5 R3 - 0x7C100200, // 000A CALL R4 1 - 0x90020404, // 000B SETMBR R0 K2 R4 - 0x4C100000, // 000C LDNIL R4 - 0x90020604, // 000D SETMBR R0 K3 R4 - 0x80000000, // 000E RET 0 + ( &(const binstruction[13]) { /* code */ + 0x58080000, // 0000 LDCONST R2 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x200C0203, // 0002 NE R3 R1 R3 + 0x740E0002, // 0003 JMPT R3 #0007 + 0x540E0013, // 0004 LDINT R3 20 + 0x1C0C0003, // 0005 EQ R3 R0 R3 + 0x780E0004, // 0006 JMPF R3 #000C + 0x5C0C0400, // 0007 MOVE R3 R2 + 0x7C0C0000, // 0008 CALL R3 0 + 0x900E0200, // 0009 SETMBR R3 K1 R0 + 0x900E0401, // 000A SETMBR R3 K2 R1 + 0x80040600, // 000B RET 1 R3 + 0x80000000, // 000C RET 0 }) ) ); @@ -791,223 +730,153 @@ be_local_closure(Matter_TLV_item_set_fulltag, /* name */ /******************************************************************** -** Solidified function: tostring +** Solidified function: parse ********************************************************************/ -be_local_closure(Matter_TLV_item_tostring, /* name */ +be_local_closure(Matter_TLV_item_parse, /* name */ be_nested_proto( - 8, /* nstack */ - 1, /* argc */ + 10, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[35]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(), - /* K2 */ be_nested_str_weak(tag_profile), - /* K3 */ be_nested_str_weak(Matter_X3A_X3A), - /* K4 */ be_nested_str_weak(tag_number), - /* K5 */ be_nested_str_weak(format), - /* K6 */ be_nested_str_weak(0x_X2508X_X20), - /* K7 */ be_nested_str_weak(tag_vendor), - /* K8 */ be_nested_str_weak(0x_X2504X_X3A_X3A), - /* K9 */ be_nested_str_weak(0x_X2504X_X3A), - /* K10 */ be_nested_str_weak(tag_sub), - /* K11 */ be_nested_str_weak(_X25i_X20), - /* K12 */ be_const_int(0), - /* K13 */ be_nested_str_weak(_X3D_X20), - /* K14 */ be_nested_str_weak(val), - /* K15 */ be_nested_str_weak(int), - /* K16 */ be_nested_str_weak(_X25i), - /* K17 */ be_nested_str_weak(typ), - /* K18 */ be_nested_str_weak(TLV), - /* K19 */ be_nested_str_weak(U1), - /* K20 */ be_nested_str_weak(U8), - /* K21 */ be_nested_str_weak(U), - /* K22 */ be_nested_str_weak(bool), - /* K23 */ be_nested_str_weak(true), - /* K24 */ be_nested_str_weak(false), - /* K25 */ be_nested_str_weak(null), - /* K26 */ be_nested_str_weak(real), - /* K27 */ be_nested_str_weak(_X25g), - /* K28 */ be_nested_str_weak(_X22_X25s_X22), - /* K29 */ be_nested_str_weak(int64), - /* K30 */ be_nested_str_weak(tostring), - /* K31 */ be_nested_str_weak(instance), - /* K32 */ be_nested_str_weak(_X25s), - /* K33 */ be_nested_str_weak(tohex), - /* K34 */ be_nested_str_weak(_X20), - }), - be_str_weak(tostring), - &be_const_str_solidified, - ( &(const binstruction[165]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x58080001, // 0001 LDCONST R2 K1 - 0xA8020099, // 0002 EXBLK 0 #009D - 0x880C0102, // 0003 GETMBR R3 R0 K2 - 0x5411FFFE, // 0004 LDINT R4 -1 - 0x1C0C0604, // 0005 EQ R3 R3 R4 - 0x780E000A, // 0006 JMPF R3 #0012 - 0x00080503, // 0007 ADD R2 R2 K3 - 0x880C0104, // 0008 GETMBR R3 R0 K4 - 0x4C100000, // 0009 LDNIL R4 - 0x200C0604, // 000A NE R3 R3 R4 - 0x780E0004, // 000B JMPF R3 #0011 - 0x8C0C0305, // 000C GETMET R3 R1 K5 - 0x58140006, // 000D LDCONST R5 K6 - 0x88180104, // 000E GETMBR R6 R0 K4 - 0x7C0C0600, // 000F CALL R3 3 - 0x00080403, // 0010 ADD R2 R2 R3 - 0x70020023, // 0011 JMP #0036 - 0x880C0107, // 0012 GETMBR R3 R0 K7 - 0x4C100000, // 0013 LDNIL R4 - 0x200C0604, // 0014 NE R3 R3 R4 - 0x780E0004, // 0015 JMPF R3 #001B - 0x8C0C0305, // 0016 GETMET R3 R1 K5 - 0x58140008, // 0017 LDCONST R5 K8 - 0x88180107, // 0018 GETMBR R6 R0 K7 - 0x7C0C0600, // 0019 CALL R3 3 - 0x00080403, // 001A ADD R2 R2 R3 - 0x880C0102, // 001B GETMBR R3 R0 K2 - 0x4C100000, // 001C LDNIL R4 - 0x200C0604, // 001D NE R3 R3 R4 - 0x780E0004, // 001E JMPF R3 #0024 - 0x8C0C0305, // 001F GETMET R3 R1 K5 - 0x58140009, // 0020 LDCONST R5 K9 - 0x88180102, // 0021 GETMBR R6 R0 K2 - 0x7C0C0600, // 0022 CALL R3 3 - 0x00080403, // 0023 ADD R2 R2 R3 - 0x880C0104, // 0024 GETMBR R3 R0 K4 - 0x4C100000, // 0025 LDNIL R4 - 0x200C0604, // 0026 NE R3 R3 R4 - 0x780E0004, // 0027 JMPF R3 #002D - 0x8C0C0305, // 0028 GETMET R3 R1 K5 - 0x58140006, // 0029 LDCONST R5 K6 - 0x88180104, // 002A GETMBR R6 R0 K4 - 0x7C0C0600, // 002B CALL R3 3 - 0x00080403, // 002C ADD R2 R2 R3 - 0x880C010A, // 002D GETMBR R3 R0 K10 - 0x4C100000, // 002E LDNIL R4 - 0x200C0604, // 002F NE R3 R3 R4 - 0x780E0004, // 0030 JMPF R3 #0036 - 0x8C0C0305, // 0031 GETMET R3 R1 K5 - 0x5814000B, // 0032 LDCONST R5 K11 - 0x8818010A, // 0033 GETMBR R6 R0 K10 - 0x7C0C0600, // 0034 CALL R3 3 - 0x00080403, // 0035 ADD R2 R2 R3 - 0x600C000C, // 0036 GETGBL R3 G12 - 0x5C100400, // 0037 MOVE R4 R2 - 0x7C0C0200, // 0038 CALL R3 1 - 0x240C070C, // 0039 GT R3 R3 K12 - 0x780E0000, // 003A JMPF R3 #003C - 0x0008050D, // 003B ADD R2 R2 K13 - 0x600C0004, // 003C GETGBL R3 G4 - 0x8810010E, // 003D GETMBR R4 R0 K14 - 0x7C0C0200, // 003E CALL R3 1 - 0x1C0C070F, // 003F EQ R3 R3 K15 - 0x780E0010, // 0040 JMPF R3 #0052 - 0x8C0C0305, // 0041 GETMET R3 R1 K5 - 0x58140010, // 0042 LDCONST R5 K16 - 0x8818010E, // 0043 GETMBR R6 R0 K14 - 0x7C0C0600, // 0044 CALL R3 3 - 0x00080403, // 0045 ADD R2 R2 R3 - 0x880C0111, // 0046 GETMBR R3 R0 K17 - 0x88100112, // 0047 GETMBR R4 R0 K18 - 0x88100913, // 0048 GETMBR R4 R4 K19 - 0x280C0604, // 0049 GE R3 R3 R4 - 0x780E0005, // 004A JMPF R3 #0051 - 0x880C0111, // 004B GETMBR R3 R0 K17 - 0x88100112, // 004C GETMBR R4 R0 K18 - 0x88100914, // 004D GETMBR R4 R4 K20 - 0x180C0604, // 004E LE R3 R3 R4 - 0x780E0000, // 004F JMPF R3 #0051 - 0x00080515, // 0050 ADD R2 R2 K21 - 0x70020048, // 0051 JMP #009B - 0x600C0004, // 0052 GETGBL R3 G4 - 0x8810010E, // 0053 GETMBR R4 R0 K14 - 0x7C0C0200, // 0054 CALL R3 1 - 0x1C0C0716, // 0055 EQ R3 R3 K22 - 0x780E0006, // 0056 JMPF R3 #005E - 0x880C010E, // 0057 GETMBR R3 R0 K14 - 0x780E0001, // 0058 JMPF R3 #005B - 0x580C0017, // 0059 LDCONST R3 K23 - 0x70020000, // 005A JMP #005C - 0x580C0018, // 005B LDCONST R3 K24 - 0x00080403, // 005C ADD R2 R2 R3 - 0x7002003C, // 005D JMP #009B - 0x880C010E, // 005E GETMBR R3 R0 K14 - 0x4C100000, // 005F LDNIL R4 - 0x1C0C0604, // 0060 EQ R3 R3 R4 - 0x780E0001, // 0061 JMPF R3 #0064 - 0x00080519, // 0062 ADD R2 R2 K25 - 0x70020036, // 0063 JMP #009B - 0x600C0004, // 0064 GETGBL R3 G4 - 0x8810010E, // 0065 GETMBR R4 R0 K14 - 0x7C0C0200, // 0066 CALL R3 1 - 0x1C0C071A, // 0067 EQ R3 R3 K26 - 0x780E0005, // 0068 JMPF R3 #006F - 0x8C0C0305, // 0069 GETMET R3 R1 K5 - 0x5814001B, // 006A LDCONST R5 K27 - 0x8818010E, // 006B GETMBR R6 R0 K14 - 0x7C0C0600, // 006C CALL R3 3 - 0x00080403, // 006D ADD R2 R2 R3 - 0x7002002B, // 006E JMP #009B - 0x600C0004, // 006F GETGBL R3 G4 - 0x8810010E, // 0070 GETMBR R4 R0 K14 - 0x7C0C0200, // 0071 CALL R3 1 - 0x1C0C0700, // 0072 EQ R3 R3 K0 - 0x780E0005, // 0073 JMPF R3 #007A - 0x8C0C0305, // 0074 GETMET R3 R1 K5 - 0x5814001C, // 0075 LDCONST R5 K28 - 0x8818010E, // 0076 GETMBR R6 R0 K14 - 0x7C0C0600, // 0077 CALL R3 3 - 0x00080403, // 0078 ADD R2 R2 R3 - 0x70020020, // 0079 JMP #009B - 0x600C000F, // 007A GETGBL R3 G15 - 0x8810010E, // 007B GETMBR R4 R0 K14 - 0xB8163A00, // 007C GETNGBL R5 K29 - 0x7C0C0400, // 007D CALL R3 2 - 0x780E000F, // 007E JMPF R3 #008F - 0x880C010E, // 007F GETMBR R3 R0 K14 - 0x8C0C071E, // 0080 GETMET R3 R3 K30 - 0x7C0C0200, // 0081 CALL R3 1 - 0x00080403, // 0082 ADD R2 R2 R3 - 0x880C0111, // 0083 GETMBR R3 R0 K17 - 0x88100112, // 0084 GETMBR R4 R0 K18 - 0x88100913, // 0085 GETMBR R4 R4 K19 - 0x280C0604, // 0086 GE R3 R3 R4 - 0x780E0005, // 0087 JMPF R3 #008E - 0x880C0111, // 0088 GETMBR R3 R0 K17 - 0x88100112, // 0089 GETMBR R4 R0 K18 - 0x88100914, // 008A GETMBR R4 R4 K20 - 0x180C0604, // 008B LE R3 R3 R4 - 0x780E0000, // 008C JMPF R3 #008E - 0x00080515, // 008D ADD R2 R2 K21 - 0x7002000B, // 008E JMP #009B - 0x600C0004, // 008F GETGBL R3 G4 - 0x8810010E, // 0090 GETMBR R4 R0 K14 - 0x7C0C0200, // 0091 CALL R3 1 - 0x1C0C071F, // 0092 EQ R3 R3 K31 - 0x780E0006, // 0093 JMPF R3 #009B - 0x8C0C0305, // 0094 GETMET R3 R1 K5 - 0x58140020, // 0095 LDCONST R5 K32 - 0x8818010E, // 0096 GETMBR R6 R0 K14 - 0x8C180D21, // 0097 GETMET R6 R6 K33 - 0x7C180200, // 0098 CALL R6 1 - 0x7C0C0600, // 0099 CALL R3 3 - 0x00080403, // 009A ADD R2 R2 R3 - 0xA8040001, // 009B EXBLK 1 1 - 0x70020006, // 009C JMP #00A4 - 0xAC0C0002, // 009D CATCH R3 0 2 - 0x70020003, // 009E JMP #00A3 - 0x00140722, // 009F ADD R5 R3 K34 - 0x00140A04, // 00A0 ADD R5 R5 R4 - 0x80040A00, // 00A1 RET 1 R5 - 0x70020000, // 00A2 JMP #00A4 - 0xB0080000, // 00A3 RAISE 2 R0 R0 - 0x80040400, // 00A4 RET 1 R2 + ( &(const bvalue[25]) { /* constants */ + /* K0 */ be_nested_str_weak(typ), + /* K1 */ be_nested_str_weak(TLV), + /* K2 */ be_nested_str_weak(_len), + /* K3 */ be_nested_str_weak(val), + /* K4 */ be_nested_str_weak(int64), + /* K5 */ be_nested_str_weak(frombytes), + /* K6 */ be_nested_str_weak(BFALSE), + /* K7 */ be_nested_str_weak(BTRUE), + /* K8 */ be_nested_str_weak(U8), + /* K9 */ be_nested_str_weak(I8), + /* K10 */ be_nested_str_weak(geti), + /* K11 */ be_nested_str_weak(get), + /* K12 */ be_nested_str_weak(FLOAT), + /* K13 */ be_nested_str_weak(getfloat), + /* K14 */ be_const_int(1), + /* K15 */ be_nested_str_weak(UTF8), + /* K16 */ be_nested_str_weak(asstring), + /* K17 */ be_nested_str_weak(NULL), + /* K18 */ be_nested_str_weak(EOC), + /* K19 */ be_nested_str_weak(tasmota), + /* K20 */ be_nested_str_weak(log), + /* K21 */ be_nested_str_weak(MTR_X3A_X20unexpected_X20eoc), + /* K22 */ be_const_int(3), + /* K23 */ be_nested_str_weak(MTR_X3A_X20unexpected_X20type_X3A_X20), + /* K24 */ be_nested_str_weak(next_idx), + }), + be_str_weak(parse), + &be_const_str_solidified, + ( &(const binstruction[105]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x88100101, // 0001 GETMBR R4 R0 K1 + 0x88140902, // 0002 GETMBR R5 R4 K2 + 0x94140A03, // 0003 GETIDX R5 R5 R3 + 0x541A0007, // 0004 LDINT R6 8 + 0x1C180A06, // 0005 EQ R6 R5 R6 + 0x781A000A, // 0006 JMPF R6 #0012 + 0xB81A0800, // 0007 GETNGBL R6 K4 + 0x7C180000, // 0008 CALL R6 0 + 0x90020606, // 0009 SETMBR R0 K3 R6 + 0x88180103, // 000A GETMBR R6 R0 K3 + 0x8C180D05, // 000B GETMET R6 R6 K5 + 0x5C200200, // 000C MOVE R8 R1 + 0x5C240400, // 000D MOVE R9 R2 + 0x7C180600, // 000E CALL R6 3 + 0x541A0007, // 000F LDINT R6 8 + 0x00080406, // 0010 ADD R2 R2 R6 + 0x70020054, // 0011 JMP #0067 + 0x88180906, // 0012 GETMBR R6 R4 K6 + 0x1C180606, // 0013 EQ R6 R3 R6 + 0x741A0002, // 0014 JMPT R6 #0018 + 0x88180907, // 0015 GETMBR R6 R4 K7 + 0x1C180606, // 0016 EQ R6 R3 R6 + 0x781A0003, // 0017 JMPF R6 #001C + 0x88180907, // 0018 GETMBR R6 R4 K7 + 0x1C180606, // 0019 EQ R6 R3 R6 + 0x90020606, // 001A SETMBR R0 K3 R6 + 0x7002004A, // 001B JMP #0067 + 0x88180908, // 001C GETMBR R6 R4 K8 + 0x14180606, // 001D LT R6 R3 R6 + 0x781A000E, // 001E JMPF R6 #002E + 0x88180909, // 001F GETMBR R6 R4 K9 + 0x18180606, // 0020 LE R6 R3 R6 + 0x781A0004, // 0021 JMPF R6 #0027 + 0x8C18030A, // 0022 GETMET R6 R1 K10 + 0x5C200400, // 0023 MOVE R8 R2 + 0x5C240A00, // 0024 MOVE R9 R5 + 0x7C180600, // 0025 CALL R6 3 + 0x70020003, // 0026 JMP #002B + 0x8C18030B, // 0027 GETMET R6 R1 K11 + 0x5C200400, // 0028 MOVE R8 R2 + 0x5C240A00, // 0029 MOVE R9 R5 + 0x7C180600, // 002A CALL R6 3 + 0x90020606, // 002B SETMBR R0 K3 R6 + 0x00080405, // 002C ADD R2 R2 R5 + 0x70020038, // 002D JMP #0067 + 0x8818090C, // 002E GETMBR R6 R4 K12 + 0x1C180606, // 002F EQ R6 R3 R6 + 0x781A0006, // 0030 JMPF R6 #0038 + 0x8C18030D, // 0031 GETMET R6 R1 K13 + 0x5C200400, // 0032 MOVE R8 R2 + 0x7C180400, // 0033 CALL R6 2 + 0x90020606, // 0034 SETMBR R0 K3 R6 + 0x541A0003, // 0035 LDINT R6 4 + 0x00080406, // 0036 ADD R2 R2 R6 + 0x7002002E, // 0037 JMP #0067 + 0x5419FFF7, // 0038 LDINT R6 -8 + 0x28180A06, // 0039 GE R6 R5 R6 + 0x781A0016, // 003A JMPF R6 #0052 + 0x5419FFFE, // 003B LDINT R6 -1 + 0x18180A06, // 003C LE R6 R5 R6 + 0x781A0013, // 003D JMPF R6 #0052 + 0x8C18030B, // 003E GETMET R6 R1 K11 + 0x5C200400, // 003F MOVE R8 R2 + 0x44240A00, // 0040 NEG R9 R5 + 0x7C180600, // 0041 CALL R6 3 + 0x441C0A00, // 0042 NEG R7 R5 + 0x00080407, // 0043 ADD R2 R2 R7 + 0x001C0406, // 0044 ADD R7 R2 R6 + 0x041C0F0E, // 0045 SUB R7 R7 K14 + 0x401C0407, // 0046 CONNECT R7 R2 R7 + 0x941C0207, // 0047 GETIDX R7 R1 R7 + 0x90020607, // 0048 SETMBR R0 K3 R7 + 0x00080406, // 0049 ADD R2 R2 R6 + 0x881C090F, // 004A GETMBR R7 R4 K15 + 0x181C0607, // 004B LE R7 R3 R7 + 0x781E0003, // 004C JMPF R7 #0051 + 0x881C0103, // 004D GETMBR R7 R0 K3 + 0x8C1C0F10, // 004E GETMET R7 R7 K16 + 0x7C1C0200, // 004F CALL R7 1 + 0x90020607, // 0050 SETMBR R0 K3 R7 + 0x70020014, // 0051 JMP #0067 + 0x88180911, // 0052 GETMBR R6 R4 K17 + 0x1C180606, // 0053 EQ R6 R3 R6 + 0x781A0000, // 0054 JMPF R6 #0056 + 0x70020010, // 0055 JMP #0067 + 0x88180912, // 0056 GETMBR R6 R4 K18 + 0x1C180606, // 0057 EQ R6 R3 R6 + 0x781A0005, // 0058 JMPF R6 #005F + 0xB81A2600, // 0059 GETNGBL R6 K19 + 0x8C180D14, // 005A GETMET R6 R6 K20 + 0x58200015, // 005B LDCONST R8 K21 + 0x58240016, // 005C LDCONST R9 K22 + 0x7C180600, // 005D CALL R6 3 + 0x70020007, // 005E JMP #0067 + 0xB81A2600, // 005F GETNGBL R6 K19 + 0x8C180D14, // 0060 GETMET R6 R6 K20 + 0x60200008, // 0061 GETGBL R8 G8 + 0x5C240600, // 0062 MOVE R9 R3 + 0x7C200200, // 0063 CALL R8 1 + 0x00222E08, // 0064 ADD R8 K23 R8 + 0x58240016, // 0065 LDCONST R9 K22 + 0x7C180600, // 0066 CALL R6 3 + 0x90023002, // 0067 SETMBR R0 K24 R2 + 0x80040400, // 0068 RET 1 R2 }) ) ); @@ -1015,26 +884,124 @@ be_local_closure(Matter_TLV_item_tostring, /* name */ /******************************************************************** -** Solidified function: init +** Solidified function: _encode_tag_len ********************************************************************/ -be_local_closure(Matter_TLV_item_init, /* name */ +be_local_closure(Matter_TLV_item__encode_tag_len, /* name */ be_nested_proto( - 2, /* nstack */ - 2, /* argc */ + 6, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(parent), + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(tag_number), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(tag_vendor), + /* K3 */ be_nested_str_weak(tag_profile), + /* K4 */ be_const_int(3), + /* K5 */ be_nested_str_weak(tag_sub), + /* K6 */ be_const_int(2), + /* K7 */ be_const_int(1), }), - be_str_weak(init), + be_str_weak(_encode_tag_len), &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x90020001, // 0000 SETMBR R0 K0 R1 - 0x80000000, // 0001 RET 0 + ( &(const binstruction[54]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x20040202, // 0002 NE R1 R1 R2 + 0x78060001, // 0003 JMPF R1 #0006 + 0x88040100, // 0004 GETMBR R1 R0 K0 + 0x70020000, // 0005 JMP #0007 + 0x58040001, // 0006 LDCONST R1 K1 + 0x540AFFFF, // 0007 LDINT R2 65536 + 0x28080202, // 0008 GE R2 R1 R2 + 0x740A0002, // 0009 JMPT R2 #000D + 0x14080301, // 000A LT R2 R1 K1 + 0x740A0000, // 000B JMPT R2 #000D + 0x50080001, // 000C LDBOOL R2 0 1 + 0x50080200, // 000D LDBOOL R2 1 0 + 0x580C0001, // 000E LDCONST R3 K1 + 0x88100102, // 000F GETMBR R4 R0 K2 + 0x4C140000, // 0010 LDNIL R5 + 0x20100805, // 0011 NE R4 R4 R5 + 0x78120006, // 0012 JMPF R4 #001A + 0x780A0002, // 0013 JMPF R2 #0017 + 0x54120008, // 0014 LDINT R4 9 + 0x80040800, // 0015 RET 1 R4 + 0x70020001, // 0016 JMP #0019 + 0x54120006, // 0017 LDINT R4 7 + 0x80040800, // 0018 RET 1 R4 + 0x7002001A, // 0019 JMP #0035 + 0x88100103, // 001A GETMBR R4 R0 K3 + 0x5415FFFE, // 001B LDINT R5 -1 + 0x1C100805, // 001C EQ R4 R4 R5 + 0x78120005, // 001D JMPF R4 #0024 + 0x780A0002, // 001E JMPF R2 #0022 + 0x54120004, // 001F LDINT R4 5 + 0x80040800, // 0020 RET 1 R4 + 0x70020000, // 0021 JMP #0023 + 0x80060800, // 0022 RET 1 K4 + 0x70020010, // 0023 JMP #0035 + 0x88100103, // 0024 GETMBR R4 R0 K3 + 0x4C140000, // 0025 LDNIL R5 + 0x20100805, // 0026 NE R4 R4 R5 + 0x78120005, // 0027 JMPF R4 #002E + 0x780A0002, // 0028 JMPF R2 #002C + 0x54120004, // 0029 LDINT R4 5 + 0x80040800, // 002A RET 1 R4 + 0x70020000, // 002B JMP #002D + 0x80060800, // 002C RET 1 K4 + 0x70020006, // 002D JMP #0035 + 0x88100105, // 002E GETMBR R4 R0 K5 + 0x4C140000, // 002F LDNIL R5 + 0x20100805, // 0030 NE R4 R4 R5 + 0x78120001, // 0031 JMPF R4 #0034 + 0x80060C00, // 0032 RET 1 K6 + 0x70020000, // 0033 JMP #0035 + 0x80060E00, // 0034 RET 1 K7 + 0x80000000, // 0035 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set +********************************************************************/ +be_local_closure(Matter_TLV_item_set, /* name */ + be_nested_proto( + 5, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(reset), + /* K1 */ be_nested_str_weak(typ), + /* K2 */ be_nested_str_weak(val), + }), + be_str_weak(set), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x8C0C0100, // 0000 GETMET R3 R0 K0 + 0x7C0C0200, // 0001 CALL R3 1 + 0x4C0C0000, // 0002 LDNIL R3 + 0x200C0403, // 0003 NE R3 R2 R3 + 0x740E0002, // 0004 JMPT R3 #0008 + 0x540E0013, // 0005 LDINT R3 20 + 0x1C0C0203, // 0006 EQ R3 R1 R3 + 0x780E0002, // 0007 JMPF R3 #000B + 0x90020201, // 0008 SETMBR R0 K1 R1 + 0x90020402, // 0009 SETMBR R0 K2 R2 + 0x80040000, // 000A RET 1 R0 + 0x80000000, // 000B RET 0 }) ) ); @@ -1476,11 +1443,11 @@ be_local_closure(Matter_TLV_item_tlv2raw, /* name */ /******************************************************************** -** Solidified function: _encode_tag_len +** Solidified function: set_anonymoustag ********************************************************************/ -be_local_closure(Matter_TLV_item__encode_tag_len, /* name */ +be_local_closure(Matter_TLV_item_set_anonymoustag, /* name */ be_nested_proto( - 6, /* nstack */ + 3, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1488,73 +1455,15 @@ be_local_closure(Matter_TLV_item__encode_tag_len, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(tag_number), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str_weak(tag_vendor), - /* K3 */ be_nested_str_weak(tag_profile), - /* K4 */ be_const_int(3), - /* K5 */ be_nested_str_weak(tag_sub), - /* K6 */ be_const_int(2), - /* K7 */ be_const_int(1), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(set_fulltag), }), - be_str_weak(_encode_tag_len), + be_str_weak(set_anonymoustag), &be_const_str_solidified, - ( &(const binstruction[54]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x20040202, // 0002 NE R1 R1 R2 - 0x78060001, // 0003 JMPF R1 #0006 - 0x88040100, // 0004 GETMBR R1 R0 K0 - 0x70020000, // 0005 JMP #0007 - 0x58040001, // 0006 LDCONST R1 K1 - 0x540AFFFF, // 0007 LDINT R2 65536 - 0x28080202, // 0008 GE R2 R1 R2 - 0x740A0002, // 0009 JMPT R2 #000D - 0x14080301, // 000A LT R2 R1 K1 - 0x740A0000, // 000B JMPT R2 #000D - 0x50080001, // 000C LDBOOL R2 0 1 - 0x50080200, // 000D LDBOOL R2 1 0 - 0x580C0001, // 000E LDCONST R3 K1 - 0x88100102, // 000F GETMBR R4 R0 K2 - 0x4C140000, // 0010 LDNIL R5 - 0x20100805, // 0011 NE R4 R4 R5 - 0x78120006, // 0012 JMPF R4 #001A - 0x780A0002, // 0013 JMPF R2 #0017 - 0x54120008, // 0014 LDINT R4 9 - 0x80040800, // 0015 RET 1 R4 - 0x70020001, // 0016 JMP #0019 - 0x54120006, // 0017 LDINT R4 7 - 0x80040800, // 0018 RET 1 R4 - 0x7002001A, // 0019 JMP #0035 - 0x88100103, // 001A GETMBR R4 R0 K3 - 0x5415FFFE, // 001B LDINT R5 -1 - 0x1C100805, // 001C EQ R4 R4 R5 - 0x78120005, // 001D JMPF R4 #0024 - 0x780A0002, // 001E JMPF R2 #0022 - 0x54120004, // 001F LDINT R4 5 - 0x80040800, // 0020 RET 1 R4 - 0x70020000, // 0021 JMP #0023 - 0x80060800, // 0022 RET 1 K4 - 0x70020010, // 0023 JMP #0035 - 0x88100103, // 0024 GETMBR R4 R0 K3 - 0x4C140000, // 0025 LDNIL R5 - 0x20100805, // 0026 NE R4 R4 R5 - 0x78120005, // 0027 JMPF R4 #002E - 0x780A0002, // 0028 JMPF R2 #002C - 0x54120004, // 0029 LDINT R4 5 - 0x80040800, // 002A RET 1 R4 - 0x70020000, // 002B JMP #002D - 0x80060800, // 002C RET 1 K4 - 0x70020006, // 002D JMP #0035 - 0x88100105, // 002E GETMBR R4 R0 K5 - 0x4C140000, // 002F LDNIL R5 - 0x20100805, // 0030 NE R4 R4 R5 - 0x78120001, // 0031 JMPF R4 #0034 - 0x80060C00, // 0032 RET 1 K6 - 0x70020000, // 0033 JMP #0035 - 0x80060E00, // 0034 RET 1 K7 - 0x80000000, // 0035 RET 0 + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80000000, // 0002 RET 0 }) ) ); @@ -1562,61 +1471,101 @@ be_local_closure(Matter_TLV_item__encode_tag_len, /* name */ /******************************************************************** -** Solidified function: sort +** Solidified function: _cmp_gt ********************************************************************/ -be_local_closure(Matter_TLV_item_sort, /* name */ +be_local_closure(Matter_TLV_item__cmp_gt, /* name */ be_nested_proto( - 9, /* nstack */ - 1, /* argc */ - 4, /* varg */ + 4, /* nstack */ + 2, /* argc */ + 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_const_class(be_class_Matter_TLV_item), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(tag_vendor), /* K1 */ be_const_int(1), - /* K2 */ be_const_int(0), - /* K3 */ be_nested_str_weak(_cmp_gt), - /* K4 */ be_nested_str_weak(stop_iteration), + /* K2 */ be_nested_str_weak(tag_profile), + /* K3 */ be_const_int(0), + /* K4 */ be_nested_str_weak(tag_number), + /* K5 */ be_nested_str_weak(tag_sub), }), - be_str_weak(sort), + be_str_weak(_cmp_gt), &be_const_str_solidified, - ( &(const binstruction[33]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0x60080010, // 0001 GETGBL R2 G16 - 0x600C000C, // 0002 GETGBL R3 G12 - 0x5C100000, // 0003 MOVE R4 R0 - 0x7C0C0200, // 0004 CALL R3 1 - 0x040C0701, // 0005 SUB R3 R3 K1 - 0x400E0203, // 0006 CONNECT R3 K1 R3 - 0x7C080200, // 0007 CALL R2 1 - 0xA8020013, // 0008 EXBLK 0 #001D - 0x5C0C0400, // 0009 MOVE R3 R2 - 0x7C0C0000, // 000A CALL R3 0 - 0x94100003, // 000B GETIDX R4 R0 R3 - 0x5C140600, // 000C MOVE R5 R3 - 0x24180B02, // 000D GT R6 R5 K2 - 0x781A000B, // 000E JMPF R6 #001B - 0x04180B01, // 000F SUB R6 R5 K1 - 0x94180006, // 0010 GETIDX R6 R0 R6 - 0x8C180D03, // 0011 GETMET R6 R6 K3 - 0x5C200800, // 0012 MOVE R8 R4 - 0x7C180400, // 0013 CALL R6 2 - 0x24180D02, // 0014 GT R6 R6 K2 - 0x781A0004, // 0015 JMPF R6 #001B - 0x04180B01, // 0016 SUB R6 R5 K1 - 0x94180006, // 0017 GETIDX R6 R0 R6 - 0x98000A06, // 0018 SETIDX R0 R5 R6 - 0x04140B01, // 0019 SUB R5 R5 K1 - 0x7001FFF1, // 001A JMP #000D - 0x98000A04, // 001B SETIDX R0 R5 R4 - 0x7001FFEB, // 001C JMP #0009 - 0x58080004, // 001D LDCONST R2 K4 - 0xAC080200, // 001E CATCH R2 1 0 - 0xB0080000, // 001F RAISE 2 R0 R0 - 0x80040000, // 0020 RET 1 R0 + ( &(const binstruction[72]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x20080403, // 0002 NE R2 R2 R3 + 0x780A0012, // 0003 JMPF R2 #0017 + 0x88080300, // 0004 GETMBR R2 R1 K0 + 0x4C0C0000, // 0005 LDNIL R3 + 0x1C080403, // 0006 EQ R2 R2 R3 + 0x780A0000, // 0007 JMPF R2 #0009 + 0x80060200, // 0008 RET 1 K1 + 0x88080100, // 0009 GETMBR R2 R0 K0 + 0x880C0300, // 000A GETMBR R3 R1 K0 + 0x24080403, // 000B GT R2 R2 R3 + 0x780A0000, // 000C JMPF R2 #000E + 0x80060200, // 000D RET 1 K1 + 0x88080100, // 000E GETMBR R2 R0 K0 + 0x880C0300, // 000F GETMBR R3 R1 K0 + 0x1C080403, // 0010 EQ R2 R2 R3 + 0x780A0004, // 0011 JMPF R2 #0017 + 0x88080102, // 0012 GETMBR R2 R0 K2 + 0x880C0302, // 0013 GETMBR R3 R1 K2 + 0x24080403, // 0014 GT R2 R2 R3 + 0x780A0000, // 0015 JMPF R2 #0017 + 0x80060200, // 0016 RET 1 K1 + 0x88080102, // 0017 GETMBR R2 R0 K2 + 0x540DFFFE, // 0018 LDINT R3 -1 + 0x1C080403, // 0019 EQ R2 R2 R3 + 0x780A0005, // 001A JMPF R2 #0021 + 0x88080302, // 001B GETMBR R2 R1 K2 + 0x4C0C0000, // 001C LDNIL R3 + 0x1C080403, // 001D EQ R2 R2 R3 + 0x780A0000, // 001E JMPF R2 #0020 + 0x80060200, // 001F RET 1 K1 + 0x70020008, // 0020 JMP #002A + 0x88080102, // 0021 GETMBR R2 R0 K2 + 0x4C0C0000, // 0022 LDNIL R3 + 0x1C080403, // 0023 EQ R2 R2 R3 + 0x780A0004, // 0024 JMPF R2 #002A + 0x88080302, // 0025 GETMBR R2 R1 K2 + 0x540DFFFE, // 0026 LDINT R3 -1 + 0x1C080403, // 0027 EQ R2 R2 R3 + 0x780A0000, // 0028 JMPF R2 #002A + 0x80060600, // 0029 RET 1 K3 + 0x88080104, // 002A GETMBR R2 R0 K4 + 0x4C0C0000, // 002B LDNIL R3 + 0x20080403, // 002C NE R2 R2 R3 + 0x780A000A, // 002D JMPF R2 #0039 + 0x88080304, // 002E GETMBR R2 R1 K4 + 0x4C0C0000, // 002F LDNIL R3 + 0x1C080403, // 0030 EQ R2 R2 R3 + 0x780A0000, // 0031 JMPF R2 #0033 + 0x80060200, // 0032 RET 1 K1 + 0x88080104, // 0033 GETMBR R2 R0 K4 + 0x880C0304, // 0034 GETMBR R3 R1 K4 + 0x24080403, // 0035 GT R2 R2 R3 + 0x780A0000, // 0036 JMPF R2 #0038 + 0x80060200, // 0037 RET 1 K1 + 0x80060600, // 0038 RET 1 K3 + 0x88080105, // 0039 GETMBR R2 R0 K5 + 0x4C0C0000, // 003A LDNIL R3 + 0x20080403, // 003B NE R2 R2 R3 + 0x780A0009, // 003C JMPF R2 #0047 + 0x88080305, // 003D GETMBR R2 R1 K5 + 0x4C0C0000, // 003E LDNIL R3 + 0x1C080403, // 003F EQ R2 R2 R3 + 0x780A0000, // 0040 JMPF R2 #0042 + 0x80060200, // 0041 RET 1 K1 + 0x88080105, // 0042 GETMBR R2 R0 K5 + 0x880C0305, // 0043 GETMBR R3 R1 K5 + 0x24080403, // 0044 GT R2 R2 R3 + 0x780A0000, // 0045 JMPF R2 #0047 + 0x80060200, // 0046 RET 1 K1 + 0x80060600, // 0047 RET 1 K3 }) ) ); @@ -1624,153 +1573,165 @@ be_local_closure(Matter_TLV_item_sort, /* name */ /******************************************************************** -** Solidified function: parse +** Solidified function: _encode_tag ********************************************************************/ -be_local_closure(Matter_TLV_item_parse, /* name */ +be_local_closure(Matter_TLV_item__encode_tag, /* name */ be_nested_proto( - 10, /* nstack */ - 3, /* argc */ + 9, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[25]) { /* constants */ - /* K0 */ be_nested_str_weak(typ), - /* K1 */ be_nested_str_weak(TLV), - /* K2 */ be_nested_str_weak(_len), - /* K3 */ be_nested_str_weak(val), - /* K4 */ be_nested_str_weak(int64), - /* K5 */ be_nested_str_weak(frombytes), - /* K6 */ be_nested_str_weak(BFALSE), - /* K7 */ be_nested_str_weak(BTRUE), - /* K8 */ be_nested_str_weak(U8), - /* K9 */ be_nested_str_weak(I8), - /* K10 */ be_nested_str_weak(geti), - /* K11 */ be_nested_str_weak(get), - /* K12 */ be_nested_str_weak(FLOAT), - /* K13 */ be_nested_str_weak(getfloat), - /* K14 */ be_const_int(1), - /* K15 */ be_nested_str_weak(UTF8), - /* K16 */ be_nested_str_weak(asstring), - /* K17 */ be_nested_str_weak(NULL), - /* K18 */ be_nested_str_weak(EOC), - /* K19 */ be_nested_str_weak(tasmota), - /* K20 */ be_nested_str_weak(log), - /* K21 */ be_nested_str_weak(MTR_X3A_X20unexpected_X20eoc), - /* K22 */ be_const_int(3), - /* K23 */ be_nested_str_weak(MTR_X3A_X20unexpected_X20type_X3A_X20), - /* K24 */ be_nested_str_weak(next_idx), + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(tag_number), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(tag_vendor), + /* K3 */ be_nested_str_weak(add), + /* K4 */ be_nested_str_weak(typ), + /* K5 */ be_const_int(1), + /* K6 */ be_const_int(2), + /* K7 */ be_nested_str_weak(tag_profile), + /* K8 */ be_nested_str_weak(tag_sub), }), - be_str_weak(parse), + be_str_weak(_encode_tag), &be_const_str_solidified, - ( &(const binstruction[105]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x88100101, // 0001 GETMBR R4 R0 K1 - 0x88140902, // 0002 GETMBR R5 R4 K2 - 0x94140A03, // 0003 GETIDX R5 R5 R3 - 0x541A0007, // 0004 LDINT R6 8 - 0x1C180A06, // 0005 EQ R6 R5 R6 - 0x781A000A, // 0006 JMPF R6 #0012 - 0xB81A0800, // 0007 GETNGBL R6 K4 - 0x7C180000, // 0008 CALL R6 0 - 0x90020606, // 0009 SETMBR R0 K3 R6 - 0x88180103, // 000A GETMBR R6 R0 K3 - 0x8C180D05, // 000B GETMET R6 R6 K5 - 0x5C200200, // 000C MOVE R8 R1 - 0x5C240400, // 000D MOVE R9 R2 - 0x7C180600, // 000E CALL R6 3 - 0x541A0007, // 000F LDINT R6 8 - 0x00080406, // 0010 ADD R2 R2 R6 - 0x70020054, // 0011 JMP #0067 - 0x88180906, // 0012 GETMBR R6 R4 K6 - 0x1C180606, // 0013 EQ R6 R3 R6 - 0x741A0002, // 0014 JMPT R6 #0018 - 0x88180907, // 0015 GETMBR R6 R4 K7 - 0x1C180606, // 0016 EQ R6 R3 R6 - 0x781A0003, // 0017 JMPF R6 #001C - 0x88180907, // 0018 GETMBR R6 R4 K7 - 0x1C180606, // 0019 EQ R6 R3 R6 - 0x90020606, // 001A SETMBR R0 K3 R6 - 0x7002004A, // 001B JMP #0067 - 0x88180908, // 001C GETMBR R6 R4 K8 - 0x14180606, // 001D LT R6 R3 R6 - 0x781A000E, // 001E JMPF R6 #002E - 0x88180909, // 001F GETMBR R6 R4 K9 - 0x18180606, // 0020 LE R6 R3 R6 - 0x781A0004, // 0021 JMPF R6 #0027 - 0x8C18030A, // 0022 GETMET R6 R1 K10 - 0x5C200400, // 0023 MOVE R8 R2 - 0x5C240A00, // 0024 MOVE R9 R5 - 0x7C180600, // 0025 CALL R6 3 - 0x70020003, // 0026 JMP #002B - 0x8C18030B, // 0027 GETMET R6 R1 K11 - 0x5C200400, // 0028 MOVE R8 R2 - 0x5C240A00, // 0029 MOVE R9 R5 - 0x7C180600, // 002A CALL R6 3 - 0x90020606, // 002B SETMBR R0 K3 R6 - 0x00080405, // 002C ADD R2 R2 R5 - 0x70020038, // 002D JMP #0067 - 0x8818090C, // 002E GETMBR R6 R4 K12 - 0x1C180606, // 002F EQ R6 R3 R6 - 0x781A0006, // 0030 JMPF R6 #0038 - 0x8C18030D, // 0031 GETMET R6 R1 K13 - 0x5C200400, // 0032 MOVE R8 R2 - 0x7C180400, // 0033 CALL R6 2 - 0x90020606, // 0034 SETMBR R0 K3 R6 - 0x541A0003, // 0035 LDINT R6 4 - 0x00080406, // 0036 ADD R2 R2 R6 - 0x7002002E, // 0037 JMP #0067 - 0x5419FFF7, // 0038 LDINT R6 -8 - 0x28180A06, // 0039 GE R6 R5 R6 - 0x781A0016, // 003A JMPF R6 #0052 + ( &(const binstruction[133]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x20080403, // 0002 NE R2 R2 R3 + 0x780A0001, // 0003 JMPF R2 #0006 + 0x88080100, // 0004 GETMBR R2 R0 K0 + 0x70020000, // 0005 JMP #0007 + 0x58080001, // 0006 LDCONST R2 K1 + 0x540EFFFF, // 0007 LDINT R3 65536 + 0x280C0403, // 0008 GE R3 R2 R3 + 0x740E0002, // 0009 JMPT R3 #000D + 0x140C0501, // 000A LT R3 R2 K1 + 0x740E0000, // 000B JMPT R3 #000D + 0x500C0001, // 000C LDBOOL R3 0 1 + 0x500C0200, // 000D LDBOOL R3 1 0 + 0x58100001, // 000E LDCONST R4 K1 + 0x88140102, // 000F GETMBR R5 R0 K2 + 0x4C180000, // 0010 LDNIL R6 + 0x20140A06, // 0011 NE R5 R5 R6 + 0x78160026, // 0012 JMPF R5 #003A + 0x780E0012, // 0013 JMPF R3 #0027 + 0x8C140303, // 0014 GETMET R5 R1 K3 + 0x541E00DF, // 0015 LDINT R7 224 + 0x88200104, // 0016 GETMBR R8 R0 K4 + 0x001C0E08, // 0017 ADD R7 R7 R8 + 0x58200005, // 0018 LDCONST R8 K5 + 0x7C140600, // 0019 CALL R5 3 + 0x8C140303, // 001A GETMET R5 R1 K3 + 0x881C0102, // 001B GETMBR R7 R0 K2 + 0x58200006, // 001C LDCONST R8 K6 + 0x7C140600, // 001D CALL R5 3 + 0x8C140303, // 001E GETMET R5 R1 K3 + 0x881C0107, // 001F GETMBR R7 R0 K7 + 0x58200006, // 0020 LDCONST R8 K6 + 0x7C140600, // 0021 CALL R5 3 + 0x8C140303, // 0022 GETMET R5 R1 K3 + 0x881C0100, // 0023 GETMBR R7 R0 K0 + 0x54220003, // 0024 LDINT R8 4 + 0x7C140600, // 0025 CALL R5 3 + 0x70020011, // 0026 JMP #0039 + 0x8C140303, // 0027 GETMET R5 R1 K3 + 0x541E00BF, // 0028 LDINT R7 192 + 0x88200104, // 0029 GETMBR R8 R0 K4 + 0x001C0E08, // 002A ADD R7 R7 R8 + 0x58200005, // 002B LDCONST R8 K5 + 0x7C140600, // 002C CALL R5 3 + 0x8C140303, // 002D GETMET R5 R1 K3 + 0x881C0102, // 002E GETMBR R7 R0 K2 + 0x58200006, // 002F LDCONST R8 K6 + 0x7C140600, // 0030 CALL R5 3 + 0x8C140303, // 0031 GETMET R5 R1 K3 + 0x881C0107, // 0032 GETMBR R7 R0 K7 + 0x58200006, // 0033 LDCONST R8 K6 + 0x7C140600, // 0034 CALL R5 3 + 0x8C140303, // 0035 GETMET R5 R1 K3 + 0x881C0100, // 0036 GETMBR R7 R0 K0 + 0x58200006, // 0037 LDCONST R8 K6 + 0x7C140600, // 0038 CALL R5 3 + 0x70020049, // 0039 JMP #0084 + 0x88140107, // 003A GETMBR R5 R0 K7 0x5419FFFE, // 003B LDINT R6 -1 - 0x18180A06, // 003C LE R6 R5 R6 - 0x781A0013, // 003D JMPF R6 #0052 - 0x8C18030B, // 003E GETMET R6 R1 K11 - 0x5C200400, // 003F MOVE R8 R2 - 0x44240A00, // 0040 NEG R9 R5 - 0x7C180600, // 0041 CALL R6 3 - 0x441C0A00, // 0042 NEG R7 R5 - 0x00080407, // 0043 ADD R2 R2 R7 - 0x001C0406, // 0044 ADD R7 R2 R6 - 0x041C0F0E, // 0045 SUB R7 R7 K14 - 0x401C0407, // 0046 CONNECT R7 R2 R7 - 0x941C0207, // 0047 GETIDX R7 R1 R7 - 0x90020607, // 0048 SETMBR R0 K3 R7 - 0x00080406, // 0049 ADD R2 R2 R6 - 0x881C090F, // 004A GETMBR R7 R4 K15 - 0x181C0607, // 004B LE R7 R3 R7 - 0x781E0003, // 004C JMPF R7 #0051 - 0x881C0103, // 004D GETMBR R7 R0 K3 - 0x8C1C0F10, // 004E GETMET R7 R7 K16 - 0x7C1C0200, // 004F CALL R7 1 - 0x90020607, // 0050 SETMBR R0 K3 R7 - 0x70020014, // 0051 JMP #0067 - 0x88180911, // 0052 GETMBR R6 R4 K17 - 0x1C180606, // 0053 EQ R6 R3 R6 - 0x781A0000, // 0054 JMPF R6 #0056 - 0x70020010, // 0055 JMP #0067 - 0x88180912, // 0056 GETMBR R6 R4 K18 - 0x1C180606, // 0057 EQ R6 R3 R6 - 0x781A0005, // 0058 JMPF R6 #005F - 0xB81A2600, // 0059 GETNGBL R6 K19 - 0x8C180D14, // 005A GETMET R6 R6 K20 - 0x58200015, // 005B LDCONST R8 K21 - 0x58240016, // 005C LDCONST R9 K22 - 0x7C180600, // 005D CALL R6 3 - 0x70020007, // 005E JMP #0067 - 0xB81A2600, // 005F GETNGBL R6 K19 - 0x8C180D14, // 0060 GETMET R6 R6 K20 - 0x60200008, // 0061 GETGBL R8 G8 - 0x5C240600, // 0062 MOVE R9 R3 - 0x7C200200, // 0063 CALL R8 1 - 0x00222E08, // 0064 ADD R8 K23 R8 - 0x58240016, // 0065 LDCONST R9 K22 - 0x7C180600, // 0066 CALL R6 3 - 0x90023002, // 0067 SETMBR R0 K24 R2 - 0x80040400, // 0068 RET 1 R2 + 0x1C140A06, // 003C EQ R5 R5 R6 + 0x78160016, // 003D JMPF R5 #0055 + 0x780E000A, // 003E JMPF R3 #004A + 0x8C140303, // 003F GETMET R5 R1 K3 + 0x541E005F, // 0040 LDINT R7 96 + 0x88200104, // 0041 GETMBR R8 R0 K4 + 0x001C0E08, // 0042 ADD R7 R7 R8 + 0x58200005, // 0043 LDCONST R8 K5 + 0x7C140600, // 0044 CALL R5 3 + 0x8C140303, // 0045 GETMET R5 R1 K3 + 0x881C0100, // 0046 GETMBR R7 R0 K0 + 0x54220003, // 0047 LDINT R8 4 + 0x7C140600, // 0048 CALL R5 3 + 0x70020009, // 0049 JMP #0054 + 0x8C140303, // 004A GETMET R5 R1 K3 + 0x541E003F, // 004B LDINT R7 64 + 0x88200104, // 004C GETMBR R8 R0 K4 + 0x001C0E08, // 004D ADD R7 R7 R8 + 0x58200005, // 004E LDCONST R8 K5 + 0x7C140600, // 004F CALL R5 3 + 0x8C140303, // 0050 GETMET R5 R1 K3 + 0x881C0100, // 0051 GETMBR R7 R0 K0 + 0x58200006, // 0052 LDCONST R8 K6 + 0x7C140600, // 0053 CALL R5 3 + 0x7002002E, // 0054 JMP #0084 + 0x88140107, // 0055 GETMBR R5 R0 K7 + 0x4C180000, // 0056 LDNIL R6 + 0x20140A06, // 0057 NE R5 R5 R6 + 0x78160016, // 0058 JMPF R5 #0070 + 0x780E000A, // 0059 JMPF R3 #0065 + 0x8C140303, // 005A GETMET R5 R1 K3 + 0x541E009F, // 005B LDINT R7 160 + 0x88200104, // 005C GETMBR R8 R0 K4 + 0x001C0E08, // 005D ADD R7 R7 R8 + 0x58200005, // 005E LDCONST R8 K5 + 0x7C140600, // 005F CALL R5 3 + 0x8C140303, // 0060 GETMET R5 R1 K3 + 0x881C0100, // 0061 GETMBR R7 R0 K0 + 0x54220003, // 0062 LDINT R8 4 + 0x7C140600, // 0063 CALL R5 3 + 0x70020009, // 0064 JMP #006F + 0x8C140303, // 0065 GETMET R5 R1 K3 + 0x541E007F, // 0066 LDINT R7 128 + 0x88200104, // 0067 GETMBR R8 R0 K4 + 0x001C0E08, // 0068 ADD R7 R7 R8 + 0x58200005, // 0069 LDCONST R8 K5 + 0x7C140600, // 006A CALL R5 3 + 0x8C140303, // 006B GETMET R5 R1 K3 + 0x881C0100, // 006C GETMBR R7 R0 K0 + 0x58200006, // 006D LDCONST R8 K6 + 0x7C140600, // 006E CALL R5 3 + 0x70020013, // 006F JMP #0084 + 0x88140108, // 0070 GETMBR R5 R0 K8 + 0x4C180000, // 0071 LDNIL R6 + 0x20140A06, // 0072 NE R5 R5 R6 + 0x7816000A, // 0073 JMPF R5 #007F + 0x8C140303, // 0074 GETMET R5 R1 K3 + 0x541E001F, // 0075 LDINT R7 32 + 0x88200104, // 0076 GETMBR R8 R0 K4 + 0x001C0E08, // 0077 ADD R7 R7 R8 + 0x58200005, // 0078 LDCONST R8 K5 + 0x7C140600, // 0079 CALL R5 3 + 0x8C140303, // 007A GETMET R5 R1 K3 + 0x881C0108, // 007B GETMBR R7 R0 K8 + 0x58200005, // 007C LDCONST R8 K5 + 0x7C140600, // 007D CALL R5 3 + 0x70020004, // 007E JMP #0084 + 0x8C140303, // 007F GETMET R5 R1 K3 + 0x881C0104, // 0080 GETMBR R7 R0 K4 + 0x001E0207, // 0081 ADD R7 K1 R7 + 0x58200005, // 0082 LDCONST R8 K5 + 0x7C140600, // 0083 CALL R5 3 + 0x80000000, // 0084 RET 0 }) ) ); @@ -1778,23 +1739,224 @@ be_local_closure(Matter_TLV_item_parse, /* name */ /******************************************************************** -** Solidified function: to_TLV +** Solidified function: tostring ********************************************************************/ -be_local_closure(Matter_TLV_item_to_TLV, /* name */ +be_local_closure(Matter_TLV_item_tostring, /* name */ be_nested_proto( - 1, /* nstack */ - 1, /* argc */ + 7, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(to_TLV), + 1, /* has constants */ + ( &(const bvalue[34]) { /* constants */ + /* K0 */ be_nested_str_weak(), + /* K1 */ be_nested_str_weak(tag_profile), + /* K2 */ be_nested_str_weak(Matter_X3A_X3A), + /* K3 */ be_nested_str_weak(tag_number), + /* K4 */ be_nested_str_weak(0x_X2508X_X20), + /* K5 */ be_nested_str_weak(tag_vendor), + /* K6 */ be_nested_str_weak(0x_X2504X_X3A_X3A), + /* K7 */ be_nested_str_weak(0x_X2504X_X3A), + /* K8 */ be_nested_str_weak(tag_sub), + /* K9 */ be_nested_str_weak(_X25i_X20), + /* K10 */ be_const_int(0), + /* K11 */ be_nested_str_weak(_X3D_X20), + /* K12 */ be_nested_str_weak(val), + /* K13 */ be_nested_str_weak(int), + /* K14 */ be_nested_str_weak(_X25i), + /* K15 */ be_nested_str_weak(typ), + /* K16 */ be_nested_str_weak(TLV), + /* K17 */ be_nested_str_weak(U1), + /* K18 */ be_nested_str_weak(U8), + /* K19 */ be_nested_str_weak(U), + /* K20 */ be_nested_str_weak(bool), + /* K21 */ be_nested_str_weak(true), + /* K22 */ be_nested_str_weak(false), + /* K23 */ be_nested_str_weak(null), + /* K24 */ be_nested_str_weak(real), + /* K25 */ be_nested_str_weak(_X25g), + /* K26 */ be_nested_str_weak(string), + /* K27 */ be_nested_str_weak(_X22_X25s_X22), + /* K28 */ be_nested_str_weak(int64), + /* K29 */ be_nested_str_weak(tostring), + /* K30 */ be_nested_str_weak(instance), + /* K31 */ be_nested_str_weak(_X25s), + /* K32 */ be_nested_str_weak(tohex), + /* K33 */ be_nested_str_weak(_X20), + }), + be_str_weak(tostring), &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80040000, // 0000 RET 1 R0 + ( &(const binstruction[167]) { /* code */ + 0x58080000, // 0000 LDCONST R2 K0 + 0xA802009C, // 0001 EXBLK 0 #009F + 0x500C0200, // 0002 LDBOOL R3 1 0 + 0x200C0203, // 0003 NE R3 R1 R3 + 0x780E0038, // 0004 JMPF R3 #003E + 0x880C0101, // 0005 GETMBR R3 R0 K1 + 0x5411FFFE, // 0006 LDINT R4 -1 + 0x1C0C0604, // 0007 EQ R3 R3 R4 + 0x780E000A, // 0008 JMPF R3 #0014 + 0x00080502, // 0009 ADD R2 R2 K2 + 0x880C0103, // 000A GETMBR R3 R0 K3 + 0x4C100000, // 000B LDNIL R4 + 0x200C0604, // 000C NE R3 R3 R4 + 0x780E0004, // 000D JMPF R3 #0013 + 0x600C0018, // 000E GETGBL R3 G24 + 0x58100004, // 000F LDCONST R4 K4 + 0x88140103, // 0010 GETMBR R5 R0 K3 + 0x7C0C0400, // 0011 CALL R3 2 + 0x00080403, // 0012 ADD R2 R2 R3 + 0x70020023, // 0013 JMP #0038 + 0x880C0105, // 0014 GETMBR R3 R0 K5 + 0x4C100000, // 0015 LDNIL R4 + 0x200C0604, // 0016 NE R3 R3 R4 + 0x780E0004, // 0017 JMPF R3 #001D + 0x600C0018, // 0018 GETGBL R3 G24 + 0x58100006, // 0019 LDCONST R4 K6 + 0x88140105, // 001A GETMBR R5 R0 K5 + 0x7C0C0400, // 001B CALL R3 2 + 0x00080403, // 001C ADD R2 R2 R3 + 0x880C0101, // 001D GETMBR R3 R0 K1 + 0x4C100000, // 001E LDNIL R4 + 0x200C0604, // 001F NE R3 R3 R4 + 0x780E0004, // 0020 JMPF R3 #0026 + 0x600C0018, // 0021 GETGBL R3 G24 + 0x58100007, // 0022 LDCONST R4 K7 + 0x88140101, // 0023 GETMBR R5 R0 K1 + 0x7C0C0400, // 0024 CALL R3 2 + 0x00080403, // 0025 ADD R2 R2 R3 + 0x880C0103, // 0026 GETMBR R3 R0 K3 + 0x4C100000, // 0027 LDNIL R4 + 0x200C0604, // 0028 NE R3 R3 R4 + 0x780E0004, // 0029 JMPF R3 #002F + 0x600C0018, // 002A GETGBL R3 G24 + 0x58100004, // 002B LDCONST R4 K4 + 0x88140103, // 002C GETMBR R5 R0 K3 + 0x7C0C0400, // 002D CALL R3 2 + 0x00080403, // 002E ADD R2 R2 R3 + 0x880C0108, // 002F GETMBR R3 R0 K8 + 0x4C100000, // 0030 LDNIL R4 + 0x200C0604, // 0031 NE R3 R3 R4 + 0x780E0004, // 0032 JMPF R3 #0038 + 0x600C0018, // 0033 GETGBL R3 G24 + 0x58100009, // 0034 LDCONST R4 K9 + 0x88140108, // 0035 GETMBR R5 R0 K8 + 0x7C0C0400, // 0036 CALL R3 2 + 0x00080403, // 0037 ADD R2 R2 R3 + 0x600C000C, // 0038 GETGBL R3 G12 + 0x5C100400, // 0039 MOVE R4 R2 + 0x7C0C0200, // 003A CALL R3 1 + 0x240C070A, // 003B GT R3 R3 K10 + 0x780E0000, // 003C JMPF R3 #003E + 0x0008050B, // 003D ADD R2 R2 K11 + 0x600C0004, // 003E GETGBL R3 G4 + 0x8810010C, // 003F GETMBR R4 R0 K12 + 0x7C0C0200, // 0040 CALL R3 1 + 0x1C0C070D, // 0041 EQ R3 R3 K13 + 0x780E0010, // 0042 JMPF R3 #0054 + 0x600C0018, // 0043 GETGBL R3 G24 + 0x5810000E, // 0044 LDCONST R4 K14 + 0x8814010C, // 0045 GETMBR R5 R0 K12 + 0x7C0C0400, // 0046 CALL R3 2 + 0x00080403, // 0047 ADD R2 R2 R3 + 0x880C010F, // 0048 GETMBR R3 R0 K15 + 0x88100110, // 0049 GETMBR R4 R0 K16 + 0x88100911, // 004A GETMBR R4 R4 K17 + 0x280C0604, // 004B GE R3 R3 R4 + 0x780E0005, // 004C JMPF R3 #0053 + 0x880C010F, // 004D GETMBR R3 R0 K15 + 0x88100110, // 004E GETMBR R4 R0 K16 + 0x88100912, // 004F GETMBR R4 R4 K18 + 0x180C0604, // 0050 LE R3 R3 R4 + 0x780E0000, // 0051 JMPF R3 #0053 + 0x00080513, // 0052 ADD R2 R2 K19 + 0x70020048, // 0053 JMP #009D + 0x600C0004, // 0054 GETGBL R3 G4 + 0x8810010C, // 0055 GETMBR R4 R0 K12 + 0x7C0C0200, // 0056 CALL R3 1 + 0x1C0C0714, // 0057 EQ R3 R3 K20 + 0x780E0006, // 0058 JMPF R3 #0060 + 0x880C010C, // 0059 GETMBR R3 R0 K12 + 0x780E0001, // 005A JMPF R3 #005D + 0x580C0015, // 005B LDCONST R3 K21 + 0x70020000, // 005C JMP #005E + 0x580C0016, // 005D LDCONST R3 K22 + 0x00080403, // 005E ADD R2 R2 R3 + 0x7002003C, // 005F JMP #009D + 0x880C010C, // 0060 GETMBR R3 R0 K12 + 0x4C100000, // 0061 LDNIL R4 + 0x1C0C0604, // 0062 EQ R3 R3 R4 + 0x780E0001, // 0063 JMPF R3 #0066 + 0x00080517, // 0064 ADD R2 R2 K23 + 0x70020036, // 0065 JMP #009D + 0x600C0004, // 0066 GETGBL R3 G4 + 0x8810010C, // 0067 GETMBR R4 R0 K12 + 0x7C0C0200, // 0068 CALL R3 1 + 0x1C0C0718, // 0069 EQ R3 R3 K24 + 0x780E0005, // 006A JMPF R3 #0071 + 0x600C0018, // 006B GETGBL R3 G24 + 0x58100019, // 006C LDCONST R4 K25 + 0x8814010C, // 006D GETMBR R5 R0 K12 + 0x7C0C0400, // 006E CALL R3 2 + 0x00080403, // 006F ADD R2 R2 R3 + 0x7002002B, // 0070 JMP #009D + 0x600C0004, // 0071 GETGBL R3 G4 + 0x8810010C, // 0072 GETMBR R4 R0 K12 + 0x7C0C0200, // 0073 CALL R3 1 + 0x1C0C071A, // 0074 EQ R3 R3 K26 + 0x780E0005, // 0075 JMPF R3 #007C + 0x600C0018, // 0076 GETGBL R3 G24 + 0x5810001B, // 0077 LDCONST R4 K27 + 0x8814010C, // 0078 GETMBR R5 R0 K12 + 0x7C0C0400, // 0079 CALL R3 2 + 0x00080403, // 007A ADD R2 R2 R3 + 0x70020020, // 007B JMP #009D + 0x600C000F, // 007C GETGBL R3 G15 + 0x8810010C, // 007D GETMBR R4 R0 K12 + 0xB8163800, // 007E GETNGBL R5 K28 + 0x7C0C0400, // 007F CALL R3 2 + 0x780E000F, // 0080 JMPF R3 #0091 + 0x880C010C, // 0081 GETMBR R3 R0 K12 + 0x8C0C071D, // 0082 GETMET R3 R3 K29 + 0x7C0C0200, // 0083 CALL R3 1 + 0x00080403, // 0084 ADD R2 R2 R3 + 0x880C010F, // 0085 GETMBR R3 R0 K15 + 0x88100110, // 0086 GETMBR R4 R0 K16 + 0x88100911, // 0087 GETMBR R4 R4 K17 + 0x280C0604, // 0088 GE R3 R3 R4 + 0x780E0005, // 0089 JMPF R3 #0090 + 0x880C010F, // 008A GETMBR R3 R0 K15 + 0x88100110, // 008B GETMBR R4 R0 K16 + 0x88100912, // 008C GETMBR R4 R4 K18 + 0x180C0604, // 008D LE R3 R3 R4 + 0x780E0000, // 008E JMPF R3 #0090 + 0x00080513, // 008F ADD R2 R2 K19 + 0x7002000B, // 0090 JMP #009D + 0x600C0004, // 0091 GETGBL R3 G4 + 0x8810010C, // 0092 GETMBR R4 R0 K12 + 0x7C0C0200, // 0093 CALL R3 1 + 0x1C0C071E, // 0094 EQ R3 R3 K30 + 0x780E0006, // 0095 JMPF R3 #009D + 0x600C0018, // 0096 GETGBL R3 G24 + 0x5810001F, // 0097 LDCONST R4 K31 + 0x8814010C, // 0098 GETMBR R5 R0 K12 + 0x8C140B20, // 0099 GETMET R5 R5 K32 + 0x7C140200, // 009A CALL R5 1 + 0x7C0C0400, // 009B CALL R3 2 + 0x00080403, // 009C ADD R2 R2 R3 + 0xA8040001, // 009D EXBLK 1 1 + 0x70020006, // 009E JMP #00A6 + 0xAC0C0002, // 009F CATCH R3 0 2 + 0x70020003, // 00A0 JMP #00A5 + 0x00140721, // 00A1 ADD R5 R3 K33 + 0x00140A04, // 00A2 ADD R5 R5 R4 + 0x80040A00, // 00A3 RET 1 R5 + 0x70020000, // 00A4 JMP #00A6 + 0xB0080000, // 00A5 RAISE 2 R0 R0 + 0x80040400, // 00A6 RET 1 R2 }) ) ); @@ -1802,94 +1964,30 @@ be_local_closure(Matter_TLV_item_to_TLV, /* name */ /******************************************************************** -** Solidified class: Matter_TLV_item -********************************************************************/ -be_local_class(Matter_TLV_item, - 8, - NULL, - be_nested_map(25, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(set_parent, -1), be_const_closure(Matter_TLV_item_set_parent_closure) }, - { be_const_key_weak(create_TLV, -1), be_const_static_closure(Matter_TLV_item_create_TLV_closure) }, - { be_const_key_weak(next_idx, -1), be_const_var(1) }, - { be_const_key_weak(TLV, -1), be_const_class(be_class_Matter_TLV) }, - { be_const_key_weak(tag_vendor, 22), be_const_var(2) }, - { be_const_key_weak(set_anonymoustag, 17), be_const_closure(Matter_TLV_item_set_anonymoustag_closure) }, - { be_const_key_weak(val, -1), be_const_var(7) }, - { be_const_key_weak(to_TLV, -1), be_const_closure(Matter_TLV_item_to_TLV_closure) }, - { be_const_key_weak(parse, -1), be_const_closure(Matter_TLV_item_parse_closure) }, - { be_const_key_weak(_cmp_gt, 7), be_const_closure(Matter_TLV_item__cmp_gt_closure) }, - { be_const_key_weak(tag_profile, -1), be_const_var(3) }, - { be_const_key_weak(encode_len, 10), be_const_closure(Matter_TLV_item_encode_len_closure) }, - { be_const_key_weak(set_contextspecific, 8), be_const_closure(Matter_TLV_item_set_contextspecific_closure) }, - { be_const_key_weak(set_fulltag, -1), be_const_closure(Matter_TLV_item_set_fulltag_closure) }, - { be_const_key_weak(parent, -1), be_const_var(0) }, - { be_const_key_weak(_encode_tag_len, 19), be_const_closure(Matter_TLV_item__encode_tag_len_closure) }, - { be_const_key_weak(tag_sub, -1), be_const_var(5) }, - { be_const_key_weak(init, 23), be_const_closure(Matter_TLV_item_init_closure) }, - { be_const_key_weak(tlv2raw, -1), be_const_closure(Matter_TLV_item_tlv2raw_closure) }, - { be_const_key_weak(tostring, -1), be_const_closure(Matter_TLV_item_tostring_closure) }, - { be_const_key_weak(set_commonprofile, 15), be_const_closure(Matter_TLV_item_set_commonprofile_closure) }, - { be_const_key_weak(sort, -1), be_const_static_closure(Matter_TLV_item_sort_closure) }, - { be_const_key_weak(_encode_tag, -1), be_const_closure(Matter_TLV_item__encode_tag_closure) }, - { be_const_key_weak(tag_number, 16), be_const_var(4) }, - { be_const_key_weak(typ, 3), be_const_var(6) }, - })), - be_str_weak(Matter_TLV_item) -); -/*******************************************************************/ - -void be_load_Matter_TLV_item_class(bvm *vm) { - be_pushntvclass(vm, &be_class_Matter_TLV_item); - be_setglobal(vm, "Matter_TLV_item"); - be_pop(vm, 1); -} - -extern const bclass be_class_Matter_TLV_list; - -/******************************************************************** -** Solidified function: add_obj +** Solidified function: set_commonprofile ********************************************************************/ -be_local_closure(Matter_TLV_list_add_obj, /* name */ +be_local_closure(Matter_TLV_item_set_commonprofile, /* name */ be_nested_proto( - 7, /* nstack */ - 3, /* argc */ + 6, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(val), - /* K1 */ be_nested_str_weak(push), - /* K2 */ be_nested_str_weak(to_TLV), - /* K3 */ be_nested_str_weak(tag_sub), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(set_fulltag), }), - be_str_weak(add_obj), + be_str_weak(set_commonprofile), &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0x4C0C0000, // 0000 LDNIL R3 - 0x200C0403, // 0001 NE R3 R2 R3 - 0x780E0010, // 0002 JMPF R3 #0014 - 0x600C000F, // 0003 GETGBL R3 G15 - 0x5C100400, // 0004 MOVE R4 R2 - 0x60140015, // 0005 GETGBL R5 G21 - 0x7C0C0400, // 0006 CALL R3 2 - 0x780E0004, // 0007 JMPF R3 #000D - 0x880C0100, // 0008 GETMBR R3 R0 K0 - 0x8C0C0701, // 0009 GETMET R3 R3 K1 - 0x5C140400, // 000A MOVE R5 R2 - 0x7C0C0400, // 000B CALL R3 2 - 0x70020006, // 000C JMP #0014 - 0x8C0C0502, // 000D GETMET R3 R2 K2 - 0x7C0C0200, // 000E CALL R3 1 - 0x900E0601, // 000F SETMBR R3 K3 R1 - 0x88100100, // 0010 GETMBR R4 R0 K0 - 0x8C100901, // 0011 GETMET R4 R4 K1 - 0x5C180600, // 0012 MOVE R6 R3 - 0x7C100400, // 0013 CALL R4 2 - 0x80040000, // 0014 RET 1 R0 + ( &(const binstruction[ 6]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x5411FFFE, // 0002 LDINT R4 -1 + 0x4C140000, // 0003 LDNIL R5 + 0x7C040800, // 0004 CALL R1 4 + 0x80000000, // 0005 RET 0 }) ) ); @@ -1897,11 +1995,11 @@ be_local_closure(Matter_TLV_list_add_obj, /* name */ /******************************************************************** -** Solidified function: add_struct +** Solidified function: init ********************************************************************/ -be_local_closure(Matter_TLV_list_add_struct, /* name */ +be_local_closure(Matter_TLV_item_init, /* name */ be_nested_proto( - 6, /* nstack */ + 2, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1909,26 +2007,14 @@ be_local_closure(Matter_TLV_list_add_struct, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(TLV), - /* K1 */ be_nested_str_weak(Matter_TLV_struct), - /* K2 */ be_nested_str_weak(tag_sub), - /* K3 */ be_nested_str_weak(val), - /* K4 */ be_nested_str_weak(push), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(parent), }), - be_str_weak(add_struct), + be_str_weak(init), &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x5C100000, // 0002 MOVE R4 R0 - 0x7C080400, // 0003 CALL R2 2 - 0x900A0401, // 0004 SETMBR R2 K2 R1 - 0x880C0103, // 0005 GETMBR R3 R0 K3 - 0x8C0C0704, // 0006 GETMET R3 R3 K4 - 0x5C140400, // 0007 MOVE R5 R2 - 0x7C0C0400, // 0008 CALL R3 2 - 0x80040400, // 0009 RET 1 R2 + ( &(const binstruction[ 2]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x80000000, // 0001 RET 0 }) ) ); @@ -1936,12 +2022,64 @@ be_local_closure(Matter_TLV_list_add_struct, /* name */ /******************************************************************** -** Solidified function: push +** Solidified class: Matter_TLV_item ********************************************************************/ -be_local_closure(Matter_TLV_list_push, /* name */ +be_local_class(Matter_TLV_item, + 8, + NULL, + be_nested_map(31, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(is_array, 17), be_const_bool(0) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_TLV_item_init_closure) }, + { be_const_key_weak(set_parent, -1), be_const_closure(Matter_TLV_item_set_parent_closure) }, + { be_const_key_weak(set_fulltag, -1), be_const_closure(Matter_TLV_item_set_fulltag_closure) }, + { be_const_key_weak(typ, -1), be_const_var(6) }, + { be_const_key_weak(parse, 30), be_const_closure(Matter_TLV_item_parse_closure) }, + { be_const_key_weak(parent, 22), be_const_var(0) }, + { be_const_key_weak(to_str_val, -1), be_const_closure(Matter_TLV_item_to_str_val_closure) }, + { be_const_key_weak(encode_len, 4), be_const_closure(Matter_TLV_item_encode_len_closure) }, + { be_const_key_weak(TLV, 20), be_const_class(be_class_Matter_TLV) }, + { be_const_key_weak(reset, 0), be_const_closure(Matter_TLV_item_reset_closure) }, + { be_const_key_weak(tag_profile, -1), be_const_var(3) }, + { be_const_key_weak(create_TLV, -1), be_const_static_closure(Matter_TLV_item_create_TLV_closure) }, + { be_const_key_weak(tag_sub, -1), be_const_var(5) }, + { be_const_key_weak(tag_vendor, -1), be_const_var(2) }, + { be_const_key_weak(tostring, -1), be_const_closure(Matter_TLV_item_tostring_closure) }, + { be_const_key_weak(val, 5), be_const_var(7) }, + { be_const_key_weak(_encode_tag, -1), be_const_closure(Matter_TLV_item__encode_tag_closure) }, + { be_const_key_weak(_cmp_gt, -1), be_const_closure(Matter_TLV_item__cmp_gt_closure) }, + { be_const_key_weak(_encode_tag_len, 25), be_const_closure(Matter_TLV_item__encode_tag_len_closure) }, + { be_const_key_weak(is_struct, -1), be_const_bool(0) }, + { be_const_key_weak(tlv2raw, -1), be_const_closure(Matter_TLV_item_tlv2raw_closure) }, + { be_const_key_weak(sort, -1), be_const_static_closure(Matter_TLV_item_sort_closure) }, + { be_const_key_weak(is_list, -1), be_const_bool(0) }, + { be_const_key_weak(to_TLV, 18), be_const_closure(Matter_TLV_item_to_TLV_closure) }, + { be_const_key_weak(set, -1), be_const_closure(Matter_TLV_item_set_closure) }, + { be_const_key_weak(set_anonymoustag, 15), be_const_closure(Matter_TLV_item_set_anonymoustag_closure) }, + { be_const_key_weak(set_commonprofile, -1), be_const_closure(Matter_TLV_item_set_commonprofile_closure) }, + { be_const_key_weak(tag_number, -1), be_const_var(4) }, + { be_const_key_weak(next_idx, 1), be_const_var(1) }, + { be_const_key_weak(set_contextspecific, -1), be_const_closure(Matter_TLV_item_set_contextspecific_closure) }, + })), + be_str_weak(Matter_TLV_item) +); +/*******************************************************************/ + +void be_load_Matter_TLV_item_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Matter_TLV_item); + be_setglobal(vm, "Matter_TLV_item"); + be_pop(vm, 1); +} + +extern const bclass be_class_Matter_TLV_list; + +/******************************************************************** +** Solidified function: findsubval +********************************************************************/ +be_local_closure(Matter_TLV_list_findsubval, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 6, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -1949,17 +2087,21 @@ be_local_closure(Matter_TLV_list_push, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(val), - /* K1 */ be_nested_str_weak(push), + /* K0 */ be_nested_str_weak(findsub), + /* K1 */ be_nested_str_weak(val), }), - be_str_weak(push), + be_str_weak(findsubval), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x5C100200, // 0002 MOVE R4 R1 - 0x7C080400, // 0003 CALL R2 2 - 0x80000000, // 0004 RET 0 + ( &(const binstruction[ 9]) { /* code */ + 0x8C0C0100, // 0000 GETMET R3 R0 K0 + 0x5C140200, // 0001 MOVE R5 R1 + 0x7C0C0400, // 0002 CALL R3 2 + 0x4C100000, // 0003 LDNIL R4 + 0x20100604, // 0004 NE R4 R3 R4 + 0x78120001, // 0005 JMPF R4 #0008 + 0x88100701, // 0006 GETMBR R4 R3 K1 + 0x80040800, // 0007 RET 1 R4 + 0x80040400, // 0008 RET 1 R2 }) ) ); @@ -1967,11 +2109,11 @@ be_local_closure(Matter_TLV_list_push, /* name */ /******************************************************************** -** Solidified function: getsubval +** Solidified function: tlv2raw ********************************************************************/ -be_local_closure(Matter_TLV_list_getsubval, /* name */ +be_local_closure(Matter_TLV_list_tlv2raw, /* name */ be_nested_proto( - 5, /* nstack */ + 8, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1979,18 +2121,66 @@ be_local_closure(Matter_TLV_list_getsubval, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(getsub), + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(_encode_tag), /* K1 */ be_nested_str_weak(val), + /* K2 */ be_nested_str_weak(is_struct), + /* K3 */ be_nested_str_weak(copy), + /* K4 */ be_nested_str_weak(sort), + /* K5 */ be_nested_str_weak(tlv2raw), + /* K6 */ be_nested_str_weak(stop_iteration), + /* K7 */ be_nested_str_weak(add), + /* K8 */ be_nested_str_weak(TLV), + /* K9 */ be_nested_str_weak(EOC), + /* K10 */ be_const_int(1), }), - be_str_weak(getsubval), + be_str_weak(tlv2raw), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C080400, // 0002 CALL R2 2 - 0x88080501, // 0003 GETMBR R2 R2 K1 - 0x80040400, // 0004 RET 1 R2 + ( &(const binstruction[44]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x1C080202, // 0001 EQ R2 R1 R2 + 0x780A0002, // 0002 JMPF R2 #0006 + 0x60080015, // 0003 GETGBL R2 G21 + 0x7C080000, // 0004 CALL R2 0 + 0x5C040400, // 0005 MOVE R1 R2 + 0x8C080100, // 0006 GETMET R2 R0 K0 + 0x5C100200, // 0007 MOVE R4 R1 + 0x7C080400, // 0008 CALL R2 2 + 0x88080101, // 0009 GETMBR R2 R0 K1 + 0x880C0102, // 000A GETMBR R3 R0 K2 + 0x780E0005, // 000B JMPF R3 #0012 + 0x8C0C0503, // 000C GETMET R3 R2 K3 + 0x7C0C0200, // 000D CALL R3 1 + 0x5C080600, // 000E MOVE R2 R3 + 0x8C0C0104, // 000F GETMET R3 R0 K4 + 0x5C140400, // 0010 MOVE R5 R2 + 0x7C0C0400, // 0011 CALL R3 2 + 0x600C0010, // 0012 GETGBL R3 G16 + 0x5C100400, // 0013 MOVE R4 R2 + 0x7C0C0200, // 0014 CALL R3 1 + 0xA802000C, // 0015 EXBLK 0 #0023 + 0x5C100600, // 0016 MOVE R4 R3 + 0x7C100000, // 0017 CALL R4 0 + 0x6014000F, // 0018 GETGBL R5 G15 + 0x5C180800, // 0019 MOVE R6 R4 + 0x601C0015, // 001A GETGBL R7 G21 + 0x7C140400, // 001B CALL R5 2 + 0x78160001, // 001C JMPF R5 #001F + 0x40140204, // 001D CONNECT R5 R1 R4 + 0x70020002, // 001E JMP #0022 + 0x8C140905, // 001F GETMET R5 R4 K5 + 0x5C1C0200, // 0020 MOVE R7 R1 + 0x7C140400, // 0021 CALL R5 2 + 0x7001FFF2, // 0022 JMP #0016 + 0x580C0006, // 0023 LDCONST R3 K6 + 0xAC0C0200, // 0024 CATCH R3 1 0 + 0xB0080000, // 0025 RAISE 2 R0 R0 + 0x8C0C0307, // 0026 GETMET R3 R1 K7 + 0x88140108, // 0027 GETMBR R5 R0 K8 + 0x88140B09, // 0028 GETMBR R5 R5 K9 + 0x5818000A, // 0029 LDCONST R6 K10 + 0x7C0C0600, // 002A CALL R3 3 + 0x80040200, // 002B RET 1 R1 }) ) ); @@ -1998,12 +2188,12 @@ be_local_closure(Matter_TLV_list_getsubval, /* name */ /******************************************************************** -** Solidified function: setitem +** Solidified function: to_str_val ********************************************************************/ -be_local_closure(Matter_TLV_list_setitem, /* name */ +be_local_closure(Matter_TLV_list_to_str_val, /* name */ be_nested_proto( 4, /* nstack */ - 3, /* argc */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -2011,14 +2201,15 @@ be_local_closure(Matter_TLV_list_setitem, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(val), + /* K0 */ be_nested_str_weak(tostring), }), - be_str_weak(setitem), + be_str_weak(to_str_val), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x980C0202, // 0001 SETIDX R3 R1 R2 - 0x80000000, // 0002 RET 0 + ( &(const binstruction[ 4]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x500C0200, // 0001 LDBOOL R3 1 0 + 0x7C040400, // 0002 CALL R1 2 + 0x80040200, // 0003 RET 1 R1 }) ) ); @@ -2026,11 +2217,11 @@ be_local_closure(Matter_TLV_list_setitem, /* name */ /******************************************************************** -** Solidified function: item +** Solidified function: tostring ********************************************************************/ -be_local_closure(Matter_TLV_list_item, /* name */ +be_local_closure(Matter_TLV_list_tostring, /* name */ be_nested_proto( - 3, /* nstack */ + 8, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2038,15 +2229,21 @@ be_local_closure(Matter_TLV_list_item, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(val), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(tostring_inner), + /* K1 */ be_nested_str_weak(_X5B_X5B), + /* K2 */ be_nested_str_weak(_X5D_X5D), }), - be_str_weak(item), + be_str_weak(tostring), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x94080401, // 0001 GETIDX R2 R2 R1 - 0x80040400, // 0002 RET 1 R2 + ( &(const binstruction[ 7]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x50100000, // 0001 LDBOOL R4 0 0 + 0x58140001, // 0002 LDCONST R5 K1 + 0x58180002, // 0003 LDCONST R6 K2 + 0x5C1C0200, // 0004 MOVE R7 R1 + 0x7C080A00, // 0005 CALL R2 5 + 0x80040400, // 0006 RET 1 R2 }) ) ); @@ -2083,11 +2280,39 @@ be_local_closure(Matter_TLV_list_size, /* name */ /******************************************************************** -** Solidified function: findsubtyp +** Solidified function: setitem ********************************************************************/ -be_local_closure(Matter_TLV_list_findsubtyp, /* name */ +be_local_closure(Matter_TLV_list_setitem, /* name */ be_nested_proto( - 5, /* nstack */ + 4, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(val), + }), + be_str_weak(setitem), + &be_const_str_solidified, + ( &(const binstruction[ 3]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x980C0202, // 0001 SETIDX R3 R1 R2 + 0x80000000, // 0002 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: add_struct +********************************************************************/ +be_local_closure(Matter_TLV_list_add_struct, /* name */ + be_nested_proto( + 6, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2095,23 +2320,26 @@ be_local_closure(Matter_TLV_list_findsubtyp, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(findsub), - /* K1 */ be_nested_str_weak(typ), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(TLV), + /* K1 */ be_nested_str_weak(Matter_TLV_struct), + /* K2 */ be_nested_str_weak(tag_sub), + /* K3 */ be_nested_str_weak(val), + /* K4 */ be_nested_str_weak(push), }), - be_str_weak(findsubtyp), + be_str_weak(add_struct), &be_const_str_solidified, ( &(const binstruction[10]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C080400, // 0002 CALL R2 2 - 0x4C0C0000, // 0003 LDNIL R3 - 0x200C0403, // 0004 NE R3 R2 R3 - 0x780E0001, // 0005 JMPF R3 #0008 - 0x880C0501, // 0006 GETMBR R3 R2 K1 - 0x80040600, // 0007 RET 1 R3 - 0x4C0C0000, // 0008 LDNIL R3 - 0x80040600, // 0009 RET 1 R3 + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100000, // 0002 MOVE R4 R0 + 0x7C080400, // 0003 CALL R2 2 + 0x900A0401, // 0004 SETMBR R2 K2 R1 + 0x880C0103, // 0005 GETMBR R3 R0 K3 + 0x8C0C0704, // 0006 GETMET R3 R3 K4 + 0x5C140400, // 0007 MOVE R5 R2 + 0x7C0C0400, // 0008 CALL R3 2 + 0x80040400, // 0009 RET 1 R2 }) ) ); @@ -2158,126 +2386,50 @@ be_local_closure(Matter_TLV_list_add_list, /* name */ /******************************************************************** -** Solidified function: tostring_inner +** Solidified function: parse ********************************************************************/ -be_local_closure(Matter_TLV_list_tostring_inner, /* name */ +be_local_closure(Matter_TLV_list_parse, /* name */ be_nested_proto( - 10, /* nstack */ - 4, /* argc */ + 8, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[20]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(), - /* K2 */ be_nested_str_weak(tag_profile), - /* K3 */ be_nested_str_weak(Matter_X3A_X3A), - /* K4 */ be_nested_str_weak(tag_number), - /* K5 */ be_nested_str_weak(format), - /* K6 */ be_nested_str_weak(0x_X2508X_X20), - /* K7 */ be_nested_str_weak(tag_vendor), - /* K8 */ be_nested_str_weak(0x_X2504X_X3A_X3A), - /* K9 */ be_nested_str_weak(0x_X2504X_X3A), - /* K10 */ be_nested_str_weak(tag_sub), - /* K11 */ be_nested_str_weak(_X25i_X20), - /* K12 */ be_const_int(0), - /* K13 */ be_nested_str_weak(_X3D_X20), - /* K14 */ be_nested_str_weak(val), - /* K15 */ be_nested_str_weak(copy), - /* K16 */ be_nested_str_weak(sort), - /* K17 */ be_nested_str_weak(concat), - /* K18 */ be_nested_str_weak(_X2C_X20), - /* K19 */ be_nested_str_weak(_X20), + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(TLV), + /* K1 */ be_nested_str_weak(EOC), + /* K2 */ be_nested_str_weak(parse), + /* K3 */ be_nested_str_weak(next_idx), + /* K4 */ be_nested_str_weak(val), + /* K5 */ be_nested_str_weak(push), + /* K6 */ be_const_int(1), }), - be_str_weak(tostring_inner), + be_str_weak(parse), &be_const_str_solidified, - ( &(const binstruction[83]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0x58140001, // 0001 LDCONST R5 K1 - 0xA8020047, // 0002 EXBLK 0 #004B - 0x88180102, // 0003 GETMBR R6 R0 K2 - 0x541DFFFE, // 0004 LDINT R7 -1 - 0x1C180C07, // 0005 EQ R6 R6 R7 - 0x781A000A, // 0006 JMPF R6 #0012 - 0x00140B03, // 0007 ADD R5 R5 K3 - 0x88180104, // 0008 GETMBR R6 R0 K4 - 0x4C1C0000, // 0009 LDNIL R7 - 0x20180C07, // 000A NE R6 R6 R7 - 0x781A0004, // 000B JMPF R6 #0011 - 0x8C180905, // 000C GETMET R6 R4 K5 - 0x58200006, // 000D LDCONST R8 K6 - 0x88240104, // 000E GETMBR R9 R0 K4 - 0x7C180600, // 000F CALL R6 3 - 0x00140A06, // 0010 ADD R5 R5 R6 - 0x70020023, // 0011 JMP #0036 - 0x88180107, // 0012 GETMBR R6 R0 K7 - 0x4C1C0000, // 0013 LDNIL R7 - 0x20180C07, // 0014 NE R6 R6 R7 - 0x781A0004, // 0015 JMPF R6 #001B - 0x8C180905, // 0016 GETMET R6 R4 K5 - 0x58200008, // 0017 LDCONST R8 K8 - 0x88240107, // 0018 GETMBR R9 R0 K7 - 0x7C180600, // 0019 CALL R6 3 - 0x00140A06, // 001A ADD R5 R5 R6 - 0x88180102, // 001B GETMBR R6 R0 K2 - 0x4C1C0000, // 001C LDNIL R7 - 0x20180C07, // 001D NE R6 R6 R7 - 0x781A0004, // 001E JMPF R6 #0024 - 0x8C180905, // 001F GETMET R6 R4 K5 - 0x58200009, // 0020 LDCONST R8 K9 - 0x88240102, // 0021 GETMBR R9 R0 K2 - 0x7C180600, // 0022 CALL R6 3 - 0x00140A06, // 0023 ADD R5 R5 R6 - 0x88180104, // 0024 GETMBR R6 R0 K4 - 0x4C1C0000, // 0025 LDNIL R7 - 0x20180C07, // 0026 NE R6 R6 R7 - 0x781A0004, // 0027 JMPF R6 #002D - 0x8C180905, // 0028 GETMET R6 R4 K5 - 0x58200006, // 0029 LDCONST R8 K6 - 0x88240104, // 002A GETMBR R9 R0 K4 - 0x7C180600, // 002B CALL R6 3 - 0x00140A06, // 002C ADD R5 R5 R6 - 0x8818010A, // 002D GETMBR R6 R0 K10 - 0x4C1C0000, // 002E LDNIL R7 - 0x20180C07, // 002F NE R6 R6 R7 - 0x781A0004, // 0030 JMPF R6 #0036 - 0x8C180905, // 0031 GETMET R6 R4 K5 - 0x5820000B, // 0032 LDCONST R8 K11 - 0x8824010A, // 0033 GETMBR R9 R0 K10 - 0x7C180600, // 0034 CALL R6 3 - 0x00140A06, // 0035 ADD R5 R5 R6 - 0x6018000C, // 0036 GETGBL R6 G12 - 0x5C1C0A00, // 0037 MOVE R7 R5 - 0x7C180200, // 0038 CALL R6 1 - 0x24180D0C, // 0039 GT R6 R6 K12 - 0x781A0000, // 003A JMPF R6 #003C - 0x00140B0D, // 003B ADD R5 R5 K13 - 0x00140A02, // 003C ADD R5 R5 R2 - 0x8818010E, // 003D GETMBR R6 R0 K14 - 0x8C180D0F, // 003E GETMET R6 R6 K15 - 0x7C180200, // 003F CALL R6 1 - 0x78060002, // 0040 JMPF R1 #0044 - 0x8C1C0110, // 0041 GETMET R7 R0 K16 - 0x5C240C00, // 0042 MOVE R9 R6 - 0x7C1C0400, // 0043 CALL R7 2 - 0x8C1C0D11, // 0044 GETMET R7 R6 K17 - 0x58240012, // 0045 LDCONST R9 K18 - 0x7C1C0400, // 0046 CALL R7 2 - 0x00140A07, // 0047 ADD R5 R5 R7 - 0x00140A03, // 0048 ADD R5 R5 R3 - 0xA8040001, // 0049 EXBLK 1 1 - 0x70020006, // 004A JMP #0052 - 0xAC180002, // 004B CATCH R6 0 2 - 0x70020003, // 004C JMP #0051 - 0x00200D13, // 004D ADD R8 R6 K19 - 0x00201007, // 004E ADD R8 R8 R7 - 0x80041000, // 004F RET 1 R8 - 0x70020000, // 0050 JMP #0052 - 0xB0080000, // 0051 RAISE 2 R0 R0 - 0x80040A00, // 0052 RET 1 R5 + ( &(const binstruction[20]) { /* code */ + 0x940C0202, // 0000 GETIDX R3 R1 R2 + 0x88100100, // 0001 GETMBR R4 R0 K0 + 0x88100901, // 0002 GETMBR R4 R4 K1 + 0x200C0604, // 0003 NE R3 R3 R4 + 0x780E000B, // 0004 JMPF R3 #0011 + 0x880C0100, // 0005 GETMBR R3 R0 K0 + 0x8C0C0702, // 0006 GETMET R3 R3 K2 + 0x5C140200, // 0007 MOVE R5 R1 + 0x5C180400, // 0008 MOVE R6 R2 + 0x5C1C0000, // 0009 MOVE R7 R0 + 0x7C0C0800, // 000A CALL R3 4 + 0x88080703, // 000B GETMBR R2 R3 K3 + 0x88100104, // 000C GETMBR R4 R0 K4 + 0x8C100905, // 000D GETMET R4 R4 K5 + 0x5C180600, // 000E MOVE R6 R3 + 0x7C100400, // 000F CALL R4 2 + 0x7001FFEE, // 0010 JMP #0000 + 0x00080506, // 0011 ADD R2 R2 K6 + 0x90020602, // 0012 SETMBR R0 K3 R2 + 0x80040400, // 0013 RET 1 R2 }) ) ); @@ -2285,45 +2437,69 @@ be_local_closure(Matter_TLV_list_tostring_inner, /* name */ /******************************************************************** -** Solidified function: encode_len +** Solidified function: init ********************************************************************/ -be_local_closure(Matter_TLV_list_encode_len, /* name */ +be_local_closure(Matter_TLV_list_init, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(init), + /* K1 */ be_nested_str_weak(typ), + /* K2 */ be_nested_str_weak(TLV), + /* K3 */ be_nested_str_weak(LIST), + /* K4 */ be_nested_str_weak(val), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x60080003, // 0000 GETGBL R2 G3 + 0x5C0C0000, // 0001 MOVE R3 R0 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080500, // 0003 GETMET R2 R2 K0 + 0x5C100200, // 0004 MOVE R4 R1 + 0x7C080400, // 0005 CALL R2 2 + 0x88080102, // 0006 GETMBR R2 R0 K2 + 0x88080503, // 0007 GETMBR R2 R2 K3 + 0x90020202, // 0008 SETMBR R0 K1 R2 + 0x60080012, // 0009 GETGBL R2 G18 + 0x7C080000, // 000A CALL R2 0 + 0x90020802, // 000B SETMBR R0 K4 R2 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: item +********************************************************************/ +be_local_closure(Matter_TLV_list_item, /* name */ be_nested_proto( - 5, /* nstack */ - 1, /* argc */ + 3, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_encode_tag_len), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str_weak(val), - /* K3 */ be_nested_str_weak(encode_len), - /* K4 */ be_const_int(1), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(val), }), - be_str_weak(encode_len), + be_str_weak(item), &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x58080001, // 0002 LDCONST R2 K1 - 0x600C000C, // 0003 GETGBL R3 G12 - 0x88100102, // 0004 GETMBR R4 R0 K2 - 0x7C0C0200, // 0005 CALL R3 1 - 0x140C0403, // 0006 LT R3 R2 R3 - 0x780E0006, // 0007 JMPF R3 #000F - 0x880C0102, // 0008 GETMBR R3 R0 K2 - 0x940C0602, // 0009 GETIDX R3 R3 R2 - 0x8C0C0703, // 000A GETMET R3 R3 K3 - 0x7C0C0200, // 000B CALL R3 1 - 0x00040203, // 000C ADD R1 R1 R3 - 0x00080504, // 000D ADD R2 R2 K4 - 0x7001FFF3, // 000E JMP #0003 - 0x00040304, // 000F ADD R1 R1 K4 - 0x80040200, // 0010 RET 1 R1 + ( &(const binstruction[ 3]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x94080401, // 0001 GETIDX R2 R2 R1 + 0x80040400, // 0002 RET 1 R2 }) ) ); @@ -2331,12 +2507,12 @@ be_local_closure(Matter_TLV_list_encode_len, /* name */ /******************************************************************** -** Solidified function: findsubval +** Solidified function: getsubval ********************************************************************/ -be_local_closure(Matter_TLV_list_findsubval, /* name */ +be_local_closure(Matter_TLV_list_getsubval, /* name */ be_nested_proto( - 6, /* nstack */ - 3, /* argc */ + 5, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -2344,21 +2520,17 @@ be_local_closure(Matter_TLV_list_findsubval, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(findsub), + /* K0 */ be_nested_str_weak(getsub), /* K1 */ be_nested_str_weak(val), }), - be_str_weak(findsubval), + be_str_weak(getsubval), &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x8C0C0100, // 0000 GETMET R3 R0 K0 - 0x5C140200, // 0001 MOVE R5 R1 - 0x7C0C0400, // 0002 CALL R3 2 - 0x4C100000, // 0003 LDNIL R4 - 0x20100604, // 0004 NE R4 R3 R4 - 0x78120001, // 0005 JMPF R4 #0008 - 0x88100701, // 0006 GETMBR R4 R3 K1 - 0x80040800, // 0007 RET 1 R4 - 0x80040400, // 0008 RET 1 R2 + ( &(const binstruction[ 5]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0x88080501, // 0003 GETMBR R2 R2 K1 + 0x80040400, // 0004 RET 1 R2 }) ) ); @@ -2366,9 +2538,9 @@ be_local_closure(Matter_TLV_list_findsubval, /* name */ /******************************************************************** -** Solidified function: init +** Solidified function: getsub ********************************************************************/ -be_local_closure(Matter_TLV_list_init, /* name */ +be_local_closure(Matter_TLV_list_getsub, /* name */ be_nested_proto( 5, /* nstack */ 2, /* argc */ @@ -2378,29 +2550,22 @@ be_local_closure(Matter_TLV_list_init, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(init), - /* K1 */ be_nested_str_weak(typ), - /* K2 */ be_nested_str_weak(TLV), - /* K3 */ be_nested_str_weak(LIST), - /* K4 */ be_nested_str_weak(val), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(findsub), + /* K1 */ be_nested_str_weak(value_error), + /* K2 */ be_nested_str_weak(sub_X20not_X20found), }), - be_str_weak(init), + be_str_weak(getsub), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x60080003, // 0000 GETGBL R2 G3 - 0x5C0C0000, // 0001 MOVE R3 R0 - 0x7C080200, // 0002 CALL R2 1 - 0x8C080500, // 0003 GETMET R2 R2 K0 - 0x5C100200, // 0004 MOVE R4 R1 - 0x7C080400, // 0005 CALL R2 2 - 0x88080102, // 0006 GETMBR R2 R0 K2 - 0x88080503, // 0007 GETMBR R2 R2 K3 - 0x90020202, // 0008 SETMBR R0 K1 R2 - 0x60080012, // 0009 GETGBL R2 G18 - 0x7C080000, // 000A CALL R2 0 - 0x90020802, // 000B SETMBR R0 K4 R2 - 0x80000000, // 000C RET 0 + ( &(const binstruction[ 8]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0x4C0C0000, // 0003 LDNIL R3 + 0x1C0C0403, // 0004 EQ R3 R2 R3 + 0x780E0000, // 0005 JMPF R3 #0007 + 0xB0060302, // 0006 RAISE 1 K1 K2 + 0x80040400, // 0007 RET 1 R2 }) ) ); @@ -2408,38 +2573,48 @@ be_local_closure(Matter_TLV_list_init, /* name */ /******************************************************************** -** Solidified function: add_array +** Solidified function: add_obj ********************************************************************/ -be_local_closure(Matter_TLV_list_add_array, /* name */ +be_local_closure(Matter_TLV_list_add_obj, /* name */ be_nested_proto( - 6, /* nstack */ - 2, /* argc */ + 7, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(TLV), - /* K1 */ be_nested_str_weak(Matter_TLV_array), - /* K2 */ be_nested_str_weak(tag_sub), - /* K3 */ be_nested_str_weak(val), - /* K4 */ be_nested_str_weak(push), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(val), + /* K1 */ be_nested_str_weak(push), + /* K2 */ be_nested_str_weak(to_TLV), + /* K3 */ be_nested_str_weak(tag_sub), }), - be_str_weak(add_array), + be_str_weak(add_obj), &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x5C100000, // 0002 MOVE R4 R0 - 0x7C080400, // 0003 CALL R2 2 - 0x900A0401, // 0004 SETMBR R2 K2 R1 - 0x880C0103, // 0005 GETMBR R3 R0 K3 - 0x8C0C0704, // 0006 GETMET R3 R3 K4 - 0x5C140400, // 0007 MOVE R5 R2 - 0x7C0C0400, // 0008 CALL R3 2 - 0x80040400, // 0009 RET 1 R2 + ( &(const binstruction[21]) { /* code */ + 0x4C0C0000, // 0000 LDNIL R3 + 0x200C0403, // 0001 NE R3 R2 R3 + 0x780E0010, // 0002 JMPF R3 #0014 + 0x600C000F, // 0003 GETGBL R3 G15 + 0x5C100400, // 0004 MOVE R4 R2 + 0x60140015, // 0005 GETGBL R5 G21 + 0x7C0C0400, // 0006 CALL R3 2 + 0x780E0004, // 0007 JMPF R3 #000D + 0x880C0100, // 0008 GETMBR R3 R0 K0 + 0x8C0C0701, // 0009 GETMET R3 R3 K1 + 0x5C140400, // 000A MOVE R5 R2 + 0x7C0C0400, // 000B CALL R3 2 + 0x70020006, // 000C JMP #0014 + 0x8C0C0502, // 000D GETMET R3 R2 K2 + 0x7C0C0200, // 000E CALL R3 1 + 0x900E0601, // 000F SETMBR R3 K3 R1 + 0x88100100, // 0010 GETMBR R4 R0 K0 + 0x8C100901, // 0011 GETMET R4 R4 K1 + 0x5C180600, // 0012 MOVE R6 R3 + 0x7C100400, // 0013 CALL R4 2 + 0x80040000, // 0014 RET 1 R0 }) ) ); @@ -2499,11 +2674,11 @@ be_local_closure(Matter_TLV_list_add_TLV, /* name */ /******************************************************************** -** Solidified function: tlv2raw +** Solidified function: add_array ********************************************************************/ -be_local_closure(Matter_TLV_list_tlv2raw, /* name */ +be_local_closure(Matter_TLV_list_add_array, /* name */ be_nested_proto( - 8, /* nstack */ + 6, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2511,66 +2686,26 @@ be_local_closure(Matter_TLV_list_tlv2raw, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ - /* K0 */ be_nested_str_weak(_encode_tag), - /* K1 */ be_nested_str_weak(val), - /* K2 */ be_nested_str_weak(is_struct), - /* K3 */ be_nested_str_weak(copy), - /* K4 */ be_nested_str_weak(sort), - /* K5 */ be_nested_str_weak(tlv2raw), - /* K6 */ be_nested_str_weak(stop_iteration), - /* K7 */ be_nested_str_weak(add), - /* K8 */ be_nested_str_weak(TLV), - /* K9 */ be_nested_str_weak(EOC), - /* K10 */ be_const_int(1), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(TLV), + /* K1 */ be_nested_str_weak(Matter_TLV_array), + /* K2 */ be_nested_str_weak(tag_sub), + /* K3 */ be_nested_str_weak(val), + /* K4 */ be_nested_str_weak(push), }), - be_str_weak(tlv2raw), + be_str_weak(add_array), &be_const_str_solidified, - ( &(const binstruction[44]) { /* code */ - 0x4C080000, // 0000 LDNIL R2 - 0x1C080202, // 0001 EQ R2 R1 R2 - 0x780A0002, // 0002 JMPF R2 #0006 - 0x60080015, // 0003 GETGBL R2 G21 - 0x7C080000, // 0004 CALL R2 0 - 0x5C040400, // 0005 MOVE R1 R2 - 0x8C080100, // 0006 GETMET R2 R0 K0 - 0x5C100200, // 0007 MOVE R4 R1 - 0x7C080400, // 0008 CALL R2 2 - 0x88080101, // 0009 GETMBR R2 R0 K1 - 0x880C0102, // 000A GETMBR R3 R0 K2 - 0x780E0005, // 000B JMPF R3 #0012 - 0x8C0C0503, // 000C GETMET R3 R2 K3 - 0x7C0C0200, // 000D CALL R3 1 - 0x5C080600, // 000E MOVE R2 R3 - 0x8C0C0104, // 000F GETMET R3 R0 K4 - 0x5C140400, // 0010 MOVE R5 R2 - 0x7C0C0400, // 0011 CALL R3 2 - 0x600C0010, // 0012 GETGBL R3 G16 - 0x5C100400, // 0013 MOVE R4 R2 - 0x7C0C0200, // 0014 CALL R3 1 - 0xA802000C, // 0015 EXBLK 0 #0023 - 0x5C100600, // 0016 MOVE R4 R3 - 0x7C100000, // 0017 CALL R4 0 - 0x6014000F, // 0018 GETGBL R5 G15 - 0x5C180800, // 0019 MOVE R6 R4 - 0x601C0015, // 001A GETGBL R7 G21 - 0x7C140400, // 001B CALL R5 2 - 0x78160001, // 001C JMPF R5 #001F - 0x40140204, // 001D CONNECT R5 R1 R4 - 0x70020002, // 001E JMP #0022 - 0x8C140905, // 001F GETMET R5 R4 K5 - 0x5C1C0200, // 0020 MOVE R7 R1 - 0x7C140400, // 0021 CALL R5 2 - 0x7001FFF2, // 0022 JMP #0016 - 0x580C0006, // 0023 LDCONST R3 K6 - 0xAC0C0200, // 0024 CATCH R3 1 0 - 0xB0080000, // 0025 RAISE 2 R0 R0 - 0x8C0C0307, // 0026 GETMET R3 R1 K7 - 0x88140108, // 0027 GETMBR R5 R0 K8 - 0x88140B09, // 0028 GETMBR R5 R5 K9 - 0x5818000A, // 0029 LDCONST R6 K10 - 0x7C0C0600, // 002A CALL R3 3 - 0x80040200, // 002B RET 1 R1 + ( &(const binstruction[10]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100000, // 0002 MOVE R4 R0 + 0x7C080400, // 0003 CALL R2 2 + 0x900A0401, // 0004 SETMBR R2 K2 R1 + 0x880C0103, // 0005 GETMBR R3 R0 K3 + 0x8C0C0704, // 0006 GETMET R3 R3 K4 + 0x5C140400, // 0007 MOVE R5 R2 + 0x7C0C0400, // 0008 CALL R3 2 + 0x80040400, // 0009 RET 1 R2 }) ) ); @@ -2621,32 +2756,157 @@ be_local_closure(Matter_TLV_list_findsub, /* name */ /******************************************************************** -** Solidified function: tostring +** Solidified function: tostring_inner +********************************************************************/ +be_local_closure(Matter_TLV_list_tostring_inner, /* name */ + be_nested_proto( + 10, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[18]) { /* constants */ + /* K0 */ be_nested_str_weak(), + /* K1 */ be_nested_str_weak(tag_profile), + /* K2 */ be_nested_str_weak(Matter_X3A_X3A), + /* K3 */ be_nested_str_weak(tag_number), + /* K4 */ be_nested_str_weak(0x_X2508X_X20), + /* K5 */ be_nested_str_weak(tag_vendor), + /* K6 */ be_nested_str_weak(0x_X2504X_X3A_X3A), + /* K7 */ be_nested_str_weak(0x_X2504X_X3A), + /* K8 */ be_nested_str_weak(tag_sub), + /* K9 */ be_nested_str_weak(_X25i_X20), + /* K10 */ be_const_int(0), + /* K11 */ be_nested_str_weak(_X3D_X20), + /* K12 */ be_nested_str_weak(val), + /* K13 */ be_nested_str_weak(copy), + /* K14 */ be_nested_str_weak(sort), + /* K15 */ be_nested_str_weak(concat), + /* K16 */ be_nested_str_weak(_X2C_X20), + /* K17 */ be_nested_str_weak(_X20), + }), + be_str_weak(tostring_inner), + &be_const_str_solidified, + ( &(const binstruction[85]) { /* code */ + 0x58140000, // 0000 LDCONST R5 K0 + 0xA802004A, // 0001 EXBLK 0 #004D + 0x50180200, // 0002 LDBOOL R6 1 0 + 0x20180806, // 0003 NE R6 R4 R6 + 0x781A0038, // 0004 JMPF R6 #003E + 0x88180101, // 0005 GETMBR R6 R0 K1 + 0x541DFFFE, // 0006 LDINT R7 -1 + 0x1C180C07, // 0007 EQ R6 R6 R7 + 0x781A000A, // 0008 JMPF R6 #0014 + 0x00140B02, // 0009 ADD R5 R5 K2 + 0x88180103, // 000A GETMBR R6 R0 K3 + 0x4C1C0000, // 000B LDNIL R7 + 0x20180C07, // 000C NE R6 R6 R7 + 0x781A0004, // 000D JMPF R6 #0013 + 0x60180018, // 000E GETGBL R6 G24 + 0x581C0004, // 000F LDCONST R7 K4 + 0x88200103, // 0010 GETMBR R8 R0 K3 + 0x7C180400, // 0011 CALL R6 2 + 0x00140A06, // 0012 ADD R5 R5 R6 + 0x70020023, // 0013 JMP #0038 + 0x88180105, // 0014 GETMBR R6 R0 K5 + 0x4C1C0000, // 0015 LDNIL R7 + 0x20180C07, // 0016 NE R6 R6 R7 + 0x781A0004, // 0017 JMPF R6 #001D + 0x60180018, // 0018 GETGBL R6 G24 + 0x581C0006, // 0019 LDCONST R7 K6 + 0x88200105, // 001A GETMBR R8 R0 K5 + 0x7C180400, // 001B CALL R6 2 + 0x00140A06, // 001C ADD R5 R5 R6 + 0x88180101, // 001D GETMBR R6 R0 K1 + 0x4C1C0000, // 001E LDNIL R7 + 0x20180C07, // 001F NE R6 R6 R7 + 0x781A0004, // 0020 JMPF R6 #0026 + 0x60180018, // 0021 GETGBL R6 G24 + 0x581C0007, // 0022 LDCONST R7 K7 + 0x88200101, // 0023 GETMBR R8 R0 K1 + 0x7C180400, // 0024 CALL R6 2 + 0x00140A06, // 0025 ADD R5 R5 R6 + 0x88180103, // 0026 GETMBR R6 R0 K3 + 0x4C1C0000, // 0027 LDNIL R7 + 0x20180C07, // 0028 NE R6 R6 R7 + 0x781A0004, // 0029 JMPF R6 #002F + 0x60180018, // 002A GETGBL R6 G24 + 0x581C0004, // 002B LDCONST R7 K4 + 0x88200103, // 002C GETMBR R8 R0 K3 + 0x7C180400, // 002D CALL R6 2 + 0x00140A06, // 002E ADD R5 R5 R6 + 0x88180108, // 002F GETMBR R6 R0 K8 + 0x4C1C0000, // 0030 LDNIL R7 + 0x20180C07, // 0031 NE R6 R6 R7 + 0x781A0004, // 0032 JMPF R6 #0038 + 0x60180018, // 0033 GETGBL R6 G24 + 0x581C0009, // 0034 LDCONST R7 K9 + 0x88200108, // 0035 GETMBR R8 R0 K8 + 0x7C180400, // 0036 CALL R6 2 + 0x00140A06, // 0037 ADD R5 R5 R6 + 0x6018000C, // 0038 GETGBL R6 G12 + 0x5C1C0A00, // 0039 MOVE R7 R5 + 0x7C180200, // 003A CALL R6 1 + 0x24180D0A, // 003B GT R6 R6 K10 + 0x781A0000, // 003C JMPF R6 #003E + 0x00140B0B, // 003D ADD R5 R5 K11 + 0x00140A02, // 003E ADD R5 R5 R2 + 0x8818010C, // 003F GETMBR R6 R0 K12 + 0x8C180D0D, // 0040 GETMET R6 R6 K13 + 0x7C180200, // 0041 CALL R6 1 + 0x78060002, // 0042 JMPF R1 #0046 + 0x8C1C010E, // 0043 GETMET R7 R0 K14 + 0x5C240C00, // 0044 MOVE R9 R6 + 0x7C1C0400, // 0045 CALL R7 2 + 0x8C1C0D0F, // 0046 GETMET R7 R6 K15 + 0x58240010, // 0047 LDCONST R9 K16 + 0x7C1C0400, // 0048 CALL R7 2 + 0x00140A07, // 0049 ADD R5 R5 R7 + 0x00140A03, // 004A ADD R5 R5 R3 + 0xA8040001, // 004B EXBLK 1 1 + 0x70020006, // 004C JMP #0054 + 0xAC180002, // 004D CATCH R6 0 2 + 0x70020003, // 004E JMP #0053 + 0x00200D11, // 004F ADD R8 R6 K17 + 0x00201007, // 0050 ADD R8 R8 R7 + 0x80041000, // 0051 RET 1 R8 + 0x70020000, // 0052 JMP #0054 + 0xB0080000, // 0053 RAISE 2 R0 R0 + 0x80040A00, // 0054 RET 1 R5 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: push ********************************************************************/ -be_local_closure(Matter_TLV_list_tostring, /* name */ +be_local_closure(Matter_TLV_list_push, /* name */ be_nested_proto( - 6, /* nstack */ - 1, /* argc */ + 5, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(tostring_inner), - /* K1 */ be_nested_str_weak(_X5B_X5B), - /* K2 */ be_nested_str_weak(_X5D_X5D), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(val), + /* K1 */ be_nested_str_weak(push), }), - be_str_weak(tostring), + be_str_weak(push), &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x500C0000, // 0001 LDBOOL R3 0 0 - 0x58100001, // 0002 LDCONST R4 K1 - 0x58140002, // 0003 LDCONST R5 K2 - 0x7C040800, // 0004 CALL R1 4 - 0x80040200, // 0005 RET 1 R1 + ( &(const binstruction[ 5]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C080400, // 0003 CALL R2 2 + 0x80000000, // 0004 RET 0 }) ) ); @@ -2654,50 +2914,35 @@ be_local_closure(Matter_TLV_list_tostring, /* name */ /******************************************************************** -** Solidified function: parse +** Solidified function: findsubtyp ********************************************************************/ -be_local_closure(Matter_TLV_list_parse, /* name */ +be_local_closure(Matter_TLV_list_findsubtyp, /* name */ be_nested_proto( - 8, /* nstack */ - 3, /* argc */ + 5, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str_weak(TLV), - /* K1 */ be_nested_str_weak(EOC), - /* K2 */ be_nested_str_weak(parse), - /* K3 */ be_nested_str_weak(next_idx), - /* K4 */ be_nested_str_weak(val), - /* K5 */ be_nested_str_weak(push), - /* K6 */ be_const_int(1), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(findsub), + /* K1 */ be_nested_str_weak(typ), }), - be_str_weak(parse), + be_str_weak(findsubtyp), &be_const_str_solidified, - ( &(const binstruction[20]) { /* code */ - 0x940C0202, // 0000 GETIDX R3 R1 R2 - 0x88100100, // 0001 GETMBR R4 R0 K0 - 0x88100901, // 0002 GETMBR R4 R4 K1 - 0x200C0604, // 0003 NE R3 R3 R4 - 0x780E000B, // 0004 JMPF R3 #0011 - 0x880C0100, // 0005 GETMBR R3 R0 K0 - 0x8C0C0702, // 0006 GETMET R3 R3 K2 - 0x5C140200, // 0007 MOVE R5 R1 - 0x5C180400, // 0008 MOVE R6 R2 - 0x5C1C0000, // 0009 MOVE R7 R0 - 0x7C0C0800, // 000A CALL R3 4 - 0x88080703, // 000B GETMBR R2 R3 K3 - 0x88100104, // 000C GETMBR R4 R0 K4 - 0x8C100905, // 000D GETMET R4 R4 K5 - 0x5C180600, // 000E MOVE R6 R3 - 0x7C100400, // 000F CALL R4 2 - 0x7001FFEE, // 0010 JMP #0000 - 0x00080506, // 0011 ADD R2 R2 K6 - 0x90020602, // 0012 SETMBR R0 K3 R2 - 0x80040400, // 0013 RET 1 R2 + ( &(const binstruction[10]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0x4C0C0000, // 0003 LDNIL R3 + 0x200C0403, // 0004 NE R3 R2 R3 + 0x780E0001, // 0005 JMPF R3 #0008 + 0x880C0501, // 0006 GETMBR R3 R2 K1 + 0x80040600, // 0007 RET 1 R3 + 0x4C0C0000, // 0008 LDNIL R3 + 0x80040600, // 0009 RET 1 R3 }) ) ); @@ -2705,34 +2950,45 @@ be_local_closure(Matter_TLV_list_parse, /* name */ /******************************************************************** -** Solidified function: getsub +** Solidified function: encode_len ********************************************************************/ -be_local_closure(Matter_TLV_list_getsub, /* name */ +be_local_closure(Matter_TLV_list_encode_len, /* name */ be_nested_proto( 5, /* nstack */ - 2, /* argc */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(findsub), - /* K1 */ be_nested_str_weak(value_error), - /* K2 */ be_nested_str_weak(sub_X20not_X20found), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_encode_tag_len), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(val), + /* K3 */ be_nested_str_weak(encode_len), + /* K4 */ be_const_int(1), }), - be_str_weak(getsub), + be_str_weak(encode_len), &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C080400, // 0002 CALL R2 2 - 0x4C0C0000, // 0003 LDNIL R3 - 0x1C0C0403, // 0004 EQ R3 R2 R3 - 0x780E0000, // 0005 JMPF R3 #0007 - 0xB0060302, // 0006 RAISE 1 K1 K2 - 0x80040400, // 0007 RET 1 R2 + ( &(const binstruction[17]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x58080001, // 0002 LDCONST R2 K1 + 0x600C000C, // 0003 GETGBL R3 G12 + 0x88100102, // 0004 GETMBR R4 R0 K2 + 0x7C0C0200, // 0005 CALL R3 1 + 0x140C0403, // 0006 LT R3 R2 R3 + 0x780E0006, // 0007 JMPF R3 #000F + 0x880C0102, // 0008 GETMBR R3 R0 K2 + 0x940C0602, // 0009 GETIDX R3 R3 R2 + 0x8C0C0703, // 000A GETMET R3 R3 K3 + 0x7C0C0200, // 000B CALL R3 1 + 0x00040203, // 000C ADD R1 R1 R3 + 0x00080504, // 000D ADD R2 R2 K4 + 0x7001FFF3, // 000E JMP #0003 + 0x00040304, // 000F ADD R1 R1 K4 + 0x80040200, // 0010 RET 1 R1 }) ) ); @@ -2746,29 +3002,30 @@ extern const bclass be_class_Matter_TLV_item; be_local_class(Matter_TLV_list, 0, &be_class_Matter_TLV_item, - be_nested_map(21, + be_nested_map(22, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(add_obj, -1), be_const_closure(Matter_TLV_list_add_obj_closure) }, - { be_const_key_weak(add_struct, -1), be_const_closure(Matter_TLV_list_add_struct_closure) }, + { be_const_key_weak(encode_len, 7), be_const_closure(Matter_TLV_list_encode_len_closure) }, + { be_const_key_weak(tlv2raw, -1), be_const_closure(Matter_TLV_list_tlv2raw_closure) }, + { be_const_key_weak(to_str_val, 14), be_const_closure(Matter_TLV_list_to_str_val_closure) }, + { be_const_key_weak(findsubval, 5), be_const_closure(Matter_TLV_list_findsubval_closure) }, + { be_const_key_weak(size, -1), be_const_closure(Matter_TLV_list_size_closure) }, + { be_const_key_weak(findsubtyp, 21), be_const_closure(Matter_TLV_list_findsubtyp_closure) }, + { be_const_key_weak(add_struct, 19), be_const_closure(Matter_TLV_list_add_struct_closure) }, { be_const_key_weak(push, -1), be_const_closure(Matter_TLV_list_push_closure) }, + { be_const_key_weak(parse, -1), be_const_closure(Matter_TLV_list_parse_closure) }, + { be_const_key_weak(init, 0), be_const_closure(Matter_TLV_list_init_closure) }, + { be_const_key_weak(item, -1), be_const_closure(Matter_TLV_list_item_closure) }, + { be_const_key_weak(tostring_inner, -1), be_const_closure(Matter_TLV_list_tostring_inner_closure) }, { be_const_key_weak(getsubval, 20), be_const_closure(Matter_TLV_list_getsubval_closure) }, { be_const_key_weak(getsub, -1), be_const_closure(Matter_TLV_list_getsub_closure) }, - { be_const_key_weak(parse, -1), be_const_closure(Matter_TLV_list_parse_closure) }, - { be_const_key_weak(size, -1), be_const_closure(Matter_TLV_list_size_closure) }, - { be_const_key_weak(findsubtyp, -1), be_const_closure(Matter_TLV_list_findsubtyp_closure) }, - { be_const_key_weak(tostring, -1), be_const_closure(Matter_TLV_list_tostring_closure) }, - { be_const_key_weak(tostring_inner, 4), be_const_closure(Matter_TLV_list_tostring_inner_closure) }, - { be_const_key_weak(encode_len, 8), be_const_closure(Matter_TLV_list_encode_len_closure) }, - { be_const_key_weak(findsubval, -1), be_const_closure(Matter_TLV_list_findsubval_closure) }, - { be_const_key_weak(init, -1), be_const_closure(Matter_TLV_list_init_closure) }, - { be_const_key_weak(add_array, 16), be_const_closure(Matter_TLV_list_add_array_closure) }, - { be_const_key_weak(setitem, 15), be_const_closure(Matter_TLV_list_setitem_closure) }, - { be_const_key_weak(tlv2raw, 18), be_const_closure(Matter_TLV_list_tlv2raw_closure) }, { be_const_key_weak(findsub, -1), be_const_closure(Matter_TLV_list_findsub_closure) }, - { be_const_key_weak(is_struct, -1), be_const_bool(0) }, + { be_const_key_weak(add_list, 17), be_const_closure(Matter_TLV_list_add_list_closure) }, + { be_const_key_weak(add_array, -1), be_const_closure(Matter_TLV_list_add_array_closure) }, { be_const_key_weak(add_TLV, -1), be_const_closure(Matter_TLV_list_add_TLV_closure) }, - { be_const_key_weak(item, 5), be_const_closure(Matter_TLV_list_item_closure) }, - { be_const_key_weak(add_list, -1), be_const_closure(Matter_TLV_list_add_list_closure) }, + { be_const_key_weak(setitem, 11), be_const_closure(Matter_TLV_list_setitem_closure) }, + { be_const_key_weak(add_obj, -1), be_const_closure(Matter_TLV_list_add_obj_closure) }, + { be_const_key_weak(is_list, -1), be_const_bool(1) }, + { be_const_key_weak(tostring, -1), be_const_closure(Matter_TLV_list_tostring_closure) }, })), be_str_weak(Matter_TLV_list) ); @@ -2782,6 +3039,40 @@ void be_load_Matter_TLV_list_class(bvm *vm) { extern const bclass be_class_Matter_TLV_struct; +/******************************************************************** +** Solidified function: tostring +********************************************************************/ +be_local_closure(Matter_TLV_struct_tostring, /* name */ + be_nested_proto( + 8, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(tostring_inner), + /* K1 */ be_nested_str_weak(_X7B), + /* K2 */ be_nested_str_weak(_X7D), + }), + be_str_weak(tostring), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x50100200, // 0001 LDBOOL R4 1 0 + 0x58140001, // 0002 LDCONST R5 K1 + 0x58180002, // 0003 LDCONST R6 K2 + 0x5C1C0200, // 0004 MOVE R7 R1 + 0x7C080A00, // 0005 CALL R2 5 + 0x80040400, // 0006 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: init ********************************************************************/ @@ -2824,39 +3115,6 @@ be_local_closure(Matter_TLV_struct_init, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: tostring -********************************************************************/ -be_local_closure(Matter_TLV_struct_tostring, /* name */ - be_nested_proto( - 6, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(tostring_inner), - /* K1 */ be_nested_str_weak(_X7B), - /* K2 */ be_nested_str_weak(_X7D), - }), - be_str_weak(tostring), - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x500C0200, // 0001 LDBOOL R3 1 0 - 0x58100001, // 0002 LDCONST R4 K1 - 0x58140002, // 0003 LDCONST R5 K2 - 0x7C040800, // 0004 CALL R1 4 - 0x80040200, // 0005 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified class: Matter_TLV_struct ********************************************************************/ @@ -2864,11 +3122,12 @@ extern const bclass be_class_Matter_TLV_list; be_local_class(Matter_TLV_struct, 0, &be_class_Matter_TLV_list, - be_nested_map(3, + be_nested_map(4, ( (struct bmapnode*) &(const bmapnode[]) { { be_const_key_weak(init, -1), be_const_closure(Matter_TLV_struct_init_closure) }, { be_const_key_weak(tostring, -1), be_const_closure(Matter_TLV_struct_tostring_closure) }, - { be_const_key_weak(is_struct, -1), be_const_bool(1) }, + { be_const_key_weak(is_list, -1), be_const_bool(0) }, + { be_const_key_weak(is_struct, 0), be_const_bool(1) }, })), be_str_weak(Matter_TLV_struct) ); @@ -2882,6 +3141,40 @@ void be_load_Matter_TLV_struct_class(bvm *vm) { extern const bclass be_class_Matter_TLV_array; +/******************************************************************** +** Solidified function: tostring +********************************************************************/ +be_local_closure(Matter_TLV_array_tostring, /* name */ + be_nested_proto( + 8, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(tostring_inner), + /* K1 */ be_nested_str_weak(_X5B), + /* K2 */ be_nested_str_weak(_X5D), + }), + be_str_weak(tostring), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x50100000, // 0001 LDBOOL R4 0 0 + 0x58140001, // 0002 LDCONST R5 K1 + 0x58180002, // 0003 LDCONST R6 K2 + 0x5C1C0200, // 0004 MOVE R7 R1 + 0x7C080A00, // 0005 CALL R2 5 + 0x80040400, // 0006 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: init ********************************************************************/ @@ -2987,39 +3280,6 @@ be_local_closure(Matter_TLV_array_parse, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: tostring -********************************************************************/ -be_local_closure(Matter_TLV_array_tostring, /* name */ - be_nested_proto( - 6, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(tostring_inner), - /* K1 */ be_nested_str_weak(_X5B), - /* K2 */ be_nested_str_weak(_X5D), - }), - be_str_weak(tostring), - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x500C0000, // 0001 LDBOOL R3 0 0 - 0x58100001, // 0002 LDCONST R4 K1 - 0x58140002, // 0003 LDCONST R5 K2 - 0x7C040800, // 0004 CALL R1 4 - 0x80040200, // 0005 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified class: Matter_TLV_array ********************************************************************/ @@ -3027,11 +3287,13 @@ extern const bclass be_class_Matter_TLV_list; be_local_class(Matter_TLV_array, 0, &be_class_Matter_TLV_list, - be_nested_map(3, + be_nested_map(5, ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(tostring, 1), be_const_closure(Matter_TLV_array_tostring_closure) }, { be_const_key_weak(init, -1), be_const_closure(Matter_TLV_array_init_closure) }, - { be_const_key_weak(parse, 2), be_const_closure(Matter_TLV_array_parse_closure) }, - { be_const_key_weak(tostring, -1), be_const_closure(Matter_TLV_array_tostring_closure) }, + { be_const_key_weak(parse, 3), be_const_closure(Matter_TLV_array_parse_closure) }, + { be_const_key_weak(is_list, -1), be_const_bool(0) }, + { be_const_key_weak(is_array, -1), be_const_bool(1) }, })), be_str_weak(Matter_TLV_array) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_UDPServer.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_UDPServer.h index a95cc82530ca..0dd231c3afc2 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_UDPServer.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_UDPServer.h @@ -120,86 +120,27 @@ void be_load_Matter_UDPPacket_sent_class(bvm *vm) { extern const bclass be_class_Matter_UDPServer; /******************************************************************** -** Solidified function: _backoff_time +** Solidified function: every_50ms ********************************************************************/ -be_local_closure(Matter_UDPServer__backoff_time, /* name */ +be_local_closure(Matter_UDPServer_every_50ms, /* name */ be_nested_proto( - 10, /* nstack */ + 3, /* nstack */ 1, /* argc */ - 4, /* varg */ + 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 1]) { - be_nested_proto( - 4, /* nstack */ - 2, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_const_int(1), - /* K1 */ be_const_int(0), - }), - be_str_weak(power_int), - &be_const_str_solidified, - ( &(const binstruction[ 7]) { /* code */ - 0x58080000, // 0000 LDCONST R2 K0 - 0x240C0301, // 0001 GT R3 R1 K1 - 0x780E0002, // 0002 JMPF R3 #0006 - 0x08080400, // 0003 MUL R2 R2 R0 - 0x04040300, // 0004 SUB R1 R1 K0 - 0x7001FFFA, // 0005 JMP #0001 - 0x80040400, // 0006 RET 1 R2 - }) - ), - }), + 0, /* has sup protos */ + NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_const_class(be_class_Matter_UDPServer), - /* K1 */ be_nested_str_weak(math), - /* K2 */ be_nested_str_weak(rand), - /* K3 */ be_const_int(0), - /* K4 */ be_const_int(1), - /* K5 */ be_const_real_hex(0x3FCCCCCD), - /* K6 */ be_const_real_hex(0x3F800000), - /* K7 */ be_const_real_hex(0x3E800000), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(loop), }), - be_str_weak(_backoff_time), + be_str_weak(every_50ms), &be_const_str_solidified, - ( &(const binstruction[29]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0x84080000, // 0001 CLOSURE R2 P0 - 0xA40E0200, // 0002 IMPORT R3 K1 - 0x5412012B, // 0003 LDINT R4 300 - 0x6014000A, // 0004 GETGBL R5 G10 - 0x8C180702, // 0005 GETMET R6 R3 K2 - 0x7C180200, // 0006 CALL R6 1 - 0x541E00FE, // 0007 LDINT R7 255 - 0x2C180C07, // 0008 AND R6 R6 R7 - 0x7C140200, // 0009 CALL R5 1 - 0x541A00FE, // 000A LDINT R6 255 - 0x0C140A06, // 000B DIV R5 R5 R6 - 0x24180103, // 000C GT R6 R0 K3 - 0x781A0001, // 000D JMPF R6 #0010 - 0x04180104, // 000E SUB R6 R0 K4 - 0x70020000, // 000F JMP #0011 - 0x58180003, // 0010 LDCONST R6 K3 - 0x5C1C0400, // 0011 MOVE R7 R2 - 0x58200005, // 0012 LDCONST R8 K5 - 0x5C240C00, // 0013 MOVE R9 R6 - 0x7C1C0400, // 0014 CALL R7 2 - 0x081C0807, // 0015 MUL R7 R4 R7 - 0x08200B07, // 0016 MUL R8 R5 K7 - 0x00220C08, // 0017 ADD R8 K6 R8 - 0x081C0E08, // 0018 MUL R7 R7 R8 - 0x60200009, // 0019 GETGBL R8 G9 - 0x5C240E00, // 001A MOVE R9 R7 - 0x7C200200, // 001B CALL R8 1 - 0x80041000, // 001C RET 1 R8 + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80000000, // 0002 RET 0 }) ) ); @@ -207,107 +148,43 @@ be_local_closure(Matter_UDPServer__backoff_time, /* name */ /******************************************************************** -** Solidified function: _resend_packets +** Solidified function: send_UDP ********************************************************************/ -be_local_closure(Matter_UDPServer__resend_packets, /* name */ +be_local_closure(Matter_UDPServer_send_UDP, /* name */ be_nested_proto( - 13, /* nstack */ - 1, /* argc */ + 6, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[23]) { /* constants */ - /* K0 */ be_const_int(0), - /* K1 */ be_nested_str_weak(packets_sent), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(time_reached), - /* K4 */ be_nested_str_weak(next_try), - /* K5 */ be_nested_str_weak(retries), - /* K6 */ be_nested_str_weak(RETRIES), - /* K7 */ be_nested_str_weak(log), - /* K8 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Resending_X20packet_X20id_X3D), - /* K9 */ be_nested_str_weak(msg_id), - /* K10 */ be_const_int(3), - /* K11 */ be_nested_str_weak(send), - /* K12 */ be_nested_str_weak(millis), - /* K13 */ be_nested_str_weak(_backoff_time), - /* K14 */ be_const_int(1), - /* K15 */ be_nested_str_weak(string), - /* K16 */ be_nested_str_weak(remove), - /* K17 */ be_nested_str_weak(format), - /* K18 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20Unacked_X20packet_X20_X27_X5B_X25s_X5D_X3A_X25i_X27_X20msg_id_X3D_X25i), - /* K19 */ be_nested_str_weak(session_id), - /* K20 */ be_nested_str_weak(addr), - /* K21 */ be_nested_str_weak(port), - /* K22 */ be_const_int(2), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(UDPPacket_sent), + /* K2 */ be_nested_str_weak(send), + /* K3 */ be_nested_str_weak(msg_id), + /* K4 */ be_nested_str_weak(packets_sent), + /* K5 */ be_nested_str_weak(push), }), - be_str_weak(_resend_packets), + be_str_weak(send_UDP), &be_const_str_solidified, - ( &(const binstruction[61]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0x6008000C, // 0001 GETGBL R2 G12 - 0x880C0101, // 0002 GETMBR R3 R0 K1 - 0x7C080200, // 0003 CALL R2 1 - 0x14080202, // 0004 LT R2 R1 R2 - 0x780A0035, // 0005 JMPF R2 #003C - 0x88080101, // 0006 GETMBR R2 R0 K1 - 0x94080401, // 0007 GETIDX R2 R2 R1 - 0xB80E0400, // 0008 GETNGBL R3 K2 - 0x8C0C0703, // 0009 GETMET R3 R3 K3 - 0x88140504, // 000A GETMBR R5 R2 K4 - 0x7C0C0400, // 000B CALL R3 2 - 0x780E002C, // 000C JMPF R3 #003A - 0x880C0505, // 000D GETMBR R3 R2 K5 - 0x88100106, // 000E GETMBR R4 R0 K6 - 0x180C0604, // 000F LE R3 R3 R4 - 0x780E0017, // 0010 JMPF R3 #0029 - 0xB80E0400, // 0011 GETNGBL R3 K2 - 0x8C0C0707, // 0012 GETMET R3 R3 K7 - 0x60140008, // 0013 GETGBL R5 G8 - 0x88180509, // 0014 GETMBR R6 R2 K9 - 0x7C140200, // 0015 CALL R5 1 - 0x00161005, // 0016 ADD R5 K8 R5 - 0x5818000A, // 0017 LDCONST R6 K10 - 0x7C0C0600, // 0018 CALL R3 3 - 0x8C0C010B, // 0019 GETMET R3 R0 K11 - 0x5C140400, // 001A MOVE R5 R2 - 0x7C0C0400, // 001B CALL R3 2 - 0xB80E0400, // 001C GETNGBL R3 K2 - 0x8C0C070C, // 001D GETMET R3 R3 K12 - 0x7C0C0200, // 001E CALL R3 1 - 0x8C10010D, // 001F GETMET R4 R0 K13 - 0x88180505, // 0020 GETMBR R6 R2 K5 - 0x7C100400, // 0021 CALL R4 2 - 0x000C0604, // 0022 ADD R3 R3 R4 - 0x900A0803, // 0023 SETMBR R2 K4 R3 - 0x880C0505, // 0024 GETMBR R3 R2 K5 - 0x000C070E, // 0025 ADD R3 R3 K14 - 0x900A0A03, // 0026 SETMBR R2 K5 R3 - 0x0004030E, // 0027 ADD R1 R1 K14 - 0x7002000F, // 0028 JMP #0039 - 0xA40E1E00, // 0029 IMPORT R3 K15 - 0x88100101, // 002A GETMBR R4 R0 K1 - 0x8C100910, // 002B GETMET R4 R4 K16 - 0x5C180200, // 002C MOVE R6 R1 - 0x7C100400, // 002D CALL R4 2 - 0xB8120400, // 002E GETNGBL R4 K2 - 0x8C100907, // 002F GETMET R4 R4 K7 - 0x8C180711, // 0030 GETMET R6 R3 K17 - 0x58200012, // 0031 LDCONST R8 K18 - 0x88240513, // 0032 GETMBR R9 R2 K19 - 0x88280514, // 0033 GETMBR R10 R2 K20 - 0x882C0515, // 0034 GETMBR R11 R2 K21 - 0x88300509, // 0035 GETMBR R12 R2 K9 - 0x7C180C00, // 0036 CALL R6 6 - 0x581C0016, // 0037 LDCONST R7 K22 - 0x7C100600, // 0038 CALL R4 3 - 0x70020000, // 0039 JMP #003B - 0x0004030E, // 003A ADD R1 R1 K14 - 0x7001FFC4, // 003B JMP #0001 - 0x80000000, // 003C RET 0 + ( &(const binstruction[14]) { /* code */ + 0xB80A0000, // 0000 GETNGBL R2 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C080400, // 0003 CALL R2 2 + 0x8C0C0102, // 0004 GETMET R3 R0 K2 + 0x5C140400, // 0005 MOVE R5 R2 + 0x7C0C0400, // 0006 CALL R3 2 + 0x880C0503, // 0007 GETMBR R3 R2 K3 + 0x780E0003, // 0008 JMPF R3 #000D + 0x880C0104, // 0009 GETMBR R3 R0 K4 + 0x8C0C0705, // 000A GETMET R3 R3 K5 + 0x5C140400, // 000B MOVE R5 R2 + 0x7C0C0400, // 000C CALL R3 2 + 0x80000000, // 000D RET 0 }) ) ); @@ -315,23 +192,75 @@ be_local_closure(Matter_UDPServer__resend_packets, /* name */ /******************************************************************** -** Solidified function: every_second +** Solidified function: received_ack ********************************************************************/ -be_local_closure(Matter_UDPServer_every_second, /* name */ +be_local_closure(Matter_UDPServer_received_ack, /* name */ be_nested_proto( - 1, /* nstack */ - 1, /* argc */ + 10, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(every_second), + 1, /* has constants */ + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str_weak(ack_message_counter), + /* K1 */ be_nested_str_weak(exchange_id), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(packets_sent), + /* K4 */ be_nested_str_weak(msg_id), + /* K5 */ be_nested_str_weak(remove), + /* K6 */ be_nested_str_weak(tasmota), + /* K7 */ be_nested_str_weak(loglevel), + /* K8 */ be_nested_str_weak(log), + /* K9 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Removed_X20packet_X20from_X20sending_X20list_X20id_X3D), + /* K10 */ be_const_int(1), + }), + be_str_weak(received_ack), &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 + ( &(const binstruction[41]) { /* code */ + 0x88080300, // 0000 GETMBR R2 R1 K0 + 0x880C0301, // 0001 GETMBR R3 R1 K1 + 0x4C100000, // 0002 LDNIL R4 + 0x1C100404, // 0003 EQ R4 R2 R4 + 0x78120000, // 0004 JMPF R4 #0006 + 0x80000800, // 0005 RET 0 + 0x58100002, // 0006 LDCONST R4 K2 + 0x6014000C, // 0007 GETGBL R5 G12 + 0x88180103, // 0008 GETMBR R6 R0 K3 + 0x7C140200, // 0009 CALL R5 1 + 0x14140805, // 000A LT R5 R4 R5 + 0x7816001B, // 000B JMPF R5 #0028 + 0x88140103, // 000C GETMBR R5 R0 K3 + 0x94140A04, // 000D GETIDX R5 R5 R4 + 0x88180B04, // 000E GETMBR R6 R5 K4 + 0x1C180C02, // 000F EQ R6 R6 R2 + 0x781A0014, // 0010 JMPF R6 #0026 + 0x88180B01, // 0011 GETMBR R6 R5 K1 + 0x1C180C03, // 0012 EQ R6 R6 R3 + 0x781A0011, // 0013 JMPF R6 #0026 + 0x88180103, // 0014 GETMBR R6 R0 K3 + 0x8C180D05, // 0015 GETMET R6 R6 K5 + 0x5C200800, // 0016 MOVE R8 R4 + 0x7C180400, // 0017 CALL R6 2 + 0xB81A0C00, // 0018 GETNGBL R6 K6 + 0x8C180D07, // 0019 GETMET R6 R6 K7 + 0x54220003, // 001A LDINT R8 4 + 0x7C180400, // 001B CALL R6 2 + 0x781A0007, // 001C JMPF R6 #0025 + 0xB81A0C00, // 001D GETNGBL R6 K6 + 0x8C180D08, // 001E GETMET R6 R6 K8 + 0x60200008, // 001F GETGBL R8 G8 + 0x5C240400, // 0020 MOVE R9 R2 + 0x7C200200, // 0021 CALL R8 1 + 0x00221208, // 0022 ADD R8 K9 R8 + 0x54260003, // 0023 LDINT R9 4 + 0x7C180600, // 0024 CALL R6 3 + 0x70020000, // 0025 JMP #0027 + 0x0010090A, // 0026 ADD R4 R4 K10 + 0x7001FFDE, // 0027 JMP #0007 + 0x80000000, // 0028 RET 0 }) ) ); @@ -339,9 +268,9 @@ be_local_closure(Matter_UDPServer_every_second, /* name */ /******************************************************************** -** Solidified function: send_UDP +** Solidified function: start ********************************************************************/ -be_local_closure(Matter_UDPServer_send_UDP, /* name */ +be_local_closure(Matter_UDPServer_start, /* name */ be_nested_proto( 6, /* nstack */ 2, /* argc */ @@ -351,31 +280,44 @@ be_local_closure(Matter_UDPServer_send_UDP, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(matter), - /* K1 */ be_nested_str_weak(UDPPacket_sent), - /* K2 */ be_nested_str_weak(send), - /* K3 */ be_nested_str_weak(msg_id), - /* K4 */ be_nested_str_weak(packets_sent), - /* K5 */ be_nested_str_weak(push), + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(listening), + /* K1 */ be_nested_str_weak(udp_socket), + /* K2 */ be_nested_str_weak(udp), + /* K3 */ be_nested_str_weak(begin), + /* K4 */ be_nested_str_weak(addr), + /* K5 */ be_nested_str_weak(port), + /* K6 */ be_nested_str_weak(network_error), + /* K7 */ be_nested_str_weak(could_X20not_X20open_X20UDP_X20server), + /* K8 */ be_nested_str_weak(dispatch_cb), + /* K9 */ be_nested_str_weak(tasmota), + /* K10 */ be_nested_str_weak(add_fast_loop), + /* K11 */ be_nested_str_weak(loop_cb), }), - be_str_weak(send_UDP), + be_str_weak(start), &be_const_str_solidified, - ( &(const binstruction[14]) { /* code */ - 0xB80A0000, // 0000 GETNGBL R2 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x5C100200, // 0002 MOVE R4 R1 - 0x7C080400, // 0003 CALL R2 2 - 0x8C0C0102, // 0004 GETMET R3 R0 K2 - 0x5C140400, // 0005 MOVE R5 R2 - 0x7C0C0400, // 0006 CALL R3 2 - 0x880C0503, // 0007 GETMBR R3 R2 K3 - 0x780E0003, // 0008 JMPF R3 #000D - 0x880C0104, // 0009 GETMBR R3 R0 K4 - 0x8C0C0705, // 000A GETMET R3 R3 K5 - 0x5C140400, // 000B MOVE R5 R2 - 0x7C0C0400, // 000C CALL R3 2 - 0x80000000, // 000D RET 0 + ( &(const binstruction[21]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x740A0011, // 0001 JMPT R2 #0014 + 0xB80A0400, // 0002 GETNGBL R2 K2 + 0x7C080000, // 0003 CALL R2 0 + 0x90020202, // 0004 SETMBR R0 K1 R2 + 0x88080101, // 0005 GETMBR R2 R0 K1 + 0x8C080503, // 0006 GETMET R2 R2 K3 + 0x88100104, // 0007 GETMBR R4 R0 K4 + 0x88140105, // 0008 GETMBR R5 R0 K5 + 0x7C080600, // 0009 CALL R2 3 + 0x5C0C0400, // 000A MOVE R3 R2 + 0x740E0000, // 000B JMPT R3 #000D + 0xB0060D07, // 000C RAISE 1 K6 K7 + 0x500C0200, // 000D LDBOOL R3 1 0 + 0x90020003, // 000E SETMBR R0 K0 R3 + 0x90021001, // 000F SETMBR R0 K8 R1 + 0xB80E1200, // 0010 GETNGBL R3 K9 + 0x8C0C070A, // 0011 GETMET R3 R3 K10 + 0x8814010B, // 0012 GETMBR R5 R0 K11 + 0x7C0C0400, // 0013 CALL R3 2 + 0x80000000, // 0014 RET 0 }) ) ); @@ -383,85 +325,83 @@ be_local_closure(Matter_UDPServer_send_UDP, /* name */ /******************************************************************** -** Solidified function: every_50ms +** Solidified function: send ********************************************************************/ -be_local_closure(Matter_UDPServer_every_50ms, /* name */ +be_local_closure(Matter_UDPServer_send, /* name */ be_nested_proto( - 13, /* nstack */ - 1, /* argc */ + 9, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str_weak(udp_socket), - /* K3 */ be_nested_str_weak(read), - /* K4 */ be_const_int(1), - /* K5 */ be_nested_str_weak(remote_ip), - /* K6 */ be_nested_str_weak(remote_port), + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(udp_socket), + /* K1 */ be_nested_str_weak(send), + /* K2 */ be_nested_str_weak(addr), + /* K3 */ be_nested_str_weak(remote_ip), + /* K4 */ be_nested_str_weak(port), + /* K5 */ be_nested_str_weak(remote_port), + /* K6 */ be_nested_str_weak(raw), /* K7 */ be_nested_str_weak(tasmota), - /* K8 */ be_nested_str_weak(log), - /* K9 */ be_nested_str_weak(format), - /* K10 */ be_nested_str_weak(MTR_X3A_X20UDP_X20received_X20from_X20_X5B_X25s_X5D_X3A_X25i), + /* K8 */ be_nested_str_weak(loglevel), + /* K9 */ be_nested_str_weak(log), + /* K10 */ be_nested_str_weak(MTR_X3A_X20sending_X20packet_X20to_X20_X27_X5B_X25s_X5D_X3A_X25i_X27), /* K11 */ be_const_int(3), - /* K12 */ be_nested_str_weak(dispatch_cb), - /* K13 */ be_nested_str_weak(MAX_PACKETS_READ), - /* K14 */ be_nested_str_weak(_resend_packets), + /* K12 */ be_nested_str_weak(MTR_X3A_X20error_X20sending_X20packet_X20to_X20_X27_X5B_X25s_X5D_X3A_X25i_X27), }), - be_str_weak(every_50ms), + be_str_weak(send), &be_const_str_solidified, ( &(const binstruction[47]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x58080001, // 0001 LDCONST R2 K1 - 0x880C0102, // 0002 GETMBR R3 R0 K2 - 0x4C100000, // 0003 LDNIL R4 - 0x1C0C0604, // 0004 EQ R3 R3 R4 - 0x780E0000, // 0005 JMPF R3 #0007 - 0x80000600, // 0006 RET 0 - 0x880C0102, // 0007 GETMBR R3 R0 K2 - 0x8C0C0703, // 0008 GETMET R3 R3 K3 - 0x7C0C0200, // 0009 CALL R3 1 - 0x4C100000, // 000A LDNIL R4 - 0x20100604, // 000B NE R4 R3 R4 - 0x7812001E, // 000C JMPF R4 #002C - 0x00080504, // 000D ADD R2 R2 K4 - 0x88100102, // 000E GETMBR R4 R0 K2 - 0x88100905, // 000F GETMBR R4 R4 K5 - 0x88140102, // 0010 GETMBR R5 R0 K2 - 0x88140B06, // 0011 GETMBR R5 R5 K6 - 0xB81A0E00, // 0012 GETNGBL R6 K7 - 0x8C180D08, // 0013 GETMET R6 R6 K8 - 0x8C200309, // 0014 GETMET R8 R1 K9 - 0x5828000A, // 0015 LDCONST R10 K10 - 0x5C2C0800, // 0016 MOVE R11 R4 - 0x5C300A00, // 0017 MOVE R12 R5 - 0x7C200800, // 0018 CALL R8 4 - 0x5824000B, // 0019 LDCONST R9 K11 - 0x7C180600, // 001A CALL R6 3 - 0x8818010C, // 001B GETMBR R6 R0 K12 - 0x781A0004, // 001C JMPF R6 #0022 - 0x8C18010C, // 001D GETMET R6 R0 K12 - 0x5C200600, // 001E MOVE R8 R3 - 0x5C240800, // 001F MOVE R9 R4 - 0x5C280A00, // 0020 MOVE R10 R5 - 0x7C180800, // 0021 CALL R6 4 - 0x8818010D, // 0022 GETMBR R6 R0 K13 - 0x14180406, // 0023 LT R6 R2 R6 - 0x781A0004, // 0024 JMPF R6 #002A - 0x88180102, // 0025 GETMBR R6 R0 K2 - 0x8C180D03, // 0026 GETMET R6 R6 K3 - 0x7C180200, // 0027 CALL R6 1 - 0x5C0C0C00, // 0028 MOVE R3 R6 - 0x70020000, // 0029 JMP #002B - 0x4C0C0000, // 002A LDNIL R3 - 0x7001FFDD, // 002B JMP #000A - 0x8C10010E, // 002C GETMET R4 R0 K14 - 0x7C100200, // 002D CALL R4 1 - 0x80000000, // 002E RET 0 + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x88100302, // 0002 GETMBR R4 R1 K2 + 0x78120001, // 0003 JMPF R4 #0006 + 0x88100302, // 0004 GETMBR R4 R1 K2 + 0x70020001, // 0005 JMP #0008 + 0x88100100, // 0006 GETMBR R4 R0 K0 + 0x88100903, // 0007 GETMBR R4 R4 K3 + 0x88140304, // 0008 GETMBR R5 R1 K4 + 0x78160001, // 0009 JMPF R5 #000C + 0x88140304, // 000A GETMBR R5 R1 K4 + 0x70020001, // 000B JMP #000E + 0x88140100, // 000C GETMBR R5 R0 K0 + 0x88140B05, // 000D GETMBR R5 R5 K5 + 0x88180306, // 000E GETMBR R6 R1 K6 + 0x7C080800, // 000F CALL R2 4 + 0x780A000E, // 0010 JMPF R2 #0020 + 0xB80E0E00, // 0011 GETNGBL R3 K7 + 0x8C0C0708, // 0012 GETMET R3 R3 K8 + 0x54160003, // 0013 LDINT R5 4 + 0x7C0C0400, // 0014 CALL R3 2 + 0x780E0008, // 0015 JMPF R3 #001F + 0xB80E0E00, // 0016 GETNGBL R3 K7 + 0x8C0C0709, // 0017 GETMET R3 R3 K9 + 0x60140018, // 0018 GETGBL R5 G24 + 0x5818000A, // 0019 LDCONST R6 K10 + 0x881C0302, // 001A GETMBR R7 R1 K2 + 0x88200304, // 001B GETMBR R8 R1 K4 + 0x7C140600, // 001C CALL R5 3 + 0x541A0003, // 001D LDINT R6 4 + 0x7C0C0600, // 001E CALL R3 3 + 0x7002000D, // 001F JMP #002E + 0xB80E0E00, // 0020 GETNGBL R3 K7 + 0x8C0C0708, // 0021 GETMET R3 R3 K8 + 0x5814000B, // 0022 LDCONST R5 K11 + 0x7C0C0400, // 0023 CALL R3 2 + 0x780E0008, // 0024 JMPF R3 #002E + 0xB80E0E00, // 0025 GETNGBL R3 K7 + 0x8C0C0709, // 0026 GETMET R3 R3 K9 + 0x60140018, // 0027 GETGBL R5 G24 + 0x5818000C, // 0028 LDCONST R6 K12 + 0x881C0302, // 0029 GETMBR R7 R1 K2 + 0x88200304, // 002A GETMBR R8 R1 K4 + 0x7C140600, // 002B CALL R5 3 + 0x5818000B, // 002C LDCONST R6 K11 + 0x7C0C0600, // 002D CALL R3 3 + 0x80040400, // 002E RET 1 R2 }) ) ); @@ -481,12 +421,13 @@ be_local_closure(Matter_UDPServer_stop, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ + ( &(const bvalue[ 6]) { /* constants */ /* K0 */ be_nested_str_weak(listening), /* K1 */ be_nested_str_weak(udp_socket), /* K2 */ be_nested_str_weak(stop), /* K3 */ be_nested_str_weak(tasmota), - /* K4 */ be_nested_str_weak(remove_driver), + /* K4 */ be_nested_str_weak(remove_fast_loop), + /* K5 */ be_nested_str_weak(loop_cb), }), be_str_weak(stop), &be_const_str_solidified, @@ -500,7 +441,7 @@ be_local_closure(Matter_UDPServer_stop, /* name */ 0x90020001, // 0006 SETMBR R0 K0 R1 0xB8060600, // 0007 GETNGBL R1 K3 0x8C040304, // 0008 GETMET R1 R1 K4 - 0x5C0C0000, // 0009 MOVE R3 R0 + 0x880C0105, // 0009 GETMBR R3 R0 K5 0x7C040400, // 000A CALL R1 2 0x80000000, // 000B RET 0 }) @@ -510,55 +451,74 @@ be_local_closure(Matter_UDPServer_stop, /* name */ /******************************************************************** -** Solidified function: start +** Solidified function: init ********************************************************************/ -be_local_closure(Matter_UDPServer_start, /* name */ +be_local_closure(Matter_UDPServer_init, /* name */ be_nested_proto( - 6, /* nstack */ - 2, /* argc */ + 5, /* nstack */ + 4, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 2, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(loop), + }), + be_str_weak(_anonymous_), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x7C000200, // 0002 CALL R0 1 + 0x80000000, // 0003 RET 0 + }) + ), + }), 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ - /* K0 */ be_nested_str_weak(listening), - /* K1 */ be_nested_str_weak(udp_socket), - /* K2 */ be_nested_str_weak(udp), - /* K3 */ be_nested_str_weak(begin), - /* K4 */ be_nested_str_weak(addr), - /* K5 */ be_nested_str_weak(port), - /* K6 */ be_nested_str_weak(network_error), - /* K7 */ be_nested_str_weak(could_X20not_X20open_X20UDP_X20server), - /* K8 */ be_nested_str_weak(dispatch_cb), - /* K9 */ be_nested_str_weak(tasmota), - /* K10 */ be_nested_str_weak(add_driver), + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(device), + /* K1 */ be_nested_str_weak(addr), + /* K2 */ be_nested_str_weak(), + /* K3 */ be_nested_str_weak(port), + /* K4 */ be_nested_str_weak(listening), + /* K5 */ be_nested_str_weak(packets_sent), + /* K6 */ be_nested_str_weak(loop_cb), }), - be_str_weak(start), + be_str_weak(init), &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x740A0011, // 0001 JMPT R2 #0014 - 0xB80A0400, // 0002 GETNGBL R2 K2 - 0x7C080000, // 0003 CALL R2 0 - 0x90020202, // 0004 SETMBR R0 K1 R2 - 0x88080101, // 0005 GETMBR R2 R0 K1 - 0x8C080503, // 0006 GETMET R2 R2 K3 - 0x88100104, // 0007 GETMBR R4 R0 K4 - 0x88140105, // 0008 GETMBR R5 R0 K5 - 0x7C080600, // 0009 CALL R2 3 - 0x5C0C0400, // 000A MOVE R3 R2 - 0x740E0000, // 000B JMPT R3 #000D - 0xB0060D07, // 000C RAISE 1 K6 K7 - 0x500C0200, // 000D LDBOOL R3 1 0 - 0x90020003, // 000E SETMBR R0 K0 R3 - 0x90021001, // 000F SETMBR R0 K8 R1 - 0xB80E1200, // 0010 GETNGBL R3 K9 - 0x8C0C070A, // 0011 GETMET R3 R3 K10 - 0x5C140000, // 0012 MOVE R5 R0 - 0x7C0C0400, // 0013 CALL R3 2 - 0x80000000, // 0014 RET 0 + ( &(const binstruction[20]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x780A0001, // 0001 JMPF R2 #0004 + 0x5C100400, // 0002 MOVE R4 R2 + 0x70020000, // 0003 JMP #0005 + 0x58100002, // 0004 LDCONST R4 K2 + 0x90020204, // 0005 SETMBR R0 K1 R4 + 0x780E0001, // 0006 JMPF R3 #0009 + 0x5C100600, // 0007 MOVE R4 R3 + 0x70020000, // 0008 JMP #000A + 0x541215A3, // 0009 LDINT R4 5540 + 0x90020604, // 000A SETMBR R0 K3 R4 + 0x50100000, // 000B LDBOOL R4 0 0 + 0x90020804, // 000C SETMBR R0 K4 R4 + 0x60100012, // 000D GETGBL R4 G18 + 0x7C100000, // 000E CALL R4 0 + 0x90020A04, // 000F SETMBR R0 K5 R4 + 0x84100000, // 0010 CLOSURE R4 P0 + 0x90020C04, // 0011 SETMBR R0 K6 R4 + 0xA0000000, // 0012 CLOSE R0 + 0x80000000, // 0013 RET 0 }) ) ); @@ -566,79 +526,103 @@ be_local_closure(Matter_UDPServer_start, /* name */ /******************************************************************** -** Solidified function: received_ack +** Solidified function: _resend_packets ********************************************************************/ -be_local_closure(Matter_UDPServer_received_ack, /* name */ +be_local_closure(Matter_UDPServer__resend_packets, /* name */ be_nested_proto( - 10, /* nstack */ - 2, /* argc */ + 11, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[12]) { /* constants */ - /* K0 */ be_nested_str_weak(ack_message_counter), - /* K1 */ be_nested_str_weak(exchange_id), + ( &(const bvalue[20]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(packets_sent), /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(log), - /* K4 */ be_nested_str_weak(MTR_X3A_X20receveived_X20ACK_X20id_X3D), - /* K5 */ be_const_int(3), - /* K6 */ be_const_int(0), - /* K7 */ be_nested_str_weak(packets_sent), - /* K8 */ be_nested_str_weak(msg_id), - /* K9 */ be_nested_str_weak(remove), - /* K10 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Removed_X20packet_X20from_X20sending_X20list_X20id_X3D), - /* K11 */ be_const_int(1), + /* K3 */ be_nested_str_weak(time_reached), + /* K4 */ be_nested_str_weak(next_try), + /* K5 */ be_nested_str_weak(retries), + /* K6 */ be_nested_str_weak(RETRIES), + /* K7 */ be_nested_str_weak(log), + /* K8 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20Resending_X20packet_X20id_X3D), + /* K9 */ be_nested_str_weak(msg_id), + /* K10 */ be_nested_str_weak(send), + /* K11 */ be_nested_str_weak(millis), + /* K12 */ be_nested_str_weak(_backoff_time), + /* K13 */ be_const_int(1), + /* K14 */ be_nested_str_weak(remove), + /* K15 */ be_nested_str_weak(MTR_X3A_X20_X2E_X20_X20_X20_X20_X20_X20_X20_X20_X20_X20_X28_X256i_X29_X20Unacked_X20packet_X20_X27_X5B_X25s_X5D_X3A_X25i_X27_X20msg_id_X3D_X25i), + /* K16 */ be_nested_str_weak(session_id), + /* K17 */ be_nested_str_weak(addr), + /* K18 */ be_nested_str_weak(port), + /* K19 */ be_const_int(3), }), - be_str_weak(received_ack), + be_str_weak(_resend_packets), &be_const_str_solidified, - ( &(const binstruction[44]) { /* code */ - 0x88080300, // 0000 GETMBR R2 R1 K0 - 0x880C0301, // 0001 GETMBR R3 R1 K1 - 0x4C100000, // 0002 LDNIL R4 - 0x1C100404, // 0003 EQ R4 R2 R4 - 0x78120000, // 0004 JMPF R4 #0006 - 0x80000800, // 0005 RET 0 - 0xB8120400, // 0006 GETNGBL R4 K2 - 0x8C100903, // 0007 GETMET R4 R4 K3 - 0x60180008, // 0008 GETGBL R6 G8 - 0x5C1C0400, // 0009 MOVE R7 R2 - 0x7C180200, // 000A CALL R6 1 - 0x001A0806, // 000B ADD R6 K4 R6 - 0x581C0005, // 000C LDCONST R7 K5 - 0x7C100600, // 000D CALL R4 3 - 0x58100006, // 000E LDCONST R4 K6 - 0x6014000C, // 000F GETGBL R5 G12 - 0x88180107, // 0010 GETMBR R6 R0 K7 - 0x7C140200, // 0011 CALL R5 1 - 0x14140805, // 0012 LT R5 R4 R5 - 0x78160016, // 0013 JMPF R5 #002B - 0x88140107, // 0014 GETMBR R5 R0 K7 - 0x94140A04, // 0015 GETIDX R5 R5 R4 - 0x88180B08, // 0016 GETMBR R6 R5 K8 - 0x1C180C02, // 0017 EQ R6 R6 R2 - 0x781A000F, // 0018 JMPF R6 #0029 - 0x88180B01, // 0019 GETMBR R6 R5 K1 - 0x1C180C03, // 001A EQ R6 R6 R3 - 0x781A000C, // 001B JMPF R6 #0029 - 0x88180107, // 001C GETMBR R6 R0 K7 - 0x8C180D09, // 001D GETMET R6 R6 K9 - 0x5C200800, // 001E MOVE R8 R4 - 0x7C180400, // 001F CALL R6 2 - 0xB81A0400, // 0020 GETNGBL R6 K2 - 0x8C180D03, // 0021 GETMET R6 R6 K3 - 0x60200008, // 0022 GETGBL R8 G8 - 0x5C240400, // 0023 MOVE R9 R2 - 0x7C200200, // 0024 CALL R8 1 - 0x00221408, // 0025 ADD R8 K10 R8 - 0x58240005, // 0026 LDCONST R9 K5 - 0x7C180600, // 0027 CALL R6 3 - 0x70020000, // 0028 JMP #002A - 0x0010090B, // 0029 ADD R4 R4 K11 - 0x7001FFE3, // 002A JMP #000F - 0x80000000, // 002B RET 0 + ( &(const binstruction[60]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x6008000C, // 0001 GETGBL R2 G12 + 0x880C0101, // 0002 GETMBR R3 R0 K1 + 0x7C080200, // 0003 CALL R2 1 + 0x14080202, // 0004 LT R2 R1 R2 + 0x780A0034, // 0005 JMPF R2 #003B + 0x88080101, // 0006 GETMBR R2 R0 K1 + 0x94080401, // 0007 GETIDX R2 R2 R1 + 0xB80E0400, // 0008 GETNGBL R3 K2 + 0x8C0C0703, // 0009 GETMET R3 R3 K3 + 0x88140504, // 000A GETMBR R5 R2 K4 + 0x7C0C0400, // 000B CALL R3 2 + 0x780E002B, // 000C JMPF R3 #0039 + 0x880C0505, // 000D GETMBR R3 R2 K5 + 0x88100106, // 000E GETMBR R4 R0 K6 + 0x180C0604, // 000F LE R3 R3 R4 + 0x780E0017, // 0010 JMPF R3 #0029 + 0xB80E0400, // 0011 GETNGBL R3 K2 + 0x8C0C0707, // 0012 GETMET R3 R3 K7 + 0x60140008, // 0013 GETGBL R5 G8 + 0x88180509, // 0014 GETMBR R6 R2 K9 + 0x7C140200, // 0015 CALL R5 1 + 0x00161005, // 0016 ADD R5 K8 R5 + 0x541A0003, // 0017 LDINT R6 4 + 0x7C0C0600, // 0018 CALL R3 3 + 0x8C0C010A, // 0019 GETMET R3 R0 K10 + 0x5C140400, // 001A MOVE R5 R2 + 0x7C0C0400, // 001B CALL R3 2 + 0xB80E0400, // 001C GETNGBL R3 K2 + 0x8C0C070B, // 001D GETMET R3 R3 K11 + 0x7C0C0200, // 001E CALL R3 1 + 0x8C10010C, // 001F GETMET R4 R0 K12 + 0x88180505, // 0020 GETMBR R6 R2 K5 + 0x7C100400, // 0021 CALL R4 2 + 0x000C0604, // 0022 ADD R3 R3 R4 + 0x900A0803, // 0023 SETMBR R2 K4 R3 + 0x880C0505, // 0024 GETMBR R3 R2 K5 + 0x000C070D, // 0025 ADD R3 R3 K13 + 0x900A0A03, // 0026 SETMBR R2 K5 R3 + 0x0004030D, // 0027 ADD R1 R1 K13 + 0x7002000E, // 0028 JMP #0038 + 0x880C0101, // 0029 GETMBR R3 R0 K1 + 0x8C0C070E, // 002A GETMET R3 R3 K14 + 0x5C140200, // 002B MOVE R5 R1 + 0x7C0C0400, // 002C CALL R3 2 + 0xB80E0400, // 002D GETNGBL R3 K2 + 0x8C0C0707, // 002E GETMET R3 R3 K7 + 0x60140018, // 002F GETGBL R5 G24 + 0x5818000F, // 0030 LDCONST R6 K15 + 0x881C0510, // 0031 GETMBR R7 R2 K16 + 0x88200511, // 0032 GETMBR R8 R2 K17 + 0x88240512, // 0033 GETMBR R9 R2 K18 + 0x88280509, // 0034 GETMBR R10 R2 K9 + 0x7C140A00, // 0035 CALL R5 5 + 0x58180013, // 0036 LDCONST R6 K19 + 0x7C0C0600, // 0037 CALL R3 3 + 0x70020000, // 0038 JMP #003A + 0x0004030D, // 0039 ADD R1 R1 K13 + 0x7001FFC5, // 003A JMP #0001 + 0x80000000, // 003B RET 0 }) ) ); @@ -646,44 +630,193 @@ be_local_closure(Matter_UDPServer_received_ack, /* name */ /******************************************************************** -** Solidified function: init +** Solidified function: _backoff_time ********************************************************************/ -be_local_closure(Matter_UDPServer_init, /* name */ +be_local_closure(Matter_UDPServer__backoff_time, /* name */ be_nested_proto( - 4, /* nstack */ - 3, /* argc */ + 10, /* nstack */ + 1, /* argc */ + 4, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_const_int(1), + /* K1 */ be_const_int(0), + }), + be_str_weak(power_int), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x58080000, // 0000 LDCONST R2 K0 + 0x240C0301, // 0001 GT R3 R1 K1 + 0x780E0002, // 0002 JMPF R3 #0006 + 0x08080400, // 0003 MUL R2 R2 R0 + 0x04040300, // 0004 SUB R1 R1 K0 + 0x7001FFFA, // 0005 JMP #0001 + 0x80040400, // 0006 RET 1 R2 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_const_class(be_class_Matter_UDPServer), + /* K1 */ be_nested_str_weak(math), + /* K2 */ be_nested_str_weak(rand), + /* K3 */ be_const_int(0), + /* K4 */ be_const_int(1), + /* K5 */ be_const_real_hex(0x3FCCCCCD), + /* K6 */ be_const_real_hex(0x3F800000), + /* K7 */ be_const_real_hex(0x3E800000), + }), + be_str_weak(_backoff_time), + &be_const_str_solidified, + ( &(const binstruction[29]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x84080000, // 0001 CLOSURE R2 P0 + 0xA40E0200, // 0002 IMPORT R3 K1 + 0x5412012B, // 0003 LDINT R4 300 + 0x6014000A, // 0004 GETGBL R5 G10 + 0x8C180702, // 0005 GETMET R6 R3 K2 + 0x7C180200, // 0006 CALL R6 1 + 0x541E00FE, // 0007 LDINT R7 255 + 0x2C180C07, // 0008 AND R6 R6 R7 + 0x7C140200, // 0009 CALL R5 1 + 0x541A00FE, // 000A LDINT R6 255 + 0x0C140A06, // 000B DIV R5 R5 R6 + 0x24180103, // 000C GT R6 R0 K3 + 0x781A0001, // 000D JMPF R6 #0010 + 0x04180104, // 000E SUB R6 R0 K4 + 0x70020000, // 000F JMP #0011 + 0x58180003, // 0010 LDCONST R6 K3 + 0x5C1C0400, // 0011 MOVE R7 R2 + 0x58200005, // 0012 LDCONST R8 K5 + 0x5C240C00, // 0013 MOVE R9 R6 + 0x7C1C0400, // 0014 CALL R7 2 + 0x081C0807, // 0015 MUL R7 R4 R7 + 0x08200B07, // 0016 MUL R8 R5 K7 + 0x00220C08, // 0017 ADD R8 K6 R8 + 0x081C0E08, // 0018 MUL R7 R7 R8 + 0x60200009, // 0019 GETGBL R8 G9 + 0x5C240E00, // 001A MOVE R9 R7 + 0x7C200200, // 001B CALL R8 1 + 0x80041000, // 001C RET 1 R8 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: loop +********************************************************************/ +be_local_closure(Matter_UDPServer_loop, /* name */ + be_nested_proto( + 12, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(addr), - /* K1 */ be_nested_str_weak(), - /* K2 */ be_nested_str_weak(port), - /* K3 */ be_nested_str_weak(listening), - /* K4 */ be_nested_str_weak(packets_sent), + ( &(const bvalue[20]) { /* constants */ + /* K0 */ be_nested_str_weak(matter), + /* K1 */ be_nested_str_weak(profiler), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_weak(udp_socket), + /* K4 */ be_nested_str_weak(read), + /* K5 */ be_nested_str_weak(packet), + /* K6 */ be_nested_str_weak(start), + /* K7 */ be_const_int(1), + /* K8 */ be_nested_str_weak(remote_ip), + /* K9 */ be_nested_str_weak(remote_port), + /* K10 */ be_nested_str_weak(tasmota), + /* K11 */ be_nested_str_weak(loglevel), + /* K12 */ be_nested_str_weak(log), + /* K13 */ be_nested_str_weak(MTR_X3A_X20UDP_X20received_X20from_X20_X5B_X25s_X5D_X3A_X25i), + /* K14 */ be_nested_str_weak(dispatch_cb), + /* K15 */ be_nested_str_weak(udp_loop_dispatch), + /* K16 */ be_nested_str_weak(dump), + /* K17 */ be_const_int(2), + /* K18 */ be_nested_str_weak(MAX_PACKETS_READ), + /* K19 */ be_nested_str_weak(_resend_packets), }), - be_str_weak(init), + be_str_weak(loop), &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x78060001, // 0000 JMPF R1 #0003 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x70020000, // 0002 JMP #0004 - 0x580C0001, // 0003 LDCONST R3 K1 - 0x90020003, // 0004 SETMBR R0 K0 R3 - 0x780A0001, // 0005 JMPF R2 #0008 - 0x5C0C0400, // 0006 MOVE R3 R2 - 0x70020000, // 0007 JMP #0009 - 0x540E15A3, // 0008 LDINT R3 5540 - 0x90020403, // 0009 SETMBR R0 K2 R3 - 0x500C0000, // 000A LDBOOL R3 0 0 - 0x90020603, // 000B SETMBR R0 K3 R3 - 0x600C0012, // 000C GETGBL R3 G18 - 0x7C0C0000, // 000D CALL R3 0 - 0x90020803, // 000E SETMBR R0 K4 R3 - 0x80000000, // 000F RET 0 + ( &(const binstruction[63]) { /* code */ + 0xB8060000, // 0000 GETNGBL R1 K0 + 0x88040301, // 0001 GETMBR R1 R1 K1 + 0x58080002, // 0002 LDCONST R2 K2 + 0x880C0103, // 0003 GETMBR R3 R0 K3 + 0x4C100000, // 0004 LDNIL R4 + 0x1C0C0604, // 0005 EQ R3 R3 R4 + 0x780E0000, // 0006 JMPF R3 #0008 + 0x80000600, // 0007 RET 0 + 0x880C0103, // 0008 GETMBR R3 R0 K3 + 0x8C0C0704, // 0009 GETMET R3 R3 K4 + 0x88140105, // 000A GETMBR R5 R0 K5 + 0x7C0C0400, // 000B CALL R3 2 + 0x4C100000, // 000C LDNIL R4 + 0x20100604, // 000D NE R4 R3 R4 + 0x7812002C, // 000E JMPF R4 #003C + 0x8C100306, // 000F GETMET R4 R1 K6 + 0x7C100200, // 0010 CALL R4 1 + 0x90020A03, // 0011 SETMBR R0 K5 R3 + 0x00080507, // 0012 ADD R2 R2 K7 + 0x88100103, // 0013 GETMBR R4 R0 K3 + 0x88100908, // 0014 GETMBR R4 R4 K8 + 0x88140103, // 0015 GETMBR R5 R0 K3 + 0x88140B09, // 0016 GETMBR R5 R5 K9 + 0xB81A1400, // 0017 GETNGBL R6 K10 + 0x8C180D0B, // 0018 GETMET R6 R6 K11 + 0x54220003, // 0019 LDINT R8 4 + 0x7C180400, // 001A CALL R6 2 + 0x781A0008, // 001B JMPF R6 #0025 + 0xB81A1400, // 001C GETNGBL R6 K10 + 0x8C180D0C, // 001D GETMET R6 R6 K12 + 0x60200018, // 001E GETGBL R8 G24 + 0x5824000D, // 001F LDCONST R9 K13 + 0x5C280800, // 0020 MOVE R10 R4 + 0x5C2C0A00, // 0021 MOVE R11 R5 + 0x7C200600, // 0022 CALL R8 3 + 0x54260003, // 0023 LDINT R9 4 + 0x7C180600, // 0024 CALL R6 3 + 0x8818010E, // 0025 GETMBR R6 R0 K14 + 0x781A0007, // 0026 JMPF R6 #002F + 0x8C18030C, // 0027 GETMET R6 R1 K12 + 0x5820000F, // 0028 LDCONST R8 K15 + 0x7C180400, // 0029 CALL R6 2 + 0x8C18010E, // 002A GETMET R6 R0 K14 + 0x5C200600, // 002B MOVE R8 R3 + 0x5C240800, // 002C MOVE R9 R4 + 0x5C280A00, // 002D MOVE R10 R5 + 0x7C180800, // 002E CALL R6 4 + 0x8C180310, // 002F GETMET R6 R1 K16 + 0x58200011, // 0030 LDCONST R8 K17 + 0x7C180400, // 0031 CALL R6 2 + 0x88180112, // 0032 GETMBR R6 R0 K18 + 0x14180406, // 0033 LT R6 R2 R6 + 0x781A0004, // 0034 JMPF R6 #003A + 0x88180103, // 0035 GETMBR R6 R0 K3 + 0x8C180D04, // 0036 GETMET R6 R6 K4 + 0x7C180200, // 0037 CALL R6 1 + 0x5C0C0C00, // 0038 MOVE R3 R6 + 0x70020000, // 0039 JMP #003B + 0x4C0C0000, // 003A LDNIL R3 + 0x7001FFCF, // 003B JMP #000C + 0x8C100113, // 003C GETMET R4 R0 K19 + 0x7C100200, // 003D CALL R4 1 + 0x80000000, // 003E RET 0 }) ) ); @@ -691,75 +824,23 @@ be_local_closure(Matter_UDPServer_init, /* name */ /******************************************************************** -** Solidified function: send +** Solidified function: every_second ********************************************************************/ -be_local_closure(Matter_UDPServer_send, /* name */ +be_local_closure(Matter_UDPServer_every_second, /* name */ be_nested_proto( - 11, /* nstack */ - 2, /* argc */ + 1, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[14]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(udp_socket), - /* K2 */ be_nested_str_weak(send), - /* K3 */ be_nested_str_weak(addr), - /* K4 */ be_nested_str_weak(remote_ip), - /* K5 */ be_nested_str_weak(port), - /* K6 */ be_nested_str_weak(remote_port), - /* K7 */ be_nested_str_weak(raw), - /* K8 */ be_nested_str_weak(tasmota), - /* K9 */ be_nested_str_weak(log), - /* K10 */ be_nested_str_weak(format), - /* K11 */ be_nested_str_weak(MTR_X3A_X20sending_X20packet_X20to_X20_X27_X5B_X25s_X5D_X3A_X25i_X27), - /* K12 */ be_nested_str_weak(MTR_X3A_X20error_X20sending_X20packet_X20to_X20_X27_X5B_X25s_X5D_X3A_X25i_X27), - /* K13 */ be_const_int(2), - }), - be_str_weak(send), + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(every_second), &be_const_str_solidified, - ( &(const binstruction[38]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x880C0101, // 0001 GETMBR R3 R0 K1 - 0x8C0C0702, // 0002 GETMET R3 R3 K2 - 0x88140303, // 0003 GETMBR R5 R1 K3 - 0x78160001, // 0004 JMPF R5 #0007 - 0x88140303, // 0005 GETMBR R5 R1 K3 - 0x70020001, // 0006 JMP #0009 - 0x88140101, // 0007 GETMBR R5 R0 K1 - 0x88140B04, // 0008 GETMBR R5 R5 K4 - 0x88180305, // 0009 GETMBR R6 R1 K5 - 0x781A0001, // 000A JMPF R6 #000D - 0x88180305, // 000B GETMBR R6 R1 K5 - 0x70020001, // 000C JMP #000F - 0x88180101, // 000D GETMBR R6 R0 K1 - 0x88180D06, // 000E GETMBR R6 R6 K6 - 0x881C0307, // 000F GETMBR R7 R1 K7 - 0x7C0C0800, // 0010 CALL R3 4 - 0x780E0009, // 0011 JMPF R3 #001C - 0xB8121000, // 0012 GETNGBL R4 K8 - 0x8C100909, // 0013 GETMET R4 R4 K9 - 0x8C18050A, // 0014 GETMET R6 R2 K10 - 0x5820000B, // 0015 LDCONST R8 K11 - 0x88240303, // 0016 GETMBR R9 R1 K3 - 0x88280305, // 0017 GETMBR R10 R1 K5 - 0x7C180800, // 0018 CALL R6 4 - 0x541E0003, // 0019 LDINT R7 4 - 0x7C100600, // 001A CALL R4 3 - 0x70020008, // 001B JMP #0025 - 0xB8121000, // 001C GETNGBL R4 K8 - 0x8C100909, // 001D GETMET R4 R4 K9 - 0x8C18050A, // 001E GETMET R6 R2 K10 - 0x5820000C, // 001F LDCONST R8 K12 - 0x88240303, // 0020 GETMBR R9 R1 K3 - 0x88280305, // 0021 GETMBR R10 R1 K5 - 0x7C180800, // 0022 CALL R6 4 - 0x581C000D, // 0023 LDCONST R7 K13 - 0x7C100600, // 0024 CALL R4 3 - 0x80040600, // 0025 RET 1 R3 + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 }) ) ); @@ -770,28 +851,32 @@ be_local_closure(Matter_UDPServer_send, /* name */ ** Solidified class: Matter_UDPServer ********************************************************************/ be_local_class(Matter_UDPServer, - 6, + 9, NULL, - be_nested_map(18, + be_nested_map(22, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(_backoff_time, 17), be_const_static_closure(Matter_UDPServer__backoff_time_closure) }, - { be_const_key_weak(packets_sent, -1), be_const_var(5) }, - { be_const_key_weak(addr, -1), be_const_var(0) }, - { be_const_key_weak(every_second, -1), be_const_closure(Matter_UDPServer_every_second_closure) }, - { be_const_key_weak(port, -1), be_const_var(1) }, - { be_const_key_weak(dispatch_cb, 1), be_const_var(4) }, - { be_const_key_weak(udp_socket, -1), be_const_var(3) }, - { be_const_key_weak(send_UDP, -1), be_const_closure(Matter_UDPServer_send_UDP_closure) }, { be_const_key_weak(every_50ms, -1), be_const_closure(Matter_UDPServer_every_50ms_closure) }, - { be_const_key_weak(send, 10), be_const_closure(Matter_UDPServer_send_closure) }, - { be_const_key_weak(RETRIES, -1), be_const_int(5) }, - { be_const_key_weak(stop, 16), be_const_closure(Matter_UDPServer_stop_closure) }, + { be_const_key_weak(send_UDP, -1), be_const_closure(Matter_UDPServer_send_UDP_closure) }, { be_const_key_weak(received_ack, -1), be_const_closure(Matter_UDPServer_received_ack_closure) }, - { be_const_key_weak(_resend_packets, 9), be_const_closure(Matter_UDPServer__resend_packets_closure) }, - { be_const_key_weak(MAX_PACKETS_READ, -1), be_const_int(4) }, + { be_const_key_weak(every_second, -1), be_const_closure(Matter_UDPServer_every_second_closure) }, + { be_const_key_weak(stop, 18), be_const_closure(Matter_UDPServer_stop_closure) }, + { be_const_key_weak(start, 4), be_const_closure(Matter_UDPServer_start_closure) }, + { be_const_key_weak(listening, -1), be_const_var(3) }, + { be_const_key_weak(send, -1), be_const_closure(Matter_UDPServer_send_closure) }, + { be_const_key_weak(loop, -1), be_const_closure(Matter_UDPServer_loop_closure) }, { be_const_key_weak(init, -1), be_const_closure(Matter_UDPServer_init_closure) }, - { be_const_key_weak(start, -1), be_const_closure(Matter_UDPServer_start_closure) }, - { be_const_key_weak(listening, -1), be_const_var(2) }, + { be_const_key_weak(udp_socket, 6), be_const_var(4) }, + { be_const_key_weak(packet, -1), be_const_var(8) }, + { be_const_key_weak(_backoff_time, -1), be_const_static_closure(Matter_UDPServer__backoff_time_closure) }, + { be_const_key_weak(_resend_packets, -1), be_const_closure(Matter_UDPServer__resend_packets_closure) }, + { be_const_key_weak(addr, -1), be_const_var(0) }, + { be_const_key_weak(dispatch_cb, 8), be_const_var(5) }, + { be_const_key_weak(port, 12), be_const_var(1) }, + { be_const_key_weak(packets_sent, -1), be_const_var(6) }, + { be_const_key_weak(device, -1), be_const_var(2) }, + { be_const_key_weak(loop_cb, -1), be_const_var(7) }, + { be_const_key_weak(MAX_PACKETS_READ, -1), be_const_int(4) }, + { be_const_key_weak(RETRIES, 3), be_const_int(5) }, })), be_str_weak(Matter_UDPServer) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_UI.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_UI.h index 76d72c390c6b..ea7755189340 100644 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_UI.h +++ b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_UI.h @@ -7,11 +7,92 @@ extern const bclass be_class_Matter_UI; /******************************************************************** -** Solidified function: show_plugins_configuration +** Solidified function: equal_map ********************************************************************/ -be_local_closure(Matter_UI_show_plugins_configuration, /* name */ +be_local_closure(Matter_UI_equal_map, /* name */ be_nested_proto( - 19, /* nstack */ + 8, /* nstack */ + 2, /* argc */ + 4, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_const_class(be_class_Matter_UI), + /* K1 */ be_nested_str_weak(keys), + /* K2 */ be_nested_str_weak(contains), + /* K3 */ be_nested_str_weak(stop_iteration), + }), + be_str_weak(equal_map), + &be_const_str_solidified, + ( &(const binstruction[53]) { /* code */ + 0x58080000, // 0000 LDCONST R2 K0 + 0x600C0010, // 0001 GETGBL R3 G16 + 0x8C100101, // 0002 GETMET R4 R0 K1 + 0x7C100200, // 0003 CALL R4 1 + 0x7C0C0200, // 0004 CALL R3 1 + 0xA8020010, // 0005 EXBLK 0 #0017 + 0x5C100600, // 0006 MOVE R4 R3 + 0x7C100000, // 0007 CALL R4 0 + 0x8C140302, // 0008 GETMET R5 R1 K2 + 0x5C1C0800, // 0009 MOVE R7 R4 + 0x7C140400, // 000A CALL R5 2 + 0x74160002, // 000B JMPT R5 #000F + 0x50140000, // 000C LDBOOL R5 0 0 + 0xA8040001, // 000D EXBLK 1 1 + 0x80040A00, // 000E RET 1 R5 + 0x94140204, // 000F GETIDX R5 R1 R4 + 0x94180004, // 0010 GETIDX R6 R0 R4 + 0x20140A06, // 0011 NE R5 R5 R6 + 0x78160002, // 0012 JMPF R5 #0016 + 0x50140000, // 0013 LDBOOL R5 0 0 + 0xA8040001, // 0014 EXBLK 1 1 + 0x80040A00, // 0015 RET 1 R5 + 0x7001FFEE, // 0016 JMP #0006 + 0x580C0003, // 0017 LDCONST R3 K3 + 0xAC0C0200, // 0018 CATCH R3 1 0 + 0xB0080000, // 0019 RAISE 2 R0 R0 + 0x600C0010, // 001A GETGBL R3 G16 + 0x8C100301, // 001B GETMET R4 R1 K1 + 0x7C100200, // 001C CALL R4 1 + 0x7C0C0200, // 001D CALL R3 1 + 0xA8020010, // 001E EXBLK 0 #0030 + 0x5C100600, // 001F MOVE R4 R3 + 0x7C100000, // 0020 CALL R4 0 + 0x8C140102, // 0021 GETMET R5 R0 K2 + 0x5C1C0800, // 0022 MOVE R7 R4 + 0x7C140400, // 0023 CALL R5 2 + 0x74160002, // 0024 JMPT R5 #0028 + 0x50140000, // 0025 LDBOOL R5 0 0 + 0xA8040001, // 0026 EXBLK 1 1 + 0x80040A00, // 0027 RET 1 R5 + 0x94140204, // 0028 GETIDX R5 R1 R4 + 0x94180004, // 0029 GETIDX R6 R0 R4 + 0x20140A06, // 002A NE R5 R5 R6 + 0x78160002, // 002B JMPF R5 #002F + 0x50140000, // 002C LDBOOL R5 0 0 + 0xA8040001, // 002D EXBLK 1 1 + 0x80040A00, // 002E RET 1 R5 + 0x7001FFEE, // 002F JMP #001F + 0x580C0003, // 0030 LDCONST R3 K3 + 0xAC0C0200, // 0031 CATCH R3 1 0 + 0xB0080000, // 0032 RAISE 2 R0 R0 + 0x500C0200, // 0033 LDBOOL R3 1 0 + 0x80040600, // 0034 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: page_part_mgr_adv +********************************************************************/ +be_local_closure(Matter_UI_page_part_mgr_adv, /* name */ + be_nested_proto( + 5, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -19,228 +100,46 @@ be_local_closure(Matter_UI_show_plugins_configuration, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[36]) { /* constants */ + ( &(const bvalue[11]) { /* constants */ /* K0 */ be_nested_str_weak(webserver), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(content_send), - /* K3 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3BCurrent_X20Configuration_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E), - /* K4 */ be_nested_str_weak(_X3Cform_X20action_X3D_X27_X2Fmatterc_X27_X20method_X3D_X27post_X27), - /* K5 */ be_nested_str_weak(onsubmit_X3D_X27return_X20confirm_X28_X22This_X20will_X20RESET_X20the_X20configuration_X20to_X20the_X20default_X2E_X20You_X20will_X20need_X20to_X20associate_X20again_X2E_X22_X29_X3B_X27_X3E), - /* K6 */ be_nested_str_weak(_X3Cbutton_X20name_X3D_X27auto_X27_X20class_X3D_X27button_X20bred_X27_X3EReset_X20to_X20default_X3C_X2Fbutton_X3E_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Fform_X3E), - /* K7 */ be_nested_str_weak(onsubmit_X3D_X27return_X20confirm_X28_X22Changing_X20the_X20configuration_X20requires_X20to_X20associate_X20again_X2E_X22_X29_X3B_X27_X3E), - /* K8 */ be_nested_str_weak(_X3Ctable_X20style_X3D_X27width_X3A100_X25_X27_X3E), - /* K9 */ be_nested_str_weak(_X3Ctr_X3E_X3Ctd_X20width_X3D_X2735_X27_X3E_X3Cb_X3EEp_X2E_X3C_X2Fb_X3E_X3C_X2Ftd_X3E_X3Ctd_X3E_X3Cb_X3EType_X3C_X2Fb_X3E_X3C_X2Ftd_X3E_X3Ctd_X3E_X3Cb_X3EParam_X3C_X2Fb_X3E_X3C_X2Ftd_X3E_X3C_X2Ftr_X3E), - /* K10 */ be_nested_str_weak(device), - /* K11 */ be_nested_str_weak(k2l_num), - /* K12 */ be_nested_str_weak(plugins_config), - /* K13 */ be_const_int(0), - /* K14 */ be_nested_str_weak(find), - /* K15 */ be_nested_str_weak(type), - /* K16 */ be_nested_str_weak(format), - /* K17 */ be_nested_str_weak(_X3Ctr_X3E_X3Ctd_X3E_X3Cinput_X20type_X3D_X27text_X27_X20name_X3D_X27ep_X2503i_X27_X20maxlength_X3D_X274_X27_X20size_X3D_X273_X27_X20value_X3D_X270_X27_X20readonly_X3E_X3C_X2Ftd_X3E), - /* K18 */ be_nested_str_weak(_X3Ctd_X3E_X3Cselect_X20name_X3D_X27pi_X2503i_X27_X3E), - /* K19 */ be_nested_str_weak(plugin_option), - /* K20 */ be_nested_str_weak(), - /* K21 */ be_nested_str_weak(_ROOT_TYPES), - /* K22 */ be_nested_str_weak(_X3C_X2Fselect_X3E_X3C_X2Ftd_X3E), - /* K23 */ be_nested_str_weak(_X3Ctd_X3E_X3Cfont_X20size_X3D_X27_X2D1_X27_X3E_X26nbsp_X3B_X3C_X2Ffont_X3E_X3C_X2Ftd_X3E), - /* K24 */ be_const_int(1), - /* K25 */ be_nested_str_weak(plugins_classes), - /* K26 */ be_nested_str_weak(ui_conf_to_string), - /* K27 */ be_nested_str_weak(_X3Ctr_X3E_X3Ctd_X3E_X3Cinput_X20type_X3D_X27text_X27_X20name_X3D_X27ep_X2503i_X27_X20maxlength_X3D_X274_X27_X20size_X3D_X273_X27_X20pattern_X3D_X27_X5B0_X2D9_X5D_X7B1_X2C4_X7D_X27_X20value_X3D_X27_X25i_X27_X3E_X3C_X2Ftd_X3E), - /* K28 */ be_nested_str_weak(_CLASSES_TYPES), - /* K29 */ be_nested_str_weak(_X3Ctd_X3E_X3Cfont_X20size_X3D_X27_X2D1_X27_X3E_X3Cinput_X20type_X3D_X27text_X27_X20name_X3D_X27arg_X2503i_X27_X20minlength_X3D_X270_X27_X20size_X3D_X278_X27_X20value_X3D_X27_X25s_X27_X3E_X3C_X2Ffont_X3E_X3C_X2Ftd_X3E), - /* K30 */ be_nested_str_weak(html_escape), - /* K31 */ be_nested_str_weak(_X3Ctr_X3E_X3Ctd_X3E_X3Cinput_X20type_X3D_X27text_X27_X20name_X3D_X27ep_X2503i_X27_X20maxlength_X3D_X274_X27_X20size_X3D_X273_X27_X20pattern_X3D_X27_X5B0_X2D9_X5D_X7B1_X2C4_X7D_X27_X20value_X3D_X27_X27_X3E_X3C_X2Ftd_X3E), - /* K32 */ be_nested_str_weak(_X3Ctd_X3E_X3Cfont_X20size_X3D_X27_X2D1_X27_X3E_X3Cinput_X20type_X3D_X27text_X27_X20name_X3D_X27arg_X2503i_X27_X20minlength_X3D_X270_X27_X20size_X3D_X278_X27_X20value_X3D_X27_X27_X3E_X3C_X2Ffont_X3E_X3C_X2Ftd_X3E), - /* K33 */ be_nested_str_weak(_X3C_X2Ftable_X3E_X3Cp_X3E_X3C_X2Fp_X3E), - /* K34 */ be_nested_str_weak(_X3Cbutton_X20name_X3D_X27config_X27_X20class_X3D_X27button_X20bgrn_X27_X3EChange_X20configuration_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E), - /* K35 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K1 */ be_nested_str_weak(check_privileged_access), + /* K2 */ be_nested_str_weak(content_start), + /* K3 */ be_nested_str_weak(Matter_X20Advanced_X20Configuration), + /* K4 */ be_nested_str_weak(content_send_style), + /* K5 */ be_nested_str_weak(matter_enabled), + /* K6 */ be_nested_str_weak(show_passcode_form), + /* K7 */ be_nested_str_weak(show_fabric_info), + /* K8 */ be_nested_str_weak(content_button), + /* K9 */ be_nested_str_weak(BUTTON_CONFIGURATION), + /* K10 */ be_nested_str_weak(content_stop), }), - be_str_weak(show_plugins_configuration), + be_str_weak(page_part_mgr_adv), &be_const_str_solidified, - ( &(const binstruction[181]) { /* code */ + ( &(const binstruction[24]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0x8C0C0302, // 0002 GETMET R3 R1 K2 - 0x58140003, // 0003 LDCONST R5 K3 - 0x7C0C0400, // 0004 CALL R3 2 - 0x8C0C0302, // 0005 GETMET R3 R1 K2 - 0x58140004, // 0006 LDCONST R5 K4 - 0x7C0C0400, // 0007 CALL R3 2 - 0x8C0C0302, // 0008 GETMET R3 R1 K2 - 0x58140005, // 0009 LDCONST R5 K5 - 0x7C0C0400, // 000A CALL R3 2 - 0x8C0C0302, // 000B GETMET R3 R1 K2 - 0x58140006, // 000C LDCONST R5 K6 - 0x7C0C0400, // 000D CALL R3 2 - 0x8C0C0302, // 000E GETMET R3 R1 K2 - 0x58140004, // 000F LDCONST R5 K4 - 0x7C0C0400, // 0010 CALL R3 2 - 0x8C0C0302, // 0011 GETMET R3 R1 K2 - 0x58140007, // 0012 LDCONST R5 K7 - 0x7C0C0400, // 0013 CALL R3 2 - 0x8C0C0302, // 0014 GETMET R3 R1 K2 - 0x58140008, // 0015 LDCONST R5 K8 - 0x7C0C0400, // 0016 CALL R3 2 - 0x8C0C0302, // 0017 GETMET R3 R1 K2 - 0x58140009, // 0018 LDCONST R5 K9 - 0x7C0C0400, // 0019 CALL R3 2 - 0x880C010A, // 001A GETMBR R3 R0 K10 - 0x8C0C070B, // 001B GETMET R3 R3 K11 - 0x8814010A, // 001C GETMBR R5 R0 K10 - 0x88140B0C, // 001D GETMBR R5 R5 K12 - 0x7C0C0400, // 001E CALL R3 2 - 0x5810000D, // 001F LDCONST R4 K13 - 0x9414070D, // 0020 GETIDX R5 R3 K13 - 0x1C140B0D, // 0021 EQ R5 R5 K13 - 0x78160026, // 0022 JMPF R5 #004A - 0x94140604, // 0023 GETIDX R5 R3 R4 - 0x8818010A, // 0024 GETMBR R6 R0 K10 - 0x601C0008, // 0025 GETGBL R7 G8 - 0x5C200A00, // 0026 MOVE R8 R5 - 0x7C1C0200, // 0027 CALL R7 1 - 0x88180D0C, // 0028 GETMBR R6 R6 K12 - 0x94180C07, // 0029 GETIDX R6 R6 R7 - 0x8C200D0E, // 002A GETMET R8 R6 K14 - 0x5828000F, // 002B LDCONST R10 K15 - 0x7C200400, // 002C CALL R8 2 - 0x5C1C1000, // 002D MOVE R7 R8 - 0x8C200302, // 002E GETMET R8 R1 K2 - 0x8C280510, // 002F GETMET R10 R2 K16 - 0x58300011, // 0030 LDCONST R12 K17 - 0x5C340800, // 0031 MOVE R13 R4 - 0x7C280600, // 0032 CALL R10 3 - 0x7C200400, // 0033 CALL R8 2 - 0x8C200302, // 0034 GETMET R8 R1 K2 - 0x8C280510, // 0035 GETMET R10 R2 K16 - 0x58300012, // 0036 LDCONST R12 K18 - 0x5C340800, // 0037 MOVE R13 R4 - 0x7C280600, // 0038 CALL R10 3 - 0x7C200400, // 0039 CALL R8 2 - 0x8C200113, // 003A GETMET R8 R0 K19 - 0x8C280D0E, // 003B GETMET R10 R6 K14 - 0x5830000F, // 003C LDCONST R12 K15 - 0x58340014, // 003D LDCONST R13 K20 - 0x7C280600, // 003E CALL R10 3 - 0x882C0115, // 003F GETMBR R11 R0 K21 - 0x7C200600, // 0040 CALL R8 3 - 0x8C200302, // 0041 GETMET R8 R1 K2 - 0x8C280510, // 0042 GETMET R10 R2 K16 - 0x58300016, // 0043 LDCONST R12 K22 - 0x7C280400, // 0044 CALL R10 2 - 0x7C200400, // 0045 CALL R8 2 - 0x8C200302, // 0046 GETMET R8 R1 K2 - 0x58280017, // 0047 LDCONST R10 K23 - 0x7C200400, // 0048 CALL R8 2 - 0x00100918, // 0049 ADD R4 R4 K24 - 0x6014000C, // 004A GETGBL R5 G12 - 0x5C180600, // 004B MOVE R6 R3 - 0x7C140200, // 004C CALL R5 1 - 0x14140805, // 004D LT R5 R4 R5 - 0x78160040, // 004E JMPF R5 #0090 - 0x94140604, // 004F GETIDX R5 R3 R4 - 0x8818010A, // 0050 GETMBR R6 R0 K10 - 0x601C0008, // 0051 GETGBL R7 G8 - 0x5C200A00, // 0052 MOVE R8 R5 - 0x7C1C0200, // 0053 CALL R7 1 - 0x88180D0C, // 0054 GETMBR R6 R6 K12 - 0x94180C07, // 0055 GETIDX R6 R6 R7 - 0x8C200D0E, // 0056 GETMET R8 R6 K14 - 0x5828000F, // 0057 LDCONST R10 K15 - 0x7C200400, // 0058 CALL R8 2 - 0x5C1C1000, // 0059 MOVE R7 R8 - 0x5C200E00, // 005A MOVE R8 R7 - 0x74220001, // 005B JMPT R8 #005E - 0x00100918, // 005C ADD R4 R4 K24 - 0x7001FFEB, // 005D JMP #004A - 0x8820010A, // 005E GETMBR R8 R0 K10 - 0x88201119, // 005F GETMBR R8 R8 K25 - 0x8C20110E, // 0060 GETMET R8 R8 K14 - 0x5C280E00, // 0061 MOVE R10 R7 - 0x7C200400, // 0062 CALL R8 2 - 0x58240014, // 0063 LDCONST R9 K20 - 0x4C280000, // 0064 LDNIL R10 - 0x2028100A, // 0065 NE R10 R8 R10 - 0x782A0004, // 0066 JMPF R10 #006C - 0x8C28111A, // 0067 GETMET R10 R8 K26 - 0x5C301000, // 0068 MOVE R12 R8 - 0x5C340C00, // 0069 MOVE R13 R6 - 0x7C280600, // 006A CALL R10 3 - 0x5C241400, // 006B MOVE R9 R10 - 0x8C280302, // 006C GETMET R10 R1 K2 - 0x8C300510, // 006D GETMET R12 R2 K16 - 0x5838001B, // 006E LDCONST R14 K27 - 0x5C3C0800, // 006F MOVE R15 R4 - 0x5C400A00, // 0070 MOVE R16 R5 - 0x7C300800, // 0071 CALL R12 4 - 0x7C280400, // 0072 CALL R10 2 - 0x8C280302, // 0073 GETMET R10 R1 K2 - 0x8C300510, // 0074 GETMET R12 R2 K16 - 0x58380012, // 0075 LDCONST R14 K18 - 0x5C3C0800, // 0076 MOVE R15 R4 - 0x7C300600, // 0077 CALL R12 3 - 0x7C280400, // 0078 CALL R10 2 - 0x8C280113, // 0079 GETMET R10 R0 K19 - 0x8C300D0E, // 007A GETMET R12 R6 K14 - 0x5838000F, // 007B LDCONST R14 K15 - 0x583C0014, // 007C LDCONST R15 K20 - 0x7C300600, // 007D CALL R12 3 - 0x8834011C, // 007E GETMBR R13 R0 K28 - 0x7C280600, // 007F CALL R10 3 - 0x8C280302, // 0080 GETMET R10 R1 K2 - 0x8C300510, // 0081 GETMET R12 R2 K16 - 0x58380016, // 0082 LDCONST R14 K22 - 0x7C300400, // 0083 CALL R12 2 - 0x7C280400, // 0084 CALL R10 2 - 0x8C280302, // 0085 GETMET R10 R1 K2 - 0x8C300510, // 0086 GETMET R12 R2 K16 - 0x5838001D, // 0087 LDCONST R14 K29 - 0x5C3C0800, // 0088 MOVE R15 R4 - 0x8C40031E, // 0089 GETMET R16 R1 K30 - 0x5C481200, // 008A MOVE R18 R9 - 0x7C400400, // 008B CALL R16 2 - 0x7C300800, // 008C CALL R12 4 - 0x7C280400, // 008D CALL R10 2 - 0x00100918, // 008E ADD R4 R4 K24 - 0x7001FFB9, // 008F JMP #004A - 0x8C140302, // 0090 GETMET R5 R1 K2 - 0x8C1C0510, // 0091 GETMET R7 R2 K16 - 0x5824001F, // 0092 LDCONST R9 K31 - 0x5C280800, // 0093 MOVE R10 R4 - 0x7C1C0600, // 0094 CALL R7 3 - 0x7C140400, // 0095 CALL R5 2 - 0x8C140302, // 0096 GETMET R5 R1 K2 - 0x8C1C0510, // 0097 GETMET R7 R2 K16 - 0x58240012, // 0098 LDCONST R9 K18 - 0x5C280800, // 0099 MOVE R10 R4 - 0x7C1C0600, // 009A CALL R7 3 - 0x7C140400, // 009B CALL R5 2 - 0x8C140113, // 009C GETMET R5 R0 K19 - 0x581C0014, // 009D LDCONST R7 K20 - 0x8820011C, // 009E GETMBR R8 R0 K28 - 0x7C140600, // 009F CALL R5 3 - 0x8C140302, // 00A0 GETMET R5 R1 K2 - 0x8C1C0510, // 00A1 GETMET R7 R2 K16 - 0x58240016, // 00A2 LDCONST R9 K22 - 0x7C1C0400, // 00A3 CALL R7 2 - 0x7C140400, // 00A4 CALL R5 2 - 0x8C140302, // 00A5 GETMET R5 R1 K2 - 0x8C1C0510, // 00A6 GETMET R7 R2 K16 - 0x58240020, // 00A7 LDCONST R9 K32 - 0x5C280800, // 00A8 MOVE R10 R4 - 0x7C1C0600, // 00A9 CALL R7 3 - 0x7C140400, // 00AA CALL R5 2 - 0x8C140302, // 00AB GETMET R5 R1 K2 - 0x581C0021, // 00AC LDCONST R7 K33 - 0x7C140400, // 00AD CALL R5 2 - 0x8C140302, // 00AE GETMET R5 R1 K2 - 0x581C0022, // 00AF LDCONST R7 K34 - 0x7C140400, // 00B0 CALL R5 2 - 0x8C140302, // 00B1 GETMET R5 R1 K2 - 0x581C0023, // 00B2 LDCONST R7 K35 - 0x7C140400, // 00B3 CALL R5 2 - 0x80000000, // 00B4 RET 0 + 0x8C080301, // 0001 GETMET R2 R1 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x740A0001, // 0003 JMPT R2 #0006 + 0x4C080000, // 0004 LDNIL R2 + 0x80040400, // 0005 RET 1 R2 + 0x8C080302, // 0006 GETMET R2 R1 K2 + 0x58100003, // 0007 LDCONST R4 K3 + 0x7C080400, // 0008 CALL R2 2 + 0x8C080304, // 0009 GETMET R2 R1 K4 + 0x7C080200, // 000A CALL R2 1 + 0x8C080105, // 000B GETMET R2 R0 K5 + 0x7C080200, // 000C CALL R2 1 + 0x780A0003, // 000D JMPF R2 #0012 + 0x8C080106, // 000E GETMET R2 R0 K6 + 0x7C080200, // 000F CALL R2 1 + 0x8C080107, // 0010 GETMET R2 R0 K7 + 0x7C080200, // 0011 CALL R2 1 + 0x8C080308, // 0012 GETMET R2 R1 K8 + 0x88100309, // 0013 GETMBR R4 R1 K9 + 0x7C080400, // 0014 CALL R2 2 + 0x8C08030A, // 0015 GETMET R2 R1 K10 + 0x7C080200, // 0016 CALL R2 1 + 0x80000000, // 0017 RET 0 }) ) ); @@ -251,8 +150,111 @@ be_local_closure(Matter_UI_show_plugins_configuration, /* name */ ** Solidified function: page_part_mgr ********************************************************************/ be_local_closure(Matter_UI_page_part_mgr, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[14]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(check_privileged_access), + /* K2 */ be_nested_str_weak(content_start), + /* K3 */ be_nested_str_weak(Matter), + /* K4 */ be_nested_str_weak(content_send_style), + /* K5 */ be_nested_str_weak(show_enable), + /* K6 */ be_nested_str_weak(matter_enabled), + /* K7 */ be_nested_str_weak(show_plugins_configuration), + /* K8 */ be_nested_str_weak(content_send), + /* K9 */ be_nested_str_weak(_X3Cdiv_X20style_X3D_X27display_X3A_X20block_X3B_X27_X3E_X3C_X2Fdiv_X3E), + /* K10 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3Cform_X20id_X3D_X27butmat_X27_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20action_X3D_X27mattera_X27_X20method_X3D_X27get_X27_X3E_X3Cbutton_X20name_X3D_X27_X27_X3EAdvanced_X20Configuration_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E), + /* K11 */ be_nested_str_weak(content_button), + /* K12 */ be_nested_str_weak(BUTTON_CONFIGURATION), + /* K13 */ be_nested_str_weak(content_stop), + }), + be_str_weak(page_part_mgr), + &be_const_str_solidified, + ( &(const binstruction[30]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080301, // 0001 GETMET R2 R1 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x740A0001, // 0003 JMPT R2 #0006 + 0x4C080000, // 0004 LDNIL R2 + 0x80040400, // 0005 RET 1 R2 + 0x8C080302, // 0006 GETMET R2 R1 K2 + 0x58100003, // 0007 LDCONST R4 K3 + 0x7C080400, // 0008 CALL R2 2 + 0x8C080304, // 0009 GETMET R2 R1 K4 + 0x7C080200, // 000A CALL R2 1 + 0x8C080105, // 000B GETMET R2 R0 K5 + 0x7C080200, // 000C CALL R2 1 + 0x8C080106, // 000D GETMET R2 R0 K6 + 0x7C080200, // 000E CALL R2 1 + 0x780A0001, // 000F JMPF R2 #0012 + 0x8C080107, // 0010 GETMET R2 R0 K7 + 0x7C080200, // 0011 CALL R2 1 + 0x8C080308, // 0012 GETMET R2 R1 K8 + 0x58100009, // 0013 LDCONST R4 K9 + 0x7C080400, // 0014 CALL R2 2 + 0x8C080308, // 0015 GETMET R2 R1 K8 + 0x5810000A, // 0016 LDCONST R4 K10 + 0x7C080400, // 0017 CALL R2 2 + 0x8C08030B, // 0018 GETMET R2 R1 K11 + 0x8810030C, // 0019 GETMBR R4 R1 K12 + 0x7C080400, // 001A CALL R2 2 + 0x8C08030D, // 001B GETMET R2 R1 K13 + 0x7C080200, // 001C CALL R2 1 + 0x80000000, // 001D RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: plugin_name +********************************************************************/ +be_local_closure(Matter_UI_plugin_name, /* name */ be_nested_proto( 6, /* nstack */ + 3, /* argc */ + 3, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(), + /* K1 */ be_nested_str_weak(device), + /* K2 */ be_nested_str_weak(get_plugin_class_displayname), + }), + be_str_weak(plugin_name), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x1C0C0300, // 0000 EQ R3 R1 K0 + 0x780E0000, // 0001 JMPF R3 #0003 + 0x80060000, // 0002 RET 1 K0 + 0x880C0101, // 0003 GETMBR R3 R0 K1 + 0x8C0C0702, // 0004 GETMET R3 R3 K2 + 0x5C140200, // 0005 MOVE R5 R1 + 0x7C0C0400, // 0006 CALL R3 2 + 0x80040600, // 0007 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: matter_enabled +********************************************************************/ +be_local_closure(Matter_UI_matter_enabled, /* name */ + be_nested_proto( + 5, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -260,51 +262,744 @@ be_local_closure(Matter_UI_page_part_mgr, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(tasmota), + /* K1 */ be_nested_str_weak(get_option), + /* K2 */ be_nested_str_weak(matter), + /* K3 */ be_nested_str_weak(MATTER_OPTION), + }), + be_str_weak(matter_enabled), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x60040017, // 0000 GETGBL R1 G23 + 0xB80A0000, // 0001 GETNGBL R2 K0 + 0x8C080501, // 0002 GETMET R2 R2 K1 + 0xB8120400, // 0003 GETNGBL R4 K2 + 0x88100903, // 0004 GETMBR R4 R4 K3 + 0x7C080400, // 0005 CALL R2 2 + 0x7C040200, // 0006 CALL R1 1 + 0x80040200, // 0007 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: generate_config_from_status +********************************************************************/ +be_local_closure(Matter_UI_generate_config_from_status, /* name */ + be_nested_proto( + 13, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[17]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str_weak(contains), + /* K2 */ be_nested_str_weak(POWER), + /* K3 */ be_const_int(1), + /* K4 */ be_nested_str_weak(HSBColor), + /* K5 */ be_nested_str_weak(CT), + /* K6 */ be_nested_str_weak(Dimmer), + /* K7 */ be_nested_str_weak(push), + /* K8 */ be_nested_str_weak(type), + /* K9 */ be_nested_str_weak(light0), + /* K10 */ be_nested_str_weak(relay), + /* K11 */ be_nested_str_weak(stop_iteration), + /* K12 */ be_nested_str_weak(light1), + /* K13 */ be_nested_str_weak(light2), + /* K14 */ be_nested_str_weak(light3), + /* K15 */ be_nested_str_weak(device), + /* K16 */ be_nested_str_weak(autoconf_sensors_list), + }), + be_str_weak(generate_config_from_status), + &be_const_str_solidified, + ( &(const binstruction[96]) { /* code */ + 0x600C0012, // 0000 GETGBL R3 G18 + 0x7C0C0000, // 0001 CALL R3 0 + 0x58100000, // 0002 LDCONST R4 K0 + 0x8C140501, // 0003 GETMET R5 R2 K1 + 0x581C0002, // 0004 LDCONST R7 K2 + 0x7C140400, // 0005 CALL R5 2 + 0x78160001, // 0006 JMPF R5 #0009 + 0x58100003, // 0007 LDCONST R4 K3 + 0x7002000E, // 0008 JMP #0018 + 0x58140003, // 0009 LDCONST R5 K3 + 0x50180200, // 000A LDBOOL R6 1 0 + 0x781A000B, // 000B JMPF R6 #0018 + 0x8C180501, // 000C GETMET R6 R2 K1 + 0x60200008, // 000D GETGBL R8 G8 + 0x5C240A00, // 000E MOVE R9 R5 + 0x7C200200, // 000F CALL R8 1 + 0x00220408, // 0010 ADD R8 K2 R8 + 0x7C180400, // 0011 CALL R6 2 + 0x781A0002, // 0012 JMPF R6 #0016 + 0x5C100A00, // 0013 MOVE R4 R5 + 0x00140B03, // 0014 ADD R5 R5 K3 + 0x70020000, // 0015 JMP #0017 + 0x70020000, // 0016 JMP #0018 + 0x7001FFF1, // 0017 JMP #000A + 0x4C140000, // 0018 LDNIL R5 + 0x4C180000, // 0019 LDNIL R6 + 0x4C1C0000, // 001A LDNIL R7 + 0x8C200501, // 001B GETMET R8 R2 K1 + 0x58280004, // 001C LDCONST R10 K4 + 0x7C200400, // 001D CALL R8 2 + 0x78220002, // 001E JMPF R8 #0022 + 0x5C1C0800, // 001F MOVE R7 R4 + 0x04100903, // 0020 SUB R4 R4 K3 + 0x7002000C, // 0021 JMP #002F + 0x8C200501, // 0022 GETMET R8 R2 K1 + 0x58280005, // 0023 LDCONST R10 K5 + 0x7C200400, // 0024 CALL R8 2 + 0x78220002, // 0025 JMPF R8 #0029 + 0x5C180800, // 0026 MOVE R6 R4 + 0x04100903, // 0027 SUB R4 R4 K3 + 0x70020005, // 0028 JMP #002F + 0x8C200501, // 0029 GETMET R8 R2 K1 + 0x58280006, // 002A LDCONST R10 K6 + 0x7C200400, // 002B CALL R8 2 + 0x78220001, // 002C JMPF R8 #002F + 0x5C140800, // 002D MOVE R5 R4 + 0x04100903, // 002E SUB R4 R4 K3 + 0x60200010, // 002F GETGBL R8 G16 + 0x40260604, // 0030 CONNECT R9 K3 R4 + 0x7C200200, // 0031 CALL R8 1 + 0xA8020008, // 0032 EXBLK 0 #003C + 0x5C241000, // 0033 MOVE R9 R8 + 0x7C240000, // 0034 CALL R9 0 + 0x8C280707, // 0035 GETMET R10 R3 K7 + 0x60300013, // 0036 GETGBL R12 G19 + 0x7C300000, // 0037 CALL R12 0 + 0x98321109, // 0038 SETIDX R12 K8 K9 + 0x98321409, // 0039 SETIDX R12 K10 R9 + 0x7C280400, // 003A CALL R10 2 + 0x7001FFF6, // 003B JMP #0033 + 0x5820000B, // 003C LDCONST R8 K11 + 0xAC200200, // 003D CATCH R8 1 0 + 0xB0080000, // 003E RAISE 2 R0 R0 + 0x4C200000, // 003F LDNIL R8 + 0x20200A08, // 0040 NE R8 R5 R8 + 0x78220005, // 0041 JMPF R8 #0048 + 0x8C200707, // 0042 GETMET R8 R3 K7 + 0x60280013, // 0043 GETGBL R10 G19 + 0x7C280000, // 0044 CALL R10 0 + 0x982A110C, // 0045 SETIDX R10 K8 K12 + 0x982A1405, // 0046 SETIDX R10 K10 R5 + 0x7C200400, // 0047 CALL R8 2 + 0x4C200000, // 0048 LDNIL R8 + 0x20200C08, // 0049 NE R8 R6 R8 + 0x78220005, // 004A JMPF R8 #0051 + 0x8C200707, // 004B GETMET R8 R3 K7 + 0x60280013, // 004C GETGBL R10 G19 + 0x7C280000, // 004D CALL R10 0 + 0x982A110D, // 004E SETIDX R10 K8 K13 + 0x982A1406, // 004F SETIDX R10 K10 R6 + 0x7C200400, // 0050 CALL R8 2 + 0x4C200000, // 0051 LDNIL R8 + 0x20200E08, // 0052 NE R8 R7 R8 + 0x78220005, // 0053 JMPF R8 #005A + 0x8C200707, // 0054 GETMET R8 R3 K7 + 0x60280013, // 0055 GETGBL R10 G19 + 0x7C280000, // 0056 CALL R10 0 + 0x982A110E, // 0057 SETIDX R10 K8 K14 + 0x982A1407, // 0058 SETIDX R10 K10 R7 + 0x7C200400, // 0059 CALL R8 2 + 0x8820010F, // 005A GETMBR R8 R0 K15 + 0x8C201110, // 005B GETMET R8 R8 K16 + 0x5C280200, // 005C MOVE R10 R1 + 0x7C200400, // 005D CALL R8 2 + 0x000C0608, // 005E ADD R3 R3 R8 + 0x80040600, // 005F RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_sensor +********************************************************************/ +be_local_closure(Matter_UI_web_sensor, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[17]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(matter_enabled), + /* K2 */ be_nested_str_weak(device), + /* K3 */ be_nested_str_weak(sessions), + /* K4 */ be_nested_str_weak(count_active_fabrics), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(content_send), + /* K7 */ be_nested_str_weak(_X3Cdiv_X20style_X3D_X27text_X2Dalign_X3Aright_X3Bfont_X2Dsize_X3A11px_X3Bcolor_X3A_X23aaa_X3Bpadding_X3A0px_X3B_X27_X3E_X25s_X3C_X2Fdiv_X3E), + /* K8 */ be_nested_str_weak(Matter_X3A_X20No_X20active_X20association), + /* K9 */ be_const_int(1), + /* K10 */ be_nested_str_weak(Matter_X3A_X20), + /* K11 */ be_nested_str_weak(_X20active_X20association), + /* K12 */ be_nested_str_weak(s), + /* K13 */ be_nested_str_weak(), + /* K14 */ be_nested_str_weak(show_bridge_status), + /* K15 */ be_nested_str_weak(is_root_commissioning_open), + /* K16 */ be_nested_str_weak(show_commissioning_info), + }), + be_str_weak(web_sensor), + &be_const_str_solidified, + ( &(const binstruction[42]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x780A0024, // 0003 JMPF R2 #0029 + 0x88080102, // 0004 GETMBR R2 R0 K2 + 0x88080503, // 0005 GETMBR R2 R2 K3 + 0x8C080504, // 0006 GETMET R2 R2 K4 + 0x7C080200, // 0007 CALL R2 1 + 0x1C0C0505, // 0008 EQ R3 R2 K5 + 0x780E0006, // 0009 JMPF R3 #0011 + 0x8C0C0306, // 000A GETMET R3 R1 K6 + 0x60140018, // 000B GETGBL R5 G24 + 0x58180007, // 000C LDCONST R6 K7 + 0x581C0008, // 000D LDCONST R7 K8 + 0x7C140400, // 000E CALL R5 2 + 0x7C0C0400, // 000F CALL R3 2 + 0x7002000F, // 0010 JMP #0021 + 0x240C0509, // 0011 GT R3 R2 K9 + 0x8C100306, // 0012 GETMET R4 R1 K6 + 0x60180018, // 0013 GETGBL R6 G24 + 0x581C0007, // 0014 LDCONST R7 K7 + 0x60200008, // 0015 GETGBL R8 G8 + 0x5C240400, // 0016 MOVE R9 R2 + 0x7C200200, // 0017 CALL R8 1 + 0x00221408, // 0018 ADD R8 K10 R8 + 0x0020110B, // 0019 ADD R8 R8 K11 + 0x780E0001, // 001A JMPF R3 #001D + 0x5824000C, // 001B LDCONST R9 K12 + 0x70020000, // 001C JMP #001E + 0x5824000D, // 001D LDCONST R9 K13 + 0x00201009, // 001E ADD R8 R8 R9 + 0x7C180400, // 001F CALL R6 2 + 0x7C100400, // 0020 CALL R4 2 + 0x8C0C010E, // 0021 GETMET R3 R0 K14 + 0x7C0C0200, // 0022 CALL R3 1 + 0x880C0102, // 0023 GETMBR R3 R0 K2 + 0x8C0C070F, // 0024 GETMET R3 R3 K15 + 0x7C0C0200, // 0025 CALL R3 1 + 0x780E0001, // 0026 JMPF R3 #0029 + 0x8C0C0110, // 0027 GETMET R3 R0 K16 + 0x7C0C0200, // 0028 CALL R3 1 + 0x80000000, // 0029 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: page_part_mgr_add +********************************************************************/ +be_local_closure(Matter_UI_page_part_mgr_add, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(check_privileged_access), + /* K2 */ be_nested_str_weak(content_start), + /* K3 */ be_nested_str_weak(Matter_X20Create_X20new_X20endpoint), + /* K4 */ be_nested_str_weak(content_send_style), + /* K5 */ be_nested_str_weak(arg), + /* K6 */ be_nested_str_weak(url), + /* K7 */ be_nested_str_weak(matter_enabled), + /* K8 */ be_nested_str_weak(show_remote_autoconf), + /* K9 */ be_nested_str_weak(content_button), + /* K10 */ be_nested_str_weak(BUTTON_CONFIGURATION), + /* K11 */ be_nested_str_weak(content_stop), + }), + be_str_weak(page_part_mgr_add), + &be_const_str_solidified, + ( &(const binstruction[26]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080301, // 0001 GETMET R2 R1 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x740A0001, // 0003 JMPT R2 #0006 + 0x4C080000, // 0004 LDNIL R2 + 0x80040400, // 0005 RET 1 R2 + 0x8C080302, // 0006 GETMET R2 R1 K2 + 0x58100003, // 0007 LDCONST R4 K3 + 0x7C080400, // 0008 CALL R2 2 + 0x8C080304, // 0009 GETMET R2 R1 K4 + 0x7C080200, // 000A CALL R2 1 + 0x8C080305, // 000B GETMET R2 R1 K5 + 0x58100006, // 000C LDCONST R4 K6 + 0x7C080400, // 000D CALL R2 2 + 0x8C0C0107, // 000E GETMET R3 R0 K7 + 0x7C0C0200, // 000F CALL R3 1 + 0x780E0002, // 0010 JMPF R3 #0014 + 0x8C0C0108, // 0011 GETMET R3 R0 K8 + 0x5C140400, // 0012 MOVE R5 R2 + 0x7C0C0400, // 0013 CALL R3 2 + 0x8C0C0309, // 0014 GETMET R3 R1 K9 + 0x8814030A, // 0015 GETMBR R5 R1 K10 + 0x7C0C0400, // 0016 CALL R3 2 + 0x8C0C030B, // 0017 GETMET R3 R1 K11 + 0x7C0C0200, // 0018 CALL R3 1 + 0x80000000, // 0019 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: show_plugins_configuration +********************************************************************/ +be_local_closure(Matter_UI_show_plugins_configuration, /* name */ + be_nested_proto( + 28, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[63]) { /* constants */ /* K0 */ be_nested_str_weak(webserver), /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(check_privileged_access), - /* K3 */ be_nested_str_weak(content_start), - /* K4 */ be_nested_str_weak(Matter), - /* K5 */ be_nested_str_weak(content_send_style), - /* K6 */ be_nested_str_weak(show_enable), - /* K7 */ be_nested_str_weak(show_passcode_form), - /* K8 */ be_nested_str_weak(show_plugins_configuration), - /* K9 */ be_nested_str_weak(show_fabric_info), - /* K10 */ be_nested_str_weak(content_button), - /* K11 */ be_nested_str_weak(BUTTON_CONFIGURATION), - /* K12 */ be_nested_str_weak(content_stop), + /* K2 */ be_nested_str_weak(introspect), + /* K3 */ be_nested_str_weak(content_send), + /* K4 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3BCurrent_X20Configuration_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K5 */ be_nested_str_weak(_X3Cform_X20action_X3D_X27_X2Fmatterc_X27_X20method_X3D_X27post_X27_X3E_X3Cp_X3E_X3Cb_X3ELocal_X20sensors_X20and_X20devices_X3C_X2Fb_X3E_X3C_X2Fp_X3E_X3Ctable_X20style_X3D_X27width_X3A100_X25_X27_X3E), + /* K6 */ be_nested_str_weak(_X3Ctr_X3E_X3Ctd_X20width_X3D_X2725_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X23_X3C_X2Ftd_X3E_X3Ctd_X20width_X3D_X2778_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3EName_X3C_X2Ftd_X3E_X3Ctd_X20width_X3D_X27115_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3EType_X3C_X2Ftd_X3E_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3EParameter_X3C_X2Ftd_X3E_X3Ctd_X20width_X3D_X2715_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3C_X2Ftd_X3E_X3C_X2Ftr_X3E), + /* K7 */ be_nested_str_weak(device), + /* K8 */ be_nested_str_weak(plugins_config), + /* K9 */ be_nested_str_weak(remove), + /* K10 */ be_nested_str_weak(0), + /* K11 */ be_nested_str_weak(k2l_num), + /* K12 */ be_const_int(0), + /* K13 */ be_nested_str_weak(find), + /* K14 */ be_nested_str_weak(type), + /* K15 */ be_const_int(1), + /* K16 */ be_nested_str_weak(http_), + /* K17 */ be_nested_str_weak(plugins_classes), + /* K18 */ be_nested_str_weak(), + /* K19 */ be_nested_str_weak(ui_conf_to_string), + /* K20 */ be_nested_str_weak(_X3Ctr_X3E_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cb_X3E_X25i_X3C_X2Fb_X3E_X3C_X2Ftd_X3E), + /* K21 */ be_nested_str_weak(_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cinput_X20type_X3D_X27text_X27_X20name_X3D_X27nam_X25i_X27_X20size_X3D_X271_X27_X20value_X3D_X27_X25s_X27_X3E_X3C_X2Ftd_X3E), + /* K22 */ be_nested_str_weak(html_escape), + /* K23 */ be_nested_str_weak(name), + /* K24 */ be_nested_str_weak(_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cb_X3E_X25s_X3C_X2Fb_X3E_X3C_X2Ftd_X3E), + /* K25 */ be_nested_str_weak(plugin_name), + /* K26 */ be_nested_str_weak(_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cinput_X20type_X3D_X27text_X27_X20name_X3D_X27arg_X25i_X27_X20size_X3D_X271_X27_X20value_X3D_X27_X25s_X27_X20placeholder_X3D_X27_X25s_X27_X3E_X3C_X2Ftd_X3E), + /* K27 */ be_nested_str_weak(ARG_HINT), + /* K28 */ be_nested_str_weak(_X3Ctd_X20style_X3D_X27text_X2Dalign_X3Acenter_X3B_X27_X3E_X3Cbutton_X20name_X3D_X27del_X25i_X27_X20style_X3D_X27background_X3Anone_X3Bborder_X3Anone_X3Bline_X2Dheight_X3A1_X3B_X27_X20onclick_X3D_X22return_X20confirm_X28_X27Confirm_X20removing_X20endpoint_X27_X29_X22_X3E_X26_X23128293_X3B_X3C_X2Fbutton_X3E_X3C_X2Ftd_X3E_X3C_X2Ftr_X3E), + /* K29 */ be_nested_str_weak(_X3C_X2Ftable_X3E), + /* K30 */ be_nested_str_weak(_X3Cp_X3E_X26lt_X3Bnone_X26gt_X3B_X3C_X2Fp_X3E), + /* K31 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E), + /* K32 */ be_nested_str_weak(url), + /* K33 */ be_nested_str_weak(push), + /* K34 */ be_nested_str_weak(stop_iteration), + /* K35 */ be_nested_str_weak(sort_distinct), + /* K36 */ be_nested_str_weak(get_plugin_remote_info), + /* K37 */ be_nested_str_weak(_X26_X23x1F517_X3B_X20_X3Ca_X20target_X3D_X27_blank_X27_X20title_X3D_X27http_X3A_X2F_X2F_X25s_X2F_X27_X20href_X3D_X22http_X3A_X2F_X2F_X25s_X2F_X3F_X22_X3E_X25s_X3C_X2Fa_X3E), + /* K38 */ be_nested_str_weak(_X3Ctable_X20style_X3D_X27width_X3A100_X25_X27_X3E), + /* K39 */ be_nested_str_weak(_X3Ctr_X3E_X3Ctd_X20width_X3D_X2725_X27_X3E_X3C_X2Ftd_X3E_X3Ctd_X20width_X3D_X2778_X27_X3E_X3C_X2Ftd_X3E_X3Ctd_X20width_X3D_X27115_X27_X3E_X3C_X2Ftd_X3E_X3Ctd_X3E_X3C_X2Ftd_X3E_X3Ctd_X20width_X3D_X2715_X27_X3E_X3C_X2Ftd_X3E_X3C_X2Ftr_X3E), + /* K40 */ be_nested_str_weak(_X3Ctr_X3E_X3Ctd_X20width_X3D_X2722_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cb_X3E_X25i_X3C_X2Fb_X3E_X3C_X2Ftd_X3E), + /* K41 */ be_nested_str_weak(_X3Ctd_X20width_X3D_X2778_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cinput_X20type_X3D_X27text_X27_X20name_X3D_X27nam_X25i_X27_X20size_X3D_X271_X27_X20value_X3D_X27_X25s_X27_X20placeholder_X3D_X27_X28optional_X29_X27_X3E_X3C_X2Ftd_X3E), + /* K42 */ be_nested_str_weak(_X3Ctd_X20width_X3D_X27115_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cb_X3E_X25s_X3C_X2Fb_X3E_X3C_X2Fselect_X3E_X3C_X2Ftd_X3E), + /* K43 */ be_nested_str_weak(_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cinput_X20type_X3D_X27text_X27_X20name_X3D_X27arg_X25i_X27_X20size_X3D_X278_X27_X20value_X3D_X27_X25s_X27_X3E_X3C_X2Ftd_X3E), + /* K44 */ be_nested_str_weak(_X3Ctd_X20width_X3D_X2715_X27_X20style_X3D_X27text_X2Dalign_X3Acenter_X3B_X27_X3E_X3Cbutton_X20name_X3D_X27del_X25i_X27_X20style_X3D_X27background_X3Anone_X3Bborder_X3Anone_X3Bline_X2Dheight_X3A1_X3B_X27_X20onclick_X3D_X22return_X20confirm_X28_X27Confirm_X20removing_X20endpoint_X27_X29_X22_X3E_X26_X23128293_X3B_X3C_X2Fbutton_X3E_X3C_X2Ftd_X3E_X3C_X2Ftr_X3E), + /* K45 */ be_nested_str_weak(_X3C_X2Ftable_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K46 */ be_nested_str_weak(_X3Cbutton_X20name_X3D_X27config_X27_X20class_X3D_X27button_X20bgrn_X27_X3EChange_X20configuration_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E), + /* K47 */ be_nested_str_weak(show_plugins_hints_js), + /* K48 */ be_nested_str_weak(_CLASSES_TYPES), + /* K49 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3BAdd_X20to_X20Configuration_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K50 */ be_nested_str_weak(_X3Cp_X3E_X3Cb_X3EAdd_X20local_X20sensor_X20or_X20device_X3C_X2Fb_X3E_X3C_X2Fp_X3E_X3Cform_X20action_X3D_X27_X2Fmatterc_X27_X20method_X3D_X27post_X27_X3E_X3Ctable_X20style_X3D_X27width_X3A100_X25_X27_X3E), + /* K51 */ be_nested_str_weak(_X3Ctr_X3E_X3Ctd_X20width_X3D_X27100_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3EName_X3C_X2Ftd_X3E_X3Ctd_X20width_X3D_X27115_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3EType_X3C_X2Ftd_X3E_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3EParameter_X3C_X2Ftd_X3E_X3C_X2Ftr_X3E), + /* K52 */ be_nested_str_weak(_X3Ctr_X3E_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cinput_X20type_X3D_X27text_X27_X20name_X3D_X27nam_X27_X20size_X3D_X271_X27_X20value_X3D_X27_X27_X20placeholder_X3D_X27_X28optional_X29_X27_X3E_X3C_X2Ftd_X3E_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cselect_X20id_X3D_X27pi_X27_X20name_X3D_X27pi_X27_X20onchange_X3D_X27otm_X28_X22arg_X22_X2Cthis_X2Evalue_X29_X27_X3E), + /* K53 */ be_nested_str_weak(plugin_option), + /* K54 */ be_nested_str_weak(_X3C_X2Fselect_X3E_X3C_X2Ftd_X3E), + /* K55 */ be_nested_str_weak(_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cinput_X20type_X3D_X27text_X27_X20id_X3D_X27arg_X27_X20name_X3D_X27arg_X27_X20size_X3D_X271_X27_X20value_X3D_X27_X27_X3E_X3C_X2Ftd_X3E_X3C_X2Ftr_X3E_X3C_X2Ftable_X3E), + /* K56 */ be_nested_str_weak(_X3Cdiv_X20style_X3D_X27display_X3A_X20block_X3B_X27_X3E_X3C_X2Fdiv_X3E), + /* K57 */ be_nested_str_weak(_X3Cbutton_X20name_X3D_X27addep_X27_X20class_X3D_X27button_X20bgrn_X27_X3ECreate_X20new_X20endpoint_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E), + /* K58 */ be_nested_str_weak(_X3Chr_X3E_X3Cp_X3E_X3Cb_X3EAdd_X20Remote_X20Tasmota_X20or_X20OpenBK_X3C_X2Fb_X3E_X3C_X2Fp_X3E_X3Cform_X20action_X3D_X27_X2Fmatteradd_X27_X20method_X3D_X27get_X27_X3E_X3Ctable_X20style_X3D_X27width_X3A100_X25_X27_X3E), + /* K59 */ be_nested_str_weak(_X3Ctr_X3E_X3Ctd_X20width_X3D_X2730_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cb_X3Ehttp_X3A_X2F_X2F_X3C_X2Fb_X3E_X3C_X2Ftd_X3E_X3Ctd_X3E_X3Cinput_X20type_X3D_X27text_X27_X20name_X3D_X27url_X27_X20size_X3D_X278_X27_X20value_X3D_X27_X27_X20required_X20placeholder_X3D_X27IP_X20or_X20domain_X27_X3E_X3C_X2Ftd_X3E_X3Ctd_X20width_X3D_X2710_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cb_X3E_X2F_X3C_X2Fb_X3E_X3C_X2Ftd_X3E_X3C_X2Ftr_X3E_X3C_X2Ftr_X3E_X3C_X2Ftable_X3E), + /* K60 */ be_nested_str_weak(_X3Cbutton_X20class_X3D_X27button_X20bgrn_X27_X3EAuto_X2Dconfigure_X20remote_X20Tasmota_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3Chr_X3E), + /* K61 */ be_nested_str_weak(_X3Cform_X20action_X3D_X27_X2Fmatterc_X27_X20method_X3D_X27post_X27onsubmit_X3D_X27return_X20confirm_X28_X22This_X20will_X20RESET_X20the_X20configuration_X20to_X20the_X20default_X2E_X20You_X20will_X20need_X20to_X20associate_X20again_X2E_X22_X29_X3B_X27_X3E_X3Cbutton_X20name_X3D_X27auto_X27_X20class_X3D_X27button_X20bred_X27_X3EReset_X20all_X20and_X20Auto_X2Ddiscover_X3C_X2Fbutton_X3E_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Fform_X3E), + /* K62 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E), }), - be_str_weak(page_part_mgr), + be_str_weak(show_plugins_configuration), &be_const_str_solidified, - ( &(const binstruction[27]) { /* code */ + ( &(const binstruction[352]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 0xA40A0200, // 0001 IMPORT R2 K1 - 0x8C0C0302, // 0002 GETMET R3 R1 K2 - 0x7C0C0200, // 0003 CALL R3 1 - 0x740E0001, // 0004 JMPT R3 #0007 - 0x4C0C0000, // 0005 LDNIL R3 - 0x80040600, // 0006 RET 1 R3 - 0x8C0C0303, // 0007 GETMET R3 R1 K3 - 0x58140004, // 0008 LDCONST R5 K4 - 0x7C0C0400, // 0009 CALL R3 2 - 0x8C0C0305, // 000A GETMET R3 R1 K5 - 0x7C0C0200, // 000B CALL R3 1 - 0x8C0C0106, // 000C GETMET R3 R0 K6 - 0x7C0C0200, // 000D CALL R3 1 - 0x780E0005, // 000E JMPF R3 #0015 - 0x8C0C0107, // 000F GETMET R3 R0 K7 - 0x7C0C0200, // 0010 CALL R3 1 - 0x8C0C0108, // 0011 GETMET R3 R0 K8 - 0x7C0C0200, // 0012 CALL R3 1 - 0x8C0C0109, // 0013 GETMET R3 R0 K9 - 0x7C0C0200, // 0014 CALL R3 1 - 0x8C0C030A, // 0015 GETMET R3 R1 K10 - 0x8814030B, // 0016 GETMBR R5 R1 K11 - 0x7C0C0400, // 0017 CALL R3 2 - 0x8C0C030C, // 0018 GETMET R3 R1 K12 - 0x7C0C0200, // 0019 CALL R3 1 - 0x80000000, // 001A RET 0 + 0xA40E0400, // 0002 IMPORT R3 K2 + 0x8C100303, // 0003 GETMET R4 R1 K3 + 0x58180004, // 0004 LDCONST R6 K4 + 0x7C100400, // 0005 CALL R4 2 + 0x8C100303, // 0006 GETMET R4 R1 K3 + 0x58180005, // 0007 LDCONST R6 K5 + 0x7C100400, // 0008 CALL R4 2 + 0x8C100303, // 0009 GETMET R4 R1 K3 + 0x58180006, // 000A LDCONST R6 K6 + 0x7C100400, // 000B CALL R4 2 + 0x88100107, // 000C GETMBR R4 R0 K7 + 0x88100908, // 000D GETMBR R4 R4 K8 + 0x8C100909, // 000E GETMET R4 R4 K9 + 0x5818000A, // 000F LDCONST R6 K10 + 0x7C100400, // 0010 CALL R4 2 + 0x88100107, // 0011 GETMBR R4 R0 K7 + 0x8C10090B, // 0012 GETMET R4 R4 K11 + 0x88180107, // 0013 GETMBR R6 R0 K7 + 0x88180D08, // 0014 GETMBR R6 R6 K8 + 0x7C100400, // 0015 CALL R4 2 + 0x5814000C, // 0016 LDCONST R5 K12 + 0x50180000, // 0017 LDBOOL R6 0 0 + 0x601C000C, // 0018 GETGBL R7 G12 + 0x5C200800, // 0019 MOVE R8 R4 + 0x7C1C0200, // 001A CALL R7 1 + 0x141C0A07, // 001B LT R7 R5 R7 + 0x781E0059, // 001C JMPF R7 #0077 + 0x941C0805, // 001D GETIDX R7 R4 R5 + 0x88200107, // 001E GETMBR R8 R0 K7 + 0x88201108, // 001F GETMBR R8 R8 K8 + 0x8C20110D, // 0020 GETMET R8 R8 K13 + 0x60280008, // 0021 GETGBL R10 G8 + 0x5C2C0E00, // 0022 MOVE R11 R7 + 0x7C280200, // 0023 CALL R10 1 + 0x7C200400, // 0024 CALL R8 2 + 0x8C24110D, // 0025 GETMET R9 R8 K13 + 0x582C000E, // 0026 LDCONST R11 K14 + 0x7C240400, // 0027 CALL R9 2 + 0x5C281200, // 0028 MOVE R10 R9 + 0x742A0001, // 0029 JMPT R10 #002C + 0x00140B0F, // 002A ADD R5 R5 K15 + 0x7001FFEB, // 002B JMP #0018 + 0x8C28050D, // 002C GETMET R10 R2 K13 + 0x5C301200, // 002D MOVE R12 R9 + 0x58340010, // 002E LDCONST R13 K16 + 0x7C280600, // 002F CALL R10 3 + 0x1C28150C, // 0030 EQ R10 R10 K12 + 0x782A0001, // 0031 JMPF R10 #0034 + 0x00140B0F, // 0032 ADD R5 R5 K15 + 0x7001FFE3, // 0033 JMP #0018 + 0x88280107, // 0034 GETMBR R10 R0 K7 + 0x88281511, // 0035 GETMBR R10 R10 K17 + 0x8C28150D, // 0036 GETMET R10 R10 K13 + 0x5C301200, // 0037 MOVE R12 R9 + 0x7C280400, // 0038 CALL R10 2 + 0x582C0012, // 0039 LDCONST R11 K18 + 0x4C300000, // 003A LDNIL R12 + 0x2030140C, // 003B NE R12 R10 R12 + 0x78320004, // 003C JMPF R12 #0042 + 0x8C301513, // 003D GETMET R12 R10 K19 + 0x5C381400, // 003E MOVE R14 R10 + 0x5C3C1000, // 003F MOVE R15 R8 + 0x7C300600, // 0040 CALL R12 3 + 0x5C2C1800, // 0041 MOVE R11 R12 + 0x50180200, // 0042 LDBOOL R6 1 0 + 0x8C300303, // 0043 GETMET R12 R1 K3 + 0x60380018, // 0044 GETGBL R14 G24 + 0x583C0014, // 0045 LDCONST R15 K20 + 0x5C400E00, // 0046 MOVE R16 R7 + 0x7C380400, // 0047 CALL R14 2 + 0x7C300400, // 0048 CALL R12 2 + 0x8C300303, // 0049 GETMET R12 R1 K3 + 0x60380018, // 004A GETGBL R14 G24 + 0x583C0015, // 004B LDCONST R15 K21 + 0x5C400E00, // 004C MOVE R16 R7 + 0x8C440316, // 004D GETMET R17 R1 K22 + 0x8C4C110D, // 004E GETMET R19 R8 K13 + 0x58540017, // 004F LDCONST R21 K23 + 0x58580012, // 0050 LDCONST R22 K18 + 0x7C4C0600, // 0051 CALL R19 3 + 0x7C440400, // 0052 CALL R17 2 + 0x7C380600, // 0053 CALL R14 3 + 0x7C300400, // 0054 CALL R12 2 + 0x8C300303, // 0055 GETMET R12 R1 K3 + 0x60380018, // 0056 GETGBL R14 G24 + 0x583C0018, // 0057 LDCONST R15 K24 + 0x8C400119, // 0058 GETMET R16 R0 K25 + 0x8C48110D, // 0059 GETMET R18 R8 K13 + 0x5850000E, // 005A LDCONST R20 K14 + 0x58540012, // 005B LDCONST R21 K18 + 0x7C480600, // 005C CALL R18 3 + 0x7C400400, // 005D CALL R16 2 + 0x7C380400, // 005E CALL R14 2 + 0x7C300400, // 005F CALL R12 2 + 0x8C300303, // 0060 GETMET R12 R1 K3 + 0x60380018, // 0061 GETGBL R14 G24 + 0x583C001A, // 0062 LDCONST R15 K26 + 0x5C400E00, // 0063 MOVE R16 R7 + 0x8C440316, // 0064 GETMET R17 R1 K22 + 0x5C4C1600, // 0065 MOVE R19 R11 + 0x7C440400, // 0066 CALL R17 2 + 0x782A0003, // 0067 JMPF R10 #006C + 0x8C480316, // 0068 GETMET R18 R1 K22 + 0x8850151B, // 0069 GETMBR R20 R10 K27 + 0x7C480400, // 006A CALL R18 2 + 0x70020000, // 006B JMP #006D + 0x58480012, // 006C LDCONST R18 K18 + 0x7C380800, // 006D CALL R14 4 + 0x7C300400, // 006E CALL R12 2 + 0x8C300303, // 006F GETMET R12 R1 K3 + 0x60380018, // 0070 GETGBL R14 G24 + 0x583C001C, // 0071 LDCONST R15 K28 + 0x5C400E00, // 0072 MOVE R16 R7 + 0x7C380400, // 0073 CALL R14 2 + 0x7C300400, // 0074 CALL R12 2 + 0x00140B0F, // 0075 ADD R5 R5 K15 + 0x7001FFA0, // 0076 JMP #0018 + 0x8C1C0303, // 0077 GETMET R7 R1 K3 + 0x5824001D, // 0078 LDCONST R9 K29 + 0x7C1C0400, // 0079 CALL R7 2 + 0x5C1C0C00, // 007A MOVE R7 R6 + 0x741E0002, // 007B JMPT R7 #007F + 0x8C1C0303, // 007C GETMET R7 R1 K3 + 0x5824001E, // 007D LDCONST R9 K30 + 0x7C1C0400, // 007E CALL R7 2 + 0x8C1C0303, // 007F GETMET R7 R1 K3 + 0x5824001F, // 0080 LDCONST R9 K31 + 0x7C1C0400, // 0081 CALL R7 2 + 0x601C0012, // 0082 GETGBL R7 G18 + 0x7C1C0000, // 0083 CALL R7 0 + 0x60200010, // 0084 GETGBL R8 G16 + 0x88240107, // 0085 GETMBR R9 R0 K7 + 0x88241308, // 0086 GETMBR R9 R9 K8 + 0x7C200200, // 0087 CALL R8 1 + 0xA802000B, // 0088 EXBLK 0 #0095 + 0x5C241000, // 0089 MOVE R9 R8 + 0x7C240000, // 008A CALL R9 0 + 0x8C28130D, // 008B GETMET R10 R9 K13 + 0x58300020, // 008C LDCONST R12 K32 + 0x7C280400, // 008D CALL R10 2 + 0x4C2C0000, // 008E LDNIL R11 + 0x202C140B, // 008F NE R11 R10 R11 + 0x782E0002, // 0090 JMPF R11 #0094 + 0x8C2C0F21, // 0091 GETMET R11 R7 K33 + 0x5C341400, // 0092 MOVE R13 R10 + 0x7C2C0400, // 0093 CALL R11 2 + 0x7001FFF3, // 0094 JMP #0089 + 0x58200022, // 0095 LDCONST R8 K34 + 0xAC200200, // 0096 CATCH R8 1 0 + 0xB0080000, // 0097 RAISE 2 R0 R0 + 0x88200107, // 0098 GETMBR R8 R0 K7 + 0x8C201123, // 0099 GETMET R8 R8 K35 + 0x5C280E00, // 009A MOVE R10 R7 + 0x7C200400, // 009B CALL R8 2 + 0x60200010, // 009C GETGBL R8 G16 + 0x5C240E00, // 009D MOVE R9 R7 + 0x7C200200, // 009E CALL R8 1 + 0xA8020082, // 009F EXBLK 0 #0123 + 0x5C241000, // 00A0 MOVE R9 R8 + 0x7C240000, // 00A1 CALL R9 0 + 0x8C280316, // 00A2 GETMET R10 R1 K22 + 0x5C301200, // 00A3 MOVE R12 R9 + 0x7C280400, // 00A4 CALL R10 2 + 0x8C2C0316, // 00A5 GETMET R11 R1 K22 + 0x88340107, // 00A6 GETMBR R13 R0 K7 + 0x8C341B24, // 00A7 GETMET R13 R13 K36 + 0x5C3C1200, // 00A8 MOVE R15 R9 + 0x7C340400, // 00A9 CALL R13 2 + 0x8C341B0D, // 00AA GETMET R13 R13 K13 + 0x583C0017, // 00AB LDCONST R15 K23 + 0x5C401200, // 00AC MOVE R16 R9 + 0x7C340600, // 00AD CALL R13 3 + 0x7C2C0400, // 00AE CALL R11 2 + 0x8C300303, // 00AF GETMET R12 R1 K3 + 0x60380018, // 00B0 GETGBL R14 G24 + 0x583C0025, // 00B1 LDCONST R15 K37 + 0x5C401400, // 00B2 MOVE R16 R10 + 0x5C441400, // 00B3 MOVE R17 R10 + 0x5C481600, // 00B4 MOVE R18 R11 + 0x7C380800, // 00B5 CALL R14 4 + 0x7C300400, // 00B6 CALL R12 2 + 0x8C300303, // 00B7 GETMET R12 R1 K3 + 0x58380026, // 00B8 LDCONST R14 K38 + 0x7C300400, // 00B9 CALL R12 2 + 0x8C300303, // 00BA GETMET R12 R1 K3 + 0x58380027, // 00BB LDCONST R14 K39 + 0x7C300400, // 00BC CALL R12 2 + 0x50180000, // 00BD LDBOOL R6 0 0 + 0x5814000C, // 00BE LDCONST R5 K12 + 0x6030000C, // 00BF GETGBL R12 G12 + 0x5C340800, // 00C0 MOVE R13 R4 + 0x7C300200, // 00C1 CALL R12 1 + 0x14300A0C, // 00C2 LT R12 R5 R12 + 0x7832005A, // 00C3 JMPF R12 #011F + 0x94300805, // 00C4 GETIDX R12 R4 R5 + 0x88340107, // 00C5 GETMBR R13 R0 K7 + 0x88341B08, // 00C6 GETMBR R13 R13 K8 + 0x8C341B0D, // 00C7 GETMET R13 R13 K13 + 0x603C0008, // 00C8 GETGBL R15 G8 + 0x5C401800, // 00C9 MOVE R16 R12 + 0x7C3C0200, // 00CA CALL R15 1 + 0x7C340400, // 00CB CALL R13 2 + 0x8C381B0D, // 00CC GETMET R14 R13 K13 + 0x5840000E, // 00CD LDCONST R16 K14 + 0x7C380400, // 00CE CALL R14 2 + 0x5C3C1C00, // 00CF MOVE R15 R14 + 0x743E0001, // 00D0 JMPT R15 #00D3 + 0x00140B0F, // 00D1 ADD R5 R5 K15 + 0x7001FFEB, // 00D2 JMP #00BF + 0x8C3C050D, // 00D3 GETMET R15 R2 K13 + 0x5C441C00, // 00D4 MOVE R17 R14 + 0x58480010, // 00D5 LDCONST R18 K16 + 0x7C3C0600, // 00D6 CALL R15 3 + 0x203C1F0C, // 00D7 NE R15 R15 K12 + 0x783E0001, // 00D8 JMPF R15 #00DB + 0x00140B0F, // 00D9 ADD R5 R5 K15 + 0x7001FFE3, // 00DA JMP #00BF + 0x8C3C1B0D, // 00DB GETMET R15 R13 K13 + 0x58440020, // 00DC LDCONST R17 K32 + 0x7C3C0400, // 00DD CALL R15 2 + 0x203C1E09, // 00DE NE R15 R15 R9 + 0x783E0001, // 00DF JMPF R15 #00E2 + 0x00140B0F, // 00E0 ADD R5 R5 K15 + 0x7001FFDC, // 00E1 JMP #00BF + 0x883C0107, // 00E2 GETMBR R15 R0 K7 + 0x883C1F11, // 00E3 GETMBR R15 R15 K17 + 0x8C3C1F0D, // 00E4 GETMET R15 R15 K13 + 0x5C441C00, // 00E5 MOVE R17 R14 + 0x7C3C0400, // 00E6 CALL R15 2 + 0x58400012, // 00E7 LDCONST R16 K18 + 0x4C440000, // 00E8 LDNIL R17 + 0x20441E11, // 00E9 NE R17 R15 R17 + 0x78460004, // 00EA JMPF R17 #00F0 + 0x8C441F13, // 00EB GETMET R17 R15 K19 + 0x5C4C1E00, // 00EC MOVE R19 R15 + 0x5C501A00, // 00ED MOVE R20 R13 + 0x7C440600, // 00EE CALL R17 3 + 0x5C402200, // 00EF MOVE R16 R17 + 0x50180200, // 00F0 LDBOOL R6 1 0 + 0x8C440303, // 00F1 GETMET R17 R1 K3 + 0x604C0018, // 00F2 GETGBL R19 G24 + 0x58500028, // 00F3 LDCONST R20 K40 + 0x5C541800, // 00F4 MOVE R21 R12 + 0x7C4C0400, // 00F5 CALL R19 2 + 0x7C440400, // 00F6 CALL R17 2 + 0x8C440303, // 00F7 GETMET R17 R1 K3 + 0x604C0018, // 00F8 GETGBL R19 G24 + 0x58500029, // 00F9 LDCONST R20 K41 + 0x5C541800, // 00FA MOVE R21 R12 + 0x8C580316, // 00FB GETMET R22 R1 K22 + 0x8C601B0D, // 00FC GETMET R24 R13 K13 + 0x58680017, // 00FD LDCONST R26 K23 + 0x586C0012, // 00FE LDCONST R27 K18 + 0x7C600600, // 00FF CALL R24 3 + 0x7C580400, // 0100 CALL R22 2 + 0x7C4C0600, // 0101 CALL R19 3 + 0x7C440400, // 0102 CALL R17 2 + 0x8C440303, // 0103 GETMET R17 R1 K3 + 0x604C0018, // 0104 GETGBL R19 G24 + 0x5850002A, // 0105 LDCONST R20 K42 + 0x8C540119, // 0106 GETMET R21 R0 K25 + 0x8C5C1B0D, // 0107 GETMET R23 R13 K13 + 0x5864000E, // 0108 LDCONST R25 K14 + 0x58680012, // 0109 LDCONST R26 K18 + 0x7C5C0600, // 010A CALL R23 3 + 0x7C540400, // 010B CALL R21 2 + 0x7C4C0400, // 010C CALL R19 2 + 0x7C440400, // 010D CALL R17 2 + 0x8C440303, // 010E GETMET R17 R1 K3 + 0x604C0018, // 010F GETGBL R19 G24 + 0x5850002B, // 0110 LDCONST R20 K43 + 0x5C541800, // 0111 MOVE R21 R12 + 0x8C580316, // 0112 GETMET R22 R1 K22 + 0x5C602000, // 0113 MOVE R24 R16 + 0x7C580400, // 0114 CALL R22 2 + 0x7C4C0600, // 0115 CALL R19 3 + 0x7C440400, // 0116 CALL R17 2 + 0x8C440303, // 0117 GETMET R17 R1 K3 + 0x604C0018, // 0118 GETGBL R19 G24 + 0x5850002C, // 0119 LDCONST R20 K44 + 0x5C541800, // 011A MOVE R21 R12 + 0x7C4C0400, // 011B CALL R19 2 + 0x7C440400, // 011C CALL R17 2 + 0x00140B0F, // 011D ADD R5 R5 K15 + 0x7001FF9F, // 011E JMP #00BF + 0x8C300303, // 011F GETMET R12 R1 K3 + 0x5838002D, // 0120 LDCONST R14 K45 + 0x7C300400, // 0121 CALL R12 2 + 0x7001FF7C, // 0122 JMP #00A0 + 0x58200022, // 0123 LDCONST R8 K34 + 0xAC200200, // 0124 CATCH R8 1 0 + 0xB0080000, // 0125 RAISE 2 R0 R0 + 0x5C200C00, // 0126 MOVE R8 R6 + 0x74220002, // 0127 JMPT R8 #012B + 0x8C200303, // 0128 GETMET R8 R1 K3 + 0x5828001E, // 0129 LDCONST R10 K30 + 0x7C200400, // 012A CALL R8 2 + 0x8C200303, // 012B GETMET R8 R1 K3 + 0x5828002E, // 012C LDCONST R10 K46 + 0x7C200400, // 012D CALL R8 2 + 0x8C20012F, // 012E GETMET R8 R0 K47 + 0x88280130, // 012F GETMBR R10 R0 K48 + 0x7C200400, // 0130 CALL R8 2 + 0x8C200303, // 0131 GETMET R8 R1 K3 + 0x58280031, // 0132 LDCONST R10 K49 + 0x7C200400, // 0133 CALL R8 2 + 0x8C200303, // 0134 GETMET R8 R1 K3 + 0x58280032, // 0135 LDCONST R10 K50 + 0x7C200400, // 0136 CALL R8 2 + 0x8C200303, // 0137 GETMET R8 R1 K3 + 0x58280033, // 0138 LDCONST R10 K51 + 0x7C200400, // 0139 CALL R8 2 + 0x8C200303, // 013A GETMET R8 R1 K3 + 0x58280034, // 013B LDCONST R10 K52 + 0x7C200400, // 013C CALL R8 2 + 0x8C200135, // 013D GETMET R8 R0 K53 + 0x58280012, // 013E LDCONST R10 K18 + 0x882C0130, // 013F GETMBR R11 R0 K48 + 0x7C200600, // 0140 CALL R8 3 + 0x8C200303, // 0141 GETMET R8 R1 K3 + 0x58280036, // 0142 LDCONST R10 K54 + 0x7C200400, // 0143 CALL R8 2 + 0x8C200303, // 0144 GETMET R8 R1 K3 + 0x58280037, // 0145 LDCONST R10 K55 + 0x7C200400, // 0146 CALL R8 2 + 0x8C200303, // 0147 GETMET R8 R1 K3 + 0x58280038, // 0148 LDCONST R10 K56 + 0x7C200400, // 0149 CALL R8 2 + 0x8C200303, // 014A GETMET R8 R1 K3 + 0x58280039, // 014B LDCONST R10 K57 + 0x7C200400, // 014C CALL R8 2 + 0x8C200303, // 014D GETMET R8 R1 K3 + 0x5828003A, // 014E LDCONST R10 K58 + 0x7C200400, // 014F CALL R8 2 + 0x8C200303, // 0150 GETMET R8 R1 K3 + 0x5828003B, // 0151 LDCONST R10 K59 + 0x7C200400, // 0152 CALL R8 2 + 0x8C200303, // 0153 GETMET R8 R1 K3 + 0x58280038, // 0154 LDCONST R10 K56 + 0x7C200400, // 0155 CALL R8 2 + 0x8C200303, // 0156 GETMET R8 R1 K3 + 0x5828003C, // 0157 LDCONST R10 K60 + 0x7C200400, // 0158 CALL R8 2 + 0x8C200303, // 0159 GETMET R8 R1 K3 + 0x5828003D, // 015A LDCONST R10 K61 + 0x7C200400, // 015B CALL R8 2 + 0x8C200303, // 015C GETMET R8 R1 K3 + 0x5828003E, // 015D LDCONST R10 K62 + 0x7C200400, // 015E CALL R8 2 + 0x80000000, // 015F RET 0 }) ) ); @@ -315,6 +1010,404 @@ be_local_closure(Matter_UI_page_part_mgr, /* name */ ** Solidified function: show_commissioning_info ********************************************************************/ be_local_closure(Matter_UI_show_commissioning_info, /* name */ + be_nested_proto( + 12, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[17]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(device), + /* K2 */ be_nested_str_weak(commissioning_open), + /* K3 */ be_nested_str_weak(tasmota), + /* K4 */ be_nested_str_weak(millis), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(content_send), + /* K7 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3BCommissioning_X20open_X20for_X20_X25i_X20min_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K8 */ be_nested_str_weak(compute_manual_pairing_code), + /* K9 */ be_nested_str_weak(_X3Cp_X3EManual_X20pairing_X20code_X3A_X3Cbr_X3E_X3Cb_X3E_X25s_X2D_X25s_X2D_X25s_X3C_X2Fb_X3E_X3C_X2Fp_X3E_X3Chr_X3E), + /* K10 */ be_const_int(3), + /* K11 */ be_const_int(2147483647), + /* K12 */ be_nested_str_weak(_X3Cdiv_X3E_X3Ccenter_X3E), + /* K13 */ be_nested_str_weak(compute_qrcode_content), + /* K14 */ be_nested_str_weak(show_qrcode), + /* K15 */ be_nested_str_weak(_X3Cp_X3E_X20_X25s_X3C_X2Fp_X3E), + /* K16 */ be_nested_str_weak(_X3C_X2Fdiv_X3E_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + }), + be_str_weak(show_commissioning_info), + &be_const_str_solidified, + ( &(const binstruction[58]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x88080101, // 0001 GETMBR R2 R0 K1 + 0x88080502, // 0002 GETMBR R2 R2 K2 + 0xB80E0600, // 0003 GETNGBL R3 K3 + 0x8C0C0704, // 0004 GETMET R3 R3 K4 + 0x7C0C0200, // 0005 CALL R3 1 + 0x04080403, // 0006 SUB R2 R2 R3 + 0x540E03E7, // 0007 LDINT R3 1000 + 0x0C080403, // 0008 DIV R2 R2 R3 + 0x140C0505, // 0009 LT R3 R2 K5 + 0x780E0000, // 000A JMPF R3 #000C + 0x58080005, // 000B LDCONST R2 K5 + 0x540E001D, // 000C LDINT R3 30 + 0x000C0403, // 000D ADD R3 R2 R3 + 0x5412003B, // 000E LDINT R4 60 + 0x0C0C0604, // 000F DIV R3 R3 R4 + 0x8C100306, // 0010 GETMET R4 R1 K6 + 0x60180018, // 0011 GETGBL R6 G24 + 0x581C0007, // 0012 LDCONST R7 K7 + 0x5C200600, // 0013 MOVE R8 R3 + 0x7C180400, // 0014 CALL R6 2 + 0x7C100400, // 0015 CALL R4 2 + 0x88100101, // 0016 GETMBR R4 R0 K1 + 0x8C100908, // 0017 GETMET R4 R4 K8 + 0x7C100200, // 0018 CALL R4 1 + 0x8C140306, // 0019 GETMET R5 R1 K6 + 0x601C0018, // 001A GETGBL R7 G24 + 0x58200009, // 001B LDCONST R8 K9 + 0x40260B0A, // 001C CONNECT R9 K5 K10 + 0x94240809, // 001D GETIDX R9 R4 R9 + 0x542A0003, // 001E LDINT R10 4 + 0x542E0005, // 001F LDINT R11 6 + 0x4028140B, // 0020 CONNECT R10 R10 R11 + 0x9428080A, // 0021 GETIDX R10 R4 R10 + 0x542E0006, // 0022 LDINT R11 7 + 0x402C170B, // 0023 CONNECT R11 R11 K11 + 0x942C080B, // 0024 GETIDX R11 R4 R11 + 0x7C1C0800, // 0025 CALL R7 4 + 0x7C140400, // 0026 CALL R5 2 + 0x8C140306, // 0027 GETMET R5 R1 K6 + 0x581C000C, // 0028 LDCONST R7 K12 + 0x7C140400, // 0029 CALL R5 2 + 0x88140101, // 002A GETMBR R5 R0 K1 + 0x8C140B0D, // 002B GETMET R5 R5 K13 + 0x7C140200, // 002C CALL R5 1 + 0x8C18010E, // 002D GETMET R6 R0 K14 + 0x5C200A00, // 002E MOVE R8 R5 + 0x7C180400, // 002F CALL R6 2 + 0x8C180306, // 0030 GETMET R6 R1 K6 + 0x60200018, // 0031 GETGBL R8 G24 + 0x5824000F, // 0032 LDCONST R9 K15 + 0x5C280A00, // 0033 MOVE R10 R5 + 0x7C200400, // 0034 CALL R8 2 + 0x7C180400, // 0035 CALL R6 2 + 0x8C180306, // 0036 GETMET R6 R1 K6 + 0x58200010, // 0037 LDCONST R8 K16 + 0x7C180400, // 0038 CALL R6 2 + 0x80000000, // 0039 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: show_remote_autoconf +********************************************************************/ +be_local_closure(Matter_UI_show_remote_autoconf, /* name */ + be_nested_proto( + 25, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[47]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(json), + /* K2 */ be_nested_str_weak(), + /* K3 */ be_nested_str_weak(matter), + /* K4 */ be_nested_str_weak(Plugin_Bridge_HTTP), + /* K5 */ be_nested_str_weak(PROBE_TIMEOUT), + /* K6 */ be_nested_str_weak(HTTP_remote), + /* K7 */ be_nested_str_weak(call_sync), + /* K8 */ be_nested_str_weak(Status_X208), + /* K9 */ be_nested_str_weak(load), + /* K10 */ be_nested_str_weak(find), + /* K11 */ be_nested_str_weak(StatusSNS), + /* K12 */ be_nested_str_weak(Status_X2011), + /* K13 */ be_nested_str_weak(StatusSTS), + /* K14 */ be_nested_str_weak(tasmota), + /* K15 */ be_nested_str_weak(log), + /* K16 */ be_nested_str_weak(MTR_X3A_X20probed_X20_X27_X25s_X27_X20status8_X3D_X25s_X20satus11_X3D_X25s), + /* K17 */ be_const_int(3), + /* K18 */ be_nested_str_weak(generate_config_from_status), + /* K19 */ be_nested_str_weak(show_plugins_hints_js), + /* K20 */ be_nested_str_weak(_CLASSES_TYPES2), + /* K21 */ be_nested_str_weak(content_send), + /* K22 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3BMatter_X20Remote_X20Device_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E_X3Cp_X3E_X3Cb_X3EAdd_X20Remote_X20sensor_X20or_X20device_X3C_X2Fb_X3E_X3C_X2Fp_X3E), + /* K23 */ be_nested_str_weak(html_escape), + /* K24 */ be_nested_str_weak(_X3Cp_X3E_X26_X23x1F517_X3B_X20_X3Ca_X20target_X3D_X27_blank_X27_X20href_X3D_X22http_X3A_X2F_X2F_X25s_X2F_X3F_X22_X3E_X25s_X3C_X2Fa_X3E_X3C_X2Fp_X3E), + /* K25 */ be_nested_str_weak(_X3Cform_X20action_X3D_X27_X2Fmatterc_X27_X20method_X3D_X27post_X27_X3E_X3Ctable_X20style_X3D_X27width_X3A100_X25_X27_X3E_X3Ctr_X3E_X3Ctd_X20width_X3D_X27100_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3EName_X3C_X2Ftd_X3E_X3Ctd_X20width_X3D_X27115_X27_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3EType_X3C_X2Ftd_X3E_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3EParameter_X3C_X2Ftd_X3E_X3C_X2Ftr_X3E), + /* K26 */ be_nested_str_weak(_X3Cinput_X20name_X3D_X27url_X27_X20type_X3D_X27hidden_X27_X20value_X3D_X27_X25s_X27_X3E), + /* K27 */ be_const_int(0), + /* K28 */ be_nested_str_weak(type), + /* K29 */ be_nested_str_weak(http_), + /* K30 */ be_nested_str_weak(device), + /* K31 */ be_nested_str_weak(plugins_classes), + /* K32 */ be_nested_str_weak(ui_conf_to_string), + /* K33 */ be_nested_str_weak(_X3Ctr_X3E_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cinput_X20type_X3D_X27text_X27_X20name_X3D_X27nam_X25i_X27_X20size_X3D_X271_X27_X20value_X3D_X27_X27_X20placeholder_X3D_X27_X28optional_X29_X27_X3E_X3C_X2Ftd_X3E), + /* K34 */ be_nested_str_weak(_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E_X3Cselect_X20name_X3D_X27pi_X25i_X27_X20onchange_X3D_X27otm_X28_X22arg_X25i_X22_X2Cthis_X2Evalue_X29_X27_X3E), + /* K35 */ be_nested_str_weak(plugin_option), + /* K36 */ be_nested_str_weak(_X3C_X2Fselect_X3E_X3C_X2Ftd_X3E_X3Ctd_X20style_X3D_X27font_X2Dsize_X3Asmaller_X3B_X27_X3E), + /* K37 */ be_nested_str_weak(_X3Cinput_X20type_X3D_X27text_X27_X20id_X3D_X27arg_X25i_X27_X20name_X3D_X27arg_X25i_X27_X20size_X3D_X271_X27_X20value_X3D_X27_X25s_X27_X20placeholder_X3D_X27_X25s_X27_X3E), + /* K38 */ be_nested_str_weak(ARG_HINT), + /* K39 */ be_nested_str_weak(_X3C_X2Ftd_X3E_X3C_X2Ftr_X3E), + /* K40 */ be_const_int(1), + /* K41 */ be_nested_str_weak(_X3Cinput_X20type_X3D_X27text_X27_X20id_X3D_X27arg_X25i_X27_X20name_X3D_X27arg_X25i_X27_X20size_X3D_X271_X27_X20value_X3D_X27_X25s_X27_X3E), + /* K42 */ be_nested_str_weak(_X3C_X2Ftable_X3E), + /* K43 */ be_nested_str_weak(_X3Cdiv_X20style_X3D_X27display_X3A_X20block_X3B_X27_X3E_X3C_X2Fdiv_X3E), + /* K44 */ be_nested_str_weak(_X3Cbutton_X20name_X3D_X27addrem_X27_X20class_X3D_X27button_X20bgrn_X27_X3EAdd_X20endpoints_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E), + /* K45 */ be_nested_str_weak(_X3C_X2Fform_X3E_X3C_X2Ffieldset_X3E), + /* K46 */ be_nested_str_weak(_X3Cp_X3E_X3Cb_X3EUnable_X20to_X20connect_X20to_X20_X27_X25s_X27_X3C_X2Fb_X3E_X3C_X2Fp_X3E), + }), + be_str_weak(show_remote_autoconf), + &be_const_str_solidified, + ( &(const binstruction[228]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0xA40E0200, // 0001 IMPORT R3 K1 + 0x1C100302, // 0002 EQ R4 R1 K2 + 0x78120000, // 0003 JMPF R4 #0005 + 0x80000800, // 0004 RET 0 + 0xB8120600, // 0005 GETNGBL R4 K3 + 0x88100904, // 0006 GETMBR R4 R4 K4 + 0x88100905, // 0007 GETMBR R4 R4 K5 + 0xB8160600, // 0008 GETNGBL R5 K3 + 0x8C140B06, // 0009 GETMET R5 R5 K6 + 0x4C1C0000, // 000A LDNIL R7 + 0x5C200200, // 000B MOVE R8 R1 + 0x5C240800, // 000C MOVE R9 R4 + 0x7C140800, // 000D CALL R5 4 + 0x8C180B07, // 000E GETMET R6 R5 K7 + 0x58200008, // 000F LDCONST R8 K8 + 0x5C240800, // 0010 MOVE R9 R4 + 0x7C180600, // 0011 CALL R6 3 + 0x4C1C0000, // 0012 LDNIL R7 + 0x201C0C07, // 0013 NE R7 R6 R7 + 0x781E0003, // 0014 JMPF R7 #0019 + 0x8C1C0709, // 0015 GETMET R7 R3 K9 + 0x5C240C00, // 0016 MOVE R9 R6 + 0x7C1C0400, // 0017 CALL R7 2 + 0x5C180E00, // 0018 MOVE R6 R7 + 0x4C1C0000, // 0019 LDNIL R7 + 0x201C0C07, // 001A NE R7 R6 R7 + 0x781E0003, // 001B JMPF R7 #0020 + 0x8C1C0D0A, // 001C GETMET R7 R6 K10 + 0x5824000B, // 001D LDCONST R9 K11 + 0x7C1C0400, // 001E CALL R7 2 + 0x5C180E00, // 001F MOVE R6 R7 + 0x4C1C0000, // 0020 LDNIL R7 + 0x4C200000, // 0021 LDNIL R8 + 0x20200C08, // 0022 NE R8 R6 R8 + 0x78220012, // 0023 JMPF R8 #0037 + 0x8C200B07, // 0024 GETMET R8 R5 K7 + 0x5828000C, // 0025 LDCONST R10 K12 + 0x5C2C0800, // 0026 MOVE R11 R4 + 0x7C200600, // 0027 CALL R8 3 + 0x5C1C1000, // 0028 MOVE R7 R8 + 0x4C200000, // 0029 LDNIL R8 + 0x20200E08, // 002A NE R8 R7 R8 + 0x78220003, // 002B JMPF R8 #0030 + 0x8C200709, // 002C GETMET R8 R3 K9 + 0x5C280E00, // 002D MOVE R10 R7 + 0x7C200400, // 002E CALL R8 2 + 0x5C1C1000, // 002F MOVE R7 R8 + 0x4C200000, // 0030 LDNIL R8 + 0x20200E08, // 0031 NE R8 R7 R8 + 0x78220003, // 0032 JMPF R8 #0037 + 0x8C200F0A, // 0033 GETMET R8 R7 K10 + 0x5828000D, // 0034 LDCONST R10 K13 + 0x7C200400, // 0035 CALL R8 2 + 0x5C1C1000, // 0036 MOVE R7 R8 + 0x4C200000, // 0037 LDNIL R8 + 0x20200C08, // 0038 NE R8 R6 R8 + 0x782200A0, // 0039 JMPF R8 #00DB + 0x4C200000, // 003A LDNIL R8 + 0x20200E08, // 003B NE R8 R7 R8 + 0x7822009D, // 003C JMPF R8 #00DB + 0xB8221C00, // 003D GETNGBL R8 K14 + 0x8C20110F, // 003E GETMET R8 R8 K15 + 0x60280018, // 003F GETGBL R10 G24 + 0x582C0010, // 0040 LDCONST R11 K16 + 0x5C300200, // 0041 MOVE R12 R1 + 0x60340008, // 0042 GETGBL R13 G8 + 0x5C380C00, // 0043 MOVE R14 R6 + 0x7C340200, // 0044 CALL R13 1 + 0x60380008, // 0045 GETGBL R14 G8 + 0x5C3C0E00, // 0046 MOVE R15 R7 + 0x7C380200, // 0047 CALL R14 1 + 0x7C280800, // 0048 CALL R10 4 + 0x582C0011, // 0049 LDCONST R11 K17 + 0x7C200600, // 004A CALL R8 3 + 0x8C200112, // 004B GETMET R8 R0 K18 + 0x5C280C00, // 004C MOVE R10 R6 + 0x5C2C0E00, // 004D MOVE R11 R7 + 0x7C200600, // 004E CALL R8 3 + 0x8C240113, // 004F GETMET R9 R0 K19 + 0x882C0114, // 0050 GETMBR R11 R0 K20 + 0x7C240400, // 0051 CALL R9 2 + 0x8C240515, // 0052 GETMET R9 R2 K21 + 0x582C0016, // 0053 LDCONST R11 K22 + 0x7C240400, // 0054 CALL R9 2 + 0x8C240517, // 0055 GETMET R9 R2 K23 + 0x5C2C0200, // 0056 MOVE R11 R1 + 0x7C240400, // 0057 CALL R9 2 + 0x8C280515, // 0058 GETMET R10 R2 K21 + 0x60300018, // 0059 GETGBL R12 G24 + 0x58340018, // 005A LDCONST R13 K24 + 0x5C381200, // 005B MOVE R14 R9 + 0x5C3C1200, // 005C MOVE R15 R9 + 0x7C300600, // 005D CALL R12 3 + 0x7C280400, // 005E CALL R10 2 + 0x8C280515, // 005F GETMET R10 R2 K21 + 0x58300019, // 0060 LDCONST R12 K25 + 0x7C280400, // 0061 CALL R10 2 + 0x8C280515, // 0062 GETMET R10 R2 K21 + 0x60300018, // 0063 GETGBL R12 G24 + 0x5834001A, // 0064 LDCONST R13 K26 + 0x8C380517, // 0065 GETMET R14 R2 K23 + 0x5C400200, // 0066 MOVE R16 R1 + 0x7C380400, // 0067 CALL R14 2 + 0x7C300400, // 0068 CALL R12 2 + 0x7C280400, // 0069 CALL R10 2 + 0x5828001B, // 006A LDCONST R10 K27 + 0x602C000C, // 006B GETGBL R11 G12 + 0x5C301000, // 006C MOVE R12 R8 + 0x7C2C0200, // 006D CALL R11 1 + 0x142C140B, // 006E LT R11 R10 R11 + 0x782E003E, // 006F JMPF R11 #00AF + 0x942C100A, // 0070 GETIDX R11 R8 R10 + 0x8C30170A, // 0071 GETMET R12 R11 K10 + 0x5838001C, // 0072 LDCONST R14 K28 + 0x583C0002, // 0073 LDCONST R15 K2 + 0x7C300600, // 0074 CALL R12 3 + 0x20341902, // 0075 NE R13 R12 K2 + 0x78360000, // 0076 JMPF R13 #0078 + 0x00323A0C, // 0077 ADD R12 K29 R12 + 0x8834011E, // 0078 GETMBR R13 R0 K30 + 0x88341B1F, // 0079 GETMBR R13 R13 K31 + 0x8C341B0A, // 007A GETMET R13 R13 K10 + 0x5C3C1800, // 007B MOVE R15 R12 + 0x7C340400, // 007C CALL R13 2 + 0x58380002, // 007D LDCONST R14 K2 + 0x4C3C0000, // 007E LDNIL R15 + 0x203C1A0F, // 007F NE R15 R13 R15 + 0x783E0004, // 0080 JMPF R15 #0086 + 0x8C3C1B20, // 0081 GETMET R15 R13 K32 + 0x5C441A00, // 0082 MOVE R17 R13 + 0x5C481600, // 0083 MOVE R18 R11 + 0x7C3C0600, // 0084 CALL R15 3 + 0x5C381E00, // 0085 MOVE R14 R15 + 0x8C3C0515, // 0086 GETMET R15 R2 K21 + 0x60440018, // 0087 GETGBL R17 G24 + 0x58480021, // 0088 LDCONST R18 K33 + 0x5C4C1400, // 0089 MOVE R19 R10 + 0x7C440400, // 008A CALL R17 2 + 0x7C3C0400, // 008B CALL R15 2 + 0x8C3C0515, // 008C GETMET R15 R2 K21 + 0x60440018, // 008D GETGBL R17 G24 + 0x58480022, // 008E LDCONST R18 K34 + 0x5C4C1400, // 008F MOVE R19 R10 + 0x5C501400, // 0090 MOVE R20 R10 + 0x7C440600, // 0091 CALL R17 3 + 0x7C3C0400, // 0092 CALL R15 2 + 0x8C3C0123, // 0093 GETMET R15 R0 K35 + 0x5C441800, // 0094 MOVE R17 R12 + 0x88480114, // 0095 GETMBR R18 R0 K20 + 0x7C3C0600, // 0096 CALL R15 3 + 0x8C3C0515, // 0097 GETMET R15 R2 K21 + 0x58440024, // 0098 LDCONST R17 K36 + 0x7C3C0400, // 0099 CALL R15 2 + 0x8C3C0515, // 009A GETMET R15 R2 K21 + 0x60440018, // 009B GETGBL R17 G24 + 0x58480025, // 009C LDCONST R18 K37 + 0x5C4C1400, // 009D MOVE R19 R10 + 0x5C501400, // 009E MOVE R20 R10 + 0x8C540517, // 009F GETMET R21 R2 K23 + 0x5C5C1C00, // 00A0 MOVE R23 R14 + 0x7C540400, // 00A1 CALL R21 2 + 0x78360003, // 00A2 JMPF R13 #00A7 + 0x8C580517, // 00A3 GETMET R22 R2 K23 + 0x88601B26, // 00A4 GETMBR R24 R13 K38 + 0x7C580400, // 00A5 CALL R22 2 + 0x70020000, // 00A6 JMP #00A8 + 0x58580002, // 00A7 LDCONST R22 K2 + 0x7C440A00, // 00A8 CALL R17 5 + 0x7C3C0400, // 00A9 CALL R15 2 + 0x8C3C0515, // 00AA GETMET R15 R2 K21 + 0x58440027, // 00AB LDCONST R17 K39 + 0x7C3C0400, // 00AC CALL R15 2 + 0x00281528, // 00AD ADD R10 R10 K40 + 0x7001FFBB, // 00AE JMP #006B + 0x8C2C0515, // 00AF GETMET R11 R2 K21 + 0x60340018, // 00B0 GETGBL R13 G24 + 0x58380021, // 00B1 LDCONST R14 K33 + 0x5C3C1400, // 00B2 MOVE R15 R10 + 0x7C340400, // 00B3 CALL R13 2 + 0x7C2C0400, // 00B4 CALL R11 2 + 0x8C2C0515, // 00B5 GETMET R11 R2 K21 + 0x60340018, // 00B6 GETGBL R13 G24 + 0x58380022, // 00B7 LDCONST R14 K34 + 0x5C3C1400, // 00B8 MOVE R15 R10 + 0x5C401400, // 00B9 MOVE R16 R10 + 0x7C340600, // 00BA CALL R13 3 + 0x7C2C0400, // 00BB CALL R11 2 + 0x8C2C0123, // 00BC GETMET R11 R0 K35 + 0x58340002, // 00BD LDCONST R13 K2 + 0x88380114, // 00BE GETMBR R14 R0 K20 + 0x7C2C0600, // 00BF CALL R11 3 + 0x8C2C0515, // 00C0 GETMET R11 R2 K21 + 0x58340024, // 00C1 LDCONST R13 K36 + 0x7C2C0400, // 00C2 CALL R11 2 + 0x8C2C0515, // 00C3 GETMET R11 R2 K21 + 0x60340018, // 00C4 GETGBL R13 G24 + 0x58380029, // 00C5 LDCONST R14 K41 + 0x5C3C1400, // 00C6 MOVE R15 R10 + 0x5C401400, // 00C7 MOVE R16 R10 + 0x58440002, // 00C8 LDCONST R17 K2 + 0x7C340800, // 00C9 CALL R13 4 + 0x7C2C0400, // 00CA CALL R11 2 + 0x8C2C0515, // 00CB GETMET R11 R2 K21 + 0x58340027, // 00CC LDCONST R13 K39 + 0x7C2C0400, // 00CD CALL R11 2 + 0x8C2C0515, // 00CE GETMET R11 R2 K21 + 0x5834002A, // 00CF LDCONST R13 K42 + 0x7C2C0400, // 00D0 CALL R11 2 + 0x8C2C0515, // 00D1 GETMET R11 R2 K21 + 0x5834002B, // 00D2 LDCONST R13 K43 + 0x7C2C0400, // 00D3 CALL R11 2 + 0x8C2C0515, // 00D4 GETMET R11 R2 K21 + 0x5834002C, // 00D5 LDCONST R13 K44 + 0x7C2C0400, // 00D6 CALL R11 2 + 0x8C2C0515, // 00D7 GETMET R11 R2 K21 + 0x5834002D, // 00D8 LDCONST R13 K45 + 0x7C2C0400, // 00D9 CALL R11 2 + 0x70020007, // 00DA JMP #00E3 + 0x8C200515, // 00DB GETMET R8 R2 K21 + 0x60280018, // 00DC GETGBL R10 G24 + 0x582C002E, // 00DD LDCONST R11 K46 + 0x8C300517, // 00DE GETMET R12 R2 K23 + 0x5C380200, // 00DF MOVE R14 R1 + 0x7C300400, // 00E0 CALL R12 2 + 0x7C280400, // 00E1 CALL R10 2 + 0x7C200400, // 00E2 CALL R8 2 + 0x80000000, // 00E3 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: show_fabric_info +********************************************************************/ +be_local_closure(Matter_UI_show_fabric_info, /* name */ be_nested_proto( 14, /* nstack */ 1, /* argc */ @@ -324,97 +1417,526 @@ be_local_closure(Matter_UI_show_commissioning_info, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[20]) { /* constants */ + ( &(const bvalue[28]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(content_send), + /* K2 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3BFabrics_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E_X3Cp_X3EAssociated_X20fabrics_X3A_X3C_X2Fp_X3E), + /* K3 */ be_nested_str_weak(device), + /* K4 */ be_nested_str_weak(sessions), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(_X3Cp_X3E_X3Cb_X3ENone_X3C_X2Fb_X3E_X3C_X2Fp_X3E), + /* K7 */ be_nested_str_weak(fabrics), + /* K8 */ be_nested_str_weak(persistables), + /* K9 */ be_nested_str_weak(_X3Chr_X3E), + /* K10 */ be_nested_str_weak(fabric_label), + /* K11 */ be_nested_str_weak(_X3CNo_X20label_X3E), + /* K12 */ be_nested_str_weak(html_escape), + /* K13 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3B_X23_X25i_X20_X25s_X3C_X2Fb_X3E_X20_X28_X25s_X29_X26nbsp_X3B_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K14 */ be_nested_str_weak(get_fabric_index), + /* K15 */ be_nested_str_weak(get_admin_vendor_name), + /* K16 */ be_nested_str_weak(get_fabric_id), + /* K17 */ be_nested_str_weak(copy), + /* K18 */ be_nested_str_weak(reverse), + /* K19 */ be_nested_str_weak(get_device_id), + /* K20 */ be_nested_str_weak(Fabric_X3A_X20_X25s_X3Cbr_X3E), + /* K21 */ be_nested_str_weak(tohex), + /* K22 */ be_nested_str_weak(Device_X3A_X20_X25s_X3Cbr_X3E_X26nbsp_X3B), + /* K23 */ be_nested_str_weak(_X3Cform_X20action_X3D_X27_X2Fmatterc_X27_X20method_X3D_X27post_X27_X20onsubmit_X3D_X27return_X20confirm_X28_X22Are_X20you_X20sure_X3F_X22_X29_X3B_X27_X3E), + /* K24 */ be_nested_str_weak(_X3Cinput_X20name_X3D_X27del_fabric_X27_X20type_X3D_X27hidden_X27_X20value_X3D_X27_X25i_X27_X3E), + /* K25 */ be_nested_str_weak(_X3Cbutton_X20name_X3D_X27del_X27_X20class_X3D_X27button_X20bgrn_X27_X3EDelete_X20Fabric_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E), + /* K26 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K27 */ be_nested_str_weak(stop_iteration), + }), + be_str_weak(show_fabric_info), + &be_const_str_solidified, + ( &(const binstruction[100]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080301, // 0001 GETMET R2 R1 K1 + 0x58100002, // 0002 LDCONST R4 K2 + 0x7C080400, // 0003 CALL R2 2 + 0x6008000C, // 0004 GETGBL R2 G12 + 0x880C0103, // 0005 GETMBR R3 R0 K3 + 0x880C0704, // 0006 GETMBR R3 R3 K4 + 0x880C0704, // 0007 GETMBR R3 R3 K4 + 0x7C080200, // 0008 CALL R2 1 + 0x1C080505, // 0009 EQ R2 R2 K5 + 0x780A0003, // 000A JMPF R2 #000F + 0x8C080301, // 000B GETMET R2 R1 K1 + 0x58100006, // 000C LDCONST R4 K6 + 0x7C080400, // 000D CALL R2 2 + 0x70020050, // 000E JMP #0060 + 0x50080200, // 000F LDBOOL R2 1 0 + 0x600C0010, // 0010 GETGBL R3 G16 + 0x88100103, // 0011 GETMBR R4 R0 K3 + 0x88100904, // 0012 GETMBR R4 R4 K4 + 0x88100907, // 0013 GETMBR R4 R4 K7 + 0x8C100908, // 0014 GETMET R4 R4 K8 + 0x7C100200, // 0015 CALL R4 1 + 0x7C0C0200, // 0016 CALL R3 1 + 0xA8020044, // 0017 EXBLK 0 #005D + 0x5C100600, // 0018 MOVE R4 R3 + 0x7C100000, // 0019 CALL R4 0 + 0x5C140400, // 001A MOVE R5 R2 + 0x74160002, // 001B JMPT R5 #001F + 0x8C140301, // 001C GETMET R5 R1 K1 + 0x581C0009, // 001D LDCONST R7 K9 + 0x7C140400, // 001E CALL R5 2 + 0x50080000, // 001F LDBOOL R2 0 0 + 0x8814090A, // 0020 GETMBR R5 R4 K10 + 0x5C180A00, // 0021 MOVE R6 R5 + 0x741A0000, // 0022 JMPT R6 #0024 + 0x5814000B, // 0023 LDCONST R5 K11 + 0x8C18030C, // 0024 GETMET R6 R1 K12 + 0x5C200A00, // 0025 MOVE R8 R5 + 0x7C180400, // 0026 CALL R6 2 + 0x5C140C00, // 0027 MOVE R5 R6 + 0x8C180301, // 0028 GETMET R6 R1 K1 + 0x60200018, // 0029 GETGBL R8 G24 + 0x5824000D, // 002A LDCONST R9 K13 + 0x8C28090E, // 002B GETMET R10 R4 K14 + 0x7C280200, // 002C CALL R10 1 + 0x5C2C0A00, // 002D MOVE R11 R5 + 0x8C30090F, // 002E GETMET R12 R4 K15 + 0x7C300200, // 002F CALL R12 1 + 0x7C200800, // 0030 CALL R8 4 + 0x7C180400, // 0031 CALL R6 2 + 0x8C180910, // 0032 GETMET R6 R4 K16 + 0x7C180200, // 0033 CALL R6 1 + 0x8C180D11, // 0034 GETMET R6 R6 K17 + 0x7C180200, // 0035 CALL R6 1 + 0x8C180D12, // 0036 GETMET R6 R6 K18 + 0x7C180200, // 0037 CALL R6 1 + 0x8C1C0913, // 0038 GETMET R7 R4 K19 + 0x7C1C0200, // 0039 CALL R7 1 + 0x8C1C0F11, // 003A GETMET R7 R7 K17 + 0x7C1C0200, // 003B CALL R7 1 + 0x8C1C0F12, // 003C GETMET R7 R7 K18 + 0x7C1C0200, // 003D CALL R7 1 + 0x8C200301, // 003E GETMET R8 R1 K1 + 0x60280018, // 003F GETGBL R10 G24 + 0x582C0014, // 0040 LDCONST R11 K20 + 0x8C300D15, // 0041 GETMET R12 R6 K21 + 0x7C300200, // 0042 CALL R12 1 + 0x7C280400, // 0043 CALL R10 2 + 0x7C200400, // 0044 CALL R8 2 + 0x8C200301, // 0045 GETMET R8 R1 K1 + 0x60280018, // 0046 GETGBL R10 G24 + 0x582C0016, // 0047 LDCONST R11 K22 + 0x8C300F15, // 0048 GETMET R12 R7 K21 + 0x7C300200, // 0049 CALL R12 1 + 0x7C280400, // 004A CALL R10 2 + 0x7C200400, // 004B CALL R8 2 + 0x8C200301, // 004C GETMET R8 R1 K1 + 0x58280017, // 004D LDCONST R10 K23 + 0x7C200400, // 004E CALL R8 2 + 0x8C200301, // 004F GETMET R8 R1 K1 + 0x60280018, // 0050 GETGBL R10 G24 + 0x582C0018, // 0051 LDCONST R11 K24 + 0x8C30090E, // 0052 GETMET R12 R4 K14 + 0x7C300200, // 0053 CALL R12 1 + 0x7C280400, // 0054 CALL R10 2 + 0x7C200400, // 0055 CALL R8 2 + 0x8C200301, // 0056 GETMET R8 R1 K1 + 0x58280019, // 0057 LDCONST R10 K25 + 0x7C200400, // 0058 CALL R8 2 + 0x8C200301, // 0059 GETMET R8 R1 K1 + 0x5828001A, // 005A LDCONST R10 K26 + 0x7C200400, // 005B CALL R8 2 + 0x7001FFBA, // 005C JMP #0018 + 0x580C001B, // 005D LDCONST R3 K27 + 0xAC0C0200, // 005E CATCH R3 1 0 + 0xB0080000, // 005F RAISE 2 R0 R0 + 0x8C080301, // 0060 GETMET R2 R1 K1 + 0x5810001A, // 0061 LDCONST R4 K26 + 0x7C080400, // 0062 CALL R2 2 + 0x80000000, // 0063 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_get_arg +********************************************************************/ +be_local_closure(Matter_UI_web_get_arg, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(has_arg), + /* K2 */ be_nested_str_weak(mtc0), + /* K3 */ be_nested_str_weak(device), + /* K4 */ be_nested_str_weak(stop_basic_commissioning), + /* K5 */ be_nested_str_weak(mtc1), + /* K6 */ be_nested_str_weak(start_root_basic_commissioning), + }), + be_str_weak(web_get_arg), + &be_const_str_solidified, + ( &(const binstruction[17]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080301, // 0001 GETMET R2 R1 K1 + 0x58100002, // 0002 LDCONST R4 K2 + 0x7C080400, // 0003 CALL R2 2 + 0x780A0003, // 0004 JMPF R2 #0009 + 0x88080103, // 0005 GETMBR R2 R0 K3 + 0x8C080504, // 0006 GETMET R2 R2 K4 + 0x7C080200, // 0007 CALL R2 1 + 0x70020006, // 0008 JMP #0010 + 0x8C080301, // 0009 GETMET R2 R1 K1 + 0x58100005, // 000A LDCONST R4 K5 + 0x7C080400, // 000B CALL R2 2 + 0x780A0002, // 000C JMPF R2 #0010 + 0x88080103, // 000D GETMBR R2 R0 K3 + 0x8C080506, // 000E GETMET R2 R2 K6 + 0x7C080200, // 000F CALL R2 1 + 0x80000000, // 0010 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: plugin_option +********************************************************************/ +be_local_closure(Matter_UI_plugin_option, /* name */ + be_nested_proto( + 16, /* nstack */ + 3, /* argc */ + 3, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[16]) { /* constants */ /* K0 */ be_nested_str_weak(webserver), /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(device), - /* K3 */ be_nested_str_weak(commissioning_open), - /* K4 */ be_nested_str_weak(tasmota), - /* K5 */ be_nested_str_weak(millis), - /* K6 */ be_const_int(0), + /* K2 */ be_nested_str_weak(split), + /* K3 */ be_nested_str_weak(_X7C), + /* K4 */ be_nested_str_weak(stop_iteration), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(), /* K7 */ be_nested_str_weak(content_send), - /* K8 */ be_nested_str_weak(format), - /* K9 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3BCommissioning_X20open_X20for_X20_X25i_X20min_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E), - /* K10 */ be_nested_str_weak(compute_manual_pairing_code), - /* K11 */ be_nested_str_weak(_X3Cp_X3EManual_X20pairing_X20code_X3A_X3Cbr_X3E_X3Cb_X3E_X25s_X2D_X25s_X2D_X25s_X3C_X2Fb_X3E_X3C_X2Fp_X3E_X3Chr_X3E), - /* K12 */ be_const_int(3), - /* K13 */ be_const_int(2147483647), - /* K14 */ be_nested_str_weak(_X3Cdiv_X3E_X3Ccenter_X3E), - /* K15 */ be_nested_str_weak(compute_qrcode_content), - /* K16 */ be_nested_str_weak(show_qrcode), - /* K17 */ be_nested_str_weak(_X3Cp_X3E_X20_X25s_X3C_X2Fp_X3E), - /* K18 */ be_nested_str_weak(_X3C_X2Fdiv_X3E), - /* K19 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K8 */ be_nested_str_weak(_X3Coption_X20value_X3D_X27_X27_X3E_X3C_X2Foption_X3E), + /* K9 */ be_nested_str_weak(_X2Dvirtual), + /* K10 */ be_nested_str_weak(_X3Coption_X20value_X3D_X27_X27_X20disabled_X3E_X2D_X2D_X2D_X20Virtual_X20Devices_X20_X2D_X2D_X2D_X3C_X2Foption_X3E), + /* K11 */ be_nested_str_weak(device), + /* K12 */ be_nested_str_weak(get_plugin_class_displayname), + /* K13 */ be_nested_str_weak(_X3Coption_X20value_X3D_X27_X25s_X27_X25s_X3E_X25s_X3C_X2Foption_X3E), + /* K14 */ be_nested_str_weak(_X20selected), + /* K15 */ be_const_int(1), }), - be_str_weak(show_commissioning_info), + be_str_weak(plugin_option), &be_const_str_solidified, - ( &(const binstruction[66]) { /* code */ + ( &(const binstruction[57]) { /* code */ + 0xA40E0000, // 0000 IMPORT R3 K0 + 0xA4120200, // 0001 IMPORT R4 K1 + 0x60140012, // 0002 GETGBL R5 G18 + 0x7C140000, // 0003 CALL R5 0 + 0x60180010, // 0004 GETGBL R6 G16 + 0x5C1C0400, // 0005 MOVE R7 R2 + 0x7C180200, // 0006 CALL R6 1 + 0xA8020007, // 0007 EXBLK 0 #0010 + 0x5C1C0C00, // 0008 MOVE R7 R6 + 0x7C1C0000, // 0009 CALL R7 0 + 0x8C200902, // 000A GETMET R8 R4 K2 + 0x5C280E00, // 000B MOVE R10 R7 + 0x582C0003, // 000C LDCONST R11 K3 + 0x7C200600, // 000D CALL R8 3 + 0x00140A08, // 000E ADD R5 R5 R8 + 0x7001FFF7, // 000F JMP #0008 + 0x58180004, // 0010 LDCONST R6 K4 + 0xAC180200, // 0011 CATCH R6 1 0 + 0xB0080000, // 0012 RAISE 2 R0 R0 + 0x58180005, // 0013 LDCONST R6 K5 + 0x601C000C, // 0014 GETGBL R7 G12 + 0x5C200A00, // 0015 MOVE R8 R5 + 0x7C1C0200, // 0016 CALL R7 1 + 0x141C0C07, // 0017 LT R7 R6 R7 + 0x781E001E, // 0018 JMPF R7 #0038 + 0x941C0A06, // 0019 GETIDX R7 R5 R6 + 0x1C200F06, // 001A EQ R8 R7 K6 + 0x78220003, // 001B JMPF R8 #0020 + 0x8C200707, // 001C GETMET R8 R3 K7 + 0x58280008, // 001D LDCONST R10 K8 + 0x7C200400, // 001E CALL R8 2 + 0x70020015, // 001F JMP #0036 + 0x1C200F09, // 0020 EQ R8 R7 K9 + 0x78220003, // 0021 JMPF R8 #0026 + 0x8C200707, // 0022 GETMET R8 R3 K7 + 0x5828000A, // 0023 LDCONST R10 K10 + 0x7C200400, // 0024 CALL R8 2 + 0x7002000F, // 0025 JMP #0036 + 0x8820010B, // 0026 GETMBR R8 R0 K11 + 0x8C20110C, // 0027 GETMET R8 R8 K12 + 0x5C280E00, // 0028 MOVE R10 R7 + 0x7C200400, // 0029 CALL R8 2 + 0x8C240707, // 002A GETMET R9 R3 K7 + 0x602C0018, // 002B GETGBL R11 G24 + 0x5830000D, // 002C LDCONST R12 K13 + 0x5C340E00, // 002D MOVE R13 R7 + 0x1C380E01, // 002E EQ R14 R7 R1 + 0x783A0001, // 002F JMPF R14 #0032 + 0x5838000E, // 0030 LDCONST R14 K14 + 0x70020000, // 0031 JMP #0033 + 0x58380006, // 0032 LDCONST R14 K6 + 0x5C3C1000, // 0033 MOVE R15 R8 + 0x7C2C0800, // 0034 CALL R11 4 + 0x7C240400, // 0035 CALL R9 2 + 0x00180D0F, // 0036 ADD R6 R6 K15 + 0x7001FFDB, // 0037 JMP #0014 + 0x80000000, // 0038 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: web_add_config_button +********************************************************************/ +be_local_closure(Matter_UI_web_add_config_button, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_nested_str_weak(content_send), + /* K2 */ be_nested_str_weak(_X3Cp_X3E_X3Cform_X20id_X3Dac_X20action_X3D_X27matterc_X27_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20method_X3D_X27get_X27_X3E_X3Cbutton_X3E), + /* K3 */ be_nested_str_weak(matter), + /* K4 */ be_nested_str_weak(_LOGO), + /* K5 */ be_nested_str_weak(_X20Configure_X20Matter_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E), + }), + be_str_weak(web_add_config_button), + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0x880C0102, // 0002 GETMBR R3 R0 K2 - 0x880C0703, // 0003 GETMBR R3 R3 K3 - 0xB8120800, // 0004 GETNGBL R4 K4 - 0x8C100905, // 0005 GETMET R4 R4 K5 + 0x8C080301, // 0001 GETMET R2 R1 K1 + 0x58100002, // 0002 LDCONST R4 K2 + 0x7C080400, // 0003 CALL R2 2 + 0x8C080301, // 0004 GETMET R2 R1 K1 + 0xB8120600, // 0005 GETNGBL R4 K3 + 0x88100904, // 0006 GETMBR R4 R4 K4 + 0x7C080400, // 0007 CALL R2 2 + 0x8C080301, // 0008 GETMET R2 R1 K1 + 0x58100005, // 0009 LDCONST R4 K5 + 0x7C080400, // 000A CALL R2 2 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Matter_UI_init, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(device), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(add_driver), + }), + be_str_weak(init), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0xB80A0200, // 0001 GETNGBL R2 K1 + 0x8C080502, // 0002 GETMET R2 R2 K2 + 0x5C100000, // 0003 MOVE R4 R0 + 0x7C080400, // 0004 CALL R2 2 + 0x80000000, // 0005 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: show_bridge_status +********************************************************************/ +be_local_closure(Matter_UI_show_bridge_status, /* name */ + be_nested_proto( + 15, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[27]) { /* constants */ + /* K0 */ be_nested_str_weak(webserver), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(device), + /* K3 */ be_nested_str_weak(plugins), + /* K4 */ be_nested_str_weak(matter), + /* K5 */ be_nested_str_weak(Plugin_Bridge_HTTP), + /* K6 */ be_nested_str_weak(http_remote), + /* K7 */ be_nested_str_weak(addr), + /* K8 */ be_nested_str_weak(contains), + /* K9 */ be_nested_str_weak(push), + /* K10 */ be_const_int(1), + /* K11 */ be_nested_str_weak(content_send), + /* K12 */ be_nested_str_weak(_X3Chr_X3E), + /* K13 */ be_nested_str_weak(_X3Ctable_X20style_X3D_X27width_X3A100_X25_X27_X3E), + /* K14 */ be_nested_str_weak(_STYLESHEET), + /* K15 */ be_nested_str_weak(k2l), + /* K16 */ be_nested_str_weak(html_escape), + /* K17 */ be_nested_str_weak(get_plugin_remote_info), + /* K18 */ be_nested_str_weak(find), + /* K19 */ be_nested_str_weak(name), + /* K20 */ be_nested_str_weak(_X3Ctr_X20class_X3D_X27ztdm_X20htrm_X27_X3E_X3Ctd_X3E_X26_X23x1F517_X3B_X20_X3Ca_X20target_X3D_X27_blank_X27_X20title_X3D_X27http_X3A_X2F_X2F_X25s_X2F_X27_X20href_X3D_X22http_X3A_X2F_X2F_X25s_X2F_X3F_X22_X27_X3E_X25s_X3C_X2Fa_X3E_X3C_X2Ftd_X3E), + /* K21 */ be_nested_str_weak(web_last_seen), + /* K22 */ be_nested_str_weak(_X3Ctr_X20class_X3D_X27htrm_X27_X3E_X3Ctd_X20colspan_X3D_X272_X27_X3E), + /* K23 */ be_nested_str_weak(web_values), + /* K24 */ be_nested_str_weak(_X3C_X2Ftd_X3E_X3C_X2Ftr_X3E), + /* K25 */ be_nested_str_weak(stop_iteration), + /* K26 */ be_nested_str_weak(_X3C_X2Ftable_X3E_X3Chr_X3E), + }), + be_str_weak(show_bridge_status), + &be_const_str_solidified, + ( &(const binstruction[116]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x580C0001, // 0002 LDCONST R3 K1 + 0x6010000C, // 0003 GETGBL R4 G12 + 0x88140102, // 0004 GETMBR R5 R0 K2 + 0x88140B03, // 0005 GETMBR R5 R5 K3 0x7C100200, // 0006 CALL R4 1 - 0x040C0604, // 0007 SUB R3 R3 R4 - 0x541203E7, // 0008 LDINT R4 1000 - 0x0C0C0604, // 0009 DIV R3 R3 R4 - 0x14100706, // 000A LT R4 R3 K6 - 0x78120000, // 000B JMPF R4 #000D - 0x580C0006, // 000C LDCONST R3 K6 - 0x5412001D, // 000D LDINT R4 30 - 0x00100604, // 000E ADD R4 R3 R4 - 0x5416003B, // 000F LDINT R5 60 - 0x0C100805, // 0010 DIV R4 R4 R5 - 0x8C140307, // 0011 GETMET R5 R1 K7 - 0x8C1C0508, // 0012 GETMET R7 R2 K8 - 0x58240009, // 0013 LDCONST R9 K9 - 0x5C280800, // 0014 MOVE R10 R4 - 0x7C1C0600, // 0015 CALL R7 3 - 0x7C140400, // 0016 CALL R5 2 - 0x88140102, // 0017 GETMBR R5 R0 K2 - 0x8C140B0A, // 0018 GETMET R5 R5 K10 - 0x7C140200, // 0019 CALL R5 1 - 0x8C180307, // 001A GETMET R6 R1 K7 - 0x8C200508, // 001B GETMET R8 R2 K8 - 0x5828000B, // 001C LDCONST R10 K11 - 0x402E0D0C, // 001D CONNECT R11 K6 K12 - 0x942C0A0B, // 001E GETIDX R11 R5 R11 - 0x54320003, // 001F LDINT R12 4 - 0x54360005, // 0020 LDINT R13 6 - 0x4030180D, // 0021 CONNECT R12 R12 R13 - 0x94300A0C, // 0022 GETIDX R12 R5 R12 - 0x54360006, // 0023 LDINT R13 7 - 0x40341B0D, // 0024 CONNECT R13 R13 K13 - 0x94340A0D, // 0025 GETIDX R13 R5 R13 - 0x7C200A00, // 0026 CALL R8 5 - 0x7C180400, // 0027 CALL R6 2 - 0x8C180307, // 0028 GETMET R6 R1 K7 - 0x8C200508, // 0029 GETMET R8 R2 K8 - 0x5828000E, // 002A LDCONST R10 K14 - 0x7C200400, // 002B CALL R8 2 - 0x7C180400, // 002C CALL R6 2 - 0x88180102, // 002D GETMBR R6 R0 K2 - 0x8C180D0F, // 002E GETMET R6 R6 K15 - 0x7C180200, // 002F CALL R6 1 - 0x8C1C0110, // 0030 GETMET R7 R0 K16 - 0x5C240C00, // 0031 MOVE R9 R6 - 0x7C1C0400, // 0032 CALL R7 2 - 0x8C1C0307, // 0033 GETMET R7 R1 K7 - 0x8C240508, // 0034 GETMET R9 R2 K8 - 0x582C0011, // 0035 LDCONST R11 K17 - 0x5C300C00, // 0036 MOVE R12 R6 - 0x7C240600, // 0037 CALL R9 3 - 0x7C1C0400, // 0038 CALL R7 2 - 0x8C1C0307, // 0039 GETMET R7 R1 K7 - 0x8C240508, // 003A GETMET R9 R2 K8 - 0x582C0012, // 003B LDCONST R11 K18 - 0x7C240400, // 003C CALL R9 2 - 0x7C1C0400, // 003D CALL R7 2 - 0x8C1C0307, // 003E GETMET R7 R1 K7 - 0x58240013, // 003F LDCONST R9 K19 - 0x7C1C0400, // 0040 CALL R7 2 - 0x80000000, // 0041 RET 0 + 0x14100604, // 0007 LT R4 R3 R4 + 0x7812001D, // 0008 JMPF R4 #0027 + 0x88100102, // 0009 GETMBR R4 R0 K2 + 0x88100903, // 000A GETMBR R4 R4 K3 + 0x94100803, // 000B GETIDX R4 R4 R3 + 0x6014000F, // 000C GETGBL R5 G15 + 0x5C180800, // 000D MOVE R6 R4 + 0xB81E0800, // 000E GETNGBL R7 K4 + 0x881C0F05, // 000F GETMBR R7 R7 K5 + 0x7C140400, // 0010 CALL R5 2 + 0x78160012, // 0011 JMPF R5 #0025 + 0x4C140000, // 0012 LDNIL R5 + 0x1C140405, // 0013 EQ R5 R2 R5 + 0x78160002, // 0014 JMPF R5 #0018 + 0x60140013, // 0015 GETGBL R5 G19 + 0x7C140000, // 0016 CALL R5 0 + 0x5C080A00, // 0017 MOVE R2 R5 + 0x88140906, // 0018 GETMBR R5 R4 K6 + 0x88140B07, // 0019 GETMBR R5 R5 K7 + 0x8C180508, // 001A GETMET R6 R2 K8 + 0x5C200A00, // 001B MOVE R8 R5 + 0x7C180400, // 001C CALL R6 2 + 0x741A0002, // 001D JMPT R6 #0021 + 0x60180012, // 001E GETGBL R6 G18 + 0x7C180000, // 001F CALL R6 0 + 0x98080A06, // 0020 SETIDX R2 R5 R6 + 0x94180405, // 0021 GETIDX R6 R2 R5 + 0x8C180D09, // 0022 GETMET R6 R6 K9 + 0x5C200800, // 0023 MOVE R8 R4 + 0x7C180400, // 0024 CALL R6 2 + 0x000C070A, // 0025 ADD R3 R3 K10 + 0x7001FFDB, // 0026 JMP #0003 + 0x4C100000, // 0027 LDNIL R4 + 0x1C100404, // 0028 EQ R4 R2 R4 + 0x78120000, // 0029 JMPF R4 #002B + 0x80000800, // 002A RET 0 + 0x8C10030B, // 002B GETMET R4 R1 K11 + 0x5818000C, // 002C LDCONST R6 K12 + 0x7C100400, // 002D CALL R4 2 + 0x8C10030B, // 002E GETMET R4 R1 K11 + 0x5818000D, // 002F LDCONST R6 K13 + 0x7C100400, // 0030 CALL R4 2 + 0x8C10030B, // 0031 GETMET R4 R1 K11 + 0xB81A0800, // 0032 GETNGBL R6 K4 + 0x88180D0E, // 0033 GETMBR R6 R6 K14 + 0x7C100400, // 0034 CALL R4 2 + 0x60100010, // 0035 GETGBL R4 G16 + 0x88140102, // 0036 GETMBR R5 R0 K2 + 0x8C140B0F, // 0037 GETMET R5 R5 K15 + 0x5C1C0400, // 0038 MOVE R7 R2 + 0x7C140400, // 0039 CALL R5 2 + 0x7C100200, // 003A CALL R4 1 + 0xA8020030, // 003B EXBLK 0 #006D + 0x5C140800, // 003C MOVE R5 R4 + 0x7C140000, // 003D CALL R5 0 + 0x8C180310, // 003E GETMET R6 R1 K16 + 0x5C200A00, // 003F MOVE R8 R5 + 0x7C180400, // 0040 CALL R6 2 + 0x8C1C0310, // 0041 GETMET R7 R1 K16 + 0x88240102, // 0042 GETMBR R9 R0 K2 + 0x8C241311, // 0043 GETMET R9 R9 K17 + 0x5C2C0A00, // 0044 MOVE R11 R5 + 0x7C240400, // 0045 CALL R9 2 + 0x8C241312, // 0046 GETMET R9 R9 K18 + 0x582C0013, // 0047 LDCONST R11 K19 + 0x5C300A00, // 0048 MOVE R12 R5 + 0x7C240600, // 0049 CALL R9 3 + 0x7C1C0400, // 004A CALL R7 2 + 0x8C20030B, // 004B GETMET R8 R1 K11 + 0x60280018, // 004C GETGBL R10 G24 + 0x582C0014, // 004D LDCONST R11 K20 + 0x5C300C00, // 004E MOVE R12 R6 + 0x5C340C00, // 004F MOVE R13 R6 + 0x5C380E00, // 0050 MOVE R14 R7 + 0x7C280800, // 0051 CALL R10 4 + 0x7C200400, // 0052 CALL R8 2 + 0x94200405, // 0053 GETIDX R8 R2 R5 + 0x94201101, // 0054 GETIDX R8 R8 K1 + 0x88201106, // 0055 GETMBR R8 R8 K6 + 0x8C24030B, // 0056 GETMET R9 R1 K11 + 0x8C2C1115, // 0057 GETMET R11 R8 K21 + 0x7C2C0200, // 0058 CALL R11 1 + 0x7C240400, // 0059 CALL R9 2 + 0x60240010, // 005A GETGBL R9 G16 + 0x94280405, // 005B GETIDX R10 R2 R5 + 0x7C240200, // 005C CALL R9 1 + 0xA802000A, // 005D EXBLK 0 #0069 + 0x5C281200, // 005E MOVE R10 R9 + 0x7C280000, // 005F CALL R10 0 + 0x8C2C030B, // 0060 GETMET R11 R1 K11 + 0x58340016, // 0061 LDCONST R13 K22 + 0x7C2C0400, // 0062 CALL R11 2 + 0x8C2C1517, // 0063 GETMET R11 R10 K23 + 0x7C2C0200, // 0064 CALL R11 1 + 0x8C2C030B, // 0065 GETMET R11 R1 K11 + 0x58340018, // 0066 LDCONST R13 K24 + 0x7C2C0400, // 0067 CALL R11 2 + 0x7001FFF4, // 0068 JMP #005E + 0x58240019, // 0069 LDCONST R9 K25 + 0xAC240200, // 006A CATCH R9 1 0 + 0xB0080000, // 006B RAISE 2 R0 R0 + 0x7001FFCE, // 006C JMP #003C + 0x58100019, // 006D LDCONST R4 K25 + 0xAC100200, // 006E CATCH R4 1 0 + 0xB0080000, // 006F RAISE 2 R0 R0 + 0x8C10030B, // 0070 GETMET R4 R1 K11 + 0x5818001A, // 0071 LDCONST R6 K26 + 0x7C100400, // 0072 CALL R4 2 + 0x80000000, // 0073 RET 0 }) ) ); @@ -432,7 +1954,53 @@ be_local_closure(Matter_UI_web_add_handler, /* name */ 0, /* has upvals */ NULL, /* no upvals */ 1, /* has sup protos */ - ( &(const struct bproto*[ 2]) { + ( &(const struct bproto*[ 4]) { + be_nested_proto( + 2, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(page_part_mgr), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x7C000200, // 0002 CALL R0 1 + 0x80040000, // 0003 RET 1 R0 + }) + ), + be_nested_proto( + 2, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(page_part_ctl), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x7C000200, // 0002 CALL R0 1 + 0x80040000, // 0003 RET 1 R0 + }) + ), be_nested_proto( 2, /* nstack */ 0, /* argc */ @@ -445,7 +2013,7 @@ be_local_closure(Matter_UI_web_add_handler, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(page_part_mgr), + /* K0 */ be_nested_str_weak(page_part_mgr_adv), }), be_str_weak(_X3Clambda_X3E), &be_const_str_solidified, @@ -468,7 +2036,7 @@ be_local_closure(Matter_UI_web_add_handler, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(page_part_ctl), + /* K0 */ be_nested_str_weak(page_part_mgr_add), }), be_str_weak(_X3Clambda_X3E), &be_const_str_solidified, @@ -481,16 +2049,18 @@ be_local_closure(Matter_UI_web_add_handler, /* name */ ), }), 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ + ( &(const bvalue[ 7]) { /* constants */ /* K0 */ be_nested_str_weak(webserver), /* K1 */ be_nested_str_weak(on), /* K2 */ be_nested_str_weak(_X2Fmatterc), /* K3 */ be_nested_str_weak(HTTP_GET), /* K4 */ be_nested_str_weak(HTTP_POST), + /* K5 */ be_nested_str_weak(_X2Fmattera), + /* K6 */ be_nested_str_weak(_X2Fmatteradd), }), be_str_weak(web_add_handler), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ + ( &(const binstruction[23]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 0x8C080301, // 0001 GETMET R2 R1 K1 0x58100002, // 0002 LDCONST R4 K2 @@ -502,56 +2072,18 @@ be_local_closure(Matter_UI_web_add_handler, /* name */ 0x84140001, // 0008 CLOSURE R5 P1 0x88180304, // 0009 GETMBR R6 R1 K4 0x7C080800, // 000A CALL R2 4 - 0xA0000000, // 000B CLOSE R0 - 0x80000000, // 000C RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: web_get_arg -********************************************************************/ -be_local_closure(Matter_UI_web_get_arg, /* name */ - be_nested_proto( - 5, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str_weak(webserver), - /* K1 */ be_nested_str_weak(has_arg), - /* K2 */ be_nested_str_weak(mtc0), - /* K3 */ be_nested_str_weak(device), - /* K4 */ be_nested_str_weak(stop_basic_commissioning), - /* K5 */ be_nested_str_weak(mtc1), - /* K6 */ be_nested_str_weak(start_root_basic_commissioning), - }), - be_str_weak(web_get_arg), - &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x58100002, // 0002 LDCONST R4 K2 - 0x7C080400, // 0003 CALL R2 2 - 0x780A0003, // 0004 JMPF R2 #0009 - 0x88080103, // 0005 GETMBR R2 R0 K3 - 0x8C080504, // 0006 GETMET R2 R2 K4 - 0x7C080200, // 0007 CALL R2 1 - 0x70020006, // 0008 JMP #0010 - 0x8C080301, // 0009 GETMET R2 R1 K1 - 0x58100005, // 000A LDCONST R4 K5 - 0x7C080400, // 000B CALL R2 2 - 0x780A0002, // 000C JMPF R2 #0010 - 0x88080103, // 000D GETMBR R2 R0 K3 - 0x8C080506, // 000E GETMET R2 R2 K6 - 0x7C080200, // 000F CALL R2 1 - 0x80000000, // 0010 RET 0 + 0x8C080301, // 000B GETMET R2 R1 K1 + 0x58100005, // 000C LDCONST R4 K5 + 0x84140002, // 000D CLOSURE R5 P2 + 0x88180303, // 000E GETMBR R6 R1 K3 + 0x7C080800, // 000F CALL R2 4 + 0x8C080301, // 0010 GETMET R2 R1 K1 + 0x58100006, // 0011 LDCONST R4 K6 + 0x84140003, // 0012 CLOSURE R5 P3 + 0x88180303, // 0013 GETMBR R6 R1 K3 + 0x7C080800, // 0014 CALL R2 4 + 0xA0000000, // 0015 CLOSE R0 + 0x80000000, // 0016 RET 0 }) ) ); @@ -563,7 +2095,7 @@ be_local_closure(Matter_UI_web_get_arg, /* name */ ********************************************************************/ be_local_closure(Matter_UI_show_passcode_form, /* name */ be_nested_proto( - 9, /* nstack */ + 8, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -571,76 +2103,66 @@ be_local_closure(Matter_UI_show_passcode_form, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[19]) { /* constants */ + ( &(const bvalue[15]) { /* constants */ /* K0 */ be_nested_str_weak(webserver), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(content_send), - /* K3 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3BMatter_X20Passcode_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E), - /* K4 */ be_nested_str_weak(_X3Cform_X20action_X3D_X27_X2Fmatterc_X27_X20method_X3D_X27post_X27_X20onsubmit_X3D_X27return_X20confirm_X28_X22This_X20will_X20cause_X20a_X20restart_X2E_X22_X29_X3B_X27_X3E), - /* K5 */ be_nested_str_weak(_X3Cp_X3EPasscode_X3A_X3C_X2Fp_X3E), - /* K6 */ be_nested_str_weak(format), - /* K7 */ be_nested_str_weak(_X3Cinput_X20type_X3D_X27number_X27_X20min_X3D_X271_X27_X20max_X3D_X2799999998_X27_X20name_X3D_X27passcode_X27_X20value_X3D_X27_X25i_X27_X3E), - /* K8 */ be_nested_str_weak(device), - /* K9 */ be_nested_str_weak(root_passcode), - /* K10 */ be_nested_str_weak(_X3Cp_X3EDistinguish_X20id_X3A_X3C_X2Fp_X3E), - /* K11 */ be_nested_str_weak(_X3Cinput_X20type_X3D_X27number_X27_X20min_X3D_X270_X27_X20max_X3D_X274095_X27_X20name_X3D_X27discriminator_X27_X20value_X3D_X27_X25i_X27_X3E), - /* K12 */ be_nested_str_weak(root_discriminator), + /* K1 */ be_nested_str_weak(content_send), + /* K2 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3BMatter_X20Advanced_X20Configuration_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K3 */ be_nested_str_weak(_X3Cform_X20action_X3D_X27_X2Fmatterc_X27_X20method_X3D_X27post_X27_X20onsubmit_X3D_X27return_X20confirm_X28_X22This_X20will_X20cause_X20a_X20restart_X2E_X22_X29_X3B_X27_X3E_X3Cp_X3EPasscode_X3A_X3C_X2Fp_X3E), + /* K4 */ be_nested_str_weak(_X3Cinput_X20type_X3D_X27number_X27_X20min_X3D_X271_X27_X20max_X3D_X2799999998_X27_X20name_X3D_X27passcode_X27_X20value_X3D_X27_X25i_X27_X3E), + /* K5 */ be_nested_str_weak(device), + /* K6 */ be_nested_str_weak(root_passcode), + /* K7 */ be_nested_str_weak(_X3Cp_X3EDistinguish_X20id_X3A_X3C_X2Fp_X3E), + /* K8 */ be_nested_str_weak(_X3Cinput_X20type_X3D_X27number_X27_X20min_X3D_X270_X27_X20max_X3D_X274095_X27_X20name_X3D_X27discriminator_X27_X20value_X3D_X27_X25i_X27_X3E), + /* K9 */ be_nested_str_weak(root_discriminator), + /* K10 */ be_nested_str_weak(ipv4only), + /* K11 */ be_nested_str_weak(_X20checked), + /* K12 */ be_nested_str_weak(), /* K13 */ be_nested_str_weak(_X3Cp_X3E_X3Cinput_X20type_X3D_X27checkbox_X27_X20name_X3D_X27ipv4_X27_X25s_X3EIPv4_X20only_X3C_X2Fp_X3E), - /* K14 */ be_nested_str_weak(ipv4only), - /* K15 */ be_nested_str_weak(_X20checked), - /* K16 */ be_nested_str_weak(), - /* K17 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3Cbutton_X20name_X3D_X27passcode_X27_X20class_X3D_X27button_X20bgrn_X27_X3EChange_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E), - /* K18 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K14 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3Cbutton_X20name_X3D_X27passcode_X27_X20class_X3D_X27button_X20bgrn_X27_X3EChange_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E), }), be_str_weak(show_passcode_form), &be_const_str_solidified, - ( &(const binstruction[46]) { /* code */ + ( &(const binstruction[40]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0x8C0C0302, // 0002 GETMET R3 R1 K2 - 0x58140003, // 0003 LDCONST R5 K3 - 0x7C0C0400, // 0004 CALL R3 2 - 0x8C0C0302, // 0005 GETMET R3 R1 K2 - 0x58140004, // 0006 LDCONST R5 K4 - 0x7C0C0400, // 0007 CALL R3 2 - 0x8C0C0302, // 0008 GETMET R3 R1 K2 - 0x58140005, // 0009 LDCONST R5 K5 - 0x7C0C0400, // 000A CALL R3 2 - 0x8C0C0302, // 000B GETMET R3 R1 K2 - 0x8C140506, // 000C GETMET R5 R2 K6 - 0x581C0007, // 000D LDCONST R7 K7 - 0x88200108, // 000E GETMBR R8 R0 K8 - 0x88201109, // 000F GETMBR R8 R8 K9 - 0x7C140600, // 0010 CALL R5 3 - 0x7C0C0400, // 0011 CALL R3 2 - 0x8C0C0302, // 0012 GETMET R3 R1 K2 - 0x5814000A, // 0013 LDCONST R5 K10 - 0x7C0C0400, // 0014 CALL R3 2 - 0x8C0C0302, // 0015 GETMET R3 R1 K2 - 0x8C140506, // 0016 GETMET R5 R2 K6 - 0x581C000B, // 0017 LDCONST R7 K11 - 0x88200108, // 0018 GETMBR R8 R0 K8 - 0x8820110C, // 0019 GETMBR R8 R8 K12 - 0x7C140600, // 001A CALL R5 3 - 0x7C0C0400, // 001B CALL R3 2 - 0x8C0C0302, // 001C GETMET R3 R1 K2 - 0x8C140506, // 001D GETMET R5 R2 K6 - 0x581C000D, // 001E LDCONST R7 K13 - 0x88200108, // 001F GETMBR R8 R0 K8 - 0x8820110E, // 0020 GETMBR R8 R8 K14 - 0x78220001, // 0021 JMPF R8 #0024 - 0x5820000F, // 0022 LDCONST R8 K15 - 0x70020000, // 0023 JMP #0025 - 0x58200010, // 0024 LDCONST R8 K16 - 0x7C140600, // 0025 CALL R5 3 + 0x8C080301, // 0001 GETMET R2 R1 K1 + 0x58100002, // 0002 LDCONST R4 K2 + 0x7C080400, // 0003 CALL R2 2 + 0x8C080301, // 0004 GETMET R2 R1 K1 + 0x58100003, // 0005 LDCONST R4 K3 + 0x7C080400, // 0006 CALL R2 2 + 0x8C080301, // 0007 GETMET R2 R1 K1 + 0x60100018, // 0008 GETGBL R4 G24 + 0x58140004, // 0009 LDCONST R5 K4 + 0x88180105, // 000A GETMBR R6 R0 K5 + 0x88180D06, // 000B GETMBR R6 R6 K6 + 0x7C100400, // 000C CALL R4 2 + 0x7C080400, // 000D CALL R2 2 + 0x8C080301, // 000E GETMET R2 R1 K1 + 0x58100007, // 000F LDCONST R4 K7 + 0x7C080400, // 0010 CALL R2 2 + 0x8C080301, // 0011 GETMET R2 R1 K1 + 0x60100018, // 0012 GETGBL R4 G24 + 0x58140008, // 0013 LDCONST R5 K8 + 0x88180105, // 0014 GETMBR R6 R0 K5 + 0x88180D09, // 0015 GETMBR R6 R6 K9 + 0x7C100400, // 0016 CALL R4 2 + 0x7C080400, // 0017 CALL R2 2 + 0x88080105, // 0018 GETMBR R2 R0 K5 + 0x8808050A, // 0019 GETMBR R2 R2 K10 + 0x780A0001, // 001A JMPF R2 #001D + 0x5808000B, // 001B LDCONST R2 K11 + 0x70020000, // 001C JMP #001E + 0x5808000C, // 001D LDCONST R2 K12 + 0x8C0C0301, // 001E GETMET R3 R1 K1 + 0x60140018, // 001F GETGBL R5 G24 + 0x5818000D, // 0020 LDCONST R6 K13 + 0x5C1C0400, // 0021 MOVE R7 R2 + 0x7C140400, // 0022 CALL R5 2 + 0x7C0C0400, // 0023 CALL R3 2 + 0x8C0C0301, // 0024 GETMET R3 R1 K1 + 0x5814000E, // 0025 LDCONST R5 K14 0x7C0C0400, // 0026 CALL R3 2 - 0x8C0C0302, // 0027 GETMET R3 R1 K2 - 0x58140011, // 0028 LDCONST R5 K17 - 0x7C0C0400, // 0029 CALL R3 2 - 0x8C0C0302, // 002A GETMET R3 R1 K2 - 0x58140012, // 002B LDCONST R5 K18 - 0x7C0C0400, // 002C CALL R3 2 - 0x80000000, // 002D RET 0 + 0x80000000, // 0027 RET 0 }) ) ); @@ -652,7 +2174,7 @@ be_local_closure(Matter_UI_show_passcode_form, /* name */ ********************************************************************/ be_local_closure(Matter_UI_page_part_ctl, /* name */ be_nested_proto( - 21, /* nstack */ + 24, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -660,7 +2182,7 @@ be_local_closure(Matter_UI_page_part_ctl, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[71]) { /* constants */ + ( &(const bvalue[100]) { /* constants */ /* K0 */ be_nested_str_weak(webserver), /* K1 */ be_nested_str_weak(check_privileged_access), /* K2 */ be_nested_str_weak(string), @@ -671,71 +2193,100 @@ be_local_closure(Matter_UI_page_part_ctl, /* name */ /* K7 */ be_nested_str_weak(discriminator), /* K8 */ be_nested_str_weak(tasmota), /* K9 */ be_nested_str_weak(log), - /* K10 */ be_nested_str_weak(format), - /* K11 */ be_nested_str_weak(MTR_X3A_X20_X2Fmatterc_X20received_X20_X27_X25s_X27_X20command), - /* K12 */ be_const_int(3), - /* K13 */ be_nested_str_weak(device), - /* K14 */ be_nested_str_weak(root_passcode), - /* K15 */ be_nested_str_weak(arg), - /* K16 */ be_nested_str_weak(root_discriminator), - /* K17 */ be_nested_str_weak(ipv4only), - /* K18 */ be_nested_str_weak(ipv4), - /* K19 */ be_nested_str_weak(on), - /* K20 */ be_nested_str_weak(save_param), - /* K21 */ be_nested_str_weak(redirect), - /* K22 */ be_nested_str_weak(_X2F_X3Frst_X3D), - /* K23 */ be_nested_str_weak(enable), - /* K24 */ be_nested_str_weak(cmd), - /* K25 */ be_nested_str_weak(SetOption), - /* K26 */ be_nested_str_weak(matter), - /* K27 */ be_nested_str_weak(MATTER_OPTION), - /* K28 */ be_nested_str_weak(_X201), - /* K29 */ be_nested_str_weak(disable), - /* K30 */ be_nested_str_weak(_X200), - /* K31 */ be_nested_str_weak(del_fabric), - /* K32 */ be_const_int(0), - /* K33 */ be_nested_str_weak(sessions), - /* K34 */ be_nested_str_weak(fabrics), - /* K35 */ be_nested_str_weak(get_fabric_index), - /* K36 */ be_nested_str_weak(remove_fabric), - /* K37 */ be_const_int(1), - /* K38 */ be_nested_str_weak(_X2Fmatterc_X3F), - /* K39 */ be_nested_str_weak(auto), - /* K40 */ be_nested_str_weak(plugins_persist), - /* K41 */ be_nested_str_weak(config), - /* K42 */ be_nested_str_weak(_X2503i), - /* K43 */ be_nested_str_weak(ep), - /* K44 */ be_nested_str_weak(pi), - /* K45 */ be_nested_str_weak(MTR_X3A_X20ep_X3D_X25i_X20type_X3D_X25s_X20arg_X3D_X25s), - /* K46 */ be_nested_str_weak(), - /* K47 */ be_nested_str_weak(plugins_classes), - /* K48 */ be_nested_str_weak(find), - /* K49 */ be_nested_str_weak(type), - /* K50 */ be_nested_str_weak(ui_string_to_conf), - /* K51 */ be_nested_str_weak(MTR_X3A_X20unknown_X20type_X20_X3D_X20_X25s), - /* K52 */ be_const_int(2), - /* K53 */ be_nested_str_weak(MTR_X3A_X20skipping_X20parameter), - /* K54 */ be_nested_str_weak(MTR_X3A_X20config_X20_X3D_X20_X25s), - /* K55 */ be_nested_str_weak(contains), - /* K56 */ be_nested_str_weak(0), - /* K57 */ be_nested_str_weak(Missing_X20endpoint_X200), - /* K58 */ be_nested_str_weak(MTR_X3A_X20config_X20error_X20_X3D_X20_X25s), - /* K59 */ be_nested_str_weak(plugins_config), - /* K60 */ be_nested_str_weak(content_start), - /* K61 */ be_nested_str_weak(Parameter_X20error), - /* K62 */ be_nested_str_weak(content_send_style), - /* K63 */ be_nested_str_weak(content_send), - /* K64 */ be_nested_str_weak(_X3Cp_X20style_X3D_X27width_X3A340px_X3B_X27_X3E_X3Cb_X3EError_X3A_X3C_X2Fb_X3E_X25s_X3C_X2Fp_X3E), - /* K65 */ be_nested_str_weak(html_escape), - /* K66 */ be_nested_str_weak(content_button), - /* K67 */ be_nested_str_weak(BUTTON_CONFIGURATION), - /* K68 */ be_nested_str_weak(content_stop), - /* K69 */ be_nested_str_weak(BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s), - /* K70 */ be_nested_str_weak(_X3Cp_X20style_X3D_X27width_X3A340px_X3B_X27_X3E_X3Cb_X3EException_X3A_X3C_X2Fb_X3E_X3Cbr_X3E_X27_X25s_X27_X3Cbr_X3E_X25s_X3C_X2Fp_X3E), + /* K10 */ be_nested_str_weak(MTR_X3A_X20_X2Fmatterc_X20received_X20_X27_X25s_X27_X20command), + /* K11 */ be_const_int(3), + /* K12 */ be_nested_str_weak(device), + /* K13 */ be_nested_str_weak(root_passcode), + /* K14 */ be_nested_str_weak(arg), + /* K15 */ be_nested_str_weak(root_discriminator), + /* K16 */ be_nested_str_weak(ipv4only), + /* K17 */ be_nested_str_weak(ipv4), + /* K18 */ be_nested_str_weak(on), + /* K19 */ be_nested_str_weak(save_param), + /* K20 */ be_nested_str_weak(redirect), + /* K21 */ be_nested_str_weak(_X2F_X3Frst_X3D), + /* K22 */ be_nested_str_weak(save), + /* K23 */ be_nested_str_weak(menable), + /* K24 */ be_nested_str_weak(comm), + /* K25 */ be_nested_str_weak(nobridge), + /* K26 */ be_nested_str_weak(disable_bridge_mode), + /* K27 */ be_nested_str_weak(matter_enabled), + /* K28 */ be_nested_str_weak(enable), + /* K29 */ be_nested_str_weak(cmd), + /* K30 */ be_nested_str_weak(SetOption), + /* K31 */ be_nested_str_weak(matter), + /* K32 */ be_nested_str_weak(MATTER_OPTION), + /* K33 */ be_nested_str_weak(_X201), + /* K34 */ be_nested_str_weak(disable), + /* K35 */ be_nested_str_weak(_X200), + /* K36 */ be_nested_str_weak(commissioning_open), + /* K37 */ be_nested_str_weak(start_root_basic_commissioning), + /* K38 */ be_nested_str_weak(stop_basic_commissioning), + /* K39 */ be_nested_str_weak(_X2F), + /* K40 */ be_nested_str_weak(del_fabric), + /* K41 */ be_const_int(0), + /* K42 */ be_nested_str_weak(sessions), + /* K43 */ be_nested_str_weak(fabrics), + /* K44 */ be_nested_str_weak(get_fabric_index), + /* K45 */ be_nested_str_weak(remove_fabric), + /* K46 */ be_const_int(1), + /* K47 */ be_nested_str_weak(_X2Fmatterc_X3F), + /* K48 */ be_nested_str_weak(auto), + /* K49 */ be_nested_str_weak(plugins_persist), + /* K50 */ be_nested_str_weak(config), + /* K51 */ be_nested_str_weak(arg_size), + /* K52 */ be_nested_str_weak(arg_name), + /* K53 */ be_nested_str_weak(find), + /* K54 */ be_const_int(2147483647), + /* K55 */ be_nested_str_weak(plugins_config), + /* K56 */ be_nested_str_weak(plugins_classes), + /* K57 */ be_nested_str_weak(type), + /* K58 */ be_nested_str_weak(), + /* K59 */ be_nested_str_weak(MTR_X3A_X20ep_X3D_X25i_X20arg_X3D_X25s), + /* K60 */ be_nested_str_weak(ui_conf_to_string), + /* K61 */ be_nested_str_weak(MTR_X3A_X20ep_X3D_X25i_X20prev_arg_X3D_X27_X25s_X27_X20arg_X3D_X27_X25s_X27_X20_X25s), + /* K62 */ be_nested_str_weak(changed), + /* K63 */ be_nested_str_weak(ui_string_to_conf), + /* K64 */ be_nested_str_weak(find_plugin_by_endpoint), + /* K65 */ be_nested_str_weak(MTR_X3A_X20apply_X20conf_X20_X27_X25s_X27_X20_X28_X25i_X29_X20to_X20_X25s), + /* K66 */ be_nested_str_weak(parse_configuration), + /* K67 */ be_nested_str_weak(MTR_X3A_X20ep_X3D_X25i_X20not_X20found), + /* K68 */ be_nested_str_weak(nam), + /* K69 */ be_nested_str_weak(name), + /* K70 */ be_nested_str_weak(set_name), + /* K71 */ be_nested_str_weak(remove), + /* K72 */ be_nested_str_weak(MTR_X3A_X20apply_X20name_X20_X27_X25s_X27_X20_X28_X25i_X29_X20to_X20_X25s), + /* K73 */ be_nested_str_weak(stop_iteration), + /* K74 */ be_nested_str_weak(MTR_X3A_X20config_X20_X3D_X20_X25s), + /* K75 */ be_nested_str_weak(MTR_X3A_X20config_X20error_X20_X3D_X20_X25s), + /* K76 */ be_nested_str_weak(addep), + /* K77 */ be_nested_str_weak(pi), + /* K78 */ be_nested_str_weak(MTR_X3A_X20add_X20endpoint_X20typ_X3D_X27_X25s_X27_X20arg_X3D_X27_X25s_X27), + /* K79 */ be_nested_str_weak(bridge_add_endpoint), + /* K80 */ be_nested_str_weak(addrem), + /* K81 */ be_nested_str_weak(url), + /* K82 */ be_nested_str_weak(value_error), + /* K83 */ be_nested_str_weak(url_X20shouldn_X27t_X20be_X20null), + /* K84 */ be_nested_str_weak(equal_map), + /* K85 */ be_nested_str_weak(MTR_X3A_X20remote_X20add_X20url_X3D_X27_X25s_X27_X20type_X3D_X27_X25s_X27_X20arg_X3D_X27_X25s_X27), + /* K86 */ be_nested_str_weak(del), + /* K87 */ be_nested_str_weak(bridge_remove_endpoint), + /* K88 */ be_nested_str_weak(content_start), + /* K89 */ be_nested_str_weak(Parameter_X20error), + /* K90 */ be_nested_str_weak(content_send_style), + /* K91 */ be_nested_str_weak(content_send), + /* K92 */ be_nested_str_weak(_X3Cp_X20style_X3D_X27width_X3A340px_X3B_X27_X3E_X3Cb_X3EError_X3A_X3C_X2Fb_X3E_X25s_X3C_X2Fp_X3E), + /* K93 */ be_nested_str_weak(html_escape), + /* K94 */ be_nested_str_weak(content_button), + /* K95 */ be_nested_str_weak(BUTTON_CONFIGURATION), + /* K96 */ be_nested_str_weak(content_stop), + /* K97 */ be_nested_str_weak(BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K98 */ be_const_int(2), + /* K99 */ be_nested_str_weak(_X3Cp_X20style_X3D_X27width_X3A340px_X3B_X27_X3E_X3Cb_X3EException_X3A_X3C_X2Fb_X3E_X3Cbr_X3E_X27_X25s_X27_X3Cbr_X3E_X25s_X3C_X2Fp_X3E), }), be_str_weak(page_part_ctl), &be_const_str_solidified, - ( &(const binstruction[353]) { /* code */ + ( &(const binstruction[675]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 0x8C080301, // 0001 GETMET R2 R1 K1 0x7C080200, // 0002 CALL R2 1 @@ -746,7 +2297,7 @@ be_local_closure(Matter_UI_page_part_ctl, /* name */ 0xA40E0600, // 0007 IMPORT R3 K3 0xA4120800, // 0008 IMPORT R4 K4 0x4C140000, // 0009 LDNIL R5 - 0xA8020136, // 000A EXBLK 0 #0142 + 0xA8020278, // 000A EXBLK 0 #0284 0x8C180305, // 000B GETMET R6 R1 K5 0x58200006, // 000C LDCONST R8 K6 0x7C180400, // 000D CALL R6 2 @@ -757,380 +2308,660 @@ be_local_closure(Matter_UI_page_part_ctl, /* name */ 0x781A002A, // 0012 JMPF R6 #003E 0xB81A1000, // 0013 GETNGBL R6 K8 0x8C180D09, // 0014 GETMET R6 R6 K9 - 0x8C20050A, // 0015 GETMET R8 R2 K10 - 0x5828000B, // 0016 LDCONST R10 K11 - 0x582C0006, // 0017 LDCONST R11 K6 - 0x7C200600, // 0018 CALL R8 3 - 0x5824000C, // 0019 LDCONST R9 K12 + 0x60200018, // 0015 GETGBL R8 G24 + 0x5824000A, // 0016 LDCONST R9 K10 + 0x58280006, // 0017 LDCONST R10 K6 + 0x7C200400, // 0018 CALL R8 2 + 0x5824000B, // 0019 LDCONST R9 K11 0x7C180600, // 001A CALL R6 3 0x8C180305, // 001B GETMET R6 R1 K5 0x58200006, // 001C LDCONST R8 K6 0x7C180400, // 001D CALL R6 2 0x781A0006, // 001E JMPF R6 #0026 - 0x8818010D, // 001F GETMBR R6 R0 K13 + 0x8818010C, // 001F GETMBR R6 R0 K12 0x601C0009, // 0020 GETGBL R7 G9 - 0x8C20030F, // 0021 GETMET R8 R1 K15 + 0x8C20030E, // 0021 GETMET R8 R1 K14 0x58280006, // 0022 LDCONST R10 K6 0x7C200400, // 0023 CALL R8 2 0x7C1C0200, // 0024 CALL R7 1 - 0x901A1C07, // 0025 SETMBR R6 K14 R7 + 0x901A1A07, // 0025 SETMBR R6 K13 R7 0x8C180305, // 0026 GETMET R6 R1 K5 0x58200007, // 0027 LDCONST R8 K7 0x7C180400, // 0028 CALL R6 2 0x781A0006, // 0029 JMPF R6 #0031 - 0x8818010D, // 002A GETMBR R6 R0 K13 + 0x8818010C, // 002A GETMBR R6 R0 K12 0x601C0009, // 002B GETGBL R7 G9 - 0x8C20030F, // 002C GETMET R8 R1 K15 + 0x8C20030E, // 002C GETMET R8 R1 K14 0x58280007, // 002D LDCONST R10 K7 0x7C200400, // 002E CALL R8 2 0x7C1C0200, // 002F CALL R7 1 - 0x901A2007, // 0030 SETMBR R6 K16 R7 - 0x8818010D, // 0031 GETMBR R6 R0 K13 - 0x8C1C030F, // 0032 GETMET R7 R1 K15 - 0x58240012, // 0033 LDCONST R9 K18 + 0x901A1E07, // 0030 SETMBR R6 K15 R7 + 0x8818010C, // 0031 GETMBR R6 R0 K12 + 0x8C1C030E, // 0032 GETMET R7 R1 K14 + 0x58240011, // 0033 LDCONST R9 K17 0x7C1C0400, // 0034 CALL R7 2 - 0x1C1C0F13, // 0035 EQ R7 R7 K19 - 0x901A2207, // 0036 SETMBR R6 K17 R7 - 0x8818010D, // 0037 GETMBR R6 R0 K13 - 0x8C180D14, // 0038 GETMET R6 R6 K20 + 0x1C1C0F12, // 0035 EQ R7 R7 K18 + 0x901A2007, // 0036 SETMBR R6 K16 R7 + 0x8818010C, // 0037 GETMBR R6 R0 K12 + 0x8C180D13, // 0038 GETMET R6 R6 K19 0x7C180200, // 0039 CALL R6 1 - 0x8C180315, // 003A GETMET R6 R1 K21 - 0x58200016, // 003B LDCONST R8 K22 + 0x8C180314, // 003A GETMET R6 R1 K20 + 0x58200015, // 003B LDCONST R8 K21 0x7C180400, // 003C CALL R6 2 - 0x700200EE, // 003D JMP #012D + 0x70020230, // 003D JMP #026F 0x8C180305, // 003E GETMET R6 R1 K5 - 0x58200017, // 003F LDCONST R8 K23 + 0x58200016, // 003F LDCONST R8 K22 0x7C180400, // 0040 CALL R6 2 - 0x781A0014, // 0041 JMPF R6 #0057 - 0xB81A1000, // 0042 GETNGBL R6 K8 - 0x8C180D09, // 0043 GETMET R6 R6 K9 - 0x8C20050A, // 0044 GETMET R8 R2 K10 - 0x5828000B, // 0045 LDCONST R10 K11 - 0x582C0017, // 0046 LDCONST R11 K23 - 0x7C200600, // 0047 CALL R8 3 - 0x5824000C, // 0048 LDCONST R9 K12 - 0x7C180600, // 0049 CALL R6 3 - 0xB81A1000, // 004A GETNGBL R6 K8 - 0x8C180D18, // 004B GETMET R6 R6 K24 - 0x60200008, // 004C GETGBL R8 G8 - 0xB8263400, // 004D GETNGBL R9 K26 - 0x8824131B, // 004E GETMBR R9 R9 K27 - 0x7C200200, // 004F CALL R8 1 - 0x00223208, // 0050 ADD R8 K25 R8 - 0x0020111C, // 0051 ADD R8 R8 K28 - 0x7C180400, // 0052 CALL R6 2 - 0x8C180315, // 0053 GETMET R6 R1 K21 - 0x58200016, // 0054 LDCONST R8 K22 - 0x7C180400, // 0055 CALL R6 2 - 0x700200D5, // 0056 JMP #012D - 0x8C180305, // 0057 GETMET R6 R1 K5 - 0x5820001D, // 0058 LDCONST R8 K29 - 0x7C180400, // 0059 CALL R6 2 - 0x781A0014, // 005A JMPF R6 #0070 - 0xB81A1000, // 005B GETNGBL R6 K8 - 0x8C180D09, // 005C GETMET R6 R6 K9 - 0x8C20050A, // 005D GETMET R8 R2 K10 - 0x5828000B, // 005E LDCONST R10 K11 - 0x582C001D, // 005F LDCONST R11 K29 - 0x7C200600, // 0060 CALL R8 3 - 0x5824000C, // 0061 LDCONST R9 K12 - 0x7C180600, // 0062 CALL R6 3 - 0xB81A1000, // 0063 GETNGBL R6 K8 - 0x8C180D18, // 0064 GETMET R6 R6 K24 - 0x60200008, // 0065 GETGBL R8 G8 - 0xB8263400, // 0066 GETNGBL R9 K26 - 0x8824131B, // 0067 GETMBR R9 R9 K27 - 0x7C200200, // 0068 CALL R8 1 - 0x00223208, // 0069 ADD R8 K25 R8 - 0x0020111E, // 006A ADD R8 R8 K30 - 0x7C180400, // 006B CALL R6 2 - 0x8C180315, // 006C GETMET R6 R1 K21 - 0x58200016, // 006D LDCONST R8 K22 - 0x7C180400, // 006E CALL R6 2 - 0x700200BC, // 006F JMP #012D - 0x8C180305, // 0070 GETMET R6 R1 K5 - 0x5820001F, // 0071 LDCONST R8 K31 - 0x7C180400, // 0072 CALL R6 2 - 0x781A0026, // 0073 JMPF R6 #009B - 0xB81A1000, // 0074 GETNGBL R6 K8 - 0x8C180D09, // 0075 GETMET R6 R6 K9 - 0x8C20050A, // 0076 GETMET R8 R2 K10 - 0x5828000B, // 0077 LDCONST R10 K11 - 0x582C001F, // 0078 LDCONST R11 K31 - 0x7C200600, // 0079 CALL R8 3 - 0x5824000C, // 007A LDCONST R9 K12 - 0x7C180600, // 007B CALL R6 3 - 0x60180009, // 007C GETGBL R6 G9 - 0x8C1C030F, // 007D GETMET R7 R1 K15 - 0x5824001F, // 007E LDCONST R9 K31 - 0x7C1C0400, // 007F CALL R7 2 - 0x7C180200, // 0080 CALL R6 1 - 0x581C0020, // 0081 LDCONST R7 K32 - 0x8820010D, // 0082 GETMBR R8 R0 K13 - 0x88201121, // 0083 GETMBR R8 R8 K33 - 0x88201122, // 0084 GETMBR R8 R8 K34 - 0x6024000C, // 0085 GETGBL R9 G12 - 0x5C281000, // 0086 MOVE R10 R8 - 0x7C240200, // 0087 CALL R9 1 - 0x14240E09, // 0088 LT R9 R7 R9 - 0x7826000C, // 0089 JMPF R9 #0097 - 0x94241007, // 008A GETIDX R9 R8 R7 - 0x8C241323, // 008B GETMET R9 R9 K35 - 0x7C240200, // 008C CALL R9 1 - 0x1C241206, // 008D EQ R9 R9 R6 - 0x78260005, // 008E JMPF R9 #0095 - 0x8824010D, // 008F GETMBR R9 R0 K13 - 0x8C241324, // 0090 GETMET R9 R9 K36 - 0x942C1007, // 0091 GETIDX R11 R8 R7 - 0x7C240400, // 0092 CALL R9 2 - 0x70020002, // 0093 JMP #0097 - 0x70020000, // 0094 JMP #0096 - 0x001C0F25, // 0095 ADD R7 R7 K37 - 0x7001FFED, // 0096 JMP #0085 - 0x8C240315, // 0097 GETMET R9 R1 K21 - 0x582C0026, // 0098 LDCONST R11 K38 - 0x7C240400, // 0099 CALL R9 2 - 0x70020091, // 009A JMP #012D - 0x8C180305, // 009B GETMET R6 R1 K5 - 0x58200027, // 009C LDCONST R8 K39 - 0x7C180400, // 009D CALL R6 2 - 0x781A0011, // 009E JMPF R6 #00B1 - 0xB81A1000, // 009F GETNGBL R6 K8 - 0x8C180D09, // 00A0 GETMET R6 R6 K9 - 0x8C20050A, // 00A1 GETMET R8 R2 K10 - 0x5828000B, // 00A2 LDCONST R10 K11 - 0x582C0027, // 00A3 LDCONST R11 K39 - 0x7C200600, // 00A4 CALL R8 3 - 0x5824000C, // 00A5 LDCONST R9 K12 - 0x7C180600, // 00A6 CALL R6 3 - 0x8818010D, // 00A7 GETMBR R6 R0 K13 - 0x501C0000, // 00A8 LDBOOL R7 0 0 - 0x901A5007, // 00A9 SETMBR R6 K40 R7 - 0x8818010D, // 00AA GETMBR R6 R0 K13 - 0x8C180D14, // 00AB GETMET R6 R6 K20 - 0x7C180200, // 00AC CALL R6 1 - 0x8C180315, // 00AD GETMET R6 R1 K21 - 0x58200016, // 00AE LDCONST R8 K22 - 0x7C180400, // 00AF CALL R6 2 - 0x7002007B, // 00B0 JMP #012D - 0x8C180305, // 00B1 GETMET R6 R1 K5 - 0x58200029, // 00B2 LDCONST R8 K41 - 0x7C180400, // 00B3 CALL R6 2 - 0x781A0077, // 00B4 JMPF R6 #012D - 0x60180013, // 00B5 GETGBL R6 G19 - 0x7C180000, // 00B6 CALL R6 0 - 0xB81E1000, // 00B7 GETNGBL R7 K8 - 0x8C1C0F09, // 00B8 GETMET R7 R7 K9 - 0x8C24050A, // 00B9 GETMET R9 R2 K10 - 0x582C000B, // 00BA LDCONST R11 K11 - 0x58300029, // 00BB LDCONST R12 K41 - 0x7C240600, // 00BC CALL R9 3 - 0x5828000C, // 00BD LDCONST R10 K12 - 0x7C1C0600, // 00BE CALL R7 3 - 0x581C0020, // 00BF LDCONST R7 K32 - 0x8C20050A, // 00C0 GETMET R8 R2 K10 - 0x5828002A, // 00C1 LDCONST R10 K42 - 0x5C2C0E00, // 00C2 MOVE R11 R7 - 0x7C200600, // 00C3 CALL R8 3 - 0x8C240305, // 00C4 GETMET R9 R1 K5 - 0x002E5608, // 00C5 ADD R11 K43 R8 - 0x7C240400, // 00C6 CALL R9 2 - 0x78260040, // 00C7 JMPF R9 #0109 - 0x8C24030F, // 00C8 GETMET R9 R1 K15 - 0x002E5608, // 00C9 ADD R11 K43 R8 - 0x7C240400, // 00CA CALL R9 2 - 0x60280009, // 00CB GETGBL R10 G9 - 0x5C2C1200, // 00CC MOVE R11 R9 - 0x7C280200, // 00CD CALL R10 1 - 0x8C2C030F, // 00CE GETMET R11 R1 K15 - 0x00365808, // 00CF ADD R13 K44 R8 - 0x7C2C0400, // 00D0 CALL R11 2 - 0x8C30030F, // 00D1 GETMET R12 R1 K15 - 0x003A1E08, // 00D2 ADD R14 K15 R8 - 0x7C300400, // 00D3 CALL R12 2 - 0xB8361000, // 00D4 GETNGBL R13 K8 - 0x8C341B09, // 00D5 GETMET R13 R13 K9 - 0x8C3C050A, // 00D6 GETMET R15 R2 K10 - 0x5844002D, // 00D7 LDCONST R17 K45 - 0x5C481200, // 00D8 MOVE R18 R9 - 0x5C4C1600, // 00D9 MOVE R19 R11 - 0x5C501800, // 00DA MOVE R20 R12 - 0x7C3C0A00, // 00DB CALL R15 5 - 0x5840000C, // 00DC LDCONST R16 K12 - 0x7C340600, // 00DD CALL R13 3 - 0x2034132E, // 00DE NE R13 R9 K46 - 0x7836001C, // 00DF JMPF R13 #00FD - 0x2034172E, // 00E0 NE R13 R11 K46 - 0x7836001A, // 00E1 JMPF R13 #00FD - 0x8834010D, // 00E2 GETMBR R13 R0 K13 - 0x88341B2F, // 00E3 GETMBR R13 R13 K47 - 0x8C341B30, // 00E4 GETMET R13 R13 K48 - 0x5C3C1600, // 00E5 MOVE R15 R11 - 0x7C340400, // 00E6 CALL R13 2 - 0x4C380000, // 00E7 LDNIL R14 - 0x20381A0E, // 00E8 NE R14 R13 R14 - 0x783A0009, // 00E9 JMPF R14 #00F4 - 0x60380013, // 00EA GETGBL R14 G19 - 0x7C380000, // 00EB CALL R14 0 - 0x983A620B, // 00EC SETIDX R14 K49 R11 - 0x8C3C1B32, // 00ED GETMET R15 R13 K50 - 0x5C441A00, // 00EE MOVE R17 R13 - 0x5C481C00, // 00EF MOVE R18 R14 - 0x5C4C1800, // 00F0 MOVE R19 R12 - 0x7C3C0800, // 00F1 CALL R15 4 - 0x9818120E, // 00F2 SETIDX R6 R9 R14 - 0x70020007, // 00F3 JMP #00FC - 0xB83A1000, // 00F4 GETNGBL R14 K8 - 0x8C381D09, // 00F5 GETMET R14 R14 K9 - 0x8C40050A, // 00F6 GETMET R16 R2 K10 - 0x58480033, // 00F7 LDCONST R18 K51 - 0x5C4C1600, // 00F8 MOVE R19 R11 - 0x7C400600, // 00F9 CALL R16 3 - 0x58440034, // 00FA LDCONST R17 K52 - 0x7C380600, // 00FB CALL R14 3 - 0x70020004, // 00FC JMP #0102 - 0xB8361000, // 00FD GETNGBL R13 K8 - 0x8C341B09, // 00FE GETMET R13 R13 K9 - 0x583C0035, // 00FF LDCONST R15 K53 - 0x58400034, // 0100 LDCONST R16 K52 - 0x7C340600, // 0101 CALL R13 3 - 0x001C0F25, // 0102 ADD R7 R7 K37 - 0x8C34050A, // 0103 GETMET R13 R2 K10 - 0x583C002A, // 0104 LDCONST R15 K42 - 0x5C400E00, // 0105 MOVE R16 R7 - 0x7C340600, // 0106 CALL R13 3 - 0x5C201A00, // 0107 MOVE R8 R13 - 0x7001FFBA, // 0108 JMP #00C4 - 0xB8261000, // 0109 GETNGBL R9 K8 - 0x8C241309, // 010A GETMET R9 R9 K9 - 0x8C2C050A, // 010B GETMET R11 R2 K10 - 0x58340036, // 010C LDCONST R13 K54 - 0x60380008, // 010D GETGBL R14 G8 - 0x5C3C0C00, // 010E MOVE R15 R6 - 0x7C380200, // 010F CALL R14 1 - 0x7C2C0600, // 0110 CALL R11 3 - 0x5830000C, // 0111 LDCONST R12 K12 - 0x7C240600, // 0112 CALL R9 3 - 0x8C240D37, // 0113 GETMET R9 R6 K55 - 0x582C0038, // 0114 LDCONST R11 K56 - 0x7C240400, // 0115 CALL R9 2 - 0x74260000, // 0116 JMPT R9 #0118 - 0x58140039, // 0117 LDCONST R5 K57 - 0x78160008, // 0118 JMPF R5 #0122 - 0xB8261000, // 0119 GETNGBL R9 K8 - 0x8C241309, // 011A GETMET R9 R9 K9 - 0x8C2C050A, // 011B GETMET R11 R2 K10 - 0x5834003A, // 011C LDCONST R13 K58 - 0x5C380A00, // 011D MOVE R14 R5 - 0x7C2C0600, // 011E CALL R11 3 - 0x5830000C, // 011F LDCONST R12 K12 - 0x7C240600, // 0120 CALL R9 3 - 0x7002000A, // 0121 JMP #012D - 0x8824010D, // 0122 GETMBR R9 R0 K13 - 0x90267606, // 0123 SETMBR R9 K59 R6 - 0x8824010D, // 0124 GETMBR R9 R0 K13 - 0x50280200, // 0125 LDBOOL R10 1 0 - 0x9026500A, // 0126 SETMBR R9 K40 R10 - 0x8824010D, // 0127 GETMBR R9 R0 K13 - 0x8C241314, // 0128 GETMET R9 R9 K20 - 0x7C240200, // 0129 CALL R9 1 - 0x8C240315, // 012A GETMET R9 R1 K21 - 0x582C0016, // 012B LDCONST R11 K22 - 0x7C240400, // 012C CALL R9 2 - 0x78160011, // 012D JMPF R5 #0140 - 0x8C18033C, // 012E GETMET R6 R1 K60 - 0x5820003D, // 012F LDCONST R8 K61 - 0x7C180400, // 0130 CALL R6 2 - 0x8C18033E, // 0131 GETMET R6 R1 K62 - 0x7C180200, // 0132 CALL R6 1 - 0x8C18033F, // 0133 GETMET R6 R1 K63 - 0x8C20050A, // 0134 GETMET R8 R2 K10 - 0x58280040, // 0135 LDCONST R10 K64 - 0x8C2C0341, // 0136 GETMET R11 R1 K65 - 0x5C340A00, // 0137 MOVE R13 R5 - 0x7C2C0400, // 0138 CALL R11 2 - 0x7C200600, // 0139 CALL R8 3 - 0x7C180400, // 013A CALL R6 2 - 0x8C180342, // 013B GETMET R6 R1 K66 - 0x88200343, // 013C GETMBR R8 R1 K67 - 0x7C180400, // 013D CALL R6 2 - 0x8C180344, // 013E GETMET R6 R1 K68 - 0x7C180200, // 013F CALL R6 1 - 0xA8040001, // 0140 EXBLK 1 1 - 0x7002001D, // 0141 JMP #0160 - 0xAC180002, // 0142 CATCH R6 0 2 - 0x7002001A, // 0143 JMP #015F - 0xB8221000, // 0144 GETNGBL R8 K8 - 0x8C201109, // 0145 GETMET R8 R8 K9 - 0x8C28050A, // 0146 GETMET R10 R2 K10 - 0x58300045, // 0147 LDCONST R12 K69 - 0x5C340C00, // 0148 MOVE R13 R6 - 0x5C380E00, // 0149 MOVE R14 R7 - 0x7C280800, // 014A CALL R10 4 - 0x582C0034, // 014B LDCONST R11 K52 - 0x7C200600, // 014C CALL R8 3 - 0x8C20033C, // 014D GETMET R8 R1 K60 - 0x5828003D, // 014E LDCONST R10 K61 - 0x7C200400, // 014F CALL R8 2 - 0x8C20033E, // 0150 GETMET R8 R1 K62 - 0x7C200200, // 0151 CALL R8 1 - 0x8C20033F, // 0152 GETMET R8 R1 K63 - 0x8C28050A, // 0153 GETMET R10 R2 K10 - 0x58300046, // 0154 LDCONST R12 K70 - 0x5C340C00, // 0155 MOVE R13 R6 - 0x5C380E00, // 0156 MOVE R14 R7 - 0x7C280800, // 0157 CALL R10 4 - 0x7C200400, // 0158 CALL R8 2 - 0x8C200342, // 0159 GETMET R8 R1 K66 - 0x88280343, // 015A GETMBR R10 R1 K67 - 0x7C200400, // 015B CALL R8 2 - 0x8C200344, // 015C GETMET R8 R1 K68 - 0x7C200200, // 015D CALL R8 1 - 0x70020000, // 015E JMP #0160 - 0xB0080000, // 015F RAISE 2 R0 R0 - 0x80000000, // 0160 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: web_add_config_button -********************************************************************/ -be_local_closure(Matter_UI_web_add_config_button, /* name */ - be_nested_proto( - 5, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(webserver), - /* K1 */ be_nested_str_weak(content_send), - /* K2 */ be_nested_str_weak(_X3Cp_X3E_X3Cform_X20id_X3Dac_X20action_X3D_X27matterc_X27_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20method_X3D_X27get_X27_X3E_X3Cbutton_X3E), - /* K3 */ be_nested_str_weak(matter), - /* K4 */ be_nested_str_weak(_LOGO), - /* K5 */ be_nested_str_weak(_X20Configure_X20Matter_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E), - }), - be_str_weak(web_add_config_button), - &be_const_str_solidified, - ( &(const binstruction[12]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x58100002, // 0002 LDCONST R4 K2 - 0x7C080400, // 0003 CALL R2 2 - 0x8C080301, // 0004 GETMET R2 R1 K1 - 0xB8120600, // 0005 GETNGBL R4 K3 - 0x88100904, // 0006 GETMBR R4 R4 K4 - 0x7C080400, // 0007 CALL R2 2 - 0x8C080301, // 0008 GETMET R2 R1 K1 - 0x58100005, // 0009 LDCONST R4 K5 - 0x7C080400, // 000A CALL R2 2 - 0x80000000, // 000B RET 0 + 0x781A0054, // 0041 JMPF R6 #0097 + 0x8C180305, // 0042 GETMET R6 R1 K5 + 0x58200017, // 0043 LDCONST R8 K23 + 0x7C180400, // 0044 CALL R6 2 + 0x8C1C0305, // 0045 GETMET R7 R1 K5 + 0x58240018, // 0046 LDCONST R9 K24 + 0x7C1C0400, // 0047 CALL R7 2 + 0x8C20030E, // 0048 GETMET R8 R1 K14 + 0x58280019, // 0049 LDCONST R10 K25 + 0x7C200400, // 004A CALL R8 2 + 0x1C201112, // 004B EQ R8 R8 K18 + 0x8824010C, // 004C GETMBR R9 R0 K12 + 0x8824131A, // 004D GETMBR R9 R9 K26 + 0x20241208, // 004E NE R9 R9 R8 + 0x78260004, // 004F JMPF R9 #0055 + 0x8824010C, // 0050 GETMBR R9 R0 K12 + 0x90263408, // 0051 SETMBR R9 K26 R8 + 0x8824010C, // 0052 GETMBR R9 R0 K12 + 0x8C241313, // 0053 GETMET R9 R9 K19 + 0x7C240200, // 0054 CALL R9 1 + 0x8C24011B, // 0055 GETMET R9 R0 K27 + 0x7C240200, // 0056 CALL R9 1 + 0x20240C09, // 0057 NE R9 R6 R9 + 0x78260027, // 0058 JMPF R9 #0081 + 0x781A0011, // 0059 JMPF R6 #006C + 0xB8261000, // 005A GETNGBL R9 K8 + 0x8C241309, // 005B GETMET R9 R9 K9 + 0x602C0018, // 005C GETGBL R11 G24 + 0x5830000A, // 005D LDCONST R12 K10 + 0x5834001C, // 005E LDCONST R13 K28 + 0x7C2C0400, // 005F CALL R11 2 + 0x5830000B, // 0060 LDCONST R12 K11 + 0x7C240600, // 0061 CALL R9 3 + 0xB8261000, // 0062 GETNGBL R9 K8 + 0x8C24131D, // 0063 GETMET R9 R9 K29 + 0x602C0008, // 0064 GETGBL R11 G8 + 0xB8323E00, // 0065 GETNGBL R12 K31 + 0x88301920, // 0066 GETMBR R12 R12 K32 + 0x7C2C0200, // 0067 CALL R11 1 + 0x002E3C0B, // 0068 ADD R11 K30 R11 + 0x002C1721, // 0069 ADD R11 R11 K33 + 0x7C240400, // 006A CALL R9 2 + 0x70020010, // 006B JMP #007D + 0xB8261000, // 006C GETNGBL R9 K8 + 0x8C241309, // 006D GETMET R9 R9 K9 + 0x602C0018, // 006E GETGBL R11 G24 + 0x5830000A, // 006F LDCONST R12 K10 + 0x58340022, // 0070 LDCONST R13 K34 + 0x7C2C0400, // 0071 CALL R11 2 + 0x5830000B, // 0072 LDCONST R12 K11 + 0x7C240600, // 0073 CALL R9 3 + 0xB8261000, // 0074 GETNGBL R9 K8 + 0x8C24131D, // 0075 GETMET R9 R9 K29 + 0x602C0008, // 0076 GETGBL R11 G8 + 0xB8323E00, // 0077 GETNGBL R12 K31 + 0x88301920, // 0078 GETMBR R12 R12 K32 + 0x7C2C0200, // 0079 CALL R11 1 + 0x002E3C0B, // 007A ADD R11 K30 R11 + 0x002C1723, // 007B ADD R11 R11 K35 + 0x7C240400, // 007C CALL R9 2 + 0x8C240314, // 007D GETMET R9 R1 K20 + 0x582C0015, // 007E LDCONST R11 K21 + 0x7C240400, // 007F CALL R9 2 + 0x70020014, // 0080 JMP #0096 + 0x8824010C, // 0081 GETMBR R9 R0 K12 + 0x88241324, // 0082 GETMBR R9 R9 K36 + 0x4C280000, // 0083 LDNIL R10 + 0x2024120A, // 0084 NE R9 R9 R10 + 0x20240E09, // 0085 NE R9 R7 R9 + 0x7826000B, // 0086 JMPF R9 #0093 + 0x781E0003, // 0087 JMPF R7 #008C + 0x8824010C, // 0088 GETMBR R9 R0 K12 + 0x8C241325, // 0089 GETMET R9 R9 K37 + 0x7C240200, // 008A CALL R9 1 + 0x70020002, // 008B JMP #008F + 0x8824010C, // 008C GETMBR R9 R0 K12 + 0x8C241326, // 008D GETMET R9 R9 K38 + 0x7C240200, // 008E CALL R9 1 + 0x8C240314, // 008F GETMET R9 R1 K20 + 0x582C0027, // 0090 LDCONST R11 K39 + 0x7C240400, // 0091 CALL R9 2 + 0x70020002, // 0092 JMP #0096 + 0x8C240314, // 0093 GETMET R9 R1 K20 + 0x582C0027, // 0094 LDCONST R11 K39 + 0x7C240400, // 0095 CALL R9 2 + 0x700201D7, // 0096 JMP #026F + 0x8C180305, // 0097 GETMET R6 R1 K5 + 0x58200028, // 0098 LDCONST R8 K40 + 0x7C180400, // 0099 CALL R6 2 + 0x781A0026, // 009A JMPF R6 #00C2 + 0xB81A1000, // 009B GETNGBL R6 K8 + 0x8C180D09, // 009C GETMET R6 R6 K9 + 0x60200018, // 009D GETGBL R8 G24 + 0x5824000A, // 009E LDCONST R9 K10 + 0x58280028, // 009F LDCONST R10 K40 + 0x7C200400, // 00A0 CALL R8 2 + 0x5824000B, // 00A1 LDCONST R9 K11 + 0x7C180600, // 00A2 CALL R6 3 + 0x60180009, // 00A3 GETGBL R6 G9 + 0x8C1C030E, // 00A4 GETMET R7 R1 K14 + 0x58240028, // 00A5 LDCONST R9 K40 + 0x7C1C0400, // 00A6 CALL R7 2 + 0x7C180200, // 00A7 CALL R6 1 + 0x581C0029, // 00A8 LDCONST R7 K41 + 0x8820010C, // 00A9 GETMBR R8 R0 K12 + 0x8820112A, // 00AA GETMBR R8 R8 K42 + 0x8820112B, // 00AB GETMBR R8 R8 K43 + 0x6024000C, // 00AC GETGBL R9 G12 + 0x5C281000, // 00AD MOVE R10 R8 + 0x7C240200, // 00AE CALL R9 1 + 0x14240E09, // 00AF LT R9 R7 R9 + 0x7826000C, // 00B0 JMPF R9 #00BE + 0x94241007, // 00B1 GETIDX R9 R8 R7 + 0x8C24132C, // 00B2 GETMET R9 R9 K44 + 0x7C240200, // 00B3 CALL R9 1 + 0x1C241206, // 00B4 EQ R9 R9 R6 + 0x78260005, // 00B5 JMPF R9 #00BC + 0x8824010C, // 00B6 GETMBR R9 R0 K12 + 0x8C24132D, // 00B7 GETMET R9 R9 K45 + 0x942C1007, // 00B8 GETIDX R11 R8 R7 + 0x7C240400, // 00B9 CALL R9 2 + 0x70020002, // 00BA JMP #00BE + 0x70020000, // 00BB JMP #00BD + 0x001C0F2E, // 00BC ADD R7 R7 K46 + 0x7001FFED, // 00BD JMP #00AC + 0x8C240314, // 00BE GETMET R9 R1 K20 + 0x582C002F, // 00BF LDCONST R11 K47 + 0x7C240400, // 00C0 CALL R9 2 + 0x700201AC, // 00C1 JMP #026F + 0x8C180305, // 00C2 GETMET R6 R1 K5 + 0x58200030, // 00C3 LDCONST R8 K48 + 0x7C180400, // 00C4 CALL R6 2 + 0x781A0011, // 00C5 JMPF R6 #00D8 + 0xB81A1000, // 00C6 GETNGBL R6 K8 + 0x8C180D09, // 00C7 GETMET R6 R6 K9 + 0x60200018, // 00C8 GETGBL R8 G24 + 0x5824000A, // 00C9 LDCONST R9 K10 + 0x58280030, // 00CA LDCONST R10 K48 + 0x7C200400, // 00CB CALL R8 2 + 0x5824000B, // 00CC LDCONST R9 K11 + 0x7C180600, // 00CD CALL R6 3 + 0x8818010C, // 00CE GETMBR R6 R0 K12 + 0x501C0000, // 00CF LDBOOL R7 0 0 + 0x901A6207, // 00D0 SETMBR R6 K49 R7 + 0x8818010C, // 00D1 GETMBR R6 R0 K12 + 0x8C180D13, // 00D2 GETMET R6 R6 K19 + 0x7C180200, // 00D3 CALL R6 1 + 0x8C180314, // 00D4 GETMET R6 R1 K20 + 0x58200015, // 00D5 LDCONST R8 K21 + 0x7C180400, // 00D6 CALL R6 2 + 0x70020196, // 00D7 JMP #026F + 0x8C180305, // 00D8 GETMET R6 R1 K5 + 0x58200032, // 00D9 LDCONST R8 K50 + 0x7C180400, // 00DA CALL R6 2 + 0x781A00D6, // 00DB JMPF R6 #01B3 + 0xB81A1000, // 00DC GETNGBL R6 K8 + 0x8C180D09, // 00DD GETMET R6 R6 K9 + 0x60200018, // 00DE GETGBL R8 G24 + 0x5824000A, // 00DF LDCONST R9 K10 + 0x58280032, // 00E0 LDCONST R10 K50 + 0x7C200400, // 00E1 CALL R8 2 + 0x5824000B, // 00E2 LDCONST R9 K11 + 0x7C180600, // 00E3 CALL R6 3 + 0x50180000, // 00E4 LDBOOL R6 0 0 + 0x601C0010, // 00E5 GETGBL R7 G16 + 0x8C200333, // 00E6 GETMET R8 R1 K51 + 0x7C200200, // 00E7 CALL R8 1 + 0x0420112E, // 00E8 SUB R8 R8 K46 + 0x40225208, // 00E9 CONNECT R8 K41 R8 + 0x7C1C0200, // 00EA CALL R7 1 + 0xA80200A0, // 00EB EXBLK 0 #018D + 0x5C200E00, // 00EC MOVE R8 R7 + 0x7C200000, // 00ED CALL R8 0 + 0x8C240334, // 00EE GETMET R9 R1 K52 + 0x5C2C1000, // 00EF MOVE R11 R8 + 0x7C240400, // 00F0 CALL R9 2 + 0x8C280535, // 00F1 GETMET R10 R2 K53 + 0x5C301200, // 00F2 MOVE R12 R9 + 0x5834000E, // 00F3 LDCONST R13 K14 + 0x7C280600, // 00F4 CALL R10 3 + 0x1C281529, // 00F5 EQ R10 R10 K41 + 0x782A005B, // 00F6 JMPF R10 #0153 + 0x60280009, // 00F7 GETGBL R10 G9 + 0x402E1736, // 00F8 CONNECT R11 K11 K54 + 0x942C120B, // 00F9 GETIDX R11 R9 R11 + 0x7C280200, // 00FA CALL R10 1 + 0x8C2C030E, // 00FB GETMET R11 R1 K14 + 0x5C341000, // 00FC MOVE R13 R8 + 0x7C2C0400, // 00FD CALL R11 2 + 0x8830010C, // 00FE GETMBR R12 R0 K12 + 0x88301937, // 00FF GETMBR R12 R12 K55 + 0x8C301935, // 0100 GETMET R12 R12 K53 + 0x60380008, // 0101 GETGBL R14 G8 + 0x5C3C1400, // 0102 MOVE R15 R10 + 0x7C380200, // 0103 CALL R14 1 + 0x7C300400, // 0104 CALL R12 2 + 0x4C340000, // 0105 LDNIL R13 + 0x2034180D, // 0106 NE R13 R12 R13 + 0x78360041, // 0107 JMPF R13 #014A + 0x8834010C, // 0108 GETMBR R13 R0 K12 + 0x88341B38, // 0109 GETMBR R13 R13 K56 + 0x8C341B35, // 010A GETMET R13 R13 K53 + 0x8C3C1935, // 010B GETMET R15 R12 K53 + 0x58440039, // 010C LDCONST R17 K57 + 0x5848003A, // 010D LDCONST R18 K58 + 0x7C3C0600, // 010E CALL R15 3 + 0x7C340400, // 010F CALL R13 2 + 0x4C380000, // 0110 LDNIL R14 + 0x20381A0E, // 0111 NE R14 R13 R14 + 0x783A0035, // 0112 JMPF R14 #0149 + 0xB83A1000, // 0113 GETNGBL R14 K8 + 0x8C381D09, // 0114 GETMET R14 R14 K9 + 0x60400018, // 0115 GETGBL R16 G24 + 0x5844003B, // 0116 LDCONST R17 K59 + 0x5C481400, // 0117 MOVE R18 R10 + 0x5C4C1600, // 0118 MOVE R19 R11 + 0x7C400600, // 0119 CALL R16 3 + 0x5844000B, // 011A LDCONST R17 K11 + 0x7C380600, // 011B CALL R14 3 + 0x8C381B3C, // 011C GETMET R14 R13 K60 + 0x5C401A00, // 011D MOVE R16 R13 + 0x5C441800, // 011E MOVE R17 R12 + 0x7C380600, // 011F CALL R14 3 + 0x203C1C0B, // 0120 NE R15 R14 R11 + 0xB8421000, // 0121 GETNGBL R16 K8 + 0x8C402109, // 0122 GETMET R16 R16 K9 + 0x60480018, // 0123 GETGBL R18 G24 + 0x584C003D, // 0124 LDCONST R19 K61 + 0x5C501400, // 0125 MOVE R20 R10 + 0x5C541C00, // 0126 MOVE R21 R14 + 0x5C581600, // 0127 MOVE R22 R11 + 0x205C1C0B, // 0128 NE R23 R14 R11 + 0x785E0001, // 0129 JMPF R23 #012C + 0x585C003E, // 012A LDCONST R23 K62 + 0x70020000, // 012B JMP #012D + 0x585C003A, // 012C LDCONST R23 K58 + 0x7C480A00, // 012D CALL R18 5 + 0x584C000B, // 012E LDCONST R19 K11 + 0x7C400600, // 012F CALL R16 3 + 0x783E0017, // 0130 JMPF R15 #0149 + 0x50180200, // 0131 LDBOOL R6 1 0 + 0x8C401B3F, // 0132 GETMET R16 R13 K63 + 0x5C481A00, // 0133 MOVE R18 R13 + 0x5C4C1800, // 0134 MOVE R19 R12 + 0x5C501600, // 0135 MOVE R20 R11 + 0x7C400800, // 0136 CALL R16 4 + 0x8840010C, // 0137 GETMBR R16 R0 K12 + 0x8C402140, // 0138 GETMET R16 R16 K64 + 0x5C481400, // 0139 MOVE R18 R10 + 0x7C400400, // 013A CALL R16 2 + 0x7842000C, // 013B JMPF R16 #0149 + 0xB8461000, // 013C GETNGBL R17 K8 + 0x8C442309, // 013D GETMET R17 R17 K9 + 0x604C0018, // 013E GETGBL R19 G24 + 0x58500041, // 013F LDCONST R20 K65 + 0x5C541800, // 0140 MOVE R21 R12 + 0x5C581400, // 0141 MOVE R22 R10 + 0x5C5C2000, // 0142 MOVE R23 R16 + 0x7C4C0800, // 0143 CALL R19 4 + 0x5850000B, // 0144 LDCONST R20 K11 + 0x7C440600, // 0145 CALL R17 3 + 0x8C442142, // 0146 GETMET R17 R16 K66 + 0x5C4C1800, // 0147 MOVE R19 R12 + 0x7C440400, // 0148 CALL R17 2 + 0x70020007, // 0149 JMP #0152 + 0xB8361000, // 014A GETNGBL R13 K8 + 0x8C341B09, // 014B GETMET R13 R13 K9 + 0x603C0018, // 014C GETGBL R15 G24 + 0x58400043, // 014D LDCONST R16 K67 + 0x5C441400, // 014E MOVE R17 R10 + 0x7C3C0400, // 014F CALL R15 2 + 0x5840000B, // 0150 LDCONST R16 K11 + 0x7C340600, // 0151 CALL R13 3 + 0x70020038, // 0152 JMP #018C + 0x8C280535, // 0153 GETMET R10 R2 K53 + 0x5C301200, // 0154 MOVE R12 R9 + 0x58340044, // 0155 LDCONST R13 K68 + 0x7C280600, // 0156 CALL R10 3 + 0x1C281529, // 0157 EQ R10 R10 K41 + 0x782A0032, // 0158 JMPF R10 #018C + 0x60280009, // 0159 GETGBL R10 G9 + 0x402E1736, // 015A CONNECT R11 K11 K54 + 0x942C120B, // 015B GETIDX R11 R9 R11 + 0x7C280200, // 015C CALL R10 1 + 0x8C2C030E, // 015D GETMET R11 R1 K14 + 0x5C341000, // 015E MOVE R13 R8 + 0x7C2C0400, // 015F CALL R11 2 + 0x8830010C, // 0160 GETMBR R12 R0 K12 + 0x88301937, // 0161 GETMBR R12 R12 K55 + 0x8C301935, // 0162 GETMET R12 R12 K53 + 0x60380008, // 0163 GETGBL R14 G8 + 0x5C3C1400, // 0164 MOVE R15 R10 + 0x7C380200, // 0165 CALL R14 1 + 0x7C300400, // 0166 CALL R12 2 + 0x4C340000, // 0167 LDNIL R13 + 0x2034180D, // 0168 NE R13 R12 R13 + 0x78360021, // 0169 JMPF R13 #018C + 0x8C341935, // 016A GETMET R13 R12 K53 + 0x583C0045, // 016B LDCONST R15 K69 + 0x5840003A, // 016C LDCONST R16 K58 + 0x7C340600, // 016D CALL R13 3 + 0x20381A0B, // 016E NE R14 R13 R11 + 0x783A001B, // 016F JMPF R14 #018C + 0x50180200, // 0170 LDBOOL R6 1 0 + 0x883C010C, // 0171 GETMBR R15 R0 K12 + 0x8C3C1F40, // 0172 GETMET R15 R15 K64 + 0x5C441400, // 0173 MOVE R17 R10 + 0x7C3C0400, // 0174 CALL R15 2 + 0x783E0015, // 0175 JMPF R15 #018C + 0x8C401F46, // 0176 GETMET R16 R15 K70 + 0x5C481600, // 0177 MOVE R18 R11 + 0x7C400400, // 0178 CALL R16 2 + 0x782E0001, // 0179 JMPF R11 #017C + 0x98328A0B, // 017A SETIDX R12 K69 R11 + 0x70020002, // 017B JMP #017F + 0x8C401947, // 017C GETMET R16 R12 K71 + 0x58480045, // 017D LDCONST R18 K69 + 0x7C400400, // 017E CALL R16 2 + 0xB8421000, // 017F GETNGBL R16 K8 + 0x8C402109, // 0180 GETMET R16 R16 K9 + 0x60480018, // 0181 GETGBL R18 G24 + 0x584C0048, // 0182 LDCONST R19 K72 + 0x5C501800, // 0183 MOVE R20 R12 + 0x5C541400, // 0184 MOVE R21 R10 + 0x5C581E00, // 0185 MOVE R22 R15 + 0x7C480800, // 0186 CALL R18 4 + 0x584C000B, // 0187 LDCONST R19 K11 + 0x7C400600, // 0188 CALL R16 3 + 0x8C401F42, // 0189 GETMET R16 R15 K66 + 0x5C481800, // 018A MOVE R18 R12 + 0x7C400400, // 018B CALL R16 2 + 0x7001FF5E, // 018C JMP #00EC + 0x581C0049, // 018D LDCONST R7 K73 + 0xAC1C0200, // 018E CATCH R7 1 0 + 0xB0080000, // 018F RAISE 2 R0 R0 + 0xB81E1000, // 0190 GETNGBL R7 K8 + 0x8C1C0F09, // 0191 GETMET R7 R7 K9 + 0x60240018, // 0192 GETGBL R9 G24 + 0x5828004A, // 0193 LDCONST R10 K74 + 0x602C0008, // 0194 GETGBL R11 G8 + 0x8830010C, // 0195 GETMBR R12 R0 K12 + 0x88301937, // 0196 GETMBR R12 R12 K55 + 0x7C2C0200, // 0197 CALL R11 1 + 0x7C240400, // 0198 CALL R9 2 + 0x5828000B, // 0199 LDCONST R10 K11 + 0x7C1C0600, // 019A CALL R7 3 + 0x78160008, // 019B JMPF R5 #01A5 + 0xB81E1000, // 019C GETNGBL R7 K8 + 0x8C1C0F09, // 019D GETMET R7 R7 K9 + 0x60240018, // 019E GETGBL R9 G24 + 0x5828004B, // 019F LDCONST R10 K75 + 0x5C2C0A00, // 01A0 MOVE R11 R5 + 0x7C240400, // 01A1 CALL R9 2 + 0x5828000B, // 01A2 LDCONST R10 K11 + 0x7C1C0600, // 01A3 CALL R7 3 + 0x7002000C, // 01A4 JMP #01B2 + 0x741A0002, // 01A5 JMPT R6 #01A9 + 0x881C010C, // 01A6 GETMBR R7 R0 K12 + 0x881C0F31, // 01A7 GETMBR R7 R7 K49 + 0x741E0005, // 01A8 JMPT R7 #01AF + 0x881C010C, // 01A9 GETMBR R7 R0 K12 + 0x50200200, // 01AA LDBOOL R8 1 0 + 0x901E6208, // 01AB SETMBR R7 K49 R8 + 0x881C010C, // 01AC GETMBR R7 R0 K12 + 0x8C1C0F13, // 01AD GETMET R7 R7 K19 + 0x7C1C0200, // 01AE CALL R7 1 + 0x8C1C0314, // 01AF GETMET R7 R1 K20 + 0x5824002F, // 01B0 LDCONST R9 K47 + 0x7C1C0400, // 01B1 CALL R7 2 + 0x700200BB, // 01B2 JMP #026F + 0x8C180305, // 01B3 GETMET R6 R1 K5 + 0x5820004C, // 01B4 LDCONST R8 K76 + 0x7C180400, // 01B5 CALL R6 2 + 0x781A002B, // 01B6 JMPF R6 #01E3 + 0x8C18030E, // 01B7 GETMET R6 R1 K14 + 0x5820004D, // 01B8 LDCONST R8 K77 + 0x7C180400, // 01B9 CALL R6 2 + 0x8C1C030E, // 01BA GETMET R7 R1 K14 + 0x5824000E, // 01BB LDCONST R9 K14 + 0x7C1C0400, // 01BC CALL R7 2 + 0x8C20030E, // 01BD GETMET R8 R1 K14 + 0x58280044, // 01BE LDCONST R10 K68 + 0x7C200400, // 01BF CALL R8 2 + 0xB8261000, // 01C0 GETNGBL R9 K8 + 0x8C241309, // 01C1 GETMET R9 R9 K9 + 0x602C0018, // 01C2 GETGBL R11 G24 + 0x5830004E, // 01C3 LDCONST R12 K78 + 0x5C340C00, // 01C4 MOVE R13 R6 + 0x5C380E00, // 01C5 MOVE R14 R7 + 0x7C2C0600, // 01C6 CALL R11 3 + 0x5830000B, // 01C7 LDCONST R12 K11 + 0x7C240600, // 01C8 CALL R9 3 + 0x8824010C, // 01C9 GETMBR R9 R0 K12 + 0x88241338, // 01CA GETMBR R9 R9 K56 + 0x8C241335, // 01CB GETMET R9 R9 K53 + 0x5C2C0C00, // 01CC MOVE R11 R6 + 0x7C240400, // 01CD CALL R9 2 + 0x4C280000, // 01CE LDNIL R10 + 0x2028120A, // 01CF NE R10 R9 R10 + 0x782A000D, // 01D0 JMPF R10 #01DF + 0x60280013, // 01D1 GETGBL R10 G19 + 0x7C280000, // 01D2 CALL R10 0 + 0x78220000, // 01D3 JMPF R8 #01D5 + 0x982A8A08, // 01D4 SETIDX R10 K69 R8 + 0x8C2C133F, // 01D5 GETMET R11 R9 K63 + 0x5C341200, // 01D6 MOVE R13 R9 + 0x5C381400, // 01D7 MOVE R14 R10 + 0x5C3C0E00, // 01D8 MOVE R15 R7 + 0x7C2C0800, // 01D9 CALL R11 4 + 0x882C010C, // 01DA GETMBR R11 R0 K12 + 0x8C2C174F, // 01DB GETMET R11 R11 K79 + 0x5C340C00, // 01DC MOVE R13 R6 + 0x5C381400, // 01DD MOVE R14 R10 + 0x7C2C0600, // 01DE CALL R11 3 + 0x8C280314, // 01DF GETMET R10 R1 K20 + 0x5830002F, // 01E0 LDCONST R12 K47 + 0x7C280400, // 01E1 CALL R10 2 + 0x7002008B, // 01E2 JMP #026F + 0x8C180305, // 01E3 GETMET R6 R1 K5 + 0x58200050, // 01E4 LDCONST R8 K80 + 0x7C180400, // 01E5 CALL R6 2 + 0x781A005E, // 01E6 JMPF R6 #0246 + 0x8C18030E, // 01E7 GETMET R6 R1 K14 + 0x58200051, // 01E8 LDCONST R8 K81 + 0x7C180400, // 01E9 CALL R6 2 + 0x4C1C0000, // 01EA LDNIL R7 + 0x1C1C0C07, // 01EB EQ R7 R6 R7 + 0x741E0001, // 01EC JMPT R7 #01EF + 0x1C1C0D3A, // 01ED EQ R7 R6 K58 + 0x781E0000, // 01EE JMPF R7 #01F0 + 0xB006A553, // 01EF RAISE 1 K82 K83 + 0x581C0029, // 01F0 LDCONST R7 K41 + 0x60200008, // 01F1 GETGBL R8 G8 + 0x5C240E00, // 01F2 MOVE R9 R7 + 0x7C200200, // 01F3 CALL R8 1 + 0x8C240305, // 01F4 GETMET R9 R1 K5 + 0x002E9A08, // 01F5 ADD R11 K77 R8 + 0x7C240400, // 01F6 CALL R9 2 + 0x78260049, // 01F7 JMPF R9 #0242 + 0x8C24030E, // 01F8 GETMET R9 R1 K14 + 0x002E9A08, // 01F9 ADD R11 K77 R8 + 0x7C240400, // 01FA CALL R9 2 + 0x8C28030E, // 01FB GETMET R10 R1 K14 + 0x00321C08, // 01FC ADD R12 K14 R8 + 0x7C280400, // 01FD CALL R10 2 + 0x8C2C030E, // 01FE GETMET R11 R1 K14 + 0x00368808, // 01FF ADD R13 K68 R8 + 0x7C2C0400, // 0200 CALL R11 2 + 0x2030133A, // 0201 NE R12 R9 K58 + 0x78320038, // 0202 JMPF R12 #023C + 0x8830010C, // 0203 GETMBR R12 R0 K12 + 0x88301938, // 0204 GETMBR R12 R12 K56 + 0x8C301935, // 0205 GETMET R12 R12 K53 + 0x5C381200, // 0206 MOVE R14 R9 + 0x7C300400, // 0207 CALL R12 2 + 0x4C340000, // 0208 LDNIL R13 + 0x2034180D, // 0209 NE R13 R12 R13 + 0x78360030, // 020A JMPF R13 #023C + 0x60340013, // 020B GETGBL R13 G19 + 0x7C340000, // 020C CALL R13 0 + 0x9836A206, // 020D SETIDX R13 K81 R6 + 0x98367209, // 020E SETIDX R13 K57 R9 + 0x782E0000, // 020F JMPF R11 #0211 + 0x98368A0B, // 0210 SETIDX R13 K69 R11 + 0x8C38193F, // 0211 GETMET R14 R12 K63 + 0x5C401800, // 0212 MOVE R16 R12 + 0x5C441A00, // 0213 MOVE R17 R13 + 0x5C481400, // 0214 MOVE R18 R10 + 0x7C380800, // 0215 CALL R14 4 + 0x50380000, // 0216 LDBOOL R14 0 0 + 0x603C0010, // 0217 GETGBL R15 G16 + 0x8840010C, // 0218 GETMBR R16 R0 K12 + 0x88402137, // 0219 GETMBR R16 R16 K55 + 0x7C3C0200, // 021A CALL R15 1 + 0xA802000B, // 021B EXBLK 0 #0228 + 0x5C401E00, // 021C MOVE R16 R15 + 0x7C400000, // 021D CALL R16 0 + 0x8C440154, // 021E GETMET R17 R0 K84 + 0x5C4C2000, // 021F MOVE R19 R16 + 0x5C501A00, // 0220 MOVE R20 R13 + 0x7C440600, // 0221 CALL R17 3 + 0x78460001, // 0222 JMPF R17 #0225 + 0x50380200, // 0223 LDBOOL R14 1 0 + 0x70020000, // 0224 JMP #0226 + 0x7001FFF5, // 0225 JMP #021C + 0xA8040001, // 0226 EXBLK 1 1 + 0x70020002, // 0227 JMP #022B + 0x583C0049, // 0228 LDCONST R15 K73 + 0xAC3C0200, // 0229 CATCH R15 1 0 + 0xB0080000, // 022A RAISE 2 R0 R0 + 0x5C3C1C00, // 022B MOVE R15 R14 + 0x743E000E, // 022C JMPT R15 #023C + 0xB83E1000, // 022D GETNGBL R15 K8 + 0x8C3C1F09, // 022E GETMET R15 R15 K9 + 0x60440018, // 022F GETGBL R17 G24 + 0x58480055, // 0230 LDCONST R18 K85 + 0x5C4C0C00, // 0231 MOVE R19 R6 + 0x5C501200, // 0232 MOVE R20 R9 + 0x5C541400, // 0233 MOVE R21 R10 + 0x7C440800, // 0234 CALL R17 4 + 0x5848000B, // 0235 LDCONST R18 K11 + 0x7C3C0600, // 0236 CALL R15 3 + 0x883C010C, // 0237 GETMBR R15 R0 K12 + 0x8C3C1F4F, // 0238 GETMET R15 R15 K79 + 0x5C441200, // 0239 MOVE R17 R9 + 0x5C481A00, // 023A MOVE R18 R13 + 0x7C3C0600, // 023B CALL R15 3 + 0x001C0F2E, // 023C ADD R7 R7 K46 + 0x60300008, // 023D GETGBL R12 G8 + 0x5C340E00, // 023E MOVE R13 R7 + 0x7C300200, // 023F CALL R12 1 + 0x5C201800, // 0240 MOVE R8 R12 + 0x7001FFB1, // 0241 JMP #01F4 + 0x8C240314, // 0242 GETMET R9 R1 K20 + 0x582C002F, // 0243 LDCONST R11 K47 + 0x7C240400, // 0244 CALL R9 2 + 0x70020028, // 0245 JMP #026F + 0x4C180000, // 0246 LDNIL R6 + 0x601C0010, // 0247 GETGBL R7 G16 + 0x8C200333, // 0248 GETMET R8 R1 K51 + 0x7C200200, // 0249 CALL R8 1 + 0x0420112E, // 024A SUB R8 R8 K46 + 0x40225208, // 024B CONNECT R8 K41 R8 + 0x7C1C0200, // 024C CALL R7 1 + 0xA8020013, // 024D EXBLK 0 #0262 + 0x5C200E00, // 024E MOVE R8 R7 + 0x7C200000, // 024F CALL R8 0 + 0x8C240334, // 0250 GETMET R9 R1 K52 + 0x5C2C1000, // 0251 MOVE R11 R8 + 0x7C240400, // 0252 CALL R9 2 + 0x8C280535, // 0253 GETMET R10 R2 K53 + 0x5C301200, // 0254 MOVE R12 R9 + 0x58340056, // 0255 LDCONST R13 K86 + 0x7C280600, // 0256 CALL R10 3 + 0x1C281529, // 0257 EQ R10 R10 K41 + 0x782A0005, // 0258 JMPF R10 #025F + 0x60280009, // 0259 GETGBL R10 G9 + 0x402E1736, // 025A CONNECT R11 K11 K54 + 0x942C120B, // 025B GETIDX R11 R9 R11 + 0x7C280200, // 025C CALL R10 1 + 0x5C181400, // 025D MOVE R6 R10 + 0x70020000, // 025E JMP #0260 + 0x7001FFED, // 025F JMP #024E + 0xA8040001, // 0260 EXBLK 1 1 + 0x70020002, // 0261 JMP #0265 + 0x581C0049, // 0262 LDCONST R7 K73 + 0xAC1C0200, // 0263 CATCH R7 1 0 + 0xB0080000, // 0264 RAISE 2 R0 R0 + 0x4C1C0000, // 0265 LDNIL R7 + 0x201C0C07, // 0266 NE R7 R6 R7 + 0x781E0006, // 0267 JMPF R7 #026F + 0x881C010C, // 0268 GETMBR R7 R0 K12 + 0x8C1C0F57, // 0269 GETMET R7 R7 K87 + 0x5C240C00, // 026A MOVE R9 R6 + 0x7C1C0400, // 026B CALL R7 2 + 0x8C1C0314, // 026C GETMET R7 R1 K20 + 0x5824002F, // 026D LDCONST R9 K47 + 0x7C1C0400, // 026E CALL R7 2 + 0x78160011, // 026F JMPF R5 #0282 + 0x8C180358, // 0270 GETMET R6 R1 K88 + 0x58200059, // 0271 LDCONST R8 K89 + 0x7C180400, // 0272 CALL R6 2 + 0x8C18035A, // 0273 GETMET R6 R1 K90 + 0x7C180200, // 0274 CALL R6 1 + 0x8C18035B, // 0275 GETMET R6 R1 K91 + 0x60200018, // 0276 GETGBL R8 G24 + 0x5824005C, // 0277 LDCONST R9 K92 + 0x8C28035D, // 0278 GETMET R10 R1 K93 + 0x5C300A00, // 0279 MOVE R12 R5 + 0x7C280400, // 027A CALL R10 2 + 0x7C200400, // 027B CALL R8 2 + 0x7C180400, // 027C CALL R6 2 + 0x8C18035E, // 027D GETMET R6 R1 K94 + 0x8820035F, // 027E GETMBR R8 R1 K95 + 0x7C180400, // 027F CALL R6 2 + 0x8C180360, // 0280 GETMET R6 R1 K96 + 0x7C180200, // 0281 CALL R6 1 + 0xA8040001, // 0282 EXBLK 1 1 + 0x7002001D, // 0283 JMP #02A2 + 0xAC180002, // 0284 CATCH R6 0 2 + 0x7002001A, // 0285 JMP #02A1 + 0xB8221000, // 0286 GETNGBL R8 K8 + 0x8C201109, // 0287 GETMET R8 R8 K9 + 0x60280018, // 0288 GETGBL R10 G24 + 0x582C0061, // 0289 LDCONST R11 K97 + 0x5C300C00, // 028A MOVE R12 R6 + 0x5C340E00, // 028B MOVE R13 R7 + 0x7C280600, // 028C CALL R10 3 + 0x582C0062, // 028D LDCONST R11 K98 + 0x7C200600, // 028E CALL R8 3 + 0x8C200358, // 028F GETMET R8 R1 K88 + 0x58280059, // 0290 LDCONST R10 K89 + 0x7C200400, // 0291 CALL R8 2 + 0x8C20035A, // 0292 GETMET R8 R1 K90 + 0x7C200200, // 0293 CALL R8 1 + 0x8C20035B, // 0294 GETMET R8 R1 K91 + 0x60280018, // 0295 GETGBL R10 G24 + 0x582C0063, // 0296 LDCONST R11 K99 + 0x5C300C00, // 0297 MOVE R12 R6 + 0x5C340E00, // 0298 MOVE R13 R7 + 0x7C280600, // 0299 CALL R10 3 + 0x7C200400, // 029A CALL R8 2 + 0x8C20035E, // 029B GETMET R8 R1 K94 + 0x8828035F, // 029C GETMBR R10 R1 K95 + 0x7C200400, // 029D CALL R8 2 + 0x8C200360, // 029E GETMET R8 R1 K96 + 0x7C200200, // 029F CALL R8 1 + 0x70020000, // 02A0 JMP #02A2 + 0xB0080000, // 02A1 RAISE 2 R0 R0 + 0x80000000, // 02A2 RET 0 }) ) ); @@ -1303,330 +3134,96 @@ be_local_closure(Matter_UI_show_qrcode, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: plugin_option -********************************************************************/ -be_local_closure(Matter_UI_plugin_option, /* name */ - be_nested_proto( - 17, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[16]) { /* constants */ - /* K0 */ be_nested_str_weak(webserver), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(split), - /* K3 */ be_nested_str_weak(_X7C), - /* K4 */ be_const_int(0), - /* K5 */ be_nested_str_weak(), - /* K6 */ be_nested_str_weak(content_send), - /* K7 */ be_nested_str_weak(_X3Coption_X20value_X3D_X27_X27_X3E_X3C_X2Foption_X3E), - /* K8 */ be_nested_str_weak(_X2Dhttp), - /* K9 */ be_nested_str_weak(_X3Coption_X20value_X3D_X27_X27_X20disabled_X3E_X2D_X2D_X2D_X20Tasmota_X20Remote_X20_X2D_X2D_X2D_X3C_X2Foption_X3E), - /* K10 */ be_nested_str_weak(device), - /* K11 */ be_nested_str_weak(get_plugin_class_displayname), - /* K12 */ be_nested_str_weak(format), - /* K13 */ be_nested_str_weak(_X3Coption_X20value_X3D_X27_X25s_X27_X25s_X3E_X25s_X3C_X2Foption_X3E), - /* K14 */ be_nested_str_weak(_X20selected), - /* K15 */ be_const_int(1), - }), - be_str_weak(plugin_option), - &be_const_str_solidified, - ( &(const binstruction[48]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xA4120200, // 0001 IMPORT R4 K1 - 0x780A0004, // 0002 JMPF R2 #0008 - 0x8C140902, // 0003 GETMET R5 R4 K2 - 0x5C1C0400, // 0004 MOVE R7 R2 - 0x58200003, // 0005 LDCONST R8 K3 - 0x7C140600, // 0006 CALL R5 3 - 0x70020001, // 0007 JMP #000A - 0x60140012, // 0008 GETGBL R5 G18 - 0x7C140000, // 0009 CALL R5 0 - 0x58180004, // 000A LDCONST R6 K4 - 0x601C000C, // 000B GETGBL R7 G12 - 0x5C200A00, // 000C MOVE R8 R5 - 0x7C1C0200, // 000D CALL R7 1 - 0x141C0C07, // 000E LT R7 R6 R7 - 0x781E001E, // 000F JMPF R7 #002F - 0x941C0A06, // 0010 GETIDX R7 R5 R6 - 0x1C200F05, // 0011 EQ R8 R7 K5 - 0x78220003, // 0012 JMPF R8 #0017 - 0x8C200706, // 0013 GETMET R8 R3 K6 - 0x58280007, // 0014 LDCONST R10 K7 - 0x7C200400, // 0015 CALL R8 2 - 0x70020015, // 0016 JMP #002D - 0x1C200F08, // 0017 EQ R8 R7 K8 - 0x78220003, // 0018 JMPF R8 #001D - 0x8C200706, // 0019 GETMET R8 R3 K6 - 0x58280009, // 001A LDCONST R10 K9 - 0x7C200400, // 001B CALL R8 2 - 0x7002000F, // 001C JMP #002D - 0x8820010A, // 001D GETMBR R8 R0 K10 - 0x8C20110B, // 001E GETMET R8 R8 K11 - 0x5C280E00, // 001F MOVE R10 R7 - 0x7C200400, // 0020 CALL R8 2 - 0x8C240706, // 0021 GETMET R9 R3 K6 - 0x8C2C090C, // 0022 GETMET R11 R4 K12 - 0x5834000D, // 0023 LDCONST R13 K13 - 0x5C380E00, // 0024 MOVE R14 R7 - 0x1C3C0E01, // 0025 EQ R15 R7 R1 - 0x783E0001, // 0026 JMPF R15 #0029 - 0x583C000E, // 0027 LDCONST R15 K14 - 0x70020000, // 0028 JMP #002A - 0x583C0005, // 0029 LDCONST R15 K5 - 0x5C401000, // 002A MOVE R16 R8 - 0x7C2C0A00, // 002B CALL R11 5 - 0x7C240400, // 002C CALL R9 2 - 0x00180D0F, // 002D ADD R6 R6 K15 - 0x7001FFDB, // 002E JMP #000B - 0x80000000, // 002F RET 0 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: show_enable ********************************************************************/ be_local_closure(Matter_UI_show_enable, /* name */ be_nested_proto( 11, /* nstack */ - 2, /* argc */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[20]) { /* constants */ + ( &(const bvalue[16]) { /* constants */ /* K0 */ be_nested_str_weak(webserver), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(get_option), - /* K4 */ be_nested_str_weak(matter), - /* K5 */ be_nested_str_weak(MATTER_OPTION), - /* K6 */ be_nested_str_weak(content_send), - /* K7 */ be_nested_str_weak(format), - /* K8 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3BMatter_X20_X25s_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E), - /* K9 */ be_nested_str_weak(Enabled), - /* K10 */ be_nested_str_weak(Disabled), - /* K11 */ be_nested_str_weak(_X3Cp_X20style_X3D_X27width_X3A320px_X3B_X27_X3ECheck_X20the_X20_X3Ca_X20href_X3D_X27https_X3A_X2F_X2Ftasmota_X2Egithub_X2Eio_X2Fdocs_X2FMatter_X2F_X27_X20target_X3D_X27_blank_X27_X3EMatter_X20documentation_X3C_X2Fa_X3E_X2E_X3C_X2Fp_X3E), - /* K12 */ be_nested_str_weak(_X3Cform_X20action_X3D_X27_X2Fmatterc_X27_X20method_X3D_X27post_X27_X20onsubmit_X3D_X27return_X20confirm_X28_X22This_X20will_X20cause_X20a_X20restart_X2E_X22_X29_X3B_X27_X3E), - /* K13 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3Cbutton_X20name_X3D_X27_X25s_X27_X20class_X3D_X27button_X20bgrn_X27_X3E), - /* K14 */ be_nested_str_weak(disable), - /* K15 */ be_nested_str_weak(enable), - /* K16 */ be_nested_str_weak(Disable), - /* K17 */ be_nested_str_weak(Enable), - /* K18 */ be_nested_str_weak(_X20Matter_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E), - /* K19 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K1 */ be_nested_str_weak(matter_enabled), + /* K2 */ be_nested_str_weak(content_send), + /* K3 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3BMatter_X20_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X20style_X3D_X27width_X3A320px_X3B_X27_X3ECheck_X20the_X20_X3Ca_X20href_X3D_X27https_X3A_X2F_X2Ftasmota_X2Egithub_X2Eio_X2Fdocs_X2FMatter_X2F_X27_X20target_X3D_X27_blank_X27_X3EMatter_X20documentation_X3C_X2Fa_X3E_X2E_X3C_X2Fp_X3E_X3Cform_X20action_X3D_X27_X2Fmatterc_X27_X20method_X3D_X27post_X27_X3E), + /* K4 */ be_nested_str_weak(checked), + /* K5 */ be_nested_str_weak(), + /* K6 */ be_nested_str_weak(_X3Cp_X3E_X3Cinput_X20id_X3D_X27menable_X27_X20type_X3D_X27checkbox_X27_X20name_X3D_X27menable_X27_X20_X25s_X3E), + /* K7 */ be_nested_str_weak(_X3Clabel_X20for_X3D_X27menable_X27_X3E_X3Cb_X3EMatter_X20enable_X3C_X2Fb_X3E_X3C_X2Flabel_X3E_X3C_X2Fp_X3E), + /* K8 */ be_nested_str_weak(device), + /* K9 */ be_nested_str_weak(commissioning_open), + /* K10 */ be_nested_str_weak(_X3Cp_X3E_X3Cinput_X20id_X3D_X27comm_X27_X20type_X3D_X27checkbox_X27_X20name_X3D_X27comm_X27_X20_X25s_X3E), + /* K11 */ be_nested_str_weak(_X3Clabel_X20for_X3D_X27comm_X27_X3E_X3Cb_X3ECommissioning_X20open_X3C_X2Fb_X3E_X3C_X2Flabel_X3E_X3C_X2Fp_X3E), + /* K12 */ be_nested_str_weak(disable_bridge_mode), + /* K13 */ be_nested_str_weak(_X20checked), + /* K14 */ be_nested_str_weak(_X3Cp_X3E_X3Cinput_X20type_X3D_X27checkbox_X27_X20name_X3D_X27nobridge_X27_X25s_X3E_X3Cb_X3EForce_X20Static_X20endpoints_X3C_X2Fb_X3E_X20_X28non_X2Dbridge_X29_X3C_X2Fp_X3E), + /* K15 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3Cbutton_X20name_X3D_X27save_X27_X20class_X3D_X27button_X20bgrn_X27_X3ESave_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E), }), be_str_weak(show_enable), &be_const_str_solidified, - ( &(const binstruction[44]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0xA40E0200, // 0001 IMPORT R3 K1 - 0xB8120400, // 0002 GETNGBL R4 K2 - 0x8C100903, // 0003 GETMET R4 R4 K3 - 0xB81A0800, // 0004 GETNGBL R6 K4 - 0x88180D05, // 0005 GETMBR R6 R6 K5 - 0x7C100400, // 0006 CALL R4 2 - 0x8C140506, // 0007 GETMET R5 R2 K6 - 0x8C1C0707, // 0008 GETMET R7 R3 K7 - 0x58240008, // 0009 LDCONST R9 K8 - 0x78120001, // 000A JMPF R4 #000D - 0x58280009, // 000B LDCONST R10 K9 - 0x70020000, // 000C JMP #000E - 0x5828000A, // 000D LDCONST R10 K10 - 0x7C1C0600, // 000E CALL R7 3 - 0x7C140400, // 000F CALL R5 2 - 0x8C140506, // 0010 GETMET R5 R2 K6 - 0x581C000B, // 0011 LDCONST R7 K11 - 0x7C140400, // 0012 CALL R5 2 - 0x8C140506, // 0013 GETMET R5 R2 K6 - 0x581C000C, // 0014 LDCONST R7 K12 - 0x7C140400, // 0015 CALL R5 2 - 0x8C140506, // 0016 GETMET R5 R2 K6 - 0x8C1C0707, // 0017 GETMET R7 R3 K7 - 0x5824000D, // 0018 LDCONST R9 K13 - 0x78120001, // 0019 JMPF R4 #001C - 0x5828000E, // 001A LDCONST R10 K14 - 0x70020000, // 001B JMP #001D - 0x5828000F, // 001C LDCONST R10 K15 - 0x7C1C0600, // 001D CALL R7 3 - 0x7C140400, // 001E CALL R5 2 - 0x8C140506, // 001F GETMET R5 R2 K6 - 0x78120001, // 0020 JMPF R4 #0023 - 0x581C0010, // 0021 LDCONST R7 K16 - 0x70020000, // 0022 JMP #0024 - 0x581C0011, // 0023 LDCONST R7 K17 + ( &(const binstruction[56]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x88080101, // 0001 GETMBR R2 R0 K1 + 0x8C0C0302, // 0002 GETMET R3 R1 K2 + 0x58140003, // 0003 LDCONST R5 K3 + 0x7C0C0400, // 0004 CALL R3 2 + 0x8C0C0101, // 0005 GETMET R3 R0 K1 + 0x7C0C0200, // 0006 CALL R3 1 + 0x780E0001, // 0007 JMPF R3 #000A + 0x580C0004, // 0008 LDCONST R3 K4 + 0x70020000, // 0009 JMP #000B + 0x580C0005, // 000A LDCONST R3 K5 + 0x8C100302, // 000B GETMET R4 R1 K2 + 0x60180018, // 000C GETGBL R6 G24 + 0x581C0006, // 000D LDCONST R7 K6 + 0x5C200600, // 000E MOVE R8 R3 + 0x7C180400, // 000F CALL R6 2 + 0x7C100400, // 0010 CALL R4 2 + 0x8C100302, // 0011 GETMET R4 R1 K2 + 0x58180007, // 0012 LDCONST R6 K7 + 0x7C100400, // 0013 CALL R4 2 + 0x8C100101, // 0014 GETMET R4 R0 K1 + 0x7C100200, // 0015 CALL R4 1 + 0x7812001C, // 0016 JMPF R4 #0034 + 0x88100108, // 0017 GETMBR R4 R0 K8 + 0x88100909, // 0018 GETMBR R4 R4 K9 + 0x4C140000, // 0019 LDNIL R5 + 0x20100805, // 001A NE R4 R4 R5 + 0x78120001, // 001B JMPF R4 #001E + 0x58100004, // 001C LDCONST R4 K4 + 0x70020000, // 001D JMP #001F + 0x58100005, // 001E LDCONST R4 K5 + 0x8C140302, // 001F GETMET R5 R1 K2 + 0x601C0018, // 0020 GETGBL R7 G24 + 0x5820000A, // 0021 LDCONST R8 K10 + 0x5C240800, // 0022 MOVE R9 R4 + 0x7C1C0400, // 0023 CALL R7 2 0x7C140400, // 0024 CALL R5 2 - 0x8C140506, // 0025 GETMET R5 R2 K6 - 0x581C0012, // 0026 LDCONST R7 K18 + 0x8C140302, // 0025 GETMET R5 R1 K2 + 0x581C000B, // 0026 LDCONST R7 K11 0x7C140400, // 0027 CALL R5 2 - 0x8C140506, // 0028 GETMET R5 R2 K6 - 0x581C0013, // 0029 LDCONST R7 K19 - 0x7C140400, // 002A CALL R5 2 - 0x80040800, // 002B RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: web_sensor -********************************************************************/ -be_local_closure(Matter_UI_web_sensor, /* name */ - be_nested_proto( - 13, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[25]) { /* constants */ - /* K0 */ be_nested_str_weak(webserver), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(tasmota), - /* K3 */ be_nested_str_weak(get_option), - /* K4 */ be_nested_str_weak(matter), - /* K5 */ be_nested_str_weak(MATTER_OPTION), - /* K6 */ be_nested_str_weak(device), - /* K7 */ be_nested_str_weak(is_root_commissioning_open), - /* K8 */ be_nested_str_weak(show_commissioning_info), - /* K9 */ be_nested_str_weak(sessions), - /* K10 */ be_nested_str_weak(count_active_fabrics), - /* K11 */ be_const_int(0), - /* K12 */ be_nested_str_weak(content_send), - /* K13 */ be_nested_str_weak(format), - /* K14 */ be_nested_str_weak(_X3Cdiv_X20style_X3D_X27text_X2Dalign_X3Aright_X3Bfont_X2Dsize_X3A11px_X3Bcolor_X3A_X23aaa_X3B_X27_X3E_X25s_X3C_X2Fdiv_X3E), - /* K15 */ be_nested_str_weak(No_X20active_X20association), - /* K16 */ be_const_int(1), - /* K17 */ be_nested_str_weak(_X20active_X20association), - /* K18 */ be_nested_str_weak(s), - /* K19 */ be_nested_str_weak(), - /* K20 */ be_nested_str_weak(_X3Cbutton_X20onclick_X3D_X27la_X28_X22_X26mtc_X25i_X3D1_X22_X29_X3B_X27_X3E), - /* K21 */ be_nested_str_weak(commissioning_open), - /* K22 */ be_nested_str_weak(_LOGO), - /* K23 */ be_nested_str_weak(_X20Open_X20Commissioning_X3C_X2Fbutton_X3E), - /* K24 */ be_nested_str_weak(_X20Close_X20Commissioning_X3C_X2Fbutton_X3E), - }), - be_str_weak(web_sensor), - &be_const_str_solidified, - ( &(const binstruction[72]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0xB80E0400, // 0002 GETNGBL R3 K2 - 0x8C0C0703, // 0003 GETMET R3 R3 K3 - 0xB8160800, // 0004 GETNGBL R5 K4 - 0x88140B05, // 0005 GETMBR R5 R5 K5 - 0x7C0C0400, // 0006 CALL R3 2 - 0x780E003E, // 0007 JMPF R3 #0047 - 0x88100106, // 0008 GETMBR R4 R0 K6 - 0x8C100907, // 0009 GETMET R4 R4 K7 - 0x7C100200, // 000A CALL R4 1 - 0x78120001, // 000B JMPF R4 #000E - 0x8C100108, // 000C GETMET R4 R0 K8 - 0x7C100200, // 000D CALL R4 1 - 0x88100106, // 000E GETMBR R4 R0 K6 - 0x88100909, // 000F GETMBR R4 R4 K9 - 0x8C10090A, // 0010 GETMET R4 R4 K10 - 0x7C100200, // 0011 CALL R4 1 - 0x1C14090B, // 0012 EQ R5 R4 K11 - 0x78160006, // 0013 JMPF R5 #001B - 0x8C14030C, // 0014 GETMET R5 R1 K12 - 0x8C1C050D, // 0015 GETMET R7 R2 K13 - 0x5824000E, // 0016 LDCONST R9 K14 - 0x5828000F, // 0017 LDCONST R10 K15 - 0x7C1C0600, // 0018 CALL R7 3 - 0x7C140400, // 0019 CALL R5 2 - 0x7002000E, // 001A JMP #002A - 0x24140910, // 001B GT R5 R4 K16 - 0x8C18030C, // 001C GETMET R6 R1 K12 - 0x8C20050D, // 001D GETMET R8 R2 K13 - 0x5828000E, // 001E LDCONST R10 K14 - 0x602C0008, // 001F GETGBL R11 G8 - 0x5C300800, // 0020 MOVE R12 R4 - 0x7C2C0200, // 0021 CALL R11 1 - 0x002C1711, // 0022 ADD R11 R11 K17 - 0x78160001, // 0023 JMPF R5 #0026 - 0x58300012, // 0024 LDCONST R12 K18 - 0x70020000, // 0025 JMP #0027 - 0x58300013, // 0026 LDCONST R12 K19 - 0x002C160C, // 0027 ADD R11 R11 R12 - 0x7C200600, // 0028 CALL R8 3 - 0x7C180400, // 0029 CALL R6 2 - 0x8C14030C, // 002A GETMET R5 R1 K12 - 0x8C1C050D, // 002B GETMET R7 R2 K13 - 0x58240014, // 002C LDCONST R9 K20 - 0x88280106, // 002D GETMBR R10 R0 K6 - 0x88281515, // 002E GETMBR R10 R10 K21 - 0x4C2C0000, // 002F LDNIL R11 - 0x1C28140B, // 0030 EQ R10 R10 R11 - 0x782A0001, // 0031 JMPF R10 #0034 - 0x58280010, // 0032 LDCONST R10 K16 - 0x70020000, // 0033 JMP #0035 - 0x5828000B, // 0034 LDCONST R10 K11 - 0x7C1C0600, // 0035 CALL R7 3 - 0x7C140400, // 0036 CALL R5 2 - 0x8C14030C, // 0037 GETMET R5 R1 K12 - 0xB81E0800, // 0038 GETNGBL R7 K4 - 0x881C0F16, // 0039 GETMBR R7 R7 K22 - 0x7C140400, // 003A CALL R5 2 - 0x88140106, // 003B GETMBR R5 R0 K6 - 0x88140B15, // 003C GETMBR R5 R5 K21 - 0x4C180000, // 003D LDNIL R6 - 0x1C140A06, // 003E EQ R5 R5 R6 - 0x78160003, // 003F JMPF R5 #0044 - 0x8C14030C, // 0040 GETMET R5 R1 K12 - 0x581C0017, // 0041 LDCONST R7 K23 - 0x7C140400, // 0042 CALL R5 2 - 0x70020002, // 0043 JMP #0047 - 0x8C14030C, // 0044 GETMET R5 R1 K12 - 0x581C0018, // 0045 LDCONST R7 K24 - 0x7C140400, // 0046 CALL R5 2 - 0x80000000, // 0047 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Matter_UI_init, /* name */ - be_nested_proto( - 5, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(device), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(add_driver), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x90020001, // 0000 SETMBR R0 K0 R1 - 0xB80A0200, // 0001 GETNGBL R2 K1 - 0x8C080502, // 0002 GETMET R2 R2 K2 - 0x5C100000, // 0003 MOVE R4 R0 - 0x7C080400, // 0004 CALL R2 2 - 0x80000000, // 0005 RET 0 + 0x88140108, // 0028 GETMBR R5 R0 K8 + 0x88140B0C, // 0029 GETMBR R5 R5 K12 + 0x78160001, // 002A JMPF R5 #002D + 0x5814000D, // 002B LDCONST R5 K13 + 0x70020000, // 002C JMP #002E + 0x58140005, // 002D LDCONST R5 K5 + 0x8C180302, // 002E GETMET R6 R1 K2 + 0x60200018, // 002F GETGBL R8 G24 + 0x5824000E, // 0030 LDCONST R9 K14 + 0x5C280A00, // 0031 MOVE R10 R5 + 0x7C200400, // 0032 CALL R8 2 + 0x7C180400, // 0033 CALL R6 2 + 0x8C100302, // 0034 GETMET R4 R1 K2 + 0x5818000F, // 0035 LDCONST R6 K15 + 0x7C100400, // 0036 CALL R4 2 + 0x80000000, // 0037 RET 0 }) ) ); @@ -1634,155 +3231,119 @@ be_local_closure(Matter_UI_init, /* name */ /******************************************************************** -** Solidified function: show_fabric_info +** Solidified function: show_plugins_hints_js ********************************************************************/ -be_local_closure(Matter_UI_show_fabric_info, /* name */ +be_local_closure(Matter_UI_show_plugins_hints_js, /* name */ be_nested_proto( 16, /* nstack */ - 1, /* argc */ - 2, /* varg */ + 2, /* argc */ + 3, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[30]) { /* constants */ + ( &(const bvalue[17]) { /* constants */ /* K0 */ be_nested_str_weak(webserver), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(content_send), - /* K3 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3BFabrics_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E), - /* K4 */ be_nested_str_weak(_X3Cp_X3EAssociated_X20fabrics_X3A_X3C_X2Fp_X3E), - /* K5 */ be_nested_str_weak(device), - /* K6 */ be_nested_str_weak(sessions), - /* K7 */ be_const_int(0), - /* K8 */ be_nested_str_weak(_X3Cp_X3E_X3Cb_X3ENone_X3C_X2Fb_X3E_X3C_X2Fp_X3E), - /* K9 */ be_nested_str_weak(fabrics), - /* K10 */ be_nested_str_weak(persistables), - /* K11 */ be_nested_str_weak(_X3Chr_X3E), - /* K12 */ be_nested_str_weak(fabric_label), - /* K13 */ be_nested_str_weak(_X3CNo_X20label_X3E), - /* K14 */ be_nested_str_weak(html_escape), - /* K15 */ be_nested_str_weak(format), - /* K16 */ be_nested_str_weak(_X3Cfieldset_X3E_X3Clegend_X3E_X3Cb_X3E_X26nbsp_X3B_X23_X25i_X20_X25s_X26nbsp_X3B_X3C_X2Fb_X3E_X3C_X2Flegend_X3E_X3Cp_X3E_X3C_X2Fp_X3E), - /* K17 */ be_nested_str_weak(get_fabric_index), - /* K18 */ be_nested_str_weak(get_fabric_id), - /* K19 */ be_nested_str_weak(copy), - /* K20 */ be_nested_str_weak(reverse), - /* K21 */ be_nested_str_weak(get_device_id), - /* K22 */ be_nested_str_weak(Fabric_X3A_X20_X25s_X3Cbr_X3E), - /* K23 */ be_nested_str_weak(tohex), - /* K24 */ be_nested_str_weak(Device_X3A_X20_X25s_X3Cbr_X3E_X26nbsp_X3B), - /* K25 */ be_nested_str_weak(_X3Cform_X20action_X3D_X27_X2Fmatterc_X27_X20method_X3D_X27post_X27_X20onsubmit_X3D_X27return_X20confirm_X28_X22Are_X20you_X20sure_X3F_X22_X29_X3B_X27_X3E), - /* K26 */ be_nested_str_weak(_X3Cinput_X20name_X3D_X27del_fabric_X27_X20type_X3D_X27hidden_X27_X20value_X3D_X27_X25i_X27_X3E), - /* K27 */ be_nested_str_weak(_X3Cbutton_X20name_X3D_X27del_X27_X20class_X3D_X27button_X20bgrn_X27_X3EDelete_X20Fabric_X3C_X2Fbutton_X3E_X3C_X2Fform_X3E_X3C_X2Fp_X3E), - /* K28 */ be_nested_str_weak(_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E), - /* K29 */ be_nested_str_weak(stop_iteration), + /* K1 */ be_nested_str_weak(json), + /* K2 */ be_nested_str_weak(string), + /* K3 */ be_nested_str_weak(split), + /* K4 */ be_nested_str_weak(_X7C), + /* K5 */ be_nested_str_weak(stop_iteration), + /* K6 */ be_nested_str_weak(), + /* K7 */ be_nested_str_weak(device), + /* K8 */ be_nested_str_weak(plugins_classes), + /* K9 */ be_nested_str_weak(find), + /* K10 */ be_nested_str_weak(ARG_HINT), + /* K11 */ be_nested_str_weak(push), + /* K12 */ be_nested_str_weak(content_send), + /* K13 */ be_nested_str_weak(_X3Cscript_X20type_X3D_X27text_X2Fjavascript_X27_X3Evar_X20hm_X3D_X25s_X3Bvar_X20hl_X3D_X25s_X3B_X3C_X2Fscript_X3E), + /* K14 */ be_nested_str_weak(dump), + /* K15 */ be_nested_str_weak(matter), + /* K16 */ be_nested_str_weak(_ADD_ENDPOINT_JS), }), - be_str_weak(show_fabric_info), + be_str_weak(show_plugins_hints_js), &be_const_str_solidified, - ( &(const binstruction[102]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0x8C0C0302, // 0002 GETMET R3 R1 K2 - 0x58140003, // 0003 LDCONST R5 K3 - 0x7C0C0400, // 0004 CALL R3 2 - 0x8C0C0302, // 0005 GETMET R3 R1 K2 - 0x58140004, // 0006 LDCONST R5 K4 - 0x7C0C0400, // 0007 CALL R3 2 - 0x600C000C, // 0008 GETGBL R3 G12 - 0x88100105, // 0009 GETMBR R4 R0 K5 - 0x88100906, // 000A GETMBR R4 R4 K6 - 0x88100906, // 000B GETMBR R4 R4 K6 - 0x7C0C0200, // 000C CALL R3 1 - 0x1C0C0707, // 000D EQ R3 R3 K7 - 0x780E0003, // 000E JMPF R3 #0013 - 0x8C0C0302, // 000F GETMET R3 R1 K2 - 0x58140008, // 0010 LDCONST R5 K8 - 0x7C0C0400, // 0011 CALL R3 2 - 0x7002004E, // 0012 JMP #0062 - 0x500C0200, // 0013 LDBOOL R3 1 0 - 0x60100010, // 0014 GETGBL R4 G16 - 0x88140105, // 0015 GETMBR R5 R0 K5 - 0x88140B06, // 0016 GETMBR R5 R5 K6 - 0x88140B09, // 0017 GETMBR R5 R5 K9 - 0x8C140B0A, // 0018 GETMET R5 R5 K10 - 0x7C140200, // 0019 CALL R5 1 - 0x7C100200, // 001A CALL R4 1 - 0xA8020042, // 001B EXBLK 0 #005F - 0x5C140800, // 001C MOVE R5 R4 - 0x7C140000, // 001D CALL R5 0 - 0x5C180600, // 001E MOVE R6 R3 - 0x741A0002, // 001F JMPT R6 #0023 - 0x8C180302, // 0020 GETMET R6 R1 K2 - 0x5820000B, // 0021 LDCONST R8 K11 - 0x7C180400, // 0022 CALL R6 2 - 0x500C0000, // 0023 LDBOOL R3 0 0 - 0x88180B0C, // 0024 GETMBR R6 R5 K12 - 0x5C1C0C00, // 0025 MOVE R7 R6 - 0x741E0000, // 0026 JMPT R7 #0028 - 0x5818000D, // 0027 LDCONST R6 K13 - 0x8C1C030E, // 0028 GETMET R7 R1 K14 - 0x5C240C00, // 0029 MOVE R9 R6 - 0x7C1C0400, // 002A CALL R7 2 - 0x5C180E00, // 002B MOVE R6 R7 - 0x8C1C0302, // 002C GETMET R7 R1 K2 - 0x8C24050F, // 002D GETMET R9 R2 K15 - 0x582C0010, // 002E LDCONST R11 K16 - 0x8C300B11, // 002F GETMET R12 R5 K17 - 0x7C300200, // 0030 CALL R12 1 - 0x5C340C00, // 0031 MOVE R13 R6 - 0x7C240800, // 0032 CALL R9 4 - 0x7C1C0400, // 0033 CALL R7 2 - 0x8C1C0B12, // 0034 GETMET R7 R5 K18 - 0x7C1C0200, // 0035 CALL R7 1 - 0x8C1C0F13, // 0036 GETMET R7 R7 K19 - 0x7C1C0200, // 0037 CALL R7 1 - 0x8C1C0F14, // 0038 GETMET R7 R7 K20 - 0x7C1C0200, // 0039 CALL R7 1 - 0x8C200B15, // 003A GETMET R8 R5 K21 - 0x7C200200, // 003B CALL R8 1 - 0x8C201113, // 003C GETMET R8 R8 K19 - 0x7C200200, // 003D CALL R8 1 - 0x8C201114, // 003E GETMET R8 R8 K20 - 0x7C200200, // 003F CALL R8 1 - 0x8C240302, // 0040 GETMET R9 R1 K2 - 0x8C2C050F, // 0041 GETMET R11 R2 K15 - 0x58340016, // 0042 LDCONST R13 K22 - 0x8C380F17, // 0043 GETMET R14 R7 K23 - 0x7C380200, // 0044 CALL R14 1 - 0x7C2C0600, // 0045 CALL R11 3 - 0x7C240400, // 0046 CALL R9 2 - 0x8C240302, // 0047 GETMET R9 R1 K2 - 0x8C2C050F, // 0048 GETMET R11 R2 K15 - 0x58340018, // 0049 LDCONST R13 K24 - 0x8C381117, // 004A GETMET R14 R8 K23 - 0x7C380200, // 004B CALL R14 1 - 0x7C2C0600, // 004C CALL R11 3 - 0x7C240400, // 004D CALL R9 2 - 0x8C240302, // 004E GETMET R9 R1 K2 - 0x582C0019, // 004F LDCONST R11 K25 - 0x7C240400, // 0050 CALL R9 2 - 0x8C240302, // 0051 GETMET R9 R1 K2 - 0x8C2C050F, // 0052 GETMET R11 R2 K15 - 0x5834001A, // 0053 LDCONST R13 K26 - 0x8C380B11, // 0054 GETMET R14 R5 K17 - 0x7C380200, // 0055 CALL R14 1 - 0x7C2C0600, // 0056 CALL R11 3 - 0x7C240400, // 0057 CALL R9 2 - 0x8C240302, // 0058 GETMET R9 R1 K2 - 0x582C001B, // 0059 LDCONST R11 K27 - 0x7C240400, // 005A CALL R9 2 - 0x8C240302, // 005B GETMET R9 R1 K2 - 0x582C001C, // 005C LDCONST R11 K28 - 0x7C240400, // 005D CALL R9 2 - 0x7001FFBC, // 005E JMP #001C - 0x5810001D, // 005F LDCONST R4 K29 - 0xAC100200, // 0060 CATCH R4 1 0 - 0xB0080000, // 0061 RAISE 2 R0 R0 - 0x8C0C0302, // 0062 GETMET R3 R1 K2 - 0x5814001C, // 0063 LDCONST R5 K28 - 0x7C0C0400, // 0064 CALL R3 2 - 0x80000000, // 0065 RET 0 + ( &(const binstruction[79]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0xA40E0200, // 0001 IMPORT R3 K1 + 0xA4120400, // 0002 IMPORT R4 K2 + 0x60140012, // 0003 GETGBL R5 G18 + 0x7C140000, // 0004 CALL R5 0 + 0x60180010, // 0005 GETGBL R6 G16 + 0x5C1C0200, // 0006 MOVE R7 R1 + 0x7C180200, // 0007 CALL R6 1 + 0xA8020007, // 0008 EXBLK 0 #0011 + 0x5C1C0C00, // 0009 MOVE R7 R6 + 0x7C1C0000, // 000A CALL R7 0 + 0x8C200903, // 000B GETMET R8 R4 K3 + 0x5C280E00, // 000C MOVE R10 R7 + 0x582C0004, // 000D LDCONST R11 K4 + 0x7C200600, // 000E CALL R8 3 + 0x00140A08, // 000F ADD R5 R5 R8 + 0x7001FFF7, // 0010 JMP #0009 + 0x58180005, // 0011 LDCONST R6 K5 + 0xAC180200, // 0012 CATCH R6 1 0 + 0xB0080000, // 0013 RAISE 2 R0 R0 + 0x60180013, // 0014 GETGBL R6 G19 + 0x7C180000, // 0015 CALL R6 0 + 0x601C0012, // 0016 GETGBL R7 G18 + 0x7C1C0000, // 0017 CALL R7 0 + 0x60200010, // 0018 GETGBL R8 G16 + 0x5C240A00, // 0019 MOVE R9 R5 + 0x7C200200, // 001A CALL R8 1 + 0xA802001F, // 001B EXBLK 0 #003C + 0x5C241000, // 001C MOVE R9 R8 + 0x7C240000, // 001D CALL R9 0 + 0x1C281306, // 001E EQ R10 R9 K6 + 0x782A0000, // 001F JMPF R10 #0021 + 0x7001FFFA, // 0020 JMP #001C + 0x88280107, // 0021 GETMBR R10 R0 K7 + 0x88281508, // 0022 GETMBR R10 R10 K8 + 0x8C281509, // 0023 GETMET R10 R10 K9 + 0x5C301200, // 0024 MOVE R12 R9 + 0x7C280400, // 0025 CALL R10 2 + 0x4C2C0000, // 0026 LDNIL R11 + 0x202C140B, // 0027 NE R11 R10 R11 + 0x782E0011, // 0028 JMPF R11 #003B + 0x882C150A, // 0029 GETMBR R11 R10 K10 + 0x4C300000, // 002A LDNIL R12 + 0x2030160C, // 002B NE R12 R11 R12 + 0x7832000D, // 002C JMPF R12 #003B + 0x8C300F09, // 002D GETMET R12 R7 K9 + 0x5C381600, // 002E MOVE R14 R11 + 0x7C300400, // 002F CALL R12 2 + 0x4C340000, // 0030 LDNIL R13 + 0x1C34180D, // 0031 EQ R13 R12 R13 + 0x78360006, // 0032 JMPF R13 #003A + 0x6034000C, // 0033 GETGBL R13 G12 + 0x5C380E00, // 0034 MOVE R14 R7 + 0x7C340200, // 0035 CALL R13 1 + 0x5C301A00, // 0036 MOVE R12 R13 + 0x8C340F0B, // 0037 GETMET R13 R7 K11 + 0x5C3C1600, // 0038 MOVE R15 R11 + 0x7C340400, // 0039 CALL R13 2 + 0x9818120C, // 003A SETIDX R6 R9 R12 + 0x7001FFDF, // 003B JMP #001C + 0x58200005, // 003C LDCONST R8 K5 + 0xAC200200, // 003D CATCH R8 1 0 + 0xB0080000, // 003E RAISE 2 R0 R0 + 0x8C20050C, // 003F GETMET R8 R2 K12 + 0x60280018, // 0040 GETGBL R10 G24 + 0x582C000D, // 0041 LDCONST R11 K13 + 0x8C30070E, // 0042 GETMET R12 R3 K14 + 0x5C380C00, // 0043 MOVE R14 R6 + 0x7C300400, // 0044 CALL R12 2 + 0x8C34070E, // 0045 GETMET R13 R3 K14 + 0x5C3C0E00, // 0046 MOVE R15 R7 + 0x7C340400, // 0047 CALL R13 2 + 0x7C280600, // 0048 CALL R10 3 + 0x7C200400, // 0049 CALL R8 2 + 0x8C20050C, // 004A GETMET R8 R2 K12 + 0xB82A1E00, // 004B GETNGBL R10 K15 + 0x88281510, // 004C GETMBR R10 R10 K16 + 0x7C200400, // 004D CALL R8 2 + 0x80000000, // 004E RET 0 }) ) ); @@ -1795,25 +3356,34 @@ be_local_closure(Matter_UI_show_fabric_info, /* name */ be_local_class(Matter_UI, 1, NULL, - be_nested_map(17, + be_nested_map(26, ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(equal_map, -1), be_const_static_closure(Matter_UI_equal_map_closure) }, + { be_const_key_weak(page_part_mgr_adv, -1), be_const_closure(Matter_UI_page_part_mgr_adv_closure) }, + { be_const_key_weak(_CLASSES_TYPES2, -1), be_nested_str_weak(_X7Chttp_relay_X7Chttp_light0_X7Chttp_light1_X7Chttp_light2_X7Chttp_light3_X7Chttp_temperature_X7Chttp_pressure_X7Chttp_illuminance_X7Chttp_humidity_X7Chttp_occupancy_X7Chttp_contact) }, + { be_const_key_weak(page_part_mgr, 25), be_const_closure(Matter_UI_page_part_mgr_closure) }, + { be_const_key_weak(show_plugins_hints_js, -1), be_const_closure(Matter_UI_show_plugins_hints_js_closure) }, + { be_const_key_weak(show_enable, -1), be_const_closure(Matter_UI_show_enable_closure) }, + { be_const_key_weak(matter_enabled, 24), be_const_closure(Matter_UI_matter_enabled_closure) }, + { be_const_key_weak(generate_config_from_status, -1), be_const_closure(Matter_UI_generate_config_from_status_closure) }, + { be_const_key_weak(show_qrcode, 21), be_const_closure(Matter_UI_show_qrcode_closure) }, + { be_const_key_weak(page_part_mgr_add, -1), be_const_closure(Matter_UI_page_part_mgr_add_closure) }, { be_const_key_weak(show_plugins_configuration, -1), be_const_closure(Matter_UI_show_plugins_configuration_closure) }, - { be_const_key_weak(_CLASSES_TYPES, 2), be_nested_str_weak(_X7Crelay_X7Clight0_X7Clight1_X7Clight2_X7Clight3_X7Cshutter_X7Cshutter_X2Btilt_X7Ctemperature_X7Cpressure_X7Cilluminance_X7Chumidity_X7C_X2Dhttp_X7Chttp_relay) }, - { be_const_key_weak(show_fabric_info, 7), be_const_closure(Matter_UI_show_fabric_info_closure) }, - { be_const_key_weak(init, -1), be_const_closure(Matter_UI_init_closure) }, - { be_const_key_weak(web_add_handler, -1), be_const_closure(Matter_UI_web_add_handler_closure) }, - { be_const_key_weak(_ROOT_TYPES, 11), be_nested_str_weak(root) }, - { be_const_key_weak(show_commissioning_info, 16), be_const_closure(Matter_UI_show_commissioning_info_closure) }, - { be_const_key_weak(device, -1), be_const_var(0) }, + { be_const_key_weak(show_commissioning_info, -1), be_const_closure(Matter_UI_show_commissioning_info_closure) }, + { be_const_key_weak(page_part_ctl, 18), be_const_closure(Matter_UI_page_part_ctl_closure) }, + { be_const_key_weak(show_fabric_info, -1), be_const_closure(Matter_UI_show_fabric_info_closure) }, + { be_const_key_weak(_CLASSES_TYPES, 4), be_nested_str_weak(_X7Crelay_X7Clight0_X7Clight1_X7Clight2_X7Clight3_X7Cshutter_X7Cshutter_X2Btilt_X7Ctemperature_X7Cpressure_X7Cilluminance_X7Chumidity_X7Coccupancy_X7Conoff_X7Ccontact_X7C_X2Dvirtual_X7Cv_relay_X7Cv_light0_X7Cv_light1_X7Cv_light2_X7Cv_light3_X7Cv_temp_X7Cv_pressure_X7Cv_illuminance_X7Cv_humidity_X7Cv_contact) }, + { be_const_key_weak(web_get_arg, -1), be_const_closure(Matter_UI_web_get_arg_closure) }, + { be_const_key_weak(plugin_option, 5), be_const_closure(Matter_UI_plugin_option_closure) }, { be_const_key_weak(web_add_config_button, -1), be_const_closure(Matter_UI_web_add_config_button_closure) }, - { be_const_key_weak(page_part_ctl, 5), be_const_closure(Matter_UI_page_part_ctl_closure) }, - { be_const_key_weak(web_get_arg, 13), be_const_closure(Matter_UI_web_get_arg_closure) }, - { be_const_key_weak(web_sensor, 12), be_const_closure(Matter_UI_web_sensor_closure) }, - { be_const_key_weak(show_enable, 14), be_const_closure(Matter_UI_show_enable_closure) }, - { be_const_key_weak(plugin_option, -1), be_const_closure(Matter_UI_plugin_option_closure) }, - { be_const_key_weak(show_qrcode, -1), be_const_closure(Matter_UI_show_qrcode_closure) }, - { be_const_key_weak(page_part_mgr, 3), be_const_closure(Matter_UI_page_part_mgr_closure) }, { be_const_key_weak(show_passcode_form, -1), be_const_closure(Matter_UI_show_passcode_form_closure) }, + { be_const_key_weak(show_remote_autoconf, 8), be_const_closure(Matter_UI_show_remote_autoconf_closure) }, + { be_const_key_weak(web_add_handler, -1), be_const_closure(Matter_UI_web_add_handler_closure) }, + { be_const_key_weak(show_bridge_status, 23), be_const_closure(Matter_UI_show_bridge_status_closure) }, + { be_const_key_weak(plugin_name, 12), be_const_closure(Matter_UI_plugin_name_closure) }, + { be_const_key_weak(init, -1), be_const_closure(Matter_UI_init_closure) }, + { be_const_key_weak(web_sensor, -1), be_const_closure(Matter_UI_web_sensor_closure) }, + { be_const_key_weak(device, -1), be_const_var(0) }, })), be_str_weak(Matter_UI) ); diff --git a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_inspect.h b/lib/libesp32/berry_matter/src/solidify/solidified_Matter_inspect.h deleted file mode 100644 index 3c038fc3a627..000000000000 --- a/lib/libesp32/berry_matter/src/solidify/solidified_Matter_inspect.h +++ /dev/null @@ -1,189 +0,0 @@ -/* Solidification of Matter_inspect.h */ -/********************************************************************\ -* Generated code, don't edit * -\********************************************************************/ -#include "be_constobj.h" - -/******************************************************************** -** Solidified function: sort -********************************************************************/ -be_local_closure(matter_sort, /* name */ - be_nested_proto( - 6, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_const_int(1), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str_weak(stop_iteration), - }), - be_str_weak(sort), - &be_const_str_solidified, - ( &(const binstruction[29]) { /* code */ - 0x60040010, // 0000 GETGBL R1 G16 - 0x6008000C, // 0001 GETGBL R2 G12 - 0x5C0C0000, // 0002 MOVE R3 R0 - 0x7C080200, // 0003 CALL R2 1 - 0x04080500, // 0004 SUB R2 R2 K0 - 0x400A0002, // 0005 CONNECT R2 K0 R2 - 0x7C040200, // 0006 CALL R1 1 - 0xA8020010, // 0007 EXBLK 0 #0019 - 0x5C080200, // 0008 MOVE R2 R1 - 0x7C080000, // 0009 CALL R2 0 - 0x940C0002, // 000A GETIDX R3 R0 R2 - 0x5C100400, // 000B MOVE R4 R2 - 0x24140901, // 000C GT R5 R4 K1 - 0x78160008, // 000D JMPF R5 #0017 - 0x04140900, // 000E SUB R5 R4 K0 - 0x94140005, // 000F GETIDX R5 R0 R5 - 0x24140A03, // 0010 GT R5 R5 R3 - 0x78160004, // 0011 JMPF R5 #0017 - 0x04140900, // 0012 SUB R5 R4 K0 - 0x94140005, // 0013 GETIDX R5 R0 R5 - 0x98000805, // 0014 SETIDX R0 R4 R5 - 0x04100900, // 0015 SUB R4 R4 K0 - 0x7001FFF4, // 0016 JMP #000C - 0x98000803, // 0017 SETIDX R0 R4 R3 - 0x7001FFEE, // 0018 JMP #0008 - 0x58040002, // 0019 LDCONST R1 K2 - 0xAC040200, // 001A CATCH R1 1 0 - 0xB0080000, // 001B RAISE 2 R0 R0 - 0x80040000, // 001C RET 1 R0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: inspect -********************************************************************/ -be_local_closure(matter_inspect, /* name */ - be_nested_proto( - 16, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[17]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(introspect), - /* K2 */ be_nested_str_weak(members), - /* K3 */ be_nested_str_weak(get), - /* K4 */ be_nested_str_weak(function), - /* K5 */ be_nested_str_weak(push), - /* K6 */ be_nested_str_weak(stop_iteration), - /* K7 */ be_nested_str_weak(matter), - /* K8 */ be_nested_str_weak(sort), - /* K9 */ be_nested_str_weak(format), - /* K10 */ be_nested_str_weak(_X27_X25s_X27_X3A_X20_X25s), - /* K11 */ be_nested_str_weak(_X7B), - /* K12 */ be_nested_str_weak(concat), - /* K13 */ be_nested_str_weak(_X2C_X20), - /* K14 */ be_nested_str_weak(_X7D), - /* K15 */ be_nested_str_weak(Exception_X3A), - /* K16 */ be_nested_str_weak(_X7C), - }), - be_str_weak(inspect), - &be_const_str_solidified, - ( &(const binstruction[85]) { /* code */ - 0xA8020044, // 0000 EXBLK 0 #0046 - 0xA4060000, // 0001 IMPORT R1 K0 - 0xA40A0200, // 0002 IMPORT R2 K1 - 0x600C0012, // 0003 GETGBL R3 G18 - 0x7C0C0000, // 0004 CALL R3 0 - 0x60100010, // 0005 GETGBL R4 G16 - 0x8C140502, // 0006 GETMET R5 R2 K2 - 0x5C1C0000, // 0007 MOVE R7 R0 - 0x7C140400, // 0008 CALL R5 2 - 0x7C100200, // 0009 CALL R4 1 - 0xA802000E, // 000A EXBLK 0 #001A - 0x5C140800, // 000B MOVE R5 R4 - 0x7C140000, // 000C CALL R5 0 - 0x8C180503, // 000D GETMET R6 R2 K3 - 0x5C200000, // 000E MOVE R8 R0 - 0x5C240A00, // 000F MOVE R9 R5 - 0x7C180600, // 0010 CALL R6 3 - 0x601C0004, // 0011 GETGBL R7 G4 - 0x5C200C00, // 0012 MOVE R8 R6 - 0x7C1C0200, // 0013 CALL R7 1 - 0x201C0F04, // 0014 NE R7 R7 K4 - 0x781E0002, // 0015 JMPF R7 #0019 - 0x8C1C0705, // 0016 GETMET R7 R3 K5 - 0x5C240A00, // 0017 MOVE R9 R5 - 0x7C1C0400, // 0018 CALL R7 2 - 0x7001FFF0, // 0019 JMP #000B - 0x58100006, // 001A LDCONST R4 K6 - 0xAC100200, // 001B CATCH R4 1 0 - 0xB0080000, // 001C RAISE 2 R0 R0 - 0xB8120E00, // 001D GETNGBL R4 K7 - 0x8C100908, // 001E GETMET R4 R4 K8 - 0x5C180600, // 001F MOVE R6 R3 - 0x7C100400, // 0020 CALL R4 2 - 0x5C0C0800, // 0021 MOVE R3 R4 - 0x60100012, // 0022 GETGBL R4 G18 - 0x7C100000, // 0023 CALL R4 0 - 0x60140010, // 0024 GETGBL R5 G16 - 0x5C180600, // 0025 MOVE R6 R3 - 0x7C140200, // 0026 CALL R5 1 - 0xA8020011, // 0027 EXBLK 0 #003A - 0x5C180A00, // 0028 MOVE R6 R5 - 0x7C180000, // 0029 CALL R6 0 - 0x8C1C0503, // 002A GETMET R7 R2 K3 - 0x5C240000, // 002B MOVE R9 R0 - 0x5C280C00, // 002C MOVE R10 R6 - 0x7C1C0600, // 002D CALL R7 3 - 0x8C200905, // 002E GETMET R8 R4 K5 - 0x8C280309, // 002F GETMET R10 R1 K9 - 0x5830000A, // 0030 LDCONST R12 K10 - 0x60340008, // 0031 GETGBL R13 G8 - 0x5C380C00, // 0032 MOVE R14 R6 - 0x7C340200, // 0033 CALL R13 1 - 0x60380008, // 0034 GETGBL R14 G8 - 0x5C3C0E00, // 0035 MOVE R15 R7 - 0x7C380200, // 0036 CALL R14 1 - 0x7C280800, // 0037 CALL R10 4 - 0x7C200400, // 0038 CALL R8 2 - 0x7001FFED, // 0039 JMP #0028 - 0x58140006, // 003A LDCONST R5 K6 - 0xAC140200, // 003B CATCH R5 1 0 - 0xB0080000, // 003C RAISE 2 R0 R0 - 0x8C14090C, // 003D GETMET R5 R4 K12 - 0x581C000D, // 003E LDCONST R7 K13 - 0x7C140400, // 003F CALL R5 2 - 0x00161605, // 0040 ADD R5 K11 R5 - 0x00140B0E, // 0041 ADD R5 R5 K14 - 0xA8040001, // 0042 EXBLK 1 1 - 0x80040A00, // 0043 RET 1 R5 - 0xA8040001, // 0044 EXBLK 1 1 - 0x7002000D, // 0045 JMP #0054 - 0xAC040002, // 0046 CATCH R1 0 2 - 0x7002000A, // 0047 JMP #0053 - 0x600C0008, // 0048 GETGBL R3 G8 - 0x5C100200, // 0049 MOVE R4 R1 - 0x7C0C0200, // 004A CALL R3 1 - 0x000E1E03, // 004B ADD R3 K15 R3 - 0x000C0710, // 004C ADD R3 R3 K16 - 0x60100008, // 004D GETGBL R4 G8 - 0x5C140400, // 004E MOVE R5 R2 - 0x7C100200, // 004F CALL R4 1 - 0x000C0604, // 0050 ADD R3 R3 R4 - 0x80040600, // 0051 RET 1 R3 - 0x70020000, // 0052 JMP #0054 - 0xB0080000, // 0053 RAISE 2 R0 R0 - 0x80000000, // 0054 RET 0 - }) - ) -); -/*******************************************************************/ - -/********************************************************************/ -/* End of solidification */ diff --git a/lib/libesp32/berry_matter/tools/vendor_to_c.be b/lib/libesp32/berry_matter/tools/vendor_to_c.be new file mode 100644 index 000000000000..924f7e9f9ce0 --- /dev/null +++ b/lib/libesp32/berry_matter/tools/vendor_to_c.be @@ -0,0 +1,91 @@ + +import json +import string + +var f = open("vendors.json") +var j = json.load(f.read()) +f.close() + +for elt: j["vendorInfo"] + + print(format(' { 0x%04X, "%s"},', elt['vendorID'], elt['vendorName'])) + +end + +#- + + { 0x100B, "Signify"}, + { 0x101D, "Assa Abloy"}, + { 0x1021, "Legrand Group"}, + { 0x1037, "NXP Semiconductors"}, + { 0x105E, "Schneider"}, + { 0x109B, "Leviton"}, + { 0x10D0, "Qorvo"}, + { 0x10EE, "UEI"}, + { 0x10F2, "ubisys"}, + { 0x111D, "Comcast Communications"}, + { 0x115A, "Nanoleaf"}, + { 0x115F, "Aqara"}, + { 0x1160, "Sengled"}, + { 0x1168, "Leedarson"}, + { 0x117E, "Feibit"}, + { 0x1188, "TP-Link"}, + { 0x118C, "Midea Group"}, + { 0x120B, "HEIMAN"}, + { 0x1217, "Amazon Alexa"}, + { 0x1219, "ORVIBO"}, + { 0x125D, "Tuya"}, + { 0x127F, "Nordic Semiconductor ASA"}, + { 0x1280, "Siterwell"}, + { 0x1286, "CoolKit"}, + { 0x128F, "EGLO"}, + { 0x130A, "Eve"}, + { 0x130D, "BouffaloLab"}, + { 0x1312, "Yeelight"}, + { 0x131B, "Espressif Systems"}, + { 0x131E, "CAME S.p.A."}, + { 0x131F, "Longan.link"}, + { 0x1321, "SONOFF"}, + { 0x1333, "Becker Antriebe"}, + { 0x1339, "GE Lighting, a Savant company"}, + { 0x133F, "ASR"}, + { 0x1342, "Beken Corporation"}, + { 0x1344, "Eltako"}, + { 0x1345, "Meross"}, + { 0x1346, "Rafael"}, + { 0x1349, "Apple Home"}, + { 0x134E, "tado"}, + { 0x134F, "mediola"}, + { 0x1351, "HooRii Technology"}, + { 0x135D, "Nuki"}, + { 0x1362, "deveritec GmbH"}, + { 0x1365, "Dooya"}, + { 0x136E, "Ambi Labs Limited"}, + { 0x1371, "Tridonic"}, + { 0x1372, "innovation matters"}, + { 0x137F, "NEO"}, + { 0x1381, "Amazon Prime Video"}, + { 0x1384, "Apple Keychain"}, + { 0x1386, "Skylux"}, + { 0x1387, "Qianyan"}, + { 0x138A, "Nature"}, + { 0x1391, "Kasa"}, + { 0x1392, "Tapo"}, + { 0x1397, "SwitchBot"}, + { 0x139C, "Zemismart Technology Limited"}, + { 0x1400, "Uascent"}, + { 0x1403, "Arlec Australia"}, + { 0x1404, "Phaten"}, + { 0x1407, "ThirdReality"}, + { 0x1410, "Quectel"}, + { 0x1413, "1Home"}, + { 0x1415, "Caveman"}, + { 0x1419, "Lorex"}, + { 0x141B, "Rang Dong VN"}, + { 0x141E, "TUO Accessories LLC"}, + { 0x141F, "Ductech"}, + { 0x142D, "QH"}, + { 0x142F, "QIACHIP"}, + { 0x6006, "Google LLC"}, + +-# diff --git a/lib/libesp32/berry_matter/tools/vendors.json b/lib/libesp32/berry_matter/tools/vendors.json new file mode 100644 index 000000000000..4a47f884ed3a --- /dev/null +++ b/lib/libesp32/berry_matter/tools/vendors.json @@ -0,0 +1,592 @@ +{ + "vendorInfo": [ + { + "vendorID": 4107, + "vendorName": "Signify", + "companyLegalName": "Signify Netherlands B.V.", + "companyPreferredName": "Signify", + "vendorLandingPageURL": "https://www.signify.com/", + "creator": "cosmos1xx8fg5nu4lesn448ytds8yjql47jp8gnfh6hck" + }, + { + "vendorID": 4125, + "vendorName": "Assa Abloy", + "companyLegalName": "Assa Abloy", + "companyPreferredName": "", + "vendorLandingPageURL": "http://www.yalehome.com", + "creator": "cosmos18wrgwrrccn49ejv4hstz9czxgw9dc2s2l9f94k" + }, + { + "vendorID": 4129, + "vendorName": "Legrand Group", + "companyLegalName": "Legrand", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.legrand.com", + "creator": "cosmos1elm6sf9yd2n7y0l0rve4zru0ukanv76vtrjnt3" + }, + { + "vendorID": 4151, + "vendorName": "NXP Semiconductors", + "companyLegalName": "NXP Semiconductors N.V.", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.nxp.com", + "creator": "cosmos1ck0arz4kky9l9qtdvqrct7783ffv2yftgmj9ch" + }, + { + "vendorID": 4190, + "vendorName": "Schneider", + "companyLegalName": "Schneider Electric", + "companyPreferredName": "Schneider Electric", + "vendorLandingPageURL": "", + "creator": "cosmos14kre58wpgterp7t9yy0393ecel9hpz9fnul6pc" + }, + { + "vendorID": 4251, + "vendorName": "Leviton", + "companyLegalName": "Leviton Manufacturing Company", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.leviton.com", + "creator": "cosmos1ypyp8zrqeu64rjmx3u34ghvl64uajr67uams3d" + }, + { + "vendorID": 4304, + "vendorName": "Qorvo", + "companyLegalName": "Qorvo, Inc.", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.qorvo.com/", + "creator": "cosmos1qrpkuzgm7hfejejfyg20g34tjxlt4k8dsspq52" + }, + { + "vendorID": 4334, + "vendorName": "UEI", + "companyLegalName": "Universal Electronics Inc", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.uei.com/", + "creator": "cosmos1pvrad6x6ettwgudttqd97r9wvarvnj5davpltg" + }, + { + "vendorID": 4338, + "vendorName": "ubisys", + "companyLegalName": "ubisys technologies GmbH", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.ubisys.de", + "creator": "cosmos1rxydw26p5k4f9rtwln6r3srvw4qq9pxnxadr3d" + }, + { + "vendorID": 4381, + "vendorName": "Comcast Communications", + "companyLegalName": "Comcast", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos1xcv4q8sjvf7nw4qj2yt5kledgwyf3ycxw8c0pe" + }, + { + "vendorID": 4442, + "vendorName": "Nanoleaf", + "companyLegalName": "Nanoleaf Ltd.", + "companyPreferredName": "", + "vendorLandingPageURL": "https://nanoleaf.me", + "creator": "cosmos1sggrrmw05e6alve8umwdaszade5qxyt53kthud" + }, + { + "vendorID": 4447, + "vendorName": "Aqara", + "companyLegalName": "Lumi United Technology Co., Ltd.", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.aqara.com/", + "creator": "cosmos1qpz3ghnqj6my7gzegkftzav9hpxymkx6zdk73v" + }, + { + "vendorID": 4448, + "vendorName": "Sengled", + "companyLegalName": "Sengled Co., Ltd.", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos1arhkv0n34xylxz9suy73dpyk6de32gpym9l3sw" + }, + { + "vendorID": 4456, + "vendorName": "Leedarson", + "companyLegalName": "Leedarson IoT Technology Inc.", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos1mzg0v94yg0cmkjqe2jqsys44tvvfk9mt2d889d" + }, + { + "vendorID": 4478, + "vendorName": "Feibit", + "companyLegalName": "Shenzhen Feibit Electronic Technology Co.,Ltd", + "companyPreferredName": "Feibit", + "vendorLandingPageURL": "http://www.feibit.com", + "creator": "cosmos162y3ehrqpuu2xjvmgq6qq7yqtdh6mlwh32wv2h" + }, + { + "vendorID": 4488, + "vendorName": "TP-Link", + "companyLegalName": "TP-Link Corporation Limited", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.tp-link.com", + "creator": "cosmos1jxpj6rr8vnetz9a2ec08az5fwqpuf4zt4hhygv" + }, + { + "vendorID": 4492, + "vendorName": "Midea Group", + "companyLegalName": "Midea Group", + "companyPreferredName": "Midea", + "vendorLandingPageURL": "", + "creator": "cosmos1a7c8us8jl76f8uue6xf9gzzqklfmfdyh8nedae" + }, + { + "vendorID": 4619, + "vendorName": "HEIMAN", + "companyLegalName": "Shenzhen Heiman Technology Co., Ltd.", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos16s4lqhxyqdr5lq6gmfpskjtwjf7dwc0lktn6dt" + }, + { + "vendorID": 4631, + "vendorName": "Amazon Alexa", + "companyLegalName": "Amazon.com, Inc.", + "companyPreferredName": "Amazon Alexa", + "vendorLandingPageURL": "https://www.amazon.com", + "creator": "cosmos152v4ejapsjl222zew0ll4eeltc0h2phh5hzpu3" + }, + { + "vendorID": 4633, + "vendorName": "ORVIBO", + "companyLegalName": "Shenzhen ORVIBO Technology Co., Ltd.", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.orvibo.com", + "creator": "cosmos1u7um30yf68zugm897tgpq7s6vhkhk4t2ykm0hq" + }, + { + "vendorID": 4701, + "vendorName": "Tuya", + "companyLegalName": "Tuya Global Inc.", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos13pwvzq2zk0r3fxuc2a5jhadnx6tda5ar2tcpp9" + }, + { + "vendorID": 4735, + "vendorName": "Nordic Semiconductor ASA", + "companyLegalName": "Nordic Semiconductor ASA", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.nordicsemi.com", + "creator": "cosmos1eatgwsxtjz0tlchllzasjfcac6m56n30njc3k2" + }, + { + "vendorID": 4736, + "vendorName": "Siterwell", + "companyLegalName": "Siterwell Electronics Co., Limited", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos1u3uhlkepx9dz9asrlucuupw2md2frvkwv583nr" + }, + { + "vendorID": 4742, + "vendorName": "CoolKit", + "companyLegalName": "SHENZHEN Coolkit Technology CO.,LTD.", + "companyPreferredName": "CoolKit", + "vendorLandingPageURL": "https://www.coolkit.cn/", + "creator": "cosmos18m8lehnvqx8zytn22fkekelt7xgmrl7cga37tl" + }, + { + "vendorID": 4751, + "vendorName": "EGLO", + "companyLegalName": "EGLO Leuchten GmbH", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.eglo.com/en/", + "creator": "cosmos1veu2f7mtgvfw8ezjfmhs64cqyt9wp2weas2rga" + }, + { + "vendorID": 4874, + "vendorName": "Eve", + "companyLegalName": "Eve Systems GmbH", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.evehome.com", + "creator": "cosmos1yh0ld8jl26rgycrtank8slxepmc8xzgyrzv99t" + }, + { + "vendorID": 4877, + "vendorName": "BouffaloLab", + "companyLegalName": "Bouffalo Lab (Nanjing) Co., Ltd.", + "companyPreferredName": "Bouffalo Lab ", + "vendorLandingPageURL": "https://www.bouffalolab.com/", + "creator": "cosmos1l8qwcjgfcnvlmtxrlcjrsmy9068mlck2cw68kx" + }, + { + "vendorID": 4882, + "vendorName": "Yeelight", + "companyLegalName": "Qingdao Yeelink Information Technology Co., Ltd.", + "companyPreferredName": "Yeelink Information Technology", + "vendorLandingPageURL": "https://en.yeelight.com/#", + "creator": "cosmos18fcq3647dkwur0d0zjyenj8sk57jehq4a8epaf" + }, + { + "vendorID": 4891, + "vendorName": "Espressif Systems", + "companyLegalName": "Espressif Systems (Shanghai) Co. Ltd.", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.espressif.com", + "creator": "cosmos1vncrg6hk30kutk4nr26mvyqc92zkygcc7aemzt" + }, + { + "vendorID": 4894, + "vendorName": "CAME S.p.A.", + "companyLegalName": "CAME S.p.A.", + "companyPreferredName": "CAME S.p.A.", + "vendorLandingPageURL": "https://www.came.com/", + "creator": "cosmos1kxjh94dcvnym6265nmxcjpn9xpkx0y7e3jjeqc" + }, + { + "vendorID": 4895, + "vendorName": "Longan.link", + "companyLegalName": "Longan Link Tech Co.,LTD", + "companyPreferredName": "", + "vendorLandingPageURL": "https://longan.link/", + "creator": "cosmos1qnd2v3n0f0ukja8z0jm4jqsqs5qhxa6ncvcxuv" + }, + { + "vendorID": 4897, + "vendorName": "SONOFF", + "companyLegalName": "Shenzhen Sonoff Technologies Co.,Ltd.", + "companyPreferredName": "SONOFF", + "vendorLandingPageURL": "https://sonoff.tech/", + "creator": "cosmos160c6r8rc2pgpgucasw4ae5gfqtz5vzcc6ay2sz" + }, + { + "vendorID": 4915, + "vendorName": "Becker Antriebe", + "companyLegalName": "Becker Antriebe GmbH", + "companyPreferredName": "Becker Antriebe", + "vendorLandingPageURL": "https://www.becker-antriebe.com/", + "creator": "cosmos1f6knru06kkxm306ckgs93zs9aqyrk9axgqh5wq" + }, + { + "vendorID": 4921, + "vendorName": "GE Lighting, a Savant company", + "companyLegalName": "GE Lighting, a Savant company", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.gelighting.com/", + "creator": "cosmos130t4m26ynex82jcgkqguxpffpva05e4zugn0xc" + }, + { + "vendorID": 4927, + "vendorName": "ASR", + "companyLegalName": "ASR Microelectronics(ShenZhen)Co., Ltd.", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos14a9n65wmumympggqnquu5ptq042ff69nehztk7" + }, + { + "vendorID": 4930, + "vendorName": "Beken Corporation", + "companyLegalName": "beken", + "companyPreferredName": "", + "vendorLandingPageURL": "http://www.bekencorp.com/", + "creator": "cosmos1aru484uj9dqkpnqg768tl6m66fvz9wkqcg79cw" + }, + { + "vendorID": 4932, + "vendorName": "Eltako", + "companyLegalName": "Eltako GmbH", + "companyPreferredName": "Eltako", + "vendorLandingPageURL": "https://www.eltako.com", + "creator": "cosmos1n3kqdwqh33grxcnzdeknercyt3wekc5zl4n3dg" + }, + { + "vendorID": 4933, + "vendorName": "Meross", + "companyLegalName": "Chengdu Meross Technology Co., Ltd.", + "companyPreferredName": "Meross", + "vendorLandingPageURL": "https://www.meross.com", + "creator": "cosmos18qu47pmqwylzm9w2tezyrmvcwmkew5yyvw3d6n" + }, + { + "vendorID": 4934, + "vendorName": "Rafael", + "companyLegalName": "Rafael Microelectronics, Inc.", + "companyPreferredName": "Rafael", + "vendorLandingPageURL": "", + "creator": "cosmos14myns7fehcxm2c896k5syhzr7zsyf7g4jdlk08" + }, + { + "vendorID": 4937, + "vendorName": "Apple Home", + "companyLegalName": "Apple Inc.", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.apple.com/home-app", + "creator": "cosmos1ysl37yl5nmcg8qr64knpscahq5zel3hjtxmvyt" + }, + { + "vendorID": 4942, + "vendorName": "tado", + "companyLegalName": "tado GmbH", + "companyPreferredName": "tado°", + "vendorLandingPageURL": "https://www.tado.com/", + "creator": "cosmos1sacvh2z4w0f3d657a2tdw2w4ha87743c8qahkv" + }, + { + "vendorID": 4943, + "vendorName": "mediola", + "companyLegalName": "mediola - connected living AG", + "companyPreferredName": "mediola", + "vendorLandingPageURL": "https://www.mediola.com", + "creator": "cosmos1j2w2zq787mkwltsdhzlxpnm50s8nrvg85u20dh" + }, + { + "vendorID": 4945, + "vendorName": "HooRii Technology", + "companyLegalName": "HooRii Technology CO., LTD", + "companyPreferredName": "HooRii Technology", + "vendorLandingPageURL": "https://www.hoorii.io/", + "creator": "cosmos1etk35ufz9z4x56t63tap7ncsvk5k5zw2npmlcu" + }, + { + "vendorID": 4957, + "vendorName": "Nuki", + "companyLegalName": "Nuki Home Solutions GmbH", + "companyPreferredName": "Nuki", + "vendorLandingPageURL": "https://nuki.io", + "creator": "cosmos1tdslga3va6luqzy2x3nlwxfh80f99vly5800ls" + }, + { + "vendorID": 4962, + "vendorName": "deveritec GmbH", + "companyLegalName": "deveritec GmbH", + "companyPreferredName": "", + "vendorLandingPageURL": "https://deveritec.de", + "creator": "cosmos19740ad8368h0h33rcu6gugtxgvyuws7puqg0za" + }, + { + "vendorID": 4965, + "vendorName": "Dooya", + "companyLegalName": "Ningbo Dooya Mechanic \u0026 Electronic Technology Co.,Ltd", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos1pqypa94grwkmk2d7e0ncdctfav5wyycu787tmk" + }, + { + "vendorID": 4974, + "vendorName": "Ambi Labs Limited", + "companyLegalName": "Ambi Labs Limited", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos12st2nx5elvkyswv7nqw6xh6j67vg472lcv0299" + }, + { + "vendorID": 4977, + "vendorName": "Tridonic", + "companyLegalName": "Tridonic GmbH \u0026 Co KG", + "companyPreferredName": "Tridonic", + "vendorLandingPageURL": "https://www.tridonic.com/matter", + "creator": "cosmos16ad3em3nrqzf854p03audmgdl3pc384467yzav" + }, + { + "vendorID": 4978, + "vendorName": "innovation matters", + "companyLegalName": "innovation matters iot GmbH", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.innovation-matters.at/", + "creator": "cosmos1v6x4nte50al0jjynvldwqse9n4ceajmja3wvph" + }, + { + "vendorID": 4991, + "vendorName": "NEO", + "companyLegalName": "Shenzhen NEO Electronic CO", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos18cvsug5mc7vj9a6kxaj0fwp99vj9ga3xd3lnql" + }, + { + "vendorID": 4993, + "vendorName": "Amazon Prime Video", + "companyLegalName": "Amazon.com, Inc.", + "companyPreferredName": "Amazon Prime Video", + "vendorLandingPageURL": "https://www.amazon.com", + "creator": "cosmos1akrkaxvlfwnnk2phtxewadmel4s567wr8xmfj8" + }, + { + "vendorID": 4996, + "vendorName": "Apple Keychain", + "companyLegalName": "Apple Inc.", + "companyPreferredName": "", + "vendorLandingPageURL": "https://support.apple.com/en-us/HT213441", + "creator": "cosmos1qqgp6p73z0lku4qzeajgtxtzy24xx467j0v0kp" + }, + { + "vendorID": 4998, + "vendorName": "Skylux", + "companyLegalName": "Skylux N.V.", + "companyPreferredName": "Skylux", + "vendorLandingPageURL": "https://www.skylux.eu", + "creator": "cosmos1f9haxa732cy6rmm3nc88q9fxx9zv0m0qn3kzcm" + }, + { + "vendorID": 4999, + "vendorName": "Qianyan", + "companyLegalName": "Shenzhen Qianyan Technology LTD", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos10plhr0fh27nred7nra3s6dld26gzcw6etje4gk" + }, + { + "vendorID": 5002, + "vendorName": "Nature", + "companyLegalName": "Nature Inc.", + "companyPreferredName": "", + "vendorLandingPageURL": "https://nature.global/", + "creator": "cosmos1yvwf85sx9mp53kptfwfz49cmmznvj2j0efavzu" + }, + { + "vendorID": 5009, + "vendorName": "Kasa", + "companyLegalName": "TP-Link Corporation Limited", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.kasasmart.com", + "creator": "cosmos1fjwwzm8zs9yc2hq73tqggdylcmm0ujmuc7x9wn" + }, + { + "vendorID": 5010, + "vendorName": "Tapo", + "companyLegalName": "TP-Link Corporation Limited", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.tapo.com", + "creator": "cosmos1acw4mmmf26e7jkxqm5epu7g56tcgz0walk3vs8" + }, + { + "vendorID": 5015, + "vendorName": "SwitchBot", + "companyLegalName": "Woan Technology (Shenzhen) Co., Ltd. ", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos1dc9patujyr2av2ezggudfalfag7p7scc0t3wnk" + }, + { + "vendorID": 5020, + "vendorName": "Zemismart Technology Limited", + "companyLegalName": "Zemismart Technology Limited", + "companyPreferredName": "Zemismart", + "vendorLandingPageURL": "https://www.zemismart.com", + "creator": "cosmos1mrv5zh6r6kcfln34vju5kfup4mv9lw27u33yj0" + }, + { + "vendorID": 5120, + "vendorName": "Uascent", + "companyLegalName": "Uascent Technology Company Limited", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos1ynw4zl6xqnvh5zhzhhpxjc6kt8z8wvxkp8edsw" + }, + { + "vendorID": 5123, + "vendorName": "Arlec Australia", + "companyLegalName": "Arlec Australia Pty. Ltd.", + "companyPreferredName": "Grid Connect", + "vendorLandingPageURL": "https://grid-connect.com.au/", + "creator": "cosmos1d9ut0ysdlw68r0705q8tagf7y9cf3d686fpf73" + }, + { + "vendorID": 5124, + "vendorName": "Phaten", + "companyLegalName": "Shenzhen Phaten Technology Co., Ltd.", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.phaten.com", + "creator": "cosmos1h4rf0hjzf498s2lu0rf8m52ujst2gl7lpdnexs" + }, + { + "vendorID": 5127, + "vendorName": "ThirdReality", + "companyLegalName": "Jiangsu Shushi Technology Co., Ltd.", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos1qwnh6tj4n938g3fmncqna22zmfxx50vnd22yux" + }, + { + "vendorID": 5136, + "vendorName": "Quectel", + "companyLegalName": "Quectel Wireless Solutions Co., Ltd.", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.quectel.com", + "creator": "cosmos1dqrg6w2jjs7sft59dpqngjzyfdjh4xjn5rjct5" + }, + { + "vendorID": 5139, + "vendorName": "1Home", + "companyLegalName": "1Home Solutions GmbH", + "companyPreferredName": "", + "vendorLandingPageURL": "https://www.1home.io/", + "creator": "cosmos1nzyp28afpumk0djal2w35s2pcl0q3e57euplkq" + }, + { + "vendorID": 5141, + "vendorName": "Caveman", + "companyLegalName": "Nanoleaf Ltd.", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos1smgmnl90h9srczk926l5kt7rydjpq7x0smc5e7" + }, + { + "vendorID": 5145, + "vendorName": "Lorex", + "companyLegalName": "Lorex Technology Inc.", + "companyPreferredName": "Lorex", + "vendorLandingPageURL": "https://www.lorex.com/", + "creator": "cosmos1c98nn3uphuya0w4km5uzamjwpkawksf5g6h5m5" + }, + { + "vendorID": 5147, + "vendorName": "Rang Dong VN", + "companyLegalName": "Rang Dong Light Source \u0026 Vacuum Flask JSC", + "companyPreferredName": "Rang Dong Light Source \u0026 Vacuum Flask JSC", + "vendorLandingPageURL": "https://rangdong.com.vn/", + "creator": "cosmos1023z8vredmrn7xlzjlrlv6wdqh0fpzs8jlc9rx" + }, + { + "vendorID": 5150, + "vendorName": "TUO Accessories LLC", + "companyLegalName": "TUO Accessories LLC", + "companyPreferredName": "TUO Accessories", + "vendorLandingPageURL": "http://tuoaccessories.com", + "creator": "cosmos1vn34dnlqvz5e997ws53yfj6a2622duzf3gg80d" + }, + { + "vendorID": 5151, + "vendorName": "Ductech", + "companyLegalName": "DUCTECH Co., Ltd.", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos18nqp48ce5k7j8qvuwk7tnzmckwsd8k2tlnj850" + }, + { + "vendorID": 5165, + "vendorName": "QH", + "companyLegalName": "Zhongshan QIHANG Electronic Technology Co.", + "companyPreferredName": "QIHANG", + "vendorLandingPageURL": "https://zsqhkj.1688.com/", + "creator": "cosmos13zzg6t6gaz36p8ctguatrguwuep9wmza6lptet" + }, + { + "vendorID": 5167, + "vendorName": "QIACHIP", + "companyLegalName": "Shenzhen QIACHIP Wireless E-commerce Co.", + "companyPreferredName": "QIACHIP", + "vendorLandingPageURL": "https://qiachip.com", + "creator": "cosmos1rhjya3hdvpyr2a3ur7s5hj48ce2qndyfcz07ht" + }, + { + "vendorID": 24582, + "vendorName": "Google LLC", + "companyLegalName": "Google LLC", + "companyPreferredName": "", + "vendorLandingPageURL": "", + "creator": "cosmos1kelvhh6cy2vmaj5zczxj52k4nys2w4e2u3awvq" + } + ], + "pagination": { + "next_key": null, + "total": "73" + } +} \ No newline at end of file diff --git a/lib/libesp32/berry_tasmota/include/be_ctypes.h b/lib/libesp32/berry_tasmota/include/be_ctypes.h index 5e029100b7e4..abaffa8c31ff 100644 --- a/lib/libesp32/berry_tasmota/include/be_ctypes.h +++ b/lib/libesp32/berry_tasmota/include/be_ctypes.h @@ -60,7 +60,13 @@ typedef struct be_ctypes_classes_t { const be_ctypes_class_t * classes; } be_ctypes_classes_t; -BE_EXPORT_VARIABLE const bclass be_class_ctypes_bytes; +#ifdef __cplusplus +extern "C" { +#endif + extern const bclass be_class_ctypes_bytes; +#ifdef __cplusplus +} +#endif static void ctypes_register_class(bvm *vm, const bclass * ctypes_class) { be_pushntvclass(vm, ctypes_class); diff --git a/lib/libesp32/berry_tasmota/include/be_port.h b/lib/libesp32/berry_tasmota/include/be_port.h new file mode 100644 index 000000000000..91e7fe8faf17 --- /dev/null +++ b/lib/libesp32/berry_tasmota/include/be_port.h @@ -0,0 +1,10 @@ +/******************************************************************** + * Tasmota - constants used in be_port and be_path_tasmota.lib.c + *******************************************************************/ +#define MPATH_MKDIR 0 +#define MPATH_RMDIR 1 +#define MPATH_LISTDIR 2 +#define MPATH_ISDIR 3 +#define MPATH_EXISTS 4 +#define MPATH_MODIFIED 5 +#define MPATH_REMOVE 6 diff --git a/lib/libesp32/berry_tasmota/solidify_all.be b/lib/libesp32/berry_tasmota/solidify_all.be index 8f2575595472..bf2ebfc6a38d 100755 --- a/lib/libesp32/berry_tasmota/solidify_all.be +++ b/lib/libesp32/berry_tasmota/solidify_all.be @@ -46,7 +46,7 @@ def parse_file(fname, prefix_out) # output solidified var fname_h = string.split(fname, '.be')[0] + '.h' # take whatever is before the first '.be' var fout = open(prefix_out + "solidified_" + fname_h, "w") - fout.write(string.format("/* Solidification of %s */\n", fname_h)) + fout.write(format("/* Solidification of %s */\n", fname_h)) fout.write("/********************************************************************\\\n") fout.write("* Generated code, don't edit *\n") fout.write("\\********************************************************************/\n") diff --git a/lib/libesp32/berry_tasmota/src/be_cron_class.cpp b/lib/libesp32/berry_tasmota/src/be_cron_class.cpp index 033dc81e7102..d5daf03f17ee 100644 --- a/lib/libesp32/berry_tasmota/src/be_cron_class.cpp +++ b/lib/libesp32/berry_tasmota/src/be_cron_class.cpp @@ -21,7 +21,7 @@ static cron_expr* ccronexpr_init(struct bvm* vm, char* expr) { cron_parse_expr(expr, cron, &error); if (error) { - be_raise(vm, "value_error", error); // TODO any way to pass VM? + be_raise(vm, "value_error", error); } return cron; } diff --git a/lib/libesp32/berry_tasmota/src/be_crypto_lib.c b/lib/libesp32/berry_tasmota/src/be_crypto_lib.c index 621d171135a4..5cb5d7f10f71 100644 --- a/lib/libesp32/berry_tasmota/src/be_crypto_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_crypto_lib.c @@ -11,9 +11,13 @@ extern int be_class_crypto_member(bvm *vm); extern int m_crypto_random(bvm *vm); +extern int m_rsa_rsassa_pkcs1_v1_5(bvm *vm); + extern int m_aes_ccm_init(bvm *vm); -extern int m_aes_ccm_encryt(bvm *vm); -extern int m_aes_ccm_decryt(bvm *vm); +extern int m_aes_ccm_encrypt(bvm *vm); +extern int m_aes_ccm_encrypt1(bvm *vm); +extern int m_aes_ccm_decrypt(bvm *vm); +extern int m_aes_ccm_decrypt1(bvm *vm); extern int m_aes_ccm_tag(bvm *vm); extern int m_aes_gcm_init(bvm *vm); @@ -56,6 +60,7 @@ extern const bclass be_class_md5; #include "solidify/solidified_crypto_pbkdf2_hmac_sha256.h" #include "solidify/solidified_crypto_spake2p_matter.h" +#include "be_fixed_be_class_rsa.h" #include "be_fixed_be_class_aes_ccm.h" #include "be_fixed_be_class_aes_gcm.h" #include "be_fixed_be_class_aes_ctr.h" @@ -104,6 +109,10 @@ const be_const_member_t be_crypto_members[] = { { "/PBKDF2_HMAC_SHA256", (intptr_t) &be_class_pbkdf2_hmac_sha256 }, #endif // USE_BERRY_CRYPTO_PBKDF2_HMAC_SHA256 +#ifdef USE_BERRY_CRYPTO_RSA + { "/RSA", (intptr_t) &be_class_rsa }, +#endif // USE_BERRY_CRYPTO_PBKDF2_HMAC_SHA256 + #ifdef USE_BERRY_CRYPTO_SHA256 { "/SHA256", (intptr_t) &be_class_sha256 }, #endif // USE_BERRY_CRYPTO_SHA256 @@ -118,14 +127,21 @@ const size_t be_crypto_members_size = sizeof(be_crypto_members)/sizeof(be_crypto /* @const_object_info_begin +class be_class_rsa (scope: global, name: RSA) { + rs256, static_func(m_rsa_rsassa_pkcs1_v1_5) +} + class be_class_aes_ccm (scope: global, name: AES_CCM) { .p1, var .p2, var init, func(m_aes_ccm_init) - encrypt, func(m_aes_ccm_encryt) - decrypt, func(m_aes_ccm_decryt) + encrypt, func(m_aes_ccm_encrypt) + decrypt, func(m_aes_ccm_decrypt) tag, func(m_aes_ccm_tag) + + decrypt1, static_func(m_aes_ccm_decrypt1) + encrypt1, static_func(m_aes_ccm_encrypt1) } class be_class_aes_gcm (scope: global, name: AES_GCM) { diff --git a/lib/libesp32/berry_tasmota/src/be_display_lib.cpp b/lib/libesp32/berry_tasmota/src/be_display_lib.c similarity index 96% rename from lib/libesp32/berry_tasmota/src/be_display_lib.cpp rename to lib/libesp32/berry_tasmota/src/be_display_lib.c index acd0754fb8a6..f1dbdad8ca81 100644 --- a/lib/libesp32/berry_tasmota/src/be_display_lib.cpp +++ b/lib/libesp32/berry_tasmota/src/be_display_lib.c @@ -12,7 +12,7 @@ extern int be_ntv_display_start(bvm *vm); extern int be_ntv_display_dimmer(bvm *vm); -extern bool be_ntv_display_started(void); +extern bbool be_ntv_display_started(void); BE_FUNC_CTYPE_DECLARE(be_ntv_display_started, "b", "") extern void be_ntv_display_touch_update(int32_t touches, int32_t raw_x, int32_t raw_y, int32_t gesture); BE_FUNC_CTYPE_DECLARE(be_ntv_display_touch_update, "", "iiii") diff --git a/lib/libesp32/berry_tasmota/src/be_energylib.c b/lib/libesp32/berry_tasmota/src/be_energylib.c index 3142872befe7..984af678b037 100644 --- a/lib/libesp32/berry_tasmota/src/be_energylib.c +++ b/lib/libesp32/berry_tasmota/src/be_energylib.c @@ -10,6 +10,7 @@ #ifdef USE_ENERGY_SENSOR extern struct ENERGY Energy; +extern int energy_update_total(bvm *vm); #include "solidify/solidified_energy.h" #include "be_fixed_energy.h" @@ -24,6 +25,8 @@ module energy (scope: global) { read, closure(energy_read_closure) member, closure(energy_member_closure) setmember, closure(energy_setmember_closure) + + update_total, func(energy_update_total) } @const_object_info_end */ diff --git a/lib/libesp32/berry_tasmota/src/be_i2s_audio_lib.cpp b/lib/libesp32/berry_tasmota/src/be_i2s_audio_lib.cpp index 4ff02c6e1b29..40322c08f060 100644 --- a/lib/libesp32/berry_tasmota/src/be_i2s_audio_lib.cpp +++ b/lib/libesp32/berry_tasmota/src/be_i2s_audio_lib.cpp @@ -39,69 +39,55 @@ extern "C" { } // AudioOutput.set_rate(rate_hz:int) -> bool -AudioOutput* be_audio_output_init_ntv(void) { +AudioOutput* be_audio_output_init(void) { return new AudioOutput(); } -int32_t be_audio_output_init(struct bvm *vm) { - return be_call_c_func(vm, (void*) &be_audio_output_init_ntv, "+.p", ""); -} +BE_FUNC_CTYPE_DECLARE(be_audio_output_init, "+.p", ""); // AudioOutput.set_rate(rate_hz:int) -> bool -int be_audio_output_set_rate_ntv(AudioOutput* out, int hz) { +int be_audio_output_set_rate(AudioOutput* out, int hz) { return out->SetRate(hz); } -int32_t be_audio_output_set_rate(struct bvm *vm) { - return be_call_c_func(vm, (void*) &be_audio_output_set_rate_ntv, "b", ".i"); -} +BE_FUNC_CTYPE_DECLARE(be_audio_output_set_rate, "b", ".i"); // AudioOutput.set_bits_per_sample(bits_per_sample:int) -> bool -int be_audio_output_set_bits_per_sample_ntv(AudioOutput* out, int bps) { +int be_audio_output_set_bits_per_sample(AudioOutput* out, int bps) { return out->SetBitsPerSample(bps); } -int32_t be_audio_output_set_bits_per_sample(struct bvm *vm) { - return be_call_c_func(vm, (void*) &be_audio_output_set_bits_per_sample_ntv, "b", ".i"); -} +BE_FUNC_CTYPE_DECLARE(be_audio_output_set_bits_per_sample, "b", ".i"); // AudioOutput.set_channels(channels:int) -> bool -int be_audio_output_set_channels_ntv(AudioOutput* out, int channels) { +int be_audio_output_set_channels(AudioOutput* out, int channels) { return out->SetChannels(channels); } -int32_t be_audio_output_set_channels(struct bvm *vm) { - return be_call_c_func(vm, (void*) &be_audio_output_set_channels_ntv, "b", ".i"); -} +BE_FUNC_CTYPE_DECLARE(be_audio_output_set_channels, "b", ".i"); // AudioOutput.set_gain(gain:real) -> bool -int be_audio_output_set_gain_ntv(AudioOutput* out, float gain) { +int be_audio_output_set_gain(AudioOutput* out, float gain) { return out->SetGain(gain); } -int32_t be_audio_output_set_gain(struct bvm *vm) { - return be_call_c_func(vm, (void*) &be_audio_output_set_gain_ntv, "b", ".f"); -} +BE_FUNC_CTYPE_DECLARE(be_audio_output_set_gain, "b", ".f"); // AudioOutput.begin() -> bool -int be_audio_output_begin_ntv(AudioOutput* out) { +int be_audio_output_begin(AudioOutput* out) { return out->begin(); } -int32_t be_audio_output_begin(struct bvm *vm) { - return be_call_c_func(vm, (void*) &be_audio_output_begin_ntv, "b", "."); -} +BE_FUNC_CTYPE_DECLARE(be_audio_output_begin, "b", "."); + // AudioOutput.stop() -> bool -int be_audio_output_stop_ntv(AudioOutput* out) { +int be_audio_output_stop(AudioOutput* out) { return out->stop(); } -int32_t be_audio_output_stop(struct bvm *vm) { - return be_call_c_func(vm, (void*) &be_audio_output_stop_ntv, "b", "."); -} +BE_FUNC_CTYPE_DECLARE(be_audio_output_stop, "b", "."); + // AudioOutput.flush() -> bool -void be_audio_output_flush_ntv(AudioOutput* out) { +void be_audio_output_flush(AudioOutput* out) { out->flush(); } -int32_t be_audio_output_flush(struct bvm *vm) { - return be_call_c_func(vm, (void*) &be_audio_output_flush_ntv, "", "."); -} +BE_FUNC_CTYPE_DECLARE(be_audio_output_flush, "", "."); // AudioOutput.consume_mono(bytes) -> int -int be_audio_output_consume_mono_ntv(AudioOutput* out, uint16_t *pcm, int bytes_len, int index) { +int be_audio_output_consume_mono(AudioOutput* out, uint16_t *pcm, int bytes_len, int index) { int pcm_len = bytes_len / 2; int n; // berry_log_C("be_audio_output_consume_mono_ntv out=%p pcm=%p bytes_len=%i index=%i", out, pcm, bytes_len, index); @@ -112,12 +98,10 @@ int be_audio_output_consume_mono_ntv(AudioOutput* out, uint16_t *pcm, int bytes_ } return n; } -int32_t be_audio_output_consume_mono(struct bvm *vm) { - return be_call_c_func(vm, (void*) &be_audio_output_consume_mono_ntv, "i", ".(bytes)~i"); -} +BE_FUNC_CTYPE_DECLARE(be_audio_output_consume_mono, "i", ".(bytes)~i"); // AudioOutput.consume_stereo(bytes) -> int -int be_audio_output_consume_stereo_ntv(AudioOutput* out, uint16_t *pcm, int bytes_len, int index) { +int be_audio_output_consume_stereo(AudioOutput* out, uint16_t *pcm, int bytes_len, int index) { int pcm_len = bytes_len / 4; // 2 samples LEFT+RIGHT of 2 bytes each int n; // berry_log_C("be_audio_output_consume_stereo_ntv out=%p pcm=%p bytes_len=%i index=%i", out, pcm, bytes_len, index); @@ -129,12 +113,10 @@ int be_audio_output_consume_stereo_ntv(AudioOutput* out, uint16_t *pcm, int byte } return n; } -int32_t be_audio_output_consume_stereo(struct bvm *vm) { - return be_call_c_func(vm, (void*) &be_audio_output_consume_stereo_ntv, "i", ".(bytes)~i"); -} +BE_FUNC_CTYPE_DECLARE(be_audio_output_consume_stereo, "i", ".(bytes)~i"); // AudioOutput.consume_silence() -> int, push silence frames -int be_audio_output_consume_silence_ntv(AudioOutput* out) { +int be_audio_output_consume_silence(AudioOutput* out) { int n = 0; int16_t ms[2] = {0, 0}; while (true) { @@ -143,12 +125,16 @@ int be_audio_output_consume_silence_ntv(AudioOutput* out) { } return n; } -int32_t be_audio_output_consume_silence(struct bvm *vm) { - return be_call_c_func(vm, (void*) &be_audio_output_consume_silence_ntv, "i", "."); -} +BE_FUNC_CTYPE_DECLARE(be_audio_output_consume_silence, "i", "."); #include "AudioOutputI2S.h" +// AudioOutputI2S.set_lsb_justified(gain:real) -> nil +int i2s_output_i2s_set_lsb_justified(AudioOutputI2S* out, bbool lsbJustified) { + return out->SetLsbJustified(lsbJustified); +} +BE_FUNC_CTYPE_DECLARE(i2s_output_i2s_set_lsb_justified, "b", ".b"); + extern "C" { #include "be_fixed_be_class_AudioOutput.h" @@ -164,20 +150,20 @@ extern "C" { class be_class_AudioOutput (scope: global, name: AudioOutput, strings: weak) { .p, var - init, func(be_audio_output_init) + init, ctype_func(be_audio_output_init) - begin, func(be_audio_output_begin) - stop, func(be_audio_output_stop) - flush, func(be_audio_output_flush) + begin, ctype_func(be_audio_output_begin) + stop, ctype_func(be_audio_output_stop) + flush, ctype_func(be_audio_output_flush) - consume_mono, func(be_audio_output_consume_mono) - consume_stereo, func(be_audio_output_consume_stereo) - consume_silence, func(be_audio_output_consume_silence) + consume_mono, ctype_func(be_audio_output_consume_mono) + consume_stereo, ctype_func(be_audio_output_consume_stereo) + consume_silence, ctype_func(be_audio_output_consume_silence) - set_rate, func(be_audio_output_set_rate) - set_bits_per_sample, func(be_audio_output_set_bits_per_sample) - set_channels, func(be_audio_output_set_channels) - set_gain, func(be_audio_output_set_gain) + set_rate, ctype_func(be_audio_output_set_rate) + set_bits_per_sample, ctype_func(be_audio_output_set_bits_per_sample) + set_channels, ctype_func(be_audio_output_set_channels) + set_gain, ctype_func(be_audio_output_set_gain) } class be_class_AudioGenerator (scope: global, name: AudioGenerator, strings: weak) { @@ -196,6 +182,8 @@ class be_class_AudioOutputI2S (scope: global, name: AudioOutputI2S, super: be_cl init, func(i2s_output_i2s_init) deinit, func(i2s_output_i2s_deinit) stop, func(i2s_output_i2s_stop) + + set_lsb_justified, ctype_func(i2s_output_i2s_set_lsb_justified) } class be_class_AudioGeneratorWAV (scope: global, name: AudioGeneratorWAV, super: be_class_AudioGenerator, strings: weak) { diff --git a/lib/libesp32/berry_tasmota/src/be_light_state_class.c b/lib/libesp32/berry_tasmota/src/be_light_state_class.c new file mode 100644 index 000000000000..fa68e51504f4 --- /dev/null +++ b/lib/libesp32/berry_tasmota/src/be_light_state_class.c @@ -0,0 +1,115 @@ +/******************************************************************** + * Light_state class - abstract light state + * + * Handles all states and events for a virtual light. + * Can be eventually subclassed to handle a physical light. + * + *******************************************************************/ +#ifdef USE_LIGHT + +#include "be_constobj.h" +#include "be_mapping.h" + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +extern void * ls_init(int32_t type); BE_FUNC_CTYPE_DECLARE(ls_init, "+_p", "i") +extern void ls_set_rgb(void* l, int32_t r, int32_t g, int32_t b); BE_FUNC_CTYPE_DECLARE(ls_set_rgb, "", ".iii") +extern void ls_set_huesat(void* l, int32_t hue, int32_t sat); BE_FUNC_CTYPE_DECLARE(ls_set_huesat, "", ".ii") +extern void ls_set_hue16sat(void* l, int32_t hue16, int32_t sat); BE_FUNC_CTYPE_DECLARE(ls_set_hue16sat, "", ".ii") +extern void ls_set_ct(void* l, int32_t ct); BE_FUNC_CTYPE_DECLARE(ls_set_ct, "", ".i") +extern void ls_set_bri(void* l, int32_t bri); BE_FUNC_CTYPE_DECLARE(ls_set_bri, "", ".i") +extern void ls_set_xy(void* l, float x, float y); BE_FUNC_CTYPE_DECLARE(ls_set_xy, "", ".ff") +extern int32_t ls_r(void* l); BE_VAR_CTYPE_DECLARE(ls_r, "i"); +extern int32_t ls_g(void* l); BE_VAR_CTYPE_DECLARE(ls_g, "i"); +extern int32_t ls_b(void* l); BE_VAR_CTYPE_DECLARE(ls_b, "i"); +extern float ls_x(void* l); BE_VAR_CTYPE_DECLARE(ls_x, "f"); +extern float ls_y(void* l); BE_VAR_CTYPE_DECLARE(ls_y, "f"); +extern int32_t ls_hue(void* l); BE_VAR_CTYPE_DECLARE(ls_hue, "i"); +extern int32_t ls_hue16(void* l); BE_VAR_CTYPE_DECLARE(ls_hue16, "i"); +extern int32_t ls_sat(void* l); BE_VAR_CTYPE_DECLARE(ls_sat, "i"); +extern int32_t ls_bri(void* l); BE_VAR_CTYPE_DECLARE(ls_bri, "i"); +extern int32_t ls_ct(void* l); BE_VAR_CTYPE_DECLARE(ls_ct, "i"); +extern int32_t ls_type(void* l); BE_VAR_CTYPE_DECLARE(ls_type, "i"); + +extern int32_t ls_mode_rgb(void* l); BE_VAR_CTYPE_DECLARE(ls_mode_rgb, "b"); +extern int32_t ls_mode_ct(void* l); BE_VAR_CTYPE_DECLARE(ls_mode_ct, "b"); +extern void ls_set_mode_rgb(void* l); BE_FUNC_CTYPE_DECLARE(ls_set_mode_rgb, "", "."); +extern void ls_set_mode_ct(void* l); BE_FUNC_CTYPE_DECLARE(ls_set_mode_ct, "", "."); +extern int32_t ls_get_power(void* l); BE_VAR_CTYPE_DECLARE(ls_get_power, "b"); +extern void ls_set_power(void* l, int32_t pow); BE_FUNC_CTYPE_DECLARE(ls_set_power, "", ".b"); +extern int32_t ls_reachable(void* p); BE_VAR_CTYPE_DECLARE(ls_reachable, "b"); +extern void ls_set_reachable(void* l, int32_t pow); BE_FUNC_CTYPE_DECLARE(ls_set_reachable, "", ".b"); + +extern void ls_signal_change(void) {} BE_FUNC_CTYPE_DECLARE(ls_signal_change, "", "."); + +extern int32_t ls_gamma8(int32_t val); BE_FUNC_CTYPE_DECLARE(ls_gamma8, "i", "i") +extern int32_t ls_gamma10(int32_t val); BE_FUNC_CTYPE_DECLARE(ls_gamma10, "i", "i") +extern int32_t ls_rev_gamma10(int32_t val); BE_FUNC_CTYPE_DECLARE(ls_rev_gamma10, "i", "i") + +// moved to constants array +const be_const_member_t light_state_members[] = { + { ">b", be_ctype(ls_b) }, + { ">bri", be_ctype(ls_bri) }, + { ">ct", be_ctype(ls_ct) }, + { ">g", be_ctype(ls_g) }, + { ">hue", be_ctype(ls_hue) }, + { ">hue16", be_ctype(ls_hue16) }, + { ">mode_ct", be_ctype(ls_mode_ct) }, + { ">mode_rgb", be_ctype(ls_mode_rgb) }, + { ">power", be_ctype(ls_get_power) }, + { ">r", be_ctype(ls_r) }, + { ">reachable", be_ctype(ls_reachable) }, + { ">sat", be_ctype(ls_sat) }, + { ">type", be_ctype(ls_type) }, + { ">x", be_ctype(ls_x) }, + { ">y", be_ctype(ls_y) }, +}; + +extern int light_state_get(bvm *vm); + +static int light_state_member(bvm *vm) { + be_const_class_member_raise(vm, light_state_members, ARRAY_SIZE(light_state_members)); + be_return(vm); +} + +#include "be_fixed_be_class_light_state.h" + +/* @const_object_info_begin +class be_class_light_state (scope: global, name: light_state) { + RELAY, int(0) + DIMMER, int(1) + CT, int(2) + RGB, int(3) + RGBW, int(4) + RGBCT, int(5) + + _p, var + init, ctype_func(ls_init) + + member, func(light_state_member) + + set_rgb, ctype_func(ls_set_rgb) + set_huesat, ctype_func(ls_set_huesat) + set_hue16sat, ctype_func(ls_set_hue16sat) + set_xy, ctype_func(ls_set_xy) + set_ct, ctype_func(ls_set_ct) + set_bri, ctype_func(ls_set_bri) + + set_mode_rgb, ctype_func(ls_set_mode_rgb) + set_mode_ct, ctype_func(ls_set_mode_ct) + set_power, ctype_func(ls_set_power) + set_reachable, ctype_func(ls_set_reachable) + + get, func(light_state_get) + + signal_change, ctype_func(ls_signal_change) + + gamma8, static_ctype_func(ls_gamma8) + gamma10, static_ctype_func(ls_gamma10) + reverse_gamma10, static_ctype_func(ls_rev_gamma10) +} +@const_object_info_end */ + +#endif // USE_LIGHT diff --git a/lib/libesp32/berry_tasmota/src/be_light_state_class.cpp b/lib/libesp32/berry_tasmota/src/be_light_state_class.cpp deleted file mode 100644 index 7d81ce6864b6..000000000000 --- a/lib/libesp32/berry_tasmota/src/be_light_state_class.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************** - * Light_state class - abstract light state - * - * Handles all states and events for a virtual light. - * Can be eventually subclassed to handle a physical light. - * - *******************************************************************/ -#ifdef USE_LIGHT - -#include "be_constobj.h" -#include "be_mapping.h" - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#endif - -extern void * ls_init(int32_t type); BE_FUNC_CTYPE_DECLARE(ls_init, "+_p", "i") -extern void ls_set_rgb(class LightStateClass* l, int32_t r, int32_t g, int32_t b); BE_FUNC_CTYPE_DECLARE(ls_set_rgb, "", ".iii") -extern void ls_set_huesat(class LightStateClass* l, int32_t hue, int32_t sat); BE_FUNC_CTYPE_DECLARE(ls_set_huesat, "", ".ii") -extern void ls_set_hue16sat(class LightStateClass* l, int32_t hue16, int32_t sat); BE_FUNC_CTYPE_DECLARE(ls_set_hue16sat, "", ".ii") -extern void ls_set_ct(class LightStateClass* l, int32_t ct); BE_FUNC_CTYPE_DECLARE(ls_set_ct, "", ".i") -extern void ls_set_bri(class LightStateClass* l, int32_t bri); BE_FUNC_CTYPE_DECLARE(ls_set_bri, "", ".i") -extern void ls_set_xy(class LightStateClass* l, float x, float y); BE_FUNC_CTYPE_DECLARE(ls_set_xy, "", ".ff") -extern int32_t ls_r(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_r, "i"); -extern int32_t ls_g(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_g, "i"); -extern int32_t ls_b(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_b, "i"); -extern float ls_x(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_x, "f"); -extern float ls_y(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_y, "f"); -extern int32_t ls_hue(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_hue, "i"); -extern int32_t ls_hue16(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_hue16, "i"); -extern int32_t ls_sat(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_sat, "i"); -extern int32_t ls_bri(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_bri, "i"); -extern int32_t ls_ct(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_ct, "i"); -extern int32_t ls_type(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_type, "i"); - -extern int32_t ls_mode_rgb(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_mode_rgb, "b"); -extern int32_t ls_mode_ct(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_mode_ct, "b"); -extern void ls_set_mode_rgb(class LightStateClass* l); BE_FUNC_CTYPE_DECLARE(ls_set_mode_rgb, "", "."); -extern void ls_set_mode_ct(class LightStateClass* l); BE_FUNC_CTYPE_DECLARE(ls_set_mode_ct, "", "."); -extern int32_t ls_get_power(class LightStateClass* l); BE_VAR_CTYPE_DECLARE(ls_get_power, "b"); -extern void ls_set_power(class LightStateClass* l, int32_t pow); BE_FUNC_CTYPE_DECLARE(ls_set_power, "", ".b"); -extern int32_t ls_reachable(class LightStateClass* p); BE_VAR_CTYPE_DECLARE(ls_reachable, "b"); -extern void ls_set_reachable(class LightStateClass* l, int32_t pow); BE_FUNC_CTYPE_DECLARE(ls_set_reachable, "", ".b"); - -extern void ls_signal_change(void) {} BE_FUNC_CTYPE_DECLARE(ls_signal_change, "", "."); - -extern int32_t ls_gamma8(int32_t val); BE_FUNC_CTYPE_DECLARE(ls_gamma8, "i", "i") -extern int32_t ls_gamma10(int32_t val); BE_FUNC_CTYPE_DECLARE(ls_gamma10, "i", "i") -extern int32_t ls_rev_gamma10(int32_t val); BE_FUNC_CTYPE_DECLARE(ls_rev_gamma10, "i", "i") - -// moved to constants array -const be_const_member_t light_state_members[] = { - { ">b", be_ctype(ls_b) }, - { ">bri", be_ctype(ls_bri) }, - { ">ct", be_ctype(ls_ct) }, - { ">g", be_ctype(ls_g) }, - { ">hue", be_ctype(ls_hue) }, - { ">hue16", be_ctype(ls_hue16) }, - { ">mode_ct", be_ctype(ls_mode_ct) }, - { ">mode_rgb", be_ctype(ls_mode_rgb) }, - { ">power", be_ctype(ls_get_power) }, - { ">r", be_ctype(ls_r) }, - { ">reachable", be_ctype(ls_reachable) }, - { ">sat", be_ctype(ls_sat) }, - { ">type", be_ctype(ls_type) }, - { ">x", be_ctype(ls_x) }, - { ">y", be_ctype(ls_y) }, -}; - -extern "C" int light_state_get(bvm *vm); - -static int light_state_member(bvm *vm) { - be_const_class_member_raise(vm, light_state_members, ARRAY_SIZE(light_state_members)); - be_return(vm); -} - -#include "be_fixed_be_class_light_state.h" - -extern "C" void be_load_light_state_class(bvm *vm) { - be_pushntvclass(vm, &be_class_light_state); - be_setglobal(vm, "light_state"); - be_pop(vm, 1); -} - -/* @const_object_info_begin -class be_class_light_state (scope: global, name: light_state) { - RELAY, int(0) - DIMMER, int(1) - CT, int(2) - RGB, int(3) - RGBW, int(4) - RGBCT, int(5) - - _p, var - init, ctype_func(ls_init) - - member, func(light_state_member) - - set_rgb, ctype_func(ls_set_rgb) - set_huesat, ctype_func(ls_set_huesat) - set_hue16sat, ctype_func(ls_set_hue16sat) - set_xy, ctype_func(ls_set_xy) - set_ct, ctype_func(ls_set_ct) - set_bri, ctype_func(ls_set_bri) - - set_mode_rgb, ctype_func(ls_set_mode_rgb) - set_mode_ct, ctype_func(ls_set_mode_ct) - set_power, ctype_func(ls_set_power) - set_reachable, ctype_func(ls_set_reachable) - - get, func(light_state_get) - - signal_change, ctype_func(ls_signal_change) - - gamma8, static_ctype_func(ls_gamma8) - gamma10, static_ctype_func(ls_gamma10) - reverse_gamma10, static_ctype_func(ls_rev_gamma10) -} -@const_object_info_end */ - -#endif // USE_LIGHT diff --git a/lib/libesp32/berry_tasmota/src/be_lv_haspmota.c b/lib/libesp32/berry_tasmota/src/be_lv_haspmota.c index e2063c5d068f..5ed132c191c5 100644 --- a/lib/libesp32/berry_tasmota/src/be_lv_haspmota.c +++ b/lib/libesp32/berry_tasmota/src/be_lv_haspmota.c @@ -468,9 +468,170 @@ void be_load_lvh_page_class(bvm *vm) { extern const bclass be_class_lvh_obj; /******************************************************************** -** Solidified function: set_radius2 +** Solidified function: parse_color ********************************************************************/ -be_local_closure(lvh_obj_set_radius2, /* name */ +be_local_closure(lvh_obj_parse_color, /* name */ + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 4, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 10, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(string), + /* K1 */ be_nested_str_weak(toupper), + /* K2 */ be_const_int(0), + /* K3 */ be_const_int(1), + /* K4 */ be_nested_str_weak(_X23), + /* K5 */ be_nested_str_weak(x), + /* K6 */ be_nested_str_weak(X), + /* K7 */ be_nested_str_weak(A), + /* K8 */ be_nested_str_weak(F), + /* K9 */ be_nested_str_weak(byte), + /* K10 */ be_nested_str_weak(0), + /* K11 */ be_nested_str_weak(9), + /* K12 */ be_nested_str_weak(stop_iteration), + }), + be_str_weak(parse_hex), + &be_const_str_solidified, + ( &(const binstruction[57]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080301, // 0001 GETMET R2 R1 K1 + 0x5C100000, // 0002 MOVE R4 R0 + 0x7C080400, // 0003 CALL R2 2 + 0x5C000400, // 0004 MOVE R0 R2 + 0x58080002, // 0005 LDCONST R2 K2 + 0x600C0010, // 0006 GETGBL R3 G16 + 0x6010000C, // 0007 GETGBL R4 G12 + 0x5C140000, // 0008 MOVE R5 R0 + 0x7C100200, // 0009 CALL R4 1 + 0x04100903, // 000A SUB R4 R4 K3 + 0x40120404, // 000B CONNECT R4 K2 R4 + 0x7C0C0200, // 000C CALL R3 1 + 0xA8020026, // 000D EXBLK 0 #0035 + 0x5C100600, // 000E MOVE R4 R3 + 0x7C100000, // 000F CALL R4 0 + 0x94140004, // 0010 GETIDX R5 R0 R4 + 0x1C180B04, // 0011 EQ R6 R5 K4 + 0x781A0000, // 0012 JMPF R6 #0014 + 0x7001FFF9, // 0013 JMP #000E + 0x1C180B05, // 0014 EQ R6 R5 K5 + 0x741A0001, // 0015 JMPT R6 #0018 + 0x1C180B06, // 0016 EQ R6 R5 K6 + 0x781A0000, // 0017 JMPF R6 #0019 + 0x7001FFF4, // 0018 JMP #000E + 0x28180B07, // 0019 GE R6 R5 K7 + 0x781A000B, // 001A JMPF R6 #0027 + 0x18180B08, // 001B LE R6 R5 K8 + 0x781A0009, // 001C JMPF R6 #0027 + 0x541A0003, // 001D LDINT R6 4 + 0x38180406, // 001E SHL R6 R2 R6 + 0x8C1C0309, // 001F GETMET R7 R1 K9 + 0x5C240A00, // 0020 MOVE R9 R5 + 0x7C1C0400, // 0021 CALL R7 2 + 0x54220036, // 0022 LDINT R8 55 + 0x041C0E08, // 0023 SUB R7 R7 R8 + 0x30180C07, // 0024 OR R6 R6 R7 + 0x5C080C00, // 0025 MOVE R2 R6 + 0x7002000C, // 0026 JMP #0034 + 0x28180B0A, // 0027 GE R6 R5 K10 + 0x781A000A, // 0028 JMPF R6 #0034 + 0x18180B0B, // 0029 LE R6 R5 K11 + 0x781A0008, // 002A JMPF R6 #0034 + 0x541A0003, // 002B LDINT R6 4 + 0x38180406, // 002C SHL R6 R2 R6 + 0x8C1C0309, // 002D GETMET R7 R1 K9 + 0x5C240A00, // 002E MOVE R9 R5 + 0x7C1C0400, // 002F CALL R7 2 + 0x5422002F, // 0030 LDINT R8 48 + 0x041C0E08, // 0031 SUB R7 R7 R8 + 0x30180C07, // 0032 OR R6 R6 R7 + 0x5C080C00, // 0033 MOVE R2 R6 + 0x7001FFD8, // 0034 JMP #000E + 0x580C000C, // 0035 LDCONST R3 K12 + 0xAC0C0200, // 0036 CATCH R3 1 0 + 0xB0080000, // 0037 RAISE 2 R0 R0 + 0x80040400, // 0038 RET 1 R2 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_const_class(be_class_lvh_obj), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(_X23), + /* K3 */ be_nested_str_weak(lv), + /* K4 */ be_nested_str_weak(color), + /* K5 */ be_nested_str_weak(string), + /* K6 */ be_nested_str_weak(introspect), + /* K7 */ be_nested_str_weak(COLOR_), + /* K8 */ be_nested_str_weak(toupper), + /* K9 */ be_nested_str_weak(get), + }), + be_str_weak(parse_color), + &be_const_str_solidified, + ( &(const binstruction[40]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x84080000, // 0001 CLOSURE R2 P0 + 0x600C0008, // 0002 GETGBL R3 G8 + 0x5C100000, // 0003 MOVE R4 R0 + 0x7C0C0200, // 0004 CALL R3 1 + 0x5C000600, // 0005 MOVE R0 R3 + 0x940C0101, // 0006 GETIDX R3 R0 K1 + 0x1C0C0702, // 0007 EQ R3 R3 K2 + 0x780E0007, // 0008 JMPF R3 #0011 + 0xB80E0600, // 0009 GETNGBL R3 K3 + 0x8C0C0704, // 000A GETMET R3 R3 K4 + 0x5C140400, // 000B MOVE R5 R2 + 0x5C180000, // 000C MOVE R6 R0 + 0x7C140200, // 000D CALL R5 1 + 0x7C0C0400, // 000E CALL R3 2 + 0x80040600, // 000F RET 1 R3 + 0x70020011, // 0010 JMP #0023 + 0xA40E0A00, // 0011 IMPORT R3 K5 + 0xA4120C00, // 0012 IMPORT R4 K6 + 0x8C140708, // 0013 GETMET R5 R3 K8 + 0x5C1C0000, // 0014 MOVE R7 R0 + 0x7C140400, // 0015 CALL R5 2 + 0x00160E05, // 0016 ADD R5 K7 R5 + 0x8C180909, // 0017 GETMET R6 R4 K9 + 0xB8220600, // 0018 GETNGBL R8 K3 + 0x5C240A00, // 0019 MOVE R9 R5 + 0x7C180600, // 001A CALL R6 3 + 0x4C1C0000, // 001B LDNIL R7 + 0x201C0C07, // 001C NE R7 R6 R7 + 0x781E0004, // 001D JMPF R7 #0023 + 0xB81E0600, // 001E GETNGBL R7 K3 + 0x8C1C0F04, // 001F GETMET R7 R7 K4 + 0x5C240C00, // 0020 MOVE R9 R6 + 0x7C1C0400, // 0021 CALL R7 2 + 0x80040E00, // 0022 RET 1 R7 + 0xB80E0600, // 0023 GETNGBL R3 K3 + 0x8C0C0704, // 0024 GETMET R3 R3 K4 + 0x58140001, // 0025 LDCONST R5 K1 + 0x7C0C0400, // 0026 CALL R3 2 + 0x80040600, // 0027 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_pad_top2 +********************************************************************/ +be_local_closure(lvh_obj_set_pad_top2, /* name */ be_nested_proto( 7, /* nstack */ 2, /* argc */ @@ -483,11 +644,11 @@ be_local_closure(lvh_obj_set_radius2, /* name */ ( &(const bvalue[ 5]) { /* constants */ /* K0 */ be_nested_str_weak(_lv_part2_selector), /* K1 */ be_nested_str_weak(_lv_obj), - /* K2 */ be_nested_str_weak(set_style_radius), + /* K2 */ be_nested_str_weak(set_style_pad_top), /* K3 */ be_nested_str_weak(lv), /* K4 */ be_nested_str_weak(STATE_DEFAULT), }), - be_str_weak(set_radius2), + be_str_weak(set_pad_top2), &be_const_str_solidified, ( &(const binstruction[15]) { /* code */ 0x88080100, // 0000 GETMBR R2 R0 K0 @@ -512,11 +673,11 @@ be_local_closure(lvh_obj_set_radius2, /* name */ /******************************************************************** -** Solidified function: register_event_cb +** Solidified function: get_text_rule ********************************************************************/ -be_local_closure(lvh_obj_register_event_cb, /* name */ +be_local_closure(lvh_obj_get_text_rule, /* name */ be_nested_proto( - 8, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -524,36 +685,14 @@ be_local_closure(lvh_obj_register_event_cb, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(_page), - /* K1 */ be_nested_str_weak(_oh), - /* K2 */ be_nested_str_weak(_event_map), - /* K3 */ be_nested_str_weak(keys), - /* K4 */ be_nested_str_weak(register_event), - /* K5 */ be_nested_str_weak(stop_iteration), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(_text_rule), }), - be_str_weak(register_event_cb), + be_str_weak(get_text_rule), &be_const_str_solidified, - ( &(const binstruction[19]) { /* code */ + ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x60080010, // 0002 GETGBL R2 G16 - 0x880C0102, // 0003 GETMBR R3 R0 K2 - 0x8C0C0703, // 0004 GETMET R3 R3 K3 - 0x7C0C0200, // 0005 CALL R3 1 - 0x7C080200, // 0006 CALL R2 1 - 0xA8020006, // 0007 EXBLK 0 #000F - 0x5C0C0400, // 0008 MOVE R3 R2 - 0x7C0C0000, // 0009 CALL R3 0 - 0x8C100304, // 000A GETMET R4 R1 K4 - 0x5C180000, // 000B MOVE R6 R0 - 0x5C1C0600, // 000C MOVE R7 R3 - 0x7C100600, // 000D CALL R4 3 - 0x7001FFF8, // 000E JMP #0008 - 0x58080005, // 000F LDCONST R2 K5 - 0xAC080200, // 0010 CATCH R2 1 0 - 0xB0080000, // 0011 RAISE 2 R0 R0 - 0x80000000, // 0012 RET 0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -561,11 +700,11 @@ be_local_closure(lvh_obj_register_event_cb, /* name */ /******************************************************************** -** Solidified function: get_value_ofs_x +** Solidified function: get_obj ********************************************************************/ -be_local_closure(lvh_obj_get_value_ofs_x, /* name */ +be_local_closure(lvh_obj_get_obj, /* name */ be_nested_proto( - 3, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -573,17 +712,14 @@ be_local_closure(lvh_obj_get_value_ofs_x, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_label), - /* K1 */ be_nested_str_weak(get_x), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_obj), }), - be_str_weak(get_value_ofs_x), + be_str_weak(get_obj), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ + ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -591,11 +727,11 @@ be_local_closure(lvh_obj_get_value_ofs_x, /* name */ /******************************************************************** -** Solidified function: set_value_ofs_x +** Solidified function: set_pad_left2 ********************************************************************/ -be_local_closure(lvh_obj_set_value_ofs_x, /* name */ +be_local_closure(lvh_obj_set_pad_left2, /* name */ be_nested_proto( - 6, /* nstack */ + 7, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -603,33 +739,41 @@ be_local_closure(lvh_obj_set_value_ofs_x, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(check_label), - /* K1 */ be_nested_str_weak(_lv_label), - /* K2 */ be_nested_str_weak(set_x), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_part2_selector), + /* K1 */ be_nested_str_weak(_lv_obj), + /* K2 */ be_nested_str_weak(set_style_pad_left), + /* K3 */ be_nested_str_weak(lv), + /* K4 */ be_nested_str_weak(STATE_DEFAULT), }), - be_str_weak(set_value_ofs_x), + be_str_weak(set_pad_left2), &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x7C080200, // 0001 CALL R2 1 - 0x88080101, // 0002 GETMBR R2 R0 K1 - 0x8C080502, // 0003 GETMET R2 R2 K2 - 0x60100009, // 0004 GETGBL R4 G9 - 0x5C140200, // 0005 MOVE R5 R1 - 0x7C100200, // 0006 CALL R4 1 - 0x7C080400, // 0007 CALL R2 2 - 0x80000000, // 0008 RET 0 - }) - ) + ( &(const binstruction[15]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x20080403, // 0002 NE R2 R2 R3 + 0x780A0009, // 0003 JMPF R2 #000E + 0x88080101, // 0004 GETMBR R2 R0 K1 + 0x8C080502, // 0005 GETMET R2 R2 K2 + 0x60100009, // 0006 GETGBL R4 G9 + 0x5C140200, // 0007 MOVE R5 R1 + 0x7C100200, // 0008 CALL R4 1 + 0x88140100, // 0009 GETMBR R5 R0 K0 + 0xB81A0600, // 000A GETNGBL R6 K3 + 0x88180D04, // 000B GETMBR R6 R6 K4 + 0x30140A06, // 000C OR R5 R5 R6 + 0x7C080600, // 000D CALL R2 3 + 0x80000000, // 000E RET 0 + }) + ) ); /*******************************************************************/ /******************************************************************** -** Solidified function: get_radius2 +** Solidified function: get_align ********************************************************************/ -be_local_closure(lvh_obj_get_radius2, /* name */ +be_local_closure(lvh_obj_get_align, /* name */ be_nested_proto( 5, /* nstack */ 1, /* argc */ @@ -639,28 +783,94 @@ be_local_closure(lvh_obj_get_radius2, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_part2_selector), - /* K1 */ be_nested_str_weak(_lv_obj), - /* K2 */ be_nested_str_weak(get_style_radius), + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_label), + /* K1 */ be_nested_str_weak(get_style_text_align), + /* K2 */ be_const_int(0), /* K3 */ be_nested_str_weak(lv), - /* K4 */ be_nested_str_weak(STATE_DEFAULT), + /* K4 */ be_nested_str_weak(TEXT_ALIGN_LEFT), + /* K5 */ be_nested_str_weak(left), + /* K6 */ be_nested_str_weak(TEXT_ALIGN_CENTER), + /* K7 */ be_nested_str_weak(center), + /* K8 */ be_nested_str_weak(TEXT_ALIGN_RIGHT), + /* K9 */ be_nested_str_weak(right), }), - be_str_weak(get_radius2), + be_str_weak(get_align), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ + ( &(const binstruction[32]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 0x4C080000, // 0001 LDNIL R2 - 0x20040202, // 0002 NE R1 R1 R2 - 0x78060007, // 0003 JMPF R1 #000C - 0x88040101, // 0004 GETMBR R1 R0 K1 - 0x8C040302, // 0005 GETMET R1 R1 K2 - 0x880C0100, // 0006 GETMBR R3 R0 K0 - 0xB8120600, // 0007 GETNGBL R4 K3 - 0x88100904, // 0008 GETMBR R4 R4 K4 - 0x300C0604, // 0009 OR R3 R3 R4 - 0x7C040400, // 000A CALL R1 2 - 0x80040200, // 000B RET 1 R1 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x78060001, // 0003 JMPF R1 #0006 + 0x4C040000, // 0004 LDNIL R1 + 0x80040200, // 0005 RET 1 R1 + 0x4C040000, // 0006 LDNIL R1 + 0x88080100, // 0007 GETMBR R2 R0 K0 + 0x8C080501, // 0008 GETMET R2 R2 K1 + 0x58100002, // 0009 LDCONST R4 K2 + 0x7C080400, // 000A CALL R2 2 + 0xB80A0600, // 000B GETNGBL R2 K3 + 0x88080504, // 000C GETMBR R2 R2 K4 + 0x1C080202, // 000D EQ R2 R1 R2 + 0x780A0001, // 000E JMPF R2 #0011 + 0x80060A00, // 000F RET 1 K5 + 0x7002000D, // 0010 JMP #001F + 0xB80A0600, // 0011 GETNGBL R2 K3 + 0x88080506, // 0012 GETMBR R2 R2 K6 + 0x1C080202, // 0013 EQ R2 R1 R2 + 0x780A0001, // 0014 JMPF R2 #0017 + 0x80060E00, // 0015 RET 1 K7 + 0x70020007, // 0016 JMP #001F + 0xB80A0600, // 0017 GETNGBL R2 K3 + 0x88080508, // 0018 GETMBR R2 R2 K8 + 0x1C080202, // 0019 EQ R2 R1 R2 + 0x780A0001, // 001A JMPF R2 #001D + 0x80061200, // 001B RET 1 K9 + 0x70020001, // 001C JMP #001F + 0x4C080000, // 001D LDNIL R2 + 0x80040400, // 001E RET 1 R2 + 0x80000000, // 001F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_hidden +********************************************************************/ +be_local_closure(lvh_obj_set_hidden, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_obj), + /* K1 */ be_nested_str_weak(add_flag), + /* K2 */ be_nested_str_weak(lv), + /* K3 */ be_nested_str_weak(OBJ_FLAG_HIDDEN), + /* K4 */ be_nested_str_weak(clear_flag), + }), + be_str_weak(set_hidden), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x78060005, // 0000 JMPF R1 #0007 + 0x88080100, // 0001 GETMBR R2 R0 K0 + 0x8C080501, // 0002 GETMET R2 R2 K1 + 0xB8120400, // 0003 GETNGBL R4 K2 + 0x88100903, // 0004 GETMBR R4 R4 K3 + 0x7C080400, // 0005 CALL R2 2 + 0x70020004, // 0006 JMP #000C + 0x88080100, // 0007 GETMBR R2 R0 K0 + 0x8C080504, // 0008 GETMET R2 R2 K4 + 0xB8120400, // 0009 GETNGBL R4 K2 + 0x88100903, // 000A GETMBR R4 R4 K3 + 0x7C080400, // 000B CALL R2 2 0x80000000, // 000C RET 0 }) ) @@ -669,11 +879,47 @@ be_local_closure(lvh_obj_get_radius2, /* name */ /******************************************************************** -** Solidified function: get_text_rule +** Solidified function: set_text_color ********************************************************************/ -be_local_closure(lvh_obj_get_text_rule, /* name */ +be_local_closure(lvh_obj_set_text_color, /* name */ be_nested_proto( - 2, /* nstack */ + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_obj), + /* K1 */ be_nested_str_weak(set_style_text_color), + /* K2 */ be_nested_str_weak(parse_color), + /* K3 */ be_const_int(0), + }), + be_str_weak(set_text_color), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x8C100102, // 0002 GETMET R4 R0 K2 + 0x5C180200, // 0003 MOVE R6 R1 + 0x7C100400, // 0004 CALL R4 2 + 0x58140003, // 0005 LDCONST R5 K3 + 0x7C080600, // 0006 CALL R2 3 + 0x80000000, // 0007 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_value_font +********************************************************************/ +be_local_closure(lvh_obj_get_value_font, /* name */ + be_nested_proto( + 3, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -682,13 +928,14 @@ be_local_closure(lvh_obj_get_text_rule, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(_text_rule), + /* K0 */ be_nested_str_weak(get_text_font), }), - be_str_weak(get_text_rule), + be_str_weak(get_value_font), &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80040200, // 0002 RET 1 R1 }) ) ); @@ -696,9 +943,9 @@ be_local_closure(lvh_obj_get_text_rule, /* name */ /******************************************************************** -** Solidified function: get_pad_right +** Solidified function: get_pad_bottom ********************************************************************/ -be_local_closure(lvh_obj_get_pad_right, /* name */ +be_local_closure(lvh_obj_get_pad_bottom, /* name */ be_nested_proto( 5, /* nstack */ 1, /* argc */ @@ -711,11 +958,11 @@ be_local_closure(lvh_obj_get_pad_right, /* name */ ( &(const bvalue[ 5]) { /* constants */ /* K0 */ be_nested_str_weak(_lv_part2_selector), /* K1 */ be_nested_str_weak(_lv_obj), - /* K2 */ be_nested_str_weak(get_style_pad_right), + /* K2 */ be_nested_str_weak(get_style_pad_bottom), /* K3 */ be_nested_str_weak(lv), /* K4 */ be_nested_str_weak(STATE_DEFAULT), }), - be_str_weak(get_pad_right), + be_str_weak(get_pad_bottom), &be_const_str_solidified, ( &(const binstruction[13]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -738,11 +985,11 @@ be_local_closure(lvh_obj_get_pad_right, /* name */ /******************************************************************** -** Solidified function: set_value_ofs_y +** Solidified function: val_rule_matched ********************************************************************/ -be_local_closure(lvh_obj_set_value_ofs_y, /* name */ +be_local_closure(lvh_obj_val_rule_matched, /* name */ be_nested_proto( - 6, /* nstack */ + 13, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -750,23 +997,53 @@ be_local_closure(lvh_obj_set_value_ofs_y, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(check_label), - /* K1 */ be_nested_str_weak(_lv_label), - /* K2 */ be_nested_str_weak(set_y), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_val_rule_function), + /* K1 */ be_nested_str_weak(string), + /* K2 */ be_nested_str_weak(format), + /* K3 */ be_nested_str_weak(HSP_X3A_X20failed_X20to_X20run_X20self_X2E_val_rule_function_X20_X2D_X20_X25s_X20_X28_X25s_X29), + /* K4 */ be_nested_str_weak(val), }), - be_str_weak(set_value_ofs_y), + be_str_weak(val_rule_matched), &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x7C080200, // 0001 CALL R2 1 - 0x88080101, // 0002 GETMBR R2 R0 K1 - 0x8C080502, // 0003 GETMET R2 R2 K2 - 0x60100009, // 0004 GETGBL R4 G9 - 0x5C140200, // 0005 MOVE R5 R1 - 0x7C100200, // 0006 CALL R4 1 - 0x7C080400, // 0007 CALL R2 2 - 0x80000000, // 0008 RET 0 + ( &(const binstruction[37]) { /* code */ + 0x6008000A, // 0000 GETGBL R2 G10 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x4C0C0000, // 0003 LDNIL R3 + 0x1C0C0403, // 0004 EQ R3 R2 R3 + 0x780E0001, // 0005 JMPF R3 #0008 + 0x500C0000, // 0006 LDBOOL R3 0 0 + 0x80040600, // 0007 RET 1 R3 + 0x880C0100, // 0008 GETMBR R3 R0 K0 + 0x4C100000, // 0009 LDNIL R4 + 0x20100604, // 000A NE R4 R3 R4 + 0x78120012, // 000B JMPF R4 #001F + 0xA8020005, // 000C EXBLK 0 #0013 + 0x5C100600, // 000D MOVE R4 R3 + 0x5C140400, // 000E MOVE R5 R2 + 0x7C100200, // 000F CALL R4 1 + 0x5C080800, // 0010 MOVE R2 R4 + 0xA8040001, // 0011 EXBLK 1 1 + 0x7002000B, // 0012 JMP #001F + 0xAC100002, // 0013 CATCH R4 0 2 + 0x70020008, // 0014 JMP #001E + 0xA41A0200, // 0015 IMPORT R6 K1 + 0x601C0001, // 0016 GETGBL R7 G1 + 0x8C200D02, // 0017 GETMET R8 R6 K2 + 0x58280003, // 0018 LDCONST R10 K3 + 0x5C2C0800, // 0019 MOVE R11 R4 + 0x5C300A00, // 001A MOVE R12 R5 + 0x7C200800, // 001B CALL R8 4 + 0x7C1C0200, // 001C CALL R7 1 + 0x70020000, // 001D JMP #001F + 0xB0080000, // 001E RAISE 2 R0 R0 + 0x60100009, // 001F GETGBL R4 G9 + 0x5C140400, // 0020 MOVE R5 R2 + 0x7C100200, // 0021 CALL R4 1 + 0x90020804, // 0022 SETMBR R0 K4 R4 + 0x50100000, // 0023 LDBOOL R4 0 0 + 0x80040800, // 0024 RET 1 R4 }) ) ); @@ -774,160 +1051,33 @@ be_local_closure(lvh_obj_set_value_ofs_y, /* name */ /******************************************************************** -** Solidified function: parse_color +** Solidified function: get_enabled ********************************************************************/ -be_local_closure(lvh_obj_parse_color, /* name */ +be_local_closure(lvh_obj_get_enabled, /* name */ be_nested_proto( - 10, /* nstack */ + 4, /* nstack */ 1, /* argc */ - 4, /* varg */ + 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 1]) { - be_nested_proto( - 10, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(toupper), - /* K2 */ be_const_int(0), - /* K3 */ be_const_int(1), - /* K4 */ be_nested_str_weak(_X23), - /* K5 */ be_nested_str_weak(x), - /* K6 */ be_nested_str_weak(X), - /* K7 */ be_nested_str_weak(A), - /* K8 */ be_nested_str_weak(F), - /* K9 */ be_nested_str_weak(byte), - /* K10 */ be_nested_str_weak(0), - /* K11 */ be_nested_str_weak(9), - /* K12 */ be_nested_str_weak(stop_iteration), - }), - be_str_weak(parse_hex), - &be_const_str_solidified, - ( &(const binstruction[57]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x5C100000, // 0002 MOVE R4 R0 - 0x7C080400, // 0003 CALL R2 2 - 0x5C000400, // 0004 MOVE R0 R2 - 0x58080002, // 0005 LDCONST R2 K2 - 0x600C0010, // 0006 GETGBL R3 G16 - 0x6010000C, // 0007 GETGBL R4 G12 - 0x5C140000, // 0008 MOVE R5 R0 - 0x7C100200, // 0009 CALL R4 1 - 0x04100903, // 000A SUB R4 R4 K3 - 0x40120404, // 000B CONNECT R4 K2 R4 - 0x7C0C0200, // 000C CALL R3 1 - 0xA8020026, // 000D EXBLK 0 #0035 - 0x5C100600, // 000E MOVE R4 R3 - 0x7C100000, // 000F CALL R4 0 - 0x94140004, // 0010 GETIDX R5 R0 R4 - 0x1C180B04, // 0011 EQ R6 R5 K4 - 0x781A0000, // 0012 JMPF R6 #0014 - 0x7001FFF9, // 0013 JMP #000E - 0x1C180B05, // 0014 EQ R6 R5 K5 - 0x741A0001, // 0015 JMPT R6 #0018 - 0x1C180B06, // 0016 EQ R6 R5 K6 - 0x781A0000, // 0017 JMPF R6 #0019 - 0x7001FFF4, // 0018 JMP #000E - 0x28180B07, // 0019 GE R6 R5 K7 - 0x781A000B, // 001A JMPF R6 #0027 - 0x18180B08, // 001B LE R6 R5 K8 - 0x781A0009, // 001C JMPF R6 #0027 - 0x541A0003, // 001D LDINT R6 4 - 0x38180406, // 001E SHL R6 R2 R6 - 0x8C1C0309, // 001F GETMET R7 R1 K9 - 0x5C240A00, // 0020 MOVE R9 R5 - 0x7C1C0400, // 0021 CALL R7 2 - 0x54220036, // 0022 LDINT R8 55 - 0x041C0E08, // 0023 SUB R7 R7 R8 - 0x30180C07, // 0024 OR R6 R6 R7 - 0x5C080C00, // 0025 MOVE R2 R6 - 0x7002000C, // 0026 JMP #0034 - 0x28180B0A, // 0027 GE R6 R5 K10 - 0x781A000A, // 0028 JMPF R6 #0034 - 0x18180B0B, // 0029 LE R6 R5 K11 - 0x781A0008, // 002A JMPF R6 #0034 - 0x541A0003, // 002B LDINT R6 4 - 0x38180406, // 002C SHL R6 R2 R6 - 0x8C1C0309, // 002D GETMET R7 R1 K9 - 0x5C240A00, // 002E MOVE R9 R5 - 0x7C1C0400, // 002F CALL R7 2 - 0x5422002F, // 0030 LDINT R8 48 - 0x041C0E08, // 0031 SUB R7 R7 R8 - 0x30180C07, // 0032 OR R6 R6 R7 - 0x5C080C00, // 0033 MOVE R2 R6 - 0x7001FFD8, // 0034 JMP #000E - 0x580C000C, // 0035 LDCONST R3 K12 - 0xAC0C0200, // 0036 CATCH R3 1 0 - 0xB0080000, // 0037 RAISE 2 R0 R0 - 0x80040400, // 0038 RET 1 R2 - }) - ), - }), + 0, /* has sup protos */ + NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_const_class(be_class_lvh_obj), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str_weak(_X23), - /* K3 */ be_nested_str_weak(lv), - /* K4 */ be_nested_str_weak(color), - /* K5 */ be_nested_str_weak(string), - /* K6 */ be_nested_str_weak(introspect), - /* K7 */ be_nested_str_weak(COLOR_), - /* K8 */ be_nested_str_weak(toupper), - /* K9 */ be_nested_str_weak(get), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_obj), + /* K1 */ be_nested_str_weak(has_flag), + /* K2 */ be_nested_str_weak(lv), + /* K3 */ be_nested_str_weak(OBJ_FLAG_CLICKABLE), }), - be_str_weak(parse_color), + be_str_weak(get_enabled), &be_const_str_solidified, - ( &(const binstruction[40]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0x84080000, // 0001 CLOSURE R2 P0 - 0x600C0008, // 0002 GETGBL R3 G8 - 0x5C100000, // 0003 MOVE R4 R0 - 0x7C0C0200, // 0004 CALL R3 1 - 0x5C000600, // 0005 MOVE R0 R3 - 0x940C0101, // 0006 GETIDX R3 R0 K1 - 0x1C0C0702, // 0007 EQ R3 R3 K2 - 0x780E0007, // 0008 JMPF R3 #0011 - 0xB80E0600, // 0009 GETNGBL R3 K3 - 0x8C0C0704, // 000A GETMET R3 R3 K4 - 0x5C140400, // 000B MOVE R5 R2 - 0x5C180000, // 000C MOVE R6 R0 - 0x7C140200, // 000D CALL R5 1 - 0x7C0C0400, // 000E CALL R3 2 - 0x80040600, // 000F RET 1 R3 - 0x70020011, // 0010 JMP #0023 - 0xA40E0A00, // 0011 IMPORT R3 K5 - 0xA4120C00, // 0012 IMPORT R4 K6 - 0x8C140708, // 0013 GETMET R5 R3 K8 - 0x5C1C0000, // 0014 MOVE R7 R0 - 0x7C140400, // 0015 CALL R5 2 - 0x00160E05, // 0016 ADD R5 K7 R5 - 0x8C180909, // 0017 GETMET R6 R4 K9 - 0xB8220600, // 0018 GETNGBL R8 K3 - 0x5C240A00, // 0019 MOVE R9 R5 - 0x7C180600, // 001A CALL R6 3 - 0x4C1C0000, // 001B LDNIL R7 - 0x201C0C07, // 001C NE R7 R6 R7 - 0x781E0004, // 001D JMPF R7 #0023 - 0xB81E0600, // 001E GETNGBL R7 K3 - 0x8C1C0F04, // 001F GETMET R7 R7 K4 - 0x5C240C00, // 0020 MOVE R9 R6 - 0x7C1C0400, // 0021 CALL R7 2 - 0x80040E00, // 0022 RET 1 R7 - 0xB80E0600, // 0023 GETNGBL R3 K3 - 0x8C0C0704, // 0024 GETMET R3 R3 K4 - 0x58140001, // 0025 LDCONST R5 K1 - 0x7C0C0400, // 0026 CALL R3 2 - 0x80040600, // 0027 RET 1 R3 + ( &(const binstruction[ 6]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0xB80E0400, // 0002 GETNGBL R3 K2 + 0x880C0703, // 0003 GETMBR R3 R3 K3 + 0x7C040400, // 0004 CALL R1 2 + 0x80040200, // 0005 RET 1 R1 }) ) ); @@ -935,23 +1085,26 @@ be_local_closure(lvh_obj_parse_color, /* name */ /******************************************************************** -** Solidified function: get_text_font +** Solidified function: set_meta ********************************************************************/ -be_local_closure(lvh_obj_get_text_font, /* name */ +be_local_closure(lvh_obj_set_meta, /* name */ be_nested_proto( - 1, /* nstack */ - 1, /* argc */ + 2, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(get_text_font), + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(_meta), + }), + be_str_weak(set_meta), &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 + ( &(const binstruction[ 2]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x80000000, // 0001 RET 0 }) ) ); @@ -959,80 +1112,26 @@ be_local_closure(lvh_obj_get_text_font, /* name */ /******************************************************************** -** Solidified function: text_rule_matched +** Solidified function: get_val_rule ********************************************************************/ -be_local_closure(lvh_obj_text_rule_matched, /* name */ +be_local_closure(lvh_obj_get_val_rule, /* name */ be_nested_proto( - 12, /* nstack */ - 2, /* argc */ + 2, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_weak(int), - /* K1 */ be_nested_str_weak(_text_rule_function), - /* K2 */ be_nested_str_weak(string), - /* K3 */ be_nested_str_weak(format), - /* K4 */ be_nested_str_weak(HSP_X3A_X20failed_X20to_X20run_X20self_X2E_text_rule_function_X20_X2D_X20_X25s_X20_X28_X25s_X29), - /* K5 */ be_nested_str_weak(_text_rule_format), - /* K6 */ be_nested_str_weak(), - /* K7 */ be_nested_str_weak(text), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(_val_rule), }), - be_str_weak(text_rule_matched), + be_str_weak(get_val_rule), &be_const_str_solidified, - ( &(const binstruction[49]) { /* code */ - 0x60080004, // 0000 GETGBL R2 G4 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x1C080500, // 0003 EQ R2 R2 K0 - 0x780A0003, // 0004 JMPF R2 #0009 - 0x6008000A, // 0005 GETGBL R2 G10 - 0x5C0C0200, // 0006 MOVE R3 R1 - 0x7C080200, // 0007 CALL R2 1 - 0x5C040400, // 0008 MOVE R1 R2 - 0x88080101, // 0009 GETMBR R2 R0 K1 - 0x4C0C0000, // 000A LDNIL R3 - 0x200C0403, // 000B NE R3 R2 R3 - 0x780E0012, // 000C JMPF R3 #0020 - 0xA8020005, // 000D EXBLK 0 #0014 - 0x5C0C0400, // 000E MOVE R3 R2 - 0x5C100200, // 000F MOVE R4 R1 - 0x7C0C0200, // 0010 CALL R3 1 - 0x5C040600, // 0011 MOVE R1 R3 - 0xA8040001, // 0012 EXBLK 1 1 - 0x7002000B, // 0013 JMP #0020 - 0xAC0C0002, // 0014 CATCH R3 0 2 - 0x70020008, // 0015 JMP #001F - 0xA4160400, // 0016 IMPORT R5 K2 - 0x60180001, // 0017 GETGBL R6 G1 - 0x8C1C0B03, // 0018 GETMET R7 R5 K3 - 0x58240004, // 0019 LDCONST R9 K4 - 0x5C280600, // 001A MOVE R10 R3 - 0x5C2C0800, // 001B MOVE R11 R4 - 0x7C1C0800, // 001C CALL R7 4 - 0x7C180200, // 001D CALL R6 1 - 0x70020000, // 001E JMP #0020 - 0xB0080000, // 001F RAISE 2 R0 R0 - 0x880C0105, // 0020 GETMBR R3 R0 K5 - 0x60100004, // 0021 GETGBL R4 G4 - 0x5C140600, // 0022 MOVE R5 R3 - 0x7C100200, // 0023 CALL R4 1 - 0x1C100902, // 0024 EQ R4 R4 K2 - 0x78120006, // 0025 JMPF R4 #002D - 0xA4120400, // 0026 IMPORT R4 K2 - 0x8C140903, // 0027 GETMET R5 R4 K3 - 0x5C1C0600, // 0028 MOVE R7 R3 - 0x5C200200, // 0029 MOVE R8 R1 - 0x7C140600, // 002A CALL R5 3 - 0x5C0C0A00, // 002B MOVE R3 R5 - 0x70020000, // 002C JMP #002E - 0x580C0006, // 002D LDCONST R3 K6 - 0x90020E03, // 002E SETMBR R0 K7 R3 - 0x50100000, // 002F LDBOOL R4 0 0 - 0x80040800, // 0030 RET 1 R4 + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -1040,11 +1139,11 @@ be_local_closure(lvh_obj_text_rule_matched, /* name */ /******************************************************************** -** Solidified function: set_pad_bottom2 +** Solidified function: set_text_rule_format ********************************************************************/ -be_local_closure(lvh_obj_set_pad_bottom2, /* name */ +be_local_closure(lvh_obj_set_text_rule_format, /* name */ be_nested_proto( - 7, /* nstack */ + 4, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1052,31 +1151,17 @@ be_local_closure(lvh_obj_set_pad_bottom2, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_part2_selector), - /* K1 */ be_nested_str_weak(_lv_obj), - /* K2 */ be_nested_str_weak(set_style_pad_bottom), - /* K3 */ be_nested_str_weak(lv), - /* K4 */ be_nested_str_weak(STATE_DEFAULT), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(_text_rule_format), }), - be_str_weak(set_pad_bottom2), + be_str_weak(set_text_rule_format), &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x20080403, // 0002 NE R2 R2 R3 - 0x780A0009, // 0003 JMPF R2 #000E - 0x88080101, // 0004 GETMBR R2 R0 K1 - 0x8C080502, // 0005 GETMET R2 R2 K2 - 0x60100009, // 0006 GETGBL R4 G9 - 0x5C140200, // 0007 MOVE R5 R1 - 0x7C100200, // 0008 CALL R4 1 - 0x88140100, // 0009 GETMBR R5 R0 K0 - 0xB81A0600, // 000A GETNGBL R6 K3 - 0x88180D04, // 000B GETMBR R6 R6 K4 - 0x30140A06, // 000C OR R5 R5 R6 - 0x7C080600, // 000D CALL R2 3 - 0x80000000, // 000E RET 0 + ( &(const binstruction[ 5]) { /* code */ + 0x60080008, // 0000 GETGBL R2 G8 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x90020002, // 0003 SETMBR R0 K0 R2 + 0x80000000, // 0004 RET 0 }) ) ); @@ -1084,65 +1169,43 @@ be_local_closure(lvh_obj_set_pad_bottom2, /* name */ /******************************************************************** -** Solidified function: set_align +** Solidified function: init ********************************************************************/ -be_local_closure(lvh_obj_set_align, /* name */ +be_local_closure(lvh_obj_init, /* name */ be_nested_proto( - 7, /* nstack */ - 2, /* argc */ + 8, /* nstack */ + 5, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ - /* K0 */ be_nested_str_weak(check_label), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str_weak(left), - /* K3 */ be_nested_str_weak(lv), - /* K4 */ be_nested_str_weak(TEXT_ALIGN_LEFT), - /* K5 */ be_const_int(1), - /* K6 */ be_nested_str_weak(center), - /* K7 */ be_nested_str_weak(TEXT_ALIGN_CENTER), - /* K8 */ be_const_int(2), - /* K9 */ be_nested_str_weak(right), - /* K10 */ be_nested_str_weak(TEXT_ALIGN_RIGHT), - /* K11 */ be_nested_str_weak(_lv_label), - /* K12 */ be_nested_str_weak(set_style_text_align), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(_page), + /* K1 */ be_nested_str_weak(_lv_class), + /* K2 */ be_nested_str_weak(_lv_obj), + /* K3 */ be_nested_str_weak(post_init), }), - be_str_weak(set_align), + be_str_weak(init), &be_const_str_solidified, - ( &(const binstruction[29]) { /* code */ - 0x4C080000, // 0000 LDNIL R2 - 0x8C0C0100, // 0001 GETMET R3 R0 K0 - 0x7C0C0200, // 0002 CALL R3 1 - 0x1C0C0301, // 0003 EQ R3 R1 K1 - 0x740E0001, // 0004 JMPT R3 #0007 - 0x1C0C0302, // 0005 EQ R3 R1 K2 - 0x780E0002, // 0006 JMPF R3 #000A - 0xB80E0600, // 0007 GETNGBL R3 K3 - 0x88080704, // 0008 GETMBR R2 R3 K4 - 0x7002000C, // 0009 JMP #0017 - 0x1C0C0305, // 000A EQ R3 R1 K5 - 0x740E0001, // 000B JMPT R3 #000E - 0x1C0C0306, // 000C EQ R3 R1 K6 - 0x780E0002, // 000D JMPF R3 #0011 - 0xB80E0600, // 000E GETNGBL R3 K3 - 0x88080707, // 000F GETMBR R2 R3 K7 - 0x70020005, // 0010 JMP #0017 - 0x1C0C0308, // 0011 EQ R3 R1 K8 - 0x740E0001, // 0012 JMPT R3 #0015 - 0x1C0C0309, // 0013 EQ R3 R1 K9 - 0x780E0001, // 0014 JMPF R3 #0017 - 0xB80E0600, // 0015 GETNGBL R3 K3 - 0x8808070A, // 0016 GETMBR R2 R3 K10 - 0x880C010B, // 0017 GETMBR R3 R0 K11 - 0x8C0C070C, // 0018 GETMET R3 R3 K12 - 0x5C140400, // 0019 MOVE R5 R2 - 0x58180001, // 001A LDCONST R6 K1 - 0x7C0C0600, // 001B CALL R3 3 - 0x80000000, // 001C RET 0 + ( &(const binstruction[16]) { /* code */ + 0x90020002, // 0000 SETMBR R0 K0 R2 + 0x4C140000, // 0001 LDNIL R5 + 0x1C140805, // 0002 EQ R5 R4 R5 + 0x78160007, // 0003 JMPF R5 #000C + 0x88140101, // 0004 GETMBR R5 R0 K1 + 0x78160005, // 0005 JMPF R5 #000C + 0x88140101, // 0006 GETMBR R5 R0 K1 + 0x5C180A00, // 0007 MOVE R6 R5 + 0x5C1C0200, // 0008 MOVE R7 R1 + 0x7C180200, // 0009 CALL R6 1 + 0x90020406, // 000A SETMBR R0 K2 R6 + 0x70020000, // 000B JMP #000D + 0x90020404, // 000C SETMBR R0 K2 R4 + 0x8C140103, // 000D GETMET R5 R0 K3 + 0x7C140200, // 000E CALL R5 1 + 0x80000000, // 000F RET 0 }) ) ); @@ -1150,11 +1213,11 @@ be_local_closure(lvh_obj_set_align, /* name */ /******************************************************************** -** Solidified function: set_text_rule_format +** Solidified function: set_value_font ********************************************************************/ -be_local_closure(lvh_obj_set_text_rule_format, /* name */ +be_local_closure(lvh_obj_set_value_font, /* name */ be_nested_proto( - 4, /* nstack */ + 5, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1163,16 +1226,15 @@ be_local_closure(lvh_obj_set_text_rule_format, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(_text_rule_format), + /* K0 */ be_nested_str_weak(set_text_font), }), - be_str_weak(set_text_rule_format), + be_str_weak(set_value_font), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x60080008, // 0000 GETGBL R2 G8 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x90020002, // 0003 SETMBR R0 K0 R2 - 0x80000000, // 0004 RET 0 + ( &(const binstruction[ 4]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0x80000000, // 0003 RET 0 }) ) ); @@ -1180,30 +1242,45 @@ be_local_closure(lvh_obj_set_text_rule_format, /* name */ /******************************************************************** -** Solidified function: set_val +** Solidified function: check_label ********************************************************************/ -be_local_closure(lvh_obj_set_val, /* name */ +be_local_closure(lvh_obj_check_label, /* name */ be_nested_proto( 5, /* nstack */ - 2, /* argc */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(set_value), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_label), + /* K1 */ be_nested_str_weak(lv), + /* K2 */ be_nested_str_weak(label), + /* K3 */ be_nested_str_weak(get_obj), + /* K4 */ be_nested_str_weak(set_align), + /* K5 */ be_nested_str_weak(ALIGN_CENTER), }), - be_str_weak(set_val), + be_str_weak(check_label), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x5C100200, // 0002 MOVE R4 R1 - 0x7C080400, // 0003 CALL R2 2 - 0x80000000, // 0004 RET 0 + ( &(const binstruction[16]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x7806000A, // 0003 JMPF R1 #000F + 0xB8060200, // 0004 GETNGBL R1 K1 + 0x8C040302, // 0005 GETMET R1 R1 K2 + 0x8C0C0103, // 0006 GETMET R3 R0 K3 + 0x7C0C0200, // 0007 CALL R3 1 + 0x7C040400, // 0008 CALL R1 2 + 0x90020001, // 0009 SETMBR R0 K0 R1 + 0x88040100, // 000A GETMBR R1 R0 K0 + 0x8C040304, // 000B GETMET R1 R1 K4 + 0xB80E0200, // 000C GETNGBL R3 K1 + 0x880C0705, // 000D GETMBR R3 R3 K5 + 0x7C040400, // 000E CALL R1 2 + 0x80000000, // 000F RET 0 }) ) ); @@ -1211,9 +1288,9 @@ be_local_closure(lvh_obj_set_val, /* name */ /******************************************************************** -** Solidified function: get_text_rule_format +** Solidified function: get_meta ********************************************************************/ -be_local_closure(lvh_obj_get_text_rule_format, /* name */ +be_local_closure(lvh_obj_get_meta, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -1224,9 +1301,9 @@ be_local_closure(lvh_obj_get_text_rule_format, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(_text_rule_format), + /* K0 */ be_nested_str_weak(_meta), }), - be_str_weak(get_text_rule_format), + be_str_weak(get_meta), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -1238,29 +1315,73 @@ be_local_closure(lvh_obj_get_text_rule_format, /* name */ /******************************************************************** -** Solidified function: set_action +** Solidified function: set_val_rule ********************************************************************/ -be_local_closure(lvh_obj_set_action, /* name */ +be_local_closure(lvh_obj_set_val_rule, /* name */ be_nested_proto( - 4, /* nstack */ + 7, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(val_rule_matched), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x68040000, // 0000 GETUPV R1 U0 + 0x8C040300, // 0001 GETMET R1 R1 K0 + 0x5C0C0000, // 0002 MOVE R3 R0 + 0x7C040400, // 0003 CALL R1 2 + 0x80040200, // 0004 RET 1 R1 + }) + ), + }), 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(_action), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(_val_rule), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(remove_rule), + /* K3 */ be_nested_str_weak(add_rule), }), - be_str_weak(set_action), + be_str_weak(set_val_rule), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x60080008, // 0000 GETGBL R2 G8 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x90020002, // 0003 SETMBR R0 K0 R2 - 0x80000000, // 0004 RET 0 + ( &(const binstruction[21]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x20080403, // 0002 NE R2 R2 R3 + 0x780A0004, // 0003 JMPF R2 #0009 + 0xB80A0200, // 0004 GETNGBL R2 K1 + 0x8C080502, // 0005 GETMET R2 R2 K2 + 0x88100100, // 0006 GETMBR R4 R0 K0 + 0x5C140000, // 0007 MOVE R5 R0 + 0x7C080600, // 0008 CALL R2 3 + 0x60080008, // 0009 GETGBL R2 G8 + 0x5C0C0200, // 000A MOVE R3 R1 + 0x7C080200, // 000B CALL R2 1 + 0x90020002, // 000C SETMBR R0 K0 R2 + 0xB80A0200, // 000D GETNGBL R2 K1 + 0x8C080503, // 000E GETMET R2 R2 K3 + 0x88100100, // 000F GETMBR R4 R0 K0 + 0x84140000, // 0010 CLOSURE R5 P0 + 0x5C180000, // 0011 MOVE R6 R0 + 0x7C080800, // 0012 CALL R2 4 + 0xA0000000, // 0013 CLOSE R0 + 0x80000000, // 0014 RET 0 }) ) ); @@ -1268,72 +1389,11 @@ be_local_closure(lvh_obj_set_action, /* name */ /******************************************************************** -** Solidified function: set_text_rule_formula +** Solidified function: set_enabled ********************************************************************/ -be_local_closure(lvh_obj_set_text_rule_formula, /* name */ +be_local_closure(lvh_obj_set_enabled, /* name */ be_nested_proto( - 13, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str_weak(_text_rule_formula), - /* K1 */ be_nested_str_weak(return_X20_X2F_X20val_X20_X2D_X3E_X20_X28), - /* K2 */ be_nested_str_weak(_X29), - /* K3 */ be_nested_str_weak(_text_rule_function), - /* K4 */ be_nested_str_weak(string), - /* K5 */ be_nested_str_weak(format), - /* K6 */ be_nested_str_weak(HSP_X3A_X20failed_X20to_X20compile_X20_X27_X25s_X27_X20_X2D_X20_X25s_X20_X28_X25s_X29), - }), - be_str_weak(set_text_rule_formula), - &be_const_str_solidified, - ( &(const binstruction[30]) { /* code */ - 0x60080008, // 0000 GETGBL R2 G8 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x90020002, // 0003 SETMBR R0 K0 R2 - 0x88080100, // 0004 GETMBR R2 R0 K0 - 0x000A0202, // 0005 ADD R2 K1 R2 - 0x00080502, // 0006 ADD R2 R2 K2 - 0xA8020007, // 0007 EXBLK 0 #0010 - 0x600C000D, // 0008 GETGBL R3 G13 - 0x5C100400, // 0009 MOVE R4 R2 - 0x7C0C0200, // 000A CALL R3 1 - 0x5C100600, // 000B MOVE R4 R3 - 0x7C100000, // 000C CALL R4 0 - 0x90020604, // 000D SETMBR R0 K3 R4 - 0xA8040001, // 000E EXBLK 1 1 - 0x7002000C, // 000F JMP #001D - 0xAC0C0002, // 0010 CATCH R3 0 2 - 0x70020009, // 0011 JMP #001C - 0xA4160800, // 0012 IMPORT R5 K4 - 0x60180001, // 0013 GETGBL R6 G1 - 0x8C1C0B05, // 0014 GETMET R7 R5 K5 - 0x58240006, // 0015 LDCONST R9 K6 - 0x5C280400, // 0016 MOVE R10 R2 - 0x5C2C0600, // 0017 MOVE R11 R3 - 0x5C300800, // 0018 MOVE R12 R4 - 0x7C1C0A00, // 0019 CALL R7 5 - 0x7C180200, // 001A CALL R6 1 - 0x70020000, // 001B JMP #001D - 0xB0080000, // 001C RAISE 2 R0 R0 - 0x80000000, // 001D RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: val_rule_matched -********************************************************************/ -be_local_closure(lvh_obj_val_rule_matched, /* name */ - be_nested_proto( - 13, /* nstack */ + 5, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1342,104 +1402,28 @@ be_local_closure(lvh_obj_val_rule_matched, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_val_rule_function), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(format), - /* K3 */ be_nested_str_weak(HSP_X3A_X20failed_X20to_X20run_X20self_X2E_val_rule_function_X20_X2D_X20_X25s_X20_X28_X25s_X29), - /* K4 */ be_nested_str_weak(val), - }), - be_str_weak(val_rule_matched), - &be_const_str_solidified, - ( &(const binstruction[37]) { /* code */ - 0x6008000A, // 0000 GETGBL R2 G10 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x4C0C0000, // 0003 LDNIL R3 - 0x1C0C0403, // 0004 EQ R3 R2 R3 - 0x780E0001, // 0005 JMPF R3 #0008 - 0x500C0000, // 0006 LDBOOL R3 0 0 - 0x80040600, // 0007 RET 1 R3 - 0x880C0100, // 0008 GETMBR R3 R0 K0 - 0x4C100000, // 0009 LDNIL R4 - 0x20100604, // 000A NE R4 R3 R4 - 0x78120012, // 000B JMPF R4 #001F - 0xA8020005, // 000C EXBLK 0 #0013 - 0x5C100600, // 000D MOVE R4 R3 - 0x5C140400, // 000E MOVE R5 R2 - 0x7C100200, // 000F CALL R4 1 - 0x5C080800, // 0010 MOVE R2 R4 - 0xA8040001, // 0011 EXBLK 1 1 - 0x7002000B, // 0012 JMP #001F - 0xAC100002, // 0013 CATCH R4 0 2 - 0x70020008, // 0014 JMP #001E - 0xA41A0200, // 0015 IMPORT R6 K1 - 0x601C0001, // 0016 GETGBL R7 G1 - 0x8C200D02, // 0017 GETMET R8 R6 K2 - 0x58280003, // 0018 LDCONST R10 K3 - 0x5C2C0800, // 0019 MOVE R11 R4 - 0x5C300A00, // 001A MOVE R12 R5 - 0x7C200800, // 001B CALL R8 4 - 0x7C1C0200, // 001C CALL R7 1 - 0x70020000, // 001D JMP #001F - 0xB0080000, // 001E RAISE 2 R0 R0 - 0x60100009, // 001F GETGBL R4 G9 - 0x5C140400, // 0020 MOVE R5 R2 - 0x7C100200, // 0021 CALL R4 1 - 0x90020804, // 0022 SETMBR R0 K4 R4 - 0x50100000, // 0023 LDBOOL R4 0 0 - 0x80040800, // 0024 RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: remove_trailing_zeroes -********************************************************************/ -be_local_closure(lvh_obj_remove_trailing_zeroes, /* name */ - be_nested_proto( - 8, /* nstack */ - 1, /* argc */ - 4, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_const_class(be_class_lvh_obj), - /* K1 */ be_const_int(0), - /* K2 */ be_const_int(1), - /* K3 */ be_nested_str_weak(resize), + /* K0 */ be_nested_str_weak(_lv_obj), + /* K1 */ be_nested_str_weak(add_flag), + /* K2 */ be_nested_str_weak(lv), + /* K3 */ be_nested_str_weak(OBJ_FLAG_CLICKABLE), + /* K4 */ be_nested_str_weak(clear_flag), }), - be_str_weak(remove_trailing_zeroes), + be_str_weak(set_enabled), &be_const_str_solidified, - ( &(const binstruction[24]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0x6008000C, // 0001 GETGBL R2 G12 - 0x5C0C0000, // 0002 MOVE R3 R0 - 0x7C080200, // 0003 CALL R2 1 - 0x580C0001, // 0004 LDCONST R3 K1 - 0x14100602, // 0005 LT R4 R3 R2 - 0x78120007, // 0006 JMPF R4 #000F - 0x5411FFFE, // 0007 LDINT R4 -1 - 0x04100803, // 0008 SUB R4 R4 R3 - 0x94100004, // 0009 GETIDX R4 R0 R4 - 0x20100901, // 000A NE R4 R4 K1 - 0x78120000, // 000B JMPF R4 #000D - 0x70020001, // 000C JMP #000F - 0x000C0702, // 000D ADD R3 R3 K2 - 0x7001FFF5, // 000E JMP #0005 - 0x24100701, // 000F GT R4 R3 K1 - 0x78120005, // 0010 JMPF R4 #0017 - 0x8C100103, // 0011 GETMET R4 R0 K3 - 0x6018000C, // 0012 GETGBL R6 G12 - 0x5C1C0000, // 0013 MOVE R7 R0 - 0x7C180200, // 0014 CALL R6 1 - 0x04180C03, // 0015 SUB R6 R6 R3 - 0x7C100400, // 0016 CALL R4 2 - 0x80040000, // 0017 RET 1 R0 + ( &(const binstruction[13]) { /* code */ + 0x78060005, // 0000 JMPF R1 #0007 + 0x88080100, // 0001 GETMBR R2 R0 K0 + 0x8C080501, // 0002 GETMET R2 R2 K1 + 0xB8120400, // 0003 GETNGBL R4 K2 + 0x88100903, // 0004 GETMBR R4 R4 K3 + 0x7C080400, // 0005 CALL R2 2 + 0x70020004, // 0006 JMP #000C + 0x88080100, // 0007 GETMBR R2 R0 K0 + 0x8C080504, // 0008 GETMET R2 R2 K4 + 0xB8120400, // 0009 GETNGBL R4 K2 + 0x88100903, // 000A GETMBR R4 R4 K3 + 0x7C080400, // 000B CALL R2 2 + 0x80000000, // 000C RET 0 }) ) ); @@ -1447,9 +1431,9 @@ be_local_closure(lvh_obj_remove_trailing_zeroes, /* name */ /******************************************************************** -** Solidified function: post_init +** Solidified function: get_action ********************************************************************/ -be_local_closure(lvh_obj_post_init, /* name */ +be_local_closure(lvh_obj_get_action, /* name */ be_nested_proto( 3, /* nstack */ 1, /* argc */ @@ -1459,15 +1443,19 @@ be_local_closure(lvh_obj_post_init, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(register_event_cb), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(_action), + /* K1 */ be_nested_str_weak(), }), - be_str_weak(post_init), + be_str_weak(get_action), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x80000000, // 0002 RET 0 + ( &(const binstruction[ 6]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x78060001, // 0001 JMPF R1 #0004 + 0x5C080200, // 0002 MOVE R2 R1 + 0x70020000, // 0003 JMP #0005 + 0x58080001, // 0004 LDCONST R2 K1 + 0x80040400, // 0005 RET 1 R2 }) ) ); @@ -1475,23 +1463,41 @@ be_local_closure(lvh_obj_post_init, /* name */ /******************************************************************** -** Solidified function: get_mode +** Solidified function: get_radius2 ********************************************************************/ -be_local_closure(lvh_obj_get_mode, /* name */ +be_local_closure(lvh_obj_get_radius2, /* name */ be_nested_proto( - 1, /* nstack */ + 5, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(get_mode), + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_part2_selector), + /* K1 */ be_nested_str_weak(_lv_obj), + /* K2 */ be_nested_str_weak(get_style_radius), + /* K3 */ be_nested_str_weak(lv), + /* K4 */ be_nested_str_weak(STATE_DEFAULT), + }), + be_str_weak(get_radius2), &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 + ( &(const binstruction[13]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x20040202, // 0002 NE R1 R1 R2 + 0x78060007, // 0003 JMPF R1 #000C + 0x88040101, // 0004 GETMBR R1 R0 K1 + 0x8C040302, // 0005 GETMET R1 R1 K2 + 0x880C0100, // 0006 GETMBR R3 R0 K0 + 0xB8120600, // 0007 GETNGBL R4 K3 + 0x88100904, // 0008 GETMBR R4 R4 K4 + 0x300C0604, // 0009 OR R3 R3 R4 + 0x7C040400, // 000A CALL R1 2 + 0x80040200, // 000B RET 1 R1 + 0x80000000, // 000C RET 0 }) ) ); @@ -1499,9 +1505,9 @@ be_local_closure(lvh_obj_get_mode, /* name */ /******************************************************************** -** Solidified function: set_pad_top2 +** Solidified function: set_pad_right2 ********************************************************************/ -be_local_closure(lvh_obj_set_pad_top2, /* name */ +be_local_closure(lvh_obj_set_pad_right2, /* name */ be_nested_proto( 7, /* nstack */ 2, /* argc */ @@ -1514,11 +1520,11 @@ be_local_closure(lvh_obj_set_pad_top2, /* name */ ( &(const bvalue[ 5]) { /* constants */ /* K0 */ be_nested_str_weak(_lv_part2_selector), /* K1 */ be_nested_str_weak(_lv_obj), - /* K2 */ be_nested_str_weak(set_style_pad_top), + /* K2 */ be_nested_str_weak(set_style_pad_right), /* K3 */ be_nested_str_weak(lv), /* K4 */ be_nested_str_weak(STATE_DEFAULT), }), - be_str_weak(set_pad_top2), + be_str_weak(set_pad_right2), &be_const_str_solidified, ( &(const binstruction[15]) { /* code */ 0x88080100, // 0000 GETMBR R2 R0 K0 @@ -1543,70 +1549,57 @@ be_local_closure(lvh_obj_set_pad_top2, /* name */ /******************************************************************** -** Solidified function: set_value_font +** Solidified function: get_value_ofs_x ********************************************************************/ -be_local_closure(lvh_obj_set_value_font, /* name */ +be_local_closure(lvh_obj_get_value_ofs_x, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 3, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(set_text_font), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_label), + /* K1 */ be_nested_str_weak(get_x), }), - be_str_weak(set_value_font), + be_str_weak(get_value_ofs_x), &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C080400, // 0002 CALL R2 2 - 0x80000000, // 0003 RET 0 - }) - ) + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) ); /*******************************************************************/ /******************************************************************** -** Solidified function: set_enabled +** Solidified function: get_value_color ********************************************************************/ -be_local_closure(lvh_obj_set_enabled, /* name */ +be_local_closure(lvh_obj_get_value_color, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 3, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(add_flag), - /* K2 */ be_nested_str_weak(lv), - /* K3 */ be_nested_str_weak(OBJ_FLAG_CLICKABLE), - /* K4 */ be_nested_str_weak(clear_flag), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(get_value_color), }), - be_str_weak(set_enabled), + be_str_weak(get_value_color), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x78060005, // 0000 JMPF R1 #0007 - 0x88080100, // 0001 GETMBR R2 R0 K0 - 0x8C080501, // 0002 GETMET R2 R2 K1 - 0xB8120400, // 0003 GETNGBL R4 K2 - 0x88100903, // 0004 GETMBR R4 R4 K3 - 0x7C080400, // 0005 CALL R2 2 - 0x70020004, // 0006 JMP #000C - 0x88080100, // 0007 GETMBR R2 R0 K0 - 0x8C080504, // 0008 GETMET R2 R2 K4 - 0xB8120400, // 0009 GETNGBL R4 K2 - 0x88100903, // 000A GETMBR R4 R4 K3 - 0x7C080400, // 000B CALL R2 2 - 0x80000000, // 000C RET 0 + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80040200, // 0002 RET 1 R1 }) ) ); @@ -1614,65 +1607,43 @@ be_local_closure(lvh_obj_set_enabled, /* name */ /******************************************************************** -** Solidified function: get_align +** Solidified function: set_pad_bottom2 ********************************************************************/ -be_local_closure(lvh_obj_get_align, /* name */ +be_local_closure(lvh_obj_set_pad_bottom2, /* name */ be_nested_proto( - 5, /* nstack */ - 1, /* argc */ + 7, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_label), - /* K1 */ be_nested_str_weak(get_style_text_align), - /* K2 */ be_const_int(0), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_part2_selector), + /* K1 */ be_nested_str_weak(_lv_obj), + /* K2 */ be_nested_str_weak(set_style_pad_bottom), /* K3 */ be_nested_str_weak(lv), - /* K4 */ be_nested_str_weak(TEXT_ALIGN_LEFT), - /* K5 */ be_nested_str_weak(left), - /* K6 */ be_nested_str_weak(TEXT_ALIGN_CENTER), - /* K7 */ be_nested_str_weak(center), - /* K8 */ be_nested_str_weak(TEXT_ALIGN_RIGHT), - /* K9 */ be_nested_str_weak(right), + /* K4 */ be_nested_str_weak(STATE_DEFAULT), }), - be_str_weak(get_align), + be_str_weak(set_pad_bottom2), &be_const_str_solidified, - ( &(const binstruction[32]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x1C040202, // 0002 EQ R1 R1 R2 - 0x78060001, // 0003 JMPF R1 #0006 - 0x4C040000, // 0004 LDNIL R1 - 0x80040200, // 0005 RET 1 R1 - 0x4C040000, // 0006 LDNIL R1 - 0x88080100, // 0007 GETMBR R2 R0 K0 - 0x8C080501, // 0008 GETMET R2 R2 K1 - 0x58100002, // 0009 LDCONST R4 K2 - 0x7C080400, // 000A CALL R2 2 - 0xB80A0600, // 000B GETNGBL R2 K3 - 0x88080504, // 000C GETMBR R2 R2 K4 - 0x1C080202, // 000D EQ R2 R1 R2 - 0x780A0001, // 000E JMPF R2 #0011 - 0x80060A00, // 000F RET 1 K5 - 0x7002000D, // 0010 JMP #001F - 0xB80A0600, // 0011 GETNGBL R2 K3 - 0x88080506, // 0012 GETMBR R2 R2 K6 - 0x1C080202, // 0013 EQ R2 R1 R2 - 0x780A0001, // 0014 JMPF R2 #0017 - 0x80060E00, // 0015 RET 1 K7 - 0x70020007, // 0016 JMP #001F - 0xB80A0600, // 0017 GETNGBL R2 K3 - 0x88080508, // 0018 GETMBR R2 R2 K8 - 0x1C080202, // 0019 EQ R2 R1 R2 - 0x780A0001, // 001A JMPF R2 #001D - 0x80061200, // 001B RET 1 K9 - 0x70020001, // 001C JMP #001F - 0x4C080000, // 001D LDNIL R2 - 0x80040400, // 001E RET 1 R2 - 0x80000000, // 001F RET 0 + ( &(const binstruction[15]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x20080403, // 0002 NE R2 R2 R3 + 0x780A0009, // 0003 JMPF R2 #000E + 0x88080101, // 0004 GETMBR R2 R0 K1 + 0x8C080502, // 0005 GETMET R2 R2 K2 + 0x60100009, // 0006 GETGBL R4 G9 + 0x5C140200, // 0007 MOVE R5 R1 + 0x7C100200, // 0008 CALL R4 1 + 0x88140100, // 0009 GETMBR R5 R0 K0 + 0xB81A0600, // 000A GETNGBL R6 K3 + 0x88180D04, // 000B GETMBR R6 R6 K4 + 0x30140A06, // 000C OR R5 R5 R6 + 0x7C080600, // 000D CALL R2 3 + 0x80000000, // 000E RET 0 }) ) ); @@ -1680,11 +1651,11 @@ be_local_closure(lvh_obj_get_align, /* name */ /******************************************************************** -** Solidified function: get_pad_left +** Solidified function: get_text_color ********************************************************************/ -be_local_closure(lvh_obj_get_pad_left, /* name */ +be_local_closure(lvh_obj_get_text_color, /* name */ be_nested_proto( - 5, /* nstack */ + 4, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1692,29 +1663,19 @@ be_local_closure(lvh_obj_get_pad_left, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_part2_selector), - /* K1 */ be_nested_str_weak(_lv_obj), - /* K2 */ be_nested_str_weak(get_style_pad_left), - /* K3 */ be_nested_str_weak(lv), - /* K4 */ be_nested_str_weak(STATE_DEFAULT), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_obj), + /* K1 */ be_nested_str_weak(get_style_text_color), + /* K2 */ be_const_int(0), }), - be_str_weak(get_pad_left), + be_str_weak(get_text_color), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ + ( &(const binstruction[ 5]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x20040202, // 0002 NE R1 R1 R2 - 0x78060007, // 0003 JMPF R1 #000C - 0x88040101, // 0004 GETMBR R1 R0 K1 - 0x8C040302, // 0005 GETMET R1 R1 K2 - 0x880C0100, // 0006 GETMBR R3 R0 K0 - 0xB8120600, // 0007 GETNGBL R4 K3 - 0x88100904, // 0008 GETMBR R4 R4 K4 - 0x300C0604, // 0009 OR R3 R3 R4 - 0x7C040400, // 000A CALL R1 2 - 0x80040200, // 000B RET 1 R1 - 0x80000000, // 000C RET 0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x580C0002, // 0002 LDCONST R3 K2 + 0x7C040400, // 0003 CALL R1 2 + 0x80040200, // 0004 RET 1 R1 }) ) ); @@ -1722,187 +1683,27 @@ be_local_closure(lvh_obj_get_pad_left, /* name */ /******************************************************************** -** Solidified function: set_text_font +** Solidified function: get_click ********************************************************************/ -be_local_closure(lvh_obj_set_text_font, /* name */ +be_local_closure(lvh_obj_get_click, /* name */ be_nested_proto( - 16, /* nstack */ - 2, /* argc */ + 3, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[21]) { /* constants */ - /* K0 */ be_nested_str_weak(int), - /* K1 */ be_nested_str_weak(lv), - /* K2 */ be_nested_str_weak(font_embedded), - /* K3 */ be_nested_str_weak(robotocondensed), - /* K4 */ be_nested_str_weak(montserrat), - /* K5 */ be_nested_str_weak(string), - /* K6 */ be_nested_str_weak(re), - /* K7 */ be_nested_str_weak(split), - /* K8 */ be_nested_str_weak(_X3A), - /* K9 */ be_const_int(1), - /* K10 */ be_nested_str_weak(_X2D), - /* K11 */ be_const_int(0), - /* K12 */ be_const_int(2), - /* K13 */ be_nested_str_weak(concat), - /* K14 */ be_nested_str_weak(match), - /* K15 */ be_nested_str_weak(_X2E_X2A_X5C_X2Ettf_X24), - /* K16 */ be_nested_str_weak(load_freetype_font), - /* K17 */ be_nested_str_weak(load_font), - /* K18 */ be_nested_str_weak(_lv_obj), - /* K19 */ be_nested_str_weak(set_style_text_font), - /* K20 */ be_nested_str_weak(HSP_X3A_X20Unsupported_X20font_X3A), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(get_enabled), }), - be_str_weak(set_text_font), + be_str_weak(get_click), &be_const_str_solidified, - ( &(const binstruction[143]) { /* code */ - 0x4C080000, // 0000 LDNIL R2 - 0x600C0004, // 0001 GETGBL R3 G4 - 0x5C100200, // 0002 MOVE R4 R1 - 0x7C0C0200, // 0003 CALL R3 1 - 0x1C0C0700, // 0004 EQ R3 R3 K0 - 0x780E001B, // 0005 JMPF R3 #0022 - 0xA8020007, // 0006 EXBLK 0 #000F - 0xB80E0200, // 0007 GETNGBL R3 K1 - 0x8C0C0702, // 0008 GETMET R3 R3 K2 - 0x58140003, // 0009 LDCONST R5 K3 - 0x5C180200, // 000A MOVE R6 R1 - 0x7C0C0600, // 000B CALL R3 3 - 0x5C080600, // 000C MOVE R2 R3 - 0xA8040001, // 000D EXBLK 1 1 - 0x70020011, // 000E JMP #0021 - 0xAC0C0000, // 000F CATCH R3 0 0 - 0x7002000E, // 0010 JMP #0020 - 0xA8020007, // 0011 EXBLK 0 #001A - 0xB80E0200, // 0012 GETNGBL R3 K1 - 0x8C0C0702, // 0013 GETMET R3 R3 K2 - 0x58140004, // 0014 LDCONST R5 K4 - 0x5C180200, // 0015 MOVE R6 R1 - 0x7C0C0600, // 0016 CALL R3 3 - 0x5C080600, // 0017 MOVE R2 R3 - 0xA8040001, // 0018 EXBLK 1 1 - 0x70020004, // 0019 JMP #001F - 0xAC0C0000, // 001A CATCH R3 0 0 - 0x70020001, // 001B JMP #001E - 0x80000600, // 001C RET 0 - 0x70020000, // 001D JMP #001F - 0xB0080000, // 001E RAISE 2 R0 R0 - 0x70020000, // 001F JMP #0021 - 0xB0080000, // 0020 RAISE 2 R0 R0 - 0x7002005E, // 0021 JMP #0081 - 0x600C0004, // 0022 GETGBL R3 G4 - 0x5C100200, // 0023 MOVE R4 R1 - 0x7C0C0200, // 0024 CALL R3 1 - 0x1C0C0705, // 0025 EQ R3 R3 K5 - 0x780E0059, // 0026 JMPF R3 #0081 - 0xA40E0A00, // 0027 IMPORT R3 K5 - 0xA4120C00, // 0028 IMPORT R4 K6 - 0x8C140707, // 0029 GETMET R5 R3 K7 - 0x5C1C0200, // 002A MOVE R7 R1 - 0x58200008, // 002B LDCONST R8 K8 - 0x58240009, // 002C LDCONST R9 K9 - 0x7C140800, // 002D CALL R5 4 - 0x8C180707, // 002E GETMET R6 R3 K7 - 0x5C200200, // 002F MOVE R8 R1 - 0x5824000A, // 0030 LDCONST R9 K10 - 0x7C180600, // 0031 CALL R6 3 - 0x5C1C0200, // 0032 MOVE R7 R1 - 0x5820000B, // 0033 LDCONST R8 K11 - 0x50240000, // 0034 LDBOOL R9 0 0 - 0x6028000C, // 0035 GETGBL R10 G12 - 0x5C2C0A00, // 0036 MOVE R11 R5 - 0x7C280200, // 0037 CALL R10 1 - 0x24281509, // 0038 GT R10 R10 K9 - 0x782A0003, // 0039 JMPF R10 #003E - 0x6028000C, // 003A GETGBL R10 G12 - 0x942C0B0B, // 003B GETIDX R11 R5 K11 - 0x7C280200, // 003C CALL R10 1 - 0x742A0000, // 003D JMPT R10 #003F - 0x50280001, // 003E LDBOOL R10 0 1 - 0x50280200, // 003F LDBOOL R10 1 0 - 0x602C000C, // 0040 GETGBL R11 G12 - 0x5C300C00, // 0041 MOVE R12 R6 - 0x7C2C0200, // 0042 CALL R11 1 - 0x282C170C, // 0043 GE R11 R11 K12 - 0x782E000B, // 0044 JMPF R11 #0051 - 0x602C0009, // 0045 GETGBL R11 G9 - 0x5431FFFE, // 0046 LDINT R12 -1 - 0x94300C0C, // 0047 GETIDX R12 R6 R12 - 0x7C2C0200, // 0048 CALL R11 1 - 0x5C201600, // 0049 MOVE R8 R11 - 0x542DFFFD, // 004A LDINT R11 -2 - 0x402E160B, // 004B CONNECT R11 K11 R11 - 0x942C0C0B, // 004C GETIDX R11 R6 R11 - 0x8C2C170D, // 004D GETMET R11 R11 K13 - 0x5834000A, // 004E LDCONST R13 K10 - 0x7C2C0400, // 004F CALL R11 2 - 0x5C1C1600, // 0050 MOVE R7 R11 - 0x8C2C090E, // 0051 GETMET R11 R4 K14 - 0x5834000F, // 0052 LDCONST R13 K15 - 0x5C380E00, // 0053 MOVE R14 R7 - 0x7C2C0600, // 0054 CALL R11 3 - 0x782E0006, // 0055 JMPF R11 #005D - 0x8C2C0707, // 0056 GETMET R11 R3 K7 - 0x5C340E00, // 0057 MOVE R13 R7 - 0x58380008, // 0058 LDCONST R14 K8 - 0x7C2C0600, // 0059 CALL R11 3 - 0x5431FFFE, // 005A LDINT R12 -1 - 0x941C160C, // 005B GETIDX R7 R11 R12 - 0x50240200, // 005C LDBOOL R9 1 0 - 0x78260007, // 005D JMPF R9 #0066 - 0xB82E0200, // 005E GETNGBL R11 K1 - 0x8C2C1710, // 005F GETMET R11 R11 K16 - 0x5C340E00, // 0060 MOVE R13 R7 - 0x5C381000, // 0061 MOVE R14 R8 - 0x583C000B, // 0062 LDCONST R15 K11 - 0x7C2C0800, // 0063 CALL R11 4 - 0x5C081600, // 0064 MOVE R2 R11 - 0x7002001A, // 0065 JMP #0081 - 0x782A0005, // 0066 JMPF R10 #006D - 0xB82E0200, // 0067 GETNGBL R11 K1 - 0x8C2C1711, // 0068 GETMET R11 R11 K17 - 0x5C340200, // 0069 MOVE R13 R1 - 0x7C2C0400, // 006A CALL R11 2 - 0x5C081600, // 006B MOVE R2 R11 - 0x70020013, // 006C JMP #0081 - 0x242C110B, // 006D GT R11 R8 K11 - 0x782E0011, // 006E JMPF R11 #0081 - 0x602C000C, // 006F GETGBL R11 G12 - 0x5C300E00, // 0070 MOVE R12 R7 - 0x7C2C0200, // 0071 CALL R11 1 - 0x242C170B, // 0072 GT R11 R11 K11 - 0x782E000C, // 0073 JMPF R11 #0081 - 0xA8020007, // 0074 EXBLK 0 #007D - 0xB82E0200, // 0075 GETNGBL R11 K1 - 0x8C2C1702, // 0076 GETMET R11 R11 K2 - 0x5C340E00, // 0077 MOVE R13 R7 - 0x5C381000, // 0078 MOVE R14 R8 - 0x7C2C0600, // 0079 CALL R11 3 - 0x5C081600, // 007A MOVE R2 R11 - 0xA8040001, // 007B EXBLK 1 1 - 0x70020003, // 007C JMP #0081 - 0xAC2C0000, // 007D CATCH R11 0 0 - 0x70020000, // 007E JMP #0080 - 0x70020000, // 007F JMP #0081 - 0xB0080000, // 0080 RAISE 2 R0 R0 - 0x4C0C0000, // 0081 LDNIL R3 - 0x200C0403, // 0082 NE R3 R2 R3 - 0x780E0005, // 0083 JMPF R3 #008A - 0x880C0112, // 0084 GETMBR R3 R0 K18 - 0x8C0C0713, // 0085 GETMET R3 R3 K19 - 0x5C140400, // 0086 MOVE R5 R2 - 0x5818000B, // 0087 LDCONST R6 K11 - 0x7C0C0600, // 0088 CALL R3 3 - 0x70020003, // 0089 JMP #008E - 0x600C0001, // 008A GETGBL R3 G1 - 0x58100014, // 008B LDCONST R4 K20 - 0x5C140200, // 008C MOVE R5 R1 - 0x7C0C0400, // 008D CALL R3 2 - 0x80000000, // 008E RET 0 + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80040200, // 0002 RET 1 R1 }) ) ); @@ -1914,7 +1715,7 @@ be_local_closure(lvh_obj_set_text_font, /* name */ ********************************************************************/ be_local_closure(lvh_obj_event_cb, /* name */ be_nested_proto( - 14, /* nstack */ + 15, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1954,7 +1755,7 @@ be_local_closure(lvh_obj_event_cb, /* name */ 0, /* varg */ 1, /* has upvals */ ( &(const bupvaldesc[ 1]) { /* upvals */ - be_local_const_upval(1, 7), + be_local_const_upval(1, 8), }), 0, /* has sup protos */ NULL, /* no sub protos */ @@ -1989,21 +1790,21 @@ be_local_closure(lvh_obj_event_cb, /* name */ /* K10 */ be_nested_str_weak(_event_map), /* K11 */ be_nested_str_weak(find), /* K12 */ be_nested_str_weak(string), - /* K13 */ be_nested_str_weak(EVENT_VALUE_CHANGED), - /* K14 */ be_nested_str_weak(val), - /* K15 */ be_nested_str_weak(format), - /* K16 */ be_nested_str_weak(_X2C_X22val_X22_X3A_X25i), - /* K17 */ be_nested_str_weak(text), - /* K18 */ be_nested_str_weak(json), - /* K19 */ be_nested_str_weak(_X2C_X22text_X22_X3A), - /* K20 */ be_nested_str_weak(dump), + /* K13 */ be_nested_str_weak(json), + /* K14 */ be_nested_str_weak(EVENT_VALUE_CHANGED), + /* K15 */ be_nested_str_weak(val), + /* K16 */ be_nested_str_weak(format), + /* K17 */ be_nested_str_weak(_X2C_X22val_X22_X3A_X25s), + /* K18 */ be_nested_str_weak(dump), + /* K19 */ be_nested_str_weak(text), + /* K20 */ be_nested_str_weak(_X2C_X22text_X22_X3A), /* K21 */ be_nested_str_weak(_X7B_X22hasp_X22_X3A_X7B_X22p_X25ib_X25i_X22_X3A_X7B_X22event_X22_X3A_X22_X25s_X22_X25s_X7D_X7D_X7D), /* K22 */ be_nested_str_weak(_page_id), /* K23 */ be_nested_str_weak(id), }), be_str_weak(event_cb), &be_const_str_solidified, - ( &(const binstruction[71]) { /* code */ + ( &(const binstruction[73]) { /* code */ 0x88080100, // 0000 GETMBR R2 R0 K0 0x88080501, // 0001 GETMBR R2 R2 K1 0x880C0302, // 0002 GETMBR R3 R1 K2 @@ -2025,56 +1826,58 @@ be_local_closure(lvh_obj_event_cb, /* name */ 0x7C100400, // 0012 CALL R4 2 0x4C140000, // 0013 LDNIL R5 0x20140805, // 0014 NE R5 R4 R5 - 0x7816002E, // 0015 JMPF R5 #0045 + 0x78160030, // 0015 JMPF R5 #0047 0xA4161800, // 0016 IMPORT R5 K12 - 0x58180004, // 0017 LDCONST R6 K4 - 0x881C0302, // 0018 GETMBR R7 R1 K2 - 0xB8220A00, // 0019 GETNGBL R8 K5 - 0x8820110D, // 001A GETMBR R8 R8 K13 - 0x1C1C0E08, // 001B EQ R7 R7 R8 - 0x781E0019, // 001C JMPF R7 #0037 - 0xA8020014, // 001D EXBLK 0 #0033 - 0x881C010E, // 001E GETMBR R7 R0 K14 - 0x4C200000, // 001F LDNIL R8 - 0x20200E08, // 0020 NE R8 R7 R8 - 0x78220004, // 0021 JMPF R8 #0027 - 0x8C200B0F, // 0022 GETMET R8 R5 K15 - 0x58280010, // 0023 LDCONST R10 K16 - 0x5C2C0E00, // 0024 MOVE R11 R7 - 0x7C200600, // 0025 CALL R8 3 - 0x5C181000, // 0026 MOVE R6 R8 - 0x88200111, // 0027 GETMBR R8 R0 K17 - 0x4C240000, // 0028 LDNIL R9 - 0x20241009, // 0029 NE R9 R8 R9 - 0x78260005, // 002A JMPF R9 #0031 - 0xA4262400, // 002B IMPORT R9 K18 - 0x00180D13, // 002C ADD R6 R6 K19 - 0x8C281314, // 002D GETMET R10 R9 K20 - 0x5C301000, // 002E MOVE R12 R8 - 0x7C280400, // 002F CALL R10 2 - 0x00180C0A, // 0030 ADD R6 R6 R10 - 0xA8040001, // 0031 EXBLK 1 1 - 0x70020003, // 0032 JMP #0037 - 0xAC1C0000, // 0033 CATCH R7 0 0 - 0x70020000, // 0034 JMP #0036 - 0x70020000, // 0035 JMP #0037 - 0xB0080000, // 0036 RAISE 2 R0 R0 - 0x8C1C0B0F, // 0037 GETMET R7 R5 K15 - 0x58240015, // 0038 LDCONST R9 K21 - 0x88280100, // 0039 GETMBR R10 R0 K0 - 0x88281516, // 003A GETMBR R10 R10 K22 - 0x882C0117, // 003B GETMBR R11 R0 K23 - 0x5C300800, // 003C MOVE R12 R4 - 0x5C340C00, // 003D MOVE R13 R6 - 0x7C1C0C00, // 003E CALL R7 6 - 0xB8220E00, // 003F GETNGBL R8 K7 - 0x8C201108, // 0040 GETMET R8 R8 K8 - 0x58280009, // 0041 LDCONST R10 K9 - 0x842C0001, // 0042 CLOSURE R11 P1 - 0x7C200600, // 0043 CALL R8 3 - 0xA0140000, // 0044 CLOSE R5 - 0xA0000000, // 0045 CLOSE R0 - 0x80000000, // 0046 RET 0 + 0xA41A1A00, // 0017 IMPORT R6 K13 + 0x581C0004, // 0018 LDCONST R7 K4 + 0x88200302, // 0019 GETMBR R8 R1 K2 + 0xB8260A00, // 001A GETNGBL R9 K5 + 0x8824130E, // 001B GETMBR R9 R9 K14 + 0x1C201009, // 001C EQ R8 R8 R9 + 0x7822001A, // 001D JMPF R8 #0039 + 0xA8020015, // 001E EXBLK 0 #0035 + 0x8820010F, // 001F GETMBR R8 R0 K15 + 0x4C240000, // 0020 LDNIL R9 + 0x20241009, // 0021 NE R9 R8 R9 + 0x78260006, // 0022 JMPF R9 #002A + 0x8C240B10, // 0023 GETMET R9 R5 K16 + 0x582C0011, // 0024 LDCONST R11 K17 + 0x8C300D12, // 0025 GETMET R12 R6 K18 + 0x5C381000, // 0026 MOVE R14 R8 + 0x7C300400, // 0027 CALL R12 2 + 0x7C240600, // 0028 CALL R9 3 + 0x5C1C1200, // 0029 MOVE R7 R9 + 0x88240113, // 002A GETMBR R9 R0 K19 + 0x4C280000, // 002B LDNIL R10 + 0x2028120A, // 002C NE R10 R9 R10 + 0x782A0004, // 002D JMPF R10 #0033 + 0x001C0F14, // 002E ADD R7 R7 K20 + 0x8C280D12, // 002F GETMET R10 R6 K18 + 0x5C301200, // 0030 MOVE R12 R9 + 0x7C280400, // 0031 CALL R10 2 + 0x001C0E0A, // 0032 ADD R7 R7 R10 + 0xA8040001, // 0033 EXBLK 1 1 + 0x70020003, // 0034 JMP #0039 + 0xAC200000, // 0035 CATCH R8 0 0 + 0x70020000, // 0036 JMP #0038 + 0x70020000, // 0037 JMP #0039 + 0xB0080000, // 0038 RAISE 2 R0 R0 + 0x8C200B10, // 0039 GETMET R8 R5 K16 + 0x58280015, // 003A LDCONST R10 K21 + 0x882C0100, // 003B GETMBR R11 R0 K0 + 0x882C1716, // 003C GETMBR R11 R11 K22 + 0x88300117, // 003D GETMBR R12 R0 K23 + 0x5C340800, // 003E MOVE R13 R4 + 0x5C380E00, // 003F MOVE R14 R7 + 0x7C200C00, // 0040 CALL R8 6 + 0xB8260E00, // 0041 GETNGBL R9 K7 + 0x8C241308, // 0042 GETMET R9 R9 K8 + 0x582C0009, // 0043 LDCONST R11 K9 + 0x84300001, // 0044 CLOSURE R12 P1 + 0x7C240600, // 0045 CALL R9 3 + 0xA0140000, // 0046 CLOSE R5 + 0xA0000000, // 0047 CLOSE R0 + 0x80000000, // 0048 RET 0 }) ) ); @@ -2082,11 +1885,11 @@ be_local_closure(lvh_obj_event_cb, /* name */ /******************************************************************** -** Solidified function: get_value_color +** Solidified function: get_toggle ********************************************************************/ -be_local_closure(lvh_obj_get_value_color, /* name */ +be_local_closure(lvh_obj_get_toggle, /* name */ be_nested_proto( - 3, /* nstack */ + 4, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2094,15 +1897,21 @@ be_local_closure(lvh_obj_get_value_color, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(get_value_color), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_obj), + /* K1 */ be_nested_str_weak(has_state), + /* K2 */ be_nested_str_weak(lv), + /* K3 */ be_nested_str_weak(STATE_CHECKED), }), - be_str_weak(get_value_color), + be_str_weak(get_toggle), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x80040200, // 0002 RET 1 R1 + ( &(const binstruction[ 6]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0xB80E0400, // 0002 GETNGBL R3 K2 + 0x880C0703, // 0003 GETMBR R3 R3 K3 + 0x7C040400, // 0004 CALL R1 2 + 0x80040200, // 0005 RET 1 R1 }) ) ); @@ -2110,26 +1919,60 @@ be_local_closure(lvh_obj_get_value_color, /* name */ /******************************************************************** -** Solidified function: get_val_rule +** Solidified function: set_text_rule_formula ********************************************************************/ -be_local_closure(lvh_obj_get_val_rule, /* name */ +be_local_closure(lvh_obj_set_text_rule_formula, /* name */ be_nested_proto( - 2, /* nstack */ - 1, /* argc */ + 13, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(_val_rule), + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(_text_rule_formula), + /* K1 */ be_nested_str_weak(return_X20_X2F_X20val_X20_X2D_X3E_X20_X28), + /* K2 */ be_nested_str_weak(_X29), + /* K3 */ be_nested_str_weak(_text_rule_function), + /* K4 */ be_nested_str_weak(string), + /* K5 */ be_nested_str_weak(format), + /* K6 */ be_nested_str_weak(HSP_X3A_X20failed_X20to_X20compile_X20_X27_X25s_X27_X20_X2D_X20_X25s_X20_X28_X25s_X29), }), - be_str_weak(get_val_rule), + be_str_weak(set_text_rule_formula), &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 + ( &(const binstruction[30]) { /* code */ + 0x60080008, // 0000 GETGBL R2 G8 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x90020002, // 0003 SETMBR R0 K0 R2 + 0x88080100, // 0004 GETMBR R2 R0 K0 + 0x000A0202, // 0005 ADD R2 K1 R2 + 0x00080502, // 0006 ADD R2 R2 K2 + 0xA8020007, // 0007 EXBLK 0 #0010 + 0x600C000D, // 0008 GETGBL R3 G13 + 0x5C100400, // 0009 MOVE R4 R2 + 0x7C0C0200, // 000A CALL R3 1 + 0x5C100600, // 000B MOVE R4 R3 + 0x7C100000, // 000C CALL R4 0 + 0x90020604, // 000D SETMBR R0 K3 R4 + 0xA8040001, // 000E EXBLK 1 1 + 0x7002000C, // 000F JMP #001D + 0xAC0C0002, // 0010 CATCH R3 0 2 + 0x70020009, // 0011 JMP #001C + 0xA4160800, // 0012 IMPORT R5 K4 + 0x60180001, // 0013 GETGBL R6 G1 + 0x8C1C0B05, // 0014 GETMET R7 R5 K5 + 0x58240006, // 0015 LDCONST R9 K6 + 0x5C280400, // 0016 MOVE R10 R2 + 0x5C2C0600, // 0017 MOVE R11 R3 + 0x5C300800, // 0018 MOVE R12 R4 + 0x7C1C0A00, // 0019 CALL R7 5 + 0x7C180200, // 001A CALL R6 1 + 0x70020000, // 001B JMP #001D + 0xB0080000, // 001C RAISE 2 R0 R0 + 0x80000000, // 001D RET 0 }) ) ); @@ -2137,11 +1980,11 @@ be_local_closure(lvh_obj_get_val_rule, /* name */ /******************************************************************** -** Solidified function: get_val +** Solidified function: get_pad_top ********************************************************************/ -be_local_closure(lvh_obj_get_val, /* name */ +be_local_closure(lvh_obj_get_pad_top, /* name */ be_nested_proto( - 3, /* nstack */ + 5, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2149,17 +1992,29 @@ be_local_closure(lvh_obj_get_val, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(get_value), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_part2_selector), + /* K1 */ be_nested_str_weak(_lv_obj), + /* K2 */ be_nested_str_weak(get_style_pad_top), + /* K3 */ be_nested_str_weak(lv), + /* K4 */ be_nested_str_weak(STATE_DEFAULT), }), - be_str_weak(get_val), + be_str_weak(get_pad_top), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ + ( &(const binstruction[13]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 + 0x4C080000, // 0001 LDNIL R2 + 0x20040202, // 0002 NE R1 R1 R2 + 0x78060007, // 0003 JMPF R1 #000C + 0x88040101, // 0004 GETMBR R1 R0 K1 + 0x8C040302, // 0005 GETMET R1 R1 K2 + 0x880C0100, // 0006 GETMBR R3 R0 K0 + 0xB8120600, // 0007 GETNGBL R4 K3 + 0x88100904, // 0008 GETMBR R4 R4 K4 + 0x300C0604, // 0009 OR R3 R3 R4 + 0x7C040400, // 000A CALL R1 2 + 0x80040200, // 000B RET 1 R1 + 0x80000000, // 000C RET 0 }) ) ); @@ -2167,27 +2022,41 @@ be_local_closure(lvh_obj_get_val, /* name */ /******************************************************************** -** Solidified function: get_click +** Solidified function: set_adjustable ********************************************************************/ -be_local_closure(lvh_obj_get_click, /* name */ +be_local_closure(lvh_obj_set_adjustable, /* name */ be_nested_proto( - 3, /* nstack */ - 1, /* argc */ + 5, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(get_enabled), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_obj), + /* K1 */ be_nested_str_weak(add_flag), + /* K2 */ be_nested_str_weak(lv), + /* K3 */ be_nested_str_weak(OBJ_FLAG_CLICKABLE), + /* K4 */ be_nested_str_weak(clear_flag), }), - be_str_weak(get_click), + be_str_weak(set_adjustable), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x80040200, // 0002 RET 1 R1 + ( &(const binstruction[13]) { /* code */ + 0x78060005, // 0000 JMPF R1 #0007 + 0x88080100, // 0001 GETMBR R2 R0 K0 + 0x8C080501, // 0002 GETMET R2 R2 K1 + 0xB8120400, // 0003 GETNGBL R4 K2 + 0x88100903, // 0004 GETMBR R4 R4 K3 + 0x7C080400, // 0005 CALL R2 2 + 0x70020004, // 0006 JMP #000C + 0x88080100, // 0007 GETMBR R2 R0 K0 + 0x8C080504, // 0008 GETMET R2 R2 K4 + 0xB8120400, // 0009 GETNGBL R4 K2 + 0x88100903, // 000A GETMBR R4 R4 K3 + 0x7C080400, // 000B CALL R2 2 + 0x80000000, // 000C RET 0 }) ) ); @@ -2195,9 +2064,9 @@ be_local_closure(lvh_obj_get_click, /* name */ /******************************************************************** -** Solidified function: set_click +** Solidified function: set_value_color ********************************************************************/ -be_local_closure(lvh_obj_set_click, /* name */ +be_local_closure(lvh_obj_set_value_color, /* name */ be_nested_proto( 5, /* nstack */ 2, /* argc */ @@ -2208,9 +2077,9 @@ be_local_closure(lvh_obj_set_click, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(set_enabled), + /* K0 */ be_nested_str_weak(set_text_color), }), - be_str_weak(set_click), + be_str_weak(set_value_color), &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ 0x8C080100, // 0000 GETMET R2 R0 K0 @@ -2224,108 +2093,92 @@ be_local_closure(lvh_obj_set_click, /* name */ /******************************************************************** -** Solidified function: member +** Solidified function: register_event_cb ********************************************************************/ -be_local_closure(lvh_obj_member, /* name */ +be_local_closure(lvh_obj_register_event_cb, /* name */ be_nested_proto( - 11, /* nstack */ - 2, /* argc */ + 8, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[16]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(introspect), - /* K2 */ be_const_int(0), - /* K3 */ be_const_int(3), - /* K4 */ be_nested_str_weak(set_), - /* K5 */ be_nested_str_weak(get_), - /* K6 */ be_nested_str_weak(_attr_ignore), - /* K7 */ be_nested_str_weak(find), - /* K8 */ be_nested_str_weak(get), - /* K9 */ be_nested_str_weak(function), - /* K10 */ be_nested_str_weak(_attr_map), - /* K11 */ be_nested_str_weak(contains), - /* K12 */ be_nested_str_weak(_lv_obj), - /* K13 */ be_nested_str_weak(style_), - /* K14 */ be_nested_str_weak(unknown_X20attribute_X20), - /* K15 */ be_nested_str_weak(value_error), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_weak(_page), + /* K1 */ be_nested_str_weak(_oh), + /* K2 */ be_nested_str_weak(_event_map), + /* K3 */ be_nested_str_weak(keys), + /* K4 */ be_nested_str_weak(register_event), + /* K5 */ be_nested_str_weak(stop_iteration), }), - be_str_weak(member), + be_str_weak(register_event_cb), &be_const_str_solidified, - ( &(const binstruction[69]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0xA40E0200, // 0001 IMPORT R3 K1 - 0x40120503, // 0002 CONNECT R4 K2 K3 - 0x94100204, // 0003 GETIDX R4 R1 R4 - 0x1C140904, // 0004 EQ R5 R4 K4 - 0x74160001, // 0005 JMPT R5 #0008 - 0x1C140905, // 0006 EQ R5 R4 K5 - 0x78160000, // 0007 JMPF R5 #0009 - 0x80000A00, // 0008 RET 0 - 0x88140106, // 0009 GETMBR R5 R0 K6 - 0x8C140B07, // 000A GETMET R5 R5 K7 - 0x5C1C0200, // 000B MOVE R7 R1 - 0x7C140400, // 000C CALL R5 2 - 0x4C180000, // 000D LDNIL R6 - 0x20140A06, // 000E NE R5 R5 R6 - 0x78160000, // 000F JMPF R5 #0011 - 0x80000A00, // 0010 RET 0 - 0x8C140708, // 0011 GETMET R5 R3 K8 - 0x5C1C0000, // 0012 MOVE R7 R0 - 0x00220A01, // 0013 ADD R8 K5 R1 - 0x7C140600, // 0014 CALL R5 3 - 0x60180004, // 0015 GETGBL R6 G4 - 0x5C1C0A00, // 0016 MOVE R7 R5 - 0x7C180200, // 0017 CALL R6 1 - 0x1C180D09, // 0018 EQ R6 R6 K9 - 0x781A0003, // 0019 JMPF R6 #001E - 0x5C180A00, // 001A MOVE R6 R5 - 0x5C1C0000, // 001B MOVE R7 R0 - 0x7C180200, // 001C CALL R6 1 - 0x80040C00, // 001D RET 1 R6 - 0x8818010A, // 001E GETMBR R6 R0 K10 - 0x8C180D0B, // 001F GETMET R6 R6 K11 - 0x5C200200, // 0020 MOVE R8 R1 - 0x7C180400, // 0021 CALL R6 2 - 0x781A001B, // 0022 JMPF R6 #003F - 0x8818010A, // 0023 GETMBR R6 R0 K10 - 0x94180C01, // 0024 GETIDX R6 R6 R1 - 0x8C1C0708, // 0025 GETMET R7 R3 K8 - 0x8824010C, // 0026 GETMBR R9 R0 K12 - 0x002A0A06, // 0027 ADD R10 K5 R6 - 0x7C1C0600, // 0028 CALL R7 3 - 0x5C140E00, // 0029 MOVE R5 R7 - 0x601C0004, // 002A GETGBL R7 G4 - 0x5C200A00, // 002B MOVE R8 R5 - 0x7C1C0200, // 002C CALL R7 1 - 0x1C1C0F09, // 002D EQ R7 R7 K9 - 0x781E000F, // 002E JMPF R7 #003F - 0x8C1C0507, // 002F GETMET R7 R2 K7 - 0x5C240C00, // 0030 MOVE R9 R6 - 0x5828000D, // 0031 LDCONST R10 K13 - 0x7C1C0600, // 0032 CALL R7 3 - 0x1C1C0F02, // 0033 EQ R7 R7 K2 - 0x781E0005, // 0034 JMPF R7 #003B - 0x5C1C0A00, // 0035 MOVE R7 R5 - 0x8820010C, // 0036 GETMBR R8 R0 K12 - 0x58240002, // 0037 LDCONST R9 K2 - 0x7C1C0400, // 0038 CALL R7 2 - 0x80040E00, // 0039 RET 1 R7 - 0x70020003, // 003A JMP #003F - 0x5C1C0A00, // 003B MOVE R7 R5 - 0x8820010C, // 003C GETMBR R8 R0 K12 - 0x7C1C0200, // 003D CALL R7 1 - 0x80040E00, // 003E RET 1 R7 - 0x60180008, // 003F GETGBL R6 G8 - 0x5C1C0200, // 0040 MOVE R7 R1 - 0x7C180200, // 0041 CALL R6 1 - 0x001A1C06, // 0042 ADD R6 K14 R6 - 0xB0061E06, // 0043 RAISE 1 K15 R6 - 0x80000000, // 0044 RET 0 + ( &(const binstruction[19]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x88040301, // 0001 GETMBR R1 R1 K1 + 0x60080010, // 0002 GETGBL R2 G16 + 0x880C0102, // 0003 GETMBR R3 R0 K2 + 0x8C0C0703, // 0004 GETMET R3 R3 K3 + 0x7C0C0200, // 0005 CALL R3 1 + 0x7C080200, // 0006 CALL R2 1 + 0xA8020006, // 0007 EXBLK 0 #000F + 0x5C0C0400, // 0008 MOVE R3 R2 + 0x7C0C0000, // 0009 CALL R3 0 + 0x8C100304, // 000A GETMET R4 R1 K4 + 0x5C180000, // 000B MOVE R6 R0 + 0x5C1C0600, // 000C MOVE R7 R3 + 0x7C100600, // 000D CALL R4 3 + 0x7001FFF8, // 000E JMP #0008 + 0x58080005, // 000F LDCONST R2 K5 + 0xAC080200, // 0010 CATCH R2 1 0 + 0xB0080000, // 0011 RAISE 2 R0 R0 + 0x80000000, // 0012 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_pad_all2 +********************************************************************/ +be_local_closure(lvh_obj_set_pad_all2, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_part2_selector), + /* K1 */ be_nested_str_weak(_lv_obj), + /* K2 */ be_nested_str_weak(set_style_pad_all), + /* K3 */ be_nested_str_weak(lv), + /* K4 */ be_nested_str_weak(STATE_DEFAULT), + }), + be_str_weak(set_pad_all2), + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x20080403, // 0002 NE R2 R2 R3 + 0x780A0009, // 0003 JMPF R2 #000E + 0x88080101, // 0004 GETMBR R2 R0 K1 + 0x8C080502, // 0005 GETMET R2 R2 K2 + 0x60100009, // 0006 GETGBL R4 G9 + 0x5C140200, // 0007 MOVE R5 R1 + 0x7C100200, // 0008 CALL R4 1 + 0x88140100, // 0009 GETMBR R5 R0 K0 + 0xB81A0600, // 000A GETNGBL R6 K3 + 0x88180D04, // 000B GETMBR R6 R6 K4 + 0x30140A06, // 000C OR R5 R5 R6 + 0x7C080600, // 000D CALL R2 3 + 0x80000000, // 000E RET 0 }) ) ); @@ -2360,29 +2213,23 @@ be_local_closure(lvh_obj_get_text_rule_formula, /* name */ /******************************************************************** -** Solidified function: get_value_ofs_y +** Solidified function: get_text_font ********************************************************************/ -be_local_closure(lvh_obj_get_value_ofs_y, /* name */ +be_local_closure(lvh_obj_get_text_font, /* name */ be_nested_proto( - 3, /* nstack */ + 1, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_label), - /* K1 */ be_nested_str_weak(get_y), - }), - be_str_weak(get_value_ofs_y), + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(get_text_font), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 }) ) ); @@ -2390,11 +2237,11 @@ be_local_closure(lvh_obj_get_value_ofs_y, /* name */ /******************************************************************** -** Solidified function: get_obj +** Solidified function: get_hidden ********************************************************************/ -be_local_closure(lvh_obj_get_obj, /* name */ +be_local_closure(lvh_obj_get_hidden, /* name */ be_nested_proto( - 2, /* nstack */ + 4, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2402,14 +2249,21 @@ be_local_closure(lvh_obj_get_obj, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ + ( &(const bvalue[ 4]) { /* constants */ /* K0 */ be_nested_str_weak(_lv_obj), + /* K1 */ be_nested_str_weak(has_flag), + /* K2 */ be_nested_str_weak(lv), + /* K3 */ be_nested_str_weak(OBJ_FLAG_HIDDEN), }), - be_str_weak(get_obj), + be_str_weak(get_hidden), &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ + ( &(const binstruction[ 6]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0xB80E0400, // 0002 GETNGBL R3 K2 + 0x880C0703, // 0003 GETMBR R3 R3 K3 + 0x7C040400, // 0004 CALL R1 2 + 0x80040200, // 0005 RET 1 R1 }) ) ); @@ -2417,38 +2271,27 @@ be_local_closure(lvh_obj_get_obj, /* name */ /******************************************************************** -** Solidified function: is_color_attribute +** Solidified function: get_value_str ********************************************************************/ -be_local_closure(lvh_obj_is_color_attribute, /* name */ +be_local_closure(lvh_obj_get_value_str, /* name */ be_nested_proto( - 9, /* nstack */ + 3, /* nstack */ 1, /* argc */ - 4, /* varg */ + 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_const_class(be_class_lvh_obj), - /* K1 */ be_nested_str_weak(re), - /* K2 */ be_nested_str_weak(search), - /* K3 */ be_nested_str_weak(color_X24), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(get_text), }), - be_str_weak(is_color_attribute), + be_str_weak(get_value_str), &be_const_str_solidified, - ( &(const binstruction[11]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0x600C0017, // 0002 GETGBL R3 G23 - 0x8C100502, // 0003 GETMET R4 R2 K2 - 0x58180003, // 0004 LDCONST R6 K3 - 0x601C0008, // 0005 GETGBL R7 G8 - 0x5C200000, // 0006 MOVE R8 R0 - 0x7C1C0200, // 0007 CALL R7 1 - 0x7C100600, // 0008 CALL R4 3 - 0x7C0C0200, // 0009 CALL R3 1 - 0x80040600, // 000A RET 1 R3 + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80040200, // 0002 RET 1 R1 }) ) ); @@ -2456,84 +2299,51 @@ be_local_closure(lvh_obj_is_color_attribute, /* name */ /******************************************************************** -** Solidified function: set_mode +** Solidified function: remove_trailing_zeroes ********************************************************************/ -be_local_closure(lvh_obj_set_mode, /* name */ +be_local_closure(lvh_obj_remove_trailing_zeroes, /* name */ be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 2, /* varg */ + 8, /* nstack */ + 1, /* argc */ + 4, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[18]) { /* constants */ - /* K0 */ be_nested_str_weak(expand), - /* K1 */ be_nested_str_weak(_lv_obj), - /* K2 */ be_nested_str_weak(set_width), - /* K3 */ be_nested_str_weak(lv), - /* K4 */ be_nested_str_weak(SIZE_CONTENT), - /* K5 */ be_nested_str_weak(break), - /* K6 */ be_nested_str_weak(LABEL_LONG_WRAP), - /* K7 */ be_nested_str_weak(dots), - /* K8 */ be_nested_str_weak(LABEL_LONG_DOT), - /* K9 */ be_nested_str_weak(scroll), - /* K10 */ be_nested_str_weak(LABEL_LONG_SCROLL), - /* K11 */ be_nested_str_weak(loop), - /* K12 */ be_nested_str_weak(LABEL_LONG_SCROLL_CIRCULAR), - /* K13 */ be_nested_str_weak(crop), - /* K14 */ be_nested_str_weak(LABEL_LONG_CLIP), - /* K15 */ be_nested_str_weak(check_label), - /* K16 */ be_nested_str_weak(_lv_label), - /* K17 */ be_nested_str_weak(set_long_mode), - }), - be_str_weak(set_mode), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_const_class(be_class_lvh_obj), + /* K1 */ be_const_int(0), + /* K2 */ be_const_int(1), + /* K3 */ be_nested_str_weak(resize), + }), + be_str_weak(remove_trailing_zeroes), &be_const_str_solidified, - ( &(const binstruction[43]) { /* code */ - 0x4C080000, // 0000 LDNIL R2 - 0x1C0C0300, // 0001 EQ R3 R1 K0 - 0x780E0005, // 0002 JMPF R3 #0009 - 0x880C0101, // 0003 GETMBR R3 R0 K1 - 0x8C0C0702, // 0004 GETMET R3 R3 K2 - 0xB8160600, // 0005 GETNGBL R5 K3 - 0x88140B04, // 0006 GETMBR R5 R5 K4 - 0x7C0C0400, // 0007 CALL R3 2 - 0x70020017, // 0008 JMP #0021 - 0x1C0C0305, // 0009 EQ R3 R1 K5 - 0x780E0002, // 000A JMPF R3 #000E - 0xB80E0600, // 000B GETNGBL R3 K3 - 0x88080706, // 000C GETMBR R2 R3 K6 - 0x70020012, // 000D JMP #0021 - 0x1C0C0307, // 000E EQ R3 R1 K7 - 0x780E0002, // 000F JMPF R3 #0013 - 0xB80E0600, // 0010 GETNGBL R3 K3 - 0x88080708, // 0011 GETMBR R2 R3 K8 - 0x7002000D, // 0012 JMP #0021 - 0x1C0C0309, // 0013 EQ R3 R1 K9 - 0x780E0002, // 0014 JMPF R3 #0018 - 0xB80E0600, // 0015 GETNGBL R3 K3 - 0x8808070A, // 0016 GETMBR R2 R3 K10 - 0x70020008, // 0017 JMP #0021 - 0x1C0C030B, // 0018 EQ R3 R1 K11 - 0x780E0002, // 0019 JMPF R3 #001D - 0xB80E0600, // 001A GETNGBL R3 K3 - 0x8808070C, // 001B GETMBR R2 R3 K12 - 0x70020003, // 001C JMP #0021 - 0x1C0C030D, // 001D EQ R3 R1 K13 - 0x780E0001, // 001E JMPF R3 #0021 - 0xB80E0600, // 001F GETNGBL R3 K3 - 0x8808070E, // 0020 GETMBR R2 R3 K14 - 0x4C0C0000, // 0021 LDNIL R3 - 0x200C0403, // 0022 NE R3 R2 R3 - 0x780E0005, // 0023 JMPF R3 #002A - 0x8C0C010F, // 0024 GETMET R3 R0 K15 - 0x7C0C0200, // 0025 CALL R3 1 - 0x880C0110, // 0026 GETMBR R3 R0 K16 - 0x8C0C0711, // 0027 GETMET R3 R3 K17 - 0x5C140400, // 0028 MOVE R5 R2 - 0x7C0C0400, // 0029 CALL R3 2 - 0x80000000, // 002A RET 0 + ( &(const binstruction[24]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x6008000C, // 0001 GETGBL R2 G12 + 0x5C0C0000, // 0002 MOVE R3 R0 + 0x7C080200, // 0003 CALL R2 1 + 0x580C0001, // 0004 LDCONST R3 K1 + 0x14100602, // 0005 LT R4 R3 R2 + 0x78120007, // 0006 JMPF R4 #000F + 0x5411FFFE, // 0007 LDINT R4 -1 + 0x04100803, // 0008 SUB R4 R4 R3 + 0x94100004, // 0009 GETIDX R4 R0 R4 + 0x20100901, // 000A NE R4 R4 K1 + 0x78120000, // 000B JMPF R4 #000D + 0x70020001, // 000C JMP #000F + 0x000C0702, // 000D ADD R3 R3 K2 + 0x7001FFF5, // 000E JMP #0005 + 0x24100701, // 000F GT R4 R3 K1 + 0x78120005, // 0010 JMPF R4 #0017 + 0x8C100103, // 0011 GETMET R4 R0 K3 + 0x6018000C, // 0012 GETGBL R6 G12 + 0x5C1C0000, // 0013 MOVE R7 R0 + 0x7C180200, // 0014 CALL R6 1 + 0x04180C03, // 0015 SUB R6 R6 R3 + 0x7C100400, // 0016 CALL R4 2 + 0x80040000, // 0017 RET 1 R0 }) ) ); @@ -2541,9 +2351,9 @@ be_local_closure(lvh_obj_set_mode, /* name */ /******************************************************************** -** Solidified function: set_value_color +** Solidified function: set_click ********************************************************************/ -be_local_closure(lvh_obj_set_value_color, /* name */ +be_local_closure(lvh_obj_set_click, /* name */ be_nested_proto( 5, /* nstack */ 2, /* argc */ @@ -2554,9 +2364,9 @@ be_local_closure(lvh_obj_set_value_color, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(set_text_color), + /* K0 */ be_nested_str_weak(set_enabled), }), - be_str_weak(set_value_color), + be_str_weak(set_click), &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ 0x8C080100, // 0000 GETMET R2 R0 K0 @@ -2570,85 +2380,11 @@ be_local_closure(lvh_obj_set_value_color, /* name */ /******************************************************************** -** Solidified function: set_text_rule -********************************************************************/ -be_local_closure(lvh_obj_set_text_rule, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 1]) { - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 1]) { /* upvals */ - be_local_const_upval(1, 0), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(text_rule_matched), - }), - be_str_weak(_X3Clambda_X3E), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x68040000, // 0000 GETUPV R1 U0 - 0x8C040300, // 0001 GETMET R1 R1 K0 - 0x5C0C0000, // 0002 MOVE R3 R0 - 0x7C040400, // 0003 CALL R1 2 - 0x80040200, // 0004 RET 1 R1 - }) - ), - }), - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(_text_rule), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(remove_rule), - /* K3 */ be_nested_str_weak(add_rule), - }), - be_str_weak(set_text_rule), - &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x20080403, // 0002 NE R2 R2 R3 - 0x780A0004, // 0003 JMPF R2 #0009 - 0xB80A0200, // 0004 GETNGBL R2 K1 - 0x8C080502, // 0005 GETMET R2 R2 K2 - 0x88100100, // 0006 GETMBR R4 R0 K0 - 0x5C140000, // 0007 MOVE R5 R0 - 0x7C080600, // 0008 CALL R2 3 - 0x60080008, // 0009 GETGBL R2 G8 - 0x5C0C0200, // 000A MOVE R3 R1 - 0x7C080200, // 000B CALL R2 1 - 0x90020002, // 000C SETMBR R0 K0 R2 - 0xB80A0200, // 000D GETNGBL R2 K1 - 0x8C080503, // 000E GETMET R2 R2 K3 - 0x88100100, // 000F GETMBR R4 R0 K0 - 0x84140000, // 0010 CLOSURE R5 P0 - 0x5C180000, // 0011 MOVE R6 R0 - 0x7C080800, // 0012 CALL R2 4 - 0xA0000000, // 0013 CLOSE R0 - 0x80000000, // 0014 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_adjustable +** Solidified function: get_text ********************************************************************/ -be_local_closure(lvh_obj_get_adjustable, /* name */ +be_local_closure(lvh_obj_get_text, /* name */ be_nested_proto( - 4, /* nstack */ + 3, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2656,21 +2392,23 @@ be_local_closure(lvh_obj_get_adjustable, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(has_flag), - /* K2 */ be_nested_str_weak(lv), - /* K3 */ be_nested_str_weak(OBJ_FLAG_CLICKABLE), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_label), + /* K1 */ be_nested_str_weak(get_text), }), - be_str_weak(get_adjustable), + be_str_weak(get_text), &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ + ( &(const binstruction[10]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0xB80E0400, // 0002 GETNGBL R3 K2 - 0x880C0703, // 0003 GETMBR R3 R3 K3 - 0x7C040400, // 0004 CALL R1 2 + 0x4C080000, // 0001 LDNIL R2 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x78060001, // 0003 JMPF R1 #0006 + 0x4C040000, // 0004 LDNIL R1 0x80040200, // 0005 RET 1 R1 + 0x88040100, // 0006 GETMBR R1 R0 K0 + 0x8C040301, // 0007 GETMET R1 R1 K1 + 0x7C040200, // 0008 CALL R1 1 + 0x80040200, // 0009 RET 1 R1 }) ) ); @@ -2678,33 +2416,29 @@ be_local_closure(lvh_obj_get_adjustable, /* name */ /******************************************************************** -** Solidified function: get_toggle +** Solidified function: set_action ********************************************************************/ -be_local_closure(lvh_obj_get_toggle, /* name */ +be_local_closure(lvh_obj_set_action, /* name */ be_nested_proto( 4, /* nstack */ - 1, /* argc */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(has_state), - /* K2 */ be_nested_str_weak(lv), - /* K3 */ be_nested_str_weak(STATE_CHECKED), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(_action), }), - be_str_weak(get_toggle), + be_str_weak(set_action), &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0xB80E0400, // 0002 GETNGBL R3 K2 - 0x880C0703, // 0003 GETMBR R3 R3 K3 - 0x7C040400, // 0004 CALL R1 2 - 0x80040200, // 0005 RET 1 R1 + ( &(const binstruction[ 5]) { /* code */ + 0x60080008, // 0000 GETGBL R2 G8 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x90020002, // 0003 SETMBR R0 K0 R2 + 0x80000000, // 0004 RET 0 }) ) ); @@ -2712,37 +2446,277 @@ be_local_closure(lvh_obj_get_toggle, /* name */ /******************************************************************** -** Solidified function: get_value_str +** Solidified function: setmember ********************************************************************/ -be_local_closure(lvh_obj_get_value_str, /* name */ +be_local_closure(lvh_obj_setmember, /* name */ be_nested_proto( - 3, /* nstack */ - 1, /* argc */ + 12, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(get_text), + ( &(const bvalue[19]) { /* constants */ + /* K0 */ be_nested_str_weak(string), + /* K1 */ be_nested_str_weak(introspect), + /* K2 */ be_const_int(0), + /* K3 */ be_const_int(3), + /* K4 */ be_nested_str_weak(set_), + /* K5 */ be_nested_str_weak(get_), + /* K6 */ be_nested_str_weak(_attr_ignore), + /* K7 */ be_nested_str_weak(find), + /* K8 */ be_nested_str_weak(get), + /* K9 */ be_nested_str_weak(function), + /* K10 */ be_nested_str_weak(_attr_map), + /* K11 */ be_nested_str_weak(contains), + /* K12 */ be_nested_str_weak(_lv_obj), + /* K13 */ be_nested_str_weak(is_color_attribute), + /* K14 */ be_nested_str_weak(parse_color), + /* K15 */ be_nested_str_weak(style_), + /* K16 */ be_nested_str_weak(_X20for_X20), + /* K17 */ be_nested_str_weak(HSP_X3A_X20Could_X20not_X20find_X20function_X20set_), + /* K18 */ be_nested_str_weak(HSP_X3A_X20unknown_X20attribute_X3A), }), - be_str_weak(get_value_str), + be_str_weak(setmember), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x80040200, // 0002 RET 1 R1 - }) - ) -); + ( &(const binstruction[93]) { /* code */ + 0xA40E0000, // 0000 IMPORT R3 K0 + 0xA4120200, // 0001 IMPORT R4 K1 + 0x40160503, // 0002 CONNECT R5 K2 K3 + 0x94140205, // 0003 GETIDX R5 R1 R5 + 0x1C180B04, // 0004 EQ R6 R5 K4 + 0x741A0001, // 0005 JMPT R6 #0008 + 0x1C180B05, // 0006 EQ R6 R5 K5 + 0x781A0000, // 0007 JMPF R6 #0009 + 0x80000C00, // 0008 RET 0 + 0x88180106, // 0009 GETMBR R6 R0 K6 + 0x8C180D07, // 000A GETMET R6 R6 K7 + 0x5C200200, // 000B MOVE R8 R1 + 0x7C180400, // 000C CALL R6 2 + 0x4C1C0000, // 000D LDNIL R7 + 0x20180C07, // 000E NE R6 R6 R7 + 0x781A0000, // 000F JMPF R6 #0011 + 0x80000C00, // 0010 RET 0 + 0x8C180908, // 0011 GETMET R6 R4 K8 + 0x5C200000, // 0012 MOVE R8 R0 + 0x00260801, // 0013 ADD R9 K4 R1 + 0x7C180600, // 0014 CALL R6 3 + 0x601C0004, // 0015 GETGBL R7 G4 + 0x5C200C00, // 0016 MOVE R8 R6 + 0x7C1C0200, // 0017 CALL R7 1 + 0x1C1C0F09, // 0018 EQ R7 R7 K9 + 0x781E0004, // 0019 JMPF R7 #001F + 0x5C1C0C00, // 001A MOVE R7 R6 + 0x5C200000, // 001B MOVE R8 R0 + 0x5C240400, // 001C MOVE R9 R2 + 0x7C1C0400, // 001D CALL R7 2 + 0x80000E00, // 001E RET 0 + 0x881C010A, // 001F GETMBR R7 R0 K10 + 0x8C1C0F0B, // 0020 GETMET R7 R7 K11 + 0x5C240200, // 0021 MOVE R9 R1 + 0x7C1C0400, // 0022 CALL R7 2 + 0x781E0033, // 0023 JMPF R7 #0058 + 0x881C010A, // 0024 GETMBR R7 R0 K10 + 0x941C0E01, // 0025 GETIDX R7 R7 R1 + 0x8C200908, // 0026 GETMET R8 R4 K8 + 0x8828010C, // 0027 GETMBR R10 R0 K12 + 0x002E0807, // 0028 ADD R11 K4 R7 + 0x7C200600, // 0029 CALL R8 3 + 0x5C181000, // 002A MOVE R6 R8 + 0x8C20010D, // 002B GETMET R8 R0 K13 + 0x5C280E00, // 002C MOVE R10 R7 + 0x7C200400, // 002D CALL R8 2 + 0x78220003, // 002E JMPF R8 #0033 + 0x8C20010E, // 002F GETMET R8 R0 K14 + 0x5C280400, // 0030 MOVE R10 R2 + 0x7C200400, // 0031 CALL R8 2 + 0x5C081000, // 0032 MOVE R2 R8 + 0x60200004, // 0033 GETGBL R8 G4 + 0x5C240C00, // 0034 MOVE R9 R6 + 0x7C200200, // 0035 CALL R8 1 + 0x1C201109, // 0036 EQ R8 R8 K9 + 0x7822001B, // 0037 JMPF R8 #0054 + 0xA8020011, // 0038 EXBLK 0 #004B + 0x8C200707, // 0039 GETMET R8 R3 K7 + 0x5C280E00, // 003A MOVE R10 R7 + 0x582C000F, // 003B LDCONST R11 K15 + 0x7C200600, // 003C CALL R8 3 + 0x1C201102, // 003D EQ R8 R8 K2 + 0x78220005, // 003E JMPF R8 #0045 + 0x5C200C00, // 003F MOVE R8 R6 + 0x8824010C, // 0040 GETMBR R9 R0 K12 + 0x5C280400, // 0041 MOVE R10 R2 + 0x582C0002, // 0042 LDCONST R11 K2 + 0x7C200600, // 0043 CALL R8 3 + 0x70020003, // 0044 JMP #0049 + 0x5C200C00, // 0045 MOVE R8 R6 + 0x8824010C, // 0046 GETMBR R9 R0 K12 + 0x5C280400, // 0047 MOVE R10 R2 + 0x7C200400, // 0048 CALL R8 2 + 0xA8040001, // 0049 EXBLK 1 1 + 0x70020006, // 004A JMP #0052 + 0xAC200002, // 004B CATCH R8 0 2 + 0x70020003, // 004C JMP #0051 + 0x00281310, // 004D ADD R10 R9 K16 + 0x00281401, // 004E ADD R10 R10 R1 + 0xB004100A, // 004F RAISE 1 R8 R10 + 0x70020000, // 0050 JMP #0052 + 0xB0080000, // 0051 RAISE 2 R0 R0 + 0x80001000, // 0052 RET 0 + 0x70020002, // 0053 JMP #0057 + 0x60200001, // 0054 GETGBL R8 G1 + 0x00262207, // 0055 ADD R9 K17 R7 + 0x7C200200, // 0056 CALL R8 1 + 0x70020003, // 0057 JMP #005C + 0x601C0001, // 0058 GETGBL R7 G1 + 0x58200012, // 0059 LDCONST R8 K18 + 0x5C240200, // 005A MOVE R9 R1 + 0x7C1C0400, // 005B CALL R7 2 + 0x80000000, // 005C RET 0 + }) + ) +); /*******************************************************************/ /******************************************************************** -** Solidified function: set_pad_right2 +** Solidified function: set_text_rule ********************************************************************/ -be_local_closure(lvh_obj_set_pad_right2, /* name */ +be_local_closure(lvh_obj_set_text_rule, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 1]) { + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 0), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(text_rule_matched), + }), + be_str_weak(_X3Clambda_X3E), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x68040000, // 0000 GETUPV R1 U0 + 0x8C040300, // 0001 GETMET R1 R1 K0 + 0x5C0C0000, // 0002 MOVE R3 R0 + 0x7C040400, // 0003 CALL R1 2 + 0x80040200, // 0004 RET 1 R1 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(_text_rule), + /* K1 */ be_nested_str_weak(tasmota), + /* K2 */ be_nested_str_weak(remove_rule), + /* K3 */ be_nested_str_weak(add_rule), + }), + be_str_weak(set_text_rule), + &be_const_str_solidified, + ( &(const binstruction[21]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x20080403, // 0002 NE R2 R2 R3 + 0x780A0004, // 0003 JMPF R2 #0009 + 0xB80A0200, // 0004 GETNGBL R2 K1 + 0x8C080502, // 0005 GETMET R2 R2 K2 + 0x88100100, // 0006 GETMBR R4 R0 K0 + 0x5C140000, // 0007 MOVE R5 R0 + 0x7C080600, // 0008 CALL R2 3 + 0x60080008, // 0009 GETGBL R2 G8 + 0x5C0C0200, // 000A MOVE R3 R1 + 0x7C080200, // 000B CALL R2 1 + 0x90020002, // 000C SETMBR R0 K0 R2 + 0xB80A0200, // 000D GETNGBL R2 K1 + 0x8C080503, // 000E GETMET R2 R2 K3 + 0x88100100, // 000F GETMBR R4 R0 K0 + 0x84140000, // 0010 CLOSURE R5 P0 + 0x5C180000, // 0011 MOVE R6 R0 + 0x7C080800, // 0012 CALL R2 4 + 0xA0000000, // 0013 CLOSE R0 + 0x80000000, // 0014 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_adjustable +********************************************************************/ +be_local_closure(lvh_obj_get_adjustable, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_obj), + /* K1 */ be_nested_str_weak(has_flag), + /* K2 */ be_nested_str_weak(lv), + /* K3 */ be_nested_str_weak(OBJ_FLAG_CLICKABLE), + }), + be_str_weak(get_adjustable), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0xB80E0400, // 0002 GETNGBL R3 K2 + 0x880C0703, // 0003 GETMBR R3 R3 K3 + 0x7C040400, // 0004 CALL R1 2 + 0x80040200, // 0005 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_pad_all +********************************************************************/ +be_local_closure(lvh_obj_get_pad_all, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(get_pad_all), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_radius2 +********************************************************************/ +be_local_closure(lvh_obj_set_radius2, /* name */ be_nested_proto( 7, /* nstack */ 2, /* argc */ @@ -2755,11 +2729,11 @@ be_local_closure(lvh_obj_set_pad_right2, /* name */ ( &(const bvalue[ 5]) { /* constants */ /* K0 */ be_nested_str_weak(_lv_part2_selector), /* K1 */ be_nested_str_weak(_lv_obj), - /* K2 */ be_nested_str_weak(set_style_pad_right), + /* K2 */ be_nested_str_weak(set_style_radius), /* K3 */ be_nested_str_weak(lv), /* K4 */ be_nested_str_weak(STATE_DEFAULT), }), - be_str_weak(set_pad_right2), + be_str_weak(set_radius2), &be_const_str_solidified, ( &(const binstruction[15]) { /* code */ 0x88080100, // 0000 GETMBR R2 R0 K0 @@ -2784,11 +2758,11 @@ be_local_closure(lvh_obj_set_pad_right2, /* name */ /******************************************************************** -** Solidified function: set_val_rule_formula +** Solidified function: set_value_ofs_y ********************************************************************/ -be_local_closure(lvh_obj_set_val_rule_formula, /* name */ +be_local_closure(lvh_obj_set_value_ofs_y, /* name */ be_nested_proto( - 13, /* nstack */ + 6, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2796,80 +2770,23 @@ be_local_closure(lvh_obj_set_val_rule_formula, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str_weak(_val_rule_formula), - /* K1 */ be_nested_str_weak(return_X20_X2F_X20val_X20_X2D_X3E_X20_X28), - /* K2 */ be_nested_str_weak(_X29), - /* K3 */ be_nested_str_weak(_val_rule_function), - /* K4 */ be_nested_str_weak(string), - /* K5 */ be_nested_str_weak(format), - /* K6 */ be_nested_str_weak(HSP_X3A_X20failed_X20to_X20compile_X20_X27_X25s_X27_X20_X2D_X20_X25s_X20_X28_X25s_X29), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(check_label), + /* K1 */ be_nested_str_weak(_lv_label), + /* K2 */ be_nested_str_weak(set_y), }), - be_str_weak(set_val_rule_formula), - &be_const_str_solidified, - ( &(const binstruction[30]) { /* code */ - 0x60080008, // 0000 GETGBL R2 G8 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x90020002, // 0003 SETMBR R0 K0 R2 - 0x88080100, // 0004 GETMBR R2 R0 K0 - 0x000A0202, // 0005 ADD R2 K1 R2 - 0x00080502, // 0006 ADD R2 R2 K2 - 0xA8020007, // 0007 EXBLK 0 #0010 - 0x600C000D, // 0008 GETGBL R3 G13 - 0x5C100400, // 0009 MOVE R4 R2 - 0x7C0C0200, // 000A CALL R3 1 - 0x5C100600, // 000B MOVE R4 R3 - 0x7C100000, // 000C CALL R4 0 - 0x90020604, // 000D SETMBR R0 K3 R4 - 0xA8040001, // 000E EXBLK 1 1 - 0x7002000C, // 000F JMP #001D - 0xAC0C0002, // 0010 CATCH R3 0 2 - 0x70020009, // 0011 JMP #001C - 0xA4160800, // 0012 IMPORT R5 K4 - 0x60180001, // 0013 GETGBL R6 G1 - 0x8C1C0B05, // 0014 GETMET R7 R5 K5 - 0x58240006, // 0015 LDCONST R9 K6 - 0x5C280400, // 0016 MOVE R10 R2 - 0x5C2C0600, // 0017 MOVE R11 R3 - 0x5C300800, // 0018 MOVE R12 R4 - 0x7C1C0A00, // 0019 CALL R7 5 - 0x7C180200, // 001A CALL R6 1 - 0x70020000, // 001B JMP #001D - 0xB0080000, // 001C RAISE 2 R0 R0 - 0x80000000, // 001D RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_line_width -********************************************************************/ -be_local_closure(lvh_obj_get_line_width, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(get_style_line_width), - /* K2 */ be_const_int(0), - }), - be_str_weak(get_line_width), + be_str_weak(set_value_ofs_y), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x580C0002, // 0002 LDCONST R3 K2 - 0x7C040400, // 0003 CALL R1 2 - 0x80040200, // 0004 RET 1 R1 + ( &(const binstruction[ 9]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x7C080200, // 0001 CALL R2 1 + 0x88080101, // 0002 GETMBR R2 R0 K1 + 0x8C080502, // 0003 GETMET R2 R2 K2 + 0x60100009, // 0004 GETGBL R4 G9 + 0x5C140200, // 0005 MOVE R5 R1 + 0x7C100200, // 0006 CALL R4 1 + 0x7C080400, // 0007 CALL R2 2 + 0x80000000, // 0008 RET 0 }) ) ); @@ -2877,11 +2794,11 @@ be_local_closure(lvh_obj_get_line_width, /* name */ /******************************************************************** -** Solidified function: set_pad_left2 +** Solidified function: set_value_str ********************************************************************/ -be_local_closure(lvh_obj_set_pad_left2, /* name */ +be_local_closure(lvh_obj_set_value_str, /* name */ be_nested_proto( - 7, /* nstack */ + 5, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2889,31 +2806,16 @@ be_local_closure(lvh_obj_set_pad_left2, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_part2_selector), - /* K1 */ be_nested_str_weak(_lv_obj), - /* K2 */ be_nested_str_weak(set_style_pad_left), - /* K3 */ be_nested_str_weak(lv), - /* K4 */ be_nested_str_weak(STATE_DEFAULT), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(set_text), }), - be_str_weak(set_pad_left2), + be_str_weak(set_value_str), &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x20080403, // 0002 NE R2 R2 R3 - 0x780A0009, // 0003 JMPF R2 #000E - 0x88080101, // 0004 GETMBR R2 R0 K1 - 0x8C080502, // 0005 GETMET R2 R2 K2 - 0x60100009, // 0006 GETGBL R4 G9 - 0x5C140200, // 0007 MOVE R5 R1 - 0x7C100200, // 0008 CALL R4 1 - 0x88140100, // 0009 GETMBR R5 R0 K0 - 0xB81A0600, // 000A GETNGBL R6 K3 - 0x88180D04, // 000B GETMBR R6 R6 K4 - 0x30140A06, // 000C OR R5 R5 R6 - 0x7C080600, // 000D CALL R2 3 - 0x80000000, // 000E RET 0 + ( &(const binstruction[ 4]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0x80000000, // 0003 RET 0 }) ) ); @@ -2921,26 +2823,187 @@ be_local_closure(lvh_obj_set_pad_left2, /* name */ /******************************************************************** -** Solidified function: get_val_rule_formula +** Solidified function: set_text_font ********************************************************************/ -be_local_closure(lvh_obj_get_val_rule_formula, /* name */ +be_local_closure(lvh_obj_set_text_font, /* name */ be_nested_proto( - 2, /* nstack */ - 1, /* argc */ + 16, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(_val_rule_formula), + ( &(const bvalue[21]) { /* constants */ + /* K0 */ be_nested_str_weak(int), + /* K1 */ be_nested_str_weak(lv), + /* K2 */ be_nested_str_weak(font_embedded), + /* K3 */ be_nested_str_weak(robotocondensed), + /* K4 */ be_nested_str_weak(montserrat), + /* K5 */ be_nested_str_weak(string), + /* K6 */ be_nested_str_weak(re), + /* K7 */ be_nested_str_weak(split), + /* K8 */ be_nested_str_weak(_X3A), + /* K9 */ be_const_int(1), + /* K10 */ be_nested_str_weak(_X2D), + /* K11 */ be_const_int(0), + /* K12 */ be_const_int(2), + /* K13 */ be_nested_str_weak(concat), + /* K14 */ be_nested_str_weak(match), + /* K15 */ be_nested_str_weak(_X2E_X2A_X5C_X2Ettf_X24), + /* K16 */ be_nested_str_weak(load_freetype_font), + /* K17 */ be_nested_str_weak(load_font), + /* K18 */ be_nested_str_weak(_lv_obj), + /* K19 */ be_nested_str_weak(set_style_text_font), + /* K20 */ be_nested_str_weak(HSP_X3A_X20Unsupported_X20font_X3A), }), - be_str_weak(get_val_rule_formula), + be_str_weak(set_text_font), &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 + ( &(const binstruction[143]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x600C0004, // 0001 GETGBL R3 G4 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C0C0200, // 0003 CALL R3 1 + 0x1C0C0700, // 0004 EQ R3 R3 K0 + 0x780E001B, // 0005 JMPF R3 #0022 + 0xA8020007, // 0006 EXBLK 0 #000F + 0xB80E0200, // 0007 GETNGBL R3 K1 + 0x8C0C0702, // 0008 GETMET R3 R3 K2 + 0x58140003, // 0009 LDCONST R5 K3 + 0x5C180200, // 000A MOVE R6 R1 + 0x7C0C0600, // 000B CALL R3 3 + 0x5C080600, // 000C MOVE R2 R3 + 0xA8040001, // 000D EXBLK 1 1 + 0x70020011, // 000E JMP #0021 + 0xAC0C0000, // 000F CATCH R3 0 0 + 0x7002000E, // 0010 JMP #0020 + 0xA8020007, // 0011 EXBLK 0 #001A + 0xB80E0200, // 0012 GETNGBL R3 K1 + 0x8C0C0702, // 0013 GETMET R3 R3 K2 + 0x58140004, // 0014 LDCONST R5 K4 + 0x5C180200, // 0015 MOVE R6 R1 + 0x7C0C0600, // 0016 CALL R3 3 + 0x5C080600, // 0017 MOVE R2 R3 + 0xA8040001, // 0018 EXBLK 1 1 + 0x70020004, // 0019 JMP #001F + 0xAC0C0000, // 001A CATCH R3 0 0 + 0x70020001, // 001B JMP #001E + 0x80000600, // 001C RET 0 + 0x70020000, // 001D JMP #001F + 0xB0080000, // 001E RAISE 2 R0 R0 + 0x70020000, // 001F JMP #0021 + 0xB0080000, // 0020 RAISE 2 R0 R0 + 0x7002005E, // 0021 JMP #0081 + 0x600C0004, // 0022 GETGBL R3 G4 + 0x5C100200, // 0023 MOVE R4 R1 + 0x7C0C0200, // 0024 CALL R3 1 + 0x1C0C0705, // 0025 EQ R3 R3 K5 + 0x780E0059, // 0026 JMPF R3 #0081 + 0xA40E0A00, // 0027 IMPORT R3 K5 + 0xA4120C00, // 0028 IMPORT R4 K6 + 0x8C140707, // 0029 GETMET R5 R3 K7 + 0x5C1C0200, // 002A MOVE R7 R1 + 0x58200008, // 002B LDCONST R8 K8 + 0x58240009, // 002C LDCONST R9 K9 + 0x7C140800, // 002D CALL R5 4 + 0x8C180707, // 002E GETMET R6 R3 K7 + 0x5C200200, // 002F MOVE R8 R1 + 0x5824000A, // 0030 LDCONST R9 K10 + 0x7C180600, // 0031 CALL R6 3 + 0x5C1C0200, // 0032 MOVE R7 R1 + 0x5820000B, // 0033 LDCONST R8 K11 + 0x50240000, // 0034 LDBOOL R9 0 0 + 0x6028000C, // 0035 GETGBL R10 G12 + 0x5C2C0A00, // 0036 MOVE R11 R5 + 0x7C280200, // 0037 CALL R10 1 + 0x24281509, // 0038 GT R10 R10 K9 + 0x782A0003, // 0039 JMPF R10 #003E + 0x6028000C, // 003A GETGBL R10 G12 + 0x942C0B0B, // 003B GETIDX R11 R5 K11 + 0x7C280200, // 003C CALL R10 1 + 0x742A0000, // 003D JMPT R10 #003F + 0x50280001, // 003E LDBOOL R10 0 1 + 0x50280200, // 003F LDBOOL R10 1 0 + 0x602C000C, // 0040 GETGBL R11 G12 + 0x5C300C00, // 0041 MOVE R12 R6 + 0x7C2C0200, // 0042 CALL R11 1 + 0x282C170C, // 0043 GE R11 R11 K12 + 0x782E000B, // 0044 JMPF R11 #0051 + 0x602C0009, // 0045 GETGBL R11 G9 + 0x5431FFFE, // 0046 LDINT R12 -1 + 0x94300C0C, // 0047 GETIDX R12 R6 R12 + 0x7C2C0200, // 0048 CALL R11 1 + 0x5C201600, // 0049 MOVE R8 R11 + 0x542DFFFD, // 004A LDINT R11 -2 + 0x402E160B, // 004B CONNECT R11 K11 R11 + 0x942C0C0B, // 004C GETIDX R11 R6 R11 + 0x8C2C170D, // 004D GETMET R11 R11 K13 + 0x5834000A, // 004E LDCONST R13 K10 + 0x7C2C0400, // 004F CALL R11 2 + 0x5C1C1600, // 0050 MOVE R7 R11 + 0x8C2C090E, // 0051 GETMET R11 R4 K14 + 0x5834000F, // 0052 LDCONST R13 K15 + 0x5C380E00, // 0053 MOVE R14 R7 + 0x7C2C0600, // 0054 CALL R11 3 + 0x782E0006, // 0055 JMPF R11 #005D + 0x8C2C0707, // 0056 GETMET R11 R3 K7 + 0x5C340E00, // 0057 MOVE R13 R7 + 0x58380008, // 0058 LDCONST R14 K8 + 0x7C2C0600, // 0059 CALL R11 3 + 0x5431FFFE, // 005A LDINT R12 -1 + 0x941C160C, // 005B GETIDX R7 R11 R12 + 0x50240200, // 005C LDBOOL R9 1 0 + 0x78260007, // 005D JMPF R9 #0066 + 0xB82E0200, // 005E GETNGBL R11 K1 + 0x8C2C1710, // 005F GETMET R11 R11 K16 + 0x5C340E00, // 0060 MOVE R13 R7 + 0x5C381000, // 0061 MOVE R14 R8 + 0x583C000B, // 0062 LDCONST R15 K11 + 0x7C2C0800, // 0063 CALL R11 4 + 0x5C081600, // 0064 MOVE R2 R11 + 0x7002001A, // 0065 JMP #0081 + 0x782A0005, // 0066 JMPF R10 #006D + 0xB82E0200, // 0067 GETNGBL R11 K1 + 0x8C2C1711, // 0068 GETMET R11 R11 K17 + 0x5C340200, // 0069 MOVE R13 R1 + 0x7C2C0400, // 006A CALL R11 2 + 0x5C081600, // 006B MOVE R2 R11 + 0x70020013, // 006C JMP #0081 + 0x242C110B, // 006D GT R11 R8 K11 + 0x782E0011, // 006E JMPF R11 #0081 + 0x602C000C, // 006F GETGBL R11 G12 + 0x5C300E00, // 0070 MOVE R12 R7 + 0x7C2C0200, // 0071 CALL R11 1 + 0x242C170B, // 0072 GT R11 R11 K11 + 0x782E000C, // 0073 JMPF R11 #0081 + 0xA8020007, // 0074 EXBLK 0 #007D + 0xB82E0200, // 0075 GETNGBL R11 K1 + 0x8C2C1702, // 0076 GETMET R11 R11 K2 + 0x5C340E00, // 0077 MOVE R13 R7 + 0x5C381000, // 0078 MOVE R14 R8 + 0x7C2C0600, // 0079 CALL R11 3 + 0x5C081600, // 007A MOVE R2 R11 + 0xA8040001, // 007B EXBLK 1 1 + 0x70020003, // 007C JMP #0081 + 0xAC2C0000, // 007D CATCH R11 0 0 + 0x70020000, // 007E JMP #0080 + 0x70020000, // 007F JMP #0081 + 0xB0080000, // 0080 RAISE 2 R0 R0 + 0x4C0C0000, // 0081 LDNIL R3 + 0x200C0403, // 0082 NE R3 R2 R3 + 0x780E0005, // 0083 JMPF R3 #008A + 0x880C0112, // 0084 GETMBR R3 R0 K18 + 0x8C0C0713, // 0085 GETMET R3 R3 K19 + 0x5C140400, // 0086 MOVE R5 R2 + 0x5818000B, // 0087 LDCONST R6 K11 + 0x7C0C0600, // 0088 CALL R3 3 + 0x70020003, // 0089 JMP #008E + 0x600C0001, // 008A GETGBL R3 G1 + 0x58100014, // 008B LDCONST R4 K20 + 0x5C140200, // 008C MOVE R5 R1 + 0x7C0C0400, // 008D CALL R3 2 + 0x80000000, // 008E RET 0 }) ) ); @@ -2948,45 +3011,65 @@ be_local_closure(lvh_obj_get_val_rule_formula, /* name */ /******************************************************************** -** Solidified function: check_label +** Solidified function: set_align ********************************************************************/ -be_local_closure(lvh_obj_check_label, /* name */ +be_local_closure(lvh_obj_set_align, /* name */ be_nested_proto( - 5, /* nstack */ - 1, /* argc */ + 7, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_label), - /* K1 */ be_nested_str_weak(lv), - /* K2 */ be_nested_str_weak(label), - /* K3 */ be_nested_str_weak(get_obj), - /* K4 */ be_nested_str_weak(set_align), - /* K5 */ be_nested_str_weak(ALIGN_CENTER), + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(check_label), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_weak(left), + /* K3 */ be_nested_str_weak(lv), + /* K4 */ be_nested_str_weak(TEXT_ALIGN_LEFT), + /* K5 */ be_const_int(1), + /* K6 */ be_nested_str_weak(center), + /* K7 */ be_nested_str_weak(TEXT_ALIGN_CENTER), + /* K8 */ be_const_int(2), + /* K9 */ be_nested_str_weak(right), + /* K10 */ be_nested_str_weak(TEXT_ALIGN_RIGHT), + /* K11 */ be_nested_str_weak(_lv_label), + /* K12 */ be_nested_str_weak(set_style_text_align), }), - be_str_weak(check_label), + be_str_weak(set_align), &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x1C040202, // 0002 EQ R1 R1 R2 - 0x7806000A, // 0003 JMPF R1 #000F - 0xB8060200, // 0004 GETNGBL R1 K1 - 0x8C040302, // 0005 GETMET R1 R1 K2 - 0x8C0C0103, // 0006 GETMET R3 R0 K3 - 0x7C0C0200, // 0007 CALL R3 1 - 0x7C040400, // 0008 CALL R1 2 - 0x90020001, // 0009 SETMBR R0 K0 R1 - 0x88040100, // 000A GETMBR R1 R0 K0 - 0x8C040304, // 000B GETMET R1 R1 K4 - 0xB80E0200, // 000C GETNGBL R3 K1 - 0x880C0705, // 000D GETMBR R3 R3 K5 - 0x7C040400, // 000E CALL R1 2 - 0x80000000, // 000F RET 0 + ( &(const binstruction[29]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x8C0C0100, // 0001 GETMET R3 R0 K0 + 0x7C0C0200, // 0002 CALL R3 1 + 0x1C0C0301, // 0003 EQ R3 R1 K1 + 0x740E0001, // 0004 JMPT R3 #0007 + 0x1C0C0302, // 0005 EQ R3 R1 K2 + 0x780E0002, // 0006 JMPF R3 #000A + 0xB80E0600, // 0007 GETNGBL R3 K3 + 0x88080704, // 0008 GETMBR R2 R3 K4 + 0x7002000C, // 0009 JMP #0017 + 0x1C0C0305, // 000A EQ R3 R1 K5 + 0x740E0001, // 000B JMPT R3 #000E + 0x1C0C0306, // 000C EQ R3 R1 K6 + 0x780E0002, // 000D JMPF R3 #0011 + 0xB80E0600, // 000E GETNGBL R3 K3 + 0x88080707, // 000F GETMBR R2 R3 K7 + 0x70020005, // 0010 JMP #0017 + 0x1C0C0308, // 0011 EQ R3 R1 K8 + 0x740E0001, // 0012 JMPT R3 #0015 + 0x1C0C0309, // 0013 EQ R3 R1 K9 + 0x780E0001, // 0014 JMPF R3 #0017 + 0xB80E0600, // 0015 GETNGBL R3 K3 + 0x8808070A, // 0016 GETMBR R2 R3 K10 + 0x880C010B, // 0017 GETMBR R3 R0 K11 + 0x8C0C070C, // 0018 GETMET R3 R3 K12 + 0x5C140400, // 0019 MOVE R5 R2 + 0x58180001, // 001A LDCONST R6 K1 + 0x7C0C0600, // 001B CALL R3 3 + 0x80000000, // 001C RET 0 }) ) ); @@ -2994,35 +3077,80 @@ be_local_closure(lvh_obj_check_label, /* name */ /******************************************************************** -** Solidified function: get_text +** Solidified function: text_rule_matched ********************************************************************/ -be_local_closure(lvh_obj_get_text, /* name */ +be_local_closure(lvh_obj_text_rule_matched, /* name */ be_nested_proto( - 3, /* nstack */ - 1, /* argc */ + 12, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_label), - /* K1 */ be_nested_str_weak(get_text), + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(int), + /* K1 */ be_nested_str_weak(_text_rule_function), + /* K2 */ be_nested_str_weak(string), + /* K3 */ be_nested_str_weak(format), + /* K4 */ be_nested_str_weak(HSP_X3A_X20failed_X20to_X20run_X20self_X2E_text_rule_function_X20_X2D_X20_X25s_X20_X28_X25s_X29), + /* K5 */ be_nested_str_weak(_text_rule_format), + /* K6 */ be_nested_str_weak(), + /* K7 */ be_nested_str_weak(text), }), - be_str_weak(get_text), + be_str_weak(text_rule_matched), &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x1C040202, // 0002 EQ R1 R1 R2 - 0x78060001, // 0003 JMPF R1 #0006 - 0x4C040000, // 0004 LDNIL R1 - 0x80040200, // 0005 RET 1 R1 - 0x88040100, // 0006 GETMBR R1 R0 K0 - 0x8C040301, // 0007 GETMET R1 R1 K1 - 0x7C040200, // 0008 CALL R1 1 - 0x80040200, // 0009 RET 1 R1 + ( &(const binstruction[49]) { /* code */ + 0x60080004, // 0000 GETGBL R2 G4 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x1C080500, // 0003 EQ R2 R2 K0 + 0x780A0003, // 0004 JMPF R2 #0009 + 0x6008000A, // 0005 GETGBL R2 G10 + 0x5C0C0200, // 0006 MOVE R3 R1 + 0x7C080200, // 0007 CALL R2 1 + 0x5C040400, // 0008 MOVE R1 R2 + 0x88080101, // 0009 GETMBR R2 R0 K1 + 0x4C0C0000, // 000A LDNIL R3 + 0x200C0403, // 000B NE R3 R2 R3 + 0x780E0012, // 000C JMPF R3 #0020 + 0xA8020005, // 000D EXBLK 0 #0014 + 0x5C0C0400, // 000E MOVE R3 R2 + 0x5C100200, // 000F MOVE R4 R1 + 0x7C0C0200, // 0010 CALL R3 1 + 0x5C040600, // 0011 MOVE R1 R3 + 0xA8040001, // 0012 EXBLK 1 1 + 0x7002000B, // 0013 JMP #0020 + 0xAC0C0002, // 0014 CATCH R3 0 2 + 0x70020008, // 0015 JMP #001F + 0xA4160400, // 0016 IMPORT R5 K2 + 0x60180001, // 0017 GETGBL R6 G1 + 0x8C1C0B03, // 0018 GETMET R7 R5 K3 + 0x58240004, // 0019 LDCONST R9 K4 + 0x5C280600, // 001A MOVE R10 R3 + 0x5C2C0800, // 001B MOVE R11 R4 + 0x7C1C0800, // 001C CALL R7 4 + 0x7C180200, // 001D CALL R6 1 + 0x70020000, // 001E JMP #0020 + 0xB0080000, // 001F RAISE 2 R0 R0 + 0x880C0105, // 0020 GETMBR R3 R0 K5 + 0x60100004, // 0021 GETGBL R4 G4 + 0x5C140600, // 0022 MOVE R5 R3 + 0x7C100200, // 0023 CALL R4 1 + 0x1C100902, // 0024 EQ R4 R4 K2 + 0x78120006, // 0025 JMPF R4 #002D + 0xA4120400, // 0026 IMPORT R4 K2 + 0x8C140903, // 0027 GETMET R5 R4 K3 + 0x5C1C0600, // 0028 MOVE R7 R3 + 0x5C200200, // 0029 MOVE R8 R1 + 0x7C140600, // 002A CALL R5 3 + 0x5C0C0A00, // 002B MOVE R3 R5 + 0x70020000, // 002C JMP #002E + 0x580C0006, // 002D LDCONST R3 K6 + 0x90020E03, // 002E SETMBR R0 K7 R3 + 0x50100000, // 002F LDBOOL R4 0 0 + 0x80040800, // 0030 RET 1 R4 }) ) ); @@ -3030,11 +3158,11 @@ be_local_closure(lvh_obj_get_text, /* name */ /******************************************************************** -** Solidified function: set_hidden +** Solidified function: set_line_width ********************************************************************/ -be_local_closure(lvh_obj_set_hidden, /* name */ +be_local_closure(lvh_obj_set_line_width, /* name */ be_nested_proto( - 5, /* nstack */ + 6, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -3042,29 +3170,22 @@ be_local_closure(lvh_obj_set_hidden, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ + ( &(const bvalue[ 3]) { /* constants */ /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(add_flag), - /* K2 */ be_nested_str_weak(lv), - /* K3 */ be_nested_str_weak(OBJ_FLAG_HIDDEN), - /* K4 */ be_nested_str_weak(clear_flag), + /* K1 */ be_nested_str_weak(set_style_line_width), + /* K2 */ be_const_int(0), }), - be_str_weak(set_hidden), + be_str_weak(set_line_width), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x78060005, // 0000 JMPF R1 #0007 - 0x88080100, // 0001 GETMBR R2 R0 K0 - 0x8C080501, // 0002 GETMET R2 R2 K1 - 0xB8120400, // 0003 GETNGBL R4 K2 - 0x88100903, // 0004 GETMBR R4 R4 K3 - 0x7C080400, // 0005 CALL R2 2 - 0x70020004, // 0006 JMP #000C - 0x88080100, // 0007 GETMBR R2 R0 K0 - 0x8C080504, // 0008 GETMET R2 R2 K4 - 0xB8120400, // 0009 GETNGBL R4 K2 - 0x88100903, // 000A GETMBR R4 R4 K3 - 0x7C080400, // 000B CALL R2 2 - 0x80000000, // 000C RET 0 + ( &(const binstruction[ 8]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x60100009, // 0002 GETGBL R4 G9 + 0x5C140200, // 0003 MOVE R5 R1 + 0x7C100200, // 0004 CALL R4 1 + 0x58140002, // 0005 LDCONST R5 K2 + 0x7C080600, // 0006 CALL R2 3 + 0x80000000, // 0007 RET 0 }) ) ); @@ -3072,43 +3193,26 @@ be_local_closure(lvh_obj_set_hidden, /* name */ /******************************************************************** -** Solidified function: set_pad_all2 +** Solidified function: get_val_rule_formula ********************************************************************/ -be_local_closure(lvh_obj_set_pad_all2, /* name */ +be_local_closure(lvh_obj_get_val_rule_formula, /* name */ be_nested_proto( - 7, /* nstack */ - 2, /* argc */ + 2, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_part2_selector), - /* K1 */ be_nested_str_weak(_lv_obj), - /* K2 */ be_nested_str_weak(set_style_pad_all), - /* K3 */ be_nested_str_weak(lv), - /* K4 */ be_nested_str_weak(STATE_DEFAULT), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(_val_rule_formula), }), - be_str_weak(set_pad_all2), + be_str_weak(get_val_rule_formula), &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x20080403, // 0002 NE R2 R2 R3 - 0x780A0009, // 0003 JMPF R2 #000E - 0x88080101, // 0004 GETMBR R2 R0 K1 - 0x8C080502, // 0005 GETMET R2 R2 K2 - 0x60100009, // 0006 GETGBL R4 G9 - 0x5C140200, // 0007 MOVE R5 R1 - 0x7C100200, // 0008 CALL R4 1 - 0x88140100, // 0009 GETMBR R5 R0 K0 - 0xB81A0600, // 000A GETNGBL R6 K3 - 0x88180D04, // 000B GETMBR R6 R6 K4 - 0x30140A06, // 000C OR R5 R5 R6 - 0x7C080600, // 000D CALL R2 3 - 0x80000000, // 000E RET 0 + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -3116,11 +3220,11 @@ be_local_closure(lvh_obj_set_pad_all2, /* name */ /******************************************************************** -** Solidified function: set_text_color +** Solidified function: set_val_rule_formula ********************************************************************/ -be_local_closure(lvh_obj_set_text_color, /* name */ +be_local_closure(lvh_obj_set_val_rule_formula, /* name */ be_nested_proto( - 7, /* nstack */ + 13, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -3128,23 +3232,48 @@ be_local_closure(lvh_obj_set_text_color, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(set_style_text_color), - /* K2 */ be_nested_str_weak(parse_color), - /* K3 */ be_const_int(0), + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_weak(_val_rule_formula), + /* K1 */ be_nested_str_weak(return_X20_X2F_X20val_X20_X2D_X3E_X20_X28), + /* K2 */ be_nested_str_weak(_X29), + /* K3 */ be_nested_str_weak(_val_rule_function), + /* K4 */ be_nested_str_weak(string), + /* K5 */ be_nested_str_weak(format), + /* K6 */ be_nested_str_weak(HSP_X3A_X20failed_X20to_X20compile_X20_X27_X25s_X27_X20_X2D_X20_X25s_X20_X28_X25s_X29), }), - be_str_weak(set_text_color), + be_str_weak(set_val_rule_formula), &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x8C100102, // 0002 GETMET R4 R0 K2 - 0x5C180200, // 0003 MOVE R6 R1 - 0x7C100400, // 0004 CALL R4 2 - 0x58140003, // 0005 LDCONST R5 K3 - 0x7C080600, // 0006 CALL R2 3 - 0x80000000, // 0007 RET 0 + ( &(const binstruction[30]) { /* code */ + 0x60080008, // 0000 GETGBL R2 G8 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x90020002, // 0003 SETMBR R0 K0 R2 + 0x88080100, // 0004 GETMBR R2 R0 K0 + 0x000A0202, // 0005 ADD R2 K1 R2 + 0x00080502, // 0006 ADD R2 R2 K2 + 0xA8020007, // 0007 EXBLK 0 #0010 + 0x600C000D, // 0008 GETGBL R3 G13 + 0x5C100400, // 0009 MOVE R4 R2 + 0x7C0C0200, // 000A CALL R3 1 + 0x5C100600, // 000B MOVE R4 R3 + 0x7C100000, // 000C CALL R4 0 + 0x90020604, // 000D SETMBR R0 K3 R4 + 0xA8040001, // 000E EXBLK 1 1 + 0x7002000C, // 000F JMP #001D + 0xAC0C0002, // 0010 CATCH R3 0 2 + 0x70020009, // 0011 JMP #001C + 0xA4160800, // 0012 IMPORT R5 K4 + 0x60180001, // 0013 GETGBL R6 G1 + 0x8C1C0B05, // 0014 GETMET R7 R5 K5 + 0x58240006, // 0015 LDCONST R9 K6 + 0x5C280400, // 0016 MOVE R10 R2 + 0x5C2C0600, // 0017 MOVE R11 R3 + 0x5C300800, // 0018 MOVE R12 R4 + 0x7C1C0A00, // 0019 CALL R7 5 + 0x7C180200, // 001A CALL R6 1 + 0x70020000, // 001B JMP #001D + 0xB0080000, // 001C RAISE 2 R0 R0 + 0x80000000, // 001D RET 0 }) ) ); @@ -3152,41 +3281,35 @@ be_local_closure(lvh_obj_set_text_color, /* name */ /******************************************************************** -** Solidified function: get_pad_bottom +** Solidified function: set_value_ofs_x ********************************************************************/ -be_local_closure(lvh_obj_get_pad_bottom, /* name */ +be_local_closure(lvh_obj_set_value_ofs_x, /* name */ be_nested_proto( - 5, /* nstack */ - 1, /* argc */ + 6, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_part2_selector), - /* K1 */ be_nested_str_weak(_lv_obj), - /* K2 */ be_nested_str_weak(get_style_pad_bottom), - /* K3 */ be_nested_str_weak(lv), - /* K4 */ be_nested_str_weak(STATE_DEFAULT), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(check_label), + /* K1 */ be_nested_str_weak(_lv_label), + /* K2 */ be_nested_str_weak(set_x), }), - be_str_weak(get_pad_bottom), + be_str_weak(set_value_ofs_x), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x20040202, // 0002 NE R1 R1 R2 - 0x78060007, // 0003 JMPF R1 #000C - 0x88040101, // 0004 GETMBR R1 R0 K1 - 0x8C040302, // 0005 GETMET R1 R1 K2 - 0x880C0100, // 0006 GETMBR R3 R0 K0 - 0xB8120600, // 0007 GETNGBL R4 K3 - 0x88100904, // 0008 GETMBR R4 R4 K4 - 0x300C0604, // 0009 OR R3 R3 R4 - 0x7C040400, // 000A CALL R1 2 - 0x80040200, // 000B RET 1 R1 - 0x80000000, // 000C RET 0 + ( &(const binstruction[ 9]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x7C080200, // 0001 CALL R2 1 + 0x88080101, // 0002 GETMBR R2 R0 K1 + 0x8C080502, // 0003 GETMET R2 R2 K2 + 0x60100009, // 0004 GETGBL R4 G9 + 0x5C140200, // 0005 MOVE R5 R1 + 0x7C100200, // 0006 CALL R4 1 + 0x7C080400, // 0007 CALL R2 2 + 0x80000000, // 0008 RET 0 }) ) ); @@ -3194,9 +3317,9 @@ be_local_closure(lvh_obj_get_pad_bottom, /* name */ /******************************************************************** -** Solidified function: get_pad_top +** Solidified function: get_pad_left ********************************************************************/ -be_local_closure(lvh_obj_get_pad_top, /* name */ +be_local_closure(lvh_obj_get_pad_left, /* name */ be_nested_proto( 5, /* nstack */ 1, /* argc */ @@ -3209,11 +3332,11 @@ be_local_closure(lvh_obj_get_pad_top, /* name */ ( &(const bvalue[ 5]) { /* constants */ /* K0 */ be_nested_str_weak(_lv_part2_selector), /* K1 */ be_nested_str_weak(_lv_obj), - /* K2 */ be_nested_str_weak(get_style_pad_top), + /* K2 */ be_nested_str_weak(get_style_pad_left), /* K3 */ be_nested_str_weak(lv), /* K4 */ be_nested_str_weak(STATE_DEFAULT), }), - be_str_weak(get_pad_top), + be_str_weak(get_pad_left), &be_const_str_solidified, ( &(const binstruction[13]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -3236,41 +3359,27 @@ be_local_closure(lvh_obj_get_pad_top, /* name */ /******************************************************************** -** Solidified function: set_adjustable +** Solidified function: post_init ********************************************************************/ -be_local_closure(lvh_obj_set_adjustable, /* name */ +be_local_closure(lvh_obj_post_init, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 3, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(add_flag), - /* K2 */ be_nested_str_weak(lv), - /* K3 */ be_nested_str_weak(OBJ_FLAG_CLICKABLE), - /* K4 */ be_nested_str_weak(clear_flag), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(register_event_cb), }), - be_str_weak(set_adjustable), + be_str_weak(post_init), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x78060005, // 0000 JMPF R1 #0007 - 0x88080100, // 0001 GETMBR R2 R0 K0 - 0x8C080501, // 0002 GETMET R2 R2 K1 - 0xB8120400, // 0003 GETNGBL R4 K2 - 0x88100903, // 0004 GETMBR R4 R4 K3 - 0x7C080400, // 0005 CALL R2 2 - 0x70020004, // 0006 JMP #000C - 0x88080100, // 0007 GETMBR R2 R0 K0 - 0x8C080504, // 0008 GETMET R2 R2 K4 - 0xB8120400, // 0009 GETNGBL R4 K2 - 0x88100903, // 000A GETMBR R4 R4 K3 - 0x7C080400, // 000B CALL R2 2 - 0x80000000, // 000C RET 0 + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80000000, // 0002 RET 0 }) ) ); @@ -3278,33 +3387,26 @@ be_local_closure(lvh_obj_set_adjustable, /* name */ /******************************************************************** -** Solidified function: get_enabled +** Solidified function: get_text_rule_format ********************************************************************/ -be_local_closure(lvh_obj_get_enabled, /* name */ +be_local_closure(lvh_obj_get_text_rule_format, /* name */ be_nested_proto( - 4, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(has_flag), - /* K2 */ be_nested_str_weak(lv), - /* K3 */ be_nested_str_weak(OBJ_FLAG_CLICKABLE), + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_weak(_text_rule_format), }), - be_str_weak(get_enabled), + be_str_weak(get_text_rule_format), &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ + ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0xB80E0400, // 0002 GETNGBL R3 K2 - 0x880C0703, // 0003 GETMBR R3 R3 K3 - 0x7C040400, // 0004 CALL R1 2 - 0x80040200, // 0005 RET 1 R1 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -3312,19 +3414,19 @@ be_local_closure(lvh_obj_get_enabled, /* name */ /******************************************************************** -** Solidified function: setmember +** Solidified function: member ********************************************************************/ -be_local_closure(lvh_obj_setmember, /* name */ +be_local_closure(lvh_obj_member, /* name */ be_nested_proto( - 12, /* nstack */ - 3, /* argc */ + 11, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[19]) { /* constants */ + ( &(const bvalue[16]) { /* constants */ /* K0 */ be_nested_str_weak(string), /* K1 */ be_nested_str_weak(introspect), /* K2 */ be_const_int(0), @@ -3338,153 +3440,82 @@ be_local_closure(lvh_obj_setmember, /* name */ /* K10 */ be_nested_str_weak(_attr_map), /* K11 */ be_nested_str_weak(contains), /* K12 */ be_nested_str_weak(_lv_obj), - /* K13 */ be_nested_str_weak(is_color_attribute), - /* K14 */ be_nested_str_weak(parse_color), - /* K15 */ be_nested_str_weak(style_), - /* K16 */ be_nested_str_weak(_X20for_X20), - /* K17 */ be_nested_str_weak(HSP_X3A_X20Could_X20not_X20find_X20function_X20set_), - /* K18 */ be_nested_str_weak(HSP_X3A_X20unknown_X20attribute_X3A), - }), - be_str_weak(setmember), - &be_const_str_solidified, - ( &(const binstruction[93]) { /* code */ - 0xA40E0000, // 0000 IMPORT R3 K0 - 0xA4120200, // 0001 IMPORT R4 K1 - 0x40160503, // 0002 CONNECT R5 K2 K3 - 0x94140205, // 0003 GETIDX R5 R1 R5 - 0x1C180B04, // 0004 EQ R6 R5 K4 - 0x741A0001, // 0005 JMPT R6 #0008 - 0x1C180B05, // 0006 EQ R6 R5 K5 - 0x781A0000, // 0007 JMPF R6 #0009 - 0x80000C00, // 0008 RET 0 - 0x88180106, // 0009 GETMBR R6 R0 K6 - 0x8C180D07, // 000A GETMET R6 R6 K7 - 0x5C200200, // 000B MOVE R8 R1 - 0x7C180400, // 000C CALL R6 2 - 0x4C1C0000, // 000D LDNIL R7 - 0x20180C07, // 000E NE R6 R6 R7 - 0x781A0000, // 000F JMPF R6 #0011 - 0x80000C00, // 0010 RET 0 - 0x8C180908, // 0011 GETMET R6 R4 K8 - 0x5C200000, // 0012 MOVE R8 R0 - 0x00260801, // 0013 ADD R9 K4 R1 - 0x7C180600, // 0014 CALL R6 3 - 0x601C0004, // 0015 GETGBL R7 G4 - 0x5C200C00, // 0016 MOVE R8 R6 - 0x7C1C0200, // 0017 CALL R7 1 - 0x1C1C0F09, // 0018 EQ R7 R7 K9 - 0x781E0004, // 0019 JMPF R7 #001F - 0x5C1C0C00, // 001A MOVE R7 R6 - 0x5C200000, // 001B MOVE R8 R0 - 0x5C240400, // 001C MOVE R9 R2 - 0x7C1C0400, // 001D CALL R7 2 - 0x80000E00, // 001E RET 0 - 0x881C010A, // 001F GETMBR R7 R0 K10 - 0x8C1C0F0B, // 0020 GETMET R7 R7 K11 - 0x5C240200, // 0021 MOVE R9 R1 - 0x7C1C0400, // 0022 CALL R7 2 - 0x781E0033, // 0023 JMPF R7 #0058 - 0x881C010A, // 0024 GETMBR R7 R0 K10 - 0x941C0E01, // 0025 GETIDX R7 R7 R1 - 0x8C200908, // 0026 GETMET R8 R4 K8 - 0x8828010C, // 0027 GETMBR R10 R0 K12 - 0x002E0807, // 0028 ADD R11 K4 R7 - 0x7C200600, // 0029 CALL R8 3 - 0x5C181000, // 002A MOVE R6 R8 - 0x8C20010D, // 002B GETMET R8 R0 K13 - 0x5C280E00, // 002C MOVE R10 R7 - 0x7C200400, // 002D CALL R8 2 - 0x78220003, // 002E JMPF R8 #0033 - 0x8C20010E, // 002F GETMET R8 R0 K14 - 0x5C280400, // 0030 MOVE R10 R2 - 0x7C200400, // 0031 CALL R8 2 - 0x5C081000, // 0032 MOVE R2 R8 - 0x60200004, // 0033 GETGBL R8 G4 - 0x5C240C00, // 0034 MOVE R9 R6 - 0x7C200200, // 0035 CALL R8 1 - 0x1C201109, // 0036 EQ R8 R8 K9 - 0x7822001B, // 0037 JMPF R8 #0054 - 0xA8020011, // 0038 EXBLK 0 #004B - 0x8C200707, // 0039 GETMET R8 R3 K7 - 0x5C280E00, // 003A MOVE R10 R7 - 0x582C000F, // 003B LDCONST R11 K15 - 0x7C200600, // 003C CALL R8 3 - 0x1C201102, // 003D EQ R8 R8 K2 - 0x78220005, // 003E JMPF R8 #0045 - 0x5C200C00, // 003F MOVE R8 R6 - 0x8824010C, // 0040 GETMBR R9 R0 K12 - 0x5C280400, // 0041 MOVE R10 R2 - 0x582C0002, // 0042 LDCONST R11 K2 - 0x7C200600, // 0043 CALL R8 3 - 0x70020003, // 0044 JMP #0049 - 0x5C200C00, // 0045 MOVE R8 R6 - 0x8824010C, // 0046 GETMBR R9 R0 K12 - 0x5C280400, // 0047 MOVE R10 R2 - 0x7C200400, // 0048 CALL R8 2 - 0xA8040001, // 0049 EXBLK 1 1 - 0x70020006, // 004A JMP #0052 - 0xAC200002, // 004B CATCH R8 0 2 - 0x70020003, // 004C JMP #0051 - 0x00281310, // 004D ADD R10 R9 K16 - 0x00281401, // 004E ADD R10 R10 R1 - 0xB004100A, // 004F RAISE 1 R8 R10 - 0x70020000, // 0050 JMP #0052 - 0xB0080000, // 0051 RAISE 2 R0 R0 - 0x80001000, // 0052 RET 0 - 0x70020002, // 0053 JMP #0057 - 0x60200001, // 0054 GETGBL R8 G1 - 0x00262207, // 0055 ADD R9 K17 R7 - 0x7C200200, // 0056 CALL R8 1 - 0x70020003, // 0057 JMP #005C - 0x601C0001, // 0058 GETGBL R7 G1 - 0x58200012, // 0059 LDCONST R8 K18 - 0x5C240200, // 005A MOVE R9 R1 - 0x7C1C0400, // 005B CALL R7 2 - 0x80000000, // 005C RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(lvh_obj_init, /* name */ - be_nested_proto( - 8, /* nstack */ - 5, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(_page), - /* K1 */ be_nested_str_weak(_lv_class), - /* K2 */ be_nested_str_weak(_lv_obj), - /* K3 */ be_nested_str_weak(post_init), + /* K13 */ be_nested_str_weak(style_), + /* K14 */ be_nested_str_weak(unknown_X20attribute_X20), + /* K15 */ be_nested_str_weak(value_error), }), - be_str_weak(init), + be_str_weak(member), &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x90020002, // 0000 SETMBR R0 K0 R2 - 0x4C140000, // 0001 LDNIL R5 - 0x1C140805, // 0002 EQ R5 R4 R5 - 0x78160007, // 0003 JMPF R5 #000C - 0x88140101, // 0004 GETMBR R5 R0 K1 - 0x78160005, // 0005 JMPF R5 #000C - 0x88140101, // 0006 GETMBR R5 R0 K1 - 0x5C180A00, // 0007 MOVE R6 R5 - 0x5C1C0200, // 0008 MOVE R7 R1 - 0x7C180200, // 0009 CALL R6 1 - 0x90020406, // 000A SETMBR R0 K2 R6 - 0x70020000, // 000B JMP #000D - 0x90020404, // 000C SETMBR R0 K2 R4 - 0x8C140103, // 000D GETMET R5 R0 K3 - 0x7C140200, // 000E CALL R5 1 - 0x80000000, // 000F RET 0 + ( &(const binstruction[69]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0xA40E0200, // 0001 IMPORT R3 K1 + 0x40120503, // 0002 CONNECT R4 K2 K3 + 0x94100204, // 0003 GETIDX R4 R1 R4 + 0x1C140904, // 0004 EQ R5 R4 K4 + 0x74160001, // 0005 JMPT R5 #0008 + 0x1C140905, // 0006 EQ R5 R4 K5 + 0x78160000, // 0007 JMPF R5 #0009 + 0x80000A00, // 0008 RET 0 + 0x88140106, // 0009 GETMBR R5 R0 K6 + 0x8C140B07, // 000A GETMET R5 R5 K7 + 0x5C1C0200, // 000B MOVE R7 R1 + 0x7C140400, // 000C CALL R5 2 + 0x4C180000, // 000D LDNIL R6 + 0x20140A06, // 000E NE R5 R5 R6 + 0x78160000, // 000F JMPF R5 #0011 + 0x80000A00, // 0010 RET 0 + 0x8C140708, // 0011 GETMET R5 R3 K8 + 0x5C1C0000, // 0012 MOVE R7 R0 + 0x00220A01, // 0013 ADD R8 K5 R1 + 0x7C140600, // 0014 CALL R5 3 + 0x60180004, // 0015 GETGBL R6 G4 + 0x5C1C0A00, // 0016 MOVE R7 R5 + 0x7C180200, // 0017 CALL R6 1 + 0x1C180D09, // 0018 EQ R6 R6 K9 + 0x781A0003, // 0019 JMPF R6 #001E + 0x5C180A00, // 001A MOVE R6 R5 + 0x5C1C0000, // 001B MOVE R7 R0 + 0x7C180200, // 001C CALL R6 1 + 0x80040C00, // 001D RET 1 R6 + 0x8818010A, // 001E GETMBR R6 R0 K10 + 0x8C180D0B, // 001F GETMET R6 R6 K11 + 0x5C200200, // 0020 MOVE R8 R1 + 0x7C180400, // 0021 CALL R6 2 + 0x781A001B, // 0022 JMPF R6 #003F + 0x8818010A, // 0023 GETMBR R6 R0 K10 + 0x94180C01, // 0024 GETIDX R6 R6 R1 + 0x8C1C0708, // 0025 GETMET R7 R3 K8 + 0x8824010C, // 0026 GETMBR R9 R0 K12 + 0x002A0A06, // 0027 ADD R10 K5 R6 + 0x7C1C0600, // 0028 CALL R7 3 + 0x5C140E00, // 0029 MOVE R5 R7 + 0x601C0004, // 002A GETGBL R7 G4 + 0x5C200A00, // 002B MOVE R8 R5 + 0x7C1C0200, // 002C CALL R7 1 + 0x1C1C0F09, // 002D EQ R7 R7 K9 + 0x781E000F, // 002E JMPF R7 #003F + 0x8C1C0507, // 002F GETMET R7 R2 K7 + 0x5C240C00, // 0030 MOVE R9 R6 + 0x5828000D, // 0031 LDCONST R10 K13 + 0x7C1C0600, // 0032 CALL R7 3 + 0x1C1C0F02, // 0033 EQ R7 R7 K2 + 0x781E0005, // 0034 JMPF R7 #003B + 0x5C1C0A00, // 0035 MOVE R7 R5 + 0x8820010C, // 0036 GETMBR R8 R0 K12 + 0x58240002, // 0037 LDCONST R9 K2 + 0x7C1C0400, // 0038 CALL R7 2 + 0x80040E00, // 0039 RET 1 R7 + 0x70020003, // 003A JMP #003F + 0x5C1C0A00, // 003B MOVE R7 R5 + 0x8820010C, // 003C GETMBR R8 R0 K12 + 0x7C1C0200, // 003D CALL R7 1 + 0x80040E00, // 003E RET 1 R7 + 0x60180008, // 003F GETGBL R6 G8 + 0x5C1C0200, // 0040 MOVE R7 R1 + 0x7C180200, // 0041 CALL R6 1 + 0x001A1C06, // 0042 ADD R6 K14 R6 + 0xB0061E06, // 0043 RAISE 1 K15 R6 + 0x80000000, // 0044 RET 0 }) ) ); @@ -3492,28 +3523,38 @@ be_local_closure(lvh_obj_init, /* name */ /******************************************************************** -** Solidified function: set_value_str +** Solidified function: is_color_attribute ********************************************************************/ -be_local_closure(lvh_obj_set_value_str, /* name */ +be_local_closure(lvh_obj_is_color_attribute, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ - 2, /* varg */ + 9, /* nstack */ + 1, /* argc */ + 4, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(set_text), + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_const_class(be_class_lvh_obj), + /* K1 */ be_nested_str_weak(re), + /* K2 */ be_nested_str_weak(search), + /* K3 */ be_nested_str_weak(color_X24), }), - be_str_weak(set_value_str), + be_str_weak(is_color_attribute), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C080400, // 0002 CALL R2 2 - 0x80000000, // 0003 RET 0 + ( &(const binstruction[11]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0xA40A0200, // 0001 IMPORT R2 K1 + 0x600C0017, // 0002 GETGBL R3 G23 + 0x8C100502, // 0003 GETMET R4 R2 K2 + 0x58180003, // 0004 LDCONST R6 K3 + 0x601C0008, // 0005 GETGBL R7 G8 + 0x5C200000, // 0006 MOVE R8 R0 + 0x7C1C0200, // 0007 CALL R7 1 + 0x7C100600, // 0008 CALL R4 3 + 0x7C0C0200, // 0009 CALL R3 1 + 0x80040600, // 000A RET 1 R3 }) ) ); @@ -3521,34 +3562,29 @@ be_local_closure(lvh_obj_set_value_str, /* name */ /******************************************************************** -** Solidified function: set_line_width +** Solidified function: get_val ********************************************************************/ -be_local_closure(lvh_obj_set_line_width, /* name */ +be_local_closure(lvh_obj_get_val, /* name */ be_nested_proto( - 6, /* nstack */ - 2, /* argc */ + 3, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ + ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(set_style_line_width), - /* K2 */ be_const_int(0), + /* K1 */ be_nested_str_weak(get_value), }), - be_str_weak(set_line_width), + be_str_weak(get_val), &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x60100009, // 0002 GETGBL R4 G9 - 0x5C140200, // 0003 MOVE R5 R1 - 0x7C100200, // 0004 CALL R4 1 - 0x58140002, // 0005 LDCONST R5 K2 - 0x7C080600, // 0006 CALL R2 3 - 0x80000000, // 0007 RET 0 + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 }) ) ); @@ -3556,64 +3592,23 @@ be_local_closure(lvh_obj_set_line_width, /* name */ /******************************************************************** -** Solidified function: set_toggle +** Solidified function: get_mode ********************************************************************/ -be_local_closure(lvh_obj_set_toggle, /* name */ +be_local_closure(lvh_obj_get_mode, /* name */ be_nested_proto( - 7, /* nstack */ - 2, /* argc */ + 1, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 9]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(toupper), - /* K2 */ be_nested_str_weak(TRUE), - /* K3 */ be_nested_str_weak(FALSE), - /* K4 */ be_nested_str_weak(_lv_obj), - /* K5 */ be_nested_str_weak(add_state), - /* K6 */ be_nested_str_weak(lv), - /* K7 */ be_nested_str_weak(STATE_CHECKED), - /* K8 */ be_nested_str_weak(clear_state), - }), - be_str_weak(set_toggle), + 0, /* has constants */ + NULL, /* no const */ + be_str_weak(get_mode), &be_const_str_solidified, - ( &(const binstruction[32]) { /* code */ - 0x60080004, // 0000 GETGBL R2 G4 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x1C080500, // 0003 EQ R2 R2 K0 - 0x780A000D, // 0004 JMPF R2 #0013 - 0xA40A0000, // 0005 IMPORT R2 K0 - 0x8C0C0501, // 0006 GETMET R3 R2 K1 - 0x60140008, // 0007 GETGBL R5 G8 - 0x5C180200, // 0008 MOVE R6 R1 - 0x7C140200, // 0009 CALL R5 1 - 0x7C0C0400, // 000A CALL R3 2 - 0x5C040600, // 000B MOVE R1 R3 - 0x1C0C0302, // 000C EQ R3 R1 K2 - 0x780E0001, // 000D JMPF R3 #0010 - 0x50040200, // 000E LDBOOL R1 1 0 - 0x70020002, // 000F JMP #0013 - 0x1C0C0303, // 0010 EQ R3 R1 K3 - 0x780E0000, // 0011 JMPF R3 #0013 - 0x50040000, // 0012 LDBOOL R1 0 0 - 0x78060005, // 0013 JMPF R1 #001A - 0x88080104, // 0014 GETMBR R2 R0 K4 - 0x8C080505, // 0015 GETMET R2 R2 K5 - 0xB8120C00, // 0016 GETNGBL R4 K6 - 0x88100907, // 0017 GETMBR R4 R4 K7 - 0x7C080400, // 0018 CALL R2 2 - 0x70020004, // 0019 JMP #001F - 0x88080104, // 001A GETMBR R2 R0 K4 - 0x8C080508, // 001B GETMET R2 R2 K8 - 0xB8120C00, // 001C GETNGBL R4 K6 - 0x88100907, // 001D GETMBR R4 R4 K7 - 0x7C080400, // 001E CALL R2 2 - 0x80000000, // 001F RET 0 + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 }) ) ); @@ -3621,73 +3616,41 @@ be_local_closure(lvh_obj_set_toggle, /* name */ /******************************************************************** -** Solidified function: set_val_rule +** Solidified function: get_pad_right ********************************************************************/ -be_local_closure(lvh_obj_set_val_rule, /* name */ +be_local_closure(lvh_obj_get_pad_right, /* name */ be_nested_proto( - 7, /* nstack */ - 2, /* argc */ + 5, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 1]) { - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 1]) { /* upvals */ - be_local_const_upval(1, 0), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(val_rule_matched), - }), - be_str_weak(_X3Clambda_X3E), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x68040000, // 0000 GETUPV R1 U0 - 0x8C040300, // 0001 GETMET R1 R1 K0 - 0x5C0C0000, // 0002 MOVE R3 R0 - 0x7C040400, // 0003 CALL R1 2 - 0x80040200, // 0004 RET 1 R1 - }) - ), - }), + 0, /* has sup protos */ + NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_weak(_val_rule), - /* K1 */ be_nested_str_weak(tasmota), - /* K2 */ be_nested_str_weak(remove_rule), - /* K3 */ be_nested_str_weak(add_rule), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_part2_selector), + /* K1 */ be_nested_str_weak(_lv_obj), + /* K2 */ be_nested_str_weak(get_style_pad_right), + /* K3 */ be_nested_str_weak(lv), + /* K4 */ be_nested_str_weak(STATE_DEFAULT), }), - be_str_weak(set_val_rule), + be_str_weak(get_pad_right), &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x20080403, // 0002 NE R2 R2 R3 - 0x780A0004, // 0003 JMPF R2 #0009 - 0xB80A0200, // 0004 GETNGBL R2 K1 - 0x8C080502, // 0005 GETMET R2 R2 K2 - 0x88100100, // 0006 GETMBR R4 R0 K0 - 0x5C140000, // 0007 MOVE R5 R0 - 0x7C080600, // 0008 CALL R2 3 - 0x60080008, // 0009 GETGBL R2 G8 - 0x5C0C0200, // 000A MOVE R3 R1 - 0x7C080200, // 000B CALL R2 1 - 0x90020002, // 000C SETMBR R0 K0 R2 - 0xB80A0200, // 000D GETNGBL R2 K1 - 0x8C080503, // 000E GETMET R2 R2 K3 - 0x88100100, // 000F GETMBR R4 R0 K0 - 0x84140000, // 0010 CLOSURE R5 P0 - 0x5C180000, // 0011 MOVE R6 R0 - 0x7C080800, // 0012 CALL R2 4 - 0xA0000000, // 0013 CLOSE R0 - 0x80000000, // 0014 RET 0 + ( &(const binstruction[13]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x20040202, // 0002 NE R1 R1 R2 + 0x78060007, // 0003 JMPF R1 #000C + 0x88040101, // 0004 GETMBR R1 R0 K1 + 0x8C040302, // 0005 GETMET R1 R1 K2 + 0x880C0100, // 0006 GETMBR R3 R0 K0 + 0xB8120600, // 0007 GETNGBL R4 K3 + 0x88100904, // 0008 GETMBR R4 R4 K4 + 0x300C0604, // 0009 OR R3 R3 R4 + 0x7C040400, // 000A CALL R1 2 + 0x80040200, // 000B RET 1 R1 + 0x80000000, // 000C RET 0 }) ) ); @@ -3695,35 +3658,29 @@ be_local_closure(lvh_obj_set_val_rule, /* name */ /******************************************************************** -** Solidified function: set_text +** Solidified function: get_value_ofs_y ********************************************************************/ -be_local_closure(lvh_obj_set_text, /* name */ +be_local_closure(lvh_obj_get_value_ofs_y, /* name */ be_nested_proto( - 6, /* nstack */ - 2, /* argc */ + 3, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(check_label), - /* K1 */ be_nested_str_weak(_lv_label), - /* K2 */ be_nested_str_weak(set_text), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_weak(_lv_label), + /* K1 */ be_nested_str_weak(get_y), }), - be_str_weak(set_text), + be_str_weak(get_value_ofs_y), &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x7C080200, // 0001 CALL R2 1 - 0x88080101, // 0002 GETMBR R2 R0 K1 - 0x8C080502, // 0003 GETMET R2 R2 K2 - 0x60100008, // 0004 GETGBL R4 G8 - 0x5C140200, // 0005 MOVE R5 R1 - 0x7C100200, // 0006 CALL R4 1 - 0x7C080400, // 0007 CALL R2 2 - 0x80000000, // 0008 RET 0 + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 }) ) ); @@ -3731,12 +3688,12 @@ be_local_closure(lvh_obj_set_text, /* name */ /******************************************************************** -** Solidified function: get_action +** Solidified function: set_val ********************************************************************/ -be_local_closure(lvh_obj_get_action, /* name */ +be_local_closure(lvh_obj_set_val, /* name */ be_nested_proto( - 3, /* nstack */ - 1, /* argc */ + 5, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -3744,18 +3701,17 @@ be_local_closure(lvh_obj_get_action, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(_action), - /* K1 */ be_nested_str_weak(), + /* K0 */ be_nested_str_weak(_lv_obj), + /* K1 */ be_nested_str_weak(set_value), }), - be_str_weak(get_action), + be_str_weak(set_val), &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x78060001, // 0001 JMPF R1 #0004 - 0x5C080200, // 0002 MOVE R2 R1 - 0x70020000, // 0003 JMP #0005 - 0x58080001, // 0004 LDCONST R2 K1 - 0x80040400, // 0005 RET 1 R2 + ( &(const binstruction[ 5]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C080400, // 0003 CALL R2 2 + 0x80000000, // 0004 RET 0 }) ) ); @@ -3763,27 +3719,64 @@ be_local_closure(lvh_obj_get_action, /* name */ /******************************************************************** -** Solidified function: get_value_font +** Solidified function: set_toggle ********************************************************************/ -be_local_closure(lvh_obj_get_value_font, /* name */ +be_local_closure(lvh_obj_set_toggle, /* name */ be_nested_proto( - 3, /* nstack */ - 1, /* argc */ + 7, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_weak(get_text_font), + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_weak(string), + /* K1 */ be_nested_str_weak(toupper), + /* K2 */ be_nested_str_weak(TRUE), + /* K3 */ be_nested_str_weak(FALSE), + /* K4 */ be_nested_str_weak(_lv_obj), + /* K5 */ be_nested_str_weak(add_state), + /* K6 */ be_nested_str_weak(lv), + /* K7 */ be_nested_str_weak(STATE_CHECKED), + /* K8 */ be_nested_str_weak(clear_state), }), - be_str_weak(get_value_font), + be_str_weak(set_toggle), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x80040200, // 0002 RET 1 R1 + ( &(const binstruction[32]) { /* code */ + 0x60080004, // 0000 GETGBL R2 G4 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x1C080500, // 0003 EQ R2 R2 K0 + 0x780A000D, // 0004 JMPF R2 #0013 + 0xA40A0000, // 0005 IMPORT R2 K0 + 0x8C0C0501, // 0006 GETMET R3 R2 K1 + 0x60140008, // 0007 GETGBL R5 G8 + 0x5C180200, // 0008 MOVE R6 R1 + 0x7C140200, // 0009 CALL R5 1 + 0x7C0C0400, // 000A CALL R3 2 + 0x5C040600, // 000B MOVE R1 R3 + 0x1C0C0302, // 000C EQ R3 R1 K2 + 0x780E0001, // 000D JMPF R3 #0010 + 0x50040200, // 000E LDBOOL R1 1 0 + 0x70020002, // 000F JMP #0013 + 0x1C0C0303, // 0010 EQ R3 R1 K3 + 0x780E0000, // 0011 JMPF R3 #0013 + 0x50040000, // 0012 LDBOOL R1 0 0 + 0x78060005, // 0013 JMPF R1 #001A + 0x88080104, // 0014 GETMBR R2 R0 K4 + 0x8C080505, // 0015 GETMET R2 R2 K5 + 0xB8120C00, // 0016 GETNGBL R4 K6 + 0x88100907, // 0017 GETMBR R4 R4 K7 + 0x7C080400, // 0018 CALL R2 2 + 0x70020004, // 0019 JMP #001F + 0x88080104, // 001A GETMBR R2 R0 K4 + 0x8C080508, // 001B GETMET R2 R2 K8 + 0xB8120C00, // 001C GETNGBL R4 K6 + 0x88100907, // 001D GETMBR R4 R4 K7 + 0x7C080400, // 001E CALL R2 2 + 0x80000000, // 001F RET 0 }) ) ); @@ -3791,9 +3784,9 @@ be_local_closure(lvh_obj_get_value_font, /* name */ /******************************************************************** -** Solidified function: get_hidden +** Solidified function: get_line_width ********************************************************************/ -be_local_closure(lvh_obj_get_hidden, /* name */ +be_local_closure(lvh_obj_get_line_width, /* name */ be_nested_proto( 4, /* nstack */ 1, /* argc */ @@ -3803,21 +3796,19 @@ be_local_closure(lvh_obj_get_hidden, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ + ( &(const bvalue[ 3]) { /* constants */ /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(has_flag), - /* K2 */ be_nested_str_weak(lv), - /* K3 */ be_nested_str_weak(OBJ_FLAG_HIDDEN), + /* K1 */ be_nested_str_weak(get_style_line_width), + /* K2 */ be_const_int(0), }), - be_str_weak(get_hidden), + be_str_weak(get_line_width), &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ + ( &(const binstruction[ 5]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 0x8C040301, // 0001 GETMET R1 R1 K1 - 0xB80E0400, // 0002 GETNGBL R3 K2 - 0x880C0703, // 0003 GETMBR R3 R3 K3 - 0x7C040400, // 0004 CALL R1 2 - 0x80040200, // 0005 RET 1 R1 + 0x580C0002, // 0002 LDCONST R3 K2 + 0x7C040400, // 0003 CALL R1 2 + 0x80040200, // 0004 RET 1 R1 }) ) ); @@ -3825,23 +3816,35 @@ be_local_closure(lvh_obj_get_hidden, /* name */ /******************************************************************** -** Solidified function: get_pad_all +** Solidified function: set_text ********************************************************************/ -be_local_closure(lvh_obj_get_pad_all, /* name */ +be_local_closure(lvh_obj_set_text, /* name */ be_nested_proto( - 1, /* nstack */ - 1, /* argc */ + 6, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_weak(get_pad_all), + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(check_label), + /* K1 */ be_nested_str_weak(_lv_label), + /* K2 */ be_nested_str_weak(set_text), + }), + be_str_weak(set_text), &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 + ( &(const binstruction[ 9]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x7C080200, // 0001 CALL R2 1 + 0x88080101, // 0002 GETMBR R2 R0 K1 + 0x8C080502, // 0003 GETMET R2 R2 K2 + 0x60100008, // 0004 GETGBL R4 G8 + 0x5C140200, // 0005 MOVE R5 R1 + 0x7C100200, // 0006 CALL R4 1 + 0x7C080400, // 0007 CALL R2 2 + 0x80000000, // 0008 RET 0 }) ) ); @@ -3849,31 +3852,84 @@ be_local_closure(lvh_obj_get_pad_all, /* name */ /******************************************************************** -** Solidified function: get_text_color +** Solidified function: set_mode ********************************************************************/ -be_local_closure(lvh_obj_get_text_color, /* name */ +be_local_closure(lvh_obj_set_mode, /* name */ be_nested_proto( - 4, /* nstack */ - 1, /* argc */ + 6, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_weak(_lv_obj), - /* K1 */ be_nested_str_weak(get_style_text_color), - /* K2 */ be_const_int(0), + ( &(const bvalue[18]) { /* constants */ + /* K0 */ be_nested_str_weak(expand), + /* K1 */ be_nested_str_weak(_lv_obj), + /* K2 */ be_nested_str_weak(set_width), + /* K3 */ be_nested_str_weak(lv), + /* K4 */ be_nested_str_weak(SIZE_CONTENT), + /* K5 */ be_nested_str_weak(break), + /* K6 */ be_nested_str_weak(LABEL_LONG_WRAP), + /* K7 */ be_nested_str_weak(dots), + /* K8 */ be_nested_str_weak(LABEL_LONG_DOT), + /* K9 */ be_nested_str_weak(scroll), + /* K10 */ be_nested_str_weak(LABEL_LONG_SCROLL), + /* K11 */ be_nested_str_weak(loop), + /* K12 */ be_nested_str_weak(LABEL_LONG_SCROLL_CIRCULAR), + /* K13 */ be_nested_str_weak(crop), + /* K14 */ be_nested_str_weak(LABEL_LONG_CLIP), + /* K15 */ be_nested_str_weak(check_label), + /* K16 */ be_nested_str_weak(_lv_label), + /* K17 */ be_nested_str_weak(set_long_mode), }), - be_str_weak(get_text_color), + be_str_weak(set_mode), &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x580C0002, // 0002 LDCONST R3 K2 - 0x7C040400, // 0003 CALL R1 2 - 0x80040200, // 0004 RET 1 R1 + ( &(const binstruction[43]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x1C0C0300, // 0001 EQ R3 R1 K0 + 0x780E0005, // 0002 JMPF R3 #0009 + 0x880C0101, // 0003 GETMBR R3 R0 K1 + 0x8C0C0702, // 0004 GETMET R3 R3 K2 + 0xB8160600, // 0005 GETNGBL R5 K3 + 0x88140B04, // 0006 GETMBR R5 R5 K4 + 0x7C0C0400, // 0007 CALL R3 2 + 0x70020017, // 0008 JMP #0021 + 0x1C0C0305, // 0009 EQ R3 R1 K5 + 0x780E0002, // 000A JMPF R3 #000E + 0xB80E0600, // 000B GETNGBL R3 K3 + 0x88080706, // 000C GETMBR R2 R3 K6 + 0x70020012, // 000D JMP #0021 + 0x1C0C0307, // 000E EQ R3 R1 K7 + 0x780E0002, // 000F JMPF R3 #0013 + 0xB80E0600, // 0010 GETNGBL R3 K3 + 0x88080708, // 0011 GETMBR R2 R3 K8 + 0x7002000D, // 0012 JMP #0021 + 0x1C0C0309, // 0013 EQ R3 R1 K9 + 0x780E0002, // 0014 JMPF R3 #0018 + 0xB80E0600, // 0015 GETNGBL R3 K3 + 0x8808070A, // 0016 GETMBR R2 R3 K10 + 0x70020008, // 0017 JMP #0021 + 0x1C0C030B, // 0018 EQ R3 R1 K11 + 0x780E0002, // 0019 JMPF R3 #001D + 0xB80E0600, // 001A GETNGBL R3 K3 + 0x8808070C, // 001B GETMBR R2 R3 K12 + 0x70020003, // 001C JMP #0021 + 0x1C0C030D, // 001D EQ R3 R1 K13 + 0x780E0001, // 001E JMPF R3 #0021 + 0xB80E0600, // 001F GETNGBL R3 K3 + 0x8808070E, // 0020 GETMBR R2 R3 K14 + 0x4C0C0000, // 0021 LDNIL R3 + 0x200C0403, // 0022 NE R3 R2 R3 + 0x780E0005, // 0023 JMPF R3 #002A + 0x8C0C010F, // 0024 GETMET R3 R0 K15 + 0x7C0C0200, // 0025 CALL R3 1 + 0x880C0110, // 0026 GETMBR R3 R0 K16 + 0x8C0C0711, // 0027 GETMET R3 R3 K17 + 0x5C140400, // 0028 MOVE R5 R2 + 0x7C0C0400, // 0029 CALL R3 2 + 0x80000000, // 002A RET 0 }) ) ); @@ -3884,16 +3940,19 @@ be_local_closure(lvh_obj_get_text_color, /* name */ ** Solidified class: lvh_obj ********************************************************************/ be_local_class(lvh_obj, - 12, + 13, NULL, - be_nested_map(88, + be_nested_map(91, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(set_radius2, 68), be_const_closure(lvh_obj_set_radius2_closure) }, - { be_const_key_weak(register_event_cb, -1), be_const_closure(lvh_obj_register_event_cb_closure) }, - { be_const_key_weak(get_text_rule_format, -1), be_const_closure(lvh_obj_get_text_rule_format_closure) }, - { be_const_key_weak(set_value_ofs_x, -1), be_const_closure(lvh_obj_set_value_ofs_x_closure) }, - { be_const_key_weak(get_radius2, -1), be_const_closure(lvh_obj_get_radius2_closure) }, - { be_const_key_weak(_attr_ignore, 30), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + { be_const_key_weak(parse_color, 3), be_const_static_closure(lvh_obj_parse_color_closure) }, + { be_const_key_weak(set_mode, 8), be_const_closure(lvh_obj_set_mode_closure) }, + { be_const_key_weak(set_pad_top2, -1), be_const_closure(lvh_obj_set_pad_top2_closure) }, + { be_const_key_weak(set_pad_left2, -1), be_const_closure(lvh_obj_set_pad_left2_closure) }, + { be_const_key_weak(get_obj, -1), be_const_closure(lvh_obj_get_obj_closure) }, + { be_const_key_weak(get_line_width, 84), be_const_closure(lvh_obj_get_line_width_closure) }, + { be_const_key_weak(get_align, -1), be_const_closure(lvh_obj_get_align_closure) }, + { be_const_key_weak(_text_rule, -1), be_const_var(9) }, + { be_const_key_weak(_attr_ignore, 42), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { be_const_list( * be_nested_list(10, ( (struct bvalue*) &(const bvalue[]) { be_nested_str_weak(tostring), @@ -3907,31 +3966,44 @@ be_local_class(lvh_obj, be_nested_str_weak(back), be_nested_str_weak(berry_run), })) ) } )) }, - { be_const_key_weak(val_rule_matched, -1), be_const_closure(lvh_obj_val_rule_matched_closure) }, - { be_const_key_weak(set_pad_top2, -1), be_const_closure(lvh_obj_set_pad_top2_closure) }, { be_const_key_weak(get_value_font, -1), be_const_closure(lvh_obj_get_value_font_closure) }, - { be_const_key_weak(_text_rule_function, -1), be_const_var(10) }, - { be_const_key_weak(_text_rule_format, -1), be_const_var(11) }, - { be_const_key_weak(set_text_font, -1), be_const_closure(lvh_obj_set_text_font_closure) }, - { be_const_key_weak(parse_color, -1), be_const_static_closure(lvh_obj_parse_color_closure) }, + { be_const_key_weak(id, 64), be_const_var(0) }, + { be_const_key_weak(_val_rule, 65), be_const_var(6) }, + { be_const_key_weak(_val_rule_function, -1), be_const_var(8) }, + { be_const_key_weak(get_pad_bottom, -1), be_const_closure(lvh_obj_get_pad_bottom_closure) }, + { be_const_key_weak(val_rule_matched, -1), be_const_closure(lvh_obj_val_rule_matched_closure) }, + { be_const_key_weak(get_enabled, 86), be_const_closure(lvh_obj_get_enabled_closure) }, + { be_const_key_weak(set_meta, 35), be_const_closure(lvh_obj_set_meta_closure) }, + { be_const_key_weak(get_val_rule, 52), be_const_closure(lvh_obj_get_val_rule_closure) }, + { be_const_key_weak(_page, 47), be_const_var(3) }, + { be_const_key_weak(init, -1), be_const_closure(lvh_obj_init_closure) }, + { be_const_key_weak(set_toggle, 36), be_const_closure(lvh_obj_set_toggle_closure) }, + { be_const_key_weak(_text_rule_function, -1), be_const_var(11) }, + { be_const_key_weak(check_label, 49), be_const_closure(lvh_obj_check_label_closure) }, + { be_const_key_weak(get_meta, -1), be_const_closure(lvh_obj_get_meta_closure) }, + { be_const_key_weak(set_val_rule, 59), be_const_closure(lvh_obj_set_val_rule_closure) }, + { be_const_key_weak(set_enabled, -1), be_const_closure(lvh_obj_set_enabled_closure) }, + { be_const_key_weak(get_action, -1), be_const_closure(lvh_obj_get_action_closure) }, + { be_const_key_weak(get_radius2, 18), be_const_closure(lvh_obj_get_radius2_closure) }, + { be_const_key_weak(_lv_obj, -1), be_const_var(1) }, + { be_const_key_weak(get_text_rule_formula, -1), be_const_closure(lvh_obj_get_text_rule_formula_closure) }, + { be_const_key_weak(get_value_ofs_x, -1), be_const_closure(lvh_obj_get_value_ofs_x_closure) }, + { be_const_key_weak(get_value_color, -1), be_const_closure(lvh_obj_get_value_color_closure) }, + { be_const_key_weak(set_pad_bottom2, -1), be_const_closure(lvh_obj_set_pad_bottom2_closure) }, + { be_const_key_weak(get_text_color, -1), be_const_closure(lvh_obj_get_text_color_closure) }, + { be_const_key_weak(get_value_ofs_y, 71), be_const_closure(lvh_obj_get_value_ofs_y_closure) }, { be_const_key_weak(get_text_font, -1), be_const_closure(lvh_obj_get_text_font_closure) }, - { be_const_key_weak(text_rule_matched, 70), be_const_closure(lvh_obj_text_rule_matched_closure) }, - { be_const_key_weak(_lv_class, -1), be_const_class(be_class_lv_obj) }, - { be_const_key_weak(set_text, 78), be_const_closure(lvh_obj_set_text_closure) }, - { be_const_key_weak(set_align, -1), be_const_closure(lvh_obj_set_align_closure) }, - { be_const_key_weak(set_val_rule, 35), be_const_closure(lvh_obj_set_val_rule_closure) }, - { be_const_key_weak(set_val, -1), be_const_closure(lvh_obj_set_val_closure) }, - { be_const_key_weak(get_pad_right, 80), be_const_closure(lvh_obj_get_pad_right_closure) }, - { be_const_key_weak(_text_rule_formula, 79), be_const_var(9) }, - { be_const_key_weak(set_action, -1), be_const_closure(lvh_obj_set_action_closure) }, - { be_const_key_weak(get_value_ofs_x, 86), be_const_closure(lvh_obj_get_value_ofs_x_closure) }, - { be_const_key_weak(set_value_ofs_y, 6), be_const_closure(lvh_obj_set_value_ofs_y_closure) }, - { be_const_key_weak(remove_trailing_zeroes, 41), be_const_static_closure(lvh_obj_remove_trailing_zeroes_closure) }, - { be_const_key_weak(post_init, 18), be_const_closure(lvh_obj_post_init_closure) }, { be_const_key_weak(get_mode, -1), be_const_closure(lvh_obj_get_mode_closure) }, - { be_const_key_weak(_action, -1), be_const_var(4) }, - { be_const_key_weak(_lv_label, 7), be_const_var(2) }, - { be_const_key_weak(set_toggle, 31), be_const_closure(lvh_obj_set_toggle_closure) }, + { be_const_key_weak(_text_rule_formula, 5), be_const_var(10) }, + { be_const_key_weak(set_text_rule_formula, -1), be_const_closure(lvh_obj_set_text_rule_formula_closure) }, + { be_const_key_weak(get_pad_top, -1), be_const_closure(lvh_obj_get_pad_top_closure) }, + { be_const_key_weak(set_adjustable, -1), be_const_closure(lvh_obj_set_adjustable_closure) }, + { be_const_key_weak(set_value_color, -1), be_const_closure(lvh_obj_set_value_color_closure) }, + { be_const_key_weak(get_val, 67), be_const_closure(lvh_obj_get_val_closure) }, + { be_const_key_weak(set_pad_all2, -1), be_const_closure(lvh_obj_set_pad_all2_closure) }, + { be_const_key_weak(_lv_label, 29), be_const_var(2) }, + { be_const_key_weak(_lv_class, -1), be_const_class(be_class_lv_obj) }, + { be_const_key_weak(setmember, 88), be_const_closure(lvh_obj_setmember_closure) }, { be_const_key_weak(_attr_map, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { be_const_map( * be_nested_map(26, ( (struct bmapnode*) &(const bmapnode[]) { @@ -3962,40 +4034,15 @@ be_local_class(lvh_obj, { be_const_key_weak(pad_top, 16), be_nested_str_weak(style_pad_top) }, { be_const_key_weak(bg_grad_dir, 14), be_nested_str_weak(style_bg_grad_dir) }, })) ) } )) }, - { be_const_key_weak(set_line_width, -1), be_const_closure(lvh_obj_set_line_width_closure) }, - { be_const_key_weak(set_value_str, 72), be_const_closure(lvh_obj_set_value_str_closure) }, - { be_const_key_weak(is_color_attribute, -1), be_const_static_closure(lvh_obj_is_color_attribute_closure) }, - { be_const_key_weak(_lv_obj, -1), be_const_var(1) }, - { be_const_key_weak(set_value_color, -1), be_const_closure(lvh_obj_set_value_color_closure) }, - { be_const_key_weak(get_value_color, -1), be_const_closure(lvh_obj_get_value_color_closure) }, - { be_const_key_weak(get_val_rule, -1), be_const_closure(lvh_obj_get_val_rule_closure) }, - { be_const_key_weak(get_val, -1), be_const_closure(lvh_obj_get_val_closure) }, - { be_const_key_weak(get_click, -1), be_const_closure(lvh_obj_get_click_closure) }, - { be_const_key_weak(get_enabled, 81), be_const_closure(lvh_obj_get_enabled_closure) }, - { be_const_key_weak(set_adjustable, -1), be_const_closure(lvh_obj_set_adjustable_closure) }, - { be_const_key_weak(get_pad_left, 16), be_const_closure(lvh_obj_get_pad_left_closure) }, - { be_const_key_weak(get_value_ofs_y, -1), be_const_closure(lvh_obj_get_value_ofs_y_closure) }, - { be_const_key_weak(_val_rule_formula, 76), be_const_var(6) }, - { be_const_key_weak(get_text_rule, 34), be_const_closure(lvh_obj_get_text_rule_closure) }, - { be_const_key_weak(set_value_font, 74), be_const_closure(lvh_obj_set_value_font_closure) }, - { be_const_key_weak(_val_rule, -1), be_const_var(5) }, - { be_const_key_weak(event_cb, 58), be_const_closure(lvh_obj_event_cb_closure) }, - { be_const_key_weak(set_text_rule, -1), be_const_closure(lvh_obj_set_text_rule_closure) }, - { be_const_key_weak(get_adjustable, -1), be_const_closure(lvh_obj_get_adjustable_closure) }, - { be_const_key_weak(get_toggle, -1), be_const_closure(lvh_obj_get_toggle_closure) }, - { be_const_key_weak(get_value_str, -1), be_const_closure(lvh_obj_get_value_str_closure) }, - { be_const_key_weak(set_pad_right2, -1), be_const_closure(lvh_obj_set_pad_right2_closure) }, - { be_const_key_weak(set_val_rule_formula, 66), be_const_closure(lvh_obj_set_val_rule_formula_closure) }, - { be_const_key_weak(id, 5), be_const_var(0) }, - { be_const_key_weak(set_pad_bottom2, 33), be_const_closure(lvh_obj_set_pad_bottom2_closure) }, - { be_const_key_weak(get_pad_top, 36), be_const_closure(lvh_obj_get_pad_top_closure) }, - { be_const_key_weak(get_val_rule_formula, -1), be_const_closure(lvh_obj_get_val_rule_formula_closure) }, - { be_const_key_weak(set_hidden, -1), be_const_closure(lvh_obj_set_hidden_closure) }, - { be_const_key_weak(_page, -1), be_const_var(3) }, - { be_const_key_weak(check_label, -1), be_const_closure(lvh_obj_check_label_closure) }, + { be_const_key_weak(remove_trailing_zeroes, -1), be_const_static_closure(lvh_obj_remove_trailing_zeroes_closure) }, + { be_const_key_weak(_action, -1), be_const_var(4) }, { be_const_key_weak(get_text, -1), be_const_closure(lvh_obj_get_text_closure) }, - { be_const_key_weak(set_text_rule_format, 60), be_const_closure(lvh_obj_set_text_rule_format_closure) }, - { be_const_key_weak(set_pad_all2, -1), be_const_closure(lvh_obj_set_pad_all2_closure) }, + { be_const_key_weak(_val_rule_formula, -1), be_const_var(7) }, + { be_const_key_weak(get_pad_all, -1), be_const_closure(lvh_obj_get_pad_all_closure) }, + { be_const_key_weak(set_action, -1), be_const_closure(lvh_obj_set_action_closure) }, + { be_const_key_weak(set_hidden, 46), be_const_closure(lvh_obj_set_hidden_closure) }, + { be_const_key_weak(get_text_rule, 75), be_const_closure(lvh_obj_get_text_rule_closure) }, + { be_const_key_weak(get_adjustable, -1), be_const_closure(lvh_obj_get_adjustable_closure) }, { be_const_key_weak(_event_map, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { be_const_map( * be_nested_map(7, ( (struct bmapnode*) &(const bmapnode[]) { @@ -4007,27 +4054,39 @@ be_local_class(lvh_obj, { be_const_key_int(5, -1), be_nested_str_weak(long) }, { be_const_key_int(6, -1), be_nested_str_weak(hold) }, })) ) } )) }, - { be_const_key_weak(set_text_color, -1), be_const_closure(lvh_obj_set_text_color_closure) }, - { be_const_key_weak(_text_rule, -1), be_const_var(8) }, - { be_const_key_weak(get_pad_bottom, -1), be_const_closure(lvh_obj_get_pad_bottom_closure) }, + { be_const_key_weak(set_radius2, 78), be_const_closure(lvh_obj_set_radius2_closure) }, + { be_const_key_weak(get_pad_left, -1), be_const_closure(lvh_obj_get_pad_left_closure) }, + { be_const_key_weak(get_value_str, 58), be_const_closure(lvh_obj_get_value_str_closure) }, + { be_const_key_weak(set_value_ofs_y, -1), be_const_closure(lvh_obj_set_value_ofs_y_closure) }, { be_const_key_weak(_lv_part2_selector, -1), be_const_nil() }, - { be_const_key_weak(set_pad_left2, 42), be_const_closure(lvh_obj_set_pad_left2_closure) }, - { be_const_key_weak(get_line_width, 11), be_const_closure(lvh_obj_get_line_width_closure) }, - { be_const_key_weak(setmember, -1), be_const_closure(lvh_obj_setmember_closure) }, - { be_const_key_weak(set_mode, -1), be_const_closure(lvh_obj_set_mode_closure) }, - { be_const_key_weak(init, -1), be_const_closure(lvh_obj_init_closure) }, - { be_const_key_weak(get_obj, -1), be_const_closure(lvh_obj_get_obj_closure) }, - { be_const_key_weak(set_enabled, 32), be_const_closure(lvh_obj_set_enabled_closure) }, - { be_const_key_weak(get_text_rule_formula, -1), be_const_closure(lvh_obj_get_text_rule_formula_closure) }, - { be_const_key_weak(get_align, -1), be_const_closure(lvh_obj_get_align_closure) }, - { be_const_key_weak(set_click, 2), be_const_closure(lvh_obj_set_click_closure) }, - { be_const_key_weak(_val_rule_function, -1), be_const_var(7) }, - { be_const_key_weak(get_action, -1), be_const_closure(lvh_obj_get_action_closure) }, - { be_const_key_weak(member, 8), be_const_closure(lvh_obj_member_closure) }, + { be_const_key_weak(set_text_font, -1), be_const_closure(lvh_obj_set_text_font_closure) }, + { be_const_key_weak(set_value_ofs_x, 45), be_const_closure(lvh_obj_set_value_ofs_x_closure) }, + { be_const_key_weak(text_rule_matched, 79), be_const_closure(lvh_obj_text_rule_matched_closure) }, + { be_const_key_weak(set_line_width, -1), be_const_closure(lvh_obj_set_line_width_closure) }, + { be_const_key_weak(get_val_rule_formula, 69), be_const_closure(lvh_obj_get_val_rule_formula_closure) }, + { be_const_key_weak(set_val_rule_formula, -1), be_const_closure(lvh_obj_set_val_rule_formula_closure) }, + { be_const_key_weak(set_align, -1), be_const_closure(lvh_obj_set_align_closure) }, + { be_const_key_weak(set_text_rule_format, 62), be_const_closure(lvh_obj_set_text_rule_format_closure) }, + { be_const_key_weak(set_value_str, -1), be_const_closure(lvh_obj_set_value_str_closure) }, + { be_const_key_weak(_text_rule_format, -1), be_const_var(12) }, + { be_const_key_weak(post_init, -1), be_const_closure(lvh_obj_post_init_closure) }, + { be_const_key_weak(get_text_rule_format, -1), be_const_closure(lvh_obj_get_text_rule_format_closure) }, + { be_const_key_weak(set_text_rule, -1), be_const_closure(lvh_obj_set_text_rule_closure) }, + { be_const_key_weak(member, -1), be_const_closure(lvh_obj_member_closure) }, + { be_const_key_weak(is_color_attribute, -1), be_const_static_closure(lvh_obj_is_color_attribute_closure) }, + { be_const_key_weak(set_click, -1), be_const_closure(lvh_obj_set_click_closure) }, { be_const_key_weak(get_hidden, -1), be_const_closure(lvh_obj_get_hidden_closure) }, - { be_const_key_weak(get_pad_all, -1), be_const_closure(lvh_obj_get_pad_all_closure) }, - { be_const_key_weak(set_text_rule_formula, -1), be_const_closure(lvh_obj_set_text_rule_formula_closure) }, - { be_const_key_weak(get_text_color, -1), be_const_closure(lvh_obj_get_text_color_closure) }, + { be_const_key_weak(get_pad_right, -1), be_const_closure(lvh_obj_get_pad_right_closure) }, + { be_const_key_weak(event_cb, 34), be_const_closure(lvh_obj_event_cb_closure) }, + { be_const_key_weak(set_val, -1), be_const_closure(lvh_obj_set_val_closure) }, + { be_const_key_weak(set_text_color, 20), be_const_closure(lvh_obj_set_text_color_closure) }, + { be_const_key_weak(get_toggle, -1), be_const_closure(lvh_obj_get_toggle_closure) }, + { be_const_key_weak(register_event_cb, 11), be_const_closure(lvh_obj_register_event_cb_closure) }, + { be_const_key_weak(get_click, -1), be_const_closure(lvh_obj_get_click_closure) }, + { be_const_key_weak(set_value_font, 7), be_const_closure(lvh_obj_set_value_font_closure) }, + { be_const_key_weak(set_pad_right2, -1), be_const_closure(lvh_obj_set_pad_right2_closure) }, + { be_const_key_weak(set_text, -1), be_const_closure(lvh_obj_set_text_closure) }, + { be_const_key_weak(_meta, 1), be_const_var(5) }, })), be_str_weak(lvh_obj) ); @@ -7214,7 +7273,7 @@ be_local_closure(HASPmota_sort, /* name */ ********************************************************************/ be_local_closure(HASPmota_parse_obj, /* name */ be_nested_proto( - 20, /* nstack */ + 21, /* nstack */ 3, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -7222,7 +7281,7 @@ be_local_closure(HASPmota_parse_obj, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[30]) { /* constants */ + ( &(const bvalue[32]) { /* constants */ /* K0 */ be_nested_str_weak(global), /* K1 */ be_nested_str_weak(string), /* K2 */ be_nested_str_weak(introspect), @@ -7233,7 +7292,7 @@ be_local_closure(HASPmota_parse_obj, /* name */ /* K7 */ be_nested_str_weak(berry_run), /* K8 */ be_nested_str_weak(nil), /* K9 */ be_nested_str_weak(format), - /* K10 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20run_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K10 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20compile_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), /* K11 */ be_const_int(1), /* K12 */ be_nested_str_weak(HSP_X3A_X20invalid_X20_X27id_X27_X3A_X20), /* K13 */ be_nested_str_weak(_X20for_X20_X27obj_X27_X3A), @@ -7249,14 +7308,16 @@ be_local_closure(HASPmota_parse_obj, /* name */ /* K23 */ be_nested_str_weak(HSP_X3A_X20cannot_X20find_X20object_X20of_X20type_X20), /* K24 */ be_nested_str_weak(set_obj), /* K25 */ be_nested_str_weak(p_X25ib_X25i), - /* K26 */ be_const_int(0), - /* K27 */ be_nested_str_weak(HSP_X3A_X20cannot_X20specify_X20_X27obj_X27_X20for_X20_X27id_X27_X3A0), - /* K28 */ be_nested_str_weak(keys), - /* K29 */ be_nested_str_weak(stop_iteration), + /* K26 */ be_nested_str_weak(function), + /* K27 */ be_nested_str_weak(HSP_X3A_X20unable_X20to_X20run_X20berry_X20code_X20_X22_X25s_X22_X20_X2D_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K28 */ be_const_int(0), + /* K29 */ be_nested_str_weak(HSP_X3A_X20cannot_X20specify_X20_X27obj_X27_X20for_X20_X27id_X27_X3A0), + /* K30 */ be_nested_str_weak(keys), + /* K31 */ be_nested_str_weak(stop_iteration), }), be_str_weak(parse_obj), &be_const_str_solidified, - ( &(const binstruction[190]) { /* code */ + ( &(const binstruction[218]) { /* code */ 0xA40E0000, // 0000 IMPORT R3 K0 0xA4120200, // 0001 IMPORT R4 K1 0xA4160400, // 0002 IMPORT R5 K2 @@ -7278,175 +7339,203 @@ be_local_closure(HASPmota_parse_obj, /* name */ 0x58340007, // 0012 LDCONST R13 K7 0x7C2C0400, // 0013 CALL R11 2 0x7C280200, // 0014 CALL R10 1 - 0x202C1508, // 0015 NE R11 R10 K8 - 0x782E0013, // 0016 JMPF R11 #002B - 0xA8020006, // 0017 EXBLK 0 #001F - 0x602C000D, // 0018 GETGBL R11 G13 - 0x5C301400, // 0019 MOVE R12 R10 - 0x7C2C0200, // 001A CALL R11 1 - 0x5C301600, // 001B MOVE R12 R11 - 0x7C300000, // 001C CALL R12 0 + 0x4C2C0000, // 0015 LDNIL R11 + 0x20301508, // 0016 NE R12 R10 K8 + 0x78320012, // 0017 JMPF R12 #002B + 0xA8020005, // 0018 EXBLK 0 #001F + 0x6030000D, // 0019 GETGBL R12 G13 + 0x5C341400, // 001A MOVE R13 R10 + 0x7C300200, // 001B CALL R12 1 + 0x5C2C1800, // 001C MOVE R11 R12 0xA8040001, // 001D EXBLK 1 1 0x7002000B, // 001E JMP #002B - 0xAC2C0002, // 001F CATCH R11 0 2 + 0xAC300002, // 001F CATCH R12 0 2 0x70020008, // 0020 JMP #002A - 0x60340001, // 0021 GETGBL R13 G1 - 0x8C380909, // 0022 GETMET R14 R4 K9 - 0x5840000A, // 0023 LDCONST R16 K10 - 0x5C441400, // 0024 MOVE R17 R10 - 0x5C481600, // 0025 MOVE R18 R11 - 0x5C4C1800, // 0026 MOVE R19 R12 - 0x7C380A00, // 0027 CALL R14 5 - 0x7C340200, // 0028 CALL R13 1 + 0x60380001, // 0021 GETGBL R14 G1 + 0x8C3C0909, // 0022 GETMET R15 R4 K9 + 0x5844000A, // 0023 LDCONST R17 K10 + 0x5C481400, // 0024 MOVE R18 R10 + 0x5C4C1800, // 0025 MOVE R19 R12 + 0x5C501A00, // 0026 MOVE R20 R13 + 0x7C3C0A00, // 0027 CALL R15 5 + 0x7C380200, // 0028 CALL R14 1 0x70020000, // 0029 JMP #002B 0xB0080000, // 002A RAISE 2 R0 R0 - 0x4C2C0000, // 002B LDNIL R11 - 0x1C2C0C0B, // 002C EQ R11 R6 R11 - 0x782E0000, // 002D JMPF R11 #002F - 0x80001600, // 002E RET 0 - 0x202C0F08, // 002F NE R11 R7 K8 - 0x782E006E, // 0030 JMPF R11 #00A0 - 0x4C2C0000, // 0031 LDNIL R11 - 0x202C0C0B, // 0032 NE R11 R6 R11 - 0x782E006B, // 0033 JMPF R11 #00A0 - 0x142C0D0B, // 0034 LT R11 R6 K11 - 0x742E0002, // 0035 JMPT R11 #0039 - 0x542E00FD, // 0036 LDINT R11 254 - 0x242C0C0B, // 0037 GT R11 R6 R11 - 0x782E0008, // 0038 JMPF R11 #0042 - 0x602C0001, // 0039 GETGBL R11 G1 - 0x60300008, // 003A GETGBL R12 G8 - 0x5C340C00, // 003B MOVE R13 R6 - 0x7C300200, // 003C CALL R12 1 - 0x0032180C, // 003D ADD R12 K12 R12 - 0x0030190D, // 003E ADD R12 R12 K13 - 0x00301807, // 003F ADD R12 R12 R7 - 0x7C2C0200, // 0040 CALL R11 1 - 0x80001600, // 0041 RET 0 - 0x4C2C0000, // 0042 LDNIL R11 - 0x60300009, // 0043 GETGBL R12 G9 - 0x8C340303, // 0044 GETMET R13 R1 K3 - 0x583C000E, // 0045 LDCONST R15 K14 - 0x7C340400, // 0046 CALL R13 2 - 0x7C300200, // 0047 CALL R12 1 - 0x4C340000, // 0048 LDNIL R13 - 0x2034180D, // 0049 NE R13 R12 R13 - 0x78360006, // 004A JMPF R13 #0052 - 0x8C34130F, // 004B GETMET R13 R9 K15 - 0x5C3C1800, // 004C MOVE R15 R12 - 0x7C340400, // 004D CALL R13 2 - 0x4C380000, // 004E LDNIL R14 - 0x20381A0E, // 004F NE R14 R13 R14 - 0x783A0000, // 0050 JMPF R14 #0052 - 0x882C1B10, // 0051 GETMBR R11 R13 K16 - 0x4C340000, // 0052 LDNIL R13 - 0x1C34160D, // 0053 EQ R13 R11 R13 - 0x78360002, // 0054 JMPF R13 #0058 - 0x8C341311, // 0055 GETMET R13 R9 K17 - 0x7C340200, // 0056 CALL R13 1 - 0x5C2C1A00, // 0057 MOVE R11 R13 - 0x8C340B12, // 0058 GETMET R13 R5 K18 - 0x5C3C0000, // 0059 MOVE R15 R0 - 0x00422607, // 005A ADD R16 K19 R7 - 0x7C340600, // 005B CALL R13 3 - 0x4C380000, // 005C LDNIL R14 - 0x4C3C0000, // 005D LDNIL R15 - 0x1C3C1A0F, // 005E EQ R15 R13 R15 - 0x783E0010, // 005F JMPF R15 #0071 - 0x8C3C0B12, // 0060 GETMET R15 R5 K18 - 0x5C440600, // 0061 MOVE R17 R3 - 0x5C480E00, // 0062 MOVE R18 R7 - 0x7C3C0600, // 0063 CALL R15 3 - 0x4C400000, // 0064 LDNIL R16 - 0x20401E10, // 0065 NE R16 R15 R16 - 0x78420009, // 0066 JMPF R16 #0071 - 0x60400004, // 0067 GETGBL R16 G4 - 0x5C441E00, // 0068 MOVE R17 R15 - 0x7C400200, // 0069 CALL R16 1 - 0x1C402114, // 006A EQ R16 R16 K20 - 0x78420004, // 006B JMPF R16 #0071 - 0x5C401E00, // 006C MOVE R16 R15 - 0x5C441600, // 006D MOVE R17 R11 - 0x7C400200, // 006E CALL R16 1 - 0x5C382000, // 006F MOVE R14 R16 - 0x88340115, // 0070 GETMBR R13 R0 K21 - 0x4C3C0000, // 0071 LDNIL R15 - 0x1C3C1A0F, // 0072 EQ R15 R13 R15 - 0x783E000F, // 0073 JMPF R15 #0084 - 0x8C3C0B16, // 0074 GETMET R15 R5 K22 - 0x5C440E00, // 0075 MOVE R17 R7 - 0x7C3C0400, // 0076 CALL R15 2 - 0x4C400000, // 0077 LDNIL R16 - 0x20401E10, // 0078 NE R16 R15 R16 - 0x78420009, // 0079 JMPF R16 #0084 - 0x60400004, // 007A GETGBL R16 G4 - 0x5C441E00, // 007B MOVE R17 R15 - 0x7C400200, // 007C CALL R16 1 - 0x1C402114, // 007D EQ R16 R16 K20 - 0x78420004, // 007E JMPF R16 #0084 - 0x5C401E00, // 007F MOVE R16 R15 - 0x5C441600, // 0080 MOVE R17 R11 - 0x7C400200, // 0081 CALL R16 1 - 0x5C382000, // 0082 MOVE R14 R16 - 0x88340115, // 0083 GETMBR R13 R0 K21 - 0x4C3C0000, // 0084 LDNIL R15 - 0x1C3C1A0F, // 0085 EQ R15 R13 R15 - 0x783E0006, // 0086 JMPF R15 #008E - 0x603C0001, // 0087 GETGBL R15 G1 - 0x60400008, // 0088 GETGBL R16 G8 - 0x5C440E00, // 0089 MOVE R17 R7 - 0x7C400200, // 008A CALL R16 1 - 0x00422E10, // 008B ADD R16 K23 R16 - 0x7C3C0200, // 008C CALL R15 1 - 0x80001E00, // 008D RET 0 - 0x5C3C1A00, // 008E MOVE R15 R13 - 0x5C401600, // 008F MOVE R16 R11 - 0x5C440400, // 0090 MOVE R17 R2 - 0x5C480200, // 0091 MOVE R18 R1 - 0x5C4C1C00, // 0092 MOVE R19 R14 - 0x7C3C0800, // 0093 CALL R15 4 - 0x5C201E00, // 0094 MOVE R8 R15 - 0x8C3C1318, // 0095 GETMET R15 R9 K24 - 0x5C440C00, // 0096 MOVE R17 R6 - 0x5C481000, // 0097 MOVE R18 R8 - 0x7C3C0600, // 0098 CALL R15 3 - 0x8C3C0909, // 0099 GETMET R15 R4 K9 - 0x58440019, // 009A LDCONST R17 K25 - 0x8C481304, // 009B GETMET R18 R9 K4 - 0x7C480200, // 009C CALL R18 1 - 0x5C4C0C00, // 009D MOVE R19 R6 - 0x7C3C0800, // 009E CALL R15 4 - 0x900C1E08, // 009F SETMBR R3 R15 R8 - 0x1C2C0D1A, // 00A0 EQ R11 R6 K26 - 0x782E0005, // 00A1 JMPF R11 #00A8 - 0x202C0F08, // 00A2 NE R11 R7 K8 - 0x782E0003, // 00A3 JMPF R11 #00A8 - 0x602C0001, // 00A4 GETGBL R11 G1 - 0x5830001B, // 00A5 LDCONST R12 K27 - 0x7C2C0200, // 00A6 CALL R11 1 - 0x80001600, // 00A7 RET 0 - 0x1C2C0D1A, // 00A8 EQ R11 R6 K26 - 0x782E0005, // 00A9 JMPF R11 #00B0 - 0x8C2C0106, // 00AA GETMET R11 R0 K6 - 0x7C2C0200, // 00AB CALL R11 1 - 0x8C2C170F, // 00AC GETMET R11 R11 K15 - 0x5834001A, // 00AD LDCONST R13 K26 - 0x7C2C0400, // 00AE CALL R11 2 - 0x5C201600, // 00AF MOVE R8 R11 - 0x602C0010, // 00B0 GETGBL R11 G16 - 0x8C30031C, // 00B1 GETMET R12 R1 K28 - 0x7C300200, // 00B2 CALL R12 1 - 0x7C2C0200, // 00B3 CALL R11 1 - 0xA8020004, // 00B4 EXBLK 0 #00BA - 0x5C301600, // 00B5 MOVE R12 R11 - 0x7C300000, // 00B6 CALL R12 0 - 0x9434020C, // 00B7 GETIDX R13 R1 R12 - 0x9020180D, // 00B8 SETMBR R8 R12 R13 - 0x7001FFFA, // 00B9 JMP #00B5 - 0x582C001D, // 00BA LDCONST R11 K29 - 0xAC2C0200, // 00BB CATCH R11 1 0 - 0xB0080000, // 00BC RAISE 2 R0 R0 - 0x80000000, // 00BD RET 0 + 0x4C300000, // 002B LDNIL R12 + 0x1C300C0C, // 002C EQ R12 R6 R12 + 0x78320000, // 002D JMPF R12 #002F + 0x80001800, // 002E RET 0 + 0x20300F08, // 002F NE R12 R7 K8 + 0x7832006E, // 0030 JMPF R12 #00A0 + 0x4C300000, // 0031 LDNIL R12 + 0x20300C0C, // 0032 NE R12 R6 R12 + 0x7832006B, // 0033 JMPF R12 #00A0 + 0x14300D0B, // 0034 LT R12 R6 K11 + 0x74320002, // 0035 JMPT R12 #0039 + 0x543200FD, // 0036 LDINT R12 254 + 0x24300C0C, // 0037 GT R12 R6 R12 + 0x78320008, // 0038 JMPF R12 #0042 + 0x60300001, // 0039 GETGBL R12 G1 + 0x60340008, // 003A GETGBL R13 G8 + 0x5C380C00, // 003B MOVE R14 R6 + 0x7C340200, // 003C CALL R13 1 + 0x0036180D, // 003D ADD R13 K12 R13 + 0x00341B0D, // 003E ADD R13 R13 K13 + 0x00341A07, // 003F ADD R13 R13 R7 + 0x7C300200, // 0040 CALL R12 1 + 0x80001800, // 0041 RET 0 + 0x4C300000, // 0042 LDNIL R12 + 0x60340009, // 0043 GETGBL R13 G9 + 0x8C380303, // 0044 GETMET R14 R1 K3 + 0x5840000E, // 0045 LDCONST R16 K14 + 0x7C380400, // 0046 CALL R14 2 + 0x7C340200, // 0047 CALL R13 1 + 0x4C380000, // 0048 LDNIL R14 + 0x20381A0E, // 0049 NE R14 R13 R14 + 0x783A0006, // 004A JMPF R14 #0052 + 0x8C38130F, // 004B GETMET R14 R9 K15 + 0x5C401A00, // 004C MOVE R16 R13 + 0x7C380400, // 004D CALL R14 2 + 0x4C3C0000, // 004E LDNIL R15 + 0x203C1C0F, // 004F NE R15 R14 R15 + 0x783E0000, // 0050 JMPF R15 #0052 + 0x88301D10, // 0051 GETMBR R12 R14 K16 + 0x4C380000, // 0052 LDNIL R14 + 0x1C38180E, // 0053 EQ R14 R12 R14 + 0x783A0002, // 0054 JMPF R14 #0058 + 0x8C381311, // 0055 GETMET R14 R9 K17 + 0x7C380200, // 0056 CALL R14 1 + 0x5C301C00, // 0057 MOVE R12 R14 + 0x8C380B12, // 0058 GETMET R14 R5 K18 + 0x5C400000, // 0059 MOVE R16 R0 + 0x00462607, // 005A ADD R17 K19 R7 + 0x7C380600, // 005B CALL R14 3 + 0x4C3C0000, // 005C LDNIL R15 + 0x4C400000, // 005D LDNIL R16 + 0x1C401C10, // 005E EQ R16 R14 R16 + 0x78420010, // 005F JMPF R16 #0071 + 0x8C400B12, // 0060 GETMET R16 R5 K18 + 0x5C480600, // 0061 MOVE R18 R3 + 0x5C4C0E00, // 0062 MOVE R19 R7 + 0x7C400600, // 0063 CALL R16 3 + 0x4C440000, // 0064 LDNIL R17 + 0x20442011, // 0065 NE R17 R16 R17 + 0x78460009, // 0066 JMPF R17 #0071 + 0x60440004, // 0067 GETGBL R17 G4 + 0x5C482000, // 0068 MOVE R18 R16 + 0x7C440200, // 0069 CALL R17 1 + 0x1C442314, // 006A EQ R17 R17 K20 + 0x78460004, // 006B JMPF R17 #0071 + 0x5C442000, // 006C MOVE R17 R16 + 0x5C481800, // 006D MOVE R18 R12 + 0x7C440200, // 006E CALL R17 1 + 0x5C3C2200, // 006F MOVE R15 R17 + 0x88380115, // 0070 GETMBR R14 R0 K21 + 0x4C400000, // 0071 LDNIL R16 + 0x1C401C10, // 0072 EQ R16 R14 R16 + 0x7842000F, // 0073 JMPF R16 #0084 + 0x8C400B16, // 0074 GETMET R16 R5 K22 + 0x5C480E00, // 0075 MOVE R18 R7 + 0x7C400400, // 0076 CALL R16 2 + 0x4C440000, // 0077 LDNIL R17 + 0x20442011, // 0078 NE R17 R16 R17 + 0x78460009, // 0079 JMPF R17 #0084 + 0x60440004, // 007A GETGBL R17 G4 + 0x5C482000, // 007B MOVE R18 R16 + 0x7C440200, // 007C CALL R17 1 + 0x1C442314, // 007D EQ R17 R17 K20 + 0x78460004, // 007E JMPF R17 #0084 + 0x5C442000, // 007F MOVE R17 R16 + 0x5C481800, // 0080 MOVE R18 R12 + 0x7C440200, // 0081 CALL R17 1 + 0x5C3C2200, // 0082 MOVE R15 R17 + 0x88380115, // 0083 GETMBR R14 R0 K21 + 0x4C400000, // 0084 LDNIL R16 + 0x1C401C10, // 0085 EQ R16 R14 R16 + 0x78420006, // 0086 JMPF R16 #008E + 0x60400001, // 0087 GETGBL R16 G1 + 0x60440008, // 0088 GETGBL R17 G8 + 0x5C480E00, // 0089 MOVE R18 R7 + 0x7C440200, // 008A CALL R17 1 + 0x00462E11, // 008B ADD R17 K23 R17 + 0x7C400200, // 008C CALL R16 1 + 0x80002000, // 008D RET 0 + 0x5C401C00, // 008E MOVE R16 R14 + 0x5C441800, // 008F MOVE R17 R12 + 0x5C480400, // 0090 MOVE R18 R2 + 0x5C4C0200, // 0091 MOVE R19 R1 + 0x5C501E00, // 0092 MOVE R20 R15 + 0x7C400800, // 0093 CALL R16 4 + 0x5C202000, // 0094 MOVE R8 R16 + 0x8C401318, // 0095 GETMET R16 R9 K24 + 0x5C480C00, // 0096 MOVE R18 R6 + 0x5C4C1000, // 0097 MOVE R19 R8 + 0x7C400600, // 0098 CALL R16 3 + 0x8C400909, // 0099 GETMET R16 R4 K9 + 0x58480019, // 009A LDCONST R18 K25 + 0x8C4C1304, // 009B GETMET R19 R9 K4 + 0x7C4C0200, // 009C CALL R19 1 + 0x5C500C00, // 009D MOVE R20 R6 + 0x7C400800, // 009E CALL R16 4 + 0x900C2008, // 009F SETMBR R3 R16 R8 + 0x4C300000, // 00A0 LDNIL R12 + 0x2030160C, // 00A1 NE R12 R11 R12 + 0x78320018, // 00A2 JMPF R12 #00BC + 0xA802000B, // 00A3 EXBLK 0 #00B0 + 0x5C301600, // 00A4 MOVE R12 R11 + 0x7C300000, // 00A5 CALL R12 0 + 0x60340004, // 00A6 GETGBL R13 G4 + 0x5C381800, // 00A7 MOVE R14 R12 + 0x7C340200, // 00A8 CALL R13 1 + 0x1C341B1A, // 00A9 EQ R13 R13 K26 + 0x78360002, // 00AA JMPF R13 #00AE + 0x5C341800, // 00AB MOVE R13 R12 + 0x5C381000, // 00AC MOVE R14 R8 + 0x7C340200, // 00AD CALL R13 1 + 0xA8040001, // 00AE EXBLK 1 1 + 0x7002000B, // 00AF JMP #00BC + 0xAC300002, // 00B0 CATCH R12 0 2 + 0x70020008, // 00B1 JMP #00BB + 0x60380001, // 00B2 GETGBL R14 G1 + 0x8C3C0909, // 00B3 GETMET R15 R4 K9 + 0x5844001B, // 00B4 LDCONST R17 K27 + 0x5C481400, // 00B5 MOVE R18 R10 + 0x5C4C1800, // 00B6 MOVE R19 R12 + 0x5C501A00, // 00B7 MOVE R20 R13 + 0x7C3C0A00, // 00B8 CALL R15 5 + 0x7C380200, // 00B9 CALL R14 1 + 0x70020000, // 00BA JMP #00BC + 0xB0080000, // 00BB RAISE 2 R0 R0 + 0x1C300D1C, // 00BC EQ R12 R6 K28 + 0x78320005, // 00BD JMPF R12 #00C4 + 0x20300F08, // 00BE NE R12 R7 K8 + 0x78320003, // 00BF JMPF R12 #00C4 + 0x60300001, // 00C0 GETGBL R12 G1 + 0x5834001D, // 00C1 LDCONST R13 K29 + 0x7C300200, // 00C2 CALL R12 1 + 0x80001800, // 00C3 RET 0 + 0x1C300D1C, // 00C4 EQ R12 R6 K28 + 0x78320005, // 00C5 JMPF R12 #00CC + 0x8C300106, // 00C6 GETMET R12 R0 K6 + 0x7C300200, // 00C7 CALL R12 1 + 0x8C30190F, // 00C8 GETMET R12 R12 K15 + 0x5838001C, // 00C9 LDCONST R14 K28 + 0x7C300400, // 00CA CALL R12 2 + 0x5C201800, // 00CB MOVE R8 R12 + 0x60300010, // 00CC GETGBL R12 G16 + 0x8C34031E, // 00CD GETMET R13 R1 K30 + 0x7C340200, // 00CE CALL R13 1 + 0x7C300200, // 00CF CALL R12 1 + 0xA8020004, // 00D0 EXBLK 0 #00D6 + 0x5C341800, // 00D1 MOVE R13 R12 + 0x7C340000, // 00D2 CALL R13 0 + 0x9438020D, // 00D3 GETIDX R14 R1 R13 + 0x90201A0E, // 00D4 SETMBR R8 R13 R14 + 0x7001FFFA, // 00D5 JMP #00D1 + 0x5830001F, // 00D6 LDCONST R12 K31 + 0xAC300200, // 00D7 CATCH R12 1 0 + 0xB0080000, // 00D8 RAISE 2 R0 R0 + 0x80000000, // 00D9 RET 0 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/be_mdns_module.c b/lib/libesp32/berry_tasmota/src/be_mdns_module.c new file mode 100644 index 000000000000..19bc1ac8434a --- /dev/null +++ b/lib/libesp32/berry_tasmota/src/be_mdns_module.c @@ -0,0 +1,45 @@ +/******************************************************************** + * Berry module `mdns` + * + * To use: `import mdns` + * + * MDNS support + *******************************************************************/ +#include "be_constobj.h" +#include "be_mapping.h" +#include "be_mem.h" + +#ifdef USE_DISCOVERY + +extern void m_mdns_start(struct bvm *vm, const char* hostname); +BE_FUNC_CTYPE_DECLARE(m_mdns_start, "", "@[s]") + +extern void m_mdns_stop(void); +BE_FUNC_CTYPE_DECLARE(m_mdns_stop, "", "") + +extern void m_mdns_set_hostname(struct bvm *vm, const char * hostname); +BE_FUNC_CTYPE_DECLARE(m_mdns_set_hostname, "", "@s") + +extern int m_mdns_add_service(struct bvm *vm); +extern int m_mdns_remove_service(struct bvm *vm); +extern int m_dns_add_subtype(struct bvm *vm); +extern int m_dns_add_hostname(struct bvm *vm); +extern int m_dns_find_service(struct bvm *vm); + +/* @const_object_info_begin +module mdns (scope: global) { + start, ctype_func(m_mdns_start) + stop, ctype_func(m_mdns_stop) + set_hostname, ctype_func(m_mdns_set_hostname) + add_service, func(m_mdns_add_service) + add_hostname, func(m_dns_add_hostname) + add_subtype, func(m_dns_add_subtype) + remove_service, func(m_mdns_remove_service) + + // querying + find_service, func(m_dns_find_service) +} +@const_object_info_end */ +#include "be_fixed_mdns.h" + +#endif // USE_DISCOVERY \ No newline at end of file diff --git a/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp b/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp deleted file mode 100644 index aa7629519908..000000000000 --- a/lib/libesp32/berry_tasmota/src/be_mdns_module.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/******************************************************************** - * Berry module `mdns` - * - * To use: `import mdns` - * - * MDNS support - *******************************************************************/ -#include "be_constobj.h" -#include "be_mapping.h" -#include "be_mem.h" - -#ifdef USE_DISCOVERY -#include "mdns.h" -#include -#include "IPAddress.h" - -// -// `mdsn.start([hostname:string]) -> nil` -// start or restart mdns, specify hostname or use tasmota.hostname() if none provided (default) -extern char* NetworkHostname(void); -static void m_mdns_start(struct bvm *vm, const char* hostname) { - esp_err_t err = mdns_init(); - if (err != ESP_OK) { - be_raisef(vm, "internal_error", "could not initialize mdns err=%i", err); - } - if (hostname == NULL) { - hostname = NetworkHostname(); // revert to default hostname if none is specified - } - err = mdns_hostname_set(hostname); - if (err != ESP_OK) { - be_raisef(vm, "internal_error", "could not set hostname err=%i", err); - } -} -BE_FUNC_CTYPE_DECLARE(m_mdns_start, "", "@[s]") - -// -// `msdn.stop() -> nil` -// free all mdns resources -static void m_mdns_stop(void) { - mdns_free(); -} -BE_FUNC_CTYPE_DECLARE(m_mdns_stop, "", "") - -// -// `mdns.set_hostname(hostname:string) -> nil` -// change the hostname -static void m_mdns_set_hostname(struct bvm *vm, const char * hostname) { - esp_err_t err = mdns_hostname_set(hostname); - if (err != ESP_OK) { - be_raisef(vm, "internal_error", "mdns set_hostname err=%i", err); - } -} -BE_FUNC_CTYPE_DECLARE(m_mdns_set_hostname, "", "@s") - -// -// `mdns.add_service(service:string, proto:string, port:int, txt:map [, instance:string, hostname:string]) -> nil` -// -// add a service declaration using the current hostname as instance name, and specify TXT fields as a `map` -// -// Test: -// import mdns mdns.add_service("_arduino","_tcp",1111, {"board":"tasmota", "tcp_check":"no", "ssh_upload":"no", "auth_upload":"no"}) -// -// import mdns mdns.add_service("_matterc","_udp", 5540, {"VP":"65521+32768", "SII":5000, "SAI":300, "T":1, "D":3840, "CM":1, "PH":33, "PI":""}) -static int32_t m_mdns_add_service(struct bvm *vm) { - int32_t top = be_top(vm); - if (top >= 3 && be_isstring(vm, 1) && be_isstring(vm, 2) && be_isint(vm, 3)) { - const char* service_type = be_tostring(vm, 1); - const char* proto = be_tostring(vm, 2); - uint16_t port = be_toint(vm, 3); - const char * instance = nullptr; - const char * hostname = nullptr; - if (top >= 5 && be_isstring(vm, 5)) { - instance = be_tostring(vm, 5); - } - if (top >= 6 && be_isstring(vm, 6)) { - hostname = be_tostring(vm, 6); - } - - mdns_txt_item_t * txt_items = NULL; - int32_t txt_num = 0; - if (top >= 4 && be_ismapinstance(vm, 4)) { - // parse txt map - be_getmember(vm, 4, ".p"); - int32_t map_len = be_data_size(vm, -1); - if (map_len > 0) { - uint32_t i= 0; - txt_items = (mdns_txt_item_t*) be_os_malloc(sizeof(mdns_txt_item_t) * map_len); - if (txt_items != NULL) { - be_pushiter(vm, -1); /* map iterator use 1 register */ - while (be_iter_hasnext(vm, -2) && i < map_len) { - be_iter_next(vm, -2); - const char* key = be_tostring(vm, -2); - const char* val = be_tostring(vm, -1); - size_t key_len = strlen(key)+1; - txt_items[i].key = (const char*)be_os_malloc(key_len); - if (txt_items[i].key) { strcpy((char*)txt_items[i].key, key); } - size_t val_len = strlen(val)+1; - txt_items[i].value = (const char*)be_os_malloc(val_len); - if (txt_items[i].value) { strcpy((char*)txt_items[i].value, val); } - be_pop(vm, 2); - i++; - } - txt_num = i; - } else { - txt_num = 0; // failed to allocate, pretend it's empty - } - be_pop(vm, 1); /* pop iterator */ - } - } - esp_err_t err; - if (hostname == nullptr) { - err = mdns_service_add(instance, service_type, proto, port, txt_items, txt_num); - } else { - err = mdns_service_add_for_host(instance, service_type, proto, hostname, port, txt_items, txt_num); - } - // free all allocated memory - if (txt_items != NULL) { - for (uint32_t i = 0; i < txt_num; i++) { - if (txt_items[i].key != NULL) { be_os_free((void*)txt_items[i].key); } - if (txt_items[i].value != NULL) { be_os_free((void*)txt_items[i].value); } - } - be_os_free(txt_items); - } - if (err != ESP_OK) { - be_raisef(vm, "internal_error", "mdns service_add err=%i", err); - } - be_return_nil(vm); - } - be_raise(vm, "value_error", "wrong or missing arguments"); -} - - -// -// `mdns.remove_service(service:string, proto:string [, instance:string, hostname:string]) -> nil` -// -// remove service from mDNS server with hostname. -// -// Test: -// import mdns mdns.remove_service("_arduino","_tcp") -// -// import mdns mdns.remove_service("_matterc","_udp") -static int32_t m_mdns_remove_service(struct bvm *vm) { - int32_t top = be_top(vm); - if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { - const char* service_type = be_tostring(vm, 1); - const char* proto = be_tostring(vm, 2); - const char * instance = nullptr; - const char * hostname = nullptr; - if (top >= 3 && be_isstring(vm, 3)) { - instance = be_tostring(vm, 3); - } - if (top >= 4 && be_isstring(vm, 4)) { - hostname = be_tostring(vm, 4); - } - - esp_err_t err; - if (hostname == nullptr) { - err = mdns_service_remove(service_type, proto); - } else { - err = mdns_service_remove_for_host(instance, service_type, proto, hostname); - } - if (err != ESP_OK) { - be_raisef(vm, "internal_error", "mdns service_remove err=%i", err); - } - be_return_nil(vm); - } - be_raise(vm, "value_error", "wrong or missing arguments"); -} - -// `mdns_service_subtype_add_for_host()` is only available in most recent esp-protocols version -// -// This alias makes sure that the compilation succeeds even if the function is not available -// -extern "C" esp_err_t __tasmota_mdns_service_subtype_add_for_host (const char *instance_name, const char *service_type, const char *proto, const char *hostname, const char *subtype) -{ return ESP_OK; } -extern "C" esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const char *service_type, const char *proto, const char *hostname, const char *subtype) __attribute__ ((weak, alias ("__tasmota_mdns_service_subtype_add_for_host"))); - -// -// `mdns.add_subtype(service:string, proto:string, instance:string, hostname:string, subtype:string) -> nil` -// -// add a subtype -// -static int32_t m_dns_add_subtype(struct bvm *vm) { - int32_t top = be_top(vm); - if (top >= 5 && be_isstring(vm, 1) && be_isstring(vm, 2) && be_isstring(vm, 3) && be_isstring(vm, 4) && be_isstring(vm, 5)) { - const char* service_type = be_tostring(vm, 1); - const char* proto = be_tostring(vm, 2); - const char* instance = be_tostring(vm, 3); - const char* hostname = be_tostring(vm, 4); - const char* subtype = be_tostring(vm, 5); - - esp_err_t err; - // Waiting for support of `mdns_service_subtype_add_for_host()` - err = mdns_service_subtype_add_for_host(instance, service_type, proto, hostname, subtype); - if (err != ESP_OK) { - be_raisef(vm, "internal_error", "mdns add_subtype err=%i", err); - } - be_return_nil(vm); - } - be_raise(vm, "value_error", "wrong or missing arguments"); -} - -// -// `mdns.add_hostname(hostname:string, ip:string [, ip:string]*) -> nil` -// -// add a delegate hostname -// -static int32_t m_dns_add_hostname(struct bvm *vm) { - int32_t top = be_top(vm); - if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { - mdns_ip_addr_t * head = nullptr; // head of the linked list of addresses - esp_err_t err = ESP_OK; // return status - - const char* hostname = be_tostring(vm, 1); - const char* ip_text = nullptr; - ip_addr_t a; - for (uint16_t i = 2; i <= top; i++) { - const char* ip_text = be_tostring(vm, i); - if (ip_text == nullptr || ip_text[0] == 0) { continue; } // ignore empty string - IPAddress ip; - if (!ip.fromString(ip_text)) { err = -1; break; } - - // allocate new slot - mdns_ip_addr_t *new_head = (mdns_ip_addr_t*) be_os_malloc(sizeof(mdns_ip_addr_t)); - if (new_head == nullptr) { err = -2; break; } - new_head->next = head; - head = new_head; - - // - ip_addr_t *ip_addr = (ip_addr_t*) ip; - head->addr.type = ip_addr->type; - if (ip_addr->type == ESP_IPADDR_TYPE_V6) { - memcpy(head->addr.u_addr.ip6.addr, ip_addr->u_addr.ip6.addr, 16); - } else { - head->addr.u_addr.ip4.addr = ip_addr->u_addr.ip4.addr; - } - } while (0); - - if (err == ESP_OK && head != nullptr) { - err = mdns_delegate_hostname_add(hostname, head); - } - - // deallocate all memory - while (head != nullptr) { - mdns_ip_addr_t * next = head->next; - be_os_free(head); - head = next; - } - - if (err == -1) { - be_raisef(vm, "value_error", "Invalid IP Address '%s'", ip_text); - } else if (err == -2) { - be_raise(vm, "memory_error", nullptr); - } else if (err != ESP_OK) { - be_raisef(vm, "value_error", "mdns_delegate_hostname_add err=%i", err); - } - be_return_nil(vm); - - } - be_raise(vm, "value_error", "wrong or missing arguments"); -} - -// -// `mdns.find_service(service:string, proto:string [timeout_ms:int(3000), max_responses:int(20)]) -> map` -// -static int32_t m_dns_find_service(struct bvm *vm) { - static const char * ip_protocol_str[] = {"v4", "v6", "max"}; - int32_t top = be_top(vm); - if (top >= 2 && be_isstring(vm, 1) && be_isstring(vm, 2)) { - const char* service_name = be_tostring(vm, 1); - const char* proto = be_tostring(vm, 2); - int32_t timeout_ms = 3000; - if (top >= 3 && be_isint(vm, 3)) { - timeout_ms = be_toint(vm, 3); - } - int32_t max_responses = 20; - if (top >= 4 && be_isint(vm, 4)) { - max_responses = be_toint(vm, 4); - } - - mdns_result_t * results = NULL; - esp_err_t err = mdns_query_ptr(service_name, proto, timeout_ms, max_responses, &results); - if (err != ESP_OK) { be_raisef(vm, "value_error", "mdns_query_ptr err=%i", err); } - if (results == NULL) { be_return_nil(vm); } - - mdns_result_t * r = results; - mdns_ip_addr_t * a = NULL; - be_newobject(vm, "list"); - while (r) { - be_newobject(vm, "map"); - be_map_insert_str(vm, "type", ip_protocol_str[r->ip_protocol]); - if (r->instance_name) { be_map_insert_str(vm, "instance", r->instance_name); } - if (r->hostname) { be_map_insert_str(vm, "hostname", r->hostname); } - // TXT - be_pushstring(vm, "txt"); - be_newobject(vm, "map"); - for (int32_t t=0; t < r->txt_count; t++){ - be_map_insert_str(vm, r->txt[t].key, r->txt[t].value); - } - // - be_pop(vm, 1); - be_data_insert(vm, -3); - be_pop(vm, 2); - // - - // IP addresses - be_pushstring(vm, "ip"); - be_newobject(vm, "list"); - // - for (a = r->addr; a != NULL; a = a->next) { - ip_addr_t ip_addr; - if (a->addr.type == IPADDR_TYPE_V6) { - ip_addr_copy_from_ip6(ip_addr, a->addr.u_addr.ip6); - } else if (a->addr.type == IPADDR_TYPE_V4) { - ip_addr_copy_from_ip4(ip_addr, a->addr.u_addr.ip4); - } else { - continue; - } - be_pushstring(vm, IPAddress(ip_addr).toString().c_str()); - be_data_push(vm, -2); - be_pop(vm, 1); - } - // - be_pop(vm, 1); - be_data_insert(vm, -3); - be_pop(vm, 2); - - be_pop(vm, 1); - be_data_push(vm, -2); - be_pop(vm, 1); - - r = r->next; - } - be_pop(vm, 1); // now list is on top - - mdns_query_results_free(results); - be_return(vm); - } - be_raise(vm, "value_error", "wrong or missing arguments"); -} - -/* @const_object_info_begin -module mdns (scope: global) { - start, ctype_func(m_mdns_start) - stop, ctype_func(m_mdns_stop) - set_hostname, ctype_func(m_mdns_set_hostname) - add_service, func(m_mdns_add_service) - add_hostname, func(m_dns_add_hostname) - add_subtype, func(m_dns_add_subtype) - remove_service, func(m_mdns_remove_service) - - // querying - find_service, func(m_dns_find_service) -} -@const_object_info_end */ -#include "be_fixed_mdns.h" - -#endif // USE_DISCOVERY \ No newline at end of file diff --git a/lib/libesp32/berry_tasmota/src/be_mqtt_lib.c b/lib/libesp32/berry_tasmota/src/be_mqtt_lib.c index c0237fc07d3f..b356dc619fbc 100644 --- a/lib/libesp32/berry_tasmota/src/be_mqtt_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_mqtt_lib.c @@ -25,7 +25,7 @@ class be_class_MQTT_ntv (scope: global, name: MQTT_ntv) { // mqtt module extern const bclass be_class_MQTT; -static int zigbee_init(bvm *vm) { +static int mqtt_init(bvm *vm) { be_pushntvclass(vm, &be_class_MQTT); be_call(vm, 0); be_return(vm); @@ -34,7 +34,7 @@ static int zigbee_init(bvm *vm) { #include "be_fixed_mqtt.h" /* @const_object_info_begin module mqtt (scope: global) { - init, func(zigbee_init) + init, func(mqtt_init) } @const_object_info_end */ diff --git a/lib/libesp32/berry_tasmota/src/be_path_tasmota_lib.c b/lib/libesp32/berry_tasmota/src/be_path_tasmota_lib.c index cfa7e829be15..1822abcc11b9 100644 --- a/lib/libesp32/berry_tasmota/src/be_path_tasmota_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_path_tasmota_lib.c @@ -18,45 +18,32 @@ #include "be_sys.h" #include -extern int m_path_listdir(bvm *vm); +// provides MPATH_ constants +#include "be_port.h" -static int m_path_exists(bvm *vm) -{ - const char *path = NULL; - if (be_top(vm) >= 1 && be_isstring(vm, 1)) { - path = be_tostring(vm, 1); - be_pushbool(vm, be_isexist(path)); - } else { - be_pushbool(vm, bfalse); - } - be_return(vm); -} -extern time_t be_last_modified(void *hfile); +// from be_port.cpp, becasue it uses c++ +extern int _m_path_action(bvm *vm, int8_t action); -static int m_path_last_modified(bvm *vm) -{ - if (be_top(vm) >= 1 && be_isstring(vm, 1)) { - const char *path = be_tostring(vm, 1); - void * f = be_fopen(path, "r"); - if (f) { - be_pushint(vm, be_last_modified(f)); - be_fclose(f); - be_return(vm); - } - } - be_return_nil(vm); +static int m_path_listdir(bvm *vm){ + return _m_path_action(vm, MPATH_LISTDIR); } - -static int m_path_remove(bvm *vm) -{ - const char *path = NULL; - if (be_top(vm) >= 1 && be_isstring(vm, 1)) { - path = be_tostring(vm, 1); - be_pushbool(vm, be_unlink(path)); - } else { - be_pushbool(vm, bfalse); - } - be_return(vm); +static int m_path_isdir(bvm *vm){ + return _m_path_action(vm, MPATH_ISDIR); +} +static int m_path_mkdir(bvm *vm) { + return _m_path_action(vm, MPATH_MKDIR); +} +static int m_path_rmdir(bvm *vm) { + return _m_path_action(vm, MPATH_RMDIR); +} +static int m_path_exists(bvm *vm) { + return _m_path_action(vm, MPATH_EXISTS); +} +static int m_path_last_modified(bvm *vm){ + return _m_path_action(vm, MPATH_MODIFIED); +} +static int m_path_remove(bvm *vm){ + return _m_path_action(vm, MPATH_REMOVE); } extern int be_format_fs(void); @@ -77,8 +64,11 @@ module path (scope: global, file: tasmota_path) { exists, func(m_path_exists) last_modified, func(m_path_last_modified) listdir, func(m_path_listdir) + isdir, func(m_path_isdir) remove, func(m_path_remove) format, func(m_path_format) + mkdir, func(m_path_mkdir) + rmdir, func(m_path_rmdir) } @const_object_info_end */ #include "be_fixed_tasmota_path.h" diff --git a/lib/libesp32/berry_tasmota/src/be_port.cpp b/lib/libesp32/berry_tasmota/src/be_port.cpp index 871885252289..647c94269cd9 100644 --- a/lib/libesp32/berry_tasmota/src/be_port.cpp +++ b/lib/libesp32/berry_tasmota/src/be_port.cpp @@ -98,36 +98,106 @@ BERRY_API void be_writebuffer(const char *buffer, size_t length) // be_fwrite(stdout, buffer, length); } - +// provides MPATH_ constants +#include "be_port.h" extern "C" { - int m_path_listdir(bvm *vm) - { + // this combined action is called from be_path_tasmota_lib.c + // by using a single function, we save >200 bytes of flash + // by reducing code repetition. + int _m_path_action(bvm *vm, int8_t action){ #ifdef USE_UFILESYS + // if this changes to not -1, we push it as a bool + int res = -1; + // this tells us to return the vm, not nil + int returnit = 0; + + // comment out if nil return is OK to save some flash + switch (action){ + case MPATH_EXISTS: + case MPATH_REMOVE: + res = 0; + break; + } + if (be_top(vm) >= 1 && be_isstring(vm, 1)) { const char *path = be_tostring(vm, 1); - be_newobject(vm, "list"); - - File dir = ffsp->open(path, "r"); - if (dir) { - dir.rewindDirectory(); - while (1) { - File entry = dir.openNextFile(); - if (!entry) { + if (path != nullptr) { + switch (action){ + case MPATH_EXISTS: + res = be_isexist(path); break; - } - const char * fn = entry.name(); - if (strcmp(fn, ".") && strcmp(fn, "..")) { - be_pushstring(vm, fn); - be_data_push(vm, -2); - be_pop(vm, 1); - } + case MPATH_REMOVE: + res = be_unlink(path); + break; + case MPATH_RMDIR: + res = zip_ufsp.rmdir(path); + break; + case MPATH_MKDIR: + res = zip_ufsp.mkdir(path); + break; + case MPATH_LISTDIR: + be_newobject(vm, "list"); // add our list object and fall through + returnit = 1; + case MPATH_ISDIR: + case MPATH_MODIFIED: { + //isdir needs to open the file, listdir does not + + // we use be_fopen because it pre-pends with '/'. + // without this TAS fails to find stuff at boot... + File *dir = (File *)be_fopen(path, "r"); + if (dir) { + String fpath; + String fname; + switch (action){ + case MPATH_LISTDIR: + dir->seekDir(0); + fpath = dir->getNextFileName(); + while (fpath.length() != 0) { + fname = fpath.substring(fpath.lastIndexOf("/") + 1); + const char * fn = fname.c_str(); + be_pushstring(vm, fn); + be_data_push(vm, -2); + be_pop(vm, 1); + fpath = dir->getNextFileName(); + } + break; + case MPATH_ISDIR: + // push bool belowthe only one to push an int, so do it here. + res = dir->isDirectory(); + break; + case MPATH_MODIFIED: + // the only one to push an int, so do it here. + be_pushint(vm, dir->getLastWrite()); + returnit = 1; + break; + } + be_fclose(dir); + } + } break; + } + // these + switch (action){ + case MPATH_LISTDIR: + // if it was list, pop always + be_pop(vm, 1); + break; } - } - be_pop(vm, 1); - be_return(vm); + } // invalid filename -> nil return + } // not a string, or no arg -> nil return unless see below + + // if we get here, and it was exists or remove, return false always + // i.e. it's false for no filename or null filename. + // if it was a boolean result + if (res != -1){ + be_pushbool(vm, res); + returnit = 1; } + if (returnit){ + be_return(vm); + } + #endif // USE_UFILESYS be_return_nil(vm); } @@ -161,6 +231,7 @@ void* be_fopen(const char *filename, const char *modes) return nullptr; // return fopen(filename, modes); } + #endif // USE_UFILESYS diff --git a/lib/libesp32/berry_tasmota/src/be_tasmota_lib.c b/lib/libesp32/berry_tasmota/src/be_tasmota_lib.c index 8b64ce03b78c..31c7ffe3de2a 100644 --- a/lib/libesp32/berry_tasmota/src/be_tasmota_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_tasmota_lib.c @@ -21,6 +21,7 @@ extern int l_getoption(bvm *vm); extern int l_millis(bvm *vm); extern int l_timereached(bvm *vm); extern int l_rtc(bvm *vm); +extern int l_rtc_utc(bvm *vm); extern int l_time_dump(bvm *vm); extern int l_strftime(bvm *vm); extern int l_strptime(bvm *vm); @@ -33,6 +34,7 @@ extern int l_delay(bvm *vm); extern int l_delay_microseconds(bvm *vm); extern int l_scaleuint(bvm *vm); extern int l_logInfo(bvm *vm); +extern int l_loglevel(bvm *vm); extern int l_save(bvm *vm); extern int t_random_byte(bvm *vm); extern int l_locale(bvm *vm); @@ -99,6 +101,7 @@ class be_class_tasmota (scope: global, name: Tasmota) { millis, func(l_millis) time_reached, func(l_timereached) rtc, func(l_rtc) + rtc_utc, func(l_rtc_utc) time_dump, func(l_time_dump) strftime, func(l_strftime) strptime, func(l_strptime) @@ -109,8 +112,9 @@ class be_class_tasmota (scope: global, name: Tasmota) { yield, func(l_yield) delay, func(l_delay) delay_microseconds, func(l_delay_microseconds) - scale_uint, func(l_scaleuint) + scale_uint, static_func(l_scaleuint) log, func(l_logInfo) + loglevel, func(l_loglevel) save, func(l_save) locale, func(l_locale) @@ -141,6 +145,7 @@ class be_class_tasmota (scope: global, name: Tasmota) { _find_op, func(tasm_find_op) // new C version for finding a rule operator _apply_str_op, func(tasm_apply_str_op) find_key_i, closure(Tasmota_find_key_i_closure) + find_list_i, closure(Tasmota_find_list_i_closure) find_op, closure(Tasmota_find_op_closure) add_rule, closure(Tasmota_add_rule_closure) remove_rule, closure(Tasmota_remove_rule_closure) diff --git a/lib/libesp32/berry_tasmota/src/be_tasmota_log_reader_class.cpp b/lib/libesp32/berry_tasmota/src/be_tasmota_log_reader_class.c similarity index 79% rename from lib/libesp32/berry_tasmota/src/be_tasmota_log_reader_class.cpp rename to lib/libesp32/berry_tasmota/src/be_tasmota_log_reader_class.c index 7f9ac60d8c7a..13277fbe2c23 100644 --- a/lib/libesp32/berry_tasmota/src/be_tasmota_log_reader_class.cpp +++ b/lib/libesp32/berry_tasmota/src/be_tasmota_log_reader_class.c @@ -10,11 +10,6 @@ extern char* tlr_get_log(uint32_t* idx, int32_t log_level); BE_FUNC_CTYPE_DECLAR #include "be_fixed_be_class_tasmota_log_reader.h" -extern "C" void be_load_tasmota_log_reader_class(bvm *vm) { - be_pushntvclass(vm, &be_class_tasmota_log_reader); - be_setglobal(vm, "tasmota_log_reader"); - be_pop(vm, 1); -} /* @const_object_info_begin class be_class_tasmota_log_reader (scope: global, name: tasmota_log_reader) { diff --git a/lib/libesp32/berry_tasmota/src/be_udp_lib.c b/lib/libesp32/berry_tasmota/src/be_udp_lib.c new file mode 100644 index 000000000000..e49dc5e48a6f --- /dev/null +++ b/lib/libesp32/berry_tasmota/src/be_udp_lib.c @@ -0,0 +1,57 @@ +/******************************************************************** + * UDP lib + * + * To use: `d = udp()` + * + *******************************************************************/ +#include "be_constobj.h" +#include "be_mapping.h" + +#ifdef USE_WEBCLIENT + +extern int be_udp_read(struct bvm *vm); + +extern void *be_udp_init_ntv(void); +BE_FUNC_CTYPE_DECLARE(be_udp_init_ntv, "+.p", "") + +extern void *be_udp_deinit_ntv(void *udp); +BE_FUNC_CTYPE_DECLARE(be_udp_deinit_ntv, "=.p", "") + +extern int32_t be_udp_begin_ntv(void *udp, const char *host, int32_t port); +BE_FUNC_CTYPE_DECLARE(be_udp_begin_ntv, "b", ".si") + +extern void be_udp_stop_ntv(void *udp); +BE_FUNC_CTYPE_DECLARE(be_udp_stop_ntv, "", ".") + +extern int32_t be_udp_begin_mcast_ntv(void *udp, const char *host, int32_t port); +BE_FUNC_CTYPE_DECLARE(be_udp_begin_mcast_ntv, "b", ".si") + +extern int32_t be_udp_send_ntv(void *udp, const char *host, int32_t port, const uint8_t* buf, int32_t len); +BE_FUNC_CTYPE_DECLARE(be_udp_send_ntv, "b", ".si(bytes)~") + +extern int32_t be_udp_send_mcast_ntv(void *udp, const uint8_t* buf, int32_t len); +BE_FUNC_CTYPE_DECLARE(be_udp_send_mcast_ntv, "b", ".(bytes)~") + +#include "be_mapping.h" +#include "be_fixed_be_class_udp.h" + +/* @const_object_info_begin + +class be_class_udp (scope: global, name: udp) { + .p, var + remote_ip, var + remote_port, var + init, ctype_func(be_udp_init_ntv) + deinit, ctype_func(be_udp_deinit_ntv) + + send, ctype_func(be_udp_send_ntv) + send_multicast, ctype_func(be_udp_send_mcast_ntv) + + begin, ctype_func(be_udp_begin_ntv) + begin_multicast, ctype_func(be_udp_begin_mcast_ntv) + read, func(be_udp_read) + close, ctype_func(be_udp_stop_ntv) +} +@const_object_info_end */ + +#endif // USE_WEBCLIENT diff --git a/lib/libesp32/berry_tasmota/src/be_unishox_lib.c b/lib/libesp32/berry_tasmota/src/be_unishox_lib.c new file mode 100644 index 000000000000..60161dd81c34 --- /dev/null +++ b/lib/libesp32/berry_tasmota/src/be_unishox_lib.c @@ -0,0 +1,24 @@ +/******************************************************************** + * Berry module `unishox` + * + * To use: `import unishox` + * + * Allows to respond to HTTP request + *******************************************************************/ + +#ifdef USE_UNISHOX_COMPRESSION + +#include "be_constobj.h" + +extern int be_ntv_unishox_compress(bvm *vm); +extern int be_ntv_unishox_decompress(bvm *vm); + +/* @const_object_info_begin +module unishox (scope: global) { + decompress, func(be_ntv_unishox_decompress) + compress, func(be_ntv_unishox_compress) +} +@const_object_info_end */ +#include "be_fixed_unishox.h" + +#endif // USE_UNISHOX_COMPRESSION diff --git a/lib/libesp32/berry_tasmota/src/be_unishox_lib.cpp b/lib/libesp32/berry_tasmota/src/be_unishox_lib.cpp deleted file mode 100644 index af431798781a..000000000000 --- a/lib/libesp32/berry_tasmota/src/be_unishox_lib.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************** - * Berry module `unishox` - * - * To use: `import unishox` - * - * Allows to respond to HTTP request - *******************************************************************/ - -#ifdef USE_UNISHOX_COMPRESSION - -#include "be_constobj.h" -#include "be_mapping.h" -#include -#include "unishox.h" - -extern Unishox compressor; - -/*********************************************************************************************\ - * Native functions mapped to Berry functions - * - * import unishox - * - * -\*********************************************************************************************/ -static int be_ntv_unishox_compress(bvm *vm) { - int32_t argc = be_top(vm); // Get the number of arguments - if (argc == 1 && be_isstring(vm, 1)) { - const char * s = be_tostring(vm, 1); - // do a dry-run to know the compressed size - int32_t compressed_size = compressor.unishox_compress(s, strlen(s), (char*) nullptr, 0); - if (compressed_size < 0) { - be_raise(vm, "internal_error", nullptr); - } - void * buf = be_pushbytes(vm, NULL, compressed_size); - if (compressed_size > 0) { - int32_t ret = compressor.unishox_compress(s, strlen(s), (char*) buf, compressed_size+5); // We expand by 4 the buffer size to avoid an error, but we are sure it will not overflow (see unishox implementation) - if (ret < 0 || ret != compressed_size) { - be_raisef(vm, "internal_error", "unishox size=%i ret=%i", compressed_size, ret); - } - } - be_return(vm); - } - be_raise(vm, "type_error", nullptr); -} - -static int be_ntv_unishox_decompress(bvm *vm) { - int32_t argc = be_top(vm); // Get the number of arguments - if (argc == 1 && be_isbytes(vm, 1)) { - size_t len; - const void * buf = be_tobytes(vm, 1, &len); - if (len == 0) { - be_pushstring(vm, ""); - } else { - int32_t decomp_size = compressor.unishox_decompress((const char*)buf, len, (char*) nullptr, 0); - if (decomp_size < 0) { - be_raise(vm, "internal_error", nullptr); - } - if (decomp_size == 0) { - be_pushstring(vm, ""); - } else { - void * buf_out = be_pushbuffer(vm, decomp_size); - int32_t ret = compressor.unishox_decompress((const char*)buf, len, (char*) buf_out, decomp_size); - if (ret < 0 || ret != decomp_size) { - be_raisef(vm, "internal_error", "unishox size=%i ret=%i", decomp_size, ret); - } - be_pushnstring(vm, (const char*) buf_out, decomp_size); - } - } - be_return(vm); - } - be_raise(vm, "type_error", nullptr); -} - - -/* @const_object_info_begin -module unishox (scope: global) { - decompress, func(be_ntv_unishox_decompress) - compress, func(be_ntv_unishox_compress) -} -@const_object_info_end */ -#include "be_fixed_unishox.h" - -#endif // USE_UNISHOX_COMPRESSION diff --git a/lib/libesp32/berry_tasmota/src/be_webclient_lib.c b/lib/libesp32/berry_tasmota/src/be_webclient_lib.c index a5c888d012ae..c49d189ecfe5 100644 --- a/lib/libesp32/berry_tasmota/src/be_webclient_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_webclient_lib.c @@ -30,6 +30,7 @@ extern int wc_getstring(bvm *vm); extern int wc_writefile(bvm *vm); extern int wc_writeflash(bvm *vm); extern int wc_getsize(bvm *vm); +extern int wc_getbytes(bvm *vm); #include "be_fixed_be_class_webclient.h" @@ -45,7 +46,7 @@ class be_class_webclient (scope: global, name: webclient) { .w, var init, func(wc_init) deinit, func(wc_deinit) - url_encode, func(wc_urlencode) + url_encode, static_func(wc_urlencode) begin, func(wc_begin) set_timeouts, func(wc_set_timeouts) @@ -68,6 +69,7 @@ class be_class_webclient (scope: global, name: webclient) { write_file, func(wc_writefile) write_flash, func(wc_writeflash) get_size, func(wc_getsize) + get_bytes, func(wc_getbytes) } @const_object_info_end */ diff --git a/lib/libesp32/berry_tasmota/src/be_webserver_lib.c b/lib/libesp32/berry_tasmota/src/be_webserver_lib.c index 0cdf4ede0e5e..541233893467 100644 --- a/lib/libesp32/berry_tasmota/src/be_webserver_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_webserver_lib.c @@ -9,6 +9,9 @@ #ifdef USE_WEBSERVER +#include "be_exec.h" +#include "be_vm.h" + extern int w_webserver_member(bvm *vm); extern int w_webserver_on(bvm *vm); extern int w_webserver_state(bvm *vm); @@ -32,6 +35,107 @@ extern int w_webserver_arg_name(bvm *vm); extern int w_webserver_has_arg(bvm *vm); +// To allow a full restart of the Berry VM, we need to supplement the webserver Request Handler +// model from Arduino framework. +// We use our own list of callbacks + +#define WEBSERVER_REQ_HANDLER_HOOK_MAX 16 // max number of callbacks, each callback requires a distinct address +typedef struct be_webserver_callback_hook_t { + bvm *vm; // make sure we are using the same VM + bvalue f; // the Berry function to call +} be_webserver_callback_hook_t; + +static be_webserver_callback_hook_t be_webserver_cb_hooks[WEBSERVER_REQ_HANDLER_HOOK_MAX]; + +static void be_call_webserver_hook_cb(int32_t num); +typedef void (*berry_webserver_cb_t)(void); +#define WEBSERVER_HOOK_CB(n) void berry_webserver_cb_##n(void) { be_call_webserver_hook_cb(n); } +// list the callbacks +WEBSERVER_HOOK_CB(0); +WEBSERVER_HOOK_CB(1); +WEBSERVER_HOOK_CB(2); +WEBSERVER_HOOK_CB(3); +WEBSERVER_HOOK_CB(4); +WEBSERVER_HOOK_CB(5); +WEBSERVER_HOOK_CB(6); +WEBSERVER_HOOK_CB(7); +WEBSERVER_HOOK_CB(8); +WEBSERVER_HOOK_CB(9); +WEBSERVER_HOOK_CB(10); +WEBSERVER_HOOK_CB(11); +WEBSERVER_HOOK_CB(12); +WEBSERVER_HOOK_CB(13); +WEBSERVER_HOOK_CB(14); +WEBSERVER_HOOK_CB(15); + +// array of callbacks +static const berry_webserver_cb_t berry_callback_array[WEBSERVER_REQ_HANDLER_HOOK_MAX] = { + berry_webserver_cb_0, + berry_webserver_cb_1, + berry_webserver_cb_2, + berry_webserver_cb_3, + berry_webserver_cb_4, + berry_webserver_cb_5, + berry_webserver_cb_6, + berry_webserver_cb_7, + berry_webserver_cb_8, + berry_webserver_cb_9, + berry_webserver_cb_10, + berry_webserver_cb_11, + berry_webserver_cb_12, + berry_webserver_cb_13, + berry_webserver_cb_14, + berry_webserver_cb_15, +}; + +// Return slot number +// -1 if no more available +berry_webserver_cb_t be_webserver_allocate_hook(bvm *vm, int32_t slot, bvalue *f) { + if (slot < 0 || slot >= WEBSERVER_REQ_HANDLER_HOOK_MAX) return NULL; // invalid call, avoid a crash + be_webserver_cb_hooks[slot].vm = vm; + be_webserver_cb_hooks[slot].f = *f; + return berry_callback_array[slot]; +} + +/*********************************************************************************************\ + * `be_webserver_cb_deinit`: + * Clean any callback for this VM +\*********************************************************************************************/ +void be_webserver_cb_deinit(bvm *vm) { + for (int32_t i = 0; i < WEBSERVER_REQ_HANDLER_HOOK_MAX; i++) { + if (be_webserver_cb_hooks[i].vm == vm) { + be_webserver_cb_hooks[i].vm = NULL; + } + } +} + +/*********************************************************************************************\ + * Callback structures + * +\*********************************************************************************************/ +void be_call_webserver_hook_cb(int32_t num) { + // call berry cb dispatcher + int32_t ret = 0; + // retrieve vm and function + if (num < 0 || num >= WEBSERVER_REQ_HANDLER_HOOK_MAX || be_webserver_cb_hooks[num].vm == NULL) return; // invalid call, avoid a crash + + bvm * vm = be_webserver_cb_hooks[num].vm; + bvalue *f = &be_webserver_cb_hooks[num].f; + + // push function (don't check type) + bvalue *top = be_incrtop(vm); + *top = *f; + + ret = be_pcall(vm, 0); // 4 arguments + if (ret != 0) { + if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_PCALL_ERROR); + be_pop(vm, be_top(vm)); // clear Berry stack + return; + } + be_pop(vm, 1); // remove result + return; +} + /* @const_object_info_begin module webserver (scope: global) { member, func(w_webserver_member) diff --git a/lib/libesp32/berry_tasmota/src/be_zigbee_zcl_attributes.c b/lib/libesp32/berry_tasmota/src/be_zigbee_zcl_attribute.c similarity index 100% rename from lib/libesp32/berry_tasmota/src/be_zigbee_zcl_attributes.c rename to lib/libesp32/berry_tasmota/src/be_zigbee_zcl_attribute.c diff --git a/lib/libesp32/berry_tasmota/src/embedded/autoconf_module.be b/lib/libesp32/berry_tasmota/src/embedded/autoconf_module.be index 42d57330605e..9620d358ac1e 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/autoconf_module.be +++ b/lib/libesp32/berry_tasmota/src/embedded/autoconf_module.be @@ -23,7 +23,7 @@ autoconf_module.init = def (m) if string.find(dir[i], ".autoconf") > 0 # does the file contain '*.autoconf', >0 to skip `.autoconf` if entry != nil # we have multiple configuration files, not allowed - tasmota.log(string.format("CFG: multiple autoconf files found, aborting ('%s' + '%s')", entry, dir[i]), 2) + tasmota.log(format("CFG: multiple autoconf files found, aborting ('%s' + '%s')", entry, dir[i]), 2) self._error = true return nil end @@ -88,24 +88,23 @@ autoconf_module.init = def (m) # Load templates from Github ##################################################################################################### def load_templates() - import string import json try - var url = string.format("https://raw.githubusercontent.com/tasmota/autoconf/main/%s_manifest.json", tasmota.arch()) - tasmota.log(string.format("CFG: loading '%s'", url), 3) + var url = format("https://raw.githubusercontent.com/tasmota/autoconf/main/%s_manifest.json", tasmota.arch()) + tasmota.log(format("CFG: loading '%s'", url), 3) # load the template var cl = webclient() cl.begin(url) var r = cl.GET() if r != 200 - tasmota.log(string.format("CFG: return_code=%i", r), 2) + tasmota.log(format("CFG: return_code=%i", r), 2) return nil end var s = cl.get_string() cl.close() # convert to json var j = json.load(s) - tasmota.log(string.format("CFG: loaded '%s'", str(j)), 3) + tasmota.log(format("CFG: loaded '%s'", str(j)), 3) var t = j.find("files") if isinstance(t, list) @@ -114,7 +113,7 @@ autoconf_module.init = def (m) return nil except .. as e, m - tasmota.log(string.format("CFG: exception '%s' - '%s'", e, m), 2) + tasmota.log(format("CFG: exception '%s' - '%s'", e, m), 2) return nil end end @@ -143,8 +142,8 @@ autoconf_module.init = def (m) var cur_module_display = cur_module ? string.tr(self.get_current_module_name(), "_", " ") : self._error ? "<Error: apply new or remove>" : "<None>" webserver.content_send("
") - webserver.content_send(string.format(" Current auto-configuration")) - webserver.content_send(string.format("

Current configuration:

%s

", cur_module_display)) + webserver.content_send(format(" Current auto-configuration")) + webserver.content_send(format("

Current configuration:

%s

", cur_module_display)) if cur_module # add button to reapply template @@ -156,7 +155,7 @@ autoconf_module.init = def (m) webserver.content_send("

") webserver.content_send("
") - webserver.content_send(string.format(" Select new auto-configuration")) + webserver.content_send(format(" Select new auto-configuration")) webserver.content_send("

") @@ -166,13 +165,13 @@ autoconf_module.init = def (m) var templates = self.load_templates() webserver.content_send("") for t:templates - webserver.content_send(string.format("", t, string.tr(t, "_", " "))) + webserver.content_send(format("", t, string.tr(t, "_", " "))) end webserver.content_send("

") webserver.content_send("") - # webserver.content_send(string.format("", ota_num)) + # webserver.content_send(format("", ota_num)) webserver.content_send("

") @@ -189,7 +188,6 @@ autoconf_module.init = def (m) # This HTTP POST manager handles the submitted web form data def page_autoconf_ctl() import webserver - import string import path if !webserver.check_privileged_access() return nil end @@ -211,16 +209,16 @@ autoconf_module.init = def (m) var arch_name = webserver.arg("zip") if arch_name != "reset" - var url = string.format("https://raw.githubusercontent.com/tasmota/autoconf/main/%s/%s.autoconf", tasmota.arch(), arch_name) - tasmota.log(string.format("CFG: downloading '%s'", url), 2); + var url = format("https://raw.githubusercontent.com/tasmota/autoconf/main/%s/%s.autoconf", tasmota.arch(), arch_name) + tasmota.log(format("CFG: downloading '%s'", url), 2); - var local_file = string.format("%s.autoconf", arch_name) + var local_file = format("%s.autoconf", arch_name) # download file and write directly to file system var cl = webclient() cl.begin(url) var r = cl.GET() - if r != 200 raise "connection_error", string.format("return code=%i", r) end + if r != 200 raise "connection_error", format("return code=%i", r) end cl.write_file(local_file) cl.close() end @@ -234,12 +232,12 @@ autoconf_module.init = def (m) raise "value_error", "Unknown command" end except .. as e, m - print(string.format("CFG: Exception> '%s' - %s", e, m)) + print(format("CFG: Exception> '%s' - %s", e, m)) #- display error page -# webserver.content_start("Parameter error") #- title of the web page -# webserver.content_send_style() #- send standard Tasmota styles -# - webserver.content_send(string.format("

Exception:
'%s'
%s

", e, m)) + webserver.content_send(format("

Exception:
'%s'
%s

", e, m)) webserver.content_button(webserver.BUTTON_CONFIGURATION) #- button back to management page -# webserver.content_stop() #- end of web page -# @@ -268,7 +266,7 @@ autoconf_module.init = def (m) var fname = dir[i] if string.find(fname, ".autoconf") > 0 # does the file contain '*.autoconf' path.remove(fname) - print(string.format("CFG: removed file '%s'", fname)) + print(format("CFG: removed file '%s'", fname)) end i += 1 end @@ -300,7 +298,6 @@ autoconf_module.init = def (m) # load and run `.bat` file as Tasmota commands ##################################################################################################### def run_bat(fname) # read a '*.bat' file and run each command - import string var f try f = open(fname, "r") # open file in read-only mode, it is expected to exist @@ -315,7 +312,7 @@ autoconf_module.init = def (m) end f.close() # close, we don't expect exception with read-only, could be added later though except .. as e, m - tasmota.log(string.format('CFG: could not run %s (%s - %s)', fname, e, m), 1) + tasmota.log(format('CFG: could not run %s (%s - %s)', fname, e, m), 1) if f != nil f.close() end end end @@ -368,7 +365,7 @@ autoconf_module.init = def (m) reboot = true tasmota.log("CFG: 'display.ini' extracted, restarting", 2) except .. as e, m - print(string.format("CFG: could not copy 'display.ini' (%s - %s)'", e, m)) + print(format("CFG: could not copy 'display.ini' (%s - %s)'", e, m)) if f != nil f.close() end if f_out != nil f_out.close() end end diff --git a/lib/libesp32/berry_tasmota/src/embedded/hue_bridge.be b/lib/libesp32/berry_tasmota/src/embedded/hue_bridge.be index 740fd169de9a..a950c8570f8a 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/hue_bridge.be +++ b/lib/libesp32/berry_tasmota/src/embedded/hue_bridge.be @@ -60,7 +60,6 @@ hue_bridge.init = def (m) def discover() import hue_ntv import json - import string var fragments = [] # store json elements for id: self.lights.keys() diff --git a/lib/libesp32/berry_tasmota/src/embedded/i2c_axp192.be b/lib/libesp32/berry_tasmota/src/embedded/i2c_axp192.be index ccf0ea770da4..56ce22147a88 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/i2c_axp192.be +++ b/lib/libesp32/berry_tasmota/src/embedded/i2c_axp192.be @@ -1,8 +1,9 @@ #------------------------------------------------------------- - Generic driver for AXP192 - solidified -------------------------------------------------------------# - - #@ solidify:AXP192 +class I2C_Driver end # for solidification + +#@ solidify:AXP192 class AXP192 : I2C_Driver def init() super(self, I2C_Driver).init("AXP192", 0x34) @@ -103,7 +104,7 @@ class AXP192 : I2C_Driver # Set voltage on DC-DC1/2/3 # dcdc: 1/2/3 (warning some C libs start at 0) - # voltage: + # voltage: def set_dc_voltage(dcdc, voltage) if dcdc < 1 || dcdc > 3 return end var v @@ -158,8 +159,7 @@ class AXP192 : I2C_Driver #- display sensor value in the web UI -# def web_sensor() if !self.wire return nil end #- exit if not initialized -# - import string - var msg = string.format( + var msg = format( "{s}VBus Voltage{m}%.3f V{e}".. "{s}VBus Current{m}%.1f mA{e}".. "{s}Batt Voltage{m}%.3f V{e}".. @@ -177,8 +177,7 @@ class AXP192 : I2C_Driver #- add sensor value to teleperiod -# def json_append() if !self.wire return nil end #- exit if not initialized -# - import string - var msg = string.format(",\"AXP192\":{\"VBusVoltage\":%.3f,\"VBusCurrent\":%.1f,\"BattVoltage\":%.3f,\"BattCurrent\":%.1f,\"Temperature\":%.1f}", + var msg = format(",\"AXP192\":{\"VBusVoltage\":%.3f,\"VBusCurrent\":%.1f,\"BattVoltage\":%.3f,\"BattCurrent\":%.1f,\"Temperature\":%.1f}", self.get_vbus_voltage(), self.get_vbus_voltage(), self.get_bat_voltage(), self.get_bat_current(), #self.get_bat_power(), diff --git a/lib/libesp32/berry_tasmota/src/embedded/i2c_axp202.be b/lib/libesp32/berry_tasmota/src/embedded/i2c_axp202.be index f2176dfd3929..e6b6f6d80a5f 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/i2c_axp202.be +++ b/lib/libesp32/berry_tasmota/src/embedded/i2c_axp202.be @@ -1,8 +1,10 @@ #------------------------------------------------------------- - Generic driver for AXP202 - solidified -------------------------------------------------------------# +class I2C_Driver end # for solidification + #@ solidify:AXP202 - class AXP202 : I2C_Driver +class AXP202 : I2C_Driver def init() super(self, I2C_Driver).init("AXP202", 0x35) end @@ -107,7 +109,7 @@ # Set voltage on DC-DC 2/3 # dcdc: 2/3 (warning some C libs start at 0) - # voltage: + # voltage: def set_dc_voltage(dcdc, voltage) if dcdc < 2 || dcdc > 3 return end var v @@ -161,8 +163,7 @@ # #- display sensor value in the web UI -# # def web_sensor() # if !self.wire return nil end #- exit if not initialized -# -# import string -# var msg = string.format( +# var msg = format( # "{s}VBus Voltage{m}%.3f V{e}".. # "{s}VBus Current{m}%.1f mA{e}".. # "{s}Batt Voltage{m}%.3f V{e}".. @@ -180,11 +181,10 @@ # #- add sensor value to teleperiod -# # def json_append() # if !self.wire return nil end #- exit if not initialized -# -# # import string # # var ax = int(self.accel[0] * 1000) # # var ay = int(self.accel[1] * 1000) # # var az = int(self.accel[2] * 1000) -# # var msg = string.format(",\"MPU6886\":{\"AX\":%i,\"AY\":%i,\"AZ\":%i,\"GX\":%i,\"GY\":%i,\"GZ\":%i}", +# # var msg = format(",\"MPU6886\":{\"AX\":%i,\"AY\":%i,\"AZ\":%i,\"GX\":%i,\"GY\":%i,\"GZ\":%i}", # # ax, ay, az, self.gyro[0], self.gyro[1], self.gyro[2]) # # tasmota.response_append(msg) # end diff --git a/lib/libesp32/berry_tasmota/src/embedded/lv_tasmota_widgets.be b/lib/libesp32/berry_tasmota/src/embedded/lv_tasmota_widgets.be index d4bd2d51ef95..7c65815e530c 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/lv_tasmota_widgets.be +++ b/lib/libesp32/berry_tasmota/src/embedded/lv_tasmota_widgets.be @@ -37,9 +37,8 @@ class lv_clock: lv_label end def set_time(hour, minute, sec) - import string if hour != self.hour || minute != self.minute || sec != self.sec - var txt = string.format("%02d%s%02d", hour, sec % 2 ? ":" : " ", minute) + var txt = format("%02d%s%02d", hour, sec % 2 ? ":" : " ", minute) self.hour = hour self.minute = minute self.sec = sec diff --git a/lib/libesp32/berry_tasmota/src/embedded/mqtt.be b/lib/libesp32/berry_tasmota/src/embedded/mqtt.be index 07d42e86f5b6..5d64ff8b0caf 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/mqtt.be +++ b/lib/libesp32/berry_tasmota/src/embedded/mqtt.be @@ -46,8 +46,7 @@ class MQTT : MQTT_ntv end def tostring() - import string - return string.format("", classname(self), self.fulltopic) + return format("", classname(self), self.fulltopic) end def mqtt_data(topic, idx, payload_s, payload_b) diff --git a/lib/libesp32/berry_tasmota/src/embedded/partition_core.be b/lib/libesp32/berry_tasmota/src/embedded/partition_core.be index b80f23ca7d44..08736292c421 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/partition_core.be +++ b/lib/libesp32/berry_tasmota/src/embedded/partition_core.be @@ -76,8 +76,7 @@ class Partition_info # elif magic == 0xEBEB #- MD5 -# else - import string - raise "internal_error", string.format("invalid magic number %02X", magic) + raise "internal_error", format("invalid magic number %02X", magic) end end @@ -121,11 +120,11 @@ class Partition_info var seg_num = 0 while seg_num < seg_count - # print(string.format("Reading 0x%08X", seg_offset)) + # print(format("Reading 0x%08X", seg_offset)) var segment_header = flash.read(seg_offset - 8, 8) var seg_start_addr = segment_header.get(0, 4) var seg_size = segment_header.get(4,4) - # print(string.format("Segment %i: flash_offset=0x%08X start_addr=0x%08X sz=0x%08X", seg_num, seg_offset, seg_start_addr, seg_size)) + # print(format("Segment %i: flash_offset=0x%08X start_addr=0x%08X sz=0x%08X", seg_num, seg_offset, seg_start_addr, seg_size)) seg_offset += seg_size + 8 # add segment_length + sizeof(esp_image_segment_header_t) if seg_offset >= (addr + sz) return -1 end @@ -134,7 +133,7 @@ class Partition_info end var total_size = seg_offset - addr + 1 # add 1KB for safety - # print(string.format("Total size = %i KB", total_size/1024)) + # print(format("Total size = %i KB", total_size/1024)) return total_size except .. as e, m @@ -147,8 +146,7 @@ class Partition_info if self.type == 0 return "app" elif self.type == 1 return "data" end - import string - return string.format("0x%02X", self.type) + return format("0x%02X", self.type) end def subtype_to_string() @@ -169,22 +167,20 @@ class Partition_info elif self.subtype == 0x82 return "spiffs" end end - import string - return string.format("0x%02X", self.subtype) + return format("0x%02X", self.subtype) end # Human readable version of Partition information # this method is not included in the solidified version to save space, # it is included only in the optional application `tapp` version def tostring() - import string var type_s = self.type_to_string() var subtype_s = self.subtype_to_string() # reformat strings if type_s != "" type_s = " (" + type_s + ")" end if subtype_s != "" subtype_s = " (" + subtype_s + ")" end - return string.format("", + return format("", self.type, type_s, self.subtype, subtype_s, self.start, self.sz, @@ -304,8 +300,8 @@ class Partition_otadata #- load otadata from SPI Flash -# def load() import flash - var otadata0 = flash.read(0xE000, 32) - var otadata1 = flash.read(0xF000, 32) + var otadata0 = flash.read(self.offset, 32) + var otadata1 = flash.read(self.offset + 0x1000, 32) self.seq0 = otadata0.get(0, 4) #- ota_seq for block 1 -# self.seq1 = otadata1.get(0, 4) #- ota_seq for block 2 -# var valid0 = otadata0.get(28, 4) == self.crc32_ota_seq(self.seq0) #- is CRC32 valid? -# @@ -361,8 +357,7 @@ class Partition_otadata # Produce a human-readable representation of the object with relevant information def tostring() - import string - return string.format("", + return format("", self.active_otadata >= 0 ? "ota_" + str(self.active_otadata) : "factory", self.seq0, self.seq1, self.maxota) end @@ -552,7 +547,6 @@ class Partition var flash_definition_sector = self.get_flash_definition_sector() if (flash_size_k != flash_size_real_k) && flash_definition_sector != nil import flash - import string flash_size_k = flash_size_real_k # try to expand the flash size definition @@ -576,7 +570,7 @@ class Partition var old_def = flash_def[3] flash_def[3] = (flash_def[3] & 0x0F) | flash_size_code flash.write(flash_definition_sector, flash_def) - tasmota.log(string.format("UPL: changing flash definition from 0x02X to 0x%02X", old_def, flash_def[3]), 3) + tasmota.log(format("UPL: changing flash definition from 0x02X to 0x%02X", old_def, flash_def[3]), 3) else raise "internal_error", "wrong flash size "+str(flash_size_real_m) end @@ -586,12 +580,11 @@ class Partition # Called at first boot # Try to expand FS to max of flash size def resize_fs_to_max() - import string try var unallocated = self.get_unallocated_k() if unallocated <= 0 return nil end - tasmota.log(string.format("BRY: Trying to expand FS by %i kB", unallocated), 2) + tasmota.log(format("BRY: Trying to expand FS by %i kB", unallocated), 2) self.resize_max_flash_size_k() # resize if needed # since unallocated succeeded, we know the last slot is FS @@ -604,7 +597,7 @@ class Partition tasmota.global.restart_flag = 2 tasmota.log("BRY: Successfully resized FS, restarting", 2) except .. as e, m - tasmota.log(string.format("BRY: Exception> '%s' - %s", e, m), 2) + tasmota.log(format("BRY: Exception> '%s' - %s", e, m), 2) end end diff --git a/lib/libesp32/berry_tasmota/src/embedded/persist.be b/lib/libesp32/berry_tasmota/src/embedded/persist.be index 8fc32a8e6182..901b7e2d5618 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/persist.be +++ b/lib/libesp32/berry_tasmota/src/embedded/persist.be @@ -10,153 +10,155 @@ #@ solidify:persist_module var persist_module = module("persist") -persist_module.init = def (m) - - class Persist - var _filename - var _p - var _dirty - - #- persist can be initialized with pre-existing values. The map is not copied so any change will be reflected -# - def init(m) - # print("Persist init") - self._filename = '_persist.json' - if isinstance(m,map) - self._p = m.copy() # need to copy instead? - else - self._p = {} - end - self.load(self._p, self._filename) - self._dirty = false - # print("Persist init") +class Persist + static var _filename = '_persist.json' + var _p + var _dirty + + #- persist can be initialized with pre-existing values. The map is not copied so any change will be reflected -# + def init(m) + # print("Persist init") + if isinstance(m,map) + self._p = m.copy() # need to copy instead? + else + self._p = {} end + self.load(self._p, self._filename) + self._dirty = false + # print("Persist init") + end - #- virtual member getter, if a key does not exists return `nil` instead of exception -# - def member(key) - return self._p.find(key) - end + #- virtual member getter, if a key does not exists return `nil` instead of exception -# + def member(key) + return self._p.find(key) + end - #- virtual member setter -# - def setmember(key, value) - self._p[key] = value - self._dirty = true - end + #- virtual member setter -# + def setmember(key, value) + self._p[key] = value + self._dirty = true + end - #- clear all entries -# - def zero() - self._p = {} + #- clear all entries -# + def zero() + self._p = {} + self._dirty = true + end + + def remove(k) + self._p.remove(k) self._dirty = true - end - - def remove(k) - self._p.remove(k) - self._dirty = true - end - - def has(k) - return self._p.has(k) - end + end - def find(k, d) - return self._p.find(k, d) - end + def has(k) + return self._p.has(k) + end - def load() - import json - import path - var f # file object - var val # values loaded from json - - if path.exists(self._filename) - try - f = open(self._filename, "r") - val = json.load(f.read()) - f.close() - except .. as e, m - if f != nil f.close() end - raise e, m - end - if isinstance(val, map) - self._p = val # sucess - else - print("BRY: failed to load _persist.json") - end - self._dirty = false - else - self.save() - end + def find(k, d) + return self._p.find(k, d) + end - # print("Loading") - end + def load() + import json + import path + var f # file object + var val # values loaded from json - def save() - var f # file object + if path.exists(self._filename) try - f = open(self._filename, "w") - self.json_fdump(f) + f = open(self._filename, "r") + val = json.load(f.read()) f.close() except .. as e, m if f != nil f.close() end - f = open(self._filename, "w") - f.write('{}') # fallback write empty map - f.close() raise e, m end + if isinstance(val, map) + self._p = val # sucess + else + print("BRY: failed to load _persist.json") + end self._dirty = false - # print("Saving") + else + self.save() end - def json_fdump_any(f, v) - import json - if isinstance(v, map) - self.json_fdump_map(f, v) - elif isinstance(v, list)v - self.json_fdump_list(f, v) - else - f.write(json.dump(v)) + # print("Loading") + end + + def save() + var f # file object + try + f = open(self._filename, "w") + self.json_fdump(f) + f.close() + except .. as e, m + if f != nil f.close() end + f = nil + try + f = open(self._filename, "w") + f.write('{}') # fallback write empty map + except .. end + if f != nil f.close() end + raise e, m end + self._dirty = false + # print("Saving") + end - def json_fdump_map(f, v) - import json - f.write('{') - var sep = nil - for k:v.keys() - if sep != nil f.write(sep) end - - f.write(json.dump(str(k))) - f.write(':') - self.json_fdump_any(f, v[k]) - - sep = "," - end - f.write('}') + def json_fdump_any(f, v) + import json + if isinstance(v, map) + self.json_fdump_map(f, v) + elif isinstance(v, list) + self.json_fdump_list(f, v) + else + f.write(json.dump(v)) end + end - def json_fdump_list(f, v) - import json - f.write('[') - var i = 0 - while i < size(v) - if i > 0 f.write(',') end - self.json_fdump_any(f, v[i]) - i += 1 - end - f.write(']') + def json_fdump_map(f, v) + import json + f.write('{') + var sep = nil + for k:v.keys() + if sep != nil f.write(sep) end + + f.write(json.dump(str(k))) + f.write(':') + self.json_fdump_any(f, v[k]) + + sep = "," end + f.write('}') + end - def json_fdump(f) - import json - if isinstance(self._p, map) - self.json_fdump_map(f, self._p) - else - raise "internal_error", "persist._p is not a map" - end + def json_fdump_list(f, v) + import json + f.write('[') + var i = 0 + while i < size(v) + if i > 0 f.write(',') end + self.json_fdump_any(f, v[i]) + i += 1 end + f.write(']') end + def json_fdump(f) + import json + if isinstance(self._p, map) + self.json_fdump_map(f, self._p) + else + raise "internal_error", "persist._p is not a map" + end + end +end +persist_module.Persist = Persist - return Persist() # return an instance of this class +persist_module.init = def (m) + return m.Persist() # return an instance of this class end return persist_module diff --git a/lib/libesp32/berry_tasmota/src/embedded/rule_matcher.be b/lib/libesp32/berry_tasmota/src/embedded/rule_matcher.be index b28b97b3d8fb..79ed625fc9a9 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/rule_matcher.be +++ b/lib/libesp32/berry_tasmota/src/embedded/rule_matcher.be @@ -1,10 +1,11 @@ #- Native code used for testing and code solidification -# #- Do not use it directly -# -#@ solidify:Rule_Matcher_Key -#@ solidify:Rule_Matcher_Wildcard -#@ solidify:Rule_Matcher_Operator -#@ solidify:Rule_Matcher_Array +#@ solidify:Rule_Matcher.Rule_Matcher_Key +#@ solidify:Rule_Matcher.Rule_Matcher_Wildcard +#@ solidify:Rule_Matcher.Rule_Matcher_Operator +#@ solidify:Rule_Matcher.Rule_Matcher_Array +#@ solidify:Rule_Matcher.Rule_Matcher_AND_List #@ solidify:Rule_Matcher @@ -118,6 +119,9 @@ class Rule_Matcher # , , # # Instance types: + # Rule_Matcher_AND_List(key): checks that the input map matches with all contains individual conditions in the list + # returns an array of sub-value or `nil` if at least one doesn't match + # # Rule_Matcher_Key(key): checks that the input map contains the key (case insensitive) and # returns the sub-value or `nil` if the key does not exist # @@ -127,6 +131,33 @@ class Rule_Matcher # Rule_Matcher_Operator: checks is a simple value (numerical or string) matches the operator and the value # returns the value unchanged if match, or `nil` if no match + + # do a logical AND of all sub-matchers + static class Rule_Matcher_AND_List + var and_list + + def init(and_list) + self.and_list = and_list + end + + def match(val) + var idx = 0 + var ret_list = [] + while idx < size(self.and_list) + var rule = self.and_list[idx] + var ret = rule.match(val) + if ret == nil return nil end # abort as soon as a matcher fails + ret_list.push(ret) + idx += 1 + end + return ret_list + end + + def tostring() + return "" + end + end + static class Rule_Matcher_Key var name # literal name of what to match @@ -204,63 +235,63 @@ class Rule_Matcher end - ########################################################################################### - # Functions to compare two values - ########################################################################################### - def op_parse(op, op_value) - self.op_str = op - - def op_eq_str(a,b) return tasmota._apply_str_op(1, str(a), b) end - def op_neq_str(a,b) return tasmota._apply_str_op(2, str(a), b) end - def op_start_str(a,b) return tasmota._apply_str_op(3, str(a), b) end - def op_end_str(a,b) return tasmota._apply_str_op(4, str(a), b) end - def op_sub_str(a,b) return tasmota._apply_str_op(5, str(a), b) end - def op_notsub_str(a,b) return tasmota._apply_str_op(6, str(a), b) end - def op_eq(a,b) return number(a) == b end - def op_neq(a,b) return number(a) != b end - def op_gt(a,b) return number(a) > b end - def op_gte(a,b) return number(a) >= b end - def op_lt(a,b) return number(a) < b end - def op_lte(a,b) return number(a) <= b end - def op_mod(a,b) return (int(a) % b) == 0 end - - var numerical = false - var f - - if op=='=' f = op_eq_str - elif op=='!==' f = op_neq_str - elif op=='$!' f = op_neq_str - elif op=='$<' f = op_start_str - elif op=='$>' f = op_end_str - elif op=='$|' f = op_sub_str - elif op=='$^' f = op_notsub_str - else - numerical = true - if op=='==' f = op_eq - elif op=='!=' f = op_neq - elif op=='>' f = op_gt - elif op=='>=' f = op_gte - elif op=='<' f = op_lt - elif op=='<=' f = op_lte - elif op=='|' f = op_mod + ########################################################################################### + # Functions to compare two values + ########################################################################################### + def op_parse(op, op_value) + self.op_str = op + + def op_eq_str(a,b) return tasmota._apply_str_op(1, str(a), b) end + def op_neq_str(a,b) return tasmota._apply_str_op(2, str(a), b) end + def op_start_str(a,b) return tasmota._apply_str_op(3, str(a), b) end + def op_end_str(a,b) return tasmota._apply_str_op(4, str(a), b) end + def op_sub_str(a,b) return tasmota._apply_str_op(5, str(a), b) end + def op_notsub_str(a,b) return tasmota._apply_str_op(6, str(a), b) end + def op_eq(a,b) return number(a) == b end + def op_neq(a,b) return number(a) != b end + def op_gt(a,b) return number(a) > b end + def op_gte(a,b) return number(a) >= b end + def op_lt(a,b) return number(a) < b end + def op_lte(a,b) return number(a) <= b end + def op_mod(a,b) return (int(a) % b) == 0 end + + var numerical = false + var f + + if op=='=' f = op_eq_str + elif op=='!==' f = op_neq_str + elif op=='$!' f = op_neq_str + elif op=='$<' f = op_start_str + elif op=='$>' f = op_end_str + elif op=='$|' f = op_sub_str + elif op=='$^' f = op_notsub_str + else + numerical = true + if op=='==' f = op_eq + elif op=='!=' f = op_neq + elif op=='>' f = op_gt + elif op=='>=' f = op_gte + elif op=='<' f = op_lt + elif op=='<=' f = op_lte + elif op=='|' f = op_mod + end end - end - self.op_func = f - if numerical # if numerical comparator, make sure that the value passed is a number - # to check if a number is correct, the safest method is to use a json decoder - import json - var val_num = json.load(op_value) - if type(val_num) != 'int' && type(val_num) != 'real' - raise "value_error", "value needs to be a number" + self.op_func = f + if numerical # if numerical comparator, make sure that the value passed is a number + # to check if a number is correct, the safest method is to use a json decoder + import json + var val_num = json.load(op_value) + if type(val_num) != 'int' && type(val_num) != 'real' + raise "value_error", "value needs to be a number" + else + self.op_value = val_num + end else - self.op_value = val_num + self.op_value = str(op_value) end - else - self.op_value = str(op_value) - end - end + end def match(val) var t = type(val) @@ -293,6 +324,18 @@ class Rule_Matcher static def parse(pattern) import string if pattern == nil return nil end + + # special case if a list of patterns, recursively make a list of matchers + if isinstance(pattern, list) + var and_list = [] + var trigger_list = [] + for p: pattern + var matcher = _class.parse(p) + and_list.push(matcher) + trigger_list.push(matcher.trigger) + end + return _class(pattern, trigger_list, [_class.Rule_Matcher_AND_List(and_list)]) + end var matchers = [] diff --git a/lib/libesp32/berry_tasmota/src/embedded/tapp.be b/lib/libesp32/berry_tasmota/src/embedded/tapp.be index a107f50f6c68..095d9ff2c750 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/tapp.be +++ b/lib/libesp32/berry_tasmota/src/embedded/tapp.be @@ -20,7 +20,7 @@ tapp_module.init = def (m) for d: dir if string.find(d, ".tapp") > 0 - tasmota.log(string.format("TAP: Loaded Tasmota App '%s'", d), 2) + tasmota.log(format("TAP: Loaded Tasmota App '%s'", d), 2) tasmota.load(d + "#autoexec.be") end end diff --git a/lib/libesp32/berry_tasmota/src/embedded/tasmota_class.be b/lib/libesp32/berry_tasmota/src/embedded/tasmota_class.be index 02bf7a814695..2259e0a68ec4 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/tasmota_class.be +++ b/lib/libesp32/berry_tasmota/src/embedded/tasmota_class.be @@ -34,7 +34,7 @@ class Tasmota try import debug self._debug_present = true - except .. + except .. end # declare `UrlFetch` command self.add_cmd('UrlFetch', def (cmd, idx, payload, payload_json) self.urlfetch_cmd(cmd, idx, payload, payload_json) end) @@ -64,6 +64,19 @@ class Tasmota end end + # find a string in a list, case insensitive + def find_list_i(l, vali) + import string + var idx = 0 + var valu = string.toupper(vali) + while idx < size(l) + if string.toupper(l[idx]) == valu + return idx + end + idx += 1 + end + return nil + end # split the item when there is an operator, returns a list of (left,op,right) #- @@ -85,8 +98,8 @@ class Tasmota # Rules def add_rule(pat, f, id) self.check_not_method(f) - if !self._rules - self._rules=[] + if self._rules == nil + self._rules = [] end if type(f) == 'function' self._rules.push(Trigger(self.Rule_Matcher.parse(pat), f, id)) @@ -131,7 +144,7 @@ class Tasmota var save_cmd_res = self.cmd_res # save initial state (for reentrance) if self._rules || save_cmd_res != nil # if there is a rule handler, or we record rule results import json - + self.cmd_res = nil # disable sunsequent recording of results var ret = false @@ -186,7 +199,9 @@ class Tasmota def set_timer(delay,f,id) self.check_not_method(f) - if !self._timers self._timers=[] end + if self._timers == nil + self._timers=[] + end self._timers.push(Trigger(self.millis(delay),f,id)) end @@ -241,11 +256,13 @@ class Tasmota end end end - + # crontab style recurring events def add_cron(pattern,f,id) self.check_not_method(f) - if !self._crons self._crons=[] end + if self._crons == nil + self._crons=[] + end var cron_obj = ccronexpr(str(pattern)) # can fail, throwing an exception var next_time = cron_obj.next() @@ -285,8 +302,8 @@ class Tasmota # Add command to list def add_cmd(c,f) self.check_not_method(f) - if !self._ccmd - self._ccmd={} + if self._ccmd == nil + self._ccmd = {} end if type(f) == 'function' self._ccmd[c]=f @@ -336,9 +353,8 @@ class Tasmota end def time_str(time) - import string var tm = self.time_dump(time) - return string.format("%04d-%02d-%02dT%02d:%02d:%02d", tm['year'], tm['month'], tm['day'], tm['hour'], tm['min'], tm['sec']) + return format("%04d-%02d-%02dT%02d:%02d:%02d", tm['year'], tm['month'], tm['day'], tm['hour'], tm['min'], tm['sec']) end def load(f) @@ -376,8 +392,7 @@ class Tasmota f.close() except .. as e if f != nil f.close() end - import string - print(string.format('BRY: failed to load compiled \'%s\' (%s)',fname_bec,e)) + print(format('BRY: failed to load compiled \'%s\' (%s)',fname_bec,e)) end return nil end @@ -399,8 +414,7 @@ class Tasmota var compiled = compile(f_name, 'file') return compiled except .. as e, m - import string - print(string.format('BRY: failed to load \'%s\' (%s - %s)',f_name,e,m)) + print(format('BRY: failed to load \'%s\' (%s - %s)',f_name,e,m)) end return nil end @@ -413,8 +427,7 @@ class Tasmota compiled_code() return true except .. as e, m - import string - print(string.format("BRY: failed to run compiled code '%s' - %s", e, m)) + print(format("BRY: failed to run compiled code '%s' - %s", e, m)) end end return false @@ -470,7 +483,7 @@ class Tasmota end # print("f_time",f_time,"f_time_bec",f_time_bec,"suffix_bec",suffix_bec) end - + # recall the working directory if f_archive self.wd = f_prefix + "#" @@ -487,10 +500,10 @@ class Tasmota var bec_version = try_get_bec_version(f_name_bec) var version_ok = true if bec_version == nil - print(string.format('BRY: corrupt bytecode \'%s\'',f_name_bec)) + print(format('BRY: corrupt bytecode \'%s\'',f_name_bec)) version_ok = false elif bec_version != 0x04 # -- this is the currenlty supported version - print(string.format('BRY: bytecode has wrong version \'%s\' (%i)',f_name_bec,bec_version)) + print(format('BRY: bytecode has wrong version \'%s\' (%i)',f_name_bec,bec_version)) version_ok = false end @@ -516,7 +529,7 @@ class Tasmota try self.save(f_name_bec, compiled_code) except .. as e - print(string.format('BRY: could not save compiled file %s (%s)',f_name_bec,e)) + print(format('BRY: could not save compiled file %s (%s)',f_name_bec,e)) end end # call the compiled code @@ -550,7 +563,9 @@ class Tasmota def add_fast_loop(cl) self.check_not_method(cl) - if !self._fl self._fl = [] end + if self._fl == nil + self._fl = [] + end if type(cl) != 'function' raise "value_error", "argument must be a function" end self.global.fast_loop_enabled = 1 # enable fast_loop at global level: `TasmotaGlobal.fast_loop_enabled = true` self._fl.push(cl) @@ -566,7 +581,6 @@ class Tasmota def event(event_type, cmd, idx, payload, raw) import introspect - import string if event_type=='every_50ms' self.run_deferred() end #- first run deferred events -# @@ -596,7 +610,7 @@ class Tasmota done = f(d, cmd, idx, payload, raw) || done if done && !keep_going break end except .. as e,m - print(string.format("BRY: Exception> '%s' - %s", e, m)) + print(format("BRY: Exception> '%s' - %s", e, m)) if self._debug_present import debug debug.traceback() @@ -644,29 +658,22 @@ class Tasmota var save_cmd_res = self.cmd_res # restore value on exit (for reentrant) self.cmd_res = true # signal buffer capture - var seriallog_level = tasmota.global.seriallog_level - var mqttlog_level = tasmota.settings.mqttlog_level - var weblog_level = tasmota.settings.weblog_level - + var maxlog_level = tasmota.global.maxlog_level if mute # mute logging - if seriallog_level >= 2 tasmota.global.seriallog_level = 1 end - if mqttlog_level >= 2 tasmota.settings.mqttlog_level = 1 end - if weblog_level >= 2 tasmota.settings.weblog_level = 1 end + if maxlog_level >= 2 tasmota.global.maxlog_level = 1 end end self._cmd(command) - + var ret = nil if self.cmd_res != true # unchanged ret = self.cmd_res end self.cmd_res = save_cmd_res # restore previous state - + # restore log_level if mute - tasmota.global.seriallog_level = seriallog_level - tasmota.settings.mqttlog_level = mqttlog_level - tasmota.settings.weblog_level = weblog_level + tasmota.global.maxlog_level = maxlog_level end return ret end @@ -709,14 +716,14 @@ class Tasmota var g = 255 # we take brightness at 100%, brightness should be set separately hue = hue % 360 # normalize to 0..359 - + if sat > 0 var i = hue / 60 # quadrant 0..5 var f = hue % 60 # 0..59 var p = 255 - sat var q = tasmota.scale_uint(f, 0, 60, 255, p) # 0..59 var t = tasmota.scale_uint(f, 0, 60, p, 255) - + if i == 0 # r = 255 g = t @@ -743,7 +750,7 @@ class Tasmota b = q end end - + return (r << 16) | (g << 8) | b end diff --git a/lib/libesp32/berry_tasmota/src/embedded/trigger_class.be b/lib/libesp32/berry_tasmota/src/embedded/trigger_class.be index 83a52556afd7..ecdd5c111bd3 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/trigger_class.be +++ b/lib/libesp32/berry_tasmota/src/embedded/trigger_class.be @@ -20,8 +20,7 @@ class Trigger end def tostring() - import string - return string.format("", + return format("", classname(self), self.shortaddr, la.get(4,4), la.get(0,4), self.name, self.model, self.manufacturer) diff --git a/lib/libesp32/berry_tasmota/src/embedded/zigbee_zb_coord.be b/lib/libesp32/berry_tasmota/src/embedded/zigbee_zb_coord.be index aab49d271817..f49ce273cf27 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/zigbee_zb_coord.be +++ b/lib/libesp32/berry_tasmota/src/embedded/zigbee_zb_coord.be @@ -17,12 +17,23 @@ class zb_coord : zb_coord_ntv raise "value_error", "instance required" end if self._handlers - self._handlers.push(h) - else + if self._handlers.find(h) == nil # make it idempotent + self._handlers.push(h) + end + else self._handlers = [h] end end + def remove_handler(h) + if self._handlers + var idx = self._handlers.find(h) + if idx != nil + self._handlers.remove(idx) + end + end + end + # dispatch incomind events # # event_type: @@ -38,7 +49,6 @@ class zb_coord : zb_coord_ntv if self._handlers == nil return end import introspect - import string var frame var attr_list @@ -50,7 +60,7 @@ class zb_coord : zb_coord_ntv attr_list = self.zcl_attribute_list(zcl_attribute_list_ptr) end - #print(string.format(">ZIG: cmd=%s data_type=%s data=%s idx=%i", event_type, data_type, str(data), idx)) + #print(format(">ZIG: cmd=%s data_type=%s data=%s idx=%i", event_type, data_type, str(data), idx)) var i = 0 while i < size(self._handlers) @@ -60,7 +70,7 @@ class zb_coord : zb_coord_ntv try f(h, event_type, frame, attr_list, idx) except .. as e,m - print(string.format("BRY: Exception> '%s' - %s", e, m)) + print(format("BRY: Exception> '%s' - %s", e, m)) if tasmota._debug_present import debug debug.traceback() diff --git a/lib/libesp32/berry_tasmota/src/embedded/zigbee_zcl_attribute.be b/lib/libesp32/berry_tasmota/src/embedded/zigbee_zcl_attribute.be index e58c463d9476..f960f8e74796 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/zigbee_zcl_attribute.be +++ b/lib/libesp32/berry_tasmota/src/embedded/zigbee_zcl_attribute.be @@ -46,7 +46,7 @@ class zcl_attribute : zcl_attribute_ntv elif k == "key" return self._get_key() else - return super(self).member(k) + return super(self).member(k) # natural mapping end end @@ -103,7 +103,6 @@ class zcl_attribute : zcl_attribute_ntv end def key_tostring() - import string var s = "" var key = self.key @@ -113,12 +112,12 @@ class zcl_attribute : zcl_attribute_ntv s += str(self.key_suffix) end elif (self.cluster != nil) && (self.attr_id != nil) - s = string.format("%04X/%04X", self.cluster, self.attr_id) + s = format("%04X/%04X", self.cluster, self.attr_id) if self.key_suffix > 1 s += "+" + str(self.key_suffix) end elif (self.cluster != nil) && (self.cmd != nil) && (self.direction != nil) - s = string.format("%04X%s%02X", self.cluster, self.direction ? "?" : "!" ,self.cmd) + s = format("%04X%s%02X", self.cluster, self.direction ? "?" : "!" ,self.cmd) if self.key_suffix > 1 s += "+" + str(self.key_suffix) end @@ -130,7 +129,6 @@ class zcl_attribute : zcl_attribute_ntv def tostring() import introspect import json - import string var s = json.dump(self.key_tostring()) s += ":" @@ -142,8 +140,8 @@ class zcl_attribute : zcl_attribute_ntv if (self.cluster != nil) && (self.attr_id != nil) && (self.key != nil) # we have an alias - var key_alias = string.format("(%s)", self.key_tostring()) - s += string.format(',%s:"%04X/%04X"', json.dump(key_alias), self.cluster, self.attr_id) + var key_alias = format("(%s)", self.key_tostring()) + s += format(',%s:"%04X/%04X"', json.dump(key_alias), self.cluster, self.attr_id) end return s @@ -200,19 +198,19 @@ class zcl_attribute_list : zcl_attribute_list_ntv end def tostring() - import string import json var items = [] # {"Device":"0x246D","Name":"Plug","EnergyTotal":"0x000000000000","Endpoint":1,"LinkQuality":229} + var v # shortaddr - if self.shortaddr != nil - items.push(string.format('"Device":"0x%04X"', self.shortaddr)) + if (v := self.shortaddr) != nil + items.push(f'"Device":"0x{v:04X}"') end # groupaddr - if self.groupaddr != nil - items.push(string.format('"Group":"0x%04X"', self.groupaddr)) + if (v := self.groupaddr) != nil + items.push(f'"Group":"0x{v:04X}"') end # attributes @@ -225,83 +223,20 @@ class zcl_attribute_list : zcl_attribute_list_ntv end # Endpoint - if self.src_ep != nil - items.push(string.format('"Endpoint":%i', self.src_ep)) + if (v := self.src_ep) != nil + items.push(f'"Endpoint":{v}') end # LQI - if self.lqi != nil - items.push(string.format('"LinkQuality":%i', self.lqi)) + if (v := self.lqi) != nil + items.push(f'"LinkQuality":{v}') end var s = "{" + items.concat(",") + "}" return s - # return string.format("shortaddr:0x%04X groupaddr:0x%04X %s", self.shortaddr, self.groupaddr, str(self.attr_list)) - end -end - -#@ solidify:zcl_attributes,weak -class zcl_attributes - var shortaddr - var groupaddr - var lqi - var src_ep - var attr_list - - def init(shortaddr, groupaddr, lqi, src_ep, attr_list) - self.shortaddr = shortaddr - self.groupaddr = groupaddr - self.lqi = lqi - self.src_ep = src_ep - if isinstance(self.attr_list, list) - self.attr_list = attr_list - else - self.attr_list = [] - end - end - - def push(attr) - self.attr_list.push(attr) + # return format("shortaddr:0x%04X groupaddr:0x%04X %s", self.shortaddr, self.groupaddr, str(self.attr_list)) end - - def tostring() - import string - import json - - var items = [] - # {"Device":"0x246D","Name":"Plug","EnergyTotal":"0x000000000000","Endpoint":1,"LinkQuality":229} - - # shortaddr - if self.shortaddr != nil - items.push(string.format('"Device":"0x%04X"', self.shortaddr)) - end - # groupaddr - if self.shortaddr != nil - items.push(string.format('"Group":"0x%04X"', self.groupaddr)) - end - - # attributes - for e: self.attr_list - items.push(e.tostring()) - end - - # Endpoint - if self.src_ep != nil - items.push(string.format('"Endpoint":%i', self.src_ep)) - end - - # Endpoint - if self.lqi != nil - items.push(string.format('"LinkQuality":%i', self.lqi)) - end - - var s = "{" + items.concat(",") + "}" - return s - - # return string.format("shortaddr:0x%04X groupaddr:0x%04X %s", self.shortaddr, self.groupaddr, str(self.attr_list)) - end - end #- diff --git a/lib/libesp32/berry_tasmota/src/embedded/zigbee_zcl_frame.be b/lib/libesp32/berry_tasmota/src/embedded/zigbee_zcl_frame.be index 044ed43f84c8..6b9d8e1166b5 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/zigbee_zcl_frame.be +++ b/lib/libesp32/berry_tasmota/src/embedded/zigbee_zcl_frame.be @@ -30,9 +30,8 @@ class zcl_frame : zcl_frame_ntv end def tomap() - import string var m = super(self).tomap() - m["shortaddr_hex"] = string.format("0x%04X", self.shortaddr) + m["shortaddr_hex"] = format("0x%04X", self.shortaddr) m["payload"] = self.payload # add payload object which is a synthetic attribute not included in tomap() return m end diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_autoconf_module.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_autoconf_module.h index c427f18dd505..c37329631ba4 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_autoconf_module.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_autoconf_module.h @@ -11,7 +11,7 @@ extern const bclass be_class_Autoconf; ********************************************************************/ be_local_closure(Autoconf_page_autoconf_ctl, /* name */ be_nested_proto( - 13, /* nstack */ + 11, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -19,169 +19,166 @@ be_local_closure(Autoconf_page_autoconf_ctl, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[41]) { /* constants */ + ( &(const bvalue[39]) { /* constants */ /* K0 */ be_nested_str(webserver), - /* K1 */ be_nested_str(string), - /* K2 */ be_nested_str(path), - /* K3 */ be_nested_str(check_privileged_access), - /* K4 */ be_nested_str(has_arg), - /* K5 */ be_nested_str(reapply), - /* K6 */ be_nested_str(tasmota), - /* K7 */ be_nested_str(log), - /* K8 */ be_nested_str(CFG_X3A_X20removing_X20first_X20time_X20marker), - /* K9 */ be_const_int(2), - /* K10 */ be_nested_str(clear_first_time), - /* K11 */ be_nested_str(redirect), - /* K12 */ be_nested_str(_X2F_X3Frst_X3D), - /* K13 */ be_nested_str(zip), - /* K14 */ be_nested_str(CFG_X3A_X20removing_X20autoconf_X20files), - /* K15 */ be_nested_str(delete_all_configs), - /* K16 */ be_nested_str(arg), - /* K17 */ be_nested_str(reset), - /* K18 */ be_nested_str(format), - /* K19 */ be_nested_str(https_X3A_X2F_X2Fraw_X2Egithubusercontent_X2Ecom_X2Ftasmota_X2Fautoconf_X2Fmain_X2F_X25s_X2F_X25s_X2Eautoconf), - /* K20 */ be_nested_str(arch), - /* K21 */ be_nested_str(CFG_X3A_X20downloading_X20_X27_X25s_X27), - /* K22 */ be_nested_str(_X25s_X2Eautoconf), - /* K23 */ be_nested_str(webclient), - /* K24 */ be_nested_str(begin), - /* K25 */ be_nested_str(GET), - /* K26 */ be_nested_str(return_X20code_X3D_X25i), - /* K27 */ be_nested_str(connection_error), - /* K28 */ be_nested_str(write_file), - /* K29 */ be_nested_str(close), - /* K30 */ be_nested_str(value_error), - /* K31 */ be_nested_str(Unknown_X20command), - /* K32 */ be_nested_str(CFG_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s), - /* K33 */ be_nested_str(content_start), - /* K34 */ be_nested_str(Parameter_X20error), - /* K35 */ be_nested_str(content_send_style), - /* K36 */ be_nested_str(content_send), - /* K37 */ be_nested_str(_X3Cp_X20style_X3D_X27width_X3A340px_X3B_X27_X3E_X3Cb_X3EException_X3A_X3C_X2Fb_X3E_X3Cbr_X3E_X27_X25s_X27_X3Cbr_X3E_X25s_X3C_X2Fp_X3E), - /* K38 */ be_nested_str(content_button), - /* K39 */ be_nested_str(BUTTON_CONFIGURATION), - /* K40 */ be_nested_str(content_stop), + /* K1 */ be_nested_str(path), + /* K2 */ be_nested_str(check_privileged_access), + /* K3 */ be_nested_str(has_arg), + /* K4 */ be_nested_str(reapply), + /* K5 */ be_nested_str(tasmota), + /* K6 */ be_nested_str(log), + /* K7 */ be_nested_str(CFG_X3A_X20removing_X20first_X20time_X20marker), + /* K8 */ be_const_int(2), + /* K9 */ be_nested_str(clear_first_time), + /* K10 */ be_nested_str(redirect), + /* K11 */ be_nested_str(_X2F_X3Frst_X3D), + /* K12 */ be_nested_str(zip), + /* K13 */ be_nested_str(CFG_X3A_X20removing_X20autoconf_X20files), + /* K14 */ be_nested_str(delete_all_configs), + /* K15 */ be_nested_str(arg), + /* K16 */ be_nested_str(reset), + /* K17 */ be_nested_str(https_X3A_X2F_X2Fraw_X2Egithubusercontent_X2Ecom_X2Ftasmota_X2Fautoconf_X2Fmain_X2F_X25s_X2F_X25s_X2Eautoconf), + /* K18 */ be_nested_str(arch), + /* K19 */ be_nested_str(CFG_X3A_X20downloading_X20_X27_X25s_X27), + /* K20 */ be_nested_str(_X25s_X2Eautoconf), + /* K21 */ be_nested_str(webclient), + /* K22 */ be_nested_str(begin), + /* K23 */ be_nested_str(GET), + /* K24 */ be_nested_str(return_X20code_X3D_X25i), + /* K25 */ be_nested_str(connection_error), + /* K26 */ be_nested_str(write_file), + /* K27 */ be_nested_str(close), + /* K28 */ be_nested_str(value_error), + /* K29 */ be_nested_str(Unknown_X20command), + /* K30 */ be_nested_str(CFG_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K31 */ be_nested_str(content_start), + /* K32 */ be_nested_str(Parameter_X20error), + /* K33 */ be_nested_str(content_send_style), + /* K34 */ be_nested_str(content_send), + /* K35 */ be_nested_str(_X3Cp_X20style_X3D_X27width_X3A340px_X3B_X27_X3E_X3Cb_X3EException_X3A_X3C_X2Fb_X3E_X3Cbr_X3E_X27_X25s_X27_X3Cbr_X3E_X25s_X3C_X2Fp_X3E), + /* K36 */ be_nested_str(content_button), + /* K37 */ be_nested_str(BUTTON_CONFIGURATION), + /* K38 */ be_nested_str(content_stop), }), &be_const_str_page_autoconf_ctl, &be_const_str_solidified, - ( &(const binstruction[117]) { /* code */ + ( &(const binstruction[116]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 0xA40A0200, // 0001 IMPORT R2 K1 - 0xA40E0400, // 0002 IMPORT R3 K2 - 0x8C100303, // 0003 GETMET R4 R1 K3 - 0x7C100200, // 0004 CALL R4 1 - 0x74120001, // 0005 JMPT R4 #0008 - 0x4C100000, // 0006 LDNIL R4 - 0x80040800, // 0007 RET 1 R4 - 0xA802004E, // 0008 EXBLK 0 #0058 - 0x8C100304, // 0009 GETMET R4 R1 K4 - 0x58180005, // 000A LDCONST R6 K5 - 0x7C100400, // 000B CALL R4 2 - 0x7812000A, // 000C JMPF R4 #0018 - 0xB8120C00, // 000D GETNGBL R4 K6 - 0x8C100907, // 000E GETMET R4 R4 K7 + 0x8C0C0302, // 0002 GETMET R3 R1 K2 + 0x7C0C0200, // 0003 CALL R3 1 + 0x740E0001, // 0004 JMPT R3 #0007 + 0x4C0C0000, // 0005 LDNIL R3 + 0x80040600, // 0006 RET 1 R3 + 0xA802004E, // 0007 EXBLK 0 #0057 + 0x8C0C0303, // 0008 GETMET R3 R1 K3 + 0x58140004, // 0009 LDCONST R5 K4 + 0x7C0C0400, // 000A CALL R3 2 + 0x780E000A, // 000B JMPF R3 #0017 + 0xB80E0A00, // 000C GETNGBL R3 K5 + 0x8C0C0706, // 000D GETMET R3 R3 K6 + 0x58140007, // 000E LDCONST R5 K7 0x58180008, // 000F LDCONST R6 K8 - 0x581C0009, // 0010 LDCONST R7 K9 - 0x7C100600, // 0011 CALL R4 3 - 0x8C10010A, // 0012 GETMET R4 R0 K10 - 0x7C100200, // 0013 CALL R4 1 - 0x8C10030B, // 0014 GETMET R4 R1 K11 - 0x5818000C, // 0015 LDCONST R6 K12 - 0x7C100400, // 0016 CALL R4 2 - 0x7002003D, // 0017 JMP #0056 - 0x8C100304, // 0018 GETMET R4 R1 K4 - 0x5818000D, // 0019 LDCONST R6 K13 - 0x7C100400, // 001A CALL R4 2 - 0x78120038, // 001B JMPF R4 #0055 - 0xB8120C00, // 001C GETNGBL R4 K6 - 0x8C100907, // 001D GETMET R4 R4 K7 - 0x5818000E, // 001E LDCONST R6 K14 - 0x581C0009, // 001F LDCONST R7 K9 - 0x7C100600, // 0020 CALL R4 3 - 0x8C10010F, // 0021 GETMET R4 R0 K15 - 0x7C100200, // 0022 CALL R4 1 - 0x8C100310, // 0023 GETMET R4 R1 K16 - 0x5818000D, // 0024 LDCONST R6 K13 - 0x7C100400, // 0025 CALL R4 2 - 0x20140911, // 0026 NE R5 R4 K17 - 0x78160026, // 0027 JMPF R5 #004F - 0x8C140512, // 0028 GETMET R5 R2 K18 - 0x581C0013, // 0029 LDCONST R7 K19 - 0xB8220C00, // 002A GETNGBL R8 K6 - 0x8C201114, // 002B GETMET R8 R8 K20 - 0x7C200200, // 002C CALL R8 1 - 0x5C240800, // 002D MOVE R9 R4 - 0x7C140800, // 002E CALL R5 4 - 0xB81A0C00, // 002F GETNGBL R6 K6 - 0x8C180D07, // 0030 GETMET R6 R6 K7 - 0x8C200512, // 0031 GETMET R8 R2 K18 - 0x58280015, // 0032 LDCONST R10 K21 - 0x5C2C0A00, // 0033 MOVE R11 R5 - 0x7C200600, // 0034 CALL R8 3 - 0x58240009, // 0035 LDCONST R9 K9 - 0x7C180600, // 0036 CALL R6 3 - 0x8C180512, // 0037 GETMET R6 R2 K18 - 0x58200016, // 0038 LDCONST R8 K22 - 0x5C240800, // 0039 MOVE R9 R4 - 0x7C180600, // 003A CALL R6 3 - 0xB81E2E00, // 003B GETNGBL R7 K23 - 0x7C1C0000, // 003C CALL R7 0 - 0x8C200F18, // 003D GETMET R8 R7 K24 - 0x5C280A00, // 003E MOVE R10 R5 - 0x7C200400, // 003F CALL R8 2 - 0x8C200F19, // 0040 GETMET R8 R7 K25 - 0x7C200200, // 0041 CALL R8 1 - 0x542600C7, // 0042 LDINT R9 200 - 0x20241009, // 0043 NE R9 R8 R9 - 0x78260004, // 0044 JMPF R9 #004A - 0x8C240512, // 0045 GETMET R9 R2 K18 - 0x582C001A, // 0046 LDCONST R11 K26 - 0x5C301000, // 0047 MOVE R12 R8 - 0x7C240600, // 0048 CALL R9 3 - 0xB0063609, // 0049 RAISE 1 K27 R9 - 0x8C240F1C, // 004A GETMET R9 R7 K28 - 0x5C2C0C00, // 004B MOVE R11 R6 - 0x7C240400, // 004C CALL R9 2 - 0x8C240F1D, // 004D GETMET R9 R7 K29 - 0x7C240200, // 004E CALL R9 1 - 0x8C14010A, // 004F GETMET R5 R0 K10 - 0x7C140200, // 0050 CALL R5 1 - 0x8C14030B, // 0051 GETMET R5 R1 K11 - 0x581C000C, // 0052 LDCONST R7 K12 - 0x7C140400, // 0053 CALL R5 2 - 0x70020000, // 0054 JMP #0056 - 0xB0063D1F, // 0055 RAISE 1 K30 K31 - 0xA8040001, // 0056 EXBLK 1 1 - 0x7002001B, // 0057 JMP #0074 - 0xAC100002, // 0058 CATCH R4 0 2 - 0x70020018, // 0059 JMP #0073 - 0x60180001, // 005A GETGBL R6 G1 - 0x8C1C0512, // 005B GETMET R7 R2 K18 - 0x58240020, // 005C LDCONST R9 K32 - 0x5C280800, // 005D MOVE R10 R4 - 0x5C2C0A00, // 005E MOVE R11 R5 - 0x7C1C0800, // 005F CALL R7 4 - 0x7C180200, // 0060 CALL R6 1 - 0x8C180321, // 0061 GETMET R6 R1 K33 - 0x58200022, // 0062 LDCONST R8 K34 - 0x7C180400, // 0063 CALL R6 2 - 0x8C180323, // 0064 GETMET R6 R1 K35 - 0x7C180200, // 0065 CALL R6 1 - 0x8C180324, // 0066 GETMET R6 R1 K36 - 0x8C200512, // 0067 GETMET R8 R2 K18 - 0x58280025, // 0068 LDCONST R10 K37 - 0x5C2C0800, // 0069 MOVE R11 R4 - 0x5C300A00, // 006A MOVE R12 R5 - 0x7C200800, // 006B CALL R8 4 - 0x7C180400, // 006C CALL R6 2 - 0x8C180326, // 006D GETMET R6 R1 K38 - 0x88200327, // 006E GETMBR R8 R1 K39 - 0x7C180400, // 006F CALL R6 2 - 0x8C180328, // 0070 GETMET R6 R1 K40 - 0x7C180200, // 0071 CALL R6 1 - 0x70020000, // 0072 JMP #0074 - 0xB0080000, // 0073 RAISE 2 R0 R0 - 0x80000000, // 0074 RET 0 + 0x7C0C0600, // 0010 CALL R3 3 + 0x8C0C0109, // 0011 GETMET R3 R0 K9 + 0x7C0C0200, // 0012 CALL R3 1 + 0x8C0C030A, // 0013 GETMET R3 R1 K10 + 0x5814000B, // 0014 LDCONST R5 K11 + 0x7C0C0400, // 0015 CALL R3 2 + 0x7002003D, // 0016 JMP #0055 + 0x8C0C0303, // 0017 GETMET R3 R1 K3 + 0x5814000C, // 0018 LDCONST R5 K12 + 0x7C0C0400, // 0019 CALL R3 2 + 0x780E0038, // 001A JMPF R3 #0054 + 0xB80E0A00, // 001B GETNGBL R3 K5 + 0x8C0C0706, // 001C GETMET R3 R3 K6 + 0x5814000D, // 001D LDCONST R5 K13 + 0x58180008, // 001E LDCONST R6 K8 + 0x7C0C0600, // 001F CALL R3 3 + 0x8C0C010E, // 0020 GETMET R3 R0 K14 + 0x7C0C0200, // 0021 CALL R3 1 + 0x8C0C030F, // 0022 GETMET R3 R1 K15 + 0x5814000C, // 0023 LDCONST R5 K12 + 0x7C0C0400, // 0024 CALL R3 2 + 0x20100710, // 0025 NE R4 R3 K16 + 0x78120026, // 0026 JMPF R4 #004E + 0x60100018, // 0027 GETGBL R4 G24 + 0x58140011, // 0028 LDCONST R5 K17 + 0xB81A0A00, // 0029 GETNGBL R6 K5 + 0x8C180D12, // 002A GETMET R6 R6 K18 + 0x7C180200, // 002B CALL R6 1 + 0x5C1C0600, // 002C MOVE R7 R3 + 0x7C100600, // 002D CALL R4 3 + 0xB8160A00, // 002E GETNGBL R5 K5 + 0x8C140B06, // 002F GETMET R5 R5 K6 + 0x601C0018, // 0030 GETGBL R7 G24 + 0x58200013, // 0031 LDCONST R8 K19 + 0x5C240800, // 0032 MOVE R9 R4 + 0x7C1C0400, // 0033 CALL R7 2 + 0x58200008, // 0034 LDCONST R8 K8 + 0x7C140600, // 0035 CALL R5 3 + 0x60140018, // 0036 GETGBL R5 G24 + 0x58180014, // 0037 LDCONST R6 K20 + 0x5C1C0600, // 0038 MOVE R7 R3 + 0x7C140400, // 0039 CALL R5 2 + 0xB81A2A00, // 003A GETNGBL R6 K21 + 0x7C180000, // 003B CALL R6 0 + 0x8C1C0D16, // 003C GETMET R7 R6 K22 + 0x5C240800, // 003D MOVE R9 R4 + 0x7C1C0400, // 003E CALL R7 2 + 0x8C1C0D17, // 003F GETMET R7 R6 K23 + 0x7C1C0200, // 0040 CALL R7 1 + 0x542200C7, // 0041 LDINT R8 200 + 0x20200E08, // 0042 NE R8 R7 R8 + 0x78220004, // 0043 JMPF R8 #0049 + 0x60200018, // 0044 GETGBL R8 G24 + 0x58240018, // 0045 LDCONST R9 K24 + 0x5C280E00, // 0046 MOVE R10 R7 + 0x7C200400, // 0047 CALL R8 2 + 0xB0063208, // 0048 RAISE 1 K25 R8 + 0x8C200D1A, // 0049 GETMET R8 R6 K26 + 0x5C280A00, // 004A MOVE R10 R5 + 0x7C200400, // 004B CALL R8 2 + 0x8C200D1B, // 004C GETMET R8 R6 K27 + 0x7C200200, // 004D CALL R8 1 + 0x8C100109, // 004E GETMET R4 R0 K9 + 0x7C100200, // 004F CALL R4 1 + 0x8C10030A, // 0050 GETMET R4 R1 K10 + 0x5818000B, // 0051 LDCONST R6 K11 + 0x7C100400, // 0052 CALL R4 2 + 0x70020000, // 0053 JMP #0055 + 0xB006391D, // 0054 RAISE 1 K28 K29 + 0xA8040001, // 0055 EXBLK 1 1 + 0x7002001B, // 0056 JMP #0073 + 0xAC0C0002, // 0057 CATCH R3 0 2 + 0x70020018, // 0058 JMP #0072 + 0x60140001, // 0059 GETGBL R5 G1 + 0x60180018, // 005A GETGBL R6 G24 + 0x581C001E, // 005B LDCONST R7 K30 + 0x5C200600, // 005C MOVE R8 R3 + 0x5C240800, // 005D MOVE R9 R4 + 0x7C180600, // 005E CALL R6 3 + 0x7C140200, // 005F CALL R5 1 + 0x8C14031F, // 0060 GETMET R5 R1 K31 + 0x581C0020, // 0061 LDCONST R7 K32 + 0x7C140400, // 0062 CALL R5 2 + 0x8C140321, // 0063 GETMET R5 R1 K33 + 0x7C140200, // 0064 CALL R5 1 + 0x8C140322, // 0065 GETMET R5 R1 K34 + 0x601C0018, // 0066 GETGBL R7 G24 + 0x58200023, // 0067 LDCONST R8 K35 + 0x5C240600, // 0068 MOVE R9 R3 + 0x5C280800, // 0069 MOVE R10 R4 + 0x7C1C0600, // 006A CALL R7 3 + 0x7C140400, // 006B CALL R5 2 + 0x8C140324, // 006C GETMET R5 R1 K36 + 0x881C0325, // 006D GETMBR R7 R1 K37 + 0x7C140400, // 006E CALL R5 2 + 0x8C140326, // 006F GETMET R5 R1 K38 + 0x7C140200, // 0070 CALL R5 1 + 0x70020000, // 0071 JMP #0073 + 0xB0080000, // 0072 RAISE 2 R0 R0 + 0x80000000, // 0073 RET 0 }) ) ); @@ -193,7 +190,7 @@ be_local_closure(Autoconf_page_autoconf_ctl, /* name */ ********************************************************************/ be_local_closure(Autoconf_autoexec, /* name */ be_nested_proto( - 14, /* nstack */ + 13, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -201,7 +198,7 @@ be_local_closure(Autoconf_autoexec, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[32]) { /* constants */ + ( &(const bvalue[30]) { /* constants */ /* K0 */ be_nested_str(_archive), /* K1 */ be_nested_str(path), /* K2 */ be_nested_str(_X23init_X2Ebat), @@ -221,23 +218,21 @@ be_local_closure(Autoconf_autoexec, /* name */ /* K16 */ be_nested_str(write), /* K17 */ be_nested_str(close), /* K18 */ be_nested_str(CFG_X3A_X20_X27display_X2Eini_X27_X20extracted_X2C_X20restarting), - /* K19 */ be_nested_str(string), - /* K20 */ be_nested_str(format), - /* K21 */ be_nested_str(CFG_X3A_X20could_X20not_X20copy_X20_X27display_X2Eini_X27_X20_X28_X25s_X20_X2D_X20_X25s_X29_X27), - /* K22 */ be_nested_str(cmd), - /* K23 */ be_nested_str(Restart_X201), - /* K24 */ be_nested_str(_X23autoexec_X2Ebat), - /* K25 */ be_nested_str(CFG_X3A_X20running_X20), - /* K26 */ be_const_int(3), - /* K27 */ be_nested_str(CFG_X3A_X20ran_X20_X20), - /* K28 */ be_nested_str(_X23autoexec_X2Ebe), - /* K29 */ be_nested_str(CFG_X3A_X20loading_X20), - /* K30 */ be_nested_str(load), - /* K31 */ be_nested_str(CFG_X3A_X20loaded_X20_X20), + /* K19 */ be_nested_str(CFG_X3A_X20could_X20not_X20copy_X20_X27display_X2Eini_X27_X20_X28_X25s_X20_X2D_X20_X25s_X29_X27), + /* K20 */ be_nested_str(cmd), + /* K21 */ be_nested_str(Restart_X201), + /* K22 */ be_nested_str(_X23autoexec_X2Ebat), + /* K23 */ be_nested_str(CFG_X3A_X20running_X20), + /* K24 */ be_const_int(3), + /* K25 */ be_nested_str(CFG_X3A_X20ran_X20_X20), + /* K26 */ be_nested_str(_X23autoexec_X2Ebe), + /* K27 */ be_nested_str(CFG_X3A_X20loading_X20), + /* K28 */ be_nested_str(load), + /* K29 */ be_nested_str(CFG_X3A_X20loaded_X20_X20), }), &be_const_str_autoexec, &be_const_str_solidified, - ( &(const binstruction[148]) { /* code */ + ( &(const binstruction[147]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 0x4C080000, // 0001 LDNIL R2 0x1C040202, // 0002 EQ R1 R1 R2 @@ -272,14 +267,14 @@ be_local_closure(Autoconf_autoexec, /* name */ 0x8C100304, // 001F GETMET R4 R1 K4 0x5C180600, // 0020 MOVE R6 R3 0x7C100400, // 0021 CALL R4 2 - 0x78120041, // 0022 JMPF R4 #0065 + 0x78120040, // 0022 JMPF R4 #0064 0x8C100103, // 0023 GETMET R4 R0 K3 0x7C100200, // 0024 CALL R4 1 0x74120003, // 0025 JMPT R4 #002A 0x8C100304, // 0026 GETMET R4 R1 K4 0x5818000C, // 0027 LDCONST R6 K12 0x7C100400, // 0028 CALL R4 2 - 0x7412003A, // 0029 JMPT R4 #0065 + 0x74120039, // 0029 JMPT R4 #0064 0x8C100103, // 002A GETMET R4 R0 K3 0x7C100200, // 002B CALL R4 1 0x78120003, // 002C JMPF R4 #0031 @@ -316,76 +311,75 @@ be_local_closure(Autoconf_autoexec, /* name */ 0x5828000A, // 004B LDCONST R10 K10 0x7C1C0600, // 004C CALL R7 3 0xA8040001, // 004D EXBLK 1 1 - 0x70020015, // 004E JMP #0065 + 0x70020014, // 004E JMP #0064 0xAC180002, // 004F CATCH R6 0 2 - 0x70020012, // 0050 JMP #0064 + 0x70020011, // 0050 JMP #0063 0x60200001, // 0051 GETGBL R8 G1 - 0xB8262600, // 0052 GETNGBL R9 K19 - 0x8C241314, // 0053 GETMET R9 R9 K20 - 0x582C0015, // 0054 LDCONST R11 K21 - 0x5C300C00, // 0055 MOVE R12 R6 - 0x5C340E00, // 0056 MOVE R13 R7 - 0x7C240800, // 0057 CALL R9 4 - 0x7C200200, // 0058 CALL R8 1 - 0x4C200000, // 0059 LDNIL R8 - 0x20200808, // 005A NE R8 R4 R8 - 0x78220001, // 005B JMPF R8 #005E - 0x8C200911, // 005C GETMET R8 R4 K17 - 0x7C200200, // 005D CALL R8 1 - 0x4C200000, // 005E LDNIL R8 - 0x20200A08, // 005F NE R8 R5 R8 - 0x78220001, // 0060 JMPF R8 #0063 - 0x8C200B11, // 0061 GETMET R8 R5 K17 - 0x7C200200, // 0062 CALL R8 1 - 0x70020000, // 0063 JMP #0065 - 0xB0080000, // 0064 RAISE 2 R0 R0 - 0x780A0004, // 0065 JMPF R2 #006B - 0xB8120E00, // 0066 GETNGBL R4 K7 - 0x8C100916, // 0067 GETMET R4 R4 K22 - 0x58180017, // 0068 LDCONST R6 K23 - 0x7C100400, // 0069 CALL R4 2 - 0x80000800, // 006A RET 0 - 0x88100100, // 006B GETMBR R4 R0 K0 - 0x00100918, // 006C ADD R4 R4 K24 - 0x5C0C0800, // 006D MOVE R3 R4 - 0x8C100304, // 006E GETMET R4 R1 K4 - 0x5C180600, // 006F MOVE R6 R3 - 0x7C100400, // 0070 CALL R4 2 - 0x7812000C, // 0071 JMPF R4 #007F - 0xB8120E00, // 0072 GETNGBL R4 K7 - 0x8C100908, // 0073 GETMET R4 R4 K8 - 0x001A3203, // 0074 ADD R6 K25 R3 - 0x581C001A, // 0075 LDCONST R7 K26 - 0x7C100600, // 0076 CALL R4 3 - 0x8C100106, // 0077 GETMET R4 R0 K6 - 0x5C180600, // 0078 MOVE R6 R3 - 0x7C100400, // 0079 CALL R4 2 - 0xB8120E00, // 007A GETNGBL R4 K7 - 0x8C100908, // 007B GETMET R4 R4 K8 - 0x001A3603, // 007C ADD R6 K27 R3 - 0x581C001A, // 007D LDCONST R7 K26 - 0x7C100600, // 007E CALL R4 3 - 0x88100100, // 007F GETMBR R4 R0 K0 - 0x0010091C, // 0080 ADD R4 R4 K28 - 0x5C0C0800, // 0081 MOVE R3 R4 - 0x8C100304, // 0082 GETMET R4 R1 K4 - 0x5C180600, // 0083 MOVE R6 R3 - 0x7C100400, // 0084 CALL R4 2 - 0x7812000C, // 0085 JMPF R4 #0093 - 0xB8120E00, // 0086 GETNGBL R4 K7 - 0x8C100908, // 0087 GETMET R4 R4 K8 - 0x001A3A03, // 0088 ADD R6 K29 R3 - 0x581C001A, // 0089 LDCONST R7 K26 - 0x7C100600, // 008A CALL R4 3 - 0xB8123C00, // 008B GETNGBL R4 K30 - 0x5C140600, // 008C MOVE R5 R3 - 0x7C100200, // 008D CALL R4 1 - 0xB8120E00, // 008E GETNGBL R4 K7 - 0x8C100908, // 008F GETMET R4 R4 K8 - 0x001A3E03, // 0090 ADD R6 K31 R3 - 0x581C001A, // 0091 LDCONST R7 K26 - 0x7C100600, // 0092 CALL R4 3 - 0x80000000, // 0093 RET 0 + 0x60240018, // 0052 GETGBL R9 G24 + 0x58280013, // 0053 LDCONST R10 K19 + 0x5C2C0C00, // 0054 MOVE R11 R6 + 0x5C300E00, // 0055 MOVE R12 R7 + 0x7C240600, // 0056 CALL R9 3 + 0x7C200200, // 0057 CALL R8 1 + 0x4C200000, // 0058 LDNIL R8 + 0x20200808, // 0059 NE R8 R4 R8 + 0x78220001, // 005A JMPF R8 #005D + 0x8C200911, // 005B GETMET R8 R4 K17 + 0x7C200200, // 005C CALL R8 1 + 0x4C200000, // 005D LDNIL R8 + 0x20200A08, // 005E NE R8 R5 R8 + 0x78220001, // 005F JMPF R8 #0062 + 0x8C200B11, // 0060 GETMET R8 R5 K17 + 0x7C200200, // 0061 CALL R8 1 + 0x70020000, // 0062 JMP #0064 + 0xB0080000, // 0063 RAISE 2 R0 R0 + 0x780A0004, // 0064 JMPF R2 #006A + 0xB8120E00, // 0065 GETNGBL R4 K7 + 0x8C100914, // 0066 GETMET R4 R4 K20 + 0x58180015, // 0067 LDCONST R6 K21 + 0x7C100400, // 0068 CALL R4 2 + 0x80000800, // 0069 RET 0 + 0x88100100, // 006A GETMBR R4 R0 K0 + 0x00100916, // 006B ADD R4 R4 K22 + 0x5C0C0800, // 006C MOVE R3 R4 + 0x8C100304, // 006D GETMET R4 R1 K4 + 0x5C180600, // 006E MOVE R6 R3 + 0x7C100400, // 006F CALL R4 2 + 0x7812000C, // 0070 JMPF R4 #007E + 0xB8120E00, // 0071 GETNGBL R4 K7 + 0x8C100908, // 0072 GETMET R4 R4 K8 + 0x001A2E03, // 0073 ADD R6 K23 R3 + 0x581C0018, // 0074 LDCONST R7 K24 + 0x7C100600, // 0075 CALL R4 3 + 0x8C100106, // 0076 GETMET R4 R0 K6 + 0x5C180600, // 0077 MOVE R6 R3 + 0x7C100400, // 0078 CALL R4 2 + 0xB8120E00, // 0079 GETNGBL R4 K7 + 0x8C100908, // 007A GETMET R4 R4 K8 + 0x001A3203, // 007B ADD R6 K25 R3 + 0x581C0018, // 007C LDCONST R7 K24 + 0x7C100600, // 007D CALL R4 3 + 0x88100100, // 007E GETMBR R4 R0 K0 + 0x0010091A, // 007F ADD R4 R4 K26 + 0x5C0C0800, // 0080 MOVE R3 R4 + 0x8C100304, // 0081 GETMET R4 R1 K4 + 0x5C180600, // 0082 MOVE R6 R3 + 0x7C100400, // 0083 CALL R4 2 + 0x7812000C, // 0084 JMPF R4 #0092 + 0xB8120E00, // 0085 GETNGBL R4 K7 + 0x8C100908, // 0086 GETMET R4 R4 K8 + 0x001A3603, // 0087 ADD R6 K27 R3 + 0x581C0018, // 0088 LDCONST R7 K24 + 0x7C100600, // 0089 CALL R4 3 + 0xB8123800, // 008A GETNGBL R4 K28 + 0x5C140600, // 008B MOVE R5 R3 + 0x7C100200, // 008C CALL R4 1 + 0xB8120E00, // 008D GETNGBL R4 K7 + 0x8C100908, // 008E GETMET R4 R4 K8 + 0x001A3A03, // 008F ADD R6 K29 R3 + 0x581C0018, // 0090 LDCONST R7 K24 + 0x7C100600, // 0091 CALL R4 3 + 0x80000000, // 0092 RET 0 }) ) ); @@ -397,7 +391,7 @@ be_local_closure(Autoconf_autoexec, /* name */ ********************************************************************/ be_local_closure(Autoconf_run_bat, /* name */ be_nested_proto( - 14, /* nstack */ + 12, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -405,93 +399,90 @@ be_local_closure(Autoconf_run_bat, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(r), - /* K2 */ be_nested_str(readline), - /* K3 */ be_const_int(0), - /* K4 */ be_nested_str(_X0A), - /* K5 */ be_nested_str(_X0D), - /* K6 */ be_nested_str(tasmota), - /* K7 */ be_nested_str(cmd), - /* K8 */ be_nested_str(close), - /* K9 */ be_nested_str(log), - /* K10 */ be_nested_str(format), - /* K11 */ be_nested_str(CFG_X3A_X20could_X20not_X20run_X20_X25s_X20_X28_X25s_X20_X2D_X20_X25s_X29), - /* K12 */ be_const_int(1), + ( &(const bvalue[11]) { /* constants */ + /* K0 */ be_nested_str(r), + /* K1 */ be_nested_str(readline), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str(_X0A), + /* K4 */ be_nested_str(_X0D), + /* K5 */ be_nested_str(tasmota), + /* K6 */ be_nested_str(cmd), + /* K7 */ be_nested_str(close), + /* K8 */ be_nested_str(log), + /* K9 */ be_nested_str(CFG_X3A_X20could_X20not_X20run_X20_X25s_X20_X28_X25s_X20_X2D_X20_X25s_X29), + /* K10 */ be_const_int(1), }), &be_const_str_run_bat, &be_const_str_solidified, - ( &(const binstruction[69]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0xA802002D, // 0002 EXBLK 0 #0031 - 0x60100011, // 0003 GETGBL R4 G17 - 0x5C140200, // 0004 MOVE R5 R1 - 0x58180001, // 0005 LDCONST R6 K1 - 0x7C100400, // 0006 CALL R4 2 - 0x5C0C0800, // 0007 MOVE R3 R4 - 0x50100200, // 0008 LDBOOL R4 1 0 - 0x78120022, // 0009 JMPF R4 #002D - 0x8C100702, // 000A GETMET R4 R3 K2 - 0x7C100200, // 000B CALL R4 1 - 0x6014000C, // 000C GETGBL R5 G12 - 0x5C180800, // 000D MOVE R6 R4 - 0x7C140200, // 000E CALL R5 1 - 0x1C140B03, // 000F EQ R5 R5 K3 - 0x78160000, // 0010 JMPF R5 #0012 - 0x7002001A, // 0011 JMP #002D - 0x6014000C, // 0012 GETGBL R5 G12 - 0x5C180800, // 0013 MOVE R6 R4 - 0x7C140200, // 0014 CALL R5 1 - 0x24140B03, // 0015 GT R5 R5 K3 - 0x7816000B, // 0016 JMPF R5 #0023 - 0x5415FFFE, // 0017 LDINT R5 -1 - 0x94140805, // 0018 GETIDX R5 R4 R5 - 0x1C140B04, // 0019 EQ R5 R5 K4 - 0x74160003, // 001A JMPT R5 #001F - 0x5415FFFE, // 001B LDINT R5 -1 - 0x94140805, // 001C GETIDX R5 R4 R5 - 0x1C140B05, // 001D EQ R5 R5 K5 - 0x78160003, // 001E JMPF R5 #0023 - 0x5415FFFD, // 001F LDINT R5 -2 - 0x40160605, // 0020 CONNECT R5 K3 R5 - 0x94100805, // 0021 GETIDX R4 R4 R5 - 0x7001FFEE, // 0022 JMP #0012 - 0x6014000C, // 0023 GETGBL R5 G12 - 0x5C180800, // 0024 MOVE R6 R4 - 0x7C140200, // 0025 CALL R5 1 - 0x24140B03, // 0026 GT R5 R5 K3 - 0x78160003, // 0027 JMPF R5 #002C - 0xB8160C00, // 0028 GETNGBL R5 K6 - 0x8C140B07, // 0029 GETMET R5 R5 K7 - 0x5C1C0800, // 002A MOVE R7 R4 - 0x7C140400, // 002B CALL R5 2 - 0x7001FFDA, // 002C JMP #0008 - 0x8C100708, // 002D GETMET R4 R3 K8 - 0x7C100200, // 002E CALL R4 1 - 0xA8040001, // 002F EXBLK 1 1 - 0x70020012, // 0030 JMP #0044 - 0xAC100002, // 0031 CATCH R4 0 2 - 0x7002000F, // 0032 JMP #0043 - 0xB81A0C00, // 0033 GETNGBL R6 K6 - 0x8C180D09, // 0034 GETMET R6 R6 K9 - 0x8C20050A, // 0035 GETMET R8 R2 K10 - 0x5828000B, // 0036 LDCONST R10 K11 - 0x5C2C0200, // 0037 MOVE R11 R1 - 0x5C300800, // 0038 MOVE R12 R4 - 0x5C340A00, // 0039 MOVE R13 R5 - 0x7C200A00, // 003A CALL R8 5 - 0x5824000C, // 003B LDCONST R9 K12 - 0x7C180600, // 003C CALL R6 3 - 0x4C180000, // 003D LDNIL R6 - 0x20180606, // 003E NE R6 R3 R6 - 0x781A0001, // 003F JMPF R6 #0042 - 0x8C180708, // 0040 GETMET R6 R3 K8 - 0x7C180200, // 0041 CALL R6 1 - 0x70020000, // 0042 JMP #0044 - 0xB0080000, // 0043 RAISE 2 R0 R0 - 0x80000000, // 0044 RET 0 + ( &(const binstruction[68]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0xA802002D, // 0001 EXBLK 0 #0030 + 0x600C0011, // 0002 GETGBL R3 G17 + 0x5C100200, // 0003 MOVE R4 R1 + 0x58140000, // 0004 LDCONST R5 K0 + 0x7C0C0400, // 0005 CALL R3 2 + 0x5C080600, // 0006 MOVE R2 R3 + 0x500C0200, // 0007 LDBOOL R3 1 0 + 0x780E0022, // 0008 JMPF R3 #002C + 0x8C0C0501, // 0009 GETMET R3 R2 K1 + 0x7C0C0200, // 000A CALL R3 1 + 0x6010000C, // 000B GETGBL R4 G12 + 0x5C140600, // 000C MOVE R5 R3 + 0x7C100200, // 000D CALL R4 1 + 0x1C100902, // 000E EQ R4 R4 K2 + 0x78120000, // 000F JMPF R4 #0011 + 0x7002001A, // 0010 JMP #002C + 0x6010000C, // 0011 GETGBL R4 G12 + 0x5C140600, // 0012 MOVE R5 R3 + 0x7C100200, // 0013 CALL R4 1 + 0x24100902, // 0014 GT R4 R4 K2 + 0x7812000B, // 0015 JMPF R4 #0022 + 0x5411FFFE, // 0016 LDINT R4 -1 + 0x94100604, // 0017 GETIDX R4 R3 R4 + 0x1C100903, // 0018 EQ R4 R4 K3 + 0x74120003, // 0019 JMPT R4 #001E + 0x5411FFFE, // 001A LDINT R4 -1 + 0x94100604, // 001B GETIDX R4 R3 R4 + 0x1C100904, // 001C EQ R4 R4 K4 + 0x78120003, // 001D JMPF R4 #0022 + 0x5411FFFD, // 001E LDINT R4 -2 + 0x40120404, // 001F CONNECT R4 K2 R4 + 0x940C0604, // 0020 GETIDX R3 R3 R4 + 0x7001FFEE, // 0021 JMP #0011 + 0x6010000C, // 0022 GETGBL R4 G12 + 0x5C140600, // 0023 MOVE R5 R3 + 0x7C100200, // 0024 CALL R4 1 + 0x24100902, // 0025 GT R4 R4 K2 + 0x78120003, // 0026 JMPF R4 #002B + 0xB8120A00, // 0027 GETNGBL R4 K5 + 0x8C100906, // 0028 GETMET R4 R4 K6 + 0x5C180600, // 0029 MOVE R6 R3 + 0x7C100400, // 002A CALL R4 2 + 0x7001FFDA, // 002B JMP #0007 + 0x8C0C0507, // 002C GETMET R3 R2 K7 + 0x7C0C0200, // 002D CALL R3 1 + 0xA8040001, // 002E EXBLK 1 1 + 0x70020012, // 002F JMP #0043 + 0xAC0C0002, // 0030 CATCH R3 0 2 + 0x7002000F, // 0031 JMP #0042 + 0xB8160A00, // 0032 GETNGBL R5 K5 + 0x8C140B08, // 0033 GETMET R5 R5 K8 + 0x601C0018, // 0034 GETGBL R7 G24 + 0x58200009, // 0035 LDCONST R8 K9 + 0x5C240200, // 0036 MOVE R9 R1 + 0x5C280600, // 0037 MOVE R10 R3 + 0x5C2C0800, // 0038 MOVE R11 R4 + 0x7C1C0800, // 0039 CALL R7 4 + 0x5820000A, // 003A LDCONST R8 K10 + 0x7C140600, // 003B CALL R5 3 + 0x4C140000, // 003C LDNIL R5 + 0x20140405, // 003D NE R5 R2 R5 + 0x78160001, // 003E JMPF R5 #0041 + 0x8C140507, // 003F GETMET R5 R2 K7 + 0x7C140200, // 0040 CALL R5 1 + 0x70020000, // 0041 JMP #0043 + 0xB0080000, // 0042 RAISE 2 R0 R0 + 0x80000000, // 0043 RET 0 }) ) ); @@ -503,7 +494,7 @@ be_local_closure(Autoconf_run_bat, /* name */ ********************************************************************/ be_local_closure(Autoconf_page_autoconf_mgr, /* name */ be_nested_proto( - 19, /* nstack */ + 18, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -511,7 +502,7 @@ be_local_closure(Autoconf_page_autoconf_mgr, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[39]) { /* constants */ + ( &(const bvalue[38]) { /* constants */ /* K0 */ be_nested_str(webserver), /* K1 */ be_nested_str(string), /* K2 */ be_nested_str(check_privileged_access), @@ -529,28 +520,27 @@ be_local_closure(Autoconf_page_autoconf_mgr, /* name */ /* K14 */ be_nested_str(_X26lt_X3BError_X3A_X20apply_X20new_X20or_X20remove_X26gt_X3B), /* K15 */ be_nested_str(_X26lt_X3BNone_X26gt_X3B), /* K16 */ be_nested_str(_X3Cfieldset_X3E_X3Cstyle_X3E_X2Ebdis_X7Bbackground_X3A_X23888_X3B_X7D_X2Ebdis_X3Ahover_X7Bbackground_X3A_X23888_X3B_X7D_X3C_X2Fstyle_X3E), - /* K17 */ be_nested_str(format), - /* K18 */ be_nested_str(_X3Clegend_X3E_X3Cb_X20title_X3D_X27Autoconfiguration_X27_X3E_X26nbsp_X3BCurrent_X20auto_X2Dconfiguration_X3C_X2Fb_X3E_X3C_X2Flegend_X3E), - /* K19 */ be_nested_str(_X3Cp_X3ECurrent_X20configuration_X3A_X20_X3C_X2Fp_X3E_X3Cp_X3E_X3Cb_X3E_X25s_X3C_X2Fb_X3E_X3C_X2Fp_X3E), - /* K20 */ be_nested_str(_X3Cp_X3E_X3Cform_X20id_X3Dreapply_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20action_X3D_X27_X2Fac_X27_X20method_X3D_X27post_X27_X20), - /* K21 */ be_nested_str(onsubmit_X3D_X27return_X20confirm_X28_X22This_X20will_X20cause_X20a_X20restart_X2E_X22_X29_X3B_X27_X3E), - /* K22 */ be_nested_str(_X3Cbutton_X20name_X3D_X27reapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3ERe_X2Dapply_X20current_X20configuration_X3C_X2Fbutton_X3E), - /* K23 */ be_nested_str(_X3C_X2Fform_X3E_X3C_X2Fp_X3E), - /* K24 */ be_nested_str(_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E), - /* K25 */ be_nested_str(_X3Clegend_X3E_X3Cb_X20title_X3D_X27New_X20autoconf_X27_X3E_X26nbsp_X3BSelect_X20new_X20auto_X2Dconfiguration_X3C_X2Fb_X3E_X3C_X2Flegend_X3E), - /* K26 */ be_nested_str(_X3Cp_X3E_X3Cform_X20id_X3Dzip_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20action_X3D_X27_X2Fac_X27_X20method_X3D_X27post_X27_X20), - /* K27 */ be_nested_str(onsubmit_X3D_X27return_X20confirm_X28_X22This_X20will_X20change_X20the_X20current_X20configuration_X20and_X20cause_X20a_X20restart_X2E_X22_X29_X3B_X27_X3E), - /* K28 */ be_nested_str(_X3Clabel_X3EChoose_X20a_X20device_X20configuration_X3A_X3C_X2Flabel_X3E_X3Cbr_X3E), - /* K29 */ be_nested_str(_X3Cselect_X20name_X3D_X27zip_X27_X3E), - /* K30 */ be_nested_str(load_templates), - /* K31 */ be_nested_str(_X3Coption_X20value_X3D_X27reset_X27_X3E_X26lt_X3BRemove_X20autoconf_X26gt_X3B_X3C_X2Foption_X3E), - /* K32 */ be_nested_str(_X3Coption_X20value_X3D_X27_X25s_X27_X3E_X25s_X3C_X2Foption_X3E), - /* K33 */ be_nested_str(stop_iteration), - /* K34 */ be_nested_str(_X3C_X2Fselect_X3E_X3Cp_X3E_X3C_X2Fp_X3E), - /* K35 */ be_nested_str(_X3Cbutton_X20name_X3D_X27zipapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3EApply_X20configuration_X3C_X2Fbutton_X3E), - /* K36 */ be_nested_str(content_button), - /* K37 */ be_nested_str(BUTTON_CONFIGURATION), - /* K38 */ be_nested_str(content_stop), + /* K17 */ be_nested_str(_X3Clegend_X3E_X3Cb_X20title_X3D_X27Autoconfiguration_X27_X3E_X26nbsp_X3BCurrent_X20auto_X2Dconfiguration_X3C_X2Fb_X3E_X3C_X2Flegend_X3E), + /* K18 */ be_nested_str(_X3Cp_X3ECurrent_X20configuration_X3A_X20_X3C_X2Fp_X3E_X3Cp_X3E_X3Cb_X3E_X25s_X3C_X2Fb_X3E_X3C_X2Fp_X3E), + /* K19 */ be_nested_str(_X3Cp_X3E_X3Cform_X20id_X3Dreapply_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20action_X3D_X27_X2Fac_X27_X20method_X3D_X27post_X27_X20), + /* K20 */ be_nested_str(onsubmit_X3D_X27return_X20confirm_X28_X22This_X20will_X20cause_X20a_X20restart_X2E_X22_X29_X3B_X27_X3E), + /* K21 */ be_nested_str(_X3Cbutton_X20name_X3D_X27reapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3ERe_X2Dapply_X20current_X20configuration_X3C_X2Fbutton_X3E), + /* K22 */ be_nested_str(_X3C_X2Fform_X3E_X3C_X2Fp_X3E), + /* K23 */ be_nested_str(_X3Cp_X3E_X3C_X2Fp_X3E_X3C_X2Ffieldset_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K24 */ be_nested_str(_X3Clegend_X3E_X3Cb_X20title_X3D_X27New_X20autoconf_X27_X3E_X26nbsp_X3BSelect_X20new_X20auto_X2Dconfiguration_X3C_X2Fb_X3E_X3C_X2Flegend_X3E), + /* K25 */ be_nested_str(_X3Cp_X3E_X3Cform_X20id_X3Dzip_X20style_X3D_X27display_X3A_X20block_X3B_X27_X20action_X3D_X27_X2Fac_X27_X20method_X3D_X27post_X27_X20), + /* K26 */ be_nested_str(onsubmit_X3D_X27return_X20confirm_X28_X22This_X20will_X20change_X20the_X20current_X20configuration_X20and_X20cause_X20a_X20restart_X2E_X22_X29_X3B_X27_X3E), + /* K27 */ be_nested_str(_X3Clabel_X3EChoose_X20a_X20device_X20configuration_X3A_X3C_X2Flabel_X3E_X3Cbr_X3E), + /* K28 */ be_nested_str(_X3Cselect_X20name_X3D_X27zip_X27_X3E), + /* K29 */ be_nested_str(load_templates), + /* K30 */ be_nested_str(_X3Coption_X20value_X3D_X27reset_X27_X3E_X26lt_X3BRemove_X20autoconf_X26gt_X3B_X3C_X2Foption_X3E), + /* K31 */ be_nested_str(_X3Coption_X20value_X3D_X27_X25s_X27_X3E_X25s_X3C_X2Foption_X3E), + /* K32 */ be_nested_str(stop_iteration), + /* K33 */ be_nested_str(_X3C_X2Fselect_X3E_X3Cp_X3E_X3C_X2Fp_X3E), + /* K34 */ be_nested_str(_X3Cbutton_X20name_X3D_X27zipapply_X27_X20class_X3D_X27button_X20bgrn_X27_X3EApply_X20configuration_X3C_X2Fbutton_X3E), + /* K35 */ be_nested_str(content_button), + /* K36 */ be_nested_str(BUTTON_CONFIGURATION), + /* K37 */ be_nested_str(content_stop), }), &be_const_str_page_autoconf_mgr, &be_const_str_solidified, @@ -589,56 +579,56 @@ be_local_closure(Autoconf_page_autoconf_mgr, /* name */ 0x581C0010, // 001F LDCONST R7 K16 0x7C140400, // 0020 CALL R5 2 0x8C140306, // 0021 GETMET R5 R1 K6 - 0x8C1C0511, // 0022 GETMET R7 R2 K17 - 0x58240012, // 0023 LDCONST R9 K18 - 0x7C1C0400, // 0024 CALL R7 2 + 0x601C0018, // 0022 GETGBL R7 G24 + 0x58200011, // 0023 LDCONST R8 K17 + 0x7C1C0200, // 0024 CALL R7 1 0x7C140400, // 0025 CALL R5 2 0x8C140306, // 0026 GETMET R5 R1 K6 - 0x8C1C0511, // 0027 GETMET R7 R2 K17 - 0x58240013, // 0028 LDCONST R9 K19 - 0x5C280800, // 0029 MOVE R10 R4 - 0x7C1C0600, // 002A CALL R7 3 + 0x601C0018, // 0027 GETGBL R7 G24 + 0x58200012, // 0028 LDCONST R8 K18 + 0x5C240800, // 0029 MOVE R9 R4 + 0x7C1C0400, // 002A CALL R7 2 0x7C140400, // 002B CALL R5 2 0x780E000B, // 002C JMPF R3 #0039 0x8C140306, // 002D GETMET R5 R1 K6 - 0x581C0014, // 002E LDCONST R7 K20 + 0x581C0013, // 002E LDCONST R7 K19 0x7C140400, // 002F CALL R5 2 0x8C140306, // 0030 GETMET R5 R1 K6 - 0x581C0015, // 0031 LDCONST R7 K21 + 0x581C0014, // 0031 LDCONST R7 K20 0x7C140400, // 0032 CALL R5 2 0x8C140306, // 0033 GETMET R5 R1 K6 - 0x581C0016, // 0034 LDCONST R7 K22 + 0x581C0015, // 0034 LDCONST R7 K21 0x7C140400, // 0035 CALL R5 2 0x8C140306, // 0036 GETMET R5 R1 K6 - 0x581C0017, // 0037 LDCONST R7 K23 + 0x581C0016, // 0037 LDCONST R7 K22 0x7C140400, // 0038 CALL R5 2 0x8C140306, // 0039 GETMET R5 R1 K6 - 0x581C0018, // 003A LDCONST R7 K24 + 0x581C0017, // 003A LDCONST R7 K23 0x7C140400, // 003B CALL R5 2 0x8C140306, // 003C GETMET R5 R1 K6 0x581C0010, // 003D LDCONST R7 K16 0x7C140400, // 003E CALL R5 2 0x8C140306, // 003F GETMET R5 R1 K6 - 0x8C1C0511, // 0040 GETMET R7 R2 K17 - 0x58240019, // 0041 LDCONST R9 K25 - 0x7C1C0400, // 0042 CALL R7 2 + 0x601C0018, // 0040 GETGBL R7 G24 + 0x58200018, // 0041 LDCONST R8 K24 + 0x7C1C0200, // 0042 CALL R7 1 0x7C140400, // 0043 CALL R5 2 0x8C140306, // 0044 GETMET R5 R1 K6 - 0x581C001A, // 0045 LDCONST R7 K26 + 0x581C0019, // 0045 LDCONST R7 K25 0x7C140400, // 0046 CALL R5 2 0x8C140306, // 0047 GETMET R5 R1 K6 - 0x581C001B, // 0048 LDCONST R7 K27 + 0x581C001A, // 0048 LDCONST R7 K26 0x7C140400, // 0049 CALL R5 2 0x8C140306, // 004A GETMET R5 R1 K6 - 0x581C001C, // 004B LDCONST R7 K28 + 0x581C001B, // 004B LDCONST R7 K27 0x7C140400, // 004C CALL R5 2 0x8C140306, // 004D GETMET R5 R1 K6 - 0x581C001D, // 004E LDCONST R7 K29 + 0x581C001C, // 004E LDCONST R7 K28 0x7C140400, // 004F CALL R5 2 - 0x8C14011E, // 0050 GETMET R5 R0 K30 + 0x8C14011D, // 0050 GETMET R5 R0 K29 0x7C140200, // 0051 CALL R5 1 0x8C180306, // 0052 GETMET R6 R1 K6 - 0x5820001F, // 0053 LDCONST R8 K31 + 0x5820001E, // 0053 LDCONST R8 K30 0x7C180400, // 0054 CALL R6 2 0x60180010, // 0055 GETGBL R6 G16 0x5C1C0A00, // 0056 MOVE R7 R5 @@ -647,36 +637,36 @@ be_local_closure(Autoconf_page_autoconf_mgr, /* name */ 0x5C1C0C00, // 0059 MOVE R7 R6 0x7C1C0000, // 005A CALL R7 0 0x8C200306, // 005B GETMET R8 R1 K6 - 0x8C280511, // 005C GETMET R10 R2 K17 - 0x58300020, // 005D LDCONST R12 K32 - 0x5C340E00, // 005E MOVE R13 R7 - 0x8C380509, // 005F GETMET R14 R2 K9 - 0x5C400E00, // 0060 MOVE R16 R7 - 0x5844000B, // 0061 LDCONST R17 K11 - 0x5848000C, // 0062 LDCONST R18 K12 - 0x7C380800, // 0063 CALL R14 4 - 0x7C280800, // 0064 CALL R10 4 + 0x60280018, // 005C GETGBL R10 G24 + 0x582C001F, // 005D LDCONST R11 K31 + 0x5C300E00, // 005E MOVE R12 R7 + 0x8C340509, // 005F GETMET R13 R2 K9 + 0x5C3C0E00, // 0060 MOVE R15 R7 + 0x5840000B, // 0061 LDCONST R16 K11 + 0x5844000C, // 0062 LDCONST R17 K12 + 0x7C340800, // 0063 CALL R13 4 + 0x7C280600, // 0064 CALL R10 3 0x7C200400, // 0065 CALL R8 2 0x7001FFF1, // 0066 JMP #0059 - 0x58180021, // 0067 LDCONST R6 K33 + 0x58180020, // 0067 LDCONST R6 K32 0xAC180200, // 0068 CATCH R6 1 0 0xB0080000, // 0069 RAISE 2 R0 R0 0x8C180306, // 006A GETMET R6 R1 K6 - 0x58200022, // 006B LDCONST R8 K34 + 0x58200021, // 006B LDCONST R8 K33 0x7C180400, // 006C CALL R6 2 0x8C180306, // 006D GETMET R6 R1 K6 - 0x58200023, // 006E LDCONST R8 K35 + 0x58200022, // 006E LDCONST R8 K34 0x7C180400, // 006F CALL R6 2 0x8C180306, // 0070 GETMET R6 R1 K6 - 0x58200017, // 0071 LDCONST R8 K23 + 0x58200016, // 0071 LDCONST R8 K22 0x7C180400, // 0072 CALL R6 2 0x8C180306, // 0073 GETMET R6 R1 K6 - 0x58200018, // 0074 LDCONST R8 K24 + 0x58200017, // 0074 LDCONST R8 K23 0x7C180400, // 0075 CALL R6 2 - 0x8C180324, // 0076 GETMET R6 R1 K36 - 0x88200325, // 0077 GETMBR R8 R1 K37 + 0x8C180323, // 0076 GETMET R6 R1 K35 + 0x88200324, // 0077 GETMBR R8 R1 K36 0x7C180400, // 0078 CALL R6 2 - 0x8C180326, // 0079 GETMET R6 R1 K38 + 0x8C180325, // 0079 GETMET R6 R1 K37 0x7C180200, // 007A CALL R6 1 0x80000000, // 007B RET 0 }) @@ -813,7 +803,7 @@ be_local_closure(Autoconf_set_first_time, /* name */ ********************************************************************/ be_local_closure(Autoconf_load_templates, /* name */ be_nested_proto( - 15, /* nstack */ + 13, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -821,118 +811,115 @@ be_local_closure(Autoconf_load_templates, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[21]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(json), - /* K2 */ be_nested_str(format), - /* K3 */ be_nested_str(https_X3A_X2F_X2Fraw_X2Egithubusercontent_X2Ecom_X2Ftasmota_X2Fautoconf_X2Fmain_X2F_X25s_manifest_X2Ejson), - /* K4 */ be_nested_str(tasmota), - /* K5 */ be_nested_str(arch), - /* K6 */ be_nested_str(log), - /* K7 */ be_nested_str(CFG_X3A_X20loading_X20_X27_X25s_X27), - /* K8 */ be_const_int(3), - /* K9 */ be_nested_str(webclient), - /* K10 */ be_nested_str(begin), - /* K11 */ be_nested_str(GET), - /* K12 */ be_nested_str(CFG_X3A_X20return_code_X3D_X25i), - /* K13 */ be_const_int(2), - /* K14 */ be_nested_str(get_string), - /* K15 */ be_nested_str(close), - /* K16 */ be_nested_str(load), - /* K17 */ be_nested_str(CFG_X3A_X20loaded_X20_X27_X25s_X27), - /* K18 */ be_nested_str(find), - /* K19 */ be_nested_str(files), - /* K20 */ be_nested_str(CFG_X3A_X20exception_X20_X27_X25s_X27_X20_X2D_X20_X27_X25s_X27), + ( &(const bvalue[19]) { /* constants */ + /* K0 */ be_nested_str(json), + /* K1 */ be_nested_str(https_X3A_X2F_X2Fraw_X2Egithubusercontent_X2Ecom_X2Ftasmota_X2Fautoconf_X2Fmain_X2F_X25s_manifest_X2Ejson), + /* K2 */ be_nested_str(tasmota), + /* K3 */ be_nested_str(arch), + /* K4 */ be_nested_str(log), + /* K5 */ be_nested_str(CFG_X3A_X20loading_X20_X27_X25s_X27), + /* K6 */ be_const_int(3), + /* K7 */ be_nested_str(webclient), + /* K8 */ be_nested_str(begin), + /* K9 */ be_nested_str(GET), + /* K10 */ be_nested_str(CFG_X3A_X20return_code_X3D_X25i), + /* K11 */ be_const_int(2), + /* K12 */ be_nested_str(get_string), + /* K13 */ be_nested_str(close), + /* K14 */ be_nested_str(load), + /* K15 */ be_nested_str(CFG_X3A_X20loaded_X20_X27_X25s_X27), + /* K16 */ be_nested_str(find), + /* K17 */ be_nested_str(files), + /* K18 */ be_nested_str(CFG_X3A_X20exception_X20_X27_X25s_X27_X20_X2D_X20_X27_X25s_X27), }), &be_const_str_load_templates, &be_const_str_solidified, - ( &(const binstruction[86]) { /* code */ + ( &(const binstruction[85]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0xA8020042, // 0002 EXBLK 0 #0046 - 0x8C0C0302, // 0003 GETMET R3 R1 K2 - 0x58140003, // 0004 LDCONST R5 K3 - 0xB81A0800, // 0005 GETNGBL R6 K4 - 0x8C180D05, // 0006 GETMET R6 R6 K5 - 0x7C180200, // 0007 CALL R6 1 - 0x7C0C0600, // 0008 CALL R3 3 - 0xB8120800, // 0009 GETNGBL R4 K4 - 0x8C100906, // 000A GETMET R4 R4 K6 - 0x8C180302, // 000B GETMET R6 R1 K2 - 0x58200007, // 000C LDCONST R8 K7 - 0x5C240600, // 000D MOVE R9 R3 - 0x7C180600, // 000E CALL R6 3 - 0x581C0008, // 000F LDCONST R7 K8 - 0x7C100600, // 0010 CALL R4 3 - 0xB8121200, // 0011 GETNGBL R4 K9 - 0x7C100000, // 0012 CALL R4 0 - 0x8C14090A, // 0013 GETMET R5 R4 K10 - 0x5C1C0600, // 0014 MOVE R7 R3 - 0x7C140400, // 0015 CALL R5 2 - 0x8C14090B, // 0016 GETMET R5 R4 K11 - 0x7C140200, // 0017 CALL R5 1 - 0x541A00C7, // 0018 LDINT R6 200 - 0x20180A06, // 0019 NE R6 R5 R6 - 0x781A000A, // 001A JMPF R6 #0026 - 0xB81A0800, // 001B GETNGBL R6 K4 - 0x8C180D06, // 001C GETMET R6 R6 K6 - 0x8C200302, // 001D GETMET R8 R1 K2 - 0x5828000C, // 001E LDCONST R10 K12 - 0x5C2C0A00, // 001F MOVE R11 R5 - 0x7C200600, // 0020 CALL R8 3 - 0x5824000D, // 0021 LDCONST R9 K13 - 0x7C180600, // 0022 CALL R6 3 - 0x4C180000, // 0023 LDNIL R6 - 0xA8040001, // 0024 EXBLK 1 1 - 0x80040C00, // 0025 RET 1 R6 - 0x8C18090E, // 0026 GETMET R6 R4 K14 - 0x7C180200, // 0027 CALL R6 1 - 0x8C1C090F, // 0028 GETMET R7 R4 K15 - 0x7C1C0200, // 0029 CALL R7 1 - 0x8C1C0510, // 002A GETMET R7 R2 K16 - 0x5C240C00, // 002B MOVE R9 R6 - 0x7C1C0400, // 002C CALL R7 2 - 0xB8220800, // 002D GETNGBL R8 K4 - 0x8C201106, // 002E GETMET R8 R8 K6 - 0x8C280302, // 002F GETMET R10 R1 K2 - 0x58300011, // 0030 LDCONST R12 K17 - 0x60340008, // 0031 GETGBL R13 G8 - 0x5C380E00, // 0032 MOVE R14 R7 - 0x7C340200, // 0033 CALL R13 1 - 0x7C280600, // 0034 CALL R10 3 - 0x582C0008, // 0035 LDCONST R11 K8 - 0x7C200600, // 0036 CALL R8 3 - 0x8C200F12, // 0037 GETMET R8 R7 K18 - 0x58280013, // 0038 LDCONST R10 K19 - 0x7C200400, // 0039 CALL R8 2 - 0x6024000F, // 003A GETGBL R9 G15 - 0x5C281000, // 003B MOVE R10 R8 - 0x602C0012, // 003C GETGBL R11 G18 - 0x7C240400, // 003D CALL R9 2 - 0x78260001, // 003E JMPF R9 #0041 - 0xA8040001, // 003F EXBLK 1 1 - 0x80041000, // 0040 RET 1 R8 - 0x4C240000, // 0041 LDNIL R9 - 0xA8040001, // 0042 EXBLK 1 1 - 0x80041200, // 0043 RET 1 R9 - 0xA8040001, // 0044 EXBLK 1 1 - 0x7002000E, // 0045 JMP #0055 - 0xAC0C0002, // 0046 CATCH R3 0 2 - 0x7002000B, // 0047 JMP #0054 - 0xB8160800, // 0048 GETNGBL R5 K4 - 0x8C140B06, // 0049 GETMET R5 R5 K6 - 0x8C1C0302, // 004A GETMET R7 R1 K2 - 0x58240014, // 004B LDCONST R9 K20 - 0x5C280600, // 004C MOVE R10 R3 - 0x5C2C0800, // 004D MOVE R11 R4 - 0x7C1C0800, // 004E CALL R7 4 - 0x5820000D, // 004F LDCONST R8 K13 - 0x7C140600, // 0050 CALL R5 3 - 0x4C140000, // 0051 LDNIL R5 - 0x80040A00, // 0052 RET 1 R5 - 0x70020000, // 0053 JMP #0055 - 0xB0080000, // 0054 RAISE 2 R0 R0 - 0x80000000, // 0055 RET 0 + 0xA8020042, // 0001 EXBLK 0 #0045 + 0x60080018, // 0002 GETGBL R2 G24 + 0x580C0001, // 0003 LDCONST R3 K1 + 0xB8120400, // 0004 GETNGBL R4 K2 + 0x8C100903, // 0005 GETMET R4 R4 K3 + 0x7C100200, // 0006 CALL R4 1 + 0x7C080400, // 0007 CALL R2 2 + 0xB80E0400, // 0008 GETNGBL R3 K2 + 0x8C0C0704, // 0009 GETMET R3 R3 K4 + 0x60140018, // 000A GETGBL R5 G24 + 0x58180005, // 000B LDCONST R6 K5 + 0x5C1C0400, // 000C MOVE R7 R2 + 0x7C140400, // 000D CALL R5 2 + 0x58180006, // 000E LDCONST R6 K6 + 0x7C0C0600, // 000F CALL R3 3 + 0xB80E0E00, // 0010 GETNGBL R3 K7 + 0x7C0C0000, // 0011 CALL R3 0 + 0x8C100708, // 0012 GETMET R4 R3 K8 + 0x5C180400, // 0013 MOVE R6 R2 + 0x7C100400, // 0014 CALL R4 2 + 0x8C100709, // 0015 GETMET R4 R3 K9 + 0x7C100200, // 0016 CALL R4 1 + 0x541600C7, // 0017 LDINT R5 200 + 0x20140805, // 0018 NE R5 R4 R5 + 0x7816000A, // 0019 JMPF R5 #0025 + 0xB8160400, // 001A GETNGBL R5 K2 + 0x8C140B04, // 001B GETMET R5 R5 K4 + 0x601C0018, // 001C GETGBL R7 G24 + 0x5820000A, // 001D LDCONST R8 K10 + 0x5C240800, // 001E MOVE R9 R4 + 0x7C1C0400, // 001F CALL R7 2 + 0x5820000B, // 0020 LDCONST R8 K11 + 0x7C140600, // 0021 CALL R5 3 + 0x4C140000, // 0022 LDNIL R5 + 0xA8040001, // 0023 EXBLK 1 1 + 0x80040A00, // 0024 RET 1 R5 + 0x8C14070C, // 0025 GETMET R5 R3 K12 + 0x7C140200, // 0026 CALL R5 1 + 0x8C18070D, // 0027 GETMET R6 R3 K13 + 0x7C180200, // 0028 CALL R6 1 + 0x8C18030E, // 0029 GETMET R6 R1 K14 + 0x5C200A00, // 002A MOVE R8 R5 + 0x7C180400, // 002B CALL R6 2 + 0xB81E0400, // 002C GETNGBL R7 K2 + 0x8C1C0F04, // 002D GETMET R7 R7 K4 + 0x60240018, // 002E GETGBL R9 G24 + 0x5828000F, // 002F LDCONST R10 K15 + 0x602C0008, // 0030 GETGBL R11 G8 + 0x5C300C00, // 0031 MOVE R12 R6 + 0x7C2C0200, // 0032 CALL R11 1 + 0x7C240400, // 0033 CALL R9 2 + 0x58280006, // 0034 LDCONST R10 K6 + 0x7C1C0600, // 0035 CALL R7 3 + 0x8C1C0D10, // 0036 GETMET R7 R6 K16 + 0x58240011, // 0037 LDCONST R9 K17 + 0x7C1C0400, // 0038 CALL R7 2 + 0x6020000F, // 0039 GETGBL R8 G15 + 0x5C240E00, // 003A MOVE R9 R7 + 0x60280012, // 003B GETGBL R10 G18 + 0x7C200400, // 003C CALL R8 2 + 0x78220001, // 003D JMPF R8 #0040 + 0xA8040001, // 003E EXBLK 1 1 + 0x80040E00, // 003F RET 1 R7 + 0x4C200000, // 0040 LDNIL R8 + 0xA8040001, // 0041 EXBLK 1 1 + 0x80041000, // 0042 RET 1 R8 + 0xA8040001, // 0043 EXBLK 1 1 + 0x7002000E, // 0044 JMP #0054 + 0xAC080002, // 0045 CATCH R2 0 2 + 0x7002000B, // 0046 JMP #0053 + 0xB8120400, // 0047 GETNGBL R4 K2 + 0x8C100904, // 0048 GETMET R4 R4 K4 + 0x60180018, // 0049 GETGBL R6 G24 + 0x581C0012, // 004A LDCONST R7 K18 + 0x5C200400, // 004B MOVE R8 R2 + 0x5C240600, // 004C MOVE R9 R3 + 0x7C180600, // 004D CALL R6 3 + 0x581C000B, // 004E LDCONST R7 K11 + 0x7C100600, // 004F CALL R4 3 + 0x4C100000, // 0050 LDNIL R4 + 0x80040800, // 0051 RET 1 R4 + 0x70020000, // 0052 JMP #0054 + 0xB0080000, // 0053 RAISE 2 R0 R0 + 0x80000000, // 0054 RET 0 }) ) ); @@ -1011,7 +998,7 @@ be_local_closure(Autoconf_is_first_time, /* name */ ********************************************************************/ be_local_closure(Autoconf_init, /* name */ be_nested_proto( - 13, /* nstack */ + 12, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1019,7 +1006,7 @@ be_local_closure(Autoconf_init, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[18]) { /* constants */ + ( &(const bvalue[17]) { /* constants */ /* K0 */ be_nested_str(path), /* K1 */ be_nested_str(string), /* K2 */ be_nested_str(listdir), @@ -1030,14 +1017,13 @@ be_local_closure(Autoconf_init, /* name */ /* K7 */ be_nested_str(find), /* K8 */ be_nested_str(_X2Eautoconf), /* K9 */ be_nested_str(log), - /* K10 */ be_nested_str(format), - /* K11 */ be_nested_str(CFG_X3A_X20multiple_X20autoconf_X20files_X20found_X2C_X20aborting_X20_X28_X27_X25s_X27_X20_X2B_X20_X27_X25s_X27_X29), - /* K12 */ be_const_int(2), - /* K13 */ be_nested_str(_error), - /* K14 */ be_const_int(1), - /* K15 */ be_nested_str(CFG_X3A_X20No_X20_X27_X2A_X2Eautoconf_X27_X20file_X20found), - /* K16 */ be_const_int(3), - /* K17 */ be_nested_str(_archive), + /* K10 */ be_nested_str(CFG_X3A_X20multiple_X20autoconf_X20files_X20found_X2C_X20aborting_X20_X28_X27_X25s_X27_X20_X2B_X20_X27_X25s_X27_X29), + /* K11 */ be_const_int(2), + /* K12 */ be_nested_str(_error), + /* K13 */ be_const_int(1), + /* K14 */ be_nested_str(CFG_X3A_X20No_X20_X27_X2A_X2Eautoconf_X27_X20file_X20found), + /* K15 */ be_const_int(3), + /* K16 */ be_nested_str(_archive), }), &be_const_str_init, &be_const_str_solidified, @@ -1069,31 +1055,31 @@ be_local_closure(Autoconf_init, /* name */ 0x781A000C, // 0018 JMPF R6 #0026 0xB81A0800, // 0019 GETNGBL R6 K4 0x8C180D09, // 001A GETMET R6 R6 K9 - 0x8C20050A, // 001B GETMET R8 R2 K10 - 0x5828000B, // 001C LDCONST R10 K11 - 0x5C2C0800, // 001D MOVE R11 R4 - 0x94300605, // 001E GETIDX R12 R3 R5 - 0x7C200800, // 001F CALL R8 4 - 0x5824000C, // 0020 LDCONST R9 K12 + 0x60200018, // 001B GETGBL R8 G24 + 0x5824000A, // 001C LDCONST R9 K10 + 0x5C280800, // 001D MOVE R10 R4 + 0x942C0605, // 001E GETIDX R11 R3 R5 + 0x7C200600, // 001F CALL R8 3 + 0x5824000B, // 0020 LDCONST R9 K11 0x7C180600, // 0021 CALL R6 3 0x50180200, // 0022 LDBOOL R6 1 0 - 0x90021A06, // 0023 SETMBR R0 K13 R6 + 0x90021806, // 0023 SETMBR R0 K12 R6 0x4C180000, // 0024 LDNIL R6 0x80040C00, // 0025 RET 1 R6 0x94100605, // 0026 GETIDX R4 R3 R5 - 0x00140B0E, // 0027 ADD R5 R5 K14 + 0x00140B0D, // 0027 ADD R5 R5 K13 0x7001FFE1, // 0028 JMP #000B 0x4C180000, // 0029 LDNIL R6 0x1C180806, // 002A EQ R6 R4 R6 0x781A0006, // 002B JMPF R6 #0033 0xB81A0800, // 002C GETNGBL R6 K4 0x8C180D09, // 002D GETMET R6 R6 K9 - 0x5820000F, // 002E LDCONST R8 K15 - 0x58240010, // 002F LDCONST R9 K16 + 0x5820000E, // 002E LDCONST R8 K14 + 0x5824000F, // 002F LDCONST R9 K15 0x7C180600, // 0030 CALL R6 3 0x4C180000, // 0031 LDNIL R6 0x80040C00, // 0032 RET 1 R6 - 0x90022204, // 0033 SETMBR R0 K17 R4 + 0x90022004, // 0033 SETMBR R0 K16 R4 0x80000000, // 0034 RET 0 }) ) @@ -1166,7 +1152,7 @@ be_local_closure(Autoconf_preinit, /* name */ ********************************************************************/ be_local_closure(Autoconf_reset, /* name */ be_nested_proto( - 12, /* nstack */ + 11, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1174,7 +1160,7 @@ be_local_closure(Autoconf_reset, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ + ( &(const bvalue[12]) { /* constants */ /* K0 */ be_nested_str(path), /* K1 */ be_nested_str(string), /* K2 */ be_nested_str(listdir), @@ -1183,11 +1169,10 @@ be_local_closure(Autoconf_reset, /* name */ /* K5 */ be_nested_str(find), /* K6 */ be_nested_str(_X2Eautoconf), /* K7 */ be_nested_str(remove), - /* K8 */ be_nested_str(format), - /* K9 */ be_nested_str(CFG_X3A_X20removed_X20file_X20_X27_X25s_X27), - /* K10 */ be_const_int(1), - /* K11 */ be_nested_str(_archive), - /* K12 */ be_nested_str(_error), + /* K8 */ be_nested_str(CFG_X3A_X20removed_X20file_X20_X27_X25s_X27), + /* K9 */ be_const_int(1), + /* K10 */ be_nested_str(_archive), + /* K11 */ be_nested_str(_error), }), &be_const_str_reset, &be_const_str_solidified, @@ -1215,17 +1200,17 @@ be_local_closure(Autoconf_reset, /* name */ 0x5C240C00, // 0014 MOVE R9 R6 0x7C1C0400, // 0015 CALL R7 2 0x601C0001, // 0016 GETGBL R7 G1 - 0x8C200508, // 0017 GETMET R8 R2 K8 - 0x58280009, // 0018 LDCONST R10 K9 - 0x5C2C0C00, // 0019 MOVE R11 R6 - 0x7C200600, // 001A CALL R8 3 + 0x60200018, // 0017 GETGBL R8 G24 + 0x58240008, // 0018 LDCONST R9 K8 + 0x5C280C00, // 0019 MOVE R10 R6 + 0x7C200400, // 001A CALL R8 2 0x7C1C0200, // 001B CALL R7 1 - 0x00140B0A, // 001C ADD R5 R5 K10 + 0x00140B09, // 001C ADD R5 R5 K9 0x7001FFE8, // 001D JMP #0007 0x4C180000, // 001E LDNIL R6 - 0x90021606, // 001F SETMBR R0 K11 R6 + 0x90021406, // 001F SETMBR R0 K10 R6 0x4C180000, // 0020 LDNIL R6 - 0x90021806, // 0021 SETMBR R0 K12 R6 + 0x90021606, // 0021 SETMBR R0 K11 R6 0x80000000, // 0022 RET 0 }) ) diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_crypto_spake2p_matter.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_crypto_spake2p_matter.h index 5d430efaa4aa..ea49d8ed8c55 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_crypto_spake2p_matter.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_crypto_spake2p_matter.h @@ -239,121 +239,122 @@ be_local_closure(SPAKE2P_Matter_compute_TT_hash, /* name */ }), be_str_weak(compute_TT_hash), &be_const_str_solidified, - ( &(const binstruction[114]) { /* code */ + ( &(const binstruction[115]) { /* code */ 0x58080000, // 0000 LDCONST R2 K0 0xB4000000, // 0001 CLASS K0 - 0xA40E0200, // 0002 IMPORT R3 K1 - 0x5C100400, // 0003 MOVE R4 R2 - 0x7C100000, // 0004 CALL R4 0 - 0x8C140902, // 0005 GETMET R5 R4 K2 - 0x881C0103, // 0006 GETMBR R7 R0 K3 - 0x7C140400, // 0007 CALL R5 2 - 0x8C140902, // 0008 GETMET R5 R4 K2 - 0x881C0104, // 0009 GETMBR R7 R0 K4 - 0x7C140400, // 000A CALL R5 2 - 0x8C140902, // 000B GETMET R5 R4 K2 - 0x881C0105, // 000C GETMBR R7 R0 K5 - 0x7C140400, // 000D CALL R5 2 - 0x8C140902, // 000E GETMET R5 R4 K2 - 0x881C0106, // 000F GETMBR R7 R0 K6 - 0x7C140400, // 0010 CALL R5 2 - 0x8C140902, // 0011 GETMET R5 R4 K2 - 0x881C0107, // 0012 GETMBR R7 R0 K7 - 0x7C140400, // 0013 CALL R5 2 - 0x8C140902, // 0014 GETMET R5 R4 K2 - 0x881C0108, // 0015 GETMBR R7 R0 K8 - 0x7C140400, // 0016 CALL R5 2 - 0x8C140902, // 0017 GETMET R5 R4 K2 - 0x881C0109, // 0018 GETMBR R7 R0 K9 - 0x7C140400, // 0019 CALL R5 2 - 0x8C140902, // 001A GETMET R5 R4 K2 - 0x881C010A, // 001B GETMBR R7 R0 K10 - 0x7C140400, // 001C CALL R5 2 - 0x8C140902, // 001D GETMET R5 R4 K2 - 0x881C010B, // 001E GETMBR R7 R0 K11 - 0x7C140400, // 001F CALL R5 2 - 0x8C140902, // 0020 GETMET R5 R4 K2 - 0x881C010C, // 0021 GETMBR R7 R0 K12 - 0x7C140400, // 0022 CALL R5 2 - 0x8C14090E, // 0023 GETMET R5 R4 K14 - 0x7C140200, // 0024 CALL R5 1 - 0x90021A05, // 0025 SETMBR R0 K13 R5 - 0x7806000A, // 0026 JMPF R1 #0032 - 0x5416000F, // 0027 LDINT R5 16 - 0x541A001E, // 0028 LDINT R6 31 - 0x40140A06, // 0029 CONNECT R5 R5 R6 - 0x8818010D, // 002A GETMBR R6 R0 K13 - 0x94140C05, // 002B GETIDX R5 R6 R5 - 0x90021E05, // 002C SETMBR R0 K15 R5 - 0x5416000E, // 002D LDINT R5 15 - 0x40162005, // 002E CONNECT R5 K16 R5 - 0x8818010D, // 002F GETMBR R6 R0 K13 - 0x94140C05, // 0030 GETIDX R5 R6 R5 - 0x90021A05, // 0031 SETMBR R0 K13 R5 - 0x8C140711, // 0032 GETMET R5 R3 K17 - 0x7C140200, // 0033 CALL R5 1 - 0x8C180B12, // 0034 GETMET R6 R5 K18 - 0x8820010D, // 0035 GETMBR R8 R0 K13 - 0x60240015, // 0036 GETGBL R9 G21 - 0x7C240000, // 0037 CALL R9 0 - 0x60280015, // 0038 GETGBL R10 G21 - 0x7C280000, // 0039 CALL R10 0 - 0x8C281513, // 003A GETMET R10 R10 K19 - 0x58300014, // 003B LDCONST R12 K20 - 0x7C280400, // 003C CALL R10 2 - 0x542E003F, // 003D LDINT R11 64 - 0x7C180A00, // 003E CALL R6 5 - 0x78060003, // 003F JMPF R1 #0044 - 0x541E000E, // 0040 LDINT R7 15 - 0x401E2007, // 0041 CONNECT R7 K16 R7 - 0x941C0C07, // 0042 GETIDX R7 R6 R7 - 0x70020002, // 0043 JMP #0047 - 0x541E001E, // 0044 LDINT R7 31 - 0x401E2007, // 0045 CONNECT R7 K16 R7 - 0x941C0C07, // 0046 GETIDX R7 R6 R7 - 0x90022A07, // 0047 SETMBR R0 K21 R7 - 0x78060004, // 0048 JMPF R1 #004E - 0x541E000F, // 0049 LDINT R7 16 - 0x5422001E, // 004A LDINT R8 31 - 0x401C0E08, // 004B CONNECT R7 R7 R8 - 0x941C0C07, // 004C GETIDX R7 R6 R7 - 0x70020003, // 004D JMP #0052 - 0x541E001F, // 004E LDINT R7 32 - 0x5422003E, // 004F LDINT R8 63 - 0x401C0E08, // 0050 CONNECT R7 R7 R8 - 0x941C0C07, // 0051 GETIDX R7 R6 R7 - 0x90022C07, // 0052 SETMBR R0 K22 R7 - 0x8C1C0B12, // 0053 GETMET R7 R5 K18 - 0x8824010D, // 0054 GETMBR R9 R0 K13 - 0x60280015, // 0055 GETGBL R10 G21 - 0x7C280000, // 0056 CALL R10 0 - 0x602C0015, // 0057 GETGBL R11 G21 - 0x7C2C0000, // 0058 CALL R11 0 - 0x8C2C1713, // 0059 GETMET R11 R11 K19 - 0x58340018, // 005A LDCONST R13 K24 - 0x7C2C0400, // 005B CALL R11 2 - 0x5432001F, // 005C LDINT R12 32 - 0x7C1C0A00, // 005D CALL R7 5 - 0x90022E07, // 005E SETMBR R0 K23 R7 - 0x8C1C071A, // 005F GETMET R7 R3 K26 - 0x88240115, // 0060 GETMBR R9 R0 K21 - 0x7C1C0400, // 0061 CALL R7 2 - 0x8C1C0F1B, // 0062 GETMET R7 R7 K27 - 0x88240109, // 0063 GETMBR R9 R0 K9 - 0x7C1C0400, // 0064 CALL R7 2 - 0x8C1C0F0E, // 0065 GETMET R7 R7 K14 - 0x7C1C0200, // 0066 CALL R7 1 - 0x90023207, // 0067 SETMBR R0 K25 R7 - 0x8C1C071A, // 0068 GETMET R7 R3 K26 - 0x88240116, // 0069 GETMBR R9 R0 K22 - 0x7C1C0400, // 006A CALL R7 2 - 0x8C1C0F1B, // 006B GETMET R7 R7 K27 - 0x88240108, // 006C GETMBR R9 R0 K8 - 0x7C1C0400, // 006D CALL R7 2 - 0x8C1C0F0E, // 006E GETMET R7 R7 K14 - 0x7C1C0200, // 006F CALL R7 1 - 0x90023807, // 0070 SETMBR R0 K28 R7 - 0x80000000, // 0071 RET 0 + 0x5C0C0400, // 0002 MOVE R3 R2 + 0xA40E0200, // 0003 IMPORT R3 K1 + 0x5C100400, // 0004 MOVE R4 R2 + 0x7C100000, // 0005 CALL R4 0 + 0x8C140902, // 0006 GETMET R5 R4 K2 + 0x881C0103, // 0007 GETMBR R7 R0 K3 + 0x7C140400, // 0008 CALL R5 2 + 0x8C140902, // 0009 GETMET R5 R4 K2 + 0x881C0104, // 000A GETMBR R7 R0 K4 + 0x7C140400, // 000B CALL R5 2 + 0x8C140902, // 000C GETMET R5 R4 K2 + 0x881C0105, // 000D GETMBR R7 R0 K5 + 0x7C140400, // 000E CALL R5 2 + 0x8C140902, // 000F GETMET R5 R4 K2 + 0x881C0106, // 0010 GETMBR R7 R0 K6 + 0x7C140400, // 0011 CALL R5 2 + 0x8C140902, // 0012 GETMET R5 R4 K2 + 0x881C0107, // 0013 GETMBR R7 R0 K7 + 0x7C140400, // 0014 CALL R5 2 + 0x8C140902, // 0015 GETMET R5 R4 K2 + 0x881C0108, // 0016 GETMBR R7 R0 K8 + 0x7C140400, // 0017 CALL R5 2 + 0x8C140902, // 0018 GETMET R5 R4 K2 + 0x881C0109, // 0019 GETMBR R7 R0 K9 + 0x7C140400, // 001A CALL R5 2 + 0x8C140902, // 001B GETMET R5 R4 K2 + 0x881C010A, // 001C GETMBR R7 R0 K10 + 0x7C140400, // 001D CALL R5 2 + 0x8C140902, // 001E GETMET R5 R4 K2 + 0x881C010B, // 001F GETMBR R7 R0 K11 + 0x7C140400, // 0020 CALL R5 2 + 0x8C140902, // 0021 GETMET R5 R4 K2 + 0x881C010C, // 0022 GETMBR R7 R0 K12 + 0x7C140400, // 0023 CALL R5 2 + 0x8C14090E, // 0024 GETMET R5 R4 K14 + 0x7C140200, // 0025 CALL R5 1 + 0x90021A05, // 0026 SETMBR R0 K13 R5 + 0x7806000A, // 0027 JMPF R1 #0033 + 0x5416000F, // 0028 LDINT R5 16 + 0x541A001E, // 0029 LDINT R6 31 + 0x40140A06, // 002A CONNECT R5 R5 R6 + 0x8818010D, // 002B GETMBR R6 R0 K13 + 0x94140C05, // 002C GETIDX R5 R6 R5 + 0x90021E05, // 002D SETMBR R0 K15 R5 + 0x5416000E, // 002E LDINT R5 15 + 0x40162005, // 002F CONNECT R5 K16 R5 + 0x8818010D, // 0030 GETMBR R6 R0 K13 + 0x94140C05, // 0031 GETIDX R5 R6 R5 + 0x90021A05, // 0032 SETMBR R0 K13 R5 + 0x8C140711, // 0033 GETMET R5 R3 K17 + 0x7C140200, // 0034 CALL R5 1 + 0x8C180B12, // 0035 GETMET R6 R5 K18 + 0x8820010D, // 0036 GETMBR R8 R0 K13 + 0x60240015, // 0037 GETGBL R9 G21 + 0x7C240000, // 0038 CALL R9 0 + 0x60280015, // 0039 GETGBL R10 G21 + 0x7C280000, // 003A CALL R10 0 + 0x8C281513, // 003B GETMET R10 R10 K19 + 0x58300014, // 003C LDCONST R12 K20 + 0x7C280400, // 003D CALL R10 2 + 0x542E003F, // 003E LDINT R11 64 + 0x7C180A00, // 003F CALL R6 5 + 0x78060003, // 0040 JMPF R1 #0045 + 0x541E000E, // 0041 LDINT R7 15 + 0x401E2007, // 0042 CONNECT R7 K16 R7 + 0x941C0C07, // 0043 GETIDX R7 R6 R7 + 0x70020002, // 0044 JMP #0048 + 0x541E001E, // 0045 LDINT R7 31 + 0x401E2007, // 0046 CONNECT R7 K16 R7 + 0x941C0C07, // 0047 GETIDX R7 R6 R7 + 0x90022A07, // 0048 SETMBR R0 K21 R7 + 0x78060004, // 0049 JMPF R1 #004F + 0x541E000F, // 004A LDINT R7 16 + 0x5422001E, // 004B LDINT R8 31 + 0x401C0E08, // 004C CONNECT R7 R7 R8 + 0x941C0C07, // 004D GETIDX R7 R6 R7 + 0x70020003, // 004E JMP #0053 + 0x541E001F, // 004F LDINT R7 32 + 0x5422003E, // 0050 LDINT R8 63 + 0x401C0E08, // 0051 CONNECT R7 R7 R8 + 0x941C0C07, // 0052 GETIDX R7 R6 R7 + 0x90022C07, // 0053 SETMBR R0 K22 R7 + 0x8C1C0B12, // 0054 GETMET R7 R5 K18 + 0x8824010D, // 0055 GETMBR R9 R0 K13 + 0x60280015, // 0056 GETGBL R10 G21 + 0x7C280000, // 0057 CALL R10 0 + 0x602C0015, // 0058 GETGBL R11 G21 + 0x7C2C0000, // 0059 CALL R11 0 + 0x8C2C1713, // 005A GETMET R11 R11 K19 + 0x58340018, // 005B LDCONST R13 K24 + 0x7C2C0400, // 005C CALL R11 2 + 0x5432001F, // 005D LDINT R12 32 + 0x7C1C0A00, // 005E CALL R7 5 + 0x90022E07, // 005F SETMBR R0 K23 R7 + 0x8C1C071A, // 0060 GETMET R7 R3 K26 + 0x88240115, // 0061 GETMBR R9 R0 K21 + 0x7C1C0400, // 0062 CALL R7 2 + 0x8C1C0F1B, // 0063 GETMET R7 R7 K27 + 0x88240109, // 0064 GETMBR R9 R0 K9 + 0x7C1C0400, // 0065 CALL R7 2 + 0x8C1C0F0E, // 0066 GETMET R7 R7 K14 + 0x7C1C0200, // 0067 CALL R7 1 + 0x90023207, // 0068 SETMBR R0 K25 R7 + 0x8C1C071A, // 0069 GETMET R7 R3 K26 + 0x88240116, // 006A GETMBR R9 R0 K22 + 0x7C1C0400, // 006B CALL R7 2 + 0x8C1C0F1B, // 006C GETMET R7 R7 K27 + 0x88240108, // 006D GETMBR R9 R0 K8 + 0x7C1C0400, // 006E CALL R7 2 + 0x8C1C0F0E, // 006F GETMET R7 R7 K14 + 0x7C1C0200, // 0070 CALL R7 1 + 0x90023807, // 0071 SETMBR R0 K28 R7 + 0x80000000, // 0072 RET 0 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_hue_bridge.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_hue_bridge.h index caad7d225cb5..1b026afda741 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_hue_bridge.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_hue_bridge.h @@ -243,7 +243,7 @@ be_local_closure(hue_bridge_monad_init, /* name */ ********************************************************************/ be_local_closure(hue_bridge_monad_discover, /* name */ be_nested_proto( - 11, /* nstack */ + 10, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -251,64 +251,62 @@ be_local_closure(hue_bridge_monad_discover, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ + ( &(const bvalue[12]) { /* constants */ /* K0 */ be_nested_str(hue_ntv), /* K1 */ be_nested_str(json), - /* K2 */ be_nested_str(string), - /* K3 */ be_nested_str(lights), - /* K4 */ be_nested_str(keys), - /* K5 */ be_nested_str(full_status), - /* K6 */ be_nested_str(_X22), - /* K7 */ be_nested_str(_X22_X3A), - /* K8 */ be_nested_str(push), - /* K9 */ be_nested_str(stop_iteration), - /* K10 */ be_const_int(0), - /* K11 */ be_nested_str(concat), - /* K12 */ be_nested_str(_X2C), + /* K2 */ be_nested_str(lights), + /* K3 */ be_nested_str(keys), + /* K4 */ be_nested_str(full_status), + /* K5 */ be_nested_str(_X22), + /* K6 */ be_nested_str(_X22_X3A), + /* K7 */ be_nested_str(push), + /* K8 */ be_nested_str(stop_iteration), + /* K9 */ be_const_int(0), + /* K10 */ be_nested_str(concat), + /* K11 */ be_nested_str(_X2C), }), &be_const_str_discover, &be_const_str_solidified, - ( &(const binstruction[40]) { /* code */ + ( &(const binstruction[39]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 0xA40A0200, // 0001 IMPORT R2 K1 - 0xA40E0400, // 0002 IMPORT R3 K2 - 0x60100012, // 0003 GETGBL R4 G18 - 0x7C100000, // 0004 CALL R4 0 - 0x60140010, // 0005 GETGBL R5 G16 - 0x88180103, // 0006 GETMBR R6 R0 K3 - 0x8C180D04, // 0007 GETMET R6 R6 K4 - 0x7C180200, // 0008 CALL R6 1 - 0x7C140200, // 0009 CALL R5 1 - 0xA802000F, // 000A EXBLK 0 #001B - 0x5C180A00, // 000B MOVE R6 R5 - 0x7C180000, // 000C CALL R6 0 - 0x8C1C0105, // 000D GETMET R7 R0 K5 - 0x5C240C00, // 000E MOVE R9 R6 - 0x7C1C0400, // 000F CALL R7 2 - 0x781E0008, // 0010 JMPF R7 #001A - 0x60200008, // 0011 GETGBL R8 G8 - 0x5C240C00, // 0012 MOVE R9 R6 - 0x7C200200, // 0013 CALL R8 1 - 0x00220C08, // 0014 ADD R8 K6 R8 - 0x00201107, // 0015 ADD R8 R8 K7 - 0x001C1007, // 0016 ADD R7 R8 R7 - 0x8C200908, // 0017 GETMET R8 R4 K8 - 0x5C280E00, // 0018 MOVE R10 R7 - 0x7C200400, // 0019 CALL R8 2 - 0x7001FFEF, // 001A JMP #000B - 0x58140009, // 001B LDCONST R5 K9 - 0xAC140200, // 001C CATCH R5 1 0 - 0xB0080000, // 001D RAISE 2 R0 R0 - 0x6014000C, // 001E GETGBL R5 G12 - 0x5C180800, // 001F MOVE R6 R4 - 0x7C140200, // 0020 CALL R5 1 - 0x24140B0A, // 0021 GT R5 R5 K10 - 0x78160003, // 0022 JMPF R5 #0027 - 0x8C14090B, // 0023 GETMET R5 R4 K11 - 0x581C000C, // 0024 LDCONST R7 K12 - 0x7C140400, // 0025 CALL R5 2 - 0x80040A00, // 0026 RET 1 R5 - 0x80000000, // 0027 RET 0 + 0x600C0012, // 0002 GETGBL R3 G18 + 0x7C0C0000, // 0003 CALL R3 0 + 0x60100010, // 0004 GETGBL R4 G16 + 0x88140102, // 0005 GETMBR R5 R0 K2 + 0x8C140B03, // 0006 GETMET R5 R5 K3 + 0x7C140200, // 0007 CALL R5 1 + 0x7C100200, // 0008 CALL R4 1 + 0xA802000F, // 0009 EXBLK 0 #001A + 0x5C140800, // 000A MOVE R5 R4 + 0x7C140000, // 000B CALL R5 0 + 0x8C180104, // 000C GETMET R6 R0 K4 + 0x5C200A00, // 000D MOVE R8 R5 + 0x7C180400, // 000E CALL R6 2 + 0x781A0008, // 000F JMPF R6 #0019 + 0x601C0008, // 0010 GETGBL R7 G8 + 0x5C200A00, // 0011 MOVE R8 R5 + 0x7C1C0200, // 0012 CALL R7 1 + 0x001E0A07, // 0013 ADD R7 K5 R7 + 0x001C0F06, // 0014 ADD R7 R7 K6 + 0x00180E06, // 0015 ADD R6 R7 R6 + 0x8C1C0707, // 0016 GETMET R7 R3 K7 + 0x5C240C00, // 0017 MOVE R9 R6 + 0x7C1C0400, // 0018 CALL R7 2 + 0x7001FFEF, // 0019 JMP #000A + 0x58100008, // 001A LDCONST R4 K8 + 0xAC100200, // 001B CATCH R4 1 0 + 0xB0080000, // 001C RAISE 2 R0 R0 + 0x6010000C, // 001D GETGBL R4 G12 + 0x5C140600, // 001E MOVE R5 R3 + 0x7C100200, // 001F CALL R4 1 + 0x24100909, // 0020 GT R4 R4 K9 + 0x78120003, // 0021 JMPF R4 #0026 + 0x8C10070A, // 0022 GETMET R4 R3 K10 + 0x5818000B, // 0023 LDCONST R6 K11 + 0x7C100400, // 0024 CALL R4 2 + 0x80040800, // 0025 RET 1 R4 + 0x80000000, // 0026 RET 0 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_i2c_axp192.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_i2c_axp192.h index 2ef43a553241..27a7bf5a7945 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_i2c_axp192.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_i2c_axp192.h @@ -516,7 +516,7 @@ be_local_closure(AXP192_set_ldo_voltage, /* name */ ********************************************************************/ be_local_closure(AXP192_json_append, /* name */ be_nested_proto( - 11, /* nstack */ + 9, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -524,44 +524,41 @@ be_local_closure(AXP192_json_append, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ + ( &(const bvalue[ 8]) { /* constants */ /* K0 */ be_nested_str(wire), - /* K1 */ be_nested_str(string), - /* K2 */ be_nested_str(format), - /* K3 */ be_nested_str(_X2C_X22AXP192_X22_X3A_X7B_X22VBusVoltage_X22_X3A_X25_X2E3f_X2C_X22VBusCurrent_X22_X3A_X25_X2E1f_X2C_X22BattVoltage_X22_X3A_X25_X2E3f_X2C_X22BattCurrent_X22_X3A_X25_X2E1f_X2C_X22Temperature_X22_X3A_X25_X2E1f_X7D), - /* K4 */ be_nested_str(get_vbus_voltage), - /* K5 */ be_nested_str(get_bat_voltage), - /* K6 */ be_nested_str(get_bat_current), - /* K7 */ be_nested_str(get_temp), - /* K8 */ be_nested_str(tasmota), - /* K9 */ be_nested_str(response_append), + /* K1 */ be_nested_str(_X2C_X22AXP192_X22_X3A_X7B_X22VBusVoltage_X22_X3A_X25_X2E3f_X2C_X22VBusCurrent_X22_X3A_X25_X2E1f_X2C_X22BattVoltage_X22_X3A_X25_X2E3f_X2C_X22BattCurrent_X22_X3A_X25_X2E1f_X2C_X22Temperature_X22_X3A_X25_X2E1f_X7D), + /* K2 */ be_nested_str(get_vbus_voltage), + /* K3 */ be_nested_str(get_bat_voltage), + /* K4 */ be_nested_str(get_bat_current), + /* K5 */ be_nested_str(get_temp), + /* K6 */ be_nested_str(tasmota), + /* K7 */ be_nested_str(response_append), }), &be_const_str_json_append, &be_const_str_solidified, - ( &(const binstruction[23]) { /* code */ + ( &(const binstruction[22]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 0x74060001, // 0001 JMPT R1 #0004 0x4C040000, // 0002 LDNIL R1 0x80040200, // 0003 RET 1 R1 - 0xA4060200, // 0004 IMPORT R1 K1 - 0x8C080302, // 0005 GETMET R2 R1 K2 - 0x58100003, // 0006 LDCONST R4 K3 - 0x8C140104, // 0007 GETMET R5 R0 K4 - 0x7C140200, // 0008 CALL R5 1 - 0x8C180104, // 0009 GETMET R6 R0 K4 - 0x7C180200, // 000A CALL R6 1 - 0x8C1C0105, // 000B GETMET R7 R0 K5 - 0x7C1C0200, // 000C CALL R7 1 - 0x8C200106, // 000D GETMET R8 R0 K6 - 0x7C200200, // 000E CALL R8 1 - 0x8C240107, // 000F GETMET R9 R0 K7 - 0x7C240200, // 0010 CALL R9 1 - 0x7C080E00, // 0011 CALL R2 7 - 0xB80E1000, // 0012 GETNGBL R3 K8 - 0x8C0C0709, // 0013 GETMET R3 R3 K9 - 0x5C140400, // 0014 MOVE R5 R2 - 0x7C0C0400, // 0015 CALL R3 2 - 0x80000000, // 0016 RET 0 + 0x60040018, // 0004 GETGBL R1 G24 + 0x58080001, // 0005 LDCONST R2 K1 + 0x8C0C0102, // 0006 GETMET R3 R0 K2 + 0x7C0C0200, // 0007 CALL R3 1 + 0x8C100102, // 0008 GETMET R4 R0 K2 + 0x7C100200, // 0009 CALL R4 1 + 0x8C140103, // 000A GETMET R5 R0 K3 + 0x7C140200, // 000B CALL R5 1 + 0x8C180104, // 000C GETMET R6 R0 K4 + 0x7C180200, // 000D CALL R6 1 + 0x8C1C0105, // 000E GETMET R7 R0 K5 + 0x7C1C0200, // 000F CALL R7 1 + 0x7C040C00, // 0010 CALL R1 6 + 0xB80A0C00, // 0011 GETNGBL R2 K6 + 0x8C080507, // 0012 GETMET R2 R2 K7 + 0x5C100200, // 0013 MOVE R4 R1 + 0x7C080400, // 0014 CALL R2 2 + 0x80000000, // 0015 RET 0 }) ) ); @@ -644,7 +641,7 @@ be_local_closure(AXP192_get_bat_current, /* name */ ********************************************************************/ be_local_closure(AXP192_web_sensor, /* name */ be_nested_proto( - 11, /* nstack */ + 9, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -652,51 +649,48 @@ be_local_closure(AXP192_web_sensor, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[14]) { /* constants */ + ( &(const bvalue[12]) { /* constants */ /* K0 */ be_nested_str(wire), - /* K1 */ be_nested_str(string), - /* K2 */ be_nested_str(format), - /* K3 */ be_nested_str(_X7Bs_X7DVBus_X20Voltage_X7Bm_X7D_X25_X2E3f_X20V_X7Be_X7D), - /* K4 */ be_nested_str(_X7Bs_X7DVBus_X20Current_X7Bm_X7D_X25_X2E1f_X20mA_X7Be_X7D), - /* K5 */ be_nested_str(_X7Bs_X7DBatt_X20Voltage_X7Bm_X7D_X25_X2E3f_X20V_X7Be_X7D), - /* K6 */ be_nested_str(_X7Bs_X7DBatt_X20Current_X7Bm_X7D_X25_X2E1f_X20mA_X7Be_X7D), - /* K7 */ be_nested_str(_X7Bs_X7DTemp_X20AXP_X7Bm_X7D_X25_X2E1f_X20_X26deg_X3BC_X7Be_X7D), - /* K8 */ be_nested_str(get_vbus_voltage), - /* K9 */ be_nested_str(get_bat_voltage), - /* K10 */ be_nested_str(get_bat_current), - /* K11 */ be_nested_str(get_temp), - /* K12 */ be_nested_str(tasmota), - /* K13 */ be_nested_str(web_send_decimal), + /* K1 */ be_nested_str(_X7Bs_X7DVBus_X20Voltage_X7Bm_X7D_X25_X2E3f_X20V_X7Be_X7D), + /* K2 */ be_nested_str(_X7Bs_X7DVBus_X20Current_X7Bm_X7D_X25_X2E1f_X20mA_X7Be_X7D), + /* K3 */ be_nested_str(_X7Bs_X7DBatt_X20Voltage_X7Bm_X7D_X25_X2E3f_X20V_X7Be_X7D), + /* K4 */ be_nested_str(_X7Bs_X7DBatt_X20Current_X7Bm_X7D_X25_X2E1f_X20mA_X7Be_X7D), + /* K5 */ be_nested_str(_X7Bs_X7DTemp_X20AXP_X7Bm_X7D_X25_X2E1f_X20_X26deg_X3BC_X7Be_X7D), + /* K6 */ be_nested_str(get_vbus_voltage), + /* K7 */ be_nested_str(get_bat_voltage), + /* K8 */ be_nested_str(get_bat_current), + /* K9 */ be_nested_str(get_temp), + /* K10 */ be_nested_str(tasmota), + /* K11 */ be_nested_str(web_send_decimal), }), &be_const_str_web_sensor, &be_const_str_solidified, - ( &(const binstruction[26]) { /* code */ + ( &(const binstruction[25]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 0x74060001, // 0001 JMPT R1 #0004 0x4C040000, // 0002 LDNIL R1 0x80040200, // 0003 RET 1 R1 - 0xA4060200, // 0004 IMPORT R1 K1 - 0x8C080302, // 0005 GETMET R2 R1 K2 - 0x40120704, // 0006 CONNECT R4 K3 K4 - 0x40100905, // 0007 CONNECT R4 R4 K5 - 0x40100906, // 0008 CONNECT R4 R4 K6 - 0x40100907, // 0009 CONNECT R4 R4 K7 - 0x8C140108, // 000A GETMET R5 R0 K8 - 0x7C140200, // 000B CALL R5 1 - 0x8C180108, // 000C GETMET R6 R0 K8 - 0x7C180200, // 000D CALL R6 1 - 0x8C1C0109, // 000E GETMET R7 R0 K9 - 0x7C1C0200, // 000F CALL R7 1 - 0x8C20010A, // 0010 GETMET R8 R0 K10 - 0x7C200200, // 0011 CALL R8 1 - 0x8C24010B, // 0012 GETMET R9 R0 K11 - 0x7C240200, // 0013 CALL R9 1 - 0x7C080E00, // 0014 CALL R2 7 - 0xB80E1800, // 0015 GETNGBL R3 K12 - 0x8C0C070D, // 0016 GETMET R3 R3 K13 - 0x5C140400, // 0017 MOVE R5 R2 - 0x7C0C0400, // 0018 CALL R3 2 - 0x80000000, // 0019 RET 0 + 0x60040018, // 0004 GETGBL R1 G24 + 0x400A0302, // 0005 CONNECT R2 K1 K2 + 0x40080503, // 0006 CONNECT R2 R2 K3 + 0x40080504, // 0007 CONNECT R2 R2 K4 + 0x40080505, // 0008 CONNECT R2 R2 K5 + 0x8C0C0106, // 0009 GETMET R3 R0 K6 + 0x7C0C0200, // 000A CALL R3 1 + 0x8C100106, // 000B GETMET R4 R0 K6 + 0x7C100200, // 000C CALL R4 1 + 0x8C140107, // 000D GETMET R5 R0 K7 + 0x7C140200, // 000E CALL R5 1 + 0x8C180108, // 000F GETMET R6 R0 K8 + 0x7C180200, // 0010 CALL R6 1 + 0x8C1C0109, // 0011 GETMET R7 R0 K9 + 0x7C1C0200, // 0012 CALL R7 1 + 0x7C040C00, // 0013 CALL R1 6 + 0xB80A1400, // 0014 GETNGBL R2 K10 + 0x8C08050B, // 0015 GETMET R2 R2 K11 + 0x5C100200, // 0016 MOVE R4 R1 + 0x7C080400, // 0017 CALL R2 2 + 0x80000000, // 0018 RET 0 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_lv_tasmota_widgets.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_lv_tasmota_widgets.h index bd85dbbb2b38..380bbc756ad7 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_lv_tasmota_widgets.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_lv_tasmota_widgets.h @@ -11,7 +11,7 @@ extern const bclass be_class_lv_clock; ********************************************************************/ be_local_closure(lv_clock_set_time, /* name */ be_nested_proto( - 11, /* nstack */ + 9, /* nstack */ 4, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -19,48 +19,45 @@ be_local_closure(lv_clock_set_time, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(hour), - /* K2 */ be_nested_str_weak(minute), - /* K3 */ be_nested_str_weak(sec), - /* K4 */ be_nested_str_weak(format), - /* K5 */ be_nested_str_weak(_X2502d_X25s_X2502d), - /* K6 */ be_const_int(2), - /* K7 */ be_nested_str_weak(_X3A), - /* K8 */ be_nested_str_weak(_X20), - /* K9 */ be_nested_str_weak(set_text), + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_weak(hour), + /* K1 */ be_nested_str_weak(minute), + /* K2 */ be_nested_str_weak(sec), + /* K3 */ be_nested_str_weak(_X2502d_X25s_X2502d), + /* K4 */ be_const_int(2), + /* K5 */ be_nested_str_weak(_X3A), + /* K6 */ be_nested_str_weak(_X20), + /* K7 */ be_nested_str_weak(set_text), }), be_str_weak(set_time), &be_const_str_solidified, - ( &(const binstruction[27]) { /* code */ - 0xA4120000, // 0000 IMPORT R4 K0 - 0x88140101, // 0001 GETMBR R5 R0 K1 - 0x20140205, // 0002 NE R5 R1 R5 - 0x74160005, // 0003 JMPT R5 #000A - 0x88140102, // 0004 GETMBR R5 R0 K2 - 0x20140405, // 0005 NE R5 R2 R5 - 0x74160002, // 0006 JMPT R5 #000A - 0x88140103, // 0007 GETMBR R5 R0 K3 - 0x20140605, // 0008 NE R5 R3 R5 - 0x7816000F, // 0009 JMPF R5 #001A - 0x8C140904, // 000A GETMET R5 R4 K4 - 0x581C0005, // 000B LDCONST R7 K5 - 0x5C200200, // 000C MOVE R8 R1 - 0x10240706, // 000D MOD R9 R3 K6 - 0x78260001, // 000E JMPF R9 #0011 - 0x58240007, // 000F LDCONST R9 K7 - 0x70020000, // 0010 JMP #0012 - 0x58240008, // 0011 LDCONST R9 K8 - 0x5C280400, // 0012 MOVE R10 R2 - 0x7C140A00, // 0013 CALL R5 5 - 0x90020201, // 0014 SETMBR R0 K1 R1 - 0x90020402, // 0015 SETMBR R0 K2 R2 - 0x90020603, // 0016 SETMBR R0 K3 R3 - 0x8C180109, // 0017 GETMET R6 R0 K9 - 0x5C200A00, // 0018 MOVE R8 R5 - 0x7C180400, // 0019 CALL R6 2 - 0x80000000, // 001A RET 0 + ( &(const binstruction[26]) { /* code */ + 0x88100100, // 0000 GETMBR R4 R0 K0 + 0x20100204, // 0001 NE R4 R1 R4 + 0x74120005, // 0002 JMPT R4 #0009 + 0x88100101, // 0003 GETMBR R4 R0 K1 + 0x20100404, // 0004 NE R4 R2 R4 + 0x74120002, // 0005 JMPT R4 #0009 + 0x88100102, // 0006 GETMBR R4 R0 K2 + 0x20100604, // 0007 NE R4 R3 R4 + 0x7812000F, // 0008 JMPF R4 #0019 + 0x60100018, // 0009 GETGBL R4 G24 + 0x58140003, // 000A LDCONST R5 K3 + 0x5C180200, // 000B MOVE R6 R1 + 0x101C0704, // 000C MOD R7 R3 K4 + 0x781E0001, // 000D JMPF R7 #0010 + 0x581C0005, // 000E LDCONST R7 K5 + 0x70020000, // 000F JMP #0011 + 0x581C0006, // 0010 LDCONST R7 K6 + 0x5C200400, // 0011 MOVE R8 R2 + 0x7C100800, // 0012 CALL R4 4 + 0x90020001, // 0013 SETMBR R0 K0 R1 + 0x90020202, // 0014 SETMBR R0 K1 R2 + 0x90020403, // 0015 SETMBR R0 K2 R3 + 0x8C140107, // 0016 GETMET R5 R0 K7 + 0x5C1C0800, // 0017 MOVE R7 R4 + 0x7C140400, // 0018 CALL R5 2 + 0x80000000, // 0019 RET 0 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_mqtt.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_mqtt.h index 48d49ae2e380..33744dd36f50 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_mqtt.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_mqtt.h @@ -268,7 +268,7 @@ extern const bclass be_class_mqtt_listener; ********************************************************************/ be_local_closure(mqtt_listener_tostring, /* name */ be_nested_proto( - 7, /* nstack */ + 5, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -276,24 +276,21 @@ be_local_closure(mqtt_listener_tostring, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(format), - /* K2 */ be_nested_str(_X3Cinstance_X3A_X20_X25s_X28_X27_X25s_X27_X29_X3E), - /* K3 */ be_nested_str(fulltopic), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str(_X3Cinstance_X3A_X20_X25s_X28_X27_X25s_X27_X29_X3E), + /* K1 */ be_nested_str(fulltopic), }), &be_const_str_tostring, &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x58100002, // 0002 LDCONST R4 K2 - 0x60140005, // 0003 GETGBL R5 G5 - 0x5C180000, // 0004 MOVE R6 R0 - 0x7C140200, // 0005 CALL R5 1 - 0x88180103, // 0006 GETMBR R6 R0 K3 - 0x7C080800, // 0007 CALL R2 4 - 0x80040400, // 0008 RET 1 R2 + ( &(const binstruction[ 8]) { /* code */ + 0x60040018, // 0000 GETGBL R1 G24 + 0x58080000, // 0001 LDCONST R2 K0 + 0x600C0005, // 0002 GETGBL R3 G5 + 0x5C100000, // 0003 MOVE R4 R0 + 0x7C0C0200, // 0004 CALL R3 1 + 0x88100101, // 0005 GETMBR R4 R0 K1 + 0x7C040600, // 0006 CALL R1 3 + 0x80040200, // 0007 RET 1 R1 }) ) ); @@ -448,7 +445,7 @@ be_local_class(mqtt_listener, ********************************************************************/ be_local_closure(MQTT_mqtt_listener_class, /* name */ be_nested_proto( - 2, /* nstack */ + 3, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -461,10 +458,11 @@ be_local_closure(MQTT_mqtt_listener_class, /* name */ }), &be_const_str_mqtt_listener_class, &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ + ( &(const binstruction[ 4]) { /* code */ 0x58040000, // 0000 LDCONST R1 K0 0xB4000000, // 0001 CLASS K0 - 0x80040200, // 0002 RET 1 R1 + 0x5C080200, // 0002 MOVE R2 R1 + 0x80040200, // 0003 RET 1 R1 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_partition_core.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_partition_core.h index 2f0cb689d9d9..caadd3a25e97 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_partition_core.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_partition_core.h @@ -99,7 +99,7 @@ be_local_closure(Partition_otadata_save, /* name */ ********************************************************************/ be_local_closure(Partition_otadata_tostring, /* name */ be_nested_proto( - 9, /* nstack */ + 7, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -107,38 +107,35 @@ be_local_closure(Partition_otadata_tostring, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(format), - /* K2 */ be_nested_str(_X3Cinstance_X3A_X20Partition_otadata_X28ota_active_X3A_X25s_X2C_X20ota_seq_X3D_X5B_X25d_X2C_X25d_X5D_X2C_X20ota_max_X3D_X25d_X29_X3E), - /* K3 */ be_nested_str(active_otadata), - /* K4 */ be_const_int(0), - /* K5 */ be_nested_str(ota_), - /* K6 */ be_nested_str(factory), - /* K7 */ be_nested_str(seq0), - /* K8 */ be_nested_str(seq1), - /* K9 */ be_nested_str(maxota), + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str(_X3Cinstance_X3A_X20Partition_otadata_X28ota_active_X3A_X25s_X2C_X20ota_seq_X3D_X5B_X25d_X2C_X25d_X5D_X2C_X20ota_max_X3D_X25d_X29_X3E), + /* K1 */ be_nested_str(active_otadata), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str(ota_), + /* K4 */ be_nested_str(factory), + /* K5 */ be_nested_str(seq0), + /* K6 */ be_nested_str(seq1), + /* K7 */ be_nested_str(maxota), }), &be_const_str_tostring, &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x58100002, // 0002 LDCONST R4 K2 - 0x88140103, // 0003 GETMBR R5 R0 K3 - 0x28140B04, // 0004 GE R5 R5 K4 - 0x78160004, // 0005 JMPF R5 #000B - 0x60140008, // 0006 GETGBL R5 G8 - 0x88180103, // 0007 GETMBR R6 R0 K3 - 0x7C140200, // 0008 CALL R5 1 - 0x00160A05, // 0009 ADD R5 K5 R5 - 0x70020000, // 000A JMP #000C - 0x58140006, // 000B LDCONST R5 K6 - 0x88180107, // 000C GETMBR R6 R0 K7 - 0x881C0108, // 000D GETMBR R7 R0 K8 - 0x88200109, // 000E GETMBR R8 R0 K9 - 0x7C080C00, // 000F CALL R2 6 - 0x80040400, // 0010 RET 1 R2 + ( &(const binstruction[16]) { /* code */ + 0x60040018, // 0000 GETGBL R1 G24 + 0x58080000, // 0001 LDCONST R2 K0 + 0x880C0101, // 0002 GETMBR R3 R0 K1 + 0x280C0702, // 0003 GE R3 R3 K2 + 0x780E0004, // 0004 JMPF R3 #000A + 0x600C0008, // 0005 GETGBL R3 G8 + 0x88100101, // 0006 GETMBR R4 R0 K1 + 0x7C0C0200, // 0007 CALL R3 1 + 0x000E0603, // 0008 ADD R3 K3 R3 + 0x70020000, // 0009 JMP #000B + 0x580C0004, // 000A LDCONST R3 K4 + 0x88100105, // 000B GETMBR R4 R0 K5 + 0x88140106, // 000C GETMBR R5 R0 K6 + 0x88180107, // 000D GETMBR R6 R0 K7 + 0x7C040A00, // 000E CALL R1 5 + 0x80040200, // 000F RET 1 R1 }) ) ); @@ -251,65 +248,68 @@ be_local_closure(Partition_otadata_load, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ + ( &(const bvalue[ 9]) { /* constants */ /* K0 */ be_nested_str(flash), /* K1 */ be_nested_str(read), - /* K2 */ be_nested_str(seq0), - /* K3 */ be_nested_str(get), - /* K4 */ be_const_int(0), - /* K5 */ be_nested_str(seq1), - /* K6 */ be_nested_str(crc32_ota_seq), - /* K7 */ be_nested_str(_validate), + /* K2 */ be_nested_str(offset), + /* K3 */ be_nested_str(seq0), + /* K4 */ be_nested_str(get), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str(seq1), + /* K7 */ be_nested_str(crc32_ota_seq), + /* K8 */ be_nested_str(_validate), }), &be_const_str_load, &be_const_str_solidified, - ( &(const binstruction[46]) { /* code */ + ( &(const binstruction[48]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x5412DFFF, // 0002 LDINT R4 57344 + 0x88100102, // 0002 GETMBR R4 R0 K2 0x5416001F, // 0003 LDINT R5 32 0x7C080600, // 0004 CALL R2 3 0x8C0C0301, // 0005 GETMET R3 R1 K1 - 0x5416EFFF, // 0006 LDINT R5 61440 - 0x541A001F, // 0007 LDINT R6 32 - 0x7C0C0600, // 0008 CALL R3 3 - 0x8C100503, // 0009 GETMET R4 R2 K3 - 0x58180004, // 000A LDCONST R6 K4 - 0x541E0003, // 000B LDINT R7 4 - 0x7C100600, // 000C CALL R4 3 - 0x90020404, // 000D SETMBR R0 K2 R4 - 0x8C100703, // 000E GETMET R4 R3 K3 - 0x58180004, // 000F LDCONST R6 K4 - 0x541E0003, // 0010 LDINT R7 4 - 0x7C100600, // 0011 CALL R4 3 - 0x90020A04, // 0012 SETMBR R0 K5 R4 - 0x8C100503, // 0013 GETMET R4 R2 K3 - 0x541A001B, // 0014 LDINT R6 28 - 0x541E0003, // 0015 LDINT R7 4 - 0x7C100600, // 0016 CALL R4 3 - 0x8C140106, // 0017 GETMET R5 R0 K6 - 0x881C0102, // 0018 GETMBR R7 R0 K2 - 0x7C140400, // 0019 CALL R5 2 - 0x1C100805, // 001A EQ R4 R4 R5 - 0x8C140703, // 001B GETMET R5 R3 K3 - 0x541E001B, // 001C LDINT R7 28 - 0x54220003, // 001D LDINT R8 4 - 0x7C140600, // 001E CALL R5 3 - 0x8C180106, // 001F GETMET R6 R0 K6 - 0x88200105, // 0020 GETMBR R8 R0 K5 - 0x7C180400, // 0021 CALL R6 2 - 0x1C140A06, // 0022 EQ R5 R5 R6 - 0x5C180800, // 0023 MOVE R6 R4 - 0x741A0001, // 0024 JMPT R6 #0027 - 0x4C180000, // 0025 LDNIL R6 - 0x90020406, // 0026 SETMBR R0 K2 R6 - 0x5C180A00, // 0027 MOVE R6 R5 - 0x741A0001, // 0028 JMPT R6 #002B - 0x4C180000, // 0029 LDNIL R6 - 0x90020A06, // 002A SETMBR R0 K5 R6 - 0x8C180107, // 002B GETMET R6 R0 K7 - 0x7C180200, // 002C CALL R6 1 - 0x80000000, // 002D RET 0 + 0x88140102, // 0006 GETMBR R5 R0 K2 + 0x541A0FFF, // 0007 LDINT R6 4096 + 0x00140A06, // 0008 ADD R5 R5 R6 + 0x541A001F, // 0009 LDINT R6 32 + 0x7C0C0600, // 000A CALL R3 3 + 0x8C100504, // 000B GETMET R4 R2 K4 + 0x58180005, // 000C LDCONST R6 K5 + 0x541E0003, // 000D LDINT R7 4 + 0x7C100600, // 000E CALL R4 3 + 0x90020604, // 000F SETMBR R0 K3 R4 + 0x8C100704, // 0010 GETMET R4 R3 K4 + 0x58180005, // 0011 LDCONST R6 K5 + 0x541E0003, // 0012 LDINT R7 4 + 0x7C100600, // 0013 CALL R4 3 + 0x90020C04, // 0014 SETMBR R0 K6 R4 + 0x8C100504, // 0015 GETMET R4 R2 K4 + 0x541A001B, // 0016 LDINT R6 28 + 0x541E0003, // 0017 LDINT R7 4 + 0x7C100600, // 0018 CALL R4 3 + 0x8C140107, // 0019 GETMET R5 R0 K7 + 0x881C0103, // 001A GETMBR R7 R0 K3 + 0x7C140400, // 001B CALL R5 2 + 0x1C100805, // 001C EQ R4 R4 R5 + 0x8C140704, // 001D GETMET R5 R3 K4 + 0x541E001B, // 001E LDINT R7 28 + 0x54220003, // 001F LDINT R8 4 + 0x7C140600, // 0020 CALL R5 3 + 0x8C180107, // 0021 GETMET R6 R0 K7 + 0x88200106, // 0022 GETMBR R8 R0 K6 + 0x7C180400, // 0023 CALL R6 2 + 0x1C140A06, // 0024 EQ R5 R5 R6 + 0x5C180800, // 0025 MOVE R6 R4 + 0x741A0001, // 0026 JMPT R6 #0029 + 0x4C180000, // 0027 LDNIL R6 + 0x90020606, // 0028 SETMBR R0 K3 R6 + 0x5C180A00, // 0029 MOVE R6 R5 + 0x741A0001, // 002A JMPT R6 #002D + 0x4C180000, // 002B LDNIL R6 + 0x90020C06, // 002C SETMBR R0 K6 R6 + 0x8C180108, // 002D GETMET R6 R0 K8 + 0x7C180200, // 002E CALL R6 1 + 0x80000000, // 002F RET 0 }) ) ); @@ -797,7 +797,7 @@ be_local_closure(Partition_get_max_flash_size_k, /* name */ ********************************************************************/ be_local_closure(Partition_resize_max_flash_size_k, /* name */ be_nested_proto( - 18, /* nstack */ + 16, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -805,29 +805,27 @@ be_local_closure(Partition_resize_max_flash_size_k, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[18]) { /* constants */ + ( &(const bvalue[16]) { /* constants */ /* K0 */ be_nested_str(tasmota), /* K1 */ be_nested_str(memory), /* K2 */ be_nested_str(flash), /* K3 */ be_nested_str(find), /* K4 */ be_nested_str(flash_real), /* K5 */ be_nested_str(get_flash_definition_sector), - /* K6 */ be_nested_str(string), - /* K7 */ be_nested_str(read), - /* K8 */ be_const_int(3), - /* K9 */ be_const_int(1), - /* K10 */ be_const_int(0), - /* K11 */ be_const_int(2), - /* K12 */ be_nested_str(write), - /* K13 */ be_nested_str(log), - /* K14 */ be_nested_str(format), - /* K15 */ be_nested_str(UPL_X3A_X20changing_X20flash_X20definition_X20from_X200x02X_X20to_X200x_X2502X), - /* K16 */ be_nested_str(wrong_X20flash_X20size_X20), - /* K17 */ be_nested_str(internal_error), + /* K6 */ be_nested_str(read), + /* K7 */ be_const_int(3), + /* K8 */ be_const_int(1), + /* K9 */ be_const_int(0), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str(write), + /* K12 */ be_nested_str(log), + /* K13 */ be_nested_str(UPL_X3A_X20changing_X20flash_X20definition_X20from_X200x02X_X20to_X200x_X2502X), + /* K14 */ be_nested_str(wrong_X20flash_X20size_X20), + /* K15 */ be_nested_str(internal_error), }), &be_const_str_resize_max_flash_size_k, &be_const_str_solidified, - ( &(const binstruction[95]) { /* code */ + ( &(const binstruction[94]) { /* code */ 0xB8060000, // 0000 GETNGBL R1 K0 0x8C040301, // 0001 GETMET R1 R1 K1 0x7C040200, // 0002 CALL R1 1 @@ -842,87 +840,86 @@ be_local_closure(Partition_resize_max_flash_size_k, /* name */ 0x8C0C0105, // 000B GETMET R3 R0 K5 0x7C0C0200, // 000C CALL R3 1 0x20100202, // 000D NE R4 R1 R2 - 0x7812004E, // 000E JMPF R4 #005E + 0x7812004D, // 000E JMPF R4 #005D 0x4C100000, // 000F LDNIL R4 0x20100604, // 0010 NE R4 R3 R4 - 0x7812004B, // 0011 JMPF R4 #005E + 0x7812004A, // 0011 JMPF R4 #005D 0xA4120400, // 0012 IMPORT R4 K2 - 0xA4160C00, // 0013 IMPORT R5 K6 - 0x5C040400, // 0014 MOVE R1 R2 - 0x8C180907, // 0015 GETMET R6 R4 K7 - 0x5C200600, // 0016 MOVE R8 R3 - 0x54260003, // 0017 LDINT R9 4 - 0x7C180600, // 0018 CALL R6 3 - 0x941C0D08, // 0019 GETIDX R7 R6 K8 - 0x4C200000, // 001A LDNIL R8 - 0x542603FF, // 001B LDINT R9 1024 - 0x0C240409, // 001C DIV R9 R2 R9 - 0x1C281309, // 001D EQ R10 R9 K9 - 0x782A0001, // 001E JMPF R10 #0021 - 0x5820000A, // 001F LDCONST R8 K10 - 0x70020020, // 0020 JMP #0042 - 0x1C28130B, // 0021 EQ R10 R9 K11 - 0x782A0001, // 0022 JMPF R10 #0025 - 0x5422000F, // 0023 LDINT R8 16 - 0x7002001C, // 0024 JMP #0042 - 0x542A0003, // 0025 LDINT R10 4 - 0x1C28120A, // 0026 EQ R10 R9 R10 - 0x782A0001, // 0027 JMPF R10 #002A - 0x5422001F, // 0028 LDINT R8 32 - 0x70020017, // 0029 JMP #0042 - 0x542A0007, // 002A LDINT R10 8 - 0x1C28120A, // 002B EQ R10 R9 R10 - 0x782A0001, // 002C JMPF R10 #002F - 0x5422002F, // 002D LDINT R8 48 - 0x70020012, // 002E JMP #0042 - 0x542A000F, // 002F LDINT R10 16 - 0x1C28120A, // 0030 EQ R10 R9 R10 - 0x782A0001, // 0031 JMPF R10 #0034 - 0x5422003F, // 0032 LDINT R8 64 - 0x7002000D, // 0033 JMP #0042 - 0x542A001F, // 0034 LDINT R10 32 - 0x1C28120A, // 0035 EQ R10 R9 R10 - 0x782A0001, // 0036 JMPF R10 #0039 - 0x5422004F, // 0037 LDINT R8 80 - 0x70020008, // 0038 JMP #0042 - 0x542A003F, // 0039 LDINT R10 64 - 0x1C28120A, // 003A EQ R10 R9 R10 - 0x782A0001, // 003B JMPF R10 #003E - 0x5422005F, // 003C LDINT R8 96 - 0x70020003, // 003D JMP #0042 - 0x542A007F, // 003E LDINT R10 128 - 0x1C28120A, // 003F EQ R10 R9 R10 - 0x782A0000, // 0040 JMPF R10 #0042 - 0x5422006F, // 0041 LDINT R8 112 - 0x4C280000, // 0042 LDNIL R10 - 0x2028100A, // 0043 NE R10 R8 R10 - 0x782A0013, // 0044 JMPF R10 #0059 - 0x94280D08, // 0045 GETIDX R10 R6 K8 - 0x942C0D08, // 0046 GETIDX R11 R6 K8 - 0x5432000E, // 0047 LDINT R12 15 - 0x2C2C160C, // 0048 AND R11 R11 R12 - 0x302C1608, // 0049 OR R11 R11 R8 - 0x981A100B, // 004A SETIDX R6 K8 R11 - 0x8C2C090C, // 004B GETMET R11 R4 K12 - 0x5C340600, // 004C MOVE R13 R3 - 0x5C380C00, // 004D MOVE R14 R6 - 0x7C2C0600, // 004E CALL R11 3 - 0xB82E0000, // 004F GETNGBL R11 K0 - 0x8C2C170D, // 0050 GETMET R11 R11 K13 - 0x8C340B0E, // 0051 GETMET R13 R5 K14 - 0x583C000F, // 0052 LDCONST R15 K15 - 0x5C401400, // 0053 MOVE R16 R10 - 0x94440D08, // 0054 GETIDX R17 R6 K8 - 0x7C340800, // 0055 CALL R13 4 - 0x58380008, // 0056 LDCONST R14 K8 - 0x7C2C0600, // 0057 CALL R11 3 - 0x70020004, // 0058 JMP #005E - 0x60280008, // 0059 GETGBL R10 G8 - 0x5C2C1200, // 005A MOVE R11 R9 - 0x7C280200, // 005B CALL R10 1 - 0x002A200A, // 005C ADD R10 K16 R10 - 0xB006220A, // 005D RAISE 1 K17 R10 - 0x80000000, // 005E RET 0 + 0x5C040400, // 0013 MOVE R1 R2 + 0x8C140906, // 0014 GETMET R5 R4 K6 + 0x5C1C0600, // 0015 MOVE R7 R3 + 0x54220003, // 0016 LDINT R8 4 + 0x7C140600, // 0017 CALL R5 3 + 0x94180B07, // 0018 GETIDX R6 R5 K7 + 0x4C1C0000, // 0019 LDNIL R7 + 0x542203FF, // 001A LDINT R8 1024 + 0x0C200408, // 001B DIV R8 R2 R8 + 0x1C241108, // 001C EQ R9 R8 K8 + 0x78260001, // 001D JMPF R9 #0020 + 0x581C0009, // 001E LDCONST R7 K9 + 0x70020020, // 001F JMP #0041 + 0x1C24110A, // 0020 EQ R9 R8 K10 + 0x78260001, // 0021 JMPF R9 #0024 + 0x541E000F, // 0022 LDINT R7 16 + 0x7002001C, // 0023 JMP #0041 + 0x54260003, // 0024 LDINT R9 4 + 0x1C241009, // 0025 EQ R9 R8 R9 + 0x78260001, // 0026 JMPF R9 #0029 + 0x541E001F, // 0027 LDINT R7 32 + 0x70020017, // 0028 JMP #0041 + 0x54260007, // 0029 LDINT R9 8 + 0x1C241009, // 002A EQ R9 R8 R9 + 0x78260001, // 002B JMPF R9 #002E + 0x541E002F, // 002C LDINT R7 48 + 0x70020012, // 002D JMP #0041 + 0x5426000F, // 002E LDINT R9 16 + 0x1C241009, // 002F EQ R9 R8 R9 + 0x78260001, // 0030 JMPF R9 #0033 + 0x541E003F, // 0031 LDINT R7 64 + 0x7002000D, // 0032 JMP #0041 + 0x5426001F, // 0033 LDINT R9 32 + 0x1C241009, // 0034 EQ R9 R8 R9 + 0x78260001, // 0035 JMPF R9 #0038 + 0x541E004F, // 0036 LDINT R7 80 + 0x70020008, // 0037 JMP #0041 + 0x5426003F, // 0038 LDINT R9 64 + 0x1C241009, // 0039 EQ R9 R8 R9 + 0x78260001, // 003A JMPF R9 #003D + 0x541E005F, // 003B LDINT R7 96 + 0x70020003, // 003C JMP #0041 + 0x5426007F, // 003D LDINT R9 128 + 0x1C241009, // 003E EQ R9 R8 R9 + 0x78260000, // 003F JMPF R9 #0041 + 0x541E006F, // 0040 LDINT R7 112 + 0x4C240000, // 0041 LDNIL R9 + 0x20240E09, // 0042 NE R9 R7 R9 + 0x78260013, // 0043 JMPF R9 #0058 + 0x94240B07, // 0044 GETIDX R9 R5 K7 + 0x94280B07, // 0045 GETIDX R10 R5 K7 + 0x542E000E, // 0046 LDINT R11 15 + 0x2C28140B, // 0047 AND R10 R10 R11 + 0x30281407, // 0048 OR R10 R10 R7 + 0x98160E0A, // 0049 SETIDX R5 K7 R10 + 0x8C28090B, // 004A GETMET R10 R4 K11 + 0x5C300600, // 004B MOVE R12 R3 + 0x5C340A00, // 004C MOVE R13 R5 + 0x7C280600, // 004D CALL R10 3 + 0xB82A0000, // 004E GETNGBL R10 K0 + 0x8C28150C, // 004F GETMET R10 R10 K12 + 0x60300018, // 0050 GETGBL R12 G24 + 0x5834000D, // 0051 LDCONST R13 K13 + 0x5C381200, // 0052 MOVE R14 R9 + 0x943C0B07, // 0053 GETIDX R15 R5 K7 + 0x7C300600, // 0054 CALL R12 3 + 0x58340007, // 0055 LDCONST R13 K7 + 0x7C280600, // 0056 CALL R10 3 + 0x70020004, // 0057 JMP #005D + 0x60240008, // 0058 GETGBL R9 G8 + 0x5C281000, // 0059 MOVE R10 R8 + 0x7C240200, // 005A CALL R9 1 + 0x00261C09, // 005B ADD R9 K14 R9 + 0xB0061E09, // 005C RAISE 1 K15 R9 + 0x80000000, // 005D RET 0 }) ) ); @@ -991,7 +988,7 @@ be_local_closure(Partition_get_flash_definition_sector, /* name */ ********************************************************************/ be_local_closure(Partition_resize_fs_to_max, /* name */ be_nested_proto( - 11, /* nstack */ + 9, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -999,83 +996,80 @@ be_local_closure(Partition_resize_fs_to_max, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[17]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(get_unallocated_k), - /* K2 */ be_const_int(0), - /* K3 */ be_nested_str(tasmota), - /* K4 */ be_nested_str(log), - /* K5 */ be_nested_str(format), - /* K6 */ be_nested_str(BRY_X3A_X20Trying_X20to_X20expand_X20FS_X20by_X20_X25i_X20kB), - /* K7 */ be_const_int(2), - /* K8 */ be_nested_str(resize_max_flash_size_k), - /* K9 */ be_nested_str(slots), - /* K10 */ be_nested_str(sz), - /* K11 */ be_nested_str(save), - /* K12 */ be_nested_str(invalidate_spiffs), - /* K13 */ be_nested_str(global), - /* K14 */ be_nested_str(restart_flag), - /* K15 */ be_nested_str(BRY_X3A_X20Successfully_X20resized_X20FS_X2C_X20restarting), - /* K16 */ be_nested_str(BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s), + ( &(const bvalue[15]) { /* constants */ + /* K0 */ be_nested_str(get_unallocated_k), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str(tasmota), + /* K3 */ be_nested_str(log), + /* K4 */ be_nested_str(BRY_X3A_X20Trying_X20to_X20expand_X20FS_X20by_X20_X25i_X20kB), + /* K5 */ be_const_int(2), + /* K6 */ be_nested_str(resize_max_flash_size_k), + /* K7 */ be_nested_str(slots), + /* K8 */ be_nested_str(sz), + /* K9 */ be_nested_str(save), + /* K10 */ be_nested_str(invalidate_spiffs), + /* K11 */ be_nested_str(global), + /* K12 */ be_nested_str(restart_flag), + /* K13 */ be_nested_str(BRY_X3A_X20Successfully_X20resized_X20FS_X2C_X20restarting), + /* K14 */ be_nested_str(BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s), }), &be_const_str_resize_fs_to_max, &be_const_str_solidified, - ( &(const binstruction[55]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xA8020026, // 0001 EXBLK 0 #0029 - 0x8C080101, // 0002 GETMET R2 R0 K1 - 0x7C080200, // 0003 CALL R2 1 - 0x180C0502, // 0004 LE R3 R2 K2 - 0x780E0002, // 0005 JMPF R3 #0009 - 0x4C0C0000, // 0006 LDNIL R3 - 0xA8040001, // 0007 EXBLK 1 1 - 0x80040600, // 0008 RET 1 R3 - 0xB80E0600, // 0009 GETNGBL R3 K3 - 0x8C0C0704, // 000A GETMET R3 R3 K4 - 0x8C140305, // 000B GETMET R5 R1 K5 - 0x581C0006, // 000C LDCONST R7 K6 - 0x5C200400, // 000D MOVE R8 R2 - 0x7C140600, // 000E CALL R5 3 - 0x58180007, // 000F LDCONST R6 K7 - 0x7C0C0600, // 0010 CALL R3 3 - 0x8C0C0108, // 0011 GETMET R3 R0 K8 - 0x7C0C0200, // 0012 CALL R3 1 - 0x540DFFFE, // 0013 LDINT R3 -1 - 0x88100109, // 0014 GETMBR R4 R0 K9 - 0x940C0803, // 0015 GETIDX R3 R4 R3 - 0x541A03FF, // 0016 LDINT R6 1024 - 0x08180406, // 0017 MUL R6 R2 R6 - 0x8814070A, // 0018 GETMBR R5 R3 K10 - 0x00140A06, // 0019 ADD R5 R5 R6 - 0x900E1405, // 001A SETMBR R3 K10 R5 - 0x8C14010B, // 001B GETMET R5 R0 K11 - 0x7C140200, // 001C CALL R5 1 - 0x8C10010C, // 001D GETMET R4 R0 K12 - 0x7C100200, // 001E CALL R4 1 - 0xB8120600, // 001F GETNGBL R4 K3 - 0x8810090D, // 0020 GETMBR R4 R4 K13 - 0x90121D07, // 0021 SETMBR R4 K14 K7 - 0xB8120600, // 0022 GETNGBL R4 K3 - 0x8C100904, // 0023 GETMET R4 R4 K4 - 0x5818000F, // 0024 LDCONST R6 K15 - 0x581C0007, // 0025 LDCONST R7 K7 - 0x7C100600, // 0026 CALL R4 3 - 0xA8040001, // 0027 EXBLK 1 1 - 0x7002000C, // 0028 JMP #0036 - 0xAC080002, // 0029 CATCH R2 0 2 - 0x70020009, // 002A JMP #0035 - 0xB8120600, // 002B GETNGBL R4 K3 - 0x8C100904, // 002C GETMET R4 R4 K4 - 0x8C180305, // 002D GETMET R6 R1 K5 - 0x58200010, // 002E LDCONST R8 K16 - 0x5C240400, // 002F MOVE R9 R2 - 0x5C280600, // 0030 MOVE R10 R3 - 0x7C180800, // 0031 CALL R6 4 - 0x581C0007, // 0032 LDCONST R7 K7 - 0x7C100600, // 0033 CALL R4 3 - 0x70020000, // 0034 JMP #0036 - 0xB0080000, // 0035 RAISE 2 R0 R0 - 0x80000000, // 0036 RET 0 + ( &(const binstruction[54]) { /* code */ + 0xA8020026, // 0000 EXBLK 0 #0028 + 0x8C040100, // 0001 GETMET R1 R0 K0 + 0x7C040200, // 0002 CALL R1 1 + 0x18080301, // 0003 LE R2 R1 K1 + 0x780A0002, // 0004 JMPF R2 #0008 + 0x4C080000, // 0005 LDNIL R2 + 0xA8040001, // 0006 EXBLK 1 1 + 0x80040400, // 0007 RET 1 R2 + 0xB80A0400, // 0008 GETNGBL R2 K2 + 0x8C080503, // 0009 GETMET R2 R2 K3 + 0x60100018, // 000A GETGBL R4 G24 + 0x58140004, // 000B LDCONST R5 K4 + 0x5C180200, // 000C MOVE R6 R1 + 0x7C100400, // 000D CALL R4 2 + 0x58140005, // 000E LDCONST R5 K5 + 0x7C080600, // 000F CALL R2 3 + 0x8C080106, // 0010 GETMET R2 R0 K6 + 0x7C080200, // 0011 CALL R2 1 + 0x5409FFFE, // 0012 LDINT R2 -1 + 0x880C0107, // 0013 GETMBR R3 R0 K7 + 0x94080602, // 0014 GETIDX R2 R3 R2 + 0x541603FF, // 0015 LDINT R5 1024 + 0x08140205, // 0016 MUL R5 R1 R5 + 0x88100508, // 0017 GETMBR R4 R2 K8 + 0x00100805, // 0018 ADD R4 R4 R5 + 0x900A1004, // 0019 SETMBR R2 K8 R4 + 0x8C100109, // 001A GETMET R4 R0 K9 + 0x7C100200, // 001B CALL R4 1 + 0x8C0C010A, // 001C GETMET R3 R0 K10 + 0x7C0C0200, // 001D CALL R3 1 + 0xB80E0400, // 001E GETNGBL R3 K2 + 0x880C070B, // 001F GETMBR R3 R3 K11 + 0x900E1905, // 0020 SETMBR R3 K12 K5 + 0xB80E0400, // 0021 GETNGBL R3 K2 + 0x8C0C0703, // 0022 GETMET R3 R3 K3 + 0x5814000D, // 0023 LDCONST R5 K13 + 0x58180005, // 0024 LDCONST R6 K5 + 0x7C0C0600, // 0025 CALL R3 3 + 0xA8040001, // 0026 EXBLK 1 1 + 0x7002000C, // 0027 JMP #0035 + 0xAC040002, // 0028 CATCH R1 0 2 + 0x70020009, // 0029 JMP #0034 + 0xB80E0400, // 002A GETNGBL R3 K2 + 0x8C0C0703, // 002B GETMET R3 R3 K3 + 0x60140018, // 002C GETGBL R5 G24 + 0x5818000E, // 002D LDCONST R6 K14 + 0x5C1C0200, // 002E MOVE R7 R1 + 0x5C200400, // 002F MOVE R8 R2 + 0x7C140600, // 0030 CALL R5 3 + 0x58180005, // 0031 LDCONST R6 K5 + 0x7C0C0600, // 0032 CALL R3 3 + 0x70020000, // 0033 JMP #0035 + 0xB0080000, // 0034 RAISE 2 R0 R0 + 0x80000000, // 0035 RET 0 }) ) ); @@ -1711,7 +1705,7 @@ be_local_closure(Partition_info_is_factory, /* name */ ********************************************************************/ be_local_closure(Partition_info_type_to_string, /* name */ be_nested_proto( - 6, /* nstack */ + 4, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1719,19 +1713,17 @@ be_local_closure(Partition_info_type_to_string, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ + ( &(const bvalue[ 6]) { /* constants */ /* K0 */ be_nested_str(type), /* K1 */ be_const_int(0), /* K2 */ be_nested_str(app), /* K3 */ be_const_int(1), /* K4 */ be_nested_str(data), - /* K5 */ be_nested_str(string), - /* K6 */ be_nested_str(format), - /* K7 */ be_nested_str(0x_X2502X), + /* K5 */ be_nested_str(0x_X2502X), }), &be_const_str_type_to_string, &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ + ( &(const binstruction[14]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 0x1C040301, // 0001 EQ R1 R1 K1 0x78060001, // 0002 JMPF R1 #0005 @@ -1741,12 +1733,11 @@ be_local_closure(Partition_info_type_to_string, /* name */ 0x1C040303, // 0006 EQ R1 R1 K3 0x78060000, // 0007 JMPF R1 #0009 0x80060800, // 0008 RET 1 K4 - 0xA4060A00, // 0009 IMPORT R1 K5 - 0x8C080306, // 000A GETMET R2 R1 K6 - 0x58100007, // 000B LDCONST R4 K7 - 0x88140100, // 000C GETMBR R5 R0 K0 - 0x7C080600, // 000D CALL R2 3 - 0x80040400, // 000E RET 1 R2 + 0x60040018, // 0009 GETGBL R1 G24 + 0x58080005, // 000A LDCONST R2 K5 + 0x880C0100, // 000B GETMBR R3 R0 K0 + 0x7C040400, // 000C CALL R1 2 + 0x80040200, // 000D RET 1 R1 }) ) ); @@ -1758,7 +1749,7 @@ be_local_closure(Partition_info_type_to_string, /* name */ ********************************************************************/ be_local_closure(Partition_info_init, /* name */ be_nested_proto( - 8, /* nstack */ + 7, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1766,7 +1757,7 @@ be_local_closure(Partition_info_init, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[18]) { /* constants */ + ( &(const bvalue[16]) { /* constants */ /* K0 */ be_nested_str(type), /* K1 */ be_const_int(0), /* K2 */ be_nested_str(subtype), @@ -1781,14 +1772,12 @@ be_local_closure(Partition_info_init, /* name */ /* K11 */ be_const_int(3), /* K12 */ be_nested_str(remove_trailing_zeroes), /* K13 */ be_nested_str(asstring), - /* K14 */ be_nested_str(string), - /* K15 */ be_nested_str(format), - /* K16 */ be_nested_str(invalid_X20magic_X20number_X20_X2502X), - /* K17 */ be_nested_str(internal_error), + /* K14 */ be_nested_str(invalid_X20magic_X20number_X20_X2502X), + /* K15 */ be_nested_str(internal_error), }), &be_const_str_init, &be_const_str_solidified, - ( &(const binstruction[61]) { /* code */ + ( &(const binstruction[60]) { /* code */ 0x90020101, // 0000 SETMBR R0 K0 K1 0x90020501, // 0001 SETMBR R0 K2 K1 0x90020701, // 0002 SETMBR R0 K3 K1 @@ -1842,14 +1831,13 @@ be_local_closure(Partition_info_init, /* name */ 0x541A0003, // 0032 LDINT R6 4 0x7C0C0600, // 0033 CALL R3 3 0x90020E03, // 0034 SETMBR R0 K7 R3 - 0x70020005, // 0035 JMP #003C - 0xA40E1C00, // 0036 IMPORT R3 K14 - 0x8C10070F, // 0037 GETMET R4 R3 K15 - 0x58180010, // 0038 LDCONST R6 K16 - 0x5C1C0400, // 0039 MOVE R7 R2 - 0x7C100600, // 003A CALL R4 3 - 0xB0062204, // 003B RAISE 1 K17 R4 - 0x80000000, // 003C RET 0 + 0x70020004, // 0035 JMP #003B + 0x600C0018, // 0036 GETGBL R3 G24 + 0x5810000E, // 0037 LDCONST R4 K14 + 0x5C140400, // 0038 MOVE R5 R2 + 0x7C0C0400, // 0039 CALL R3 2 + 0xB0061E03, // 003A RAISE 1 K15 R3 + 0x80000000, // 003B RET 0 }) ) ); @@ -1861,7 +1849,7 @@ be_local_closure(Partition_info_init, /* name */ ********************************************************************/ be_local_closure(Partition_info_subtype_to_string, /* name */ be_nested_proto( - 6, /* nstack */ + 4, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1869,7 +1857,7 @@ be_local_closure(Partition_info_subtype_to_string, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[21]) { /* constants */ + ( &(const bvalue[19]) { /* constants */ /* K0 */ be_nested_str(type), /* K1 */ be_const_int(0), /* K2 */ be_nested_str(subtype), @@ -1888,13 +1876,11 @@ be_local_closure(Partition_info_subtype_to_string, /* name */ /* K15 */ be_nested_str(esphttpd), /* K16 */ be_nested_str(fat), /* K17 */ be_nested_str(spiffs), - /* K18 */ be_nested_str(string), - /* K19 */ be_nested_str(format), - /* K20 */ be_nested_str(0x_X2502X), + /* K18 */ be_nested_str(0x_X2502X), }), &be_const_str_subtype_to_string, &be_const_str_solidified, - ( &(const binstruction[88]) { /* code */ + ( &(const binstruction[87]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 0x1C040301, // 0001 EQ R1 R1 K1 0x7806001A, // 0002 JMPF R1 #001E @@ -1977,12 +1963,11 @@ be_local_closure(Partition_info_subtype_to_string, /* name */ 0x1C040202, // 004F EQ R1 R1 R2 0x78060000, // 0050 JMPF R1 #0052 0x80062200, // 0051 RET 1 K17 - 0xA4062400, // 0052 IMPORT R1 K18 - 0x8C080313, // 0053 GETMET R2 R1 K19 - 0x58100014, // 0054 LDCONST R4 K20 - 0x88140102, // 0055 GETMBR R5 R0 K2 - 0x7C080600, // 0056 CALL R2 3 - 0x80040400, // 0057 RET 1 R2 + 0x60040018, // 0052 GETGBL R1 G24 + 0x58080012, // 0053 LDCONST R2 K18 + 0x880C0102, // 0054 GETMBR R3 R0 K2 + 0x7C040400, // 0055 CALL R1 2 + 0x80040200, // 0056 RET 1 R1 }) ) ); @@ -1994,7 +1979,7 @@ be_local_closure(Partition_info_subtype_to_string, /* name */ ********************************************************************/ be_local_closure(Partition_info_tostring, /* name */ be_nested_proto( - 15, /* nstack */ + 13, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2002,52 +1987,49 @@ be_local_closure(Partition_info_tostring, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[14]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(type_to_string), - /* K2 */ be_nested_str(subtype_to_string), - /* K3 */ be_nested_str(), - /* K4 */ be_nested_str(_X20_X28), - /* K5 */ be_nested_str(_X29), - /* K6 */ be_nested_str(format), - /* K7 */ be_nested_str(_X3Cinstance_X3A_X20Partition_info_X28_X25d_X25s_X2C_X25d_X25s_X2C0x_X2508X_X2C0x_X2508X_X2C_X27_X25s_X27_X2C0x_X25X_X29_X3E), - /* K8 */ be_nested_str(type), - /* K9 */ be_nested_str(subtype), - /* K10 */ be_nested_str(start), - /* K11 */ be_nested_str(sz), - /* K12 */ be_nested_str(label), - /* K13 */ be_nested_str(flags), + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str(type_to_string), + /* K1 */ be_nested_str(subtype_to_string), + /* K2 */ be_nested_str(), + /* K3 */ be_nested_str(_X20_X28), + /* K4 */ be_nested_str(_X29), + /* K5 */ be_nested_str(_X3Cinstance_X3A_X20Partition_info_X28_X25d_X25s_X2C_X25d_X25s_X2C0x_X2508X_X2C0x_X2508X_X2C_X27_X25s_X27_X2C0x_X25X_X29_X3E), + /* K6 */ be_nested_str(type), + /* K7 */ be_nested_str(subtype), + /* K8 */ be_nested_str(start), + /* K9 */ be_nested_str(sz), + /* K10 */ be_nested_str(label), + /* K11 */ be_nested_str(flags), }), &be_const_str_tostring, &be_const_str_solidified, - ( &(const binstruction[27]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080101, // 0001 GETMET R2 R0 K1 - 0x7C080200, // 0002 CALL R2 1 - 0x8C0C0102, // 0003 GETMET R3 R0 K2 - 0x7C0C0200, // 0004 CALL R3 1 - 0x20100503, // 0005 NE R4 R2 K3 - 0x78120002, // 0006 JMPF R4 #000A - 0x00120802, // 0007 ADD R4 K4 R2 - 0x00100905, // 0008 ADD R4 R4 K5 - 0x5C080800, // 0009 MOVE R2 R4 - 0x20100703, // 000A NE R4 R3 K3 - 0x78120002, // 000B JMPF R4 #000F - 0x00120803, // 000C ADD R4 K4 R3 - 0x00100905, // 000D ADD R4 R4 K5 - 0x5C0C0800, // 000E MOVE R3 R4 - 0x8C100306, // 000F GETMET R4 R1 K6 - 0x58180007, // 0010 LDCONST R6 K7 - 0x881C0108, // 0011 GETMBR R7 R0 K8 - 0x5C200400, // 0012 MOVE R8 R2 - 0x88240109, // 0013 GETMBR R9 R0 K9 - 0x5C280600, // 0014 MOVE R10 R3 - 0x882C010A, // 0015 GETMBR R11 R0 K10 - 0x8830010B, // 0016 GETMBR R12 R0 K11 - 0x8834010C, // 0017 GETMBR R13 R0 K12 - 0x8838010D, // 0018 GETMBR R14 R0 K13 - 0x7C101400, // 0019 CALL R4 10 - 0x80040800, // 001A RET 1 R4 + ( &(const binstruction[26]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x8C080101, // 0002 GETMET R2 R0 K1 + 0x7C080200, // 0003 CALL R2 1 + 0x200C0302, // 0004 NE R3 R1 K2 + 0x780E0002, // 0005 JMPF R3 #0009 + 0x000E0601, // 0006 ADD R3 K3 R1 + 0x000C0704, // 0007 ADD R3 R3 K4 + 0x5C040600, // 0008 MOVE R1 R3 + 0x200C0502, // 0009 NE R3 R2 K2 + 0x780E0002, // 000A JMPF R3 #000E + 0x000E0602, // 000B ADD R3 K3 R2 + 0x000C0704, // 000C ADD R3 R3 K4 + 0x5C080600, // 000D MOVE R2 R3 + 0x600C0018, // 000E GETGBL R3 G24 + 0x58100005, // 000F LDCONST R4 K5 + 0x88140106, // 0010 GETMBR R5 R0 K6 + 0x5C180200, // 0011 MOVE R6 R1 + 0x881C0107, // 0012 GETMBR R7 R0 K7 + 0x5C200400, // 0013 MOVE R8 R2 + 0x88240108, // 0014 GETMBR R9 R0 K8 + 0x88280109, // 0015 GETMBR R10 R0 K9 + 0x882C010A, // 0016 GETMBR R11 R0 K10 + 0x8830010B, // 0017 GETMBR R12 R0 K11 + 0x7C0C1200, // 0018 CALL R3 9 + 0x80040600, // 0019 RET 1 R3 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_persist.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_persist.h index aed177dfa7d3..935b07d6533b 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_persist.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_persist.h @@ -4,6 +4,34 @@ \********************************************************************/ #include "be_constobj.h" +/******************************************************************** +** Solidified function: _anonymous_ +********************************************************************/ +be_local_closure(persist__anonymous_, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str(Persist), + }), + &be_const_str__anonymous_, + &be_const_str_solidified, + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80040200, // 0002 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + extern const bclass be_class_Persist; /******************************************************************** @@ -331,7 +359,7 @@ be_local_closure(Persist_save, /* name */ }), &be_const_str_save, &be_const_str_solidified, - ( &(const binstruction[37]) { /* code */ + ( &(const binstruction[48]) { /* code */ 0x4C040000, // 0000 LDNIL R1 0xA802000B, // 0001 EXBLK 0 #000E 0x60080011, // 0002 GETGBL R2 G17 @@ -345,30 +373,41 @@ be_local_closure(Persist_save, /* name */ 0x8C080303, // 000A GETMET R2 R1 K3 0x7C080200, // 000B CALL R2 1 0xA8040001, // 000C EXBLK 1 1 - 0x70020013, // 000D JMP #0022 + 0x7002001E, // 000D JMP #002D 0xAC080002, // 000E CATCH R2 0 2 - 0x70020010, // 000F JMP #0021 + 0x7002001B, // 000F JMP #002C 0x4C100000, // 0010 LDNIL R4 0x20100204, // 0011 NE R4 R1 R4 0x78120001, // 0012 JMPF R4 #0015 0x8C100303, // 0013 GETMET R4 R1 K3 0x7C100200, // 0014 CALL R4 1 - 0x60100011, // 0015 GETGBL R4 G17 - 0x88140100, // 0016 GETMBR R5 R0 K0 - 0x58180001, // 0017 LDCONST R6 K1 - 0x7C100400, // 0018 CALL R4 2 - 0x5C040800, // 0019 MOVE R1 R4 - 0x8C100304, // 001A GETMET R4 R1 K4 - 0x58180005, // 001B LDCONST R6 K5 - 0x7C100400, // 001C CALL R4 2 - 0x8C100303, // 001D GETMET R4 R1 K3 - 0x7C100200, // 001E CALL R4 1 - 0xB0040403, // 001F RAISE 1 R2 R3 - 0x70020000, // 0020 JMP #0022 - 0xB0080000, // 0021 RAISE 2 R0 R0 - 0x50080000, // 0022 LDBOOL R2 0 0 - 0x90020C02, // 0023 SETMBR R0 K6 R2 - 0x80000000, // 0024 RET 0 + 0x4C040000, // 0015 LDNIL R1 + 0xA8020009, // 0016 EXBLK 0 #0021 + 0x60100011, // 0017 GETGBL R4 G17 + 0x88140100, // 0018 GETMBR R5 R0 K0 + 0x58180001, // 0019 LDCONST R6 K1 + 0x7C100400, // 001A CALL R4 2 + 0x5C040800, // 001B MOVE R1 R4 + 0x8C100304, // 001C GETMET R4 R1 K4 + 0x58180005, // 001D LDCONST R6 K5 + 0x7C100400, // 001E CALL R4 2 + 0xA8040001, // 001F EXBLK 1 1 + 0x70020003, // 0020 JMP #0025 + 0xAC100000, // 0021 CATCH R4 0 0 + 0x70020000, // 0022 JMP #0024 + 0x70020000, // 0023 JMP #0025 + 0xB0080000, // 0024 RAISE 2 R0 R0 + 0x4C100000, // 0025 LDNIL R4 + 0x20100204, // 0026 NE R4 R1 R4 + 0x78120001, // 0027 JMPF R4 #002A + 0x8C100303, // 0028 GETMET R4 R1 K3 + 0x7C100200, // 0029 CALL R4 1 + 0xB0040403, // 002A RAISE 1 R2 R3 + 0x70020000, // 002B JMP #002D + 0xB0080000, // 002C RAISE 2 R0 R0 + 0x50080000, // 002D LDBOOL R2 0 0 + 0x90020C02, // 002E SETMBR R0 K6 R2 + 0x80000000, // 002F RET 0 }) ) ); @@ -505,37 +544,35 @@ be_local_closure(Persist_init, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str(_filename), - /* K1 */ be_nested_str(_persist_X2Ejson), - /* K2 */ be_nested_str(_p), - /* K3 */ be_nested_str(copy), - /* K4 */ be_nested_str(load), - /* K5 */ be_nested_str(_dirty), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str(_p), + /* K1 */ be_nested_str(copy), + /* K2 */ be_nested_str(load), + /* K3 */ be_nested_str(_filename), + /* K4 */ be_nested_str(_dirty), }), &be_const_str_init, &be_const_str_solidified, - ( &(const binstruction[20]) { /* code */ - 0x90020101, // 0000 SETMBR R0 K0 K1 - 0x6008000F, // 0001 GETGBL R2 G15 - 0x5C0C0200, // 0002 MOVE R3 R1 - 0x60100013, // 0003 GETGBL R4 G19 - 0x7C080400, // 0004 CALL R2 2 - 0x780A0003, // 0005 JMPF R2 #000A - 0x8C080303, // 0006 GETMET R2 R1 K3 - 0x7C080200, // 0007 CALL R2 1 - 0x90020402, // 0008 SETMBR R0 K2 R2 - 0x70020002, // 0009 JMP #000D - 0x60080013, // 000A GETGBL R2 G19 - 0x7C080000, // 000B CALL R2 0 - 0x90020402, // 000C SETMBR R0 K2 R2 - 0x8C080104, // 000D GETMET R2 R0 K4 - 0x88100102, // 000E GETMBR R4 R0 K2 - 0x88140100, // 000F GETMBR R5 R0 K0 - 0x7C080600, // 0010 CALL R2 3 - 0x50080000, // 0011 LDBOOL R2 0 0 - 0x90020A02, // 0012 SETMBR R0 K5 R2 - 0x80000000, // 0013 RET 0 + ( &(const binstruction[19]) { /* code */ + 0x6008000F, // 0000 GETGBL R2 G15 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x60100013, // 0002 GETGBL R4 G19 + 0x7C080400, // 0003 CALL R2 2 + 0x780A0003, // 0004 JMPF R2 #0009 + 0x8C080301, // 0005 GETMET R2 R1 K1 + 0x7C080200, // 0006 CALL R2 1 + 0x90020002, // 0007 SETMBR R0 K0 R2 + 0x70020002, // 0008 JMP #000C + 0x60080013, // 0009 GETGBL R2 G19 + 0x7C080000, // 000A CALL R2 0 + 0x90020002, // 000B SETMBR R0 K0 R2 + 0x8C080102, // 000C GETMET R2 R0 K2 + 0x88100100, // 000D GETMBR R4 R0 K0 + 0x88140103, // 000E GETMBR R5 R0 K3 + 0x7C080600, // 000F CALL R2 3 + 0x50080000, // 0010 LDBOOL R2 0 0 + 0x90020802, // 0011 SETMBR R0 K4 R2 + 0x80000000, // 0012 RET 0 }) ) ); @@ -634,7 +671,7 @@ be_local_closure(Persist_has, /* name */ ** Solidified class: Persist ********************************************************************/ be_local_class(Persist, - 3, + 2, NULL, be_nested_map(16, ( (struct bmapnode*) &(const bmapnode[]) { @@ -648,54 +685,25 @@ be_local_class(Persist, { be_const_key(find, -1), be_const_closure(Persist_find_closure) }, { be_const_key(save, -1), be_const_closure(Persist_save_closure) }, { be_const_key(json_fdump_any, 12), be_const_closure(Persist_json_fdump_any_closure) }, - { be_const_key(_p, 7), be_const_var(1) }, - { be_const_key(_filename, -1), be_const_var(0) }, + { be_const_key(_p, 7), be_const_var(0) }, + { be_const_key(_filename, -1), be_nested_str(_persist_X2Ejson) }, { be_const_key(load, -1), be_const_closure(Persist_load_closure) }, { be_const_key(json_fdump_map, 5), be_const_closure(Persist_json_fdump_map_closure) }, - { be_const_key(_dirty, -1), be_const_var(2) }, + { be_const_key(_dirty, -1), be_const_var(1) }, { be_const_key(member, -1), be_const_closure(Persist_member_closure) }, })), (bstring*) &be_const_str_Persist ); -/******************************************************************** -** Solidified function: _anonymous_ -********************************************************************/ -be_local_closure(persist__anonymous_, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_const_class(be_class_Persist), - }), - &be_const_str__anonymous_, - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0xB4000000, // 0001 CLASS K0 - 0x5C080200, // 0002 MOVE R2 R1 - 0x7C080000, // 0003 CALL R2 0 - 0x80040400, // 0004 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified module: persist ********************************************************************/ be_local_module(persist, "persist", - be_nested_map(1, + be_nested_map(2, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key(init, -1), be_const_closure(persist__anonymous__closure) }, + { be_const_key(Persist, -1), be_const_class(be_class_Persist) }, + { be_const_key(init, 0), be_const_closure(persist__anonymous__closure) }, })) ); BE_EXPORT_VARIABLE be_define_const_native_module(persist); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_rule_matcher.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_rule_matcher.h index b8e5bbfb74e5..ced3ca45eb0b 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_rule_matcher.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_rule_matcher.h @@ -1052,12 +1052,39 @@ void be_load_Rule_Matcher_Array_class(bvm *vm) { be_pop(vm, 1); } -extern const bclass be_class_Rule_Matcher; +extern const bclass be_class_Rule_Matcher_AND_List; + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Rule_Matcher_AND_List_init, /* name */ + be_nested_proto( + 2, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str(and_list), + }), + &be_const_str_init, + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x80000000, // 0001 RET 0 + }) + ) +); +/*******************************************************************/ + /******************************************************************** ** Solidified function: tostring ********************************************************************/ -be_local_closure(Rule_Matcher_tostring, /* name */ +be_local_closure(Rule_Matcher_AND_List_tostring, /* name */ be_nested_proto( 3, /* nstack */ 1, /* argc */ @@ -1067,16 +1094,20 @@ be_local_closure(Rule_Matcher_tostring, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str(matchers), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str(_X3CMatcher_AND_List_X20), + /* K1 */ be_nested_str(and_list), + /* K2 */ be_nested_str(_X3E), }), &be_const_str_tostring, &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ + ( &(const binstruction[ 6]) { /* code */ 0x60040008, // 0000 GETGBL R1 G8 - 0x88080100, // 0001 GETMBR R2 R0 K0 + 0x88080101, // 0001 GETMBR R2 R0 K1 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 + 0x00060001, // 0003 ADD R1 K0 R1 + 0x00040302, // 0004 ADD R1 R1 K2 + 0x80040200, // 0005 RET 1 R1 }) ) ); @@ -1084,153 +1115,106 @@ be_local_closure(Rule_Matcher_tostring, /* name */ /******************************************************************** -** Solidified function: parse +** Solidified function: match ********************************************************************/ -be_local_closure(Rule_Matcher_parse, /* name */ +be_local_closure(Rule_Matcher_AND_List_match, /* name */ be_nested_proto( - 20, /* nstack */ + 9, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str(and_list), + /* K2 */ be_nested_str(match), + /* K3 */ be_nested_str(push), + /* K4 */ be_const_int(1), + }), + &be_const_str_match, + &be_const_str_solidified, + ( &(const binstruction[24]) { /* code */ + 0x58080000, // 0000 LDCONST R2 K0 + 0x600C0012, // 0001 GETGBL R3 G18 + 0x7C0C0000, // 0002 CALL R3 0 + 0x6010000C, // 0003 GETGBL R4 G12 + 0x88140101, // 0004 GETMBR R5 R0 K1 + 0x7C100200, // 0005 CALL R4 1 + 0x14100404, // 0006 LT R4 R2 R4 + 0x7812000E, // 0007 JMPF R4 #0017 + 0x88100101, // 0008 GETMBR R4 R0 K1 + 0x94100802, // 0009 GETIDX R4 R4 R2 + 0x8C140902, // 000A GETMET R5 R4 K2 + 0x5C1C0200, // 000B MOVE R7 R1 + 0x7C140400, // 000C CALL R5 2 + 0x4C180000, // 000D LDNIL R6 + 0x1C180A06, // 000E EQ R6 R5 R6 + 0x781A0001, // 000F JMPF R6 #0012 + 0x4C180000, // 0010 LDNIL R6 + 0x80040C00, // 0011 RET 1 R6 + 0x8C180703, // 0012 GETMET R6 R3 K3 + 0x5C200A00, // 0013 MOVE R8 R5 + 0x7C180400, // 0014 CALL R6 2 + 0x00080504, // 0015 ADD R2 R2 K4 + 0x7001FFEB, // 0016 JMP #0003 + 0x80040600, // 0017 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Rule_Matcher_AND_List +********************************************************************/ +be_local_class(Rule_Matcher_AND_List, + 1, + NULL, + be_nested_map(4, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key(and_list, -1), be_const_var(0) }, + { be_const_key(tostring, -1), be_const_closure(Rule_Matcher_AND_List_tostring_closure) }, + { be_const_key(match, -1), be_const_closure(Rule_Matcher_AND_List_match_closure) }, + { be_const_key(init, 0), be_const_closure(Rule_Matcher_AND_List_init_closure) }, + })), + (bstring*) &be_const_str_Rule_Matcher_AND_List +); +/*******************************************************************/ + +void be_load_Rule_Matcher_AND_List_class(bvm *vm) { + be_pushntvclass(vm, &be_class_Rule_Matcher_AND_List); + be_setglobal(vm, "Rule_Matcher_AND_List"); + be_pop(vm, 1); +} + +extern const bclass be_class_Rule_Matcher; + +/******************************************************************** +** Solidified function: tostring +********************************************************************/ +be_local_closure(Rule_Matcher_tostring, /* name */ + be_nested_proto( + 3, /* nstack */ 1, /* argc */ - 4, /* varg */ + 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[22]) { /* constants */ - /* K0 */ be_const_class(be_class_Rule_Matcher), - /* K1 */ be_nested_str(string), - /* K2 */ be_nested_str(tasmota), - /* K3 */ be_nested_str(find_op), - /* K4 */ be_const_int(0), - /* K5 */ be_const_int(1), - /* K6 */ be_const_int(2), - /* K7 */ be_nested_str(find), - /* K8 */ be_nested_str(_X23), - /* K9 */ be_nested_str(pattern_error), - /* K10 */ be_nested_str(empty_X20pattern_X20not_X20allowed), - /* K11 */ be_const_int(2147483647), - /* K12 */ be_nested_str(_X5B), - /* K13 */ be_nested_str(_X5D), - /* K14 */ be_nested_str(value_error), - /* K15 */ be_nested_str(missing_X20_X27_X5D_X27_X20in_X20rule_X20pattern), - /* K16 */ be_nested_str(_X3F), - /* K17 */ be_nested_str(push), - /* K18 */ be_nested_str(Rule_Matcher_Wildcard), - /* K19 */ be_nested_str(Rule_Matcher_Key), - /* K20 */ be_nested_str(Rule_Matcher_Array), - /* K21 */ be_nested_str(Rule_Matcher_Operator), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str(matchers), }), - &be_const_str_parse, + &be_const_str_tostring, &be_const_str_solidified, - ( &(const binstruction[108]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0x4C0C0000, // 0002 LDNIL R3 - 0x1C0C0003, // 0003 EQ R3 R0 R3 - 0x780E0001, // 0004 JMPF R3 #0007 - 0x4C0C0000, // 0005 LDNIL R3 - 0x80040600, // 0006 RET 1 R3 - 0x600C0012, // 0007 GETGBL R3 G18 - 0x7C0C0000, // 0008 CALL R3 0 - 0xB8120400, // 0009 GETNGBL R4 K2 - 0x8C100903, // 000A GETMET R4 R4 K3 - 0x5C180000, // 000B MOVE R6 R0 - 0x7C100400, // 000C CALL R4 2 - 0x94140904, // 000D GETIDX R5 R4 K4 - 0x94180905, // 000E GETIDX R6 R4 K5 - 0x941C0906, // 000F GETIDX R7 R4 K6 - 0x6020000C, // 0010 GETGBL R8 G12 - 0x5C240A00, // 0011 MOVE R9 R5 - 0x7C200200, // 0012 CALL R8 1 - 0x58240004, // 0013 LDCONST R9 K4 - 0x5429FFFE, // 0014 LDINT R10 -1 - 0x142C1208, // 0015 LT R11 R9 R8 - 0x782E0042, // 0016 JMPF R11 #005A - 0x8C2C0507, // 0017 GETMET R11 R2 K7 - 0x5C340A00, // 0018 MOVE R13 R5 - 0x58380008, // 0019 LDCONST R14 K8 - 0x5C3C1200, // 001A MOVE R15 R9 - 0x7C2C0800, // 001B CALL R11 4 - 0x4C300000, // 001C LDNIL R12 - 0x28341704, // 001D GE R13 R11 K4 - 0x78360008, // 001E JMPF R13 #0028 - 0x1C341609, // 001F EQ R13 R11 R9 - 0x78360000, // 0020 JMPF R13 #0022 - 0xB006130A, // 0021 RAISE 1 K9 K10 - 0x04341705, // 0022 SUB R13 R11 K5 - 0x4034120D, // 0023 CONNECT R13 R9 R13 - 0x94300A0D, // 0024 GETIDX R12 R5 R13 - 0x00381705, // 0025 ADD R14 R11 K5 - 0x5C241C00, // 0026 MOVE R9 R14 - 0x70020002, // 0027 JMP #002B - 0x4034130B, // 0028 CONNECT R13 R9 K11 - 0x94300A0D, // 0029 GETIDX R12 R5 R13 - 0x5C241000, // 002A MOVE R9 R8 - 0x8C340507, // 002B GETMET R13 R2 K7 - 0x5C3C1800, // 002C MOVE R15 R12 - 0x5840000C, // 002D LDCONST R16 K12 - 0x7C340600, // 002E CALL R13 3 - 0x4C380000, // 002F LDNIL R14 - 0x283C1B04, // 0030 GE R15 R13 K4 - 0x783E0012, // 0031 JMPF R15 #0045 - 0x8C3C0507, // 0032 GETMET R15 R2 K7 - 0x5C441800, // 0033 MOVE R17 R12 - 0x5848000D, // 0034 LDCONST R18 K13 - 0x5C4C1A00, // 0035 MOVE R19 R13 - 0x7C3C0800, // 0036 CALL R15 4 - 0x14401F04, // 0037 LT R16 R15 K4 - 0x78420000, // 0038 JMPF R16 #003A - 0xB0061D0F, // 0039 RAISE 1 K14 K15 - 0x00401B05, // 003A ADD R16 R13 K5 - 0x04441F05, // 003B SUB R17 R15 K5 - 0x40402011, // 003C CONNECT R16 R16 R17 - 0x94401810, // 003D GETIDX R16 R12 R16 - 0x04441B05, // 003E SUB R17 R13 K5 - 0x40460811, // 003F CONNECT R17 K4 R17 - 0x94301811, // 0040 GETIDX R12 R12 R17 - 0x60480009, // 0041 GETGBL R18 G9 - 0x5C4C2000, // 0042 MOVE R19 R16 - 0x7C480200, // 0043 CALL R18 1 - 0x5C382400, // 0044 MOVE R14 R18 - 0x1C3C1910, // 0045 EQ R15 R12 K16 - 0x783E0004, // 0046 JMPF R15 #004C - 0x8C3C0711, // 0047 GETMET R15 R3 K17 - 0x8C440312, // 0048 GETMET R17 R1 K18 - 0x7C440200, // 0049 CALL R17 1 - 0x7C3C0400, // 004A CALL R15 2 - 0x70020004, // 004B JMP #0051 - 0x8C3C0711, // 004C GETMET R15 R3 K17 - 0x8C440313, // 004D GETMET R17 R1 K19 - 0x5C4C1800, // 004E MOVE R19 R12 - 0x7C440400, // 004F CALL R17 2 - 0x7C3C0400, // 0050 CALL R15 2 - 0x4C3C0000, // 0051 LDNIL R15 - 0x203C1C0F, // 0052 NE R15 R14 R15 - 0x783E0004, // 0053 JMPF R15 #0059 - 0x8C3C0711, // 0054 GETMET R15 R3 K17 - 0x8C440314, // 0055 GETMET R17 R1 K20 - 0x5C4C1C00, // 0056 MOVE R19 R14 - 0x7C440400, // 0057 CALL R17 2 - 0x7C3C0400, // 0058 CALL R15 2 - 0x7001FFBA, // 0059 JMP #0015 - 0x4C2C0000, // 005A LDNIL R11 - 0x202C0C0B, // 005B NE R11 R6 R11 - 0x782E0008, // 005C JMPF R11 #0066 - 0x4C2C0000, // 005D LDNIL R11 - 0x202C0E0B, // 005E NE R11 R7 R11 - 0x782E0005, // 005F JMPF R11 #0066 - 0x8C2C0711, // 0060 GETMET R11 R3 K17 - 0x8C340315, // 0061 GETMET R13 R1 K21 - 0x5C3C0C00, // 0062 MOVE R15 R6 - 0x5C400E00, // 0063 MOVE R16 R7 - 0x7C340600, // 0064 CALL R13 3 - 0x7C2C0400, // 0065 CALL R11 2 - 0x5C2C0200, // 0066 MOVE R11 R1 - 0x5C300000, // 0067 MOVE R12 R0 - 0x5C340A00, // 0068 MOVE R13 R5 - 0x5C380600, // 0069 MOVE R14 R3 - 0x7C2C0600, // 006A CALL R11 3 - 0x80041600, // 006B RET 1 R11 + ( &(const binstruction[ 4]) { /* code */ + 0x60040008, // 0000 GETGBL R1 G8 + 0x88080100, // 0001 GETMBR R2 R0 K0 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 }) ) ); @@ -1268,6 +1252,203 @@ be_local_closure(Rule_Matcher_init, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: parse +********************************************************************/ +be_local_closure(Rule_Matcher_parse, /* name */ + be_nested_proto( + 20, /* nstack */ + 1, /* argc */ + 4, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[26]) { /* constants */ + /* K0 */ be_const_class(be_class_Rule_Matcher), + /* K1 */ be_nested_str(string), + /* K2 */ be_nested_str(parse), + /* K3 */ be_nested_str(push), + /* K4 */ be_nested_str(trigger), + /* K5 */ be_nested_str(stop_iteration), + /* K6 */ be_nested_str(Rule_Matcher_AND_List), + /* K7 */ be_nested_str(tasmota), + /* K8 */ be_nested_str(find_op), + /* K9 */ be_const_int(0), + /* K10 */ be_const_int(1), + /* K11 */ be_const_int(2), + /* K12 */ be_nested_str(find), + /* K13 */ be_nested_str(_X23), + /* K14 */ be_nested_str(pattern_error), + /* K15 */ be_nested_str(empty_X20pattern_X20not_X20allowed), + /* K16 */ be_const_int(2147483647), + /* K17 */ be_nested_str(_X5B), + /* K18 */ be_nested_str(_X5D), + /* K19 */ be_nested_str(value_error), + /* K20 */ be_nested_str(missing_X20_X27_X5D_X27_X20in_X20rule_X20pattern), + /* K21 */ be_nested_str(_X3F), + /* K22 */ be_nested_str(Rule_Matcher_Wildcard), + /* K23 */ be_nested_str(Rule_Matcher_Key), + /* K24 */ be_nested_str(Rule_Matcher_Array), + /* K25 */ be_nested_str(Rule_Matcher_Operator), + }), + &be_const_str_parse, + &be_const_str_solidified, + ( &(const binstruction[147]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0xA40A0200, // 0001 IMPORT R2 K1 + 0x4C0C0000, // 0002 LDNIL R3 + 0x1C0C0003, // 0003 EQ R3 R0 R3 + 0x780E0001, // 0004 JMPF R3 #0007 + 0x4C0C0000, // 0005 LDNIL R3 + 0x80040600, // 0006 RET 1 R3 + 0x600C000F, // 0007 GETGBL R3 G15 + 0x5C100000, // 0008 MOVE R4 R0 + 0x60140012, // 0009 GETGBL R5 G18 + 0x7C0C0400, // 000A CALL R3 2 + 0x780E0021, // 000B JMPF R3 #002E + 0x600C0012, // 000C GETGBL R3 G18 + 0x7C0C0000, // 000D CALL R3 0 + 0x60100012, // 000E GETGBL R4 G18 + 0x7C100000, // 000F CALL R4 0 + 0x60140010, // 0010 GETGBL R5 G16 + 0x5C180000, // 0011 MOVE R6 R0 + 0x7C140200, // 0012 CALL R5 1 + 0xA802000B, // 0013 EXBLK 0 #0020 + 0x5C180A00, // 0014 MOVE R6 R5 + 0x7C180000, // 0015 CALL R6 0 + 0x8C1C0302, // 0016 GETMET R7 R1 K2 + 0x5C240C00, // 0017 MOVE R9 R6 + 0x7C1C0400, // 0018 CALL R7 2 + 0x8C200703, // 0019 GETMET R8 R3 K3 + 0x5C280E00, // 001A MOVE R10 R7 + 0x7C200400, // 001B CALL R8 2 + 0x8C200903, // 001C GETMET R8 R4 K3 + 0x88280F04, // 001D GETMBR R10 R7 K4 + 0x7C200400, // 001E CALL R8 2 + 0x7001FFF3, // 001F JMP #0014 + 0x58140005, // 0020 LDCONST R5 K5 + 0xAC140200, // 0021 CATCH R5 1 0 + 0xB0080000, // 0022 RAISE 2 R0 R0 + 0x5C140200, // 0023 MOVE R5 R1 + 0x5C180000, // 0024 MOVE R6 R0 + 0x5C1C0800, // 0025 MOVE R7 R4 + 0x60200012, // 0026 GETGBL R8 G18 + 0x7C200000, // 0027 CALL R8 0 + 0x8C240306, // 0028 GETMET R9 R1 K6 + 0x5C2C0600, // 0029 MOVE R11 R3 + 0x7C240400, // 002A CALL R9 2 + 0x40241009, // 002B CONNECT R9 R8 R9 + 0x7C140600, // 002C CALL R5 3 + 0x80040A00, // 002D RET 1 R5 + 0x600C0012, // 002E GETGBL R3 G18 + 0x7C0C0000, // 002F CALL R3 0 + 0xB8120E00, // 0030 GETNGBL R4 K7 + 0x8C100908, // 0031 GETMET R4 R4 K8 + 0x5C180000, // 0032 MOVE R6 R0 + 0x7C100400, // 0033 CALL R4 2 + 0x94140909, // 0034 GETIDX R5 R4 K9 + 0x9418090A, // 0035 GETIDX R6 R4 K10 + 0x941C090B, // 0036 GETIDX R7 R4 K11 + 0x6020000C, // 0037 GETGBL R8 G12 + 0x5C240A00, // 0038 MOVE R9 R5 + 0x7C200200, // 0039 CALL R8 1 + 0x58240009, // 003A LDCONST R9 K9 + 0x5429FFFE, // 003B LDINT R10 -1 + 0x142C1208, // 003C LT R11 R9 R8 + 0x782E0042, // 003D JMPF R11 #0081 + 0x8C2C050C, // 003E GETMET R11 R2 K12 + 0x5C340A00, // 003F MOVE R13 R5 + 0x5838000D, // 0040 LDCONST R14 K13 + 0x5C3C1200, // 0041 MOVE R15 R9 + 0x7C2C0800, // 0042 CALL R11 4 + 0x4C300000, // 0043 LDNIL R12 + 0x28341709, // 0044 GE R13 R11 K9 + 0x78360008, // 0045 JMPF R13 #004F + 0x1C341609, // 0046 EQ R13 R11 R9 + 0x78360000, // 0047 JMPF R13 #0049 + 0xB0061D0F, // 0048 RAISE 1 K14 K15 + 0x0434170A, // 0049 SUB R13 R11 K10 + 0x4034120D, // 004A CONNECT R13 R9 R13 + 0x94300A0D, // 004B GETIDX R12 R5 R13 + 0x0038170A, // 004C ADD R14 R11 K10 + 0x5C241C00, // 004D MOVE R9 R14 + 0x70020002, // 004E JMP #0052 + 0x40341310, // 004F CONNECT R13 R9 K16 + 0x94300A0D, // 0050 GETIDX R12 R5 R13 + 0x5C241000, // 0051 MOVE R9 R8 + 0x8C34050C, // 0052 GETMET R13 R2 K12 + 0x5C3C1800, // 0053 MOVE R15 R12 + 0x58400011, // 0054 LDCONST R16 K17 + 0x7C340600, // 0055 CALL R13 3 + 0x4C380000, // 0056 LDNIL R14 + 0x283C1B09, // 0057 GE R15 R13 K9 + 0x783E0012, // 0058 JMPF R15 #006C + 0x8C3C050C, // 0059 GETMET R15 R2 K12 + 0x5C441800, // 005A MOVE R17 R12 + 0x58480012, // 005B LDCONST R18 K18 + 0x5C4C1A00, // 005C MOVE R19 R13 + 0x7C3C0800, // 005D CALL R15 4 + 0x14401F09, // 005E LT R16 R15 K9 + 0x78420000, // 005F JMPF R16 #0061 + 0xB0062714, // 0060 RAISE 1 K19 K20 + 0x00401B0A, // 0061 ADD R16 R13 K10 + 0x04441F0A, // 0062 SUB R17 R15 K10 + 0x40402011, // 0063 CONNECT R16 R16 R17 + 0x94401810, // 0064 GETIDX R16 R12 R16 + 0x04441B0A, // 0065 SUB R17 R13 K10 + 0x40461211, // 0066 CONNECT R17 K9 R17 + 0x94301811, // 0067 GETIDX R12 R12 R17 + 0x60480009, // 0068 GETGBL R18 G9 + 0x5C4C2000, // 0069 MOVE R19 R16 + 0x7C480200, // 006A CALL R18 1 + 0x5C382400, // 006B MOVE R14 R18 + 0x1C3C1915, // 006C EQ R15 R12 K21 + 0x783E0004, // 006D JMPF R15 #0073 + 0x8C3C0703, // 006E GETMET R15 R3 K3 + 0x8C440316, // 006F GETMET R17 R1 K22 + 0x7C440200, // 0070 CALL R17 1 + 0x7C3C0400, // 0071 CALL R15 2 + 0x70020004, // 0072 JMP #0078 + 0x8C3C0703, // 0073 GETMET R15 R3 K3 + 0x8C440317, // 0074 GETMET R17 R1 K23 + 0x5C4C1800, // 0075 MOVE R19 R12 + 0x7C440400, // 0076 CALL R17 2 + 0x7C3C0400, // 0077 CALL R15 2 + 0x4C3C0000, // 0078 LDNIL R15 + 0x203C1C0F, // 0079 NE R15 R14 R15 + 0x783E0004, // 007A JMPF R15 #0080 + 0x8C3C0703, // 007B GETMET R15 R3 K3 + 0x8C440318, // 007C GETMET R17 R1 K24 + 0x5C4C1C00, // 007D MOVE R19 R14 + 0x7C440400, // 007E CALL R17 2 + 0x7C3C0400, // 007F CALL R15 2 + 0x7001FFBA, // 0080 JMP #003C + 0x4C2C0000, // 0081 LDNIL R11 + 0x202C0C0B, // 0082 NE R11 R6 R11 + 0x782E0008, // 0083 JMPF R11 #008D + 0x4C2C0000, // 0084 LDNIL R11 + 0x202C0E0B, // 0085 NE R11 R7 R11 + 0x782E0005, // 0086 JMPF R11 #008D + 0x8C2C0703, // 0087 GETMET R11 R3 K3 + 0x8C340319, // 0088 GETMET R13 R1 K25 + 0x5C3C0C00, // 0089 MOVE R15 R6 + 0x5C400E00, // 008A MOVE R16 R7 + 0x7C340600, // 008B CALL R13 3 + 0x7C2C0400, // 008C CALL R11 2 + 0x5C2C0200, // 008D MOVE R11 R1 + 0x5C300000, // 008E MOVE R12 R0 + 0x5C340A00, // 008F MOVE R13 R5 + 0x5C380600, // 0090 MOVE R14 R3 + 0x7C2C0600, // 0091 CALL R11 3 + 0x80041600, // 0092 RET 1 R11 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: match ********************************************************************/ @@ -1329,19 +1510,20 @@ be_local_closure(Rule_Matcher_match, /* name */ be_local_class(Rule_Matcher, 3, NULL, - be_nested_map(11, + be_nested_map(12, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key(Rule_Matcher_Wildcard, -1), be_const_class(be_class_Rule_Matcher_Wildcard) }, - { be_const_key(Rule_Matcher_Array, -1), be_const_class(be_class_Rule_Matcher_Array) }, - { be_const_key(trigger, -1), be_const_var(1) }, - { be_const_key(tostring, 2), be_const_closure(Rule_Matcher_tostring_closure) }, - { be_const_key(init, 7), be_const_closure(Rule_Matcher_init_closure) }, + { be_const_key(Rule_Matcher_AND_List, -1), be_const_class(be_class_Rule_Matcher_AND_List) }, + { be_const_key(tostring, 0), be_const_closure(Rule_Matcher_tostring_closure) }, + { be_const_key(match, 6), be_const_closure(Rule_Matcher_match_closure) }, + { be_const_key(init, 5), be_const_closure(Rule_Matcher_init_closure) }, + { be_const_key(Rule_Matcher_Array, 11), be_const_class(be_class_Rule_Matcher_Array) }, + { be_const_key(rule, -1), be_const_var(0) }, { be_const_key(Rule_Matcher_Key, -1), be_const_class(be_class_Rule_Matcher_Key) }, + { be_const_key(Rule_Matcher_Operator, 8), be_const_class(be_class_Rule_Matcher_Operator) }, + { be_const_key(trigger, -1), be_const_var(1) }, + { be_const_key(Rule_Matcher_Wildcard, -1), be_const_class(be_class_Rule_Matcher_Wildcard) }, + { be_const_key(matchers, 2), be_const_var(2) }, { be_const_key(parse, -1), be_const_static_closure(Rule_Matcher_parse_closure) }, - { be_const_key(rule, -1), be_const_var(0) }, - { be_const_key(matchers, 6), be_const_var(2) }, - { be_const_key(Rule_Matcher_Operator, 4), be_const_class(be_class_Rule_Matcher_Operator) }, - { be_const_key(match, -1), be_const_closure(Rule_Matcher_match_closure) }, })), (bstring*) &be_const_str_Rule_Matcher ); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_tapp.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_tapp.h index 67cacbde3c6f..77f4f1f03a31 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_tapp.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_tapp.h @@ -42,7 +42,7 @@ be_local_closure(Tapp_init, /* name */ ********************************************************************/ be_local_closure(Tapp_autoexec, /* name */ be_nested_proto( - 12, /* nstack */ + 11, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -50,7 +50,7 @@ be_local_closure(Tapp_autoexec, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ + ( &(const bvalue[14]) { /* constants */ /* K0 */ be_nested_str(path), /* K1 */ be_nested_str(string), /* K2 */ be_nested_str(listdir), @@ -60,12 +60,11 @@ be_local_closure(Tapp_autoexec, /* name */ /* K6 */ be_const_int(0), /* K7 */ be_nested_str(tasmota), /* K8 */ be_nested_str(log), - /* K9 */ be_nested_str(format), - /* K10 */ be_nested_str(TAP_X3A_X20Loaded_X20Tasmota_X20App_X20_X27_X25s_X27), - /* K11 */ be_const_int(2), - /* K12 */ be_nested_str(load), - /* K13 */ be_nested_str(_X23autoexec_X2Ebe), - /* K14 */ be_nested_str(stop_iteration), + /* K9 */ be_nested_str(TAP_X3A_X20Loaded_X20Tasmota_X20App_X20_X27_X25s_X27), + /* K10 */ be_const_int(2), + /* K11 */ be_nested_str(load), + /* K12 */ be_nested_str(_X23autoexec_X2Ebe), + /* K13 */ be_nested_str(stop_iteration), }), &be_const_str_autoexec, &be_const_str_solidified, @@ -89,18 +88,18 @@ be_local_closure(Tapp_autoexec, /* name */ 0x781A000B, // 0010 JMPF R6 #001D 0xB81A0E00, // 0011 GETNGBL R6 K7 0x8C180D08, // 0012 GETMET R6 R6 K8 - 0x8C200509, // 0013 GETMET R8 R2 K9 - 0x5828000A, // 0014 LDCONST R10 K10 - 0x5C2C0A00, // 0015 MOVE R11 R5 - 0x7C200600, // 0016 CALL R8 3 - 0x5824000B, // 0017 LDCONST R9 K11 + 0x60200018, // 0013 GETGBL R8 G24 + 0x58240009, // 0014 LDCONST R9 K9 + 0x5C280A00, // 0015 MOVE R10 R5 + 0x7C200400, // 0016 CALL R8 2 + 0x5824000A, // 0017 LDCONST R9 K10 0x7C180600, // 0018 CALL R6 3 0xB81A0E00, // 0019 GETNGBL R6 K7 - 0x8C180D0C, // 001A GETMET R6 R6 K12 - 0x00200B0D, // 001B ADD R8 R5 K13 + 0x8C180D0B, // 001A GETMET R6 R6 K11 + 0x00200B0C, // 001B ADD R8 R5 K12 0x7C180400, // 001C CALL R6 2 0x7001FFEA, // 001D JMP #0009 - 0x5810000E, // 001E LDCONST R4 K14 + 0x5810000D, // 001E LDCONST R4 K13 0xAC100200, // 001F CATCH R4 1 0 0xB0080000, // 0020 RAISE 2 R0 R0 0x80000000, // 0021 RET 0 diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_tasmota_class.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_tasmota_class.h index 8762cef14350..1488c004f7de 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_tasmota_class.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_tasmota_class.h @@ -7,85 +7,43 @@ extern const bclass be_class_Tasmota; /******************************************************************** -** Solidified function: exec_rules +** Solidified function: try_rule ********************************************************************/ -be_local_closure(Tasmota_exec_rules, /* name */ +be_local_closure(Tasmota_try_rule, /* name */ be_nested_proto( - 14, /* nstack */ - 3, /* argc */ + 9, /* nstack */ + 4, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[12]) { /* constants */ - /* K0 */ be_nested_str(cmd_res), - /* K1 */ be_nested_str(_rules), - /* K2 */ be_nested_str(json), - /* K3 */ be_nested_str(load), - /* K4 */ be_nested_str(log), - /* K5 */ be_nested_str(BRY_X3A_X20ERROR_X2C_X20bad_X20json_X3A_X20), - /* K6 */ be_const_int(3), - /* K7 */ be_const_int(0), - /* K8 */ be_nested_str(try_rule), - /* K9 */ be_nested_str(trig), - /* K10 */ be_nested_str(f), - /* K11 */ be_const_int(1), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str(match), + /* K1 */ be_nested_str(trigger), }), - &be_const_str_exec_rules, + &be_const_str_try_rule, &be_const_str_solidified, - ( &(const binstruction[50]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x88100101, // 0001 GETMBR R4 R0 K1 - 0x74120002, // 0002 JMPT R4 #0006 - 0x4C100000, // 0003 LDNIL R4 - 0x20100604, // 0004 NE R4 R3 R4 - 0x78120029, // 0005 JMPF R4 #0030 - 0xA4120400, // 0006 IMPORT R4 K2 - 0x4C140000, // 0007 LDNIL R5 - 0x90020005, // 0008 SETMBR R0 K0 R5 - 0x50140000, // 0009 LDBOOL R5 0 0 - 0x8C180903, // 000A GETMET R6 R4 K3 - 0x5C200200, // 000B MOVE R8 R1 - 0x7C180400, // 000C CALL R6 2 - 0x4C1C0000, // 000D LDNIL R7 - 0x1C1C0C07, // 000E EQ R7 R6 R7 - 0x781E0004, // 000F JMPF R7 #0015 - 0x8C1C0104, // 0010 GETMET R7 R0 K4 - 0x00260A01, // 0011 ADD R9 K5 R1 - 0x58280006, // 0012 LDCONST R10 K6 - 0x7C1C0600, // 0013 CALL R7 3 - 0x5C180200, // 0014 MOVE R6 R1 - 0x780A0014, // 0015 JMPF R2 #002B - 0x881C0101, // 0016 GETMBR R7 R0 K1 - 0x781E0012, // 0017 JMPF R7 #002B - 0x581C0007, // 0018 LDCONST R7 K7 - 0x6020000C, // 0019 GETGBL R8 G12 - 0x88240101, // 001A GETMBR R9 R0 K1 - 0x7C200200, // 001B CALL R8 1 - 0x14200E08, // 001C LT R8 R7 R8 - 0x7822000C, // 001D JMPF R8 #002B - 0x88200101, // 001E GETMBR R8 R0 K1 - 0x94201007, // 001F GETIDX R8 R8 R7 - 0x8C240108, // 0020 GETMET R9 R0 K8 - 0x5C2C0C00, // 0021 MOVE R11 R6 - 0x88301109, // 0022 GETMBR R12 R8 K9 - 0x8834110A, // 0023 GETMBR R13 R8 K10 - 0x7C240800, // 0024 CALL R9 4 - 0x74260001, // 0025 JMPT R9 #0028 - 0x74160000, // 0026 JMPT R5 #0028 - 0x50140001, // 0027 LDBOOL R5 0 1 - 0x50140200, // 0028 LDBOOL R5 1 0 - 0x001C0F0B, // 0029 ADD R7 R7 K11 - 0x7001FFED, // 002A JMP #0019 - 0x4C1C0000, // 002B LDNIL R7 - 0x201C0607, // 002C NE R7 R3 R7 - 0x781E0000, // 002D JMPF R7 #002F - 0x90020006, // 002E SETMBR R0 K0 R6 - 0x80040A00, // 002F RET 1 R5 - 0x50100000, // 0030 LDBOOL R4 0 0 - 0x80040800, // 0031 RET 1 R4 + ( &(const binstruction[18]) { /* code */ + 0x8C100500, // 0000 GETMET R4 R2 K0 + 0x5C180200, // 0001 MOVE R6 R1 + 0x7C100400, // 0002 CALL R4 2 + 0x4C140000, // 0003 LDNIL R5 + 0x20140805, // 0004 NE R5 R4 R5 + 0x78160009, // 0005 JMPF R5 #0010 + 0x4C140000, // 0006 LDNIL R5 + 0x20140605, // 0007 NE R5 R3 R5 + 0x78160004, // 0008 JMPF R5 #000E + 0x5C140600, // 0009 MOVE R5 R3 + 0x5C180800, // 000A MOVE R6 R4 + 0x881C0501, // 000B GETMBR R7 R2 K1 + 0x5C200200, // 000C MOVE R8 R1 + 0x7C140600, // 000D CALL R5 3 + 0x50140200, // 000E LDBOOL R5 1 0 + 0x80040A00, // 000F RET 1 R5 + 0x50140000, // 0010 LDBOOL R5 0 0 + 0x80040A00, // 0011 RET 1 R5 }) ) ); @@ -93,82 +51,30 @@ be_local_closure(Tasmota_exec_rules, /* name */ /******************************************************************** -** Solidified function: cmd +** Solidified function: gen_cb ********************************************************************/ -be_local_closure(Tasmota_cmd, /* name */ +be_local_closure(Tasmota_gen_cb, /* name */ be_nested_proto( - 10, /* nstack */ - 3, /* argc */ + 6, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str(cmd_res), - /* K1 */ be_nested_str(tasmota), - /* K2 */ be_nested_str(global), - /* K3 */ be_nested_str(seriallog_level), - /* K4 */ be_nested_str(settings), - /* K5 */ be_nested_str(mqttlog_level), - /* K6 */ be_nested_str(weblog_level), - /* K7 */ be_const_int(2), - /* K8 */ be_const_int(1), - /* K9 */ be_nested_str(_cmd), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str(cb), + /* K1 */ be_nested_str(gen_cb), }), - &be_const_str_cmd, + &be_const_str_gen_cb, &be_const_str_solidified, - ( &(const binstruction[49]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x50100200, // 0001 LDBOOL R4 1 0 - 0x90020004, // 0002 SETMBR R0 K0 R4 - 0xB8120200, // 0003 GETNGBL R4 K1 - 0x88100902, // 0004 GETMBR R4 R4 K2 - 0x88100903, // 0005 GETMBR R4 R4 K3 - 0xB8160200, // 0006 GETNGBL R5 K1 - 0x88140B04, // 0007 GETMBR R5 R5 K4 - 0x88140B05, // 0008 GETMBR R5 R5 K5 - 0xB81A0200, // 0009 GETNGBL R6 K1 - 0x88180D04, // 000A GETMBR R6 R6 K4 - 0x88180D06, // 000B GETMBR R6 R6 K6 - 0x780A000E, // 000C JMPF R2 #001C - 0x281C0907, // 000D GE R7 R4 K7 - 0x781E0002, // 000E JMPF R7 #0012 - 0xB81E0200, // 000F GETNGBL R7 K1 - 0x881C0F02, // 0010 GETMBR R7 R7 K2 - 0x901E0708, // 0011 SETMBR R7 K3 K8 - 0x281C0B07, // 0012 GE R7 R5 K7 - 0x781E0002, // 0013 JMPF R7 #0017 - 0xB81E0200, // 0014 GETNGBL R7 K1 - 0x881C0F04, // 0015 GETMBR R7 R7 K4 - 0x901E0B08, // 0016 SETMBR R7 K5 K8 - 0x281C0D07, // 0017 GE R7 R6 K7 - 0x781E0002, // 0018 JMPF R7 #001C - 0xB81E0200, // 0019 GETNGBL R7 K1 - 0x881C0F04, // 001A GETMBR R7 R7 K4 - 0x901E0D08, // 001B SETMBR R7 K6 K8 - 0x8C1C0109, // 001C GETMET R7 R0 K9 - 0x5C240200, // 001D MOVE R9 R1 - 0x7C1C0400, // 001E CALL R7 2 - 0x4C1C0000, // 001F LDNIL R7 - 0x88200100, // 0020 GETMBR R8 R0 K0 - 0x50240200, // 0021 LDBOOL R9 1 0 - 0x20201009, // 0022 NE R8 R8 R9 - 0x78220000, // 0023 JMPF R8 #0025 - 0x881C0100, // 0024 GETMBR R7 R0 K0 - 0x90020003, // 0025 SETMBR R0 K0 R3 - 0x780A0008, // 0026 JMPF R2 #0030 - 0xB8220200, // 0027 GETNGBL R8 K1 - 0x88201102, // 0028 GETMBR R8 R8 K2 - 0x90220604, // 0029 SETMBR R8 K3 R4 - 0xB8220200, // 002A GETNGBL R8 K1 - 0x88201104, // 002B GETMBR R8 R8 K4 - 0x90220A05, // 002C SETMBR R8 K5 R5 - 0xB8220200, // 002D GETNGBL R8 K1 - 0x88201104, // 002E GETMBR R8 R8 K4 - 0x90220C06, // 002F SETMBR R8 K6 R6 - 0x80040E00, // 0030 RET 1 R7 + ( &(const binstruction[ 5]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0x8C0C0501, // 0001 GETMET R3 R2 K1 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x80040600, // 0004 RET 1 R3 }) ) ); @@ -176,43 +82,40 @@ be_local_closure(Tasmota_cmd, /* name */ /******************************************************************** -** Solidified function: check_not_method +** Solidified function: fast_loop ********************************************************************/ -be_local_closure(Tasmota_check_not_method, /* name */ +be_local_closure(Tasmota_fast_loop, /* name */ be_nested_proto( - 6, /* nstack */ - 2, /* argc */ + 5, /* nstack */ + 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str(introspect), - /* K1 */ be_nested_str(function), - /* K2 */ be_nested_str(type_error), - /* K3 */ be_nested_str(BRY_X3A_X20argument_X20must_X20be_X20a_X20function), - /* K4 */ be_nested_str(ismethod), - /* K5 */ be_nested_str(BRY_X3A_X20method_X20not_X20allowed_X2C_X20use_X20a_X20closure_X20like_X20_X27_X2F_X20args_X20_X2D_X3E_X20obj_X2Efunc_X28args_X29_X27), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str(_fl), + /* K1 */ be_const_int(0), + /* K2 */ be_const_int(1), }), - &be_const_str_check_not_method, + &be_const_str_fast_loop, &be_const_str_solidified, ( &(const binstruction[15]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x600C0004, // 0001 GETGBL R3 G4 - 0x5C100200, // 0002 MOVE R4 R1 - 0x7C0C0200, // 0003 CALL R3 1 - 0x200C0701, // 0004 NE R3 R3 K1 - 0x780E0000, // 0005 JMPF R3 #0007 - 0xB0060503, // 0006 RAISE 1 K2 K3 - 0x8C0C0504, // 0007 GETMET R3 R2 K4 - 0x5C140200, // 0008 MOVE R5 R1 - 0x7C0C0400, // 0009 CALL R3 2 - 0x50100200, // 000A LDBOOL R4 1 0 - 0x1C0C0604, // 000B EQ R3 R3 R4 - 0x780E0000, // 000C JMPF R3 #000E - 0xB0060505, // 000D RAISE 1 K2 K5 + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x5C080200, // 0001 MOVE R2 R1 + 0x740A0000, // 0002 JMPT R2 #0004 + 0x80000400, // 0003 RET 0 + 0x58080001, // 0004 LDCONST R2 K1 + 0x600C000C, // 0005 GETGBL R3 G12 + 0x5C100200, // 0006 MOVE R4 R1 + 0x7C0C0200, // 0007 CALL R3 1 + 0x14100403, // 0008 LT R4 R2 R3 + 0x78120003, // 0009 JMPF R4 #000E + 0x94100202, // 000A GETIDX R4 R1 R2 + 0x7C100000, // 000B CALL R4 0 + 0x00080502, // 000C ADD R2 R2 K2 + 0x7001FFF9, // 000D JMP #0008 0x80000000, // 000E RET 0 }) ) @@ -221,57 +124,41 @@ be_local_closure(Tasmota_check_not_method, /* name */ /******************************************************************** -** Solidified function: remove_rule +** Solidified function: remove_fast_loop ********************************************************************/ -be_local_closure(Tasmota_remove_rule, /* name */ +be_local_closure(Tasmota_remove_fast_loop, /* name */ be_nested_proto( - 7, /* nstack */ - 3, /* argc */ + 6, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str(_rules), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str(trig), - /* K3 */ be_nested_str(rule), - /* K4 */ be_nested_str(id), - /* K5 */ be_nested_str(remove), - /* K6 */ be_const_int(1), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str(_fl), + /* K1 */ be_nested_str(find), + /* K2 */ be_nested_str(remove), }), - &be_const_str_remove_rule, + &be_const_str_remove_fast_loop, &be_const_str_solidified, - ( &(const binstruction[27]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x780E0017, // 0001 JMPF R3 #001A - 0x580C0001, // 0002 LDCONST R3 K1 - 0x6010000C, // 0003 GETGBL R4 G12 - 0x88140100, // 0004 GETMBR R5 R0 K0 - 0x7C100200, // 0005 CALL R4 1 - 0x14100604, // 0006 LT R4 R3 R4 - 0x78120011, // 0007 JMPF R4 #001A - 0x88100100, // 0008 GETMBR R4 R0 K0 - 0x94100803, // 0009 GETIDX R4 R4 R3 - 0x88100902, // 000A GETMBR R4 R4 K2 - 0x88100903, // 000B GETMBR R4 R4 K3 - 0x1C100801, // 000C EQ R4 R4 R1 - 0x78120009, // 000D JMPF R4 #0018 - 0x88100100, // 000E GETMBR R4 R0 K0 - 0x94100803, // 000F GETIDX R4 R4 R3 - 0x88100904, // 0010 GETMBR R4 R4 K4 - 0x1C100802, // 0011 EQ R4 R4 R2 - 0x78120004, // 0012 JMPF R4 #0018 - 0x88100100, // 0013 GETMBR R4 R0 K0 - 0x8C100905, // 0014 GETMET R4 R4 K5 - 0x5C180600, // 0015 MOVE R6 R3 - 0x7C100400, // 0016 CALL R4 2 - 0x70020000, // 0017 JMP #0019 - 0x000C0706, // 0018 ADD R3 R3 K6 - 0x7001FFE8, // 0019 JMP #0003 - 0x80000000, // 001A RET 0 + ( &(const binstruction[15]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x740A0000, // 0001 JMPT R2 #0003 + 0x80000400, // 0002 RET 0 + 0x88080100, // 0003 GETMBR R2 R0 K0 + 0x8C080501, // 0004 GETMET R2 R2 K1 + 0x5C100200, // 0005 MOVE R4 R1 + 0x7C080400, // 0006 CALL R2 2 + 0x4C0C0000, // 0007 LDNIL R3 + 0x200C0403, // 0008 NE R3 R2 R3 + 0x780E0003, // 0009 JMPF R3 #000E + 0x880C0100, // 000A GETMBR R3 R0 K0 + 0x8C0C0702, // 000B GETMET R3 R3 K2 + 0x5C140400, // 000C MOVE R5 R2 + 0x7C0C0400, // 000D CALL R3 2 + 0x80000000, // 000E RET 0 }) ) ); @@ -279,53 +166,12 @@ be_local_closure(Tasmota_remove_rule, /* name */ /******************************************************************** -** Solidified function: remove_driver +** Solidified function: find_key_i ********************************************************************/ -be_local_closure(Tasmota_remove_driver, /* name */ +be_local_closure(Tasmota_find_key_i, /* name */ be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str(_drivers), - /* K1 */ be_nested_str(find), - /* K2 */ be_nested_str(pop), - }), - &be_const_str_remove_driver, - &be_const_str_solidified, - ( &(const binstruction[14]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x780A000A, // 0001 JMPF R2 #000D - 0x88080100, // 0002 GETMBR R2 R0 K0 - 0x8C080501, // 0003 GETMET R2 R2 K1 - 0x5C100200, // 0004 MOVE R4 R1 - 0x7C080400, // 0005 CALL R2 2 - 0x4C0C0000, // 0006 LDNIL R3 - 0x200C0403, // 0007 NE R3 R2 R3 - 0x780E0003, // 0008 JMPF R3 #000D - 0x880C0100, // 0009 GETMBR R3 R0 K0 - 0x8C0C0702, // 000A GETMET R3 R3 K2 - 0x5C140400, // 000B MOVE R5 R2 - 0x7C0C0400, // 000C CALL R3 2 - 0x80000000, // 000D RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: find_key_i -********************************************************************/ -be_local_closure(Tasmota_find_key_i, /* name */ - be_nested_proto( - 10, /* nstack */ - 3, /* argc */ + 10, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -379,11 +225,11 @@ be_local_closure(Tasmota_find_key_i, /* name */ /******************************************************************** -** Solidified function: remove_timer +** Solidified function: check_not_method ********************************************************************/ -be_local_closure(Tasmota_remove_timer, /* name */ +be_local_closure(Tasmota_check_not_method, /* name */ be_nested_proto( - 7, /* nstack */ + 6, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -392,34 +238,31 @@ be_local_closure(Tasmota_remove_timer, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str(_timers), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str(size), - /* K3 */ be_nested_str(id), - /* K4 */ be_nested_str(remove), - /* K5 */ be_const_int(1), + /* K0 */ be_nested_str(introspect), + /* K1 */ be_nested_str(function), + /* K2 */ be_nested_str(type_error), + /* K3 */ be_nested_str(BRY_X3A_X20argument_X20must_X20be_X20a_X20function), + /* K4 */ be_nested_str(ismethod), + /* K5 */ be_nested_str(BRY_X3A_X20method_X20not_X20allowed_X2C_X20use_X20a_X20closure_X20like_X20_X27_X2F_X20args_X20_X2D_X3E_X20obj_X2Efunc_X28args_X29_X27), }), - &be_const_str_remove_timer, + &be_const_str_check_not_method, &be_const_str_solidified, - ( &(const binstruction[18]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x780A000E, // 0001 JMPF R2 #0011 - 0x580C0001, // 0002 LDCONST R3 K1 - 0x8C100502, // 0003 GETMET R4 R2 K2 - 0x7C100200, // 0004 CALL R4 1 - 0x14100604, // 0005 LT R4 R3 R4 - 0x78120009, // 0006 JMPF R4 #0011 - 0x94100403, // 0007 GETIDX R4 R2 R3 - 0x88100903, // 0008 GETMBR R4 R4 K3 - 0x1C100801, // 0009 EQ R4 R4 R1 - 0x78120003, // 000A JMPF R4 #000F - 0x8C100504, // 000B GETMET R4 R2 K4 - 0x5C180600, // 000C MOVE R6 R3 - 0x7C100400, // 000D CALL R4 2 - 0x70020000, // 000E JMP #0010 - 0x000C0705, // 000F ADD R3 R3 K5 - 0x7001FFF1, // 0010 JMP #0003 - 0x80000000, // 0011 RET 0 + ( &(const binstruction[15]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0x600C0004, // 0001 GETGBL R3 G4 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C0C0200, // 0003 CALL R3 1 + 0x200C0701, // 0004 NE R3 R3 K1 + 0x780E0000, // 0005 JMPF R3 #0007 + 0xB0060503, // 0006 RAISE 1 K2 K3 + 0x8C0C0504, // 0007 GETMET R3 R2 K4 + 0x5C140200, // 0008 MOVE R5 R1 + 0x7C0C0400, // 0009 CALL R3 2 + 0x50100200, // 000A LDBOOL R4 1 0 + 0x1C0C0604, // 000B EQ R3 R3 R4 + 0x780E0000, // 000C JMPF R3 #000E + 0xB0060505, // 000D RAISE 1 K2 K5 + 0x80000000, // 000E RET 0 }) ) ); @@ -495,56 +338,156 @@ be_local_closure(Tasmota_run_cron, /* name */ /******************************************************************** -** Solidified function: run_deferred +** Solidified function: event ********************************************************************/ -be_local_closure(Tasmota_run_deferred, /* name */ +be_local_closure(Tasmota_event, /* name */ be_nested_proto( - 7, /* nstack */ - 1, /* argc */ + 19, /* nstack */ + 6, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str(_timers), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str(size), - /* K3 */ be_nested_str(time_reached), - /* K4 */ be_nested_str(trig), - /* K5 */ be_nested_str(f), - /* K6 */ be_nested_str(remove), - /* K7 */ be_const_int(1), + ( &(const bvalue[25]) { /* constants */ + /* K0 */ be_nested_str(introspect), + /* K1 */ be_nested_str(every_50ms), + /* K2 */ be_nested_str(run_deferred), + /* K3 */ be_nested_str(every_250ms), + /* K4 */ be_nested_str(run_cron), + /* K5 */ be_nested_str(mqtt_data), + /* K6 */ be_nested_str(cmd), + /* K7 */ be_nested_str(exec_cmd), + /* K8 */ be_nested_str(tele), + /* K9 */ be_nested_str(exec_tele), + /* K10 */ be_nested_str(rule), + /* K11 */ be_nested_str(exec_rules), + /* K12 */ be_nested_str(gc), + /* K13 */ be_nested_str(_drivers), + /* K14 */ be_const_int(0), + /* K15 */ be_nested_str(get), + /* K16 */ be_nested_str(function), + /* K17 */ be_nested_str(BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K18 */ be_nested_str(_debug_present), + /* K19 */ be_nested_str(debug), + /* K20 */ be_nested_str(traceback), + /* K21 */ be_const_int(1), + /* K22 */ be_nested_str(save_before_restart), + /* K23 */ be_nested_str(persist), + /* K24 */ be_nested_str(save), }), - &be_const_str_run_deferred, + &be_const_str_event, &be_const_str_solidified, - ( &(const binstruction[25]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x78060015, // 0001 JMPF R1 #0018 - 0x58040001, // 0002 LDCONST R1 K1 - 0x88080100, // 0003 GETMBR R2 R0 K0 - 0x8C080502, // 0004 GETMET R2 R2 K2 - 0x7C080200, // 0005 CALL R2 1 - 0x14080202, // 0006 LT R2 R1 R2 - 0x780A000F, // 0007 JMPF R2 #0018 - 0x88080100, // 0008 GETMBR R2 R0 K0 - 0x94080401, // 0009 GETIDX R2 R2 R1 - 0x8C0C0103, // 000A GETMET R3 R0 K3 - 0x88140504, // 000B GETMBR R5 R2 K4 - 0x7C0C0400, // 000C CALL R3 2 - 0x780E0007, // 000D JMPF R3 #0016 - 0x880C0505, // 000E GETMBR R3 R2 K5 - 0x88100100, // 000F GETMBR R4 R0 K0 - 0x8C100906, // 0010 GETMET R4 R4 K6 - 0x5C180200, // 0011 MOVE R6 R1 - 0x7C100400, // 0012 CALL R4 2 - 0x5C100600, // 0013 MOVE R4 R3 - 0x7C100000, // 0014 CALL R4 0 - 0x70020000, // 0015 JMP #0017 - 0x00040307, // 0016 ADD R1 R1 K7 - 0x7001FFEA, // 0017 JMP #0003 - 0x80000000, // 0018 RET 0 + ( &(const binstruction[108]) { /* code */ + 0xA41A0000, // 0000 IMPORT R6 K0 + 0x1C1C0301, // 0001 EQ R7 R1 K1 + 0x781E0001, // 0002 JMPF R7 #0005 + 0x8C1C0102, // 0003 GETMET R7 R0 K2 + 0x7C1C0200, // 0004 CALL R7 1 + 0x1C1C0303, // 0005 EQ R7 R1 K3 + 0x781E0001, // 0006 JMPF R7 #0009 + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x7C1C0200, // 0008 CALL R7 1 + 0x501C0000, // 0009 LDBOOL R7 0 0 + 0x50200000, // 000A LDBOOL R8 0 0 + 0x1C240305, // 000B EQ R9 R1 K5 + 0x78260000, // 000C JMPF R9 #000E + 0x50200200, // 000D LDBOOL R8 1 0 + 0x1C240306, // 000E EQ R9 R1 K6 + 0x78260006, // 000F JMPF R9 #0017 + 0x8C240107, // 0010 GETMET R9 R0 K7 + 0x5C2C0400, // 0011 MOVE R11 R2 + 0x5C300600, // 0012 MOVE R12 R3 + 0x5C340800, // 0013 MOVE R13 R4 + 0x7C240800, // 0014 CALL R9 4 + 0x80041200, // 0015 RET 1 R9 + 0x7002004E, // 0016 JMP #0066 + 0x1C240308, // 0017 EQ R9 R1 K8 + 0x78260004, // 0018 JMPF R9 #001E + 0x8C240109, // 0019 GETMET R9 R0 K9 + 0x5C2C0800, // 001A MOVE R11 R4 + 0x7C240400, // 001B CALL R9 2 + 0x80041200, // 001C RET 1 R9 + 0x70020047, // 001D JMP #0066 + 0x1C24030A, // 001E EQ R9 R1 K10 + 0x78260007, // 001F JMPF R9 #0028 + 0x8C24010B, // 0020 GETMET R9 R0 K11 + 0x5C2C0800, // 0021 MOVE R11 R4 + 0x60300017, // 0022 GETGBL R12 G23 + 0x5C340600, // 0023 MOVE R13 R3 + 0x7C300200, // 0024 CALL R12 1 + 0x7C240600, // 0025 CALL R9 3 + 0x80041200, // 0026 RET 1 R9 + 0x7002003D, // 0027 JMP #0066 + 0x1C24030C, // 0028 EQ R9 R1 K12 + 0x78260003, // 0029 JMPF R9 #002E + 0x8C24010C, // 002A GETMET R9 R0 K12 + 0x7C240200, // 002B CALL R9 1 + 0x80041200, // 002C RET 1 R9 + 0x70020037, // 002D JMP #0066 + 0x8824010D, // 002E GETMBR R9 R0 K13 + 0x78260035, // 002F JMPF R9 #0066 + 0x5824000E, // 0030 LDCONST R9 K14 + 0x6028000C, // 0031 GETGBL R10 G12 + 0x882C010D, // 0032 GETMBR R11 R0 K13 + 0x7C280200, // 0033 CALL R10 1 + 0x1428120A, // 0034 LT R10 R9 R10 + 0x782A002F, // 0035 JMPF R10 #0066 + 0x8828010D, // 0036 GETMBR R10 R0 K13 + 0x94281409, // 0037 GETIDX R10 R10 R9 + 0x8C2C0D0F, // 0038 GETMET R11 R6 K15 + 0x5C341400, // 0039 MOVE R13 R10 + 0x5C380200, // 003A MOVE R14 R1 + 0x7C2C0600, // 003B CALL R11 3 + 0x60300004, // 003C GETGBL R12 G4 + 0x5C341600, // 003D MOVE R13 R11 + 0x7C300200, // 003E CALL R12 1 + 0x1C301910, // 003F EQ R12 R12 K16 + 0x78320022, // 0040 JMPF R12 #0064 + 0xA8020011, // 0041 EXBLK 0 #0054 + 0x5C301600, // 0042 MOVE R12 R11 + 0x5C341400, // 0043 MOVE R13 R10 + 0x5C380400, // 0044 MOVE R14 R2 + 0x5C3C0600, // 0045 MOVE R15 R3 + 0x5C400800, // 0046 MOVE R16 R4 + 0x5C440A00, // 0047 MOVE R17 R5 + 0x7C300A00, // 0048 CALL R12 5 + 0x74320001, // 0049 JMPT R12 #004C + 0x741E0000, // 004A JMPT R7 #004C + 0x501C0001, // 004B LDBOOL R7 0 1 + 0x501C0200, // 004C LDBOOL R7 1 0 + 0x781E0003, // 004D JMPF R7 #0052 + 0x5C301000, // 004E MOVE R12 R8 + 0x74320001, // 004F JMPT R12 #0052 + 0xA8040001, // 0050 EXBLK 1 1 + 0x70020013, // 0051 JMP #0066 + 0xA8040001, // 0052 EXBLK 1 1 + 0x7002000F, // 0053 JMP #0064 + 0xAC300002, // 0054 CATCH R12 0 2 + 0x7002000C, // 0055 JMP #0063 + 0x60380001, // 0056 GETGBL R14 G1 + 0x603C0018, // 0057 GETGBL R15 G24 + 0x58400011, // 0058 LDCONST R16 K17 + 0x5C441800, // 0059 MOVE R17 R12 + 0x5C481A00, // 005A MOVE R18 R13 + 0x7C3C0600, // 005B CALL R15 3 + 0x7C380200, // 005C CALL R14 1 + 0x88380112, // 005D GETMBR R14 R0 K18 + 0x783A0002, // 005E JMPF R14 #0062 + 0xA43A2600, // 005F IMPORT R14 K19 + 0x8C3C1D14, // 0060 GETMET R15 R14 K20 + 0x7C3C0200, // 0061 CALL R15 1 + 0x70020000, // 0062 JMP #0064 + 0xB0080000, // 0063 RAISE 2 R0 R0 + 0x00241315, // 0064 ADD R9 R9 K21 + 0x7001FFCA, // 0065 JMP #0031 + 0x1C240316, // 0066 EQ R9 R1 K22 + 0x78260002, // 0067 JMPF R9 #006B + 0xA4262E00, // 0068 IMPORT R9 K23 + 0x8C281318, // 0069 GETMET R10 R9 K24 + 0x7C280200, // 006A CALL R10 1 + 0x80040E00, // 006B RET 1 R7 }) ) ); @@ -552,11 +495,11 @@ be_local_closure(Tasmota_run_deferred, /* name */ /******************************************************************** -** Solidified function: wire_scan +** Solidified function: urlfetch ********************************************************************/ -be_local_closure(Tasmota_wire_scan, /* name */ +be_local_closure(Tasmota_urlfetch, /* name */ be_nested_proto( - 6, /* nstack */ + 10, /* nstack */ 3, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -564,49 +507,76 @@ be_local_closure(Tasmota_wire_scan, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str(i2c_enabled), - /* K1 */ be_nested_str(wire1), - /* K2 */ be_nested_str(enabled), - /* K3 */ be_nested_str(detect), - /* K4 */ be_nested_str(wire2), + ( &(const bvalue[17]) { /* constants */ + /* K0 */ be_nested_str(string), + /* K1 */ be_nested_str(split), + /* K2 */ be_nested_str(_X2F), + /* K3 */ be_nested_str(pop), + /* K4 */ be_const_int(0), + /* K5 */ be_nested_str(index_X2Ehtml), + /* K6 */ be_nested_str(webclient), + /* K7 */ be_nested_str(set_follow_redirects), + /* K8 */ be_nested_str(begin), + /* K9 */ be_nested_str(GET), + /* K10 */ be_nested_str(status_X3A_X20), + /* K11 */ be_nested_str(connection_error), + /* K12 */ be_nested_str(write_file), + /* K13 */ be_nested_str(close), + /* K14 */ be_nested_str(log), + /* K15 */ be_nested_str(BRY_X3A_X20Fetched_X20), + /* K16 */ be_const_int(3), }), - &be_const_str_wire_scan, + &be_const_str_urlfetch, &be_const_str_solidified, - ( &(const binstruction[33]) { /* code */ + ( &(const binstruction[48]) { /* code */ 0x4C0C0000, // 0000 LDNIL R3 - 0x200C0403, // 0001 NE R3 R2 R3 - 0x780E0005, // 0002 JMPF R3 #0009 - 0x8C0C0100, // 0003 GETMET R3 R0 K0 - 0x5C140400, // 0004 MOVE R5 R2 - 0x7C0C0400, // 0005 CALL R3 2 - 0x740E0001, // 0006 JMPT R3 #0009 - 0x4C0C0000, // 0007 LDNIL R3 - 0x80040600, // 0008 RET 1 R3 - 0x880C0101, // 0009 GETMBR R3 R0 K1 - 0x8C0C0702, // 000A GETMET R3 R3 K2 - 0x7C0C0200, // 000B CALL R3 1 - 0x780E0006, // 000C JMPF R3 #0014 - 0x880C0101, // 000D GETMBR R3 R0 K1 - 0x8C0C0703, // 000E GETMET R3 R3 K3 - 0x5C140200, // 000F MOVE R5 R1 - 0x7C0C0400, // 0010 CALL R3 2 - 0x780E0001, // 0011 JMPF R3 #0014 - 0x880C0101, // 0012 GETMBR R3 R0 K1 - 0x80040600, // 0013 RET 1 R3 - 0x880C0104, // 0014 GETMBR R3 R0 K4 - 0x8C0C0702, // 0015 GETMET R3 R3 K2 - 0x7C0C0200, // 0016 CALL R3 1 - 0x780E0006, // 0017 JMPF R3 #001F - 0x880C0104, // 0018 GETMBR R3 R0 K4 - 0x8C0C0703, // 0019 GETMET R3 R3 K3 - 0x5C140200, // 001A MOVE R5 R1 - 0x7C0C0400, // 001B CALL R3 2 - 0x780E0001, // 001C JMPF R3 #001F - 0x880C0104, // 001D GETMBR R3 R0 K4 - 0x80040600, // 001E RET 1 R3 - 0x4C0C0000, // 001F LDNIL R3 - 0x80040600, // 0020 RET 1 R3 + 0x1C0C0403, // 0001 EQ R3 R2 R3 + 0x780E000D, // 0002 JMPF R3 #0011 + 0xA40E0000, // 0003 IMPORT R3 K0 + 0x8C100701, // 0004 GETMET R4 R3 K1 + 0x5C180200, // 0005 MOVE R6 R1 + 0x581C0002, // 0006 LDCONST R7 K2 + 0x7C100600, // 0007 CALL R4 3 + 0x8C100903, // 0008 GETMET R4 R4 K3 + 0x7C100200, // 0009 CALL R4 1 + 0x5C080800, // 000A MOVE R2 R4 + 0x6010000C, // 000B GETGBL R4 G12 + 0x5C140400, // 000C MOVE R5 R2 + 0x7C100200, // 000D CALL R4 1 + 0x1C100904, // 000E EQ R4 R4 K4 + 0x78120000, // 000F JMPF R4 #0011 + 0x58080005, // 0010 LDCONST R2 K5 + 0xB80E0C00, // 0011 GETNGBL R3 K6 + 0x7C0C0000, // 0012 CALL R3 0 + 0x8C100707, // 0013 GETMET R4 R3 K7 + 0x50180200, // 0014 LDBOOL R6 1 0 + 0x7C100400, // 0015 CALL R4 2 + 0x8C100708, // 0016 GETMET R4 R3 K8 + 0x5C180200, // 0017 MOVE R6 R1 + 0x7C100400, // 0018 CALL R4 2 + 0x8C100709, // 0019 GETMET R4 R3 K9 + 0x7C100200, // 001A CALL R4 1 + 0x541600C7, // 001B LDINT R5 200 + 0x20140805, // 001C NE R5 R4 R5 + 0x78160004, // 001D JMPF R5 #0023 + 0x60140008, // 001E GETGBL R5 G8 + 0x5C180800, // 001F MOVE R6 R4 + 0x7C140200, // 0020 CALL R5 1 + 0x00161405, // 0021 ADD R5 K10 R5 + 0xB0061605, // 0022 RAISE 1 K11 R5 + 0x8C14070C, // 0023 GETMET R5 R3 K12 + 0x5C1C0400, // 0024 MOVE R7 R2 + 0x7C140400, // 0025 CALL R5 2 + 0x8C18070D, // 0026 GETMET R6 R3 K13 + 0x7C180200, // 0027 CALL R6 1 + 0x8C18010E, // 0028 GETMET R6 R0 K14 + 0x60200008, // 0029 GETGBL R8 G8 + 0x5C240A00, // 002A MOVE R9 R5 + 0x7C200200, // 002B CALL R8 1 + 0x00221E08, // 002C ADD R8 K15 R8 + 0x58240010, // 002D LDCONST R9 K16 + 0x7C180600, // 002E CALL R6 3 + 0x80040800, // 002F RET 1 R4 }) ) ); @@ -614,12 +584,68 @@ be_local_closure(Tasmota_wire_scan, /* name */ /******************************************************************** -** Solidified function: next_cron +** Solidified function: exec_cmd ********************************************************************/ -be_local_closure(Tasmota_next_cron, /* name */ +be_local_closure(Tasmota_exec_cmd, /* name */ be_nested_proto( - 6, /* nstack */ - 2, /* argc */ + 12, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str(_ccmd), + /* K1 */ be_nested_str(json), + /* K2 */ be_nested_str(load), + /* K3 */ be_nested_str(find_key_i), + /* K4 */ be_nested_str(resolvecmnd), + }), + &be_const_str_exec_cmd, + &be_const_str_solidified, + ( &(const binstruction[27]) { /* code */ + 0x88100100, // 0000 GETMBR R4 R0 K0 + 0x78120016, // 0001 JMPF R4 #0019 + 0xA4120200, // 0002 IMPORT R4 K1 + 0x8C140902, // 0003 GETMET R5 R4 K2 + 0x5C1C0600, // 0004 MOVE R7 R3 + 0x7C140400, // 0005 CALL R5 2 + 0x8C180103, // 0006 GETMET R6 R0 K3 + 0x88200100, // 0007 GETMBR R8 R0 K0 + 0x5C240200, // 0008 MOVE R9 R1 + 0x7C180600, // 0009 CALL R6 3 + 0x4C1C0000, // 000A LDNIL R7 + 0x201C0C07, // 000B NE R7 R6 R7 + 0x781E000B, // 000C JMPF R7 #0019 + 0x8C1C0104, // 000D GETMET R7 R0 K4 + 0x5C240C00, // 000E MOVE R9 R6 + 0x7C1C0400, // 000F CALL R7 2 + 0x881C0100, // 0010 GETMBR R7 R0 K0 + 0x941C0E06, // 0011 GETIDX R7 R7 R6 + 0x5C200C00, // 0012 MOVE R8 R6 + 0x5C240400, // 0013 MOVE R9 R2 + 0x5C280600, // 0014 MOVE R10 R3 + 0x5C2C0A00, // 0015 MOVE R11 R5 + 0x7C1C0800, // 0016 CALL R7 4 + 0x501C0200, // 0017 LDBOOL R7 1 0 + 0x80040E00, // 0018 RET 1 R7 + 0x50100000, // 0019 LDBOOL R4 0 0 + 0x80040800, // 001A RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: remove_cron +********************************************************************/ +be_local_closure(Tasmota_remove_cron, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -631,29 +657,78 @@ be_local_closure(Tasmota_next_cron, /* name */ /* K1 */ be_const_int(0), /* K2 */ be_nested_str(size), /* K3 */ be_nested_str(id), - /* K4 */ be_nested_str(trig), + /* K4 */ be_nested_str(remove), /* K5 */ be_const_int(1), }), - &be_const_str_next_cron, + &be_const_str_remove_cron, &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ + ( &(const binstruction[18]) { /* code */ 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x780A000D, // 0001 JMPF R2 #0010 + 0x780A000E, // 0001 JMPF R2 #0011 0x580C0001, // 0002 LDCONST R3 K1 0x8C100502, // 0003 GETMET R4 R2 K2 0x7C100200, // 0004 CALL R4 1 0x14100604, // 0005 LT R4 R3 R4 - 0x78120008, // 0006 JMPF R4 #0010 + 0x78120009, // 0006 JMPF R4 #0011 0x94100403, // 0007 GETIDX R4 R2 R3 0x88100903, // 0008 GETMBR R4 R4 K3 0x1C100801, // 0009 EQ R4 R4 R1 - 0x78120002, // 000A JMPF R4 #000E - 0x94100403, // 000B GETIDX R4 R2 R3 - 0x88100904, // 000C GETMBR R4 R4 K4 - 0x80040800, // 000D RET 1 R4 - 0x000C0705, // 000E ADD R3 R3 K5 - 0x7001FFF2, // 000F JMP #0003 - 0x80000000, // 0010 RET 0 + 0x78120003, // 000A JMPF R4 #000F + 0x8C100504, // 000B GETMET R4 R2 K4 + 0x5C180600, // 000C MOVE R6 R3 + 0x7C100400, // 000D CALL R4 2 + 0x70020000, // 000E JMP #0010 + 0x000C0705, // 000F ADD R3 R3 K5 + 0x7001FFF1, // 0010 JMP #0003 + 0x80000000, // 0011 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: find_list_i +********************************************************************/ +be_local_closure(Tasmota_find_list_i, /* name */ + be_nested_proto( + 9, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str(string), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str(toupper), + /* K3 */ be_const_int(1), + }), + &be_const_str_find_list_i, + &be_const_str_solidified, + ( &(const binstruction[20]) { /* code */ + 0xA40E0000, // 0000 IMPORT R3 K0 + 0x58100001, // 0001 LDCONST R4 K1 + 0x8C140702, // 0002 GETMET R5 R3 K2 + 0x5C1C0400, // 0003 MOVE R7 R2 + 0x7C140400, // 0004 CALL R5 2 + 0x6018000C, // 0005 GETGBL R6 G12 + 0x5C1C0200, // 0006 MOVE R7 R1 + 0x7C180200, // 0007 CALL R6 1 + 0x14180806, // 0008 LT R6 R4 R6 + 0x781A0007, // 0009 JMPF R6 #0012 + 0x8C180702, // 000A GETMET R6 R3 K2 + 0x94200204, // 000B GETIDX R8 R1 R4 + 0x7C180400, // 000C CALL R6 2 + 0x1C180C05, // 000D EQ R6 R6 R5 + 0x781A0000, // 000E JMPF R6 #0010 + 0x80040800, // 000F RET 1 R4 + 0x00100903, // 0010 ADD R4 R4 K3 + 0x7001FFF2, // 0011 JMP #0005 + 0x4C180000, // 0012 LDNIL R6 + 0x80040C00, // 0013 RET 1 R6 }) ) ); @@ -706,9 +781,90 @@ be_local_closure(Tasmota_set_light, /* name */ /******************************************************************** -** Solidified function: remove_fast_loop +** Solidified function: remove_timer ********************************************************************/ -be_local_closure(Tasmota_remove_fast_loop, /* name */ +be_local_closure(Tasmota_remove_timer, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str(_timers), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str(size), + /* K3 */ be_nested_str(id), + /* K4 */ be_nested_str(remove), + /* K5 */ be_const_int(1), + }), + &be_const_str_remove_timer, + &be_const_str_solidified, + ( &(const binstruction[18]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A000E, // 0001 JMPF R2 #0011 + 0x580C0001, // 0002 LDCONST R3 K1 + 0x8C100502, // 0003 GETMET R4 R2 K2 + 0x7C100200, // 0004 CALL R4 1 + 0x14100604, // 0005 LT R4 R3 R4 + 0x78120009, // 0006 JMPF R4 #0011 + 0x94100403, // 0007 GETIDX R4 R2 R3 + 0x88100903, // 0008 GETMBR R4 R4 K3 + 0x1C100801, // 0009 EQ R4 R4 R1 + 0x78120003, // 000A JMPF R4 #000F + 0x8C100504, // 000B GETMET R4 R2 K4 + 0x5C180600, // 000C MOVE R6 R3 + 0x7C100400, // 000D CALL R4 2 + 0x70020000, // 000E JMP #0010 + 0x000C0705, // 000F ADD R3 R3 K5 + 0x7001FFF1, // 0010 JMP #0003 + 0x80000000, // 0011 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: remove_cmd +********************************************************************/ +be_local_closure(Tasmota_remove_cmd, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str(_ccmd), + /* K1 */ be_nested_str(remove), + }), + &be_const_str_remove_cmd, + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A0003, // 0001 JMPF R2 #0006 + 0x88080100, // 0002 GETMBR R2 R0 K0 + 0x8C080501, // 0003 GETMET R2 R2 K1 + 0x5C100200, // 0004 MOVE R4 R1 + 0x7C080400, // 0005 CALL R2 2 + 0x80000000, // 0006 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: remove_driver +********************************************************************/ +be_local_closure(Tasmota_remove_driver, /* name */ be_nested_proto( 6, /* nstack */ 2, /* argc */ @@ -719,28 +875,27 @@ be_local_closure(Tasmota_remove_fast_loop, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str(_fl), + /* K0 */ be_nested_str(_drivers), /* K1 */ be_nested_str(find), - /* K2 */ be_nested_str(remove), + /* K2 */ be_nested_str(pop), }), - &be_const_str_remove_fast_loop, + &be_const_str_remove_driver, &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ + ( &(const binstruction[14]) { /* code */ 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x740A0000, // 0001 JMPT R2 #0003 - 0x80000400, // 0002 RET 0 - 0x88080100, // 0003 GETMBR R2 R0 K0 - 0x8C080501, // 0004 GETMET R2 R2 K1 - 0x5C100200, // 0005 MOVE R4 R1 - 0x7C080400, // 0006 CALL R2 2 - 0x4C0C0000, // 0007 LDNIL R3 - 0x200C0403, // 0008 NE R3 R2 R3 - 0x780E0003, // 0009 JMPF R3 #000E - 0x880C0100, // 000A GETMBR R3 R0 K0 - 0x8C0C0702, // 000B GETMET R3 R3 K2 - 0x5C140400, // 000C MOVE R5 R2 - 0x7C0C0400, // 000D CALL R3 2 - 0x80000000, // 000E RET 0 + 0x780A000A, // 0001 JMPF R2 #000D + 0x88080100, // 0002 GETMBR R2 R0 K0 + 0x8C080501, // 0003 GETMET R2 R2 K1 + 0x5C100200, // 0004 MOVE R4 R1 + 0x7C080400, // 0005 CALL R2 2 + 0x4C0C0000, // 0006 LDNIL R3 + 0x200C0403, // 0007 NE R3 R2 R3 + 0x780E0003, // 0008 JMPF R3 #000D + 0x880C0100, // 0009 GETMBR R3 R0 K0 + 0x8C0C0702, // 000A GETMET R3 R3 K2 + 0x5C140400, // 000B MOVE R5 R2 + 0x7C0C0400, // 000C CALL R3 2 + 0x80000000, // 000D RET 0 }) ) ); @@ -858,102 +1013,131 @@ be_local_closure(Tasmota_init, /* name */ /******************************************************************** -** Solidified function: set_timer +** Solidified function: add_driver ********************************************************************/ -be_local_closure(Tasmota_set_timer, /* name */ +be_local_closure(Tasmota_add_driver, /* name */ be_nested_proto( - 10, /* nstack */ - 4, /* argc */ + 5, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str(check_not_method), - /* K1 */ be_nested_str(_timers), - /* K2 */ be_nested_str(push), - /* K3 */ be_nested_str(Trigger), - /* K4 */ be_nested_str(millis), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str(instance), + /* K1 */ be_nested_str(value_error), + /* K2 */ be_nested_str(instance_X20required), + /* K3 */ be_nested_str(_drivers), + /* K4 */ be_nested_str(find), + /* K5 */ be_nested_str(push), }), - &be_const_str_set_timer, + &be_const_str_add_driver, &be_const_str_solidified, - ( &(const binstruction[19]) { /* code */ - 0x8C100100, // 0000 GETMET R4 R0 K0 - 0x5C180400, // 0001 MOVE R6 R2 - 0x7C100400, // 0002 CALL R4 2 - 0x88100101, // 0003 GETMBR R4 R0 K1 - 0x74120002, // 0004 JMPT R4 #0008 - 0x60100012, // 0005 GETGBL R4 G18 - 0x7C100000, // 0006 CALL R4 0 - 0x90020204, // 0007 SETMBR R0 K1 R4 - 0x88100101, // 0008 GETMBR R4 R0 K1 - 0x8C100902, // 0009 GETMET R4 R4 K2 - 0xB81A0600, // 000A GETNGBL R6 K3 - 0x8C1C0104, // 000B GETMET R7 R0 K4 - 0x5C240200, // 000C MOVE R9 R1 - 0x7C1C0400, // 000D CALL R7 2 - 0x5C200400, // 000E MOVE R8 R2 - 0x5C240600, // 000F MOVE R9 R3 - 0x7C180600, // 0010 CALL R6 3 - 0x7C100400, // 0011 CALL R4 2 - 0x80000000, // 0012 RET 0 - }) - ) -); + ( &(const binstruction[25]) { /* code */ + 0x60080004, // 0000 GETGBL R2 G4 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x20080500, // 0003 NE R2 R2 K0 + 0x780A0000, // 0004 JMPF R2 #0006 + 0xB0060302, // 0005 RAISE 1 K1 K2 + 0x88080103, // 0006 GETMBR R2 R0 K3 + 0x780A000B, // 0007 JMPF R2 #0014 + 0x88080103, // 0008 GETMBR R2 R0 K3 + 0x8C080504, // 0009 GETMET R2 R2 K4 + 0x5C100200, // 000A MOVE R4 R1 + 0x7C080400, // 000B CALL R2 2 + 0x4C0C0000, // 000C LDNIL R3 + 0x1C080403, // 000D EQ R2 R2 R3 + 0x780A0003, // 000E JMPF R2 #0013 + 0x88080103, // 000F GETMBR R2 R0 K3 + 0x8C080505, // 0010 GETMET R2 R2 K5 + 0x5C100200, // 0011 MOVE R4 R1 + 0x7C080400, // 0012 CALL R2 2 + 0x70020003, // 0013 JMP #0018 + 0x60080012, // 0014 GETGBL R2 G18 + 0x7C080000, // 0015 CALL R2 0 + 0x400C0401, // 0016 CONNECT R3 R2 R1 + 0x90020602, // 0017 SETMBR R0 K3 R2 + 0x80000000, // 0018 RET 0 + }) + ) +); /*******************************************************************/ /******************************************************************** -** Solidified function: add_cron +** Solidified function: exec_tele ********************************************************************/ -be_local_closure(Tasmota_add_cron, /* name */ +be_local_closure(Tasmota_exec_tele, /* name */ be_nested_proto( - 13, /* nstack */ - 4, /* argc */ + 12, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str(check_not_method), - /* K1 */ be_nested_str(_crons), - /* K2 */ be_nested_str(ccronexpr), - /* K3 */ be_nested_str(next), - /* K4 */ be_nested_str(push), - /* K5 */ be_nested_str(Trigger), + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str(_rules), + /* K1 */ be_nested_str(json), + /* K2 */ be_nested_str(load), + /* K3 */ be_nested_str(log), + /* K4 */ be_nested_str(BRY_X3A_X20ERROR_X2C_X20bad_X20json_X3A_X20), + /* K5 */ be_const_int(3), + /* K6 */ be_nested_str(Tele), + /* K7 */ be_const_int(0), + /* K8 */ be_nested_str(try_rule), + /* K9 */ be_nested_str(trig), + /* K10 */ be_nested_str(f), + /* K11 */ be_const_int(1), }), - &be_const_str_add_cron, + &be_const_str_exec_tele, &be_const_str_solidified, - ( &(const binstruction[25]) { /* code */ - 0x8C100100, // 0000 GETMET R4 R0 K0 - 0x5C180400, // 0001 MOVE R6 R2 - 0x7C100400, // 0002 CALL R4 2 - 0x88100101, // 0003 GETMBR R4 R0 K1 - 0x74120002, // 0004 JMPT R4 #0008 - 0x60100012, // 0005 GETGBL R4 G18 - 0x7C100000, // 0006 CALL R4 0 - 0x90020204, // 0007 SETMBR R0 K1 R4 - 0xB8120400, // 0008 GETNGBL R4 K2 - 0x60140008, // 0009 GETGBL R5 G8 - 0x5C180200, // 000A MOVE R6 R1 - 0x7C140200, // 000B CALL R5 1 - 0x7C100200, // 000C CALL R4 1 - 0x8C140903, // 000D GETMET R5 R4 K3 - 0x7C140200, // 000E CALL R5 1 - 0x88180101, // 000F GETMBR R6 R0 K1 - 0x8C180D04, // 0010 GETMET R6 R6 K4 - 0xB8220A00, // 0011 GETNGBL R8 K5 - 0x5C240A00, // 0012 MOVE R9 R5 - 0x5C280400, // 0013 MOVE R10 R2 - 0x5C2C0600, // 0014 MOVE R11 R3 - 0x5C300800, // 0015 MOVE R12 R4 - 0x7C200800, // 0016 CALL R8 4 - 0x7C180400, // 0017 CALL R6 2 - 0x80000000, // 0018 RET 0 + ( &(const binstruction[41]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A0024, // 0001 JMPF R2 #0027 + 0xA40A0200, // 0002 IMPORT R2 K1 + 0x8C0C0502, // 0003 GETMET R3 R2 K2 + 0x5C140200, // 0004 MOVE R5 R1 + 0x7C0C0400, // 0005 CALL R3 2 + 0x50100000, // 0006 LDBOOL R4 0 0 + 0x4C140000, // 0007 LDNIL R5 + 0x1C140605, // 0008 EQ R5 R3 R5 + 0x78160004, // 0009 JMPF R5 #000F + 0x8C140103, // 000A GETMET R5 R0 K3 + 0x001E0801, // 000B ADD R7 K4 R1 + 0x58200005, // 000C LDCONST R8 K5 + 0x7C140600, // 000D CALL R5 3 + 0x5C0C0200, // 000E MOVE R3 R1 + 0x60140013, // 000F GETGBL R5 G19 + 0x7C140000, // 0010 CALL R5 0 + 0x98160C03, // 0011 SETIDX R5 K6 R3 + 0x5C0C0A00, // 0012 MOVE R3 R5 + 0x58140007, // 0013 LDCONST R5 K7 + 0x6018000C, // 0014 GETGBL R6 G12 + 0x881C0100, // 0015 GETMBR R7 R0 K0 + 0x7C180200, // 0016 CALL R6 1 + 0x14180A06, // 0017 LT R6 R5 R6 + 0x781A000C, // 0018 JMPF R6 #0026 + 0x88180100, // 0019 GETMBR R6 R0 K0 + 0x94180C05, // 001A GETIDX R6 R6 R5 + 0x8C1C0108, // 001B GETMET R7 R0 K8 + 0x5C240600, // 001C MOVE R9 R3 + 0x88280D09, // 001D GETMBR R10 R6 K9 + 0x882C0D0A, // 001E GETMBR R11 R6 K10 + 0x7C1C0800, // 001F CALL R7 4 + 0x741E0001, // 0020 JMPT R7 #0023 + 0x74120000, // 0021 JMPT R4 #0023 + 0x50100001, // 0022 LDBOOL R4 0 1 + 0x50100200, // 0023 LDBOOL R4 1 0 + 0x00140B0B, // 0024 ADD R5 R5 K11 + 0x7001FFED, // 0025 JMP #0014 + 0x80040800, // 0026 RET 1 R4 + 0x50080000, // 0027 LDBOOL R2 0 0 + 0x80040400, // 0028 RET 1 R2 }) ) ); @@ -961,32 +1145,48 @@ be_local_closure(Tasmota_add_cron, /* name */ /******************************************************************** -** Solidified function: gc +** Solidified function: add_cmd ********************************************************************/ -be_local_closure(Tasmota_gc, /* name */ +be_local_closure(Tasmota_add_cmd, /* name */ be_nested_proto( - 4, /* nstack */ - 1, /* argc */ + 6, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str(gc), - /* K1 */ be_nested_str(collect), - /* K2 */ be_nested_str(allocated), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str(check_not_method), + /* K1 */ be_nested_str(_ccmd), + /* K2 */ be_nested_str(function), + /* K3 */ be_nested_str(value_error), + /* K4 */ be_nested_str(the_X20second_X20argument_X20is_X20not_X20a_X20function), }), - &be_const_str_gc, + &be_const_str_add_cmd, &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x7C080200, // 0002 CALL R2 1 - 0x8C080302, // 0003 GETMET R2 R1 K2 - 0x7C080200, // 0004 CALL R2 1 - 0x80040400, // 0005 RET 1 R2 + ( &(const binstruction[20]) { /* code */ + 0x8C0C0100, // 0000 GETMET R3 R0 K0 + 0x5C140400, // 0001 MOVE R5 R2 + 0x7C0C0400, // 0002 CALL R3 2 + 0x880C0101, // 0003 GETMBR R3 R0 K1 + 0x4C100000, // 0004 LDNIL R4 + 0x1C0C0604, // 0005 EQ R3 R3 R4 + 0x780E0002, // 0006 JMPF R3 #000A + 0x600C0013, // 0007 GETGBL R3 G19 + 0x7C0C0000, // 0008 CALL R3 0 + 0x90020203, // 0009 SETMBR R0 K1 R3 + 0x600C0004, // 000A GETGBL R3 G4 + 0x5C100400, // 000B MOVE R4 R2 + 0x7C0C0200, // 000C CALL R3 1 + 0x1C0C0702, // 000D EQ R3 R3 K2 + 0x780E0002, // 000E JMPF R3 #0012 + 0x880C0101, // 000F GETMBR R3 R0 K1 + 0x980C0202, // 0010 SETIDX R3 R1 R2 + 0x70020000, // 0011 JMP #0013 + 0xB0060704, // 0012 RAISE 1 K3 K4 + 0x80000000, // 0013 RET 0 }) ) ); @@ -994,11 +1194,11 @@ be_local_closure(Tasmota_gc, /* name */ /******************************************************************** -** Solidified function: get_light +** Solidified function: find_op ********************************************************************/ -be_local_closure(Tasmota_get_light, /* name */ +be_local_closure(Tasmota_find_op, /* name */ be_nested_proto( - 6, /* nstack */ + 7, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1006,30 +1206,46 @@ be_local_closure(Tasmota_get_light, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str(tasmota_X2Eget_light_X28_X29_X20is_X20deprecated_X2C_X20use_X20light_X2Eget_X28_X29), - /* K1 */ be_nested_str(light), - /* K2 */ be_nested_str(get), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str(_find_op), + /* K1 */ be_const_int(0), + /* K2 */ be_const_int(1), + /* K3 */ be_const_int(2147483647), }), - &be_const_str_get_light, + &be_const_str_find_op, &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x60080001, // 0000 GETGBL R2 G1 - 0x580C0000, // 0001 LDCONST R3 K0 - 0x7C080200, // 0002 CALL R2 1 - 0xA40A0200, // 0003 IMPORT R2 K1 - 0x4C0C0000, // 0004 LDNIL R3 - 0x200C0203, // 0005 NE R3 R1 R3 - 0x780E0004, // 0006 JMPF R3 #000C - 0x8C0C0502, // 0007 GETMET R3 R2 K2 - 0x5C140200, // 0008 MOVE R5 R1 - 0x7C0C0400, // 0009 CALL R3 2 - 0x80040600, // 000A RET 1 R3 - 0x70020002, // 000B JMP #000F - 0x8C0C0502, // 000C GETMET R3 R2 K2 - 0x7C0C0200, // 000D CALL R3 1 - 0x80040600, // 000E RET 1 R3 - 0x80000000, // 000F RET 0 + ( &(const binstruction[31]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0x280C0501, // 0003 GE R3 R2 K1 + 0x780E0011, // 0004 JMPF R3 #0017 + 0x540E7FFE, // 0005 LDINT R3 32767 + 0x2C0C0403, // 0006 AND R3 R2 R3 + 0x5412000F, // 0007 LDINT R4 16 + 0x3C100404, // 0008 SHR R4 R2 R4 + 0x60140012, // 0009 GETGBL R5 G18 + 0x7C140000, // 000A CALL R5 0 + 0x04180702, // 000B SUB R6 R3 K2 + 0x401A0206, // 000C CONNECT R6 K1 R6 + 0x94180206, // 000D GETIDX R6 R1 R6 + 0x40180A06, // 000E CONNECT R6 R5 R6 + 0x04180902, // 000F SUB R6 R4 K2 + 0x40180606, // 0010 CONNECT R6 R3 R6 + 0x94180206, // 0011 GETIDX R6 R1 R6 + 0x40180A06, // 0012 CONNECT R6 R5 R6 + 0x40180903, // 0013 CONNECT R6 R4 K3 + 0x94180206, // 0014 GETIDX R6 R1 R6 + 0x40180A06, // 0015 CONNECT R6 R5 R6 + 0x80040A00, // 0016 RET 1 R5 + 0x600C0012, // 0017 GETGBL R3 G18 + 0x7C0C0000, // 0018 CALL R3 0 + 0x40100601, // 0019 CONNECT R4 R3 R1 + 0x4C100000, // 001A LDNIL R4 + 0x40100604, // 001B CONNECT R4 R3 R4 + 0x4C100000, // 001C LDNIL R4 + 0x40100604, // 001D CONNECT R4 R3 R4 + 0x80040600, // 001E RET 1 R3 }) ) ); @@ -1037,32 +1253,56 @@ be_local_closure(Tasmota_get_light, /* name */ /******************************************************************** -** Solidified function: remove_cmd +** Solidified function: add_cron ********************************************************************/ -be_local_closure(Tasmota_remove_cmd, /* name */ +be_local_closure(Tasmota_add_cron, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 13, /* nstack */ + 4, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str(_ccmd), - /* K1 */ be_nested_str(remove), + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str(check_not_method), + /* K1 */ be_nested_str(_crons), + /* K2 */ be_nested_str(ccronexpr), + /* K3 */ be_nested_str(next), + /* K4 */ be_nested_str(push), + /* K5 */ be_nested_str(Trigger), }), - &be_const_str_remove_cmd, + &be_const_str_add_cron, &be_const_str_solidified, - ( &(const binstruction[ 7]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x780A0003, // 0001 JMPF R2 #0006 - 0x88080100, // 0002 GETMBR R2 R0 K0 - 0x8C080501, // 0003 GETMET R2 R2 K1 - 0x5C100200, // 0004 MOVE R4 R1 - 0x7C080400, // 0005 CALL R2 2 - 0x80000000, // 0006 RET 0 + ( &(const binstruction[27]) { /* code */ + 0x8C100100, // 0000 GETMET R4 R0 K0 + 0x5C180400, // 0001 MOVE R6 R2 + 0x7C100400, // 0002 CALL R4 2 + 0x88100101, // 0003 GETMBR R4 R0 K1 + 0x4C140000, // 0004 LDNIL R5 + 0x1C100805, // 0005 EQ R4 R4 R5 + 0x78120002, // 0006 JMPF R4 #000A + 0x60100012, // 0007 GETGBL R4 G18 + 0x7C100000, // 0008 CALL R4 0 + 0x90020204, // 0009 SETMBR R0 K1 R4 + 0xB8120400, // 000A GETNGBL R4 K2 + 0x60140008, // 000B GETGBL R5 G8 + 0x5C180200, // 000C MOVE R6 R1 + 0x7C140200, // 000D CALL R5 1 + 0x7C100200, // 000E CALL R4 1 + 0x8C140903, // 000F GETMET R5 R4 K3 + 0x7C140200, // 0010 CALL R5 1 + 0x88180101, // 0011 GETMBR R6 R0 K1 + 0x8C180D04, // 0012 GETMET R6 R6 K4 + 0xB8220A00, // 0013 GETNGBL R8 K5 + 0x5C240A00, // 0014 MOVE R9 R5 + 0x5C280400, // 0015 MOVE R10 R2 + 0x5C2C0600, // 0016 MOVE R11 R3 + 0x5C300800, // 0017 MOVE R12 R4 + 0x7C200800, // 0018 CALL R8 4 + 0x7C180400, // 0019 CALL R6 2 + 0x80000000, // 001A RET 0 }) ) ); @@ -1070,54 +1310,270 @@ be_local_closure(Tasmota_remove_cmd, /* name */ /******************************************************************** -** Solidified function: add_driver +** Solidified function: remove_rule ********************************************************************/ -be_local_closure(Tasmota_add_driver, /* name */ +be_local_closure(Tasmota_remove_rule, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 7, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str(instance), - /* K1 */ be_nested_str(value_error), - /* K2 */ be_nested_str(instance_X20required), - /* K3 */ be_nested_str(_drivers), - /* K4 */ be_nested_str(find), - /* K5 */ be_nested_str(push), - }), - &be_const_str_add_driver, + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str(_rules), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str(trig), + /* K3 */ be_nested_str(rule), + /* K4 */ be_nested_str(id), + /* K5 */ be_nested_str(remove), + /* K6 */ be_const_int(1), + }), + &be_const_str_remove_rule, &be_const_str_solidified, - ( &(const binstruction[25]) { /* code */ - 0x60080004, // 0000 GETGBL R2 G4 - 0x5C0C0200, // 0001 MOVE R3 R1 + ( &(const binstruction[27]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x780E0017, // 0001 JMPF R3 #001A + 0x580C0001, // 0002 LDCONST R3 K1 + 0x6010000C, // 0003 GETGBL R4 G12 + 0x88140100, // 0004 GETMBR R5 R0 K0 + 0x7C100200, // 0005 CALL R4 1 + 0x14100604, // 0006 LT R4 R3 R4 + 0x78120011, // 0007 JMPF R4 #001A + 0x88100100, // 0008 GETMBR R4 R0 K0 + 0x94100803, // 0009 GETIDX R4 R4 R3 + 0x88100902, // 000A GETMBR R4 R4 K2 + 0x88100903, // 000B GETMBR R4 R4 K3 + 0x1C100801, // 000C EQ R4 R4 R1 + 0x78120009, // 000D JMPF R4 #0018 + 0x88100100, // 000E GETMBR R4 R0 K0 + 0x94100803, // 000F GETIDX R4 R4 R3 + 0x88100904, // 0010 GETMBR R4 R4 K4 + 0x1C100802, // 0011 EQ R4 R4 R2 + 0x78120004, // 0012 JMPF R4 #0018 + 0x88100100, // 0013 GETMBR R4 R0 K0 + 0x8C100905, // 0014 GETMET R4 R4 K5 + 0x5C180600, // 0015 MOVE R6 R3 + 0x7C100400, // 0016 CALL R4 2 + 0x70020000, // 0017 JMP #0019 + 0x000C0706, // 0018 ADD R3 R3 K6 + 0x7001FFE8, // 0019 JMP #0003 + 0x80000000, // 001A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: wire_scan +********************************************************************/ +be_local_closure(Tasmota_wire_scan, /* name */ + be_nested_proto( + 6, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str(i2c_enabled), + /* K1 */ be_nested_str(wire1), + /* K2 */ be_nested_str(enabled), + /* K3 */ be_nested_str(detect), + /* K4 */ be_nested_str(wire2), + }), + &be_const_str_wire_scan, + &be_const_str_solidified, + ( &(const binstruction[33]) { /* code */ + 0x4C0C0000, // 0000 LDNIL R3 + 0x200C0403, // 0001 NE R3 R2 R3 + 0x780E0005, // 0002 JMPF R3 #0009 + 0x8C0C0100, // 0003 GETMET R3 R0 K0 + 0x5C140400, // 0004 MOVE R5 R2 + 0x7C0C0400, // 0005 CALL R3 2 + 0x740E0001, // 0006 JMPT R3 #0009 + 0x4C0C0000, // 0007 LDNIL R3 + 0x80040600, // 0008 RET 1 R3 + 0x880C0101, // 0009 GETMBR R3 R0 K1 + 0x8C0C0702, // 000A GETMET R3 R3 K2 + 0x7C0C0200, // 000B CALL R3 1 + 0x780E0006, // 000C JMPF R3 #0014 + 0x880C0101, // 000D GETMBR R3 R0 K1 + 0x8C0C0703, // 000E GETMET R3 R3 K3 + 0x5C140200, // 000F MOVE R5 R1 + 0x7C0C0400, // 0010 CALL R3 2 + 0x780E0001, // 0011 JMPF R3 #0014 + 0x880C0101, // 0012 GETMBR R3 R0 K1 + 0x80040600, // 0013 RET 1 R3 + 0x880C0104, // 0014 GETMBR R3 R0 K4 + 0x8C0C0702, // 0015 GETMET R3 R3 K2 + 0x7C0C0200, // 0016 CALL R3 1 + 0x780E0006, // 0017 JMPF R3 #001F + 0x880C0104, // 0018 GETMBR R3 R0 K4 + 0x8C0C0703, // 0019 GETMET R3 R3 K3 + 0x5C140200, // 001A MOVE R5 R1 + 0x7C0C0400, // 001B CALL R3 2 + 0x780E0001, // 001C JMPF R3 #001F + 0x880C0104, // 001D GETMBR R3 R0 K4 + 0x80040600, // 001E RET 1 R3 + 0x4C0C0000, // 001F LDNIL R3 + 0x80040600, // 0020 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_light +********************************************************************/ +be_local_closure(Tasmota_get_light, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str(tasmota_X2Eget_light_X28_X29_X20is_X20deprecated_X2C_X20use_X20light_X2Eget_X28_X29), + /* K1 */ be_nested_str(light), + /* K2 */ be_nested_str(get), + }), + &be_const_str_get_light, + &be_const_str_solidified, + ( &(const binstruction[16]) { /* code */ + 0x60080001, // 0000 GETGBL R2 G1 + 0x580C0000, // 0001 LDCONST R3 K0 0x7C080200, // 0002 CALL R2 1 - 0x20080500, // 0003 NE R2 R2 K0 - 0x780A0000, // 0004 JMPF R2 #0006 - 0xB0060302, // 0005 RAISE 1 K1 K2 - 0x88080103, // 0006 GETMBR R2 R0 K3 - 0x780A000B, // 0007 JMPF R2 #0014 - 0x88080103, // 0008 GETMBR R2 R0 K3 - 0x8C080504, // 0009 GETMET R2 R2 K4 - 0x5C100200, // 000A MOVE R4 R1 - 0x7C080400, // 000B CALL R2 2 - 0x4C0C0000, // 000C LDNIL R3 - 0x1C080403, // 000D EQ R2 R2 R3 - 0x780A0003, // 000E JMPF R2 #0013 - 0x88080103, // 000F GETMBR R2 R0 K3 - 0x8C080505, // 0010 GETMET R2 R2 K5 - 0x5C100200, // 0011 MOVE R4 R1 - 0x7C080400, // 0012 CALL R2 2 - 0x70020003, // 0013 JMP #0018 - 0x60080012, // 0014 GETGBL R2 G18 - 0x7C080000, // 0015 CALL R2 0 - 0x400C0401, // 0016 CONNECT R3 R2 R1 - 0x90020602, // 0017 SETMBR R0 K3 R2 - 0x80000000, // 0018 RET 0 + 0xA40A0200, // 0003 IMPORT R2 K1 + 0x4C0C0000, // 0004 LDNIL R3 + 0x200C0203, // 0005 NE R3 R1 R3 + 0x780E0004, // 0006 JMPF R3 #000C + 0x8C0C0502, // 0007 GETMET R3 R2 K2 + 0x5C140200, // 0008 MOVE R5 R1 + 0x7C0C0400, // 0009 CALL R3 2 + 0x80040600, // 000A RET 1 R3 + 0x70020002, // 000B JMP #000F + 0x8C0C0502, // 000C GETMET R3 R2 K2 + 0x7C0C0200, // 000D CALL R3 1 + 0x80040600, // 000E RET 1 R3 + 0x80000000, // 000F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: cmd +********************************************************************/ +be_local_closure(Tasmota_cmd, /* name */ + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str(cmd_res), + /* K1 */ be_nested_str(tasmota), + /* K2 */ be_nested_str(global), + /* K3 */ be_nested_str(maxlog_level), + /* K4 */ be_const_int(2), + /* K5 */ be_const_int(1), + /* K6 */ be_nested_str(_cmd), + }), + &be_const_str_cmd, + &be_const_str_solidified, + ( &(const binstruction[27]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x50100200, // 0001 LDBOOL R4 1 0 + 0x90020004, // 0002 SETMBR R0 K0 R4 + 0xB8120200, // 0003 GETNGBL R4 K1 + 0x88100902, // 0004 GETMBR R4 R4 K2 + 0x88100903, // 0005 GETMBR R4 R4 K3 + 0x780A0004, // 0006 JMPF R2 #000C + 0x28140904, // 0007 GE R5 R4 K4 + 0x78160002, // 0008 JMPF R5 #000C + 0xB8160200, // 0009 GETNGBL R5 K1 + 0x88140B02, // 000A GETMBR R5 R5 K2 + 0x90160705, // 000B SETMBR R5 K3 K5 + 0x8C140106, // 000C GETMET R5 R0 K6 + 0x5C1C0200, // 000D MOVE R7 R1 + 0x7C140400, // 000E CALL R5 2 + 0x4C140000, // 000F LDNIL R5 + 0x88180100, // 0010 GETMBR R6 R0 K0 + 0x501C0200, // 0011 LDBOOL R7 1 0 + 0x20180C07, // 0012 NE R6 R6 R7 + 0x781A0000, // 0013 JMPF R6 #0015 + 0x88140100, // 0014 GETMBR R5 R0 K0 + 0x90020003, // 0015 SETMBR R0 K0 R3 + 0x780A0002, // 0016 JMPF R2 #001A + 0xB81A0200, // 0017 GETNGBL R6 K1 + 0x88180D02, // 0018 GETMBR R6 R6 K2 + 0x901A0604, // 0019 SETMBR R6 K3 R4 + 0x80040A00, // 001A RET 1 R5 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_timer +********************************************************************/ +be_local_closure(Tasmota_set_timer, /* name */ + be_nested_proto( + 10, /* nstack */ + 4, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str(check_not_method), + /* K1 */ be_nested_str(_timers), + /* K2 */ be_nested_str(push), + /* K3 */ be_nested_str(Trigger), + /* K4 */ be_nested_str(millis), + }), + &be_const_str_set_timer, + &be_const_str_solidified, + ( &(const binstruction[21]) { /* code */ + 0x8C100100, // 0000 GETMET R4 R0 K0 + 0x5C180400, // 0001 MOVE R6 R2 + 0x7C100400, // 0002 CALL R4 2 + 0x88100101, // 0003 GETMBR R4 R0 K1 + 0x4C140000, // 0004 LDNIL R5 + 0x1C100805, // 0005 EQ R4 R4 R5 + 0x78120002, // 0006 JMPF R4 #000A + 0x60100012, // 0007 GETGBL R4 G18 + 0x7C100000, // 0008 CALL R4 0 + 0x90020204, // 0009 SETMBR R0 K1 R4 + 0x88100101, // 000A GETMBR R4 R0 K1 + 0x8C100902, // 000B GETMET R4 R4 K2 + 0xB81A0600, // 000C GETNGBL R6 K3 + 0x8C1C0104, // 000D GETMET R7 R0 K4 + 0x5C240200, // 000E MOVE R9 R1 + 0x7C1C0400, // 000F CALL R7 2 + 0x5C200400, // 0010 MOVE R8 R2 + 0x5C240600, // 0011 MOVE R9 R3 + 0x7C180600, // 0012 CALL R6 3 + 0x7C100400, // 0013 CALL R4 2 + 0x80000000, // 0014 RET 0 }) ) ); @@ -1129,7 +1585,7 @@ be_local_closure(Tasmota_add_driver, /* name */ ********************************************************************/ be_local_closure(Tasmota_load, /* name */ be_nested_proto( - 27, /* nstack */ + 26, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1203,7 +1659,7 @@ be_local_closure(Tasmota_load, /* name */ }) ), be_nested_proto( - 10, /* nstack */ + 8, /* nstack */ 1, /* argc */ 0, /* varg */ 0, /* has upvals */ @@ -1211,7 +1667,7 @@ be_local_closure(Tasmota_load, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ + ( &(const bvalue[ 8]) { /* constants */ /* K0 */ be_nested_str(r), /* K1 */ be_nested_str(readbytes), /* K2 */ be_const_int(3), @@ -1219,13 +1675,11 @@ be_local_closure(Tasmota_load, /* name */ /* K4 */ be_nested_str(BECDFE), /* K5 */ be_const_int(0), /* K6 */ be_nested_str(close), - /* K7 */ be_nested_str(string), - /* K8 */ be_nested_str(format), - /* K9 */ be_nested_str(BRY_X3A_X20failed_X20to_X20load_X20compiled_X20_X27_X25s_X27_X20_X28_X25s_X29), + /* K7 */ be_nested_str(BRY_X3A_X20failed_X20to_X20load_X20compiled_X20_X27_X25s_X27_X20_X28_X25s_X29), }), &be_const_str_try_get_bec_version, &be_const_str_solidified, - ( &(const binstruction[44]) { /* code */ + ( &(const binstruction[43]) { /* code */ 0x4C040000, // 0000 LDNIL R1 0xA8020016, // 0001 EXBLK 0 #0019 0x60080011, // 0002 GETGBL R2 G17 @@ -1250,26 +1704,25 @@ be_local_closure(Tasmota_load, /* name */ 0x8C100306, // 0015 GETMET R4 R1 K6 0x7C100200, // 0016 CALL R4 1 0xA8040001, // 0017 EXBLK 1 1 - 0x70020010, // 0018 JMP #002A + 0x7002000F, // 0018 JMP #0029 0xAC080001, // 0019 CATCH R2 0 1 - 0x7002000D, // 001A JMP #0029 + 0x7002000C, // 001A JMP #0028 0x4C0C0000, // 001B LDNIL R3 0x200C0203, // 001C NE R3 R1 R3 0x780E0001, // 001D JMPF R3 #0020 0x8C0C0306, // 001E GETMET R3 R1 K6 0x7C0C0200, // 001F CALL R3 1 - 0xA40E0E00, // 0020 IMPORT R3 K7 - 0x60100001, // 0021 GETGBL R4 G1 - 0x8C140708, // 0022 GETMET R5 R3 K8 - 0x581C0009, // 0023 LDCONST R7 K9 - 0x5C200000, // 0024 MOVE R8 R0 - 0x5C240400, // 0025 MOVE R9 R2 - 0x7C140800, // 0026 CALL R5 4 - 0x7C100200, // 0027 CALL R4 1 - 0x70020000, // 0028 JMP #002A - 0xB0080000, // 0029 RAISE 2 R0 R0 - 0x4C080000, // 002A LDNIL R2 - 0x80040400, // 002B RET 1 R2 + 0x600C0001, // 0020 GETGBL R3 G1 + 0x60100018, // 0021 GETGBL R4 G24 + 0x58140007, // 0022 LDCONST R5 K7 + 0x5C180000, // 0023 MOVE R6 R0 + 0x5C1C0400, // 0024 MOVE R7 R2 + 0x7C100600, // 0025 CALL R4 3 + 0x7C0C0200, // 0026 CALL R3 1 + 0x70020000, // 0027 JMP #0029 + 0xB0080000, // 0028 RAISE 2 R0 R0 + 0x4C080000, // 0029 LDNIL R2 + 0x80040400, // 002A RET 1 R2 }) ), be_nested_proto( @@ -1306,7 +1759,7 @@ be_local_closure(Tasmota_load, /* name */ }) ), be_nested_proto( - 11, /* nstack */ + 9, /* nstack */ 1, /* argc */ 0, /* varg */ 0, /* has upvals */ @@ -1314,15 +1767,13 @@ be_local_closure(Tasmota_load, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ + ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str(file), - /* K1 */ be_nested_str(string), - /* K2 */ be_nested_str(format), - /* K3 */ be_nested_str(BRY_X3A_X20failed_X20to_X20load_X20_X27_X25s_X27_X20_X28_X25s_X20_X2D_X20_X25s_X29), + /* K1 */ be_nested_str(BRY_X3A_X20failed_X20to_X20load_X20_X27_X25s_X27_X20_X28_X25s_X20_X2D_X20_X25s_X29), }), &be_const_str_try_compile, &be_const_str_solidified, - ( &(const binstruction[24]) { /* code */ + ( &(const binstruction[23]) { /* code */ 0xA8020007, // 0000 EXBLK 0 #0009 0x6004000D, // 0001 GETGBL R1 G13 0x5C080000, // 0002 MOVE R2 R0 @@ -1331,26 +1782,25 @@ be_local_closure(Tasmota_load, /* name */ 0xA8040001, // 0005 EXBLK 1 1 0x80040200, // 0006 RET 1 R1 0xA8040001, // 0007 EXBLK 1 1 - 0x7002000C, // 0008 JMP #0016 + 0x7002000B, // 0008 JMP #0015 0xAC040002, // 0009 CATCH R1 0 2 - 0x70020009, // 000A JMP #0015 - 0xA40E0200, // 000B IMPORT R3 K1 - 0x60100001, // 000C GETGBL R4 G1 - 0x8C140702, // 000D GETMET R5 R3 K2 - 0x581C0003, // 000E LDCONST R7 K3 - 0x5C200000, // 000F MOVE R8 R0 - 0x5C240200, // 0010 MOVE R9 R1 - 0x5C280400, // 0011 MOVE R10 R2 - 0x7C140A00, // 0012 CALL R5 5 - 0x7C100200, // 0013 CALL R4 1 - 0x70020000, // 0014 JMP #0016 - 0xB0080000, // 0015 RAISE 2 R0 R0 - 0x4C040000, // 0016 LDNIL R1 - 0x80040200, // 0017 RET 1 R1 + 0x70020008, // 000A JMP #0014 + 0x600C0001, // 000B GETGBL R3 G1 + 0x60100018, // 000C GETGBL R4 G24 + 0x58140001, // 000D LDCONST R5 K1 + 0x5C180000, // 000E MOVE R6 R0 + 0x5C1C0200, // 000F MOVE R7 R1 + 0x5C200400, // 0010 MOVE R8 R2 + 0x7C100800, // 0011 CALL R4 4 + 0x7C0C0200, // 0012 CALL R3 1 + 0x70020000, // 0013 JMP #0015 + 0xB0080000, // 0014 RAISE 2 R0 R0 + 0x4C040000, // 0015 LDNIL R1 + 0x80040200, // 0016 RET 1 R1 }) ), be_nested_proto( - 10, /* nstack */ + 8, /* nstack */ 1, /* argc */ 0, /* varg */ 0, /* has upvals */ @@ -1358,17 +1808,15 @@ be_local_closure(Tasmota_load, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(format), - /* K2 */ be_nested_str(BRY_X3A_X20failed_X20to_X20run_X20compiled_X20code_X20_X27_X25s_X27_X20_X2D_X20_X25s), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str(BRY_X3A_X20failed_X20to_X20run_X20compiled_X20code_X20_X27_X25s_X27_X20_X2D_X20_X25s), }), &be_const_str_try_run_compiled, &be_const_str_solidified, - ( &(const binstruction[25]) { /* code */ + ( &(const binstruction[24]) { /* code */ 0x4C040000, // 0000 LDNIL R1 0x20040001, // 0001 NE R1 R0 R1 - 0x78060013, // 0002 JMPF R1 #0017 + 0x78060012, // 0002 JMPF R1 #0016 0xA8020006, // 0003 EXBLK 0 #000B 0x5C040000, // 0004 MOVE R1 R0 0x7C040000, // 0005 CALL R1 0 @@ -1376,26 +1824,25 @@ be_local_closure(Tasmota_load, /* name */ 0xA8040001, // 0007 EXBLK 1 1 0x80040200, // 0008 RET 1 R1 0xA8040001, // 0009 EXBLK 1 1 - 0x7002000B, // 000A JMP #0017 + 0x7002000A, // 000A JMP #0016 0xAC040002, // 000B CATCH R1 0 2 - 0x70020008, // 000C JMP #0016 - 0xA40E0000, // 000D IMPORT R3 K0 - 0x60100001, // 000E GETGBL R4 G1 - 0x8C140701, // 000F GETMET R5 R3 K1 - 0x581C0002, // 0010 LDCONST R7 K2 - 0x5C200200, // 0011 MOVE R8 R1 - 0x5C240400, // 0012 MOVE R9 R2 - 0x7C140800, // 0013 CALL R5 4 - 0x7C100200, // 0014 CALL R4 1 - 0x70020000, // 0015 JMP #0017 - 0xB0080000, // 0016 RAISE 2 R0 R0 - 0x50040000, // 0017 LDBOOL R1 0 0 - 0x80040200, // 0018 RET 1 R1 + 0x70020007, // 000C JMP #0015 + 0x600C0001, // 000D GETGBL R3 G1 + 0x60100018, // 000E GETGBL R4 G24 + 0x58140000, // 000F LDCONST R5 K0 + 0x5C180200, // 0010 MOVE R6 R1 + 0x5C1C0400, // 0011 MOVE R7 R2 + 0x7C100600, // 0012 CALL R4 3 + 0x7C0C0200, // 0013 CALL R3 1 + 0x70020000, // 0014 JMP #0016 + 0xB0080000, // 0015 RAISE 2 R0 R0 + 0x50040000, // 0016 LDBOOL R1 0 0 + 0x80040200, // 0017 RET 1 R1 }) ), }), 1, /* has constants */ - ( &(const bvalue[22]) { /* constants */ + ( &(const bvalue[21]) { /* constants */ /* K0 */ be_nested_str(string), /* K1 */ be_nested_str(path), /* K2 */ be_const_int(0), @@ -1413,11 +1860,10 @@ be_local_closure(Tasmota_load, /* name */ /* K14 */ be_nested_str(c), /* K15 */ be_nested_str(wd), /* K16 */ be_nested_str(), - /* K17 */ be_nested_str(format), - /* K18 */ be_nested_str(BRY_X3A_X20corrupt_X20bytecode_X20_X27_X25s_X27), - /* K19 */ be_nested_str(BRY_X3A_X20bytecode_X20has_X20wrong_X20version_X20_X27_X25s_X27_X20_X28_X25i_X29), - /* K20 */ be_nested_str(save), - /* K21 */ be_nested_str(BRY_X3A_X20could_X20not_X20save_X20compiled_X20file_X20_X25s_X20_X28_X25s_X29), + /* K17 */ be_nested_str(BRY_X3A_X20corrupt_X20bytecode_X20_X27_X25s_X27), + /* K18 */ be_nested_str(BRY_X3A_X20bytecode_X20has_X20wrong_X20version_X20_X27_X25s_X27_X20_X28_X25i_X29), + /* K19 */ be_nested_str(save), + /* K20 */ be_nested_str(BRY_X3A_X20could_X20not_X20save_X20compiled_X20file_X20_X25s_X20_X28_X25s_X29), }), &be_const_str_load, &be_const_str_solidified, @@ -1527,10 +1973,10 @@ be_local_closure(Tasmota_load, /* name */ 0x1C542615, // 0066 EQ R21 R19 R21 0x78560007, // 0067 JMPF R21 #0070 0x60540001, // 0068 GETGBL R21 G1 - 0x8C581111, // 0069 GETMET R22 R8 K17 - 0x58600012, // 006A LDCONST R24 K18 - 0x5C642200, // 006B MOVE R25 R17 - 0x7C580600, // 006C CALL R22 3 + 0x60580018, // 0069 GETGBL R22 G24 + 0x585C0011, // 006A LDCONST R23 K17 + 0x5C602200, // 006B MOVE R24 R17 + 0x7C580400, // 006C CALL R22 2 0x7C540200, // 006D CALL R21 1 0x50500000, // 006E LDBOOL R20 0 0 0x7002000A, // 006F JMP #007B @@ -1538,11 +1984,11 @@ be_local_closure(Tasmota_load, /* name */ 0x20542615, // 0071 NE R21 R19 R21 0x78560007, // 0072 JMPF R21 #007B 0x60540001, // 0073 GETGBL R21 G1 - 0x8C581111, // 0074 GETMET R22 R8 K17 - 0x58600013, // 0075 LDCONST R24 K19 - 0x5C642200, // 0076 MOVE R25 R17 - 0x5C682600, // 0077 MOVE R26 R19 - 0x7C580800, // 0078 CALL R22 4 + 0x60580018, // 0074 GETGBL R22 G24 + 0x585C0012, // 0075 LDCONST R23 K18 + 0x5C602200, // 0076 MOVE R24 R17 + 0x5C642600, // 0077 MOVE R25 R19 + 0x7C580600, // 0078 CALL R22 3 0x7C540200, // 0079 CALL R21 1 0x50500000, // 007A LDBOOL R20 0 0 0x78520003, // 007B JMPF R20 #0080 @@ -1573,7 +2019,7 @@ be_local_closure(Tasmota_load, /* name */ 0x5C4C1A00, // 0094 MOVE R19 R13 0x744E0011, // 0095 JMPT R19 #00A8 0xA8020005, // 0096 EXBLK 0 #009D - 0x8C4C0114, // 0097 GETMET R19 R0 K20 + 0x8C4C0113, // 0097 GETMET R19 R0 K19 0x5C542200, // 0098 MOVE R21 R17 0x5C582400, // 0099 MOVE R22 R18 0x7C4C0600, // 009A CALL R19 3 @@ -1582,11 +2028,11 @@ be_local_closure(Tasmota_load, /* name */ 0xAC4C0001, // 009D CATCH R19 0 1 0x70020007, // 009E JMP #00A7 0x60500001, // 009F GETGBL R20 G1 - 0x8C541111, // 00A0 GETMET R21 R8 K17 - 0x585C0015, // 00A1 LDCONST R23 K21 - 0x5C602200, // 00A2 MOVE R24 R17 - 0x5C642600, // 00A3 MOVE R25 R19 - 0x7C540800, // 00A4 CALL R21 4 + 0x60540018, // 00A0 GETGBL R21 G24 + 0x58580014, // 00A1 LDCONST R22 K20 + 0x5C5C2200, // 00A2 MOVE R23 R17 + 0x5C602600, // 00A3 MOVE R24 R19 + 0x7C540600, // 00A4 CALL R21 3 0x7C500200, // 00A5 CALL R20 1 0x70020000, // 00A6 JMP #00A8 0xB0080000, // 00A7 RAISE 2 R0 R0 @@ -1605,177 +2051,11 @@ be_local_closure(Tasmota_load, /* name */ /******************************************************************** -** Solidified function: urlfetch +** Solidified function: next_cron ********************************************************************/ -be_local_closure(Tasmota_urlfetch, /* name */ +be_local_closure(Tasmota_next_cron, /* name */ be_nested_proto( - 10, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[17]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(split), - /* K2 */ be_nested_str(_X2F), - /* K3 */ be_nested_str(pop), - /* K4 */ be_const_int(0), - /* K5 */ be_nested_str(index_X2Ehtml), - /* K6 */ be_nested_str(webclient), - /* K7 */ be_nested_str(set_follow_redirects), - /* K8 */ be_nested_str(begin), - /* K9 */ be_nested_str(GET), - /* K10 */ be_nested_str(status_X3A_X20), - /* K11 */ be_nested_str(connection_error), - /* K12 */ be_nested_str(write_file), - /* K13 */ be_nested_str(close), - /* K14 */ be_nested_str(log), - /* K15 */ be_nested_str(BRY_X3A_X20Fetched_X20), - /* K16 */ be_const_int(3), - }), - &be_const_str_urlfetch, - &be_const_str_solidified, - ( &(const binstruction[48]) { /* code */ - 0x4C0C0000, // 0000 LDNIL R3 - 0x1C0C0403, // 0001 EQ R3 R2 R3 - 0x780E000D, // 0002 JMPF R3 #0011 - 0xA40E0000, // 0003 IMPORT R3 K0 - 0x8C100701, // 0004 GETMET R4 R3 K1 - 0x5C180200, // 0005 MOVE R6 R1 - 0x581C0002, // 0006 LDCONST R7 K2 - 0x7C100600, // 0007 CALL R4 3 - 0x8C100903, // 0008 GETMET R4 R4 K3 - 0x7C100200, // 0009 CALL R4 1 - 0x5C080800, // 000A MOVE R2 R4 - 0x6010000C, // 000B GETGBL R4 G12 - 0x5C140400, // 000C MOVE R5 R2 - 0x7C100200, // 000D CALL R4 1 - 0x1C100904, // 000E EQ R4 R4 K4 - 0x78120000, // 000F JMPF R4 #0011 - 0x58080005, // 0010 LDCONST R2 K5 - 0xB80E0C00, // 0011 GETNGBL R3 K6 - 0x7C0C0000, // 0012 CALL R3 0 - 0x8C100707, // 0013 GETMET R4 R3 K7 - 0x50180200, // 0014 LDBOOL R6 1 0 - 0x7C100400, // 0015 CALL R4 2 - 0x8C100708, // 0016 GETMET R4 R3 K8 - 0x5C180200, // 0017 MOVE R6 R1 - 0x7C100400, // 0018 CALL R4 2 - 0x8C100709, // 0019 GETMET R4 R3 K9 - 0x7C100200, // 001A CALL R4 1 - 0x541600C7, // 001B LDINT R5 200 - 0x20140805, // 001C NE R5 R4 R5 - 0x78160004, // 001D JMPF R5 #0023 - 0x60140008, // 001E GETGBL R5 G8 - 0x5C180800, // 001F MOVE R6 R4 - 0x7C140200, // 0020 CALL R5 1 - 0x00161405, // 0021 ADD R5 K10 R5 - 0xB0061605, // 0022 RAISE 1 K11 R5 - 0x8C14070C, // 0023 GETMET R5 R3 K12 - 0x5C1C0400, // 0024 MOVE R7 R2 - 0x7C140400, // 0025 CALL R5 2 - 0x8C18070D, // 0026 GETMET R6 R3 K13 - 0x7C180200, // 0027 CALL R6 1 - 0x8C18010E, // 0028 GETMET R6 R0 K14 - 0x60200008, // 0029 GETGBL R8 G8 - 0x5C240A00, // 002A MOVE R9 R5 - 0x7C200200, // 002B CALL R8 1 - 0x00221E08, // 002C ADD R8 K15 R8 - 0x58240010, // 002D LDCONST R9 K16 - 0x7C180600, // 002E CALL R6 3 - 0x80040800, // 002F RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: exec_tele -********************************************************************/ -be_local_closure(Tasmota_exec_tele, /* name */ - be_nested_proto( - 12, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[12]) { /* constants */ - /* K0 */ be_nested_str(_rules), - /* K1 */ be_nested_str(json), - /* K2 */ be_nested_str(load), - /* K3 */ be_nested_str(log), - /* K4 */ be_nested_str(BRY_X3A_X20ERROR_X2C_X20bad_X20json_X3A_X20), - /* K5 */ be_const_int(3), - /* K6 */ be_nested_str(Tele), - /* K7 */ be_const_int(0), - /* K8 */ be_nested_str(try_rule), - /* K9 */ be_nested_str(trig), - /* K10 */ be_nested_str(f), - /* K11 */ be_const_int(1), - }), - &be_const_str_exec_tele, - &be_const_str_solidified, - ( &(const binstruction[41]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x780A0024, // 0001 JMPF R2 #0027 - 0xA40A0200, // 0002 IMPORT R2 K1 - 0x8C0C0502, // 0003 GETMET R3 R2 K2 - 0x5C140200, // 0004 MOVE R5 R1 - 0x7C0C0400, // 0005 CALL R3 2 - 0x50100000, // 0006 LDBOOL R4 0 0 - 0x4C140000, // 0007 LDNIL R5 - 0x1C140605, // 0008 EQ R5 R3 R5 - 0x78160004, // 0009 JMPF R5 #000F - 0x8C140103, // 000A GETMET R5 R0 K3 - 0x001E0801, // 000B ADD R7 K4 R1 - 0x58200005, // 000C LDCONST R8 K5 - 0x7C140600, // 000D CALL R5 3 - 0x5C0C0200, // 000E MOVE R3 R1 - 0x60140013, // 000F GETGBL R5 G19 - 0x7C140000, // 0010 CALL R5 0 - 0x98160C03, // 0011 SETIDX R5 K6 R3 - 0x5C0C0A00, // 0012 MOVE R3 R5 - 0x58140007, // 0013 LDCONST R5 K7 - 0x6018000C, // 0014 GETGBL R6 G12 - 0x881C0100, // 0015 GETMBR R7 R0 K0 - 0x7C180200, // 0016 CALL R6 1 - 0x14180A06, // 0017 LT R6 R5 R6 - 0x781A000C, // 0018 JMPF R6 #0026 - 0x88180100, // 0019 GETMBR R6 R0 K0 - 0x94180C05, // 001A GETIDX R6 R6 R5 - 0x8C1C0108, // 001B GETMET R7 R0 K8 - 0x5C240600, // 001C MOVE R9 R3 - 0x88280D09, // 001D GETMBR R10 R6 K9 - 0x882C0D0A, // 001E GETMBR R11 R6 K10 - 0x7C1C0800, // 001F CALL R7 4 - 0x741E0001, // 0020 JMPT R7 #0023 - 0x74120000, // 0021 JMPT R4 #0023 - 0x50100001, // 0022 LDBOOL R4 0 1 - 0x50100200, // 0023 LDBOOL R4 1 0 - 0x00140B0B, // 0024 ADD R5 R5 K11 - 0x7001FFED, // 0025 JMP #0014 - 0x80040800, // 0026 RET 1 R4 - 0x50080000, // 0027 LDBOOL R2 0 0 - 0x80040400, // 0028 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: time_str -********************************************************************/ -be_local_closure(Tasmota_time_str, /* name */ - be_nested_proto( - 13, /* nstack */ + 6, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1783,348 +2063,34 @@ be_local_closure(Tasmota_time_str, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(time_dump), - /* K2 */ be_nested_str(format), - /* K3 */ be_nested_str(_X2504d_X2D_X2502d_X2D_X2502dT_X2502d_X3A_X2502d_X3A_X2502d), - /* K4 */ be_nested_str(year), - /* K5 */ be_nested_str(month), - /* K6 */ be_nested_str(day), - /* K7 */ be_nested_str(hour), - /* K8 */ be_nested_str(min), - /* K9 */ be_nested_str(sec), - }), - &be_const_str_time_str, - &be_const_str_solidified, - ( &(const binstruction[14]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x8C0C0101, // 0001 GETMET R3 R0 K1 - 0x5C140200, // 0002 MOVE R5 R1 - 0x7C0C0400, // 0003 CALL R3 2 - 0x8C100502, // 0004 GETMET R4 R2 K2 - 0x58180003, // 0005 LDCONST R6 K3 - 0x941C0704, // 0006 GETIDX R7 R3 K4 - 0x94200705, // 0007 GETIDX R8 R3 K5 - 0x94240706, // 0008 GETIDX R9 R3 K6 - 0x94280707, // 0009 GETIDX R10 R3 K7 - 0x942C0708, // 000A GETIDX R11 R3 K8 - 0x94300709, // 000B GETIDX R12 R3 K9 - 0x7C101000, // 000C CALL R4 8 - 0x80040800, // 000D RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: urlfetch_cmd -********************************************************************/ -be_local_closure(Tasmota_urlfetch_cmd, /* name */ - be_nested_proto( - 10, /* nstack */ - 5, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(find), - /* K2 */ be_nested_str(http), - /* K3 */ be_const_int(0), - /* K4 */ be_nested_str(resp_cmnd_str), - /* K5 */ be_nested_str(URL_X20must_X20start_X20with_X20_X27http_X28s_X29_X27), - /* K6 */ be_nested_str(urlfetch), - /* K7 */ be_nested_str(resp_cmnd_failed), - /* K8 */ be_nested_str(tasmota), - /* K9 */ be_nested_str(resp_cmnd_done), - }), - &be_const_str_urlfetch_cmd, - &be_const_str_solidified, - ( &(const binstruction[34]) { /* code */ - 0xA4160000, // 0000 IMPORT R5 K0 - 0x8C180B01, // 0001 GETMET R6 R5 K1 - 0x5C200600, // 0002 MOVE R8 R3 - 0x58240002, // 0003 LDCONST R9 K2 - 0x7C180600, // 0004 CALL R6 3 - 0x20180D03, // 0005 NE R6 R6 K3 - 0x781A0003, // 0006 JMPF R6 #000B - 0x8C180104, // 0007 GETMET R6 R0 K4 - 0x58200005, // 0008 LDCONST R8 K5 - 0x7C180400, // 0009 CALL R6 2 - 0x80000C00, // 000A RET 0 - 0xA802000A, // 000B EXBLK 0 #0017 - 0x8C180106, // 000C GETMET R6 R0 K6 - 0x5C200600, // 000D MOVE R8 R3 - 0x7C180400, // 000E CALL R6 2 - 0x141C0D03, // 000F LT R7 R6 K3 - 0x781E0003, // 0010 JMPF R7 #0015 - 0x8C1C0107, // 0011 GETMET R7 R0 K7 - 0x7C1C0200, // 0012 CALL R7 1 - 0xA8040001, // 0013 EXBLK 1 1 - 0x80000E00, // 0014 RET 0 - 0xA8040001, // 0015 EXBLK 1 1 - 0x70020006, // 0016 JMP #001E - 0xAC180002, // 0017 CATCH R6 0 2 - 0x70020003, // 0018 JMP #001D - 0x8C200107, // 0019 GETMET R8 R0 K7 - 0x7C200200, // 001A CALL R8 1 - 0x80001000, // 001B RET 0 - 0x70020000, // 001C JMP #001E - 0xB0080000, // 001D RAISE 2 R0 R0 - 0xB81A1000, // 001E GETNGBL R6 K8 - 0x8C180D09, // 001F GETMET R6 R6 K9 - 0x7C180200, // 0020 CALL R6 1 - 0x80000000, // 0021 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: hs2rgb -********************************************************************/ -be_local_closure(Tasmota_hs2rgb, /* name */ - be_nested_proto( - 17, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_const_int(0), - /* K1 */ be_nested_str(tasmota), - /* K2 */ be_nested_str(scale_uint), - /* K3 */ be_const_int(1), - /* K4 */ be_const_int(2), - /* K5 */ be_const_int(3), - }), - &be_const_str_hs2rgb, - &be_const_str_solidified, - ( &(const binstruction[68]) { /* code */ - 0x4C0C0000, // 0000 LDNIL R3 - 0x1C0C0403, // 0001 EQ R3 R2 R3 - 0x780E0000, // 0002 JMPF R3 #0004 - 0x540A00FE, // 0003 LDINT R2 255 - 0x540E00FE, // 0004 LDINT R3 255 - 0x541200FE, // 0005 LDINT R4 255 - 0x541600FE, // 0006 LDINT R5 255 - 0x541A0167, // 0007 LDINT R6 360 - 0x10040206, // 0008 MOD R1 R1 R6 - 0x24180500, // 0009 GT R6 R2 K0 - 0x781A0031, // 000A JMPF R6 #003D - 0x541A003B, // 000B LDINT R6 60 - 0x0C180206, // 000C DIV R6 R1 R6 - 0x541E003B, // 000D LDINT R7 60 - 0x101C0207, // 000E MOD R7 R1 R7 - 0x542200FE, // 000F LDINT R8 255 - 0x04201002, // 0010 SUB R8 R8 R2 - 0xB8260200, // 0011 GETNGBL R9 K1 - 0x8C241302, // 0012 GETMET R9 R9 K2 - 0x5C2C0E00, // 0013 MOVE R11 R7 - 0x58300000, // 0014 LDCONST R12 K0 - 0x5436003B, // 0015 LDINT R13 60 - 0x543A00FE, // 0016 LDINT R14 255 - 0x5C3C1000, // 0017 MOVE R15 R8 - 0x7C240C00, // 0018 CALL R9 6 - 0xB82A0200, // 0019 GETNGBL R10 K1 - 0x8C281502, // 001A GETMET R10 R10 K2 - 0x5C300E00, // 001B MOVE R12 R7 - 0x58340000, // 001C LDCONST R13 K0 - 0x543A003B, // 001D LDINT R14 60 - 0x5C3C1000, // 001E MOVE R15 R8 - 0x544200FE, // 001F LDINT R16 255 - 0x7C280C00, // 0020 CALL R10 6 - 0x1C2C0D00, // 0021 EQ R11 R6 K0 - 0x782E0002, // 0022 JMPF R11 #0026 - 0x5C141400, // 0023 MOVE R5 R10 - 0x5C101000, // 0024 MOVE R4 R8 - 0x70020016, // 0025 JMP #003D - 0x1C2C0D03, // 0026 EQ R11 R6 K3 - 0x782E0002, // 0027 JMPF R11 #002B - 0x5C0C1200, // 0028 MOVE R3 R9 - 0x5C101000, // 0029 MOVE R4 R8 - 0x70020011, // 002A JMP #003D - 0x1C2C0D04, // 002B EQ R11 R6 K4 - 0x782E0002, // 002C JMPF R11 #0030 - 0x5C0C1000, // 002D MOVE R3 R8 - 0x5C101400, // 002E MOVE R4 R10 - 0x7002000C, // 002F JMP #003D - 0x1C2C0D05, // 0030 EQ R11 R6 K5 - 0x782E0002, // 0031 JMPF R11 #0035 - 0x5C0C1000, // 0032 MOVE R3 R8 - 0x5C141200, // 0033 MOVE R5 R9 - 0x70020007, // 0034 JMP #003D - 0x542E0003, // 0035 LDINT R11 4 - 0x1C2C0C0B, // 0036 EQ R11 R6 R11 - 0x782E0002, // 0037 JMPF R11 #003B - 0x5C0C1400, // 0038 MOVE R3 R10 - 0x5C141000, // 0039 MOVE R5 R8 - 0x70020001, // 003A JMP #003D - 0x5C141000, // 003B MOVE R5 R8 - 0x5C101200, // 003C MOVE R4 R9 - 0x541A000F, // 003D LDINT R6 16 - 0x38180606, // 003E SHL R6 R3 R6 - 0x541E0007, // 003F LDINT R7 8 - 0x381C0A07, // 0040 SHL R7 R5 R7 - 0x30180C07, // 0041 OR R6 R6 R7 - 0x30180C04, // 0042 OR R6 R6 R4 - 0x80040C00, // 0043 RET 1 R6 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: try_rule -********************************************************************/ -be_local_closure(Tasmota_try_rule, /* name */ - be_nested_proto( - 9, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str(match), - /* K1 */ be_nested_str(trigger), - }), - &be_const_str_try_rule, - &be_const_str_solidified, - ( &(const binstruction[18]) { /* code */ - 0x8C100500, // 0000 GETMET R4 R2 K0 - 0x5C180200, // 0001 MOVE R6 R1 - 0x7C100400, // 0002 CALL R4 2 - 0x4C140000, // 0003 LDNIL R5 - 0x20140805, // 0004 NE R5 R4 R5 - 0x78160009, // 0005 JMPF R5 #0010 - 0x4C140000, // 0006 LDNIL R5 - 0x20140605, // 0007 NE R5 R3 R5 - 0x78160004, // 0008 JMPF R5 #000E - 0x5C140600, // 0009 MOVE R5 R3 - 0x5C180800, // 000A MOVE R6 R4 - 0x881C0501, // 000B GETMBR R7 R2 K1 - 0x5C200200, // 000C MOVE R8 R1 - 0x7C140600, // 000D CALL R5 3 - 0x50140200, // 000E LDBOOL R5 1 0 - 0x80040A00, // 000F RET 1 R5 - 0x50140000, // 0010 LDBOOL R5 0 0 - 0x80040A00, // 0011 RET 1 R5 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: exec_cmd -********************************************************************/ -be_local_closure(Tasmota_exec_cmd, /* name */ - be_nested_proto( - 12, /* nstack */ - 4, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str(_ccmd), - /* K1 */ be_nested_str(json), - /* K2 */ be_nested_str(load), - /* K3 */ be_nested_str(find_key_i), - /* K4 */ be_nested_str(resolvecmnd), - }), - &be_const_str_exec_cmd, - &be_const_str_solidified, - ( &(const binstruction[27]) { /* code */ - 0x88100100, // 0000 GETMBR R4 R0 K0 - 0x78120016, // 0001 JMPF R4 #0019 - 0xA4120200, // 0002 IMPORT R4 K1 - 0x8C140902, // 0003 GETMET R5 R4 K2 - 0x5C1C0600, // 0004 MOVE R7 R3 - 0x7C140400, // 0005 CALL R5 2 - 0x8C180103, // 0006 GETMET R6 R0 K3 - 0x88200100, // 0007 GETMBR R8 R0 K0 - 0x5C240200, // 0008 MOVE R9 R1 - 0x7C180600, // 0009 CALL R6 3 - 0x4C1C0000, // 000A LDNIL R7 - 0x201C0C07, // 000B NE R7 R6 R7 - 0x781E000B, // 000C JMPF R7 #0019 - 0x8C1C0104, // 000D GETMET R7 R0 K4 - 0x5C240C00, // 000E MOVE R9 R6 - 0x7C1C0400, // 000F CALL R7 2 - 0x881C0100, // 0010 GETMBR R7 R0 K0 - 0x941C0E06, // 0011 GETIDX R7 R7 R6 - 0x5C200C00, // 0012 MOVE R8 R6 - 0x5C240400, // 0013 MOVE R9 R2 - 0x5C280600, // 0014 MOVE R10 R3 - 0x5C2C0A00, // 0015 MOVE R11 R5 - 0x7C1C0800, // 0016 CALL R7 4 - 0x501C0200, // 0017 LDBOOL R7 1 0 - 0x80040E00, // 0018 RET 1 R7 - 0x50100000, // 0019 LDBOOL R4 0 0 - 0x80040800, // 001A RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: add_cmd -********************************************************************/ -be_local_closure(Tasmota_add_cmd, /* name */ - be_nested_proto( - 6, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str(check_not_method), - /* K1 */ be_nested_str(_ccmd), - /* K2 */ be_nested_str(function), - /* K3 */ be_nested_str(value_error), - /* K4 */ be_nested_str(the_X20second_X20argument_X20is_X20not_X20a_X20function), + /* K0 */ be_nested_str(_crons), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str(size), + /* K3 */ be_nested_str(id), + /* K4 */ be_nested_str(trig), + /* K5 */ be_const_int(1), }), - &be_const_str_add_cmd, + &be_const_str_next_cron, &be_const_str_solidified, - ( &(const binstruction[18]) { /* code */ - 0x8C0C0100, // 0000 GETMET R3 R0 K0 - 0x5C140400, // 0001 MOVE R5 R2 - 0x7C0C0400, // 0002 CALL R3 2 - 0x880C0101, // 0003 GETMBR R3 R0 K1 - 0x740E0002, // 0004 JMPT R3 #0008 - 0x600C0013, // 0005 GETGBL R3 G19 - 0x7C0C0000, // 0006 CALL R3 0 - 0x90020203, // 0007 SETMBR R0 K1 R3 - 0x600C0004, // 0008 GETGBL R3 G4 - 0x5C100400, // 0009 MOVE R4 R2 - 0x7C0C0200, // 000A CALL R3 1 - 0x1C0C0702, // 000B EQ R3 R3 K2 - 0x780E0002, // 000C JMPF R3 #0010 - 0x880C0101, // 000D GETMBR R3 R0 K1 - 0x980C0202, // 000E SETIDX R3 R1 R2 - 0x70020000, // 000F JMP #0011 - 0xB0060704, // 0010 RAISE 1 K3 K4 - 0x80000000, // 0011 RET 0 + ( &(const binstruction[17]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A000D, // 0001 JMPF R2 #0010 + 0x580C0001, // 0002 LDCONST R3 K1 + 0x8C100502, // 0003 GETMET R4 R2 K2 + 0x7C100200, // 0004 CALL R4 1 + 0x14100604, // 0005 LT R4 R3 R4 + 0x78120008, // 0006 JMPF R4 #0010 + 0x94100403, // 0007 GETIDX R4 R2 R3 + 0x88100903, // 0008 GETMBR R4 R4 K3 + 0x1C100801, // 0009 EQ R4 R4 R1 + 0x78120002, // 000A JMPF R4 #000E + 0x94100403, // 000B GETIDX R4 R2 R3 + 0x88100904, // 000C GETMBR R4 R4 K4 + 0x80040800, // 000D RET 1 R4 + 0x000C0705, // 000E ADD R3 R3 K5 + 0x7001FFF2, // 000F JMP #0003 + 0x80000000, // 0010 RET 0 }) ) ); @@ -2132,11 +2098,11 @@ be_local_closure(Tasmota_add_cmd, /* name */ /******************************************************************** -** Solidified function: find_op +** Solidified function: time_str ********************************************************************/ -be_local_closure(Tasmota_find_op, /* name */ +be_local_closure(Tasmota_time_str, /* name */ be_nested_proto( - 7, /* nstack */ + 11, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2144,46 +2110,32 @@ be_local_closure(Tasmota_find_op, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str(_find_op), - /* K1 */ be_const_int(0), - /* K2 */ be_const_int(1), - /* K3 */ be_const_int(2147483647), + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str(time_dump), + /* K1 */ be_nested_str(_X2504d_X2D_X2502d_X2D_X2502dT_X2502d_X3A_X2502d_X3A_X2502d), + /* K2 */ be_nested_str(year), + /* K3 */ be_nested_str(month), + /* K4 */ be_nested_str(day), + /* K5 */ be_nested_str(hour), + /* K6 */ be_nested_str(min), + /* K7 */ be_nested_str(sec), }), - &be_const_str_find_op, + &be_const_str_time_str, &be_const_str_solidified, - ( &(const binstruction[31]) { /* code */ + ( &(const binstruction[13]) { /* code */ 0x8C080100, // 0000 GETMET R2 R0 K0 0x5C100200, // 0001 MOVE R4 R1 0x7C080400, // 0002 CALL R2 2 - 0x280C0501, // 0003 GE R3 R2 K1 - 0x780E0011, // 0004 JMPF R3 #0017 - 0x540E7FFE, // 0005 LDINT R3 32767 - 0x2C0C0403, // 0006 AND R3 R2 R3 - 0x5412000F, // 0007 LDINT R4 16 - 0x3C100404, // 0008 SHR R4 R2 R4 - 0x60140012, // 0009 GETGBL R5 G18 - 0x7C140000, // 000A CALL R5 0 - 0x04180702, // 000B SUB R6 R3 K2 - 0x401A0206, // 000C CONNECT R6 K1 R6 - 0x94180206, // 000D GETIDX R6 R1 R6 - 0x40180A06, // 000E CONNECT R6 R5 R6 - 0x04180902, // 000F SUB R6 R4 K2 - 0x40180606, // 0010 CONNECT R6 R3 R6 - 0x94180206, // 0011 GETIDX R6 R1 R6 - 0x40180A06, // 0012 CONNECT R6 R5 R6 - 0x40180903, // 0013 CONNECT R6 R4 K3 - 0x94180206, // 0014 GETIDX R6 R1 R6 - 0x40180A06, // 0015 CONNECT R6 R5 R6 - 0x80040A00, // 0016 RET 1 R5 - 0x600C0012, // 0017 GETGBL R3 G18 - 0x7C0C0000, // 0018 CALL R3 0 - 0x40100601, // 0019 CONNECT R4 R3 R1 - 0x4C100000, // 001A LDNIL R4 - 0x40100604, // 001B CONNECT R4 R3 R4 - 0x4C100000, // 001C LDNIL R4 - 0x40100604, // 001D CONNECT R4 R3 R4 - 0x80040600, // 001E RET 1 R3 + 0x600C0018, // 0003 GETGBL R3 G24 + 0x58100001, // 0004 LDCONST R4 K1 + 0x94140502, // 0005 GETIDX R5 R2 K2 + 0x94180503, // 0006 GETIDX R6 R2 K3 + 0x941C0504, // 0007 GETIDX R7 R2 K4 + 0x94200505, // 0008 GETIDX R8 R2 K5 + 0x94240506, // 0009 GETIDX R9 R2 K6 + 0x94280507, // 000A GETIDX R10 R2 K7 + 0x7C0C0E00, // 000B CALL R3 7 + 0x80040600, // 000C RET 1 R3 }) ) ); @@ -2191,53 +2143,85 @@ be_local_closure(Tasmota_find_op, /* name */ /******************************************************************** -** Solidified function: add_fast_loop +** Solidified function: exec_rules ********************************************************************/ -be_local_closure(Tasmota_add_fast_loop, /* name */ +be_local_closure(Tasmota_exec_rules, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 14, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 9]) { /* constants */ - /* K0 */ be_nested_str(check_not_method), - /* K1 */ be_nested_str(_fl), - /* K2 */ be_nested_str(function), - /* K3 */ be_nested_str(value_error), - /* K4 */ be_nested_str(argument_X20must_X20be_X20a_X20function), - /* K5 */ be_nested_str(global), - /* K6 */ be_nested_str(fast_loop_enabled), - /* K7 */ be_const_int(1), - /* K8 */ be_nested_str(push), + ( &(const bvalue[12]) { /* constants */ + /* K0 */ be_nested_str(cmd_res), + /* K1 */ be_nested_str(_rules), + /* K2 */ be_nested_str(json), + /* K3 */ be_nested_str(load), + /* K4 */ be_nested_str(log), + /* K5 */ be_nested_str(BRY_X3A_X20ERROR_X2C_X20bad_X20json_X3A_X20), + /* K6 */ be_const_int(3), + /* K7 */ be_const_int(0), + /* K8 */ be_nested_str(try_rule), + /* K9 */ be_nested_str(trig), + /* K10 */ be_nested_str(f), + /* K11 */ be_const_int(1), }), - &be_const_str_add_fast_loop, + &be_const_str_exec_rules, &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C080400, // 0002 CALL R2 2 - 0x88080101, // 0003 GETMBR R2 R0 K1 - 0x740A0002, // 0004 JMPT R2 #0008 - 0x60080012, // 0005 GETGBL R2 G18 - 0x7C080000, // 0006 CALL R2 0 - 0x90020202, // 0007 SETMBR R0 K1 R2 - 0x60080004, // 0008 GETGBL R2 G4 - 0x5C0C0200, // 0009 MOVE R3 R1 - 0x7C080200, // 000A CALL R2 1 - 0x20080502, // 000B NE R2 R2 K2 - 0x780A0000, // 000C JMPF R2 #000E - 0xB0060704, // 000D RAISE 1 K3 K4 - 0x88080105, // 000E GETMBR R2 R0 K5 - 0x900A0D07, // 000F SETMBR R2 K6 K7 - 0x88080101, // 0010 GETMBR R2 R0 K1 - 0x8C080508, // 0011 GETMET R2 R2 K8 - 0x5C100200, // 0012 MOVE R4 R1 - 0x7C080400, // 0013 CALL R2 2 - 0x80000000, // 0014 RET 0 + ( &(const binstruction[50]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x88100101, // 0001 GETMBR R4 R0 K1 + 0x74120002, // 0002 JMPT R4 #0006 + 0x4C100000, // 0003 LDNIL R4 + 0x20100604, // 0004 NE R4 R3 R4 + 0x78120029, // 0005 JMPF R4 #0030 + 0xA4120400, // 0006 IMPORT R4 K2 + 0x4C140000, // 0007 LDNIL R5 + 0x90020005, // 0008 SETMBR R0 K0 R5 + 0x50140000, // 0009 LDBOOL R5 0 0 + 0x8C180903, // 000A GETMET R6 R4 K3 + 0x5C200200, // 000B MOVE R8 R1 + 0x7C180400, // 000C CALL R6 2 + 0x4C1C0000, // 000D LDNIL R7 + 0x1C1C0C07, // 000E EQ R7 R6 R7 + 0x781E0004, // 000F JMPF R7 #0015 + 0x8C1C0104, // 0010 GETMET R7 R0 K4 + 0x00260A01, // 0011 ADD R9 K5 R1 + 0x58280006, // 0012 LDCONST R10 K6 + 0x7C1C0600, // 0013 CALL R7 3 + 0x5C180200, // 0014 MOVE R6 R1 + 0x780A0014, // 0015 JMPF R2 #002B + 0x881C0101, // 0016 GETMBR R7 R0 K1 + 0x781E0012, // 0017 JMPF R7 #002B + 0x581C0007, // 0018 LDCONST R7 K7 + 0x6020000C, // 0019 GETGBL R8 G12 + 0x88240101, // 001A GETMBR R9 R0 K1 + 0x7C200200, // 001B CALL R8 1 + 0x14200E08, // 001C LT R8 R7 R8 + 0x7822000C, // 001D JMPF R8 #002B + 0x88200101, // 001E GETMBR R8 R0 K1 + 0x94201007, // 001F GETIDX R8 R8 R7 + 0x8C240108, // 0020 GETMET R9 R0 K8 + 0x5C2C0C00, // 0021 MOVE R11 R6 + 0x88301109, // 0022 GETMBR R12 R8 K9 + 0x8834110A, // 0023 GETMBR R13 R8 K10 + 0x7C240800, // 0024 CALL R9 4 + 0x74260001, // 0025 JMPT R9 #0028 + 0x74160000, // 0026 JMPT R5 #0028 + 0x50140001, // 0027 LDBOOL R5 0 1 + 0x50140200, // 0028 LDBOOL R5 1 0 + 0x001C0F0B, // 0029 ADD R7 R7 K11 + 0x7001FFED, // 002A JMP #0019 + 0x4C1C0000, // 002B LDNIL R7 + 0x201C0607, // 002C NE R7 R3 R7 + 0x781E0000, // 002D JMPF R7 #002F + 0x90020006, // 002E SETMBR R0 K0 R6 + 0x80040A00, // 002F RET 1 R5 + 0x50100000, // 0030 LDBOOL R4 0 0 + 0x80040800, // 0031 RET 1 R4 }) ) ); @@ -2270,34 +2254,137 @@ be_local_closure(Tasmota_add_rule, /* name */ }), &be_const_str_add_rule, &be_const_str_solidified, - ( &(const binstruction[27]) { /* code */ + ( &(const binstruction[29]) { /* code */ 0x8C100100, // 0000 GETMET R4 R0 K0 0x5C180400, // 0001 MOVE R6 R2 0x7C100400, // 0002 CALL R4 2 0x88100101, // 0003 GETMBR R4 R0 K1 - 0x74120002, // 0004 JMPT R4 #0008 - 0x60100012, // 0005 GETGBL R4 G18 - 0x7C100000, // 0006 CALL R4 0 - 0x90020204, // 0007 SETMBR R0 K1 R4 - 0x60100004, // 0008 GETGBL R4 G4 - 0x5C140400, // 0009 MOVE R5 R2 - 0x7C100200, // 000A CALL R4 1 - 0x1C100902, // 000B EQ R4 R4 K2 - 0x7812000B, // 000C JMPF R4 #0019 - 0x88100101, // 000D GETMBR R4 R0 K1 - 0x8C100903, // 000E GETMET R4 R4 K3 - 0xB81A0800, // 000F GETNGBL R6 K4 - 0x881C0105, // 0010 GETMBR R7 R0 K5 - 0x8C1C0F06, // 0011 GETMET R7 R7 K6 - 0x5C240200, // 0012 MOVE R9 R1 - 0x7C1C0400, // 0013 CALL R7 2 - 0x5C200400, // 0014 MOVE R8 R2 - 0x5C240600, // 0015 MOVE R9 R3 - 0x7C180600, // 0016 CALL R6 3 - 0x7C100400, // 0017 CALL R4 2 - 0x70020000, // 0018 JMP #001A - 0xB0060F08, // 0019 RAISE 1 K7 K8 - 0x80000000, // 001A RET 0 + 0x4C140000, // 0004 LDNIL R5 + 0x1C100805, // 0005 EQ R4 R4 R5 + 0x78120002, // 0006 JMPF R4 #000A + 0x60100012, // 0007 GETGBL R4 G18 + 0x7C100000, // 0008 CALL R4 0 + 0x90020204, // 0009 SETMBR R0 K1 R4 + 0x60100004, // 000A GETGBL R4 G4 + 0x5C140400, // 000B MOVE R5 R2 + 0x7C100200, // 000C CALL R4 1 + 0x1C100902, // 000D EQ R4 R4 K2 + 0x7812000B, // 000E JMPF R4 #001B + 0x88100101, // 000F GETMBR R4 R0 K1 + 0x8C100903, // 0010 GETMET R4 R4 K3 + 0xB81A0800, // 0011 GETNGBL R6 K4 + 0x881C0105, // 0012 GETMBR R7 R0 K5 + 0x8C1C0F06, // 0013 GETMET R7 R7 K6 + 0x5C240200, // 0014 MOVE R9 R1 + 0x7C1C0400, // 0015 CALL R7 2 + 0x5C200400, // 0016 MOVE R8 R2 + 0x5C240600, // 0017 MOVE R9 R3 + 0x7C180600, // 0018 CALL R6 3 + 0x7C100400, // 0019 CALL R4 2 + 0x70020000, // 001A JMP #001C + 0xB0060F08, // 001B RAISE 1 K7 K8 + 0x80000000, // 001C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: gc +********************************************************************/ +be_local_closure(Tasmota_gc, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str(gc), + /* K1 */ be_nested_str(collect), + /* K2 */ be_nested_str(allocated), + }), + &be_const_str_gc, + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080301, // 0001 GETMET R2 R1 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x7C080200, // 0004 CALL R2 1 + 0x80040400, // 0005 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: urlfetch_cmd +********************************************************************/ +be_local_closure(Tasmota_urlfetch_cmd, /* name */ + be_nested_proto( + 10, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str(string), + /* K1 */ be_nested_str(find), + /* K2 */ be_nested_str(http), + /* K3 */ be_const_int(0), + /* K4 */ be_nested_str(resp_cmnd_str), + /* K5 */ be_nested_str(URL_X20must_X20start_X20with_X20_X27http_X28s_X29_X27), + /* K6 */ be_nested_str(urlfetch), + /* K7 */ be_nested_str(resp_cmnd_failed), + /* K8 */ be_nested_str(tasmota), + /* K9 */ be_nested_str(resp_cmnd_done), + }), + &be_const_str_urlfetch_cmd, + &be_const_str_solidified, + ( &(const binstruction[34]) { /* code */ + 0xA4160000, // 0000 IMPORT R5 K0 + 0x8C180B01, // 0001 GETMET R6 R5 K1 + 0x5C200600, // 0002 MOVE R8 R3 + 0x58240002, // 0003 LDCONST R9 K2 + 0x7C180600, // 0004 CALL R6 3 + 0x20180D03, // 0005 NE R6 R6 K3 + 0x781A0003, // 0006 JMPF R6 #000B + 0x8C180104, // 0007 GETMET R6 R0 K4 + 0x58200005, // 0008 LDCONST R8 K5 + 0x7C180400, // 0009 CALL R6 2 + 0x80000C00, // 000A RET 0 + 0xA802000A, // 000B EXBLK 0 #0017 + 0x8C180106, // 000C GETMET R6 R0 K6 + 0x5C200600, // 000D MOVE R8 R3 + 0x7C180400, // 000E CALL R6 2 + 0x141C0D03, // 000F LT R7 R6 K3 + 0x781E0003, // 0010 JMPF R7 #0015 + 0x8C1C0107, // 0011 GETMET R7 R0 K7 + 0x7C1C0200, // 0012 CALL R7 1 + 0xA8040001, // 0013 EXBLK 1 1 + 0x80000E00, // 0014 RET 0 + 0xA8040001, // 0015 EXBLK 1 1 + 0x70020006, // 0016 JMP #001E + 0xAC180002, // 0017 CATCH R6 0 2 + 0x70020003, // 0018 JMP #001D + 0x8C200107, // 0019 GETMET R8 R0 K7 + 0x7C200200, // 001A CALL R8 1 + 0x80001000, // 001B RET 0 + 0x70020000, // 001C JMP #001E + 0xB0080000, // 001D RAISE 2 R0 R0 + 0xB81A1000, // 001E GETNGBL R6 K8 + 0x8C180D09, // 001F GETMET R6 R6 K9 + 0x7C180200, // 0020 CALL R6 1 + 0x80000000, // 0021 RET 0 }) ) ); @@ -2305,11 +2392,11 @@ be_local_closure(Tasmota_add_rule, /* name */ /******************************************************************** -** Solidified function: gen_cb +** Solidified function: add_fast_loop ********************************************************************/ -be_local_closure(Tasmota_gen_cb, /* name */ +be_local_closure(Tasmota_add_fast_loop, /* name */ be_nested_proto( - 6, /* nstack */ + 5, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2317,178 +2404,43 @@ be_local_closure(Tasmota_gen_cb, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str(cb), - /* K1 */ be_nested_str(gen_cb), - }), - &be_const_str_gen_cb, - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x8C0C0501, // 0001 GETMET R3 R2 K1 - 0x5C140200, // 0002 MOVE R5 R1 - 0x7C0C0400, // 0003 CALL R3 2 - 0x80040600, // 0004 RET 1 R3 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: event -********************************************************************/ -be_local_closure(Tasmota_event, /* name */ - be_nested_proto( - 21, /* nstack */ - 6, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[27]) { /* constants */ - /* K0 */ be_nested_str(introspect), - /* K1 */ be_nested_str(string), - /* K2 */ be_nested_str(every_50ms), - /* K3 */ be_nested_str(run_deferred), - /* K4 */ be_nested_str(every_250ms), - /* K5 */ be_nested_str(run_cron), - /* K6 */ be_nested_str(mqtt_data), - /* K7 */ be_nested_str(cmd), - /* K8 */ be_nested_str(exec_cmd), - /* K9 */ be_nested_str(tele), - /* K10 */ be_nested_str(exec_tele), - /* K11 */ be_nested_str(rule), - /* K12 */ be_nested_str(exec_rules), - /* K13 */ be_nested_str(gc), - /* K14 */ be_nested_str(_drivers), - /* K15 */ be_const_int(0), - /* K16 */ be_nested_str(get), - /* K17 */ be_nested_str(function), - /* K18 */ be_nested_str(format), - /* K19 */ be_nested_str(BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s), - /* K20 */ be_nested_str(_debug_present), - /* K21 */ be_nested_str(debug), - /* K22 */ be_nested_str(traceback), - /* K23 */ be_const_int(1), - /* K24 */ be_nested_str(save_before_restart), - /* K25 */ be_nested_str(persist), - /* K26 */ be_nested_str(save), + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str(check_not_method), + /* K1 */ be_nested_str(_fl), + /* K2 */ be_nested_str(function), + /* K3 */ be_nested_str(value_error), + /* K4 */ be_nested_str(argument_X20must_X20be_X20a_X20function), + /* K5 */ be_nested_str(global), + /* K6 */ be_nested_str(fast_loop_enabled), + /* K7 */ be_const_int(1), + /* K8 */ be_nested_str(push), }), - &be_const_str_event, + &be_const_str_add_fast_loop, &be_const_str_solidified, - ( &(const binstruction[109]) { /* code */ - 0xA41A0000, // 0000 IMPORT R6 K0 - 0xA41E0200, // 0001 IMPORT R7 K1 - 0x1C200302, // 0002 EQ R8 R1 K2 - 0x78220001, // 0003 JMPF R8 #0006 - 0x8C200103, // 0004 GETMET R8 R0 K3 - 0x7C200200, // 0005 CALL R8 1 - 0x1C200304, // 0006 EQ R8 R1 K4 - 0x78220001, // 0007 JMPF R8 #000A - 0x8C200105, // 0008 GETMET R8 R0 K5 - 0x7C200200, // 0009 CALL R8 1 - 0x50200000, // 000A LDBOOL R8 0 0 - 0x50240000, // 000B LDBOOL R9 0 0 - 0x1C280306, // 000C EQ R10 R1 K6 - 0x782A0000, // 000D JMPF R10 #000F - 0x50240200, // 000E LDBOOL R9 1 0 - 0x1C280307, // 000F EQ R10 R1 K7 - 0x782A0006, // 0010 JMPF R10 #0018 - 0x8C280108, // 0011 GETMET R10 R0 K8 - 0x5C300400, // 0012 MOVE R12 R2 - 0x5C340600, // 0013 MOVE R13 R3 - 0x5C380800, // 0014 MOVE R14 R4 - 0x7C280800, // 0015 CALL R10 4 - 0x80041400, // 0016 RET 1 R10 - 0x7002004E, // 0017 JMP #0067 - 0x1C280309, // 0018 EQ R10 R1 K9 - 0x782A0004, // 0019 JMPF R10 #001F - 0x8C28010A, // 001A GETMET R10 R0 K10 - 0x5C300800, // 001B MOVE R12 R4 - 0x7C280400, // 001C CALL R10 2 - 0x80041400, // 001D RET 1 R10 - 0x70020047, // 001E JMP #0067 - 0x1C28030B, // 001F EQ R10 R1 K11 - 0x782A0007, // 0020 JMPF R10 #0029 - 0x8C28010C, // 0021 GETMET R10 R0 K12 - 0x5C300800, // 0022 MOVE R12 R4 - 0x60340017, // 0023 GETGBL R13 G23 - 0x5C380600, // 0024 MOVE R14 R3 - 0x7C340200, // 0025 CALL R13 1 - 0x7C280600, // 0026 CALL R10 3 - 0x80041400, // 0027 RET 1 R10 - 0x7002003D, // 0028 JMP #0067 - 0x1C28030D, // 0029 EQ R10 R1 K13 - 0x782A0003, // 002A JMPF R10 #002F - 0x8C28010D, // 002B GETMET R10 R0 K13 - 0x7C280200, // 002C CALL R10 1 - 0x80041400, // 002D RET 1 R10 - 0x70020037, // 002E JMP #0067 - 0x8828010E, // 002F GETMBR R10 R0 K14 - 0x782A0035, // 0030 JMPF R10 #0067 - 0x5828000F, // 0031 LDCONST R10 K15 - 0x602C000C, // 0032 GETGBL R11 G12 - 0x8830010E, // 0033 GETMBR R12 R0 K14 - 0x7C2C0200, // 0034 CALL R11 1 - 0x142C140B, // 0035 LT R11 R10 R11 - 0x782E002F, // 0036 JMPF R11 #0067 - 0x882C010E, // 0037 GETMBR R11 R0 K14 - 0x942C160A, // 0038 GETIDX R11 R11 R10 - 0x8C300D10, // 0039 GETMET R12 R6 K16 - 0x5C381600, // 003A MOVE R14 R11 - 0x5C3C0200, // 003B MOVE R15 R1 - 0x7C300600, // 003C CALL R12 3 - 0x60340004, // 003D GETGBL R13 G4 - 0x5C381800, // 003E MOVE R14 R12 - 0x7C340200, // 003F CALL R13 1 - 0x1C341B11, // 0040 EQ R13 R13 K17 - 0x78360022, // 0041 JMPF R13 #0065 - 0xA8020011, // 0042 EXBLK 0 #0055 - 0x5C341800, // 0043 MOVE R13 R12 - 0x5C381600, // 0044 MOVE R14 R11 - 0x5C3C0400, // 0045 MOVE R15 R2 - 0x5C400600, // 0046 MOVE R16 R3 - 0x5C440800, // 0047 MOVE R17 R4 - 0x5C480A00, // 0048 MOVE R18 R5 - 0x7C340A00, // 0049 CALL R13 5 - 0x74360001, // 004A JMPT R13 #004D - 0x74220000, // 004B JMPT R8 #004D - 0x50200001, // 004C LDBOOL R8 0 1 - 0x50200200, // 004D LDBOOL R8 1 0 - 0x78220003, // 004E JMPF R8 #0053 - 0x5C341200, // 004F MOVE R13 R9 - 0x74360001, // 0050 JMPT R13 #0053 - 0xA8040001, // 0051 EXBLK 1 1 - 0x70020013, // 0052 JMP #0067 - 0xA8040001, // 0053 EXBLK 1 1 - 0x7002000F, // 0054 JMP #0065 - 0xAC340002, // 0055 CATCH R13 0 2 - 0x7002000C, // 0056 JMP #0064 - 0x603C0001, // 0057 GETGBL R15 G1 - 0x8C400F12, // 0058 GETMET R16 R7 K18 - 0x58480013, // 0059 LDCONST R18 K19 - 0x5C4C1A00, // 005A MOVE R19 R13 - 0x5C501C00, // 005B MOVE R20 R14 - 0x7C400800, // 005C CALL R16 4 - 0x7C3C0200, // 005D CALL R15 1 - 0x883C0114, // 005E GETMBR R15 R0 K20 - 0x783E0002, // 005F JMPF R15 #0063 - 0xA43E2A00, // 0060 IMPORT R15 K21 - 0x8C401F16, // 0061 GETMET R16 R15 K22 - 0x7C400200, // 0062 CALL R16 1 - 0x70020000, // 0063 JMP #0065 - 0xB0080000, // 0064 RAISE 2 R0 R0 - 0x00281517, // 0065 ADD R10 R10 K23 - 0x7001FFCA, // 0066 JMP #0032 - 0x1C280318, // 0067 EQ R10 R1 K24 - 0x782A0002, // 0068 JMPF R10 #006C - 0xA42A3200, // 0069 IMPORT R10 K25 - 0x8C2C151A, // 006A GETMET R11 R10 K26 - 0x7C2C0200, // 006B CALL R11 1 - 0x80041000, // 006C RET 1 R8 + ( &(const binstruction[23]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0x88080101, // 0003 GETMBR R2 R0 K1 + 0x4C0C0000, // 0004 LDNIL R3 + 0x1C080403, // 0005 EQ R2 R2 R3 + 0x780A0002, // 0006 JMPF R2 #000A + 0x60080012, // 0007 GETGBL R2 G18 + 0x7C080000, // 0008 CALL R2 0 + 0x90020202, // 0009 SETMBR R0 K1 R2 + 0x60080004, // 000A GETGBL R2 G4 + 0x5C0C0200, // 000B MOVE R3 R1 + 0x7C080200, // 000C CALL R2 1 + 0x20080502, // 000D NE R2 R2 K2 + 0x780A0000, // 000E JMPF R2 #0010 + 0xB0060704, // 000F RAISE 1 K3 K4 + 0x88080105, // 0010 GETMBR R2 R0 K5 + 0x900A0D07, // 0011 SETMBR R2 K6 K7 + 0x88080101, // 0012 GETMBR R2 R0 K1 + 0x8C080508, // 0013 GETMET R2 R2 K8 + 0x5C100200, // 0014 MOVE R4 R1 + 0x7C080400, // 0015 CALL R2 2 + 0x80000000, // 0016 RET 0 }) ) ); @@ -2496,11 +2448,11 @@ be_local_closure(Tasmota_event, /* name */ /******************************************************************** -** Solidified function: fast_loop +** Solidified function: run_deferred ********************************************************************/ -be_local_closure(Tasmota_fast_loop, /* name */ +be_local_closure(Tasmota_run_deferred, /* name */ be_nested_proto( - 5, /* nstack */ + 7, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2508,29 +2460,44 @@ be_local_closure(Tasmota_fast_loop, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str(_fl), + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str(_timers), /* K1 */ be_const_int(0), - /* K2 */ be_const_int(1), + /* K2 */ be_nested_str(size), + /* K3 */ be_nested_str(time_reached), + /* K4 */ be_nested_str(trig), + /* K5 */ be_nested_str(f), + /* K6 */ be_nested_str(remove), + /* K7 */ be_const_int(1), }), - &be_const_str_fast_loop, + &be_const_str_run_deferred, &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ + ( &(const binstruction[25]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x5C080200, // 0001 MOVE R2 R1 - 0x740A0000, // 0002 JMPT R2 #0004 - 0x80000400, // 0003 RET 0 - 0x58080001, // 0004 LDCONST R2 K1 - 0x600C000C, // 0005 GETGBL R3 G12 - 0x5C100200, // 0006 MOVE R4 R1 - 0x7C0C0200, // 0007 CALL R3 1 - 0x14100403, // 0008 LT R4 R2 R3 - 0x78120003, // 0009 JMPF R4 #000E - 0x94100202, // 000A GETIDX R4 R1 R2 - 0x7C100000, // 000B CALL R4 0 - 0x00080502, // 000C ADD R2 R2 K2 - 0x7001FFF9, // 000D JMP #0008 - 0x80000000, // 000E RET 0 + 0x78060015, // 0001 JMPF R1 #0018 + 0x58040001, // 0002 LDCONST R1 K1 + 0x88080100, // 0003 GETMBR R2 R0 K0 + 0x8C080502, // 0004 GETMET R2 R2 K2 + 0x7C080200, // 0005 CALL R2 1 + 0x14080202, // 0006 LT R2 R1 R2 + 0x780A000F, // 0007 JMPF R2 #0018 + 0x88080100, // 0008 GETMBR R2 R0 K0 + 0x94080401, // 0009 GETIDX R2 R2 R1 + 0x8C0C0103, // 000A GETMET R3 R0 K3 + 0x88140504, // 000B GETMBR R5 R2 K4 + 0x7C0C0400, // 000C CALL R3 2 + 0x780E0007, // 000D JMPF R3 #0016 + 0x880C0505, // 000E GETMBR R3 R2 K5 + 0x88100100, // 000F GETMBR R4 R0 K0 + 0x8C100906, // 0010 GETMET R4 R4 K6 + 0x5C180200, // 0011 MOVE R6 R1 + 0x7C100400, // 0012 CALL R4 2 + 0x5C100600, // 0013 MOVE R4 R3 + 0x7C100000, // 0014 CALL R4 0 + 0x70020000, // 0015 JMP #0017 + 0x00040307, // 0016 ADD R1 R1 K7 + 0x7001FFEA, // 0017 JMP #0003 + 0x80000000, // 0018 RET 0 }) ) ); @@ -2538,12 +2505,12 @@ be_local_closure(Tasmota_fast_loop, /* name */ /******************************************************************** -** Solidified function: remove_cron +** Solidified function: hs2rgb ********************************************************************/ -be_local_closure(Tasmota_remove_cron, /* name */ +be_local_closure(Tasmota_hs2rgb, /* name */ be_nested_proto( - 7, /* nstack */ - 2, /* argc */ + 17, /* nstack */ + 3, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -2551,34 +2518,84 @@ be_local_closure(Tasmota_remove_cron, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str(_crons), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str(size), - /* K3 */ be_nested_str(id), - /* K4 */ be_nested_str(remove), - /* K5 */ be_const_int(1), + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str(tasmota), + /* K2 */ be_nested_str(scale_uint), + /* K3 */ be_const_int(1), + /* K4 */ be_const_int(2), + /* K5 */ be_const_int(3), }), - &be_const_str_remove_cron, + &be_const_str_hs2rgb, &be_const_str_solidified, - ( &(const binstruction[18]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x780A000E, // 0001 JMPF R2 #0011 - 0x580C0001, // 0002 LDCONST R3 K1 - 0x8C100502, // 0003 GETMET R4 R2 K2 - 0x7C100200, // 0004 CALL R4 1 - 0x14100604, // 0005 LT R4 R3 R4 - 0x78120009, // 0006 JMPF R4 #0011 - 0x94100403, // 0007 GETIDX R4 R2 R3 - 0x88100903, // 0008 GETMBR R4 R4 K3 - 0x1C100801, // 0009 EQ R4 R4 R1 - 0x78120003, // 000A JMPF R4 #000F - 0x8C100504, // 000B GETMET R4 R2 K4 - 0x5C180600, // 000C MOVE R6 R3 - 0x7C100400, // 000D CALL R4 2 - 0x70020000, // 000E JMP #0010 - 0x000C0705, // 000F ADD R3 R3 K5 - 0x7001FFF1, // 0010 JMP #0003 - 0x80000000, // 0011 RET 0 + ( &(const binstruction[68]) { /* code */ + 0x4C0C0000, // 0000 LDNIL R3 + 0x1C0C0403, // 0001 EQ R3 R2 R3 + 0x780E0000, // 0002 JMPF R3 #0004 + 0x540A00FE, // 0003 LDINT R2 255 + 0x540E00FE, // 0004 LDINT R3 255 + 0x541200FE, // 0005 LDINT R4 255 + 0x541600FE, // 0006 LDINT R5 255 + 0x541A0167, // 0007 LDINT R6 360 + 0x10040206, // 0008 MOD R1 R1 R6 + 0x24180500, // 0009 GT R6 R2 K0 + 0x781A0031, // 000A JMPF R6 #003D + 0x541A003B, // 000B LDINT R6 60 + 0x0C180206, // 000C DIV R6 R1 R6 + 0x541E003B, // 000D LDINT R7 60 + 0x101C0207, // 000E MOD R7 R1 R7 + 0x542200FE, // 000F LDINT R8 255 + 0x04201002, // 0010 SUB R8 R8 R2 + 0xB8260200, // 0011 GETNGBL R9 K1 + 0x8C241302, // 0012 GETMET R9 R9 K2 + 0x5C2C0E00, // 0013 MOVE R11 R7 + 0x58300000, // 0014 LDCONST R12 K0 + 0x5436003B, // 0015 LDINT R13 60 + 0x543A00FE, // 0016 LDINT R14 255 + 0x5C3C1000, // 0017 MOVE R15 R8 + 0x7C240C00, // 0018 CALL R9 6 + 0xB82A0200, // 0019 GETNGBL R10 K1 + 0x8C281502, // 001A GETMET R10 R10 K2 + 0x5C300E00, // 001B MOVE R12 R7 + 0x58340000, // 001C LDCONST R13 K0 + 0x543A003B, // 001D LDINT R14 60 + 0x5C3C1000, // 001E MOVE R15 R8 + 0x544200FE, // 001F LDINT R16 255 + 0x7C280C00, // 0020 CALL R10 6 + 0x1C2C0D00, // 0021 EQ R11 R6 K0 + 0x782E0002, // 0022 JMPF R11 #0026 + 0x5C141400, // 0023 MOVE R5 R10 + 0x5C101000, // 0024 MOVE R4 R8 + 0x70020016, // 0025 JMP #003D + 0x1C2C0D03, // 0026 EQ R11 R6 K3 + 0x782E0002, // 0027 JMPF R11 #002B + 0x5C0C1200, // 0028 MOVE R3 R9 + 0x5C101000, // 0029 MOVE R4 R8 + 0x70020011, // 002A JMP #003D + 0x1C2C0D04, // 002B EQ R11 R6 K4 + 0x782E0002, // 002C JMPF R11 #0030 + 0x5C0C1000, // 002D MOVE R3 R8 + 0x5C101400, // 002E MOVE R4 R10 + 0x7002000C, // 002F JMP #003D + 0x1C2C0D05, // 0030 EQ R11 R6 K5 + 0x782E0002, // 0031 JMPF R11 #0035 + 0x5C0C1000, // 0032 MOVE R3 R8 + 0x5C141200, // 0033 MOVE R5 R9 + 0x70020007, // 0034 JMP #003D + 0x542E0003, // 0035 LDINT R11 4 + 0x1C2C0C0B, // 0036 EQ R11 R6 R11 + 0x782E0002, // 0037 JMPF R11 #003B + 0x5C0C1400, // 0038 MOVE R3 R10 + 0x5C141000, // 0039 MOVE R5 R8 + 0x70020001, // 003A JMP #003D + 0x5C141000, // 003B MOVE R5 R8 + 0x5C101200, // 003C MOVE R4 R9 + 0x541A000F, // 003D LDINT R6 16 + 0x38180606, // 003E SHL R6 R3 R6 + 0x541E0007, // 003F LDINT R7 8 + 0x381C0A07, // 0040 SHL R7 R5 R7 + 0x30180C07, // 0041 OR R6 R6 R7 + 0x30180C04, // 0042 OR R6 R6 R4 + 0x80040C00, // 0043 RET 1 R6 }) ) ); @@ -2591,57 +2608,58 @@ be_local_closure(Tasmota_remove_cron, /* name */ be_local_class(Tasmota, 13, NULL, - be_nested_map(49, + be_nested_map(50, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key(exec_rules, 45), be_const_closure(Tasmota_exec_rules_closure) }, - { be_const_key(cmd, 30), be_const_closure(Tasmota_cmd_closure) }, - { be_const_key(remove_cron, -1), be_const_closure(Tasmota_remove_cron_closure) }, - { be_const_key(remove_rule, 23), be_const_closure(Tasmota_remove_rule_closure) }, + { be_const_key(hs2rgb, 34), be_const_closure(Tasmota_hs2rgb_closure) }, + { be_const_key(gen_cb, 22), be_const_closure(Tasmota_gen_cb_closure) }, + { be_const_key(fast_loop, 44), be_const_closure(Tasmota_fast_loop_closure) }, + { be_const_key(remove_fast_loop, -1), be_const_closure(Tasmota_remove_fast_loop_closure) }, + { be_const_key(global, -1), be_const_var(9) }, + { be_const_key(try_rule, 17), be_const_closure(Tasmota_try_rule_closure) }, + { be_const_key(wd, -1), be_const_var(11) }, + { be_const_key(check_not_method, -1), be_const_closure(Tasmota_check_not_method_closure) }, { be_const_key(run_deferred, -1), be_const_closure(Tasmota_run_deferred_closure) }, - { be_const_key(find_key_i, 22), be_const_closure(Tasmota_find_key_i_closure) }, - { be_const_key(remove_timer, -1), be_const_closure(Tasmota_remove_timer_closure) }, - { be_const_key(_crons, -1), be_const_var(3) }, - { be_const_key(gen_cb, -1), be_const_closure(Tasmota_gen_cb_closure) }, - { be_const_key(add_cron, -1), be_const_closure(Tasmota_add_cron_closure) }, - { be_const_key(_rules, -1), be_const_var(1) }, - { be_const_key(_drivers, 4), be_const_var(5) }, - { be_const_key(wire1, -1), be_const_var(6) }, - { be_const_key(run_cron, 7), be_const_closure(Tasmota_run_cron_closure) }, - { be_const_key(wire_scan, 9), be_const_closure(Tasmota_wire_scan_closure) }, - { be_const_key(add_rule, -1), be_const_closure(Tasmota_add_rule_closure) }, - { be_const_key(_fl, 36), be_const_var(0) }, - { be_const_key(get_light, -1), be_const_closure(Tasmota_get_light_closure) }, - { be_const_key(find_op, -1), be_const_closure(Tasmota_find_op_closure) }, - { be_const_key(init, -1), be_const_closure(Tasmota_init_closure) }, - { be_const_key(_ccmd, -1), be_const_var(4) }, - { be_const_key(set_timer, -1), be_const_closure(Tasmota_set_timer_closure) }, - { be_const_key(urlfetch, -1), be_const_closure(Tasmota_urlfetch_closure) }, { be_const_key(exec_cmd, -1), be_const_closure(Tasmota_exec_cmd_closure) }, + { be_const_key(urlfetch, -1), be_const_closure(Tasmota_urlfetch_closure) }, + { be_const_key(urlfetch_cmd, -1), be_const_closure(Tasmota_urlfetch_cmd_closure) }, + { be_const_key(remove_cron, 24), be_const_closure(Tasmota_remove_cron_closure) }, + { be_const_key(find_list_i, 23), be_const_closure(Tasmota_find_list_i_closure) }, { be_const_key(gc, -1), be_const_closure(Tasmota_gc_closure) }, - { be_const_key(remove_fast_loop, 17), be_const_closure(Tasmota_remove_fast_loop_closure) }, - { be_const_key(remove_cmd, -1), be_const_closure(Tasmota_remove_cmd_closure) }, - { be_const_key(add_driver, 18), be_const_closure(Tasmota_add_driver_closure) }, - { be_const_key(settings, 41), be_const_var(10) }, - { be_const_key(wire2, -1), be_const_var(7) }, + { be_const_key(remove_timer, -1), be_const_closure(Tasmota_remove_timer_closure) }, + { be_const_key(_timers, -1), be_const_var(2) }, + { be_const_key(init, 48), be_const_closure(Tasmota_init_closure) }, { be_const_key(remove_driver, -1), be_const_closure(Tasmota_remove_driver_closure) }, - { be_const_key(check_not_method, 29), be_const_closure(Tasmota_check_not_method_closure) }, - { be_const_key(set_light, 37), be_const_closure(Tasmota_set_light_closure) }, - { be_const_key(cmd_res, -1), be_const_var(8) }, - { be_const_key(wd, 8), be_const_var(11) }, - { be_const_key(urlfetch_cmd, -1), be_const_closure(Tasmota_urlfetch_cmd_closure) }, - { be_const_key(global, 39), be_const_var(9) }, - { be_const_key(time_str, -1), be_const_closure(Tasmota_time_str_closure) }, - { be_const_key(try_rule, -1), be_const_closure(Tasmota_try_rule_closure) }, + { be_const_key(wire1, -1), be_const_var(6) }, + { be_const_key(_fl, -1), be_const_var(0) }, + { be_const_key(add_driver, 14), be_const_closure(Tasmota_add_driver_closure) }, { be_const_key(exec_tele, -1), be_const_closure(Tasmota_exec_tele_closure) }, - { be_const_key(add_cmd, -1), be_const_closure(Tasmota_add_cmd_closure) }, - { be_const_key(load, -1), be_const_closure(Tasmota_load_closure) }, - { be_const_key(add_fast_loop, -1), be_const_closure(Tasmota_add_fast_loop_closure) }, - { be_const_key(next_cron, 15), be_const_closure(Tasmota_next_cron_closure) }, + { be_const_key(_ccmd, -1), be_const_var(4) }, + { be_const_key(time_str, 36), be_const_closure(Tasmota_time_str_closure) }, { be_const_key(_debug_present, -1), be_const_var(12) }, - { be_const_key(_timers, -1), be_const_var(2) }, - { be_const_key(event, -1), be_const_closure(Tasmota_event_closure) }, - { be_const_key(fast_loop, -1), be_const_closure(Tasmota_fast_loop_closure) }, - { be_const_key(hs2rgb, 2), be_const_closure(Tasmota_hs2rgb_closure) }, + { be_const_key(find_key_i, 31), be_const_closure(Tasmota_find_key_i_closure) }, + { be_const_key(add_cron, -1), be_const_closure(Tasmota_add_cron_closure) }, + { be_const_key(remove_rule, 6), be_const_closure(Tasmota_remove_rule_closure) }, + { be_const_key(add_cmd, 39), be_const_closure(Tasmota_add_cmd_closure) }, + { be_const_key(wire_scan, -1), be_const_closure(Tasmota_wire_scan_closure) }, + { be_const_key(get_light, 40), be_const_closure(Tasmota_get_light_closure) }, + { be_const_key(cmd, 9), be_const_closure(Tasmota_cmd_closure) }, + { be_const_key(set_timer, 11), be_const_closure(Tasmota_set_timer_closure) }, + { be_const_key(load, 32), be_const_closure(Tasmota_load_closure) }, + { be_const_key(_drivers, -1), be_const_var(5) }, + { be_const_key(cmd_res, -1), be_const_var(8) }, + { be_const_key(next_cron, -1), be_const_closure(Tasmota_next_cron_closure) }, + { be_const_key(wire2, -1), be_const_var(7) }, + { be_const_key(_crons, -1), be_const_var(3) }, + { be_const_key(find_op, 41), be_const_closure(Tasmota_find_op_closure) }, + { be_const_key(settings, -1), be_const_var(10) }, + { be_const_key(exec_rules, 20), be_const_closure(Tasmota_exec_rules_closure) }, + { be_const_key(add_rule, -1), be_const_closure(Tasmota_add_rule_closure) }, + { be_const_key(remove_cmd, 45), be_const_closure(Tasmota_remove_cmd_closure) }, + { be_const_key(set_light, -1), be_const_closure(Tasmota_set_light_closure) }, + { be_const_key(add_fast_loop, 8), be_const_closure(Tasmota_add_fast_loop_closure) }, + { be_const_key(_rules, -1), be_const_var(1) }, + { be_const_key(run_cron, 47), be_const_closure(Tasmota_run_cron_closure) }, + { be_const_key(event, 0), be_const_closure(Tasmota_event_closure) }, })), (bstring*) &be_const_str_Tasmota ); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_trigger_class.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_trigger_class.h index 5a42d66bfe5b..8373c3722a53 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_trigger_class.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_trigger_class.h @@ -44,7 +44,7 @@ be_local_closure(Trigger_init, /* name */ ********************************************************************/ be_local_closure(Trigger_tostring, /* name */ be_nested_proto( - 10, /* nstack */ + 8, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -52,36 +52,33 @@ be_local_closure(Trigger_tostring, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(format), - /* K2 */ be_nested_str(_X3Cinstance_X3A_X20_X25s_X28_X25s_X2C_X20_X25s_X2C_X20_X25s_X29), - /* K3 */ be_nested_str(trig), - /* K4 */ be_nested_str(f), - /* K5 */ be_nested_str(id), + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str(_X3Cinstance_X3A_X20_X25s_X28_X25s_X2C_X20_X25s_X2C_X20_X25s_X29), + /* K1 */ be_nested_str(trig), + /* K2 */ be_nested_str(f), + /* K3 */ be_nested_str(id), }), &be_const_str_tostring, &be_const_str_solidified, - ( &(const binstruction[19]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x58100002, // 0002 LDCONST R4 K2 - 0x60140008, // 0003 GETGBL R5 G8 - 0x60180006, // 0004 GETGBL R6 G6 - 0x5C1C0000, // 0005 MOVE R7 R0 - 0x7C180200, // 0006 CALL R6 1 - 0x7C140200, // 0007 CALL R5 1 - 0x60180008, // 0008 GETGBL R6 G8 - 0x881C0103, // 0009 GETMBR R7 R0 K3 - 0x7C180200, // 000A CALL R6 1 - 0x601C0008, // 000B GETGBL R7 G8 - 0x88200104, // 000C GETMBR R8 R0 K4 - 0x7C1C0200, // 000D CALL R7 1 - 0x60200008, // 000E GETGBL R8 G8 - 0x88240105, // 000F GETMBR R9 R0 K5 - 0x7C200200, // 0010 CALL R8 1 - 0x7C080C00, // 0011 CALL R2 6 - 0x80040400, // 0012 RET 1 R2 + ( &(const binstruction[18]) { /* code */ + 0x60040018, // 0000 GETGBL R1 G24 + 0x58080000, // 0001 LDCONST R2 K0 + 0x600C0008, // 0002 GETGBL R3 G8 + 0x60100006, // 0003 GETGBL R4 G6 + 0x5C140000, // 0004 MOVE R5 R0 + 0x7C100200, // 0005 CALL R4 1 + 0x7C0C0200, // 0006 CALL R3 1 + 0x60100008, // 0007 GETGBL R4 G8 + 0x88140101, // 0008 GETMBR R5 R0 K1 + 0x7C100200, // 0009 CALL R4 1 + 0x60140008, // 000A GETGBL R5 G8 + 0x88180102, // 000B GETMBR R6 R0 K2 + 0x7C140200, // 000C CALL R5 1 + 0x60180008, // 000D GETGBL R6 G8 + 0x881C0103, // 000E GETMBR R7 R0 K3 + 0x7C180200, // 000F CALL R6 1 + 0x7C040A00, // 0010 CALL R1 5 + 0x80040200, // 0011 RET 1 R1 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_uuid.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_uuid.h index 80438461279a..b02da5c7c96e 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_uuid.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_uuid.h @@ -9,7 +9,7 @@ ********************************************************************/ be_local_closure(uuid__anonymous_, /* name */ be_nested_proto( - 12, /* nstack */ + 10, /* nstack */ 0, /* argc */ 0, /* varg */ 0, /* has upvals */ @@ -17,46 +17,43 @@ be_local_closure(uuid__anonymous_, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(math), - /* K2 */ be_nested_str(format), - /* K3 */ be_nested_str(_X2508x_X2D_X2504x_X2D_X2504x_X2D_X2504x_X2D_X2504x_X2508x), - /* K4 */ be_nested_str(rand), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str(math), + /* K1 */ be_nested_str(_X2508x_X2D_X2504x_X2D_X2504x_X2D_X2504x_X2D_X2504x_X2508x), + /* K2 */ be_nested_str(rand), }), &be_const_str__anonymous_, &be_const_str_solidified, - ( &(const binstruction[30]) { /* code */ + ( &(const binstruction[29]) { /* code */ 0xA4020000, // 0000 IMPORT R0 K0 - 0xA4060200, // 0001 IMPORT R1 K1 - 0x8C080102, // 0002 GETMET R2 R0 K2 - 0x58100003, // 0003 LDCONST R4 K3 - 0x8C140304, // 0004 GETMET R5 R1 K4 - 0x7C140200, // 0005 CALL R5 1 - 0x8C180304, // 0006 GETMET R6 R1 K4 - 0x7C180200, // 0007 CALL R6 1 - 0x541EFFFE, // 0008 LDINT R7 65535 - 0x2C180C07, // 0009 AND R6 R6 R7 - 0x8C1C0304, // 000A GETMET R7 R1 K4 - 0x7C1C0200, // 000B CALL R7 1 - 0x54220FFE, // 000C LDINT R8 4095 - 0x2C1C0E08, // 000D AND R7 R7 R8 - 0x54223FFF, // 000E LDINT R8 16384 - 0x301C0E08, // 000F OR R7 R7 R8 - 0x8C200304, // 0010 GETMET R8 R1 K4 - 0x7C200200, // 0011 CALL R8 1 - 0x54263FFE, // 0012 LDINT R9 16383 - 0x2C201009, // 0013 AND R8 R8 R9 - 0x54267FFF, // 0014 LDINT R9 32768 - 0x30201009, // 0015 OR R8 R8 R9 - 0x8C240304, // 0016 GETMET R9 R1 K4 - 0x7C240200, // 0017 CALL R9 1 - 0x542AFFFE, // 0018 LDINT R10 65535 - 0x2C24120A, // 0019 AND R9 R9 R10 - 0x8C280304, // 001A GETMET R10 R1 K4 - 0x7C280200, // 001B CALL R10 1 - 0x7C081000, // 001C CALL R2 8 - 0x80040400, // 001D RET 1 R2 + 0x60040018, // 0001 GETGBL R1 G24 + 0x58080001, // 0002 LDCONST R2 K1 + 0x8C0C0102, // 0003 GETMET R3 R0 K2 + 0x7C0C0200, // 0004 CALL R3 1 + 0x8C100102, // 0005 GETMET R4 R0 K2 + 0x7C100200, // 0006 CALL R4 1 + 0x5416FFFE, // 0007 LDINT R5 65535 + 0x2C100805, // 0008 AND R4 R4 R5 + 0x8C140102, // 0009 GETMET R5 R0 K2 + 0x7C140200, // 000A CALL R5 1 + 0x541A0FFE, // 000B LDINT R6 4095 + 0x2C140A06, // 000C AND R5 R5 R6 + 0x541A3FFF, // 000D LDINT R6 16384 + 0x30140A06, // 000E OR R5 R5 R6 + 0x8C180102, // 000F GETMET R6 R0 K2 + 0x7C180200, // 0010 CALL R6 1 + 0x541E3FFE, // 0011 LDINT R7 16383 + 0x2C180C07, // 0012 AND R6 R6 R7 + 0x541E7FFF, // 0013 LDINT R7 32768 + 0x30180C07, // 0014 OR R6 R6 R7 + 0x8C1C0102, // 0015 GETMET R7 R0 K2 + 0x7C1C0200, // 0016 CALL R7 1 + 0x5422FFFE, // 0017 LDINT R8 65535 + 0x2C1C0E08, // 0018 AND R7 R7 R8 + 0x8C200102, // 0019 GETMET R8 R0 K2 + 0x7C200200, // 001A CALL R8 1 + 0x7C040E00, // 001B CALL R1 7 + 0x80040200, // 001C RET 1 R1 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee.h index 04e8bf1dd6e9..0c1dc7c27ae7 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee.h @@ -9,7 +9,7 @@ ********************************************************************/ be_local_closure(zb_device_tostring, /* name */ be_nested_proto( - 14, /* nstack */ + 12, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -17,44 +17,41 @@ be_local_closure(zb_device_tostring, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[11]) { /* constants */ + ( &(const bvalue[ 9]) { /* constants */ /* K0 */ be_nested_str_weak(json), - /* K1 */ be_nested_str_weak(string), - /* K2 */ be_nested_str_weak(longaddr), - /* K3 */ be_nested_str_weak(format), - /* K4 */ be_nested_str_weak(_X3Cinstance_X3A_X20_X25s_X280x_X2504X_X2C_X200x_X2508X_X2508X_X2C_X20name_X3A_X27_X25s_X27_X2C_X20model_X3A_X27_X25s_X27_X2C_X20manufacturer_X3A_X27_X25s_X27_X29_X3E), - /* K5 */ be_nested_str_weak(shortaddr), - /* K6 */ be_nested_str_weak(get), - /* K7 */ be_const_int(0), - /* K8 */ be_nested_str_weak(name), - /* K9 */ be_nested_str_weak(model), - /* K10 */ be_nested_str_weak(manufacturer), + /* K1 */ be_nested_str_weak(longaddr), + /* K2 */ be_nested_str_weak(_X3Cinstance_X3A_X20_X25s_X280x_X2504X_X2C_X200x_X2508X_X2508X_X2C_X20name_X3A_X27_X25s_X27_X2C_X20model_X3A_X27_X25s_X27_X2C_X20manufacturer_X3A_X27_X25s_X27_X29_X3E), + /* K3 */ be_nested_str_weak(shortaddr), + /* K4 */ be_nested_str_weak(get), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str_weak(name), + /* K7 */ be_nested_str_weak(model), + /* K8 */ be_nested_str_weak(manufacturer), }), be_str_weak(tostring), &be_const_str_solidified, - ( &(const binstruction[22]) { /* code */ + ( &(const binstruction[21]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0x880C0102, // 0002 GETMBR R3 R0 K2 - 0x8C100503, // 0003 GETMET R4 R2 K3 - 0x58180004, // 0004 LDCONST R6 K4 - 0x601C0005, // 0005 GETGBL R7 G5 - 0x5C200000, // 0006 MOVE R8 R0 - 0x7C1C0200, // 0007 CALL R7 1 - 0x88200105, // 0008 GETMBR R8 R0 K5 - 0x8C240706, // 0009 GETMET R9 R3 K6 - 0x542E0003, // 000A LDINT R11 4 - 0x54320003, // 000B LDINT R12 4 - 0x7C240600, // 000C CALL R9 3 - 0x8C280706, // 000D GETMET R10 R3 K6 - 0x58300007, // 000E LDCONST R12 K7 - 0x54360003, // 000F LDINT R13 4 - 0x7C280600, // 0010 CALL R10 3 - 0x882C0108, // 0011 GETMBR R11 R0 K8 - 0x88300109, // 0012 GETMBR R12 R0 K9 - 0x8834010A, // 0013 GETMBR R13 R0 K10 - 0x7C101200, // 0014 CALL R4 9 - 0x80040800, // 0015 RET 1 R4 + 0x88080101, // 0001 GETMBR R2 R0 K1 + 0x600C0018, // 0002 GETGBL R3 G24 + 0x58100002, // 0003 LDCONST R4 K2 + 0x60140005, // 0004 GETGBL R5 G5 + 0x5C180000, // 0005 MOVE R6 R0 + 0x7C140200, // 0006 CALL R5 1 + 0x88180103, // 0007 GETMBR R6 R0 K3 + 0x8C1C0504, // 0008 GETMET R7 R2 K4 + 0x54260003, // 0009 LDINT R9 4 + 0x542A0003, // 000A LDINT R10 4 + 0x7C1C0600, // 000B CALL R7 3 + 0x8C200504, // 000C GETMET R8 R2 K4 + 0x58280005, // 000D LDCONST R10 K5 + 0x542E0003, // 000E LDINT R11 4 + 0x7C200600, // 000F CALL R8 3 + 0x88240106, // 0010 GETMBR R9 R0 K6 + 0x88280107, // 0011 GETMBR R10 R0 K7 + 0x882C0108, // 0012 GETMBR R11 R0 K8 + 0x7C0C1000, // 0013 CALL R3 8 + 0x80040600, // 0014 RET 1 R3 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee_zb_coord.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee_zb_coord.h index 10dc93c3345d..b39885b98c5b 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee_zb_coord.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee_zb_coord.h @@ -50,16 +50,17 @@ be_local_closure(zb_coord_add_handler, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ + ( &(const bvalue[ 6]) { /* constants */ /* K0 */ be_nested_str_weak(instance), /* K1 */ be_nested_str_weak(value_error), /* K2 */ be_nested_str_weak(instance_X20required), /* K3 */ be_nested_str_weak(_handlers), - /* K4 */ be_nested_str_weak(push), + /* K4 */ be_nested_str_weak(find), + /* K5 */ be_nested_str_weak(push), }), be_str_weak(add_handler), &be_const_str_solidified, - ( &(const binstruction[18]) { /* code */ + ( &(const binstruction[25]) { /* code */ 0x60080004, // 0000 GETGBL R2 G4 0x5C0C0200, // 0001 MOVE R3 R1 0x7C080200, // 0002 CALL R2 1 @@ -67,17 +68,24 @@ be_local_closure(zb_coord_add_handler, /* name */ 0x780A0000, // 0004 JMPF R2 #0006 0xB0060302, // 0005 RAISE 1 K1 K2 0x88080103, // 0006 GETMBR R2 R0 K3 - 0x780A0004, // 0007 JMPF R2 #000D + 0x780A000B, // 0007 JMPF R2 #0014 0x88080103, // 0008 GETMBR R2 R0 K3 0x8C080504, // 0009 GETMET R2 R2 K4 0x5C100200, // 000A MOVE R4 R1 0x7C080400, // 000B CALL R2 2 - 0x70020003, // 000C JMP #0011 - 0x60080012, // 000D GETGBL R2 G18 - 0x7C080000, // 000E CALL R2 0 - 0x400C0401, // 000F CONNECT R3 R2 R1 - 0x90020602, // 0010 SETMBR R0 K3 R2 - 0x80000000, // 0011 RET 0 + 0x4C0C0000, // 000C LDNIL R3 + 0x1C080403, // 000D EQ R2 R2 R3 + 0x780A0003, // 000E JMPF R2 #0013 + 0x88080103, // 000F GETMBR R2 R0 K3 + 0x8C080505, // 0010 GETMET R2 R2 K5 + 0x5C100200, // 0011 MOVE R4 R1 + 0x7C080400, // 0012 CALL R2 2 + 0x70020003, // 0013 JMP #0018 + 0x60080012, // 0014 GETGBL R2 G18 + 0x7C080000, // 0015 CALL R2 0 + 0x400C0401, // 0016 CONNECT R3 R2 R1 + 0x90020602, // 0017 SETMBR R0 K3 R2 + 0x80000000, // 0018 RET 0 }) ) ); @@ -89,7 +97,7 @@ be_local_closure(zb_coord_add_handler, /* name */ ********************************************************************/ be_local_closure(zb_coord_dispatch, /* name */ be_nested_proto( - 21, /* nstack */ + 19, /* nstack */ 5, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -97,98 +105,136 @@ be_local_closure(zb_coord_dispatch, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[16]) { /* constants */ + ( &(const bvalue[14]) { /* constants */ /* K0 */ be_nested_str_weak(_handlers), /* K1 */ be_nested_str_weak(introspect), - /* K2 */ be_nested_str_weak(string), - /* K3 */ be_nested_str_weak(toptr), - /* K4 */ be_const_int(0), - /* K5 */ be_nested_str_weak(zcl_frame), - /* K6 */ be_nested_str_weak(zcl_attribute_list), - /* K7 */ be_nested_str_weak(get), - /* K8 */ be_nested_str_weak(function), - /* K9 */ be_nested_str_weak(format), - /* K10 */ be_nested_str_weak(BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s), - /* K11 */ be_nested_str_weak(tasmota), - /* K12 */ be_nested_str_weak(_debug_present), - /* K13 */ be_nested_str_weak(debug), - /* K14 */ be_nested_str_weak(traceback), - /* K15 */ be_const_int(1), + /* K2 */ be_nested_str_weak(toptr), + /* K3 */ be_const_int(0), + /* K4 */ be_nested_str_weak(zcl_frame), + /* K5 */ be_nested_str_weak(zcl_attribute_list), + /* K6 */ be_nested_str_weak(get), + /* K7 */ be_nested_str_weak(function), + /* K8 */ be_nested_str_weak(BRY_X3A_X20Exception_X3E_X20_X27_X25s_X27_X20_X2D_X20_X25s), + /* K9 */ be_nested_str_weak(tasmota), + /* K10 */ be_nested_str_weak(_debug_present), + /* K11 */ be_nested_str_weak(debug), + /* K12 */ be_nested_str_weak(traceback), + /* K13 */ be_const_int(1), }), be_str_weak(dispatch), &be_const_str_solidified, - ( &(const binstruction[71]) { /* code */ + ( &(const binstruction[70]) { /* code */ 0x88140100, // 0000 GETMBR R5 R0 K0 0x4C180000, // 0001 LDNIL R6 0x1C140A06, // 0002 EQ R5 R5 R6 0x78160000, // 0003 JMPF R5 #0005 0x80000A00, // 0004 RET 0 0xA4160200, // 0005 IMPORT R5 K1 - 0xA41A0400, // 0006 IMPORT R6 K2 + 0x4C180000, // 0006 LDNIL R6 0x4C1C0000, // 0007 LDNIL R7 - 0x4C200000, // 0008 LDNIL R8 - 0x8C240B03, // 0009 GETMET R9 R5 K3 - 0x582C0004, // 000A LDCONST R11 K4 - 0x7C240400, // 000B CALL R9 2 - 0x20280409, // 000C NE R10 R2 R9 - 0x782A0003, // 000D JMPF R10 #0012 - 0x8C280105, // 000E GETMET R10 R0 K5 - 0x5C300400, // 000F MOVE R12 R2 - 0x7C280400, // 0010 CALL R10 2 - 0x5C1C1400, // 0011 MOVE R7 R10 - 0x20280609, // 0012 NE R10 R3 R9 - 0x782A0003, // 0013 JMPF R10 #0018 - 0x8C280106, // 0014 GETMET R10 R0 K6 - 0x5C300600, // 0015 MOVE R12 R3 - 0x7C280400, // 0016 CALL R10 2 - 0x5C201400, // 0017 MOVE R8 R10 - 0x58280004, // 0018 LDCONST R10 K4 - 0x602C000C, // 0019 GETGBL R11 G12 - 0x88300100, // 001A GETMBR R12 R0 K0 - 0x7C2C0200, // 001B CALL R11 1 - 0x142C140B, // 001C LT R11 R10 R11 - 0x782E0027, // 001D JMPF R11 #0046 - 0x882C0100, // 001E GETMBR R11 R0 K0 - 0x942C160A, // 001F GETIDX R11 R11 R10 - 0x8C300B07, // 0020 GETMET R12 R5 K7 - 0x5C381600, // 0021 MOVE R14 R11 - 0x5C3C0200, // 0022 MOVE R15 R1 - 0x7C300600, // 0023 CALL R12 3 - 0x60340004, // 0024 GETGBL R13 G4 - 0x5C381800, // 0025 MOVE R14 R12 - 0x7C340200, // 0026 CALL R13 1 - 0x1C341B08, // 0027 EQ R13 R13 K8 - 0x7836001A, // 0028 JMPF R13 #0044 - 0xA8020008, // 0029 EXBLK 0 #0033 - 0x5C341800, // 002A MOVE R13 R12 - 0x5C381600, // 002B MOVE R14 R11 - 0x5C3C0200, // 002C MOVE R15 R1 + 0x8C200B02, // 0008 GETMET R8 R5 K2 + 0x58280003, // 0009 LDCONST R10 K3 + 0x7C200400, // 000A CALL R8 2 + 0x20240408, // 000B NE R9 R2 R8 + 0x78260003, // 000C JMPF R9 #0011 + 0x8C240104, // 000D GETMET R9 R0 K4 + 0x5C2C0400, // 000E MOVE R11 R2 + 0x7C240400, // 000F CALL R9 2 + 0x5C181200, // 0010 MOVE R6 R9 + 0x20240608, // 0011 NE R9 R3 R8 + 0x78260003, // 0012 JMPF R9 #0017 + 0x8C240105, // 0013 GETMET R9 R0 K5 + 0x5C2C0600, // 0014 MOVE R11 R3 + 0x7C240400, // 0015 CALL R9 2 + 0x5C1C1200, // 0016 MOVE R7 R9 + 0x58240003, // 0017 LDCONST R9 K3 + 0x6028000C, // 0018 GETGBL R10 G12 + 0x882C0100, // 0019 GETMBR R11 R0 K0 + 0x7C280200, // 001A CALL R10 1 + 0x1428120A, // 001B LT R10 R9 R10 + 0x782A0027, // 001C JMPF R10 #0045 + 0x88280100, // 001D GETMBR R10 R0 K0 + 0x94281409, // 001E GETIDX R10 R10 R9 + 0x8C2C0B06, // 001F GETMET R11 R5 K6 + 0x5C341400, // 0020 MOVE R13 R10 + 0x5C380200, // 0021 MOVE R14 R1 + 0x7C2C0600, // 0022 CALL R11 3 + 0x60300004, // 0023 GETGBL R12 G4 + 0x5C341600, // 0024 MOVE R13 R11 + 0x7C300200, // 0025 CALL R12 1 + 0x1C301907, // 0026 EQ R12 R12 K7 + 0x7832001A, // 0027 JMPF R12 #0043 + 0xA8020008, // 0028 EXBLK 0 #0032 + 0x5C301600, // 0029 MOVE R12 R11 + 0x5C341400, // 002A MOVE R13 R10 + 0x5C380200, // 002B MOVE R14 R1 + 0x5C3C0C00, // 002C MOVE R15 R6 0x5C400E00, // 002D MOVE R16 R7 - 0x5C441000, // 002E MOVE R17 R8 - 0x5C480800, // 002F MOVE R18 R4 - 0x7C340A00, // 0030 CALL R13 5 - 0xA8040001, // 0031 EXBLK 1 1 - 0x70020010, // 0032 JMP #0044 - 0xAC340002, // 0033 CATCH R13 0 2 - 0x7002000D, // 0034 JMP #0043 - 0x603C0001, // 0035 GETGBL R15 G1 - 0x8C400D09, // 0036 GETMET R16 R6 K9 - 0x5848000A, // 0037 LDCONST R18 K10 - 0x5C4C1A00, // 0038 MOVE R19 R13 - 0x5C501C00, // 0039 MOVE R20 R14 - 0x7C400800, // 003A CALL R16 4 - 0x7C3C0200, // 003B CALL R15 1 - 0xB83E1600, // 003C GETNGBL R15 K11 - 0x883C1F0C, // 003D GETMBR R15 R15 K12 - 0x783E0002, // 003E JMPF R15 #0042 - 0xA43E1A00, // 003F IMPORT R15 K13 - 0x8C401F0E, // 0040 GETMET R16 R15 K14 - 0x7C400200, // 0041 CALL R16 1 - 0x70020000, // 0042 JMP #0044 - 0xB0080000, // 0043 RAISE 2 R0 R0 - 0x0028150F, // 0044 ADD R10 R10 K15 - 0x7001FFD2, // 0045 JMP #0019 - 0x80000000, // 0046 RET 0 + 0x5C440800, // 002E MOVE R17 R4 + 0x7C300A00, // 002F CALL R12 5 + 0xA8040001, // 0030 EXBLK 1 1 + 0x70020010, // 0031 JMP #0043 + 0xAC300002, // 0032 CATCH R12 0 2 + 0x7002000D, // 0033 JMP #0042 + 0x60380001, // 0034 GETGBL R14 G1 + 0x603C0018, // 0035 GETGBL R15 G24 + 0x58400008, // 0036 LDCONST R16 K8 + 0x5C441800, // 0037 MOVE R17 R12 + 0x5C481A00, // 0038 MOVE R18 R13 + 0x7C3C0600, // 0039 CALL R15 3 + 0x7C380200, // 003A CALL R14 1 + 0xB83A1200, // 003B GETNGBL R14 K9 + 0x88381D0A, // 003C GETMBR R14 R14 K10 + 0x783A0002, // 003D JMPF R14 #0041 + 0xA43A1600, // 003E IMPORT R14 K11 + 0x8C3C1D0C, // 003F GETMET R15 R14 K12 + 0x7C3C0200, // 0040 CALL R15 1 + 0x70020000, // 0041 JMP #0043 + 0xB0080000, // 0042 RAISE 2 R0 R0 + 0x0024130D, // 0043 ADD R9 R9 K13 + 0x7001FFD2, // 0044 JMP #0018 + 0x80000000, // 0045 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: remove_handler +********************************************************************/ +be_local_closure(zb_coord_remove_handler, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(_handlers), + /* K1 */ be_nested_str_weak(find), + /* K2 */ be_nested_str_weak(remove), + }), + be_str_weak(remove_handler), + &be_const_str_solidified, + ( &(const binstruction[14]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A000A, // 0001 JMPF R2 #000D + 0x88080100, // 0002 GETMBR R2 R0 K0 + 0x8C080501, // 0003 GETMET R2 R2 K1 + 0x5C100200, // 0004 MOVE R4 R1 + 0x7C080400, // 0005 CALL R2 2 + 0x4C0C0000, // 0006 LDNIL R3 + 0x200C0403, // 0007 NE R3 R2 R3 + 0x780E0003, // 0008 JMPF R3 #000D + 0x880C0100, // 0009 GETMBR R3 R0 K0 + 0x8C0C0702, // 000A GETMET R3 R3 K2 + 0x5C140400, // 000B MOVE R5 R2 + 0x7C0C0400, // 000C CALL R3 2 + 0x80000000, // 000D RET 0 }) ) ); @@ -202,12 +248,13 @@ extern const bclass be_class_zb_coord_ntv; be_local_class(zb_coord, 1, &be_class_zb_coord_ntv, - be_nested_map(4, + be_nested_map(5, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(dispatch, 1), be_const_closure(zb_coord_dispatch_closure) }, - { be_const_key_weak(add_handler, 2), be_const_closure(zb_coord_add_handler_closure) }, - { be_const_key_weak(_handlers, -1), be_const_var(0) }, - { be_const_key_weak(init, 0), be_const_closure(zb_coord_init_closure) }, + { be_const_key_weak(init, -1), be_const_closure(zb_coord_init_closure) }, + { be_const_key_weak(remove_handler, 2), be_const_closure(zb_coord_remove_handler_closure) }, + { be_const_key_weak(add_handler, -1), be_const_closure(zb_coord_add_handler_closure) }, + { be_const_key_weak(dispatch, -1), be_const_closure(zb_coord_dispatch_closure) }, + { be_const_key_weak(_handlers, 1), be_const_var(0) }, })), be_str_weak(zb_coord) ); diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee_zcl_attribute.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee_zcl_attribute.h index d2e4cc8477da..bbf637b6b584 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee_zcl_attribute.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee_zcl_attribute.h @@ -60,7 +60,7 @@ be_local_closure(zcl_attribute_tomap, /* name */ ********************************************************************/ be_local_closure(zcl_attribute_key_tostring, /* name */ be_nested_proto( - 10, /* nstack */ + 8, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -68,96 +68,93 @@ be_local_closure(zcl_attribute_key_tostring, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(_X3Cundefined_X3E), - /* K2 */ be_nested_str_weak(key), - /* K3 */ be_nested_str_weak(key_suffix), - /* K4 */ be_const_int(1), - /* K5 */ be_nested_str_weak(cluster), - /* K6 */ be_nested_str_weak(attr_id), - /* K7 */ be_nested_str_weak(format), - /* K8 */ be_nested_str_weak(_X2504X_X2F_X2504X), - /* K9 */ be_nested_str_weak(_X2B), - /* K10 */ be_nested_str_weak(cmd), - /* K11 */ be_nested_str_weak(direction), - /* K12 */ be_nested_str_weak(_X2504X_X25s_X2502X), - /* K13 */ be_nested_str_weak(_X3F), - /* K14 */ be_nested_str_weak(_X21), + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_weak(_X3Cundefined_X3E), + /* K1 */ be_nested_str_weak(key), + /* K2 */ be_nested_str_weak(key_suffix), + /* K3 */ be_const_int(1), + /* K4 */ be_nested_str_weak(cluster), + /* K5 */ be_nested_str_weak(attr_id), + /* K6 */ be_nested_str_weak(_X2504X_X2F_X2504X), + /* K7 */ be_nested_str_weak(_X2B), + /* K8 */ be_nested_str_weak(cmd), + /* K9 */ be_nested_str_weak(direction), + /* K10 */ be_nested_str_weak(_X2504X_X25s_X2502X), + /* K11 */ be_nested_str_weak(_X3F), + /* K12 */ be_nested_str_weak(_X21), }), be_str_weak(key_tostring), &be_const_str_solidified, - ( &(const binstruction[70]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x58080001, // 0001 LDCONST R2 K1 - 0x880C0102, // 0002 GETMBR R3 R0 K2 - 0x4C100000, // 0003 LDNIL R4 - 0x20100604, // 0004 NE R4 R3 R4 - 0x78120008, // 0005 JMPF R4 #000F - 0x5C080600, // 0006 MOVE R2 R3 - 0x88100103, // 0007 GETMBR R4 R0 K3 - 0x24100904, // 0008 GT R4 R4 K4 - 0x78120003, // 0009 JMPF R4 #000E - 0x60100008, // 000A GETGBL R4 G8 - 0x88140103, // 000B GETMBR R5 R0 K3 - 0x7C100200, // 000C CALL R4 1 - 0x00080404, // 000D ADD R2 R2 R4 - 0x70020035, // 000E JMP #0045 - 0x88100105, // 000F GETMBR R4 R0 K5 - 0x4C140000, // 0010 LDNIL R5 - 0x20100805, // 0011 NE R4 R4 R5 - 0x78120012, // 0012 JMPF R4 #0026 - 0x88100106, // 0013 GETMBR R4 R0 K6 - 0x4C140000, // 0014 LDNIL R5 - 0x20100805, // 0015 NE R4 R4 R5 - 0x7812000E, // 0016 JMPF R4 #0026 - 0x8C100307, // 0017 GETMET R4 R1 K7 - 0x58180008, // 0018 LDCONST R6 K8 - 0x881C0105, // 0019 GETMBR R7 R0 K5 - 0x88200106, // 001A GETMBR R8 R0 K6 - 0x7C100800, // 001B CALL R4 4 - 0x5C080800, // 001C MOVE R2 R4 - 0x88100103, // 001D GETMBR R4 R0 K3 - 0x24100904, // 001E GT R4 R4 K4 - 0x78120004, // 001F JMPF R4 #0025 - 0x60100008, // 0020 GETGBL R4 G8 - 0x88140103, // 0021 GETMBR R5 R0 K3 - 0x7C100200, // 0022 CALL R4 1 - 0x00121204, // 0023 ADD R4 K9 R4 - 0x00080404, // 0024 ADD R2 R2 R4 - 0x7002001E, // 0025 JMP #0045 - 0x88100105, // 0026 GETMBR R4 R0 K5 - 0x4C140000, // 0027 LDNIL R5 - 0x20100805, // 0028 NE R4 R4 R5 - 0x7812001A, // 0029 JMPF R4 #0045 - 0x8810010A, // 002A GETMBR R4 R0 K10 - 0x4C140000, // 002B LDNIL R5 - 0x20100805, // 002C NE R4 R4 R5 - 0x78120016, // 002D JMPF R4 #0045 - 0x8810010B, // 002E GETMBR R4 R0 K11 - 0x4C140000, // 002F LDNIL R5 - 0x20100805, // 0030 NE R4 R4 R5 - 0x78120012, // 0031 JMPF R4 #0045 - 0x8C100307, // 0032 GETMET R4 R1 K7 - 0x5818000C, // 0033 LDCONST R6 K12 - 0x881C0105, // 0034 GETMBR R7 R0 K5 - 0x8820010B, // 0035 GETMBR R8 R0 K11 - 0x78220001, // 0036 JMPF R8 #0039 - 0x5820000D, // 0037 LDCONST R8 K13 - 0x70020000, // 0038 JMP #003A - 0x5820000E, // 0039 LDCONST R8 K14 - 0x8824010A, // 003A GETMBR R9 R0 K10 - 0x7C100A00, // 003B CALL R4 5 - 0x5C080800, // 003C MOVE R2 R4 - 0x88100103, // 003D GETMBR R4 R0 K3 - 0x24100904, // 003E GT R4 R4 K4 - 0x78120004, // 003F JMPF R4 #0045 - 0x60100008, // 0040 GETGBL R4 G8 - 0x88140103, // 0041 GETMBR R5 R0 K3 - 0x7C100200, // 0042 CALL R4 1 - 0x00121204, // 0043 ADD R4 K9 R4 - 0x00080404, // 0044 ADD R2 R2 R4 - 0x80040400, // 0045 RET 1 R2 + ( &(const binstruction[69]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x88080101, // 0001 GETMBR R2 R0 K1 + 0x4C0C0000, // 0002 LDNIL R3 + 0x200C0403, // 0003 NE R3 R2 R3 + 0x780E0008, // 0004 JMPF R3 #000E + 0x5C040400, // 0005 MOVE R1 R2 + 0x880C0102, // 0006 GETMBR R3 R0 K2 + 0x240C0703, // 0007 GT R3 R3 K3 + 0x780E0003, // 0008 JMPF R3 #000D + 0x600C0008, // 0009 GETGBL R3 G8 + 0x88100102, // 000A GETMBR R4 R0 K2 + 0x7C0C0200, // 000B CALL R3 1 + 0x00040203, // 000C ADD R1 R1 R3 + 0x70020035, // 000D JMP #0044 + 0x880C0104, // 000E GETMBR R3 R0 K4 + 0x4C100000, // 000F LDNIL R4 + 0x200C0604, // 0010 NE R3 R3 R4 + 0x780E0012, // 0011 JMPF R3 #0025 + 0x880C0105, // 0012 GETMBR R3 R0 K5 + 0x4C100000, // 0013 LDNIL R4 + 0x200C0604, // 0014 NE R3 R3 R4 + 0x780E000E, // 0015 JMPF R3 #0025 + 0x600C0018, // 0016 GETGBL R3 G24 + 0x58100006, // 0017 LDCONST R4 K6 + 0x88140104, // 0018 GETMBR R5 R0 K4 + 0x88180105, // 0019 GETMBR R6 R0 K5 + 0x7C0C0600, // 001A CALL R3 3 + 0x5C040600, // 001B MOVE R1 R3 + 0x880C0102, // 001C GETMBR R3 R0 K2 + 0x240C0703, // 001D GT R3 R3 K3 + 0x780E0004, // 001E JMPF R3 #0024 + 0x600C0008, // 001F GETGBL R3 G8 + 0x88100102, // 0020 GETMBR R4 R0 K2 + 0x7C0C0200, // 0021 CALL R3 1 + 0x000E0E03, // 0022 ADD R3 K7 R3 + 0x00040203, // 0023 ADD R1 R1 R3 + 0x7002001E, // 0024 JMP #0044 + 0x880C0104, // 0025 GETMBR R3 R0 K4 + 0x4C100000, // 0026 LDNIL R4 + 0x200C0604, // 0027 NE R3 R3 R4 + 0x780E001A, // 0028 JMPF R3 #0044 + 0x880C0108, // 0029 GETMBR R3 R0 K8 + 0x4C100000, // 002A LDNIL R4 + 0x200C0604, // 002B NE R3 R3 R4 + 0x780E0016, // 002C JMPF R3 #0044 + 0x880C0109, // 002D GETMBR R3 R0 K9 + 0x4C100000, // 002E LDNIL R4 + 0x200C0604, // 002F NE R3 R3 R4 + 0x780E0012, // 0030 JMPF R3 #0044 + 0x600C0018, // 0031 GETGBL R3 G24 + 0x5810000A, // 0032 LDCONST R4 K10 + 0x88140104, // 0033 GETMBR R5 R0 K4 + 0x88180109, // 0034 GETMBR R6 R0 K9 + 0x781A0001, // 0035 JMPF R6 #0038 + 0x5818000B, // 0036 LDCONST R6 K11 + 0x70020000, // 0037 JMP #0039 + 0x5818000C, // 0038 LDCONST R6 K12 + 0x881C0108, // 0039 GETMBR R7 R0 K8 + 0x7C0C0800, // 003A CALL R3 4 + 0x5C040600, // 003B MOVE R1 R3 + 0x880C0102, // 003C GETMBR R3 R0 K2 + 0x240C0703, // 003D GT R3 R3 K3 + 0x780E0004, // 003E JMPF R3 #0044 + 0x600C0008, // 003F GETGBL R3 G8 + 0x88100102, // 0040 GETMBR R4 R0 K2 + 0x7C0C0200, // 0041 CALL R3 1 + 0x000E0E03, // 0042 ADD R3 K7 R3 + 0x00040203, // 0043 ADD R1 R1 R3 + 0x80040200, // 0044 RET 1 R1 }) ) ); @@ -275,7 +272,7 @@ be_local_closure(zcl_attribute_setmember, /* name */ ********************************************************************/ be_local_closure(zcl_attribute_tostring, /* name */ be_nested_proto( - 12, /* nstack */ + 10, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -283,77 +280,74 @@ be_local_closure(zcl_attribute_tostring, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ + ( &(const bvalue[13]) { /* constants */ /* K0 */ be_nested_str_weak(introspect), /* K1 */ be_nested_str_weak(json), - /* K2 */ be_nested_str_weak(string), - /* K3 */ be_nested_str_weak(dump), - /* K4 */ be_nested_str_weak(key_tostring), - /* K5 */ be_nested_str_weak(_X3A), - /* K6 */ be_nested_str_weak(get), - /* K7 */ be_nested_str_weak(val), - /* K8 */ be_nested_str_weak(tojson), - /* K9 */ be_nested_str_weak(cluster), - /* K10 */ be_nested_str_weak(attr_id), - /* K11 */ be_nested_str_weak(key), - /* K12 */ be_nested_str_weak(format), - /* K13 */ be_nested_str_weak(_X28_X25s_X29), - /* K14 */ be_nested_str_weak(_X2C_X25s_X3A_X22_X2504X_X2F_X2504X_X22), + /* K2 */ be_nested_str_weak(dump), + /* K3 */ be_nested_str_weak(key_tostring), + /* K4 */ be_nested_str_weak(_X3A), + /* K5 */ be_nested_str_weak(get), + /* K6 */ be_nested_str_weak(val), + /* K7 */ be_nested_str_weak(tojson), + /* K8 */ be_nested_str_weak(cluster), + /* K9 */ be_nested_str_weak(attr_id), + /* K10 */ be_nested_str_weak(key), + /* K11 */ be_nested_str_weak(_X28_X25s_X29), + /* K12 */ be_nested_str_weak(_X2C_X25s_X3A_X22_X2504X_X2F_X2504X_X22), }), be_str_weak(tostring), &be_const_str_solidified, - ( &(const binstruction[51]) { /* code */ + ( &(const binstruction[50]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 0xA40A0200, // 0001 IMPORT R2 K1 - 0xA40E0400, // 0002 IMPORT R3 K2 - 0x8C100503, // 0003 GETMET R4 R2 K3 - 0x8C180104, // 0004 GETMET R6 R0 K4 - 0x7C180200, // 0005 CALL R6 1 - 0x7C100400, // 0006 CALL R4 2 - 0x00100905, // 0007 ADD R4 R4 K5 - 0x8C140306, // 0008 GETMET R5 R1 K6 - 0x881C0107, // 0009 GETMBR R7 R0 K7 - 0x58200008, // 000A LDCONST R8 K8 - 0x7C140600, // 000B CALL R5 3 - 0x4C180000, // 000C LDNIL R6 - 0x20140A06, // 000D NE R5 R5 R6 - 0x78160004, // 000E JMPF R5 #0014 - 0x88140107, // 000F GETMBR R5 R0 K7 - 0x8C140B08, // 0010 GETMET R5 R5 K8 - 0x7C140200, // 0011 CALL R5 1 - 0x00100805, // 0012 ADD R4 R4 R5 - 0x70020003, // 0013 JMP #0018 - 0x8C140503, // 0014 GETMET R5 R2 K3 - 0x881C0107, // 0015 GETMBR R7 R0 K7 - 0x7C140400, // 0016 CALL R5 2 - 0x00100805, // 0017 ADD R4 R4 R5 - 0x88140109, // 0018 GETMBR R5 R0 K9 - 0x4C180000, // 0019 LDNIL R6 - 0x20140A06, // 001A NE R5 R5 R6 - 0x78160015, // 001B JMPF R5 #0032 - 0x8814010A, // 001C GETMBR R5 R0 K10 - 0x4C180000, // 001D LDNIL R6 - 0x20140A06, // 001E NE R5 R5 R6 - 0x78160011, // 001F JMPF R5 #0032 - 0x8814010B, // 0020 GETMBR R5 R0 K11 - 0x4C180000, // 0021 LDNIL R6 - 0x20140A06, // 0022 NE R5 R5 R6 - 0x7816000D, // 0023 JMPF R5 #0032 - 0x8C14070C, // 0024 GETMET R5 R3 K12 - 0x581C000D, // 0025 LDCONST R7 K13 - 0x8C200104, // 0026 GETMET R8 R0 K4 - 0x7C200200, // 0027 CALL R8 1 - 0x7C140600, // 0028 CALL R5 3 - 0x8C18070C, // 0029 GETMET R6 R3 K12 - 0x5820000E, // 002A LDCONST R8 K14 - 0x8C240503, // 002B GETMET R9 R2 K3 - 0x5C2C0A00, // 002C MOVE R11 R5 - 0x7C240400, // 002D CALL R9 2 - 0x88280109, // 002E GETMBR R10 R0 K9 - 0x882C010A, // 002F GETMBR R11 R0 K10 - 0x7C180A00, // 0030 CALL R6 5 - 0x00100806, // 0031 ADD R4 R4 R6 - 0x80040800, // 0032 RET 1 R4 + 0x8C0C0502, // 0002 GETMET R3 R2 K2 + 0x8C140103, // 0003 GETMET R5 R0 K3 + 0x7C140200, // 0004 CALL R5 1 + 0x7C0C0400, // 0005 CALL R3 2 + 0x000C0704, // 0006 ADD R3 R3 K4 + 0x8C100305, // 0007 GETMET R4 R1 K5 + 0x88180106, // 0008 GETMBR R6 R0 K6 + 0x581C0007, // 0009 LDCONST R7 K7 + 0x7C100600, // 000A CALL R4 3 + 0x4C140000, // 000B LDNIL R5 + 0x20100805, // 000C NE R4 R4 R5 + 0x78120004, // 000D JMPF R4 #0013 + 0x88100106, // 000E GETMBR R4 R0 K6 + 0x8C100907, // 000F GETMET R4 R4 K7 + 0x7C100200, // 0010 CALL R4 1 + 0x000C0604, // 0011 ADD R3 R3 R4 + 0x70020003, // 0012 JMP #0017 + 0x8C100502, // 0013 GETMET R4 R2 K2 + 0x88180106, // 0014 GETMBR R6 R0 K6 + 0x7C100400, // 0015 CALL R4 2 + 0x000C0604, // 0016 ADD R3 R3 R4 + 0x88100108, // 0017 GETMBR R4 R0 K8 + 0x4C140000, // 0018 LDNIL R5 + 0x20100805, // 0019 NE R4 R4 R5 + 0x78120015, // 001A JMPF R4 #0031 + 0x88100109, // 001B GETMBR R4 R0 K9 + 0x4C140000, // 001C LDNIL R5 + 0x20100805, // 001D NE R4 R4 R5 + 0x78120011, // 001E JMPF R4 #0031 + 0x8810010A, // 001F GETMBR R4 R0 K10 + 0x4C140000, // 0020 LDNIL R5 + 0x20100805, // 0021 NE R4 R4 R5 + 0x7812000D, // 0022 JMPF R4 #0031 + 0x60100018, // 0023 GETGBL R4 G24 + 0x5814000B, // 0024 LDCONST R5 K11 + 0x8C180103, // 0025 GETMET R6 R0 K3 + 0x7C180200, // 0026 CALL R6 1 + 0x7C100400, // 0027 CALL R4 2 + 0x60140018, // 0028 GETGBL R5 G24 + 0x5818000C, // 0029 LDCONST R6 K12 + 0x8C1C0502, // 002A GETMET R7 R2 K2 + 0x5C240800, // 002B MOVE R9 R4 + 0x7C1C0400, // 002C CALL R7 2 + 0x88200108, // 002D GETMBR R8 R0 K8 + 0x88240109, // 002E GETMBR R9 R0 K9 + 0x7C140800, // 002F CALL R5 4 + 0x000C0605, // 0030 ADD R3 R3 R5 + 0x80040600, // 0031 RET 1 R3 }) ) ); @@ -791,7 +785,7 @@ be_local_closure(zcl_attribute_list_deinit, /* name */ ********************************************************************/ be_local_closure(zcl_attribute_list_tostring, /* name */ be_nested_proto( - 12, /* nstack */ + 11, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -799,92 +793,90 @@ be_local_closure(zcl_attribute_list_tostring, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[20]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(json), - /* K2 */ be_nested_str_weak(shortaddr), - /* K3 */ be_nested_str_weak(push), - /* K4 */ be_nested_str_weak(format), - /* K5 */ be_nested_str_weak(_X22Device_X22_X3A_X220x_X2504X_X22), - /* K6 */ be_nested_str_weak(groupaddr), - /* K7 */ be_nested_str_weak(_X22Group_X22_X3A_X220x_X2504X_X22), - /* K8 */ be_const_int(0), - /* K9 */ be_nested_str_weak(size), - /* K10 */ be_nested_str_weak(tostring), - /* K11 */ be_const_int(1), - /* K12 */ be_nested_str_weak(src_ep), - /* K13 */ be_nested_str_weak(_X22Endpoint_X22_X3A_X25i), - /* K14 */ be_nested_str_weak(lqi), - /* K15 */ be_nested_str_weak(_X22LinkQuality_X22_X3A_X25i), - /* K16 */ be_nested_str_weak(_X7B), - /* K17 */ be_nested_str_weak(concat), - /* K18 */ be_nested_str_weak(_X2C), - /* K19 */ be_nested_str_weak(_X7D), + ( &(const bvalue[18]) { /* constants */ + /* K0 */ be_nested_str_weak(json), + /* K1 */ be_nested_str_weak(shortaddr), + /* K2 */ be_nested_str_weak(push), + /* K3 */ be_nested_str_weak(_X22Device_X22_X3A_X220x_X2504X_X22), + /* K4 */ be_nested_str_weak(groupaddr), + /* K5 */ be_nested_str_weak(_X22Group_X22_X3A_X220x_X2504X_X22), + /* K6 */ be_const_int(0), + /* K7 */ be_nested_str_weak(size), + /* K8 */ be_nested_str_weak(tostring), + /* K9 */ be_const_int(1), + /* K10 */ be_nested_str_weak(src_ep), + /* K11 */ be_nested_str_weak(_X22Endpoint_X22_X3A_X25s), + /* K12 */ be_nested_str_weak(lqi), + /* K13 */ be_nested_str_weak(_X22LinkQuality_X22_X3A_X25s), + /* K14 */ be_nested_str_weak(_X7B), + /* K15 */ be_nested_str_weak(concat), + /* K16 */ be_nested_str_weak(_X2C), + /* K17 */ be_nested_str_weak(_X7D), }), be_str_weak(tostring), &be_const_str_solidified, ( &(const binstruction[62]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0x600C0012, // 0002 GETGBL R3 G18 - 0x7C0C0000, // 0003 CALL R3 0 - 0x88100102, // 0004 GETMBR R4 R0 K2 - 0x4C140000, // 0005 LDNIL R5 - 0x20100805, // 0006 NE R4 R4 R5 - 0x78120005, // 0007 JMPF R4 #000E - 0x8C100703, // 0008 GETMET R4 R3 K3 - 0x8C180304, // 0009 GETMET R6 R1 K4 - 0x58200005, // 000A LDCONST R8 K5 - 0x88240102, // 000B GETMBR R9 R0 K2 - 0x7C180600, // 000C CALL R6 3 - 0x7C100400, // 000D CALL R4 2 - 0x88100106, // 000E GETMBR R4 R0 K6 - 0x4C140000, // 000F LDNIL R5 - 0x20100805, // 0010 NE R4 R4 R5 - 0x78120005, // 0011 JMPF R4 #0018 - 0x8C100703, // 0012 GETMET R4 R3 K3 - 0x8C180304, // 0013 GETMET R6 R1 K4 - 0x58200007, // 0014 LDCONST R8 K7 - 0x88240106, // 0015 GETMBR R9 R0 K6 - 0x7C180600, // 0016 CALL R6 3 - 0x7C100400, // 0017 CALL R4 2 - 0x58100008, // 0018 LDCONST R4 K8 - 0x8C140109, // 0019 GETMET R5 R0 K9 + 0x60080012, // 0001 GETGBL R2 G18 + 0x7C080000, // 0002 CALL R2 0 + 0x4C0C0000, // 0003 LDNIL R3 + 0x880C0101, // 0004 GETMBR R3 R0 K1 + 0x4C100000, // 0005 LDNIL R4 + 0x200C0604, // 0006 NE R3 R3 R4 + 0x780E0005, // 0007 JMPF R3 #000E + 0x8C0C0502, // 0008 GETMET R3 R2 K2 + 0x60140018, // 0009 GETGBL R5 G24 + 0x58180003, // 000A LDCONST R6 K3 + 0x5C1C0600, // 000B MOVE R7 R3 + 0x7C140400, // 000C CALL R5 2 + 0x7C0C0400, // 000D CALL R3 2 + 0x880C0104, // 000E GETMBR R3 R0 K4 + 0x4C100000, // 000F LDNIL R4 + 0x200C0604, // 0010 NE R3 R3 R4 + 0x780E0005, // 0011 JMPF R3 #0018 + 0x8C0C0502, // 0012 GETMET R3 R2 K2 + 0x60140018, // 0013 GETGBL R5 G24 + 0x58180005, // 0014 LDCONST R6 K5 + 0x5C1C0600, // 0015 MOVE R7 R3 + 0x7C140400, // 0016 CALL R5 2 + 0x7C0C0400, // 0017 CALL R3 2 + 0x58100006, // 0018 LDCONST R4 K6 + 0x8C140107, // 0019 GETMET R5 R0 K7 0x7C140200, // 001A CALL R5 1 0x14180805, // 001B LT R6 R4 R5 0x781A0006, // 001C JMPF R6 #0024 - 0x8C180703, // 001D GETMET R6 R3 K3 + 0x8C180502, // 001D GETMET R6 R2 K2 0x94200004, // 001E GETIDX R8 R0 R4 - 0x8C20110A, // 001F GETMET R8 R8 K10 + 0x8C201108, // 001F GETMET R8 R8 K8 0x7C200200, // 0020 CALL R8 1 0x7C180400, // 0021 CALL R6 2 - 0x0010090B, // 0022 ADD R4 R4 K11 + 0x00100909, // 0022 ADD R4 R4 K9 0x7001FFF6, // 0023 JMP #001B - 0x8818010C, // 0024 GETMBR R6 R0 K12 - 0x4C1C0000, // 0025 LDNIL R7 - 0x20180C07, // 0026 NE R6 R6 R7 - 0x781A0005, // 0027 JMPF R6 #002E - 0x8C180703, // 0028 GETMET R6 R3 K3 - 0x8C200304, // 0029 GETMET R8 R1 K4 - 0x5828000D, // 002A LDCONST R10 K13 - 0x882C010C, // 002B GETMBR R11 R0 K12 - 0x7C200600, // 002C CALL R8 3 + 0x880C010A, // 0024 GETMBR R3 R0 K10 + 0x4C180000, // 0025 LDNIL R6 + 0x200C0606, // 0026 NE R3 R3 R6 + 0x780E0005, // 0027 JMPF R3 #002E + 0x8C180502, // 0028 GETMET R6 R2 K2 + 0x60200018, // 0029 GETGBL R8 G24 + 0x5824000B, // 002A LDCONST R9 K11 + 0x5C280600, // 002B MOVE R10 R3 + 0x7C200400, // 002C CALL R8 2 0x7C180400, // 002D CALL R6 2 - 0x8818010E, // 002E GETMBR R6 R0 K14 - 0x4C1C0000, // 002F LDNIL R7 - 0x20180C07, // 0030 NE R6 R6 R7 - 0x781A0005, // 0031 JMPF R6 #0038 - 0x8C180703, // 0032 GETMET R6 R3 K3 - 0x8C200304, // 0033 GETMET R8 R1 K4 - 0x5828000F, // 0034 LDCONST R10 K15 - 0x882C010E, // 0035 GETMBR R11 R0 K14 - 0x7C200600, // 0036 CALL R8 3 + 0x880C010C, // 002E GETMBR R3 R0 K12 + 0x4C180000, // 002F LDNIL R6 + 0x200C0606, // 0030 NE R3 R3 R6 + 0x780E0005, // 0031 JMPF R3 #0038 + 0x8C180502, // 0032 GETMET R6 R2 K2 + 0x60200018, // 0033 GETGBL R8 G24 + 0x5824000D, // 0034 LDCONST R9 K13 + 0x5C280600, // 0035 MOVE R10 R3 + 0x7C200400, // 0036 CALL R8 2 0x7C180400, // 0037 CALL R6 2 - 0x8C180711, // 0038 GETMET R6 R3 K17 - 0x58200012, // 0039 LDCONST R8 K18 + 0x8C18050F, // 0038 GETMET R6 R2 K15 + 0x58200010, // 0039 LDCONST R8 K16 0x7C180400, // 003A CALL R6 2 - 0x001A2006, // 003B ADD R6 K16 R6 - 0x00180D13, // 003C ADD R6 R6 K19 + 0x001A1C06, // 003B ADD R6 K14 R6 + 0x00180D11, // 003C ADD R6 R6 K17 0x80040C00, // 003D RET 1 R6 }) ) @@ -917,216 +909,5 @@ void be_load_zcl_attribute_list_class(bvm *vm) { be_setglobal(vm, "zcl_attribute_list"); be_pop(vm, 1); } - -extern const bclass be_class_zcl_attributes; - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(zcl_attributes_init, /* name */ - be_nested_proto( - 9, /* nstack */ - 6, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(shortaddr), - /* K1 */ be_nested_str_weak(groupaddr), - /* K2 */ be_nested_str_weak(lqi), - /* K3 */ be_nested_str_weak(src_ep), - /* K4 */ be_nested_str_weak(attr_list), - }), - be_str_weak(init), - &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x90020001, // 0000 SETMBR R0 K0 R1 - 0x90020202, // 0001 SETMBR R0 K1 R2 - 0x90020403, // 0002 SETMBR R0 K2 R3 - 0x90020604, // 0003 SETMBR R0 K3 R4 - 0x6018000F, // 0004 GETGBL R6 G15 - 0x881C0104, // 0005 GETMBR R7 R0 K4 - 0x60200012, // 0006 GETGBL R8 G18 - 0x7C180400, // 0007 CALL R6 2 - 0x781A0001, // 0008 JMPF R6 #000B - 0x90020805, // 0009 SETMBR R0 K4 R5 - 0x70020002, // 000A JMP #000E - 0x60180012, // 000B GETGBL R6 G18 - 0x7C180000, // 000C CALL R6 0 - 0x90020806, // 000D SETMBR R0 K4 R6 - 0x80000000, // 000E RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: tostring -********************************************************************/ -be_local_closure(zcl_attributes_tostring, /* name */ - be_nested_proto( - 10, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[19]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(json), - /* K2 */ be_nested_str_weak(shortaddr), - /* K3 */ be_nested_str_weak(push), - /* K4 */ be_nested_str_weak(format), - /* K5 */ be_nested_str_weak(_X22Device_X22_X3A_X220x_X2504X_X22), - /* K6 */ be_nested_str_weak(_X22Group_X22_X3A_X220x_X2504X_X22), - /* K7 */ be_nested_str_weak(groupaddr), - /* K8 */ be_nested_str_weak(attr_list), - /* K9 */ be_nested_str_weak(tostring), - /* K10 */ be_nested_str_weak(stop_iteration), - /* K11 */ be_nested_str_weak(src_ep), - /* K12 */ be_nested_str_weak(_X22Endpoint_X22_X3A_X25i), - /* K13 */ be_nested_str_weak(lqi), - /* K14 */ be_nested_str_weak(_X22LinkQuality_X22_X3A_X25i), - /* K15 */ be_nested_str_weak(_X7B), - /* K16 */ be_nested_str_weak(concat), - /* K17 */ be_nested_str_weak(_X2C), - /* K18 */ be_nested_str_weak(_X7D), - }), - be_str_weak(tostring), - &be_const_str_solidified, - ( &(const binstruction[64]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0xA40A0200, // 0001 IMPORT R2 K1 - 0x600C0012, // 0002 GETGBL R3 G18 - 0x7C0C0000, // 0003 CALL R3 0 - 0x88100102, // 0004 GETMBR R4 R0 K2 - 0x4C140000, // 0005 LDNIL R5 - 0x20100805, // 0006 NE R4 R4 R5 - 0x78120005, // 0007 JMPF R4 #000E - 0x8C100703, // 0008 GETMET R4 R3 K3 - 0x8C180304, // 0009 GETMET R6 R1 K4 - 0x58200005, // 000A LDCONST R8 K5 - 0x88240102, // 000B GETMBR R9 R0 K2 - 0x7C180600, // 000C CALL R6 3 - 0x7C100400, // 000D CALL R4 2 - 0x88100102, // 000E GETMBR R4 R0 K2 - 0x4C140000, // 000F LDNIL R5 - 0x20100805, // 0010 NE R4 R4 R5 - 0x78120005, // 0011 JMPF R4 #0018 - 0x8C100703, // 0012 GETMET R4 R3 K3 - 0x8C180304, // 0013 GETMET R6 R1 K4 - 0x58200006, // 0014 LDCONST R8 K6 - 0x88240107, // 0015 GETMBR R9 R0 K7 - 0x7C180600, // 0016 CALL R6 3 - 0x7C100400, // 0017 CALL R4 2 - 0x60100010, // 0018 GETGBL R4 G16 - 0x88140108, // 0019 GETMBR R5 R0 K8 - 0x7C100200, // 001A CALL R4 1 - 0xA8020006, // 001B EXBLK 0 #0023 - 0x5C140800, // 001C MOVE R5 R4 - 0x7C140000, // 001D CALL R5 0 - 0x8C180703, // 001E GETMET R6 R3 K3 - 0x8C200B09, // 001F GETMET R8 R5 K9 - 0x7C200200, // 0020 CALL R8 1 - 0x7C180400, // 0021 CALL R6 2 - 0x7001FFF8, // 0022 JMP #001C - 0x5810000A, // 0023 LDCONST R4 K10 - 0xAC100200, // 0024 CATCH R4 1 0 - 0xB0080000, // 0025 RAISE 2 R0 R0 - 0x8810010B, // 0026 GETMBR R4 R0 K11 - 0x4C140000, // 0027 LDNIL R5 - 0x20100805, // 0028 NE R4 R4 R5 - 0x78120005, // 0029 JMPF R4 #0030 - 0x8C100703, // 002A GETMET R4 R3 K3 - 0x8C180304, // 002B GETMET R6 R1 K4 - 0x5820000C, // 002C LDCONST R8 K12 - 0x8824010B, // 002D GETMBR R9 R0 K11 - 0x7C180600, // 002E CALL R6 3 - 0x7C100400, // 002F CALL R4 2 - 0x8810010D, // 0030 GETMBR R4 R0 K13 - 0x4C140000, // 0031 LDNIL R5 - 0x20100805, // 0032 NE R4 R4 R5 - 0x78120005, // 0033 JMPF R4 #003A - 0x8C100703, // 0034 GETMET R4 R3 K3 - 0x8C180304, // 0035 GETMET R6 R1 K4 - 0x5820000E, // 0036 LDCONST R8 K14 - 0x8824010D, // 0037 GETMBR R9 R0 K13 - 0x7C180600, // 0038 CALL R6 3 - 0x7C100400, // 0039 CALL R4 2 - 0x8C100710, // 003A GETMET R4 R3 K16 - 0x58180011, // 003B LDCONST R6 K17 - 0x7C100400, // 003C CALL R4 2 - 0x00121E04, // 003D ADD R4 K15 R4 - 0x00100912, // 003E ADD R4 R4 K18 - 0x80040800, // 003F RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: push -********************************************************************/ -be_local_closure(zcl_attributes_push, /* name */ - be_nested_proto( - 5, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_weak(attr_list), - /* K1 */ be_nested_str_weak(push), - }), - be_str_weak(push), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x5C100200, // 0002 MOVE R4 R1 - 0x7C080400, // 0003 CALL R2 2 - 0x80000000, // 0004 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: zcl_attributes -********************************************************************/ -be_local_class(zcl_attributes, - 5, - NULL, - be_nested_map(8, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(groupaddr, 6), be_const_var(1) }, - { be_const_key_weak(push, 4), be_const_closure(zcl_attributes_push_closure) }, - { be_const_key_weak(shortaddr, -1), be_const_var(0) }, - { be_const_key_weak(init, -1), be_const_closure(zcl_attributes_init_closure) }, - { be_const_key_weak(tostring, -1), be_const_closure(zcl_attributes_tostring_closure) }, - { be_const_key_weak(lqi, 1), be_const_var(2) }, - { be_const_key_weak(attr_list, -1), be_const_var(4) }, - { be_const_key_weak(src_ep, 0), be_const_var(3) }, - })), - be_str_weak(zcl_attributes) -); -/*******************************************************************/ - -void be_load_zcl_attributes_class(bvm *vm) { - be_pushntvclass(vm, &be_class_zcl_attributes); - be_setglobal(vm, "zcl_attributes"); - be_pop(vm, 1); -} /********************************************************************/ /* End of solidification */ diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee_zcl_frame.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee_zcl_frame.h index f979a30661da..33405b7c1bf1 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee_zcl_frame.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_zigbee_zcl_frame.h @@ -135,7 +135,7 @@ be_local_closure(zcl_frame_init, /* name */ ********************************************************************/ be_local_closure(zcl_frame_tomap, /* name */ be_nested_proto( - 7, /* nstack */ + 5, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -143,32 +143,29 @@ be_local_closure(zcl_frame_tomap, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str_weak(string), - /* K1 */ be_nested_str_weak(tomap), - /* K2 */ be_nested_str_weak(shortaddr_hex), - /* K3 */ be_nested_str_weak(format), - /* K4 */ be_nested_str_weak(0x_X2504X), - /* K5 */ be_nested_str_weak(shortaddr), - /* K6 */ be_nested_str_weak(payload), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_weak(tomap), + /* K1 */ be_nested_str_weak(shortaddr_hex), + /* K2 */ be_nested_str_weak(0x_X2504X), + /* K3 */ be_nested_str_weak(shortaddr), + /* K4 */ be_nested_str_weak(payload), }), be_str_weak(tomap), &be_const_str_solidified, - ( &(const binstruction[14]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x60080003, // 0001 GETGBL R2 G3 - 0x5C0C0000, // 0002 MOVE R3 R0 - 0x7C080200, // 0003 CALL R2 1 - 0x8C080501, // 0004 GETMET R2 R2 K1 - 0x7C080200, // 0005 CALL R2 1 - 0x8C0C0303, // 0006 GETMET R3 R1 K3 - 0x58140004, // 0007 LDCONST R5 K4 - 0x88180105, // 0008 GETMBR R6 R0 K5 - 0x7C0C0600, // 0009 CALL R3 3 - 0x980A0403, // 000A SETIDX R2 K2 R3 - 0x880C0106, // 000B GETMBR R3 R0 K6 - 0x980A0C03, // 000C SETIDX R2 K6 R3 - 0x80040400, // 000D RET 1 R2 + ( &(const binstruction[13]) { /* code */ + 0x60040003, // 0000 GETGBL R1 G3 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x8C040300, // 0003 GETMET R1 R1 K0 + 0x7C040200, // 0004 CALL R1 1 + 0x60080018, // 0005 GETGBL R2 G24 + 0x580C0002, // 0006 LDCONST R3 K2 + 0x88100103, // 0007 GETMBR R4 R0 K3 + 0x7C080400, // 0008 CALL R2 2 + 0x98060202, // 0009 SETIDX R1 K1 R2 + 0x88080104, // 000A GETMBR R2 R0 K4 + 0x98060802, // 000B SETIDX R1 K4 R2 + 0x80040200, // 000C RET 1 R1 }) ) ); diff --git a/lib/libesp32/lib_mail/.github/FUNDING.yml b/lib/libesp32/lib_mail/.github/FUNDING.yml deleted file mode 100644 index c6f438926514..000000000000 --- a/lib/libesp32/lib_mail/.github/FUNDING.yml +++ /dev/null @@ -1,12 +0,0 @@ -# These are supported funding model platforms - -github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: ["https://www.paypal.me/mobizt"] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/lib/libesp32/lib_mail/.github/stale.yml b/lib/libesp32/lib_mail/.github/stale.yml deleted file mode 100644 index 73494a333fd8..000000000000 --- a/lib/libesp32/lib_mail/.github/stale.yml +++ /dev/null @@ -1,17 +0,0 @@ -# Number of days of inactivity before an issue becomes stale -daysUntilStale: 20 -# Number of days of inactivity before a stale issue is closed -daysUntilClose: 5 -# Issues with these labels will never be considered stale -exemptLabels: - - pinned - - security -# Label to use when marking an issue as stale -staleLabel: wontfix -# Comment to post when marking an issue as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. -# Comment to post when closing a stale issue. Set to `false` to disable -closeComment: false diff --git a/lib/libesp32/lib_mail/README.md b/lib/libesp32/lib_mail/README.md deleted file mode 100644 index 6025aec0efae..000000000000 --- a/lib/libesp32/lib_mail/README.md +++ /dev/null @@ -1,385 +0,0 @@ -# Mail Client Arduino Library for ESP32 and ESP8266 v 1.2.0 - -[![Join the chat at https://gitter.im/mobizt/ESP_Mail_Client](https://badges.gitter.im/mobizt/ESP_Mail_Client.svg)](https://gitter.im/mobizt/ESP_Mail_Client?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -The complete and secure Mail Client for ESP32 and ESP8266 devices for sending and reading the Email through the SMTP and IMAP servers. - -With this library, the devices can both send and read the Email with many types of attachments supported and provides more reliable and flexibilities of usages. - -The library was tested and work well with ESP32s and ESP8266s based modules. - -This library was developed to replace the deprecated ESP32 Mail Client library with more options and features, better reliability and also conforms to the RFC standards. - -![ESP Mail](/media/images/esp-mail-client.svg) - -Copyright (c) 2021 K. Suwatchai (Mobizt). - -# Features - -* Support Espressif ESP32 and ESP8266 MCUs based devices. -* Support TCP session reusage. -* Support PLAIN, LOGIN and XOAUTH2 authentication mechanisms. -* Support secured (with SSL and TLS) and non-secure ports. -* Support mailbox selection for Email reading and searching. -* Support the content encodings e.g. quoted-printable and base64. -* Support the content decodings e.g. base64, UTF-8, UTF-7, quoted-printable, ISO-8859-1 (latin1) and ISO-8859-11 (Thai). -* Support many types of embedded contents e.g. inline images, attachments, parallel media attachments and RFC822 message. -* Support full debuging. -* Support flash memory and SD card for file storages which can be changed in [**ESP_Mail_FS.h**](/src/ESP_Mail_FS.h). -* Support Ethernet (ESP32 using LAN8720, TLK110 and IP101 Ethernet boards). ESP8266 Ethernet is not yet supported. -* Customizable operating configurations (see the examples for the usages) - -## Tested Devices - -This following devices were tested. - - * Sparkfun ESP32 Thing - * NodeMCU-32 - * WEMOS LOLIN32 - * TTGO T8 V1.8 - * M5Stack ESP32 - * NodeMCU ESP8266 - * Wemos D1 Mini (ESP8266) - - - -## Prerequisites - - -The library requires Arduino's ESP32 or ESP8266 Core SDK to be installed based on the platform. - -The latest Core SDK is recommended. For ESP8266, the Core SDK version 2.6.3 or later is recommended. - -The ESP8266 Core SDK version 2.5.x and earlier are not supported. - - - -## Instalation - - -Click on **Clone or download** dropdown at the top of repository, select **Download ZIP** and save file on your computer. - -From Arduino IDE, goto menu **Sketch** -> **Include Library** -> **Add .ZIP Library...** and choose **ESP-Mail-Client-master.zip** that previously downloaded. - -Go to menu **Files** -> **Examples** -> **ESP-Mail-Client-master** and choose one from examples - - - - - - -## IDE Configuaration for ESP8266 MMU - Adjust the Ratio of ICACHE to IRAM - -### Arduino IDE - -When you update the ESP8266 Arduino Core SDK to v3.0.0, the memory can be configurable from Arduino IDE board settings. - -By default MMU **option 1** was selected, the free Heap can be low and may not suitable for the SSL client usage in this library. - -To increase the Heap, choose the MMU **option 3**, 16KB cache + 48KB IRAM and 2nd Heap (shared). - -![Arduino IDE config](/media/images/ArduinoIDE.png) - - -More about MMU settings. -https://arduino-esp8266.readthedocs.io/en/latest/mmu.html - -### PlatformIO IDE - -When Core SDK v3.0.0 becomes available in PlatformIO, - -By default the balanced ratio (32KB cache + 32KB IRAM) configuration is used. - -To increase the heap, **PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED** build flag should be assigned in platformio.ini. - -At the time of writing, to update SDK to v3.0.0 you can follow these steps. - -1. In platformio.ini, edit the config as the following - -```ini -[env:d1_mini] -platform = https://github.com/platformio/platform-espressif8266.git -build_flags = -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED -board = d1_mini -framework = arduino -monitor_speed = 115200 -``` - -2. Delete this folder **C:\Users\UserName\\.platformio\platforms\espressif8266@src-?????????????** -3. Delete .pio and .vscode folders in your project. -4. Clean and Compile the project. - - - -The supportedd MMU build flags in PlatformIO. - -- **PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48** - - 16KB cache + 48KB IRAM (IRAM) - -- **PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED** - - 16KB cache + 48KB IRAM and 2nd Heap (shared) - -- **PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM32_SECHEAP_NOTSHARED** - - 16KB cache + 32KB IRAM + 16KB 2nd Heap (not shared) - -- **PIO_FRAMEWORK_ARDUINO_MMU_EXTERNAL_128K** - - 128K External 23LC1024 - -- **PIO_FRAMEWORK_ARDUINO_MMU_EXTERNAL_1024K** - - 1M External 64 MBit PSRAM - -- **PIO_FRAMEWORK_ARDUINO_MMU_CUSTOM** - - Disables default configuration and expects user-specified flags - - -### Test code for MMU - -```cpp - -#include -#include - -void setup() -{ - Serial.begin(74880); - HeapSelectIram ephemeral; - Serial.printf("IRAM free: %6d bytes\r\n", ESP.getFreeHeap()); - { - HeapSelectDram ephemeral; - Serial.printf("DRAM free: %6d bytes\r\n", ESP.getFreeHeap()); - } -} - -void loop() { - // put your main code here, to run repeatedly: -} - -``` - - - - - - -## Usage - - -See [Full Examples](/examples) for complete usages. - -See [Function Description](/src/README.md) for all available functions. - - -The following examples showed the minimum usage which many options are not configured. - -The examples in the examples folder provide the full options usages. - -## Notes - -The string in the function's parameters or properties of structured data is the pointer to constant char or char array. - -You need to assign the string literal or char array or pointer to constant char to it. - -#### Ex. - -```cpp -message.sender.name = "My Mail"; -message.sender.email = "sender or your Email address"; -``` - -Or using String class - -```cpp -String name = "John"; -String email = "john@mail.com"; - -message.sender.name = name.c_str(); -message.sender.email = email.c_str(); -``` - - - - -### Send the Email - - -```C++ - -// Include ESP Mail Client library (this library) -#include - - -// Define the SMTP Session object which used for SMTP transsport -SMTPSession smtp; - -// Define the session config data which used to store the TCP session configuration -ESP_Mail_Session session; - -// Set the session config -session.server.host_name = "smtp.office365.com"; //for outlook.com -session.server.port = 587; -session.login.email = "your Email address"; //set to empty for no SMTP Authentication -session.login.password = "your Email password"; //set to empty for no SMTP Authentication -session.login.user_domain = "client domain or ip e.g. mydomain.com"; - -// Define the SMTP_Message class variable to handle to message being transport -SMTP_Message message; - -// Set the message headers -message.sender.name = "My Mail"; -message.sender.email = "sender or your Email address"; -message.subject = "Test sending Email"; -message.addRecipient("name1", "email1"); -message.addRecipient("name2", "email2"); - -message.addCc("email3"); -message.addBcc("email4"); - -// Set the message content -message.text.content = "This is simple plain text message"; - -//Base64 data of image -const char *greenImg = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAoUlEQVR42u3RAQ0AMAgAoJviyWxtAtNYwzmoQGT/eqwRQoQgRAhChCBECEKECBGCECEIEYIQIQgRghCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCBGCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQghAhCBGCECEIEYIQIUKEIEQIQoQg5LoBBaDPbQYiMoMAAAAASUVORK5CYII="; - -// Define the attachment data -SMTP_Attachment att; - -// Set the attatchment info -att.descr.filename = "green.png"; -att.descr.mime = "image/png"; -att.blob.data = (uint8_t *)greenImg; -att.blob.size = strlen(greenImg); -// Set the transfer encoding to base64 -att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; -// We set the content encoding to match the above greenImage data -att.descr.content_encoding = Content_Transfer_Encoding::enc_base64; - -// Add attachment to the message -message.addAttachment(att); - -// Connect to server with the session config -smtp.connect(&session); - -// Start sending Email and close the session -if (!MailClient.sendMail(&smtp, &message)) - Serial.println("Error sending Email, " + smtp.errorReason()); - - -``` - - -### Read the Email - - -```C++ - -// Include ESP Mail Client library (this library) -#include - - -// Define the IMAP Session object which used for IMAP transsport -IMAP_Config config; - - -// Define the session config data which used to store the TCP session configuration -ESP_Mail_Session session; - -// Set the session config -session.server.host_name = "outlook.office365.com"; //for outlook.com -session.server.port = 993; -session.login.email = "your Email address"; -session.login.password = "your Email password"; - -// Define the config class variable for searching or fetching operation and store the messsagess data -IMAP_Config config; - -// Define the message UID which required to fetch or read the message -config.fetch.uid = "100"; - -// Define the empty search criteria to disable the messsage search -config.search.criteria = ""; - -// Set to enable the message content which will be stored in the IMAP_Config data -config.enable.html = true; -config.enable.text = true; - - -// Connect to the server with the defined session and options -imap.connect(&session, &config); - -// Open or select the mailbox folder to read the message -imap.selectFolder("INBOX"); - - -// Read the Email and close the session -MailClient.readMail(&imap); - - -// Get the message(s) list -IMAP_MSG_List msgList = imap.data(); - -for (size_t i = 0; i < msgList.msgItems.size(); i++) -{ - // Iterate to get each message data through the message item data - IMAP_MSG_Item msg = msgList.msgItems[i]; - - Serial.println("################################"); - Serial.printf("Messsage Number: %s\n", msg.msgNo); - Serial.printf("Messsage UID: %s\n", msg.UID); - Serial.printf("Messsage ID: %s\n", msg.ID); - Serial.printf("Accept Language: %s\n", msg.acceptLang); - Serial.printf("Content Language: %s\n", msg.contentLang); - Serial.printf("From: %s\n", msg.from); - Serial.printf("From Charset: %s\n", msg.fromCharset); - Serial.printf("To: %s\n", msg.to); - Serial.printf("To Charset: %s\n", msg.toCharset); - Serial.printf("CC: %s\n", msg.cc); - Serial.printf("CC Charset: %s\n", msg.ccCharset); - Serial.printf("Date: %s\n", msg.date); - Serial.printf("Subject: %s\n", msg.subject); - Serial.printf("Subject Charset: %s\n", msg.subjectCharset); - - // If the message body is available - if (!imap.headerOnly()) - { - Serial.printf("Text Message: %s\n", msg.text.content); - Serial.printf("Text Message Charset: %s\n", msg.text.charSet); - Serial.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - Serial.printf("HTML Message: %s\n", msg.html.content); - Serial.printf("HTML Message Charset: %s\n", msg.html.charSet); - Serial.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - } -} - -``` - - - -## License - -The MIT License (MIT) - -Copyright (c) 2021 K. Suwatchai (Mobizt) - - -Permission is hereby granted, free of charge, to any person returning a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/libesp32/lib_mail/examples/Copy_Messages/Copy_Messsages.ino b/lib/libesp32/lib_mail/examples/Copy_Messages/Copy_Messsages.ino deleted file mode 100644 index 539a0956ac3a..000000000000 --- a/lib/libesp32/lib_mail/examples/Copy_Messages/Copy_Messsages.ino +++ /dev/null @@ -1,147 +0,0 @@ -/** - * This example showed how to copy messages from the opened mailbox folder to other folder. - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -/** To receive Email using Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * -*/ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. -*/ - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "################" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 -*/ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(IMAPSession &imap); - -/* The IMAP Session object used for Email reading */ -IMAPSession imap; - - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - imap.debug(1); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /* Set the session config */ - session.server.host_name = IMAP_HOST; - session.server.port = IMAP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - - - /* Setup the configuration for searching or fetching operation and its result */ - IMAP_Config config; - - /* Connect to server with the session and config */ - if (!imap.connect(&session, &config)) - return; - - /* {Optional] */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder("INBOX")) - return; - - /* Define the MessageList class to add the message to copy */ - MessageList toCopy; - - /* Add message uid to copy to the list */ - toCopy.add(3); - toCopy.add(4); - - //imap.createFolder("test"); - - /* Copy all messages in the list to the folder "test" */ - if (imap.deleteMessages(&toCopy, "test")) - Serial.println("Messages copied"); - - /* Delete all messages in the list from the opened folder (move to trash) */ - //imap.deleteMessages(&toCopy); - - //imap.deleteolder("test"); -} - -void loop() -{ - -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - Serial.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} diff --git a/lib/libesp32/lib_mail/examples/Delete_Messages/Delete_Messsages.ino b/lib/libesp32/lib_mail/examples/Delete_Messages/Delete_Messsages.ino deleted file mode 100644 index f52e3c708b29..000000000000 --- a/lib/libesp32/lib_mail/examples/Delete_Messages/Delete_Messsages.ino +++ /dev/null @@ -1,142 +0,0 @@ -/** - * This example showed how to delete messages from the opened mailbox folder. - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -/** To receive Email using Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * -*/ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. -*/ - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "################" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 -*/ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(IMAPSession &imap); - -/* The IMAP Session object used for Email reading */ -IMAPSession imap; - - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - imap.debug(1); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /* Set the session config */ - session.server.host_name = IMAP_HOST; - session.server.port = IMAP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - - - /* Setup the configuration for searching or fetching operation and its result */ - IMAP_Config config; - - /* Connect to server with the session and config */ - if (!imap.connect(&session, &config)) - return; - - /* {Optional] */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder("INBOX")) - return; - - /* Define the MessageList class to add the message to delete */ - MessageList toDelete; - /* Add message uid to delete to the list */ - toDelete.add(10); - toDelete.add(12); - - /* Delete all messages in the list (move to trash) */ - if(imap.deleteMessages(&toDelete)) - Serial.println("Messages deeted"); - - /* Delete all messages permanently by assign the second param to true*/ - //imap.deleteMessages(&toDelete, true); -} - -void loop() -{ - -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - Serial.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} diff --git a/lib/libesp32/lib_mail/examples/ESP32_Ethernet_Send_Text/ESP32_Ethernet_Send_Text.ino b/lib/libesp32/lib_mail/examples/ESP32_Ethernet_Send_Text/ESP32_Ethernet_Send_Text.ino deleted file mode 100644 index 3dc3192deca0..000000000000 --- a/lib/libesp32/lib_mail/examples/ESP32_Ethernet_Send_Text/ESP32_Ethernet_Send_Text.ino +++ /dev/null @@ -1,307 +0,0 @@ - - -/** - * This example will send the Email in plain text version using ESP32 and LAN8720 Ethernet module. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -/** - * There are many sources for LAN8720 and ESP32 interconnection on the internet which may - * work for your LAN8720 board. - * - * Some methods worked unless no IP is available. - * - * This modification and interconnection provided in this example are mostly worked as - * the 50 MHz clock was created internally in ESP32 which GPIO 17 is set to be output of this clock - * and feeds to the LAN8720 chip XTAL input. - * - * The on-board LAN8720 50 MHz XTAL chip will be disabled by connect its enable pin or pin 1 to GND. - * - * Please see the images in the folder "modified_LAN8720_board_images" for how to modify the LAN8720 board. - * - * The LAN8720 Ethernet modified board and ESP32 board wiring connection. - * - * ESP32 LAN8720 - * - * GPIO17 - EMAC_CLK_OUT_180 nINT/REFCLK - LAN8720 XTAL1/CLKIN 4k7 Pulldown - * GPIO22 - EMAC_TXD1 TX1 - * GPIO19 - EMAC_TXD0 TX0 - * GPIO21 - EMAC_TX_EN TX_EN - * GPIO26 - EMAC_RXD1 RX1 - * GPIO25 - EMAC_RXD0 RX0 - * GPIO27 - EMAC_RX_DV CRS - * GPIO23 - MDC MDC - * GPIO18 - MDIO MDIO - * GND GND - * 3V3 VCC - * -*/ - -//In case of Gmail, to send the Email via port 465 (SSL), less secure app option should be enabled in the account settings. https://myaccount.google.com/lesssecureapps?pli=1 - -#include -#include - -#ifdef ETH_CLK_MODE -#undef ETH_CLK_MODE -#endif -#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT //RMII clock output from GPIO17 - -// Pin# of the enable signal for the external crystal oscillator (-1 to disable) -#define ETH_POWER_PIN -1 - -// Type of the Ethernet PHY (LAN8720 or TLK110) -#define ETH_TYPE ETH_PHY_LAN8720 - -// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110) -#define ETH_ADDR 1 - -// Pin# of the I²C clock signal for the Ethernet PHY -#define ETH_MDC_PIN 23 - -// Pin# of the I²C IO signal for the Ethernet PHY -#define ETH_MDIO_PIN 18 - -static bool eth_connected = false; - - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com - * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * and use the app password as password with your yahoo mail account to login. - * The google app password signin is also available https://support.google.com/mail/answer/185833?hl=en -*/ -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT 25 - -/* The sign in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -unsigned long sendMillis = 0; - -void WiFiEvent(WiFiEvent_t event) -{ - //Do not run any function here to prevent stack overflow or nested interrupt - switch (event) - { - case SYSTEM_EVENT_ETH_START: - Serial.println("ETH Started"); - //set eth hostname here - ETH.setHostname("esp32-ethernet"); - - break; - case SYSTEM_EVENT_ETH_CONNECTED: - Serial.println("ETH Connected"); - break; - case SYSTEM_EVENT_ETH_GOT_IP: - Serial.print("ETH MAC: "); - Serial.print(ETH.macAddress()); - Serial.print(", IPv4: "); - Serial.print(ETH.localIP()); - if (ETH.fullDuplex()) - { - Serial.print(", FULL_DUPLEX"); - } - Serial.print(", "); - Serial.print(ETH.linkSpeed()); - Serial.println("Mbps"); - eth_connected = true; - - break; - case SYSTEM_EVENT_ETH_DISCONNECTED: - Serial.println("ETH Disconnected"); - eth_connected = false; - break; - case SYSTEM_EVENT_ETH_STOP: - Serial.println("ETH Stopped"); - eth_connected = false; - break; - default: - break; - } -} - -void sendMail() -{ - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /** ######################################################## - * Some properties of SMTPSession data and parameters pass to - * SMTP_Message class accept the pointer to constant char - * i.e. const char*. - * - * You may assign a string literal to that properties or function - * like below example. - * - * session.login.user_domain = "mydomain.net"; - * session.login.user_domain = String("mydomain.net").c_str(); - * - * or - * - * String doman = "mydomain.net"; - * session.login.user_domain = domain.c_str(); - * - * And - * - * String name = "Jack " + String("dawson"); - * String email = "jack_dawson" + String(123) + "@mail.com"; - * - * message.addRecipient(name.c_str(), email.c_str()); - * - * message.addHeader(String("Message-ID: ").c_str()); - * - * or - * - * String header = "Message-ID: "; - * message.addHeader(header.c_str()); - * - * ########################################################### - */ - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - message.subject = "Test sending plain text Email"; - message.addRecipient("Someone", "####@#####_dot_com"); - - String textMsg = "This is simple plain text message"; - message.text.content = textMsg.c_str(); - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = "us-ascii"; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void setup() -{ - Serial.begin(115200); - Serial.println(); - - WiFi.onEvent(WiFiEvent); - - ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE); -} - -void loop() -{ - if (eth_connected && (millis() - sendMillis > 300000 || sendMillis == 0)) - { - sendMillis = millis(); - sendMail(); - } -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Read_Email_Access_Token/Read_Email_Access_Token.ino b/lib/libesp32/lib_mail/examples/Read_Email_Access_Token/Read_Email_Access_Token.ino deleted file mode 100644 index 6778e6cbe6aa..000000000000 --- a/lib/libesp32/lib_mail/examples/Read_Email_Access_Token/Read_Email_Access_Token.ino +++ /dev/null @@ -1,370 +0,0 @@ -/** - * This example will log in with the SASL XOAUTH2 mechanisme using OAuth2.0 access token. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -/** To receive Email using Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * -*/ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. -*/ - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "################" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 -*/ -#define IMAP_PORT 993 - -/* The user Email for OAuth2.0 access token */ -#define AUTHOR_EMAIL "################" - -/** The OAuth2.0 access token - * The generation, exchange and refresh of the access token are not available - * in this library. - * - * To test this using GMail, get the OAuth2.0 access token from this web site - * https://developers.google.com/oauthplayground/ - * - * 1. Select the following scope (in Step 1) from Gmail API V1 - * https://mail.google.com/ - * https://mail.google.com/ - * - * 2. Click Authorize APIs button. - * 3. Cick Exchangeauthorization code for tokens. - * 4. From the response, look at access_token from the JSON payload node. - * 5. Copy that access token and paste to the AUTHOR_ACCESS_TOKEN value. - * - * The token will be expired in 3600 seconds (1 Hr). - * The AUTHOR_EMAIL above is the Email address that you granted to access the Gmail services. -*/ -#define AUTHOR_ACCESS_TOKEN "################" - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(IMAPSession &imap); - -/* Print all messages from the message list */ -void printMessages(IMAPSession &imap); - -/* Print all rfc822 messages included in the message */ -void printRFC822Messages(IMAP_MSG_Item &msg); - -/* Print all attachments info from the message */ -void printAttacements(IMAP_MSG_Item &msg); - -/* The IMAP Session object used for Email reading */ -IMAPSession imap; - - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Declare the session config data */ - ESP_Mail_Session session; - - /* Set the session config */ - session.server.host_name = IMAP_HOST; - session.server.port = IMAP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.accessToken = AUTHOR_ACCESS_TOKEN; - - - /* Setup the configuration for searching or fetching operation and its result */ - IMAP_Config config; - - /* Message UID to fetch or read e.g. 100 */ - config.fetch.uid = "100"; - - /* Set seen flag*/ - //config.fetch.set_seen = true; - - /* Search criteria */ - config.search.criteria = ""; - - /* Also search the unseen message */ - config.search.unseen_msg = true; - - /* Set the storage to save the downloaded files and attachments */ - config.storage.saved_path = "/email_data"; - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - config.storage.type = esp_mail_file_storage_type_flash; - - /** Set to download heades, text and html messaeges, - * attachments and inline images respectively. - */ - config.download.header = true; - config.download.text = true; - config.download.html = true; - config.download.attachment = true; - config.download.inlineImg = true; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option config.limit.msg_size. - * The whole message can be download through config.download.text - * or config.download.html which not depends on these enable options. - */ - config.enable.html = true; - config.enable.text = true; - - /* Set to enable the sort the result by message UID in the ascending order */ - config.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - config.enable.download_status = true; - - /* Set the limit of number of messages in the search results */ - config.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - config.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - config.limit.attachment_size = 1024 * 1024 * 5; - - - /* Connect to server with the session and config */ - if (!imap.connect(&session, &config)) - return; - - /* {Optional] */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder("INBOX")) - return; - - /* {Optional] */ - printSelectedMailboxInfo(imap); - - /* Read or search the Email and close the session */ - MailClient.readMail(&imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); -} - -void loop() -{ - -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - printMessages(imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - Serial.printf("Free Heap: %d", ESP.getFreeHeap()); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - Serial.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(IMAPSession &imap) -{ - /* Declare the selected folder info class to get the info of selected mailbox folder */ - SelectedFolderInfo sFolder = imap.selectedFolder(); - - /* Show the mailbox info */ - Serial.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - Serial.printf("Predicted next UID: %d\n", sFolder.nextUID()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - Serial.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); -} - -void printRFC822Messages(IMAP_MSG_Item &msg) -{ - Serial.printf("RFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - for (size_t j = 0; j < msg.rfc822.size(); j++) - { - IMAP_MSG_Item rfc822 = msg.rfc822[j]; - Serial.printf("%d. \n", j + 1); - Serial.printf("Messsage ID: %s\n", rfc822.messageID); - Serial.printf("From: %s\n", rfc822.from); - Serial.printf("Sender: %s\n", rfc822.sender); - Serial.printf("To: %s\n", rfc822.to); - Serial.printf("CC: %s\n", rfc822.cc); - Serial.printf("Subject: %s\n", rfc822.subject); - Serial.printf("Date: %s\n", rfc822.date); - Serial.printf("Reply-To: %s\n", rfc822.reply_to); - Serial.printf("Return-Path: %s\n", rfc822.return_path); - Serial.printf("Comment: %s\n", rfc822.comment); - Serial.printf("Keyword: %s\n", rfc822.keyword); - Serial.printf("Text Message: %s\n", rfc822.text.content); - Serial.printf("Text Message Charset: %s\n", rfc822.text.charSet); - Serial.printf("Text Message Transfer Encoding: %s\n", rfc822.text.transfer_encoding); - Serial.printf("HTML Message: %s\n", rfc822.html.content); - Serial.printf("HTML Message Charset: %s\n", rfc822.html.charSet); - Serial.printf("HTML Message Transfer Encoding: %s\n\n", rfc822.html.transfer_encoding); - - if (rfc822.attachments.size() > 0) - printAttacements(rfc822); - } -} - -void printAttacements(IMAP_MSG_Item &msg) -{ - Serial.printf("Attachment: %d file(s)\n****************************\n", msg.attachments.size()); - for (size_t j = 0; j < msg.attachments.size(); j++) - { - IMAP_Attach_Item att = msg.attachments[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - Serial.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.creationDate); - } - Serial.println(); -} - -void printMessages(IMAPSession &imap) -{ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - - for (size_t i = 0; i < msgList.msgItems.size(); i++) - { - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgList.msgItems[i]; - - Serial.println("################################"); - Serial.printf("Messsage Number: %s\n", msg.msgNo); - Serial.printf("Messsage UID: %s\n", msg.UID); - Serial.printf("Messsage ID: %s\n", msg.ID); - Serial.printf("Accept Language: %s\n", msg.acceptLang); - Serial.printf("Content Language: %s\n", msg.contentLang); - Serial.printf("From: %s\n", msg.from); - Serial.printf("From Charset: %s\n", msg.fromCharset); - Serial.printf("To: %s\n", msg.to); - Serial.printf("To Charset: %s\n", msg.toCharset); - Serial.printf("CC: %s\n", msg.cc); - Serial.printf("CC Charset: %s\n", msg.ccCharset); - Serial.printf("Date: %s\n", msg.date); - Serial.printf("Subject: %s\n", msg.subject); - Serial.printf("Subject Charset: %s\n", msg.subjectCharset); - - /* If the result contains the message info (Fetch mode) */ - if (!imap.headerOnly()) - { - Serial.printf("Text Message: %s\n", msg.text.content); - Serial.printf("Text Message Charset: %s\n", msg.text.charSet); - Serial.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - Serial.printf("HTML Message: %s\n", msg.html.content); - Serial.printf("HTML Message Charset: %s\n", msg.html.charSet); - Serial.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.attachments.size() > 0) - printAttacements(msg); - - if (msg.rfc822.size() > 0) - printRFC822Messages(msg); - } - - Serial.println(); - } -} diff --git a/lib/libesp32/lib_mail/examples/Read_Single_Email/Read_Single_Email.ino b/lib/libesp32/lib_mail/examples/Read_Single_Email/Read_Single_Email.ino deleted file mode 100644 index 31fa6348c3b4..000000000000 --- a/lib/libesp32/lib_mail/examples/Read_Single_Email/Read_Single_Email.ino +++ /dev/null @@ -1,364 +0,0 @@ -/** - * This example will fetch or read the Email which the known message UID - * was used for fetching. - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -/** To receive Email using Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * -*/ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. -*/ - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "################" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 -*/ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(IMAPSession &imap); - -/* Print all messages from the message list */ -void printMessages(IMAPSession &imap); - -/* Print all rfc822 messages included in the message */ -void printRFC822Messages(IMAP_MSG_Item &msg); - -/* Print all attachments info from the message */ -void printAttacements(IMAP_MSG_Item &msg); - -/* The IMAP Session object used for Email reading */ -IMAPSession imap; - - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Declare the session config data */ - ESP_Mail_Session session; - - /** ######################################################## - * Some properties of IMAP_Config and ESP_Mail_Session data - * accept the pointer to constant char i.e. const char*. - * - * You may assign a string literal to that properties like - * below example. - * - * config.storage.saved_path = String("/email_data").c_str(); - * - * String folder = "INBOX"; - * imap.selectFolder(folder.c_str()); - * - * ########################################################### - */ - - /* Set the session config */ - session.server.host_name = IMAP_HOST; - session.server.port = IMAP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - - - /* Setup the configuration for searching or fetching operation and its result */ - IMAP_Config config; - - /* Message UID to fetch or read e.g. 100 */ - config.fetch.uid = "100"; - - /* Set seen flag */ - //config.fetch.set_seen = true; - - /* Search criteria */ - config.search.criteria = ""; - - /* Also search the unseen message */ - config.search.unseen_msg = true; - - /* Set the storage to save the downloaded files and attachments */ - config.storage.saved_path = "/email_data"; - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - config.storage.type = esp_mail_file_storage_type_flash; - - /** Set to download heades, text and html messaeges, - * attachments and inline images respectively. - */ - config.download.header = true; - config.download.text = true; - config.download.html = true; - config.download.attachment = true; - config.download.inlineImg = true; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option config.limit.msg_size. - * The whole message can be download through config.download.text - * or config.download.html which not depends on these enable options. - */ - config.enable.html = true; - config.enable.text = true; - - /* Set to enable the sort the result by message UID in the ascending order */ - config.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - config.enable.download_status = true; - - /* Set the limit of number of messages in the search results */ - config.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - config.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - config.limit.attachment_size = 1024 * 1024 * 5; - - - /* Connect to server with the session and config */ - if (!imap.connect(&session, &config)) - return; - - /* {Optional] */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder("INBOX")) - return; - - /* {Optional] */ - printSelectedMailboxInfo(imap); - - /* Read or search the Email and close the session */ - MailClient.readMail(&imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); -} - -void loop() -{ - -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - printMessages(imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - Serial.printf("Free Heap: %d", ESP.getFreeHeap()); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - Serial.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(IMAPSession &imap) -{ - /* Declare the selected folder info class to get the info of selected mailbox folder */ - SelectedFolderInfo sFolder = imap.selectedFolder(); - - /* Show the mailbox info */ - Serial.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - Serial.printf("Predicted next UID: %d\n", sFolder.nextUID()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - Serial.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); -} - -void printRFC822Messages(IMAP_MSG_Item &msg) -{ - Serial.printf("RFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - for (size_t j = 0; j < msg.rfc822.size(); j++) - { - IMAP_MSG_Item rfc822 = msg.rfc822[j]; - Serial.printf("%d. \n", j + 1); - Serial.printf("Messsage ID: %s\n", rfc822.messageID); - Serial.printf("From: %s\n", rfc822.from); - Serial.printf("Sender: %s\n", rfc822.sender); - Serial.printf("To: %s\n", rfc822.to); - Serial.printf("CC: %s\n", rfc822.cc); - Serial.printf("Subject: %s\n", rfc822.subject); - Serial.printf("Date: %s\n", rfc822.date); - Serial.printf("Reply-To: %s\n", rfc822.reply_to); - Serial.printf("Return-Path: %s\n", rfc822.return_path); - Serial.printf("Comment: %s\n", rfc822.comment); - Serial.printf("Keyword: %s\n", rfc822.keyword); - Serial.printf("Text Message: %s\n", rfc822.text.content); - Serial.printf("Text Message Charset: %s\n", rfc822.text.charSet); - Serial.printf("Text Message Transfer Encoding: %s\n", rfc822.text.transfer_encoding); - Serial.printf("HTML Message: %s\n", rfc822.html.content); - Serial.printf("HTML Message Charset: %s\n", rfc822.html.charSet); - Serial.printf("HTML Message Transfer Encoding: %s\n\n", rfc822.html.transfer_encoding); - - if (rfc822.attachments.size() > 0) - printAttacements(rfc822); - } -} - -void printAttacements(IMAP_MSG_Item &msg) -{ - Serial.printf("Attachment: %d file(s)\n****************************\n", msg.attachments.size()); - for (size_t j = 0; j < msg.attachments.size(); j++) - { - IMAP_Attach_Item att = msg.attachments[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - Serial.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.creationDate); - } - Serial.println(); -} - -void printMessages(IMAPSession &imap) -{ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - - for (size_t i = 0; i < msgList.msgItems.size(); i++) - { - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgList.msgItems[i]; - - Serial.println("################################"); - Serial.printf("Messsage Number: %s\n", msg.msgNo); - Serial.printf("Messsage UID: %s\n", msg.UID); - Serial.printf("Messsage ID: %s\n", msg.ID); - Serial.printf("Accept Language: %s\n", msg.acceptLang); - Serial.printf("Content Language: %s\n", msg.contentLang); - Serial.printf("From: %s\n", msg.from); - Serial.printf("From Charset: %s\n", msg.fromCharset); - Serial.printf("To: %s\n", msg.to); - Serial.printf("To Charset: %s\n", msg.toCharset); - Serial.printf("CC: %s\n", msg.cc); - Serial.printf("CC Charset: %s\n", msg.ccCharset); - Serial.printf("Date: %s\n", msg.date); - Serial.printf("Subject: %s\n", msg.subject); - Serial.printf("Subject Charset: %s\n", msg.subjectCharset); - - /* If the result contains the message info (Fetch mode) */ - if (!imap.headerOnly()) - { - Serial.printf("Text Message: %s\n", msg.text.content); - Serial.printf("Text Message Charset: %s\n", msg.text.charSet); - Serial.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - Serial.printf("HTML Message: %s\n", msg.html.content); - Serial.printf("HTML Message Charset: %s\n", msg.html.charSet); - Serial.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.attachments.size() > 0) - printAttacements(msg); - - if (msg.rfc822.size() > 0) - printRFC822Messages(msg); - } - - Serial.println(); - } -} diff --git a/lib/libesp32/lib_mail/examples/Read_Single_Email_Loop/Read_Single_Email_Loop.ino b/lib/libesp32/lib_mail/examples/Read_Single_Email_Loop/Read_Single_Email_Loop.ino deleted file mode 100644 index b6b484a2908a..000000000000 --- a/lib/libesp32/lib_mail/examples/Read_Single_Email_Loop/Read_Single_Email_Loop.ino +++ /dev/null @@ -1,376 +0,0 @@ -/** - * This example will repeatedly fetch or read the Email via the loop function - * using the predict next message UID as the starting count down message UID. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -/** To receive Email using Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * -*/ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. -*/ - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "################" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 -*/ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(IMAPSession &imap); - -/* Print all messages from the message list */ -void printMessages(IMAPSession &imap); - -/* Print all rfc822 messages included in the message */ -void printRFC822Messages(IMAP_MSG_Item &msg); - -/* Print all attachments info from the message */ -void printAttacements(IMAP_MSG_Item &msg); - -/* The IMAP Session object used for Email reading */ -IMAPSession imap; - -unsigned long readMillis = 0; - -int nextMsgUID = 0; -int msgUID = 0; -int sign = -1; - -/* Declare the session config data */ -ESP_Mail_Session session; - -/* Setup the configuration for searching or fetching operation and its result */ -IMAP_Config config; - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Set the session config */ - session.server.host_name = IMAP_HOST; - session.server.port = IMAP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - - - /* Message UID to fetch or read */ - config.fetch.uid = ""; - - /* Search criteria */ - config.search.criteria = ""; - - /* Also search the unseen message */ - config.search.unseen_msg = true; - - /* Set the storage to save the downloaded files and attachments */ - config.storage.saved_path = "/email_data"; - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - config.storage.type = esp_mail_file_storage_type_flash; - - /** Set to download heades, text and html messaeges, - * attachments and inline images respectively. - */ - config.download.header = false; - config.download.text = false; - config.download.html = false; - config.download.attachment = false; - config.download.inlineImg = false; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option config.limit.msg_size. - * The whole message can be download through config.download.text - * or config.download.html which not depends on these enable options. - */ - config.enable.html = true; - config.enable.text = true; - - /* Set to enable the sort the result by message UID in the ascending order */ - config.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - config.enable.download_status = true; - - /* Set the limit of number of messages in the search results */ - config.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - config.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - config.limit.attachment_size = 1024 * 1024 * 5; - - - /* Connect to server with the session and config */ - if (!imap.connect(&session, &config)) - return; - - /* {Optional] */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder("INBOX")) - return; - - /* {Optional] */ - printSelectedMailboxInfo(imap); -} - -void loop() -{ - if (millis() - readMillis > 10000 || readMillis == 0) - { - readMillis = millis(); - - if (msgUID == 0) - sign = 1; - else if (msgUID >= nextMsgUID) - sign = -1; - - msgUID += sign; - - String uid = String(msgUID); - - /* Message UID to fetch or read */ - config.fetch.uid = uid.c_str(); - - /* Set seen flag */ - //config.fetch.set_seen = true; - - /** Read or search the Email and keep the TCP session to open - * The second parameter is for close the session. - */ - MailClient.readMail(&imap, false); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - } -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - printMessages(imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - Serial.printf("Free Heap: %d", ESP.getFreeHeap()); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - Serial.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(IMAPSession &imap) -{ - /* Declare the selected folder info class to get the info of selected mailbox folder */ - SelectedFolderInfo sFolder = imap.selectedFolder(); - - nextMsgUID = sFolder.nextUID(); - msgUID = nextMsgUID; - - /* Show the mailbox info */ - Serial.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - Serial.printf("Predicted next UID: %d\n", sFolder.nextUID()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - Serial.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); -} - -void printRFC822Messages(IMAP_MSG_Item &msg) -{ - Serial.printf("RFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - for (size_t j = 0; j < msg.rfc822.size(); j++) - { - IMAP_MSG_Item rfc822 = msg.rfc822[j]; - Serial.printf("%d. \n", j + 1); - Serial.printf("Messsage ID: %s\n", rfc822.messageID); - Serial.printf("From: %s\n", rfc822.from); - Serial.printf("Sender: %s\n", rfc822.sender); - Serial.printf("To: %s\n", rfc822.to); - Serial.printf("CC: %s\n", rfc822.cc); - Serial.printf("Subject: %s\n", rfc822.subject); - Serial.printf("Date: %s\n", rfc822.date); - Serial.printf("Reply-To: %s\n", rfc822.reply_to); - Serial.printf("Return-Path: %s\n", rfc822.return_path); - Serial.printf("Comment: %s\n", rfc822.comment); - Serial.printf("Keyword: %s\n", rfc822.keyword); - Serial.printf("Text Message: %s\n", rfc822.text.content); - Serial.printf("Text Message Charset: %s\n", rfc822.text.charSet); - Serial.printf("Text Message Transfer Encoding: %s\n", rfc822.text.transfer_encoding); - Serial.printf("HTML Message: %s\n", rfc822.html.content); - Serial.printf("HTML Message Charset: %s\n", rfc822.html.charSet); - Serial.printf("HTML Message Transfer Encoding: %s\n\n", rfc822.html.transfer_encoding); - - if (rfc822.attachments.size() > 0) - printAttacements(rfc822); - } -} - -void printAttacements(IMAP_MSG_Item &msg) -{ - Serial.printf("Attachment: %d file(s)\n****************************\n", msg.attachments.size()); - for (size_t j = 0; j < msg.attachments.size(); j++) - { - IMAP_Attach_Item att = msg.attachments[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - Serial.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.creationDate); - } - Serial.println(); -} - -void printMessages(IMAPSession &imap) -{ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - - for (size_t i = 0; i < msgList.msgItems.size(); i++) - { - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgList.msgItems[i]; - - Serial.println("################################"); - Serial.printf("Messsage Number: %s\n", msg.msgNo); - Serial.printf("Messsage UID: %s\n", msg.UID); - Serial.printf("Messsage ID: %s\n", msg.ID); - Serial.printf("Accept Language: %s\n", msg.acceptLang); - Serial.printf("Content Language: %s\n", msg.contentLang); - Serial.printf("From: %s\n", msg.from); - Serial.printf("From Charset: %s\n", msg.fromCharset); - Serial.printf("To: %s\n", msg.to); - Serial.printf("To Charset: %s\n", msg.toCharset); - Serial.printf("CC: %s\n", msg.cc); - Serial.printf("CC Charset: %s\n", msg.ccCharset); - Serial.printf("Date: %s\n", msg.date); - Serial.printf("Subject: %s\n", msg.subject); - Serial.printf("Subject Charset: %s\n", msg.subjectCharset); - - /* If the result contains the message info (Fetch mode) */ - if (!imap.headerOnly()) - { - Serial.printf("Text Message: %s\n", msg.text.content); - Serial.printf("Text Message Charset: %s\n", msg.text.charSet); - Serial.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - Serial.printf("HTML Message: %s\n", msg.html.content); - Serial.printf("HTML Message Charset: %s\n", msg.html.charSet); - Serial.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.attachments.size() > 0) - printAttacements(msg); - - if (msg.rfc822.size() > 0) - printRFC822Messages(msg); - } - - Serial.println(); - } -} diff --git a/lib/libesp32/lib_mail/examples/Search_Emails/Search_Emails.ino b/lib/libesp32/lib_mail/examples/Search_Emails/Search_Emails.ino deleted file mode 100644 index e82c84b6f78b..000000000000 --- a/lib/libesp32/lib_mail/examples/Search_Emails/Search_Emails.ino +++ /dev/null @@ -1,402 +0,0 @@ -/** - * This example will search all Emails in the opened mailbox folder. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -/** To receive Email using Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * -*/ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. -*/ - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "################" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 -*/ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(IMAPSession &imap); - -/* Print all messages from the message list */ -void printMessages(IMAPSession &imap); - -/* Print all rfc822 messages included in the message */ -void printRFC822Messages(IMAP_MSG_Item &msg); - -/* Print all attachments info from the message */ -void printAttacements(IMAP_MSG_Item &msg); - -/* The IMAP Session object used for Email reading */ -IMAPSession imap; - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /** ######################################################## - * Some properties of IMAP_Config and ESP_Mail_Session data - * accept the pointer to constant char i.e. const char*. - * - * You may assign a string literal to that properties like - * below example. - * - * config.search.criteria = String("UID SEARCH ALL").c_str(); - * - * String folder = "INBOX"; - * imap.selectFolder(folder.c_str()); - * - * ########################################################### - */ - - /* Set the session config */ - session.server.host_name = IMAP_HOST; - session.server.port = IMAP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - - /* Setup the configuration for searching or fetching operation and its result */ - IMAP_Config config; - - /* Message UID to fetch or read */ - config.fetch.uid = ""; - - /** Search criteria - * - * A search key can also be a parenthesized list of one or more search keys - * (e.g., for use with the OR and NOT keys). - * - * Since IMAP protocol uses Polish notation, the search criteria which in the polish notation form can be. - * - * To search the message from "someone@email.com" with the subject "my subject" since 1 Jan 2021, your search criteria can be - * UID SEARCH (OR SUBJECT "my subject" FROM "someone@email.com") SINCE "Fri, 1 Jan 2021 21:52:25 -0800" - * - * To search the message from "mail1@domain.com" or from "mail2@domain.com", the search criteria will be - * UID SEARCH OR FROM mail1@domain.com FROM mail2@domain.com - * - * For more details on using parentheses, AND, OR and NOT search keys in search criteria. - * https://www.limilabs.com/blog/imap-search-requires-parentheses - * - * - */ - config.search.criteria = "UID SEARCH ALL"; - - /* Also search the unseen message */ - config.search.unseen_msg = true; - - /* Set the storage to save the downloaded files and attachments */ - config.storage.saved_path = "/email_data"; - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - config.storage.type = esp_mail_file_storage_type_flash; - - /** Set to download heades, text and html messaeges, - * attachments and inline images respectively. - */ - config.download.header = true; - config.download.text = true; - config.download.html = true; - config.download.attachment = true; - config.download.inlineImg = true; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option config.limit.msg_size. - * The whole message can be download through config.download.text - * or config.download.html which not depends on these enable options. - */ - config.enable.html = true; - config.enable.text = true; - - /* Set to enable the sort the result by message UID in the ascending order */ - config.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - config.enable.download_status = true; - - /* Set the limit of number of messages in the search results */ - config.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - config.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - config.limit.attachment_size = 1024 * 1024 * 5; - - - /* Connect to server with the session and config */ - if (!imap.connect(&session, &config)) - return; - - /* {Optional] */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder("INBOX")) - return; - - /* {Optional] */ - printSelectedMailboxInfo(imap); - - /** Read or search the Email and keep the TCP session to open - * The second parameter is for close the session. - */ - MailClient.readMail(&imap, false); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - - /** Open or select other mailbox folder - * The folder that previousely opened will be closed - */ - if (imap.selectFolder("Junk")) - { - /* {Optional] */ - printSelectedMailboxInfo(imap); - - /* Config to search all messages in the opened mailboax (Search mode) */ - config.search.criteria = "UID SEARCH ALL"; // or "UID SEARCH NEW" for recent received messages - - /* No message UID provide for fetching */ - config.fetch.uid = ""; - - /* Search the Email and close the session */ - MailClient.readMail(&imap); - } - - /* Close the seeion in case the session is still open */ - imap.closeSession(); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); -} - -void loop() -{ -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - printMessages(imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - Serial.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(IMAPSession &imap) -{ - /* Declare the selected folder info class to get the info of selected mailbox folder */ - SelectedFolderInfo sFolder = imap.selectedFolder(); - - /* Show the mailbox info */ - Serial.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - Serial.printf("Predicted next UID: %d\n", sFolder.nextUID()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - Serial.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); -} - -void printRFC822Messages(IMAP_MSG_Item &msg) -{ - Serial.printf("RFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - for (size_t j = 0; j < msg.rfc822.size(); j++) - { - IMAP_MSG_Item rfc822 = msg.rfc822[j]; - Serial.printf("%d. \n", j + 1); - Serial.printf("Messsage ID: %s\n", rfc822.messageID); - Serial.printf("From: %s\n", rfc822.from); - Serial.printf("Sender: %s\n", rfc822.sender); - Serial.printf("To: %s\n", rfc822.to); - Serial.printf("CC: %s\n", rfc822.cc); - Serial.printf("Subject: %s\n", rfc822.subject); - Serial.printf("Date: %s\n", rfc822.date); - Serial.printf("Reply-To: %s\n", rfc822.reply_to); - Serial.printf("Return-Path: %s\n", rfc822.return_path); - Serial.printf("Comment: %s\n", rfc822.comment); - Serial.printf("Keyword: %s\n", rfc822.keyword); - Serial.printf("Text Message: %s\n", rfc822.text.content); - Serial.printf("Text Message Charset: %s\n", rfc822.text.charSet); - Serial.printf("Text Message Transfer Encoding: %s\n", rfc822.text.transfer_encoding); - Serial.printf("HTML Message: %s\n", rfc822.html.content); - Serial.printf("HTML Message Charset: %s\n", rfc822.html.charSet); - Serial.printf("HTML Message Transfer Encoding: %s\n\n", rfc822.html.transfer_encoding); - - if (rfc822.attachments.size() > 0) - printAttacements(rfc822); - } -} - -void printAttacements(IMAP_MSG_Item &msg) -{ - Serial.printf("Attachment: %d file(s)\n****************************\n", msg.attachments.size()); - for (size_t j = 0; j < msg.attachments.size(); j++) - { - IMAP_Attach_Item att = msg.attachments[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - Serial.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.creationDate); - } - Serial.println(); -} - -void printMessages(IMAPSession &imap) -{ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - - for (size_t i = 0; i < msgList.msgItems.size(); i++) - { - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgList.msgItems[i]; - - Serial.println("################################"); - Serial.printf("Messsage Number: %s\n", msg.msgNo); - Serial.printf("Messsage UID: %s\n", msg.UID); - Serial.printf("Messsage ID: %s\n", msg.ID); - Serial.printf("Accept Language: %s\n", msg.acceptLang); - Serial.printf("Content Language: %s\n", msg.contentLang); - Serial.printf("From: %s\n", msg.from); - Serial.printf("From Charset: %s\n", msg.fromCharset); - Serial.printf("To: %s\n", msg.to); - Serial.printf("To Charset: %s\n", msg.toCharset); - Serial.printf("CC: %s\n", msg.cc); - Serial.printf("CC Charset: %s\n", msg.ccCharset); - Serial.printf("Date: %s\n", msg.date); - Serial.printf("Subject: %s\n", msg.subject); - Serial.printf("Subject Charset: %s\n", msg.subjectCharset); - - /* If the result contains the message info (Fetch mode) */ - if (!imap.headerOnly()) - { - Serial.printf("Text Message: %s\n", msg.text.content); - Serial.printf("Text Message Charset: %s\n", msg.text.charSet); - Serial.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - Serial.printf("HTML Message: %s\n", msg.html.content); - Serial.printf("HTML Message Charset: %s\n", msg.html.charSet); - Serial.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.attachments.size() > 0) - printAttacements(msg); - - if (msg.rfc822.size() > 0) - printRFC822Messages(msg); - } - - Serial.println(); - } -} diff --git a/lib/libesp32/lib_mail/examples/Send_Access_Token/Send_Access_Token.ino b/lib/libesp32/lib_mail/examples/Send_Access_Token/Send_Access_Token.ino deleted file mode 100644 index bdebd82a5587..000000000000 --- a/lib/libesp32/lib_mail/examples/Send_Access_Token/Send_Access_Token.ino +++ /dev/null @@ -1,203 +0,0 @@ - - -/** - *This example will log in with the SASL XOAUTH2 mechanisme using OAuth2.0 access token. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - - -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT 25 - -/* The user Email for OAuth2.0 access token */ -#define AUTHOR_EMAIL "################" - -/** The OAuth2.0 access token - * The generation, exchange and refresh of the access token are not available - * in this library. - * - * To test this using GMail, get the OAuth2.0 access token from this web site - * https://developers.google.com/oauthplayground/ - * - * You can use the ESP Signer library to generate OAuth2.0 access token - * The library is available here https://github.com/mobizt/ESP-Signer - * - * 1. Select the following scope (in Step 1) from Gmail API V1 - * https://mail.google.com/ - * https://mail.google.com/ - * - * 2. Click Authorize APIs button. - * 3. Cick Exchangeauthorization code for tokens. - * 4. From the response, look at access_token from the JSON payload node. - * 5. Copy that access token and paste to the AUTHOR_ACCESS_TOKEN value. - * - * The token will be expired in 3600 seconds (1 Hr). - * The AUTHOR_EMAIL above is the Email address that you granted to access the Gmail services. -*/ -#define AUTHOR_ACCESS_TOKEN "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.accessToken = AUTHOR_ACCESS_TOKEN; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - message.subject = "Test sending Email using Access token"; - message.addRecipient("Admin", "####@#####_dot_com"); - - message.text.content = "This is simple plain text message"; - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = "us-ascii"; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Send_Attachment_Blob/Send_Attachment_Blob.ino b/lib/libesp32/lib_mail/examples/Send_Attachment_Blob/Send_Attachment_Blob.ino deleted file mode 100644 index 7ff054a80b0f..000000000000 --- a/lib/libesp32/lib_mail/examples/Send_Attachment_Blob/Send_Attachment_Blob.ino +++ /dev/null @@ -1,268 +0,0 @@ - - -/** - * This example will send the Email with attachments and - * inline images stored in heap and flash memories. - * - * The html and text version messages will be sent. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -/* This is for attachment data */ -#include "image.h" - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com - * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * and use the app password as password with your yahoo mail account to login. - * The google app password signin is also available https://support.google.com/mail/answer/185833?hl=en -*/ -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Enable the chunked data transfer with pipelining for large message if server supported */ - message.enable.chunking = true; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - - message.subject = "Test sending Email with attachments and inline images"; - message.addRecipient("user1", "####@#####_dot_com"); - - message.html.content = "This message contains 3 inline images and 1 attachment file.

"; - - /** The HTML text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = "utf-8"; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - message.text.content = "This message contains 3 inline images and 1 attachment file.\r\nThe inline images were not shown in the plain text message."; - message.text.charSet = "utf-8"; - message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - /* The attachment data item */ - SMTP_Attachment att; - - /** Set the inline image info e.g. - * file name, MIME type, BLOB data, BLOB data size, - * transfer encoding (should be base64 for inline image) - */ - att.descr.filename = "firebase_logo.png"; - att.descr.mime = "image/png"; - att.blob.data = firebase_png; - att.blob.size = sizeof(firebase_png); - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att); - - /** Set the inline image info e.g. - * file name, MIME type, BLOB data, BLOB data size. - * The default transfer encoding is base64. - */ - message.resetAttachItem(att); //Clear the attach item data to reuse - att.descr.filename = "tree.gif"; - att.descr.mime = "image/gif"; - att.blob.data = tree_gif; - att.blob.size = sizeof(tree_gif); - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att); - - /** Set the inline image info e.g. - * file name, MIME type, BLOB data, BLOB data size. - * The default transfer encoding is base64. - */ - message.resetAttachItem(att); //Clear the attach item data to reuse - att.descr.filename = "bird.gif"; - att.descr.mime = "image/gif"; - att.blob.data = bird_gif; - att.blob.size = sizeof(bird_gif); - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att); - - /* Prepare the attachment data (from ram) */ - uint8_t *a = new uint8_t[512]; - int j = 0; - - for (int i = 0; i < 512; i++) - { - a[i] = j; - j++; - if (j > 255) - j = 0; - } - - /** Set the attachment info e.g. - * file name, MIME type, BLOB data, BLOB data size. - * The default transfer encoding is base64. - */ - message.resetAttachItem(att); //Clear the attach item data to reuse - att.descr.filename = "test.dat"; - att.descr.mime = "application/octet-stream"; - att.blob.data = a; - att.blob.size = 512; - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - /* Add attachment to the message */ - message.addAttachment(att); - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /* Start sending the Email and close the session */ - if (!MailClient.sendMail(&smtp, &message, true)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Send_Attachment_File/Send_Attachment_File.ino b/lib/libesp32/lib_mail/examples/Send_Attachment_File/Send_Attachment_File.ino deleted file mode 100644 index 3dcd0fc9efc8..000000000000 --- a/lib/libesp32/lib_mail/examples/Send_Attachment_File/Send_Attachment_File.ino +++ /dev/null @@ -1,427 +0,0 @@ - - -/** - * This example will send the Email with attachments and - * inline images stored in flash and SD card. - * - * The html and text version messages will be sent. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 - -//The file systems for flash and sd memory can be changed in ESP_Mail_FS.h. - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com - * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * and use the app password as password with your yahoo mail account to login. - * The google app password signin is also available https://support.google.com/mail/answer/185833?hl=en -*/ -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - static uint8_t buf[512]; - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - Serial.println("Mounting SD Card..."); - -#if defined(ESP32) - if (SD.begin()) // MailClient.sdBegin(14,2,15,13) for TTGO T8 v1.7 or 1.8 -#elif defined(ESP8266) - if (SD.begin(15)) -#endif - { - - if (SD.exists("/orange.png")) - SD.remove("/orange.png"); - if (SD.exists("/bin1.dat")) - SD.remove("/bin1.dat"); - - Serial.println("Preparing SD file attachments..."); - - const char *orangeImg = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAoUlEQVR42u3RMQ0AMAgAsCFgftHLiQpsENJaaFT+fqwRQoQgRAhChCBECEKECBGCECEIEYIQIQgRghCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCBGCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQghAhCBGCECEIEYIQIUKEIEQIQoQg5LoBGi/oCaOpTXoAAAAASUVORK5CYII="; - - File file = SD.open("/orange.png", FILE_WRITE); - file.print(orangeImg); - file.close(); - - file = SD.open("/bin1.dat", FILE_WRITE); - - buf[0] = 'H'; - buf[1] = 'E'; - buf[2] = 'A'; - buf[3] = 'D'; - file.write(buf, 4); - - size_t i; - - for (i = 0; i < 4; i++) - { - memset(buf, i + 1, 512); - file.write(buf, 512); - } - - buf[0] = 'T'; - buf[1] = 'A'; - buf[2] = 'I'; - buf[3] = 'L'; - file.write(buf, 4); - file.close(); - } - else - { - Serial.println("SD Card Monting Failed"); - } - - Serial.println("Mounting SPIFFS..."); - -#if defined(ESP32) - if (SPIFFS.begin(true)) -#elif defined(ESP8266) - if (SPIFFS.begin()) -#endif - { - //SPIFFS.format(); - - if (SPIFFS.exists("/green.png")) - SPIFFS.remove("/green.png"); - if (SPIFFS.exists("/bin2.dat")) - SPIFFS.remove("/bin2.dat"); - - Serial.println("Preparing SPIFFS attachments..."); - - const char *greenImg = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAoUlEQVR42u3RAQ0AMAgAoJviyWxtAtNYwzmoQGT/eqwRQoQgRAhChCBECEKECBGCECEIEYIQIQgRghCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCBGCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQghAhCBGCECEIEYIQIUKEIEQIQoQg5LoBBaDPbQYiMoMAAAAASUVORK5CYII="; - -#if defined(ESP32) - File file = SPIFFS.open("/green.png", FILE_WRITE); -#elif defined(ESP8266) - File file = SPIFFS.open("/green.png", "w"); -#endif - - file.print(greenImg); - file.close(); - -#if defined(ESP32) - file = SPIFFS.open("/bin2.dat", FILE_WRITE); -#elif defined(ESP8266) - file = SPIFFS.open("/bin2.dat", "w"); -#endif - - buf[0] = 'H'; - buf[1] = 'E'; - buf[2] = 'L'; - buf[3] = 'L'; - buf[4] = 'O'; - file.write(buf, 5); - - size_t i; - for (i = 0; i < 4; i++) - { - memset(buf, i + 1, 512); - file.write(buf, 512); - } - - buf[0] = 'G'; - buf[1] = 'O'; - buf[2] = 'O'; - buf[3] = 'D'; - buf[4] = 'B'; - buf[5] = 'Y'; - buf[6] = 'E'; - file.write(buf, 7); - file.close(); - } - else - { - Serial.println("SPIFFS Monting Failed"); - } - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /** ######################################################## - * Some properties of SMTPSession data and parameters pass to - * SMTP_Message class accept the pointer to constant char - * i.e. const char*. - * - * You may assign a string literal to that properties or function - * like below example. - * - * session.login.user_domain = "mydomain.net"; - * session.login.user_domain = String("mydomain.net").c_str(); - * - * or - * - * String doman = "mydomain.net"; - * session.login.user_domain = domain.c_str(); - * - * And - * - * String name = "Jack " + String("dawson"); - * String email = "jack_dawson" + String(123) + "@mail.com"; - * - * message.addRecipient(name.c_str(), email.c_str()); - * - * message.addHeader(String("Message-ID: ").c_str()); - * - * or - * - * String header = "Message-ID: "; - * message.addHeader(header.c_str()); - * - * ########################################################### - */ - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Enable the chunked data transfer with pipelining for large message if server supported */ - message.enable.chunking = true; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - - message.subject = "Test sending Email with attachments and inline images from SD card and Flash"; - message.addRecipient("user1", "####@#####_dot_com"); - - /** Two alternative content versions are sending in this example e.g. plain text and html */ - String htmlMsg = "This message contains 2 inline images and 2 attachment files.

"; - message.html.content = htmlMsg.c_str(); - - /** The HTML text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = "utf-8"; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - message.text.content = "This message contains 2 inline images and 2 attachment files.\r\nThe inline images were not shown in the plain text message."; - message.text.charSet = "utf-8"; - message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - /* The attachment data item */ - SMTP_Attachment att; - - /** Set the inline image info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - att.descr.filename = "orange.png"; - att.descr.mime = "image/png"; - att.file.path = "/orange.png"; - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - att.file.storage_type = esp_mail_file_storage_type_sd; - - /* Need to be base64 transfer encoding for inline image */ - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The orange.png file is already base64 encoded file. - * Then set the content encoding to match the transfer encoding - * which no encoding was taken place prior to sending. - */ - att.descr.content_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att); - - /** Set the attachment info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - message.resetAttachItem(att); //Clear the attach item data to reuse - att.descr.filename = "bin1.dat"; - att.descr.mime = "application/octet-stream"; //binary data - att.file.path = "/bin1.dat"; - att.file.storage_type = esp_mail_file_storage_type_sd; - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add attachment to the message */ - message.addAttachment(att); - - /** Set the inline image info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - message.resetAttachItem(att); //Clear the attach item data to reuse - att.descr.filename = "green.png"; - att.descr.mime = "image/png"; - att.file.path = "/green.png"; - att.file.storage_type = esp_mail_file_storage_type_flash; - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - att.descr.content_encoding = Content_Transfer_Encoding::enc_base64; - message.addInlineImage(att); - - /** Set the attachment info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - message.resetAttachItem(att); //Clear the attach item data to reuse - att.descr.filename = "bin2.dat"; - att.descr.mime = "application/octet-stream"; - att.file.path = "/bin2.dat"; - att.file.storage_type = esp_mail_file_storage_type_flash; - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - message.addAttachment(att); - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /* Start sending the Email and close the session */ - if (!MailClient.sendMail(&smtp, &message, true)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Send_Embedded_Message/Send_Embedded_Message.ino b/lib/libesp32/lib_mail/examples/Send_Embedded_Message/Send_Embedded_Message.ino deleted file mode 100644 index 8cc3b5e36df4..000000000000 --- a/lib/libesp32/lib_mail/examples/Send_Embedded_Message/Send_Embedded_Message.ino +++ /dev/null @@ -1,203 +0,0 @@ - - -/** - * This example will send the Email which the - * message html and text body will be embedded as - * attachment or inline content. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com - * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * and use the app password as password with your yahoo mail account to login. - * The google app password signin is also available https://support.google.com/mail/answer/185833?hl=en -*/ -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT 25 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - message.subject = "Test sending message as embedded files"; - message.addRecipient("Admin", "####@#####_dot_com"); - - message.html.content = "This is html message"; - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = "utf-8"; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - /* Enable to send this message body as file */ - message.html.embed.enable = true; - - /* The name of embedded file */ - message.html.embed.filename = "test.html"; - - /** The embedded type - * esp_mail_smtp_embed_message_type_attachment or 0 - * esp_mail_smtp_embed_message_type_inline or 1 - */ - message.html.embed.type = esp_mail_smtp_embed_message_type_attachment; - - - - message.text.content = "This is simple plain text message"; - message.text.charSet = "utf-8"; - message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; - message.text.embed.enable = true; - message.text.embed.filename = "test.txt"; - message.text.embed.type = esp_mail_smtp_embed_message_type_inline; - - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Send_Enriched_Text/Send_Enriched_Text.ino b/lib/libesp32/lib_mail/examples/Send_Enriched_Text/Send_Enriched_Text.ino deleted file mode 100644 index be8f2578d946..000000000000 --- a/lib/libesp32/lib_mail/examples/Send_Enriched_Text/Send_Enriched_Text.ino +++ /dev/null @@ -1,187 +0,0 @@ - - -/** - * This example will send the Email in enriched text version. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com - * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * and use the app password as password with your yahoo mail account to login. - * The google app password signin is also available https://support.google.com/mail/answer/185833?hl=en -*/ -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT 25 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - message.subject = "Test sending enriched text Email"; - message.addRecipient("Someone", "####@#####_dot_com"); - - message.text.content = "This is enriched as defined in RFC 1896\r\n\r\nIsn't it cool?"; - - message.text.content_type = "text/enriched"; - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = "us-ascii"; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Send_Flash_Message_with_Inline_Image/Send_Flash_Message_with_Inline_Image.ino b/lib/libesp32/lib_mail/examples/Send_Flash_Message_with_Inline_Image/Send_Flash_Message_with_Inline_Image.ino deleted file mode 100644 index 1ba0a3ec5ae0..000000000000 --- a/lib/libesp32/lib_mail/examples/Send_Flash_Message_with_Inline_Image/Send_Flash_Message_with_Inline_Image.ino +++ /dev/null @@ -1,287 +0,0 @@ - - -/** - * This example will send the Email with inline images stored in flash memory. - * The message content stores as HTML data in flash memory - * - * The html and text version messages will be sent. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 - -//The file systems for flash and sd memory can be changed in ESP_Mail_FS.h. - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com - * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * and use the app password as password with your yahoo mail account to login. - * The google app password signin is also available https://support.google.com/mail/answer/185833?hl=en -*/ -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - Serial.println("Mounting SPIFFS..."); - - const char *html = "This message contains 2 inline images.

\"orange \"green"; - const char *orangeImg = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAoUlEQVR42u3RMQ0AMAgAsCFgftHLiQpsENJaaFT+fqwRQoQgRAhChCBECEKECBGCECEIEYIQIQgRghCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCBGCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQghAhCBGCECEIEYIQIUKEIEQIQoQg5LoBGi/oCaOpTXoAAAAASUVORK5CYII="; - const char *greenImg = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAoUlEQVR42u3RAQ0AMAgAoJviyWxtAtNYwzmoQGT/eqwRQoQgRAhChCBECEKECBGCECEIEYIQIQgRghCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCBGCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQghAhCBGCECEIEYIQIUKEIEQIQoQg5LoBBaDPbQYiMoMAAAAASUVORK5CYII="; - -#if defined(ESP32) - if (SPIFFS.begin(true)) -#elif defined(ESP8266) - if (SPIFFS.begin()) -#endif - { - - //SPIFFS.format(); - - if (SPIFFS.exists("/orange.png")) - SPIFFS.remove("/orange.png"); - if (SPIFFS.exists("/green.png")) - SPIFFS.remove("/green.png"); - if (SPIFFS.exists("/msg.html")) - SPIFFS.remove("/msg.html"); - - Serial.println("Preparing SPIFFS attachments..."); - -#if defined(ESP32) - File file = SPIFFS.open("/orange.png", FILE_WRITE); -#elif defined(ESP8266) - File file = SPIFFS.open("/orange.png", "w"); -#endif - file.print(orangeImg); - file.close(); - -#if defined(ESP32) - file = SPIFFS.open("/green.png", FILE_WRITE); -#elif defined(ESP8266) - file = SPIFFS.open("/green.png", "w"); -#endif - file.print(greenImg); - file.close(); - -#if defined(ESP32) - file = SPIFFS.open("/msg.html", FILE_WRITE); -#elif defined(ESP8266) - file = SPIFFS.open("/msg.html", "w"); -#endif - file.print(html); - file.close(); - } - else - { - Serial.println("SPIFFS Monting Failed"); - } - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Enable the chunked data transfer with pipelining for large message if server supported */ - message.enable.chunking = true; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - - message.subject = "Test sending Email with message content and inline images stored in flash memory"; - message.addRecipient("user1", "####@#####_dot_com"); - - /* Two alternative content versions are sending in this example e.g. plain text and html */ - - /* Assign blob data (in flash or ram) as HTML message */ - message.html.blob.data = (const uint8_t *)html; - message.html.blob.size = strlen(html); - - //Or get the content from file - //message.html.file.name = "/msg.html"; - //message.html.file.type = esp_mail_file_storage_type_flash; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) <- not supported for message from blob and file - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The HTML text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = "utf-8"; - - message.text.content = "This message contains 2 inline images.\r\nThe inline images were not shown in the plain text message."; - message.text.charSet = "utf-8"; - message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - /* The attachment data item */ - SMTP_Attachment att; - - /** Set the inline image info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - att.descr.filename = "orange.png"; - att.descr.mime = "image/png"; - att.file.path = "/orange.png"; - att.descr.content_id = "image-001"; //The content id (cid) of orange image in the src tag - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - att.file.storage_type = esp_mail_file_storage_type_flash; - - /* Need to be base64 transfer encoding for inline image */ - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The orange.png file is already base64 encoded file. - * Then set the content encoding to match the transfer encoding - * which no encoding was taken place prior to sending. - */ - att.descr.content_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att); - - /** Set the inline image info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - message.resetAttachItem(att); //Clear the attach item data to reuse - att.descr.filename = "green.png"; - att.descr.mime = "image/png"; - att.file.path = "/green.png"; - att.descr.content_id = "image-002"; //The content id (cid) of green image in the src tag - att.file.storage_type = esp_mail_file_storage_type_flash; - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - att.descr.content_encoding = Content_Transfer_Encoding::enc_base64; - message.addInlineImage(att); - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /* Start sending the Email and close the session */ - if (!MailClient.sendMail(&smtp, &message, true)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Send_HTML/Send_HTML.ino b/lib/libesp32/lib_mail/examples/Send_HTML/Send_HTML.ino deleted file mode 100644 index 81b0a59982ba..000000000000 --- a/lib/libesp32/lib_mail/examples/Send_HTML/Send_HTML.ino +++ /dev/null @@ -1,221 +0,0 @@ - - -/** - * This example will send the Email in - * the html version. - * - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com - * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * and use the app password as password with your yahoo mail account to login. - * The google app password signin is also available https://support.google.com/mail/answer/185833?hl=en -*/ -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT 25 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /** ######################################################## - * Some properties of SMTPSession data and parameters pass to - * SMTP_Message class accept the pointer to constant char - * i.e. const char*. - * - * You may assign a string literal to that properties or function - * like below example. - * - * session.login.user_domain = "mydomain.net"; - * session.login.user_domain = String("mydomain.net").c_str(); - * - * or - * - * String doman = "mydomain.net"; - * session.login.user_domain = domain.c_str(); - * - * And - * - * String name = "Jack " + String("dawson"); - * String email = "jack_dawson" + String(123) + "@mail.com"; - * - * message.addRecipient(name.c_str(), email.c_str()); - * - * message.addHeader(String("Message-ID: ").c_str()); - * - * or - * - * String header = "Message-ID: "; - * message.addHeader(header.c_str()); - * - * ########################################################### - */ - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - message.subject = "Test sending html Email"; - message.addRecipient("Admin", "####@#####_dot_com"); - - String htmlMsg = "

This is the html text message.

The message was sent via ESP device.

"; - message.html.content = htmlMsg.c_str(); - - /** The html text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = "us-ascii"; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Send_Parallel_Attachment/Send_Parallel_Attachment.ino b/lib/libesp32/lib_mail/examples/Send_Parallel_Attachment/Send_Parallel_Attachment.ino deleted file mode 100644 index 65f6d353659a..000000000000 --- a/lib/libesp32/lib_mail/examples/Send_Parallel_Attachment/Send_Parallel_Attachment.ino +++ /dev/null @@ -1,229 +0,0 @@ - - -/** - * This example will send the Email with media as parallen attachments - * e.g. audio and images and play or display them simultaneously on the Email client. - * - * This depends on the Mail client supports. - * - * The html and text version messages will be sent. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 - -//The file systems for flash and sd memory can be changed in ESP_Mail_FS.h. - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -/* This is for attachment data */ -#include "data.h" - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com - * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * and use the app password as password with your yahoo mail account to login -*/ -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Enable the chunked data transfer with pipelining for large message if server supported */ - message.enable.chunking = true; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - - message.subject = "Test sending Email with parallel attachments"; - message.addRecipient("user1", "####@#####_dot_com"); - - message.html.content = "This message contains image and audio file which will play on the Mail client in parallel or simultaneously (depends on the client supports)."; - - /** The HTML text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = "utf-8"; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - message.text.content = "This message contains image and audio file which will play on the Mail client in parallel or simultaneously (depends on the client supports)."; - message.text.charSet = "us-ascii"; - message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - /* The attachment data item */ - SMTP_Attachment att; - - /** Set the attachment info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - att.descr.filename = "haun.png"; - att.descr.mime = "image/png"; - att.blob.data = shaun_png; - att.blob.size = sizeof(shaun_png); - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - message.addParallelAttachment(att); - - /** Set the attachment info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - message.resetAttachItem(att); //Clear the attach item data to reuse - att.descr.filename = "mu_law.wav"; - att.descr.mime = "audio/basic"; - att.blob.data = mu_law_wave; - att.blob.size = sizeof(mu_law_wave); - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - message.addParallelAttachment(att); - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /* Start sending the Email and close the session */ - if (!MailClient.sendMail(&smtp, &message, true)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Send_RFC822_Attachment/Send_RFC822_Attachment.ino b/lib/libesp32/lib_mail/examples/Send_RFC822_Attachment/Send_RFC822_Attachment.ino deleted file mode 100644 index 371515fe1568..000000000000 --- a/lib/libesp32/lib_mail/examples/Send_RFC822_Attachment/Send_RFC822_Attachment.ino +++ /dev/null @@ -1,252 +0,0 @@ - - -/** - * This example will send the Email in plain text version - * with rfc822 message attachment which the rfc822 message - * also contains its attachement. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -/* This is for attachment data */ -#include "image.h" - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com - * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * and use the app password as password with your yahoo mail account to login. - * The google app password signin is also available https://support.google.com/mail/answer/185833?hl=en -*/ -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT 25 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - Serial.println("Connect to NTP server and set the device time\r\nPlease wait...\r\n"); - float timeZone = 3;//GMT+3 - float daylightOffset = 0; - - /* Set the device time */ - MailClient.Time.setClock(timeZone, daylightOffset); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - message.subject = "Test sending Email with rfc822 attachment"; - message.addRecipient("Someone", "####@#####_dot_com"); - - message.text.content = "This is simple plain text message with rfc822 attachment"; - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = "us-ascii"; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - SMTP_Message rfc822; - rfc822.messageID = "1234@local.machine.example"; - rfc822.from.name = "rob"; - rfc822.from.email = "rob@example.com"; - rfc822.sender.name = "steve"; - rfc822.sender.email = "steve@example.com"; - String dt = MailClient.Time.getDateTimeString(); - rfc822.date = dt.c_str(); - rfc822.subject = "Test rfc822 message"; - rfc822.comment = "This is comment"; - rfc822.addRecipient("joe", "joe@example.com"); - rfc822.response.reply_to = "rob@example.com"; - rfc822.text.charSet = "utf-8"; - rfc822.text.content = "This is rfc822 text message"; - rfc822.text.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - rfc822.html.charSet = "utf-8"; - rfc822.html.content = "This is rfc822 html message"; - rfc822.html.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* The attachment data item */ - SMTP_Attachment att; - - /** Set the attachment info e.g. - * file name, MIME type, BLOB data, BLOB data size, - * and transfer encoding - */ - att.descr.filename = "firebase_logo.png"; - att.descr.mime = "image/png"; - att.blob.data = firebase_png; - att.blob.size = sizeof(firebase_png); - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add the attachment to the rfc822 message */ - rfc822.addAttachment(att); - - /* Prepare other attachment data */ - uint8_t *a = new uint8_t[512]; - int j = 0; - - for (int i = 0; i < 512; i++) - { - a[i] = j; - j++; - if (j > 255) - j = 0; - } - - /** Set the attachment info e.g. - * file name, MIME type, BLOB data, BLOB data size. - * The default transfer encoding is base64. - */ - message.resetAttachItem(att); //Clear the attach item data to reuse - att.descr.filename = "test.dat"; - att.descr.mime = "application/octet-stream"; - att.blob.data = a; - att.blob.size = 512; - - /* Add this attachment to the message */ - message.addAttachment(att); - - /* Add rfc822 message in the message */ - message.addMessage(rfc822); - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Send_Reuse_Session/Send_Reuse_Session.ino b/lib/libesp32/lib_mail/examples/Send_Reuse_Session/Send_Reuse_Session.ino deleted file mode 100644 index 45bd373f0e05..000000000000 --- a/lib/libesp32/lib_mail/examples/Send_Reuse_Session/Send_Reuse_Session.ino +++ /dev/null @@ -1,245 +0,0 @@ - - -/** - * This example will send multiple messages which - * the session was keep open during sending. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com - * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * and use the app password as password with your yahoo mail account to login. - * The google app password signin is also available https://support.google.com/mail/answer/185833?hl=en -*/ -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - message.subject = "First Email with session reusage"; - message.addRecipient("Admin1", "####@#####_dot_com"); - message.addRecipient("Admin2", "####@#####_dot_com"); - message.addCc("####@#####_dot_com"); - message.addBcc("####@#####_dot_com"); - - message.html.content = "

This is the first message.

"; - - /** The HTML text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = "utf-8"; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - /** The option to add soft line break to to the message for - * the long text message > 78 characters (rfc 3676) - * Some Servers may not compliant with the standard. - */ - message.text.flowed = true; - - message.text.content = "This is the first message"; - message.text.charSet = "us-ascii"; - - message.html.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - Serial.println(); - Serial.println("Sending first Email..."); - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /** Start sending the first Email and keep open the session - * The third parameter is for close the session. - */ - if (!MailClient.sendMail(&smtp, &message, false)) - Serial.println("Error sending Email, " + smtp.errorReason()); - - - /* To clear all message data */ - //message.clear(); - - /** Clear primary recipients, Cc recipients, Bcc recipients, custom headers - * attachments and inline images - */ - message.clearRecipients(); - message.clearCc(); - message.clearBcc(); - //message.clearAttachments(); - //message.clearInlineimages(); - - message.subject = "Second Email with session reusage"; - - message.addRecipient("Admin3", "####@#####_dot_com"); - message.addRecipient("Admin4", "####@#####_dot_com"); - message.addCc("####@#####_dot_com"); - message.addBcc("####@#####_dot_com"); - - message.html.content = "

This is the second message.

"; - message.html.charSet = "us-ascii"; - - message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - message.text.content = "This is the second message"; - message.text.charSet = "UTF-8"; - message.text.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - Serial.println(); - Serial.println("Sending second Email..."); - - /* Start sending the second mail and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Send_Text/Send_Text.ino b/lib/libesp32/lib_mail/examples/Send_Text/Send_Text.ino deleted file mode 100644 index 8c7cfc418d4b..000000000000 --- a/lib/libesp32/lib_mail/examples/Send_Text/Send_Text.ino +++ /dev/null @@ -1,219 +0,0 @@ - - -/** - * This example will send the Email in plain text version. - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com - * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * and use the app password as password with your yahoo mail account to login. - * The google app password signin is also available https://support.google.com/mail/answer/185833?hl=en -*/ -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT 25 - -/* The sign in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /** ######################################################## - * Some properties of SMTPSession data and parameters pass to - * SMTP_Message class accept the pointer to constant char - * i.e. const char*. - * - * You may assign a string literal to that properties or function - * like below example. - * - * session.login.user_domain = "mydomain.net"; - * session.login.user_domain = String("mydomain.net").c_str(); - * - * or - * - * String doman = "mydomain.net"; - * session.login.user_domain = domain.c_str(); - * - * And - * - * String name = "Jack " + String("dawson"); - * String email = "jack_dawson" + String(123) + "@mail.com"; - * - * message.addRecipient(name.c_str(), email.c_str()); - * - * message.addHeader(String("Message-ID: ").c_str()); - * - * or - * - * String header = "Message-ID: "; - * message.addHeader(header.c_str()); - * - * ########################################################### - */ - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - message.subject = "Test sending plain text Email"; - message.addRecipient("Someone", "####@#####_dot_com"); - - String textMsg = "This is simple plain text message"; - message.text.content = textMsg.c_str(); - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = "us-ascii"; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Send_Text_Flowed/Send_Text_Flowed.ino b/lib/libesp32/lib_mail/examples/Send_Text_Flowed/Send_Text_Flowed.ino deleted file mode 100644 index a1ea2f4fe883..000000000000 --- a/lib/libesp32/lib_mail/examples/Send_Text_Flowed/Send_Text_Flowed.ino +++ /dev/null @@ -1,229 +0,0 @@ - - -/** - * This example will send the Email in plain text version - * with the quoted text and long line text. - * - * - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com - * For yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * and use the app password as password with your yahoo mail account to login. - * The google app password signin is also available https://support.google.com/mail/answer/185833?hl=en -*/ -#define SMTP_HOST "################" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 -*/ -#define SMTP_PORT 25 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* The SMTP Session object used for Email sending */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the session config data */ - ESP_Mail_Session session; - - /** ######################################################## - * Some properties of SMTPSession data and parameters pass to - * SMTP_Message class accept the pointer to constant char - * i.e. const char*. - * - * You may assign a string literal to that properties or function - * like below example. - * - * session.login.user_domain = "mydomain.net"; - * session.login.user_domain = String("mydomain.net").c_str(); - * - * or - * - * String doman = "mydomain.net"; - * session.login.user_domain = domain.c_str(); - * - * And - * - * String name = "Jack " + String("dawson"); - * String email = "jack_dawson" + String(123) + "@mail.com"; - * - * message.addRecipient(name.c_str(), email.c_str()); - * - * message.addHeader(String("Message-ID: ").c_str()); - * - * or - * - * String header = "Message-ID: "; - * message.addHeader(header.c_str()); - * - * ########################################################### - */ - - /* Set the session config */ - session.server.host_name = SMTP_HOST; - session.server.port = SMTP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - session.login.user_domain = "mydomain.net"; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = "ESP Mail"; - message.sender.email = AUTHOR_EMAIL; - message.subject = "Test sending flowed plain text Email"; - message.addRecipient("Someone", "####@#####_dot_com"); - - /** The option to add soft line break to to the message for - * the long text message > 78 characters (rfc 3676) - * Some Servers may not compliant with the standard. - */ - message.text.flowed = true; - - /** if the option message.text.flowed is true, - * the following plain text message will be wrapped. - */ - message.text.content = "The text below is the long quoted text which breaks into several lines.\r\n\r\n>> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\r\n\r\nThis is the normal short text.\r\n\r\nAnother long text, abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz."; - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = "us-ascii"; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader("Message-ID: "); - - /* Connect to server with the session config */ - if (!smtp.connect(&session)) - return; - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - Serial.printf("Message sent success: %d\n", status.completedCount()); - Serial.printf("Message sent failled: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - localtime_r(&result.timesstamp, &dt); - - Serial.printf("Message No: %d\n", i + 1); - Serial.printf("Status: %s\n", result.completed ? "success" : "failed"); - Serial.printf("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); - Serial.printf("Recipient: %s\n", result.recipients); - Serial.printf("Subject: %s\n", result.subject); - } - Serial.println("----------------\n"); - } -} diff --git a/lib/libesp32/lib_mail/examples/Set_Flags/Set_Flags.ino b/lib/libesp32/lib_mail/examples/Set_Flags/Set_Flags.ino deleted file mode 100644 index 238a17ddfa8c..000000000000 --- a/lib/libesp32/lib_mail/examples/Set_Flags/Set_Flags.ino +++ /dev/null @@ -1,363 +0,0 @@ -/** - * This example will set the argument to the flags and read the message. - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2021 mobizt - * -*/ - -/** To receive Email using Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * -*/ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. -*/ - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif -#include - -#define WIFI_SSID "################" -#define WIFI_PASSWORD "################" - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "################" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 -*/ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "################" -#define AUTHOR_PASSWORD "################" - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(IMAPSession &imap); - -/* Print all messages from the message list */ -void printMessages(IMAPSession &imap); - -/* Print all rfc822 messages included in the message */ -void printRFC822Messages(IMAP_MSG_Item &msg); - -/* Print all attachments info from the message */ -void printAttacements(IMAP_MSG_Item &msg); - -/* The IMAP Session object used for Email reading */ -IMAPSession imap; - - -void setup() -{ - - Serial.begin(115200); - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * none debug or 0 - * basic debug or 1 - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Declare the session config data */ - ESP_Mail_Session session; - - /* Set the session config */ - session.server.host_name = IMAP_HOST; - session.server.port = IMAP_PORT; - session.login.email = AUTHOR_EMAIL; - session.login.password = AUTHOR_PASSWORD; - - - /* Setup the configuration for searching or fetching operation and its result */ - IMAP_Config config; - - /* Message UID to fetch or read e.g. 100 */ - config.fetch.uid = "100"; - - /* Set seen flag */ - //config.fetch.set_seen = true; - - /* Search criteria */ - config.search.criteria = ""; - - /* Also search the unseen message */ - config.search.unseen_msg = true; - - /* Set the storage to save the downloaded files and attachments */ - config.storage.saved_path = "/email_data"; - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - config.storage.type = esp_mail_file_storage_type_flash; - - /** Set to download heades, text and html messaeges, - * attachments and inline images respectively. - */ - config.download.header = true; - config.download.text = true; - config.download.html = true; - config.download.attachment = true; - config.download.inlineImg = true; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option config.limit.msg_size. - * The whole message can be download through config.download.text - * or config.download.html which not depends on these enable options. - */ - config.enable.html = true; - config.enable.text = true; - - /* Set to enable the sort the result by message UID in the ascending order */ - config.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - config.enable.download_status = true; - - /* Set the limit of number of messages in the search results */ - config.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - config.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - config.limit.attachment_size = 1024 * 1024 * 5; - - - - /* Connect to server with the session and config */ - if (!imap.connect(&session, &config)) - return; - - /* {Optional] */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder("INBOX")) - return; - - /* {Optional] */ - printSelectedMailboxInfo(imap); - - /** Set \Seen and \Answered to flags for message with UID 100 - * The seesion will keep open. - */ - if (MailClient.setFlag(&imap, 100, "\\Seen \\Answered", false)) - Serial.println("Setting FLAG success"); - else - Serial.println("Error, setting FLAG"); - - /* Add \Seen and \Answered to flags for message with UID 100 */ - //MailClient.addFlag(imap, 100, "\\Seen \\Answered", false); - - /* Remove \Seen and \Answered from flags for message with UID 100 */ - //MailClient.removeFlag(imap, 100, "\\Seen \\Answered", false); - - /* Read or search the Email and close the session */ - MailClient.readMail(&imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); -} - -void loop() -{ - -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - printMessages(imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - Serial.printf("Free Heap: %d", ESP.getFreeHeap()); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - Serial.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(IMAPSession &imap) -{ - /* Declare the selected folder info class to get the info of selected mailbox folder */ - SelectedFolderInfo sFolder = imap.selectedFolder(); - - /* Show the mailbox info */ - Serial.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - Serial.printf("Predicted next UID: %d\n", sFolder.nextUID()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - Serial.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); -} - -void printRFC822Messages(IMAP_MSG_Item &msg) -{ - Serial.printf("RFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - for (size_t j = 0; j < msg.rfc822.size(); j++) - { - IMAP_MSG_Item rfc822 = msg.rfc822[j]; - Serial.printf("%d. \n", j + 1); - Serial.printf("Messsage ID: %s\n", rfc822.messageID); - Serial.printf("From: %s\n", rfc822.from); - Serial.printf("Sender: %s\n", rfc822.sender); - Serial.printf("To: %s\n", rfc822.to); - Serial.printf("CC: %s\n", rfc822.cc); - Serial.printf("Subject: %s\n", rfc822.subject); - Serial.printf("Date: %s\n", rfc822.date); - Serial.printf("Reply-To: %s\n", rfc822.reply_to); - Serial.printf("Return-Path: %s\n", rfc822.return_path); - Serial.printf("Comment: %s\n", rfc822.comment); - Serial.printf("Keyword: %s\n", rfc822.keyword); - Serial.printf("Text Message: %s\n", rfc822.text.content); - Serial.printf("Text Message Charset: %s\n", rfc822.text.charSet); - Serial.printf("Text Message Transfer Encoding: %s\n", rfc822.text.transfer_encoding); - Serial.printf("HTML Message: %s\n", rfc822.html.content); - Serial.printf("HTML Message Charset: %s\n", rfc822.html.charSet); - Serial.printf("HTML Message Transfer Encoding: %s\n\n", rfc822.html.transfer_encoding); - - if (rfc822.attachments.size() > 0) - printAttacements(rfc822); - } -} - -void printAttacements(IMAP_MSG_Item &msg) -{ - Serial.printf("Attachment: %d file(s)\n****************************\n", msg.attachments.size()); - for (size_t j = 0; j < msg.attachments.size(); j++) - { - IMAP_Attach_Item att = msg.attachments[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - Serial.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.creationDate); - } - Serial.println(); -} - -void printMessages(IMAPSession &imap) -{ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - - for (size_t i = 0; i < msgList.msgItems.size(); i++) - { - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgList.msgItems[i]; - - Serial.println("################################"); - Serial.printf("Messsage Number: %s\n", msg.msgNo); - Serial.printf("Messsage UID: %s\n", msg.UID); - Serial.printf("Messsage ID: %s\n", msg.ID); - Serial.printf("Accept Language: %s\n", msg.acceptLang); - Serial.printf("Content Language: %s\n", msg.contentLang); - Serial.printf("From: %s\n", msg.from); - Serial.printf("From Charset: %s\n", msg.fromCharset); - Serial.printf("To: %s\n", msg.to); - Serial.printf("To Charset: %s\n", msg.toCharset); - Serial.printf("CC: %s\n", msg.cc); - Serial.printf("CC Charset: %s\n", msg.ccCharset); - Serial.printf("Date: %s\n", msg.date); - Serial.printf("Subject: %s\n", msg.subject); - Serial.printf("Subject Charset: %s\n", msg.subjectCharset); - - /* If the result contains the message info (Fetch mode) */ - if (!imap.headerOnly()) - { - Serial.printf("Text Message: %s\n", msg.text.content); - Serial.printf("Text Message Charset: %s\n", msg.text.charSet); - Serial.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - Serial.printf("HTML Message: %s\n", msg.html.content); - Serial.printf("HTML Message Charset: %s\n", msg.html.charSet); - Serial.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.attachments.size() > 0) - printAttacements(msg); - - if (msg.rfc822.size() > 0) - printRFC822Messages(msg); - } - - Serial.println(); - } -} diff --git a/lib/libesp32/lib_mail/library.json b/lib/libesp32/lib_mail/library.json deleted file mode 100644 index 30dac17bbc83..000000000000 --- a/lib/libesp32/lib_mail/library.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "ESP Mail Client", - "version": "1.2.0", - "keywords": "communication, email, imap, smtp, esp32, esp8266, arduino", - "description": "Mail Client Arduino Library for Espressif ESP32 and ESP8266 devices. This library allows the ESP32 and ESP8266 devices to send and read Email with the many options and features e.g. the attachments, inline images, embeded rfc822 messages are supported for upload when sending and download when reading the Emails.", - "repository": { - "type": "git", - "url": "https://github.com/mobizt/ESP-Mail-Client.git" - }, - "authors": [{ - "name": "Mobizt", - "email": "suwatchai@outlook.com" - }], - "frameworks": "arduino", - "platforms": "espressif32, espressif8266" -} diff --git a/lib/libesp32/lib_mail/library.properties b/lib/libesp32/lib_mail/library.properties deleted file mode 100644 index a574456bd108..000000000000 --- a/lib/libesp32/lib_mail/library.properties +++ /dev/null @@ -1,17 +0,0 @@ -name=ESP Mail Client - -version=1.2.0 - -author=Mobizt - -maintainer=Mobizt - -sentence=Mail Client Arduino Library for Espressif ESP32 and ESP8266 devices. - -paragraph=This library allows the ESP32 and ESP8266 devices to send and read Email with the many options and features e.g. the attachments, inline images, embeded rfc822 messages are supported for upload when sending and download when reading the Emails. - -category=Communication - -url=https://github.com/mobizt/ESP-Mail-Client - -architectures=esp32,esp8266 diff --git a/lib/libesp32/lib_mail/src/ESP_Mail_Client.cpp b/lib/libesp32/lib_mail/src/ESP_Mail_Client.cpp deleted file mode 100644 index 897d832b8748..000000000000 --- a/lib/libesp32/lib_mail/src/ESP_Mail_Client.cpp +++ /dev/null @@ -1,8548 +0,0 @@ -/** - * Mail Client Arduino Library for Espressif's ESP32 and ESP8266 - * - * Version: 1.2.0 - * Released: May 17, 2021 - * - * Updates: - * - Add support ESP8266 Core SDK v3.x.x. - * - * - * This library allows Espressif's ESP32 and ESP8266 devices to send and read Email - * through the SMTP and IMAP servers. - * - * The MIT License (MIT) - * Copyright (c) 2021 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef ESP_Mail_Client_CPP -#define ESP_Mail_Client_CPP - -#include "ESP_Mail_Client.h" - -#if defined(ESP32) -extern "C" -{ -#include -#include -} -#endif - -bool ESP_Mail_Client::sendIMAPCommand(IMAPSession *imap, int msgIndex, int cmdCase) -{ - - std::string cmd; - if (imap->_uidSearch || strlen(imap->_config->fetch.uid) > 0) - appendP(cmd, esp_mail_str_142, true); - else - appendP(cmd, esp_mail_str_143, true); - - char *tmp = intStr(imap->_msgNum[msgIndex]); - cmd += tmp; - delS(tmp); - appendP(cmd, esp_mail_str_147, false); - if (!imap->_config->fetch.set_seen) - { - appendP(cmd, esp_mail_str_152, false); - appendP(cmd, esp_mail_str_214, false); - } - appendP(cmd, esp_mail_str_218, false); - - switch (cmdCase) - { - case 1: - - appendP(cmd, esp_mail_str_269, false); - break; - - case 2: - - if (cPart(imap)->partNumFetchStr.length() > 0) - cmd += cPart(imap)->partNumFetchStr; - else - appendP(cmd, esp_mail_str_215, false); - appendP(cmd, esp_mail_str_156, false); - break; - - case 3: - - cmd += cPart(imap)->partNumFetchStr; - appendP(cmd, esp_mail_str_156, false); - break; - - default: - break; - } - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - return true; -} - -bool ESP_Mail_Client::readMail(IMAPSession *imap, bool closeSession) -{ - - imap->checkUID(); - imap->checkPath(); - - if (!imap->_tcpConnected) - imap->_mailboxOpened = false; - - std::string buf; - std::string command; - std::string _uid; - appendP(command, esp_mail_str_27, true); - char *tmp = nullptr; - size_t readCount = 0; - imap->_multipart_levels.clear(); - - if (!reconnect(imap)) - return false; - - int cmem = ESP.getFreeHeap(); - - if (cmem < ESP_MAIL_MIN_MEM) - { - if (imap->_debug) - { - esp_mail_debug(""); - errorStatusCB(imap, MAIL_CLIENT_ERROR_OUT_OF_MEMORY); - } - goto out; - } - - //new session - if (!imap->_tcpConnected) - { - //authenticate new - if (!imapAuth(imap)) - { - closeTCP(imap); - return false; - } - } - else - { - //reuse session - for (size_t i = 0; i < imap->_headers.size(); i++) - imap->_headers[i].part_headers.clear(); - imap->_headers.clear(); - - if (strlen(imap->_config->fetch.uid) > 0) - imap->_headerOnly = false; - else - imap->_headerOnly = true; - } - imap->_rfc822_part_count = 0; - imap->_mbif._availableItems = 0; - imap->_msgNum.clear(); - imap->_uidSearch = false; - imap->_mbif._searchCount = 0; - - if (imap->_currentFolder.length() == 0) - return handleIMAPError(imap, IMAP_STATUS_NO_MAILBOX_FOLDER_OPENED, false); - - if (!imap->_mailboxOpened || (imap->_config->fetch.set_seen && !imap->_headerOnly && imap->_readOnlyMode)) - { - if (!imap->openFolder(imap->_currentFolder.c_str(), imap->_readOnlyMode && !imap->_config->fetch.set_seen)) - return handleIMAPError(imap, IMAP_STATUS_OPEN_MAILBOX_FAILED, false); - } - - if (imap->_headerOnly) - { - if (strlen(imap->_config->search.criteria) > 0) - { - - if (imap->_readCallback) - { - imapCB(imap, "", false); - imapCBP(imap, esp_mail_str_66, false); - } - - if (imap->_debug) - debugInfoP(esp_mail_str_232); - - if (strposP(imap->_config->search.criteria, esp_mail_str_137, 0) != -1) - { - imap->_uidSearch = true; - appendP(command, esp_mail_str_138, false); - } - - appendP(command, esp_mail_str_139, false); - - for (size_t i = 0; i < strlen(imap->_config->search.criteria); i++) - { - if (imap->_config->search.criteria[i] != ' ' && imap->_config->search.criteria[i] != '\r' && imap->_config->search.criteria[i] != '\n' && imap->_config->search.criteria[i] != '$') - buf.append(1, imap->_config->search.criteria[i]); - - if (imap->_config->search.criteria[i] == ' ') - { - tmp = strP(esp_mail_str_140); - char *tmp2 = strP(esp_mail_str_224); - - if ((imap->_uidSearch && strcmp(buf.c_str(), tmp) == 0) || (imap->_unseen && buf.find(tmp2) != std::string::npos)) - buf.clear(); - delS(tmp); - delS(tmp2); - - tmp = strP(esp_mail_str_141); - if (strcmp(buf.c_str(), tmp) != 0 && buf.length() > 0) - { - appendP(command, esp_mail_str_131, false); - command += buf; - } - delS(tmp); - buf.clear(); - } - } - - tmp = strP(esp_mail_str_223); - if (imap->_unseen && strpos(imap->_config->search.criteria, tmp, 0) == -1) - appendP(command, esp_mail_str_223, false); - delS(tmp); - - if (buf.length() > 0) - { - appendP(command, esp_mail_str_131, false); - command += buf; - } - - if (imapSend(imap, command.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - std::string().swap(command); - - imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_search; - - if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, closeSession)) - return false; - - if (imap->_readCallback) - { - std::string s; - appendP(s, esp_mail_str_34, true); - appendP(s, esp_mail_str_68, false); - char *tmp = intStr(imap->_config->limit.search); - s += tmp; - delS(tmp); - imapCB(imap, s.c_str(), false); - - if (imap->_msgNum.size() > 0) - { - - appendP(s, esp_mail_str_69, true); - tmp = intStr(imap->_mbif._searchCount); - s += tmp; - delS(tmp); - appendP(s, esp_mail_str_70, false); - imapCB(imap, s.c_str(), false); - - appendP(s, esp_mail_str_71, true); - tmp = intStr(imap->_msgNum.size()); - s += tmp; - delS(tmp); - appendP(s, esp_mail_str_70, false); - imapCB(imap, s.c_str(), false); - } - else - imapCBP(imap, esp_mail_str_72, false); - } - } - else - { - imap->_mbif._availableItems++; - imap->_msgNum.push_back(imap->_mbif._nextUID - 1); - imap->_headerOnly = false; - char *tmp = intStr(imap->_mbif._nextUID - 1); - _uid = tmp; - delS(tmp); - imap->_config->fetch.uid = _uid.c_str(); - - if (imap->_readCallback) - imapCBP(imap, esp_mail_str_73, false); - } - } - else - { - imap->_mbif._availableItems++; - imap->_msgNum.push_back(atoi(imap->_config->fetch.uid)); - } - - for (size_t i = 0; i < imap->_msgNum.size(); i++) - { - - imap->_cMsgIdx = i; - imap->_totalRead++; - - if (ESP.getFreeHeap() - (imap->_config->limit.msg_size * (i + 1)) < ESP_MAIL_MIN_MEM) - { - if (imap->_debug) - errorStatusCB(imap, MAIL_CLIENT_ERROR_OUT_OF_MEMORY); - goto out; - } - - if (imap->_readCallback) - { - readCount++; - - std::string s; - appendP(s, esp_mail_str_74, true); - char *tmp = intStr(imap->_totalRead); - s += tmp; - delS(tmp); - - if (imap->_uidSearch || strlen(imap->_config->fetch.uid) > 0) - appendP(s, esp_mail_str_75, false); - else - appendP(s, esp_mail_str_76, false); - - tmp = intStr(imap->_msgNum[i]); - s += tmp; - delS(tmp); - imapCB(imap, "", false); - imapCB(imap, s.c_str(), false); - } - - if (imap->_debug) - debugInfoP(esp_mail_str_233); - - std::string cmd; - if (imap->_uidSearch || strlen(imap->_config->fetch.uid) > 0) - appendP(cmd, esp_mail_str_142, true); - else - appendP(cmd, esp_mail_str_143, true); - - if (imap->_debug) - debugInfoP(esp_mail_str_77); - - char *tmp = intStr(imap->_msgNum[i]); - cmd += tmp; - delS(tmp); - - appendP(cmd, esp_mail_str_147, false); - if (!imap->_config->fetch.set_seen) - { - appendP(cmd, esp_mail_str_152, false); - appendP(cmd, esp_mail_str_214, false); - } - appendP(cmd, esp_mail_str_218, false); - - appendP(cmd, esp_mail_str_144, false); - appendP(cmd, esp_mail_str_156, false); - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_fetch_body_header; - - int err = IMAP_STATUS_BAD_COMMAND; - if (imap->_headerOnly) - err = IMAP_STATUS_IMAP_RESPONSE_FAILED; - - if (!handleIMAPResponse(imap, err, closeSession)) - return false; - - if (!imap->_headerOnly) - { - imap->_cPartIdx = 0; - - //multipart - if (cHeader(imap)->multipart) - { - struct esp_mail_imap_multipart_level_t mlevel; - mlevel.level = 1; - mlevel.fetch_rfc822_header = false; - mlevel.append_body_text = false; - imap->_multipart_levels.push_back(mlevel); - - if (!fetchMultipartBodyHeader(imap, i)) - return false; - } - else - { - //singlepart - if (imap->_debug) - { - std::string s; - appendP(s, esp_mail_str_81, true); - s += '1'; - esp_mail_debug(s.c_str()); - } - - cHeader(imap)->partNumStr.clear(); - if (!sendIMAPCommand(imap, i, 1)) - return false; - - imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_fetch_body_mime; - if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, closeSession)) - return false; - } - - if (imap->_config->download.text || imap->_config->download.html || imap->_config->download.attachment || imap->_config->download.inlineImg) - { - if (!_sdOk && imap->_storageType == esp_mail_file_storage_type_sd) - { - _sdOk = sdTest(); - if (_sdOk) - if (!ESP_MAIL_SD_FS.exists(imap->_config->storage.saved_path)) - createDirs(imap->_config->storage.saved_path); - } - else if (!_flashOk && imap->_storageType == esp_mail_file_storage_type_flash) -#if defined(ESP32) - _flashOk = ESP_MAIL_FLASH_FS.begin(FORMAT_FLASH); -#elif defined(ESP8266) - _flashOk = ESP_MAIL_FLASH_FS.begin(); -#endif - } - - if (cHeader(imap)->part_headers.size() > 0) - { - if (cHeader(imap)->attachment_count > 0 && imap->_readCallback) - { - std::string s; - appendP(s, esp_mail_str_34, true); - appendP(s, esp_mail_str_78, false); - char *tmp = intStr(cHeader(imap)->attachment_count); - s += tmp; - delS(tmp); - appendP(s, esp_mail_str_79, false); - imapCB(imap, s.c_str(), false); - - for (size_t j = 0; j < cHeader(imap)->part_headers.size(); j++) - { - imap->_cPartIdx = j; - if (!cPart(imap)->rfc822_part && cPart(imap)->attach_type != esp_mail_att_type_none) - imapCB(imap, cPart(imap)->filename.c_str(), false); - } - } - - std::string s1, s2; - int _idx1 = 0; - for (size_t j = 0; j < cHeader(imap)->part_headers.size(); j++) - { - imap->_cPartIdx = j; - if (cPart(imap)->rfc822_part) - { - s1 = cPart(imap)->partNumStr; - _idx1 = cPart(imap)->rfc822_msg_Idx; - } - else if (s1.length() > 0) - { - if (multipartMember(s1, cPart(imap)->partNumStr)) - { - cPart(imap)->message_sub_type = esp_mail_imap_message_sub_type_rfc822; - cPart(imap)->rfc822_msg_Idx = _idx1; - } - } - - if (cPart(imap)->multipart_sub_type == esp_mail_imap_multipart_sub_type_parallel) - s2 = cPart(imap)->partNumStr; - else if (s2.length() > 0) - { - if (multipartMember(s2, cPart(imap)->partNumStr)) - { - cPart(imap)->attach_type = esp_mail_att_type_attachment; - if (cPart(imap)->filename.length() == 0) - { - if (cPart(imap)->name.length() > 0) - cPart(imap)->filename = cPart(imap)->name; - else - { - char *tmp = getUID(); - cPart(imap)->filename = tmp; - appendP(cPart(imap)->filename, esp_mail_str_40, false); - delS(tmp); - } - } - } - } - } - - int acnt = 0; - int ccnt = 0; - - for (size_t j = 0; j < cHeader(imap)->part_headers.size(); j++) - { - imap->_cPartIdx = j; - - if (cPart(imap)->rfc822_part || cPart(imap)->multipart_sub_type != esp_mail_imap_multipart_sub_type_none) - continue; - - bool rfc822_body_subtype = cPart(imap)->message_sub_type == esp_mail_imap_message_sub_type_rfc822; - - if (cPart(imap)->attach_type == esp_mail_att_type_none || cPart(imap)->msg_type == esp_mail_msg_type_html || cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) - { - - bool ret = ((imap->_config->enable.rfc822 || imap->_config->download.rfc822) && rfc822_body_subtype) || (!rfc822_body_subtype && ((imap->_config->enable.text && (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched)) || (imap->_config->enable.html && cPart(imap)->msg_type == esp_mail_msg_type_html) || (cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_config->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_config->download.text))); - if (!ret) - continue; - - if ((imap->_config->download.rfc822 && rfc822_body_subtype) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_config->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_config->download.text)))) - { - - if (ccnt == 0) - { - imapCB(imap, "", false); - imapCBP(imap, esp_mail_str_57, false); - } - - if (imap->_debug) - { - if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) - debugInfoP(esp_mail_str_59); - else if (cPart(imap)->msg_type == esp_mail_msg_type_html) - debugInfoP(esp_mail_str_60); - } - } - else - { - if (ccnt == 0) - { - imapCB(imap, "", false); - imapCBP(imap, esp_mail_str_307, false); - } - - if (imap->_debug) - { - if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) - debugInfoP(esp_mail_str_308); - else if (cPart(imap)->msg_type == esp_mail_msg_type_html) - debugInfoP(esp_mail_str_309); - } - } - - ccnt++; - - if (!sendIMAPCommand(imap, i, 2)) - return false; - - imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_fetch_body_text; - if (!handleIMAPResponse(imap, IMAP_STATUS_IMAP_RESPONSE_FAILED, closeSession)) - return false; - } - else if (cPart(imap)->attach_type != esp_mail_att_type_none && (_sdOk || _flashOk)) - { - - if (imap->_config->download.attachment || imap->_config->download.inlineImg) - { - if (acnt == 0) - { - imapCB(imap, "", false); - imapCBP(imap, esp_mail_str_80, false); - } - - if (imap->_debug) - debugInfoP(esp_mail_str_55); - - acnt++; - if (cPart(imap)->octetLen <= (int)imap->_config->limit.attachment_size) - { - - if (_sdOk || _flashOk) - { - - if ((int)j < (int)cHeader(imap)->part_headers.size() - 1) - if (cHeader(imap)->part_headers[j + 1].octetLen > (int)imap->_config->limit.attachment_size) - cHeader(imap)->downloaded_bytes += cHeader(imap)->part_headers[j + 1].octetLen; - - if (!sendIMAPCommand(imap, i, 3)) - return false; - - imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_fetch_body_attachment; - if (!handleIMAPResponse(imap, IMAP_STATUS_IMAP_RESPONSE_FAILED, closeSession)) - return false; - delay(0); - } - } - else - { - if ((int)j == (int)cHeader(imap)->part_headers.size() - 1) - cHeader(imap)->downloaded_bytes += cPart(imap)->octetLen; - } - } - } - } - } - - if (imap->_config->download.header && !imap->_headerSaved) - { - if (imap->_readCallback) - { - imapCB(imap, "", false); - imapCBP(imap, esp_mail_str_124, false); - } - saveHeader(imap); - } - - if (closeSession) - { - if (imap->_storageType == esp_mail_file_storage_type_sd) - { - if (_sdOk) - ESP_MAIL_SD_FS.end(); - _sdOk = false; - } - else if (imap->_storageType == esp_mail_file_storage_type_flash) - { - if (_flashOk) - ESP_MAIL_FLASH_FS.end(); - - _flashOk = false; - } - } - - imap->_cMsgIdx++; - } - - if (imap->_debug) - { - std::string s; - appendP(s, esp_mail_str_261, true); - appendP(s, esp_mail_str_84, false); - char *tmp = intStr(ESP.getFreeHeap()); - s += tmp; - delS(tmp); - esp_mail_debug(s.c_str()); - } - } - -out: - - if (readCount < imap->_msgNum.size()) - { - imap->_mbif._availableItems = readCount; - imap->_msgNum.erase(imap->_msgNum.begin() + readCount, imap->_msgNum.end()); - } - - if (closeSession) - { - if (!imap->closeSession()) - return false; - } - else - { - if (imap->_readCallback) - { - imapCB(imap, "", false); - imapCBP(imap, esp_mail_str_87, false); - } - - if (imap->_debug) - debugInfoP(esp_mail_str_88); - } - - if (imap->_readCallback) - imapCB(imap, "", true); - - return true; -} -bool ESP_Mail_Client::getMultipartFechCmd(IMAPSession *imap, int msgIdx, std::string &partText) -{ - if (imap->_multipart_levels.size() == 0) - return false; - - int cLevel = imap->_multipart_levels.size() - 1; - - cHeader(imap)->partNumStr.clear(); - - if (imap->_uidSearch || strlen(imap->_config->fetch.uid) > 0) - appendP(partText, esp_mail_str_142, true); - else - appendP(partText, esp_mail_str_143, true); - - char *tmp = intStr(imap->_msgNum[msgIdx]); - partText += tmp; - delS(tmp); - - appendP(partText, esp_mail_str_147, false); - if (!imap->_config->fetch.set_seen) - { - appendP(partText, esp_mail_str_152, false); - appendP(partText, esp_mail_str_214, false); - } - appendP(partText, esp_mail_str_218, false); - - for (size_t i = 0; i < imap->_multipart_levels.size(); i++) - { - if (i > 0) - { - appendP(partText, esp_mail_str_152, false); - appendP(cHeader(imap)->partNumStr, esp_mail_str_152, false); - } - - tmp = intStr(imap->_multipart_levels[i].level); - partText += tmp; - cHeader(imap)->partNumStr += tmp; - delS(tmp); - } - - if (imap->_multipart_levels[cLevel].fetch_rfc822_header) - { - appendP(partText, esp_mail_str_51, false); - imap->_multipart_levels[cLevel].append_body_text = true; - } - else - appendP(partText, esp_mail_str_148, false); - - imap->_multipart_levels[cLevel].fetch_rfc822_header = false; - - return true; -} - -bool ESP_Mail_Client::multipartMember(const std::string &part, const std::string &check) -{ - if (part.length() > check.length()) - return false; - - for (size_t i = 0; i < part.length(); i++) - if (part[i] != check[i]) - return false; - - return true; -} - -bool ESP_Mail_Client::fetchMultipartBodyHeader(IMAPSession *imap, int msgIdx) -{ - bool ret = true; - - if (!connected(imap)) - { - closeTCP(imap); - return false; - } - int cLevel = 0; - - do - { - - struct esp_mail_message_part_info_t *_cpart = &cHeader(imap)->part_headers[cHeader(imap)->message_data_count - 1]; - bool rfc822_body_subtype = _cpart->message_sub_type == esp_mail_imap_message_sub_type_rfc822; - - std::string cmd; - - if (!getMultipartFechCmd(imap, msgIdx, cmd)) - return true; - - if (imap->_debug) - { - std::string s; - if (imap->_multipart_levels.size() > 1) - appendP(s, esp_mail_str_86, true); - else - appendP(s, esp_mail_str_81, true); - s += cHeader(imap)->partNumStr; - esp_mail_debug(s.c_str()); - } - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_mime; - - ret = handleIMAPResponse(imap, IMAP_STATUS_IMAP_RESPONSE_FAILED, false); - - _cpart = &cHeader(imap)->part_headers[cHeader(imap)->message_data_count - 1]; - rfc822_body_subtype = _cpart->message_sub_type == esp_mail_imap_message_sub_type_rfc822; - cLevel = imap->_multipart_levels.size() - 1; - - if (ret) - { - - if (_cpart->multipart) - { - if (_cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_parallel || _cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_alternative || _cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_related || _cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_mixed) - { - struct esp_mail_imap_multipart_level_t mlevel; - mlevel.level = 1; - mlevel.fetch_rfc822_header = false; - mlevel.append_body_text = false; - imap->_multipart_levels.push_back(mlevel); - fetchMultipartBodyHeader(imap, msgIdx); - } - else - imap->_multipart_levels[cLevel].level++; - } - else - { - if (rfc822_body_subtype) - { - //to get additional rfc822 message header - imap->_multipart_levels[cLevel].fetch_rfc822_header = true; - fetchMultipartBodyHeader(imap, msgIdx); - } - else - { - if (imap->_multipart_levels[cLevel].append_body_text) - { - //single part rfc822 message body, append TEXT to the body fetch command - appendP(_cpart->partNumFetchStr, esp_mail_str_152, false); - appendP(_cpart->partNumFetchStr, esp_mail_str_215, false); - imap->_multipart_levels[cLevel].append_body_text = false; - } - imap->_multipart_levels[cLevel].level++; - } - } - } - - } while (ret); - - imap->_multipart_levels.pop_back(); - - if (imap->_multipart_levels.size() > 0) - { - cLevel = imap->_multipart_levels.size() - 1; - imap->_multipart_levels[cLevel].level++; - } - - return true; -} - -bool ESP_Mail_Client::connected(IMAPSession *imap) -{ - if (!imap->_secure) - { - if (!imap->httpClient._stream()) - return false; - return imap->httpClient._stream()->_ns_connected(); - } - else - { - if (!imap->httpClient.stream()) - return false; - return imap->httpClient.stream()->connected(); - } -} - -bool ESP_Mail_Client::imapAuth(IMAPSession *imap) -{ - - bool ssl = false; - std::string buf; -#if defined(ESP32) - imap->httpClient.setDebugCallback(NULL); -#elif defined(ESP8266) - -#endif - - if (imap->_config != nullptr) - { - if (strlen(imap->_config->fetch.uid) > 0) - imap->_headerOnly = false; - else - imap->_headerOnly = true; - } - - imap->_totalRead = 0; - imap->_secure = true; - bool secureMode = true; - -#if defined(ESP32) - if (imap->_debug) - imap->httpClient.setDebugCallback(esp_mail_debug); -#elif defined(ESP8266) - imap->httpClient.txBufDivider = 16; //minimum, tx buffer size for ssl data and request command data - imap->httpClient.rxBufDivider = 1; - if (imap->_config != nullptr) - { - if (!imap->_headerOnly && !imap->_config->enable.html && !imap->_config->enable.text && !imap->_config->download.attachment && !imap->_config->download.inlineImg && !imap->_config->download.html && !imap->_config->download.text) - imap->httpClient.rxBufDivider = 16; // minimum rx buffer size for only message header - } -#endif - - if (imap->_sesson_cfg->server.port == esp_mail_imap_port_143) - { - imap->_secure = false; - secureMode = false; - } - else - secureMode = !imap->_sesson_cfg->secure.startTLS; - - setSecure(imap->httpClient, imap->_sesson_cfg, imap->_caCert); - - if (imap->_readCallback) - imapCBP(imap, esp_mail_str_50, false); - - if (imap->_debug) - { - std::string s; - appendP(s, esp_mail_str_314, true); - s += ESP_MAIL_VERSION; - esp_mail_debug(s.c_str()); - - debugInfoP(esp_mail_str_225); - appendP(s, esp_mail_str_261, true); - appendP(s, esp_mail_str_211, false); - s += imap->_sesson_cfg->server.host_name; - esp_mail_debug(s.c_str()); - char *tmp = intStr(imap->_sesson_cfg->server.port); - appendP(s, esp_mail_str_261, true); - appendP(s, esp_mail_str_201, false); - s += tmp; - delS(tmp); - esp_mail_debug(s.c_str()); - } - - imap->httpClient.begin(imap->_sesson_cfg->server.host_name, imap->_sesson_cfg->server.port); - - if (!imap->httpClient.connect(secureMode)) - return handleIMAPError(imap, IMAP_STATUS_SERVER_CONNECT_FAILED, false); - - imap->_tcpConnected = true; - WiFiClient *stream = imap->httpClient.stream(); -#if defined(ESP32) - stream->setTimeout(ESP_MAIL_DEFAULT_TCP_TIMEOUT_SEC); -#elif defined(ESP8266) - stream->setTimeout(ESP_MAIL_DEFAULT_TCP_TIMEOUT_SEC * 1000); -#endif - imap->httpClient.tcpTimeout = ESP_MAIL_DEFAULT_TCP_TIMEOUT_SEC * 1000; - - if (imap->_readCallback) - imapCBP(imap, esp_mail_str_54, false); - - if (imap->_debug) - debugInfoP(esp_mail_str_228); - -init: - - if (!imap->checkCapability()) - return false; - - //start TLS when needed or the server issue - if ((imap->_auth_capability.start_tls || imap->_sesson_cfg->secure.startTLS) && !ssl) - { - std::string s; - if (imap->_readCallback) - { - appendP(s, esp_mail_str_34, true); - appendP(s, esp_mail_str_209, false); - esp_mail_debug(s.c_str()); - } - - if (imap->_debug) - { - appendP(s, esp_mail_str_196, true); - esp_mail_debug(s.c_str()); - } - - imapSendP(imap, esp_mail_str_311, false); - imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_starttls; - if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - if (imap->_debug) - { - debugInfoP(esp_mail_str_310); - } - - //connect in secure mode - //do ssl handshaking - if (!imap->httpClient._stream()->_ns_connect_ssl()) - return handleIMAPError(imap, MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP, false); - - //set the secure mode - imap->_sesson_cfg->secure.startTLS = false; - ssl = true; - imap->_secure = true; - - //check the capabilitiy again - goto init; - } - - imap->clearMessageData(); - imap->_mailboxOpened = false; - - bool creds = strlen(imap->_sesson_cfg->login.email) > 0 && strlen(imap->_sesson_cfg->login.password) > 0; - bool xoauth_auth = strlen(imap->_sesson_cfg->login.accessToken) > 0 && imap->_auth_capability.xoauth2; - bool login_auth = creds; - bool plain_auth = imap->_auth_capability.plain && creds; - - bool supported_auth = xoauth_auth || login_auth || plain_auth; - - if (!supported_auth) - return handleIMAPError(imap, IMAP_STATUS_NO_SUPPORTED_AUTH, false); - - //rfc4959 - if (supported_auth) - { - if (imap->_readCallback) - { - imapCB(imap, "", false); - imapCBP(imap, esp_mail_str_56, false); - } - } - - if (xoauth_auth) - { - if (!imap->_auth_capability.xoauth2) - return handleIMAPError(imap, IMAP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED, false); - - if (imap->_debug) - debugInfoP(esp_mail_str_291); - - std::string cmd; - appendP(cmd, esp_mail_str_292, true); - cmd += getEncodedToken(imap); - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_auth; - if (!handleIMAPResponse(imap, IMAP_STATUS_LOGIN_FAILED, false)) - return false; - } - else if (login_auth) - { - - if (imap->_debug) - debugInfoP(esp_mail_str_229); - - std::string cmd; - - appendP(cmd, esp_mail_str_130, true); - cmd += imap->_sesson_cfg->login.email; - appendP(cmd, esp_mail_str_131, false); - cmd += imap->_sesson_cfg->login.password; - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_login; - if (!handleIMAPResponse(imap, IMAP_STATUS_LOGIN_FAILED, true)) - return false; - } - else if (plain_auth) - { - if (imap->_debug) - debugInfoP(esp_mail_str_290); - - const char *usr = imap->_sesson_cfg->login.email; - const char *psw = imap->_sesson_cfg->login.password; - int len = strlen(usr) + strlen(psw) + 2; - uint8_t *tmp = new uint8_t[len]; - memset(tmp, 0, len); - int p = 1; - memcpy(tmp + p, usr, strlen(usr)); - p += strlen(usr) + 1; - memcpy(tmp + p, psw, strlen(psw)); - p += strlen(psw); - - std::string s; - appendP(s, esp_mail_str_41, true); - s += encodeBase64Str(tmp, p); - delete[] tmp; - - if (imapSend(imap, s.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_login; - if (!handleIMAPResponse(imap, IMAP_STATUS_LOGIN_FAILED, true)) - return false; - } - - return true; -} - -std::string ESP_Mail_Client::getEncodedToken(IMAPSession *imap) -{ - std::string raw; - appendP(raw, esp_mail_str_285, true); - raw += imap->_sesson_cfg->login.email; - appendP(raw, esp_mail_str_286, false); - raw += imap->_sesson_cfg->login.accessToken; - appendP(raw, esp_mail_str_287, false); - std::string s = encodeBase64Str((const unsigned char *)raw.c_str(), raw.length()); - return s; -} - -bool ESP_Mail_Client::imapLogout(IMAPSession *imap) -{ - if (imap->_readCallback) - { - imapCB(imap, "", false); - imapCBP(imap, esp_mail_str_85, false); - } - - if (imap->_debug) - debugInfoP(esp_mail_str_234); - - if (imapSendP(imap, esp_mail_str_146, true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_cmd_logout; - if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - if (imap->_readCallback) - { - imapCB(imap, "", false); - imapCBP(imap, esp_mail_str_187, false); - } - - if (imap->_debug) - debugInfoP(esp_mail_str_235); - - return true; -} - -void ESP_Mail_Client::errorStatusCB(IMAPSession *imap, int error) -{ - imap->_imapStatus.statusCode = error; - std::string s; - if (imap->_readCallback) - { - appendP(s, esp_mail_str_53, true); - s += imap->errorReason().c_str(); - imapCB(imap, s.c_str(), false); - } - - if (imap->_debug) - { - appendP(s, esp_mail_str_185, true); - s += imap->errorReason().c_str(); - esp_mail_debug(s.c_str()); - } -} - -size_t ESP_Mail_Client::imapSendP(IMAPSession *imap, PGM_P v, bool newline) -{ - if (!reconnect(imap)) - { - closeTCP(imap); - return 0; - } - - if (!connected(imap)) - { - errorStatusCB(imap, MAIL_CLIENT_ERROR_CONNECTION_LOST); - return 0; - } - - if (!imap->_tcpConnected) - { - errorStatusCB(imap, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - return 0; - } - - char *tmp = strP(v); - size_t len = 0; - - if (newline) - { - if (imap->_debugLevel > esp_mail_debug_level_2) - esp_mail_debug(tmp); - if (!imap->_secure) - len = imap->httpClient._ns_println(tmp); - else - len = imap->httpClient.stream()->println(tmp); - } - else - { - if (imap->_debugLevel > esp_mail_debug_level_2) - esp_mail_debug_line(tmp, false); - if (!imap->_secure) - len = imap->httpClient._ns_print(tmp); - else - len = imap->httpClient.stream()->print(tmp); - } - - if (len != strlen(tmp) && len != strlen(tmp) + 2) - { - errorStatusCB(imap, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - len = 0; - } - - delS(tmp); - - return len; -} - -size_t ESP_Mail_Client::imapSend(IMAPSession *imap, const char *data, bool newline) -{ - if (!reconnect(imap)) - { - closeTCP(imap); - return 0; - } - - if (!connected(imap)) - { - errorStatusCB(imap, MAIL_CLIENT_ERROR_CONNECTION_LOST); - return 0; - } - - if (!imap->_tcpConnected) - { - errorStatusCB(imap, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - return 0; - } - - size_t len = 0; - - if (newline) - { - if (imap->_debugLevel > esp_mail_debug_level_2) - esp_mail_debug(data); - if (!imap->_secure) - len = imap->httpClient._ns_println(data); - else - len = imap->httpClient.stream()->println(data); - } - else - { - if (imap->_debugLevel > esp_mail_debug_level_2) - esp_mail_debug_line(data, false); - if (!imap->_secure) - len = imap->httpClient._ns_print(data); - else - len = imap->httpClient.stream()->print(data); - } - - if (len != strlen(data) && len != strlen(data) + 2) - { - errorStatusCB(imap, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - len = 0; - } - return len; -} - -size_t ESP_Mail_Client::imapSend(IMAPSession *imap, int data, bool newline) -{ - if (!reconnect(imap)) - { - closeTCP(imap); - return 0; - } - - if (!connected(imap)) - { - errorStatusCB(imap, MAIL_CLIENT_ERROR_CONNECTION_LOST); - return 0; - } - - if (!imap->_tcpConnected) - { - errorStatusCB(imap, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - return 0; - } - - char *tmp = intStr(data); - size_t len = 0; - - if (newline) - { - if (imap->_debugLevel > esp_mail_debug_level_2) - esp_mail_debug(tmp); - if (!imap->_secure) - len = imap->httpClient._ns_println(tmp); - else - len = imap->httpClient.stream()->println(tmp); - } - else - { - if (imap->_debugLevel > esp_mail_debug_level_2) - esp_mail_debug_line(tmp, false); - if (!imap->_secure) - len = imap->httpClient._ns_print(tmp); - else - len = imap->httpClient.stream()->print(tmp); - } - - if (len != strlen(tmp) && len != strlen(tmp) + 2) - { - errorStatusCB(imap, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - len = 0; - } - - delS(tmp); - - return len; -} - -bool ESP_Mail_Client::setFlag(IMAPSession *imap, int msgUID, const char *flag, bool closeSession) -{ - return _setFlag(imap, msgUID, flag, 0, closeSession); -} - -bool ESP_Mail_Client::addFlag(IMAPSession *imap, int msgUID, const char *flag, bool closeSession) -{ - return _setFlag(imap, msgUID, flag, 1, closeSession); -} - -bool ESP_Mail_Client::removeFlag(IMAPSession *imap, int msgUID, const char *flag, bool closeSession) -{ - return _setFlag(imap, msgUID, flag, 2, closeSession); -} - -bool ESP_Mail_Client::_setFlag(IMAPSession *imap, int msgUID, const char *flag, uint8_t action, bool closeSession) -{ - if (!reconnect(imap)) - return false; - - if (!imap->_tcpConnected) - { - imap->_mailboxOpened = false; - return false; - } - - if (imap->_currentFolder.length() == 0) - { - if (imap->_readCallback) - debugInfoP(esp_mail_str_153); - - if (imap->_debug) - { - std::string e; - appendP(e, esp_mail_str_185, true); - appendP(e, esp_mail_str_151, false); - esp_mail_debug(e.c_str()); - } - } - else - { - if (imap->_readOnlyMode || !imap->_mailboxOpened) - { - if (!imap->selectFolder(imap->_currentFolder.c_str(), false)) - return false; - } - } - - if (imap->_readCallback) - { - imapCB(imap, "", false); - if (action == 0) - debugInfoP(esp_mail_str_157); - else if (action == 1) - debugInfoP(esp_mail_str_155); - else - debugInfoP(esp_mail_str_154); - } - - if (imap->_debug) - { - if (action == 0) - debugInfoP(esp_mail_str_253); - else if (action == 1) - debugInfoP(esp_mail_str_254); - else - debugInfoP(esp_mail_str_255); - } - - std::string cmd; - appendP(cmd, esp_mail_str_249, true); - char *tmp = intStr(msgUID); - cmd += tmp; - delS(tmp); - if (action == 0) - appendP(cmd, esp_mail_str_250, false); - else if (action == 1) - appendP(cmd, esp_mail_str_251, false); - else - appendP(cmd, esp_mail_str_252, false); - cmd += flag; - appendP(cmd, esp_mail_str_192, false); - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_cmd_store; - - if (!handleIMAPResponse(imap, IMAP_STATUS_PARSE_FLAG_FAILED, false)) - return false; - - if (closeSession) - imap->closeSession(); - - return true; -} - -void ESP_Mail_Client::createDirs(std::string dirs) -{ - std::string dir = ""; - int count = 0; - for (size_t i = 0; i < dirs.length(); i++) - { - dir.append(1, dirs[i]); - count++; - if (dirs[i] == '/') - { - if (dir.length() > 0) - ESP_MAIL_SD_FS.mkdir(dir.substr(0, dir.length() - 1).c_str()); - count = 0; - } - } - if (count > 0) - ESP_MAIL_SD_FS.mkdir(dir.c_str()); - std::string().swap(dir); -} - -bool ESP_Mail_Client::sdTest() -{ -#if defined(CARD_TYPE_SD) - if (_sdConfigSet) - sdBegin(_sck, _miso, _mosi, _ss); - else - sdBegin(); -#endif - -#if defined(ESP32) -#if defined(CARD_TYPE_SD_MMC) - if (_sdConfigSet) - sdMMCBegin(sd_mmc_mountpoint, sd_mmc_mode1bit, sd_mmc_format_if_mount_failed); -#endif -#endif - - file = ESP_MAIL_SD_FS.open(esp_mail_str_204, FILE_WRITE); - if (!file) - return false; - - if (!file.write(32)) - return false; - file.close(); - - file = ESP_MAIL_SD_FS.open(esp_mail_str_204); - if (!file) - return false; - - while (file.available()) - { - if (file.read() != 32) - return false; - } - file.close(); - - ESP_MAIL_SD_FS.remove(esp_mail_str_204); - - return true; -} - -std::string ESP_Mail_Client::getEncodedToken(SMTPSession *smtp) -{ - std::string raw; - appendP(raw, esp_mail_str_285, true); - raw += smtp->_sesson_cfg->login.email; - appendP(raw, esp_mail_str_286, false); - raw += smtp->_sesson_cfg->login.accessToken; - appendP(raw, esp_mail_str_287, false); - return encodeBase64Str((const unsigned char *)raw.c_str(), raw.length()); -} - -bool ESP_Mail_Client::smtpAuth(SMTPSession *smtp) -{ - - if (!reconnect(smtp)) - return false; - - bool ssl = false; - smtp->_secure = true; - bool secureMode = true; - - std::string s; - -#if defined(ESP32) - smtp->httpClient.setDebugCallback(NULL); -#elif defined(ESP8266) - smtp->httpClient.rxBufDivider = 16; // minimum rx buffer for smtp status response - smtp->httpClient.txBufDivider = 8; // medium tx buffer for faster attachment/inline data transfer -#endif - - if (smtp->_sesson_cfg->server.port == esp_mail_smtp_port_25) - { - smtp->_secure = false; - secureMode = false; - } - else - { - if (smtp->_sesson_cfg->server.port == esp_mail_smtp_port_587) - smtp->_sesson_cfg->secure.startTLS = true; - - secureMode = !smtp->_sesson_cfg->secure.startTLS; - - //to prevent to send the connection upgrade command when some server promotes - //the starttls capability even the current connection was already secured. - if (smtp->_sesson_cfg->server.port == esp_mail_smtp_port_465) - ssl = true; - } - - setSecure(smtp->httpClient, smtp->_sesson_cfg, smtp->_caCert); - - //Server connection attempt: no status code - if (smtp->_sendCallback) - smtpCBP(smtp, esp_mail_str_120); - - if (smtp->_debug) - { - appendP(s, esp_mail_str_314, true); - s += ESP_MAIL_VERSION; - esp_mail_debug(s.c_str()); - - debugInfoP(esp_mail_str_236); - appendP(s, esp_mail_str_261, true); - appendP(s, esp_mail_str_211, false); - s += smtp->_sesson_cfg->server.host_name; - esp_mail_debug(s.c_str()); - char *tmp = intStr(smtp->_sesson_cfg->server.port); - appendP(s, esp_mail_str_261, true); - appendP(s, esp_mail_str_201, false); - s += tmp; - delS(tmp); - esp_mail_debug(s.c_str()); - } -#if defined(ESP32) - if (smtp->_debug) - smtp->httpClient.setDebugCallback(esp_mail_debug); -#endif - - smtp->httpClient.begin(smtp->_sesson_cfg->server.host_name, smtp->_sesson_cfg->server.port); - - if (!smtp->httpClient.connect(secureMode)) - return handleSMTPError(smtp, SMTP_STATUS_SERVER_CONNECT_FAILED); - - //server connected - smtp->_tcpConnected = true; - - if (smtp->_debug) - debugInfoP(esp_mail_str_238); - - if (smtp->_sendCallback) - { - smtpCB(smtp, ""); - smtpCBP(smtp, esp_mail_str_121); - } - -#if defined(ESP32) - smtp->httpClient.stream()->setTimeout(ESP_MAIL_DEFAULT_TCP_TIMEOUT_SEC); -#elif defined(ESP8266) - smtp->httpClient.stream()->setTimeout(ESP_MAIL_DEFAULT_TCP_TIMEOUT_SEC * 1000); -#endif - smtp->httpClient.tcpTimeout = ESP_MAIL_DEFAULT_TCP_TIMEOUT_SEC * 1000; - - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_initial_state; - - //expected status code 220 for ready to service - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_220, SMTP_STATUS_SMTP_GREETING_GET_RESPONSE_FAILED)) - return false; - -init: - - //Sending greeting hello response - if (smtp->_sendCallback) - { - smtpCB(smtp, ""); - smtpCBP(smtp, esp_mail_str_122); - } - - if (smtp->_debug) - debugInfoP(esp_mail_str_239); - - appendP(s, esp_mail_str_6, true); - if (strlen(smtp->_sesson_cfg->login.user_domain) > 0) - s += smtp->_sesson_cfg->login.user_domain; - else - appendP(s, esp_mail_str_44, false); - - if (smtpSendP(smtp, s.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_greeting; - - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_250, 0)) - { - appendP(s, esp_mail_str_5, true); - if (strlen(smtp->_sesson_cfg->login.user_domain) > 0) - s += smtp->_sesson_cfg->login.user_domain; - else - appendP(s, esp_mail_str_44, false); - - if (smtpSend(smtp, s.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_250, SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED)) - return false; - smtp->_send_capability.esmtp = false; - smtp->_auth_capability.login = true; - } - else - smtp->_send_capability.esmtp = true; - - //start TLS when needed - if ((smtp->_auth_capability.start_tls || smtp->_sesson_cfg->secure.startTLS) && !ssl) - { - //send starttls command - if (smtp->_sendCallback) - { - smtpCB(smtp, ""); - smtpCBP(smtp, esp_mail_str_209); - } - - if (smtp->_debug) - { - appendP(s, esp_mail_str_196, true); - esp_mail_debug(s.c_str()); - } - - //expected status code 250 for complete the request - //some server returns 220 to restart to initial state - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_start_tls; - smtpSendP(smtp, esp_mail_str_311, false); - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_250, SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED)) - return false; - - if (smtp->_debug) - { - debugInfoP(esp_mail_str_310); - } - - //connect using secure mode - //do ssl handshaking - if (!smtp->httpClient._stream()->_ns_connect_ssl()) - return handleSMTPError(smtp, MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP); - - //set the secure mode - smtp->_sesson_cfg->secure.startTLS = false; - ssl = true; - smtp->_secure = true; - - //return to initial state if the response status is 220. - if (smtp->_smtpStatus.respCode == esp_mail_smtp_status_code_220) - goto init; - } - - bool creds = strlen(smtp->_sesson_cfg->login.email) > 0 && strlen(smtp->_sesson_cfg->login.password) > 0; - bool xoauth_auth = strlen(smtp->_sesson_cfg->login.accessToken) > 0 && smtp->_auth_capability.xoauth2; - bool login_auth = smtp->_auth_capability.login && creds; - bool plain_auth = smtp->_auth_capability.plain && creds; - - if (xoauth_auth || login_auth || plain_auth) - { - if (smtp->_sendCallback) - { - smtpCB(smtp, "", false); - smtpCBP(smtp, esp_mail_str_56, false); - } - - //log in - if (xoauth_auth) - { - if (smtp->_debug) - debugInfoP(esp_mail_str_288); - - if (!smtp->_auth_capability.xoauth2) - return handleSMTPError(smtp, SMTP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED, false); - - if (smtpSendP(smtp, esp_mail_str_289, false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (smtpSend(smtp, getEncodedToken(smtp).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_auth; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_235, SMTP_STATUS_AUTHEN_FAILED)) - return false; - - return true; - } - else if (plain_auth) - { - - if (smtp->_debug) - debugInfoP(esp_mail_str_241); - - if (smtp->_debug) - { - appendP(s, esp_mail_str_261, true); - s += smtp->_sesson_cfg->login.email; - esp_mail_debug(s.c_str()); - - appendP(s, esp_mail_str_131, false); - for (size_t i = 0; i < strlen(smtp->_sesson_cfg->login.password); i++) - appendP(s, esp_mail_str_183, false); - esp_mail_debug(s.c_str()); - } - - //rfc4616 - const char *usr = smtp->_sesson_cfg->login.email; - const char *psw = smtp->_sesson_cfg->login.password; - int len = strlen(usr) + strlen(psw) + 2; - uint8_t *tmp = new uint8_t[len]; - memset(tmp, 0, len); - int p = 1; - memcpy(tmp + p, usr, strlen(usr)); - p += strlen(usr) + 1; - memcpy(tmp + p, psw, strlen(psw)); - p += strlen(psw); - - std::string s; - appendP(s, esp_mail_str_45, true); - appendP(s, esp_mail_str_131, false); - s += encodeBase64Str(tmp, p); - delete[] tmp; - - if (smtpSend(smtp, s.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_auth_plain; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_235, SMTP_STATUS_USER_LOGIN_FAILED)) - return false; - - return true; - } - else if (login_auth) - { - if (smtp->_debug) - debugInfoP(esp_mail_str_240); - - if (smtpSendP(smtp, esp_mail_str_4, true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_334, SMTP_STATUS_AUTHEN_FAILED)) - return false; - - if (smtp->_debug) - { - appendP(s, esp_mail_str_261, true); - s += smtp->_sesson_cfg->login.email; - esp_mail_debug(s.c_str()); - } - - if (smtpSend(smtp, encodeBase64Str((const unsigned char *)smtp->_sesson_cfg->login.email, strlen(smtp->_sesson_cfg->login.email)).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_login_user; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_334, SMTP_STATUS_USER_LOGIN_FAILED)) - return false; - - if (smtp->_debug) - { - appendP(s, esp_mail_str_261, true); - for (size_t i = 0; i < strlen(smtp->_sesson_cfg->login.password); i++) - appendP(s, esp_mail_str_183, false); - esp_mail_debug(s.c_str()); - } - - if (smtpSend(smtp, encodeBase64Str((const unsigned char *)smtp->_sesson_cfg->login.password, strlen(smtp->_sesson_cfg->login.password)).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_login_psw; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_235, SMTP_STATUS_PASSWORD_LOGIN_FAILED)) - return false; - - return true; - } - } - - return true; -} - -void ESP_Mail_Client::mimeFromFile(const char *name, std::string &mime) -{ - std::string ext = name; - size_t p = ext.find_last_of("."); - if (p != std::string::npos) - { - ext = ext.substr(p, ext.length() - p); - if (ext.length() > 0) - getMIME(ext.c_str(), mime); - } -} - -bool ESP_Mail_Client::connected(SMTPSession *smtp) -{ - if (smtp->_sesson_cfg->secure.startTLS || !smtp->_secure) - { - if (!smtp->httpClient._stream()) - return false; - return smtp->httpClient._stream()->_ns_connected(); - } - else - { - if (!smtp->httpClient.stream()) - return false; - return smtp->httpClient.stream()->connected(); - } -} - -bool ESP_Mail_Client::setSendingResult(SMTPSession *smtp, SMTP_Message *msg, bool result) -{ - if (result) - smtp->_sentSuccessCount++; - else - smtp->_sentFailedCount++; - - if (smtp->_sendCallback) - { - struct esp_mail_smtp_send_status_t status; - status.completed = result; - status.timesstamp = time(nullptr); - status.subject = msg->subject; - status.recipients = msg->_rcp[0].email; - - smtp->sendingResult.add(status); - - smtp->_cbData._sentSuccess = smtp->_sentSuccessCount; - smtp->_cbData._sentFailed = smtp->_sentFailedCount; - } - - return result; -} - -bool ESP_Mail_Client::sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession) -{ - - if (strlen(msg->html.content) > 0 || msg->html.blob.size > 0 || strlen(msg->html.file.name) > 0) - msg->type |= esp_mail_msg_type_html; - - if (strlen(msg->text.content) > 0 || msg->text.blob.size > 0 || strlen(msg->text.file.name) > 0) - msg->type |= esp_mail_msg_type_plain; - - for (size_t i = 0; i < msg->_rfc822.size(); i++) - { - if (strlen(msg->_rfc822[i].html.content) > 0) - msg->_rfc822[i].type |= esp_mail_msg_type_html; - - if (strlen(msg->_rfc822[i].text.content) > 0) - msg->_rfc822[i].type |= esp_mail_msg_type_plain; - } - - return _sendMail(smtp, msg, closeSession); -} - -void ESP_Mail_Client::getMIME(const char *ext, std::string &mime) -{ - mime = ""; - for (int i = 0; i < esp_mail_file_extension_maxType; i++) - { - if (strcmp_P(ext, mimeinfo[i].endsWith) == 0) - { - char *tmp = strP(mimeinfo[i].mimeType); - mime = tmp; - delS(tmp); - break; - } - } -} - -size_t ESP_Mail_Client::numAtt(SMTPSession *smtp, esp_mail_attach_type type, SMTP_Message *msg) -{ - size_t count = 0; - for (size_t i = 0; i < msg->_att.size(); i++) - { - if (msg->_att[i]._int.att_type == type) - count++; - } - return count; -} - -bool ESP_Mail_Client::validEmail(const char *s) -{ - std::string str(s); - auto at = std::find(str.begin(), str.end(), '@'); - auto dot = std::find(at, str.end(), '.'); - return (at != str.end()) && (dot != str.end()); -} -bool ESP_Mail_Client::checkEmail(SMTPSession *smtp, SMTP_Message *msg) -{ - bool validRecipient = false; - - if (!validEmail(msg->sender.email)) - { - errorStatusCB(smtp, SMTP_STATUS_NO_VALID_SENDER_EXISTED); - return setSendingResult(smtp, msg, false); - } - - for (uint8_t i = 0; i < msg->_rcp.size(); i++) - { - if (validEmail(msg->_rcp[i].email)) - validRecipient = true; - } - - if (!validRecipient) - { - errorStatusCB(smtp, SMTP_STATUS_NO_VALID_RECIPIENTS_EXISTED); - return setSendingResult(smtp, msg, false); - } - - return true; -} - -bool ESP_Mail_Client::_sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession) -{ - - smtp->_smtpStatus.statusCode = 0; - smtp->_smtpStatus.respCode = 0; - smtp->_smtpStatus.text.clear(); - bool rfc822MSG = false; - - if (!checkEmail(smtp, msg)) - return false; - - smtp->_chunkedEnable = false; - smtp->_chunkCount = 0; - - //new session - if (!smtp->_tcpConnected) - { - if (!smtpAuth(smtp)) - { - closeTCP(smtp); - return setSendingResult(smtp, msg, false); - } - smtp->_sentSuccessCount = 0; - smtp->_sentFailedCount = 0; - smtp->sendingResult.clear(); - } - else - { - //reuse session - if (smtp->_sendCallback) - { - smtpCB(smtp, ""); - if (smtp->_sentSuccessCount || smtp->_sentFailedCount) - smtpCBP(smtp, esp_mail_str_267); - else - smtpCBP(smtp, esp_mail_str_208); - } - - if (smtp->_debug) - { - if (smtp->_sentSuccessCount || smtp->_sentFailedCount) - debugInfoP(esp_mail_str_268); - else - debugInfoP(esp_mail_str_207); - } - } - - if (smtp->_sendCallback) - { - smtpCB(smtp, ""); - smtpCBP(smtp, esp_mail_str_125); - } - - if (smtp->_debug) - debugInfoP(esp_mail_str_242); - - std::string buf; - std::string buf2; - checkBinaryData(smtp, msg); - - if (msg->priority >= esp_mail_smtp_priority_high && msg->priority <= esp_mail_smtp_priority_low) - { - char *tmp = intStr(msg->priority); - appendP(buf2, esp_mail_str_17, true); - buf2 += tmp; - delS(tmp); - appendP(buf2, esp_mail_str_34, false); - - if (msg->priority == esp_mail_smtp_priority_high) - { - appendP(buf2, esp_mail_str_18, false); - appendP(buf2, esp_mail_str_21, false); - } - else if (msg->priority == esp_mail_smtp_priority_normal) - { - appendP(buf2, esp_mail_str_19, false); - appendP(buf2, esp_mail_str_22, false); - } - else if (msg->priority == esp_mail_smtp_priority_low) - { - appendP(buf2, esp_mail_str_20, false); - appendP(buf2, esp_mail_str_23, false); - } - } - - appendP(buf2, esp_mail_str_10, false); - - if (strlen(msg->sender.name) > 0) - buf2 += msg->sender.name; - - appendP(buf2, esp_mail_str_14, false); - buf2 += msg->sender.email; - appendP(buf2, esp_mail_str_15, false); - appendP(buf2, esp_mail_str_34, false); - - appendP(buf, esp_mail_str_8, true); - appendP(buf, esp_mail_str_14, false); - buf += msg->sender.email; - appendP(buf, esp_mail_str_15, false); - - if (smtp->_send_capability.binaryMIME && smtp->_send_capability.chunking && msg->enable.chunking && (msg->text._int.binary || msg->html._int.binary)) - appendP(buf, esp_mail_str_104, false); - - if (smtpSend(smtp, buf.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_send_header_sender; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_SENDER_FAILED)) - return setSendingResult(smtp, msg, false); - - for (uint8_t i = 0; i < msg->_rcp.size(); i++) - { - if (i == 0) - { - appendP(buf2, esp_mail_str_11, false); - if (strlen(msg->_rcp[i].name) > 0) - buf2 += msg->_rcp[i].name; - - appendP(buf2, esp_mail_str_14, false); - buf2 += msg->_rcp[i].email; - appendP(buf2, esp_mail_str_15, false); - } - else - { - if (strlen(msg->_rcp[i].name) > 0) - { - appendP(buf2, esp_mail_str_263, false); - buf2 += msg->_rcp[i].name; - appendP(buf2, esp_mail_str_14, false); - } - else - appendP(buf2, esp_mail_str_13, false); - buf2 += msg->_rcp[i].email; - appendP(buf2, esp_mail_str_15, false); - } - - if (i == msg->_rcp.size() - 1) - appendP(buf2, esp_mail_str_34, false); - - buf.clear(); - //only address - appendP(buf, esp_mail_str_9, false); - appendP(buf, esp_mail_str_14, false); - buf += msg->_rcp[i].email; - appendP(buf, esp_mail_str_15, false); - - //rfc3461, rfc3464 - if (smtp->_send_capability.dsn) - { - if (msg->response.notify != esp_mail_smtp_notify::esp_mail_smtp_notify_never) - { - appendP(buf, esp_mail_str_262, false); - int opcnt = 0; - if (msg->response.notify && esp_mail_smtp_notify::esp_mail_smtp_notify_success) - { - if (opcnt > 0) - appendP(buf, esp_mail_str_263, false); - appendP(buf, esp_mail_str_264, false); - opcnt++; - } - if (msg->response.notify && esp_mail_smtp_notify::esp_mail_smtp_notify_failure) - { - if (opcnt > 0) - appendP(buf, esp_mail_str_263, false); - appendP(buf, esp_mail_str_265, false); - opcnt++; - } - if (msg->response.notify && esp_mail_smtp_notify::esp_mail_smtp_notify_delay) - { - if (opcnt > 0) - appendP(buf, esp_mail_str_263, false); - appendP(buf, esp_mail_str_266, false); - opcnt++; - } - } - } - - if (smtpSend(smtp, buf.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_send_header_recipient; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED)) - return setSendingResult(smtp, msg, false); - } - - for (uint8_t i = 0; i < msg->_cc.size(); i++) - { - if (i == 0) - { - appendP(buf2, esp_mail_str_12, false); - appendP(buf2, esp_mail_str_14, false); - buf2 += msg->_cc[i].email; - appendP(buf2, esp_mail_str_15, false); - } - else - { - appendP(buf2, esp_mail_str_13, false); - buf2 += msg->_cc[i].email; - appendP(buf2, esp_mail_str_15, false); - } - - if (i == msg->_cc.size() - 1) - appendP(buf2, esp_mail_str_34, false); - - buf.clear(); - - appendP(buf, esp_mail_str_9, false); - appendP(buf, esp_mail_str_14, false); - buf += msg->_cc[i].email; - appendP(buf, esp_mail_str_15, false); - - if (smtpSend(smtp, buf.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_send_header_recipient; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED)) - return setSendingResult(smtp, msg, false); - } - - for (uint8_t i = 0; i < msg->_bcc.size(); i++) - { - appendP(buf, esp_mail_str_9, true); - appendP(buf, esp_mail_str_14, false); - buf += msg->_bcc[i].email; - appendP(buf, esp_mail_str_15, false); - if (smtpSend(smtp, buf.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_send_header_recipient; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED)) - return setSendingResult(smtp, msg, false); - } - - if (smtp->_sendCallback) - { - smtpCB(smtp, ""); - smtpCBP(smtp, esp_mail_str_126); - } - - if (smtp->_debug) - debugInfoP(esp_mail_str_243); - - if (smtp->_send_capability.chunking && msg->enable.chunking) - { - smtp->_chunkedEnable = true; - if (!bdat(smtp, msg, buf2.length(), false)) - return false; - } - else - { - if (smtpSendP(smtp, esp_mail_str_16, true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_send_body; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_354, SMTP_STATUS_SEND_BODY_FAILED)) - return setSendingResult(smtp, msg, false); - } - - if (smtpSend(smtp, buf2.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - - std::string s; - appendP(s, esp_mail_str_24, true); - s += msg->subject; - appendP(s, esp_mail_str_34, false); - - if (msg->_hdr.size() > 0) - { - for (uint8_t k = 0; k < msg->_hdr.size(); k++) - { - s += msg->_hdr[k]; - appendP(s, esp_mail_str_34, false); - } - } - - if (strlen(msg->response.reply_to) > 0) - { - appendP(s, esp_mail_str_184, false); - appendP(s, esp_mail_str_14, false); - s += msg->response.reply_to; - appendP(s, esp_mail_str_15, false); - appendP(s, esp_mail_str_34, false); - } - - if (strlen(msg->response.return_path) > 0) - { - appendP(s, esp_mail_str_46, false); - appendP(s, esp_mail_str_14, false); - s += msg->response.return_path; - appendP(s, esp_mail_str_15, false); - appendP(s, esp_mail_str_34, false); - } - - appendP(s, esp_mail_str_3, false); - - if (!bdat(smtp, msg, s.length(), false)) - return false; - - if (smtpSend(smtp, s.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - - return sendMSGData(smtp, msg, closeSession, rfc822MSG); -} - -bool ESP_Mail_Client::sendMSGData(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG) -{ - std::string s; - std::string mixed = getBoundary(15); - std::string alt = getBoundary(15); - - if (numAtt(smtp, esp_mail_att_type_attachment, msg) == 0 && msg->_parallel.size() == 0 && msg->_rfc822.size() == 0) - { - if (msg->type == (esp_mail_msg_type_plain | esp_mail_msg_type_html | esp_mail_msg_type_enriched) || numAtt(smtp, esp_mail_att_type_inline, msg) > 0) - { - if (!sendMSG(smtp, msg, alt)) - return setSendingResult(smtp, msg, false); - } - else if (msg->type != esp_mail_msg_type_none) - { - if (!sendPartText(smtp, msg, msg->type, "")) - return setSendingResult(smtp, msg, false); - } - } - else - { - appendP(s, esp_mail_str_1, true); - s += mixed; - appendP(s, esp_mail_str_35, false); - - appendP(s, esp_mail_str_33, false); - s += mixed; - appendP(s, esp_mail_str_34, false); - - if (!bdat(smtp, msg, s.length(), false)) - return false; - - if (smtpSend(smtp, s.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - - if (!sendMSG(smtp, msg, alt)) - return setSendingResult(smtp, msg, false); - - if (!bdat(smtp, msg, 2, false)) - return false; - - if (smtpSendP(smtp, esp_mail_str_34, false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - - if (smtp->_sendCallback) - { - smtpCB(smtp, ""); - smtpCBP(smtp, esp_mail_str_127); - } - - if (smtp->_debug) - debugInfoP(esp_mail_str_244); - - if (smtp->_sendCallback && numAtt(smtp, esp_mail_att_type_attachment, msg) > 0) - esp_mail_debug(""); - - if (!sendAttachments(smtp, msg, mixed)) - return setSendingResult(smtp, msg, false); - - if (!sendParallelAttachments(smtp, msg, mixed)) - return setSendingResult(smtp, msg, false); - - if (!sendRFC822Msg(smtp, msg, mixed, closeSession, msg->_rfc822.size() > 0)) - return setSendingResult(smtp, msg, false); - - appendP(s, esp_mail_str_33, true); - s += mixed; - appendP(s, esp_mail_str_33, false); - - if (!bdat(smtp, msg, s.length(), false)) - return false; - - if (smtpSend(smtp, s.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - } - - if (!rfc822MSG) - { - if (smtp->_sendCallback) - { - smtpCB(smtp, ""); - smtpCBP(smtp, esp_mail_str_303); - } - - if (smtp->_debug) - debugInfoP(esp_mail_str_304); - - if (smtp->_chunkedEnable) - { - - if (!bdat(smtp, msg, 0, true)) - return false; - - smtp->_smtp_cmd = esp_mail_smtp_cmd_chunk_termination; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_BODY_FAILED)) - return false; - } - else - { - if (smtpSendP(smtp, esp_mail_str_37, false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_send_body; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_BODY_FAILED)) - return setSendingResult(smtp, msg, false); - } - - setSendingResult(smtp, msg, true); - - if (closeSession) - if (!smtp->closeSession()) - return false; - } - - return true; -} - -bool ESP_Mail_Client::sendRFC822Msg(SMTPSession *smtp, SMTP_Message *msg, const std::string &boundary, bool closeSession, bool rfc822MSG) -{ - if (msg->_rfc822.size() == 0) - return true; - std::string buf; - for (uint8_t i = 0; i < msg->_rfc822.size(); i++) - { - buf.clear(); - getRFC822PartHeader(smtp, buf, boundary); - - getRFC822MsgEnvelope(smtp, &msg->_rfc822[i], buf); - - if (!bdat(smtp, msg, buf.length(), false)) - return false; - - if (smtpSend(smtp, buf.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (!sendMSGData(smtp, &msg->_rfc822[i], closeSession, rfc822MSG)) - return false; - } - - return true; -} - -void ESP_Mail_Client::getRFC822MsgEnvelope(SMTPSession *smtp, SMTP_Message *msg, std::string &buf) -{ - if (strlen(msg->date) > 0) - { - appendP(buf, esp_mail_str_99, false); - buf += msg->date; - appendP(buf, esp_mail_str_34, false); - } - - if (strlen(msg->from.email) > 0) - { - appendP(buf, esp_mail_str_10, false); - - if (strlen(msg->from.name) > 0) - buf += msg->from.name; - - appendP(buf, esp_mail_str_14, false); - buf += msg->from.email; - appendP(buf, esp_mail_str_15, false); - appendP(buf, esp_mail_str_34, false); - } - - if (strlen(msg->sender.email) > 0) - { - appendP(buf, esp_mail_str_150, false); - - if (strlen(msg->sender.name) > 0) - buf += msg->sender.name; - - appendP(buf, esp_mail_str_14, false); - buf += msg->sender.email; - appendP(buf, esp_mail_str_15, false); - appendP(buf, esp_mail_str_34, false); - } - - if (strlen(msg->response.reply_to) > 0) - { - appendP(buf, esp_mail_str_184, false); - appendP(buf, esp_mail_str_14, false); - buf += msg->response.reply_to; - appendP(buf, esp_mail_str_15, false); - appendP(buf, esp_mail_str_34, false); - } - - if (strlen(msg->response.return_path) > 0) - { - appendP(buf, esp_mail_str_46, false); - appendP(buf, esp_mail_str_14, false); - buf += msg->response.return_path; - appendP(buf, esp_mail_str_15, false); - appendP(buf, esp_mail_str_34, false); - } - - for (uint8_t i = 0; i < msg->_rcp.size(); i++) - { - if (i == 0) - { - appendP(buf, esp_mail_str_11, false); - if (strlen(msg->_rcp[i].name) > 0) - buf += msg->_rcp[i].name; - - appendP(buf, esp_mail_str_14, false); - buf += msg->_rcp[i].email; - appendP(buf, esp_mail_str_15, false); - } - else - { - if (strlen(msg->_rcp[i].name) > 0) - { - appendP(buf, esp_mail_str_263, false); - buf += msg->_rcp[i].name; - appendP(buf, esp_mail_str_14, false); - } - else - appendP(buf, esp_mail_str_13, false); - buf += msg->_rcp[i].email; - appendP(buf, esp_mail_str_15, false); - } - - if (i == msg->_rcp.size() - 1) - appendP(buf, esp_mail_str_34, false); - } - - for (uint8_t i = 0; i < msg->_cc.size(); i++) - { - if (i == 0) - { - appendP(buf, esp_mail_str_12, false); - appendP(buf, esp_mail_str_14, false); - buf += msg->_cc[i].email; - appendP(buf, esp_mail_str_15, false); - } - else - { - appendP(buf, esp_mail_str_13, false); - buf += msg->_cc[i].email; - appendP(buf, esp_mail_str_15, false); - } - - if (i == msg->_cc.size() - 1) - appendP(buf, esp_mail_str_34, false); - } - - for (uint8_t i = 0; i < msg->_bcc.size(); i++) - { - if (i == 0) - { - appendP(buf, esp_mail_str_149, false); - appendP(buf, esp_mail_str_14, false); - buf += msg->_bcc[i].email; - appendP(buf, esp_mail_str_15, false); - } - else - { - appendP(buf, esp_mail_str_13, false); - buf += msg->_bcc[i].email; - appendP(buf, esp_mail_str_15, false); - } - - if (i == msg->_bcc.size() - 1) - appendP(buf, esp_mail_str_34, false); - } - - if (strlen(msg->subject) > 0) - { - appendP(buf, esp_mail_str_279, false); - buf += msg->subject; - appendP(buf, esp_mail_str_34, false); - } - - if (strlen(msg->keyword) > 0) - { - appendP(buf, esp_mail_str_145, false); - buf += msg->keyword; - appendP(buf, esp_mail_str_34, false); - } - - if (strlen(msg->comment) > 0) - { - appendP(buf, esp_mail_str_134, false); - buf += msg->comment; - appendP(buf, esp_mail_str_34, false); - } - - if (strlen(msg->messageID) > 0) - { - appendP(buf, esp_mail_str_274, false); - appendP(buf, esp_mail_str_14, false); - buf += msg->messageID; - appendP(buf, esp_mail_str_15, false); - appendP(buf, esp_mail_str_34, false); - } -} - -bool ESP_Mail_Client::bdat(SMTPSession *smtp, SMTP_Message *msg, int len, bool last) -{ - if (!smtp->_chunkedEnable || !msg->enable.chunking) - return true; - - smtp->_chunkCount++; - - std::string bdat; - appendP(bdat, esp_mail_str_106, true); - char *tmp = intStr(len); - bdat += tmp; - if (last) - appendP(bdat, esp_mail_str_173, false); - delS(tmp); - if (smtpSend(smtp, bdat.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - - if (!smtp->_send_capability.pipelining) - { - smtp->_smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_send_body; - if (!handleSMTPResponse(smtp, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_BODY_FAILED)) - return setSendingResult(smtp, msg, false); - smtp->_chunkCount = 0; - } - return true; -} - -void ESP_Mail_Client::checkBinaryData(SMTPSession *smtp, SMTP_Message *msg) -{ - if (msg->type & esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched || msg->type & esp_mail_msg_type_html) - { - if ((msg->type & esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched) > 0) - { - if (strlen(msg->text.transfer_encoding) > 0) - { - if (strcmp(msg->text.transfer_encoding, Content_Transfer_Encoding::enc_binary) == 0) - { - msg->text._int.binary = true; - } - } - } - - if ((msg->type & esp_mail_msg_type_html) > 0) - { - if (strlen(msg->html.transfer_encoding) > 0) - { - if (strcmp(msg->html.transfer_encoding, Content_Transfer_Encoding::enc_binary) == 0) - { - msg->html._int.binary = true; - } - } - } - } - - for (size_t i = 0; i < msg->_att.size(); i++) - { - if (strcmpP(msg->_att[i].descr.transfer_encoding, 0, esp_mail_str_166)) - { - msg->_att[i]._int.binary = true; - } - } -} - -bool ESP_Mail_Client::sendBlob(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att) -{ - if (strcmp(att->descr.transfer_encoding, Content_Transfer_Encoding::enc_base64) == 0 && strcmp(att->descr.transfer_encoding, att->descr.content_encoding) != 0) - { - if (!sendBase64(smtp, msg, (const unsigned char *)att->blob.data, att->blob.size, att->_int.flash_blob, att->descr.filename, smtp->_sendCallback != NULL)) - return false; - return true; - } - else - { - if (att->blob.size > 0) - { - size_t chunkSize = ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE; - size_t writeLen = 0; - uint8_t *buf = new uint8_t[chunkSize]; - int pg = 0, _pg = 0; - while (writeLen < att->blob.size) - { - if (writeLen > att->blob.size - chunkSize) - chunkSize = att->blob.size - writeLen; - - if (!bdat(smtp, msg, chunkSize, false)) - break; - memcpy_P(buf, att->blob.data, chunkSize); - if (smtpSend(smtp, buf, chunkSize) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - break; - - if (smtp->_sendCallback) - { - pg = (float)(100.0f * writeLen / att->blob.size); - if (pg != _pg) - uploadReport(att->descr.filename, pg); - _pg = pg; - } - writeLen += chunkSize; - } - delete[] buf; - if (smtp->_sendCallback && _pg < 100) - uploadReport(att->descr.filename, 100); - - return writeLen >= att->blob.size; - } - } - return false; -} - -bool ESP_Mail_Client::sendFile(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att, File &file) -{ - if (strcmp(att->descr.transfer_encoding, Content_Transfer_Encoding::enc_base64) == 0 && strcmp(att->descr.transfer_encoding, att->descr.content_encoding) != 0) - { - if (!sendBase64Stream(smtp, msg, file, att->descr.filename, smtp->_sendCallback != NULL)) - return false; - return true; - } - else - { - if (file.size() > 0) - { - size_t chunkSize = ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE; - size_t writeLen = 0; - if (file.size() < chunkSize) - chunkSize = file.size(); - uint8_t *buf = new uint8_t[chunkSize]; - int pg = 0, _pg = 0; - while (writeLen < file.size() && file.available()) - { - if (writeLen > file.size() - chunkSize) - chunkSize = file.size() - writeLen; - size_t readLen = file.read(buf, chunkSize); - if (readLen != chunkSize) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_FILE_IO_ERROR); - break; - } - - if (!bdat(smtp, msg, chunkSize, false)) - break; - - if (smtpSend(smtp, buf, chunkSize) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - break; - - if (smtp->_sendCallback) - { - pg = (float)(100.0f * writeLen / file.size()); - if (pg != _pg) - uploadReport(att->descr.filename, pg); - _pg = pg; - } - writeLen += chunkSize; - } - delete[] buf; - if (smtp->_sendCallback && _pg < 100) - uploadReport(att->descr.filename, 100); - return writeLen == file.size(); - } - return false; - } - return false; -} - -bool ESP_Mail_Client::sendParallelAttachments(SMTPSession *smtp, SMTP_Message *msg, const std::string &boundary) -{ - if (msg->_parallel.size() == 0) - return true; - - std::string buf; - std::string parallel = getBoundary(15); - appendP(buf, esp_mail_str_33, true); - buf += boundary; - appendP(buf, esp_mail_str_34, false); - - appendP(buf, esp_mail_str_28, false); - buf += parallel; - appendP(buf, esp_mail_str_35, false); - - if (!bdat(smtp, msg, buf.length(), false)) - return false; - - if (smtpSend(smtp, buf.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - - if (!sendAttachments(smtp, msg, parallel, true)) - return setSendingResult(smtp, msg, false); - - appendP(buf, esp_mail_str_33, true); - buf += parallel; - appendP(buf, esp_mail_str_33, false); - - if (!bdat(smtp, msg, buf.length(), false)) - return false; - - if (smtpSend(smtp, buf.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return setSendingResult(smtp, msg, false); - - return true; -} - -bool ESP_Mail_Client::sendAttachments(SMTPSession *smtp, SMTP_Message *msg, const std::string &boundary, bool parallel) -{ - std::string s; - std::string buf; - int cnt = 0; - - SMTP_Attachment *att = nullptr; - - size_t sz = msg->_att.size(); - if (parallel) - sz = msg->_parallel.size(); - - for (size_t i = 0; i < sz; i++) - { - if (parallel) - att = &msg->_parallel[i]; - else - att = &msg->_att[i]; - - if (att->_int.att_type == esp_mail_att_type_attachment) - { - appendP(s, esp_mail_str_261, true); - s += att->descr.filename; - - if (smtp->_sendCallback) - { - if (cnt > 0) - smtpCB(smtp, ""); - smtpCB(smtp, att->descr.filename); - } - - if (smtp->_debug) - esp_mail_debug(s.c_str()); - - cnt++; - - if (att->file.storage_type == esp_mail_file_storage_type_none) - { - if (!att->blob.data) - continue; - - if (smtp->_sendCallback) - smtpCB(smtp, att->descr.filename); - - if (smtp->_debug) - esp_mail_debug(s.c_str()); - - buf.clear(); - getAttachHeader(buf, boundary, att, att->blob.size); - - if (!bdat(smtp, msg, buf.length(), false)) - return false; - - if (smtpSend(smtp, buf.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (!sendBlob(smtp, msg, att)) - return false; - - if (!bdat(smtp, msg, 2, false)) - return false; - - if (smtpSendP(smtp, esp_mail_str_34, false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - } - else - { - - if (!_sdOk && att->file.storage_type == esp_mail_file_storage_type_sd) - _sdOk = sdTest(); - - if (!_flashOk && att->file.storage_type == esp_mail_file_storage_type_flash) -#if defined(ESP32) - _flashOk = ESP_MAIL_FLASH_FS.begin(FORMAT_FLASH); -#elif defined(ESP8266) - _flashOk = ESP_MAIL_FLASH_FS.begin(); -#endif - - if ((!_sdOk && att->file.storage_type == esp_mail_file_storage_type_sd) || (!_flashOk && att->file.storage_type == esp_mail_file_storage_type_flash)) - { - - if (smtp->_sendCallback) - debugInfoP(esp_mail_str_158); - - if (smtp->_debug) - { - std::string e; - appendP(e, esp_mail_str_185, true); - appendP(e, esp_mail_str_158, false); - esp_mail_debug(e.c_str()); - } - - continue; - } - - if (openFileRead(smtp, msg, att, file, s, buf, boundary, false)) - { - if (file) - { - - if (!sendFile(smtp, msg, att, file)) - return false; - - if (!bdat(smtp, msg, 2, false)) - return false; - - if (smtpSendP(smtp, esp_mail_str_34, false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - } - } - } - } - } - return true; -} - -bool ESP_Mail_Client::openFileRead(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att, File &file, std::string &s, std::string &buf, const std::string &boundary, bool inlined) -{ - bool file_existed = false; - std::string filepath; - - if (strlen(att->file.path) > 0) - { - if (att->file.path[0] != '/') - appendP(filepath, esp_mail_str_202, true); - filepath += att->file.path; - } - - if (att->file.storage_type == esp_mail_file_storage_type_sd) { - file_existed = ESP_MAIL_SD_FS.exists(filepath.c_str()); - } else if (att->file.storage_type == esp_mail_file_storage_type_flash) { - file_existed = ESP_MAIL_FLASH_FS.exists(filepath.c_str()); - } else if (att->file.storage_type == esp_mail_file_storage_type_univ) { - file_existed = ufsp->exists(filepath.c_str()); - } - - if (!file_existed) - { - - if (strlen(att->descr.filename) > 0) - { - filepath.clear(); - if (att->descr.filename[0] != '/') - appendP(filepath, esp_mail_str_202, true); - filepath += att->descr.filename; - } - - if (att->file.storage_type == esp_mail_file_storage_type_sd) { - file_existed = ESP_MAIL_SD_FS.exists(filepath.c_str()); - } else if (att->file.storage_type == esp_mail_file_storage_type_flash) { - file_existed = ESP_MAIL_FLASH_FS.exists(filepath.c_str()); - } else if (att->file.storage_type == esp_mail_file_storage_type_univ) { - file_existed = ufsp->exists(filepath.c_str()); - } - } - - if (!file_existed) - { - if (smtp->_sendCallback) - debugInfoP(esp_mail_str_158); - - if (smtp->_debug) - { - std::string e; - appendP(e, esp_mail_str_185, true); - appendP(e, esp_mail_str_158, false); - esp_mail_debug(e.c_str()); - } - } - - if (file_existed) - { - - buf.clear(); - - if (att->file.storage_type == esp_mail_file_storage_type_sd) { - file = ESP_MAIL_SD_FS.open(filepath.c_str(), FILE_READ); - } else if (att->file.storage_type == esp_mail_file_storage_type_flash) { -#if defined(ESP32) - file = ESP_MAIL_FLASH_FS.open(filepath.c_str(), FILE_READ); -#elif defined(ESP8266) - file = ESP_MAIL_FLASH_FS.open(filepath.c_str(), "r"); -#endif - } else if (att->file.storage_type == esp_mail_file_storage_type_univ) { - file = ufsp->open(filepath.c_str(), "r"); - } - - if (!file) - return false; - - if (inlined) - getInlineHeader(buf, boundary, att, file.size()); - else - getAttachHeader(buf, boundary, att, file.size()); - - if (!bdat(smtp, msg, buf.length(), false)) - return false; - - if (smtpSend(smtp, buf.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - return true; - } - - return false; -} - -bool ESP_Mail_Client::openFileRead2(SMTPSession *smtp, SMTP_Message *msg, File &file, const char *path, esp_mail_file_storage_type storageType) -{ - bool file_existed = false; - std::string filepath; - - if (strlen(path) > 0) - { - if (path[0] != '/') - appendP(filepath, esp_mail_str_202, true); - filepath += path; - } - - if (storageType == esp_mail_file_storage_type_sd) { - file_existed = ESP_MAIL_SD_FS.exists(filepath.c_str()); - } else if (storageType == esp_mail_file_storage_type_flash) { - file_existed = ESP_MAIL_FLASH_FS.exists(filepath.c_str()); - } else if (storageType == esp_mail_file_storage_type_univ) { - file_existed = ufsp->exists(filepath.c_str()); - } - - if (!file_existed) - { - if (smtp->_sendCallback) - debugInfoP(esp_mail_str_158); - - if (smtp->_debug) - { - std::string e; - appendP(e, esp_mail_str_185, true); - appendP(e, esp_mail_str_158, false); - esp_mail_debug(e.c_str()); - } - } - - if (file_existed) - { - if (storageType == esp_mail_file_storage_type_sd) - file = ESP_MAIL_SD_FS.open(filepath.c_str(), FILE_READ); - else if (storageType == esp_mail_file_storage_type_flash) -#if defined(ESP32) - file = ESP_MAIL_FLASH_FS.open(filepath.c_str(), FILE_READ); -#elif defined(ESP8266) - file = ESP_MAIL_FLASH_FS.open(filepath.c_str(), "r"); -#endif - return true; - } - - return false; -} - -bool ESP_Mail_Client::sendInline(SMTPSession *smtp, SMTP_Message *msg, const std::string &boundary, byte type) -{ - size_t num = numAtt(smtp, esp_mail_att_type_inline, msg) > 0; - - if (num > 0) - { - if (smtp->_sendCallback) - { - smtpCB(smtp, ""); - smtpCBP(smtp, esp_mail_str_167); - } - - if (smtp->_debug) - debugInfoP(esp_mail_str_271); - } - - std::string s; - std::string buf; - std::string related = getBoundary(15); - int cnt = 0; - SMTP_Attachment *att = nullptr; - - appendP(s, esp_mail_str_33, true); - s += boundary; - appendP(s, esp_mail_str_34, false); - - appendP(s, esp_mail_str_298, false); - s += related; - appendP(s, esp_mail_str_35, false); - - if (!bdat(smtp, msg, s.length(), false)) - return false; - - if (smtpSend(smtp, s.c_str()) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (!sendPartText(smtp, msg, type, related.c_str())) - return false; - - if (smtp->_sendCallback && numAtt(smtp, esp_mail_att_type_inline, msg) > 0) - esp_mail_debug(""); - - if (num > 0) - { - for (uint8_t i = 0; i < msg->_att.size(); i++) - { - att = &msg->_att[i]; - if (att->_int.att_type == esp_mail_att_type_inline) - { - appendP(s, esp_mail_str_261, true); - s += att->descr.filename; - - if (smtp->_sendCallback) - { - if (cnt > 0) - smtpCB(smtp, ""); - smtpCB(smtp, att->descr.filename); - } - - if (smtp->_debug) - esp_mail_debug(s.c_str()); - - cnt++; - - if (att->file.storage_type == esp_mail_file_storage_type_none) - { - if (!att->blob.data) - continue; - - if (smtp->_sendCallback) - smtpCB(smtp, att->descr.filename); - - if (smtp->_debug) - esp_mail_debug(s.c_str()); - - buf.clear(); - getInlineHeader(buf, related, att, att->blob.size); - - if (!bdat(smtp, msg, buf.length(), false)) - return false; - - if (smtpSend(smtp, buf.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (!sendBlob(smtp, msg, att)) - return false; - - if (!bdat(smtp, msg, 2, false)) - return false; - - if (smtpSendP(smtp, esp_mail_str_34, false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - } - else - { - if (!_sdOk && att->file.storage_type == esp_mail_file_storage_type_sd) - _sdOk = sdTest(); - - if (!_flashOk && att->file.storage_type == esp_mail_file_storage_type_flash) -#if defined(ESP32) - _flashOk = ESP_MAIL_FLASH_FS.begin(FORMAT_FLASH); -#elif defined(ESP8266) - _flashOk = ESP_MAIL_FLASH_FS.begin(); -#endif - - if ((!_sdOk && att->file.storage_type == esp_mail_file_storage_type_sd) || (!_flashOk && att->file.storage_type == esp_mail_file_storage_type_flash)) - { - - if (smtp->_sendCallback) - debugInfoP(esp_mail_str_158); - - if (smtp->_debug) - { - std::string e; - appendP(e, esp_mail_str_185, true); - appendP(e, esp_mail_str_158, false); - esp_mail_debug(e.c_str()); - } - - continue; - } - - if (openFileRead(smtp, msg, att, file, s, buf, related, true)) - { - if (!file) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_FILE_IO_ERROR); - return false; - } - - if (!sendFile(smtp, msg, att, file)) - return false; - - if (!bdat(smtp, msg, 2, false)) - return false; - - if (smtpSendP(smtp, esp_mail_str_34, false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - } - } - } - } - } - - appendP(s, esp_mail_str_34, true); - appendP(s, esp_mail_str_33, false); - s += related; - appendP(s, esp_mail_str_33, false); - appendP(s, esp_mail_str_34, false); - - if (!bdat(smtp, msg, s.length(), false)) - return false; - - if (smtpSend(smtp, s.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - return true; -} - -void ESP_Mail_Client::errorStatusCB(SMTPSession *smtp, int error) -{ - smtp->_smtpStatus.statusCode = error; - std::string s; - - if (smtp->_sendCallback) - { - appendP(s, esp_mail_str_53, true); - s += smtp->errorReason().c_str(); - smtpCB(smtp, s.c_str(), false); - } - - if (smtp->_debug) - { - appendP(s, esp_mail_str_185, true); - s += smtp->errorReason().c_str(); - esp_mail_debug(s.c_str()); - } -} - -size_t ESP_Mail_Client::smtpSendP(SMTPSession *smtp, PGM_P v, bool newline) -{ - if (!reconnect(smtp)) - { - closeTCP(smtp); - return 0; - } - - if (!connected(smtp)) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_CONNECTION_LOST); - return 0; - } - - if (!smtp->_tcpConnected) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - return 0; - } - - char *tmp = strP(v); - size_t len = 0; - - if (newline) - { - if (smtp->_debugLevel > esp_mail_debug_level_2) - esp_mail_debug(tmp); - if (smtp->_sesson_cfg->secure.startTLS || !smtp->_secure) - len = smtp->httpClient._ns_println(tmp); - else - len = smtp->httpClient.stream()->println(tmp); - } - else - { - if (smtp->_debugLevel > esp_mail_debug_level_2) - esp_mail_debug_line(tmp, false); - - if (smtp->_sesson_cfg->secure.startTLS || !smtp->_secure) - len = smtp->httpClient._ns_print(tmp); - else - len = smtp->httpClient.stream()->print(tmp); - } - - if (len != strlen(tmp) && len != strlen(tmp) + 2) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - len = 0; - } - - delS(tmp); - - return len; -} - -size_t ESP_Mail_Client::smtpSend(SMTPSession *smtp, const char *data, bool newline) -{ - if (!reconnect(smtp)) - { - closeTCP(smtp); - return 0; - } - - if (!connected(smtp)) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_CONNECTION_LOST); - return 0; - } - - if (!smtp->_tcpConnected) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - return 0; - } - - size_t len = 0; - - if (newline) - { - if (smtp->_debugLevel > esp_mail_debug_level_2) - esp_mail_debug(data); - - if (smtp->_sesson_cfg->secure.startTLS || !smtp->_secure) - len = smtp->httpClient._ns_println(data); - else - len = smtp->httpClient.stream()->println(data); - } - else - { - if (smtp->_debugLevel > esp_mail_debug_level_2) - esp_mail_debug_line(data, false); - - if (smtp->_sesson_cfg->secure.startTLS || !smtp->_secure) - len = smtp->httpClient._ns_print(data); - else - len = smtp->httpClient.stream()->print(data); - } - - if (len != strlen(data) && len != strlen(data) + 2) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - len = 0; - } - - return len; -} - -size_t ESP_Mail_Client::smtpSend(SMTPSession *smtp, int data, bool newline) -{ - if (!reconnect(smtp)) - { - closeTCP(smtp); - return 0; - } - - if (!connected(smtp)) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_CONNECTION_LOST); - return 0; - } - - if (!smtp->_tcpConnected) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - return 0; - } - - char *tmp = intStr(data); - size_t len = 0; - - if (newline) - { - if (smtp->_debugLevel > esp_mail_debug_level_2) - esp_mail_debug(tmp); - - if (smtp->_sesson_cfg->secure.startTLS || !smtp->_secure) - len = smtp->httpClient._ns_println(tmp); - else - len = smtp->httpClient.stream()->println(tmp); - } - else - { - if (smtp->_debugLevel > esp_mail_debug_level_2) - esp_mail_debug_line(tmp, false); - - if (smtp->_sesson_cfg->secure.startTLS || !smtp->_secure) - len = smtp->httpClient._ns_print(tmp); - else - len = smtp->httpClient.stream()->print(tmp); - } - - if (len != strlen(tmp) && len != strlen(tmp) + 2) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - len = 0; - } - - delS(tmp); - - return len; -} - -size_t ESP_Mail_Client::smtpSend(SMTPSession *smtp, uint8_t *data, size_t size) -{ - if (!reconnect(smtp)) - { - closeTCP(smtp); - return 0; - } - - if (!connected(smtp)) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_CONNECTION_LOST); - return 0; - } - - if (!smtp->_tcpConnected) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - return 0; - } - - size_t len = 0; - - if (smtp->_sesson_cfg->secure.startTLS || !smtp->_secure) - len = smtp->httpClient._stream()->write(data, size); - else - len = smtp->httpClient.stream()->write(data, size); - - if (len != size) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED); - len = 0; - } - - return len; -} - -bool ESP_Mail_Client::handleSMTPError(SMTPSession *smtp, int err, bool ret) -{ - if (err < 0) - errorStatusCB(smtp, err); - - if (smtp->_tcpConnected) - closeTCP(smtp); - - return ret; -} - -void ESP_Mail_Client::debugInfoP(PGM_P info) -{ - char *tmp = strP(info); - esp_mail_debug(tmp); - delS(tmp); -} - -bool ESP_Mail_Client::sdBegin(uint8_t sck, uint8_t miso, uint8_t mosi, uint8_t ss) -{ - _sck = sck; - _miso = miso; - _mosi = mosi; - _ss = ss; - _sdConfigSet = true; -#if defined(ESP32) -#if defined(CARD_TYPE_SD) - SPI.begin(_sck, _miso, _mosi, _ss); - return ESP_MAIL_SD_FS.begin(_ss, SPI); -#endif -#elif defined(ESP8266) - return ESP_MAIL_SD_FS.begin(_ss); -#endif - return false; -} - -bool ESP_Mail_Client::sdBegin(void) -{ - _sdConfigSet = false; -#if defined(ESP32) - return ESP_MAIL_SD_FS.begin(); -#elif defined(ESP8266) - return ESP_MAIL_SD_FS.begin(SD_CS_PIN); -#endif - return false; -} - -bool ESP_Mail_Client::sdMMCBegin(const char *mountpoint, bool mode1bit, bool format_if_mount_failed) -{ -#if defined(ESP32) -#if defined(CARD_TYPE_SD_MMC) - _sdConfigSet = true; - sd_mmc_mountpoint = mountpoint; - sd_mmc_mode1bit = mode1bit; - sd_mmc_format_if_mount_failed = format_if_mount_failed; - return ESP_MAIL_SD_FS.begin(mountpoint, mode1bit, format_if_mount_failed); -#endif -#endif - return false; -} - -bool ESP_Mail_Client::sendPartText(SMTPSession *smtp, SMTP_Message *msg, uint8_t type, const char *boundary) -{ - std::string header; - - if (strlen(boundary) > 0) - { - appendP(header, esp_mail_str_33, false); - header += boundary; - appendP(header, esp_mail_str_34, false); - } - - if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) - { - if (strlen(msg->text.content_type) > 0) - { - appendP(header, esp_mail_str_25, false); - header += msg->text.content_type; - - if (strlen(msg->text.charSet) > 0) - { - appendP(header, esp_mail_str_97, false); - appendP(header, esp_mail_str_131, false); - appendP(header, esp_mail_str_168, false); - header += msg->text.charSet; - appendP(header, esp_mail_str_136, false); - } - - if (msg->text.flowed) - { - appendP(header, esp_mail_str_97, false); - appendP(header, esp_mail_str_131, false); - appendP(header, esp_mail_str_270, false); - - appendP(header, esp_mail_str_97, false); - appendP(header, esp_mail_str_131, false); - appendP(header, esp_mail_str_110, false); - } - - if (msg->text.embed.enable) - { - appendP(header, esp_mail_str_26, false); - appendP(header, esp_mail_str_164, false); - appendP(header, esp_mail_str_136, false); - char *tmp = getUID(); - msg->text._int.cid = tmp; - delS(tmp); - } - - appendP(header, esp_mail_str_34, false); - } - - if (strlen(msg->text.transfer_encoding) > 0) - { - appendP(header, esp_mail_str_272, false); - header += msg->text.transfer_encoding; - appendP(header, esp_mail_str_34, false); - } - } - else if (type == esp_mail_msg_type_html) - { - if (strlen(msg->text.content_type) > 0) - { - appendP(header, esp_mail_str_25, false); - header += msg->html.content_type; - - if (strlen(msg->html.charSet) > 0) - { - appendP(header, esp_mail_str_97, false); - appendP(header, esp_mail_str_131, false); - appendP(header, esp_mail_str_168, false); - header += msg->html.charSet; - appendP(header, esp_mail_str_136, false); - } - if (msg->html.embed.enable) - { - appendP(header, esp_mail_str_26, false); - appendP(header, esp_mail_str_159, false); - appendP(header, esp_mail_str_136, false); - char *tmp = getUID(); - msg->html._int.cid = tmp; - delS(tmp); - } - appendP(header, esp_mail_str_34, false); - } - - if (strlen(msg->html.transfer_encoding) > 0) - { - appendP(header, esp_mail_str_272, false); - header += msg->html.transfer_encoding; - appendP(header, esp_mail_str_34, false); - } - } - - if ((type == esp_mail_msg_type_html && msg->html.embed.enable) || ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && msg->text.embed.enable)) - { - - if ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && msg->text.embed.enable) - { - if (msg->text.embed.type == esp_mail_smtp_embed_message_type_attachment) - appendP(header, esp_mail_str_30, false); - else if (msg->text.embed.type == esp_mail_smtp_embed_message_type_inline) - appendP(header, esp_mail_str_299, false); - - if (strlen(msg->text.embed.filename) > 0) - header += msg->text.embed.filename; - else - appendP(header, esp_mail_str_164, false); - appendP(header, esp_mail_str_36, false); - - if (msg->text.embed.type == esp_mail_smtp_embed_message_type_inline) - { - appendP(header, esp_mail_str_300, false); - if (strlen(msg->text.embed.filename) > 0) - header += msg->text.embed.filename; - else - appendP(header, esp_mail_str_159, false); - appendP(header, esp_mail_str_34, false); - - appendP(header, esp_mail_str_301, false); - header += msg->text._int.cid; - appendP(header, esp_mail_str_15, false); - appendP(header, esp_mail_str_34, false); - } - } - else if (type == esp_mail_msg_type_html && msg->html.embed.enable) - { - if (msg->html.embed.type == esp_mail_smtp_embed_message_type_attachment) - appendP(header, esp_mail_str_30, false); - else if (msg->html.embed.type == esp_mail_smtp_embed_message_type_inline) - appendP(header, esp_mail_str_299, false); - - if (strlen(msg->html.embed.filename) > 0) - header += msg->html.embed.filename; - else - appendP(header, esp_mail_str_159, false); - appendP(header, esp_mail_str_36, false); - - if (msg->html.embed.type == esp_mail_smtp_embed_message_type_inline) - { - appendP(header, esp_mail_str_300, false); - if (strlen(msg->html.embed.filename) > 0) - header += msg->html.embed.filename; - else - appendP(header, esp_mail_str_159, false); - appendP(header, esp_mail_str_34, false); - - appendP(header, esp_mail_str_301, false); - header += msg->html._int.cid; - appendP(header, esp_mail_str_15, false); - appendP(header, esp_mail_str_34, false); - } - } - } - - appendP(header, esp_mail_str_34, false); - - if ((msg->text.blob.size > 0 && (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched)) || (msg->html.blob.size > 0 && type == esp_mail_msg_type_html)) - { - if (!bdat(smtp, msg, header.length(), false)) - return false; - - if (smtpSend(smtp, header.c_str()) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - header.clear(); - - if (!sendBlobBody(smtp, msg, type)) - return false; - } - else if ((strlen(msg->text.file.name) > 0 && (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched)) || (strlen(msg->html.file.name) > 0 && type == esp_mail_msg_type_html)) - { - if (!bdat(smtp, msg, header.length(), false)) - return false; - - if (smtpSend(smtp, header.c_str()) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - header.clear(); - - if (!sendFileBody(smtp, msg, type)) - return false; - } - else - encodingText(smtp, msg, type, header); - - appendP(header, esp_mail_str_34, false); - - if (strlen(boundary) > 0) - appendP(header, esp_mail_str_34, false); - - if (!bdat(smtp, msg, header.length(), false)) - return false; - - if (smtpSend(smtp, header.c_str()) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - return true; -} - -char *ESP_Mail_Client::getUID() -{ - char *tmp = new char[36]; - memset(tmp, 0, 36); - itoa(random(10000000, 20000000), tmp, 10); - return tmp; -} - -bool ESP_Mail_Client::sendBlobBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type) -{ - - if (msg->text.blob.size == 0 && msg->html.blob.size == 0) - return true; - - bool ret = true; - int bufLen = 512; - size_t pos = 0; - int pg = 0, _pg = 0; - - if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) - { - char *tmp = strP(esp_mail_str_325); - - if (strlen(msg->text.transfer_encoding) > 0) - { - if (strcmp(msg->text.transfer_encoding, Content_Transfer_Encoding::enc_base64) == 0) - { - ret = sendBase64(smtp, msg, (const unsigned char *)msg->text.blob.data, msg->text.blob.size, true, tmp, smtp->_sendCallback != NULL); - delS(tmp); - return ret; - } - } - - int len = msg->text.blob.size; - int available = len; - uint8_t *buf = new uint8_t[bufLen + 1]; - while (available) - { - if (available > bufLen) - available = bufLen; - - memcpy_P(buf, msg->text.blob.data + pos, available); - - if (!bdat(smtp, msg, available, false)) - break; - if (smtpSend(smtp, buf, available) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - break; - pos += available; - len -= available; - available = len; - if (smtp->_sendCallback) - { - pg = (float)(100.0f * pos / msg->text.blob.size); - if (pg != _pg) - uploadReport(tmp, pg); - _pg = pg; - } - } - delete[] buf; - delS(tmp); - } - else if (type == esp_mail_message_type::esp_mail_msg_type_html) - { - char *tmp = strP(esp_mail_str_325); - - if (strlen(msg->html.transfer_encoding) > 0) - { - if (strcmp(msg->html.transfer_encoding, Content_Transfer_Encoding::enc_base64) == 0) - { - ret = sendBase64(smtp, msg, (const unsigned char *)msg->html.blob.data, msg->html.blob.size, true, tmp, smtp->_sendCallback != NULL); - delS(tmp); - return ret; - } - } - int len = msg->html.blob.size; - int available = len; - uint8_t *buf = new uint8_t[bufLen + 1]; - while (available) - { - - if (available > bufLen) - available = bufLen; - - memcpy_P(buf, msg->html.blob.data + pos, available); - - if (!bdat(smtp, msg, available, false)) - { - ret = false; - break; - } - - if (smtpSend(smtp, buf, available) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - { - ret = false; - break; - } - pos += available; - len -= available; - available = len; - if (smtp->_sendCallback) - { - pg = (float)(100.0f * pos / msg->html.blob.size); - if (pg != _pg) - uploadReport(tmp, pg); - _pg = pg; - } - } - delete[] buf; - delS(tmp); - } - return ret; -} - -bool ESP_Mail_Client::sendFileBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type) -{ - - if (strlen(msg->text.file.name) == 0 && strlen(msg->html.file.name) == 0) - return true; - - bool ret = true; - size_t chunkSize = ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE; - size_t writeLen = 0; - int pg = 0, _pg = 0; - - if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) - { - - if (!openFileRead2(smtp, msg, file, msg->text.file.name, msg->text.file.type)) - return false; - - char *tmp = strP(esp_mail_str_326); - - if (strlen(msg->text.transfer_encoding) > 0) - { - if (strcmp(msg->text.transfer_encoding, Content_Transfer_Encoding::enc_base64) == 0) - { - ret = sendBase64Stream(smtp, msg, file, tmp, smtp->_sendCallback != NULL); - delS(tmp); - return ret; - } - } - - if (file.size() > 0) - { - - if (file.size() < chunkSize) - chunkSize = file.size(); - uint8_t *buf = new uint8_t[chunkSize]; - while (writeLen < file.size() && file.available()) - { - if (writeLen > file.size() - chunkSize) - chunkSize = file.size() - writeLen; - size_t readLen = file.read(buf, chunkSize); - - if (readLen != chunkSize) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_FILE_IO_ERROR); - break; - } - - if (!bdat(smtp, msg, chunkSize, false)) - { - ret = false; - break; - } - - if (smtpSend(smtp, buf, chunkSize) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - { - ret = false; - break; - } - - if (smtp->_sendCallback) - { - pg = (float)(100.0f * writeLen / file.size()); - if (pg != _pg) - uploadReport(tmp, pg); - _pg = pg; - } - writeLen += chunkSize; - } - delete[] buf; - if (smtp->_sendCallback && _pg < 100) - uploadReport(tmp, 100); - - delS(tmp); - return ret && writeLen == file.size(); - } - } - else if (type == esp_mail_message_type::esp_mail_msg_type_html) - { - - if (!openFileRead2(smtp, msg, file, msg->html.file.name, msg->html.file.type)) - return false; - - char *tmp = strP(esp_mail_str_326); - - if (strlen(msg->html.transfer_encoding) > 0) - { - if (strcmp(msg->html.transfer_encoding, Content_Transfer_Encoding::enc_base64) == 0) - { - ret = sendBase64Stream(smtp, msg, file, tmp, smtp->_sendCallback != NULL); - delS(tmp); - return ret; - } - } - - if (file.size() > 0) - { - - if (file.size() < chunkSize) - chunkSize = file.size(); - uint8_t *buf = new uint8_t[chunkSize]; - while (writeLen < file.size() && file.available()) - { - if (writeLen > file.size() - chunkSize) - chunkSize = file.size() - writeLen; - size_t readLen = file.read(buf, chunkSize); - - if (readLen != chunkSize) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_FILE_IO_ERROR); - break; - } - - if (!bdat(smtp, msg, chunkSize, false)) - { - ret = false; - break; - } - - if (smtpSend(smtp, buf, chunkSize) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - { - ret = false; - break; - } - - if (smtp->_sendCallback) - { - pg = (float)(100.0f * writeLen / file.size()); - if (pg != _pg) - uploadReport(tmp, pg); - _pg = pg; - } - writeLen += chunkSize; - } - delete[] buf; - if (smtp->_sendCallback && _pg < 100) - uploadReport(tmp, 100); - - delS(tmp); - return ret && writeLen == file.size(); - } - } - - return false; -} - -void ESP_Mail_Client::encodingText(SMTPSession *smtp, SMTP_Message *msg, uint8_t type, std::string &content) -{ - if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) - { - std::string s = msg->text.content; - - if (msg->text.flowed) - formatFlowedText(s); - - if (strlen(msg->text.transfer_encoding) > 0) - { - if (strcmp(msg->text.transfer_encoding, Content_Transfer_Encoding::enc_base64) == 0) - content += encodeBase64Str((const unsigned char *)s.c_str(), s.length()); - else if (strcmp(msg->text.transfer_encoding, Content_Transfer_Encoding::enc_qp) == 0) - { - char *out = newS(s.length() * 3 + 1); - encodeQP(s.c_str(), out); - content += out; - delS(out); - } - else - content += s; - } - else - content += s; - } - else if (type == esp_mail_message_type::esp_mail_msg_type_html) - { - char *tmp = nullptr; - std::string s = msg->html.content; - std::string fnd, rep; - SMTP_Attachment *att = nullptr; - for (uint8_t i = 0; i < msg->_att.size(); i++) - { - att = &msg->_att[i]; - if (att->_int.att_type == esp_mail_att_type_inline) - { - std::string filename(att->descr.filename); - - size_t found = filename.find_last_of("/\\"); - if (found != std::string::npos) - filename = filename.substr(found + 1); - - appendP(fnd, esp_mail_str_136, true); - fnd += filename; - appendP(fnd, esp_mail_str_136, false); - - appendP(rep, esp_mail_str_136, true); - appendP(rep, esp_mail_str_302, false); - if (strlen(att->descr.content_id) > 0) - rep += att->descr.content_id; - else - rep += att->_int.cid; - appendP(rep, esp_mail_str_136, false); - - tmp = strReplace((char *)s.c_str(), (char *)fnd.c_str(), (char *)rep.c_str()); - s = tmp; - delS(tmp); - } - } - - if (strlen(msg->html.transfer_encoding) > 0) - { - if (strcmp(msg->html.transfer_encoding, Content_Transfer_Encoding::enc_base64) == 0) - content += encodeBase64Str((const unsigned char *)s.c_str(), s.length()); - else if (strcmp(msg->html.transfer_encoding, Content_Transfer_Encoding::enc_qp) == 0) - { - char *out = newS(strlen(msg->html.content) * 3 + 1); - encodeQP(msg->html.content, out); - content += out; - delS(out); - } - else - content += s; - } - else - content += s; - std::string().swap(s); - } -} - -/* Safe string splitter to avoid strsep bugs*/ -void ESP_Mail_Client::splitTk(std::string &str, std::vector &tk, const char *delim) -{ - std::size_t current, previous = 0; - current = str.find(delim, previous); - std::string s; - while (current != std::string::npos) - { - s = str.substr(previous, current - previous); - tk.push_back(s); - previous = current + strlen(delim); - current = str.find(delim, previous); - } - s = str.substr(previous, current - previous); - tk.push_back(s); - std::string().swap(s); -} - -/** Add the soft line break to the long text line (rfc 3676) - * and add Format=flowed parameter in the plain text content-type header. - * We use the existing white space as a part of this soft line break - * and set delSp="no" parameter to the header. - * - * Some servers are not rfc 3676 compliant. - * This causes the text lines are wrapped instead of joined. - * - * Some mail clients trim the space before the line break - * which makes the soft line break cannot be seen. -*/ -void ESP_Mail_Client::formatFlowedText(std::string &content) -{ - int count = 0; - std::string qms; - int j = 0; - std::vector tokens = std::vector(); - char *stk = strP(esp_mail_str_34); - char *qm = strP(esp_mail_str_15); - splitTk(content, tokens, stk); - content.clear(); - for (size_t i = 0; i < tokens.size(); i++) - { - if (tokens[i].length() > 0) - { - j = 0; - qms.clear(); - while (tokens[i][j] == qm[0]) - { - qms += qm; - j++; - } - softBreak(tokens[i], qms.c_str()); - if (count > 0) - content += stk; - content += tokens[i]; - } - else if (count > 0) - content += stk; - count++; - } - - delS(stk); - delS(qm); - tokens.clear(); -} - -void ESP_Mail_Client::softBreak(std::string &content, const char *quoteMarks) -{ - size_t len = 0; - char *stk = strP(esp_mail_str_131); - std::vector tokens = std::vector(); - splitTk(content, tokens, stk); - content.clear(); - for (size_t i = 0; i < tokens.size(); i++) - { - if (tokens[i].length() > 0) - { - if (len + tokens[i].length() + 3 > FLOWED_TEXT_LEN) - { - /* insert soft crlf */ - content += stk; - appendP(content, esp_mail_str_34, false); - - /* insert quote marks */ - if (strlen(quoteMarks) > 0) - content += quoteMarks; - content += tokens[i]; - len = tokens[i].length(); - } - else - { - if (len > 0) - { - content += stk; - len += strlen(stk); - } - content += tokens[i]; - len += tokens[i].length(); - } - } - } - delS(stk); - tokens.clear(); -} - -bool ESP_Mail_Client::sendMSG(SMTPSession *smtp, SMTP_Message *msg, const std::string &boundary) -{ - std::string alt = getBoundary(15); - std::string s; - - if (numAtt(smtp, esp_mail_att_type_inline, msg) > 0) - { - appendP(s, esp_mail_str_297, true); - s += alt; - appendP(s, esp_mail_str_35, false); - - if (!bdat(smtp, msg, s.length(), false)) - return false; - - if (smtpSend(smtp, s.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (msg->type == esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched || msg->type == esp_mail_msg_type_html) - { - if (!sendInline(smtp, msg, alt, msg->type)) - return false; - } - else if (msg->type == (esp_mail_msg_type_html | esp_mail_msg_type_enriched | esp_mail_msg_type_plain)) - { - if (!sendPartText(smtp, msg, esp_mail_msg_type_plain, alt.c_str())) - return false; - if (!sendInline(smtp, msg, alt, esp_mail_msg_type_html)) - return false; - } - - appendP(s, esp_mail_str_33, true); - s += alt; - appendP(s, esp_mail_str_33, false); - appendP(s, esp_mail_str_34, false); - - if (!bdat(smtp, msg, s.length(), false)) - return false; - - if (smtpSend(smtp, s.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - } - else - { - if (msg->type == esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched || msg->type == esp_mail_msg_type_html) - { - if (!sendPartText(smtp, msg, msg->type, "")) - return false; - } - else if (msg->type == (esp_mail_msg_type_html | esp_mail_msg_type_enriched | esp_mail_msg_type_plain)) - { - appendP(s, esp_mail_str_33, true); - s += boundary; - appendP(s, esp_mail_str_34, false); - appendP(s, esp_mail_str_297, false); - s += alt; - appendP(s, esp_mail_str_35, false); - - if (!bdat(smtp, msg, s.length(), false)) - return false; - - if (smtpSend(smtp, s.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (!sendPartText(smtp, msg, esp_mail_msg_type_plain, alt.c_str())) - return false; - - if (!sendPartText(smtp, msg, esp_mail_msg_type_html, alt.c_str())) - return false; - } - } - return true; -} - -void ESP_Mail_Client::getInlineHeader(std::string &header, const std::string &boundary, SMTP_Attachment *inlineAttach, size_t size) -{ - appendP(header, esp_mail_str_33, false); - header += boundary; - appendP(header, esp_mail_str_34, false); - - appendP(header, esp_mail_str_25, false); - - if (strlen(inlineAttach->descr.mime) == 0) - { - std::string mime; - mimeFromFile(inlineAttach->descr.filename, mime); - if (mime.length() > 0) - header += mime; - else - appendP(header, esp_mail_str_32, false); - } - else - header += inlineAttach->descr.mime; - - appendP(header, esp_mail_str_26, false); - - std::string filename = inlineAttach->descr.filename; - - size_t found = filename.find_last_of("/\\"); - - if (found != std::string::npos) - filename = filename.substr(found + 1); - - header += filename; - appendP(header, esp_mail_str_36, false); - - appendP(header, esp_mail_str_299, false); - header += filename; - appendP(header, esp_mail_str_327, false); - char *tmp = intStr(size); - header += tmp; - delS(tmp); - appendP(header, esp_mail_str_34, false); - - appendP(header, esp_mail_str_300, false); - header += filename; - appendP(header, esp_mail_str_34, false); - - appendP(header, esp_mail_str_301, false); - if (strlen(inlineAttach->descr.content_id) > 0) - header += inlineAttach->descr.content_id; - else - header += inlineAttach->_int.cid; - - appendP(header, esp_mail_str_15, false); - - appendP(header, esp_mail_str_34, false); - - if (strlen(inlineAttach->descr.transfer_encoding) > 0) - { - appendP(header, esp_mail_str_272, false); - header += inlineAttach->descr.transfer_encoding; - appendP(header, esp_mail_str_34, false); - } - appendP(header, esp_mail_str_34, false); - - std::string().swap(filename); -} - -void ESP_Mail_Client::getAttachHeader(std::string &header, const std::string &boundary, SMTP_Attachment *attach, size_t size) -{ - appendP(header, esp_mail_str_33, false); - header += boundary; - appendP(header, esp_mail_str_34, false); - - appendP(header, esp_mail_str_25, false); - - if (strlen(attach->descr.mime) == 0) - { - std::string mime; - mimeFromFile(attach->descr.filename, mime); - if (mime.length() > 0) - header += mime; - else - appendP(header, esp_mail_str_32, false); - } - else - header += attach->descr.mime; - - appendP(header, esp_mail_str_26, false); - - std::string filename = attach->descr.filename; - - size_t found = filename.find_last_of("/\\"); - if (found != std::string::npos) - filename = filename.substr(found + 1); - - header += filename; - appendP(header, esp_mail_str_36, false); - - if (!attach->_int.parallel) - { - appendP(header, esp_mail_str_30, false); - header += filename; - appendP(header, esp_mail_str_327, false); - char *tmp = intStr(size); - header += tmp; - delS(tmp); - appendP(header, esp_mail_str_34, false); - } - - if (strlen(attach->descr.transfer_encoding) > 0) - { - appendP(header, esp_mail_str_272, false); - header += attach->descr.transfer_encoding; - appendP(header, esp_mail_str_34, false); - } - - appendP(header, esp_mail_str_34, false); - - std::string().swap(filename); -} - -void ESP_Mail_Client::getRFC822PartHeader(SMTPSession *smtp, std::string &header, const std::string &boundary) -{ - appendP(header, esp_mail_str_33, false); - header += boundary; - appendP(header, esp_mail_str_34, false); - - appendP(header, esp_mail_str_25, false); - - appendP(header, esp_mail_str_123, false); - appendP(header, esp_mail_str_34, false); - - appendP(header, esp_mail_str_98, false); - - appendP(header, esp_mail_str_34, false); -} - -void ESP_Mail_Client::smtpCBP(SMTPSession *smtp, PGM_P info, bool success) -{ - std::string s; - appendP(s, info, true); - smtp->_cbData._info = s; - smtp->_cbData._success = success; - smtp->_sendCallback(smtp->_cbData); - std::string().swap(s); -} - -void ESP_Mail_Client::smtpCB(SMTPSession *smtp, const char *info, bool success) -{ - smtp->_cbData._info = info; - smtp->_cbData._success = success; - smtp->_sendCallback(smtp->_cbData); -} - -void ESP_Mail_Client::imapCBP(IMAPSession *imap, PGM_P info, bool success) -{ - char *tmp = strP(info); - imap->_cbData._info = tmp; - imap->_cbData._success = success; - imap->_readCallback(imap->_cbData); - delS(tmp); -} - -void ESP_Mail_Client::imapCB(IMAPSession *imap, const char *info, bool success) -{ - imap->_cbData._info = info; - imap->_cbData._success = success; - imap->_readCallback(imap->_cbData); -} - -void ESP_Mail_Client::strcat_c(char *str, char c) -{ - for (; *str; str++) - ; - *str++ = c; - *str++ = 0; -} -int ESP_Mail_Client::strpos(const char *haystack, const char *needle, int offset) -{ - size_t len = strlen(haystack); - size_t len2 = strlen(needle); - if (len == 0 || len < len2 || len2 == 0 || offset >= (int)len || offset < 0) - return -1; - char *_haystack = newS(len - offset + 1); - _haystack[len - offset] = 0; - strncpy(_haystack, haystack + offset, len - offset); - char *p = stristr(_haystack, needle); - int r = -1; - if (p) - r = p - _haystack + offset; - delS(_haystack); - return r; -} - -char *ESP_Mail_Client::stristr(const char *str1, const char *str2) -{ - const char *p1 = str1; - const char *p2 = str2; - const char *r = *p2 == 0 ? str1 : 0; - - while (*p1 != 0 && *p2 != 0) - { - if (tolower((unsigned char)*p1) == tolower((unsigned char)*p2)) - { - if (r == 0) - r = p1; - p2++; - } - else - { - p2 = str2; - if (r != 0) - p1 = r + 1; - - if (tolower((unsigned char)*p1) == tolower((unsigned char)*p2)) - { - r = p1; - p2++; - } - else - r = 0; - } - - p1++; - } - - return *p2 == 0 ? (char *)r : 0; -} - -char *ESP_Mail_Client::rstrstr(const char *haystack, const char *needle) -{ - size_t needle_length = strlen(needle); - const char *haystack_end = haystack + strlen(haystack) - needle_length; - const char *p; - size_t i; - for (p = haystack_end; p >= haystack; --p) - { - for (i = 0; i < needle_length; ++i) - { - if (p[i] != needle[i]) - goto next; - } - return (char *)p; - next:; - } - return 0; -} - -int ESP_Mail_Client::rstrpos(const char *haystack, const char *needle, int offset) -{ - size_t len = strlen(haystack); - size_t len2 = strlen(needle); - if (len == 0 || len < len2 || len2 == 0 || offset >= (int)len) - return -1; - char *_haystack = newS(len - offset + 1); - _haystack[len - offset] = 0; - strncpy(_haystack, haystack + offset, len - offset); - char *p = rstrstr(_haystack, needle); - int r = -1; - if (p) - r = p - _haystack + offset; - delS(_haystack); - return r; -} - -int ESP_Mail_Client::readLine(WiFiClient *stream, char *buf, int bufLen, bool crlf, int &count) -{ - int ret = -1; - char c = 0; - char _c = 0; - int idx = 0; - if (!stream) - return idx; - while (stream->available() && idx < bufLen) - { - ret = stream->read(); - if (ret > -1) - { - if (idx >= bufLen - 1) - return idx; - - c = (char)ret; - strcat_c(buf, c); - idx++; - count++; - if (_c == '\r' && c == '\n') - { - if (!crlf) - { - buf[idx - 2] = 0; - idx -= 2; - } - return idx; - } - _c = c; - } - if (!stream) - return idx; - } - return idx; -} - -#if defined(ESP32) -int ESP_Mail_Client::_readLine(ESP_Mail_WCS32 *stream, char *buf, int bufLen, bool crlf, int &count) -#elif defined(ESP8266) -int ESP_Mail_Client::_readLine(ESP_Mail::ESP_Mail_WCS *stream, char *buf, int bufLen, bool crlf, int &count) -#endif -{ - int ret = -1; - char c = 0; - char _c = 0; - int idx = 0; - if (!stream) - return idx; - while (stream->_ns_available() && idx < bufLen) - { - ret = stream->_ns_read(); - if (ret > -1) - { - if (idx >= bufLen - 1) - return idx; - - c = (char)ret; - strcat_c(buf, c); - idx++; - count++; - if (_c == '\r' && c == '\n') - { - if (!crlf) - { - buf[idx - 2] = 0; - idx -= 2; - } - return idx; - } - _c = c; - } - if (!stream) - return idx; - } - return idx; -} - -int ESP_Mail_Client::getMSGNUM(IMAPSession *imap, char *buf, int bufLen, int &chunkIdx, bool &endSearch, int &nump, const char *key, const char *pc) -{ - int ret = -1; - char c = 0; - int idx = 0; - int num = 0; - while (available(imap) > 0 && idx < bufLen) - { - delay(0); - if (!imap->_secure) - ret = imap->httpClient._stream()->read(); - else - ret = imap->httpClient.stream()->read(); - - if (ret > -1) - { - - if (idx >= bufLen - 1) - return idx; - - c = (char)ret; - - if (c == '\n') - c = ' '; - - strcat_c(buf, c); - idx++; - - if (chunkIdx == 0) - { - if (strcmp(buf, key) == 0) - { - chunkIdx++; - return 0; - } - - if (strposP(buf, esp_mail_imap_response_1, 0) > -1) - goto end_search; - } - else - { - if (c == ' ') - { - imap->_mbif._searchCount++; - if (imap->_config->enable.recent_sort) - { - imap->_msgNum.push_back(atoi(buf)); - if (imap->_msgNum.size() > imap->_config->limit.search) - imap->_msgNum.erase(imap->_msgNum.begin()); - } - else - { - if (imap->_msgNum.size() < imap->_config->limit.search) - imap->_msgNum.push_back(atoi(buf)); - } - - if (imap->_debug) - { - num = (float)(100.0f * imap->_mbif._searchCount / imap->_mbif._msgCount); - if (nump != num) - { - nump = num; - searchReport(num, pc); - } - } - - chunkIdx++; - return idx; - } - else if (c == '$') - { - if (imap->_config->enable.recent_sort) - std::sort(imap->_msgNum.begin(), imap->_msgNum.end(), compFunc); - - goto end_search; - } - } - } - } - - return idx; - -end_search: - - endSearch = true; - int read = available(imap); - - if (!imap->_secure) - idx = imap->httpClient._stream()->readBytes(buf + idx, read); - else - idx = imap->httpClient.stream()->readBytes(buf + idx, read); - - return idx; -} - -struct esp_mail_message_part_info_t *ESP_Mail_Client::cPart(IMAPSession *imap) -{ - return &cHeader(imap)->part_headers[imap->_cPartIdx]; -} - -struct esp_mail_message_header_t *ESP_Mail_Client::cHeader(IMAPSession *imap) -{ - return &imap->_headers[cIdx(imap)]; -} - -void ESP_Mail_Client::handleHeader(IMAPSession *imap, char *buf, int bufLen, int &chunkIdx, struct esp_mail_message_header_t &header, int &headerState, int &octetCount) -{ - - char *tmp = nullptr; - if (chunkIdx == 0) - { - if (strposP(buf, esp_mail_str_324, 0) != -1 && buf[0] == '*') - chunkIdx++; - - tmp = subStr(buf, esp_mail_str_193, esp_mail_str_194, 0); - if (tmp) - { - octetCount = 2; - header.header_data_len = atoi(tmp); - delS(tmp); - } - } - else - { - if (octetCount > header.header_data_len + 2) - return; - - if (strcmpP(buf, 0, esp_mail_str_10)) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_from; - tmp = subStr(buf, esp_mail_str_10, NULL, 0, -1); - setHeader(imap, tmp, header, headerState); - delS(tmp); - } - else if (strcmpP(buf, 0, esp_mail_str_11)) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_to; - tmp = subStr(buf, esp_mail_str_11, NULL, 0, -1); - setHeader(imap, tmp, header, headerState); - delS(tmp); - } - else if (strcmpP(buf, 0, esp_mail_str_276)) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_cc; - tmp = subStr(buf, esp_mail_str_276, NULL, 0, -1); - setHeader(imap, tmp, header, headerState); - delS(tmp); - } - else if (strcmpP(buf, 0, esp_mail_str_279)) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_subject; - tmp = subStr(buf, esp_mail_str_279, NULL, 0, -1); - setHeader(imap, tmp, header, headerState); - delS(tmp); - } - else if (strcmpP(buf, 0, esp_mail_str_25)) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_content_type; - tmp = subStr(buf, esp_mail_str_25, esp_mail_str_97, 0); - if (tmp) - { - setHeader(imap, buf, header, headerState); - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_172)) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_content_transfer_encoding; - tmp = subStr(buf, esp_mail_str_172, NULL, 0, -1); - if (tmp) - { - setHeader(imap, tmp, header, headerState); - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_190)) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_accept_language; - tmp = subStr(buf, esp_mail_str_190, NULL, 0, -1); - if (tmp) - { - setHeader(imap, tmp, header, headerState); - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_191)) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_content_language; - tmp = subStr(buf, esp_mail_str_191, NULL, 0, -1); - if (tmp) - { - setHeader(imap, tmp, header, headerState); - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_273)) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_date; - tmp = subStr(buf, esp_mail_str_273, NULL, 0, -1); - if (tmp) - { - setHeader(imap, tmp, header, headerState); - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_274)) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_msg_id; - tmp = subStr(buf, esp_mail_str_274, NULL, 0, -1); - if (tmp) - { - setHeader(imap, tmp, header, headerState); - delS(tmp); - } - } - chunkIdx++; - } -} - -void ESP_Mail_Client::setHeader(IMAPSession *imap, char *buf, struct esp_mail_message_header_t &header, int state) -{ - switch (state) - { - case esp_mail_imap_header_state::esp_mail_imap_state_from: - header.from += buf; - break; - case esp_mail_imap_header_state::esp_mail_imap_state_to: - header.to += buf; - break; - case esp_mail_imap_header_state::esp_mail_imap_state_cc: - header.cc += buf; - break; - case esp_mail_imap_header_state::esp_mail_imap_state_subject: - header.subject += buf; - break; - case esp_mail_imap_header_state::esp_mail_imap_state_content_type: - header.content_type += buf; - break; - case esp_mail_imap_header_state::esp_mail_imap_state_content_transfer_encoding: - header.content_transfer_encoding += buf; - break; - case esp_mail_imap_header_state::esp_mail_imap_state_accept_language: - header.accept_language += buf; - break; - case esp_mail_imap_header_state::esp_mail_imap_state_content_language: - header.content_language += buf; - break; - case esp_mail_imap_header_state::esp_mail_imap_state_date: - header.date += buf; - break; - case esp_mail_imap_header_state::esp_mail_imap_state_msg_id: - header.message_id += buf; - break; - case esp_mail_imap_header_state::esp_mail_imap_state_char_set: - header.char_set += buf; - break; - case esp_mail_imap_header_state::esp_mail_imap_state_boundary: - header.boundary += buf; - break; - default: - break; - } -} - -void ESP_Mail_Client::handlePartHeader(IMAPSession *imap, char *buf, int &chunkIdx, struct esp_mail_message_part_info_t &part) -{ - char *tmp = nullptr; - if (chunkIdx == 0) - { - tmp = subStr(buf, esp_mail_imap_response_7, NULL, 0, -1); - if (tmp) - { - delS(tmp); - tmp = subStr(buf, esp_mail_str_193, esp_mail_str_194, 0); - if (tmp) - { - chunkIdx++; - part.octetLen = atoi(tmp); - delS(tmp); - } - } - } - else - { - if (strcmpP(buf, 0, esp_mail_str_25)) - { - tmp = subStr(buf, esp_mail_str_25, esp_mail_str_97, 0); - bool con_type = false; - if (tmp) - { - con_type = true; - part.content_type = tmp; - delS(tmp); - int p1 = strposP(part.content_type.c_str(), esp_mail_imap_composite_media_type_t::multipart, 0); - if (p1 != -1) - { - p1 += strlen(esp_mail_imap_composite_media_type_t::multipart) + 1; - part.multipart = true; - //inline or embedded images - if (strpos(part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::related, p1) != -1) - part.multipart_sub_type = esp_mail_imap_multipart_sub_type_related; - //multiple text formats e.g. plain, html, enriched - else if (strpos(part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::alternative, p1) != -1) - part.multipart_sub_type = esp_mail_imap_multipart_sub_type_alternative; - //medias - else if (strpos(part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::parallel, p1) != -1) - part.multipart_sub_type = esp_mail_imap_multipart_sub_type_parallel; - //rfc822 encapsulated - else if (strpos(part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::digest, p1) != -1) - part.multipart_sub_type = esp_mail_imap_multipart_sub_type_digest; - else if (strpos(part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::report, p1) != -1) - part.multipart_sub_type = esp_mail_imap_multipart_sub_type_report; - //others can be attachments - else if (strpos(part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::mixed, p1) != -1) - part.multipart_sub_type = esp_mail_imap_multipart_sub_type_mixed; - } - - p1 = strposP(part.content_type.c_str(), esp_mail_imap_composite_media_type_t::message, 0); - if (p1 != -1) - { - p1 += strlen(esp_mail_imap_composite_media_type_t::message) + 1; - if (strpos(part.content_type.c_str(), esp_mail_imap_message_sub_type_t::rfc822, p1) != -1) - part.message_sub_type = esp_mail_imap_message_sub_type_rfc822; - else if (strpos(part.content_type.c_str(), esp_mail_imap_message_sub_type_t::Partial, p1) != -1) - part.message_sub_type = esp_mail_imap_message_sub_type_partial; - else if (strpos(part.content_type.c_str(), esp_mail_imap_message_sub_type_t::External_Body, p1) != -1) - part.message_sub_type = esp_mail_imap_message_sub_type_external_body; - else if (strpos(part.content_type.c_str(), esp_mail_imap_message_sub_type_t::delivery_status, p1) != -1) - part.message_sub_type = esp_mail_imap_message_sub_type_delivery_status; - } - - p1 = strpos(part.content_type.c_str(), esp_mail_imap_descrete_media_type_t::text, 0); - if (p1 != -1) - { - p1 += strlen(esp_mail_imap_descrete_media_type_t::text) + 1; - if (strpos(part.content_type.c_str(), esp_mail_imap_media_text_sub_type_t::plain, p1) != -1) - part.msg_type = esp_mail_msg_type_plain; - else if (strpos(part.content_type.c_str(), esp_mail_imap_media_text_sub_type_t::enriched, p1) != -1) - part.msg_type = esp_mail_msg_type_enriched; - else if (strpos(part.content_type.c_str(), esp_mail_imap_media_text_sub_type_t::html, p1) != -1) - part.msg_type = esp_mail_msg_type_html; - else - part.msg_type = esp_mail_msg_type_plain; - } - } - - if (con_type) - { - if (part.msg_type == esp_mail_msg_type_plain || part.msg_type == esp_mail_msg_type_enriched) - { - tmp = subStr(buf, esp_mail_str_168, esp_mail_str_136, 0); - if (tmp) - { - part.charset = tmp; - delS(tmp); - } - else - { - tmp = subStr(buf, esp_mail_str_169, NULL, 0, -1); - if (tmp) - { - part.charset = tmp; - delS(tmp); - } - } - - if (strposP(buf, esp_mail_str_275, 0) > -1 || strposP(buf, esp_mail_str_270, 0) > -1) - part.plain_flowed = true; - if (strposP(buf, esp_mail_str_259, 0) > -1 || strposP(buf, esp_mail_str_257, 0) > -1) - part.plain_delsp = true; - } - - if (part.charset.length() == 0) - { - tmp = subStr(buf, esp_mail_str_168, esp_mail_str_136, 0); - if (tmp) - { - part.charset = tmp; - delS(tmp); - } - else - { - tmp = subStr(buf, esp_mail_str_169, NULL, 0, -1); - if (tmp) - { - part.charset = tmp; - delS(tmp); - } - } - } - - tmp = subStr(buf, esp_mail_str_170, esp_mail_str_136, 0); - if (tmp) - { - part.name = tmp; - delS(tmp); - } - else - { - tmp = subStr(buf, esp_mail_str_171, NULL, 0, -1); - if (tmp) - { - part.name = tmp; - delS(tmp); - } - } - } - } - else if (strcmpP(buf, 0, esp_mail_str_172)) - { - tmp = subStr(buf, esp_mail_str_172, NULL, 0, -1); - if (tmp) - { - part.content_transfer_encoding = tmp; - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_174)) - { - tmp = subStr(buf, esp_mail_str_174, NULL, 0, -1); - if (tmp) - { - part.descr = tmp; - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_175)) - { - tmp = subStr(buf, esp_mail_str_175, esp_mail_str_97, 0); - if (tmp) - { - //don't count altenative part text and html as embedded contents - if (cHeader(imap)->multipart_sub_type != esp_mail_imap_multipart_sub_type_alternative) - { - part.content_disposition = tmp; - if (strcmp(tmp, esp_mail_imap_content_disposition_type_t::attachment) == 0) - part.attach_type = esp_mail_att_type_attachment; - else if (strcmp(tmp, esp_mail_imap_content_disposition_type_t::inline_) == 0) - part.attach_type = esp_mail_att_type_inline; - } - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_150)) - { - tmp = subStr(buf, esp_mail_str_150, NULL, 0, -1); - if (tmp) - { - part.rfc822_header.sender = tmp; - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_10)) - { - tmp = subStr(buf, esp_mail_str_10, NULL, 0, -1); - if (tmp) - { - part.rfc822_header.from = tmp; - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_11)) - { - tmp = subStr(buf, esp_mail_str_11, NULL, 0, -1); - if (tmp) - { - part.rfc822_header.to = tmp; - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_12)) - { - tmp = subStr(buf, esp_mail_str_12, NULL, 0, -1); - if (tmp) - { - part.rfc822_header.cc = tmp; - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_184)) - { - tmp = subStr(buf, esp_mail_str_184, NULL, 0, -1); - if (tmp) - { - part.rfc822_header.reply_to = tmp; - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_134)) - { - tmp = subStr(buf, esp_mail_str_134, NULL, 0, -1); - if (tmp) - { - part.rfc822_header.comment = tmp; - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_24)) - { - tmp = subStr(buf, esp_mail_str_24, NULL, 0, -1); - if (tmp) - { - part.rfc822_header.subject = tmp; - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_189)) - { - tmp = subStr(buf, esp_mail_str_189, NULL, 0, -1); - if (tmp) - { - part.rfc822_header.messageID = tmp; - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_46)) - { - tmp = subStr(buf, esp_mail_str_46, NULL, 0, -1); - if (tmp) - { - part.rfc822_header.return_path = tmp; - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_99)) - { - tmp = subStr(buf, esp_mail_str_99, NULL, 0, -1); - if (tmp) - { - part.rfc822_header.date = tmp; - delS(tmp); - } - } - else if (strcmpP(buf, 0, esp_mail_str_145)) - { - tmp = subStr(buf, esp_mail_str_145, NULL, 0, -1); - if (tmp) - { - part.rfc822_header.keyword = tmp; - delS(tmp); - } - } - - if (part.content_disposition.length() > 0) - { - tmp = subStr(buf, esp_mail_str_176, esp_mail_str_136, 0); - if (tmp) - { - part.filename = tmp; - delS(tmp); - } - else - { - tmp = subStr(buf, esp_mail_str_177, NULL, 0, -1); - if (tmp) - { - part.filename = tmp; - delS(tmp); - } - } - - tmp = subStr(buf, esp_mail_str_178, esp_mail_str_97, 0); - if (tmp) - { - part.attach_data_size = atoi(tmp); - delS(tmp); - cHeader(imap)->total_attach_data_size += part.attach_data_size; - part.sizeProp = true; - } - else - { - tmp = subStr(buf, esp_mail_str_178, NULL, 0, -1); - if (tmp) - { - part.attach_data_size = atoi(tmp); - delS(tmp); - cHeader(imap)->total_attach_data_size += part.attach_data_size; - part.sizeProp = true; - } - } - - tmp = subStr(buf, esp_mail_str_179, esp_mail_str_136, 0); - if (tmp) - { - part.creation_date = tmp; - delS(tmp); - } - else - { - tmp = subStr(buf, esp_mail_str_180, NULL, 0, -1); - if (tmp) - { - part.creation_date = tmp; - delS(tmp); - } - } - - tmp = subStr(buf, esp_mail_str_181, esp_mail_str_136, 0); - if (tmp) - { - part.modification_date = tmp; - delS(tmp); - } - else - { - tmp = subStr(buf, esp_mail_str_182, NULL, 0, -1); - if (tmp) - { - part.modification_date = tmp; - delS(tmp); - } - } - } - - chunkIdx++; - } -} - -char *ESP_Mail_Client::subStr(const char *buf, PGM_P beginH, PGM_P endH, int beginPos, int endPos) -{ - - char *tmp = nullptr; - int p1 = strposP(buf, beginH, beginPos); - if (p1 != -1) - { - int p2 = -1; - if (endPos == 0) - p2 = strposP(buf, endH, p1 + strlen_P(beginH)); - - if (p2 == -1) - p2 = strlen(buf); - - int len = p2 - p1 - strlen_P(beginH); - tmp = newS(len + 1); - memcpy(tmp, &buf[p1 + strlen_P(beginH)], len); - return tmp; - } - - return nullptr; -} - -void ESP_Mail_Client::handleAuth(SMTPSession *smtp, char *buf) -{ - if (strposP(buf, esp_mail_smtp_response_1, 0) > -1) - { - if (strposP(buf, esp_mail_smtp_response_2, 0) > -1) - smtp->_auth_capability.login = true; - if (strposP(buf, esp_mail_smtp_response_3, 0) > -1) - smtp->_auth_capability.plain = true; - if (strposP(buf, esp_mail_smtp_response_4, 0) > -1) - smtp->_auth_capability.xoauth2 = true; - if (strposP(buf, esp_mail_smtp_response_11, 0) > -1) - smtp->_auth_capability.cram_md5 = true; - if (strposP(buf, esp_mail_smtp_response_12, 0) > -1) - smtp->_auth_capability.digest_md5 = true; - } - else if (strposP(buf, esp_mail_smtp_response_5, 0) > -1) - smtp->_auth_capability.start_tls = true; - else if (strposP(buf, esp_mail_smtp_response_6, 0) > -1) - smtp->_send_capability._8bitMIME = true; - else if (strposP(buf, esp_mail_smtp_response_7, 0) > -1) - smtp->_send_capability.binaryMIME = true; - else if (strposP(buf, esp_mail_smtp_response_8, 0) > -1) - smtp->_send_capability.chunking = true; - else if (strposP(buf, esp_mail_smtp_response_9, 0) > -1) - smtp->_send_capability.utf8 = true; - else if (strposP(buf, esp_mail_smtp_response_10, 0) > -1) - smtp->_send_capability.pipelining = true; - else if (strposP(buf, esp_mail_smtp_response_13, 0) > -1) - smtp->_send_capability.dsn = true; -} - -int ESP_Mail_Client::available(SMTPSession *smtp) -{ - int sz = 0; - if (smtp->_sesson_cfg->secure.startTLS || !smtp->_secure) - { - if (smtp->httpClient._stream()) - sz = smtp->httpClient._stream()->_ns_available(); - } - else - { - if (smtp->httpClient.stream()) - sz = smtp->httpClient.stream()->available(); - } - - return sz; -} - -bool ESP_Mail_Client::handleSMTPResponse(SMTPSession *smtp, esp_mail_smtp_status_code respCode, int errCode) -{ - if (!reconnect(smtp)) - return false; - - bool ret = false; - char *response = nullptr; - int readLen = 0; - long dataTime = millis(); - int chunkBufSize = 0; - std::string s, r; - int chunkIndex = 0; - int count = 0; - bool completedResponse = false; - smtp->_smtpStatus.statusCode = 0; - smtp->_smtpStatus.respCode = 0; - smtp->_smtpStatus.text.clear(); - uint8_t minResLen = 5; - struct esp_mail_smtp_response_status_t status; - - chunkBufSize = available(smtp); - - while (smtp->_tcpConnected && chunkBufSize <= 0) - { - if (!reconnect(smtp, dataTime)) - return false; - if (!connected(smtp)) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_CONNECTION_LOST); - return false; - } - chunkBufSize = available(smtp); - delay(0); - } - - dataTime = millis(); - - if (chunkBufSize > 1) - { - while (!completedResponse) - { - delay(0); - - if (!reconnect(smtp, dataTime)) - return false; - - if (!connected(smtp)) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_CONNECTION_LOST); - return false; - } - - chunkBufSize = available(smtp); - - if (chunkBufSize <= 0) - break; - - if (chunkBufSize > 0) - { - chunkBufSize = 512; - response = newS(chunkBufSize + 1); - - if (smtp->_sesson_cfg->secure.startTLS || !smtp->_secure) - readLen = _readLine(smtp->httpClient._stream(), response, chunkBufSize, false, count); - else - readLen = readLine(smtp->httpClient.stream(), response, chunkBufSize, false, count); - - if (readLen) - { - if (smtp->_smtp_cmd != esp_mail_smtp_command::esp_mail_smtp_cmd_initial_state) - { - //sometimes server sent multiple lines response - //sometimes rx buffer may not ready for a while - if (strlen(response) < minResLen) - { - r += response; - chunkBufSize = 0; - while (chunkBufSize == 0) - { - delay(0); - if (!reconnect(smtp, dataTime)) - return false; - chunkBufSize = available(smtp); - } - } - else - { - if (r.length() > 0) - { - r += response; - memset(response, 0, chunkBufSize); - strcpy(response, r.c_str()); - } - - if (smtp->_debugLevel > esp_mail_debug_level_1) - esp_mail_debug((const char *)response); - } - - if (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_greeting) - handleAuth(smtp, response); - } - - getResponseStatus(response, respCode, 0, status); - - //get the status code again for unexpected return code - if (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_start_tls || status.respCode == 0) - getResponseStatus(response, esp_mail_smtp_status_code_0, 0, status); - - ret = respCode == status.respCode; - smtp->_smtpStatus = status; - - if (status.respCode > 0 && (status.respCode < 400 || status.respCode == respCode)) - ret = true; - - if (smtp->_debug && strlen(response) >= minResLen) - { - appendP(s, esp_mail_str_260, true); - if (smtp->_smtpStatus.respCode != esp_mail_smtp_status_code_334) - s += response; - else - { - //base64 response - size_t olen; - char *decoded = (char *)decodeBase64((const unsigned char *)status.text.c_str(), status.text.length(), &olen); - if (decoded && olen > 0) - { - olen += s.length(); - s += decoded; - s[olen] = 0; - delete[] decoded; - } - } - esp_mail_debug(s.c_str()); - r.clear(); - } - - completedResponse = smtp->_smtpStatus.respCode > 0 && status.text.length() > minResLen; - - if (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_auth && smtp->_smtpStatus.respCode == esp_mail_smtp_status_code_334) - { - if (authFailed(response, readLen, chunkIndex, 4)) - { - smtp->_smtpStatus.statusCode = -1; - ret = false; - } - } - - chunkIndex++; - - if (smtp->_chunkedEnable && smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_chunk_termination) - completedResponse = smtp->_chunkCount == chunkIndex; - } - delS(response); - } - } - - if (!ret) - handleSMTPError(smtp, errCode, false); - } - - return ret; -} - -void ESP_Mail_Client::getResponseStatus(const char *buf, esp_mail_smtp_status_code respCode, int beginPos, struct esp_mail_smtp_response_status_t &status) -{ - std::string s; - char *tmp = nullptr; - int p1 = 0; - if (respCode > esp_mail_smtp_status_code_0) - { - tmp = intStr((int)respCode); - s = tmp; - appendP(s, esp_mail_str_131, false); - delS(tmp); - p1 = strpos(buf, (const char *)s.c_str(), beginPos); - } - - if (p1 != -1) - { - int ofs = s.length() - 2; - if (ofs < 0) - ofs = 1; - - int p2 = strposP(buf, esp_mail_str_131, p1 + ofs); - - if (p2 < 4 && p2 > -1) - { - tmp = newS(p2 + 1); - memcpy(tmp, &buf[p1], p2); - status.respCode = atoi(tmp); - delS(tmp); - - p1 = p2 + 1; - p2 = strlen(buf); - if (p2 > p1) - { - tmp = newS(p2 + 1); - memcpy(tmp, &buf[p1], p2 - p1); - status.text = tmp; - delS(tmp); - } - } - } -} - -void ESP_Mail_Client::closeTCP(SMTPSession *smtp) -{ - - if (smtp->_tcpConnected) - { - if (smtp->httpClient.stream()) - { - if (connected(smtp)) - { - if (smtp->_sesson_cfg->secure.startTLS || !smtp->_secure) - smtp->httpClient._stream()->stop(); - else - smtp->httpClient.stream()->stop(); - } - } - _lastReconnectMillis = millis(); - } - smtp->_tcpConnected = false; -} - -void ESP_Mail_Client::closeTCP(IMAPSession *imap) -{ - - if (imap->_tcpConnected) - { - if (imap->httpClient.stream()) - { - if (connected(imap)) - { - if (!imap->_secure) - imap->httpClient._stream()->stop(); - else - imap->httpClient.stream()->stop(); - } - } - _lastReconnectMillis = millis(); - } - imap->_tcpConnected = false; -} - -#if defined(ESP32) -void ESP_Mail_Client::setSecure(ESP_Mail_HTTPClient32 &httpClient, ESP_Mail_Session *session, std::shared_ptr caCert) -#elif defined(ESP8266) -void ESP_Mail_Client::setSecure(ESP_Mail_HTTPClient &httpClient, ESP_Mail_Session *session, std::shared_ptr caCert) -#endif -{ - -#if defined(ESP32) - if (httpClient._certType == -1) - { - if (strlen(session->certificate.cert_file) == 0) - { - if (caCert != nullptr) - httpClient.setCACert(caCert.get()); - else - httpClient.setCACert(nullptr); - } - else - { - httpClient.setCertFile(session->certificate.cert_file, session->certificate.cert_file_storage_type); - } - } -#elif defined(ESP8266) - - if (httpClient._certType == -1) - { - -#ifndef USING_AXTLS - if (!MailClient._clockReady && (strlen(session->certificate.cert_file) > 0 || caCert != nullptr)) - { - MailClient.setClock(MailClient._gmtOffset); - httpClient._clockReady = MailClient._clockReady; - } -#endif - if (strlen(session->certificate.cert_file) == 0) - { - if (caCert != nullptr) - httpClient.setCACert(caCert.get()); - else - httpClient.setCACert(nullptr); - } - else - { - httpClient.setCertFile(session->certificate.cert_file, session->certificate.cert_file_storage_type, MailClient._sdPin); - } - } -#endif -} - -bool ESP_Mail_Client::ethLinkUp() -{ - bool ret = false; -#if defined(ESP32) - char *ip = strP(esp_mail_str_328); - if (strcmp(ETH.localIP().toString().c_str(), ip) != 0) -// ret = ETH.linkUp(); - ret = true; - delS(ip); -#endif - return ret; -} - -bool ESP_Mail_Client::reconnect(SMTPSession *smtp, unsigned long dataTime) -{ - - bool status = WiFi.status() == WL_CONNECTED || ethLinkUp(); - - if (dataTime > 0) - { - if (millis() - dataTime > smtp->httpClient.tcpTimeout) - { - closeTCP(smtp); - errorStatusCB(smtp, MAIL_CLIENT_ERROR_READ_TIMEOUT); - return false; - } - } - - if (!status) - { - if (smtp->_tcpConnected) - closeTCP(smtp); - - errorStatusCB(smtp, MAIL_CLIENT_ERROR_CONNECTION_LOST); - - if (millis() - _lastReconnectMillis > _reconnectTimeout && !smtp->_tcpConnected) - { -#if defined(ESP32) - esp_wifi_connect(); -#elif defined(ESP8266) - WiFi.reconnect(); -#endif - _lastReconnectMillis = millis(); - } - - status = WiFi.status() == WL_CONNECTED || ethLinkUp(); - } - - return status; -} - -bool ESP_Mail_Client::reconnect(IMAPSession *imap, unsigned long dataTime, bool downloadRequest) -{ - - bool status = WiFi.status() == WL_CONNECTED || ethLinkUp(); - - if (dataTime > 0) - { - if (millis() - dataTime > imap->httpClient.tcpTimeout) - { - - closeTCP(imap); - - if (imap->_headers.size() > 0) - { - if (downloadRequest) - { - errorStatusCB(imap, IMAP_STATUS_ERROR_DOWNLAD_TIMEOUT); - if (cHeader(imap)->part_headers.size() > 0) - cPart(imap)->download_error = imap->errorReason().c_str(); - } - else - { - errorStatusCB(imap, MAIL_CLIENT_ERROR_READ_TIMEOUT); - cHeader(imap)->error_msg = imap->errorReason().c_str(); - } - } - return false; - } - } - - if (!status) - { - - if (imap->_tcpConnected) - closeTCP(imap); - - errorStatusCB(imap, MAIL_CLIENT_ERROR_CONNECTION_LOST); - - if (imap->_headers.size() > 0) - { - if (downloadRequest) - cPart(imap)->download_error = imap->errorReason().c_str(); - else - cHeader(imap)->error_msg = imap->errorReason().c_str(); - } - - if (millis() - _lastReconnectMillis > _reconnectTimeout && !imap->_tcpConnected) - { -#if defined(ESP32) - esp_wifi_connect(); -#elif defined(ESP8266) - WiFi.reconnect(); -#endif - _lastReconnectMillis = millis(); - } - - status = WiFi.status() == WL_CONNECTED || ethLinkUp(); - } - - return status; -} - -void ESP_Mail_Client::delS(char *p) -{ - if (p != nullptr) - delete[] p; -} - -char *ESP_Mail_Client::newS(size_t len) -{ - char *p = new char[len]; - memset(p, 0, len); - return p; -} - -char *ESP_Mail_Client::newS(char *p, size_t len) -{ - delS(p); - p = newS(len); - return p; -} - -char *ESP_Mail_Client::newS(char *p, size_t len, char *d) -{ - delS(p); - p = newS(len); - strcpy(p, d); - return p; -} - -bool ESP_Mail_Client::strcmpP(const char *buf, int ofs, PGM_P beginH) -{ - char *tmp = nullptr; - if (ofs < 0) - { - int p = strposP(buf, beginH, 0); - if (p == -1) - return false; - ofs = p; - } - tmp = strP(beginH); - char *tmp2 = newS(strlen_P(beginH) + 1); - memcpy(tmp2, &buf[ofs], strlen_P(beginH)); - tmp2[strlen_P(beginH)] = 0; - bool ret = (strcasecmp(tmp, tmp2) == 0); - delS(tmp); - delS(tmp2); - return ret; -} - -int ESP_Mail_Client::strposP(const char *buf, PGM_P beginH, int ofs) -{ - char *tmp = strP(beginH); - int p = strpos(buf, tmp, ofs); - delS(tmp); - return p; -} - -char *ESP_Mail_Client::strP(PGM_P pgm) -{ - size_t len = strlen_P(pgm) + 1; - char *buf = newS(len); - strcpy_P(buf, pgm); - buf[len - 1] = 0; - return buf; -} - -void ESP_Mail_Client::appendP(std::string &buf, PGM_P p, bool empty) -{ - if (empty) - buf.clear(); - char *b = strP(p); - buf += b; - delS(b); -} - -char *ESP_Mail_Client::intStr(int value) -{ - char *buf = newS(36); - memset(buf, 0, 36); - itoa(value, buf, 10); - return buf; -} - -int ESP_Mail_Client::available(IMAPSession *imap) -{ - int sz = 0; - if (!imap->_secure) - { - if (imap->httpClient._stream()) - sz = imap->httpClient._stream()->_ns_available(); - } - else - { - if (imap->httpClient.stream()) - sz = imap->httpClient.stream()->available(); - } - return sz; -} - -bool ESP_Mail_Client::handleIMAPResponse(IMAPSession *imap, int errCode, bool closeSession) -{ - - if (!reconnect(imap)) - return false; - - esp_mail_imap_response_status imapResp = esp_mail_imap_response_status::esp_mail_imap_resp_unknown; - char *response = nullptr; - int readLen = 0; - long dataTime = millis(); - int chunkBufSize = available(imap); - int chunkIdx = 0; - std::string s; - bool completedResponse = false; - bool endSearch = false; - struct esp_mail_message_header_t header; - struct esp_mail_message_part_info_t part; - - std::string filePath = ""; - bool downloadRequest = false; - int reportState = 0; - int octetCount = 0; - int octetLength = 0; - int oCount = 0; - bool tmo = false; - int headerState = 0; - int scnt = 0; - int dcnt = -1; - char *skey = nullptr; - char *spc = nullptr; - char *lastBuf = nullptr; - char *tmp = nullptr; - bool crLF = imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text && strcmpP(cPart(imap)->content_transfer_encoding.c_str(), 0, esp_mail_str_31); - - while (imap->_tcpConnected && chunkBufSize <= 0) - { - if (!reconnect(imap, dataTime)) - return false; - if (!connected(imap)) - { - errorStatusCB(imap, MAIL_CLIENT_ERROR_CONNECTION_LOST); - return false; - } - chunkBufSize = available(imap); - delay(0); - } - - dataTime = millis(); - - if (chunkBufSize > 1) - { - if (imap->_imap_cmd == esp_mail_imap_cmd_examine) - { - imap->_mbif.clear(); - imap->_mbif._msgCount = 0; - imap->_nextUID = ""; - } - - if (imap->_imap_cmd == esp_mail_imap_cmd_search) - { - imap->_mbif._searchCount = 0; - imap->_msgNum.clear(); - } - - chunkBufSize = 512; - response = newS(chunkBufSize + 1); - - if (imap->_imap_cmd == esp_mail_imap_command::esp_mail_imap_cmd_search) - { - skey = strP(esp_mail_imap_response_6); - spc = strP(esp_mail_str_92); - } - - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) - lastBuf = newS(BASE64_CHUNKED_LEN + 1); - - while (!completedResponse) - { - delay(0); - if (!reconnect(imap, dataTime) || !connected(imap)) - { - if (imap->_imap_cmd == esp_mail_imap_command::esp_mail_imap_cmd_search) - { - delS(skey); - delS(spc); - } - - if (!connected(imap)) - { - errorStatusCB(imap, MAIL_CLIENT_ERROR_CONNECTION_LOST); - return false; - } - return false; - } - chunkBufSize = available(imap); - - if (chunkBufSize > 0) - { - chunkBufSize = 512; - - if (imap->_imap_cmd == esp_mail_imap_command::esp_mail_imap_cmd_search) - { - readLen = getMSGNUM(imap, response, chunkBufSize, chunkIdx, endSearch, scnt, skey, spc); - imap->_mbif._availableItems = imap->_msgNum.size(); - } - else - { - if (!imap->_secure) - readLen = _readLine(imap->httpClient._stream(), response, chunkBufSize, crLF, octetCount); - else - readLen = readLine(imap->httpClient.stream(), response, chunkBufSize, crLF, octetCount); - } - - if (readLen) - { - - if (imap->_debugLevel > esp_mail_debug_level_1) - { - if (imap->_imap_cmd != esp_mail_imap_cmd_search && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_text && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_attachment && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_inline) - esp_mail_debug((const char *)response); - } - - if (imap->_imap_cmd != esp_mail_imap_cmd_search || (imap->_imap_cmd == esp_mail_imap_cmd_search && endSearch)) - imapResp = imapResponseStatus(imap, response); - - if (imapResp != esp_mail_imap_response_status::esp_mail_imap_resp_unknown) - { - if (imap->_debugLevel > esp_mail_debug_level_1) - { - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) - esp_mail_debug((const char *)response); - } - - if (imap->_imap_cmd == esp_mail_imap_cmd_close) - completedResponse = true; - else - { - //some IMAP servers advertise CAPABILITY in their responses - //try to read the next available response - memset(response, 0, chunkBufSize); - if (!imap->_secure) - readLen = _readLine(imap->httpClient._stream(), response, chunkBufSize, true, octetCount); - else - readLen = readLine(imap->httpClient.stream(), response, chunkBufSize, true, octetCount); - if (readLen) - { - completedResponse = false; - imapResp = imapResponseStatus(imap, response); - if (imapResp > esp_mail_imap_response_status::esp_mail_imap_resp_unknown) - completedResponse = true; - } - else - completedResponse = true; - } - } - else - { - if (imap->_imap_cmd == esp_mail_imap_cmd_auth) - { - if (authFailed(response, readLen, chunkIdx, 2)) - completedResponse = true; - } - else if (imap->_imap_cmd == esp_mail_imap_cmd_capability) - handleCapability(imap, response, chunkIdx); - else if (imap->_imap_cmd == esp_mail_imap_cmd_list) - handleFolders(imap, response); - else if (imap->_imap_cmd == esp_mail_imap_cmd_select || imap->_imap_cmd == esp_mail_imap_cmd_examine) - handleExamine(imap, response); - else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_header) - { - char *tmp = intStr(cMSG(imap)); - header.message_uid = tmp; - delS(tmp); - - tmp = intStr(imap->_totalRead); - header.message_no = tmp; - delS(tmp); - - int _st = headerState; - handleHeader(imap, response, readLen, chunkIdx, header, headerState, octetCount); - if (_st == headerState && headerState > 0 && octetCount <= header.header_data_len) - setHeader(imap, response, header, headerState); - } - else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_mime) - handlePartHeader(imap, response, chunkIdx, part); - else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text) - decodeText(imap, response, readLen, chunkIdx, file, filePath, downloadRequest, octetLength, octetCount, dcnt); - else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) - { - - if (strcmpP(cPart(imap)->content_transfer_encoding.c_str(), 0, esp_mail_str_31)) - { - //multi-line chunked base64 string attachment handle - if (octetCount < octetLength && readLen < BASE64_CHUNKED_LEN) - { - if (strlen(lastBuf) > 0) - { - tmp = newS(readLen + strlen(lastBuf) + 2); - strcpy(tmp, lastBuf); - strcat(tmp, response); - readLen = strlen(tmp); - tmo = handleAttachment(imap, tmp, readLen, chunkIdx, file, filePath, downloadRequest, octetCount, octetLength, oCount, reportState, dcnt); - delS(tmp); - memset(lastBuf, 0, BASE64_CHUNKED_LEN + 1); - if (!tmo) - break; - } - else if (readLen < BASE64_CHUNKED_LEN + 1) - strcpy(lastBuf, response); - } - else - { - tmo = handleAttachment(imap, response, readLen, chunkIdx, file, filePath, downloadRequest, octetCount, octetLength, oCount, reportState, dcnt); - if (!tmo) - break; - } - } - else - tmo = handleAttachment(imap, response, readLen, chunkIdx, file, filePath, downloadRequest, octetCount, octetLength, oCount, reportState, dcnt); - } - dataTime = millis(); - } - } - memset(response, 0, chunkBufSize); - } - } - delS(response); - if (imap->_imap_cmd == esp_mail_imap_command::esp_mail_imap_cmd_search) - { - if (imap->_debug && scnt > 0 && scnt < 100) - searchReport(100, spc); - delS(skey); - delS(spc); - } - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment) - delS(lastBuf); - } - - if ((imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_header && header.header_data_len == 0) || imapResp == esp_mail_imap_response_status::esp_mail_imap_resp_no) - { - if (imapResp == esp_mail_imap_response_status::esp_mail_imap_resp_no) - imap->_imapStatus.statusCode = IMAP_STATUS_IMAP_RESPONSE_FAILED; - else - imap->_imapStatus.statusCode = IMAP_STATUS_NO_MESSAGE; - - if (imap->_readCallback) - { - std::string s; - appendP(s, esp_mail_str_53, true); - s += imap->errorReason().c_str(); - imapCB(imap, s.c_str(), false); - } - - if (imap->_debug) - { - std::string s; - appendP(s, esp_mail_str_185, true); - s += imap->errorReason().c_str(); - esp_mail_debug_line(s.c_str(), true); - } - - return false; - } - - if (imapResp == esp_mail_imap_response_status::esp_mail_imap_resp_ok) - { - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_header) - { - char *buf = newS(header.content_type.length() + 1); - strcpy(buf, header.content_type.c_str()); - header.content_type.clear(); - - tmp = subStr(buf, esp_mail_str_25, esp_mail_str_97, 0); - if (tmp) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_content_type; - setHeader(imap, tmp, header, headerState); - delS(tmp); - - int p1 = strposP(header.content_type.c_str(), esp_mail_imap_composite_media_type_t::multipart, 0); - if (p1 != -1) - { - p1 += strlen(esp_mail_imap_composite_media_type_t::multipart) + 1; - header.multipart = true; - //inline or embedded images - if (strpos(part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::related, p1) != -1) - header.multipart_sub_type = esp_mail_imap_multipart_sub_type_related; - //multiple text formats e.g. plain, html, enriched - else if (strpos(part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::alternative, p1) != -1) - header.multipart_sub_type = esp_mail_imap_multipart_sub_type_alternative; - //medias - else if (strpos(part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::parallel, p1) != -1) - header.multipart_sub_type = esp_mail_imap_multipart_sub_type_parallel; - //rfc822 encapsulated - else if (strpos(part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::digest, p1) != -1) - header.multipart_sub_type = esp_mail_imap_multipart_sub_type_digest; - else if (strpos(part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::report, p1) != -1) - header.multipart_sub_type = esp_mail_imap_multipart_sub_type_report; - //others can be attachments - else if (strpos(part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::mixed, p1) != -1) - header.multipart_sub_type = esp_mail_imap_multipart_sub_type_mixed; - } - - p1 = strposP(header.content_type.c_str(), esp_mail_imap_composite_media_type_t::message, 0); - if (p1 != -1) - { - p1 += strlen(esp_mail_imap_composite_media_type_t::message) + 1; - if (strpos(part.content_type.c_str(), esp_mail_imap_message_sub_type_t::rfc822, p1) != -1) - { - header.rfc822_part = true; - header.message_sub_type = esp_mail_imap_message_sub_type_rfc822; - } - else if (strpos(part.content_type.c_str(), esp_mail_imap_message_sub_type_t::Partial, p1) != -1) - header.message_sub_type = esp_mail_imap_message_sub_type_partial; - else if (strpos(part.content_type.c_str(), esp_mail_imap_message_sub_type_t::External_Body, p1) != -1) - header.message_sub_type = esp_mail_imap_message_sub_type_external_body; - else if (strpos(part.content_type.c_str(), esp_mail_imap_message_sub_type_t::delivery_status, p1) != -1) - header.message_sub_type = esp_mail_imap_message_sub_type_delivery_status; - } - - tmp = subStr(buf, esp_mail_str_169, NULL, 0, -1); - if (tmp) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_char_set; - setHeader(imap, tmp, header, headerState); - delS(tmp); - } - - if (header.multipart) - { - if (strcmpP(buf, 0, esp_mail_str_277)) - { - tmp = subStr(buf, esp_mail_str_277, esp_mail_str_136, 0); - if (tmp) - { - headerState = esp_mail_imap_header_state::esp_mail_imap_state_boundary; - setHeader(imap, tmp, header, headerState); - delS(tmp); - } - } - } - } - - delS(buf); - - decodeHeader(header.from, header.from_charset); - decodeHeader(header.to, header.to_charset); - decodeHeader(header.cc, header.cc_charset); - decodeHeader(header.subject, header.subject_charset); - - imap->_headers.push_back(header); - } - - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_mime) - { - //expect the octet length in the response for the existent part - if (part.octetLen > 0) - { - - part.partNumStr = cHeader(imap)->partNumStr; - part.partNumFetchStr = cHeader(imap)->partNumStr; - if (cHeader(imap)->part_headers.size() > 0) - { - - struct esp_mail_message_part_info_t *_part = &cHeader(imap)->part_headers[cHeader(imap)->part_headers.size() - 1]; - bool rfc822_body_subtype = _part->message_sub_type == esp_mail_imap_message_sub_type_rfc822; - - if (rfc822_body_subtype) - { - if (!_part->rfc822_part) - { - //additional rfc822 message header, store it to the rfc822 part header - _part->rfc822_part = true; - _part->rfc822_header = part.rfc822_header; - imap->_rfc822_part_count++; - _part->rfc822_msg_Idx = imap->_rfc822_part_count; - } - } - } - - cHeader(imap)->part_headers.push_back(part); - cHeader(imap)->message_data_count = cHeader(imap)->part_headers.size(); - - if (part.msg_type == esp_mail_msg_type_plain || part.msg_type == esp_mail_msg_type_enriched || part.msg_type == esp_mail_msg_type_html || part.attach_type == esp_mail_att_type_none || (part.attach_type == esp_mail_att_type_attachment && imap->_config->download.attachment) || (part.attach_type == esp_mail_att_type_inline && imap->_config->download.inlineImg)) - { - if (part.message_sub_type != esp_mail_imap_message_sub_type_rfc822) - { - if (part.attach_type != esp_mail_att_type_none && cHeader(imap)->multipart_sub_type != esp_mail_imap_multipart_sub_type_alternative) - cHeader(imap)->attachment_count++; - } - } - } - else - { - //nonexistent part - //return false to exit the loop without closing the connection - if (closeSession) - imap->closeSession(); - return false; - } - } - - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) - { - if (cPart(imap)->file_open_write) - file.close(); - } - - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text) - cPart(imap)->text[cPart(imap)->textLen] = 0; - } - else - { - //some server responses NO and should exit (false) from MIME feching loop without - //closing the session - if (imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_mime) - return handleIMAPError(imap, errCode, false); - - if (closeSession) - imap->closeSession(); - return false; - } - - return true; -} - -void ESP_Mail_Client::saveHeader(IMAPSession *imap) -{ - - std::string headerFilePath; - prepareFilePath(imap, headerFilePath, true); - if (imap->_storageType == esp_mail_file_storage_type_sd && !_sdOk) - _sdOk = sdTest(); - else if (imap->_storageType == esp_mail_file_storage_type_flash && !_flashOk) -#if defined(ESP32) - _flashOk = ESP_MAIL_FLASH_FS.begin(FORMAT_FLASH); -#elif defined(ESP8266) - _flashOk = ESP_MAIL_FLASH_FS.begin(); -#endif - - if (_sdOk || _flashOk) - { - if (file) - file.close(); - - if (imap->_storageType == esp_mail_file_storage_type_sd) { - file = ESP_MAIL_SD_FS.open(headerFilePath.c_str(), FILE_WRITE); - } else if (imap->_storageType == esp_mail_file_storage_type_flash) { -#if defined(ESP32) - file = ESP_MAIL_FLASH_FS.open(headerFilePath.c_str(), FILE_WRITE); -#elif defined(ESP8266) - file = ESP_MAIL_FLASH_FS.open(headerFilePath.c_str(), "w"); -#endif - } else if (imap->_storageType == esp_mail_file_storage_type_univ) { - file = ufsp->open(headerFilePath.c_str(), "w"); - } - - if (file) - { - std::string s; - appendP(s, esp_mail_str_99, true); - file.print(s.c_str()); - file.println(cHeader(imap)->date.c_str()); - - appendP(s, esp_mail_str_100, true); - file.print(s.c_str()); - if (imap->_uidSearch) - file.println(cMSG(imap)); - else - file.println(); - - appendP(s, esp_mail_str_101, true); - file.print(s.c_str()); - file.println(cMSG(imap)); - - appendP(s, esp_mail_str_102, true); - file.print(s.c_str()); - file.println(cHeader(imap)->accept_language.c_str()); - - appendP(s, esp_mail_str_103, true); - file.print(s.c_str()); - file.println(cHeader(imap)->content_language.c_str()); - - appendP(s, esp_mail_str_10, true); - file.print(s.c_str()); - file.println(cHeader(imap)->from.c_str()); - - appendP(s, esp_mail_str_105, true); - file.print(s.c_str()); - file.println(cHeader(imap)->from_charset.c_str()); - - appendP(s, esp_mail_str_11, true); - file.print(s.c_str()); - file.println(cHeader(imap)->to.c_str()); - - appendP(s, esp_mail_str_107, true); - file.print(s.c_str()); - file.println(cHeader(imap)->to_charset.c_str()); - - appendP(s, esp_mail_str_108, true); - file.print(s.c_str()); - file.println(cHeader(imap)->cc.c_str()); - - appendP(s, esp_mail_str_109, true); - file.print(s.c_str()); - file.println(cHeader(imap)->cc_charset.c_str()); - - appendP(s, esp_mail_str_24, true); - file.print(s.c_str()); - file.println(cHeader(imap)->subject.c_str()); - - appendP(s, esp_mail_str_111, true); - file.print(s.c_str()); - file.println(cHeader(imap)->subject_charset.c_str()); - - appendP(s, esp_mail_str_112, true); - file.print(s.c_str()); - file.println(cPart(imap)->charset.c_str()); - - if (cHeader(imap)->attachment_count > 0) - { - - appendP(s, esp_mail_str_113, true); - file.print(s.c_str()); - file.println(cHeader(imap)->attachment_count); - - for (int j = 0; j < cHeader(imap)->attachment_count; j++) - { - if (imap->_headers[cIdx(imap)].part_headers[j].attach_type == esp_mail_att_type_none || imap->_headers[cIdx(imap)].part_headers[j].rfc822_part) - continue; - struct esp_mail_attacment_info_t att; - att.filename = imap->_headers[cIdx(imap)].part_headers[j].filename.c_str(); - att.mime = imap->_headers[cIdx(imap)].part_headers[j].content_type.c_str(); - att.name = imap->_headers[cIdx(imap)].part_headers[j].name.c_str(); - att.size = imap->_headers[cIdx(imap)].part_headers[j].attach_data_size; - att.creationDate = imap->_headers[cIdx(imap)].part_headers[j].creation_date.c_str(); - att.type = imap->_headers[cIdx(imap)].part_headers[j].attach_type; - - appendP(s, esp_mail_str_114, true); - file.print(s.c_str()); - file.println(j + 1); - - appendP(s, esp_mail_str_115, true); - file.print(s.c_str()); - file.println(att.filename); - - appendP(s, esp_mail_str_116, true); - file.print(s.c_str()); - file.println(att.name); - - appendP(s, esp_mail_str_117, true); - file.print(s.c_str()); - file.println(att.size); - - appendP(s, esp_mail_str_118, true); - file.print(s.c_str()); - file.println(att.mime); - - appendP(s, esp_mail_str_119, true); - file.print(s.c_str()); - file.println(att.creationDate); - } - } - - file.close(); - } - imap->_headerSaved = true; - } -} - -esp_mail_imap_response_status ESP_Mail_Client::imapResponseStatus(IMAPSession *imap, char *response) -{ - imap->_imapStatus.text.clear(); - if (strposP(response, esp_mail_imap_response_1, 0) > -1) - return esp_mail_imap_response_status::esp_mail_imap_resp_ok; - else if (strposP(response, esp_mail_imap_response_2, 0) > -1) - { - imap->_imapStatus.text = response; - imap->_imapStatus.text = imap->_imapStatus.text.substr(strlen_P(esp_mail_imap_response_2)); - return esp_mail_imap_response_status::esp_mail_imap_resp_no; - } - else if (strposP(response, esp_mail_imap_response_3, 0) > -1) - { - imap->_imapStatus.text = response; - imap->_imapStatus.text = imap->_imapStatus.text.substr(strlen_P(esp_mail_imap_response_3)); - return esp_mail_imap_response_status::esp_mail_imap_resp_bad; - } - return esp_mail_imap_response_status::esp_mail_imap_resp_unknown; -} - -void ESP_Mail_Client::decodeHeader(std::string &headerField, std::string &headerEnc) -{ - - size_t p1 = 0, p2 = 0; - - while (headerField[p1] == ' ' && p1 < headerField.length() - 1) - p1++; - - if (headerField[p1] == '=' && headerField[p1 + 1] == '?') - { - p2 = headerField.find("?", p1 + 2); - if (p2 != std::string::npos) - headerEnc = headerField.substr(p1 + 2, p2 - p1 - 2); - } - - int bufSize = 512; - char *buf = newS(bufSize); - - RFC2047Decoder.rfc2047Decode(buf, headerField.c_str(), bufSize); - - if (getEncodingFromCharset(headerEnc.c_str()) == esp_mail_char_decoding_scheme_iso8859_1) - { - int len = strlen(buf); - int olen = (len + 1) * 2; - unsigned char *out = (unsigned char *)newS(olen); - decodeLatin1_UTF8(out, &olen, (unsigned char *)buf, &len); - delS(buf); - buf = (char *)out; - } - else if (getEncodingFromCharset(headerEnc.c_str()) == esp_mail_char_decoding_scheme_tis620) - { - size_t len2 = strlen(buf); - char *tmp = newS((len2 + 1) * 3); - decodeTIS620_UTF8(tmp, buf, len2); - delS(buf); - buf = tmp; - } - - headerField = buf; - delS(buf); -} - -esp_mail_char_decoding_scheme ESP_Mail_Client::getEncodingFromCharset(const char *enc) -{ - esp_mail_char_decoding_scheme scheme = esp_mail_char_decoding_scheme_default; - - if (strposP(enc, esp_mail_str_237, 0) > -1 || strposP(enc, esp_mail_str_231, 0) > -1 || strposP(enc, esp_mail_str_226, 0) > -1) - scheme = esp_mail_char_decoding_scheme_tis620; - else if (strposP(enc, esp_mail_str_227, 0) > -1) - scheme = esp_mail_char_decoding_scheme_iso8859_1; - - return scheme; -} - -bool ESP_Mail_Client::handleAttachment(IMAPSession *imap, char *buf, int bufLen, int &chunkIdx, File &file, std::string &filePath, bool &downloadRequest, int &octetCount, int &octetLength, int &oCount, int &reportState, int &downloadCount) -{ - if (chunkIdx == 0) - { - char *tmp = subStr(buf, esp_mail_str_193, esp_mail_str_194, 0); - if (tmp) - { - octetCount = 2; //CRLF counted from first line - octetLength = atoi(tmp); - delS(tmp); - chunkIdx++; - cHeader(imap)->total_download_size += octetLength; - } - return true; - } - - if (octetLength == 0) - return true; - - chunkIdx++; - - delay(0); - - if (!cPart(imap)->file_open_write) - { - - cPart(imap)->file_open_write = true; - - if (imap->_storageType == esp_mail_file_storage_type_sd && !_sdOk) - _sdOk = sdTest(); - else if (imap->_storageType == esp_mail_file_storage_type_flash && !_flashOk) -#if defined(ESP32) - _flashOk = ESP_MAIL_FLASH_FS.begin(FORMAT_FLASH); -#elif defined(ESP8266) - _flashOk = ESP_MAIL_FLASH_FS.begin(); -#endif - - if (_sdOk || _flashOk) - { - - downloadRequest = true; - - filePath.clear(); - filePath += imap->_config->storage.saved_path; - appendP(filePath, esp_mail_str_202, false); - - char *tmp = intStr(cMSG(imap)); - filePath += tmp; - delS(tmp); - - if (imap->_storageType == esp_mail_file_storage_type_sd) - if (!ESP_MAIL_SD_FS.exists(filePath.c_str())) - createDirs(filePath); - - appendP(filePath, esp_mail_str_202, false); - - filePath += cPart(imap)->filename; - - if (imap->_storageType == esp_mail_file_storage_type_sd) - file = ESP_MAIL_SD_FS.open(filePath.c_str(), FILE_WRITE); - else if (imap->_storageType == esp_mail_file_storage_type_flash) -#if defined(ESP32) - file = ESP_MAIL_FLASH_FS.open(filePath.c_str(), FILE_WRITE); -#elif defined(ESP8266) - file = ESP_MAIL_FLASH_FS.open(filePath.c_str(), "w"); -#endif - } - } - - if (_sdOk || _flashOk) - { - int nOctet = oCount + bufLen + 2; - if (nOctet > octetLength) - { - if (imap->_readCallback) - downloadReport(imap, 100); - - if (oCount < octetLength) - { - int dLen = nOctet - 2 - octetLength; - bufLen -= dLen; - buf[bufLen] = 0; - } - else - return true; - } - - oCount += bufLen + 2; - - if (strcmpP(cPart(imap)->content_transfer_encoding.c_str(), 0, esp_mail_str_31)) - { - - size_t olen = 0; - unsigned char *decoded = decodeBase64((const unsigned char *)buf, bufLen, &olen); - - if (decoded) - { - - if (!cPart(imap)->sizeProp) - { - cPart(imap)->attach_data_size += olen; - cHeader(imap)->total_attach_data_size += cPart(imap)->attach_data_size; - } - - file.write((const uint8_t *)decoded, olen); - delay(0); - delete[] decoded; - - if (imap->_config->enable.download_status) - { - int p = 0; - if (cHeader(imap)->total_download_size > 0) - p = 100 * octetCount / cHeader(imap)->total_download_size; - - if ((p != downloadCount) && (p <= 100)) - { - downloadCount = p; - if (imap->_readCallback && reportState != -1) - downloadReport(imap, p); - reportState = -1; - } - else - reportState = 0; - } - } - - if (!reconnect(imap)) - return false; - } - else - { - //binary content - if (!cPart(imap)->sizeProp) - { - cPart(imap)->attach_data_size += bufLen; - cHeader(imap)->total_attach_data_size += cPart(imap)->attach_data_size; - } - - file.write((const uint8_t *)buf, bufLen); - delay(0); - - if (imap->_config->enable.download_status) - { - int p = 0; - if (cHeader(imap)->total_download_size > 0) - p = 100 * octetCount / cHeader(imap)->total_download_size; - - if ((p != downloadCount) && (p <= 100)) - { - downloadCount = p; - if (imap->_readCallback && reportState != -1) - downloadReport(imap, p); - reportState = -1; - } - else - reportState = 0; - } - - if (!reconnect(imap)) - return false; - } - } - return true; -} - -void ESP_Mail_Client::downloadReport(IMAPSession *imap, int progress) -{ - if (imap->_readCallback && progress % ESP_MAIL_PROGRESS_REPORT_STEP == 0) - { - std::string s; - char *tmp = intStr(progress); - appendP(s, esp_mail_str_90, true); - appendP(s, esp_mail_str_131, false); - s += cPart(imap)->filename; - appendP(s, esp_mail_str_91, false); - s += tmp; - delS(tmp); - appendP(s, esp_mail_str_92, false); - appendP(s, esp_mail_str_34, false); - esp_mail_debug_line(s.c_str(), false); - std::string().swap(s); - } -} - -void ESP_Mail_Client::fetchReport(IMAPSession *imap, int progress, bool download) -{ - if (imap->_readCallback && progress % ESP_MAIL_PROGRESS_REPORT_STEP == 0) - { - std::string s; - char *tmp = intStr(progress); - if (download) - appendP(s, esp_mail_str_90, true); - else - appendP(s, esp_mail_str_83, true); - appendP(s, esp_mail_str_131, false); - if (cPart(imap)->filename.length() > 0) - { - s += cPart(imap)->filename; - appendP(s, esp_mail_str_91, false); - } - s += tmp; - delS(tmp); - appendP(s, esp_mail_str_92, false); - appendP(s, esp_mail_str_34, false); - esp_mail_debug_line(s.c_str(), false); - std::string().swap(s); - } -} - -void ESP_Mail_Client::searchReport(int progress, const char *percent) -{ - if (progress % ESP_MAIL_PROGRESS_REPORT_STEP == 0) - { - char *tmp = intStr(progress); - std::string s; - appendP(s, esp_mail_str_261, true); - s += tmp; - s += percent; - appendP(s, esp_mail_str_34, false); - esp_mail_debug_line(s.c_str(), false); - delS(tmp); - } -} - -void ESP_Mail_Client::uploadReport(const char *filename, int progress) -{ - if (progress % ESP_MAIL_PROGRESS_REPORT_STEP == 0) - { - std::string s; - char *tmp = intStr(progress); - appendP(s, esp_mail_str_160, true); - s += filename; - appendP(s, esp_mail_str_91, false); - s += tmp; - delS(tmp); - appendP(s, esp_mail_str_92, false); - appendP(s, esp_mail_str_34, false); - esp_mail_debug_line(s.c_str(), false); - std::string().swap(s); - } -} - -int ESP_Mail_Client::cMSG(IMAPSession *imap) -{ - return imap->_msgNum[cIdx(imap)]; -} - -int ESP_Mail_Client::cIdx(IMAPSession *imap) -{ - return imap->_cMsgIdx; -} - -void ESP_Mail_Client::decodeTIS620_UTF8(char *out, const char *in, size_t len) -{ - //output is the 3-byte value UTF-8 - int j = 0; - for (size_t i = 0; i < len; i++) - { - if (in[i] < 0x80) - out[j++] = in[i]; - else if ((in[i] >= 0xa0 && in[i] < 0xdb) || (in[i] > 0xde && in[i] < 0xfc)) - { - int unicode = 0x0e00 + in[i] - 0xa0; - out[j++] = 0xe0 | ((unicode >> 12) & 0xf); - out[j++] = 0x80 | ((unicode >> 6) & 0x3f); - out[j++] = 0x80 | (unicode & 0x3f); - } - } -} - -int ESP_Mail_Client::decodeLatin1_UTF8(unsigned char *out, int *outlen, const unsigned char *in, int *inlen) -{ - unsigned char *outstart = out; - const unsigned char *base = in; - const unsigned char *processed = in; - unsigned char *outend = out + *outlen; - const unsigned char *inend; - unsigned int c; - int bits; - - inend = in + (*inlen); - while ((in < inend) && (out - outstart + 5 < *outlen)) - { - c = *in++; - - /* assertion: c is a single UTF-4 value */ - if (out >= outend) - break; - if (c < 0x80) - { - *out++ = c; - bits = -6; - } - else - { - *out++ = ((c >> 6) & 0x1F) | 0xC0; - bits = 0; - } - - for (; bits >= 0; bits -= 6) - { - if (out >= outend) - break; - *out++ = ((c >> bits) & 0x3F) | 0x80; - } - processed = (const unsigned char *)in; - } - *outlen = out - outstart; - *inlen = processed - base; - return (0); -} - -void ESP_Mail_Client::decodeText(IMAPSession *imap, char *buf, int bufLen, int &chunkIdx, File &file, std::string &filePath, bool &downloadRequest, int &octetLength, int &octetCount, int &readCount) -{ - bool rfc822_body_subtype = cPart(imap)->message_sub_type == esp_mail_imap_message_sub_type_rfc822; - if (chunkIdx == 0) - { - char *tmp = subStr(buf, esp_mail_str_193, esp_mail_str_194, 0); - if (tmp) - { - octetCount = 2; - octetLength = atoi(tmp); - delS(tmp); - chunkIdx++; - cPart(imap)->octetLen = octetLength; - - if ((rfc822_body_subtype && imap->_config->download.rfc822) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_config->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_config->download.text)))) - prepareFilePath(imap, filePath, false); - - if (filePath.length() == 0) - { - if (!rfc822_body_subtype) - appendP(filePath, esp_mail_str_67, false); - else - { - appendP(filePath, esp_mail_str_82, false); - appendP(filePath, esp_mail_str_131, false); - appendP(filePath, esp_mail_str_67, false); - } - } - cPart(imap)->filename = filePath; - - return; - } - else - { - if (imap->_debug) - { - char *tmp = strP(esp_mail_str_280); - esp_mail_debug_line(tmp, false); - delS(tmp); - } - } - } - - delay(0); - - if (octetLength == 0) - return; - - if (imap->_config->download.rfc822 || imap->_config->download.html || imap->_config->download.text || (rfc822_body_subtype && imap->_config->enable.rfc822) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_config->enable.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_config->enable.text)))) - { - if (imap->_readCallback && octetCount > octetLength + 2 && readCount < 100) - fetchReport(imap, 100, (imap->_config->download.rfc822 && rfc822_body_subtype) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_config->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_config->download.text)))); - - if (octetCount <= octetLength + 2) - { - size_t olen = 0; - char *decoded = nullptr; - bool newC = true; - if (strcmpP(cPart(imap)->content_transfer_encoding.c_str(), 0, esp_mail_str_31)) - { - decoded = (char *)decodeBase64((const unsigned char *)buf, bufLen, &olen); - } - else if (strcmpP(cPart(imap)->content_transfer_encoding.c_str(), 0, esp_mail_str_278)) - { - decoded = newS(bufLen + 10); - decodeQP(buf, decoded); - olen = strlen(decoded); - } - else if (strcmpP(cPart(imap)->content_transfer_encoding.c_str(), 0, esp_mail_str_29)) - { - decoded = decode7Bit(buf); - olen = strlen(decoded); - } - else - { - //8bit and binary - newC = false; - decoded = buf; - olen = bufLen; - } - - if (decoded) - { - - if ((rfc822_body_subtype && imap->_config->enable.rfc822) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_config->enable.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_config->enable.text)))) - { - - if (getEncodingFromCharset(cPart(imap)->charset.c_str()) == esp_mail_char_decoding_scheme_iso8859_1) - { - int ilen = olen; - int olen2 = (ilen + 1) * 2; - unsigned char *tmp = (unsigned char *)newS(olen2); - decodeLatin1_UTF8(tmp, &olen2, (unsigned char *)decoded, &ilen); - delS(decoded); - olen = olen2; - decoded = (char *)tmp; - } - else if (getEncodingFromCharset(cPart(imap)->charset.c_str()) == esp_mail_char_decoding_scheme_tis620) - { - char *out = newS((olen + 1) * 3); - delS(decoded); - decodeTIS620_UTF8(out, decoded, olen); - olen = strlen(out); - decoded = out; - } - - int p = 0; - - if (octetLength > 0) - p = 100 * octetCount / octetLength; - - if ((p != readCount) && (p <= 100)) - { - readCount = p; - if (imap->_readCallback) - fetchReport(imap, p, (imap->_config->download.rfc822 && rfc822_body_subtype) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_config->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_config->download.text)))); - } - - if (cPart(imap)->text.length() < imap->_config->limit.msg_size) - { - - if (cPart(imap)->text.length() + olen < imap->_config->limit.msg_size) - { - cPart(imap)->textLen += olen; - cPart(imap)->text.append(decoded, olen); - } - else - { - int d = imap->_config->limit.msg_size - cPart(imap)->text.length(); - cPart(imap)->textLen += d; - if (d > 0) - cPart(imap)->text.append(decoded, d); - } - } - } - - if (filePath.length() > 0) - { - if (!cPart(imap)->file_open_write) - { - cPart(imap)->file_open_write = true; - - if (_sdOk || _flashOk) - { - downloadRequest = true; - - if (imap->_storageType == esp_mail_file_storage_type_sd) - file = ESP_MAIL_SD_FS.open(filePath.c_str(), FILE_WRITE); - else if (imap->_storageType == esp_mail_file_storage_type_flash) -#if defined(ESP32) - file = ESP_MAIL_FLASH_FS.open(filePath.c_str(), FILE_WRITE); -#elif defined(ESP8266) - file = ESP_MAIL_FLASH_FS.open(filePath.c_str(), "w"); -#endif - } - } - - if (_sdOk || _flashOk) - file.write((const uint8_t *)decoded, olen); - } - - if (newC) - delS(decoded); - } - } - } -} -void ESP_Mail_Client::prepareFilePath(IMAPSession *imap, std::string &filePath, bool header) -{ - bool rfc822_body_subtype = cPart(imap)->message_sub_type == esp_mail_imap_message_sub_type_rfc822; - std::string fpath = imap->_config->storage.saved_path; - appendP(fpath, esp_mail_str_202, false); - char *tmp = intStr(cMSG(imap)); - fpath += tmp; - delS(tmp); - - if (imap->_storageType == esp_mail_file_storage_type_sd) - if (!ESP_MAIL_SD_FS.exists(fpath.c_str())) - createDirs(fpath); - - if (header) - { - appendP(fpath, esp_mail_str_203, false); - } - else - { - if (!rfc822_body_subtype) - { - appendP(fpath, esp_mail_str_161, false); - if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) - appendP(fpath, esp_mail_str_95, false); - else if (cPart(imap)->msg_type == esp_mail_msg_type_html) - appendP(fpath, esp_mail_str_94, false); - } - else - { - appendP(fpath, esp_mail_str_163, false); - - if (cPart(imap)->rfc822_msg_Idx > 0) - { - char *tmp = intStr(cPart(imap)->rfc822_msg_Idx); - fpath += tmp; - delS(tmp); - } - - if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) - appendP(fpath, esp_mail_str_95, false); - else if (cPart(imap)->msg_type == esp_mail_msg_type_html) - appendP(fpath, esp_mail_str_94, false); - else - //possible rfc822 encapsulated message which cannot fetch its header - appendP(fpath, esp_mail_str_40, false); - } - } - - filePath = fpath; -} - -char *ESP_Mail_Client::strReplace(char *orig, char *rep, char *with) -{ - char *result = nullptr; - char *ins = nullptr; - char *tmp = nullptr; - int len_rep; - int len_with; - int len_front; - int count; - - len_with = strlen(with); - len_rep = strlen(rep); - - ins = orig; - for (count = 0; (tmp = strstr(ins, rep)); ++count) - ins = tmp + len_rep; - - tmp = result = newS(strlen(orig) + (len_with - len_rep) * count + 1); - while (count--) - { - ins = strstr(orig, rep); - len_front = ins - orig; - tmp = strncpy(tmp, orig, len_front) + len_front; - tmp = strcpy(tmp, with) + len_with; - orig += len_front + len_rep; - } - strcpy(tmp, orig); - return result; -} - -int ESP_Mail_Client::decodeChar(const char *s) -{ - assert(s); - assert(*s == '='); - return 16 * hexval(*(s + 1)) + hexval(*(s + 2)); -} - -void ESP_Mail_Client::decodeQP(const char *buf, char *out) -{ - char *tmp = strP(esp_mail_str_295); - while (*buf) - { - if (*buf != '=') - strcat_c(out, *buf++); - else if (*(buf + 1) == '\r' && *(buf + 2) == '\n') - buf += 3; - else if (*(buf + 1) == '\n') - buf += 2; - else if (!strchr(tmp, *(buf + 1))) - strcat_c(out, *buf++); - else if (!strchr(tmp, *(buf + 2))) - strcat_c(out, *buf++); - else - { - strcat_c(out, decodeChar(buf)); - buf += 3; - } - } - delS(tmp); -} - -std::string ESP_Mail_Client::getBoundary(size_t len) -{ - char *tmp = strP(boundary_table); - char *buf = newS(len); - if (len) - { - --len; - buf[0] = tmp[0]; - buf[1] = tmp[1]; - for (size_t n = 2; n < len; n++) - { - int key = rand() % (int)(strlen(tmp) - 1); - buf[n] = tmp[key]; - } - buf[len] = '\0'; - } - std::string s = buf; - delS(buf); - delS(tmp); - return s; -} - -char *ESP_Mail_Client::decode7Bit(char *buf) -{ - char *out = strReplaceP(buf, imap_7bit_key1, imap_7bit_val1); - char *tmp = newS(strlen(out) + 10); - strcpy(tmp, out); - delS(out); - out = strReplaceP(tmp, imap_7bit_key2, imap_7bit_val2); - - delS(tmp); - tmp = newS(strlen(out) + 10); - strcpy(tmp, out); - delS(out); - out = strReplaceP(tmp, imap_7bit_key3, imap_7bit_val3); - - delS(tmp); - tmp = newS(strlen(out) + 10); - strcpy(tmp, out); - delS(out); - out = strReplaceP(tmp, imap_7bit_key4, imap_7bit_val4); - - delS(tmp); - tmp = newS(strlen(out) + 10); - strcpy(tmp, out); - delS(out); - out = strReplaceP(tmp, imap_7bit_key5, imap_7bit_val5); - - delS(tmp); - tmp = newS(strlen(out) + 10); - strcpy(tmp, out); - delS(out); - out = strReplaceP(tmp, imap_7bit_key6, imap_7bit_val6); - - delS(tmp); - tmp = newS(strlen(out) + 10); - strcpy(tmp, out); - delS(out); - out = strReplaceP(tmp, imap_7bit_key7, imap_7bit_val7); - - delS(tmp); - tmp = newS(strlen(out) + 10); - strcpy(tmp, out); - delS(out); - out = strReplaceP(tmp, imap_7bit_key8, imap_7bit_val8); - - delS(tmp); - tmp = newS(strlen(out) + 10); - strcpy(tmp, out); - delS(out); - out = strReplaceP(tmp, imap_7bit_key9, imap_7bit_val9); - - delS(tmp); - tmp = newS(strlen(out) + 10); - strcpy(tmp, out); - delS(out); - out = strReplaceP(tmp, imap_7bit_key10, imap_7bit_val10); - - delS(tmp); - tmp = newS(strlen(out) + 10); - strcpy(tmp, out); - delS(out); - out = strReplaceP(tmp, imap_7bit_key11, imap_7bit_val11); - - delS(tmp); - tmp = newS(strlen(out) + 10); - strcpy(tmp, out); - delS(out); - out = strReplaceP(tmp, imap_7bit_key12, imap_7bit_val12); - - delS(tmp); - tmp = newS(strlen(out) + 10); - strcpy(tmp, out); - delS(out); - out = strReplaceP(tmp, imap_7bit_key13, imap_7bit_val13); - delS(tmp); - return out; -} - -char *ESP_Mail_Client::strReplaceP(char *buf, PGM_P name, PGM_P value) -{ - char *n = strP(name); - char *v = strP(value); - char *out = strReplace(buf, n, v); - delS(n); - delS(v); - return out; -} - -void ESP_Mail_Client::handleCapability(IMAPSession *imap, char *buf, int &chunkIdx) -{ - if (chunkIdx == 0) - { - if (strposP(buf, esp_mail_imap_response_10, 0) > -1) - { - if (strposP(buf, esp_mail_imap_response_11, 0) > -1) - imap->_auth_capability.login = true; - if (strposP(buf, esp_mail_imap_response_12, 0) > -1) - imap->_auth_capability.plain = true; - if (strposP(buf, esp_mail_imap_response_13, 0) > -1) - imap->_auth_capability.xoauth2 = true; - if (strposP(buf, esp_mail_imap_response_14, 0) > -1) - imap->_auth_capability.start_tls = true; - if (strposP(buf, esp_mail_imap_response_15, 0) > -1) - imap->_auth_capability.cram_md5 = true; - if (strposP(buf, esp_mail_imap_response_16, 0) > -1) - imap->_auth_capability.digest_md5 = true; - } - } -} - -bool ESP_Mail_Client::authFailed(char *buf, int bufLen, int &chunkIdx, int ofs) -{ - bool ret = false; - if (chunkIdx == 0) - { - size_t olen; - unsigned char *decoded = decodeBase64((const unsigned char *)(buf + ofs), bufLen - ofs, &olen); - if (decoded) - { - ret = strposP((char *)decoded, esp_mail_str_294, 0) > -1; - delete[] decoded; - } - chunkIdx++; - } - return ret; -} - -void ESP_Mail_Client::handleFolders(IMAPSession *imap, char *buf) -{ - struct esp_mail_folder_info_t fd; - char *tmp = nullptr; - int p1 = strposP(buf, esp_mail_imap_response_4, 0); - int p2 = 0; - if (p1 != -1) - { - p1 = strposP(buf, esp_mail_str_198, 0); - if (p1 != -1) - { - p2 = strposP(buf, esp_mail_str_192, p1 + 1); - if (p2 != -1) - { - tmp = newS(p2 - p1); - strncpy(tmp, buf + p1 + 1, p2 - p1 - 1); - if (tmp[p2 - p1 - 2] == '\r') - tmp[p2 - p1 - 2] = 0; - fd.attributes = tmp; - delS(tmp); - } - } - - p1 = strposP(buf, esp_mail_str_136, 0); - if (p1 != -1) - { - p2 = strposP(buf, esp_mail_str_136, p1 + 1); - if (p2 != -1) - { - tmp = newS(p2 - p1); - strncpy(tmp, buf + p1 + 1, p2 - p1 - 1); - if (tmp[p2 - p1 - 2] == '\r') - tmp[p2 - p1 - 2] = 0; - fd.delimiter = tmp; - delS(tmp); - } - } - - p1 = strposP(buf, esp_mail_str_131, p2); - if (p1 != -1) - { - p2 = strlen(buf); - tmp = newS(p2 - p1); - if (buf[p1 + 1] == '"') - p1++; - strncpy(tmp, buf + p1 + 1, p2 - p1 - 1); - if (tmp[p2 - p1 - 2] == '\r') - tmp[p2 - p1 - 2] = 0; - if (tmp[strlen(tmp) - 1] == '"') - tmp[strlen(tmp) - 1] = 0; - fd.name = tmp; - delS(tmp); - } - imap->_folders.add(fd); - } -} - -void ESP_Mail_Client::handleExamine(IMAPSession *imap, char *buf) -{ - char *tmp = nullptr; - int p1, p2; - - if (imap->_mbif._msgCount == 0) - { - p1 = strposP(buf, esp_mail_str_199, 0); - if (p1 != -1) - { - tmp = newS(p1); - strncpy(tmp, buf + 2, p1 - 1); - imap->_mbif._msgCount = atoi(tmp); - delS(tmp); - return; - } - } - - if (imap->_mbif._flags.size() == 0) - { - p1 = strposP(buf, esp_mail_imap_response_5, 0); - if (p1 != -1) - { - p1 = strposP(buf, esp_mail_str_198, 0); - if (p1 != -1) - { - p2 = strposP(buf, esp_mail_str_192, p1 + 1); - if (p2 != -1) - { - tmp = newS(p2 - p1); - strncpy(tmp, buf + p1 + 1, p2 - p1 - 1); - char *stk = strP(esp_mail_str_131); - char *end_token; - char *token = strtok_r(tmp, stk, &end_token); - while (token != NULL) - { - imap->_mbif.addFlag(token); - token = strtok_r(NULL, stk, &end_token); - } - if (token) - delS(token); - delS(tmp); - delS(stk); - } - } - return; - } - } - - if (imap->_nextUID.length() == 0) - { - p1 = strposP(buf, esp_mail_str_200, 0); - if (p1 != -1) - { - p2 = strposP(buf, esp_mail_str_156, p1 + strlen_P(esp_mail_str_200)); - if (p2 != -1) - { - tmp = newS(p2 - p1 - strlen_P(esp_mail_str_200) + 1); - strncpy(tmp, buf + p1 + strlen_P(esp_mail_str_200), p2 - p1 - strlen_P(esp_mail_str_200)); - imap->_nextUID = tmp; - imap->_mbif._nextUID = atoi(tmp); - delS(tmp); - } - return; - } - } -} - -bool ESP_Mail_Client::handleIMAPError(IMAPSession *imap, int err, bool ret) -{ - if (err < 0) - { - errorStatusCB(imap, err); - - if (imap->_headers.size() > 0) - { - if ((imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) && (imap->_config->download.attachment || imap->_config->download.inlineImg)) - { - if (cHeader(imap)->part_headers.size() > 0) - cPart(imap)->download_error = imap->errorReason().c_str(); - } - else - cHeader(imap)->error_msg = imap->errorReason().c_str(); - - cHeader(imap)->error = true; - } - } - - if (imap->_tcpConnected) - closeTCP(imap); - - imap->_cbData.empty(); - - return ret; -} - -unsigned char *ESP_Mail_Client::decodeBase64(const unsigned char *src, size_t len, size_t *out_len) -{ - - unsigned char *out, *pos, block[4], tmp; - size_t i, count, olen; - int pad = 0; - size_t extra_pad; - - unsigned char *dtable = new unsigned char[256]; - - memset(dtable, 0x80, 256); - - for (i = 0; i < sizeof(b64_index_table) - 1; i++) - dtable[b64_index_table[i]] = (unsigned char)i; - dtable['='] = 0; - - count = 0; - for (i = 0; i < len; i++) - { - if (dtable[src[i]] != 0x80) - count++; - } - - if (count == 0) - goto exit; - extra_pad = (4 - count % 4) % 4; - - olen = (count + extra_pad) / 4 * 3; - pos = out = (unsigned char *)malloc(olen); - if (out == NULL) - goto exit; - - count = 0; - for (i = 0; i < len + extra_pad; i++) - { - unsigned char val; - - if (i >= len) - val = '='; - else - val = src[i]; - tmp = dtable[val]; - if (tmp == 0x80) - continue; - - if (val == '=') - pad++; - block[count] = tmp; - count++; - if (count == 4) - { - *pos++ = (block[0] << 2) | (block[1] >> 4); - *pos++ = (block[1] << 4) | (block[2] >> 2); - *pos++ = (block[2] << 6) | block[3]; - count = 0; - if (pad) - { - if (pad == 1) - pos--; - else if (pad == 2) - pos -= 2; - else - { - free(out); - goto exit; - } - break; - } - } - } - - *out_len = pos - out; - delete[] dtable; - return out; -exit: - delete[] dtable; - return nullptr; -} - -std::string ESP_Mail_Client::encodeBase64Str(const unsigned char *src, size_t len) -{ - return encodeBase64Str((uint8_t *)src, len); -} - -std::string ESP_Mail_Client::encodeBase64Str(uint8_t *src, size_t len) -{ - std::string outStr; - unsigned char *out, *pos; - const unsigned char *end, *in; - size_t olen = 4 * ((len + 2) / 3); - if (olen < len) - return outStr; - - outStr.resize(olen); - out = (unsigned char *)&outStr[0]; - - end = src + len; - in = src; - pos = out; - - while (end - in >= 3) - { - *pos++ = b64_index_table[in[0] >> 2]; - *pos++ = b64_index_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; - *pos++ = b64_index_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; - *pos++ = b64_index_table[in[2] & 0x3f]; - in += 3; - } - - if (end - in) - { - *pos++ = b64_index_table[in[0] >> 2]; - if (end - in == 1) - { - *pos++ = b64_index_table[(in[0] & 0x03) << 4]; - *pos++ = '='; - } - else - { - *pos++ = b64_index_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; - *pos++ = b64_index_table[(in[1] & 0x0f) << 2]; - } - *pos++ = '='; - } - - return outStr; -} - -void ESP_Mail_Client::encodeQP(const char *buf, char *out) -{ - int n = 0, p = 0, pos = 0; - assert(buf); - for (n = 0; *buf; buf++) - { - if (n >= 73 && *buf != 10 && *buf != 13) - { - p = sprintf(out + pos, "=\r\n"); - pos += p; - n = 0; - } - - if (*buf == 10 || *buf == 13) - { - strcat_c(out, *buf); - pos++; - n = 0; - } - else if (*buf < 32 || *buf == 61 || *buf > 126) - { - p = sprintf(out + pos, "=%02X", (unsigned char)*buf); - n += p; - pos += p; - } - else if (*buf != 32 || (*(buf + 1) != 10 && *(buf + 1) != 13)) - { - strcat_c(out, *buf); - n++; - pos++; - } - else - { - p = sprintf(out + pos, "=20"); - n += p; - pos += p; - } - } -} - -bool ESP_Mail_Client::sendBase64(SMTPSession *smtp, SMTP_Message *msg, const unsigned char *data, size_t len, bool flashMem, const char *filename, bool report) -{ - bool ret = false; - const unsigned char *end, *in; - - size_t olen = 4 * ((len + 2) / 3); - - if (olen < len) - return false; - - end = data + len; - in = data; - - size_t chunkSize = 936; - size_t byteAdded = 0; - size_t byteSent = 0; - - int dByte = 0; - unsigned char *buf = new unsigned char[chunkSize]; - memset(buf, 0, chunkSize); - - unsigned char *tmp = new unsigned char[3]; - int bcnt = 0; - int pg = 0, _pg = 0; - - if (report) - uploadReport(filename, bcnt); - - while (end - in >= 3) - { - - memset(tmp, 0, 3); - if (flashMem) - memcpy_P(tmp, in, 3); - else - memcpy(tmp, in, 3); - bcnt += 3; - - buf[byteAdded++] = b64_index_table[tmp[0] >> 2]; - buf[byteAdded++] = b64_index_table[((tmp[0] & 0x03) << 4) | (tmp[1] >> 4)]; - buf[byteAdded++] = b64_index_table[((tmp[1] & 0x0f) << 2) | (tmp[2] >> 6)]; - buf[byteAdded++] = b64_index_table[tmp[2] & 0x3f]; - dByte += 4; - if (dByte == BASE64_CHUNKED_LEN) - { - if (byteAdded + 1 < chunkSize) - { - buf[byteAdded++] = 0x0d; - buf[byteAdded++] = 0x0a; - } - dByte = 0; - } - if (byteAdded >= chunkSize - 4) - { - byteSent += byteAdded; - - if (!bdat(smtp, msg, byteAdded, false)) - goto ex; - - if (smtpSend(smtp, buf, byteAdded) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - goto ex; - memset(buf, 0, chunkSize); - byteAdded = 0; - } - in += 3; - - if (report) - { - pg = (float)(100.0f * bcnt / len); - if (pg != _pg) - uploadReport(filename, pg); - _pg = pg; - } - } - - if (byteAdded > 0) - { - if (!bdat(smtp, msg, byteAdded, false)) - goto ex; - - if (smtpSend(smtp, buf, byteAdded) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - goto ex; - } - - if (end - in) - { - memset(buf, 0, chunkSize); - byteAdded = 0; - memset(tmp, 0, 3); - if (flashMem) - { - if (end - in == 1) - memcpy_P(tmp, in, 1); - else - memcpy_P(tmp, in, 2); - } - else - { - if (end - in == 1) - memcpy(tmp, in, 1); - else - memcpy(tmp, in, 2); - } - - buf[byteAdded++] = b64_index_table[tmp[0] >> 2]; - if (end - in == 1) - { - buf[byteAdded++] = b64_index_table[(tmp[0] & 0x03) << 4]; - buf[byteAdded++] = '='; - } - else - { - buf[byteAdded++] = b64_index_table[((tmp[0] & 0x03) << 4) | (tmp[1] >> 4)]; - buf[byteAdded++] = b64_index_table[(tmp[1] & 0x0f) << 2]; - } - buf[byteAdded++] = '='; - - if (!bdat(smtp, msg, byteAdded, false)) - goto ex; - - if (smtpSend(smtp, buf, byteAdded) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - goto ex; - memset(buf, 0, chunkSize); - } - - if (report && _pg < 100) - uploadReport(filename, 100); - - ret = true; -ex: - if (report) - esp_mail_debug(""); - delete[] tmp; - delete[] buf; - return ret; -} - -bool ESP_Mail_Client::sendBase64Stream(SMTPSession *smtp, SMTP_Message *msg, File file, const char *filename, bool report) -{ - bool ret = false; - - if (!file) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_FILE_IO_ERROR); - return false; - } - - size_t chunkSize = 936; - size_t byteAdded = 0; - size_t byteSent = 0; - - unsigned char *buf = new unsigned char[chunkSize]; - memset(buf, 0, chunkSize); - - size_t len = file.size(); - size_t fbufIndex = 0; - unsigned char *fbuf = new unsigned char[3]; - - int dByte = 0; - - int bcnt = 0; - int pg = 0, _pg = 0; - - if (report) - uploadReport(filename, bcnt); - - while (file.available()) - { - memset(fbuf, 0, 3); - if (len - fbufIndex >= 3) - { - bcnt += 3; - size_t readLen = file.read(fbuf, 3); - if (readLen != 3) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_FILE_IO_ERROR); - break; - } - - buf[byteAdded++] = b64_index_table[fbuf[0] >> 2]; - buf[byteAdded++] = b64_index_table[((fbuf[0] & 0x03) << 4) | (fbuf[1] >> 4)]; - buf[byteAdded++] = b64_index_table[((fbuf[1] & 0x0f) << 2) | (fbuf[2] >> 6)]; - buf[byteAdded++] = b64_index_table[fbuf[2] & 0x3f]; - dByte += 4; - if (dByte == BASE64_CHUNKED_LEN) - { - if (byteAdded + 1 < chunkSize) - { - buf[byteAdded++] = 0x0d; - buf[byteAdded++] = 0x0a; - } - dByte = 0; - } - if (byteAdded >= chunkSize - 4) - { - byteSent += byteAdded; - - if (!bdat(smtp, msg, byteAdded, false)) - goto ex; - - if (smtpSend(smtp, buf, byteAdded) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - goto ex; - - memset(buf, 0, chunkSize); - byteAdded = 0; - } - fbufIndex += 3; - - if (report) - { - pg = (float)(100.0f * bcnt / len); - if (pg != _pg) - uploadReport(filename, pg); - _pg = pg; - } - } - else - { - size_t readLen = file.read(fbuf, len - fbufIndex); - if (readLen != len - fbufIndex) - { - errorStatusCB(smtp, MAIL_CLIENT_ERROR_FILE_IO_ERROR); - break; - } - } - } - - file.close(); - if (byteAdded > 0) - { - if (!bdat(smtp, msg, byteAdded, false)) - goto ex; - - if (smtpSend(smtp, buf, byteAdded) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - goto ex; - } - - if (len - fbufIndex > 0) - { - memset(buf, 0, chunkSize); - byteAdded = 0; - buf[byteAdded++] = b64_index_table[fbuf[0] >> 2]; - if (len - fbufIndex == 1) - { - buf[byteAdded++] = b64_index_table[(fbuf[0] & 0x03) << 4]; - buf[byteAdded++] = '='; - } - else - { - buf[byteAdded++] = b64_index_table[((fbuf[0] & 0x03) << 4) | (fbuf[1] >> 4)]; - buf[byteAdded++] = b64_index_table[(fbuf[1] & 0x0f) << 2]; - } - buf[byteAdded++] = '='; - - if (!bdat(smtp, msg, byteAdded, false)) - goto ex; - - if (smtpSend(smtp, buf, byteAdded) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - goto ex; - } - ret = true; - - if (report && _pg < 100) - uploadReport(filename, 100); - -ex: - delete[] buf; - delete[] fbuf; - file.close(); - return ret; -} - -IMAPSession::IMAPSession() {} -IMAPSession::~IMAPSession() -{ - empty(); - _caCert.reset(); - _caCert = nullptr; -} - -bool IMAPSession::closeSession() -{ - if (!_tcpConnected) - return false; -#if defined(ESP32) - /** - * The strange behavior in ESP8266 SSL client, BearSSLWiFiClientSecure - * The client disposed without memory released after the server close - * the connection due to LOGOUT command, which caused the memory leaks. - */ - if (!MailClient.imapLogout(this)) - return false; -#endif - return MailClient.handleIMAPError(this, 0, true); -} - -bool IMAPSession::connect(ESP_Mail_Session *sesssion, IMAP_Config *config) -{ - if (_tcpConnected) - MailClient.closeTCP(this); - - _sesson_cfg = sesssion; - _config = config; - _caCert = nullptr; - - if (strlen(_sesson_cfg->certificate.cert_data) > 0) - _caCert = std::shared_ptr(_sesson_cfg->certificate.cert_data); - - if (strlen(_sesson_cfg->certificate.cert_file) > 0) - { - if (_sesson_cfg->certificate.cert_file_storage_type == esp_mail_file_storage_type::esp_mail_file_storage_type_sd && !MailClient._sdOk) - MailClient._sdOk = MailClient.sdTest(); - if (_sesson_cfg->certificate.cert_file_storage_type == esp_mail_file_storage_type::esp_mail_file_storage_type_flash && !MailClient._flashOk) -#if defined(ESP32) - MailClient._flashOk = ESP_MAIL_FLASH_FS.begin(FORMAT_FLASH); -#elif defined(ESP8266) - MailClient._flashOk = ESP_MAIL_FLASH_FS.begin(); -#endif - } - - return MailClient.imapAuth(this); -} - -void IMAPSession::debug(int level) -{ - if (level > esp_mail_debug_level_0) - { - if (level > esp_mail_debug_level_3) - level = esp_mail_debug_level_1; - _debugLevel = level; - _debug = true; - } - else - { - _debugLevel = esp_mail_debug_level_0; - _debug = false; - } -} - -String IMAPSession::errorReason() -{ - std::string ret; - - if (_imapStatus.text.length() > 0) - return _imapStatus.text.c_str(); - - switch (_imapStatus.statusCode) - { - case IMAP_STATUS_SERVER_CONNECT_FAILED: - MailClient.appendP(ret, esp_mail_str_38, true); - break; - case MAIL_CLIENT_ERROR_CONNECTION_LOST: - MailClient.appendP(ret, esp_mail_str_221, true); - break; - case MAIL_CLIENT_ERROR_READ_TIMEOUT: - MailClient.appendP(ret, esp_mail_str_258, true); - break; - case MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED: - MailClient.appendP(ret, esp_mail_str_305, true); - break; - case IMAP_STATUS_NO_MESSAGE: - MailClient.appendP(ret, esp_mail_str_306, true); - break; - case IMAP_STATUS_ERROR_DOWNLAD_TIMEOUT: - MailClient.appendP(ret, esp_mail_str_93, true); - break; - case MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP: - MailClient.appendP(ret, esp_mail_str_132, true); - break; - case IMAP_STATUS_CLOSE_MAILBOX_FAILED: - MailClient.appendP(ret, esp_mail_str_188, true); - break; - case IMAP_STATUS_OPEN_MAILBOX_FAILED: - MailClient.appendP(ret, esp_mail_str_281, true); - break; - case IMAP_STATUS_LIST_MAILBOXS_FAILED: - MailClient.appendP(ret, esp_mail_str_62, true); - break; - case IMAP_STATUS_NO_SUPPORTED_AUTH: - MailClient.appendP(ret, esp_mail_str_42, true); - break; - case IMAP_STATUS_CHECK_CAPABILITIES_FAILED: - MailClient.appendP(ret, esp_mail_str_63, true); - break; - case MAIL_CLIENT_ERROR_OUT_OF_MEMORY: - MailClient.appendP(ret, esp_mail_str_186, true); - break; - case IMAP_STATUS_NO_MAILBOX_FOLDER_OPENED: - MailClient.appendP(ret, esp_mail_str_153, true); - break; - - default: - break; - } - return ret.c_str(); -} - -bool IMAPSession::selectFolder(const char *folderName, bool readOnly) -{ - if (_tcpConnected) - { - if (!openFolder(folderName, readOnly)) - return false; - } - else - { - _currentFolder = folderName; - } - return true; -} - -bool IMAPSession::openFolder(const char *folderName, bool readOnly) -{ - if (!_tcpConnected) - return false; - if (readOnly) - return openMailbox(folderName, esp_mail_imap_auth_mode::esp_mail_imap_mode_examine, true); - else - return openMailbox(folderName, esp_mail_imap_auth_mode::esp_mail_imap_mode_select, true); -} - -bool IMAPSession::getFolders(FoldersCollection &folders) -{ - if (!_tcpConnected) - return false; - return getMailboxes(folders); -} - -bool IMAPSession::closeFolder(const char *folderName) -{ - if (!_tcpConnected) - return false; - return closeMailbox(); -} - -void IMAPSession::checkUID() -{ - if (MailClient.strcmpP(_config->fetch.uid, 0, esp_mail_str_140) || MailClient.strcmpP(_config->fetch.uid, 0, esp_mail_str_212) || - MailClient.strcmpP(_config->fetch.uid, 0, esp_mail_str_213) || MailClient.strcmpP(_config->fetch.uid, 0, esp_mail_str_214) || MailClient.strcmpP(_config->fetch.uid, 0, esp_mail_str_215) || - MailClient.strcmpP(_config->fetch.uid, 0, esp_mail_str_216) || MailClient.strcmpP(_config->fetch.uid, 0, esp_mail_str_217) || MailClient.strcmpP(_config->fetch.uid, 0, esp_mail_str_218) || - MailClient.strcmpP(_config->fetch.uid, 0, esp_mail_str_219) || MailClient.strcmpP(_config->fetch.uid, 0, esp_mail_str_220)) - _config->fetch.uid = "*"; -} - -void IMAPSession::checkPath() -{ - std::string path = _config->storage.saved_path; - if (path[0] != '/') - { - path = "/"; - path += _config->storage.saved_path; - path = path.c_str(); - } -} - -bool IMAPSession::headerOnly() -{ - return _headerOnly; -} - -struct esp_mail_imap_msg_list_t IMAPSession::data() -{ - struct esp_mail_imap_msg_list_t ret; - - for (size_t i = 0; i < _headers.size(); i++) - { - if (ESP.getFreeHeap() < ESP_MAIL_MIN_MEM) - continue; - - struct esp_mail_imap_msg_item_t itm; - - itm.UID = _headers[i].message_uid.c_str(); - itm.ID = _headers[i].message_id.c_str(); - itm.msgNo = _headers[i].message_no.c_str(); - itm.from = _headers[i].from.c_str(); - itm.fromCharset = _headers[i].from_charset.c_str(); - itm.to = _headers[i].to.c_str(); - itm.toCharset = _headers[i].to_charset.c_str(); - itm.cc = _headers[i].cc.c_str(); - itm.ccCharset = _headers[i].cc_charset.c_str(); - itm.subject = _headers[i].subject.c_str(); - itm.subjectCharset = _headers[i].subject_charset.c_str(); - itm.date = _headers[i].date.c_str(); - itm.fetchError = _headers[i].error_msg.c_str(); - - getMessages(i, itm); - - getRFC822Messages(i, itm); - - ret.msgItems.push_back(itm); - } - - return ret; -} - -SelectedFolderInfo IMAPSession::selectedFolder() -{ - return _mbif; -} - -void IMAPSession::callback(imapStatusCallback imapCallback) -{ - _readCallback = std::move(imapCallback); -} - -void IMAPSession::getMessages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg) -{ - msg.text.content = ""; - msg.text.charSet = ""; - msg.text.content_type = ""; - msg.text.transfer_encoding = ""; - msg.html.content = ""; - msg.html.charSet = ""; - msg.html.content_type = ""; - msg.html.transfer_encoding = ""; - - if (messageIndex < _headers.size()) - { - int sz = _headers[messageIndex].part_headers.size(); - if (sz > 0) - { - for (int i = 0; i < sz; i++) - { - if (!_headers[messageIndex].part_headers[i].rfc822_part && _headers[messageIndex].part_headers[i].message_sub_type != esp_mail_imap_message_sub_type_rfc822) - { - if (_headers[messageIndex].part_headers[i].attach_type == esp_mail_att_type_none) - { - if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_plain || _headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_enriched) - { - msg.text.content = _headers[messageIndex].part_headers[i].text.c_str(); - msg.text.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); - msg.text.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); - msg.text.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); - } - - if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_html) - { - msg.html.content = _headers[messageIndex].part_headers[i].text.c_str(); - msg.html.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); - msg.html.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); - msg.html.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); - } - } - else - { - struct esp_mail_attacment_info_t att; - att.filename = _headers[messageIndex].part_headers[i].filename.c_str(); - att.mime = _headers[messageIndex].part_headers[i].content_type.c_str(); - att.name = _headers[messageIndex].part_headers[i].name.c_str(); - att.size = _headers[messageIndex].part_headers[i].attach_data_size; - att.creationDate = _headers[messageIndex].part_headers[i].creation_date.c_str(); - att.type = _headers[messageIndex].part_headers[i].attach_type; - msg.attachments.push_back(att); - } - } - } - } - } -} - -void IMAPSession::getRFC822Messages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg) -{ - if (messageIndex < _headers.size()) - { - int sz = _headers[messageIndex].part_headers.size(); - int partIdx = 0; - int cIdx = 0; - IMAP_MSG_Item *_rfc822 = nullptr; - if (sz > 0) - { - for (int i = 0; i < sz; i++) - { - if (_headers[messageIndex].part_headers[i].message_sub_type == esp_mail_imap_message_sub_type_rfc822) - { - if (_headers[messageIndex].part_headers[i].rfc822_part) - { - if (partIdx > 0) - msg.rfc822.push_back(*_rfc822); - cIdx = i; - partIdx++; - _rfc822 = new IMAP_MSG_Item(); - - _rfc822->from = _headers[messageIndex].part_headers[i].rfc822_header.from.c_str(); - _rfc822->sender = _headers[messageIndex].part_headers[i].rfc822_header.sender.c_str(); - _rfc822->to = _headers[messageIndex].part_headers[i].rfc822_header.to.c_str(); - _rfc822->cc = _headers[messageIndex].part_headers[i].rfc822_header.cc.c_str(); - _rfc822->bcc = _headers[messageIndex].part_headers[i].rfc822_header.bcc.c_str(); - _rfc822->return_path = _headers[messageIndex].part_headers[i].rfc822_header.return_path.c_str(); - _rfc822->reply_to = _headers[messageIndex].part_headers[i].rfc822_header.reply_to.c_str(); - _rfc822->subject = _headers[messageIndex].part_headers[i].rfc822_header.subject.c_str(); - _rfc822->comment = _headers[messageIndex].part_headers[i].rfc822_header.comment.c_str(); - _rfc822->keyword = _headers[messageIndex].part_headers[i].rfc822_header.keyword.c_str(); - _rfc822->date = _headers[messageIndex].part_headers[i].rfc822_header.date.c_str(); - _rfc822->messageID = _headers[messageIndex].part_headers[i].rfc822_header.messageID.c_str(); - _rfc822->text.charSet = ""; - _rfc822->text.content_type = ""; - _rfc822->text.transfer_encoding = ""; - _rfc822->html.charSet = ""; - _rfc822->html.content_type = ""; - _rfc822->html.transfer_encoding = ""; - } - else - { - if (MailClient.multipartMember(_headers[messageIndex].part_headers[cIdx].partNumStr, _headers[messageIndex].part_headers[i].partNumStr)) - { - if (_headers[messageIndex].part_headers[i].attach_type == esp_mail_att_type_none) - { - if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_plain || _headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_enriched) - { - _rfc822->text.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); - _rfc822->text.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); - _rfc822->text.content = _headers[messageIndex].part_headers[i].text.c_str(); - _rfc822->text.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); - } - if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_html) - { - _rfc822->html.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); - _rfc822->html.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); - _rfc822->html.content = _headers[messageIndex].part_headers[i].text.c_str(); - _rfc822->html.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); - } - } - else - { - struct esp_mail_attacment_info_t att; - att.filename = _headers[messageIndex].part_headers[i].filename.c_str(); - att.mime = _headers[messageIndex].part_headers[i].content_type.c_str(); - att.name = _headers[messageIndex].part_headers[i].name.c_str(); - att.size = _headers[messageIndex].part_headers[i].attach_data_size; - att.creationDate = _headers[messageIndex].part_headers[i].creation_date.c_str(); - att.type = _headers[messageIndex].part_headers[i].attach_type; - _rfc822->attachments.push_back(att); - } - } - } - } - } - - if ((int)msg.rfc822.size() < partIdx && _rfc822 != nullptr) - msg.rfc822.push_back(*_rfc822); - } - } -} - -bool IMAPSession::closeMailbox() -{ - - if (!MailClient.reconnect(this)) - return false; - - std::string s; - - if (_readCallback) - { - MailClient.appendP(s, esp_mail_str_210, true); - s += _currentFolder; - MailClient.appendP(s, esp_mail_str_96, false); - MailClient.imapCB(this, "", false); - MailClient.imapCB(this, s.c_str(), false); - } - - if (_debug) - MailClient.debugInfoP(esp_mail_str_197); - - if (MailClient.imapSendP(this, esp_mail_str_195, true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - _imap_cmd = esp_mail_imap_cmd_close; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_CLOSE_MAILBOX_FAILED, false)) - return false; - - _currentFolder.clear(); - _mailboxOpened = false; - - return true; -} - -bool IMAPSession::openMailbox(const char *folder, esp_mail_imap_auth_mode mode, bool waitResponse) -{ - - if (!MailClient.reconnect(this)) - return false; - - if (_currentFolder.length() > 0) - { - if (strcmp(_currentFolder.c_str(), folder) != 0) - { - if (!closeMailbox()) - return false; - } - } - - _currentFolder = folder; - std::string s; - if (_readCallback) - { - MailClient.appendP(s, esp_mail_str_61, true); - s += _currentFolder; - MailClient.appendP(s, esp_mail_str_96, false); - MailClient.imapCB(this, "", false); - MailClient.imapCB(this, s.c_str(), false); - } - - if (_debug) - MailClient.debugInfoP(esp_mail_str_248); - - if (mode == esp_mail_imap_mode_examine) - { - MailClient.appendP(s, esp_mail_str_135, true); - _imap_cmd = esp_mail_imap_cmd_examine; - } - else if (mode == esp_mail_imap_mode_select) - { - MailClient.appendP(s, esp_mail_str_247, true); - _imap_cmd = esp_mail_imap_cmd_select; - } - s += _currentFolder; - MailClient.appendP(s, esp_mail_str_136, false); - if (MailClient.imapSend(this, s.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - if (waitResponse) - { - - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_OPEN_MAILBOX_FAILED, false)) - return false; - } - - if (mode == esp_mail_imap_mode_examine) - _readOnlyMode = true; - else if (mode == esp_mail_imap_mode_select) - _readOnlyMode = false; - - _mailboxOpened = true; - - return true; -} - -bool IMAPSession::getMailboxes(FoldersCollection &folders) -{ - _folders.clear(); - - if (_readCallback) - { - MailClient.imapCB(this, "", false); - MailClient.imapCBP(this, esp_mail_str_58, false); - } - - if (_debug) - MailClient.debugInfoP(esp_mail_str_230); - - if (MailClient.imapSendP(this, esp_mail_str_133, true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - _imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_list; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) - return false; - - folders = _folders; - return true; -} - -bool IMAPSession::checkCapability() -{ - if (_readCallback) - { - MailClient.imapCB(this, "", false); - MailClient.imapCBP(this, esp_mail_str_64, false); - } - - if (_debug) - MailClient.debugInfoP(esp_mail_str_65); - - if (MailClient.imapSendP(this, esp_mail_str_2, true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_capability; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_CHECK_CAPABILITIES_FAILED, false)) - return false; - - return true; -} - -bool IMAPSession::createFolder(const char *folderName) -{ - if (_debug) - { - MailClient.imapCB(this, "", false); - MailClient.debugInfoP(esp_mail_str_320); - } - - std::string cmd; - MailClient.appendP(cmd, esp_mail_str_322, true); - cmd += folderName; - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_create; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - return true; -} - -bool IMAPSession::deleteFolder(const char *folderName) -{ - if (_debug) - { - MailClient.imapCB(this, "", false); - MailClient.debugInfoP(esp_mail_str_321); - } - - std::string cmd; - MailClient.appendP(cmd, esp_mail_str_323, true); - cmd += folderName; - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_delete; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - return true; -} - -bool IMAPSession::deleteMessages(MessageList *toDelete, bool expunge) -{ - if (toDelete->_list.size() > 0) - { - - if (!selectFolder(_currentFolder.c_str(), false)) - return false; - - if (_debug) - { - MailClient.imapCB(this, "", false); - MailClient.debugInfoP(esp_mail_str_316); - } - - std::string cmd; - char *tmp = nullptr; - MailClient.appendP(cmd, esp_mail_str_249, true); - for (size_t i = 0; i < toDelete->_list.size(); i++) - { - if (i > 0) - MailClient.appendP(cmd, esp_mail_str_263, false); - tmp = MailClient.intStr(toDelete->_list[i]); - cmd += tmp; - MailClient.delS(tmp); - } - MailClient.appendP(cmd, esp_mail_str_315, false); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_store; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - if (expunge) - { - if (MailClient.imapSendP(this, esp_mail_str_317, true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_expunge; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - } - } - - return true; -} - -bool IMAPSession::copyMessages(MessageList *toCopy, const char *dest) -{ - if (toCopy->_list.size() > 0) - { - - if (!selectFolder(_currentFolder.c_str(), false)) - return false; - - if (_debug) - { - MailClient.imapCB(this, "", false); - std::string s; - MailClient.appendP(s, esp_mail_str_318, true); - s += dest; - esp_mail_debug(s.c_str()); - } - - std::string cmd; - char *tmp = nullptr; - MailClient.appendP(cmd, esp_mail_str_319, true); - for (size_t i = 0; i < toCopy->_list.size(); i++) - { - if (i > 0) - MailClient.appendP(cmd, esp_mail_str_263, false); - tmp = MailClient.intStr(toCopy->_list[i]); - cmd += tmp; - MailClient.delS(tmp); - } - MailClient.appendP(cmd, esp_mail_str_131, false); - cmd += dest; - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_store; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - } - - return true; -} - -#if defined(ESP8266) -void ESP_Mail_Client::setClock(float offset) -{ - if (WiFi.status() != WL_CONNECTED) - WiFi.reconnect(); - - time_t now = time(nullptr); - - _clockReady = now > ESP_MAIL_CLIENT_VALID_TS; - - if (!_clockReady) - { - char *server1 = strP(esp_mail_str_283); - char *server2 = strP(esp_mail_str_296); - - configTime(offset * 3600, 0, server1, server2); - - now = time(nullptr); - uint8_t attempts = 0; - while (now < ESP_MAIL_CLIENT_VALID_TS) - { - now = time(nullptr); - attempts++; - if (attempts > 200 || now > ESP_MAIL_CLIENT_VALID_TS) - break; - delay(100); - } - - delS(server1); - delS(server2); - } - - _clockReady = now > ESP_MAIL_CLIENT_VALID_TS; -} -#endif - -void IMAPSession::empty() -{ - std::string().swap(_nextUID); - clearMessageData(); -} - -void IMAPSession::clearMessageData() -{ - for (size_t i = 0; i < _headers.size(); i++) - { - _headers[i].part_headers.clear(); - std::vector().swap(_headers[i].part_headers); - } - std::vector().swap(_headers); - std::vector().swap(_msgNum); - _folders.clear(); - _mbif._flags.clear(); - _mbif._searchCount = 0; -} - -SMTPSession::SMTPSession() -{ -} - -SMTPSession::~SMTPSession() -{ - closeSession(); - _caCert.reset(); - _caCert = nullptr; -} - -bool SMTPSession::connect(ESP_Mail_Session *config) -{ - if (_tcpConnected) - MailClient.closeTCP(this); - - _sesson_cfg = config; - _caCert = nullptr; - - if (strlen(_sesson_cfg->certificate.cert_data) > 0) - _caCert = std::shared_ptr(_sesson_cfg->certificate.cert_data); - - if (strlen(_sesson_cfg->certificate.cert_file) > 0) - { - if (_sesson_cfg->certificate.cert_file_storage_type == esp_mail_file_storage_type::esp_mail_file_storage_type_sd && !MailClient._sdOk) - MailClient._sdOk = MailClient.sdTest(); - if (_sesson_cfg->certificate.cert_file_storage_type == esp_mail_file_storage_type::esp_mail_file_storage_type_flash && !MailClient._flashOk) -#if defined(ESP32) - MailClient._flashOk = ESP_MAIL_FLASH_FS.begin(FORMAT_FLASH); -#elif defined(ESP8266) - MailClient._flashOk = ESP_MAIL_FLASH_FS.begin(); -#endif - } - return MailClient.smtpAuth(this); -} - -void SMTPSession::debug(int level) -{ - if (level > esp_mail_debug_level_0) - { - if (level > esp_mail_debug_level_3) - level = esp_mail_debug_level_1; - _debugLevel = level; - _debug = true; - } - else - { - _debugLevel = esp_mail_debug_level_0; - _debug = false; - } -} - -String SMTPSession::errorReason() -{ - std::string ret; - - switch (_smtpStatus.statusCode) - { - case SMTP_STATUS_SERVER_CONNECT_FAILED: - MailClient.appendP(ret, esp_mail_str_38, true); - break; - case SMTP_STATUS_SMTP_GREETING_GET_RESPONSE_FAILED: - MailClient.appendP(ret, esp_mail_str_39, true); - break; - case SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED: - MailClient.appendP(ret, esp_mail_str_39, true); - break; - case SMTP_STATUS_AUTHEN_NOT_SUPPORT: - MailClient.appendP(ret, esp_mail_str_42, true); - break; - case SMTP_STATUS_AUTHEN_FAILED: - MailClient.appendP(ret, esp_mail_str_43, true); - break; - case SMTP_STATUS_USER_LOGIN_FAILED: - MailClient.appendP(ret, esp_mail_str_43, true); - break; - case SMTP_STATUS_PASSWORD_LOGIN_FAILED: - MailClient.appendP(ret, esp_mail_str_47, true); - break; - case SMTP_STATUS_SEND_HEADER_SENDER_FAILED: - MailClient.appendP(ret, esp_mail_str_48, true); - break; - case SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED: - MailClient.appendP(ret, esp_mail_str_222, true); - break; - case SMTP_STATUS_SEND_BODY_FAILED: - MailClient.appendP(ret, esp_mail_str_49, true); - break; - case MAIL_CLIENT_ERROR_CONNECTION_LOST: - MailClient.appendP(ret, esp_mail_str_221, true); - break; - case MAIL_CLIENT_ERROR_READ_TIMEOUT: - MailClient.appendP(ret, esp_mail_str_258, true); - break; - case MAIL_CLIENT_ERROR_FILE_IO_ERROR: - MailClient.appendP(ret, esp_mail_str_282, true); - break; - case SMTP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED: - MailClient.appendP(ret, esp_mail_str_293, true); - break; - case MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED: - MailClient.appendP(ret, esp_mail_str_305, true); - break; - case MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP: - MailClient.appendP(ret, esp_mail_str_132, true); - break; - case SMTP_STATUS_NO_VALID_RECIPIENTS_EXISTED: - MailClient.appendP(ret, esp_mail_str_206, true); - break; - case SMTP_STATUS_NO_VALID_SENDER_EXISTED: - MailClient.appendP(ret, esp_mail_str_205, true); - break; - case MAIL_CLIENT_ERROR_OUT_OF_MEMORY: - MailClient.appendP(ret, esp_mail_str_186, true); - break; - case SMTP_STATUS_NO_SUPPORTED_AUTH: - MailClient.appendP(ret, esp_mail_str_42, true); - break; - - default: - break; - } - - if (_smtpStatus.text.length() > 0 && ret.length() == 0) - { - MailClient.appendP(ret, esp_mail_str_312, true); - char *code = MailClient.intStr(_smtpStatus.respCode); - ret += code; - MailClient.delS(code); - MailClient.appendP(ret, esp_mail_str_313, false); - ret += _smtpStatus.text; - return ret.c_str(); - } - return ret.c_str(); -} - -bool SMTPSession::closeSession() -{ - if (!_tcpConnected) - return false; - - if (_sendCallback) - { - _cbData._sentSuccess = _sentSuccessCount; - _cbData._sentFailed = _sentFailedCount; - MailClient.smtpCB(this, ""); - MailClient.smtpCBP(this, esp_mail_str_128); - } - - if (_debug) - MailClient.debugInfoP(esp_mail_str_245); - - bool ret = true; - -/* Sign out */ -#if defined(ESP32) - /** - * The strange behavior in ESP8266 SSL client, BearSSLWiFiClientSecure - * The client disposed without memory released after the server close - * the connection due to QUIT command, which caused the memory leaks. - */ - MailClient.smtpSendP(this, esp_mail_str_7, true); - _smtp_cmd = esp_mail_smtp_cmd_logout; - ret = MailClient.handleSMTPResponse(this, esp_mail_smtp_status_code_221, SMTP_STATUS_SEND_BODY_FAILED); -#endif - - if (ret) - { - - if (_sendCallback) - { - MailClient.smtpCB(this, ""); - MailClient.smtpCBP(this, esp_mail_str_129, false); - } - - if (_debug) - MailClient.debugInfoP(esp_mail_str_246); - - if (_sendCallback) - MailClient.smtpCB(this, "", true); - } - - return MailClient.handleSMTPError(this, 0, ret); -} - -void SMTPSession::callback(smtpStatusCallback smtpCallback) -{ - _sendCallback = std::move(smtpCallback); -} - -IMAP_Status::IMAP_Status() -{ -} -IMAP_Status::~IMAP_Status() -{ - empty(); -} - -const char *IMAP_Status::info() -{ - return _info.c_str(); -} - -bool IMAP_Status::success() -{ - return _success; -} - -void IMAP_Status::empty() -{ - std::string().swap(_info); -} - -SMTP_Status::SMTP_Status() -{ -} - -SMTP_Status::~SMTP_Status() -{ - empty(); -} - -const char *SMTP_Status::info() -{ - return _info.c_str(); -} - -bool SMTP_Status::success() -{ - return _success; -} - -size_t SMTP_Status::completedCount() -{ - return _sentSuccess; -} - -size_t SMTP_Status::failedCount() -{ - return _sentFailed; -} - -void SMTP_Status::empty() -{ - std::string().swap(_info); -} - -ESP_Mail_Client MailClient = ESP_Mail_Client(); - -#endif /* ESP_Mail_Client_CPP */ diff --git a/lib/libesp32/lib_mail/src/ESP_Mail_Client.h b/lib/libesp32/lib_mail/src/ESP_Mail_Client.h deleted file mode 100644 index 88785170a7a6..000000000000 --- a/lib/libesp32/lib_mail/src/ESP_Mail_Client.h +++ /dev/null @@ -1,2820 +0,0 @@ -#ifndef ESP_Mail_Client_H -#define ESP_Mail_Client_H - -#define ESP_MAIL_VERSION "1.2.0" - -/** - * Mail Client Arduino Library for Espressif's ESP32 and ESP8266 - * - * Version: 1.2.0 - * Released: May 17, 2021 - * - * Updates: - * - Add support ESP8266 Core SDK v3.x.x. - * - * - * This library allows Espressif's ESP32 and ESP8266 devices to send and read - * Email - * through the SMTP and IMAP servers. - * - * The MIT License (MIT) - * Copyright (c) 2021 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of - * the Software, and to permit persons to whom the Software is furnished to do - * so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS - * OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include -#include "extras/RFC2047.h" -#include "extras/ESPTimeHelper.h" - -#if defined(ESP32) -#define FORMAT_FLASH FORMAT_FLASH_IF_MOUNT_FAILED -#include -#include -//#include -#include -#include "wcs/esp32/ESP_Mail_HTTPClient32.h" -#elif defined(ESP8266) -#include -#define FS_NO_GLOBALS -#include -#include "wcs/esp8266/ESP_Mail_HTTPClient.h" -#endif - -#include "extras/MIMEInfo.h" - -#include -#include -#include - -#if defined(ESP8266) -#define SD_CS_PIN 15 -#endif - -#define SMTP_STATUS_SERVER_CONNECT_FAILED -100 -#define SMTP_STATUS_SMTP_GREETING_GET_RESPONSE_FAILED -101 -#define SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED -102 -#define SMTP_STATUS_AUTHEN_NOT_SUPPORT -103 -#define SMTP_STATUS_AUTHEN_FAILED -104 -#define SMTP_STATUS_USER_LOGIN_FAILED -105 -#define SMTP_STATUS_PASSWORD_LOGIN_FAILED -106 -#define SMTP_STATUS_SEND_HEADER_SENDER_FAILED -107 -#define SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED -108 -#define SMTP_STATUS_SEND_BODY_FAILED -109 -#define SMTP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED -110 -#define SMTP_STATUS_NO_VALID_RECIPIENTS_EXISTED -111 -#define SMTP_STATUS_NO_VALID_SENDER_EXISTED -112 -#define SMTP_STATUS_NO_SUPPORTED_AUTH -113 - -#define IMAP_STATUS_SERVER_CONNECT_FAILED -200 -#define IMAP_STATUS_IMAP_RESPONSE_FAILED -201 -#define IMAP_STATUS_LOGIN_FAILED -202 -#define IMAP_STATUS_BAD_COMMAND -203 -#define IMAP_STATUS_PARSE_FLAG_FAILED -204 -#define IMAP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED -205 -#define IMAP_STATUS_NO_MESSAGE -206 -#define IMAP_STATUS_ERROR_DOWNLAD_TIMEOUT -207 -#define IMAP_STATUS_CLOSE_MAILBOX_FAILED -208 -#define IMAP_STATUS_OPEN_MAILBOX_FAILED -209 -#define IMAP_STATUS_LIST_MAILBOXS_FAILED -210 -#define IMAP_STATUS_CHECK_CAPABILITIES_FAILED -211 -#define IMAP_STATUS_NO_SUPPORTED_AUTH -212 -#define IMAP_STATUS_NO_MAILBOX_FOLDER_OPENED -213 - -#define MAIL_CLIENT_ERROR_CONNECTION_LOST -28 -#define MAIL_CLIENT_ERROR_READ_TIMEOUT -29 -#define MAIL_CLIENT_ERROR_FILE_IO_ERROR -30 -#define MAIL_CLIENT_ERROR_SERVER_CONNECTION_FAILED -31 -#define MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP -32 -#define MAIL_CLIENT_ERROR_OUT_OF_MEMORY -33 - -#define MAX_EMAIL_SEARCH_LIMIT 1000 -#define BASE64_CHUNKED_LEN 76 -#define FLOWED_TEXT_LEN 78 -#define ESP_MAIL_WIFI_RECONNECT_TIMEOUT 10000 -#define ESP_MAIL_PROGRESS_REPORT_STEP 20 -#define ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED 0 -#define ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE 256 -#define ESP_MAIL_CLIENT_VALID_TS 1577836800 - -#if defined(ESP32) -#define ESP_MAIL_MIN_MEM 70000 -#elif defined(ESP8266) -#define ESP_MAIL_MIN_MEM 4000 -#endif - -class IMAPSession; -class SMTPSession; -class SMTP_Status; -class DownloadProgress; -class MessageData; - -enum esp_mail_smtp_status_code -{ - esp_mail_smtp_status_code_0, // default - - /* Positive Completion */ - esp_mail_smtp_status_code_211 = 221, // System status, or system help reply - esp_mail_smtp_status_code_214 = - 214, // Help message(A response to the HELP command) - esp_mail_smtp_status_code_220 = 220, // Service ready - esp_mail_smtp_status_code_221 = - 221, // Service closing transmission channel [RFC 2034] - esp_mail_smtp_status_code_235 = - 235, // 2.7.0 Authentication succeeded[RFC 4954] - esp_mail_smtp_status_code_250 = 250, // Requested mail action okay, completed - esp_mail_smtp_status_code_251 = 251, // User not local; will forward - esp_mail_smtp_status_code_252 = 252, // Cannot verify the user, but it will - // try to deliver the message anyway - - /* Positive Intermediate */ - esp_mail_smtp_status_code_334 = 334, //(Server challenge - the text part - //contains the Base64 - encoded - //challenge)[RFC 4954] - esp_mail_smtp_status_code_354 = 354, // Start mail input - - /* Transient Negative Completion */ - /* "Transient Negative" means the error condition is temporary, and the action - may be requested again.*/ - esp_mail_smtp_status_code_421 = - 421, // Service is unavailable because the server is shutting down. - esp_mail_smtp_status_code_432 = - 432, // 4.7.12 A password transition is needed [RFC 4954] - esp_mail_smtp_status_code_450 = - 450, // Requested mail action not taken: mailbox unavailable (e.g., - // mailbox busy or temporarily blocked for policy reasons) - esp_mail_smtp_status_code_451 = - 451, // Requested action aborted : local error in processing - // e.g.IMAP server unavailable[RFC 4468] - esp_mail_smtp_status_code_452 = - 452, // Requested action not taken : insufficient system storage - esp_mail_smtp_status_code_454 = - 454, // 4.7.0 Temporary authentication failure[RFC 4954] - esp_mail_smtp_status_code_455 = - 455, // Server unable to accommodate parameters - - /* Permanent Negative Completion */ - esp_mail_smtp_status_code_500 = 500, // Syntax error, command unrecognized - // (This may include errors such as - // command line too long) - // e.g. Authentication Exchange line is too long [RFC 4954] - esp_mail_smtp_status_code_501 = - 501, // Syntax error in parameters or arguments - // e.g. 5.5.2 Cannot Base64-decode Client responses [RFC 4954] - // 5.7.0 Client initiated Authentication Exchange (only when the SASL - // mechanism specified that client does not begin the authentication exchange) - // [RFC 4954] - esp_mail_smtp_status_code_502 = 502, // Command not implemented - esp_mail_smtp_status_code_503 = 503, // Bad sequence of commands - esp_mail_smtp_status_code_504 = 504, // Command parameter is not implemented - // e.g. 5.5.4 Unrecognized authentication type [RFC 4954] - esp_mail_smtp_status_code_521 = 521, // Server does not accept mail [RFC 7504] - esp_mail_smtp_status_code_523 = 523, // Encryption Needed [RFC 5248] - esp_mail_smtp_status_code_530 = - 530, // 5.7.0 Authentication required [RFC 4954] - esp_mail_smtp_status_code_534 = - 534, // 5.7.9 Authentication mechanism is too weak [RFC 4954] - esp_mail_smtp_status_code_535 = - 535, // 5.7.8 Authentication credentials invalid [RFC 4954] - esp_mail_smtp_status_code_538 = 538, // 5.7.11 Encryption required for - // requested authentication mechanism[RFC - // 4954] - esp_mail_smtp_status_code_550 = - 550, // Requested action not taken: mailbox unavailable (e.g., mailbox not - // found, no access, or command rejected for policy reasons) - esp_mail_smtp_status_code_551 = - 551, // User not local; please try - esp_mail_smtp_status_code_552 = - 552, // Requested mail action aborted: exceeded storage allocation - esp_mail_smtp_status_code_553 = - 553, // Requested action not taken: mailbox name not allowed - esp_mail_smtp_status_code_554 = 554, // Transaction has failed (Or, in the - // case of a connection-opening response, - // "No SMTP service here") - // e.g. 5.3.4 Message too big for system [RFC 4468] - esp_mail_smtp_status_code_556 = 556, // Domain does not accept mail[RFC 7504] -}; - -enum esp_mail_smtp_port -{ - esp_mail_smtp_port_25 = 25, // PLAIN/TLS with STARTTLS - esp_mail_smtp_port_465 = 465, // SSL - esp_mail_smtp_port_587 = 587 // TLS with STARTTLS -}; - -enum esp_mail_imap_port -{ - esp_mail_imap_port_143 = 143, // PLAIN/TLS with STARTTLS - esp_mail_imap_port_993 = 993, // SSL -}; - -enum esp_mail_smtp_notify -{ - esp_mail_smtp_notify_never = 0, - esp_mail_smtp_notify_success = 1, - esp_mail_smtp_notify_failure = 2, - esp_mail_smtp_notify_delay = 4 -}; - -enum esp_mail_attach_type -{ - esp_mail_att_type_none, - esp_mail_att_type_attachment, - esp_mail_att_type_inline -}; - -enum esp_mail_message_type -{ - esp_mail_msg_type_none = 0, - esp_mail_msg_type_plain = 1, - esp_mail_msg_type_html = 2, - esp_mail_msg_type_enriched = 1 -}; - -enum esp_mail_auth_type -{ - esp_mail_auth_type_psw, - esp_mail_auth_type_oath2, - esp_mail_auth_type_token -}; - -enum esp_mail_imap_auth_mode -{ - esp_mail_imap_mode_examine, - esp_mail_imap_mode_select -}; - -enum esp_mail_imap_response_status -{ - esp_mail_imap_resp_unknown, - esp_mail_imap_resp_ok, - esp_mail_imap_resp_no, - esp_mail_imap_resp_bad -}; - -enum esp_mail_imap_header_state -{ - esp_mail_imap_state_from = 1, - esp_mail_imap_state_to, - esp_mail_imap_state_cc, - esp_mail_imap_state_subject, - esp_mail_imap_state_content_type, - esp_mail_imap_state_content_transfer_encoding, - esp_mail_imap_state_accept_language, - esp_mail_imap_state_content_language, - esp_mail_imap_state_date, - esp_mail_imap_state_msg_id, - esp_mail_imap_state_char_set, - esp_mail_imap_state_boundary -}; - -enum esp_mail_imap_command -{ - esp_mail_imap_cmd_capability, - esp_mail_imap_cmd_starttls, - esp_mail_imap_cmd_login, - esp_mail_imap_cmd_plain, - esp_mail_imap_cmd_auth, - esp_mail_imap_cmd_list, - esp_mail_imap_cmd_select, - esp_mail_imap_cmd_examine, - esp_mail_imap_cmd_close, - esp_mail_imap_cmd_status, - esp_mail_imap_cmd_search, - esp_mail_imap_cmd_fetch_body_header, - esp_mail_imap_cmd_fetch_body_mime, - esp_mail_imap_cmd_fetch_body_text, - esp_mail_imap_cmd_fetch_body_attachment, - esp_mail_imap_cmd_fetch_body_inline, - esp_mail_imap_cmd_logout, - esp_mail_imap_cmd_store, - esp_mail_imap_cmd_expunge, - esp_mail_imap_cmd_create, - esp_mail_imap_cmd_delete -}; - -enum esp_mail_imap_mime_fetch_type -{ - esp_mail_imap_mime_fetch_type_part, - esp_mail_imap_mime_fetch_type_sub_part1, - esp_mail_imap_mime_fetch_type_sub_part2 -}; - -enum esp_mail_smtp_command -{ - esp_mail_smtp_cmd_initial_state, - esp_mail_smtp_cmd_greeting, - esp_mail_smtp_cmd_start_tls, - esp_mail_smtp_cmd_login_user, - esp_mail_smtp_cmd_auth_plain, - esp_mail_smtp_cmd_auth, - esp_mail_smtp_cmd_login_psw, - esp_mail_smtp_cmd_send_header_sender, - esp_mail_smtp_cmd_send_header_recipient, - esp_mail_smtp_cmd_send_body, - esp_mail_smtp_cmd_chunk_termination, - esp_mail_smtp_cmd_logout -}; - -enum esp_mail_imap_header_type -{ - esp_mail_imap_header_from, - esp_mail_imap_header_to, - esp_mail_imap_header_cc, - esp_mail_imap_header_subject, - esp_mail_imap_header_date, - esp_mail_imap_header_msg_id, - esp_mail_imap_header_cont_lang, - esp_mail_imap_header_accept_lang -}; - -enum esp_mail_char_decoding_scheme -{ - esp_mail_char_decoding_scheme_default, - esp_mail_char_decoding_scheme_iso8859_1, - esp_mail_char_decoding_scheme_tis620 -}; - -enum esp_mail_smtp_priority -{ - esp_mail_smtp_priority_high = 1, - esp_mail_smtp_priority_normal = 3, - esp_mail_smtp_priority_low = 5, -}; - -enum esp_mail_smtp_embed_message_type -{ - esp_mail_smtp_embed_message_type_attachment = 0, - esp_mail_smtp_embed_message_type_inline -}; - -enum esp_mail_debug_level -{ - esp_mail_debug_level_0 = 0, - esp_mail_debug_level_1, - esp_mail_debug_level_2 = 222, - esp_mail_debug_level_3 = 333 -}; - -enum esp_mail_imap_multipart_sub_type -{ - esp_mail_imap_multipart_sub_type_none = 0, - esp_mail_imap_multipart_sub_type_mixed, - esp_mail_imap_multipart_sub_type_alternative, - esp_mail_imap_multipart_sub_type_parallel, - esp_mail_imap_multipart_sub_type_digest, - esp_mail_imap_multipart_sub_type_related, - esp_mail_imap_multipart_sub_type_report, -}; - -enum esp_mail_imap_message_sub_type -{ - esp_mail_imap_message_sub_type_none = 0, - esp_mail_imap_message_sub_type_rfc822, - esp_mail_imap_message_sub_type_delivery_status, - esp_mail_imap_message_sub_type_partial, - esp_mail_imap_message_sub_type_external_body, -}; - -/* descrete media types (rfc 2046) */ -struct esp_mail_imap_descrete_media_type_t -{ - /** textual information with subtypes - * "plain" - * "enriched" (rfc 1896 revised from richtext in rfc 1341) - * - * unrecognized subtypes and charset should be interpreted as - * application/octet-stream - * - * parameters: - * "charset" (rfc 2045) default is us-ascii - * for character set includes 8-bit characters - * and such characters are used in the body, Content-Transfer-Encoding - * header field and a corresponding encoding on the data are required - * - * ISO-8859-X where "X" is to be replaced, as - * necessary, for the parts of ISO-8859 [ISO-8859]. - */ - static constexpr const char *text = "text"; - - /** image data with subtypes (rfc 2048) - * "jpeg" - * "gif" - * - * unrecognized subtypes should be interpreted as application/octet-stream - */ - static constexpr const char *image = "image"; - - /** audio data with initial subtype - * "baic" -- for single channel audio encoded using 8bit ISDN mu-law [PCM] - * at a sample rate of 8000 Hz. - * - * Unrecognized subtypes of "audio" should at a miniumum be treated as - * "application/octet-stream" - */ - static constexpr const char *audio = "audio"; - - /** video data with initial subtype - * "mpeg" - * - * Unrecognized subtypes of "video" should at a minumum be treated as - * "application/octet-stream" - */ - static constexpr const char *video = "video"; - - /** some other kind of data, typically either - * uninterpreted binary data or information to be - * processed by an application with subtypes - * - * "octet-stream" -- uninterpreted binary data - * "PostScript" -- for the transport of PostScript material - * - * Other expected uses include spreadsheets, data for mail-based - * scheduling systems, and languages for "active" (computational) - * messaging, and word processing formats that are not directly readable. - * - * The octet-stream subtype parameters: - * TYPE, PADDING, NAME - */ - static constexpr const char *application = "application"; -}; - -/** composite media types (rfc 2046) - * - * As stated in the definition of the Content-Transfer-Encoding field - * [RFC 2045], no encoding other than "7bit", "8bit", or "binary" is - * permitted for entities of type "multipart". The "multipart" boundary - * delimiters and header fields are always represented as 7bit US-ASCII - * in any case (though the header fields may encode non-US-ASCII header - * text as per RFC 2047) and data within the body parts can be encoded - * on a part-by-part basis, with Content-Transfer-Encoding fields for - * each appropriate body part. -*/ -struct esp_mail_imap_composite_media_type_t -{ - /** data consisting of multiple entities of independent data types - * The Content-Type field for multipart entities requires one parameter, - * "boundary". - * The boundary delimiter line is then defined as a line - * consisting entirely of two hyphen characters ("-", decimal value 45) - * followed by the boundary parameter value from the Content-Type header - * field, optional linear whitespace, and a terminating CRLF. - * - * NOTE: The CRLF preceding the boundary delimiter line is conceptually - * attached to the boundary so that it is possible to have a part that - * does not end with a CRLF (line break). Body parts that must be - * considered to end with line breaks, therefore, must have two CRLFs - * preceding the boundary delimiter line, the first of which is part of - * the preceding body part, and the second of which is part of the - * encapsulation boundary. - * - * Boundary delimiters must not appear within the encapsulated material, - * and must be no longer than 70 characters, not counting the two - * leading hyphens. - * - * The boundary delimiter line following the last body part is a - * distinguished delimiter that indicates that no further body parts - * will follow. Such a delimiter line is identical to the previous - * delimiter lines, with the addition of two more hyphens after the - * boundary parameter value. - * - * See rfc2049 Appendix A for a Complex Multipart Example - */ - static constexpr const char *multipart = "multipart"; - - /* an encapsulated message */ - static constexpr const char *message = "message"; -}; - -struct esp_mail_imap_media_text_sub_type_t -{ - static constexpr const char *plain = "plain"; - static constexpr const char *enriched = "enriched"; - static constexpr const char *html = "html"; -}; - -/* multipart sub types */ -struct esp_mail_imap_multipart_sub_type_t -{ - /* a generic mixed set of parts */ - static constexpr const char *mixed = "mixed"; - - /* the same data in multiple formats */ - static constexpr const char *alternative = "alternative"; - - /* parts intended to be viewed simultaneously */ - static constexpr const char *parallel = "parallel"; - - /* multipart entities in which each part has a default type of - * "message/rfc822" */ - static constexpr const char *digest = "digest"; - - /* for compound objects consisting of several inter-related body parts (rfc - * 2387) */ - static constexpr const char *related = "related"; - - /* rfc 3462 */ - static constexpr const char *report = "report"; -}; - -/* message body sub types */ -struct esp_mail_imap_message_sub_type_t -{ - /* body contains an encapsulated message, with the syntax of an RFC 822 - * message. */ - static constexpr const char *rfc822 = "rfc822"; - - /* to allow large objects to be delivered as several separate pieces of mail - */ - static constexpr const char *Partial = "Partial"; - - /* the actual body data are not included, but merely referenced */ - static constexpr const char *External_Body = "External-Body"; - - static constexpr const char *delivery_status = "delivery-status"; -}; - -/** content disposition rfc 2183 - * - * Parameters: - * "filename", "creation-date","modification-date", - * "read-date", * "size" -*/ -struct esp_mail_imap_content_disposition_type_t -{ - /** if it is intended to be displayed automatically - * upon display of the message. - */ - static constexpr const char *inline_ = "inline"; - - /** to indicate that they are separate from the main body - * of the mail message, and that their display should not - * be automatic, but contingent upon some further action of the user. - */ - static constexpr const char *attachment = "attachment"; -}; - -struct esp_mail_internal_use_t -{ - bool binary = false; - std::string cid = ""; -}; - -struct esp_mail_content_transfer_encoding_t -{ - /* The default 7-bit transfer encoding for US-ACII characters*/ - static constexpr const char *enc_7bit = "7bit"; - - /* The quoted printable transfer encoding for non-US-ASCII characters*/ - static constexpr const char *enc_qp = "quoted-printable"; - - /* The base64 encoded transfer encoding */ - static constexpr const char *enc_base64 = "base64"; - - /* The 8-bit transfer encoding for extended-US-ASCII characters*/ - static constexpr const char *enc_8bit = "8bit"; - - /* The binary transfer encoding for extended-US-ASCII characters with no line - * length limit*/ - static constexpr const char *enc_binary = "binary"; -}; - -struct esp_mail_smtp_response_status_t -{ - int respCode = 0; - int statusCode = 0; - std::string text = ""; -}; - -struct esp_mail_imap_response_status_t -{ - int statusCode = 0; - std::string text = ""; -}; - -/* The option to embed this message content as a file */ -struct esp_mail_smtp_embed_message_body_t -{ - /* Enable to send this message body as file */ - bool enable = false; - - /* The name of embedded file */ - const char *filename = ""; - - /** The embedded type - * esp_mail_smtp_embed_message_type_attachment or 0 - * esp_mail_smtp_embed_message_type_inline or 1 - */ - esp_mail_smtp_embed_message_type type = - esp_mail_smtp_embed_message_type_attachment; -}; - -struct esp_mail_file_message_content_t -{ - /* The file path include its name */ - const char *name = ""; - - /** The type of file storages e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - esp_mail_file_storage_type type = esp_mail_file_storage_type_flash; -}; - -struct esp_mail_blob_message_content_t -{ - /* The array of content in flash memory */ - const uint8_t *data = nullptr; - - /* The array size in bytes */ - size_t size = 0; -}; - -/* The PLAIN text body details of the message */ -struct esp_mail_plain_body_t -{ - /* The option to embed this message content as a file */ - struct esp_mail_smtp_embed_message_body_t embed; - - /* The PLAIN text content of the message */ - const char *content = ""; - - /* The blob that contins PLAIN text content of the message */ - struct esp_mail_blob_message_content_t blob; - - /* The file that contins PLAIN text content of the message */ - struct esp_mail_file_message_content_t file; - - /* The charset of the PLAIN text content of the message */ - const char *charSet = "UTF-8"; - - /* The content type of message */ - const char *content_type = "text/plain"; - - /* The option to encode the content for data transfer */ - const char *transfer_encoding = "7bit"; - - /* The option to send the PLAIN text with wrapping */ - bool flowed = false; - - /* The internal usage data */ - struct esp_mail_internal_use_t _int; -}; - -struct esp_mail_html_body_t -{ - /* The option to embedded the content as a file */ - struct esp_mail_smtp_embed_message_body_t embed; - - /* The HTML content of the message */ - const char *content = ""; - - /* The blob that contins HTML content of the message */ - struct esp_mail_blob_message_content_t blob; - - /* The file that contins HTML content of the message */ - struct esp_mail_file_message_content_t file; - - /* The charset of the HTML content of the message */ - const char *charSet = "UTF-8"; - - /* The content type of message */ - const char *content_type = "text/html"; - - /* The option to encode the content for data transfer */ - const char *transfer_encoding = "7bit"; - - /* The internal usage data */ - struct esp_mail_internal_use_t _int; -}; - -struct esp_mail_link_internal_t -{ - std::string cid = ""; -}; - -struct esp_mail_email_info_t -{ - /* The name of Email author*/ - const char *name = ""; - - /* The Email address */ - const char *email = ""; -}; -struct esp_mail_smtp_msg_response_t -{ - /* The author Email address to reply */ - const char *reply_to = ""; - - /* The sender Email address to return the message */ - const char *return_path = ""; - - /** The Delivery Status Notifications e.g. esp_mail_smtp_notify_never, - * esp_mail_smtp_notify_success, - * esp_mail_smtp_notify_failure, and - * esp_mail_smtp_notify_delay - */ - int notify = esp_mail_smtp_notify::esp_mail_smtp_notify_never; -}; - -struct esp_mail_smtp_enable_option_t -{ - /* Enable chunk data sending for large message */ - bool chunking = false; -}; - -struct esp_mail_attach_blob_t -{ - /* BLOB data (flash or ram) */ - const uint8_t *data = nullptr; - - /* BLOB data size in byte */ - size_t size = 0; -}; - -struct esp_mail_attach_file_t -{ - const char *path = ""; - /** The file storage type e.g. esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - esp_mail_file_storage_type storage_type = esp_mail_file_storage_type_none; -}; - -struct esp_mail_attach_descr_t -{ - /* The name of attachment */ - const char *name = ""; - - /* The attachment file name */ - const char *filename = ""; - - /* The MIME type of attachment */ - const char *mime = ""; - - /* The transfer encoding of attachment e.g. base64 */ - const char *transfer_encoding = "base64"; - - /* The content encoding of attachment e.g. base64 */ - const char *content_encoding = ""; - - /* The content id of attachment file */ - const char *content_id = ""; -}; - -struct esp_mail_attach_internal_t -{ - esp_mail_attach_type att_type = esp_mail_att_type_attachment; - int index = 0; - int msg_uid = 0; - bool flash_blob = false; - bool binary = false; - bool parallel = false; - std::string cid = ""; -}; - -struct esp_mail_attachment_t -{ - /* The attachment description */ - struct esp_mail_attach_descr_t descr; - - /* The BLOB data config */ - struct esp_mail_attach_blob_t blob; - - /* The file data config */ - struct esp_mail_attach_file_t file; - - /* reserved for internal usage */ - struct esp_mail_attach_internal_t _int; -}; - -struct esp_mail_smtp_recipient_t -{ - /* The recipient's name */ - const char *name = ""; - - /* The recipient's Email address */ - const char *email = ""; -}; - -struct esp_mail_smtp_recipient_address_t -{ - /* The recipient's Email address */ - const char *email = ""; -}; - -struct esp_mail_smtp_send_status_t -{ - /* The status of the message */ - bool completed = false; - - /* The primary recipient mailbox of the message */ - const char *recipients = ""; - - /* The topic of the message */ - const char *subject = ""; - - /* The timestamp of the message */ - time_t timesstamp = 0; -}; - -struct esp_mail_attacment_info_t -{ - const char *filename = ""; - const char *name = ""; - const char *creationDate = ""; - const char *mime = ""; - esp_mail_attach_type type = esp_mail_att_type_none; - size_t size; -}; - -struct esp_mail_auth_capability_t -{ - bool plain = false; - bool xoauth2 = false; - bool cram_md5 = false; - bool digest_md5 = false; - bool login = false; - bool start_tls = false; -}; - -struct esp_mail_smtp_capability_t -{ - bool esmtp = false; - bool binaryMIME = false; - bool _8bitMIME = false; - bool chunking = false; - bool utf8 = false; - bool pipelining = false; - bool dsn = false; -}; - -struct esp_mail_imap_rfc822_msg_header_item_t -{ - std::string sender = ""; - std::string from; - std::string subject = ""; - std::string messageID = ""; - std::string keyword = ""; - std::string comment = ""; - std::string date = ""; - std::string return_path = ""; - std::string reply_to; - std::string to = ""; - std::string cc = ""; - std::string bcc = ""; -}; - -struct esp_mail_message_part_info_t -{ - int octetLen = 0; - int attach_data_size = 0; - int textLen = 0; - bool sizeProp = false; - int nestedLevel = 0; - std::string partNumStr = ""; - std::string partNumFetchStr = ""; - std::string text = ""; - std::string filename = ""; - std::string type = ""; - std::string save_path = ""; - std::string name = ""; - std::string content_disposition = ""; - std::string content_type = ""; - std::string descr = ""; - std::string content_transfer_encoding = ""; - std::string creation_date = ""; - std::string modification_date = ""; - std::string charset = ""; - std::string download_error = ""; - esp_mail_attach_type attach_type = esp_mail_att_type_none; - esp_mail_message_type msg_type = esp_mail_msg_type_none; - bool file_open_write = false; - bool multipart = false; - esp_mail_imap_multipart_sub_type multipart_sub_type = - esp_mail_imap_multipart_sub_type_none; - esp_mail_imap_message_sub_type message_sub_type = - esp_mail_imap_message_sub_type_none; - bool rfc822_part = false; - int rfc822_msg_Idx = 0; - struct esp_mail_imap_rfc822_msg_header_item_t rfc822_header; - bool error = false; - bool plain_flowed = false; - bool plain_delsp = false; -}; - -struct esp_mail_message_header_t -{ - int header_data_len = 0; - std::string from = ""; - std::string to = ""; - std::string cc = ""; - std::string subject = ""; - std::string content_type = ""; - std::string content_transfer_encoding = ""; - std::string date = ""; - std::string message_id = ""; - std::string message_uid = ""; - std::string message_no = ""; - std::string boundary = ""; - std::string accept_language = ""; - std::string content_language = ""; - std::string char_set = ""; - bool multipart = false; - bool rfc822_part = false; - int rfc822Idx = 0; - std::string partNumStr = ""; - - esp_mail_imap_multipart_sub_type multipart_sub_type = - esp_mail_imap_multipart_sub_type_none; - esp_mail_imap_message_sub_type message_sub_type = - esp_mail_imap_message_sub_type_none; - std::string from_charset = ""; - std::string to_charset = ""; - std::string cc_charset = ""; - std::string subject_charset = ""; - std::string msgID = ""; - std::string error_msg = ""; - bool error = false; - std::vector part_headers = - std::vector(); - int attachment_count = 0; - int total_download_size = 0; - int downloaded_size = 0; - int total_attach_data_size = 0; - int downloaded_bytes = 0; - int message_data_count = 0; -}; - -/* Internal use */ -struct esp_mail_folder_info_t -{ - std::string name = ""; - std::string attributes = ""; - std::string delimiter = ""; -}; - -struct esp_mail_folder_info_item_t -{ - /* The name of folder */ - const char *name = ""; - - /* The attributes of folder */ - const char *attributes = ""; - - /* The delimeter of folder */ - const char *delimiter = ""; -}; - -struct esp_mail_sesson_cert_config_t -{ - /* The certificate data (base64 data) */ - const char *cert_data = ""; - - /* The certificate file (DER format) */ - const char *cert_file = ""; - - /* The storage type */ - esp_mail_file_storage_type cert_file_storage_type; -}; - -struct esp_mail_sesson_sever_config_t -{ - /* The hostName of the server */ - const char *host_name = ""; - /* The port on the server to connect to */ - uint16_t port = 0; -}; - -/* The log in credentials */ -struct esp_mail_sesson_login_config_t -{ - /* The user Email address to log in */ - const char *email = ""; - - /* The user password to log in */ - const char *password = ""; - - /* The OAuth2.0 access token to log in */ - const char *accessToken = ""; - - /* The user domain or ip of client */ - const char *user_domain = ""; -}; - -struct esp_mail_sesson_secure_config_t -{ - /* The option to send the command to start the TLS connection */ - bool startTLS = false; -}; - -struct esp_mail_session_config_t -{ - /* The server config */ - struct esp_mail_sesson_sever_config_t server; - - /* The log in config */ - struct esp_mail_sesson_login_config_t login; - - /* The secure config */ - struct esp_mail_sesson_secure_config_t secure; - - /* The certificate config */ - struct esp_mail_sesson_cert_config_t certificate; -}; - -struct esp_mail_imap_download_config_t -{ - /* To download the PLAIN text content of the message */ - bool text = false; - - /* To download the HTML content of the message */ - bool html = false; - - /* To download the attachments of the message */ - bool attachment = false; - - /* To download the inline image of the message */ - bool inlineImg = false; - - /* To download the rfc822 mesages in the message */ - bool rfc822 = false; - - /* To download the message header */ - bool header = false; -}; - -struct esp_mail_imap_enable_config_t -{ - /* To store the PLAIN text of the message in the IMAPSession */ - bool text = false; - - /* To store the HTML of the message in the IMAPSession */ - bool html = false; - - /* To store the rfc822 messages in the IMAPSession */ - bool rfc822 = false; - - /* To enable the download status via the serial port */ - bool download_status = false; - - /* To sort the message UID of the search result in descending order */ - bool recent_sort = false; -}; - -struct esp_mail_imap_limit_config_t -{ - /* The maximum messages from the search result */ - size_t search = 10; - - /** The maximum size of the memory buffer to store the message content. - * This is only limit for data to be stored in the IMAPSession. - */ - size_t msg_size = 1024; - - /* The maximum size of each attachment to download */ - size_t attachment_size = 1024 * 1024 * 5; -}; - -struct esp_mail_imap_storage_config_t -{ - /* The path to save the downloaded file */ - const char *saved_path = "/"; - - /** The type of file storages e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - esp_mail_file_storage_type type = esp_mail_file_storage_type_flash; -}; - -struct esp_mail_imap_search_config_t -{ - /* The search criteria */ - const char *criteria = ""; - - /* The option to search the unseen message */ - bool unseen_msg = false; -}; - -struct esp_mail_imap_fetch_config_t -{ - /* The UID of message to fetch */ - const char *uid = ""; - - /* Set the message flag as seen */ - bool set_seen = false; -}; - -struct esp_mail_imap_read_config_t -{ - /* The config for fetching */ - struct esp_mail_imap_fetch_config_t fetch; - - /* The config for search */ - struct esp_mail_imap_search_config_t search; - - /* The config about the limits */ - struct esp_mail_imap_limit_config_t limit; - - /* The config to enable the features */ - struct esp_mail_imap_enable_config_t enable; - - /* The config about downloads */ - struct esp_mail_imap_download_config_t download; - - /* The config about the storage and path to save the downloaded file */ - struct esp_mail_imap_storage_config_t storage; -}; - -/* Mail and MIME Header Fields */ -struct esp_mail_imap_msg_item_t -{ - /* The message number */ - const char *msgNo = ""; - - /* The message UID */ - const char *UID = ""; - - /* The message identifier (RFC 4021) */ - const char *ID = ""; - - /* The language(s) for auto-responses (RFC 4021) */ - const char *acceptLang = ""; - - /* The language of message content (RFC 4021) */ - const char *contentLang = ""; - - /* The mailbox of message author (RFC 4021) */ - const char *from = ""; - - /* The charset of the mailbox of message author */ - const char *fromCharset = ""; - - /* The primary recipient mailbox (RFC 4021) */ - const char *to = ""; - - /* The charset of the primary recipient mailbox */ - const char *toCharset = ""; - - /* The Carbon-copy recipient mailboxes (RFC 4021) */ - const char *cc = ""; - - /* The charset of the Carbon-copy recipient mailbox header */ - const char *ccCharset = ""; - - /* The message date and time (RFC 4021) */ - const char *date = ""; - - /* The topic of message (RFC 4021) */ - const char *subject = ""; - - /* The topic of message charset */ - const char *subjectCharset = ""; - - /* The PLAIN text content of the message */ - struct esp_mail_plain_body_t text; - - /* The HTML content of the message */ - struct esp_mail_html_body_t html; - - /* rfc822 related */ - - /* The sender Email */ - const char *sender; - - /* The message identifier */ - const char *messageID = ""; - - /* The keywords or phrases, separated by commas */ - const char *keyword = ""; - - /* The comment about message */ - const char *comment = ""; - - /* The return recipient of the message */ - const char *return_path = ""; - - /* The Email address to reply */ - const char *reply_to; - - /* The Blind carbon-copy recipients */ - const char *bcc = ""; - - /* The error description from fetching the message */ - const char *fetchError = ""; - - /* The info about the attachments in the message */ - std::vector attachments = - std::vector(); - - /* The info about the rfc822 messages included in the message */ - std::vector rfc822 = - std::vector(); -}; - -struct esp_mail_imap_msg_list_t -{ - /* The info of a message */ - std::vector msgItems = - std::vector(); -}; - -struct esp_mail_smtp_msg_type_t -{ - bool rfc822 = false; - int rfc822Idx = 0; -}; -struct esp_mail_imap_multipart_level_t -{ - uint8_t level = 0; - bool fetch_rfc822_header = false; - bool append_body_text = false; -}; - -/** The content transfer encoding - * enc_7bit or "7bit" - * enc_qp or "quoted-printable" - * enc_base64 or "base64" - * enc_binary or "binary" - * enc_8bit or "8bit" -*/ -typedef struct esp_mail_content_transfer_encoding_t Content_Transfer_Encoding; - -/* The result from sending the Email */ -typedef struct esp_mail_smtp_send_status_t SMTP_Result; - -/* The attachment item details for a message which returned from fetching the - * Email */ -typedef struct esp_mail_attacment_info_t IMAP_Attach_Item; - -/* The attachment details for sending the Email */ -typedef struct esp_mail_attachment_t SMTP_Attachment; - -/* The info of the selected or open mailbox folder e.g. name, attributes and - * delimiter */ -typedef struct esp_mail_folder_info_item_t FolderInfo; - -/* The session configuations */ -typedef struct esp_mail_session_config_t ESP_Mail_Session; - -/** The IMAP operation configuations */ -typedef struct esp_mail_imap_read_config_t IMAP_Config; - -/* The message item data of the IMAP_MSG_List which contains header, body and - * attachments info for eacch message*/ -typedef struct esp_mail_imap_msg_item_t IMAP_MSG_Item; - -/* The list that contains the message items from searching or fetching the Email - */ -typedef struct esp_mail_imap_msg_list_t IMAP_MSG_List; - -static const char esp_mail_str_1[] PROGMEM = - "Content-Type: multipart/mixed; boundary=\""; -static const char esp_mail_str_2[] PROGMEM = "$ CAPABILITY"; -static const char esp_mail_str_3[] PROGMEM = "Mime-Version: 1.0\r\n"; -static const char esp_mail_str_4[] PROGMEM = "AUTH LOGIN"; -static const char esp_mail_str_5[] PROGMEM = "HELO "; -static const char esp_mail_str_6[] PROGMEM = "EHLO "; -static const char esp_mail_str_7[] PROGMEM = "QUIT"; -static const char esp_mail_str_8[] PROGMEM = "MAIL FROM:"; -static const char esp_mail_str_9[] PROGMEM = "RCPT TO:"; -static const char esp_mail_str_10[] PROGMEM = "From: "; -static const char esp_mail_str_11[] PROGMEM = "To: "; -static const char esp_mail_str_12[] PROGMEM = "Cc: "; -static const char esp_mail_str_13[] PROGMEM = ",<"; -static const char esp_mail_str_14[] PROGMEM = "<"; -static const char esp_mail_str_15[] PROGMEM = ">"; -static const char esp_mail_str_16[] PROGMEM = "DATA"; -static const char esp_mail_str_17[] PROGMEM = "X-Priority: "; -static const char esp_mail_str_18[] PROGMEM = "X-MSMail-Priority: High\r\n"; -static const char esp_mail_str_19[] PROGMEM = "X-MSMail-Priority: Normal\r\n"; -static const char esp_mail_str_20[] PROGMEM = "X-MSMail-Priority: Low\r\n"; -static const char esp_mail_str_21[] PROGMEM = "Importance: High\r\n"; -static const char esp_mail_str_22[] PROGMEM = "Importance: Normal\r\n"; -static const char esp_mail_str_23[] PROGMEM = "Importance: Low\r\n"; -static const char esp_mail_str_24[] PROGMEM = "Subject: "; -static const char esp_mail_str_25[] PROGMEM = "Content-Type: "; -static const char esp_mail_str_26[] PROGMEM = "; Name=\""; -static const char esp_mail_str_27[] PROGMEM = "$"; -static const char esp_mail_str_28[] PROGMEM = - "Content-Type: multipart/parallel; boundary=\""; -static const char esp_mail_str_29[] PROGMEM = "7bit"; -static const char esp_mail_str_30[] PROGMEM = - "Content-Disposition: attachment; filename=\""; -static const char esp_mail_str_31[] PROGMEM = "base64"; -static const char esp_mail_str_32[] PROGMEM = "application/octet-stream"; -static const char esp_mail_str_33[] PROGMEM = "--"; -static const char esp_mail_str_34[] PROGMEM = "\r\n"; -static const char esp_mail_str_35[] PROGMEM = "\"\r\n\r\n"; -static const char esp_mail_str_36[] PROGMEM = "\"\r\n"; -static const char esp_mail_str_37[] PROGMEM = "\r\n.\r\n"; -static const char esp_mail_str_38[] PROGMEM = "unable to connect to server"; -static const char esp_mail_str_39[] PROGMEM = "SMTP server greeting failed"; -static const char esp_mail_str_40[] PROGMEM = ".dat"; -static const char esp_mail_str_41[] PROGMEM = "$ AUTHENTICATE PLAIN "; -static const char esp_mail_str_42[] PROGMEM = - "the provided SASL authentication mechanism is not support"; -static const char esp_mail_str_43[] PROGMEM = "authentication failed"; -static const char esp_mail_str_44[] PROGMEM = "mydomain.com"; -static const char esp_mail_str_45[] PROGMEM = "AUTH PLAIN"; -static const char esp_mail_str_46[] PROGMEM = "Return-Path: "; -static const char esp_mail_str_47[] PROGMEM = "login password is not valid"; -static const char esp_mail_str_48[] PROGMEM = "send header failed"; -static const char esp_mail_str_49[] PROGMEM = "send body failed"; -static const char esp_mail_str_50[] PROGMEM = "Connecting to IMAP server..."; -static const char esp_mail_str_51[] PROGMEM = - ".HEADER.FIELDS (SUBJECT FROM SENDER RETURN-PATH TO REPLY-TO DATE CC " - "Message-ID COMMENT KEYWORD content-type Content-transfer-encoding)]"; -static const char esp_mail_str_52[] PROGMEM = "failed"; -static const char esp_mail_str_53[] PROGMEM = "Error, "; -static const char esp_mail_str_54[] PROGMEM = "IMAP server connected"; -static const char esp_mail_str_55[] PROGMEM = "> C: download attachment"; -static const char esp_mail_str_56[] PROGMEM = "Logging in..."; -static const char esp_mail_str_57[] PROGMEM = "Downloading messages..."; -static const char esp_mail_str_58[] PROGMEM = - "Reading the list of mailboxes..."; -static const char esp_mail_str_59[] PROGMEM = - "> C: download plain TEXT message"; -static const char esp_mail_str_60[] PROGMEM = "> C: download HTML message"; -static const char esp_mail_str_61[] PROGMEM = "Selecting the "; -static const char esp_mail_str_62[] PROGMEM = "fail to list the mailboxes"; -static const char esp_mail_str_63[] PROGMEM = "fail to check the capabilities"; -static const char esp_mail_str_64[] PROGMEM = "Check the capability..."; -static const char esp_mail_str_65[] PROGMEM = "> C: check the capability"; -static const char esp_mail_str_66[] PROGMEM = "Searching messages..."; -static const char esp_mail_str_67[] PROGMEM = "message"; -static const char esp_mail_str_68[] PROGMEM = "Search limit:"; -static const char esp_mail_str_69[] PROGMEM = "Found "; -static const char esp_mail_str_70[] PROGMEM = " messages"; -static const char esp_mail_str_71[] PROGMEM = "Show "; -static const char esp_mail_str_72[] PROGMEM = - "No message found for search criteria"; -static const char esp_mail_str_73[] PROGMEM = - "Search criteria does not set, fetch the recent message"; -static const char esp_mail_str_74[] PROGMEM = "Fetching message "; -static const char esp_mail_str_75[] PROGMEM = ", UID: "; -static const char esp_mail_str_76[] PROGMEM = ", Number: "; -static const char esp_mail_str_77[] PROGMEM = "> C: fetch message header"; -static const char esp_mail_str_78[] PROGMEM = "Attachments ("; -static const char esp_mail_str_79[] PROGMEM = ")"; -static const char esp_mail_str_80[] PROGMEM = "Downloading attachments..."; -static const char esp_mail_str_81[] PROGMEM = "> C: fetch body part header, "; -static const char esp_mail_str_82[] PROGMEM = "rfc822"; -static const char esp_mail_str_83[] PROGMEM = "reading"; -static const char esp_mail_str_84[] PROGMEM = "Free Heap: "; -static const char esp_mail_str_85[] PROGMEM = "Logging out..."; -static const char esp_mail_str_86[] PROGMEM = - "> C: fetch body sub part header, "; -static const char esp_mail_str_87[] PROGMEM = "Finished reading Email"; -static const char esp_mail_str_88[] PROGMEM = "> C: finished reading Email"; -static const char esp_mail_str_89[] PROGMEM = "SD card mount failed"; -static const char esp_mail_str_90[] PROGMEM = "download"; -static const char esp_mail_str_91[] PROGMEM = ", "; -static const char esp_mail_str_92[] PROGMEM = "%"; -static const char esp_mail_str_93[] PROGMEM = "connection timeout"; -static const char esp_mail_str_94[] PROGMEM = ".html"; -static const char esp_mail_str_95[] PROGMEM = ".txt"; -static const char esp_mail_str_96[] PROGMEM = " folder..."; -static const char esp_mail_str_97[] PROGMEM = ";"; -static const char esp_mail_str_98[] PROGMEM = - "Content-Disposition: attachment\r\n"; -static const char esp_mail_str_99[] PROGMEM = "Date: "; -static const char esp_mail_str_100[] PROGMEM = "Messsage UID: "; -static const char esp_mail_str_101[] PROGMEM = "Messsage ID: "; -static const char esp_mail_str_102[] PROGMEM = "Accept Language: "; -static const char esp_mail_str_103[] PROGMEM = "Content Language: "; -static const char esp_mail_str_104[] PROGMEM = " BODY=BINARYMIME"; -static const char esp_mail_str_105[] PROGMEM = "From Charset: "; -static const char esp_mail_str_106[] PROGMEM = "BDAT "; -static const char esp_mail_str_107[] PROGMEM = "To Charset: "; -static const char esp_mail_str_108[] PROGMEM = "CC: "; -static const char esp_mail_str_109[] PROGMEM = "CC Charset: "; -static const char esp_mail_str_110[] PROGMEM = "delsp=\"no\""; -static const char esp_mail_str_111[] PROGMEM = "Subject Charset: "; -static const char esp_mail_str_112[] PROGMEM = "Message Charset: "; -static const char esp_mail_str_113[] PROGMEM = "Attachment: "; -static const char esp_mail_str_114[] PROGMEM = "File Index: "; -static const char esp_mail_str_115[] PROGMEM = "Filename: "; -static const char esp_mail_str_116[] PROGMEM = "Name: "; -static const char esp_mail_str_117[] PROGMEM = "Size: "; -static const char esp_mail_str_118[] PROGMEM = "Type: "; -static const char esp_mail_str_119[] PROGMEM = "Creation Date: "; -static const char esp_mail_str_120[] PROGMEM = "Connecting to SMTP server..."; -static const char esp_mail_str_121[] PROGMEM = - "SMTP server connected, wait for greeting..."; -static const char esp_mail_str_122[] PROGMEM = "Sending greeting response..."; -static const char esp_mail_str_123[] PROGMEM = "message/rfc822"; -static const char esp_mail_str_124[] PROGMEM = - "Saving message header to file..."; -static const char esp_mail_str_125[] PROGMEM = "Sending message header..."; -static const char esp_mail_str_126[] PROGMEM = "Sending message body..."; -static const char esp_mail_str_127[] PROGMEM = "Sending attachments..."; -static const char esp_mail_str_128[] PROGMEM = "Closing the session..."; -static const char esp_mail_str_129[] PROGMEM = "Message sent successfully"; -static const char esp_mail_str_130[] PROGMEM = "$ LOGIN "; -static const char esp_mail_str_131[] PROGMEM = " "; -static const char esp_mail_str_132[] PROGMEM = - "fail to set up the SSL/TLS structure"; -static const char esp_mail_str_133[] PROGMEM = "$ LIST \"\" *"; -static const char esp_mail_str_134[] PROGMEM = "Comment: "; -static const char esp_mail_str_135[] PROGMEM = "$ EXAMINE \""; -static const char esp_mail_str_136[] PROGMEM = "\""; -static const char esp_mail_str_137[] PROGMEM = "UID "; -static const char esp_mail_str_138[] PROGMEM = " UID"; -static const char esp_mail_str_139[] PROGMEM = " SEARCH"; -static const char esp_mail_str_140[] PROGMEM = "UID"; -static const char esp_mail_str_141[] PROGMEM = "SEARCH"; -static const char esp_mail_str_142[] PROGMEM = "$ UID FETCH "; -static const char esp_mail_str_143[] PROGMEM = "$ FETCH "; -static const char esp_mail_str_144[] PROGMEM = - "HEADER.FIELDS (SUBJECT FROM TO DATE CC Message-ID Accept-Language " - "content-type Content-transfer-encoding Content-Language)"; -static const char esp_mail_str_145[] PROGMEM = "Keyword: "; -static const char esp_mail_str_146[] PROGMEM = "$ LOGOUT"; -static const char esp_mail_str_147[] PROGMEM = " BODY"; -static const char esp_mail_str_148[] PROGMEM = ".MIME]"; -static const char esp_mail_str_149[] PROGMEM = "Bcc: "; -static const char esp_mail_str_150[] PROGMEM = "Sender: "; -static const char esp_mail_str_151[] PROGMEM = "no mailbox opened"; -static const char esp_mail_str_152[] PROGMEM = "."; -static const char esp_mail_str_153[] PROGMEM = "No mailbox opened"; -static const char esp_mail_str_154[] PROGMEM = "Remove FLAG"; -static const char esp_mail_str_155[] PROGMEM = "Add FLAG"; -static const char esp_mail_str_156[] PROGMEM = "]"; -static const char esp_mail_str_157[] PROGMEM = "Set FLAG"; -static const char esp_mail_str_158[] PROGMEM = - "file does not exist or can't access"; -static const char esp_mail_str_159[] PROGMEM = "msg.html"; -static const char esp_mail_str_160[] PROGMEM = "upload "; -static const char esp_mail_str_161[] PROGMEM = "/msg"; -static const char esp_mail_str_163[] PROGMEM = "/rfc822_msg"; -static const char esp_mail_str_164[] PROGMEM = "msg.txt"; -static const char esp_mail_str_165[] PROGMEM = "Content-Length: "; -static const char esp_mail_str_166[] PROGMEM = "binary"; -static const char esp_mail_str_167[] PROGMEM = "Sending inline data..."; -static const char esp_mail_str_168[] PROGMEM = "charset=\""; -static const char esp_mail_str_169[] PROGMEM = "charset="; -static const char esp_mail_str_170[] PROGMEM = "name=\""; -static const char esp_mail_str_171[] PROGMEM = "name="; -static const char esp_mail_str_172[] PROGMEM = "content-transfer-encoding: "; -static const char esp_mail_str_173[] PROGMEM = " LAST"; -static const char esp_mail_str_174[] PROGMEM = "content-description: "; -static const char esp_mail_str_175[] PROGMEM = "content-disposition: "; -static const char esp_mail_str_176[] PROGMEM = "filename=\""; -static const char esp_mail_str_177[] PROGMEM = "filename="; -static const char esp_mail_str_178[] PROGMEM = "size="; -static const char esp_mail_str_179[] PROGMEM = "creation-date=\""; -static const char esp_mail_str_180[] PROGMEM = "creation-date="; -static const char esp_mail_str_181[] PROGMEM = "modification-date=\""; -static const char esp_mail_str_182[] PROGMEM = "modification-date="; -static const char esp_mail_str_183[] PROGMEM = "*"; -static const char esp_mail_str_184[] PROGMEM = "Reply-To: "; -static const char esp_mail_str_185[] PROGMEM = "> E: "; -static const char esp_mail_str_186[] PROGMEM = "out of memory"; -static const char esp_mail_str_187[] PROGMEM = "Message fetch cmpleted"; -static const char esp_mail_str_188[] PROGMEM = "fail to close the mailbox"; -static const char esp_mail_str_189[] PROGMEM = "message-id: "; -static const char esp_mail_str_190[] PROGMEM = "accept-language: "; -static const char esp_mail_str_191[] PROGMEM = "content-language: "; -static const char esp_mail_str_192[] PROGMEM = ")"; -static const char esp_mail_str_193[] PROGMEM = "{"; -static const char esp_mail_str_194[] PROGMEM = "}"; -static const char esp_mail_str_195[] PROGMEM = "$ CLOSE\r\n"; -static const char esp_mail_str_196[] PROGMEM = "> C: send STARTTLS command"; -static const char esp_mail_str_197[] PROGMEM = "> C: close the mailbox folder"; -static const char esp_mail_str_198[] PROGMEM = "("; -static const char esp_mail_str_199[] PROGMEM = " EXISTS"; -static const char esp_mail_str_200[] PROGMEM = " [UIDNEXT "; -static const char esp_mail_str_201[] PROGMEM = "port > "; -static const char esp_mail_str_202[] PROGMEM = "/"; -static const char esp_mail_str_203[] PROGMEM = "/header.txt"; -static const char esp_mail_str_204[] PROGMEM = "/esp.32"; -static const char esp_mail_str_205[] PROGMEM = - "sender Email address is not valid"; -static const char esp_mail_str_206[] PROGMEM = - "some of the recipient Email address is not valid"; -static const char esp_mail_str_207[] PROGMEM = "> C: send Email"; -static const char esp_mail_str_208[] PROGMEM = "Sending Email..."; -static const char esp_mail_str_209[] PROGMEM = "Send command, STARTTLS"; -static const char esp_mail_str_210[] PROGMEM = "Closing the "; -static const char esp_mail_str_211[] PROGMEM = "host > "; -static const char esp_mail_str_212[] PROGMEM = "FLAGS"; -static const char esp_mail_str_213[] PROGMEM = "BODY"; -static const char esp_mail_str_214[] PROGMEM = "PEEK"; -static const char esp_mail_str_215[] PROGMEM = "TEXT"; -static const char esp_mail_str_216[] PROGMEM = "HEADER"; -static const char esp_mail_str_217[] PROGMEM = "FIELDS"; -static const char esp_mail_str_218[] PROGMEM = "["; -static const char esp_mail_str_219[] PROGMEM = "]"; -static const char esp_mail_str_220[] PROGMEM = "MIME"; -static const char esp_mail_str_221[] PROGMEM = "connection lost"; -static const char esp_mail_str_222[] PROGMEM = "set recipient failed"; -static const char esp_mail_str_223[] PROGMEM = " NEW"; -static const char esp_mail_str_224[] PROGMEM = "ALL"; -static const char esp_mail_str_225[] PROGMEM = "> C: connect to IMAP server"; -static const char esp_mail_str_226[] PROGMEM = "windows-874"; -static const char esp_mail_str_227[] PROGMEM = "iso-8859-1"; -static const char esp_mail_str_228[] PROGMEM = "> C: server connected"; -static const char esp_mail_str_229[] PROGMEM = "> C: send imap command, LOGIN"; -static const char esp_mail_str_230[] PROGMEM = "> C: send imap command, LIST"; -static const char esp_mail_str_231[] PROGMEM = "iso-8859-11"; -static const char esp_mail_str_232[] PROGMEM = "> C: search messages"; -static const char esp_mail_str_233[] PROGMEM = "> C: send imap command, FETCH"; -static const char esp_mail_str_234[] PROGMEM = "> C: send imap command, LOGOUT"; -static const char esp_mail_str_235[] PROGMEM = "> C: message fetch completed"; -static const char esp_mail_str_236[] PROGMEM = "> C: connect to SMTP server"; -static const char esp_mail_str_237[] PROGMEM = "tis-620"; -static const char esp_mail_str_238[] PROGMEM = "> C: smtp server connected"; -static const char esp_mail_str_239[] PROGMEM = "> C: send smtp command, HELO"; -static const char esp_mail_str_240[] PROGMEM = - "> C: send smtp command, AUTH LOGIN"; -static const char esp_mail_str_241[] PROGMEM = - "> C: send smtp command, AUTH PLAIN"; -static const char esp_mail_str_242[] PROGMEM = "> C: send message header"; -static const char esp_mail_str_243[] PROGMEM = "> C: send message body"; -static const char esp_mail_str_244[] PROGMEM = "> C: send attachments"; -static const char esp_mail_str_245[] PROGMEM = - "> C: terminate the SMTP session"; -static const char esp_mail_str_246[] PROGMEM = "> C: Message sent successfully"; -static const char esp_mail_str_247[] PROGMEM = "$ SELECT \""; -static const char esp_mail_str_248[] PROGMEM = "> C: open the mailbox folder"; -static const char esp_mail_str_249[] PROGMEM = "$ UID STORE "; -static const char esp_mail_str_250[] PROGMEM = " FLAGS ("; -static const char esp_mail_str_251[] PROGMEM = " +FLAGS ("; -static const char esp_mail_str_252[] PROGMEM = " -FLAGS ("; -static const char esp_mail_str_253[] PROGMEM = "> C: set FLAG"; -static const char esp_mail_str_254[] PROGMEM = "> C: add FLAG"; -static const char esp_mail_str_255[] PROGMEM = "> C: remove FLAG"; -static const char esp_mail_str_256[] PROGMEM = "could not parse flag"; -static const char esp_mail_str_257[] PROGMEM = "delsp=\"yes\""; -static const char esp_mail_str_258[] PROGMEM = "session timed out"; -static const char esp_mail_str_259[] PROGMEM = "delsp=yes"; -static const char esp_mail_str_260[] PROGMEM = "< S: "; -static const char esp_mail_str_261[] PROGMEM = "> C: "; -static const char esp_mail_str_262[] PROGMEM = " NOTIFY="; -static const char esp_mail_str_263[] PROGMEM = ","; -static const char esp_mail_str_264[] PROGMEM = "SUCCESS"; -static const char esp_mail_str_265[] PROGMEM = "FAILURE"; -static const char esp_mail_str_266[] PROGMEM = "DELAY"; -static const char esp_mail_str_267[] PROGMEM = "Sending next Email..."; -static const char esp_mail_str_268[] PROGMEM = "> C: send next Email"; -static const char esp_mail_str_269[] PROGMEM = - "header.fields (content-type Content-transfer-encoding)]"; -static const char esp_mail_str_270[] PROGMEM = "format=\"flowed\""; -static const char esp_mail_str_271[] PROGMEM = "> C: send inline data"; -static const char esp_mail_str_272[] PROGMEM = "Content-transfer-encoding: "; -static const char esp_mail_str_273[] PROGMEM = "Date: "; -static const char esp_mail_str_274[] PROGMEM = "Message-ID:"; -static const char esp_mail_str_275[] PROGMEM = "format=flowed"; -static const char esp_mail_str_276[] PROGMEM = "CC: "; -static const char esp_mail_str_277[] PROGMEM = "boundary=\""; -static const char esp_mail_str_278[] PROGMEM = "quoted-printable"; -static const char esp_mail_str_279[] PROGMEM = "Subject:"; -static const char esp_mail_str_280[] PROGMEM = "> C: no content"; -static const char esp_mail_str_281[] PROGMEM = "fail to open the mailbox"; -static const char esp_mail_str_282[] PROGMEM = "file I/O error"; -static const char esp_mail_str_283[] PROGMEM = "time.nist.gov"; -static const char esp_mail_str_284[] PROGMEM = - "log in was disabled for this server"; -static const char esp_mail_str_285[] PROGMEM = "user="; -static const char esp_mail_str_286[] PROGMEM = "\1auth=Bearer "; -static const char esp_mail_str_287[] PROGMEM = "\1\1"; -static const char esp_mail_str_288[] PROGMEM = - "> C: send smtp command, AUTH XOAUTH2"; -static const char esp_mail_str_289[] PROGMEM = "AUTH XOAUTH2 "; -static const char esp_mail_str_290[] PROGMEM = - "> C: send imap command, AUTHENTICATE PLAIN"; -static const char esp_mail_str_291[] PROGMEM = - "> C: send imap command, AUTH XOAUTH2"; -static const char esp_mail_str_292[] PROGMEM = "$ AUTHENTICATE XOAUTH2 "; -static const char esp_mail_str_293[] PROGMEM = - "OAuth2.0 log in was disabled for this server"; -static const char esp_mail_str_294[] PROGMEM = "{\"status\":"; -static const char esp_mail_str_295[] PROGMEM = "0123456789ABCDEF"; -static const char esp_mail_str_296[] PROGMEM = "pool.ntp.org"; -static const char esp_mail_str_297[] PROGMEM = - "Content-Type: multipart/alternative; boundary=\""; -static const char esp_mail_str_298[] PROGMEM = - "Content-Type: multipart/related; boundary=\""; -static const char esp_mail_str_299[] PROGMEM = - "Content-Disposition: inline; filename=\""; -static const char esp_mail_str_300[] PROGMEM = "Content-Location: "; -static const char esp_mail_str_301[] PROGMEM = "Content-ID: <"; -static const char esp_mail_str_302[] PROGMEM = "cid:"; -static const char esp_mail_str_303[] PROGMEM = - "Finishing the message sending..."; -static const char esp_mail_str_304[] PROGMEM = - "> C: Finish the message sending"; -static const char esp_mail_str_305[] PROGMEM = "connection failed"; -static const char esp_mail_str_306[] PROGMEM = - "some of the requested messages no longer exist"; -static const char esp_mail_str_307[] PROGMEM = "Reading messages..."; -static const char esp_mail_str_308[] PROGMEM = - "> C: reading plain TEXT message"; -static const char esp_mail_str_309[] PROGMEM = "> C: reading HTML message"; -static const char esp_mail_str_310[] PROGMEM = - "> C: performing the SSL/TLS handshake"; -static const char esp_mail_str_311[] PROGMEM = "STARTTLS\r\n"; -static const char esp_mail_str_312[] PROGMEM = "code: "; -static const char esp_mail_str_313[] PROGMEM = ", text: "; -static const char esp_mail_str_314[] PROGMEM = "> C: ESP Mail Client v"; -static const char esp_mail_str_315[] PROGMEM = " +FLAGS.SILENT (\\Deleted)"; -static const char esp_mail_str_316[] PROGMEM = "> C: delete message(s)"; -static const char esp_mail_str_317[] PROGMEM = "$ EXPUNGE"; -static const char esp_mail_str_318[] PROGMEM = "> C: copy message(s) to "; -static const char esp_mail_str_319[] PROGMEM = "$ UID COPY "; -static const char esp_mail_str_320[] PROGMEM = "> C: create folder"; -static const char esp_mail_str_321[] PROGMEM = "> C: delete folder"; -static const char esp_mail_str_322[] PROGMEM = "$ CREATE "; -static const char esp_mail_str_323[] PROGMEM = "$ DELETE "; -static const char esp_mail_str_324[] PROGMEM = "HEADER.FIELDS"; -static const char esp_mail_str_325[] PROGMEM = "flash content message"; -static const char esp_mail_str_326[] PROGMEM = "file content message"; -static const char esp_mail_str_327[] PROGMEM = "\"; size="; -static const char esp_mail_str_328[] PROGMEM = "0.0.0.0"; - -static const char esp_mail_smtp_response_1[] PROGMEM = "AUTH "; -static const char esp_mail_smtp_response_2[] PROGMEM = " LOGIN"; -static const char esp_mail_smtp_response_3[] PROGMEM = " PLAIN"; -static const char esp_mail_smtp_response_4[] PROGMEM = " XOAUTH2"; -static const char esp_mail_smtp_response_5[] PROGMEM = "STARTTLS"; -static const char esp_mail_smtp_response_6[] PROGMEM = "8BITMIME"; -static const char esp_mail_smtp_response_7[] PROGMEM = "BINARYMIME"; -static const char esp_mail_smtp_response_8[] PROGMEM = "CHUNKING"; -static const char esp_mail_smtp_response_9[] PROGMEM = "SMTPUTF8"; -static const char esp_mail_smtp_response_10[] PROGMEM = "PIPELINING"; -static const char esp_mail_smtp_response_11[] PROGMEM = " CRAM-MD5"; -static const char esp_mail_smtp_response_12[] PROGMEM = " DIGEST-MD5"; -static const char esp_mail_smtp_response_13[] PROGMEM = "DSN"; -// Tagged -static const char esp_mail_imap_response_1[] PROGMEM = "$ OK "; -static const char esp_mail_imap_response_2[] PROGMEM = "$ NO "; -static const char esp_mail_imap_response_3[] PROGMEM = "$ BAD "; -// Untagged -static const char esp_mail_imap_response_4[] PROGMEM = "* LIST "; -static const char esp_mail_imap_response_5[] PROGMEM = "* FLAGS "; -static const char esp_mail_imap_response_6[] PROGMEM = "* SEARCH "; -static const char esp_mail_imap_response_7[] PROGMEM = " FETCH "; -static const char esp_mail_imap_response_8[] PROGMEM = " NIL "; -static const char esp_mail_imap_response_9[] PROGMEM = " UID "; -static const char esp_mail_imap_response_10[] PROGMEM = "* CAPABILITY "; -static const char esp_mail_imap_response_11[] PROGMEM = "LOGINDISABLED"; -static const char esp_mail_imap_response_12[] PROGMEM = "AUTH=PLAIN"; -static const char esp_mail_imap_response_13[] PROGMEM = "AUTH=XOAUTH2"; -static const char esp_mail_imap_response_14[] PROGMEM = "STARTTLS"; -static const char esp_mail_imap_response_15[] PROGMEM = "CRAM-MD5"; -static const char esp_mail_imap_response_16[] PROGMEM = "DIGEST-MD5"; - -static const char imap_7bit_key1[] PROGMEM = "=20"; -static const char imap_7bit_val1[] PROGMEM = " "; -static const char imap_7bit_key2[] PROGMEM = "=2C"; -static const char imap_7bit_val2[] PROGMEM = ","; -static const char imap_7bit_key3[] PROGMEM = "=E2=80=99"; -static const char imap_7bit_val3[] PROGMEM = "'"; -static const char imap_7bit_key4[] PROGMEM = "=0A"; -static const char imap_7bit_val4[] PROGMEM = "\r\n"; -static const char imap_7bit_key5[] PROGMEM = "=0D"; -static const char imap_7bit_val5[] PROGMEM = "\r\n"; -static const char imap_7bit_key6[] PROGMEM = "=A0"; -static const char imap_7bit_val6[] PROGMEM = " "; -static const char imap_7bit_key7[] PROGMEM = "=B9"; -static const char imap_7bit_val7[] PROGMEM = "$sup1"; -static const char imap_7bit_key8[] PROGMEM = "=C2=A0"; -static const char imap_7bit_val8[] PROGMEM = " "; -static const char imap_7bit_key9[] PROGMEM = "=\r\n"; -static const char imap_7bit_val9[] PROGMEM = ""; -static const char imap_7bit_key10[] PROGMEM = "=E2=80=A6"; -static const char imap_7bit_val10[] PROGMEM = "…"; -static const char imap_7bit_key11[] PROGMEM = "=E2=80=A2"; -static const char imap_7bit_val11[] PROGMEM = "•"; -static const char imap_7bit_key12[] PROGMEM = "=E2=80=93"; -static const char imap_7bit_val12[] PROGMEM = "–"; -static const char imap_7bit_key13[] PROGMEM = "=E2=80=94"; -static const char imap_7bit_val13[] PROGMEM = "—"; - -static const unsigned char b64_index_table[65] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static const char boundary_table[] PROGMEM = - "=_abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -__attribute__((used)) static bool compFunc(uint32_t i, uint32_t j) -{ - return (i > j); -} - -class MessageList -{ -public: - friend class IMAPSession; - MessageList(){}; - ~MessageList() { clear(); }; - void add(int uid) - { - if (uid > 0) - _list.push_back(uid); - } - - void clear() { _list.clear(); } - -private: - std::vector _list = std::vector(); -}; - -/* The class that provides the info of selected or opened mailbox folder */ -class SelectedFolderInfo -{ -public: - friend class ESP_Mail_Client; - friend class IMAPSession; - SelectedFolderInfo(){}; - ~SelectedFolderInfo() { clear(); }; - - /* Get the flags count for this mailbox */ - size_t flagCount() { return _flags.size(); }; - - /* Get the numbers of messages in this mailbox */ - size_t msgCount() { return _msgCount; }; - - /* Get the predict next message UID */ - size_t nextUID() { return _nextUID; }; - - /* Get the numbers of messages from search result based on the search criteria - */ - size_t searchCount() { return _searchCount; }; - - /* Get the numbers of messages to be stored in the ressult */ - size_t availableMessages() { return _availableItems; }; - - /* Get the flag argument at the specified index */ - String flag(size_t index) - { - if (index < _flags.size()) - return _flags[index].c_str(); - return ""; - } - -private: - void addFlag(const char *flag) { _flags.push_back(flag); }; - void clear() - { - for (size_t i = 0; i < _flags.size(); i++) - std::string().swap(_flags[i]); - _flags.clear(); - } - size_t _msgCount = 0; - size_t _nextUID = 0; - size_t _searchCount = 0; - size_t _availableItems = 0; - std::vector _flags = std::vector(); -}; - -/* The class that provides the list of FolderInfo e.g. name, attributes and - * delimiter */ -class FoldersCollection -{ -public: - friend class ESP_Mail_Client; - friend class IMAPSession; - FoldersCollection(){}; - ~FoldersCollection() { clear(); }; - size_t size() { return _folders.size(); }; - - struct esp_mail_folder_info_item_t info(size_t index) - { - struct esp_mail_folder_info_item_t fd; - if (index < _folders.size()) - { - fd.name = _folders[index].name.c_str(); - fd.attributes = _folders[index].attributes.c_str(); - fd.delimiter = _folders[index].delimiter.c_str(); - } - return fd; - } - -private: - void add(struct esp_mail_folder_info_t &fd) { _folders.push_back(fd); }; - void clear() - { - for (size_t i = 0; i < _folders.size(); i++) - { - if (_folders[i].name.length() > 0) - std::string().swap(_folders[i].name); - if (_folders[i].attributes.length() > 0) - std::string().swap(_folders[i].attributes); - if (_folders[i].delimiter.length() > 0) - std::string().swap(_folders[i].delimiter); - } - _folders.clear(); - } - std::vector _folders = - std::vector(); -}; - -/* The class that provides the status of message feching and searching */ -class IMAP_Status -{ -public: - IMAP_Status(); - ~IMAP_Status(); - const char *info(); - bool success(); - void empty(); - friend class IMAPSession; - - std::string _info = ""; - bool _success = false; -}; - -/* The SMTP message class */ -class SMTP_Message -{ -public: - SMTP_Message(){}; - ~SMTP_Message() { clear(); }; - - void resetAttachItem(SMTP_Attachment &att) - { - att.blob.size = 0; - att.blob.data = nullptr; - att.file.path = ""; - att.file.storage_type = esp_mail_file_storage_type_none; - att.descr.name = ""; - att.descr.filename = ""; - att.descr.transfer_encoding = ""; - att.descr.content_encoding = ""; - att.descr.mime = ""; - att.descr.content_id = ""; - att._int.att_type = esp_mail_att_type_none; - att._int.index = 0; - att._int.msg_uid = 0; - att._int.flash_blob = false; - att._int.binary = false; - att._int.parallel = false; - att._int.cid = ""; - } - - void clear() - { - sender.name = ""; - sender.email = ""; - subject = ""; - text.charSet = ""; - text.content = ""; - text.content_type = ""; - text.embed.enable = false; - html.charSet = ""; - html.content = ""; - html.content_type = ""; - html.embed.enable = false; - response.reply_to = ""; - response.notify = esp_mail_smtp_notify::esp_mail_smtp_notify_never; - priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; - - for (size_t i = 0; i < _rcp.size(); i++) - { - _rcp[i].name = ""; - _rcp[i].email = ""; - } - - for (size_t i = 0; i < _cc.size(); i++) - _cc[i].email = ""; - - for (size_t i = 0; i < _bcc.size(); i++) - _bcc[i].email = ""; - - for (size_t i = 0; i < _hdr.size(); i++) - _hdr[i] = ""; - - for (size_t i = 0; i < _att.size(); i++) - { - _att[i].descr.filename = ""; - _att[i].blob.data = nullptr; - _att[i].descr.mime = ""; - _att[i].descr.name = ""; - _att[i].blob.size = 0; - _att[i].descr.transfer_encoding = ""; - _att[i].file.path = ""; - _att[i].file.storage_type = esp_mail_file_storage_type_none; - } - - for (size_t i = 0; i < _parallel.size(); i++) - { - _parallel[i].descr.filename = ""; - _parallel[i].blob.data = nullptr; - _parallel[i].descr.mime = ""; - _parallel[i].descr.name = ""; - _parallel[i].blob.size = 0; - _parallel[i].descr.transfer_encoding = ""; - _parallel[i].file.path = ""; - _parallel[i].file.storage_type = esp_mail_file_storage_type_none; - } - _rcp.clear(); - _cc.clear(); - _bcc.clear(); - _hdr.clear(); - _att.clear(); - _parallel.clear(); - } - - /** Clear all the inline images - */ - void clearInlineimages() - { - for (int i = (int)_att.size() - 1; i >= 0; i--) - { - if (_att[i]._int.att_type == esp_mail_att_type_inline) - _att.erase(_att.begin() + i); - } - }; - - /* Clear all the attachments */ - void clearAttachments() - { - for (int i = (int)_att.size() - 1; i >= 0; i--) - { - if (_att[i]._int.att_type == esp_mail_att_type_attachment) - _att.erase(_att.begin() + i); - } - - for (int i = (int)_parallel.size() - 1; i >= 0; i--) - _parallel.erase(_parallel.begin() + i); - }; - - /** Clear all rfc822 message attachment - */ - void clearRFC822Messages() - { - for (int i = (int)_rfc822.size() - 1; i >= 0; i--) - { - _rfc822[i].clear(); - _rfc822.erase(_rfc822.begin() + i); - } - }; - - /** Clear the primary recipient mailboxes - */ - void clearRecipients() { _rcp.clear(); }; - - /** Clear the Carbon-copy recipient mailboxes - */ - void clearCc() { _cc.clear(); }; - - /** Clear the Blind-carbon-copy recipient mailboxes - */ - void clearBcc() { _bcc.clear(); }; - - /** Clear the custom message headers - */ - void clearHeader() { _hdr.clear(); }; - - /** Add attachment to the message - * - * @param att The SMTP_Attachment data item - */ - void addAttachment(SMTP_Attachment &att) - { - att._int.att_type = esp_mail_att_type_attachment; - att._int.parallel = false; - att._int.flash_blob = true; - _att.push_back(att); - }; - - /** Add parallel attachment to the message - * - * @param att The SMTP_Attachment data item - */ - void addParallelAttachment(SMTP_Attachment &att) - { - att._int.att_type = esp_mail_att_type_attachment; - att._int.parallel = true; - att._int.flash_blob = true; - _parallel.push_back(att); - }; - - /** Add inline image to the message - * - * @param att The SMTP_Attachment data item - */ - void addInlineImage(SMTP_Attachment &att) - { - att._int.flash_blob = true; - att._int.parallel = false; - att._int.att_type = esp_mail_att_type_inline; - char *tmp = new char[36]; - memset(tmp, 0, 36); - itoa(random(10000000, 20000000), tmp, 10); - att._int.cid = tmp; - delete[] tmp; - _att.push_back(att); - }; - - /** Add rfc822 message to the message - * - * @param msg The RFC822_Message class object - */ - void addMessage(SMTP_Message &msg) { _rfc822.push_back(msg); } - - /** Add the primary recipient mailbox to the message - * - * @param name The name of primary recipient - * @param email The Email address of primary recipient - */ - void addRecipient(const char *name, const char *email) - { - struct esp_mail_smtp_recipient_t rcp; - rcp.name = name; - rcp.email = email; - _rcp.push_back(rcp); - }; - - /** Add Carbon-copy recipient mailbox - * - * @param email The Email address of the secondary recipient - */ - void addCc(const char *email) - { - struct esp_mail_smtp_recipient_address_t cc; - cc.email = email; - _cc.push_back(cc); - }; - - /** Add Blind-carbon-copy recipient mailbox - * - * @param email The Email address of the tertiary recipient - */ - void addBcc(const char *email) - { - struct esp_mail_smtp_recipient_address_t bcc; - bcc.email = email; - _bcc.push_back(bcc); - }; - - /** Add the custom header to the message - * - * @param hdr The header name and value - */ - void addHeader(const char *hdr) { _hdr.push_back(hdr); }; - - /* The message author config */ - struct esp_mail_email_info_t sender; - - /* The topic of message */ - const char *subject = ""; - - /* The message type */ - byte type = esp_mail_msg_type_none; - - /* The PLAIN text message */ - struct esp_mail_plain_body_t text; - - /* The HTML text message */ - struct esp_mail_html_body_t html; - - /* The response config */ - struct esp_mail_smtp_msg_response_t response; - - /* The priority of the message */ - esp_mail_smtp_priority priority = - esp_mail_smtp_priority::esp_mail_smtp_priority_normal; - - /* The enable options */ - struct esp_mail_smtp_enable_option_t enable; - - /* The message from config */ - struct esp_mail_email_info_t from; - - /* The message identifier */ - const char *messageID = ""; - - /* The keywords or phrases, separated by commas */ - const char *keyword = ""; - - /* The comment about message */ - const char *comment = ""; - - /* The date of message */ - const char *date = ""; - - /* The return recipient of the message */ - const char *return_path = ""; - -private: - friend class ESP_Mail_Client; - std::vector _rcp = - std::vector(); - std::vector _cc = - std::vector(); - std::vector _bcc = - std::vector(); - std::vector _hdr = std::vector(); - std::vector _att = std::vector(); - std::vector _parallel = std::vector(); - std::vector _rfc822 = std::vector(); -}; - -class SMTP_Status -{ -public: - friend class SMTPSession; - friend class ESP_Mail_Client; - - SMTP_Status(); - ~SMTP_Status(); - const char *info(); - bool success(); - void empty(); - size_t completedCount(); - size_t failedCount(); - -private: - std::string _info = ""; - bool _success = false; - size_t _sentSuccess = 0; - size_t _sentFailed = 0; -}; - -typedef void (*imapStatusCallback)(IMAP_Status); -typedef void (*smtpStatusCallback)(SMTP_Status); - -class ESP_Mail_Client -{ - -public: - /** Sending Email through the SMTP server - * - * @param smtp The pointer to SMTP session object which holds the data and the - * TCP client. - * @param msg The pointer to SMTP_Message class which contains the header, - * body, and attachments. - * @param closeSession The option to Close the SMTP session after sent. - * @return The boolean value indicates the success of operation. - */ - bool sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession = true); - - /** Reading Email through IMAP server. - * - * @param imap The pointer to IMAP sesssion object which holds the data and - the TCP client. - - * @param closeSession The option to close the IMAP session after fetching or - searching the Email. - * @return The boolean value indicates the success of operation. - */ - bool readMail(IMAPSession *imap, bool closeSession = true); - - /** Set the argument to the Flags for the specified message. - * - * @param imap The pointer to IMAP session object which holds the data and the - * TCP client. - * @param msgUID The UID of the message. - * @param flags The flag list to set. - * @param closeSession The option to close the IMAP session after set flag. - * @return The boolean value indicates the success of operation. - */ - bool setFlag(IMAPSession *imap, int msgUID, const char *flags, - bool closeSession); - - /** Add the argument to the Flags for the specified message. - * - * @param imap The pointer to IMAP session object which holds the data and the - * TCP client. - * @param msgUID The UID of the message. - * @param flags The flag list to set. - * @param closeSession The option to close the IMAP session after add flag. - * @return The boolean value indicates the success of operation. - */ - bool addFlag(IMAPSession *imap, int msgUID, const char *flags, - bool closeSession); - - /** Remove the argument from the Flags for the specified message. - * - * @param imap The pointer to IMAP session object which holds the data and the - * TCP client. - * @param msgUID The UID of the message that flags to be removed. - * @param flags The flag list to remove. - * @param closeSession The option to close the IMAP session after remove flag. - * @return The boolean value indicates the success of operation. - */ - bool removeFlag(IMAPSession *imap, int msgUID, const char *flags, - bool closeSession); - - /** Initialize the SD card with the SPI port. - * - * @param sck The SPI Clock pin (ESP32 only). - * @param miso The SPI MISO pin (ESSP32 only). - * @param mosi The SPI MOSI pin (ESP32 only). - * @param ss The SPI Chip/Slave Select pin (ESP32 and ESP8266). - * @return The boolean value indicates the success of operation. - */ - bool sdBegin(uint8_t sck, uint8_t miso, uint8_t mosi, uint8_t ss); - - /** Initialize the SD card with the default SPI port. - * - * @return The boolean value which indicates the success of operation. - */ - bool sdBegin(); - - /** Initialize the SD_MMC card (ESSP32 only). - * - * @param mountpoint The mounting point. - * @param mode1bit Allow 1 bit data line. - * @param format_if_mount_failed Format SD_MMC card if mount failed. - * @return The boolean value indicates the success of operation. - */ - bool sdMMCBegin(const char *mountpoint = "/sdcard", bool mode1bit = false, bool format_if_mount_failed = false); - - - ESPTimeHelper Time; - -private: - friend class SMTPSession; - friend class IMAPSession; -#if defined(ESP8266) - void setClock(float offset); -#endif - - RFC2047_Decoder RFC2047Decoder; - File file; - - bool _sdOk = false; - bool _flashOk = false; - bool _sdConfigSet = false; - uint8_t _sck, _miso, _mosi, _ss; - const char *sd_mmc_mountpoint = ""; - bool sd_mmc_mode1bit = false; - bool sd_mmc_format_if_mount_failed = false; - -#if defined(ESP8266) - bool _clockReady = false; - uint8_t _sdPin = SD_CS_PIN; - float _gmtOffset = 0.0; -#endif - - unsigned long _lastReconnectMillis = 0; - uint16_t _reconnectTimeout = ESP_MAIL_WIFI_RECONNECT_TIMEOUT; - - bool _sendMail(SMTPSession *smtp, SMTP_Message *msg, - bool closeSession = true); - bool ethLinkUp(); - bool reconnect(SMTPSession *smtp, unsigned long dataTime = 0); - bool reconnect(IMAPSession *imap, unsigned long dataTime = 0, - bool downloadRequestuest = false); - void closeTCP(SMTPSession *smtp); - void closeTCP(IMAPSession *imap); - void getMIME(const char *ext, std::string &mime); - void mimeFromFile(const char *name, std::string &mime); -#if defined(ESP32) - void setSecure(ESP_Mail_HTTPClient32 &httpClient, ESP_Mail_Session *session, - std::shared_ptr caCert); -#elif defined(ESP8266) - void setSecure(ESP_Mail_HTTPClient &httpClient, ESP_Mail_Session *session, - std::shared_ptr caCert); -#endif - void delS(char *p); - char *newS(size_t len); - char *newS(char *p, size_t len); - char *newS(char *p, size_t len, char *d); - bool strcmpP(const char *buf, int ofs, PGM_P beginH); - int strposP(const char *buf, PGM_P beginH, int ofs); - char *strP(PGM_P pgm); - void appendP(std::string &buf, PGM_P p, bool empty); - char *intStr(int value); - void errorStatusCB(SMTPSession *smtp, int error); - size_t smtpSendP(SMTPSession *smtp, PGM_P v, bool newline = false); - size_t smtpSend(SMTPSession *smtp, const char *data, bool newline = false); - size_t smtpSend(SMTPSession *smtp, int data, bool newline = false); - size_t smtpSend(SMTPSession *smtp, uint8_t *data, size_t size); - bool getMultipartFechCmd(IMAPSession *imap, int msgIdx, - std::string &partText); - bool multipartMember(const std::string &part, const std::string &check); - bool fetchMultipartBodyHeader(IMAPSession *imap, int msgIdx); - bool connected(IMAPSession *imap); - bool imapAuth(IMAPSession *imap); - bool sendIMAPCommand(IMAPSession *imap, int msgIndex, int cmdCase); - bool handleSMTPError(SMTPSession *smtp, int err, bool ret = false); - void errorStatusCB(IMAPSession *imap, int error); - size_t imapSendP(IMAPSession *imap, PGM_P v, bool newline = false); - size_t imapSend(IMAPSession *imap, const char *data, bool nwline = false); - size_t imapSend(IMAPSession *imap, int data, bool newline = false); - std::string getBoundary(size_t len); - std::string getEncodedToken(IMAPSession *imap); - bool imapLogout(IMAPSession *imap); - bool sendParallelAttachments(SMTPSession *smtp, SMTP_Message *msg, - const std::string &boundary); - bool sendAttachments(SMTPSession *smtp, SMTP_Message *msg, - const std::string &boundary, bool parallel = false); - - bool sendMSGData(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, - bool rfc822MSG); - bool sendRFC822Msg(SMTPSession *smtp, SMTP_Message *msg, - const std::string &boundary, bool closeSession, - bool rfc822MSG); - void getRFC822MsgEnvelope(SMTPSession *smtp, SMTP_Message *msg, - std::string &buf); - bool bdat(SMTPSession *smtp, SMTP_Message *msg, int len, bool last); - void checkBinaryData(SMTPSession *smtp, SMTP_Message *msg); - bool sendBlob(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att); - bool sendFile(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att, - File &file); - bool openFileRead(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att, - File &file, std::string &s, std::string &buf, - const std::string &boundary, bool inlined); - bool openFileRead2(SMTPSession *smtp, SMTP_Message *msg, File &file, - const char *path, esp_mail_file_storage_type storageType); - bool sendInline(SMTPSession *smtp, SMTP_Message *msg, - const std::string &boundary, byte type); - void debugInfoP(PGM_P info); - size_t numAtt(SMTPSession *smtp, esp_mail_attach_type type, - SMTP_Message *msg); - bool validEmail(const char *s); - bool checkEmail(SMTPSession *smtp, SMTP_Message *msg); - bool sendPartText(SMTPSession *smtp, SMTP_Message *msg, byte type, - const char *boundary); - char *getUID(); - bool sendBlobBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type); - bool sendFileBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type); - void encodingText(SMTPSession *smtp, SMTP_Message *msg, uint8_t type, - std::string &content); - void splitTk(std::string &str, std::vector &tk, - const char *delim); - void formatFlowedText(std::string &content); - void softBreak(std::string &content, const char *quoteMarks); - bool sendMSG(SMTPSession *smtp, SMTP_Message *msg, - const std::string &boundary); - void getAttachHeader(std::string &header, const std::string &boundary, - SMTP_Attachment *attach, size_t size); - void getRFC822PartHeader(SMTPSession *smtp, std::string &header, - const std::string &boundary); - void getInlineHeader(std::string &header, const std::string &boundary, - SMTP_Attachment *inlineAttach, size_t size); - unsigned char *decodeBase64(const unsigned char *src, size_t len, - size_t *out_len); - std::string encodeBase64Str(const unsigned char *src, size_t len); - std::string encodeBase64Str(uint8_t *src, size_t len); - void encodeQP(const char *buf, char *out); - bool sendBase64(SMTPSession *smtp, SMTP_Message *msg, - const unsigned char *data, size_t len, bool flashMem, - const char *filename, bool report); - bool sendBase64Stream(SMTPSession *smtp, SMTP_Message *msg, File file, - const char *filename, bool report); - void smtpCBP(SMTPSession *smtp, PGM_P info, bool success = false); - void smtpCB(SMTPSession *smtp, const char *info, bool success = false); - void imapCBP(IMAPSession *imap, PGM_P info, bool success); - void imapCB(IMAPSession *imap, const char *info, bool success); - int readLine(WiFiClient *stream, char *buf, int bufLen, bool crlf, - int &count); -#if defined(ESP32) - int _readLine(ESP_Mail_WCS32 *stream, char *buf, int bufLen, bool crlf, - int &count); -#elif defined(ESP8266) - int _readLine(ESP_Mail::ESP_Mail_WCS *stream, char *buf, int bufLen, - bool crlf, int &count); -#endif - int getMSGNUM(IMAPSession *imap, char *buf, int bufLen, int &chunkIdx, - bool &endSearch, int &nump, const char *key, const char *pc); - void handleHeader(IMAPSession *imap, char *buf, int bufLen, int &chunkIdx, - struct esp_mail_message_header_t &header, int &headerState, - int &octetCount); - void setHeader(IMAPSession *imap, char *buf, - struct esp_mail_message_header_t &header, int state); - void handlePartHeader(IMAPSession *imap, char *buf, int &chunkIdx, - struct esp_mail_message_part_info_t &part); - char *subStr(const char *buf, PGM_P beginH, PGM_P endH, int beginPos, - int endPos = 0); - struct esp_mail_message_part_info_t *cPart(IMAPSession *imap); - struct esp_mail_message_header_t *cHeader(IMAPSession *imap); - void strcat_c(char *str, char c); - int strpos(const char *haystack, const char *needle, int offset); - char *stristr(const char *str1, const char *str2); - char *rstrstr(const char *haystack, const char *needle); - int rstrpos(const char *haystack, const char *needle, int offset); - void getResponseStatus(const char *buf, esp_mail_smtp_status_code respCode, - int beginPos, - struct esp_mail_smtp_response_status_t &status); - void handleAuth(SMTPSession *smtp, char *buf); - std::string getEncodedToken(SMTPSession *smtp); - bool connected(SMTPSession *smtp); - bool setSendingResult(SMTPSession *smtp, SMTP_Message *msg, bool result); - bool smtpAuth(SMTPSession *smtp); - int available(SMTPSession *smtp); - bool handleSMTPResponse(SMTPSession *smtp, esp_mail_smtp_status_code respCode, - int errCode); - int available(IMAPSession *imap); - bool handleIMAPResponse(IMAPSession *imap, int errCode, bool closeSession); - void downloadReport(IMAPSession *imap, int progress); - void fetchReport(IMAPSession *imap, int progress, bool html); - void searchReport(int progress, const char *percent); - void uploadReport(const char *filename, int progress); - int cMSG(IMAPSession *imap); - int cIdx(IMAPSession *imap); - esp_mail_imap_response_status imapResponseStatus(IMAPSession *imap, - char *response); - void saveHeader(IMAPSession *imap); - esp_mail_char_decoding_scheme getEncodingFromCharset(const char *enc); - void decodeHeader(std::string &headerField, std::string &headerEnc); - bool handleAttachment(IMAPSession *imap, char *buf, int bufLen, int &chunkIdx, - File &file, std::string &filePath, - bool &downloadRequest, int &octetCount, - int &octetLength, int &oCount, int &reportState, - int &downloadCount); - int decodeLatin1_UTF8(unsigned char *out, int *outlen, - const unsigned char *in, int *inlen); - void decodeTIS620_UTF8(char *out, const char *in, size_t len); - void decodeText(IMAPSession *imap, char *buf, int bufLen, int &chunkIdx, - File &file, std::string &filePath, bool &downloadRequest, - int &octetLength, int &readDataLen, int &readCount); - void prepareFilePath(IMAPSession *imap, std::string &filePath, bool header); - int decodeChar(const char *s); - void decodeQP(const char *buf, char *out); - char *decode7Bit(char *buf); - char *strReplace(char *orig, char *rep, char *with); - char *strReplaceP(char *buf, PGM_P key, PGM_P value); - bool authFailed(char *buf, int bufLen, int &chunkIdx, int ofs); - void handleFolders(IMAPSession *imap, char *buf); - void handleCapability(IMAPSession *imap, char *buf, int &chunkIdx); - void handleExamine(IMAPSession *imap, char *buf); - bool handleIMAPError(IMAPSession *imap, int err, bool ret); - bool _setFlag(IMAPSession *imap, int msgUID, const char *flags, - uint8_t action, bool closeSession); - void createDirs(std::string dirs); - bool sdTest(); -}; - -class IMAPSession -{ -public: - IMAPSession(); - ~IMAPSession(); - - /** Begin the IMAP server connection. - * - * @param session The pointer to ESP_Mail_Session structured data that keeps - * the server and log in details. - * @param config The pointer to IMAP_Config structured data that keeps the - * operation options. - * @return The boolean value which indicates the success of operation. - */ - bool connect(ESP_Mail_Session *session, IMAP_Config *config); - - /** Close the IMAP session. - * - * @return The boolean value which indicates the success of operation. - */ - bool closeSession(); - - /** Set to enable the debug. - * - * @param level The level to enable the debug message - * level = 0, no debug - * level = 1, basic debug - * level = 2, full debug 1 - * level = 333, full debug 2 - */ - void debug(int level); - - /** Get the list of all the mailbox folders since the TCP session was opened - * and user was authenticated. - * - * @param folders The FoldersCollection class that contains the collection of - * the - * FolderInfo structured data. - * @return The boolean value which indicates the success of operation. - */ - bool getFolders(FoldersCollection &folders); - - /** Select or open the mailbox folder to search or fetch the message inside. - * - * @param folderName The known mailbox folder name. The default name is INBOX. - * @param readOnly The option to open the mailbox for read only. Set this - * option to false when you wish - * to modify the Flags using the setFlag, addFlag and removeFlag functions. - * @return The boolean value which indicates the success of operation. - */ - bool selectFolder(const char *folderName, bool readOnly = true); - - /** Open the mailbox folder to read or search the mesages. - * - * @param folderName The name of known mailbox folder to be opened. - * @param readOnly The option to open the mailbox for reading only. Set this - * option to false when you wish - * to modify the flags using the setFlag, addFlag and removeFlag functions. - * @return The boolean value which indicates the success of operation. - */ - bool openFolder(const char *folderName, bool readOnly = true); - - /** Close the mailbox folder that was opened. - * - * @param folderName The known mailbox folder name. - * @return The boolean value which indicates the success of operation. - */ - bool closeFolder(const char *folderName); - - /** Create folder. - * - * @param folderName The name of folder to create. - * @return The boolean value which indicates the success of operation. - */ - bool createFolder(const char *folderName); - - /** Delete folder. - * - * @param folderName The name of folder to delete. - * @return The boolean value which indicates the success of operation. - */ - bool deleteFolder(const char *folderName); - - /** Copy the messages to the defined mailbox folder. - * - * @param toCopy The pointer to the MessageListList class that contains the - * list of messages to copy. - * @param dest The destination folder that the messages to copy to. - * @return The boolean value which indicates the success of operation. - */ - bool copyMessages(MessageList *toCopy, const char *dest); - - /** Delete the messages in the opened mailbox folder. - * - * @param toDelete The pointer to the MessageListList class that contains the - * list of messages to delete. - * @param expunge The boolean option to expunge all messages. - * @return The boolean value which indicates the success of operation. - */ - bool deleteMessages(MessageList *toDelete, bool expunge = false); - - /** Assign the callback function that returns the operating status when - * fetching or reading the Email. - * - * @param imapCallback The function that accepts the imapStatusCallback as - * parameter. - */ - void callback(imapStatusCallback imapCallback); - - /** Determine if no message body contained in the search result and only the - * message header is available. - */ - bool headerOnly(); - - /** Get the message list from search or fetch the Emails - * - * @return The IMAP_MSG_List structured data which contains text and html - * contents, - * attachments, inline images, embedded rfc822 messages details for each - * message. - */ - IMAP_MSG_List data(); - - /** Get the details of the selected or opned mailbox folder - * - * @return The SelectedFolderInfo class which contains the info about flags, - * total messages, next UID, - * search count and the available messages count. - */ - SelectedFolderInfo selectedFolder(); - - /** Get the error details when readingg the Emails - * - * @return The string of error details. - */ - String errorReason(); - - /** Clear all the cache data stored in the IMAP session object. - */ - void empty(); - - friend class ESP_Mail_Client; - friend class foldderList; - -private: - void clearMessageData(); - void checkUID(); - void checkPath(); - void getMessages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg); - void getRFC822Messages(uint16_t messageIndex, - struct esp_mail_imap_msg_item_t &msg); - bool closeMailbox(); - bool openMailbox(const char *folder, esp_mail_imap_auth_mode mode, - bool waitResponse); - bool getMailboxes(FoldersCollection &flders); - bool checkCapability(); - - bool _tcpConnected = false; - struct esp_mail_imap_response_status_t _imapStatus; - int _cMsgIdx = 0; - int _cPartIdx = 0; - int _totalRead = 0; - std::vector _headers = - std::vector(); - - esp_mail_imap_command _imap_cmd = - esp_mail_imap_command::esp_mail_imap_cmd_login; - // std::string _partNumStr = ""; - std::vector _multipart_levels = - std::vector(); - int _rfc822_part_count = 0; - esp_mail_file_storage_type _storageType = - esp_mail_file_storage_type::esp_mail_file_storage_type_flash; - bool _unseen = false; - bool _readOnlyMode = true; - struct esp_mail_auth_capability_t _auth_capability; - ESP_Mail_Session *_sesson_cfg; - std::string _currentFolder = ""; - bool _mailboxOpened = false; - std::string _nextUID = ""; - - struct esp_mail_imap_read_config_t *_config = nullptr; - - bool _headerOnly = true; - bool _uidSearch = false; - bool _headerSaved = false; - bool _debug = false; - int _debugLevel = 0; - bool _secure = false; - imapStatusCallback _readCallback = NULL; - - std::vector _msgNum = std::vector(); - FoldersCollection _folders; - SelectedFolderInfo _mbif; - - int _certType = -1; - std::shared_ptr _caCert = nullptr; - -#if defined(ESP32) - ESP_Mail_HTTPClient32 httpClient; -#elif defined(ESP8266) - ESP_Mail_HTTPClient httpClient; -#endif - - IMAP_Status _cbData; -}; - -class SendingResult -{ -private: - std::vector _result = - std::vector(); - void add(struct esp_mail_smtp_send_status_t r) - { - struct esp_mail_smtp_send_status_t _r = r; - _result.push_back(_r); - } - void clear() - { - for (size_t i = 0; i < _result.size(); i++) - { - _result[i].recipients = ""; - _result[i].subject = ""; - _result[i].timesstamp = 0; - _result[i].completed = false; - } - _result.clear(); - } - -public: - friend class SMTPSession; - friend class ESP_Mail_Client; - SendingResult(){}; - ~SendingResult() { clear(); }; - SMTP_Result getItem(size_t index) - { - struct esp_mail_smtp_send_status_t r; - if (index < _result.size()) - return _result[index]; - return r; - } - size_t size() { return _result.size(); }; -}; - -class SMTPSession -{ -public: - SMTPSession(); - ~SMTPSession(); - - /** Begin the SMTP server connection. - * - * @param session The pointer to ESP_Mail_Session structured data that keeps - * the server and log in details. - * @return The boolean value indicates the success of operation. - */ - bool connect(ESP_Mail_Session *session); - - /** Close the SMTP session. - * - */ - bool closeSession(); - - /** Set to enable the debug. - * - * @param level The level to enable the debug message - * level = 0, no debug - * level = 1, basic debug - * level = 2, full debug 1 - * level = 333, full debug 2 - */ - void debug(int level); - - /** Get the error details when sending the Email - * - * @return The string of error details. - */ - String errorReason(); - - /** Set the Email sending status callback function. - * - * @param smtpCallback The callback function that accept the - * smtpStatusCallback param. - */ - void callback(smtpStatusCallback smtpCallback); - - SendingResult sendingResult; - - friend class ESP_Mail_Client; - -private: - bool _tcpConnected = false; - struct esp_mail_smtp_response_status_t _smtpStatus; - int _sentSuccessCount = 0; - int _sentFailedCount = 0; - bool _chunkedEnable = false; - int _chunkCount = 0; - - esp_mail_smtp_command _smtp_cmd = - esp_mail_smtp_command::esp_mail_smtp_cmd_greeting; - struct esp_mail_auth_capability_t _auth_capability; - struct esp_mail_smtp_capability_t _send_capability; - ESP_Mail_Session *_sesson_cfg = NULL; - - bool _debug = false; - int _debugLevel = 0; - bool _secure = false; - smtpStatusCallback _sendCallback = NULL; - - SMTP_Status _cbData; - struct esp_mail_smtp_msg_type_t _msgType; - - int _certType = -1; - std::shared_ptr _caCert = nullptr; - -#if defined(ESP32) - ESP_Mail_HTTPClient32 httpClient; -#elif defined(ESP8266) - ESP_Mail_HTTPClient httpClient; -#endif -}; - - -//#define EMAIL_DEBUG_PRINTLN Serial.println -//#define EMAIL_DEBUG_PRINT Serial.print -#define EMAIL_DEBUG_PRINTLN Tasmota_print -#define EMAIL_DEBUG_PRINT Tasmota_print - -extern void Tasmota_print(const char *); - -static void __attribute__((used)) esp_mail_debug(const char *msg) -{ - delay(0); - EMAIL_DEBUG_PRINTLN(msg); -} - -static void __attribute__((used)) -esp_mail_debug_line(const char *msg, bool newline) -{ - delay(0); - if (newline) - EMAIL_DEBUG_PRINTLN(msg); - else - EMAIL_DEBUG_PRINT(msg); -} - -extern ESP_Mail_Client MailClient; - -extern FS *ufsp; - -#endif // ESP_Mail_Client_H diff --git a/lib/libesp32/lib_mail/src/ESP_Mail_FS.h b/lib/libesp32/lib_mail/src/ESP_Mail_FS.h deleted file mode 100644 index 0e9007fcbbc4..000000000000 --- a/lib/libesp32/lib_mail/src/ESP_Mail_FS.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef ESP_Mail_CONFIG_H -#define ESP_Mail_CONFIG_H -#include - -/** - * To use other flash file systems - * - * LittleFS File system - * - * #include - * #define ESP_Mail_DEFAULT_FLASH_FS LittleFS //For ESP8266 LitteFS - * - * - * FFat File system - * - * #include - * #define ESP_Mail_DEFAULT_FLASH_FS FFat //For ESP32 FFat - * -*/ -// #define ESP_Mail_DEFAULT_FLASH_FS SPIFFS - -#include -#define ESP_Mail_DEFAULT_FLASH_FS LittleFS - -/** - * To use SD card file systems with different hardware interface - * e.g. SDMMC hardware bus on the ESP32 - * https://github.com/espressif/arduino-esp32/tree/master/libraries/SD#faq - * - #include - #define ESP_Mail_DEFAULT_SD_FS SD_MMC //For ESP32 SDMMC - #define CARD_TYPE_SD_MMC 1 - * -*/ -#define ESP_Mail_DEFAULT_SD_FS SD -#define CARD_TYPE_SD 1 - -//For ESP32, format SPIFFS or FFat if mounting failed -#define FORMAT_FLASH_IF_MOUNT_FAILED 1 - - -#endif \ No newline at end of file diff --git a/lib/libesp32/lib_mail/src/README.md b/lib/libesp32/lib_mail/src/README.md deleted file mode 100644 index 0e9c5094e10b..000000000000 --- a/lib/libesp32/lib_mail/src/README.md +++ /dev/null @@ -1,2031 +0,0 @@ -# ESP Mail Client Arduino Library for ESP32 and ESP8266 - - -The detail and usage of the available functions in the latest version (1.2.0) are showed below. - - -## Global functions - - -#### Sending Email through the SMTP server. - -param **`smtp`** The pointer to SMTP session object which holds the data and the TCP client. - -param **`msg`** The pointer to SMTP_Message class which contains the header, body, and attachments. - -param **`closeSession`** The option to Close the SMTP session after sent. - -return **`boolean`** The boolean value indicates the success of operation. - -```C++ -bool sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession = true); -``` - - - - - -#### Reading Email through IMAP server. - -param **`imap`** The pointer to IMAP sesssion object which holds the data and the TCP client. - -param **`closeSession`** The option to close the IMAP session after fetching or searching the Email. - -return **`boolean`** The boolean value indicates the success of operation. - -```C++ -bool readMail(IMAPSession *imap, bool closeSession = true); -``` - - - - - -#### Set the argument to the Flags for the specified message. - -param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. - -param **`msgUID`** The UID of the message. - -param **`flags`** The flag list to set. - -param **`closeSession`** The option to close the IMAP session after set flag. - -return **`boolean`** The boolean value indicates the success of operation. - -```C++ -bool setFlag(IMAPSession *imap, int msgUID, const char *flags, bool closeSession); -``` - - - - - -#### Add the argument to the Flags for the specified message. - -param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. - -param **`msgUID`** The UID of the message. - -param **`flags`** The flag list to set. - -param **`closeSession`** The option to close the IMAP session after add flag. - -return **`boolean`** The boolean value indicates the success of operation. - -```C++ -bool addFlag(IMAPSession *imap, int msgUID, const char *flags, bool closeSession); -``` - - - - - - -#### Remove the argument from the Flags for the specified message. - -param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. - -param **`msgUID`** The UID of the message that flags to be removed. - -param **`flags`** The flag list to remove. - -param **`closeSession`** The option to close the IMAP session after remove flag. - -return **`boolean`** The boolean value indicates the success of operation. - -```C++ -bool removeFlag(IMAPSession *imap, int msgUID, const char *flags, bool closeSession); -``` - - - - - - -#### Initialize the SD card with the SPI port. - -param **`sck`** The SPI Clock pin (ESP32 only). - -param **`miso`** The SPI MISO pin (ESSP32 only). - -param **`mosi`** The SPI MOSI pin (ESP32 only). - -param **`ss`** The SPI Chip/Slave Select pin (ESP32 and ESP8266). - -return **`boolean`** The boolean value indicates the success of operation. - -```C++ -bool sdBegin(uint8_t sck, uint8_t miso, uint8_t mosi, uint8_t ss); -``` - - - - - - -#### Initialize the SD_MMC card (ESP32 only). - -param **`mountpoint`** The mounting point. - -param **`mode1bit`** Allow 1 bit data line (SPI mode). - -param **`format_if_mount_failed`** Format SD_MMC card if mount failed. - -return **`Boolean`** type status indicates the success of the operation. - -```C++ -bool sdMMCBegin(const char *mountpoint = "/sdcard", bool mode1bit = false, bool format_if_mount_failed = false); -``` - - - - - - -#### Initialize the SD card with the default SPI port. - -return **`boolean`** The boolean value which indicates the success of operation. - -```C++ -bool sdBegin(void); -``` - - - - - - -## IMAPSession class functions - - -The following functions are available from the IMAP Session class. - -This class used for controlling IMAP transports and retrieving the data from the IMAP server. - - - - - -#### Begin the IMAP server connection. - -param **`session`** The pointer to ESP_Mail_Session structured data that keeps the server and log in details. - -param **`config`** The pointer to IMAP_Config structured data that keeps the operation options. - -return **`boolean`** The boolean value which indicates the success of operation. - -```C++ -bool connect(ESP_Mail_Session *session, IMAP_Config *config); -``` - - -#### Close the IMAP session. - -return **`boolean`** The boolean value which indicates the success of operation. - -```C++ -bool closeSession(); -``` - - - - - - -#### Set to enable the debug. - -param **`level`** The level to enable the debug message - -level = 0, no debug - -level = 1, basic debug - -level = 2, full debug 1 - -level = 333, full debug 2 - -```C++ -void debug(int level); -``` - - - - - -#### Get the list of all the mailbox folders since the TCP session was opened and user was authenticated. - -param **`folders`** The FoldersCollection class that contains the collection of the -FolderInfo structured data. - -return **`boolean`** The boolean value which indicates the success of operation. - -```C++ -bool getFolders(FoldersCollection &folders); -``` - - - - - -#### Select or open the mailbox folder to search or fetch the message inside. - -param **`folderName`** The known mailbox folder name. The default name is INBOX. - -param **`readOnly`** The option to open the mailbox for read only. Set this option to false when you wish -to modify the Flags using the setFlag, addFlag and removeFlag functions. - -return **`boolean`** The boolean value which indicates the success of operation. - -```C++ -bool selectFolder(const char *folderName, bool readOnly = true); -``` - - - - - -#### Open the mailbox folder to read or search the mesages. - -param **`folderName`** The name of known mailbox folder to be opened. - -param **`readOnly`** The option to open the mailbox for reading only. Set this option to false when you wish -to modify the flags using the setFlag, addFlag and removeFlag functions. - -return **`boolean`** The boolean value which indicates the success of operation. - -```C++ -bool openFolder(const char *folderName, bool readOnly = true); -``` - - - - - -#### Close the mailbox folder that was opened. - -param **`folderName`** The mailbox folder name. - -return **`boolean`** The boolean value which indicates the success of operation. - -```C++ -bool closeFolder(const char *folderName); -``` - - - - - - -#### Create folder. - -param **`folderName`** The name of folder to create. - -return **`boolean`** The boolean value which indicates the success of operation. - -```C++ -bool createFolder(const char *folderName); -``` - - - - - - -#### Delete folder. - -param **`folderName`** The name of folder to delete.. - -return **`boolean`** The boolean value which indicates the success of operation. - -```C++ -bool deleteFolder(const char *folderName); -``` - - - - - - -#### Copy the messages to the defined mailbox folder. - -param **`toCopy`** The pointer to the MessageList class that contains the list of messages to copy. - -param **`dest`** The destination folder that the messages to copy to. - -return **`boolean`** The boolean value which indicates the success of operation. - -```C++ -bool copyMessages(MessageList *toCopy, const char *dest); -``` - - - - - -#### Delete the messages in the opened mailbox folder. - -param **`toDelete`** The pointer to the MessageList class that contains the list of messages to delete. - -param **`expunge`** The boolean option to expunge all messages. - -return **`boolean`** The boolean value which indicates the success of operation. - -```C++ -bool deleteMessages(MessageList *toDelete, bool expunge = false); -``` - - - - - - - -#### Assign the callback function that returns the operating status when fetching or reading the Email. - -param **`imapCallback`** The function that accepts the imapStatusCallback as parameter. - -```C++ -void callback(imapStatusCallback imapCallback); -``` - - - - - -#### Determine if no message body contained in the search result and only the message header is available. - -```C++ -bool headerOnly(); -``` - - - - - -#### Get the message list from search or fetch the Emails - -return **`The IMAP_MSG_List structured`** data which contains the text and html contents, -attachments, inline images, embedded rfc822 messages details for each message. - -```C++ -IMAP_MSG_List data(); -``` - - - - - -#### Get the details of the selected or opned mailbox folder - -return **`The SelectedFolderInfo class`** instance which contains the info about flags, total messages, next UID, -earch count and the available messages count. - -```C++ -SelectedFolderInfo selectedFolder(); -``` - - - - - -#### Get the error details when readingg the Emails - -return **`String`** The string of error details. - -```C++ -String errorReason(); -``` - - - - - -#### Clear all the cache data stored in the IMAP session object. - -```C++ -void empty(); -``` - - - - - -## IMAPSession class functions - - -The following functions are available from the SMTP Session class. - -This class is similar to the IMAP session class, used for controlling SMTP transports -and retrieving the data from the SMTP server. - - - - - - -#### Begin the SMTP server connection. - -param **`session`** The pointer to ESP_Mail_Session structured data that keeps the server and log in details. - -return **`boolean`** The boolean value indicates the success of operation. - -```C++ -bool connect(ESP_Mail_Session *session); -``` - - - - - -### Close the SMTP session. - -```C++ -bool closeSession(); -``` - - - - - -#### Set to enable the debug. - -param **`level`** The level to enable the debug message - -level = 0, no debug - -level = 1, basic debug - -level = 2, full debug 1 - -level = 333, full debug 2 - -```C++ -void debug(int level); -``` - - - - - -#### Get the error details when sending the Email - -return **`String`** The string of error details. - -```C++ -String errorReason(); -``` - - - - - -#### Set the Email sending status callback function. - -param **`smtpCallback`** The callback function that accept the smtpStatusCallback param. - -```C++ -void callback(smtpStatusCallback smtpCallback); -``` - - - - - -## SMTP_Message class functions - - -The following functions are available from the SMTP Message class. - -This class is used for storing the message data including headers, body and attachments -which will be processed with the SMTP session class. - - - - -#### To reset the SMTP_Attachment item data - -param **`att`** The SMTP_Attachment class that stores the info about attachment - -This function was used for clear the internal data of attachment item to be ready for reuse. - -```C++ -void resetAttachItem(SMTP_Attachment &att); -``` - - - -#### To clear all data in SMTP_Message class included headers, bodies and attachments - -```C++ -void clear(); -``` - - - - -#### To clear all the inline images in SMTP_Message class. - -```C++ -void clearInlineimages(); -``` - - - - - -#### To clear all the attachments. - -```C++ -void clearAttachments(); -``` - - - - - -#### To clear all rfc822 message attachment. - -```C++ -void clearRFC822Messages(); -``` - - - - - -#### To clear the primary recipient mailboxes. - -```C++ -void clearRecipients(); -``` - - - - - -#### To clear the Carbon-copy recipient mailboxes. - -```C++ -void clearCc(); -``` - - - - - -#### To clear the Blind-carbon-copy recipient mailboxes. - -```C++ -void clearBcc(); -``` - - -#### To clear the custom message headers. - -```C++ -void clearHeader(); -``` - - - - -#### To add attachment to the message. - -param **`att`** The SMTP_Attachment data item - -```C++ -void addAttachment(SMTP_Attachment &att); -``` - - - - - -#### To add parallel attachment to the message. - -param **`att`** The SMTP_Attachment data item - -```C++ -void addParallelAttachment(SMTP_Attachment &att); -``` - - - - - -#### To add inline image to the message. - -param **`att`** The SMTP_Attachment data item - -```C++ -void addInlineImage(SMTP_Attachment &att); -``` - - - - - -#### To add rfc822 message to the message. - -param **`msg`** The RFC822_Message class object - -```C++ -void addMessage(SMTP_Message &msg); -``` - - - - - -#### To add the primary recipient mailbox to the message. - -param **`name`** The name of primary recipient - -param **`email`** The Email address of primary recipient - -```C++ -void addRecipient(const char *name, const char *email); -``` - - - - - -#### To add Carbon-copy recipient mailbox. - -param **`email`** The Email address of secondary recipient - -```C++ -void addCc(const char *email); -``` - - - - - -#### To add Blind-carbon-copy recipient mailbox. - -param **`email`** The Email address of the tertiary recipient - -```C++ -void addBcc(const char *email); -``` - - - - - -#### To add the custom header to the message. - -param **`hdr`** The header name and value - -```C++ -void addHeader(const char *hdr); -``` - - - - -##### [properties] The message author config - -This property has the sub properties - -###### [const char*] name - The sender name. - -###### [const char*] email - The sender Email address. - -```C++ -esp_mail_email_info_t sender; -``` - - -##### [properties] The topic of message - -```C++ -const char *subject; -``` - - -##### [properties] The message type - -```C++ -byte type; -``` - - -##### [properties] The PLAIN text message - -This property has the sub properties - -###### [esp_mail_smtp_embed_message_body_t] embed - The option to embed this message content as a file. - -###### [const char*] content - The PLAIN text content of the message. - -###### [esp_mail_blob_message_content_t] blob - The blob that contins PLAIN text content of the message. - -###### [esp_mail_file_message_content_t] file - The file that contins PLAIN text content of the message. - -###### [const char*] charSet - The character transcoding of the PLAIN text content of the message. - -###### [const char*] content_type - The content type of message. - -###### [const char*] transfer_encoding - The option to encode the content for data transfer. - -###### [boolean] flowed - The option to send the PLAIN text with wrapping. - -```C++ -esp_mail_plain_body_t text; -``` - - -##### [properties] The HTML text message - -This propery has the sub properties - -###### [const char*] content - The HTML content of the message. - -###### [esp_mail_blob_message_content_t] blob - The blob that contins HTML content of the message. - -###### [esp_mail_file_message_content_t] file - The file that contins HTML content of the message. - -###### [const char*] charSet - The character transcoding of the HTML content of the message. - -###### [const char*] content_type - The content type of message. - -###### [const char*] transfer_encoding - The option to encode the content for data transfer. - -```C++ -esp_mail_html_body_t html; -``` - - -##### [properties] The response config - -This propery has the sub properties - -###### [const char*] reply_to - The author Email address to reply. - -###### [const char*] return_path - The sender Email address to return the message. - -###### [int] notify - The Delivery Status Notifications enumeration e.g. - -esp_mail_smtp_notify_never = 0, - -esp_mail_smtp_notify_success = 1, - -esp_mail_smtp_notify_failure = 2, and - -esp_mail_smtp_notify_delay = 4 - -```C++ -esp_mail_smtp_msg_response_t response; -``` - - -##### [properties] The priority of the message - -This property has the enumeration values - -esp_mail_smtp_priority_high = 1, - -esp_mail_smtp_priority_normal = 3, - -esp_mail_smtp_priority_low = 5 - -```C++ -esp_mail_smtp_priority priority; -``` - - -##### [properties] The enable options - -This propery has the sub property - -###### [boolean] chunking - enable chunk data sending for large message. - -```C++ -esp_mail_smtp_enable_option_t enable; -``` - - -##### [properties] The message from config - -This property has the sub properties - -###### [const char*] name - The messsage author name. - -###### [const char*] email - The message author Email address. - -```C++ -esp_mail_email_info_t from; -``` - - -##### [properties] The message identifier - -```C++ -const char *messageID; -``` - -##### [properties] The keywords or phrases, separated by commas - -```C++ -const char *keyword; -``` - - -##### [properties] The comment about message - -```C++ -const char *comment; -``` - - -##### [properties] The date of message - -```C++ -const char *date; -``` - - -##### [properties] The return recipient of the message - -```C++ -const char *return_path; -``` - - - - - - -## IMAP_Status class functions - - -The following functions are available from the IMAP Status class. - -This class is used as the callback parameter for retrieving the status while reading the Email. - - - - -#### Provide the information of each process in the reading operation. - -return **`string`** The info for each process - -```C++ -const char *info(); -``` - - - - -#### Provide the status of completion. - -return **`boolean`** The bool value indicates that all reading processes are finished - -```C++ -bool success(); -``` - - - - - -#### To clear all data store in this class. - -```C++ -void empty(); -``` - - - - - - -## SMTP_Status class functions - - -The following functions are available from the SMTP Status class. - -This class is used as the callback parameter for retrieving the status while sending the Email. - - - - -#### Provide the information of each process in the sending operation. - -return **`string`** The info for each process - -```C++ -const char *info(); -``` - - - - -#### Provide the status of completion. - -return **`boolean`** The bool value indicates that all sending processes are finished - -```C++ -bool success(); -``` - - - - - -#### To clear all data store in this class. - -```C++ -void empty(); -``` - - - - -#### Provide the number of complete sending message. - -return **`number`** The number of message that was sent - -```C++ -size_t completedCount(); -``` - - - - - -#### Provide the number of failed sending message. - -return **`number`** The number of message that was not sent - -```C++ -size_t failedCount(); -``` - - - - -## SendingResult class functions - - -The following functions are available from the SendingResult class. - -This class is used for retrieving the info about the result of sending the messages. - - - - -#### Provide the information of a message sending status. - -param **`index`** The index number of a message sending status - -return **`SMTP_Result`** The SMTP_Result type data that provides these properties - -##### [bool] completed - The status of the message - -#### [const char *] recipients - The primary recipient mailbox of the message - -#### [const char *] subject - The topic of the message - -#### [time_t] timesstamp - The timestamp of the message - -```C++ -SMTP_Result getItem(size_t index); -``` - - - - - -#### Provide the amount of the result data. - -return **`number`** The number of result item - -```C++ -size_t size(); -``` - - - - -## FoldersCollection class functions - - -The following functions are available from the FoldersCollection class. - -This class is used for retrieving the info about the mailbox folders which available to read or serach -in the user Email mailbox. - - - - -#### Provide the information of a folder in a folder collection. - -param **`index`** The index number of folders - -return **`esp_mail_folder_info_item_t`** The esp_mail_folder_info_item_t structured data that provides these properties - -#### [const char *] name - The name of folder - -#### [const char *] attributes - The attributes of folder - -#### [const char *] delimiter - The delimeter of folder - -```C++ -esp_mail_folder_info_item_t info(size_t index); -``` - - - - - -#### Provide the number of folders in the collection. - -return **`number`** The number of folder in the collection - -```C++ -size_t size(); -``` - - - - - - -## SelectedFolderInfo class functions - - -The following functions are available from the SelectedFolderInfo class. - -This class is used for retrieving the info about the sselected or opened mailbox folder. - - - - -#### Provide the numbers of flags in the user Email mailbox. - -return **`number`** The numbers of flags - -```C++ -size_t flagCount(); -``` - - - - - -#### Provide the numbers of messages in this mailbox. - -return **`number`** The numbers of messages in the selected mailbox folder - -```C++ -size_t msgCount(); -``` - - - - - -#### Provide the predicted next message UID in the sselected folder. - -return **`number`** The number represents the next message UID number - -```C++ -size_t nextUID(); -``` - - - - - -#### Provide the numbers of messages from search result based on the search criteria. - -return **`number`** The total number of messsages from search - -```C++ -size_t searchCount(); -``` - - - - - -#### Provide the numbers of messages to be stored in the ressult. - -return **`number`** The number of messsage stored from search - -```C++ -size_t availableMessages(); -``` - - - - - -#### Provide the flag argument at the specified index. - -return **`index`** The index of flag in the flags list - -return **`String`** The argument of selected flag - -```C++ -String flag(size_t index); -``` - - - - -## ESP_Mail_Session type data - - -The following properties are available from the ESP_Mail_Session data type. - -This data type is used for storing the session info about the server and login credentials. - - -#### [Properties] The server config - -This property has the sub properties - -##### [const char *] host_name - The hostName of the server. - -##### [uint16_t] port - The port on the server to connect to. - -```C++ -esp_mail_sesson_sever_config_t server; -``` - - -#### [Properties] The log in config - -This property has the sub properties - -##### [const char *] email - The user Email address to log in. - -##### [consst char *] password - The user password to log in. - -##### [consst char *] accessToken - The OAuth2.0 access token to log in. - -##### [consst char *] user_domain - The user domain or ip of client. - -```C++ -esp_mail_sesson_login_config_t login; -``` - - -#### [Properties] The secure config - -This property has the sub properties - -##### [bool] startTLS - The option to send the command to start the TLS connection. - -```C++ -esp_mail_sesson_secure_config_t secure; -``` - - - -#### [Properties] The certificate config - -##### [const char *] cert_data - The certificate data (base64 data). - -##### [consst char *] cert_file - The certificate file (DER format). - -##### [esp_mail_file_storage_type] cert_file_storage_type - The storage type. - -```C++ -esp_mail_sesson_cert_config_t certificate; -``` - - - - -## IMAP_Config type data - - -The following properties are available from the IMAP_Config data type. - -This data type is used for storing the IMAP transport and operating options to -control and store the operation result e.g. the messahe contents from search and fetch. - - - - -#### [Properties] The config for fetching - -This property has the sub property - -##### [const char *] uid - The UID of message to fetch. - -```C++ -esp_mail_imap_fetch_config_t fetch; -``` - - -#### [Properties] The config for search - -This property has the sub properties - -##### [const char *] criteria - The search criteria. - -##### [boolean] unseen_msg - The option to search the unseen message. - -```C++ -esp_mail_imap_search_config_t search; -``` - - -#### [Properties] The config about the limits - -This property has the sub properties - -##### [size_t] search - The maximum messages from the search result. - -##### [size_t] msg_size - The maximum size of the memory buffer to store the message content. - -This is only limit for data to be stored in the IMAPSession. - -##### [size_t] attachment_size - The maximum size of each attachment to download. - -```C++ -esp_mail_imap_limit_config_t limit; -``` - - - -#### [Properties] The config to enable the features - -This property has the sub properties - -##### [boolean] text - To store the PLAIN text of the message in the IMAPSession. - -##### [boolean] html - To store the HTML of the message in the IMAPSession. - -##### [boolean] rfc822 - To store the rfc822 messages in the IMAPSession. - -##### [boolean] download_status - To enable the download status via the serial port. - -##### [boolean] recent_sort - To sort the message UID of the search result in descending order. - -```C++ -esp_mail_imap_enable_config_t enable; -``` - - - -#### [Properties] The config about downloads - -This property has the sub properties - -##### [boolean] text - To download the PLAIN text content of the message. - -##### [boolean] html - To download the HTML content of the message. - -##### [boolean] attachment - To download the attachments of the message. - -##### [boolean] inlineImg - To download the inline image of the message. - -##### [boolean] rfc822 - To download the rfc822 mesages in the message. - -##### [boolean] header - To download the message header. - -```C++ -esp_mail_imap_download_config_t download; -``` - - - -#### [Properties] The config about the storage and path to save the downloaded file. - -This property has the sub properties - -##### [const char*] saved_path - The path to save the downloaded file. - -##### [esp_mail_file_storage_type] type - The type of file storages enumeration e.g. - -esp_mail_file_storage_type_none = 0, - -esp_mail_file_storage_type_flash = 1, and - -esp_mail_file_storage_type_sd = 2 - -```C++ -esp_mail_imap_storage_config_t storage; -``` - - - - - -## esp_mail_smtp_embed_message_body_t structured data - - -The following properties are available from the IMAP_Config data type. - -This data type is used for storing the IMAP transport and operating options to -control and store the operation result e.g. the messahe contents from search and fetch. - - - - -##### [Properties] Enable to send this message body as file - -```C++ -bool enable; -``` - - -##### [Properties] The name of embedded file - -```C++ -const char* enable; -``` - - -##### [Properties] The embedded type enumeration - -esp_mail_smtp_embed_message_type_attachment = 0 - -sp_mail_smtp_embed_message_type_inline = 1 - -```C++ -esp_mail_smtp_embed_message_type type; -``` - - - - - - -## esp_mail_blob_message_content_t structured data - - -The following properties are available from the esp_mail_blob_message_content_t data type. - -This data type is used for storing the blob info of message body. - - - - -##### [Properties] The array of content in flash memory. - -```C++ -const uint8_t * data; -``` - - -##### [Properties] The array size in bytes. - -```C++ -size_t size; -``` - - - - - -## esp_mail_file_message_content_t structured data - - -The following properties are available from the esp_mail_file_message_content_t data type. - -This data type is used for storing the file info of message body. - - - - -##### [Properties] The file path include its name. - -```C++ -const char *name; -``` - - -##### [Properties] The type of file storages. - -```C++ -esp_mail_file_storage_type type; -``` - - - - - - -## IMAP_MSG_Item type data - - -The following properties are available from the IMAP_MSG_Item data type. - -This data type is used for message item info and its contents from search and fetch. - - - - -#### [Properties] The message number - -```C++ -const char *msgNo; -``` - - -#### [Properties] The message UID - -```C++ -const char *UID; -``` - - -#### [Properties] The message identifier - -```C++ -const char *ID; -``` - - - -#### [Properties] The language(s) for auto-responses - -```C++ -const char *acceptLang; -``` - - - -#### [Properties] The language of message content - -```C++ -const char *contentLang; -``` - - - -#### [Properties] The mailbox of message author - -```C++ -const char *from; -``` - - -#### [Properties] The charset of the mailbox of message author - -```C++ -const char *fromCharset; -``` - - -#### [Properties] The primary recipient mailbox - -```C++ -const char *to; -``` - - -#### [Properties] The charset of the primary recipient mailbox - -```C++ -const char *toCharset; -``` - - -#### [Properties] The Carbon-copy recipient mailboxes - -```C++ -const char *cc; -``` - - -#### [Properties] The charset of the Carbon-copy recipient mailbox header - -```C++ -const char *ccCharset; -``` - -#### [Properties] The message date and time - -```C++ -const char *date; -``` - -#### [Properties] The topic of message - -```C++ -const char *subject; -``` - -#### [Properties] The topic of message charset - -```C++ -const char *subjectCharset; -``` - -#### [Properties] The PLAIN text content of the message - -```C++ -esp_mail_plain_body_t text; -``` - -#### [Properties] The HTML content of the message - -```C++ -esp_mail_html_body_t html; -``` - -#### [Properties] The sender Email - -```C++ -const char *sender; -``` - -#### [Properties] The message identifier - -```C++ -const char *messageID; -``` - -#### [Properties] The keywords or phrases, separated by commas - -```C++ -const char *keyword; -``` - -#### [Properties] The comment about message - -```C++ -const char *comment; -``` - - -#### [Properties] The return recipient of the message - -```C++ -const char *return_path; -``` - - -#### [Properties] The Email address to reply - -```C++ -const char *reply_to; -``` - - -#### [Properties] The Blind carbon-copy recipients - -```C++ -const char *bcc; -``` - - -#### [Properties] The error description from fetching the message - -```C++ -const char *fetchError; -``` - - -#### [Properties] The info about the attachments in the message - -```C++ -std::vector attachments; -``` - -#### [Properties] The info about the rfc822 messages included in the message - -```C++ -std::vector rfc822; -``` - - - - - - -## Search Criteria - -Search crieria is used for searching the mailbox for messages that match -the given searching criteria. - -Searching criteria consist of one or more search keys. When multiple keys are -specified, the result is the intersection (AND function) of all the messages -that match those keys. - -Example: - - **`DELETED FROM "SMITH" SINCE 1-Feb-1994`** refers -to all deleted messages from Smith that were placed in the mailbox since -February 1, 1994. - -A search key can also be a parenthesized list of one or more search keys -(e.g., for use with the OR and NOT keys). - -**`SINCE 10-Feb-2019`** will search all messages that received since 10 Feb 2019 - -**`UID SEARCH ALL`** will seach all message which will return the message UID -that can be use later for fetch one or more messages. - - -The following keywords can be used for the search criteria. - - -**ALL** - All messages in the mailbox; the default initial key for ANDing. - -**ANSWERED** - Messages with the \Answered flag set. - -**BCC** - Messages that contain the specified string in the envelope structure's BCC field. - -**BEFORE** - Messages whose internal date (disregarding time and timezone) is earlier than the specified date. - -**BODY** - Messages that contain the specified string in the body of the message. - -**CC** - Messages that contain the specified string in the envelope structure's CC field. - -**DELETED** - Messages with the \Deleted flag set. - -**DRAFT** - Messages with the \Draft flag set. - -**FLAGGED** - Messages with the \Flagged flag set. - -**FROM** - Messages that contain the specified string in the envelope structure's FROM field. - -**HEADER** - Messages that have a header with the specified field-name (as defined in [RFC-2822]) - -and that contains the specified string in the text of the header (what comes after the colon). - -If the string to search is zero-length, this matches all messages that have a header line with - -the specified field-name regardless of the contents. - -**KEYWORD** - Messages with the specified keyword flag set. - -**LARGER** - Messages with an (RFC-2822) size larger than the specified number of octets. - -**NEW** - Messages that have the \Recent flag set but not the \Seen flag. - -This is functionally equivalent to **"(RECENT UNSEEN)"**. - -**NOT** - Messages that do not match the specified search key. - -**OLD** - Messages that do not have the \Recent flag set. This is functionally equivalent to - -**"NOT RECENT"** (as opposed to **"NOT NEW"**). - -**ON** - Messages whose internal date (disregarding time and timezone) is within the specified date. - -**OR** - Messages that match either search key. - -**RECENT** - Messages that have the \Recent flag set. - -**SEEN** - Messages that have the \Seen flag set. - -**SENTBEFORE** - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is earlier than the specified date. - -**SENTON** - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is within the specified date. - -**SENTSINCE** - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is within or later than the specified date. - -**SINCE** - Messages whose internal date (disregarding time and timezone) is within or later than the specified date. - -**SMALLER** - Messages with an (RFC-2822) size smaller than the specified number of octets. - -**SUBJECT** - Messages that contain the specified string in the envelope structure's SUBJECT field. - -**TEXT** - Messages that contain the specified string in the header or body of the message. - -**TO** - Messages that contain the specified string in the envelope structure's TO field. - -**UID** - Messages with unique identifiers corresponding to the specified unique identifier set. - -Sequence set ranges are permitted. - -**UNANSWERED** - Messages that do not have the \Answered flag set. - -**UNDELETED** - Messages that do not have the \Deleted flag set. - -**UNDRAFT** - Messages that do not have the \Draft flag set. - -**UNFLAGGED** - Messages that do not have the \Flagged flag set. - -**UNKEYWORD** - Messages that do not have the specified keyword flag set. - -**UNSEEN** - Messages that do not have the \Seen flag set. - - - - - - - - - -## MailClient.Time functions - - -The helper function to set and get the system time. - - - - - -#### Set the system time from the NTP server - -param **`gmtOffset`** The GMT time offset in hour. - -param **`daylightOffset`** The Daylight time offset in hour. - -return **`boolean`** The status indicates the success of operation. - -This requires internet connection - -```C++ -bool setClock(float gmtOffset, float daylightOffset); -``` - - - - - - -#### Provide the Unix time - -return **`uint32_t`** The value of current Unix time. - -```C++ -uint32_t getUnixTime(); -``` - - - - - - -#### Provide the timestamp from the year, month, date, hour, minute, and second provided - -param **`year`** The year. - -param **`mon`** The months from 1 to 12. - -param **`date`** The dates. - -param **`hour`** The hours. - -param **`mins`** The minutes. - -param **`sec`** The seconds. - -return **`time_t`** The value of timestamp. - -```C++ -time_t getTimestamp(int year, int mon, int date, int hour, int mins, int sec); -``` - - - - - - -#### Provide the current year. - -return **`int`** The value of current year. - -```C++ -int getYear(); -``` - - - - - - -#### Provide the current month. - -return **`int`** The value of current month. - -```C++ -int getMonth(); -``` - - - - - -#### Provide the current date. - -return **`int`** The value of current date. - -```C++ -int getDay(); -``` - - - - - - -#### Provide the current day of week. - -return **`int`** The value of day of week. - -1 for sunday and 7 for saturday - -```C++ -int getDayOfWeek(); -``` - - - - - -#### Provide the current day of week in String. - -return **`String`** The value of day of week. - -Returns sunday, monday, tuesday, wednesday, thurseday, friday and saturday. - -```C++ -String getDayOfWeekString(); -``` - - - - - - -#### Provide the current hour. - -return **`int`** The value of current hour (0 to 23). - -```C++ -int getHour(); -``` - - - - - - -#### Provide the current minute. - -return **`int`** The value of current minute (0 to 59). - -```C++ -int getMin(); -``` - - - - - - -#### Provide the current second. - -return **`int`** The value of current second (0 to 59). - -```C++ -int getSecond(); -``` - - - - - - - -#### Provide the total days of current year. - -return **`int`** The value of total days of current year. - -```C++ -int getNumberOfDayThisYear(); -``` - - - - - - -#### Provide the total days of from January 1, 1970 to specific date. - -param **`year`** The years from 1970. - -param **`mon`** The months from 1 to 12. - -param **`date`** The dates. - -return **`int`** The value of total days. - -```C++ -int getTotalDays(int year, int month, int day); -``` - - - - - -#### Provide the day of week from specific date. - -param **`year`** The years. - -param **`month`** The months from 1 to 12. - -param **`day`** The dates. - -return **`int`** The value of day of week. - -1 for sunday and 7 for saturday - -```C++ -int dayofWeek(int year, int month, int day); -``` - - - - - - -#### Provide the second of current hour. - -return **`int`** The value of current second. - -```C++ -int getCurrentSecond(); -``` - - - - - -#### Provide the current timestamp. - -return **`uint64_t`** The value of current timestamp. - -```C++ -uint64_t getCurrentTimestamp(); -``` - - - - - - -#### Provide the date and time from second counted from January 1, 1970. - -param **`sec`** The seconds from January 1, 1970 00.00. - -return **`tm`** The tm structured data. - -The returned structured data tm has the members e.g. - -tm_year (from 1900), tm_mon (from 0 to 11), tm_mday, tm_hour, tm_min and tm_sec. - -```C++ -struct tm getTimeFromSec(int secCount); -``` - - - - - - -#### Provide the current date time string that valid for Email - -return **`String`** The current date time string. - -```C++ -String getDateTimeString(); -``` - - - - - - - -## License - -The MIT License (MIT) - -Copyright (c) 2021 K. Suwatchai (Mobizt) - - -Permission is hereby granted, free of charge, to any person returning a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/lib/libesp32/lib_mail/src/SDK_Version_Common.h b/lib/libesp32/lib_mail/src/SDK_Version_Common.h deleted file mode 100644 index c0db7a62cb9f..000000000000 --- a/lib/libesp32/lib_mail/src/SDK_Version_Common.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _SDK_VERSION_COMMON_H -#define _SDK_VERSION_COMMON_H - -#if defined(ESP8266) - -#include - -//__GNUC__ -//__GNUC_MINOR__ -//__GNUC_PATCHLEVEL__ - -#ifdef __GNUC__ -#if __GNUC__ > 4 || __GNUC__ == 10 -#define ESP8266_CORE_SDK_V3_X_X -#endif -#endif - -#endif - -#endif \ No newline at end of file diff --git a/lib/libesp32/lib_mail/src/extras/ESPTimeHelper.cpp b/lib/libesp32/lib_mail/src/extras/ESPTimeHelper.cpp deleted file mode 100644 index b88b1c753d77..000000000000 --- a/lib/libesp32/lib_mail/src/extras/ESPTimeHelper.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* - * ESP8266/ESP32 Internet Time Helper Arduino Library v 1.0.2 - * - * The MIT License (MIT) - * Copyright (c) 2021 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person returning a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef ESPTimeHelper_CPP -#define ESPTimeHelper_CPP - -#include "ESPTimeHelper.h" - -ESPTimeHelper::ESPTimeHelper() -{ -} - -uint32_t ESPTimeHelper::getUnixTime() -{ - uint32_t utime = (msec_time_diff + millis()) / 1000; - return utime; -} - -int ESPTimeHelper::setTimestamp(time_t ts) -{ - struct timeval tm = {ts, 0};//sec, us - return settimeofday((const timeval *)&tm, 0); -} - -time_t ESPTimeHelper::getTimestamp(int year, int mon, int date, int hour, int mins, int sec) -{ - struct tm timeinfo; - timeinfo.tm_year = year - 1900; - timeinfo.tm_mon = mon - 1; - timeinfo.tm_mday = date; - timeinfo.tm_hour = hour; - timeinfo.tm_min = mins; - timeinfo.tm_sec = sec; - time_t ts = mktime(&timeinfo); - return ts; -} - -bool ESPTimeHelper::setClock(float gmtOffset, float daylightOffset) -{ - TZ = gmtOffset; - DST_MN = daylightOffset; - configTime((TZ)*3600, (DST_MN)*60, "pool.ntp.org", "time.nist.gov"); - - now = time(nullptr); - uint8_t attempts = 0; - while (now < 1577836800) - { - now = time(nullptr); - attempts++; - if (attempts > 200 || now > 1577836800) - break; - delay(100); - } - - uint64_t tmp = now; - tmp = tmp * 1000; - msec_time_diff = tmp - millis(); - -#if defined(ESP32) - getLocalTime(&timeinfo); -#elif defined(ESP8266) - gmtime_r(&now, &timeinfo); -#endif - - clockReady = now > 8 * 3600 * 2; - return clockReady; -} - -int ESPTimeHelper::getYear() -{ - setSysTime(); - return timeinfo.tm_year + 1900; -} -int ESPTimeHelper::getMonth() -{ - setSysTime(); - return timeinfo.tm_mon + 1; -} -int ESPTimeHelper::getDay() -{ - setSysTime(); - return timeinfo.tm_mday; -} - -int ESPTimeHelper::getDayOfWeek() -{ - setSysTime(); - return timeinfo.tm_wday; -} -String ESPTimeHelper::getDayOfWeekString() -{ - setSysTime(); - return dow[timeinfo.tm_wday]; -} - -int ESPTimeHelper::getHour() -{ - setSysTime(); - return timeinfo.tm_hour; -} - -int ESPTimeHelper::getMin() -{ - setSysTime(); - return timeinfo.tm_min; -} -int ESPTimeHelper::getSec() -{ - setSysTime(); - return timeinfo.tm_sec; -} -int ESPTimeHelper::getNumberOfDayThisYear() -{ - setSysTime(); - return timeinfo.tm_yday + 1; -} - -int ESPTimeHelper::totalDays(int y, int m, int d) -{ - static char daytab[2][13] = - { - {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; - int daystotal = d; - for (int year = 1; year <= y; year++) - { - int max_month = (year < y ? 12 : m - 1); - int leap = (year % 4 == 0); - if (year % 100 == 0 && year % 400 != 0) - leap = 0; - for (int month = 1; month <= max_month; month++) - { - daystotal += daytab[leap][month]; - } - } - return daystotal; -} -int ESPTimeHelper::getTotalDays(int year, int month, int day) -{ - return totalDays(year, month, day) - totalDays(1970, 1, 1); -} - -int ESPTimeHelper::dayofWeek(int year, int month, int day) /* 1 <= m <= 12, y > 1752 (in the U.K.) */ -{ - static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; - year -= month < 3; - return (year + year / 4 - year / 100 + year / 400 + t[month - 1] + day) % 7; -} - -int ESPTimeHelper::getCurrentSecond() -{ - return (timeinfo.tm_hour * 3600) + (timeinfo.tm_min * 60) + timeinfo.tm_sec; -} -uint64_t ESPTimeHelper::getCurrentTimestamp() -{ - return now; -} -struct tm ESPTimeHelper::getTimeFromSec(int seconds) -{ - struct tm timeinfo; - int _yrs = seconds / (365 * 24 * 3600); - seconds = seconds - _yrs * (365 * 24 * 3600); - timeinfo.tm_year = _yrs - 1900; - int _months = seconds / (30 * 24 * 3600); - seconds = seconds - _months * (30 * 24 * 3600); - timeinfo.tm_mon = _months - 1; - int _days = seconds / (24 * 3600); - seconds = seconds - _days * (24 * 3600); - timeinfo.tm_mday = _days; - int _hr = seconds / 3600; - seconds = seconds - _hr * 3600; - timeinfo.tm_hour = _hr; - int _min = seconds / 60; - seconds = seconds - _min * 60; - timeinfo.tm_min = _min; - timeinfo.tm_sec = seconds; - return timeinfo; -} - -char *ESPTimeHelper::intStr(int value) -{ - char *buf = new char[36]; - memset(buf, 0, 36); - itoa(value, buf, 10); - return buf; -} - -String ESPTimeHelper::getDateTimeString() -{ - setSysTime(); - std::string s; - - s = sdow[timeinfo.tm_wday]; - - s += ", "; - char *tmp = intStr(timeinfo.tm_mday); - s += tmp; - delete[] tmp; - - s += " "; - s += months[timeinfo.tm_mon]; - - s += " "; - tmp = intStr(timeinfo.tm_year + 1900); - s += tmp; - delete[] tmp; - - s += " "; - if (timeinfo.tm_hour < 10) - s += "0"; - tmp = intStr(timeinfo.tm_hour); - s += tmp; - delete[] tmp; - - s += ":"; - if (timeinfo.tm_min < 10) - s += "0"; - tmp = intStr(timeinfo.tm_min); - s += tmp; - delete[] tmp; - - s += ":"; - if (timeinfo.tm_sec < 10) - s += "0"; - tmp = intStr(timeinfo.tm_sec); - s += tmp; - delete[] tmp; - - int p = 1; - if (TZ < 0) - p = -1; - int tz = TZ; - float dif = (p * (TZ - tz)) * 60.0; - if (TZ < 0) - s += " -"; - else - s += " +"; - - if (tz < 10) - s += "0"; - tmp = intStr(tz); - s += tmp; - delete[] tmp; - - if (dif < 10) - s += "0"; - tmp = intStr((int)dif); - s += tmp; - delete[] tmp; - - return s.c_str(); -} - -void ESPTimeHelper::setSysTime() -{ -#if defined(ESP32) - getLocalTime(&timeinfo); -#elif defined(ESP8266) - now = time(nullptr); - localtime_r(&now, &timeinfo); -#endif -} - -#endif //ESPTimeHelper_CPP \ No newline at end of file diff --git a/lib/libesp32/lib_mail/src/extras/ESPTimeHelper.h b/lib/libesp32/lib_mail/src/extras/ESPTimeHelper.h deleted file mode 100644 index 2cc5fcddfa7b..000000000000 --- a/lib/libesp32/lib_mail/src/extras/ESPTimeHelper.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * ESP8266/ESP32 Internet Time Helper Arduino Library v 1.0.2 - * - * The MIT License (MIT) - * Copyright (c) 2021 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person returning a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef ESPTimeHelper_H -#define ESPTimeHelper_H - -#include -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#include "SDK_Version_Common.h" -#endif - -class ESPTimeHelper -{ -public: - ESPTimeHelper(); - - /** Set the system time from the NTP server - * - * @param gmtOffset The GMT time offset in hour. - * @param daylightOffset The Daylight time offset in hour. - * @return boolean The status indicates the success of operation. - * - * @note This requires internet connection - */ - bool setClock(float gmtOffset, float daylightOffset); - - /** Set system time with provided timestamp - * - * @param ts timestamp in seconds from midnight Jan 1, 1970. - * @return error number, 0 for success. - */ - int setTimestamp(time_t ts); - - /** Provide the Unix time - * - * @return uint32_t The value of current Unix time. - */ - uint32_t getUnixTime(); - - /** Provide the timestamp from the year, month, date, hour, minute, - * and second provided. - * - * @param year The year. - * @param mon The month from 1 to 12. - * @param date The dates. - * @param hour The hours. - * @param mins The minutes. - * @param sec The seconds. - * @return time_t The value of timestamp. - */ - time_t getTimestamp(int year, int mon, int date, int hour, int mins, int sec); - - /** Provide the current year. - * - * @return int The value of current year. - */ - int getYear(); - - /** Provide the current month. - * - * @return int The value of current month. - */ - int getMonth(); - - /** Provide the current date. - * - * @return int The value of current date. - */ - int getDay(); - - /** Provide the current day of week. - * - * @return int The value of current day of week. - * - * @note 1 for sunday and 7 for saturday. - */ - int getDayOfWeek(); - - /** Provide the current day of week in String. - * - * @return String The value of day of week. - */ - String getDayOfWeekString(); - - /** Provide the current hour. - * - * @return int The value of current hour (0 to 23). - */ - int getHour(); - - /** Provide the current minute. - * - * @return int The value of current minute. - */ - int getMin(); - - /** Provide the current second. - * - * @return int The value of current second. - */ - int getSec(); - - /** Provide the total days of current year. - * - * @return int The value of total days of current year. - */ - int getNumberOfDayThisYear(); - - /** Provide the total days of from January 1, 1970 to specific date. - * - * @param year The year from 1970. - * @param mon The month from 1 to 12. - * @param day The dates. - * @return int The value of total days. - */ - int getTotalDays(int year, int month, int day); - - /** Provide the day of week from specific date. - * - * @param year The year from 1970. - * @param mon The month from 1 to 12. - * @param day The dates. - * @return int the value of day of week. - * @note 1 for sunday and 7 for saturday - */ - int dayofWeek(int year, int month, int day); - - /** Provide the second of current hour. - * - * @return int The value of current second. - */ - int getCurrentSecond(); - - /** Provide the current timestamp. - * - * @return uint64_t The value of current timestamp. - */ - uint64_t getCurrentTimestamp(); - - /** Provide the date and time from second counted from January 1, 1970. - * - * @param sec The seconds from January 1, 1970 00.00. - * @return tm The tm structured data. - * - * @note The returned structured data tm has the members e.g. - * tm_year (from 1900), tm_mon (from 0 to 11), tm_mday, tm_hour, - * tm_min and tm_sec. - */ - struct tm getTimeFromSec(int seconds); - - /** Provide the current date time string that valid for Email. - * - * @return String The current date time string. - */ - String getDateTimeString(); - - time_t now; - uint64_t msec_time_diff = 0; - struct tm timeinfo; - float TZ = 0.0; - uint8_t DST_MN = 0; - bool clockReady = false; - -private: - int totalDays(int y, int m, int d); - char *intStr(int value); - void setSysTime(); - const char *dow[7] = {"sunday", "monday", "tuesday", "wednesday", "thurseday", "friday", "saturday"}; - const char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - const char *sdow[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; -}; - -#endif //ESPTimeHelper_H diff --git a/lib/libesp32/lib_mail/src/extras/MIMEInfo.h b/lib/libesp32/lib_mail/src/extras/MIMEInfo.h deleted file mode 100644 index 38269eb6b0b3..000000000000 --- a/lib/libesp32/lib_mail/src/extras/MIMEInfo.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef MIMEInfo_H -#define MIMEInfo_H -#include - -enum esp_mail_file_extension -{ - esp_mail_file_extension_html, - esp_mail_file_extension_htm, - esp_mail_file_extension_css, - esp_mail_file_extension_txt, - esp_mail_file_extension_js, - esp_mail_file_extension_json, - esp_mail_file_extension_png, - esp_mail_file_extension_gif, - esp_mail_file_extension_jpg, - esp_mail_file_extension_ico, - esp_mail_file_extension_svg, - esp_mail_file_extension_ttf, - esp_mail_file_extension_otf, - esp_mail_file_extension_woff, - esp_mail_file_extension_woff2, - esp_mail_file_extension_eot, - esp_mail_file_extension_sfnt, - esp_mail_file_extension_xml, - esp_mail_file_extension_pdf, - esp_mail_file_extension_zip, - esp_mail_file_extension_gz, - esp_mail_file_extension_appcache, - esp_mail_file_extension_none, - esp_mail_file_extension_maxType -}; - -struct esp_mail_mime_prop_t -{ - char endsWith[10]; - char mimeType[50]; -}; - -const struct esp_mail_mime_prop_t mimeinfo[esp_mail_file_extension_maxType] PROGMEM = - { - {".html", "text/html"}, - {".htm", "text/html"}, - {".css", "text/css"}, - {".txt", "text/plain"}, - {".js", "application/javascript"}, - {".json", "application/json"}, - {".png", "image/png"}, - {".gif", "image/gif"}, - {".jpg", "image/jpeg"}, - {".ico", "image/x-icon"}, - {".svg", "image/svg+xml"}, - {".ttf", "application/x-font-ttf"}, - {".otf", "application/x-font-opentype"}, - {".woff", "application/font-woff"}, - {".woff2", "application/font-woff2"}, - {".eot", "application/vnd.ms-fontobject"}, - {".sfnt", "application/font-sfnt"}, - {".xml", "text/xml"}, - {".pdf", "application/pdf"}, - {".zip", "application/zip"}, - {".gz", "application/x-gzip"}, - {".appcache", "text/cache-manifest"}, - {"", "application/octet-stream"}}; - -#endif diff --git a/lib/libesp32/lib_mail/src/extras/RFC2047.cpp b/lib/libesp32/lib_mail/src/extras/RFC2047.cpp deleted file mode 100644 index 8f5dc31e3f29..000000000000 --- a/lib/libesp32/lib_mail/src/extras/RFC2047.cpp +++ /dev/null @@ -1,237 +0,0 @@ -#ifndef RFC2047_CPP -#define RFC2047_CPP - -#include "RFC2047.h" - -RFC2047_Decoder::RFC2047_Decoder() {} -RFC2047_Decoder::~RFC2047_Decoder() {} - -void RFC2047_Decoder::rfc2047Decode(char *d, const char *s, size_t dlen) -{ - - const char *p, *q; - size_t n; - int found_encoded = 0; - - dlen--; /* save room for the terminal nul */ - - while (*s && dlen > 0) - { - if ((p = strstr (s, "=?")) == NULL || - (q = strchr (p + 2, '?')) == NULL || - (q = strchr (q + 1, '?')) == NULL || - (q = strstr (q + 1, "?=")) == NULL) - { - /* no encoded words */ - if (d != s) - strfcpy (d, s, dlen + 1); - return; - } - - if (p != s) - { - n = (size_t) (p - s); - /* ignore spaces between encoded words */ - if (!found_encoded || strspn (s, " \t\r\n") != n) - { - if (n > dlen) - n = dlen; - if (d != s) - memcpy (d, s, n); - d += n; - dlen -= n; - } - } - - rfc2047DecodeWord (d, p, dlen); - found_encoded = 1; - s = q + 2; - n = strlen (d); - dlen -= n; - d += n; - } - *d = 0; -} - -void RFC2047_Decoder::rfc2047DecodeWord(char *d, const char *s, size_t dlen) -{ - - char *p = safe_strdup (s); - char *pp = p; - char *pd = d; - size_t len = dlen; - int enc = 0, filter = 0, count = 0, c1, c2, c3, c4; - - while ((pp = strtok (pp, "?")) != NULL) - { - count++; - switch (count) - { - case 2: - if (strcasecmp (pp, Charset) != 0) - { - filter = 1; - } - break; - case 3: - if (toupper (*pp) == 'Q') - enc = ENCQUOTEDPRINTABLE; - else if (toupper (*pp) == 'B') - enc = ENCBASE64; - else - return; - break; - case 4: - if (enc == ENCQUOTEDPRINTABLE) - { - while (*pp && len > 0) - { - if (*pp == '_') - { - *pd++ = ' '; - len--; - } - else if (*pp == '=') - { - *pd++ = (hexval(pp[1]) << 4) | hexval(pp[2]); - len--; - pp += 2; - } - else - { - *pd++ = *pp; - len--; - } - pp++; - } - *pd = 0; - } - else if (enc == ENCBASE64) - { - while (*pp && len > 0) - { - c1 = base64val(pp[0]); - c2 = base64val(pp[1]); - *pd++ = (c1 << 2) | ((c2 >> 4) & 0x3); - if (--len == 0) break; - - if (pp[2] == '=') break; - - c3 = base64val(pp[2]); - *pd++ = ((c2 & 0xf) << 4) | ((c3 >> 2) & 0xf); - if (--len == 0) - break; - - if (pp[3] == '=') - break; - - c4 = base64val(pp[3]); - *pd++ = ((c3 & 0x3) << 6) | c4; - if (--len == 0) - break; - - pp += 4; - } - *pd = 0; - } - break; - } - pp = 0; - } - safe_free (&p); - if (filter) - { - - pd = d; - while (*pd) - { - if (!IsPrint (*pd)) - *pd = '?'; - pd++; - } - } - return; -} - -void *RFC2047_Decoder::safe_calloc(size_t nmemb, size_t size) -{ - void *p; - - if (!nmemb || !size) - return NULL; - if (!(p = calloc (nmemb, size))) - { - //out of memory - return NULL; - } - return p; -} - -void *RFC2047_Decoder::safe_malloc(unsigned int siz) -{ - void *p; - - if (siz == 0) - return 0; - if ((p = (void *) malloc (siz)) == 0) - { - //out of memory - return NULL; - } - return (p); -} - -void RFC2047_Decoder::safe_realloc(void **p, size_t siz) -{ - void *r; - - if (siz == 0) - { - if (*p) - { - free (*p); - *p = NULL; - } - return; - } - - if (*p) - r = (void *) realloc (*p, siz); - else - { - r = (void *) malloc (siz); - } - - if (!r) - { - //out of memory - return; - } - - *p = r; -} - -void RFC2047_Decoder::safe_free(void *ptr) -{ - void **p = (void **)ptr; - if (*p) - { - free (*p); - *p = 0; - } -} - -char *RFC2047_Decoder::safe_strdup(const char *s) -{ - char *p; - size_t l; - - if (!s || !*s) return 0; - l = strlen (s) + 1; - p = (char *)safe_malloc (l); - memcpy (p, s, l); - return (p); -} - - -#endif //RFC2047_CPP \ No newline at end of file diff --git a/lib/libesp32/lib_mail/src/wcs/esp32/ESP_Mail_HTTPClient32.cpp b/lib/libesp32/lib_mail/src/wcs/esp32/ESP_Mail_HTTPClient32.cpp deleted file mode 100644 index a1d386ea63ee..000000000000 --- a/lib/libesp32/lib_mail/src/wcs/esp32/ESP_Mail_HTTPClient32.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Customized version of ESP32 HTTPClient Library. - * - * v 1.1.5 - * - * The MIT License (MIT) - * Copyright (c) 2021 K. Suwatchai (Mobizt) - * - * HTTPClient Arduino library for ESP32 - * - * Copyright (c) 2015 Markus Sattler. All rights reserved. - * This file is part of the HTTPClient for Arduino. - * Port to ESP32 by Evandro Luis Copercini (2017), - * changed fingerprints to CA verification. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * -*/ - -#ifndef ESP_Mail_HTTPClient32_CPP -#define ESP_Mail_HTTPClient32_CPP - -#ifdef ESP32 - -#include "ESP_Mail_HTTPClient32.h" - -ESP_Mail_HTTPClient32::ESP_Mail_HTTPClient32() -{ -} - -ESP_Mail_HTTPClient32::~ESP_Mail_HTTPClient32() -{ - if (_wcs) - { - _wcs->stop(); - _wcs.reset(nullptr); - _wcs.release(); - } - std::string().swap(_host); - std::string().swap(_caCertFile); -} - -bool ESP_Mail_HTTPClient32::begin(const char *host, uint16_t port) -{ - _host = host; - _port = port; - return true; -} - -bool ESP_Mail_HTTPClient32::connected() -{ - if (_wcs) - { - if (_secured) - return _wcs->connected(); - else - return _wcs->_ns_connected(); - } - return false; -} - -bool ESP_Mail_HTTPClient32::send(const char *header) -{ - if (!connected()) - return false; - if (_secured) - return (_wcs->write(header, strlen(header)) == strlen(header)); - else - return (_wcs->_ns_write(header, strlen(header)) == strlen(header)); -} - -int ESP_Mail_HTTPClient32::send(const char *header, const char *payload) -{ - size_t size = strlen(payload); - if (strlen(header) > 0) - { - if (!connect(_secured)) - { - return ESP_MAIL_ERROR_HTTPC_ERROR_CONNECTION_REFUSED; - } - - if (!send(header)) - { - return ESP_MAIL_ERROR_HTTPC_ERROR_SEND_HEADER_FAILED; - } - } - - if (size > 0) - { - if (_secured) - { - if (_wcs->write(&payload[0], size) != size) - return ESP_MAIL_ERROR_HTTPC_ERROR_SEND_PAYLOAD_FAILED; - } - else - { - if (_wcs->_ns_write(&payload[0], size) != size) - return ESP_MAIL_ERROR_HTTPC_ERROR_SEND_PAYLOAD_FAILED; - } - } - - return 0; -} - -WiFiClient *ESP_Mail_HTTPClient32::stream(void) -{ - if (connected()) - return _wcs.get(); - return nullptr; -} -ESP_Mail_WCS32 *ESP_Mail_HTTPClient32::_stream(void) -{ - if (connected()) - return _wcs.get(); - return nullptr; -} - -size_t ESP_Mail_HTTPClient32::_ns_print(const char *buf) -{ - size_t size = strlen(buf); - return _wcs->_ns_write(&buf[0], size); -} - -size_t ESP_Mail_HTTPClient32::_ns_println(const char *buf) -{ - size_t size = strlen(buf); - size_t wr = _wcs->_ns_write((const char *)&buf[0], size); - std::string s = "\r\n"; - wr += _wcs->_ns_write(s.c_str(), s.length()); - return wr; -} - -bool ESP_Mail_HTTPClient32::connect(void) -{ - return connect(false); -} - -bool ESP_Mail_HTTPClient32::connect(bool secured) -{ - _secured = secured; - - if (connected()) - { - if (_secured) - { - while (_wcs->available() > 0) - _wcs->read(); - } - else - { - while (_wcs->_ns_available() > 0) - _wcs->_ns_read(); - } - return true; - } - - if (_debugCallback) - _wcs->setDebugCB(&_debugCallback); - _wcs->setSTARTTLS(!secured); - - if (!_wcs->connect(_host.c_str(), _port)) - return false; - return connected(); -} - -void ESP_Mail_HTTPClient32::setDebugCallback(DebugMsgCallback cb) -{ - _debugCallback = std::move(cb); -} - -void ESP_Mail_HTTPClient32::setCACert(const char *caCert) -{ - _wcs->setCACert(caCert); - if (caCert) - _certType = 1; - else - { - setInsecure(); - _certType = 0; - } - //_wcs->setNoDelay(true); -} - -void ESP_Mail_HTTPClient32::setCertFile(const char *caCertFile, esp_mail_file_storage_type storageType) -{ - - if (strlen(caCertFile) > 0) - { - File f; - if (storageType == esp_mail_file_storage_type_flash) - { - ESP_MAIL_FLASH_FS.begin(); - if (ESP_MAIL_FLASH_FS.exists(caCertFile)) - f = ESP_MAIL_FLASH_FS.open(caCertFile, FILE_READ); - } - else if (storageType == esp_mail_file_storage_type_sd) - { - ESP_MAIL_SD_FS.begin(); - if (ESP_MAIL_SD_FS.exists(caCertFile)) - f = ESP_MAIL_SD_FS.open(caCertFile, FILE_READ); - } - - if (f) - { - size_t len = f.size(); - _wcs->loadCACert(f, len); - f.close(); - } - _certType = 2; - } - //_wcs->setNoDelay(true); -} - -void ESP_Mail_HTTPClient32::setInsecure() -{ - _wcs->setInsecure(); -} - -#endif //ESP32 - -#endif //ESP_Mail_HTTPClient32_CPP diff --git a/lib/libesp32/lib_mail/src/wcs/esp32/ESP_Mail_HTTPClient32.h b/lib/libesp32/lib_mail/src/wcs/esp32/ESP_Mail_HTTPClient32.h deleted file mode 100644 index 189e25ad156c..000000000000 --- a/lib/libesp32/lib_mail/src/wcs/esp32/ESP_Mail_HTTPClient32.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Customized version of ESP32 HTTPClient Library. - * - * v 1.1.5 - * - * The MIT License (MIT) - * Copyright (c) 2021 K. Suwatchai (Mobizt) - * - * HTTPClient Arduino library for ESP32 - * - * Copyright (c) 2015 Markus Sattler. All rights reserved. - * This file is part of the HTTPClient for Arduino. - * Port to ESP32 by Evandro Luis Copercini (2017), - * changed fingerprints to CA verification. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * -*/ - -#ifndef ESP_Mail_HTTPClient32_H -#define ESP_Mail_HTTPClient32_H - -#ifdef ESP32 - -#include -#include -#include -//#include -#include -#include "ESP_Mail_FS.h" -#include "ESP_Mail_WCS32.h" - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#define ESP_MAIL_FLASH_FS ESP_Mail_DEFAULT_FLASH_FS -#define ESP_MAIL_SD_FS ESP_Mail_DEFAULT_SD_FS - -#if __has_include() || __has_include() -#error WiFi UART bridge was not supported. -#endif - -#define ESP_MAIL_ERROR_HTTPC_ERROR_CONNECTION_REFUSED (-1) -#define ESP_MAIL_ERROR_HTTPC_ERROR_SEND_HEADER_FAILED (-2) -#define ESP_MAIL_ERROR_HTTPC_ERROR_SEND_PAYLOAD_FAILED (-3) -#define ESP_MAIL_DEFAULT_TCP_TIMEOUT_SEC 30 - -enum esp_mail_file_storage_type -{ - esp_mail_file_storage_type_none, - esp_mail_file_storage_type_flash, - esp_mail_file_storage_type_sd, - esp_mail_file_storage_type_univ -}; - -class ESP_Mail_HTTPClient32 -{ -public: - ESP_Mail_HTTPClient32(); - ~ESP_Mail_HTTPClient32(); - - /** - * Initialization of new http connection. - * \param host - Host name without protocols. - * \param port - Server's port. - * \return True as default. - * If no certificate string provided, use (const char*)NULL to CAcert param - */ - bool begin(const char *host, uint16_t port); - - /** - * Check the http connection status. - * \return True if connected. - */ - bool connected(); - - /** - * Establish http connection if header provided and send it, send payload if provided. - * \param header - The header string (constant chars array). - * \param payload - The payload string (constant chars array), optional. - * \return http status code, Return zero if new http connection and header and/or payload sent - * with no error or no header and payload provided. If obly payload provided, no new http connection was established. - */ - int send(const char *header, const char *payload); - - /** - * Send extra header without making new http connection (if send has been called) - * \param header - The header string (constant chars array). - * \return True if header sending success. - * Need to call send with header first. - */ - bool send(const char *header); - - /** - * Get the WiFi client pointer. - * \return WiFi client pointer. - */ - WiFiClient *stream(void); - - /** - * Set insecure mode - */ - void setInsecure(); - - ESP_Mail_WCS32 *_stream(void); - size_t _ns_print(const char *buf); - size_t _ns_println(const char *buf); - - int tcpTimeout = 40000; - bool connect(void); - bool connect(bool secured); - void setCACert(const char *caCert); - void setCertFile(const char *caCertFile, esp_mail_file_storage_type storageType); - void setDebugCallback(DebugMsgCallback cb); - bool _secured = true; - - int _certType = -1; - std::string _caCertFile = ""; - esp_mail_file_storage_type _caCertFileStoreageType = esp_mail_file_storage_type::esp_mail_file_storage_type_none; - -protected: - DebugMsgCallback _debugCallback = NULL; - std::unique_ptr _wcs = std::unique_ptr(new ESP_Mail_WCS32()); - - std::string _host = ""; - uint16_t _port = 0; -}; - -#endif //ESP32 - -#endif //ESP_Mail_HTTPClient32_H diff --git a/lib/libesp32/lib_mail/src/wcs/esp32/ESP_Mail_WCS32.cpp b/lib/libesp32/lib_mail/src/wcs/esp32/ESP_Mail_WCS32.cpp deleted file mode 100644 index 72946d9e2ae3..000000000000 --- a/lib/libesp32/lib_mail/src/wcs/esp32/ESP_Mail_WCS32.cpp +++ /dev/null @@ -1,564 +0,0 @@ -/* - *Customized WiFiClientSecure.cpp version 1.0.8 - * - * The MIT License (MIT) - * Copyright (c) 2021 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -/* - WiFiClientSecure.cpp - Client Secure class for ESP32 - Copyright (c) 2016 Hristo Gochkov All right reserved. - Additions Copyright (C) 2017 Evandro Luis Copercini. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef ESP_Mail_WCS32_CPP -#define ESP_Mail_WCS32_CPP - -#ifdef ESP32 - -#include "ESP_Mail_WCS32.h" -#include -#include -#include - -#undef connect -#undef write -#undef read - -ESP_Mail_WCS32::ESP_Mail_WCS32() -{ - _connected = false; - - sslclient = new esp_mail_ssl_client32::esp_mail_ssl_ctx32; - _ssl_client32.ssl_init(sslclient); - sslclient->socket = -1; - sslclient->handshake_timeout = 120000; - _use_insecure = false; - _CA_cert = NULL; - _cert = NULL; - _private_key = NULL; - _pskIdent = NULL; - _psKey = NULL; - next = NULL; -} - -ESP_Mail_WCS32::ESP_Mail_WCS32(int sock) -{ - _connected = false; - _timeout = 0; - - sslclient = new esp_mail_ssl_client32::esp_mail_ssl_ctx32; - _ssl_client32.ssl_init(sslclient); - sslclient->socket = sock; - sslclient->handshake_timeout = 120000; - - if (sock >= 0) - { - _connected = true; - } - - _CA_cert = NULL; - _cert = NULL; - _private_key = NULL; - _pskIdent = NULL; - _psKey = NULL; - next = NULL; -} - -ESP_Mail_WCS32::ESP_Mail_WCS32(bool secured) -{ - _connected = false; - - sslclient = new esp_mail_ssl_client32::esp_mail_ssl_ctx32; - _ssl_client32.ssl_init(sslclient); - sslclient->socket = -1; - sslclient->handshake_timeout = 120000; - _use_insecure = !secured; - _secured = secured; - _CA_cert = NULL; - _cert = NULL; - _private_key = NULL; - _pskIdent = NULL; - _psKey = NULL; - next = NULL; -} - -ESP_Mail_WCS32::~ESP_Mail_WCS32() -{ - stop(); - delete sslclient; -} - -ESP_Mail_WCS32 &ESP_Mail_WCS32::operator=(const ESP_Mail_WCS32 &other) -{ - stop(); - sslclient->socket = other.sslclient->socket; - _connected = other._connected; - return *this; -} - -void ESP_Mail_WCS32::stop() -{ - if (sslclient->socket >= 0) - { - close(sslclient->socket); - sslclient->socket = -1; - _connected = false; - _peek = -1; - } - _ssl_client32.stop_ssl_socket(sslclient, _CA_cert, _cert, _private_key); -} - -int ESP_Mail_WCS32::connect(IPAddress ip, uint16_t port) -{ - if (_pskIdent && _psKey) - return connect(ip, port, _pskIdent, _psKey); - return connect(ip, port, _CA_cert, _cert, _private_key); -} - -int ESP_Mail_WCS32::connect(IPAddress ip, uint16_t port, int32_t timeout) -{ - _timeout = timeout; - return connect(ip, port); -} - -int ESP_Mail_WCS32::connect(const char *host, uint16_t port) -{ - if (_pskIdent && _psKey) - return connect(host, port, _pskIdent, _psKey); - return connect(host, port, _CA_cert, _cert, _private_key); -} - -int ESP_Mail_WCS32::connect(const char *host, uint16_t port, int32_t timeout) -{ - _timeout = timeout; - return connect(host, port); -} - -int ESP_Mail_WCS32::connect(IPAddress ip, uint16_t port, const char *CA_cert, const char *cert, const char *private_key) -{ - return connect(ip.toString().c_str(), port, CA_cert, cert, private_key); -} - -int ESP_Mail_WCS32::connect(const char *host, uint16_t port, const char *CA_cert, const char *cert, const char *private_key) -{ - _host = host; - _port = port; - _withCert = true; - - if (_timeout > 0) - { - sslclient->handshake_timeout = _timeout; - } - - int ret = _ssl_client32.start_socket(sslclient, host, port, _timeout, CA_cert, cert, private_key, NULL, NULL, _use_insecure); - - _lastError = ret; - if (ret < 0) - { - log_e("start_ssl_client: %d", ret); - stop(); - return 0; - } - - if (_secured) - { - ret = _ssl_client32.start_ssl_client(sslclient, host, port, _timeout, CA_cert, cert, private_key, NULL, NULL, _use_insecure); - _lastError = ret; - if (ret < 0) - { - log_e("start_ssl_client: %d", ret); - stop(); - return 0; - } - } - - _connected = true; - return 1; -} - -int ESP_Mail_WCS32::connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psKey) -{ - return connect(ip.toString().c_str(), port, pskIdent, psKey); -} - -int ESP_Mail_WCS32::connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey) -{ - _host = host; - _port = port; - _withCert = true; - - log_v("start_ssl_client with PSK"); - if (_timeout > 0) - { - sslclient->handshake_timeout = _timeout; - } - - int ret = _ssl_client32.start_socket(sslclient, host, port, _timeout, NULL, NULL, NULL, pskIdent, psKey, _use_insecure); - _lastError = ret; - if (ret < 0) - { - log_e("start_ssl_client: %d", ret); - stop(); - return 0; - } - - if (_secured) - { - ret = _ssl_client32.start_ssl_client(sslclient, host, port, _timeout, NULL, NULL, NULL, pskIdent, psKey, _use_insecure); - _lastError = ret; - if (ret < 0) - { - log_e("start_ssl_client: %d", ret); - stop(); - return 0; - } - } - _connected = true; - return 1; -} - -int ESP_Mail_WCS32::peek() -{ - if (_peek >= 0) - { - return _peek; - } - _peek = timedRead(); - return _peek; -} - -size_t ESP_Mail_WCS32::write(uint8_t data) -{ - return write(&data, 1); -} - -int ESP_Mail_WCS32::read() -{ - uint8_t data = -1; - int res = read(&data, 1); - if (res < 0) - { - return res; - } - return data; -} - -size_t ESP_Mail_WCS32::write(const uint8_t *buf, size_t size) -{ - if (!_connected) - { - return 0; - } - int res = _ssl_client32.send_ssl_data(sslclient, buf, size); - if (res < 0) - { - stop(); - res = 0; - } - return res; -} - -int ESP_Mail_WCS32::read(uint8_t *buf, size_t size) -{ - int peeked = 0; - int avail = available(); - if ((!buf && size) || avail <= 0) - { - return -1; - } - if (!size) - { - return 0; - } - if (_peek >= 0) - { - buf[0] = _peek; - _peek = -1; - size--; - avail--; - if (!size || !avail) - { - return 1; - } - buf++; - peeked = 1; - } - - int res = _ssl_client32.get_ssl_receive(sslclient, buf, size); - if (res < 0) - { - stop(); - return peeked ? peeked : res; - } - return res + peeked; -} - -int ESP_Mail_WCS32::available() -{ - int peeked = (_peek >= 0); - if (!_connected) - { - return peeked; - } - int res = _ssl_client32.data_to_read(sslclient); - if (res < 0) - { - stop(); - return peeked ? peeked : res; - } - return res + peeked; -} - -uint8_t ESP_Mail_WCS32::connected() -{ - uint8_t dummy = 0; - read(&dummy, 0); - - return _connected; -} - -void ESP_Mail_WCS32::setInsecure() -{ - _CA_cert = NULL; - _cert = NULL; - _private_key = NULL; - _pskIdent = NULL; - _psKey = NULL; - _use_insecure = true; -} - -void ESP_Mail_WCS32::setCACert(const char *rootCA) -{ - _CA_cert = rootCA; -} - -void ESP_Mail_WCS32::setCertificate(const char *client_ca) -{ - _cert = client_ca; -} - -void ESP_Mail_WCS32::setPrivateKey(const char *private_key) -{ - _private_key = private_key; -} - -void ESP_Mail_WCS32::setPreSharedKey(const char *pskIdent, const char *psKey) -{ - _pskIdent = pskIdent; - _psKey = psKey; -} - -bool ESP_Mail_WCS32::verify(const char *fp, const char *domain_name) -{ - if (!sslclient) - return false; - - return _ssl_client32.verify_ssl_fingerprint(sslclient, fp, domain_name); -} - -char *ESP_Mail_WCS32::_streamLoad(Stream &stream, size_t size) -{ - char *dest = (char *)malloc(size + 1); - if (!dest) - { - return nullptr; - } - if (size != stream.readBytes(dest, size)) - { - free(dest); - dest = nullptr; - return nullptr; - } - dest[size] = '\0'; - return dest; -} - -bool ESP_Mail_WCS32::loadCACert(Stream &stream, size_t size) -{ - char *dest = _streamLoad(stream, size); - bool ret = false; - if (dest) - { - setCACert(dest); - ret = true; - } - return ret; -} - -bool ESP_Mail_WCS32::loadCertificate(Stream &stream, size_t size) -{ - char *dest = _streamLoad(stream, size); - bool ret = false; - if (dest) - { - setCertificate(dest); - ret = true; - } - return ret; -} - -bool ESP_Mail_WCS32::loadPrivateKey(Stream &stream, size_t size) -{ - char *dest = _streamLoad(stream, size); - bool ret = false; - if (dest) - { - setPrivateKey(dest); - ret = true; - } - return ret; -} - -int ESP_Mail_WCS32::lastError(char *buf, const size_t size) -{ - if (!_lastError) - { - return 0; - } - mbedtls_strerror(_lastError, buf, size); - return _lastError; -} - -void ESP_Mail_WCS32::setHandshakeTimeout(unsigned long handshake_timeout) -{ - sslclient->handshake_timeout = handshake_timeout * 1000; -} - -void ESP_Mail_WCS32::setSTARTTLS(bool enable) -{ - _secured = !enable; -} - -void ESP_Mail_WCS32::setDebugCB(DebugMsgCallback *cb) -{ - sslclient->_debugCallback = cb; -} - -int ESP_Mail_WCS32::_ns_available() -{ - if (sslclient->socket < 0) - return false; - - if (_rxBuf.length() == 0) - { - int bufLen = 1024; - char *tmp = new char[bufLen]; - memset(tmp, 0, bufLen); - int ret = _ssl_client32._ns_lwip_read(sslclient, tmp, bufLen); - if (ret > 0) - _rxBuf += tmp; - delete[] tmp; - } - - int result = _rxBuf.length(); - - if (!result) - { - optimistic_yield(100); - } - return result; -} - -size_t ESP_Mail_WCS32::_ns_write(const char *buf, size_t size) -{ - if (sslclient->socket < 0 || !size) - return 0; - return _ssl_client32._ns_lwip_write(sslclient, buf, size); -} - -size_t ESP_Mail_WCS32::_ns_read(char *buf, size_t size) -{ - if (_rxBuf.length() == 0) - return _ssl_client32._ns_lwip_read(sslclient, buf, size); - else - { - size_t sz = size; - if (sz > _rxBuf.length()) - sz = _rxBuf.length(); - strncpy(buf, _rxBuf.c_str(), sz); - _rxBuf.erase(0, sz); - return sz; - } -} - -int ESP_Mail_WCS32::_ns_read() -{ - int c = -1; - if (_rxBuf.length() == 0) - { - char *buf = new char[2]; - memset(buf, 0, 2); - int ret = _ssl_client32._ns_lwip_read(sslclient, buf, 1); - if (ret > 0) - c = buf[0]; - delete[] buf; - } - else - { - c = _rxBuf.c_str()[0]; - _rxBuf.erase(0, 1); - } - - return c; -} - -uint8_t ESP_Mail_WCS32::_ns_connected() -{ - return sslclient->socket >= 0; -} - -bool ESP_Mail_WCS32::_ns_connect_ssl() -{ - int ret = 0; - if (_withKey) - ret = _ssl_client32.start_ssl_client(sslclient, _host.c_str(), _port, _timeout, _CA_cert, _cert, _private_key, NULL, NULL, _use_insecure); - else if (_withCert) - ret = _ssl_client32.start_ssl_client(sslclient, _host.c_str(), _port, _timeout, NULL, NULL, NULL, _pskIdent, _psKey, _use_insecure); - - _lastError = ret; - if (ret < 0) - { - log_e("start_ssl_client: %d", ret); - stop(); - return 0; - } - - return 1; -} - -#endif //ESP32 - -#endif //ESP_Mail_WCS32_CPP \ No newline at end of file diff --git a/lib/libesp32/lib_mail/src/wcs/esp32/ESP_Mail_WCS32.h b/lib/libesp32/lib_mail/src/wcs/esp32/ESP_Mail_WCS32.h deleted file mode 100644 index 35be7527dd67..000000000000 --- a/lib/libesp32/lib_mail/src/wcs/esp32/ESP_Mail_WCS32.h +++ /dev/null @@ -1,160 +0,0 @@ - -/* - *Customized WiFiClientSecure.h version 1.0.8 - * - * The MIT License (MIT) - * Copyright (c) 2021 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -/* - WiFiClientSecure.h - Base class that provides Client SSL to ESP32 - Copyright (c) 2011 Adrian McEwen. All right reserved. - Additions Copyright (C) 2017 Evandro Luis Copercini. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef ESP_Mail_WCS32_H -#define ESP_Mail_WCS32_H - -#ifdef ESP32 - -#include "Arduino.h" -#include "IPAddress.h" -#include -#include "esp_mail_ssl_client32.h" - -typedef void (*DebugMsgCallback)(const char *msg); - -class ESP_Mail_WCS32 : public WiFiClient -{ - friend class ESP_Mail_HTTPClient32; - -protected: - esp_mail_ssl_client32::esp_mail_ssl_ctx32 *sslclient; - - int _lastError = 0; - int _peek = -1; - int _timeout = 0; - bool _use_insecure; - const char *_CA_cert; - const char *_cert; - const char *_private_key; - const char *_pskIdent; // identity for PSK cipher suites - const char *_psKey; // key in hex for PSK cipher suites - -public: - ESP_Mail_WCS32 *next; - ESP_Mail_WCS32(); - ESP_Mail_WCS32(int socket); - ESP_Mail_WCS32(bool secured); - ~ESP_Mail_WCS32(); - int connect(IPAddress ip, uint16_t port); - int connect(IPAddress ip, uint16_t port, int32_t timeout); - int connect(const char *host, uint16_t port); - int connect(const char *host, uint16_t port, int32_t timeout); - int connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key); - int connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key); - int connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psKey); - int connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey); - int peek(); - size_t write(uint8_t data); - size_t write(const uint8_t *buf, size_t size); - int available(); - int read(); - int read(uint8_t *buf, size_t size); - void flush() {} - void stop(); - uint8_t connected(); - int lastError(char *buf, const size_t size); - void setInsecure(); // Don't validate the chain, just accept whatever is given. VERY INSECURE! - void setPreSharedKey(const char *pskIdent, const char *psKey); // psKey in Hex - void setCACert(const char *rootCA); - void setCertificate(const char *client_ca); - void setPrivateKey(const char *private_key); - bool loadCACert(Stream &stream, size_t size); - bool loadCertificate(Stream &stream, size_t size); - bool loadPrivateKey(Stream &stream, size_t size); - bool verify(const char *fingerprint, const char *domain_name); - void setHandshakeTimeout(unsigned long handshake_timeout); - int setTimeout(uint32_t seconds) { return 0; } - void setSTARTTLS(bool enable); - void setDebugCB(DebugMsgCallback *cb); - int _ns_available(); - size_t _ns_write(const char *buf, size_t size); - size_t _ns_read(char *buf, size_t size); - int _ns_read(); - uint8_t _ns_connected(); - bool _ns_connect_ssl(); - - operator bool() - { - return connected(); - } - ESP_Mail_WCS32 &operator=(const ESP_Mail_WCS32 &other); - bool operator==(const bool value) - { - return bool() == value; - } - bool operator!=(const bool value) - { - return bool() != value; - } - bool operator==(const ESP_Mail_WCS32 &); - bool operator!=(const ESP_Mail_WCS32 &rhs) - { - return !this->operator==(rhs); - }; - - int socket() - { - return sslclient->socket = -1; - } - -private: - esp_mail_ssl_client32 _ssl_client32; - char *_streamLoad(Stream &stream, size_t size); - bool _secured = true; - bool _withCert = false; - bool _withKey = false; - std::string _host = ""; - std::string _rxBuf = ""; - int _port; - - //friend class WiFiServer; - using Print::write; -}; - -#endif //ESP32 - -#endif //ESP_Mail_WCS32_H diff --git a/lib/libesp32/lib_mail/src/wcs/esp32/esp_mail_ssl_client32.cpp b/lib/libesp32/lib_mail/src/wcs/esp32/esp_mail_ssl_client32.cpp deleted file mode 100644 index a96e2d6c8a99..000000000000 --- a/lib/libesp32/lib_mail/src/wcs/esp32/esp_mail_ssl_client32.cpp +++ /dev/null @@ -1,702 +0,0 @@ -/* - *Customized ssl_client.cpp to support STARTTLS protocol, version 1.0.8 - * - * The MIT License (MIT) - * Copyright (c) 2021 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* Provide SSL/TLS functions to ESP32 with Arduino IDE -* -* Adapted from the ssl_client1 example of mbedtls. -* -* Original Copyright (C) 2006-2015, ARM Limited, All Rights Reserved, Apache 2.0 License. -* Additions Copyright (C) 2017 Evandro Luis Copercini, Apache 2.0 License. -*/ - -#ifndef ESP_MAIL_SSL_CLIENT32_CPP -#define ESP_MAIL_SSL_CLIENT32_CPP - -#ifdef ESP32 - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "esp_mail_ssl_client32.h" -#include - -#if !defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) && !defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) -#error "Please configure IDF framework to include mbedTLS -> Enable pre-shared-key ciphersuites and activate at least one cipher" -#endif - -const char *_esp_mail_pers32 = "esp_mail_esp32-tls"; - -static int _handle_error(int err, const char *file, int line) -{ - if (err == -30848) - { - return err; - } -#ifdef MBEDTLS_ERROR_C - char error_buf[100]; - mbedtls_strerror(err, error_buf, 100); - log_e("[%s():%d]: (%d) %s", file, line, err, error_buf); -#else - log_e("[%s():%d]: code %d", file, line, err); -#endif - return err; -} - -#define handle_error(e) _handle_error(e, __FUNCTION__, __LINE__) - -void esp_mail_ssl_client32::ssl_init(esp_mail_ssl_ctx32 *ssl_client) -{ - mbedtls_ssl_init(&ssl_client->ssl_ctx); - mbedtls_ssl_config_init(&ssl_client->ssl_conf); - mbedtls_ctr_drbg_init(&ssl_client->drbg_ctx); -} - -int esp_mail_ssl_client32::start_socket(esp_mail_ssl_ctx32 *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure) -{ - - if (rootCABuff == NULL && pskIdent == NULL && psKey == NULL && !insecure) - { - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_27); - return -1; - } - - int enable = 1; - - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_2); - - log_v("Free internal heap before TLS %u", ESP.getFreeHeap()); - - log_v("Starting socket"); - ssl_client->socket = -1; - - ssl_client->socket = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (ssl_client->socket < 0) - { - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_3); - log_e("ERROR opening socket"); - return ssl_client->socket; - } - - IPAddress srv((uint32_t)0); - if (!WiFiGenericClass::hostByName(host, srv)) - { - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_4); - return -1; - } - - struct sockaddr_in serv_addr; - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = srv; - serv_addr.sin_port = htons(port); - - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_5); - - if (lwip_connect(ssl_client->socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) - { - if (timeout <= 0) - { - timeout = 30000; // Milli seconds. - } - timeval so_timeout = {.tv_sec = timeout / 1000, .tv_usec = (timeout % 1000) * 1000}; - -#define ROE(x, msg) \ - { \ - if (((x) < 0)) \ - { \ - log_e("LWIP Socket config of " msg " failed."); \ - return -1; \ - } \ - } - ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_RCVTIMEO, &so_timeout, sizeof(so_timeout)), "SO_RCVTIMEO"); - ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_SNDTIMEO, &so_timeout, sizeof(so_timeout)), "SO_SNDTIMEO"); - - ROE(lwip_setsockopt(ssl_client->socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)), "TCP_NODELAY"); - ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)), "SO_KEEPALIVE"); - } - else - { - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_7); - log_e("Connect to Server failed!"); - return -1; - } - - fcntl(ssl_client->socket, F_SETFL, fcntl(ssl_client->socket, F_GETFL, 0) | O_NONBLOCK); - - return ssl_client->socket; -} - -int esp_mail_ssl_client32::start_ssl_client(esp_mail_ssl_ctx32 *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure) -{ - - char buf[512]; - int ret, flags; - - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_9); - - log_v("Seeding the random number generator"); - mbedtls_entropy_init(&ssl_client->entropy_ctx); - - ret = mbedtls_ctr_drbg_seed(&ssl_client->drbg_ctx, mbedtls_entropy_func, &ssl_client->entropy_ctx, (const unsigned char *)_esp_mail_pers32, strlen(_esp_mail_pers32)); - if (ret < 0) - { - if (ssl_client->_debugCallback) - ssl_client_send_mbedtls_error_cb(ssl_client, ret); - return handle_error(ret); - } - - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_10); - - log_v("Setting up the SSL/TLS structure..."); - - if ((ret = mbedtls_ssl_config_defaults(&ssl_client->ssl_conf, - MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT)) != 0) - { - if (ssl_client->_debugCallback) - ssl_client_send_mbedtls_error_cb(ssl_client, ret); - return handle_error(ret); - } - - // MBEDTLS_SSL_VERIFY_REQUIRED if a CA certificate is defined on Arduino IDE and - // MBEDTLS_SSL_VERIFY_NONE if not. - - if (insecure) - { - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_28); - - mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_NONE); - log_i("WARNING: Skipping SSL Verification. INSECURE!"); - } - else if (rootCABuff != NULL) - { - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_11); - log_v("Loading CA cert"); - mbedtls_x509_crt_init(&ssl_client->ca_cert); - mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED); - ret = mbedtls_x509_crt_parse(&ssl_client->ca_cert, (const unsigned char *)rootCABuff, strlen(rootCABuff) + 1); - mbedtls_ssl_conf_ca_chain(&ssl_client->ssl_conf, &ssl_client->ca_cert, NULL); - //mbedtls_ssl_conf_verify(&ssl_client->ssl_ctx, my_verify, NULL ); - if (ret < 0) - { - if (ssl_client->_debugCallback) - ssl_client_send_mbedtls_error_cb(ssl_client, ret); - // free the ca_cert in the case parse failed, otherwise, the old ca_cert still in the heap memory, that lead to "out of memory" crash. - mbedtls_x509_crt_free(&ssl_client->ca_cert); - return handle_error(ret); - } - } - else if (pskIdent != NULL && psKey != NULL) - { - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_12); - log_v("Setting up PSK"); - // convert PSK from hex to binary - if ((strlen(psKey) & 1) != 0 || strlen(psKey) > 2 * MBEDTLS_PSK_MAX_LEN) - { - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_13); - log_e("pre-shared key not valid hex or too long"); - return -1; - } - - unsigned char psk[MBEDTLS_PSK_MAX_LEN]; - size_t psk_len = strlen(psKey) / 2; - for (int j = 0; j < strlen(psKey); j += 2) - { - char c = psKey[j]; - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'F') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'f') - c -= 'a' - 10; - else - return -1; - psk[j / 2] = c << 4; - c = psKey[j + 1]; - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'F') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'f') - c -= 'a' - 10; - else - return -1; - psk[j / 2] |= c; - } - // set mbedtls config - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_14); - - ret = mbedtls_ssl_conf_psk(&ssl_client->ssl_conf, psk, psk_len, - (const unsigned char *)pskIdent, strlen(pskIdent)); - if (ret != 0) - { - if (ssl_client->_debugCallback) - ssl_client_send_mbedtls_error_cb(ssl_client, ret); - - log_e("mbedtls_ssl_conf_psk returned %d", ret); - return handle_error(ret); - } - } - else - { - return -1; - } - - if (!insecure && cli_cert != NULL && cli_key != NULL) - { - - mbedtls_x509_crt_init(&ssl_client->client_cert); - mbedtls_pk_init(&ssl_client->client_key); - - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_15); - - log_v("Loading CRT cert"); - - ret = mbedtls_x509_crt_parse(&ssl_client->client_cert, (const unsigned char *)cli_cert, strlen(cli_cert) + 1); - if (ret < 0) - { - if (ssl_client->_debugCallback) - ssl_client_send_mbedtls_error_cb(ssl_client, ret); - // free the client_cert in the case parse failed, otherwise, the old client_cert still in the heap memory, that lead to "out of memory" crash. - mbedtls_x509_crt_free(&ssl_client->client_cert); - return handle_error(ret); - } - - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_16); - - log_v("Loading private key"); - ret = mbedtls_pk_parse_key(&ssl_client->client_key, (const unsigned char *)cli_key, strlen(cli_key) + 1, NULL, 0); - - if (ret != 0) - { - if (ssl_client->_debugCallback) - ssl_client_send_mbedtls_error_cb(ssl_client, ret); - return handle_error(ret); - } - - mbedtls_ssl_conf_own_cert(&ssl_client->ssl_conf, &ssl_client->client_cert, &ssl_client->client_key); - } - - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_17); - - log_v("Setting hostname for TLS session..."); - - // Hostname set here should match CN in server certificate - if ((ret = mbedtls_ssl_set_hostname(&ssl_client->ssl_ctx, host)) != 0) - { - if (ssl_client->_debugCallback) - ssl_client_send_mbedtls_error_cb(ssl_client, ret); - return handle_error(ret); - } - - mbedtls_ssl_conf_rng(&ssl_client->ssl_conf, mbedtls_ctr_drbg_random, &ssl_client->drbg_ctx); - - if ((ret = mbedtls_ssl_setup(&ssl_client->ssl_ctx, &ssl_client->ssl_conf)) != 0) - { - if (ssl_client->_debugCallback) - ssl_client_send_mbedtls_error_cb(ssl_client, ret); - return handle_error(ret); - } - - mbedtls_ssl_set_bio(&ssl_client->ssl_ctx, &ssl_client->socket, mbedtls_net_send, mbedtls_net_recv, NULL); - - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_18); - - log_v("Performing the SSL/TLS handshake..."); - unsigned long handshake_start_time = millis(); - while ((ret = mbedtls_ssl_handshake(&ssl_client->ssl_ctx)) != 0) - { - if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) - { - if (ssl_client->_debugCallback) - ssl_client_send_mbedtls_error_cb(ssl_client, ret); - return handle_error(ret); - } - if ((millis() - handshake_start_time) > ssl_client->handshake_timeout) - return -1; - vTaskDelay(2); //2 ticks - } - - if (cli_cert != NULL && cli_key != NULL) - { - log_d("Protocol is %s Ciphersuite is %s", mbedtls_ssl_get_version(&ssl_client->ssl_ctx), mbedtls_ssl_get_ciphersuite(&ssl_client->ssl_ctx)); - if ((ret = mbedtls_ssl_get_record_expansion(&ssl_client->ssl_ctx)) >= 0) - { - log_d("Record expansion is %d", ret); - } - else - { - log_w("Record expansion is unknown (compression)"); - } - } - - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_19); - - log_v("Verifying peer X.509 certificate..."); - - if ((flags = mbedtls_ssl_get_verify_result(&ssl_client->ssl_ctx)) != 0) - { - memset(buf, 0, sizeof(buf)); - mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", flags); - log_e("Failed to verify peer certificate! verification info: %s", buf); - stop_ssl_socket(ssl_client, rootCABuff, cli_cert, cli_key); //It's not safe continue. - return handle_error(ret); - } - else - { - log_v("Certificate verified."); - } - - if (rootCABuff != NULL) - { - mbedtls_x509_crt_free(&ssl_client->ca_cert); - } - - if (cli_cert != NULL) - { - mbedtls_x509_crt_free(&ssl_client->client_cert); - } - - if (cli_key != NULL) - { - mbedtls_pk_free(&ssl_client->client_key); - } - - log_v("Free internal heap after TLS %u", ESP.getFreeHeap()); - - return ssl_client->socket; -} - -void esp_mail_ssl_client32::stop_ssl_socket(esp_mail_ssl_ctx32 *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key) -{ - if (ssl_client->_debugCallback) - ssl_client_debug_pgm_send_cb(ssl_client, esp_ssl_client_str_22); - - log_v("Cleaning SSL connection."); - - if (ssl_client->socket >= 0) - { - close(ssl_client->socket); - ssl_client->socket = -1; - } - - mbedtls_ssl_free(&ssl_client->ssl_ctx); - mbedtls_ssl_config_free(&ssl_client->ssl_conf); - mbedtls_ctr_drbg_free(&ssl_client->drbg_ctx); - mbedtls_entropy_free(&ssl_client->entropy_ctx); -} - -int esp_mail_ssl_client32::data_to_read(esp_mail_ssl_ctx32 *ssl_client) -{ - int ret, res; - ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, NULL, 0); - //log_e("RET: %i",ret); //for low level debug - res = mbedtls_ssl_get_bytes_avail(&ssl_client->ssl_ctx); - //log_e("RES: %i",res); //for low level debug - if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret < 0) - { - if (ssl_client->_debugCallback) - ssl_client_send_mbedtls_error_cb(ssl_client, ret); - return handle_error(ret); - } - - return res; -} - -int esp_mail_ssl_client32::send_ssl_data(esp_mail_ssl_ctx32 *ssl_client, const uint8_t *data, size_t len) -{ - log_v("Writing HTTP request with %d bytes...", len); //for low level debug - int ret = -1; - - while ((ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data, len)) <= 0) - { - if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret < 0) - { - log_v("Handling error %d", ret); //for low level debug - return handle_error(ret); - } - //wait for space to become available - vTaskDelay(2); - } - - return ret; -} - -int esp_mail_ssl_client32::get_ssl_receive(esp_mail_ssl_ctx32 *ssl_client, uint8_t *data, int length) -{ - - //log_d( "Reading HTTP response..."); //for low level debug - int ret = -1; - - ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, data, length); - - //log_v( "%d bytes read", ret); //for low level debug - return ret; -} - -bool esp_mail_ssl_client32::parseHexNibble(char pb, uint8_t *res) -{ - if (pb >= '0' && pb <= '9') - { - *res = (uint8_t)(pb - '0'); - return true; - } - else if (pb >= 'a' && pb <= 'f') - { - *res = (uint8_t)(pb - 'a' + 10); - return true; - } - else if (pb >= 'A' && pb <= 'F') - { - *res = (uint8_t)(pb - 'A' + 10); - return true; - } - return false; -} - -// Compare a name from certificate and domain name, return true if they match -bool esp_mail_ssl_client32::matchName(const std::string &name, const std::string &domainName) -{ - size_t wildcardPos = name.find('*'); - if (wildcardPos == std::string::npos) - { - // Not a wildcard, expect an exact match - return name == domainName; - } - - size_t firstDotPos = name.find('.'); - if (wildcardPos > firstDotPos) - { - // Wildcard is not part of leftmost component of domain name - // Do not attempt to match (rfc6125 6.4.3.1) - return false; - } - if (wildcardPos != 0 || firstDotPos != 1) - { - // Matching of wildcards such as baz*.example.com and b*z.example.com - // is optional. Maybe implement this in the future? - return false; - } - size_t domainNameFirstDotPos = domainName.find('.'); - if (domainNameFirstDotPos == std::string::npos) - { - return false; - } - return domainName.substr(domainNameFirstDotPos) == name.substr(firstDotPos); -} - -// Verifies certificate provided by the peer to match specified SHA256 fingerprint -bool esp_mail_ssl_client32::verify_ssl_fingerprint(esp_mail_ssl_ctx32 *ssl_client, const char *fp, const char *domain_name) -{ - // Convert hex string to byte array - uint8_t fingerprint_local[32]; - int len = strlen(fp); - int pos = 0; - for (size_t i = 0; i < sizeof(fingerprint_local); ++i) - { - while (pos < len && ((fp[pos] == ' ') || (fp[pos] == ':'))) - { - ++pos; - } - if (pos > len - 2) - { - log_d("pos:%d len:%d fingerprint too short", pos, len); - return false; - } - uint8_t high, low; - if (!parseHexNibble(fp[pos], &high) || !parseHexNibble(fp[pos + 1], &low)) - { - log_d("pos:%d len:%d invalid hex sequence: %c%c", pos, len, fp[pos], fp[pos + 1]); - return false; - } - pos += 2; - fingerprint_local[i] = low | (high << 4); - } - - // Get certificate provided by the peer - const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&ssl_client->ssl_ctx); - - if (!crt) - { - log_d("could not fetch peer certificate"); - return false; - } - - // Calculate certificate's SHA256 fingerprint - uint8_t fingerprint_remote[32]; - mbedtls_sha256_context sha256_ctx; - mbedtls_sha256_init(&sha256_ctx); - mbedtls_sha256_starts(&sha256_ctx, false); - mbedtls_sha256_update(&sha256_ctx, crt->raw.p, crt->raw.len); - mbedtls_sha256_finish(&sha256_ctx, fingerprint_remote); - - // Check if fingerprints match - if (memcmp(fingerprint_local, fingerprint_remote, 32)) - { - log_d("fingerprint doesn't match"); - return false; - } - - // Additionally check if certificate has domain name if provided - if (domain_name) - return verify_ssl_dn(ssl_client, domain_name); - else - return true; -} - -// Checks if peer certificate has specified domain in CN or SANs -bool esp_mail_ssl_client32::verify_ssl_dn(esp_mail_ssl_ctx32 *ssl_client, const char *domain_name) -{ - log_d("domain name: '%s'", (domain_name) ? domain_name : "(null)"); - std::string domain_name_str(domain_name); - std::transform(domain_name_str.begin(), domain_name_str.end(), domain_name_str.begin(), ::tolower); - - // Get certificate provided by the peer - const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&ssl_client->ssl_ctx); - - // Check for domain name in SANs - const mbedtls_x509_sequence *san = &crt->subject_alt_names; - while (san != nullptr) - { - std::string san_str((const char *)san->buf.p, san->buf.len); - std::transform(san_str.begin(), san_str.end(), san_str.begin(), ::tolower); - - if (matchName(san_str, domain_name_str)) - return true; - - log_d("SAN '%s': no match", san_str.c_str()); - - // Fetch next SAN - san = san->next; - } - - // Check for domain name in CN - const mbedtls_asn1_named_data *common_name = &crt->subject; - while (common_name != nullptr) - { - // While iterating through DN objects, check for CN object - if (!MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &common_name->oid)) - { - std::string common_name_str((const char *)common_name->val.p, common_name->val.len); - - if (matchName(common_name_str, domain_name_str)) - return true; - - log_d("CN '%s': not match", common_name_str.c_str()); - } - - // Fetch next DN object - common_name = common_name->next; - } - - return false; -} - -int esp_mail_ssl_client32::_ns_lwip_write(esp_mail_ssl_ctx32 *ssl_client, const char *buf, int bufLen) -{ - return lwip_write(ssl_client->socket, buf, bufLen); -} - -int esp_mail_ssl_client32::_ns_lwip_read(esp_mail_ssl_ctx32 *ssl_client, char *buf, int bufLen) -{ - fd_set readset; - fd_set writeset; - fd_set errset; - - struct timeval tv; - - FD_ZERO(&readset); - FD_SET(ssl_client->socket, &readset); - FD_ZERO(&writeset); - FD_SET(ssl_client->socket, &writeset); - - FD_ZERO(&errset); - FD_SET(ssl_client->socket, &errset); - - tv.tv_sec = 1; - tv.tv_usec = 0; - int ret = lwip_select(ssl_client->socket, &readset, &writeset, &errset, &tv); - - if (ret < 0) - return ret; - - return read(ssl_client->socket, buf, bufLen); -} - -void esp_mail_ssl_client32::ssl_client_send_mbedtls_error_cb(esp_mail_ssl_ctx32 *ssl_client, int errNo) -{ - char *buf = new char[512]; - char *error_buf = new char[100]; - memset(buf, 0, 512); - strcpy_P(buf, esp_ssl_client_str_1); - mbedtls_strerror(errNo, error_buf, 100); - strcat(buf, error_buf); - DebugMsgCallback cb = *ssl_client->_debugCallback; - cb(buf); - delete[] error_buf; - delete[] buf; -} - -void esp_mail_ssl_client32::ssl_client_debug_pgm_send_cb(esp_mail_ssl_ctx32 *ssl_client, PGM_P info) -{ - size_t dbgInfoLen = strlen_P(info) + 10; - char *dbgInfo = new char[dbgInfoLen]; - memset(dbgInfo, 0, dbgInfoLen); - strcpy_P(dbgInfo, info); - DebugMsgCallback cb = *ssl_client->_debugCallback; - cb(dbgInfo); - delete[] dbgInfo; -} - -#endif //ESP32 - -#endif //ESP_MAIL_SSL_CLIENT32_CPP diff --git a/lib/libesp32/lib_mail/src/wcs/esp32/esp_mail_ssl_client32.h b/lib/libesp32/lib_mail/src/wcs/esp32/esp_mail_ssl_client32.h deleted file mode 100644 index b0704d13f5ff..000000000000 --- a/lib/libesp32/lib_mail/src/wcs/esp32/esp_mail_ssl_client32.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - *Customized ssl_client.h to support STARTTLS protocol, version 1.0.8 - * - * The MIT License (MIT) - * Copyright (c) 2021 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -/* Provide SSL/TLS functions to ESP32 with Arduino IDE - * by Evandro Copercini - 2017 - Apache 2.0 License - */ - -#ifndef ESP_MAIL_SSL_CLIENT32_H -#define ESP_MAIL_SSL_CLIENT32_H - -#ifdef ESP32 -#include -#include "mbedtls/platform.h" -#include "mbedtls/net.h" -#include "mbedtls/debug.h" -#include "mbedtls/ssl.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/error.h" - -static const char esp_ssl_client_str_1[] PROGMEM = "! E: "; -static const char esp_ssl_client_str_2[] PROGMEM = "> C: starting socket"; -static const char esp_ssl_client_str_3[] PROGMEM = "! E: opening socket"; -static const char esp_ssl_client_str_4[] PROGMEM = "! E: could not get ip from host"; -static const char esp_ssl_client_str_5[] PROGMEM = "> C: connecting to Server"; -static const char esp_ssl_client_str_6[] PROGMEM = "> C: server connected"; -static const char esp_ssl_client_str_7[] PROGMEM = "! E: connect to Server failed!"; -static const char esp_ssl_client_str_8[] PROGMEM = "< S: "; -static const char esp_ssl_client_str_9[] PROGMEM = "> C: seeding the random number generator"; -static const char esp_ssl_client_str_10[] PROGMEM = "> C: setting up the SSL/TLS structure"; -static const char esp_ssl_client_str_11[] PROGMEM = "> C: loading CA cert"; -static const char esp_ssl_client_str_12[] PROGMEM = "> C: setting up PSK"; -static const char esp_ssl_client_str_13[] PROGMEM = "! E: pre-shared key not valid hex or too long"; -static const char esp_ssl_client_str_14[] PROGMEM = "> C: set mbedtls config"; -static const char esp_ssl_client_str_15[] PROGMEM = "> C: loading CRT cert"; -static const char esp_ssl_client_str_16[] PROGMEM = "> C: loading private key"; -static const char esp_ssl_client_str_17[] PROGMEM = "> C: setting hostname for TLS session"; -static const char esp_ssl_client_str_18[] PROGMEM = "> C: performing the SSL/TLS handshake"; -static const char esp_ssl_client_str_19[] PROGMEM = "> C: verifying peer X.509 certificate"; -static const char esp_ssl_client_str_20[] PROGMEM = "! E: failed to verify peer certificate!"; -static const char esp_ssl_client_str_21[] PROGMEM = "> C: certificate verified"; -static const char esp_ssl_client_str_22[] PROGMEM = "> C: cleaning SSL connection"; -static const char esp_ssl_client_str_23[] PROGMEM = "! E: fingerprint too short"; -static const char esp_ssl_client_str_24[] PROGMEM = "! E: invalid hex sequence"; -static const char esp_ssl_client_str_25[] PROGMEM = "! E: could not fetch peer certificate"; -static const char esp_ssl_client_str_26[] PROGMEM = "! E: fingerprint doesn't match"; -static const char esp_ssl_client_str_27[] PROGMEM = "! E: root certificate, PSK identity or keys are required for secured connection"; -static const char esp_ssl_client_str_28[] PROGMEM = "! W: Skipping SSL Verification. INSECURE!"; - -class esp_mail_ssl_client32 -{ -public: - esp_mail_ssl_client32(){}; - - typedef void (*DebugMsgCallback)(const char *msg); - - typedef struct esp_mail_ssl_ctx32 - { - int socket; - mbedtls_ssl_context ssl_ctx; - mbedtls_ssl_config ssl_conf; - - mbedtls_ctr_drbg_context drbg_ctx; - mbedtls_entropy_context entropy_ctx; - - mbedtls_x509_crt ca_cert; - mbedtls_x509_crt client_cert; - mbedtls_pk_context client_key; - DebugMsgCallback *_debugCallback = NULL; - - unsigned long handshake_timeout; - } esp_mail_ssl_ctx32; - - void ssl_init(esp_mail_ssl_ctx32 *ssl_client); - - int start_socket(esp_mail_ssl_ctx32 *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure); - int start_ssl_client(esp_mail_ssl_ctx32 *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure); - void stop_ssl_socket(esp_mail_ssl_ctx32 *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key); - - int data_to_read(esp_mail_ssl_ctx32 *ssl_client); - int send_ssl_data(esp_mail_ssl_ctx32 *ssl_client, const uint8_t *data, size_t len); - int get_ssl_receive(esp_mail_ssl_ctx32 *ssl_client, uint8_t *data, int length); - bool verify_ssl_fingerprint(esp_mail_ssl_ctx32 *ssl_client, const char *fp, const char *domain_name); - bool verify_ssl_dn(esp_mail_ssl_ctx32 *ssl_client, const char *domain_name); - - int _ns_lwip_write(esp_mail_ssl_ctx32 *ssl_client, const char *buf, int bufLen); - int _ns_lwip_read(esp_mail_ssl_ctx32 *ssl_client, char *buf, int bufLen); - void ssl_client_send_mbedtls_error_cb(esp_mail_ssl_ctx32 *ssl_client, int errNo); - void ssl_client_debug_pgm_send_cb(esp_mail_ssl_ctx32 *ssl_client, PGM_P info); - bool parseHexNibble(char pb, uint8_t *res); - bool matchName(const std::string &name, const std::string &domainName); -}; - -#endif //ESP32 - -#endif //ESP_MAIL_SSL_CLIENT32_H diff --git a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_BearSSLHelpers.h b/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_BearSSLHelpers.h deleted file mode 100644 index 4ee319736572..000000000000 --- a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_BearSSLHelpers.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - Copy of BearSSLHelpers.h - - WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries - - Mostly compatible with Arduino WiFi shield library and standard - WiFiClient/ServerSecure (except for certificate handling). - - Copyright (c) 2018 Earle F. Philhower, III - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef ESP_Mail_BearSSLHelpers_H -#define ESP_Mail_BearSSLHelpers_H - -#ifdef ESP8266 - -#include -#include - -// Internal opaque structures, not needed by user applications -namespace ESP_Mail_brssl -{ - class public_key; - class private_key; -}; // namespace ESP_Mail_brssl - -namespace ESP_Mail -{ - - // Holds either a single public RSA or EC key for use when BearSSL wants a pubkey. - // Copies all associated data so no need to keep input PEM/DER keys. - // All inputs can be either in RAM or PROGMEM. - class PublicKey - { - public: - PublicKey(); - PublicKey(const char *pemKey); - PublicKey(const uint8_t *derKey, size_t derLen); - ~PublicKey(); - - bool parse(const char *pemKey); - bool parse(const uint8_t *derKey, size_t derLen); - - // Accessors for internal use, not needed by apps - bool isRSA() const; - bool isEC() const; - const br_rsa_public_key *getRSA() const; - const br_ec_public_key *getEC() const; - - // Disable the copy constructor, we're pointer based - PublicKey(const PublicKey &that) = delete; - - private: - ESP_Mail_brssl::public_key *_key; - }; - - // Holds either a single private RSA or EC key for use when BearSSL wants a secretkey. - // Copies all associated data so no need to keep input PEM/DER keys. - // All inputs can be either in RAM or PROGMEM. - class PrivateKey - { - public: - PrivateKey(); - PrivateKey(const char *pemKey); - PrivateKey(const uint8_t *derKey, size_t derLen); - ~PrivateKey(); - - bool parse(const char *pemKey); - bool parse(const uint8_t *derKey, size_t derLen); - - // Accessors for internal use, not needed by apps - bool isRSA() const; - bool isEC() const; - const br_rsa_private_key *getRSA() const; - const br_ec_private_key *getEC() const; - - // Disable the copy constructor, we're pointer based - PrivateKey(const PrivateKey &that) = delete; - - private: - ESP_Mail_brssl::private_key *_key; - }; - - // Holds one or more X.509 certificates and associated trust anchors for - // use whenever BearSSL needs a cert or TA. May want to have multiple - // certs for things like a series of trusted CAs (but check the CertStore class - // for a more memory efficient way). - // Copies all associated data so no need to keep input PEM/DER certs. - // All inputs can be either in RAM or PROGMEM. - class ESP_Mail_X509List - { - public: - ESP_Mail_X509List(); - ESP_Mail_X509List(const char *pemCert); - ESP_Mail_X509List(const uint8_t *derCert, size_t derLen); - ~ESP_Mail_X509List(); - - bool append(const char *pemCert); - bool append(const uint8_t *derCert, size_t derLen); - - // Accessors - size_t getCount() const - { - return _count; - } - const br_x509_certificate *getX509Certs() const - { - return _cert; - } - const br_x509_trust_anchor *getTrustAnchors() const - { - return _ta; - } - - // Disable the copy constructor, we're pointer based - ESP_Mail_X509List(const ESP_Mail_X509List &that) = delete; - - private: - size_t _count; - br_x509_certificate *_cert; - br_x509_trust_anchor *_ta; - }; - - // Opaque object which wraps the BearSSL SSL session to make repeated connections - // significantly faster. Completely optional. - class ESP_Mail_WCS; - - class Session - { - friend class ESP_Mail_WCS; - - public: - Session() { memset(&_session, 0, sizeof(_session)); } - - private: - br_ssl_session_parameters *getSession() { return &_session; } - // The actual BearSSL ession information - br_ssl_session_parameters _session; - }; - - // Updater SHA256 hash and signature verification - class HashSHA256 : public UpdaterHashClass - { - public: - virtual void begin() override; - virtual void add(const void *data, uint32_t len) override; - virtual void end() override; - virtual int len() override; - virtual const void *hash() override; - virtual const unsigned char *oid() override; - - private: - br_sha256_context _cc; - unsigned char _sha256[32]; - }; - - class SigningVerifier : public UpdaterVerifyClass - { - public: - virtual uint32_t length() override; - virtual bool verify(UpdaterHashClass *hash, const void *signature, uint32_t signatureLen) override; - - public: - SigningVerifier(PublicKey *pubKey) { _pubKey = pubKey; } - - private: - PublicKey *_pubKey; - }; - /* -// Stack thunked versions of calls -extern "C" { -extern unsigned char *thunk_br_ssl_engine_recvapp_buf( const br_ssl_engine_context *cc, size_t *len); -extern void thunk_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len); -extern unsigned char *thunk_br_ssl_engine_recvrec_buf( const br_ssl_engine_context *cc, size_t *len); -extern void thunk_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len); -extern unsigned char *thunk_br_ssl_engine_sendapp_buf( const br_ssl_engine_context *cc, size_t *len); -extern void thunk_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len); -extern unsigned char *thunk_br_ssl_engine_sendrec_buf( const br_ssl_engine_context *cc, size_t *len); -extern void thunk_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len); -}; -*/ - -}; // namespace ESP_Mail - -#endif /* ESP8266 */ - -#endif /* ESP_Mail_BearSSLHelpers_H */ diff --git a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_CertStoreBearSSL.cpp b/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_CertStoreBearSSL.cpp deleted file mode 100644 index f8efb1155967..000000000000 --- a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_CertStoreBearSSL.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* - Copy of CertStoreBearSSL.cpp - Library for Arduino ESP8266 - Copyright (c) 2018 Earle F. Philhower, III - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#ifndef ESP_Mail_CertStoreBearSSL_CPP -#define ESP_Mail_CertStoreBearSSL_CPP - -#ifdef ESP8266 - -#include "ESP_Mail_CertStoreBearSSL.h" -#include - - -#ifdef DEBUG_ESP_SSL -#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__) -#else -#define DEBUG_BSSL(...) -#endif - -namespace ESP_Mail { - -extern "C" { - // Callback for the x509 decoder - static void dn_append(void *ctx, const void *buf, size_t len) { - br_sha256_context *sha1 = (br_sha256_context*)ctx; - br_sha256_update(sha1, buf, len); - } -} - - -ESP_Mail_CertStore::~ESP_Mail_CertStore() { - free(_indexName); - free(_dataName); -} - -ESP_Mail_CertStore::ESP_Mail_CertInfo ESP_Mail_CertStore::_preprocessCert(uint32_t length, uint32_t offset, const void *raw) { - ESP_Mail_CertStore::ESP_Mail_CertInfo ci; - - // Clear the CertInfo - memset(&ci, 0, sizeof(ci)); - - // Process it using SHA256, same as the hashed_dn - br_x509_decoder_context *ctx = new br_x509_decoder_context; - br_sha256_context *sha256 = new br_sha256_context; - if (!ctx || !sha256) { - DEBUG_BSSL("CertStore::_preprocessCert: OOM\n"); - return ci; - } - - br_sha256_init(sha256); - br_x509_decoder_init(ctx, dn_append, sha256, nullptr, nullptr); - br_x509_decoder_push(ctx, (const void*)raw, length); - - // Copy result to structure - br_sha256_out(sha256, &ci.sha256); - ci.length = length; - ci.offset = offset; - - // Clean up allocated memory - delete sha256; - delete ctx; - - // Return result - return ci; -} - -// The certs.ar file is a UNIX ar format file, concatenating all the -// individual certificates into a single blob in a space-efficient way. -int ESP_Mail_CertStore::initCertStore(FS &fs, const char *indexFileName, const char *dataFileName) { - int count = 0; - uint32_t offset = 0; - - _fs = &fs; - - // In case initCertStore called multiple times, don't leak old filenames - free(_indexName); - free(_dataName); - - // No strdup_P, so manually do it - _indexName = (char *)malloc(strlen_P(indexFileName) + 1); - _dataName = (char *)malloc(strlen_P(dataFileName) + 1); - if (!_indexName || !_dataName) { - free(_indexName); - free(_dataName); - return 0; - } - memcpy_P(_indexName, indexFileName, strlen_P(indexFileName) + 1); - memcpy_P(_dataName, dataFileName, strlen_P(dataFileName) + 1); - - File index = _fs->open(_indexName, "w"); - if (!index) { - return 0; - } - - File data = _fs->open(_dataName, "r"); - if (!data) { - index.close(); - return 0; - } - - uint8_t magic[8]; - if (data.read(magic, sizeof(magic)) != sizeof(magic) || - memcmp(magic, "!\n", sizeof(magic)) ) { - data.close(); - index.close(); - return 0; - } - offset += sizeof(magic); - - while (true) { - uint8_t fileHeader[60]; - // 0..15 = filename in ASCII - // 48...57 = length in decimal ASCII - uint32_t length; - if (data.read(fileHeader, sizeof(fileHeader)) != sizeof(fileHeader)) { - break; - } - offset += sizeof(fileHeader); - fileHeader[58] = 0; - if (1 != sscanf((char *)(fileHeader + 48), "%d", &length) || !length) { - break; - } - - void *raw = malloc(length); - if (!raw) { - break; - } - if (data.read((uint8_t *)raw, length) != length) { - free(raw); - break; - } - - // If the filename starts with "//" then this is a rename file, skip it - if (fileHeader[0] != '/' || fileHeader[1] != '/') { - ESP_Mail_CertStore::ESP_Mail_CertInfo ci = _preprocessCert(length, offset, raw); - if (index.write((uint8_t *)&ci, sizeof(ci)) != (ssize_t)sizeof(ci)) { - free(raw); - break; - } - count++; - } - - offset += length; - free(raw); - if (offset & 1) { - uint8_t x; - data.read(&x, 1); - offset++; - } - } - data.close(); - index.close(); - return count; -} - -void ESP_Mail_CertStore::installCertStore(br_x509_minimal_context *ctx) { - br_x509_minimal_set_dynamic(ctx, (void*)this, findHashedTA, freeHashedTA); -} - -const br_x509_trust_anchor *ESP_Mail_CertStore::findHashedTA(void *ctx, void *hashed_dn, size_t len) { - ESP_Mail_CertStore *cs = static_cast(ctx); - ESP_Mail_CertStore::ESP_Mail_CertInfo ci; - - if (!cs || len != sizeof(ci.sha256) || !cs->_indexName || !cs->_dataName || !cs->_fs) { - return nullptr; - } - - File index = cs->_fs->open(cs->_indexName, "r"); - if (!index) { - return nullptr; - } - - while (index.read((uint8_t *)&ci, sizeof(ci)) == sizeof(ci)) { - if (!memcmp(ci.sha256, hashed_dn, sizeof(ci.sha256))) { - index.close(); - uint8_t *der = (uint8_t*)malloc(ci.length); - if (!der) { - return nullptr; - } - File data = cs->_fs->open(cs->_dataName, "r"); - if (!data) { - free(der); - return nullptr; - } - if (!data.seek(ci.offset, SeekSet)) { - data.close(); - free(der); - return nullptr; - } - if (data.read((uint8_t *)der, ci.length) != ci.length) { - free(der); - return nullptr; - } - data.close(); - cs->_x509 = new ESP_Mail_X509List(der, ci.length); - free(der); - if (!cs->_x509) { - DEBUG_BSSL("CertStore::findHashedTA: OOM\n"); - return nullptr; - } - - br_x509_trust_anchor *ta = (br_x509_trust_anchor*)cs->_x509->getTrustAnchors(); - memcpy(ta->dn.data, ci.sha256, sizeof(ci.sha256)); - ta->dn.len = sizeof(ci.sha256); - - return ta; - } - } - index.close(); - return nullptr; -} - -void ESP_Mail_CertStore::freeHashedTA(void *ctx, const br_x509_trust_anchor *ta) { - ESP_Mail_CertStore *cs = static_cast(ctx); - (void) ta; // Unused - delete cs->_x509; - cs->_x509 = nullptr; -} - -} - -#endif /* ESP8266 */ - -#endif /* ESP_Mail_CertStoreBearSSL_CPP */ \ No newline at end of file diff --git a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_HTTPClient.cpp b/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_HTTPClient.cpp deleted file mode 100644 index b1fdbff5feae..000000000000 --- a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_HTTPClient.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * HTTP Client for ESP8266 wrapper v1.0.3 - * - * The MIT License (MIT) - * Copyright (c) 2021 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person returning a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef ESP_Mail_HTTPClient_CPP -#define ESP_Mail_HTTPClient_CPP - -#ifdef ESP8266 - -#include "ESP_Mail_HTTPClient.h" - -ESP_Mail_HTTPClient::ESP_Mail_HTTPClient() -{ -} - -ESP_Mail_HTTPClient::~ESP_Mail_HTTPClient() -{ - if (_wcs) - { - _wcs->stop(); - _wcs.reset(nullptr); - _wcs.release(); - } - - std::string().swap(_host); - std::string().swap(_caCertFile); - _cacert.reset(new char); - _cacert = nullptr; -} - -bool ESP_Mail_HTTPClient::begin(const char *host, uint16_t port) -{ - if (strcmp(_host.c_str(), host) != 0) - mflnChecked = false; - - _host = host; - _port = port; - - //probe for fragmentation support at the specified size - if (!mflnChecked) - { - fragmentable = _wcs->probeMaxFragmentLength(_host.c_str(), _port, chunkSize); - if (fragmentable) - { - _bsslRxSize = chunkSize; - _bsslTxSize = chunkSize; - _wcs->setBufferSizes(_bsslRxSize, _bsslTxSize); - } - mflnChecked = true; - } - - if (!fragmentable) - _wcs->setBufferSizes(maxRXBufSize / rxBufDivider, maxTXBufSize / txBufDivider); - - return true; -} - -bool ESP_Mail_HTTPClient::connected() -{ - if (_wcs) - { - if (_secured) - return _wcs->connected(); - else - return _wcs->_ns_connected(); - } - - return false; -} - -bool ESP_Mail_HTTPClient::send(const char *header) -{ - if (!connected()) - return false; - if (_secured) - return (_wcs->write((uint8_t *)header, strlen(header)) == strlen(header)); - else - return (_wcs->_ns_write((uint8_t *)header, strlen(header)) == strlen(header)); -} - -int ESP_Mail_HTTPClient::send(const char *header, const char *payload) -{ - size_t size = strlen(payload); - if (strlen(header) > 0) - { - if (!connect(_secured)) - { - return ESP_MAIL_ERROR_HTTPC_ERROR_CONNECTION_REFUSED; - } - - if (!send(header)) - { - return ESP_MAIL_ERROR_HTTPC_ERROR_SEND_HEADER_FAILED; - } - } - - if (size > 0) - { - if (_secured) - { - if (_wcs->write((uint8_t *)&payload[0], size) != size) - return ESP_MAIL_ERROR_HTTPC_ERROR_SEND_PAYLOAD_FAILED; - } - else - { - if (_wcs->_ns_write((uint8_t *)&payload[0], size) != size) - return ESP_MAIL_ERROR_HTTPC_ERROR_SEND_PAYLOAD_FAILED; - } - } - - return 0; -} - -WiFiClient *ESP_Mail_HTTPClient::stream(void) -{ - if (connected()) - return _wcs.get(); - return nullptr; -} - -ESP_Mail::ESP_Mail_WCS *ESP_Mail_HTTPClient::_stream(void) -{ - if (connected()) - return _wcs.get(); - return nullptr; -} - -size_t ESP_Mail_HTTPClient::_ns_print(const char *buf) -{ - size_t size = strlen(buf); - return _wcs->_ns_write((uint8_t *)&buf[0], size); -} - -size_t ESP_Mail_HTTPClient::_ns_println(const char *buf) -{ - size_t size = strlen(buf); - size_t wr = _wcs->_ns_write((uint8_t *)&buf[0], size); - std::string s = "\r\n"; - wr += _wcs->_ns_write((uint8_t *)s.c_str(), s.length()); - return wr; -} - -bool ESP_Mail_HTTPClient::connect(bool secured) -{ - _secured = secured; - - if (connected()) - { - if (_secured) - { - while (_wcs->available() > 0) - _wcs->read(); - } - else - { - while (_wcs->_ns_available() > 0) - _wcs->_ns_read(); - } - return true; - } - - _wcs->setStartTLS(!_secured); - if (!_wcs->connect(_host.c_str(), _port)) - return false; - - return connected(); -} - - -void ESP_Mail_HTTPClient::setCACert(const char *caCert) -{ - -#ifndef USING_AXTLS - _wcs->setBufferSizes(_bsslRxSize, _bsslTxSize); -#endif - - if (caCert) - { -#ifndef USING_AXTLS - _wcs->setTrustAnchors(new ESP_Mail::ESP_Mail_X509List(caCert)); -#else - _wcs->setCACert_P(caCert, strlen_P(caCert)); -#endif - _certType = 1; - } - else - { -#ifndef USING_AXTLS - _wcs->setInsecure(); -#endif - _certType = 0; - } - - _wcs->setNoDelay(true); -} - -void ESP_Mail_HTTPClient::setCertFile(const char *caCertFile, esp_mail_file_storage_type storageType, uint8_t sdPin) -{ - -#ifndef USING_AXTLS - _sdPin = sdPin; - _wcs->setBufferSizes(_bsslRxSize, _bsslTxSize); - - if (_clockReady && strlen(caCertFile) > 0) - { - - fs::File f; - if (storageType == esp_mail_file_storage_type_flash) - { - ESP_MAIL_FLASH_FS.begin(); - if (ESP_MAIL_FLASH_FS.exists(caCertFile)) - f = ESP_MAIL_FLASH_FS.open(caCertFile, "r"); - } - else if (storageType == esp_mail_file_storage_type_sd) - { - ESP_MAIL_SD_FS.begin(_sdPin); - if (ESP_MAIL_SD_FS.exists(caCertFile)) - f = ESP_MAIL_SD_FS.open(caCertFile, FILE_READ); - } - - if (f) - { - size_t len = f.size(); - uint8_t *der = new uint8_t[len]; - if (f.available()) - f.read(der, len); - f.close(); - _wcs->setTrustAnchors(new ESP_Mail::ESP_Mail_X509List(der, len)); - delete[] der; - } - _certType = 2; - } -#endif - - _wcs->setNoDelay(true); -} - -#endif /* ESP8266 */ - -#endif /* ESP_Mail_HTTPClient_CPP */ \ No newline at end of file diff --git a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_HTTPClient.h b/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_HTTPClient.h deleted file mode 100644 index 883158a8d0a0..000000000000 --- a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_HTTPClient.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * HTTP Client for ESP8266 wrapper v1.0.3 - * - * The MIT License (MIT) - * Copyright (c) 2021 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person returning a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef ESP_Mail_HTTPClient_H -#define ESP_Mail_HTTPClient_H - -#ifdef ESP8266 - -//ARDUINO_ESP8266_GIT_VER -//2.6.2 0xbc204a9b -//2.6.1 0x482516e3 -//2.6.0 0x643ec203 -//2.5.2 0x8b899c12 -//2.5.1 0xac02aff5 -//2.5.0 0x951aeffa -//2.5.0-beta3 0x21db8fc9 -//2.5.0-beta2 0x0fd86a07 -//2.5.0-beta1 0x9c1e03a1 -//2.4.2 0xbb28d4a3 -//2.4.1 0x614f7c32 -//2.4.0 0x4ceabea9 -//2.4.0-rc2 0x0c897c37 -//2.4.0-rc1 0xf6d232f1 - -#include -#include -#include -#include - -#include "SDK_Version_Common.h" - -#ifndef ARDUINO_ESP8266_GIT_VER -#error Your ESP8266 Arduino Core SDK is outdated, please update. From Arduino IDE go to Boards Manager and search 'esp8266' then select the latest version. -#endif - -#include - -#if ARDUINO_ESP8266_GIT_VER != 0xf6d232f1 && ARDUINO_ESP8266_GIT_VER != 0x0c897c37 && ARDUINO_ESP8266_GIT_VER != 0x4ceabea9 && ARDUINO_ESP8266_GIT_VER != 0x614f7c32 && ARDUINO_ESP8266_GIT_VER != 0xbb28d4a3 -#include "ESP_Mail_WCS.h" -#include "ESP_Mail_BearSSLHelpers.h" -#define ESP_MAIL_SSL_CLIENT ESP_Mail::ESP_Mail_WCS -#else -#error Please update the ESP8266 Arduino Core SDK to latest version. -#endif - -#define FS_NO_GLOBALS -#include -#include -#include "ESP_Mail_FS.h" -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#define ESP_MAIL_FLASH_FS ESP_Mail_DEFAULT_FLASH_FS -#define ESP_MAIL_SD_FS ESP_Mail_DEFAULT_SD_FS - -#if __has_include() || __has_include() -#error WiFi UART bridge was not supported. -#endif - -#define ESP_MAIL_ERROR_HTTPC_ERROR_CONNECTION_REFUSED (-1) -#define ESP_MAIL_ERROR_HTTPC_ERROR_SEND_HEADER_FAILED (-2) -#define ESP_MAIL_ERROR_HTTPC_ERROR_SEND_PAYLOAD_FAILED (-3) -#define ESP_MAIL_DEFAULT_TCP_TIMEOUT_SEC 30 - -enum esp_mail_file_storage_type -{ - esp_mail_file_storage_type_none, - esp_mail_file_storage_type_flash, - esp_mail_file_storage_type_sd, - esp_mail_file_storage_type_univ -}; - -class ESP_Mail_HTTPClient -{ - -public: - ESP_Mail_HTTPClient(); - ~ESP_Mail_HTTPClient(); - - bool begin(const char *host, uint16_t port); - - bool connected(void); - - int send(const char *header, const char *payload); - - bool send(const char *header); - - WiFiClient *stream(void); - - ESP_Mail::ESP_Mail_WCS *_stream(void); - - size_t _ns_print(const char *buf); - - size_t _ns_println(const char *buf); - - void setCACert(const char *caCert); - void setCertFile(const char *caCertFile, esp_mail_file_storage_type storageType, uint8_t sdPin); - bool connect(bool secured); - - int _certType = -1; - std::string _caCertFile = ""; - esp_mail_file_storage_type _caCertFileStoreageType = esp_mail_file_storage_type::esp_mail_file_storage_type_none; - uint16_t tcpTimeout = 40000; - - uint8_t _sdPin = 15; - bool _clockReady = false; - uint16_t _bsslRxSize = 1024; - uint16_t _bsslTxSize = 1024; - bool fragmentable = false; - int chunkSize = 1024; - int maxRXBufSize = 16384; //SSL full supported 16 kB - int maxTXBufSize = 16384; - bool mflnChecked = false; - int rxBufDivider = maxRXBufSize / chunkSize; - int txBufDivider = maxRXBufSize / chunkSize; - ; - -private: - std::unique_ptr _wcs = std::unique_ptr(new ESP_MAIL_SSL_CLIENT()); - std::unique_ptr _cacert; - std::string _host = ""; - uint16_t _port = 0; - bool _secured = true; -}; - -#endif /* ESP8266 */ - -#endif /* ESP_Mail_HTTPClient_H */ \ No newline at end of file diff --git a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_WCS.cpp b/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_WCS.cpp deleted file mode 100644 index d419a9249d0c..000000000000 --- a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_WCS.cpp +++ /dev/null @@ -1,2139 +0,0 @@ -/* - Customized version of WiFiClientSecure.cpp v1.0.1 - - WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries - - Mostly compatible with Arduino WiFi shield library and standard - WiFiClient/ServerSecure (except for certificate handling). - - Copyright (c) 2018 Earle F. Philhower, III - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef ESP_Mail_WCS_CPP -#define ESP_Mail_WCS_CPP - -#ifdef ESP8266 - -#define LWIP_INTERNAL - -#include -#include -#include - -extern "C" -{ -#include -#include -} -#include -#include -#include -#include -#include "ESP_Mail_WCS.h" -#include -#include -#include -#include -#include -#include -#include -#ifdef ESP8266 - #include -#endif -#include - -#if !CORE_MOCK - -// The BearSSL thunks in use for now -#define br_ssl_engine_recvapp_ack thunk_br_ssl_engine_recvapp_ack -#define br_ssl_engine_recvapp_buf thunk_br_ssl_engine_recvapp_buf -#define br_ssl_engine_recvrec_ack thunk_br_ssl_engine_recvrec_ack -#define br_ssl_engine_recvrec_buf thunk_br_ssl_engine_recvrec_buf -#define br_ssl_engine_sendapp_ack thunk_br_ssl_engine_sendapp_ack -#define br_ssl_engine_sendapp_buf thunk_br_ssl_engine_sendapp_buf -#define br_ssl_engine_sendrec_ack thunk_br_ssl_engine_sendrec_ack -#define br_ssl_engine_sendrec_buf thunk_br_ssl_engine_sendrec_buf - -#endif - -#ifdef DEBUG_ESP_SSL -#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR("BSSL:" fmt), ##__VA_ARGS__) -#else -#define DEBUG_BSSL(...) -#endif - -namespace ESP_Mail -{ - - void ESP_Mail_WCS::_clear() - { - // TLS handshake may take more than the 5 second default timeout - _timeout = 15000; - - _sc = nullptr; - _sc_svr = nullptr; - _eng = nullptr; - _x509_minimal = nullptr; - _x509_insecure = nullptr; - _x509_knownkey = nullptr; - _iobuf_in = nullptr; - _iobuf_out = nullptr; - _now = 0; // You can override or ensure time() is correct w/configTime - _ta = nullptr; - setBufferSizes(16384, 512); // Minimum safe - _handshake_done = false; - _recvapp_buf = nullptr; - _recvapp_len = 0; - _oom_err = false; - _session = nullptr; - _cipher_list = nullptr; - _cipher_cnt = 0; - } - - void ESP_Mail_WCS::_clearAuthenticationSettings() - { - _use_insecure = false; - _use_fingerprint = false; - _use_self_signed = false; - _knownkey = nullptr; - _sk = nullptr; - _ta = nullptr; - _axtls_ta = nullptr; - _axtls_chain = nullptr; - _axtls_sk = nullptr; - } - - ESP_Mail_WCS::ESP_Mail_WCS() : WiFiClient() - { - _clear(); - _clearAuthenticationSettings(); - _certStore = nullptr; // Don't want to remove cert store on a clear, should be long lived - stack_thunk_add_ref(); - } - - ESP_Mail_WCS::ESP_Mail_WCS(const ESP_Mail_WCS &rhs) : WiFiClient(rhs) - { - *this = rhs; - stack_thunk_add_ref(); - } - - ESP_Mail_WCS::~ESP_Mail_WCS() - { - if (_client) - { - _client->unref(); - _client = nullptr; - } - _cipher_list = nullptr; // std::shared will free if last reference - _freeSSL(); - stack_thunk_del_ref(); - // Clean up any dangling axtls compat structures, if needed - _axtls_ta = nullptr; - _axtls_chain = nullptr; - _axtls_sk = nullptr; - } - - ESP_Mail_WCS::ESP_Mail_WCS(ClientContext *client, - const ESP_Mail_X509List *chain, const PrivateKey *sk, - int iobuf_in_size, int iobuf_out_size, const ESP_Mail_X509List *client_CA_ta) - { - _clear(); - _clearAuthenticationSettings(); - stack_thunk_add_ref(); - _iobuf_in_size = iobuf_in_size; - _iobuf_out_size = iobuf_out_size; - _client = client; - _client->ref(); - if (!_connectSSLServerRSA(chain, sk, client_CA_ta)) - { - _client->unref(); - _client = nullptr; - _clear(); - } - } - - ESP_Mail_WCS::ESP_Mail_WCS(ClientContext *client, - const ESP_Mail_X509List *chain, - unsigned cert_issuer_key_type, const PrivateKey *sk, - int iobuf_in_size, int iobuf_out_size, const ESP_Mail_X509List *client_CA_ta) - { - _clear(); - _clearAuthenticationSettings(); - stack_thunk_add_ref(); - _iobuf_in_size = iobuf_in_size; - _iobuf_out_size = iobuf_out_size; - _client = client; - _client->ref(); - if (!_connectSSLServerEC(chain, cert_issuer_key_type, sk, client_CA_ta)) - { - _client->unref(); - _client = nullptr; - _clear(); - } - } - - void ESP_Mail_WCS::setClientRSACert(const ESP_Mail_X509List *chain, const PrivateKey *sk) - { - _chain = chain; - _sk = sk; - } - - void ESP_Mail_WCS::setClientECCert(const ESP_Mail_X509List *chain, - const PrivateKey *sk, unsigned allowed_usages, unsigned cert_issuer_key_type) - { - _chain = chain; - _sk = sk; - _allowed_usages = allowed_usages; - _cert_issuer_key_type = cert_issuer_key_type; - } - - void ESP_Mail_WCS::setBufferSizes(int recv, int xmit) - { - // Following constants taken from bearssl/src/ssl/ssl_engine.c (not exported unfortunately) - const int MAX_OUT_OVERHEAD = 85; - const int MAX_IN_OVERHEAD = 325; - - // The data buffers must be between 512B and 16KB - recv = std::max(512, std::min(16384, recv)); - xmit = std::max(512, std::min(16384, xmit)); - - // Add in overhead for SSL protocol - recv += MAX_IN_OVERHEAD; - xmit += MAX_OUT_OVERHEAD; - _iobuf_in_size = recv; - _iobuf_out_size = xmit; - } - - bool ESP_Mail_WCS::stop(unsigned int maxWaitMs) - { - bool ret = WiFiClient::stop(maxWaitMs); // calls our virtual flush() - // Only if we've already connected, store session params and clear the connection options - if (_handshake_done) - { - if (_session) - { - br_ssl_engine_get_session_parameters(_eng, _session->getSession()); - } - } - _freeSSL(); - return ret; - } - - bool ESP_Mail_WCS::flush(unsigned int maxWaitMs) - { - (void)_run_until(BR_SSL_SENDAPP); - return WiFiClient::flush(maxWaitMs); - } - - int ESP_Mail_WCS::connect(IPAddress ip, uint16_t port) - { - if (!WiFiClient::connect(ip, port)) - { - return 0; - } - return _connectSSL(nullptr); - } - - int ESP_Mail_WCS::connect(const char *name, uint16_t port) - { - IPAddress remote_addr; - if (!WiFi.hostByName(name, remote_addr)) - { - DEBUG_BSSL("connect: Name loopup failure\n"); - return 0; - } - if (!WiFiClient::connect(remote_addr, port)) - { - DEBUG_BSSL("connect: Unable to connect TCP socket\n"); - return 0; - } - _host_name = name; - if (!_secured) - return true; - return _connectSSL(name); - } - - int ESP_Mail_WCS::connect(const String &host, uint16_t port) - { - return connect(host.c_str(), port); - } - - void ESP_Mail_WCS::_freeSSL() - { - // These are smart pointers and will free if refcnt==0 - _sc = nullptr; - _sc_svr = nullptr; - _x509_minimal = nullptr; - _x509_insecure = nullptr; - _x509_knownkey = nullptr; - _iobuf_in = nullptr; - _iobuf_out = nullptr; - // Reset non-allocated ptrs (pointing to bits potentially free'd above) - _recvapp_buf = nullptr; - _recvapp_len = 0; - // This connection is toast - _handshake_done = false; - _timeout = 15000; - } - - bool ESP_Mail_WCS::_clientConnected() - { - return (_client && _client->state() == ESTABLISHED); - } - - uint8_t ESP_Mail_WCS::connected() - { - if (available() || (_clientConnected() && _handshake_done && (br_ssl_engine_current_state(_eng) != BR_SSL_CLOSED))) - { - return true; - } - return false; - } - - size_t ESP_Mail_WCS::_write(const uint8_t *buf, size_t size, bool pmem) - { - size_t sent_bytes = 0; - - if (!connected() || !size || !_handshake_done) - { - return 0; - } - - do - { - // Ensure we yield if we need multiple fragments to avoid WDT - if (sent_bytes) - { - optimistic_yield(1000); - } - - // Get BearSSL to a state where we can send - if (_run_until(BR_SSL_SENDAPP) < 0) - { - break; - } - - if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) - { - size_t sendapp_len; - unsigned char *sendapp_buf = br_ssl_engine_sendapp_buf(_eng, &sendapp_len); - int to_send = size > sendapp_len ? sendapp_len : size; - if (pmem) - { - memcpy_P(sendapp_buf, buf, to_send); - } - else - { - memcpy(sendapp_buf, buf, to_send); - } - br_ssl_engine_sendapp_ack(_eng, to_send); - br_ssl_engine_flush(_eng, 0); - flush(); - buf += to_send; - sent_bytes += to_send; - size -= to_send; - } - else - { - break; - } - } while (size); - - return sent_bytes; - } - - size_t ESP_Mail_WCS::write(const uint8_t *buf, size_t size) - { - return _write(buf, size, false); - } - - size_t ESP_Mail_WCS::write_P(PGM_P buf, size_t size) - { - return _write((const uint8_t *)buf, size, true); - } - - // We have to manually read and send individual chunks. - size_t ESP_Mail_WCS::write(Stream &stream) - { - size_t totalSent = 0; - size_t countRead; - size_t countSent; - - if (!connected() || !_handshake_done) - { - DEBUG_BSSL("write: Connect/handshake not completed yet\n"); - return 0; - } - - do - { - uint8_t temp[256]; // Temporary chunk size same as ClientContext - countSent = 0; - countRead = stream.readBytes(temp, sizeof(temp)); - if (countRead) - { - countSent = _write((const uint8_t *)temp, countRead, true); - totalSent += countSent; - } - yield(); // Feed the WDT - } while ((countSent == countRead) && (countSent > 0)); - return totalSent; - } - - int ESP_Mail_WCS::read(uint8_t *buf, size_t size) - { - if (!ctx_present() || !_handshake_done) - { - return -1; - } - - int avail = available(); - bool conn = connected(); - if (!avail && conn) - { - return 0; // We're still connected, but nothing to read - } - if (!avail && !conn) - { - DEBUG_BSSL("read: Not connected, none left available\n"); - return -1; - } - - if (avail) - { - // Take data from the recvapp buffer - int to_copy = _recvapp_len < size ? _recvapp_len : size; - memcpy(buf, _recvapp_buf, to_copy); - br_ssl_engine_recvapp_ack(_eng, to_copy); - _recvapp_buf = nullptr; - _recvapp_len = 0; - return to_copy; - } - - if (!conn) - { - DEBUG_BSSL("read: Not connected\n"); - return -1; - } - return 0; // If we're connected, no error but no read. - } - - int ESP_Mail_WCS::read() - { - uint8_t c; - if (1 == read(&c, 1)) - { - return c; - } - DEBUG_BSSL("read: failed\n"); - return -1; - } - - int ESP_Mail_WCS::available() - { - if (_recvapp_buf) - { - return _recvapp_len; // Anything from last call? - } - _recvapp_buf = nullptr; - _recvapp_len = 0; - if (!ctx_present() || _run_until(BR_SSL_RECVAPP, false) < 0) - { - return 0; - } - int st = br_ssl_engine_current_state(_eng); - if (st == BR_SSL_CLOSED) - { - return 0; // Nothing leftover, SSL is closed - } - if (st & BR_SSL_RECVAPP) - { - _recvapp_buf = br_ssl_engine_recvapp_buf(_eng, &_recvapp_len); - return _recvapp_len; - } - - return 0; - } - - int ESP_Mail_WCS::peek() - { - if (!ctx_present() || !available()) - { - DEBUG_BSSL("peek: Not connected, none left available\n"); - return -1; - } - if (_recvapp_buf && _recvapp_len) - { - return _recvapp_buf[0]; - } - DEBUG_BSSL("peek: No data left\n"); - return -1; - } - - size_t ESP_Mail_WCS::peekBytes(uint8_t *buffer, size_t length) - { - size_t to_copy = 0; - if (!ctx_present()) - { - DEBUG_BSSL("peekBytes: Not connected\n"); - return 0; - } - - _startMillis = millis(); - while ((available() < (int)length) && ((millis() - _startMillis) < 5000)) - { - yield(); - } - - to_copy = _recvapp_len < length ? _recvapp_len : length; - memcpy(buffer, _recvapp_buf, to_copy); - return to_copy; - } - - /* --- Copied almost verbatim from BEARSSL SSL_IO.C --- - Run the engine, until the specified target state is achieved, or - an error occurs. The target state is SENDAPP, RECVAPP, or the - combination of both (the combination matches either). When a match is - achieved, this function returns 0. On error, it returns -1. -*/ - int ESP_Mail_WCS::_run_until(unsigned target, bool blocking) - { - if (!ctx_present()) - { - DEBUG_BSSL("_run_until: Not connected\n"); - return -1; - } - - esp8266::polledTimeout::oneShotMs loopTimeout(_timeout); - - for (int no_work = 0; blocking || no_work < 2;) - { - optimistic_yield(100); - - if (loopTimeout) - { - DEBUG_BSSL("_run_until: Timeout\n"); - return -1; - } - - int state; - state = br_ssl_engine_current_state(_eng); - if (state & BR_SSL_CLOSED) - { - return -1; - } - - if (!(_client->state() == ESTABLISHED) && !WiFiClient::available()) - { - return (state & target) ? 0 : -1; - } - - /* - If there is some record data to send, do it. This takes - precedence over everything else. - */ - if (state & BR_SSL_SENDREC) - { - unsigned char *buf; - size_t len; - int wlen; - size_t availForWrite; - - buf = br_ssl_engine_sendrec_buf(_eng, &len); - availForWrite = WiFiClient::availableForWrite(); - - if (!blocking && len > availForWrite) - { - /* - writes on WiFiClient will block if len > availableForWrite() - this is needed to prevent available() calls from blocking - on dropped connections - */ - len = availForWrite; - } - wlen = WiFiClient::write(buf, len); - if (wlen <= 0) - { - /* - If we received a close_notify and we - still send something, then we have our - own response close_notify to send, and - the peer is allowed by RFC 5246 not to - wait for it. - */ - return -1; - } - if (wlen > 0) - { - br_ssl_engine_sendrec_ack(_eng, wlen); - } - no_work = 0; - continue; - } - - /* - If we reached our target, then we are finished. - */ - if (state & target) - { - return 0; - } - - /* - If some application data must be read, and we did not - exit, then this means that we are trying to write data, - and that's not possible until the application data is - read. This may happen if using a shared in/out buffer, - and the underlying protocol is not strictly half-duplex. - This is unrecoverable here, so we report an error. - */ - if (state & BR_SSL_RECVAPP) - { - DEBUG_BSSL("_run_until: Fatal protocol state\n"); - return -1; - } - - /* - If we reached that point, then either we are trying - to read data and there is some, or the engine is stuck - until a new record is obtained. - */ - if (state & BR_SSL_RECVREC) - { - if (WiFiClient::available()) - { - unsigned char *buf; - size_t len; - int rlen; - - buf = br_ssl_engine_recvrec_buf(_eng, &len); - rlen = WiFiClient::read(buf, len); - if (rlen < 0) - { - return -1; - } - if (rlen > 0) - { - br_ssl_engine_recvrec_ack(_eng, rlen); - } - no_work = 0; - continue; - } - } - - /* - We can reach that point if the target RECVAPP, and - the state contains SENDAPP only. This may happen with - a shared in/out buffer. In that case, we must flush - the buffered data to "make room" for a new incoming - record. - */ - br_ssl_engine_flush(_eng, 0); - - no_work++; // We didn't actually advance here - } - // We only get here if we ran through the loop without getting anything done - return -1; - } - - bool ESP_Mail_WCS::_wait_for_handshake() - { - _handshake_done = false; - while (!_handshake_done && _clientConnected()) - { - int ret = _run_until(BR_SSL_SENDAPP); - if (ret < 0) - { - DEBUG_BSSL("_wait_for_handshake: failed\n"); - break; - } - if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) - { - _handshake_done = true; - } - optimistic_yield(1000); - } - return _handshake_done; - } - - static uint8_t htoi(unsigned char c) - { - if (c >= '0' && c <= '9') - return c - '0'; - else if (c >= 'A' && c <= 'F') - return 10 + c - 'A'; - else if (c >= 'a' && c <= 'f') - return 10 + c - 'a'; - else - return 255; - } - - // Set a fingerprint by parsing an ASCII string - bool ESP_Mail_WCS::setFingerprint(const char *fpStr) - { - int idx = 0; - uint8_t c, d; - uint8_t fp[20]; - - while (idx < 20) - { - c = pgm_read_byte(fpStr++); - if (!c) - break; // String ended, done processing - d = pgm_read_byte(fpStr++); - if (!d) - { - DEBUG_BSSL("setFingerprint: FP too short\n"); - return false; // Only half of the last hex digit, error - } - c = htoi(c); - d = htoi(d); - if ((c > 15) || (d > 15)) - { - DEBUG_BSSL("setFingerprint: Invalid char\n"); - return false; // Error in one of the hex characters - } - fp[idx++] = (c << 4) | d; - - // Skip 0 or more spaces or colons - while (pgm_read_byte(fpStr) && (pgm_read_byte(fpStr) == ' ' || pgm_read_byte(fpStr) == ':')) - { - fpStr++; - } - } - if ((idx != 20) || pgm_read_byte(fpStr)) - { - DEBUG_BSSL("setFingerprint: Garbage at end of fp\n"); - return false; // Garbage at EOL or we didn't have enough hex digits - } - return setFingerprint(fp); - } - - extern "C" - { - - // BearSSL doesn't define a true insecure decoder, so we make one ourselves - // from the simple parser. It generates the issuer and subject hashes and - // the SHA1 fingerprint, only one (or none!) of which will be used to - // "verify" the certificate. - - // Private x509 decoder state - struct br_x509_insecure_context - { - const br_x509_class *vtable; - bool done_cert; - const uint8_t *match_fingerprint; - br_sha1_context sha1_cert; - bool allow_self_signed; - br_sha256_context sha256_subject; - br_sha256_context sha256_issuer; - br_x509_decoder_context ctx; - }; - - // Callback for the x509_minimal subject DN - static void insecure_subject_dn_append(void *ctx, const void *buf, size_t len) - { - br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; - br_sha256_update(&xc->sha256_subject, buf, len); - } - - // Callback for the x509_minimal issuer DN - static void insecure_issuer_dn_append(void *ctx, const void *buf, size_t len) - { - br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; - br_sha256_update(&xc->sha256_issuer, buf, len); - } - - // Callback on the first byte of any certificate - static void insecure_start_chain(const br_x509_class **ctx, const char *server_name) - { - br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; - br_x509_decoder_init(&xc->ctx, insecure_subject_dn_append, xc, insecure_issuer_dn_append, xc); - xc->done_cert = false; - br_sha1_init(&xc->sha1_cert); - br_sha256_init(&xc->sha256_subject); - br_sha256_init(&xc->sha256_issuer); - (void)server_name; - } - - // Callback for each certificate present in the chain (but only operates - // on the first one by design). - static void insecure_start_cert(const br_x509_class **ctx, uint32_t length) - { - (void)ctx; - (void)length; - } - - // Callback for each byte stream in the chain. Only process first cert. - static void insecure_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) - { - br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; - // Don't process anything but the first certificate in the chain - if (!xc->done_cert) - { - br_sha1_update(&xc->sha1_cert, buf, len); - br_x509_decoder_push(&xc->ctx, (const void *)buf, len); -#ifdef DEBUG_ESP_SSL - DEBUG_BSSL("CERT: "); - for (size_t i = 0; i < len; i++) - { - DEBUG_ESP_PORT.printf_P(PSTR("%02x "), buf[i] & 0xff); - } - DEBUG_ESP_PORT.printf_P(PSTR("\n")); -#endif - } - } - - // Callback on individual cert end. - static void insecure_end_cert(const br_x509_class **ctx) - { - br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; - xc->done_cert = true; - } - - // Callback when complete chain has been parsed. - // Return 0 on validation success, !0 on validation error - static unsigned insecure_end_chain(const br_x509_class **ctx) - { - const br_x509_insecure_context *xc = (const br_x509_insecure_context *)ctx; - if (!xc->done_cert) - { - DEBUG_BSSL("insecure_end_chain: No cert seen\n"); - return 1; // error - } - - // Handle SHA1 fingerprint matching - char res[20]; - br_sha1_out(&xc->sha1_cert, res); - if (xc->match_fingerprint && memcmp(res, xc->match_fingerprint, sizeof(res))) - { -#ifdef DEBUG_ESP_SSL - DEBUG_BSSL("insecure_end_chain: Received cert FP doesn't match\n"); - char buff[3 * sizeof(res) + 1]; // 3 chars per byte XX_, and null - buff[0] = 0; - for (size_t i = 0; i < sizeof(res); i++) - { - char hex[4]; // XX_\0 - snprintf(hex, sizeof(hex), "%02x ", xc->match_fingerprint[i] & 0xff); - strlcat(buff, hex, sizeof(buff)); - } - DEBUG_BSSL("insecure_end_chain: expected %s\n", buff); - buff[0] = 0; - for (size_t i = 0; i < sizeof(res); i++) - { - char hex[4]; // XX_\0 - snprintf(hex, sizeof(hex), "%02x ", res[i] & 0xff); - strlcat(buff, hex, sizeof(buff)); - } - DEBUG_BSSL("insecure_end_chain: received %s\n", buff); -#endif - return BR_ERR_X509_NOT_TRUSTED; - } - - // Handle self-signer certificate acceptance - char res_issuer[32]; - char res_subject[32]; - br_sha256_out(&xc->sha256_issuer, res_issuer); - br_sha256_out(&xc->sha256_subject, res_subject); - if (xc->allow_self_signed && memcmp(res_subject, res_issuer, sizeof(res_issuer))) - { - DEBUG_BSSL("insecure_end_chain: Didn't get self-signed cert\n"); - return BR_ERR_X509_NOT_TRUSTED; - } - - // Default (no validation at all) or no errors in prior checks = success. - return 0; - } - - // Return the public key from the validator (set by x509_minimal) - static const br_x509_pkey *insecure_get_pkey(const br_x509_class *const *ctx, unsigned *usages) - { - const br_x509_insecure_context *xc = (const br_x509_insecure_context *)ctx; - if (usages != NULL) - { - *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN; // I said we were insecure! - } - return &xc->ctx.pkey; - } - - // Set up the x509 insecure data structures for BearSSL core to use. - void esp_mail_br_x509_insecure_init(br_x509_insecure_context *ctx, int _use_fingerprint, const uint8_t _fingerprint[20], int _allow_self_signed) - { - static const br_x509_class br_x509_insecure_vtable PROGMEM = { - sizeof(br_x509_insecure_context), - insecure_start_chain, - insecure_start_cert, - insecure_append, - insecure_end_cert, - insecure_end_chain, - insecure_get_pkey}; - - memset(ctx, 0, sizeof *ctx); - ctx->vtable = &br_x509_insecure_vtable; - ctx->done_cert = false; - ctx->match_fingerprint = _use_fingerprint ? _fingerprint : nullptr; - ctx->allow_self_signed = _allow_self_signed ? 1 : 0; - } - - // Some constants uses to init the server/client contexts - // Note that suites_P needs to be copied to RAM before use w/BearSSL! - // List copied verbatim from BearSSL/ssl_client_full.c - /* - * The "full" profile supports all implemented cipher suites. - * - * Rationale for suite order, from most important to least - * important rule: - * - * -- Don't use 3DES if AES or ChaCha20 is available. - * -- Try to have Forward Secrecy (ECDHE suite) if possible. - * -- When not using Forward Secrecy, ECDH key exchange is - * better than RSA key exchange (slightly more expensive on the - * client, but much cheaper on the server, and it implies smaller - * messages). - * -- ChaCha20+Poly1305 is better than AES/GCM (faster, smaller code). - * -- GCM is better than CCM and CBC. CCM is better than CBC. - * -- CCM is preferable over CCM_8 (with CCM_8, forgeries may succeed - * with probability 2^(-64)). - * -- AES-128 is preferred over AES-256 (AES-128 is already - * strong enough, and AES-256 is 40% more expensive). - */ - static const uint16_t suites_P[] PROGMEM = { -#ifndef BEARSSL_SSL_BASIC - BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_RSA_WITH_AES_128_CCM, - BR_TLS_RSA_WITH_AES_256_CCM, - BR_TLS_RSA_WITH_AES_128_CCM_8, - BR_TLS_RSA_WITH_AES_256_CCM_8, -#endif - BR_TLS_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_RSA_WITH_AES_256_CBC_SHA256, - BR_TLS_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_RSA_WITH_AES_256_CBC_SHA, -#ifndef BEARSSL_SSL_BASIC - BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA -#endif - }; -#ifndef BEARSSL_SSL_BASIC - // Server w/EC has one set, not possible with basic SSL config - static const uint16_t suites_server_ec_P[] PROGMEM = { - BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA}; -#endif - - static const uint16_t suites_server_rsa_P[] PROGMEM = { -#ifndef BEARSSL_SSL_BASIC - BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_RSA_WITH_AES_128_CCM, - BR_TLS_RSA_WITH_AES_256_CCM, - BR_TLS_RSA_WITH_AES_128_CCM_8, - BR_TLS_RSA_WITH_AES_256_CCM_8, -#endif - BR_TLS_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_RSA_WITH_AES_256_CBC_SHA256, - BR_TLS_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_RSA_WITH_AES_256_CBC_SHA, -#ifndef BEARSSL_SSL_BASIC - BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA -#endif - }; - - // For apps which want to use less secure but faster ciphers, only - static const uint16_t faster_suites_P[] PROGMEM = { - BR_TLS_RSA_WITH_AES_256_CBC_SHA256, - BR_TLS_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_RSA_WITH_AES_128_CBC_SHA}; - - // Install hashes into the SSL engine - static void br_ssl_client_install_hashes(br_ssl_engine_context *eng) - { - br_ssl_engine_set_hash(eng, br_md5_ID, &br_md5_vtable); - br_ssl_engine_set_hash(eng, br_sha1_ID, &br_sha1_vtable); - br_ssl_engine_set_hash(eng, br_sha224_ID, &br_sha224_vtable); - br_ssl_engine_set_hash(eng, br_sha256_ID, &br_sha256_vtable); - br_ssl_engine_set_hash(eng, br_sha384_ID, &br_sha384_vtable); - br_ssl_engine_set_hash(eng, br_sha512_ID, &br_sha512_vtable); - } - - static void br_x509_minimal_install_hashes(br_x509_minimal_context *x509) - { - br_x509_minimal_set_hash(x509, br_md5_ID, &br_md5_vtable); - br_x509_minimal_set_hash(x509, br_sha1_ID, &br_sha1_vtable); - br_x509_minimal_set_hash(x509, br_sha224_ID, &br_sha224_vtable); - br_x509_minimal_set_hash(x509, br_sha256_ID, &br_sha256_vtable); - br_x509_minimal_set_hash(x509, br_sha384_ID, &br_sha384_vtable); - br_x509_minimal_set_hash(x509, br_sha512_ID, &br_sha512_vtable); - } - - // Default initializion for our SSL clients - static void br_ssl_client_base_init(br_ssl_client_context *cc, const uint16_t *cipher_list, int cipher_cnt) - { - uint16_t suites[cipher_cnt]; - memcpy_P(suites, cipher_list, cipher_cnt * sizeof(cipher_list[0])); - br_ssl_client_zero(cc); - br_ssl_engine_add_flags(&cc->eng, BR_OPT_NO_RENEGOTIATION); // forbid SSL renegociation, as we free the Private Key after handshake - br_ssl_engine_set_versions(&cc->eng, BR_TLS10, BR_TLS12); - br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); - br_ssl_client_set_default_rsapub(cc); - br_ssl_engine_set_default_rsavrfy(&cc->eng); -#ifndef BEARSSL_SSL_BASIC - br_ssl_engine_set_default_ecdsa(&cc->eng); -#endif - br_ssl_client_install_hashes(&cc->eng); - br_ssl_engine_set_prf10(&cc->eng, &br_tls10_prf); - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf); - br_ssl_engine_set_default_aes_cbc(&cc->eng); -#ifndef BEARSSL_SSL_BASIC - br_ssl_engine_set_default_aes_gcm(&cc->eng); - br_ssl_engine_set_default_aes_ccm(&cc->eng); - br_ssl_engine_set_default_des_cbc(&cc->eng); - br_ssl_engine_set_default_chapol(&cc->eng); -#endif - } - - // Default initializion for our SSL clients - static void br_ssl_server_base_init(br_ssl_server_context *cc, const uint16_t *cipher_list, int cipher_cnt) - { - uint16_t suites[cipher_cnt]; - memcpy_P(suites, cipher_list, cipher_cnt * sizeof(cipher_list[0])); - br_ssl_server_zero(cc); - br_ssl_engine_add_flags(&cc->eng, BR_OPT_NO_RENEGOTIATION); // forbid SSL renegociation, as we free the Private Key after handshake - br_ssl_engine_set_versions(&cc->eng, BR_TLS10, BR_TLS12); - br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); -#ifndef BEARSSL_SSL_BASIC - br_ssl_engine_set_default_ec(&cc->eng); -#endif - - br_ssl_client_install_hashes(&cc->eng); - br_ssl_engine_set_prf10(&cc->eng, &br_tls10_prf); - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf); - br_ssl_engine_set_default_aes_cbc(&cc->eng); -#ifndef BEARSSL_SSL_BASIC - br_ssl_engine_set_default_aes_ccm(&cc->eng); - br_ssl_engine_set_default_aes_gcm(&cc->eng); - br_ssl_engine_set_default_des_cbc(&cc->eng); - br_ssl_engine_set_default_chapol(&cc->eng); -#endif - } - } - - // Set custom list of ciphers - bool ESP_Mail_WCS::setCiphers(const uint16_t *cipherAry, int cipherCount) - { - _cipher_list = nullptr; - _cipher_list = std::shared_ptr(new uint16_t[cipherCount], std::default_delete()); - if (!_cipher_list.get()) - { - DEBUG_BSSL("setCiphers: list empty\n"); - return false; - } - memcpy_P(_cipher_list.get(), cipherAry, cipherCount * sizeof(uint16_t)); - _cipher_cnt = cipherCount; - return true; - } - - bool ESP_Mail_WCS::setCiphersLessSecure() - { - return setCiphers(faster_suites_P, sizeof(faster_suites_P) / sizeof(faster_suites_P[0])); - } - - bool ESP_Mail_WCS::setCiphers(std::vector list) - { - return setCiphers(&list[0], list.size()); - } - - // Installs the appropriate X509 cert validation method for a client connection - bool ESP_Mail_WCS::_installClientX509Validator() - { - if (_use_insecure || _use_fingerprint || _use_self_signed) - { - // Use common insecure x509 authenticator - _x509_insecure = std::make_shared(); - if (!_x509_insecure) - { - DEBUG_BSSL("_installClientX509Validator: OOM for _x509_insecure\n"); - return false; - } - esp_mail_br_x509_insecure_init(_x509_insecure.get(), _use_fingerprint, _fingerprint, _use_self_signed); - br_ssl_engine_set_x509(_eng, &_x509_insecure->vtable); - } - else if (_knownkey) - { - // Simple, pre-known public key authenticator, ignores cert completely. - _x509_knownkey = std::make_shared(); - if (!_x509_knownkey) - { - DEBUG_BSSL("_installClientX509Validator: OOM for _x509_knownkey\n"); - return false; - } - if (_knownkey->isRSA()) - { - br_x509_knownkey_init_rsa(_x509_knownkey.get(), _knownkey->getRSA(), _knownkey_usages); - } - else if (_knownkey->isEC()) - { -#ifndef BEARSSL_SSL_BASIC - br_x509_knownkey_init_ec(_x509_knownkey.get(), _knownkey->getEC(), _knownkey_usages); -#else - (void)_knownkey; - (void)_knownkey_usages; - DEBUG_BSSL("_installClientX509Validator: Attempting to use EC keys in minimal cipher mode (no EC)\n"); - return false; -#endif - } - br_ssl_engine_set_x509(_eng, &_x509_knownkey->vtable); - } - else - { - // X509 minimal validator. Checks dates, cert chain for trusted CA, etc. - _x509_minimal = std::make_shared(); - if (!_x509_minimal) - { - DEBUG_BSSL("_installClientX509Validator: OOM for _x509_minimal\n"); - return false; - } - br_x509_minimal_init(_x509_minimal.get(), &br_sha256_vtable, _ta ? _ta->getTrustAnchors() : nullptr, _ta ? _ta->getCount() : 0); - br_x509_minimal_set_rsa(_x509_minimal.get(), br_ssl_engine_get_rsavrfy(_eng)); -#ifndef BEARSSL_SSL_BASIC - br_x509_minimal_set_ecdsa(_x509_minimal.get(), br_ssl_engine_get_ec(_eng), br_ssl_engine_get_ecdsa(_eng)); -#endif - br_x509_minimal_install_hashes(_x509_minimal.get()); - if (_now) - { - // Magic constants convert to x509 times - br_x509_minimal_set_time(_x509_minimal.get(), ((uint32_t)_now) / 86400 + 719528, ((uint32_t)_now) % 86400); - } - if (_certStore) - { - _certStore->installCertStore(_x509_minimal.get()); - } - br_ssl_engine_set_x509(_eng, &_x509_minimal->vtable); - } - return true; - } - - // Called by connect() to do the actual SSL setup and handshake. - // Returns if the SSL handshake succeeded. - bool ESP_Mail_WCS::_connectSSL(const char *hostName) - { - DEBUG_BSSL("_connectSSL: start connection\n"); - _freeSSL(); - _oom_err = false; - -#ifdef DEBUG_ESP_SSL - // BearSSL will reject all connections unless an authentication option is set, warn in DEBUG builds - if (!_use_insecure && !_use_fingerprint && !_use_self_signed && !_knownkey && !_certStore && !_ta) - { - DEBUG_BSSL("Connection *will* fail, no authentication method is setup\n"); - } -#endif - - _sc = std::make_shared(); - _eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr - _iobuf_in = std::shared_ptr(new unsigned char[_iobuf_in_size], std::default_delete()); - _iobuf_out = std::shared_ptr(new unsigned char[_iobuf_out_size], std::default_delete()); - - if (!_sc || !_iobuf_in || !_iobuf_out) - { - _freeSSL(); // Frees _sc, _iobuf* - _oom_err = true; - DEBUG_BSSL("_connectSSL: OOM error\n"); - return false; - } - - // If no cipher list yet set, use defaults - if (_cipher_list.get() == nullptr) - { - br_ssl_client_base_init(_sc.get(), suites_P, sizeof(suites_P) / sizeof(suites_P[0])); - } - else - { - br_ssl_client_base_init(_sc.get(), _cipher_list.get(), _cipher_cnt); - } - // Only failure possible in the installation is OOM - if (!_installClientX509Validator()) - { - _freeSSL(); - _oom_err = true; - DEBUG_BSSL("_connectSSL: Can't install x509 validator\n"); - return false; - } - br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size); - - // Apply any client certificates, if supplied. - if (_sk && _sk->isRSA()) - { - br_ssl_client_set_single_rsa(_sc.get(), _chain ? _chain->getX509Certs() : nullptr, _chain ? _chain->getCount() : 0, - _sk->getRSA(), br_rsa_pkcs1_sign_get_default()); - } - else if (_sk && _sk->isEC()) - { -#ifndef BEARSSL_SSL_BASIC - br_ssl_client_set_single_ec(_sc.get(), _chain ? _chain->getX509Certs() : nullptr, _chain ? _chain->getCount() : 0, - _sk->getEC(), _allowed_usages, - _cert_issuer_key_type, br_ec_get_default(), br_ecdsa_sign_asn1_get_default()); -#else - _freeSSL(); - DEBUG_BSSL("_connectSSL: Attempting to use EC cert in minimal cipher mode (no EC)\n"); - return false; -#endif - } - - // Restore session from the storage spot, if present - if (_session) - { - br_ssl_engine_set_session_parameters(_eng, _session->getSession()); - } - - if (!br_ssl_client_reset(_sc.get(), hostName, _session ? 1 : 0)) - { - _freeSSL(); - DEBUG_BSSL("_connectSSL: Can't reset client\n"); - return false; - } - - auto ret = _wait_for_handshake(); -#ifdef DEBUG_ESP_SSL - if (!ret) - { - char err[256]; - getLastSSLError(err, sizeof(err)); - DEBUG_BSSL("Couldn't connect. Error = '%s'\n", err); - } - else - { - DEBUG_BSSL("Connected!\n"); - } -#endif - - // Session is already validated here, there is no need to keep following - _x509_minimal = nullptr; - _x509_insecure = nullptr; - _x509_knownkey = nullptr; - - // reduce timeout after successful handshake to fail fast if server stop accepting our data for whathever reason - if (ret) - _timeout = 5000; - - return ret; - } - - // Slightly different X509 setup for servers who want to validate client - // certificates, so factor it out as it's used in RSA and EC servers. - bool ESP_Mail_WCS::_installServerX509Validator(const ESP_Mail_X509List *client_CA_ta) - { - if (client_CA_ta) - { - _ta = client_CA_ta; - // X509 minimal validator. Checks dates, cert chain for trusted CA, etc. - _x509_minimal = std::make_shared(); - if (!_x509_minimal) - { - _freeSSL(); - _oom_err = true; - DEBUG_BSSL("_installServerX509Validator: OOM for _x509_minimal\n"); - return false; - } - br_x509_minimal_init(_x509_minimal.get(), &br_sha256_vtable, _ta->getTrustAnchors(), _ta->getCount()); - br_ssl_engine_set_default_rsavrfy(_eng); -#ifndef BEARSSL_SSL_BASIC - br_ssl_engine_set_default_ecdsa(_eng); -#endif - br_x509_minimal_set_rsa(_x509_minimal.get(), br_ssl_engine_get_rsavrfy(_eng)); -#ifndef BEARSSL_SSL_BASIC - br_x509_minimal_set_ecdsa(_x509_minimal.get(), br_ssl_engine_get_ec(_eng), br_ssl_engine_get_ecdsa(_eng)); -#endif - br_x509_minimal_install_hashes(_x509_minimal.get()); - if (_now) - { - // Magic constants convert to x509 times - br_x509_minimal_set_time(_x509_minimal.get(), ((uint32_t)_now) / 86400 + 719528, ((uint32_t)_now) % 86400); - } - br_ssl_engine_set_x509(_eng, &_x509_minimal->vtable); - br_ssl_server_set_trust_anchor_names_alt(_sc_svr.get(), _ta->getTrustAnchors(), _ta->getCount()); - } - return true; - } - - // Called by WiFiServerBearSSL when an RSA cert/key is specified. - bool ESP_Mail_WCS::_connectSSLServerRSA(const ESP_Mail_X509List *chain, - const PrivateKey *sk, - const ESP_Mail_X509List *client_CA_ta) - { - _freeSSL(); - _oom_err = false; - _sc_svr = std::make_shared(); - _eng = &_sc_svr->eng; // Allocation/deallocation taken care of by the _sc shared_ptr - _iobuf_in = std::shared_ptr(new unsigned char[_iobuf_in_size], std::default_delete()); - _iobuf_out = std::shared_ptr(new unsigned char[_iobuf_out_size], std::default_delete()); - - if (!_sc_svr || !_iobuf_in || !_iobuf_out) - { - _freeSSL(); - _oom_err = true; - DEBUG_BSSL("_connectSSLServerRSA: OOM error\n"); - return false; - } - - br_ssl_server_base_init(_sc_svr.get(), suites_server_rsa_P, sizeof(suites_server_rsa_P) / sizeof(suites_server_rsa_P[0])); - br_ssl_server_set_single_rsa(_sc_svr.get(), chain ? chain->getX509Certs() : nullptr, chain ? chain->getCount() : 0, - sk ? sk->getRSA() : nullptr, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, - br_rsa_private_get_default(), br_rsa_pkcs1_sign_get_default()); - br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size); - if (client_CA_ta && !_installServerX509Validator(client_CA_ta)) - { - DEBUG_BSSL("_connectSSLServerRSA: Can't install serverX509check\n"); - return false; - } - if (!br_ssl_server_reset(_sc_svr.get())) - { - _freeSSL(); - DEBUG_BSSL("_connectSSLServerRSA: Can't reset server ctx\n"); - return false; - } - - return _wait_for_handshake(); - } - - // Called by WiFiServerBearSSL when an elliptic curve cert/key is specified. - bool ESP_Mail_WCS::_connectSSLServerEC(const ESP_Mail_X509List *chain, - unsigned cert_issuer_key_type, const PrivateKey *sk, - const ESP_Mail_X509List *client_CA_ta) - { -#ifndef BEARSSL_SSL_BASIC - _freeSSL(); - _oom_err = false; - _sc_svr = std::make_shared(); - _eng = &_sc_svr->eng; // Allocation/deallocation taken care of by the _sc shared_ptr - _iobuf_in = std::shared_ptr(new unsigned char[_iobuf_in_size], std::default_delete()); - _iobuf_out = std::shared_ptr(new unsigned char[_iobuf_out_size], std::default_delete()); - - if (!_sc_svr || !_iobuf_in || !_iobuf_out) - { - _freeSSL(); - _oom_err = true; - DEBUG_BSSL("_connectSSLServerEC: OOM error\n"); - return false; - } - - br_ssl_server_base_init(_sc_svr.get(), suites_server_ec_P, sizeof(suites_server_ec_P) / sizeof(suites_server_ec_P[0])); - br_ssl_server_set_single_ec(_sc_svr.get(), chain ? chain->getX509Certs() : nullptr, chain ? chain->getCount() : 0, - sk ? sk->getEC() : nullptr, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, - cert_issuer_key_type, br_ssl_engine_get_ec(_eng), br_ecdsa_i15_sign_asn1); - br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size); - if (client_CA_ta && !_installServerX509Validator(client_CA_ta)) - { - DEBUG_BSSL("_connectSSLServerEC: Can't install serverX509check\n"); - return false; - } - if (!br_ssl_server_reset(_sc_svr.get())) - { - _freeSSL(); - DEBUG_BSSL("_connectSSLServerEC: Can't reset server ctx\n"); - return false; - } - - return _wait_for_handshake(); -#else - (void)chain; - (void)cert_issuer_key_type; - (void)sk; - (void)client_CA_ta; - DEBUG_BSSL("_connectSSLServerEC: Attempting to use EC cert in minimal cipher mode (no EC)\n"); - return false; -#endif - } - - // Returns an error ID and possibly a string (if dest != null) of the last - // BearSSL reported error. - int ESP_Mail_WCS::getLastSSLError(char *dest, size_t len) - { - int err = 0; - const char *t = PSTR("OK"); - if (_sc || _sc_svr) - { - err = br_ssl_engine_last_error(_eng); - } - if (_oom_err) - { - err = -1000; - } - switch (err) - { - case -1000: - t = PSTR("Unable to allocate memory for SSL structures and buffers."); - break; - case BR_ERR_BAD_PARAM: - t = PSTR("Caller-provided parameter is incorrect."); - break; - case BR_ERR_BAD_STATE: - t = PSTR("Operation requested by the caller cannot be applied with the current context state (e.g. reading data while outgoing data is waiting to be sent)."); - break; - case BR_ERR_UNSUPPORTED_VERSION: - t = PSTR("Incoming protocol or record version is unsupported."); - break; - case BR_ERR_BAD_VERSION: - t = PSTR("Incoming record version does not match the expected version."); - break; - case BR_ERR_BAD_LENGTH: - t = PSTR("Incoming record length is invalid."); - break; - case BR_ERR_TOO_LARGE: - t = PSTR("Incoming record is too large to be processed, or buffer is too small for the handshake message to send."); - break; - case BR_ERR_BAD_MAC: - t = PSTR("Decryption found an invalid padding, or the record MAC is not correct."); - break; - case BR_ERR_NO_RANDOM: - t = PSTR("No initial entropy was provided, and none can be obtained from the OS."); - break; - case BR_ERR_UNKNOWN_TYPE: - t = PSTR("Incoming record type is unknown."); - break; - case BR_ERR_UNEXPECTED: - t = PSTR("Incoming record or message has wrong type with regards to the current engine state."); - break; - case BR_ERR_BAD_CCS: - t = PSTR("ChangeCipherSpec message from the peer has invalid contents."); - break; - case BR_ERR_BAD_ALERT: - t = PSTR("Alert message from the peer has invalid contents (odd length)."); - break; - case BR_ERR_BAD_HANDSHAKE: - t = PSTR("Incoming handshake message decoding failed."); - break; - case BR_ERR_OVERSIZED_ID: - t = PSTR("ServerHello contains a session ID which is larger than 32 bytes."); - break; - case BR_ERR_BAD_CIPHER_SUITE: - t = PSTR("Server wants to use a cipher suite that we did not claim to support. This is also reported if we tried to advertise a cipher suite that we do not support."); - break; - case BR_ERR_BAD_COMPRESSION: - t = PSTR("Server wants to use a compression that we did not claim to support."); - break; - case BR_ERR_BAD_FRAGLEN: - t = PSTR("Server's max fragment length does not match client's."); - break; - case BR_ERR_BAD_SECRENEG: - t = PSTR("Secure renegotiation failed."); - break; - case BR_ERR_EXTRA_EXTENSION: - t = PSTR("Server sent an extension type that we did not announce, or used the same extension type several times in a single ServerHello."); - break; - case BR_ERR_BAD_SNI: - t = PSTR("Invalid Server Name Indication contents (when used by the server, this extension shall be empty)."); - break; - case BR_ERR_BAD_HELLO_DONE: - t = PSTR("Invalid ServerHelloDone from the server (length is not 0)."); - break; - case BR_ERR_LIMIT_EXCEEDED: - t = PSTR("Internal limit exceeded (e.g. server's public key is too large)."); - break; - case BR_ERR_BAD_FINISHED: - t = PSTR("Finished message from peer does not match the expected value."); - break; - case BR_ERR_RESUME_MISMATCH: - t = PSTR("Session resumption attempt with distinct version or cipher suite."); - break; - case BR_ERR_INVALID_ALGORITHM: - t = PSTR("Unsupported or invalid algorithm (ECDHE curve, signature algorithm, hash function)."); - break; - case BR_ERR_BAD_SIGNATURE: - t = PSTR("Invalid signature in ServerKeyExchange or CertificateVerify message."); - break; - case BR_ERR_WRONG_KEY_USAGE: - t = PSTR("Peer's public key does not have the proper type or is not allowed for the requested operation."); - break; - case BR_ERR_NO_CLIENT_AUTH: - t = PSTR("Client did not send a certificate upon request, or the client certificate could not be validated."); - break; - case BR_ERR_IO: - t = PSTR("I/O error or premature close on transport stream."); - break; - case BR_ERR_X509_INVALID_VALUE: - t = PSTR("Invalid value in an ASN.1 structure."); - break; - case BR_ERR_X509_TRUNCATED: - t = PSTR("Truncated certificate or other ASN.1 object."); - break; - case BR_ERR_X509_EMPTY_CHAIN: - t = PSTR("Empty certificate chain (no certificate at all)."); - break; - case BR_ERR_X509_INNER_TRUNC: - t = PSTR("Decoding error: inner element extends beyond outer element size."); - break; - case BR_ERR_X509_BAD_TAG_CLASS: - t = PSTR("Decoding error: unsupported tag class (application or private)."); - break; - case BR_ERR_X509_BAD_TAG_VALUE: - t = PSTR("Decoding error: unsupported tag value."); - break; - case BR_ERR_X509_INDEFINITE_LENGTH: - t = PSTR("Decoding error: indefinite length."); - break; - case BR_ERR_X509_EXTRA_ELEMENT: - t = PSTR("Decoding error: extraneous element."); - break; - case BR_ERR_X509_UNEXPECTED: - t = PSTR("Decoding error: unexpected element."); - break; - case BR_ERR_X509_NOT_CONSTRUCTED: - t = PSTR("Decoding error: expected constructed element, but is primitive."); - break; - case BR_ERR_X509_NOT_PRIMITIVE: - t = PSTR("Decoding error: expected primitive element, but is constructed."); - break; - case BR_ERR_X509_PARTIAL_BYTE: - t = PSTR("Decoding error: BIT STRING length is not multiple of 8."); - break; - case BR_ERR_X509_BAD_BOOLEAN: - t = PSTR("Decoding error: BOOLEAN value has invalid length."); - break; - case BR_ERR_X509_OVERFLOW: - t = PSTR("Decoding error: value is off-limits."); - break; - case BR_ERR_X509_BAD_DN: - t = PSTR("Invalid distinguished name."); - break; - case BR_ERR_X509_BAD_TIME: - t = PSTR("Invalid date/time representation."); - break; - case BR_ERR_X509_UNSUPPORTED: - t = PSTR("Certificate contains unsupported features that cannot be ignored."); - break; - case BR_ERR_X509_LIMIT_EXCEEDED: - t = PSTR("Key or signature size exceeds internal limits."); - break; - case BR_ERR_X509_WRONG_KEY_TYPE: - t = PSTR("Key type does not match that which was expected."); - break; - case BR_ERR_X509_BAD_SIGNATURE: - t = PSTR("Signature is invalid."); - break; - case BR_ERR_X509_TIME_UNKNOWN: - t = PSTR("Validation time is unknown."); - break; - case BR_ERR_X509_EXPIRED: - t = PSTR("Certificate is expired or not yet valid."); - break; - case BR_ERR_X509_DN_MISMATCH: - t = PSTR("Issuer/Subject DN mismatch in the chain."); - break; - case BR_ERR_X509_BAD_SERVER_NAME: - t = PSTR("Expected server name was not found in the chain."); - break; - case BR_ERR_X509_CRITICAL_EXTENSION: - t = PSTR("Unknown critical extension in certificate."); - break; - case BR_ERR_X509_NOT_CA: - t = PSTR("Not a CA, or path length constraint violation."); - break; - case BR_ERR_X509_FORBIDDEN_KEY_USAGE: - t = PSTR("Key Usage extension prohibits intended usage."); - break; - case BR_ERR_X509_WEAK_PUBLIC_KEY: - t = PSTR("Public key found in certificate is too small."); - break; - case BR_ERR_X509_NOT_TRUSTED: - t = PSTR("Chain could not be linked to a trust anchor."); - break; - default: - t = PSTR("Unknown error code."); - break; - } - if (dest) - { - strncpy_P(dest, t, len); - dest[len - 1] = 0; - } - return err; - } - - bool ESP_Mail_WCS::probeMaxFragmentLength(const char *name, uint16_t port, uint16_t len) - { - IPAddress remote_addr; - if (!WiFi.hostByName(name, remote_addr)) - { - DEBUG_BSSL("probeMaxFragmentLength: Can't resolve host\n"); - return false; - } - return ESP_Mail_WCS::probeMaxFragmentLength(remote_addr, port, len); - } - - bool ESP_Mail_WCS::probeMaxFragmentLength(const String &host, uint16_t port, uint16_t len) - { - return ESP_Mail_WCS::probeMaxFragmentLength(host.c_str(), port, len); - } - - // Helper function which aborts a TLS handshake by sending TLS - // ClientAbort and ClientClose messages. - static bool _SendAbort(WiFiClient &probe, bool supportsLen) - { - // If we're still connected, send the appropriate notice that - // we're aborting the handshake per RFCs. - static const uint8_t clientAbort_P[] PROGMEM = { - 0x15 /*alert*/, 0x03, 0x03 /*TLS 1.2*/, 0x00, 0x02, - 1, 90 /* warning: user_cancelled */ - }; - static const uint8_t clientClose_P[] PROGMEM = { - 0x15 /*alert*/, 0x03, 0x03 /*TLS 1.2*/, 0x00, 0x02, - 1, 0 /* warning: close_notify */ - }; - if (probe.connected()) - { - uint8_t msg[sizeof(clientAbort_P)]; - memcpy_P(msg, clientAbort_P, sizeof(clientAbort_P)); - probe.write(msg, sizeof(clientAbort_P)); - memcpy_P(msg, clientClose_P, sizeof(clientClose_P)); - probe.write(msg, sizeof(clientClose_P)); - } - return supportsLen; - } - - // Checks for support of Maximum Frame Length Negotiation at the given - // blocksize. Note that, per spec, only 512, 1024, 2048, and 4096 are - // supported. Many servers today do not support this negotiation. - - // TODO - Allow for fragmentation...but not very critical as the ServerHello - // we use comes to < 80 bytes which has no reason to ever be fragmented. - // TODO - Check the type of returned extensions and that the MFL is the exact - // same one we sent. Not critical as only horribly broken servers would - // return changed or add their own extensions. - bool ESP_Mail_WCS::probeMaxFragmentLength(IPAddress ip, uint16_t port, uint16_t len) - { - // Hardcoded TLS 1.2 packets used throughout - static const uint8_t clientHelloHead_P[] PROGMEM = { - 0x16, 0x03, 0x03, 0x00, 0, // TLS header, change last 2 bytes to len - 0x01, 0x00, 0x00, 0, // Last 3 bytes == length - 0x03, 0x03, // Proto version TLS 1.2 - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Random (gmtime + rand[28]) - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x00, // Session ID - }; - // Followed by our cipher-suite, generated on-the-fly - // 0x00, 0x02, // cipher suite len - // 0xc0, 0x13, // BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - static const uint8_t clientHelloTail_P[] PROGMEM = { - 0x01, 0x00, // No compression - 0x00, 26 + 14 + 6 + 5, // Extension length - 0x00, 0x0d, 0x00, 0x16, 0x00, 0x14, 0x04, 0x03, 0x03, 0x03, 0x05, 0x03, - 0x06, 0x03, 0x02, 0x03, 0x04, 0x01, 0x03, 0x01, 0x05, 0x01, 0x06, - 0x01, 0x02, 0x01, // Supported signature algorithms - 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, - 0x00, 0x1d, // Supported groups - 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, // Supported EC formats - 0x00, 0x01, // Max Frag Len - 0x00, 0x01, // len of MaxFragLen - }; - // Followed by a 1-byte MFLN size requesst - // 0x04 // 2^12 = 4K - uint8_t mfl; - - switch (len) - { - case 512: - mfl = 1; - break; - case 1024: - mfl = 2; - break; - case 2048: - mfl = 3; - break; - case 4096: - mfl = 4; - break; - default: - return false; // Invalid size - } - int ttlLen = sizeof(clientHelloHead_P) + (2 + sizeof(suites_P)) + (sizeof(clientHelloTail_P) + 1); - uint8_t *clientHello = new uint8_t[ttlLen]; - if (!clientHello) - { - DEBUG_BSSL("probeMaxFragmentLength: OOM\n"); - return false; - } - memcpy_P(clientHello, clientHelloHead_P, sizeof(clientHelloHead_P)); - clientHello[sizeof(clientHelloHead_P) + 0] = sizeof(suites_P) >> 8; // MSB byte len - clientHello[sizeof(clientHelloHead_P) + 1] = sizeof(suites_P) & 0xff; // LSB byte len - for (size_t i = 0; i < sizeof(suites_P) / sizeof(suites_P[0]); i++) - { - uint16_t flip = pgm_read_word(&suites_P[i]); - // Swap to network byte order - flip = ((flip >> 8) & 0xff) | ((flip & 0xff) << 8); - memcpy(clientHello + sizeof(clientHelloHead_P) + 2 + 2 * i, &flip, 2); - } - memcpy_P(clientHello + sizeof(clientHelloHead_P) + 2 + sizeof(suites_P), clientHelloTail_P, sizeof(clientHelloTail_P)); - clientHello[sizeof(clientHelloHead_P) + 2 + sizeof(suites_P) + sizeof(clientHelloTail_P)] = mfl; - - // Fix up TLS fragment length - clientHello[3] = (ttlLen - 5) >> 8; - clientHello[4] = (ttlLen - 5) & 0xff; - // Fix up ClientHello message length - clientHello[7] = (ttlLen - 5 - 4) >> 8; - clientHello[8] = (ttlLen - 5 - 4) & 0xff; - - WiFiClient probe; - probe.connect(ip, port); - if (!probe.connected()) - { - delete[] clientHello; - DEBUG_BSSL("probeMaxFragmentLength: Can't connect\n"); - return false; - } - - int ret = probe.write(clientHello, ttlLen); - delete[] clientHello; // We're done w/the hello message - if (!probe.connected() || (ret != ttlLen)) - { - DEBUG_BSSL("probeMaxFragmentLength: Protocol error\n"); - return false; - } - - bool supportsLen = false; - uint8_t fragResp[5]; - int fragLen; - uint8_t hand[4]; - int handLen; - uint8_t protoVer[2]; - uint8_t rand[32]; - uint8_t sessionLen; - uint8_t cipher[2]; - uint8_t comp; - uint8_t extBytes[2]; - uint16_t extLen; - - ret = probe.readBytes(fragResp, 5); - if (!probe.connected() || (ret != 5) || (fragResp[0] != 0x16) || (fragResp[1] != 0x03) || (fragResp[2] != 0x03)) - { - // Short read, not a HANDSHAKE or not TLS 1.2, so it's not supported - return _SendAbort(probe, supportsLen); - } - fragLen = (fragResp[3] << 8) | fragResp[4]; - if (fragLen < 4 + 2 + 32 + 1 + 2 + 1) - { - // Too short to have an extension - return _SendAbort(probe, supportsLen); - } - - ret = probe.readBytes(hand, 4); - fragLen -= ret; - if ((ret != 4) || (hand[0] != 2)) - { - // Short read or not server_hello - return _SendAbort(probe, supportsLen); - } - handLen = (hand[1] << 16) | (hand[2] << 8) | hand[3]; - if (handLen != fragLen) - { - // Got some weird mismatch, this is invalid - return _SendAbort(probe, supportsLen); - } - - ret = probe.readBytes(protoVer, 2); - handLen -= ret; - if ((ret != 2) || (protoVer[0] != 0x03) || (protoVer[1] != 0x03)) - { - // Short read or not tls 1.2, so can't do MFLN - return _SendAbort(probe, supportsLen); - } - - ret = probe.readBytes(rand, 32); - handLen -= ret; - if (ret != 32) - { - // short read of random data - return _SendAbort(probe, supportsLen); - } - - ret = probe.readBytes(&sessionLen, 1); - handLen -= ret; - if ((ret != 1) || (sessionLen > 32)) - { - // short read of session len or invalid size - return _SendAbort(probe, supportsLen); - } - if (sessionLen) - { - ret = probe.readBytes(rand, sessionLen); - handLen -= ret; - if (ret != sessionLen) - { - // short session id read - return _SendAbort(probe, supportsLen); - } - } - - ret = probe.readBytes(cipher, 2); - handLen -= ret; - if (ret != 2) - { - // Short read...we don't check the cipher here - return _SendAbort(probe, supportsLen); - } - - ret = probe.readBytes(&comp, 1); - handLen -= ret; - if ((ret != 1) || comp != 0) - { - // short read or invalid compression - return _SendAbort(probe, supportsLen); - } - - ret = probe.readBytes(extBytes, 2); - handLen -= ret; - extLen = extBytes[1] | (extBytes[0] << 8); - if ((extLen == 0) || (ret != 2)) - { - return _SendAbort(probe, supportsLen); - } - - while (handLen > 0) - { - // Parse each extension and look for MFLN - uint8_t typeBytes[2]; - ret = probe.readBytes(typeBytes, 2); - handLen -= 2; - if ((ret != 2) || (handLen <= 0)) - { - return _SendAbort(probe, supportsLen); - } - uint8_t lenBytes[2]; - ret = probe.readBytes(lenBytes, 2); - handLen -= 2; - uint16_t extLen = lenBytes[1] | (lenBytes[0] << 8); - if ((ret != 2) || (handLen <= 0) || (extLen > 32) || (extLen > handLen)) - { - return _SendAbort(probe, supportsLen); - } - if ((typeBytes[0] == 0x00) && (typeBytes[1] == 0x01)) - { // MFLN extension! - // If present and 1-byte in length, it's supported - return _SendAbort(probe, extLen == 1 ? true : false); - } - // Skip the extension, move to next one - uint8_t junk[32]; - ret = probe.readBytes(junk, extLen); - handLen -= extLen; - if (ret != extLen) - { - return _SendAbort(probe, supportsLen); - } - } - return _SendAbort(probe, supportsLen); - } - - // AXTLS compatibility interfaces - bool ESP_Mail_WCS::setCACert(const uint8_t *pk, size_t size) - { - _axtls_ta = nullptr; - _axtls_ta = std::shared_ptr(new ESP_Mail_X509List(pk, size)); - _ta = _axtls_ta.get(); - return _ta ? true : false; - } - - bool ESP_Mail_WCS::setCertificate(const uint8_t *pk, size_t size) - { - _axtls_chain = nullptr; - _axtls_chain = std::shared_ptr(new ESP_Mail_X509List(pk, size)); - _chain = _axtls_chain.get(); - return _chain ? true : false; - } - - bool ESP_Mail_WCS::setPrivateKey(const uint8_t *pk, size_t size) - { - _axtls_sk = nullptr; - _axtls_sk = std::shared_ptr(new PrivateKey(pk, size)); - _sk = _axtls_sk.get(); - return _sk ? true : false; - } - - uint8_t *ESP_Mail_WCS::_streamLoad(Stream &stream, size_t size) - { - uint8_t *dest = (uint8_t *)malloc(size); - if (!dest) - { - return nullptr; - } - if (size != stream.readBytes(dest, size)) - { - free(dest); - return nullptr; - } - return dest; - } - - bool ESP_Mail_WCS::loadCACert(Stream &stream, size_t size) - { - uint8_t *dest = _streamLoad(stream, size); - bool ret = false; - if (dest) - { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - ret = setCACert(dest, size); -#pragma GCC diagnostic pop - } - free(dest); - return ret; - } - - bool ESP_Mail_WCS::loadCertificate(Stream &stream, size_t size) - { - uint8_t *dest = _streamLoad(stream, size); - bool ret = false; - if (dest) - { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - ret = setCertificate(dest, size); -#pragma GCC diagnostic pop - } - free(dest); - return ret; - } - - bool ESP_Mail_WCS::loadPrivateKey(Stream &stream, size_t size) - { - uint8_t *dest = _streamLoad(stream, size); - bool ret = false; - if (dest) - { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - ret = setPrivateKey(dest, size); -#pragma GCC diagnostic pop - } - free(dest); - return ret; - } - - void ESP_Mail_WCS::setStartTLS(bool enable) - { - _secured = !enable; - } - - size_t ESP_Mail_WCS::_ns_write(uint8_t b) - { - return write(&b, 1); - } - - size_t ESP_Mail_WCS::_ns_write(const uint8_t *buf, size_t size) - { - if (!_client || !size) - { - return 0; - } - _client->setTimeout(_timeout); -#if defined(ESP8266_CORE_SDK_V3_X_X) - return _client->write((const char *)buf, size); -#else - return _client->write(buf, size); -#endif - } - - size_t ESP_Mail_WCS::_ns_write(Stream &stream, size_t unused) - { - (void)unused; - return WiFiClient::write(stream); - } - - size_t ESP_Mail_WCS::_ns_write(Stream &stream) - { - if (!_client || !stream.available()) - { - return 0; - } - _client->setTimeout(_timeout); -#if defined(ESP8266_CORE_SDK_V3_X_X) - size_t dl = stream.available(); - uint8_t buf[dl]; - stream.readBytes(buf, dl); - return _client->write((const char *)buf, dl); -#else - return _client->write(stream); -#endif - } - - size_t ESP_Mail_WCS::_ns_write_P(PGM_P buf, size_t size) - { - - if (!_client || !size) - { - return 0; - } - _client->setTimeout(_timeout); - -#if defined(ESP8266_CORE_SDK_V3_X_X) - char dest[size]; - memcpy_P((void *)dest, (PGM_VOID_P)buf, size); - return _client->write((const char *)dest, size); -#else - return _client->write_P(buf, size); -#endif - } - - int ESP_Mail_WCS::_ns_available() - { - if (!_client) - return false; - - int result = _client->getSize(); - - if (!result) - { - optimistic_yield(100); - } - return result; - } - - int ESP_Mail_WCS::_ns_read() - { - if (!_ns_available()) - return -1; - - return _client->read(); - } - - int ESP_Mail_WCS::_ns_read(uint8_t *buf, size_t size) - { - return (int)_client->read(reinterpret_cast(buf), size); - } - - int ESP_Mail_WCS::_ns_peek() - { - if (!_ns_available()) - return -1; - - return _client->peek(); - } - - size_t ESP_Mail_WCS::_ns_peekBytes(uint8_t *buffer, size_t length) - { - size_t count = 0; - - if (!_client) - { - return 0; - } - - _startMillis = millis(); - while ((_ns_available() < (int)length) && ((millis() - _startMillis) < _timeout)) - { - yield(); - } - - if (_ns_available() < (int)length) - { - count = _ns_available(); - } - else - { - count = length; - } - - return _client->peekBytes((char *)buffer, count); - } - - uint8_t ESP_Mail_WCS::_ns_connected() - { - if (!_client || _client->state() == CLOSED) - return 0; - - return _client->state() == ESTABLISHED || _ns_available(); - } - - bool ESP_Mail_WCS::_ns_connect_ssl() - { - return _connectSSL(_host_name.c_str()); - } -}; // namespace ESP_Mail - -#endif /* ESP8266 */ - -#endif /* ESP_Mail_WCS_CPP */ \ No newline at end of file diff --git a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_WCS.h b/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_WCS.h deleted file mode 100644 index aef48cc5e710..000000000000 --- a/lib/libesp32/lib_mail/src/wcs/esp8266/ESP_Mail_WCS.h +++ /dev/null @@ -1,306 +0,0 @@ -/* - Customized version of WiFiClientSecure.h v1.0.1 - - WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries - - Mostly compatible with Arduino WiFi shield library and standard - WiFiClient/ServerSecure (except for certificate handling). - - Copyright (c) 2018 Earle F. Philhower, III - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef ESP_Mail_WCS_H -#define ESP_Mail_WCS_H - -#ifdef ESP8266 - -#include -#include -#include -#include "ESP_Mail_BearSSLHelpers.h" -#include "ESP_Mail_CertStoreBearSSL.h" -#include "SDK_Version_Common.h" - -namespace ESP_Mail { - -//#define DEBUG_ESP_SSL -//#define DEBUG_ESP_PORT Serial - - struct br_x509_insecure_context; - - class ESP_Mail_WCS : public WiFiClient - { - public: - ESP_Mail_WCS(); - ESP_Mail_WCS(const ESP_Mail_WCS &rhs); - ~ESP_Mail_WCS() override; - - ESP_Mail_WCS& operator=(const ESP_Mail_WCS&) = default; // The shared-ptrs handle themselves automatically - - int connect(IPAddress ip, uint16_t port) override; - int connect(const String& host, uint16_t port) override; - int connect(const char* name, uint16_t port) override; - - uint8_t connected() override; - size_t write(const uint8_t *buf, size_t size) override; - size_t write_P(PGM_P buf, size_t size) override; - size_t write(const char *buf) { - return write((const uint8_t*)buf, strlen(buf)); - } - size_t write_P(const char *buf) { - return write_P((PGM_P)buf, strlen_P(buf)); - } - size_t write(Stream& stream); // Note this is not virtual - int read(uint8_t *buf, size_t size) override; - int available() override; - int read() override; - int peek() override; - size_t peekBytes(uint8_t *buffer, size_t length) override; - bool flush(unsigned int maxWaitMs); - bool stop(unsigned int maxWaitMs); - void flush() override { (void)flush(0); } - void stop() override { (void)stop(0); } - - // Allow sessions to be saved/restored automatically to a memory area - void setSession(Session *session) { _session = session; } - - // Don't validate the chain, just accept whatever is given. VERY INSECURE! - void setInsecure() { - _clearAuthenticationSettings(); - _use_insecure = true; - } - // Assume a given public key, don't validate or use cert info at all - void setKnownKey(const PublicKey *pk, unsigned usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN) { - _clearAuthenticationSettings(); - _knownkey = pk; - _knownkey_usages = usages; - } - // Only check SHA1 fingerprint of certificate - bool setFingerprint(const uint8_t fingerprint[20]) { - _clearAuthenticationSettings(); - _use_fingerprint = true; - memcpy_P(_fingerprint, fingerprint, 20); - return true; - } - bool setFingerprint(const char *fpStr); - // Accept any certificate that's self-signed - void allowSelfSignedCerts() { - _clearAuthenticationSettings(); - _use_self_signed = true; - } - // Install certificates of trusted CAs or specific site - void setTrustAnchors(const ESP_Mail_X509List *ta) { - _clearAuthenticationSettings(); - _ta = ta; - } - // In cases when NTP is not used, app must set a time manually to check cert validity - void setX509Time(time_t now) { - _now = now; - } - // Install a client certificate for this connection, in case the server requires it (i.e. MQTT) - void setClientRSACert(const ESP_Mail_X509List *cert, const PrivateKey *sk); - void setClientECCert(const ESP_Mail_X509List *cert, const PrivateKey *sk, - unsigned allowed_usages, unsigned cert_issuer_key_type); - - // Sets the requested buffer size for transmit and receive - void setBufferSizes(int recv, int xmit); - - // Returns whether MFLN negotiation for the above buffer sizes succeeded (after connection) - int getMFLNStatus() { - return connected() && br_ssl_engine_get_mfln_negotiated(_eng); - } - - // Return an error code and possibly a text string in a passed-in buffer with last SSL failure - int getLastSSLError(char *dest = NULL, size_t len = 0); - - // Attach a preconfigured certificate store - void setCertStore(ESP_Mail_CertStore *certStore) { - _certStore = certStore; - } - - // Select specific ciphers (i.e. optimize for speed over security) - // These may be in PROGMEM or RAM, either will run properly - bool setCiphers(const uint16_t *cipherAry, int cipherCount); - bool setCiphers(std::vector list); - bool setCiphersLessSecure(); // Only use the limited set of RSA ciphers without EC - - // Check for Maximum Fragment Length support for given len before connection (possibly insecure) - static bool probeMaxFragmentLength(IPAddress ip, uint16_t port, uint16_t len); - static bool probeMaxFragmentLength(const char *hostname, uint16_t port, uint16_t len); - static bool probeMaxFragmentLength(const String& host, uint16_t port, uint16_t len); - - void setStartTLS(bool enable); - size_t _ns_write(uint8_t b); - size_t _ns_write(const uint8_t *buf, size_t size); - size_t _ns_write(Stream &stream, size_t unused); - size_t _ns_write(Stream &stream); - size_t _ns_write_P(PGM_P buf, size_t size); - int _ns_available(); - int _ns_read(); - int _ns_read(uint8_t *buf, size_t size); - int _ns_peek(); - size_t _ns_peekBytes(uint8_t *buffer, size_t length); - uint8_t _ns_connected(); - bool _ns_connect_ssl(); - - //////////////////////////////////////////////////// - // AxTLS API deprecated warnings to help upgrading - - bool setCACert(const uint8_t* pk, size_t size) ; - bool setCertificate(const uint8_t* pk, size_t size) ; - bool setPrivateKey(const uint8_t* pk, size_t size) ; - - bool loadCACert(Stream& stream, size_t size) ; - bool loadCertificate(Stream& stream, size_t size) ; - bool loadPrivateKey(Stream& stream, size_t size) ; - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - - bool setCACert_P(PGM_VOID_P pk, size_t size) { - return setCACert((const uint8_t *)pk, size); - } - - bool setCertificate_P(PGM_VOID_P pk, size_t size) { - return setCertificate((const uint8_t *)pk, size); - } - - bool setPrivateKey_P(PGM_VOID_P pk, size_t size) { - return setPrivateKey((const uint8_t *)pk, size); - } - -#pragma GCC diagnostic pop - - template - bool loadCertificate(TFile& file) { - return loadCertificate(file, file.size()); - } - - template - bool loadPrivateKey(TFile& file) { - return loadPrivateKey(file, file.size()); - } - - template - bool loadCACert(TFile& file) { - return loadCACert(file, file.size()); - } - - bool verify(const char* fingerprint, const char* domain_name) { - (void)fingerprint; - (void)domain_name; - return connected(); - } - - bool verifyCertChain(const char* domain_name) { - (void)domain_name; - return connected(); - } - - // AxTLS API deprecated section end - ///////////////////////////////////// - - protected: - bool _connectSSL(const char *hostName); // Do initial SSL handshake - - private: - void _clear(); - void _clearAuthenticationSettings(); - // Only one of the following two should ever be != nullptr! - std::shared_ptr _sc; - std::shared_ptr _sc_svr; - inline bool ctx_present() { - return (_sc != nullptr) || (_sc_svr != nullptr); - } - br_ssl_engine_context *_eng; // &_sc->eng, to allow for client or server contexts - std::shared_ptr _x509_minimal; - std::shared_ptr _x509_insecure; - std::shared_ptr _x509_knownkey; - std::shared_ptr _iobuf_in; - std::shared_ptr _iobuf_out; - time_t _now; - const ESP_Mail_X509List *_ta; - ESP_Mail_CertStore *_certStore; - int _iobuf_in_size; - int _iobuf_out_size; - bool _handshake_done; - bool _oom_err; - - bool _secured; - std::string _host_name; - - // AXTLS compatibility shim elements: - // AXTLS managed memory for certs and keys, while BearSSL assumes - // the app manages these. Use this local storage for holding the - // BearSSL created objects in a shared form. - std::shared_ptr _axtls_ta; - std::shared_ptr _axtls_chain; - std::shared_ptr _axtls_sk; - - // Optional storage space pointer for session parameters - // Will be used on connect and updated on close - Session *_session; - - bool _use_insecure; - bool _use_fingerprint; - uint8_t _fingerprint[20]; - bool _use_self_signed; - const PublicKey *_knownkey; - unsigned _knownkey_usages; - - // Custom cipher list pointer or NULL if default - std::shared_ptr _cipher_list; - uint8_t _cipher_cnt; - - unsigned char *_recvapp_buf; - size_t _recvapp_len; - - bool _clientConnected(); // Is the underlying socket alive? - void _freeSSL(); - int _run_until(unsigned target, bool blocking = true); - size_t _write(const uint8_t *buf, size_t size, bool pmem); - bool _wait_for_handshake(); // Sets and return the _handshake_done after connecting - - // Optional client certificate - const ESP_Mail_X509List *_chain; - const PrivateKey *_sk; - unsigned _allowed_usages; - unsigned _cert_issuer_key_type; - - // Methods for handling server.available() call which returns a client connection. - friend class WiFiServerSecure; // Server needs to access these constructors - ESP_Mail_WCS(ClientContext *client, const ESP_Mail_X509List *chain, unsigned cert_issuer_key_type, - const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, const ESP_Mail_X509List *client_CA_ta); - ESP_Mail_WCS(ClientContext* client, const ESP_Mail_X509List *chain, const PrivateKey *sk, - int iobuf_in_size, int iobuf_out_size, const ESP_Mail_X509List *client_CA_ta); - - // RSA keyed server - bool _connectSSLServerRSA(const ESP_Mail_X509List *chain, const PrivateKey *sk, const ESP_Mail_X509List *client_CA_ta); - // EC keyed server - bool _connectSSLServerEC(const ESP_Mail_X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk, - const ESP_Mail_X509List *client_CA_ta); - - // X.509 validators differ from server to client - bool _installClientX509Validator(); // Set up X509 validator for a client conn. - bool _installServerX509Validator(const ESP_Mail_X509List *client_CA_ta); // Setup X509 client cert validation, if supplied - - uint8_t *_streamLoad(Stream& stream, size_t size); - }; -}; - -#endif /* ESP8266 */ - -#endif /* ESP_Mail_WCS_H */ diff --git a/lib/libesp32/rtsp/CRtspSession.cpp b/lib/libesp32/rtsp/CRtspSession.cpp index 7462e8f898c7..79e210d1ee42 100755 --- a/lib/libesp32/rtsp/CRtspSession.cpp +++ b/lib/libesp32/rtsp/CRtspSession.cpp @@ -5,7 +5,7 @@ CRtspSession::CRtspSession(SOCKET aRtspClient, CStreamer * aStreamer) : m_RtspClient(aRtspClient),m_Streamer(aStreamer) { - printf("Creating RTSP session\n"); +// printf("Creating RTSP session\n"); Init(); m_RtspSessionID = getRandom(); // create a session ID @@ -95,11 +95,11 @@ bool CRtspSession::ParseRtspRequest(char const * aRequest, unsigned aRequestSize } CmdName[i] = '\0'; if (!parseSucceeded) { - printf("failed to parse RTSP\n"); +// printf("failed to parse RTSP\n"); return false; } - printf("RTSP received %s\n", CmdName); +// printf("RTSP received %s\n", CmdName); // find out the command type if (strstr(CmdName,"OPTIONS") != nullptr) m_RtspCmdType = RTSP_OPTIONS; else @@ -400,7 +400,7 @@ bool CRtspSession::handleRequests(uint32_t readTimeoutMs) return true; } else if(res == 0) { - printf("client closed socket, exiting\n"); +// printf("client closed socket, exiting\n"); m_stopped = true; return true; } diff --git a/lib/libesp32/rtsp/CStreamer.cpp b/lib/libesp32/rtsp/CStreamer.cpp index af4519ec7c3c..a9f638de971c 100755 --- a/lib/libesp32/rtsp/CStreamer.cpp +++ b/lib/libesp32/rtsp/CStreamer.cpp @@ -6,7 +6,7 @@ CStreamer::CStreamer(SOCKET aClient, u_short width, u_short height) : m_Client(aClient) { - printf("Creating TSP streamer\n"); +// printf("Creating TSP streamer\n"); m_RtpServerPort = 0; m_RtcpServerPort = 0; m_RtpClientPort = 0; @@ -228,7 +228,7 @@ bool findJPEGheader(BufPtr *start, uint32_t *len, uint8_t marker) { while(bytes - *start < *len) { uint8_t framing = *bytes++; // better be 0xff if(framing != 0xff) { - printf("malformed jpeg, framing=%x\n", framing); +// printf("malformed jpeg, framing=%x\n", framing); return false; } uint8_t typecode = *bytes++; @@ -263,13 +263,13 @@ bool findJPEGheader(BufPtr *start, uint32_t *len, uint8_t marker) { break; } default: - printf("unexpected jpeg typecode 0x%x\n", typecode); +// printf("unexpected jpeg typecode 0x%x\n", typecode); break; } } } - printf("failed to find jpeg marker 0x%x", marker); +// printf("failed to find jpeg marker 0x%x", marker); return false; } @@ -309,7 +309,7 @@ bool decodeJPEGfile(BufPtr *start, uint32_t *len, BufPtr *qtable0, BufPtr *qtabl BufPtr quantstart = *start; uint32_t quantlen = *len; if(!findJPEGheader(&quantstart, &quantlen, 0xdb)) { - printf("error can't find quant table 0\n"); +// printf("error can't find quant table 0\n"); } else { // printf("found quant table %x\n", quantstart[2]); @@ -317,7 +317,7 @@ bool decodeJPEGfile(BufPtr *start, uint32_t *len, BufPtr *qtable0, BufPtr *qtabl *qtable0 = quantstart + 3; // 3 bytes of header skipped nextJpegBlock(&quantstart); if(!findJPEGheader(&quantstart, &quantlen, 0xdb)) { - printf("error can't find quant table 1\n"); +// printf("error can't find quant table 1\n"); } else { // printf("found quant table %x\n", quantstart[2]); diff --git a/lib/libesp32/rtsp/OV2640.cpp b/lib/libesp32/rtsp/OV2640.cpp index 9c1908b99bb6..f8abe39f9bed 100755 --- a/lib/libesp32/rtsp/OV2640.cpp +++ b/lib/libesp32/rtsp/OV2640.cpp @@ -184,7 +184,7 @@ esp_err_t OV2640::init(camera_config_t config) esp_err_t err = esp_camera_init(&_cam_config); if (err != ESP_OK) { - printf("Camera probe failed with error 0x%x", err); +// printf("Camera probe failed with error 0x%x", err); return err; } // ESP_ERROR_CHECK(gpio_install_isr_service(0)); diff --git a/lib/libesp32/rtsp/OV2640Streamer.cpp b/lib/libesp32/rtsp/OV2640Streamer.cpp index 679594f488af..43e92b647322 100755 --- a/lib/libesp32/rtsp/OV2640Streamer.cpp +++ b/lib/libesp32/rtsp/OV2640Streamer.cpp @@ -6,7 +6,7 @@ OV2640Streamer::OV2640Streamer(SOCKET aClient, OV2640 &cam) : CStreamer(aClient, cam.getWidth(), cam.getHeight()), m_cam(cam) { - Serial.printf("Created streamer width=%d, height=%d\n", cam.getWidth(), cam.getHeight()); +// Serial.printf("Created streamer width=%d, height=%d\n", cam.getWidth(), cam.getHeight()); } void OV2640Streamer::streamImage(uint32_t curMsec) @@ -15,5 +15,5 @@ void OV2640Streamer::streamImage(uint32_t curMsec) BufPtr bytes = m_cam.getfb(); streamFrame(bytes, m_cam.getSize(), curMsec); - Serial.printf("get frame: %d\n",m_cam.getSize()); +// Serial.printf("get frame: %d\n",m_cam.getSize()); } diff --git a/lib/libesp32/rtsp/platglue-esp32.h b/lib/libesp32/rtsp/platglue-esp32.h index 8646904c9145..0d921bb80e85 100755 --- a/lib/libesp32/rtsp/platglue-esp32.h +++ b/lib/libesp32/rtsp/platglue-esp32.h @@ -22,7 +22,7 @@ typedef uint16_t IPPORT; // on linux use network byte order #define NULLSOCKET NULL inline void closesocket(SOCKET s) { - printf("closing TCP socket\n"); +// printf("closing TCP socket\n"); if(s) { s->stop(); @@ -38,7 +38,7 @@ inline void socketpeeraddr(SOCKET s, IPADDRESS *addr, IPPORT *port) { } inline void udpsocketclose(UDPSOCKET s) { - printf("closing UDP socket\n"); +// printf("closing UDP socket\n"); if(s) { s->stop(); delete s; @@ -50,7 +50,7 @@ inline UDPSOCKET udpsocketcreate(unsigned short portNum) UDPSOCKET s = new WiFiUDP(); if(!s->begin(portNum)) { - printf("Can't bind port %d\n", portNum); +// printf("Can't bind port %d\n", portNum); delete s; return NULL; } @@ -69,8 +69,9 @@ inline ssize_t udpsocketsend(UDPSOCKET sockfd, const void *buf, size_t len, { sockfd->beginPacket(destaddr, destport); sockfd->write((const uint8_t *) buf, len); - if(!sockfd->endPacket()) - printf("error sending udp packet\n"); + if(!sockfd->endPacket()) { +// printf("error sending udp packet\n"); + } return len; } @@ -83,7 +84,7 @@ inline ssize_t udpsocketsend(UDPSOCKET sockfd, const void *buf, size_t len, inline int socketread(SOCKET sock, char *buf, size_t buflen, int timeoutmsec) { if(!sock->connected()) { - printf("client has closed the socket\n"); +// printf("client has closed the socket\n"); return 0; } diff --git a/lib/libesp32/rtsp/platglue-posix.h b/lib/libesp32/rtsp/platglue-posix.h index 046258ef52e1..fd442731c002 100755 --- a/lib/libesp32/rtsp/platglue-posix.h +++ b/lib/libesp32/rtsp/platglue-posix.h @@ -28,7 +28,7 @@ inline void socketpeeraddr(SOCKET s, IPADDRESS *addr, IPPORT *port) { sockaddr_in r; socklen_t len = sizeof(r); if(getpeername(s,(struct sockaddr*)&r,&len) < 0) { - printf("getpeername failed\n"); +// printf("getpeername failed\n"); *addr = 0; *port = 0; } @@ -54,7 +54,7 @@ inline UDPSOCKET udpsocketcreate(unsigned short portNum) int s = socket(AF_INET, SOCK_DGRAM, 0); addr.sin_port = htons(portNum); if (bind(s,(sockaddr*)&addr,sizeof(addr)) != 0) { - printf("Error, can't bind\n"); +// printf("Error, can't bind\n"); close(s); s = 0; } diff --git a/lib/libesp32_audio/es7210/src/es7210.cpp b/lib/libesp32_audio/es7210/src/es7210.cpp index 65b2c0cb766f..e84834e136c1 100644 --- a/lib/libesp32_audio/es7210/src/es7210.cpp +++ b/lib/libesp32_audio/es7210/src/es7210.cpp @@ -27,6 +27,7 @@ #include #include #include "esp_log.h" +#include "rom/ets_sys.h" #include "es7210.h" diff --git a/lib/libesp32_audio/es7243e/src/es7243e.cpp b/lib/libesp32_audio/es7243e/src/es7243e.cpp index 6ea7824fb06e..124f3d4dbb7b 100644 --- a/lib/libesp32_audio/es7243e/src/es7243e.cpp +++ b/lib/libesp32_audio/es7243e/src/es7243e.cpp @@ -27,7 +27,8 @@ #include #include "string.h" #include "esp_log.h" -#include "es7243e.h" + #include "rom/ets_sys.h" + #include "es7243e.h" static const char *TAG = "DRV7243E"; diff --git a/lib/libesp32_audio/es8156/src/es8156.cpp b/lib/libesp32_audio/es8156/src/es8156.cpp index 1de1ed716c07..30c237c10bba 100644 --- a/lib/libesp32_audio/es8156/src/es8156.cpp +++ b/lib/libesp32_audio/es8156/src/es8156.cpp @@ -28,6 +28,7 @@ #include #include "string.h" #include "esp_log.h" +#include "rom/ets_sys.h" #include "es8156.h" /* diff --git a/lib/libesp32_audio/es8311/src/es8311.cpp b/lib/libesp32_audio/es8311/src/es8311.cpp index 6cdc41f75568..06518d82c484 100644 --- a/lib/libesp32_audio/es8311/src/es8311.cpp +++ b/lib/libesp32_audio/es8311/src/es8311.cpp @@ -27,6 +27,7 @@ #include #include #include "esp_log.h" +#include "rom/ets_sys.h" #include "es8311.h" diff --git a/lib/libesp32_audio/mp3_shine_esp32/src/l3bitstream.cpp b/lib/libesp32_audio/mp3_shine_esp32/src/l3bitstream.cpp index 9952e04c7e61..2450036a53f5 100755 --- a/lib/libesp32_audio/mp3_shine_esp32/src/l3bitstream.cpp +++ b/lib/libesp32_audio/mp3_shine_esp32/src/l3bitstream.cpp @@ -34,7 +34,7 @@ void shine_format_bitstream(shine_global_config *config) { for ( gr = 0; gr < config->mpeg.granules_per_frame; gr++ ) { int *pi = &config->l3_enc[ch][gr][0]; - int32_t *pr = &config->mdct_freq[ch][gr][0]; + int *pr = &config->mdct_freq[ch][gr][0]; for ( i = 0; i < GRANULE_SIZE; i++ ) { if ( (pr[i] < 0) && (pi[i] > 0) ) diff --git a/lib/libesp32_audio/mp3_shine_esp32/src/l3loop.cpp b/lib/libesp32_audio/mp3_shine_esp32/src/l3loop.cpp index 0dd25df90a96..170ffb8bda31 100755 --- a/lib/libesp32_audio/mp3_shine_esp32/src/l3loop.cpp +++ b/lib/libesp32_audio/mp3_shine_esp32/src/l3loop.cpp @@ -31,7 +31,7 @@ static void calc_xmin( gr_info *cod_info, shine_psy_xmin_t *l3_xmin, int gr, int static int quantize(int ix[GRANULE_SIZE], int stepsize, shine_global_config *config); -int32_t sqrt_int(int32_t r) { +int sqrt_int(int r) { float x; float rr = r; float y = rr*0.5; @@ -40,7 +40,7 @@ int32_t sqrt_int(int32_t r) { x = (1.5f*x) - (x*x)*(x*y); if(r>101123) x = (1.5f*x) - (x*x)*(x*y); - int32_t is = (int32_t)(x*rr + 0.5f); + int is = (int)(x*rr + 0.5f); return is + ((r - is*is)>>31); } @@ -382,7 +382,7 @@ void shine_loop_initialise(shine_global_config *config) { * In quantize, the long multiply does not shift it's result left one * bit to compensate. */ - config->l3loop->steptabi[i] = (int32_t)((config->l3loop->steptab[i]*2) + 0.5); + config->l3loop->steptabi[i] = (int)((config->l3loop->steptab[i]*2) + 0.5); } /* quantize: vector conversion, three quarter power table. @@ -401,7 +401,7 @@ void shine_loop_initialise(shine_global_config *config) { int quantize(int ix[GRANULE_SIZE], int stepsize, shine_global_config *config ) { int i, max, ln; - int32_t scalei; + int scalei; float scale, dbl; scalei = config->l3loop->steptabi[stepsize+127]; /* 2**(-stepsize/4) */ diff --git a/lib/libesp32_audio/mp3_shine_esp32/src/l3mdct.cpp b/lib/libesp32_audio/mp3_shine_esp32/src/l3mdct.cpp index c51c6b5a9ab7..fd7b41fcbbc8 100755 --- a/lib/libesp32_audio/mp3_shine_esp32/src/l3mdct.cpp +++ b/lib/libesp32_audio/mp3_shine_esp32/src/l3mdct.cpp @@ -5,8 +5,8 @@ #include "l3subband.h" /* This is table B.9: coefficients for aliasing reduction */ -#define MDCT_CA(coef) (int32_t)(coef / sqrt(1.0 + (coef * coef)) * 0x7fffffff) -#define MDCT_CS(coef) (int32_t)(1.0 / sqrt(1.0 + (coef * coef)) * 0x7fffffff) +#define MDCT_CA(coef) (int)(coef / sqrt(1.0 + (coef * coef)) * 0x7fffffff) +#define MDCT_CS(coef) (int)(1.0 / sqrt(1.0 + (coef * coef)) * 0x7fffffff) #define MDCT_CA0 MDCT_CA(-0.6) #define MDCT_CA1 MDCT_CA(-0.535) @@ -38,7 +38,7 @@ void shine_mdct_initialise(shine_global_config *config) { for(k=36; k--; ) /* combine window and mdct coefficients into a single table */ /* scale and convert to fixed point before storing */ - config->mdct.cos_l[m][k] = (int32_t)(sin(PI36*(k+0.5)) + config->mdct.cos_l[m][k] = (int)(sin(PI36*(k+0.5)) * cos((PI/72)*(2*k+19)*(2*m+1)) * 0x7fffffff); } @@ -50,17 +50,17 @@ void shine_mdct_sub(shine_global_config *config, int stride) { /* note. we wish to access the array 'config->mdct_freq[2][2][576]' as * [2][2][32][18]. (32*18=576), */ - int32_t (*mdct_enc)[18]; + int (*mdct_enc)[18]; int ch,gr,band,j,k; - int32_t mdct_in[36]; + int mdct_in[36]; for(ch=config->wave.channels; ch--; ) { for(gr=0; grmpeg.granules_per_frame; gr++) { /* set up pointer to the part of config->mdct_freq we're using */ - mdct_enc = (int32_t (*)[18]) config->mdct_freq[ch][gr]; + mdct_enc = (int (*)[18]) config->mdct_freq[ch][gr]; /* polyphase filtering */ for(k=0; k<18; k+=2) @@ -91,7 +91,7 @@ void shine_mdct_sub(shine_global_config *config, int stride) { for(k=18; k--; ) { - int32_t vm; + int vm; #ifdef __BORLANDC__ uint32_t vm_lo; #else diff --git a/lib/libesp32_audio/mp3_shine_esp32/src/l3subband.cpp b/lib/libesp32_audio/mp3_shine_esp32/src/l3subband.cpp index 683dd2cf1be5..717ae5fbe597 100755 --- a/lib/libesp32_audio/mp3_shine_esp32/src/l3subband.cpp +++ b/lib/libesp32_audio/mp3_shine_esp32/src/l3subband.cpp @@ -28,7 +28,7 @@ void shine_subband_initialise(shine_global_config *config) { else modf(filter-0.5, &filter); /* scale and convert to fixed point before storing */ - config->subband.fl[i][j] = (int32_t)(filter * (0x7fffffff * 1e-9)); + config->subband.fl[i][j] = (int)(filter * (0x7fffffff * 1e-9)); } } @@ -46,20 +46,20 @@ void shine_subband_initialise(shine_global_config *config) { * picking out values from the windowed samples, and then multiplying * them by the filter matrix, producing 32 subband samples. */ -void shine_window_filter_subband(int16_t **buffer, int32_t s[SBLIMIT], int ch, shine_global_config *config, int stride) { - int32_t y[64]; +void shine_window_filter_subband(int16_t **buffer, int s[SBLIMIT], int ch, shine_global_config *config, int stride) { + int y[64]; int i,j; int16_t *ptr = *buffer; /* replace 32 oldest samples with 32 new samples */ for (i=32;i--;) { - config->subband.x[ch][i+config->subband.off[ch]] = ((int32_t)*ptr) << 16; + config->subband.x[ch][i+config->subband.off[ch]] = ((int)*ptr) << 16; ptr += stride; } *buffer = ptr; for (i=64; i--; ) { - int32_t s_value; + int s_value; #ifdef __BORLANDC__ uint32_t s_value_lo; #else @@ -81,7 +81,7 @@ void shine_window_filter_subband(int16_t **buffer, int32_t s[SBLIMIT], int ch, s config->subband.off[ch] = (config->subband.off[ch] + 480) & (HAN_SIZE-1); /* offset is modulo (HAN_SIZE)*/ for (i=SBLIMIT; i--; ) { - int32_t s_value; + int s_value; #ifdef __BORLANDC__ uint32_t s_value_lo; #else diff --git a/lib/libesp32_audio/mp3_shine_esp32/src/l3subband.h b/lib/libesp32_audio/mp3_shine_esp32/src/l3subband.h index 9bfe861eeb23..631ac42a2995 100755 --- a/lib/libesp32_audio/mp3_shine_esp32/src/l3subband.h +++ b/lib/libesp32_audio/mp3_shine_esp32/src/l3subband.h @@ -4,6 +4,6 @@ #include void shine_subband_initialise( shine_global_config *config ); -void shine_window_filter_subband(int16_t **buffer, int32_t s[SBLIMIT], int k, shine_global_config *config, int stride); +void shine_window_filter_subband(int16_t **buffer, int s[SBLIMIT], int k, shine_global_config *config, int stride); #endif diff --git a/lib/libesp32_audio/mp3_shine_esp32/src/layer3.cpp b/lib/libesp32_audio/mp3_shine_esp32/src/layer3.cpp index 80d7b0626df0..a2164e9f8d5e 100755 --- a/lib/libesp32_audio/mp3_shine_esp32/src/layer3.cpp +++ b/lib/libesp32_audio/mp3_shine_esp32/src/layer3.cpp @@ -106,12 +106,12 @@ shine_global_config *shine_initialise(shine_config_t *pub_config) { for (x = 0; x < MAX_CHANNELS; x++) { for (y = 0; y < MAX_GRANULES; y++) { // 2 * 2 * 576 each - config->l3_enc[x][y] = (int*)heap_caps_malloc_prefer(sizeof(int32_t)*GRANULE_SIZE, MALLOC_CAP_32BIT, MALLOC_CAP_SPIRAM|MALLOC_CAP_32BIT); //Significant performance hit in IRAM + config->l3_enc[x][y] = (int*)heap_caps_malloc_prefer(4*GRANULE_SIZE, MALLOC_CAP_32BIT, MALLOC_CAP_SPIRAM|MALLOC_CAP_32BIT); //Significant performance hit in IRAM if (!config->l3_enc[x][y]) { // error should never occur because of spiram size //config->l3_enc[x][y] = (int*)heap_caps_malloc(sizeof(int32_t)*GRANULE_SIZE,MALLOC_CAP_SPIRAM|MALLOC_CAP_32BIT); } - config->mdct_freq[x][y] = (int*)heap_caps_malloc_prefer(sizeof(int32_t)*GRANULE_SIZE, MALLOC_CAP_32BIT, MALLOC_CAP_SPIRAM|MALLOC_CAP_32BIT); //OK 1% + config->mdct_freq[x][y] = (int*)heap_caps_malloc_prefer(4*GRANULE_SIZE, MALLOC_CAP_32BIT, MALLOC_CAP_SPIRAM|MALLOC_CAP_32BIT); //OK 1% if (!config->mdct_freq[x][y]) { // error //config->mdct_freq[x][y] = (int*)heap_caps_malloc(sizeof(int32_t)*GRANULE_SIZE, MALLOC_CAP_SPIRAM|MALLOC_CAP_32BIT); @@ -123,15 +123,15 @@ shine_global_config *shine_initialise(shine_config_t *pub_config) { #endif config->l3loop = (l3loop_t*)heap_caps_malloc(sizeof(l3loop_t), MALLOC_CAP_SPIRAM); #ifdef SHINE_DEBUG - printf("xrsq & xrabs each: %d\n", sizeof(int32_t)*GRANULE_SIZE); + printf("xrsq & xrabs each: %d\n", sizeof(int)*GRANULE_SIZE); #endif - config->l3loop->xrsq = (int*)heap_caps_malloc_prefer(sizeof(int32_t)*GRANULE_SIZE, MALLOC_CAP_32BIT, MALLOC_CAP_SPIRAM|MALLOC_CAP_32BIT); //OK 0.5% + config->l3loop->xrsq = (int*)heap_caps_malloc_prefer(4*GRANULE_SIZE, MALLOC_CAP_32BIT, MALLOC_CAP_SPIRAM|MALLOC_CAP_32BIT); //OK 0.5% if (!config->l3loop->xrsq) { // error //config->l3loop->xrsq = (int*)heap_caps_malloc(sizeof(int32_t)*GRANULE_SIZE, MALLOC_CAP_SPIRAM|MALLOC_CAP_32BIT); //OK 0.5% } - config->l3loop->xrabs = (int*)heap_caps_malloc_prefer(sizeof(int32_t)*GRANULE_SIZE, MALLOC_CAP_32BIT, MALLOC_CAP_SPIRAM|MALLOC_CAP_32BIT); //OK 0.5% + config->l3loop->xrabs = (int*)heap_caps_malloc_prefer(4*GRANULE_SIZE, MALLOC_CAP_32BIT, MALLOC_CAP_SPIRAM|MALLOC_CAP_32BIT); //OK 0.5% if (!config->l3loop->xrabs) { //config->l3loop->xrabs = (int*)heap_caps_malloc(sizeof(int32_t)*GRANULE_SIZE, MALLOC_CAP_SPIRAM|MALLOC_CAP_32BIT); //OK 0.5% } diff --git a/lib/libesp32_audio/mp3_shine_esp32/src/mult_mips_gcc.h b/lib/libesp32_audio/mp3_shine_esp32/src/mult_mips_gcc.h index 092ed844e1a3..43ca1aa8ca65 100755 --- a/lib/libesp32_audio/mp3_shine_esp32/src/mult_mips_gcc.h +++ b/lib/libesp32_audio/mp3_shine_esp32/src/mult_mips_gcc.h @@ -2,7 +2,7 @@ #define mul(a,b) \ ({ \ - register int32_t res; \ + register int res; \ __asm__ __volatile__("mult %0, %1" : : "r" (a), "r" (b)); \ __asm__ __volatile__("mfhi %0" : "=r" (res)); \ res; \ @@ -19,14 +19,14 @@ #define mulz(hi,lo) \ do { \ - register int32_t t; \ + register int t; \ __asm__ __volatile__("mfhi %0" : "=r" (t)); \ (hi) = t; \ } while (0) #define cmuls(dre, dim, are, aim, bre, bim) \ do { \ - register int32_t t1, t2, tre; \ + register int t1, t2, tre; \ __asm__ __volatile__("mult %0, %1" : : "r" (are), "r" (bre)); \ __asm__ __volatile__("msub %0, %1" : : "r" (aim), "r" (bim)); \ __asm__ __volatile__("mfhi %0; mflo %1" : "=r" (t1), "=r" (t2)); \ diff --git a/lib/libesp32_audio/mp3_shine_esp32/src/mult_noarch_gcc.h b/lib/libesp32_audio/mp3_shine_esp32/src/mult_noarch_gcc.h index e1143f830c32..aa9c2293ebc4 100755 --- a/lib/libesp32_audio/mp3_shine_esp32/src/mult_noarch_gcc.h +++ b/lib/libesp32_audio/mp3_shine_esp32/src/mult_noarch_gcc.h @@ -1,11 +1,11 @@ #include #ifndef asm_mul -//#define /// mul(a,b) (int32_t) ( ( ((int64_t) a) * ((int64_t) b) ) >>32 ) +//#define /// mul(a,b) (int) ( ( ((int64_t) a) * ((int64_t) b) ) >>32 ) #define asm_mul(x,y) \ ({ \ - register int32_t result; \ + register int result; \ asm ("mulsh %0, %2, %1" : "=r" (result) : "r" (x), "r" (y)); \ result ;\ }) @@ -15,7 +15,7 @@ #ifndef asm_muls //Not sure about this #define asm_muls(x,y) \ ({ \ - register int32_t result; \ + register int result; \ asm ( \ "mulsh %0, %2, %1\n\t" \ "add %0, %0, %0" \ @@ -25,24 +25,24 @@ -//#define muls(a,b) (int32_t) ( ( ((int64_t) a) * ((int64_t) b) ) >>31 ) +//#define muls(a,b) (int) ( ( ((int64_t) a) * ((int64_t) b) ) >>31 ) #endif #ifndef asm_mulr //no rounding shortcut #define asm_mulr(x,y) \ ({ \ - register int32_t result; \ + register int result; \ asm ("mulsh %0, %2, %1" : "=r" (result) : "r" (x), "r" (y)); \ result ;\ }) -//#define mulr(a,b) (int32_t) ( ( ( ((int64_t) a) * ((int64_t) b)) + 0x80000000LL ) >>32 ) +//#define mulr(a,b) (int) ( ( ( ((int64_t) a) * ((int64_t) b)) + 0x80000000LL ) >>32 ) #endif #ifndef asm_mulsr //no rounding shortcut #define asm_mulsr(x,y) \ ({ \ - register int32_t result; \ + register int result; \ asm ( \ "mulsh %0, %2, %1\n\t" \ "add %0, %0, %0" \ @@ -50,7 +50,7 @@ result ;\ }) -//#define mulsr(a,b) (int32_t) ( ( ( ((int64_t) a) * ((int64_t) b)) + 0x40000000LL ) >>31 ) +//#define mulsr(a,b) (int) ( ( ( ((int64_t) a) * ((int64_t) b)) + 0x40000000LL ) >>31 ) #endif #ifndef asm_mul0 @@ -84,7 +84,7 @@ /* #define cmuls(dre, dim, are, aim, bre, bim) \ do { \ - register int32_t tre, tim; \ + register int tre, tim; \ asm ( \ "mull %0, %2, %4\n\t" \ //mulsh "mulsh r3, %2, %4\n\t" \ //mulsh @@ -111,9 +111,9 @@ do { \ #define asm_cmuls(dre, dim, are, aim, bre, bim) \ do { \ - int32_t tre; \ - (tre) = (int32_t) (((int64_t) (are) * (int64_t) (bre) - (int64_t) (aim) * (int64_t) (bim)) >> 31); \ - (dim) = (int32_t) (((int64_t) (are) * (int64_t) (bim) + (int64_t) (aim) * (int64_t) (bre)) >> 31); \ + int tre; \ + (tre) = (int) (((int64_t) (are) * (int64_t) (bre) - (int64_t) (aim) * (int64_t) (bim)) >> 31); \ + (dim) = (int) (((int64_t) (are) * (int64_t) (bim) + (int64_t) (aim) * (int64_t) (bre)) >> 31); \ (dre) = tre; \ } while (0) #endif diff --git a/lib/libesp32_audio/mp3_shine_esp32/src/mult_sarm_gcc.h b/lib/libesp32_audio/mp3_shine_esp32/src/mult_sarm_gcc.h index d229effd8b03..4f7bb9ca3019 100755 --- a/lib/libesp32_audio/mp3_shine_esp32/src/mult_sarm_gcc.h +++ b/lib/libesp32_audio/mp3_shine_esp32/src/mult_sarm_gcc.h @@ -4,14 +4,14 @@ #if __ARM_ARCH >= 6 #define mul(x,y) \ ({ \ - register int32_t result; \ + register int result; \ asm ("smmul %0, %2, %1" : "=r" (result) : "r" (x), "r" (y)); \ result ;\ }) #else #define mul(x,y) \ ({ \ - register int32_t result; \ + register int result; \ asm ("smull r3, %0, %2, %1" : "=r" (result) : "r" (x), "r" (y) : "r3"); \ result ; \ }) @@ -20,7 +20,7 @@ /* Fractional multiply with single bit left shift. */ #define muls(x,y) \ ({ \ - register int32_t result; \ + register int result; \ asm ( \ "smull r3, %0, %2, %1\n\t" \ "movs r3, r3, lsl #1\n\t" \ @@ -34,7 +34,7 @@ #if __ARM_ARCH >= 6 #define mulr(x,y) \ ({ \ - register int32_t result; \ + register int result; \ asm ( \ "smmulr %0, %2, %1" : "=r" (result) : "r" (x), "r" (y) \ ); \ @@ -43,7 +43,7 @@ #else #define mulr(x,y) \ ({ \ - register int32_t result; \ + register int result; \ asm ( \ "smull r3, %0, %2, %1\n\t" \ "adds r3, r3, #0x80000000\n\t" \ @@ -56,7 +56,7 @@ #define mulsr(x,y) \ ({ \ - register int32_t result; \ + register int result; \ asm ( \ "smull r3, %0, %1, %2\n\t" \ "movs r3, r3, lsl #1\n\t" \ @@ -81,7 +81,7 @@ #define cmuls(dre, dim, are, aim, bre, bim) \ do { \ - register int32_t tre, tim; \ + register int tre, tim; \ asm ( \ "smull r3, %0, %2, %4\n\t" \ "smlal r3, %0, %3, %5\n\t" \ diff --git a/lib/libesp32_audio/mp3_shine_esp32/src/tables.cpp b/lib/libesp32_audio/mp3_shine_esp32/src/tables.cpp index ff7e37492682..40cdd9d995dc 100755 --- a/lib/libesp32_audio/mp3_shine_esp32/src/tables.cpp +++ b/lib/libesp32_audio/mp3_shine_esp32/src/tables.cpp @@ -66,11 +66,11 @@ const int shine_scale_fact_band_index[9][23] = /* note. 0.035781 is shine_enwindow maximum value */ /* scale and convert to fixed point before storing */ -#define SHINE_EW(x) (int32_t)((double)(x) * 0x7fffffff) +#define SHINE_EW(x) (int)((double)(x) * 0x7fffffff) #define SHINE_EW2(a,b) SHINE_EW(a), SHINE_EW(b) #define SHINE_EW10(a,b,c,d,e,f,g,h,i,j) SHINE_EW2(a,b), SHINE_EW2(c,d), SHINE_EW2(e,f), SHINE_EW2(g,h), SHINE_EW2(i,j) -const int32_t shine_enwindow[] = { +const int shine_enwindow[] = { SHINE_EW10( 0.000000, -0.000000, -0.000000, -0.000000, -0.000000, -0.000000, -0.000000, -0.000001, -0.000001, -0.000001), SHINE_EW10( -0.000001, -0.000001, -0.000001, -0.000002, -0.000002, -0.000002, -0.000002, -0.000003, -0.000003, -0.000003), SHINE_EW10( -0.000004, -0.000004, -0.000005, -0.000005, -0.000006, -0.000007, -0.000008, -0.000008, -0.000009, -0.000010), diff --git a/lib/libesp32_audio/mp3_shine_esp32/src/tables.h b/lib/libesp32_audio/mp3_shine_esp32/src/tables.h index 5c94228cb7b3..1fbde4bd4c4e 100755 --- a/lib/libesp32_audio/mp3_shine_esp32/src/tables.h +++ b/lib/libesp32_audio/mp3_shine_esp32/src/tables.h @@ -10,7 +10,7 @@ extern const int samplerates[9]; extern const int bitrates[16][4]; extern const int shine_scale_fact_band_index[9][23]; -extern const int32_t shine_enwindow[]; +extern const int shine_enwindow[]; #endif diff --git a/lib/libesp32_audio/mp3_shine_esp32/src/types.h b/lib/libesp32_audio/mp3_shine_esp32/src/types.h index 69827481c43b..44a420440da9 100755 --- a/lib/libesp32_audio/mp3_shine_esp32/src/types.h +++ b/lib/libesp32_audio/mp3_shine_esp32/src/types.h @@ -85,27 +85,27 @@ typedef struct { } priv_shine_mpeg_t; typedef struct { - int32_t *xr; /* magnitudes of the spectral values */ - int32_t *xrsq; /* xr squared */ - int32_t *xrabs; /* xr absolute */ - int32_t xrmax; /* maximum of xrabs array */ - int32_t en_tot[MAX_GRANULES]; /* gr */ - int32_t en[MAX_GRANULES][21]; - int32_t xm[MAX_GRANULES][21]; - int32_t xrmaxl[MAX_GRANULES]; + int *xr; /* magnitudes of the spectral values */ + int *xrsq; /* xr squared */ + int *xrabs; /* xr absolute */ + int xrmax; /* maximum of xrabs array */ + int en_tot[MAX_GRANULES]; /* gr */ + int en[MAX_GRANULES][21]; + int xm[MAX_GRANULES][21]; + int xrmaxl[MAX_GRANULES]; double steptab[128]; /* 2**(-x/4) for x = -127..0 */ - int32_t steptabi[128]; /* 2**(-x/4) for x = -127..0 */ + int steptabi[128]; /* 2**(-x/4) for x = -127..0 */ int16_t int2idx[10000]; /* x**(3/4) for x = 0..9999 */ } l3loop_t; typedef struct { - int32_t cos_l[18][36]; + int cos_l[18][36]; } mdct_t; typedef struct { int off[MAX_CHANNELS]; - int32_t fl[SBLIMIT][64]; - int32_t x[MAX_CHANNELS][HAN_SIZE]; + int fl[SBLIMIT][64]; + int x[MAX_CHANNELS][HAN_SIZE]; } subband_t; /* Side information */ @@ -150,8 +150,8 @@ typedef struct { } shine_psy_xmin_t; typedef struct { - int32_t l[MAX_GRANULES][MAX_CHANNELS][22]; /* [cb] */ - int32_t s[MAX_GRANULES][MAX_CHANNELS][13][3]; /* [window][cb] */ + int l[MAX_GRANULES][MAX_CHANNELS][22]; /* [cb] */ + int s[MAX_GRANULES][MAX_CHANNELS][13][3]; /* [window][cb] */ } shine_scalefac_t; @@ -167,8 +167,8 @@ typedef struct shine_global_flags { int16_t *buffer[MAX_CHANNELS]; double pe[MAX_CHANNELS][MAX_GRANULES]; int *l3_enc[MAX_CHANNELS][MAX_GRANULES]; //4% reduction in performance IRAM - int32_t l3_sb_sample[MAX_CHANNELS][MAX_GRANULES+1][18][SBLIMIT]; - int32_t *mdct_freq[MAX_CHANNELS][MAX_GRANULES]; //1% reduction in perormance IRAM + int l3_sb_sample[MAX_CHANNELS][MAX_GRANULES+1][18][SBLIMIT]; + int *mdct_freq[MAX_CHANNELS][MAX_GRANULES]; //1% reduction in perormance IRAM int ResvSize; int ResvMax; l3loop_t *l3loop; diff --git a/lib/libesp32_div/ESP32-HomeKit/src/port/bignum.h b/lib/libesp32_div/ESP32-HomeKit/src/port/bignum.h index 158c22cb19a6..51394c66ffe3 100644 --- a/lib/libesp32_div/ESP32-HomeKit/src/port/bignum.h +++ b/lib/libesp32_div/ESP32-HomeKit/src/port/bignum.h @@ -15,6 +15,6 @@ #if CONFIG_IDF_TARGET_ESP32 #include "bignum_ESP32.h" -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32S3 #include "bignum_ESP32_C3.h" #endif diff --git a/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_ESP32.c b/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_ESP32.c index d21b44a80186..9e7158fe6096 100644 --- a/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_ESP32.c +++ b/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_ESP32.c @@ -38,7 +38,10 @@ #include #if CONFIG_IDF_TARGET_ESP32C3 #include "esp32c3/dport_access.h" -#endif +#endif +#if CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/dport_access.h" +#endif #if CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/dport_access.h" #endif diff --git a/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_ESP32_C3.c b/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_ESP32_C3.c index 1c579005fe71..5cd600d69aee 100644 --- a/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_ESP32_C3.c +++ b/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_ESP32_C3.c @@ -21,7 +21,7 @@ * */ -#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32S3 #if __has_include("esp_idf_version.h") #include "esp_idf_version.h" #endif @@ -105,4 +105,4 @@ static inline void wait_op_complete(void) REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); } -#endif //CONFIG_IDF_TARGET_ESP32C3 +#endif // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32S3 diff --git a/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_ESP32_C3.h b/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_ESP32_C3.h index e664dd779b76..dd87e04630a6 100644 --- a/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_ESP32_C3.h +++ b/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_ESP32_C3.h @@ -11,7 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32S3 #pragma once #include_next "mbedtls/bignum.h" @@ -84,4 +84,4 @@ void esp_mpi_mul_mpi_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t nu //#endif // CONFIG_MBEDTLS_HARDWARE_MPI -#endif //CONFIG_IDF_TARGET_ESP32C3 +#endif // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6|| CONFIG_IDF_TARGET_ESP32S3 diff --git a/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_impl.h b/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_impl.h index 1b1fa8e5651d..bf98c00746a9 100644 --- a/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_impl.h +++ b/lib/libesp32_div/ESP32-HomeKit/src/port/bignum_impl.h @@ -89,7 +89,7 @@ void esp_mpi_exp_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const #endif //CONFIG_IDF_TARGET_ESP32 #endif //ESP_MPI_USE_MONT_EXP -#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32S3 void esp_mpi_exp_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words); extern int esp_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv ); extern size_t esp_mpi_hardware_words(size_t words); @@ -97,6 +97,6 @@ extern void esp_mpi_enable_hardware_hw_op( void ); extern void esp_mpi_disable_hardware_hw_op( void ); extern void esp_mpi_read_result_hw_op(mbedtls_mpi *Z, size_t z_words); extern void esp_mpi_mult_mpi_failover_mod_mult_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words); -#endif //CONFIG_IDF_TARGET_ESP32C3 +#endif // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32S3 #endif diff --git a/lib/libesp32_div/ESP32-HomeKit/src/port/esp_bignum.c b/lib/libesp32_div/ESP32-HomeKit/src/port/esp_bignum.c index 5b8e124cefc5..0dbc343140d9 100644 --- a/lib/libesp32_div/ESP32-HomeKit/src/port/esp_bignum.c +++ b/lib/libesp32_div/ESP32-HomeKit/src/port/esp_bignum.c @@ -79,7 +79,7 @@ static inline size_t bits_to_words(size_t bits) /* Return the number of words actually used to represent an mpi number. */ -#if defined(MBEDTLS_MPI_EXP_MOD_ALT) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) +#if defined(MBEDTLS_MPI_EXP_MOD_ALT) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32S3) static size_t mpi_words(const mbedtls_mpi *mpi) { for (size_t i = mpi->n; i > 0; i--) { @@ -369,7 +369,7 @@ int esp_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, #endif /* MBEDTLS_MPI_EXP_MOD_ALT */ -#if CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 int esp_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv ) { int ret = 0; diff --git a/lib/libesp32_div/NimBLE-Arduino/library.json b/lib/libesp32_div/NimBLE-Arduino/library.json index 348f77d3dfe6..1f55748d6894 100644 --- a/lib/libesp32_div/NimBLE-Arduino/library.json +++ b/lib/libesp32_div/NimBLE-Arduino/library.json @@ -2,7 +2,7 @@ "name": "NimBLE-Arduino", "keywords": "esp32, bluetooth", "description": "Bluetooth low energy (BLE) library for arduino-esp32 based on NimBLE", - "version": "1.4.0", + "version": "1.4.1", "frameworks": "arduino", "platforms": "espressif32" } diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.cpp index 43ba21909d1c..d2553b0e81a5 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.cpp +++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.cpp @@ -867,7 +867,7 @@ void NimBLEDevice::init(const std::string &deviceName) { esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); -#if defined (CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) +#if defined (CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32S3) bt_cfg.bluetooth_mode = ESP_BT_MODE_BLE; #else bt_cfg.mode = ESP_BT_MODE_BLE; diff --git a/lib/libesp32_div/NimBLE-Arduino/src/nimconfig.h b/lib/libesp32_div/NimBLE-Arduino/src/nimconfig.h index 8214e1d9b291..9d991ae212dd 100644 --- a/lib/libesp32_div/NimBLE-Arduino/src/nimconfig.h +++ b/lib/libesp32_div/NimBLE-Arduino/src/nimconfig.h @@ -149,6 +149,12 @@ End Arduino user-config **********************************/ +#ifndef CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE +#define CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE 4096 +#endif + +#ifndef CONFIG_BT_NIMBLE_ROLE_CENTRAL // means for Tasmota: nimble was already embedded into the Arduino framework + /* This section should not be altered */ #ifndef CONFIG_BT_NIMBLE_ROLE_CENTRAL_DISABLED #define CONFIG_BT_NIMBLE_ROLE_CENTRAL @@ -170,10 +176,6 @@ #define CONFIG_BT_NIMBLE_PINNED_TO_CORE 0 #endif -#ifndef CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE -#define CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE 4096 -#endif - #ifndef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL #define CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL 1 #endif @@ -284,7 +286,7 @@ #define CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE 2 #endif -#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) +#if !defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(CONFIG_IDF_TARGET_ESP32S3) #define CONFIG_IDF_TARGET_ESP32 1 #endif @@ -324,9 +326,12 @@ #define CONFIG_BT_NIMBLE_ROLE_BROADCASTER #endif +#endif //CONFIG_BT_NIMBLE_ROLE_CENTRAL + /* Enables the use of Arduino String class for attribute values */ #if defined __has_include # if __has_include () # define NIMBLE_CPP_ARDUINO_STRING_AVAILABLE # endif #endif + diff --git a/lib/libesp32_div/esp-nimble-cpp/.github/workflows/build.yml b/lib/libesp32_div/esp-nimble-cpp/.github/workflows/build.yml new file mode 100644 index 000000000000..f256daaff528 --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/.github/workflows/build.yml @@ -0,0 +1,65 @@ +name: Build + +on: + workflow_dispatch: # Start a workflow + pull_request: + push: + +jobs: + build-esp-idf-component: + name: Build with ESP-IDF ${{ matrix.idf_ver }} for ${{ matrix.idf_target }} + runs-on: ubuntu-latest + strategy: + matrix: + # The version names here correspond to the versions of espressif/idf Docker image. + # See https://hub.docker.com/r/espressif/idf/tags and + # https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html + # for details. + idf_ver: ["release-v4.4", "release-v5.1"] + idf_target: ["esp32", "esp32s3", "esp32c2", "esp32c3", "esp32c6"] + example: + - Advanced/NimBLE_Client + - Advanced/NimBLE_Server + - basic/BLE_client + - basic/BLE_notify + - basic/BLE_scan + - basic/BLE_server + - basic/BLE_uart + - Bluetooth_5/NimBLE_extended_client + - Bluetooth_5/NimBLE_extended_server + - Bluetooth_5/NimBLE_multi_advertiser + exclude: + - idf_target: "esp32" + example: Bluetooth_5/NimBLE_extended_client + - idf_target: "esp32" + example: Bluetooth_5/NimBLE_extended_server + - idf_target: "esp32" + example: Bluetooth_5/NimBLE_multi_advertiser + - idf_ver: release-v4.4 + idf_target: "esp32c2" + - idf_ver: release-v4.4 + idf_target: "esp32c6" + + container: espressif/idf:${{ matrix.idf_ver }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + path: components/esp-nimble-cpp + - name: Build examples + env: + IDF_TARGET: ${{ matrix.idf_target }} + shell: bash + run: | + . ${IDF_PATH}/export.sh + cp -r components/esp-nimble-cpp/examples/* . + idf.py -C ${{ matrix.example }} -DEXTRA_COMPONENT_DIRS=$PWD/components build + + build_docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Doxygen Action + uses: mattnotmitt/doxygen-action@v1.9.5 + with: + working-directory: 'docs/' diff --git a/lib/libesp32_div/esp-nimble-cpp/.gitignore b/lib/libesp32_div/esp-nimble-cpp/.gitignore new file mode 100644 index 000000000000..343d1f4179e3 --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/.gitignore @@ -0,0 +1 @@ +docs/doxydocs \ No newline at end of file diff --git a/lib/libesp32_div/esp-nimble-cpp/CHANGELOG.md b/lib/libesp32_div/esp-nimble-cpp/CHANGELOG.md new file mode 100644 index 000000000000..f8b6e42cbd78 --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/CHANGELOG.md @@ -0,0 +1,280 @@ +# Changelog + +All notable changes to this project will be documented in this file. +## [Unreleased] + +### Changed +- NimBLESecurity class removed. + +### Added +- `NimBLEDevice::setDeviceName` to change the device name after initialization. +- `NimBLEHIDDevice::batteryLevel` returns the HID device battery level characteristic. + +## [1.4.0] - 2022-07-31 + +### Fixed +- Fixed missing data from long notification values. +- Fixed NimbleCharacteristicCallbacks::onRead not being called when a non-long read command is received. +- Prevent a potential crash when retrieving characteristics from a service if the result was successful but no characteristics found. +- logs/typos. + +### Changed +- AD flags are no longer set in the advertisements of non-connectable beacons, freeing up 3 bytes of advertisement room. +- Save resources when retrieving descriptors if the characteristic handle is the same as the end handle (no descriptors). +- Subscribing to characteristic notifications/indications will now always use write with response, as per BLE specifications. +- `NimBLEClient::discoverAttributes` now returns a bool value to indicate success/failure. +- Scan result callbacks are no longer called when the scan response data is updated in order to reduce duplicates. + +### Added +- Preliminary support for non-esp devices, NRF51 and NRF52 devices supported with [n-able arduino core](https://github.com/h2zero/n-able-Arduino) +- Alias added for `NimBLEServerCallbacks::onMTUChange` to `onMtuChanged` in order to support porting code from original library. +- `NimBLEAttValue` Class added to reduce and control RAM footprint of characteristic/descriptor values and support conversions from Arduino Strings and many other data types. +- Bluetooth 5 extended advertising support for capable devices. CODED Phy, 2M Phy, extended advertising data, and multi-advertising are supported, periodic advertising will be implemented in the future. + +## [1.3.3] - 2022-02-15 + +### Changed +- If attribute retrieval fails with a "not found" try again with the 16 bit version if a 128 bit base uuid is used. + +### Fixed +- Memory leak when deleting client instance. +- IDf version check for data length extension. +- Memory leak when server services changed. +- Compiler warnings for non-esp32 devices. + +## [1.3.2] - 2022-01-15 + +### Fixed +- Initialize advertising complete callback in NimBLEAdvertising constructor. +- Clear client disconnect timer in constructor before initializing. +- Fix missing data when reading large values. +- Fix missing data in notifications when using a large MTU size and more than 270 bytes of data are sent. +- Workaround fix added for cases when the task notification value is not cleared, causing various functions that should block not to block. + +### Added +- `NimBLEClient::getLastError` : Gets the error code of the last function call that produces a return code from the stack. +- `NimBLECharacteristic::notify` : Overload method to send notifications/indications with custom values. +- Added conditional checks for ESP32 specific functions/values to support use of the library on non-esp32 devices. +- Added an alias to use the callback name from the original library `onMtuChanged`. +- `NimBLEClient::setDataLen` and `NimBLEServer::setDataLen`: Data length extension support (IDF version >= 4.3.2 only) +- Config option to set logging level for esp-nimble-cpp + +### Changed +- Critical section calls now use the NimBLE API instead of FreeRTOS directly. This removes the need for a `portMUX_TYPE` variable in the class definitions. +- Removed unnecessary variables in `NimBLEService` and changed the constructor no no longer accept `numHandles` and `inst_id` parameters. + +## [1.3.1] - 2021-08-04 + +### Fixed +- Corrected a compiler/linker error when an application or a library uses bluetooth classic due to the redefinition of `btInUse`. + +## [1.3.0] - 2021-08-02 + +### Added +- `NimBLECharacteristic::removeDescriptor`: Dynamically remove a descriptor from a characterisic. Takes effect after all connections are closed and sends a service changed indication. +- `NimBLEService::removeCharacteristic`: Dynamically remove a characteristic from a service. Takes effect after all connections are closed and sends a service changed indication +- `NimBLEServerCallbacks::onMTUChange`: This is callback is called when the MTU is updated after connection with a client. +- ESP32C3 support + +- Whitelist API: + - `NimBLEDevice::whiteListAdd`: Add a device to the whitelist. + - `NimBLEDevice::whiteListRemove`: Remove a device from the whitelist. + - `NimBLEDevice::onWhiteList`: Check if the device is on the whitelist. + - `NimBLEDevice::getWhiteListCount`: Gets the size of the whitelist + - `NimBLEDevice::getWhiteListAddress`: Get the address of a device on the whitelist by index value. + +- Bond management API: + - `NimBLEDevice::getNumBonds`: Gets the number of bonds stored. + - `NimBLEDevice::isBonded`: Checks if the device is bonded. + - `NimBLEDevice::deleteAllBonds`: Deletes all bonds. + - `NimBLEDevice::getBondedAddress`: Gets the address of a bonded device by the index value. + +- `NimBLECharacteristic::getCallbacks` to retrieve the current callback handler. +- Connection Information class: `NimBLEConnInfo`. +- `NimBLEScan::clearDuplicateCache`: This can be used to reset the cache of advertised devices so they will be immediately discovered again. + +### Changed +- FreeRTOS files have been removed as they are not used by the library. +- Services, characteristics and descriptors can now be created statically and added after. +- Excess logging and some asserts removed. +- Use ESP_LOGx macros to enable using local log level filtering. + +### Fixed +- `NimBLECharacteristicCallbacks::onSubscribe` Is now called after the connection is added to the vector. +- Corrected bonding failure when reinitializing the BLE stack. +- Writing to a characterisic with a std::string value now correctly writes values with null characters. +- Retrieving remote descriptors now uses the characterisic end handle correctly. +- Missing data in long writes to remote descriptors. +- Hanging on task notification when sending an indication from the characteristic callback. +- BLE controller memory could be released when using Arduino as a component. +- Complile errors with NimBLE release 1.3.0. + +## [1.2.0] - 2021-02-08 + +### Added +- `NimBLECharacteristic::getDescriptorByHandle`: Return the BLE Descriptor for the given handle. + +- `NimBLEDescriptor::getStringValue`: Get the value of this descriptor as a string. + +- `NimBLEServer::getServiceByHandle`: Get a service by its handle. + +- `NimBLEService::getCharacteristicByHandle`: Get a pointer to the characteristic object with the specified handle. + +- `NimBLEService::getCharacteristics`: Get the vector containing pointers to each characteristic associated with this service. +Overloads to get a vector containing pointers to all the characteristics in a service with the UUID. (supports multiple same UUID's in a service) + - `NimBLEService::getCharacteristics(const char *uuid)` + - `NimBLEService::getCharacteristics(const NimBLEUUID &uuid)` + +- `NimBLEAdvertisementData` New methods: + - `NimBLEAdvertisementData::addTxPower`: Adds transmission power to the advertisement. + - `NimBLEAdvertisementData::setPreferredParams`: Adds connection parameters to the advertisement. + - `NimBLEAdvertisementData::setURI`: Adds URI data to the advertisement. + +- `NimBLEAdvertising` New methods: + - `NimBLEAdvertising::setName`: Set the name advertised. + - `NimBLEAdvertising::setManufacturerData`: Adds manufacturer data to the advertisement. + - `NimBLEAdvertising::setURI`: Adds URI data to the advertisement. + - `NimBLEAdvertising::setServiceData`: Adds service data to the advertisement. + - `NimBLEAdvertising::addTxPower`: Adds transmission power to the advertisement. + - `NimBLEAdvertising::reset`: Stops the current advertising and resets the advertising data to the default values. + +- `NimBLEDevice::setScanFilterMode`: Set the controller duplicate filter mode for filtering scanned devices. + +- `NimBLEDevice::setScanDuplicateCacheSize`: Sets the number of advertisements filtered before the cache is reset. + +- `NimBLEScan::setMaxResults`: This allows for setting a maximum number of advertised devices stored in the results vector. + +- `NimBLEAdvertisedDevice` New data retrieval methods added: + - `haveAdvInterval/getAdvInterval`: checks if the interval is advertised / gets the advertisement interval value. + + - `haveConnParams/getMinInterval/getMaxInterval`: checks if the parameters are advertised / get min value / get max value. + + - `haveURI/getURI`: checks if a URI is advertised / gets the URI data. + + - `haveTargetAddress/getTargetAddressCount/getTargetAddress(index)`: checks if a target address is present / gets a count of the addresses targeted / gets the address of the target at index. + +### Changed +- `nimconfig.h` (Arduino) is now easier to use. + +- `NimBLEServer::getServiceByUUID` Now takes an extra parameter of instanceID to support multiple services with the same UUID. + +- `NimBLEService::getCharacteristic` Now takes an extra parameter of instanceID to support multiple characteristics with the same UUID. + +- `NimBLEAdvertising` Transmission power is no longer advertised by default and can be added to the advertisement by calling `NimBLEAdvertising::addTxPower` + +- `NimBLEAdvertising` Custom scan response data can now be used without custom advertisment. + +- `NimBLEScan` Now uses the controller duplicate filter. + +- `NimBLEAdvertisedDevice` Has been refactored to store the complete advertisement payload and no longer parses the data from each advertisement. +Instead the data will be parsed on-demand when the user application asks for specific data. + +### Fixed +- `NimBLEHIDDevice` Characteristics now use encryption, this resolves an issue with communicating with devices requiring encryption for HID devices. + + +## [1.1.0] - 2021-01-20 + +### Added +- `NimBLEDevice::setOwnAddrType` added to enable the use of random and random-resolvable addresses, by asukiaaa + +- New examples for securing and authenticating client/server connections, by mblasee. + +- `NimBLEAdvertising::SetMinPreferred` and `NimBLEAdvertising::SetMinPreferred` re-added. + +- Conditional checks added for command line config options in `nimconfig.h` to support custom configuration in platformio. + +- `NimBLEClient::setValue` Now takes an extra bool parameter `response` to enable the use of write with response (default = false). + +- `NimBLEClient::getCharacteristic(uint16_t handle)` Enabling the use of the characteristic handle to be used to find +the NimBLERemoteCharacteristic object. + +- `NimBLEHIDDevice` class added by wakwak-koba. + +- `NimBLEServerCallbacks::onDisconnect` overloaded callback added to provide a ble_gap_conn_desc parameter for the application +to obtain information about the disconnected client. + +- Conditional checks in `nimconfig.h` for command line defined macros to support platformio config settings. + +### Changed +- `NimBLEAdvertising::start` now returns a bool value to indicate success/failure. + +- Some asserts were removed in `NimBLEAdvertising::start` and replaced with better return code handling and logging. + +- If a host reset event occurs, scanning and advertising will now only be restarted if their previous duration was indefinite. + +- `NimBLERemoteCharacteristic::subscribe` and `NimBLERemoteCharacteristic::registerForNotify` will now set the callback +regardless of the existance of the CCCD and return true unless the descriptor write operation failed. + +- Advertising tx power level is now sent in the advertisement packet instead of scan response. + +- `NimBLEScan` When the scan ends the scan stopped flag is now set before calling the scan complete callback (if used) +this allows the starting of a new scan from the callback function. + +### Fixed +- Sometimes `NimBLEClient::connect` would hang on the task block if no event arrived to unblock. +A time limit has been added to timeout appropriately. + +- When getting descriptors for a characterisic the end handle of the service was used as a proxy for the characteristic end +handle. This would be rejected by some devices and has been changed to use the next characteristic handle as the end when possible. + +- An exception could occur when deleting a client instance if a notification arrived while the attribute vectors were being +deleted. A flag has been added to prevent this. + +- An exception could occur after a host reset event when the host re-synced if the tasks that were stopped during the event did +not finish processing. A yield has been added after re-syncing to allow tasks to finish before proceeding. + +- Occasionally the controller would fail to send a disconnected event causing the client to indicate it is connected +and would be unable to reconnect. A timer has been added to reset the host/controller if it expires. + +- Occasionally the call to start scanning would get stuck in a loop on BLE_HS_EBUSY, this loop has been removed. + +- 16bit and 32bit UUID's in some cases were not discovered or compared correctly if the device +advertised them as 16/32bit but resolved them to 128bits. Both are now checked. + +- `FreeRTOS` compile errors resolved in latest Ardruino core and IDF v3.3. + +- Multiple instances of `time()` called inside critical sections caused sporadic crashes, these have been moved out of critical regions. + +- Advertisement type now correctly set when using non-connectable (advertiser only) mode. + +- Advertising payload length correction, now accounts for appearance. + +- (Arduino) Ensure controller mode is set to BLE Only. + + +## [1.0.2] - 2020-09-13 + +### Changed + +- `NimBLEAdvertising::start` Now takes 2 optional parameters, the first is the duration to advertise for (in seconds), the second is a +callback that is invoked when advertsing ends and takes a pointer to a `NimBLEAdvertising` object (similar to the `NimBLEScan::start` API). + +- (Arduino) Maximum BLE connections can now be altered by only changing the value of `CONFIG_BT_NIMBLE_MAX_CONNECTIONS` in `nimconfig.h`. +Any changes to the controller max connection settings in `sdkconfig.h` will now have no effect when using this library. + +- (Arduino) Revert the previous change to fix the advertising start delay. Instead a replacement fix that routes all BLE controller commands from +a task running on core 0 (same as the controller) has been implemented. This improves response times and reliability for all BLE functions. + + +## [1.0.1] - 2020-09-02 + +### Added + +- Empty `NimBLEAddress` constructor: `NimBLEAddress()` produces an address of 00:00:00:00:00:00 type 0. +- Documentation of the difference of NimBLEAddress::getNative vs the original bluedroid library. + +### Changed + +- notify_callback typedef is now defined as std::function to enable the use of std::bind to call a class member function. + +### Fixed + +- Fix advertising start delay when first called. + + +## [1.0.0] - 2020-08-22 + +First stable release. + +All the original library functionality is complete and many extras added with full documentation. diff --git a/lib/libesp32_div/esp-nimble-cpp/CMakeLists.txt b/lib/libesp32_div/esp-nimble-cpp/CMakeLists.txt new file mode 100644 index 000000000000..90c22bd19c73 --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/CMakeLists.txt @@ -0,0 +1,64 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +idf_build_get_property(__hack_component_targets __COMPONENT_TARGETS) + +if("esp-nimble-component" IN_LIST BUILD_COMPONENTS OR "__esp-nimble-component" IN_LIST __hack_component_targets) + list(APPEND ESP_NIMBLE_PRIV_REQUIRES + esp-nimble-component + ) +elseif("nimble" IN_LIST BUILD_COMPONENTS OR "__nimble" IN_LIST __hack_component_targets) + list(APPEND ESP_NIMBLE_PRIV_REQUIRES + nimble + ) +endif() + +if("arduino" IN_LIST BUILD_COMPONENTS OR __hack_component_targets MATCHES "__idf_arduino") + list(APPEND ESP_NIMBLE_PRIV_REQUIRES + arduino + ) +elseif("framework-arduinoespressif32" IN_LIST BUILD_COMPONENTS OR __hack_component_targets MATCHES "___idf_framework-arduinoespressif32") + list(APPEND ESP_NIMBLE_PRIV_REQUIRES + framework-arduinoespressif32 + ) +endif() + +idf_component_register( + REQUIRED_IDF_TARGETS + "esp32" + "esp32s3" + "esp32c2" + "esp32c3" + "esp32c6" + INCLUDE_DIRS + "src" + SRCS + "src/NimBLE2904.cpp" + "src/NimBLEAddress.cpp" + "src/NimBLEAdvertisedDevice.cpp" + "src/NimBLEAdvertising.cpp" + "src/NimBLEBeacon.cpp" + "src/NimBLECharacteristic.cpp" + "src/NimBLEClient.cpp" + "src/NimBLEDescriptor.cpp" + "src/NimBLEDevice.cpp" + "src/NimBLEEddystoneTLM.cpp" + "src/NimBLEEddystoneURL.cpp" + "src/NimBLEExtAdvertising.cpp" + "src/NimBLEHIDDevice.cpp" + "src/NimBLERemoteCharacteristic.cpp" + "src/NimBLERemoteDescriptor.cpp" + "src/NimBLERemoteService.cpp" + "src/NimBLEScan.cpp" + "src/NimBLEServer.cpp" + "src/NimBLEService.cpp" + "src/NimBLEUtils.cpp" + "src/NimBLEUUID.cpp" + REQUIRES + bt + nvs_flash + PRIV_REQUIRES + ${ESP_NIMBLE_PRIV_REQUIRES} +) + diff --git a/lib/libesp32_div/esp-nimble-cpp/CMakeLists.txt_idf3 b/lib/libesp32_div/esp-nimble-cpp/CMakeLists.txt_idf3 new file mode 100644 index 000000000000..c548f90212bc --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/CMakeLists.txt_idf3 @@ -0,0 +1,56 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +set(SUPPORTED_TARGETS esp32) + +set(COMPONENT_SRCS + "src/NimBLE2904.cpp" + "src/NimBLEAddress.cpp" + "src/NimBLEAdvertisedDevice.cpp" + "src/NimBLEAdvertising.cpp" + "src/NimBLEBeacon.cpp" + "src/NimBLECharacteristic.cpp" + "src/NimBLEClient.cpp" + "src/NimBLEDescriptor.cpp" + "src/NimBLEDevice.cpp" + "src/NimBLEEddystoneTLM.cpp" + "src/NimBLEEddystoneURL.cpp" + "src/NimBLEHIDDevice.cpp" + "src/NimBLERemoteCharacteristic.cpp" + "src/NimBLERemoteDescriptor.cpp" + "src/NimBLERemoteService.cpp" + "src/NimBLEScan.cpp" + "src/NimBLESecurity.cpp" + "src/NimBLEServer.cpp" + "src/NimBLEService.cpp" + "src/NimBLEUtils.cpp" + "src/NimBLEUUID.cpp" +) + +set(COMPONENT_ADD_INCLUDEDIRS + src +) + +set(COMPONENT_PRIV_REQUIRES + nvs_flash + bt +) + +if(COMPONENTS MATCHES "esp-nimble-component") + list(APPEND COMPONENT_PRIV_REQUIRES + esp-nimble-component + ) +elseif(COMPONENTS MATCHES "nimble") + list(APPEND COMPONENT_PRIV_REQUIRES + nimble + ) +endif() + +if(COMPONENTS MATCHES "arduino") + list(APPEND COMPONENT_PRIV_REQUIRES + arduino + ) +endif() + +register_component() diff --git a/lib/libesp32_div/esp-nimble-cpp/Kconfig b/lib/libesp32_div/esp-nimble-cpp/Kconfig new file mode 100644 index 000000000000..730f8cd968cd --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/Kconfig @@ -0,0 +1,72 @@ +menu "ESP-NimBLE-CPP configuration" + +choice NIMBLE_CPP_LOG_LEVEL + prompt "NimBLE CPP log verbosity" + default NIMBLE_CPP_LOG_LEVEL_NONE + help + Select NimBLE CPP log verbosity level. + + config NIMBLE_CPP_LOG_LEVEL_NONE + bool "No logs" + config NIMBLE_CPP_LOG_LEVEL_ERROR + bool "Error logs" + config NIMBLE_CPP_LOG_LEVEL_WARNING + bool "Warning logs" + config NIMBLE_CPP_LOG_LEVEL_INFO + bool "Info logs" + config NIMBLE_CPP_LOG_LEVEL_DEBUG + bool "Debug logs" +endchoice #NIMBLE_CPP_LOG_LEVEL + +config NIMBLE_CPP_LOG_LEVEL + int + default 0 if NIMBLE_CPP_LOG_LEVEL_NONE + default 1 if NIMBLE_CPP_LOG_LEVEL_ERROR + default 2 if NIMBLE_CPP_LOG_LEVEL_WARNING + default 3 if NIMBLE_CPP_LOG_LEVEL_INFO + default 4 if NIMBLE_CPP_LOG_LEVEL_DEBUG + +config NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT + bool "Show NimBLE return codes as text in debug log." + default "n" + help + Enabling this option will display return code values as text + messages in the debug log. This will use approximately 8kB + of flash memory. + +config NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT + bool "Show NimBLE gap events as text in debug log." + default "n" + help + Enabling this option will display gap event codes as text + messages in the debug log. This will use approximately 1kB + of flash memory. + +config NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT + bool "Show advertisment types as text in debug log." + default "n" + help + Enabling this option will display advertisment types recieved + while scanning as text messages in the debug log. + This will use approximately 250 bytes of flash memory. + +config NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED + bool "Enable timestamps to be stored with attribute values." + default "n" + help + Enabling this option will store the timestamp when an attribute value is updated. + This allows for checking the last update time using getTimeStamp() + or getValue(time_t*). If disabled, the timestamp returned from these functions will be 0. + Disabling timestamps will reduce the memory used for each value. + +config NIMBLE_CPP_ATT_VALUE_INIT_LENGTH + int "Initial attribute value size (bytes) for empty values." + range 1 512 + default 20 + help + Sets the default allocation size (bytes) for each attribute if not specified + when the constructor is called. This is also the size used when a remote + characteristic or descriptor is constructed before a value is read/notifed. + Increasing this will reduce reallocations but increase memory footprint. + +endmenu diff --git a/lib/libesp32_div/esp-nimble-cpp/LICENSE b/lib/libesp32_div/esp-nimble-cpp/LICENSE new file mode 100644 index 000000000000..ff162769ff3d --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/LICENSE @@ -0,0 +1,203 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {2020} {Ryan Powell} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + This product partly derives from esp32-snippets; Copyright 2017 Neil Kolban. \ No newline at end of file diff --git a/lib/libesp32_div/esp-nimble-cpp/README.md b/lib/libesp32_div/esp-nimble-cpp/README.md new file mode 100644 index 000000000000..7f37effadbc4 --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/README.md @@ -0,0 +1,70 @@ +[Latest release ![Release Version](https://img.shields.io/github/release/h2zero/esp-nimble-cpp.svg?style=plastic) +![Release Date](https://img.shields.io/github/release-date/h2zero/esp-nimble-cpp.svg?style=plastic)](https://github.com/h2zero/esp-nimble-cpp/releases/latest/) + +Need help? Have questions or suggestions? Join the [![Gitter](https://badges.gitter.im/NimBLE-Arduino/community.svg)](https://gitter.im/NimBLE-Arduino/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +
+ +# esp-nimble-cpp + +NimBLE CPP library for use with ESP32 that attempts to maintain compatibility with the [nkolban cpp_uitls BLE API](https://github.com/nkolban/esp32-snippets/tree/master/cpp_utils). + +**An Arduino version of this library, including NimBLE, can be [found here.](https://github.com/h2zero/NimBLE-Arduino)** + +This library **significantly** reduces resource usage and improves performance for ESP32 BLE applications as compared +with the bluedroid based library. The goal is to maintain, as much as reasonable, compatibility with the original +library but refactored to use the NimBLE stack. In addition, this library will be more actively developed and maintained +to provide improved capabilites and stability over the original. + +**Testing shows a nearly 50% reduction in flash use and approx. 100kB less ram consumed vs the original!** +*Your results may vary* +
+ +# What is NimBLE? +NimBLE is a completely open source Bluetooth Low Energy stack produced by [Apache](https://github.com/apache/mynewt-nimble). +It is more suited to resource constrained devices than bluedroid and has now been ported to the ESP32 by Espressif. +
+ +# Installation + +### ESP-IDF v4.0+ +Download as .zip and extract or clone into the components folder in your esp-idf project. + +Run menuconfig, go to `Component config->Bluetooth` enable Bluetooth and in `Bluetooth host` NimBLE. +Configure settings in `NimBLE Options`. +`#include "NimBLEDevice.h"` in main.cpp. +Call `NimBLEDevice::init("");` in `app_main`. +
+ +### ESP-IDF v3.2 & v3.3 +The NimBLE component does not come with these versions of IDF (now included in 3.3.2 and above). +A backport that works in these versions has been created and is [available here](https://github.com/h2zero/esp-nimble-component). +Download or clone that repo into your project/components folder and run menuconfig. +Configure settings in `main menu -> NimBLE Options`. + +`#include "NimBLEDevice.h"` in main.cpp. +Call `NimBLEDevice::init("");` in `app_main`. +
+ +# Using +This library is intended to be compatible with the original ESP32 BLE functions and types with minor changes. + +If you have not used the original Bluedroid library please refer to the [New user guide](docs/New_user_guide.md). + +If you are familiar with the original library, see: [The migration guide](docs/Migration_guide.md) for details about breaking changes and migration. + +Also see [Improvements_and_updates](docs/Improvements_and_updates.md) for information about non-breaking changes. + +[Full API documentation and class list can be found here.](https://h2zero.github.io/esp-nimble-cpp/) +
+ +## Using with Arduino as an IDF component and CMake +When using this library along with Arduino and compiling with *CMake* you must add `add_compile_definitions(ARDUINO_ARCH_ESP32=1)` +in your project/CMakeLists.txt after the line `include($ENV{IDF_PATH}/tools/cmake/project.cmake)` to prevent Arduino from releasing BLE memory. +
+ +# Acknowledgments +* [nkolban](https://github.com/nkolban) and [chegewara](https://github.com/chegewara) for the [original esp32 BLE library](https://github.com/nkolban/esp32-snippets/tree/master/cpp_utils) this project was derived from. +* [beegee-tokyo](https://github.com/beegee-tokyo) for contributing your time to test/debug and contributing the beacon examples. +* [Jeroen88](https://github.com/Jeroen88) for the amazing help debugging and improving the client code. +
+ diff --git a/lib/libesp32_div/esp-nimble-cpp/component.mk b/lib/libesp32_div/esp-nimble-cpp/component.mk new file mode 100644 index 000000000000..563436815500 --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/component.mk @@ -0,0 +1,2 @@ +COMPONENT_ADD_INCLUDEDIRS := src +COMPONENT_SRCDIRS := src \ No newline at end of file diff --git a/lib/libesp32_div/esp-nimble-cpp/docs/Bluetooth 5 features.md b/lib/libesp32_div/esp-nimble-cpp/docs/Bluetooth 5 features.md new file mode 100644 index 000000000000..3737b0d7e553 --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/docs/Bluetooth 5 features.md @@ -0,0 +1,28 @@ +# Bluetooth 5.x features + +## About extended advertising +Extended advertising allows for much more capability and flexibility. + +* Allows for 251 bytes of advertisement data and up to 1650 bytes when chained (configuration dependant) vs 31. + +* New PHY's (physical layers) that allow for faster data rate (2M PHY) or long range/slower data rates (CODED PHY) as well as the original 1M PHY. + +* New periodic advertising, allowing the scanning device to sync with the advertisements of a beacon. This allows for the scanning device to sleep or perform other tasks before the next expected advertisement is sent, preserving cpu cycles and power (To be implemented). +
+ +## Enabling extended advertising +Extended advertising is supported when enabled with the config option `CONFIG_BT_NIMBLE_EXT_ADV` set to a value of 1. This is done in menuconfig under `Component config > Bluetooth > NimBLE options > Enable extended advertising`, or set in `nimconfig.h` for Arduino, or in `build_flags` in PlatformIO. + +When enabled the following will occur: +* `NimBLEScan::start` method will scan on both the 1M PHY and the coded PHY standards automatically. + +* `NimBLEClient::connect` will use the primary PHY the device is listening on, unless specified (see below). + +* `NimBLEClient::setConnectPhy` becomes available to specify the PHY's to connect with (default is all). + +* `NimBLEAdvertising` is no longer available for use and is replaced by `NimBLEExtAdvertising`. `NimBLEDevice::getAdvertising` will now return an instance of `NimBLEExtAdvertising`. + +* `NimBLEAdvertisementData` is no longer available for use and is replaced by `NimBLEExtAdvertisement`. This new class is where everything about the advertisement is configured, including the advertisement intervals and advertisement ended callback. + + + diff --git a/lib/libesp32_div/esp-nimble-cpp/docs/Doxyfile b/lib/libesp32_div/esp-nimble-cpp/docs/Doxyfile new file mode 100644 index 000000000000..c67e49f5a7fa --- /dev/null +++ b/lib/libesp32_div/esp-nimble-cpp/docs/Doxyfile @@ -0,0 +1,2778 @@ +# Doxyfile 1.9.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = esp-nimble-cpp + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = 1.4.1 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = doxydocs + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# numer of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:^^" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = YES + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = YES + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = NO + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# Possible values are: NO, YES and FAIL_ON_WARNINGS. +# The default value is: NO. + +WARN_AS_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = ../CHANGELOG.md \ + . \ + ../src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, +# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C +# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.doc \ + *.txt \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f18 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = ../src/nimconfig_rename.h + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# ANamespace::AClass, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = index.md + +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: +# http://clang.llvm.org/) for more accurate parsing at the cost of reduced +# performance. This can be particularly helpful with template rich C++ code for +# which doxygen's built-in parser lacks the necessary type information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS +# tag is set to YES then doxygen will add the directory of each input to the +# include path. +# The default value is: YES. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_ADD_INC_PATHS = YES + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +# If clang assisted parsing is enabled you can provide the clang parser with the +# path to the directory containing a file called compile_commands.json. This +# file is the compilation database (see: +# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the +# options used when the source files were built. This is equivalent to +# specifying the -p option to a clang tool, such as clang-check. These options +# will then be passed to the parser. Any options specified with CLANG_OPTIONS +# will be added as well. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. + +CLANG_DATABASE_PATH = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. Default setting AUTO_LIGHT +# enables light output unless the user preference is dark output. Other options +# are DARK to always use dark mode, LIGHT to always use light mode, AUTO_DARK to +# default to dark mode unless the user prefers light mode, and TOGGLE to let the +# user toggle between dark and light mode via a button. +# Possible values are: LIGHT Always generate light output., DARK Always generate +# dark output., AUTO_LIGHT Automatically set the mode according to the user +# preference, use light mode if no preference is set (the default)., AUTO_DARK +# Automatically set the mode according to the user preference, use dark mode if +# no preference is set. and TOGGLE Allow to user to switch between light and +# dark mode via a button.. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use gray-scales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2 + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see https://docs.mathjax.org/en/v2.7-latest/tex.html +# #tex-and-latex-extensions): +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /